Сессионная аутентификация на CheckPoint FW-1


После опубликования заметки "Борьба с Proxy ARP на Token-Ring'е", в которой косвенно был упомянут CheckPoint Firewall-1, я получил письмо от Константина Червоненко <chervone@rclotus.voz.ru>, жаловавшегося на проблемы с сессионной аутентификацией на файрволле.

Для тех кто не знает, небольшая справка: Firewall-1 использует множество схем аутентификации, и, при использовании одной из них -- сессионной, необходимо использование специального сессионного агента FW-1 Session Agent. Как это стало доброй традицией, CheckPoint не стал утруждать себя написанием версии для OS/2, в результате чего единственным способом выпустить пользователя OS/2 в Интернет стал отказ от сессионной аутентификации в пользу клиентской. Этот способ допускает аутентификацию с помощью броузера (для этого надо обратиться броузером по адресу http://ip_адрес_файрволла:900) или, например, телнетом зайти на 259 порт файрволла.

Однако для того, чтобы отказаться от сессионной аутентификации, надо быть, как минимум, администратором файрволла :) Поскольку Константин им не является, то пришлось искать другое решение проблемы. В течение двухнедельной переписки мы рассмотрели несколько вариантов, вкючая использование Win16-версии агента (в новой версии файрволла таковая уже отсутствует) и даже запуск Win32-версии посредством ODIN'а :). В процессе обсуждения я поделился с Константином скриптом autofwlogin.cmd, который представлял собой переписанный с помощью sunlover'а wwwget.zip Дмитрия Максимовича. Работа autofwlogin заключается в периодической аутентификации по http на 900'ом порту файрволла. Прошу отнестись к этому скрипту снисходительно и обратить внимание на то, что он и сейчас работает и не глючит :))) Естественно, autofwlogin не устроил Константина хотя бы тем, что не заменяет Session Agent'а. И вот результат, публикуемый с любезного разрешения Константина:

------------------------
/* FW Session authentification Agent */
/* Trace Results */

nl = '00'x
lf = '0a'x

parse arg fwaddr user pswd

/* Load REXX Socket library if not already loaded  */
IF RxFuncQuery("SockLoadFuncs") THEN DO
   rc = RxFuncAdd("SockLoadFuncs","rxSock","SockLoadFuncs")
   rc = SockLoadFuncs()
END

signal on SYNTAX Name UsrBreak
/* Вешаем 261 порт в ожидание */
l_sock = SockSocket('AF_INET','SOCK_STREAM',0)
IF l_sock < 0 THEN DO
   SAY 'UNABLE TO CREATE A SOCKET'
   Say 'ErrNo='errno 'H_ErrNo='h_errno
   EXIT -1
END
localaddr.family = 'AF_INET'
localaddr.port = '261'
localaddr.addr = SockGetHostId()
rc = SockBind(l_sock, 'localaddr.')
rc = SockListen(l_sock, 5)

call on halt Name UsrBreak
   /* Это чтоб из цикла по Ctrl-C можно было выйти */
do forever
     say 'Listen...'
     s = SockAccept(l_sock, 'address.')
     if address.addr\==fwaddr then do
          /* Это не наши.. */
          say 'This is Inthruder:' address.addr
          rc = SockShutDown(s, 2)
          rc = SockClose(s)
          iterate
     end
     do until s==0
          Buff = ''
          remlen = 256
          do until remlen < 256
          /* а что делать в сл. точно 256, я не знаю..*/
               remlen = SockRecv(s,'rest',256)
               Buff = Buff || rest
          end

          /* Разбираем на строки */
          do until Buff==''
               parse var Buff line_1 (lf) rest
               Buff = rest
               /* Выделяем код сообщения */
               parse var line_1 n rest
               Select
                 when n==331 then do
                    /* Это запрос! */
                    if pos('User:', rest)>0 then line_1 = user
                    else
                      if pos('assword:', rest)>0 then line_1 = pswd
                      else do
                         Say 'UnRecognized Ask:' line_1
                         signal UsrBreak
                    end
                    rc = SockSend(s, line_1||nl)
                 end
                 when n==200 | n==211 | n==220 then do
                    say line_1
                 end
                 when n==230 | n==530 then do
                    /* Ok либо NotOk */
                    say line_1
                    rc = SockClose(s)
                    s = 0
                 end
               Otherwise
                    Say 'UnRecognized Msg:' line_1
                    signal UsrBreak
               end /* select */
          end
     end
end

UsrBreak:
rc = SockShutDown(l_sock, 2)
rc = SockClose(l_sock)
rc = SockShutDown(s, 2)
rc = SockClose(s)

rc = SockDropFuncs()
-------------------------
Тут была прорва консольного output. Я их не всё после отладки вырезал. Так что в окошке во время browsing-а все время что-то идет, наверное притормаживает, но не сильно.

Вначале сгоряча чуть не сваял полномасштабную асинхронную обработку, да не хватило документации. В Rexx API сплошная ссылка на C API, а у меня всего-то и нашлось, что покорябанный с:\tcpip\dos\doc\winsock.txt из поставки Ося. К счастью/несчастью :-/, все эти вкусности оказались лишними.

Таким образом, Константину хватило таких стандартных средств OS/2, как Rexx и iptrace для того, чтобы победить и CheckPoint, и собственного администратора файрволла :) Обратите внимание на то, что приведенный скрипт представляет собой полноценный сервер, обслуживающий TCP соединения, так что при желании можно и httpd и ftpd на rexx написать :)
Степан Трубачёв


Интересные ссылки:
Комментариев к странице: 0 | Добавить комментарий
Домой | Проект ядро Core/2 | Проект OS/4 Download | Новости | Гостевая книга | Подробно обо всем | Нужные программы | Проекты | OS/2 FAQ | Всячина | За и Против | Металлолом | #OS2Russian | RDM/2 | Весёлые картинки | Наша галерея | Доска объявлений | Карта сайта | ПОИСК | ФОРУМ