pjmedia

written on Thursday, September 13, 2012

Есть такой хороший SIP-клиент Telephone.app. В ней используется одна хорошая библиотека pjsip, правда она под GPL, а библиотеки под GPL публикуют не очень хорошие люди.

И есть у этой библиотеки достаточно стремное поведение, которое наверняка где-то сто раз описано, но лишний раз тыкнуть палочкой будет не лишним.

Еще раз про деревянный voip

В заметке про webrtc есть описание примитивной реализации voip, краткое содержание тако: две программы говорят друг-другу UDP адреса, через котрые будут обмениваться голосовым трафиком. Лирические отступления по повоу кодеков и, аутентификации, виртуального номеронабирателя и виртуального подъема трубки оставим за кадром.

Сколько адресов у твоего модема

Современный интернет - это такая жопа с дефицитом адресов и криво настроенными маршрутизаторами, в которой у каждой хреновины есть по сто разных адресов.

Один из частных случаев - связь двух абонентов внутри одной локальной сети.

Первый абонент имеет внутренний адрес 192.168.1.44, второй абонент - 192.168.1.45, внешний адрес роутера, через который они ходят наружу - 109.109.255.230, а сервер, на котором они зарегистрированы имеет какой-то свой адрес, например 109.200.152.80

Когда один абонент звонит другому, поскольку они общаются SIP-пакетами через сервер, они оба указывают в качестве своего адреса, внешний адрес роутера:

192.168.1.44 -> 109.200.152.80 -> 192.168.1.45
c=IN IP4 109.109.255.230
m=audio 5320 RTP/AVP 102

192.168.1.45 -> 109.200.152.80 -> 192.168.1.44
c=IN IP4 109.109.255.230
m=audio 4001 RTP/AVP 102

Поскольку роутер может быть настроен черезжопу или кто-то из абонентов окажется дохуя умным и отправит свой внутренний адрес, может произойти следующее: первый абонент будет отправлять свой поток на внешний адрес роутера, а получать входящий с внутреннего адреса второго абонента:

// at 192.168.1.44
sendto(192.168.1.45, msg)

// at 192.168.1.45
sendto(109.109.255.230:4001, msg)
recvmsg(&addr, &msg)
// addr == 192.168.1.44:4001

Финт ушами в исполнении pjmedia

Я пока не увидел в стандартах какого-то указания по этому поводу, но pjmedia делают финт ушами - если голосовой поток приходит не с того адреса, который указан в SDP, то на адрес в SDP все забивают и дальнейшая коммуникация идет уже туда.

То есть живой MiTM, позволяющий угнать голосовую сессию и сесть посередие, зная адреса обоих абонентов и послав им парочку валидных RTP пакетов, даже с дурным пейлоадом или шумом.

Я понимаю, зачем это сделано - вдруг у абонента кривой роутер, кривой UA или вообще сменился адрес во время разговора. Я также понимаю, что в том софте, который я видел, шифрования голосового потока нет или оно выключено при сборке, либо при конфигурации. А если нет шифрования, то все изначально плохо, а активный MiTM просто делает все еще хуже, при том, что шифрование сразу все исправило бы.

This entry was tagged code, pjmedia and voip