- PVSM.RU - https://www.pvsm.ru -
TorChat — это анонимный кроссплатформенный мессенджер, использующий сеть Tor и шифрующий переписку. В данной статье рассмотрен протокол, используемый TorChat, и улучшения, внесённые в реализацию TorChat на Python.
Система обеспечения анонимности Tor, которая часто всплывает в СМИ, служит для анонимного посещения и создания сайтов. Любой желающий может получить «домен» вида test3unszyhvy7um.onion и через несколько секунд этот сайт станет доступен для посещения всеми пользователями сети Tor. Для создания домена создается RSA-ключ, от публичной части которого вычисляется хеш-сумма (в случае данного домена она равна test3unszyhvy7um). Tor запоминает соответствие доменного имена публичному ключу в DHT. Такой сайт называется hidden service. Tor создает TCP-соединение между клиентом и hidden service. Через такое соединение можно пропускать разные протоколы: HTTP(S), SSH, IRC, Bitcoin и другие. Описание одного из таких протоколов, TorChat, находится в следующем разделе.
Алгоритм подключения к hidden service [2] не связан напрямую с темой статьи, его рассмотрение заслуживает отдельной статьи. Пока что отмечу важные моменты. Доменное имя hidden service невозможно отобрать без доступа к приватной части ключа RSA. Невозможно прослушивать канал между клиентом и hidden service или подменять данные на этом канале. Невозможно узнать IP-адрес, на котором работает hidden service или IP-адрес её клиента.
Данный раздел базируется на файле tc_client.py [3]. В файле достаточно комментариев, однако протокол в текстовом виде отсутствует.
Клиенты взаимодействуют напрямую через Tor, серверов в системе TorChat нет. Клиент запускает собственный процесс Tor или использует уже запущенный Tor, управляя им через Control port.
Каждый пользователь имеет собственный hidden service с доменное именем вида abc.onion, на котором он слушает порт 11009. Первая часть имени (abc) имет длину 16 символов, может состоять из символов 234567abcdefghijklmnopqrstuvwxyz (base32) и служит в качестве TorChat ID. Каждый пользователь имеет возможность подключаться к другим пользователям через их TorChat ID.
Tor гарантирует, что данным доменным именем может управлять только его создатель, держатель соответствующего ключа. Однако о том, кто подключается к hidden service, нет никакой информации, поэтому аутентификация включает создание обратного соединения. Итак, допустим, Алиса (alice.onion) подключается к Бобу (bob.onion). Для этого Алиса отправляет Бобу сообщение вида «ping alice <случайная строка от Алисы>». Боб отправляет Алисе «ping bob <случайная строка от Боба>» и «pong <случайная строка от Алисы>». Алиса отвечает «pong <случайная строка от Боба>». Стороны сравнивают отправленные и полученные случайные строки. Совпадение строк подтверждает, что входящее соединение действительно от того, кем оно «представляется». Таким образом, оба имеют по паре сокетов (входящий и исходящий) и уверенность, что входящий сокет от того же, кому направлен исходящий. Сообщения по сокетам передаются только в одном направлении (за исключением передач файлов, которые передаются в противоположном направлении, чтобы не конкурировать с передачей текста).
Схема протокольного сообщения в TorChat:
<command> <encoded>n
Команда может содержать только строчные латинские буквы и знаки подчеркивания. Encoded состоит из любых символов, кроме символа конца строки. Символ конца строки заменяется на «» и «n». Предварительно «» заменяется на «» и «».
Список команд:
Мне удалось найти 4 реализации клиента TorChat.
torchat_py [4] на Python от Prof7bit (Bernd Kreuss, Hannover, Germany), 2007 год. Первая реализация. Сейчас находится в ветке torchat_py репозитория на github.
torchat2 [5] на Lazarus + Free Pascal от Prof7bit. Новая реализация, 2012 год. Упрощён запуск нескольких экземпляров на одной машине. Ядро полностью отделено от GUI, что позволяет запускать в том числе без GUI. Реализован плагин для библиотеки Purple, которую используют IM-клиенты Pidgin и Finch. Использует всего один поток исполнения на программу. Питоновская создает несколько потоков на каждый контакт.
TorChat для Max OS X [6] от Julien-Pierre Avérous, Франция. В 2010 году написан на C++, в 2013 году код залит на github [7], затем от C++ перешли к Objective-C. Есть возможность делать приватные заметки о собеседнике или блокировать собеседника. Есть многопользовательский чат.
jTorchat [8] на Java от daux2a. Написан в 2012 году. Не реализована передача файлов. Добавлен широковещательный режим, позволяющий передавать сообщения всем пользователям сети TorChat, даже тем, которых нет в списке контактов. Реализован запрос случайного собеседника из сети.
Были изучены дистрибутивы Gentoo, Debian, OpenSuse, Fedora и Windows.
На данных момент TorChat включён только в дистрибутив Debian.
Страница пакета: packages.debian.org/wheezy/torchat [9]
Рассмотрим реализацию TorChat на Python версии 0.9.9.553 [10].
При отправке сообщений получателю, которого нет в сети, эти сообщения сохраняются локально и отправляются с префиксом [delayed], когда получатель появляется в сети одновременно с отправителем. Отправитель получает уведомление [delayed messages have been sent].
Если оставить TorChat включённым на неделю и не пользоваться им, то получится примерно 50 мегабайт исходящего и 100 входящего трафика. Создание нового аккаунта происходит мгновенно (время генерации ключа RSA), первая активация занимает полминуты. Последующие активации происходят за пару секунд. Видимо, при первой активации время тратится на «первое знакомство» программы Tor с сетью Tor.
Когда создают новый аккаунт TorChat, он автоматически добавляется в контакты к себе под ником self. Это полезно по многим причинам. Во-первых, статус этого контакта показывает, в сети ли наш аккаунт. Во-вторых, можно быстро скопировать свой TorChat ID (правая кнопка мыши — Copy ID to clipboard). В-третьих, «переписываясь» с собой, можно оценить задержку сети. Обычно пинг порядка 1 секунды. В-четвёртых, этот контакт удобно использовать в плагинах, например в конференции (см. ниже).
В папке с программой лежит файл portable.txt. Если он есть, папка программы используется для хранения конфигов. Иначе используется папка ~/.torchat или ~/.torchat_<название аккаунта>. Название аккаунта подается аргументом командной строки. Конфиг включает файлы buddy-list.txt и torchat.ini и папку Tor с RSA-ключом.
Интерес представляют модули tc_client.py [11] (ядро), tc_gui.py [12] (GUI), dlg_settings.py [13] (окно настроек), config.py [14] (хранилище настроек).
В файле tc_client.py [11] есть классы:
В файле tc_gui.py [12] находится код на wxPython. Из интересных классов: ChatWindow [21] (окно чата), MainWindow [22] (основное окно, содержит ссылку на BuddyList).
В файле dlg_settings.py [13] всего один класс, Dialog, отвечающий за окно настроек. Добавление своих пунктов в окно настроек из плагина происходит путём подмены метода addPluginSettings [23] (метод добавлен в моём форке).
Файл config.py [14] содержит функции-обёртки set [24] и get [25] для ConfigParser из стандартной библиотеки Python. В этом же файле находятся значения настроек по умолчанию (config_defaults). Настройки хранятся в файле torchat.ini.
Список контактов хранится в файле buddy-list.txt в табличном виде (torchat_id [локальный ник]).
Переводы реализованы как файлы lang_xx.py, где xx — код языка. Файлы лежат в папке translations [26]. Каждый текст для перевода хранится в переменной, на которую ссылаются из остальных частей программы. Нестандартный вариант, зато удобен при написании плагинов: нужно просто создать необходимые переменные в соответствующих модулях. TorChat переведён на много языков, в том числе на русский (2011 год, переводчик: SB14.org, RusInfo.cc).
Люди жаловались, что в TorChat не хватает кое-каких функций. Некоторые из них, например возможность запуска нескольких экземпляров, очень просты в реализации. Странно, что автор их сразу не сделал. Другие (например многопользовательские чаты) уже не так просты, однако их можно реализовать без изменения протокола (способ описывался на хабре). Наконец, есть вещи, требующие изменений протокола, например голосовая связь. Я вообще не уверен, что её реализация возможна, с учётом задержек сети Tor. Наконец, есть вещи, которые наверняка сделать не получится. К таким вещам относится видеосвязь.
Когда накопилась критическая масса запросов к TorChat, я начал думать, как получить эти функции. К сожалению, основной разработчик в данный момент неактивен, его нет в TorChat и по почте с ним не удаётся связаться. Писать на Pascal, Java, Objective-C или Max OS X мне не хотелось, поэтому сделал ставку на старую Python-реализацию, вопреки предпочтениям автора. Python и реализация TorChat на Python оказались очень удобными для написания плагинов и внесения улучшений. Дополнительным аргументом стало то, что именно Python-реализацию включили хотя бы в один дистрибутив, Debian.
Когда я стал изучать исходники, мне сначала показалось, что не зря говорили, что код низкого качества. Видимо, этому поспособствовало описание протокола исключительно в исходниках. Однако потом я вгляделся и увидел, что протокол и реализация выполнены на совесть. Осмелюсь предположить, что автор, когда писал этот код несколько лет назад, не имел особого опыта с Python. Кое-где можно встретить <>, которое говорит о «бейсиковском» или «паскалевском» прошлом. Тем не менее, код написан на славу.
Я форкнул [27] репозиторий на github и довольно быстро сделал всё, что хотелось. Что было сделано:
Хотелось бы включить их в Debian отдельно от новшеств.
Автор: bit_fag
Источник [46]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/python/48439
Ссылки в тексте:
[1] Image: https://github.com/prof7bit/TorChat
[2] Алгоритм подключения к hidden service: https://www.torproject.org/docs/hidden-services.html.en
[3] tc_client.py: https://github.com/prof7bit/TorChat/blob/torchat_py/torchat/src/tc_client.py
[4] torchat_py: https://github.com/prof7bit/TorChat/tree/torchat_py
[5] torchat2: https://github.com/prof7bit/TorChat/tree/torchat2
[6] TorChat для Max OS X: http://www.sourcemac.com/?page=torchat
[7] github: https://github.com/javerous/torchat-mac
[8] jTorchat: https://github.com/jtorchat/jtorchat
[9] packages.debian.org/wheezy/torchat: http://packages.debian.org/wheezy/torchat
[10] 0.9.9.553: https://github.com/prof7bit/TorChat/tree/17e7e51d1ed330807ba9d3df5481e6eca32e7068/torchat/src
[11] tc_client.py: https://github.com/prof7bit/TorChat/blob/17e7e51d1ed330807ba9d3df5481e6eca32e7068/torchat/src/tc_client.py
[12] tc_gui.py: https://github.com/prof7bit/TorChat/blob/17e7e51d1ed330807ba9d3df5481e6eca32e7068/torchat/src/tc_gui.py
[13] dlg_settings.py: https://github.com/prof7bit/TorChat/blob/17e7e51d1ed330807ba9d3df5481e6eca32e7068/torchat/src/dlg_settings.py
[14] config.py: https://github.com/prof7bit/TorChat/blob/17e7e51d1ed330807ba9d3df5481e6eca32e7068/torchat/src/config.py
[15] BuddyList: https://github.com/prof7bit/TorChat/blob/17e7e51d1ed330807ba9d3df5481e6eca32e7068/torchat/src/tc_client.py#L529
[16] добавления: https://github.com/prof7bit/TorChat/blob/17e7e51d1ed330807ba9d3df5481e6eca32e7068/torchat/src/tc_client.py#L619
[17] удаления: https://github.com/prof7bit/TorChat/blob/17e7e51d1ed330807ba9d3df5481e6eca32e7068/torchat/src/tc_client.py#L632
[18] Buddy: https://github.com/prof7bit/TorChat/blob/17e7e51d1ed330807ba9d3df5481e6eca32e7068/torchat/src/tc_client.py#L176
[19] отправки сообщения: https://github.com/prof7bit/TorChat/blob/17e7e51d1ed330807ba9d3df5481e6eca32e7068/torchat/src/tc_client.py#L310
[20] ProtocolMsg: https://github.com/prof7bit/TorChat/blob/17e7e51d1ed330807ba9d3df5481e6eca32e7068/torchat/src/tc_client.py#L1112
[21] ChatWindow: https://github.com/prof7bit/TorChat/blob/17e7e51d1ed330807ba9d3df5481e6eca32e7068/torchat/src/tc_gui.py#L1097
[22] MainWindow: https://github.com/prof7bit/TorChat/blob/17e7e51d1ed330807ba9d3df5481e6eca32e7068/torchat/src/tc_gui.py#L1786
[23] addPluginSettings: https://github.com/bit-fag/TorChat/blob/34ea697e950bc3c25130d3fc8911ae86098686d0/torchat/src/dlg_settings.py#L119
[24] set: https://github.com/prof7bit/TorChat/blob/17e7e51d1ed330807ba9d3df5481e6eca32e7068/torchat/src/config.py#L299
[25] get: https://github.com/prof7bit/TorChat/blob/17e7e51d1ed330807ba9d3df5481e6eca32e7068/torchat/src/config.py#L267
[26] translations: https://github.com/bit-fag/TorChat/tree/34ea697e950bc3c25130d3fc8911ae86098686d0/torchat/src/translations
[27] форкнул: https://github.com/bit-fag/TorChat/tree/torchat_py
[28] нужно было: https://github.com/prof7bit/TorChat/blob/torchat_py/torchat/doc/howto_second_instance.html
[29] плагина: https://github.com/bit-fag/TorChat/blob/torchat_py/torchat/src/plugins/fake_user_agent.py
[30] плагина: https://github.com/bit-fag/TorChat/blob/torchat_py/torchat/src/plugins/ping.py
[31] плагина: https://github.com/bit-fag/TorChat/blob/torchat_py/torchat/src/plugins/rps.py
[32] bash-скрипт: http://pastebin.com/7PeXNhwB
[33] программу на Qt: https://github.com/bit-fag/rpsqt
[34] плагина: https://github.com/bit-fag/TorChat/blob/torchat_py/torchat/src/plugins/add_password.py
[35] плагина: https://github.com/bit-fag/TorChat/blob/torchat_py/torchat/src/plugins/conference.py
[36] Плагин: https://github.com/bit-fag/TorChat/blob/torchat_py/torchat/src/plugins/disable_echo.py
[37] Исправлена ошибка при выставлении checked для чекбокса: https://github.com/bit-fag/TorChat/commit/916e7f9d0fc210052bf04e9012db6999bbf1ee08
[38] Если пользователь удаляет аватар, то у его контактов висел старый аватар до рестарта программы: https://github.com/bit-fag/TorChat/commit/99d64426451dd4e99ef228656f781f94c9a87266
[39] Используемый тип прокси-сервера изменен с SOCKS4 на SOCKS5: https://github.com/bit-fag/TorChat/commit/b69465fb816d32c7d9c78edb4540210c248a4dfd
[40] Починено в некоторых случаях отражение изменения пользователем своего ника у других пользователей: https://github.com/bit-fag/TorChat/commit/d38d51b5f2135f0b0234ef0bd1d58c29c0dc69b5
[41] Забытые () после вызова функции: https://github.com/bit-fag/TorChat/commit/fe43c02725d52c0ce8e26d7da76559347416078c
[42] Дезинфекция имени пользователя, полученного от него: https://github.com/bit-fag/TorChat/commit/3f3406884892725d564626d8056f96875068ea9a
[43] tails: https://tails.boum.org/
[44] torfone.org: http://torfone.org
[45] пулл-реквест: https://github.com/prof7bit/TorChat/pull/47
[46] Источник: http://habrahabr.ru/post/201696/
Нажмите здесь для печати.