ПРОЕКТЫ 


  АРХИВ 


  СТАТЬИ 


  ПЕРСОНАЛЬНОЕ 


  ПРОГРАММЫ 


Модули Apache 

Прочие программы 



ПИШИТЕ
ПИСЬМА














     ПРОГРАММЫ :: Прочие программы

cyrproxy - перекодировщик кириллицы для текстовых протоколов.
Версия 1.4.0

(C) 1996,1997,1998 Alex Tutubalin lexa@lexa.ru

частично использован код, написанный Vadim Kurland и Mike Shoyher

Download: ftp://ftp.lexa.ru/pub/domestic/lexa/


Copyright Notice

Эта программа появилась после того, как меня не удовлетворили несколько программ аналогичного назначения. Не так важно почему, но пришлось писать свою.

Мною были использованы куски из программы transl Вадима Курланда, втч в текущей версии перекодировщики для Telnet и Gopher взяты из transl без серьезных изменений. Функции, перекодирующие HTTP-протокол написаны после того, как я посмотрел на аналогичные функции, написанные Дмитрием Антиповым (dima@elvis.ru). Однако я совершенно не помнил как ко мне попала программа Антипова и не был уверен, что куски из нее можно использовать, поэтому весь HTTP-гейт написан с нуля.

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

  • сохраните в тексте упоминание о моем авторстве
  • пришлете мне тексты ваших правок по адресу lexa@lexa.ru

Если вы хотите использовать программу в коммерческих целях, то свяжитесь предварительно со мной (lexa@lexa.ru).

0. Что входит в состав пакета программ.
Изначально это была одна программа - cyrproxy, предназначенная для прозрачной для пользователя перекодировки русских букв в почте, http, gopher, telnet. Однако к настоящему моменту программ стало больше и приходится их документиро- вать. В комплект поставки входят:
  • cyrproxy - собственно программа для перекодировки tcp-соединений. Далее в этом тексте описаны процедуры ее наладки, настройки и использования
  • spy - программа, которая скидывает протокол tcp-соединения в логфайлы. См. README.spy (он еще не написан :). Пришлось написать для отладки HTTP-протокола.
  • discover - программа, восстанавливающая таблицу перекодировки по двум файлам с одинаковым содержанием, но в разных кодировках.
  • cyrtrans - перекодировщик-фильтр (stdin->stdout)
  • transfiles - скрипт, перекодирующий много файлов с помощью cyrtrans
  • transtree - скрипт перекодирующий целиком дерево каталогов
  • cyrwww - WWW-интерфейс к cyrtrans. Позволяет сделать Paste текста в окно броузера, нажать кнопку и получить перекодированный текст. Idea from Alexander Nikolaev (ati@samovar.ru). Сам я эту фичу не использую и не развиваю.
1.а Как это работает (в общих чертах).

Программа cyrproxy запускается через inetd и перенаправляет входящее соединение на любой tcp-порт любой доступной по ip машины. Это выглядит примерно так:

 $ tail /etc/services:

 smtp-cyr 10025/tcp  # SMTP-порт отличается от стандартного :)
 smtp-old 25/tcp    # А это порт, который эмулирует SMTP

 $ tail /etc/inetd.conf

 smtp-old stream tcp nowait root /usr/local/libexec/cyrproxy cyrproxy 
  -p smtp-cyr -h localhost
При входящем соединении на 25-й порт это соединение будет "прокинуто" на порт 10025 машины localhost с (возможной) перекодировкой.

1.б Принципы выбора перекодировок.

Перекодировки управляются конфигурационным файлом (см ниже) и/или опциями командной строки. Выбор перекодировки между клиентом и сервером производится на основе адреса клиента или адреса сервера (приоритет задается в конфигурационном файле). Выбор на основе адреса клиента очевиден (у всех клиентов разные адреса), выбор на основе адреса сервера подразумевает, что сервер имеет несколько ip-aдресов (разные интерфейсы или aliases одного интерфейса), скажем koi8.lexa.ru и win.lexa.ru, клиент при запросе указывает один из этих адресов, а сервер (перекодировщик) выбирает нужный вид перекодировки по destination address.

Все адреса (в конфигфайле и в командной строке) можно задавать либо в dotted notation, либо в символьном (host.my.domain) виде. При старте перекодировщика все символьные адреса преобразуются в IP-адрес и все сравнения производятся над ними. Естественно, задание адресов в cимвольном виде подразумевает работающий resolver.

1.в. Gateways.

Очевидно, что "простая побайтовая перекодировка" годится только для самых простых _текстовых_ протоколов (SMTP, POP3, NNTP). Более сложные протоколы (telnet, gopher, http) передают часть данных в двоичном виде, а перекодировать в них нужно только текстовую часть. Для этого в программу включены несколько разных "Gateways". На сегодняшний день существуют такие:

  • default - перекодирует весь поток байт, не разбираясь с их содержанием
  • telnet - поддерживает telnet protocol
  • gopher - анализирует протоколо gopher
  • pop, smtp - практически аналогичны default, за тем исключением, что в строке Content-Type: text/plain; charset=some_charset, в строку сharset= принудительно вписывается заданное администратором значение charset. POP gateway делает эту операцию на потоке сервер->клиент, SMTP-gateway - на потоке клиент-сервер.
  • http - анализирует содержимое http-потока данных и перекодирует только данные text/* и application/x-www-form-urlencoded. При этом, если для данного способа перекодировки описан 'emailcharset' (см ниже), то производится замена charset в HTTP-заголовке content-type (аналогично POP-gateway)

gateway по-умолчанию - default. Все остальные могут быть выбраны либо опцией командной строки, либо по TOS или номеру порта через описание в config file.

1.г Transparent Gateway
Иногда "для гарантии" хочется точно ничего не перекодировать. Для этого реализовано понятие transparent host. Идея заключается в том, что если адрес destination совпадает с адресом, описанным как transparent host, то все перекодировки отключаются и сервер действует аналогично программе cat.
1.д Transparent Exec
опция Transparent Exec (может быть задана только в командной строке) предназначена для того, чтобы запустить нужный сервис напрямую, а не через TCP-проброс. Это может быть полезно, например, в случае, когда сам запускаемый сервис должен определить адрес Peer. Т.е., например, если на 25-м порту висит перекодировщик, который запускает sendmail пробросом на другой порт, то в логах sendmail'а все 'relay' будут указаны как localhost, что неприятно. Решение таково:
  • хост, который работает как MX (скажем mx.lexa.ru) объявить TransparentHost'ом в конфигурационном файле cyrproxy.
  • при приходе клиента на этот хост вместо "себя" запускать (exec'ом) sendmail, тогда все его записи в лог будут корректными
  • при приходе клиента на другие virtualhosts ({koi8,win}.lexa.ru) - выполнять обычную перекодировку.

2. Installation.
a) Отредактируйте policy.h в соответствии с вашими вкусами (все опции там описаны).
Отредактируйте пути до configfile и таблиц в Makefile
Отредактируйте параметр SUBDIRS в Makefile (subdirs таковы:
discover -- программа, которая по двум текстам в разных кодировках строит перекодировочную таблицу
cyrcoder -- перекодировщик с командной строкой)
Запустите
		make all
Должны получиться исполняемыe файлы с программами

б) Кроме всего прочего, получится файл config.gen Его стоит поредактировать в соответствии с реалиями (hostnames и прочее).

в) 'make install-bin', 'make install-config' и 'make install-tables' установят бинарь, конфиг-файл (скопируют config.gen в $CONF_FILE) и таблицы для перекодировки соответственно. Эти три команды можно заменить одной -- make install

3. Таблицы перекодировки.
Это двоичные файлы длиной 256 байт. На каждый тип перекодировок (каждую кодовую таблицу) нужно два таких файла, один управляет перекодировкой "от клиента", второй - "от сервера". Содержание этих 256-байтных файлов должно отвечать такому замыслу: recoded_char = table[original_char];

4. Файл конфигурации
(по умолчанию - /etc/cyrproxy.conf. Путь задается в makefile) Синтаксис очень простой - либо комментарий (начинается с #, либо пустая строка, либо option-name value(s)

Возможные options такие:

a) tabledir tabledir - диpектоpия, в которой лежат таблицы перекодировки (умолчание задается при комппиляции в Makefile:

tabledir /usr/local/share/proxy

б) encoding Описание кодировок:
encoding name table_from_client table_to_client
name - имя кодировки, которое используется дальше, и два имени файлов, относительно $tabledir.
первый файл - перекодировка клиент->сервер, второй - наоборот. Зарезервированное имя NONE означает, что перекодировку производить не нужно (точнее, оно означает таблицу table[i] = i) Пример:

encoding koi8 NONE NONE
encoding alt  koi8-alt alt-koi8
encoding win  koi8-win win-koi8

в) emailcharset описание правила замены charset в строке Content-Type (POP, SMTP, HTTP) emailcharset encoding_name server-charset client-charset

encoding-name - имя кодировки из описания encoding
server-charset - строка, которую SMTP_gateway подставит в Content-Type: text/plain; charset=server-charset
client-charset - Charset, который увидит клиент при работе через POP3 или HTTP gateway

Если для кодировки описан emailcharset, то HTTP-gateway будет менять charset в Content-Type _только_ в заголовке и только если charset в заголовке уже имелся. Для POP3 и SMTP протоколов все гораздо хуже. Т.к. за одну сессию может быть передано больше одного письма, то я не вижу пристойного простого способа отделять заголовки писем от всего остального. Т.е. если письмо содержит (в теле) строку

Content-Type: text/plain; charset=some
То some будет заменен на charset, назначенный администратором.

Пример:

emailcharset win koi8-r windows-1251

г) transparenthost - см. раздел "5. Прозрачный фильтр"
Пример:
transparenthost ns.lexa.ru

д) encprecedence - в каком порядке выбирается тип кодировки.

Выбор кодировки может производиться по адресу клиента (Peer) и по адресу сервера (Virtual host). Порядок выбора определяется параметром encprecedence. Возможны два его значения - VP и PV, первое означает, что сначала происходит поиск по Virtualhost, если какая-то кодировка находится, то она и используется, если нет, то происходит поиск по Peer, если не найдено ничего, то используется кодировка, заданная параметром default. Пример:

encprecedence VP

е) default - кодировка по умолчанию (см выше).
Синтаксис - default <name> (<name> - одно из определенных выше имен кодировок).
Например:
default koi8

ж) gwprecedence. - порядок определения типа gateway (cм выше).
Gateway может выбираться по следующим параметрам:

  • задание в командной строке (при этом содержимое config-file игнорируется)
  • по номеру порта (имена портов пока не поддерживаются)
  • по значению поля TOS (Type of service) в TCP-пакетах.
Параметр gwprecedence может иметь два значения PT (сначала проверять номер порта, а потом TOS) и TP (сначала TOS, а потом номер порта).
gwprecedence  PT

з) option
- ассоциирует gateway и номер порта или значение TOS. Из примеров все понятно (после слова протокол идет одно из названий gateways - telnet, gopher, http)

option port 23 protocol telnet
option port 70 protocol gopher
option port 8080 protocol http
option tos  16 protocol telnet

и) peer - ассоциирует адрес клиента и кодировку. Используется если _все_ программы у клиента используют одну кодировку. Синтаксис:
peer <address> <encoding>
где <address> - IP-адрес или domain name
<encoding> - одна из кодировок, описанных выше.
Например:

peer 1.2.3.4 win

к) Virtualhost - ассоциирует адрес сервера и кодировку. Рекомендуется к использованию - используя virtualhost можно заставить работать у клиента программы в _разных_ кодировках.
Синтаксис:
virtualhost address encoding
где address - один из локальных адресов сервера (dotted notation or domain name)
encoding - одно из имен кодировок.
Например:

virtualhost win.lexa.ru  win

5. Параметры командной строки.
Запуск программы осуществляется через inetd. В командной строке задаются такие параметры:

а) Обязательные параметры:

  • -p port - имя (из /etc/services) или номер порта, на который будет осуществлен "проброс"
  • -h host - имя или адрес хоста, на который будет осуществлен проброс.

б) Необязательные:

  • -c configfile - использовать configfile вместо файла по умолчанию (файл по умолчанию задается в Makefile, в дистрибутиве это /etc/cyrproxy.conf)
  • -t timeout (в секундах) - задает таймаут для убиения соединений (соединение будет убито, если за это время по нему не проехало ни одного байта)
  • -g gwname (gwname - одно из слов default, telnet, gopher, http) - использовать указанный gateway, а не искать его по номеру порта/TOS -e encname - явно задает кодировку клиента и выключает поиск по конфигфайлу.
  • -T - включает режим Transparent Host для всех сочетаний адреса клиента и сервера.
  • -R - включает режим Transparent Exec. В этом режиме вместо transparent host mode ( не важно, заданной опцией -T или выбранной по destination address) перекодировщик выполняет execp() c такими параметрами: имя исполняемого файла - первая лексема после опции -R аргументы командной строки (argv[0]...) - все прочие параметры, до конца командной строки перекодировщика.

6. Некоторые замечания. Может получиться так, что при одинаковой собственно перекодировке, вам нужно разное поведение Gateways в зависимости от клиентского софта. Скажем, для части софтов нужно менять charset= в E-mail и HTTP, а для части нет. Кажущееся противоречие обходится очень просто: вы описываете две различных (по именам) кодировки с одинаковыми таблицами, а правила для них задаете разные. Примеры:

а) Установить замену charset для одного клиента (по адресу) персонально:


 encoding win  win-koi8 koi8-win 
 encoding win2  win-koi8 koi8-win 
 emailcharset win2  koi8-r windows-1251
 encprecedence PV
 peer 1.2.3.4 win2
 virtualhost win.my.domain win
б) Два виртуальных хоста с различным поведением:
 encoding win  win-koi8 koi8-win 
 encoding win2  win-koi8 koi8-win 
 emailcharset win2  koi8-r windows-1251
 virtualhost win.my.domain win
 virtualhost win-2.my.domain win2

7. Different software notes
а) sendmail.
К сожалению, я не нашел способа подвесить sendmail на другом порту с сохранением функциональности. Проблема заключается в том, что он вешается демоном на port=getservbyname("smtp") и ходит на тот же порт других хостов. Поэтому _нельзя_ переопределить номер порта smtp в /etc/services. Решение этой проблемы таково (в терминах /etc/services и /etc/inetd.conf):

$ tail /etc/services
 smtp	25/tcp
 smtp2  10025/tcp # этот номер может быть любым незанятым

$ tail /etc/inetd.conf
 # Проброс порта 25 на порт smtp2
 smtp	stream tcp nowait root /sbin/cyrproxy cyrproxy -p smtp2 -h localhost
 # запуск sendmail в inetd mode
 smtp2  stream tcp nowait root /usr/sbin/sendmail sendmail -bs
Возможное решение этой проблемы заключается в том, что:
при описании мэйлера smtp (или того, который занимается посылкой почты во внешний мир) явно задается номер порта 25, порт smtp переопределяется, sendmail подвешивается демоном на этом переопределенном порту, а со старого (25-го) порта делается проброс на новый.
Но я так еще не делал за ненадобностью.

Совместно с sendmail полезно использовать опцию -R перекодировщика, это позволяет иметь корректные адреса relays в логах и позволяет работать в secure mode (i.e. проверять соответствие HELO и адреса peer).

б) HTTP-servers.
Текущая версия httpGW работает только как перекодировщик, но не работает как proxy. Поэтому ее приходится использовать совместно с каким-то из http-proxies (Squid, Harvest, CERN, Apache 1.1). Идея заключается в том, что WWW-proxy подвешивается, скажем, к порту 8000, а перекодировщик - к порту 8080 ( -p 8000 -h localhost). Соответственно, WWW-browser'у нужно указать имя одного из virtualhosts в качестве адреса Proxy и порт 8080 как имя порта. С помощью этого перекодировщика можно, также, русифицировать "отдельно стоящий WWW-server". Это можно сделать, например, явным указанием типа gateway и кодировки в командной строке перекодировщика в inetd.conf. В предположении, что HTTP-сервер "расположен" на порте 80, командная строка может выглядеть как

  -p 80 -h localhost -e win -g http  - для перекодировщика на 'Windows-порту'
  -p 80 -h localhost -e msdos -g http  - для перекодировщика на 'MSDOS-порту'
Мне так приходилось делать, но вообще для "русификации отдельно стоящего сервера" cyrproxy не предназначена по тривиальной причине - она не ведет http-логов, а в логах сервера будет только адрес localhost. Рекомендую не забивать себе голову :), а взять 'Russian Apache' by Dmitry Kryukov (dvk@stack.net) and Alex Tutubalin с http://apache.lexa.ru/ и использовать его - для этой цели он существенно пригоднее

в) POP3.
Никаких особых проблем или замечаний.

г) Telnet.
В текущей версии использован telnetGW Вадима Курланда. Он довольно странно работает с telnet от FreeBSD, но таки работает.

д) Gopher.
Извините, но мне не на чем попробовать. Использован переработанный gopherGW Вадима Курланда, однако я его не проверял.

8. Feedback. Помощь и поддержка. Никакой поддержки и помощи я никому не обещаю. Но если вы таки решите ее у меня получить, то не нужно присылать мне письмо из одной строчки "твоя программа под ZUINIX не работает" (почему-то половина писем - именно такая :). Чтобы реально помочь, мне нужно знать гораздо больше:

  1. если программа не собирается. Мне нужно знать версию OS, версию компилятора, версию make и видеть те сообщения об ошибках, которые выдает компилятор, make итп (т.е. эти строчки). Только не нужно присылать графическую копию экрана, шлите текст.
  2. если программа не работает так как нужно. Раскомментируйте строчки про DEBUG_LOG и NETWORK_DEBUG в policy.h и пересоберите cyrproxy. Пришлите мне выдержку из лога, cyrproxy.conf и описание проблемы. Не забудте сообщить версию OS, версию компилятора.
Bugfix, перенос под другие OS итп.

Если вы нашли явную багу, перенесли cyrproxy под какую-то OS или добавили новую feature - не стесняйтесь, пришлите ваши изменения мне. Очень вероятно, что эти изменения (скорее всего, правда, в сильно измененном виде) будут включены в очередную версию cyrproxy.

Я буду рад услышать любые пожелания и предложения ( но не факт, что буду их воплощать). На настоящий момент запланированы следующие features:

  • конфигурация через autoconf/configure
  • корректная отработка Accept: в HTTP
  • Возможность подключения внешних gateways

Пишите мне на lexa@lexa.ru

9. Home site.
Новые версии программы будут появляться на ftp://ftp.lexa.ru/pub/domestic/lexa. Анонсы помещаются в relcom.unix (FIDO: RU.UNIX)

10. Ожидаемые баги :)
Я не имею возможности проверить таблицы для Macintosh, которые мне прислали. Прислали мне их со словами "С Eudora работает, а с Netscape - нет". Если у вас есть другие таблицы -- пришлите их мне. Лучше всего -- сразу полный набор (mac-iso, mac-alt, mac-win, mac-koi8) :)

11. Благодарности
Многие люди помогли мне найти многие баги. Я не в состоянии вспомнить всех, поэтому если вы не попали в этот список - не обижайтесь. Особую помощь оказали:
Mike Shoyher
Dmitry Barabanov
Bill Fick
Alexey Pialkin
... и многие другие.


 




Copyright © Lexa Software, 1996-2009.