\ IPV6_MODE ON 72000 PacketSize ! 4 TO WriteSocketRetryDelay 100 TO ListenQlen \ максимальная очередь запросов коннекта к серверному сокету MaxThreads: 1000 \ максимальное число потоков в пуле, включая усыпленные - ожидающие заданий или в/в MaxConcurrentThreads: 4 \ максимальное число одновременно _выполняемых_ потоков MaxSPoolLen: 20 \ максимальная длина очереди сокетов, направленных в пул MaxIsapiCnt: 30 \ максимальное число одновременно запущенных isapi-скриптов MaxCgiCnt: 40 10000 TO vUdpSockets \ UsePool \ 1 FcgiServers ! \ vSEvDebug ON \ vDebugRules ON GetDNS 0= | SMTP[DNSServer] DNS,, Server[ExternIPs] ExternIPlist SelectPort WARNING OFF : HTTP-PROXY\OnThreadConnect ALSO __PROXY__ 300000 TIMEOUT ! \ 5 минут на исходящие коннекты \ 7 LogLevel ! S" PROXY[DebugNtlm]" EVALUATE >FLAG uNtlmDebug ! S" PROXY[WeakNtlm]" EVALUATE >FLAG uNtlmWeak ! S" E4auth" SetAuthMethod \ для случая Basic-авторизации SelectTPlan ; : OnConnect \ Port [ IRC[Port] >NUM ] LITERAL = \ IF IRC ELSE HTTP THEN Port MyPORT @ = IF HTTP ELSE Port ExecPortProto? IF EXECUTE ELSE TcpMaps THEN THEN ; : NMSG2 ( id str -- ) STR@ S" :syslog PRIVMSG &logs :" StringAfter DROP <{hh:mm:ss}: {s}" STR@ CFPUT DROP ; : IRC\OnThreadConnect 0 SetTimeout IrcWelcome 5 LogLevel ! ; : HTTP\OnThreadConnect \ uUseTransmitFile ON 120000 SetTimeout S" HTTP[CgiTimeout]" EVALUATE >NUM uCgiTimeout ! ['] NMSG2 uNMSG ! Port [ HTTP[SslPort] >NUM ] LITERAL = Port [ HTTP[AdminSslPort] >NUM ] LITERAL = OR IF S" HTTP[Certificate]" EVALUATE DUP 0= IF 2DROP S" Server[Certificate]" EVALUATE THEN S" HTTP[SslVerifyClient]" EVALUATE >NUM vClientSocket SslServerSocket SetPeerCert SetSslClient SSL_CLIENT 250 LOG THEN ; : HTTPS\OnThreadConnect HTTP\OnThreadConnect ; : OnThreadConnect ( DebugProtocol vDebugRules ON) \ S" E4auth" SetAuthMethod S" AUTH[UseClientMac]" EVALUATE >FLAG TO vUseClientMac NewSession " {PROTOCOL}\OnThreadConnect" STR@ EvalRules ; : SslServerPem { a u -- a2 u2 } a u " ..\cert\{s}.pem" STR@ \ 2DUP TYPE CR 2DUP FILE-EXISTS IF EXIT THEN 2DROP a u ; ' SslServerPem TO vSslServer : http\SelectMailDocumentRoot StdFileMap SiteDomain GetDomDir ?DUP IF DocumentRoot EXIT THEN DROP " {Dirs[Domains]}/{SiteDomain}" STR@ 2DUP IsDirectory IF DocumentRoot EXIT THEN 2DROP " {Dirs[Domains]}/{HOST}" STR@ 2DUP IsDirectory IF DocumentRoot EXIT THEN 2DROP " {Dirs[Domains]}/{L2HOST}" STR@ 2DUP IsDirectory IF DocumentRoot EXIT THEN 2DROP HOST 4 MIN S" www." COMPARE-U 0= IF HOST 4 /STRING " {Dirs[Domains]}/{s}" STR@ 2DUP IsDirectory IF DocumentRoot EXIT THEN 2DROP THEN ; : http\SelectDocumentRoot HOST S" 127.0.0.1" COMPARE 0= IF S" localhost" SetHost THEN \ локально лучше соединяться с 127.0.0.1, т.к. \ по localhost браузеры сначала идут к ::1, замедляя процесс HOST 4 MIN S" wpad" COMPARE-U 0= IF S" localhost" SetHost THEN \ автодетект прокси HOST S" [::1]" COMPARE 0= IF S" localhost" SetHost THEN \ IPv6 localhost \ URI S" /e4a/*" ~= IF S" apps" DocumentRoot S" NOT_FOUND" SetAction EXIT THEN URI S" /MailClassify/*" ~= IF S" SMTP[SpamDir]" EVALUATE DocumentRoot S" Replace /" EVALUATE S" text/plain" SetContentType S" MailClassify" SetAction EXIT THEN " {Dirs[Root]}/{L2HOST}/{HOST}/wwwroot" STR@ 2DUP IsDirectory IF DocumentRoot EXIT THEN 2DROP " {Dirs[Root]}/{L2HOST}/{HOST}" STR@ 2DUP IsDirectory IF DocumentRoot EXIT THEN 2DROP " {Dirs[Root]}/{L2HOST}/wwwroot" STR@ 2DUP IsDirectory IF DocumentRoot EXIT THEN 2DROP " {Dirs[Root]}/{HOST}" STR@ 2DUP IsDirectory IF DocumentRoot EXIT THEN 2DROP " {Dirs[Data]}/web/{HOST}" STR@ 2DUP IsDirectory IF DocumentRoot EXIT THEN 2DROP " {Dirs[Data]}/wwwroot" STR@ 2DUP IsDirectory IF DocumentRoot EXIT THEN 2DROP " wwwroot/{HOST}" STR@ 2DUP IsDirectory IF DocumentRoot EXIT THEN 2DROP " wwwroot" STR@ 2DUP IsDirectory IF DocumentRoot EXIT THEN 2DROP http\SelectMailDocumentRoot ROOT_DIR NIP 0= IF HOST 2DUP S" :" SEARCH NIP NIP IF L2D THEN \ IPv6 непригоден в качестве имени каталога... " {Dirs[Domains]}/{s}" STR@ 2DUP " {s}\web\.auto_created" STR@ R/W CREATE-FILE-PATH IF DROP ELSE CLOSE-FILE DROP THEN DocumentRoot S" NOT_FOUND" SetAction THEN ; : http\DefFileHandler ROOT_DIR NIP 0= IF EXIT THEN \ корень документов не найден ['] FILENAME CATCH ?DUP IF ABS DUP " HTTP/1.0 500 Server error {n} (filename){CRLF}Content-Type: text/plain{CRLF}{CRLF}Server error {n} (filename)" FPUTS StopProtocol EXIT ELSE 2DUP S" *.rules.txt" WildCMP-U 0= IF 2DROP NotFound EXIT THEN 2DUP S" *.inc" WildCMP-U 0= IF 2DROP NotFound EXIT THEN 2DUP S" *fs.ini" WildCMP-U 0= IF 2DROP NotFound EXIT THEN 2DROP THEN URI S" /admin/*" ~= ( PeerIP IsMyIP 0= AND) UID @ 0= AND IF S" Unauthorized ADMIN" EVALUATE EXIT THEN URI S" /secret/*" ~= PeerIP IsMyIP 0= AND UID @ 0= AND IF S" Unauthorized AUTHOR" EVALUATE EXIT THEN FILENAME S" *.e" ~= IF ForthScript EXIT THEN FILENAME S" *.php*" ~= IF S" HTTP[PhpInterface]" EVALUATE S" ISAPI" COMPARE 0= IF S" Isapi PHP5" EVALUATE S' text/html' SetContentType ELSE S" HTTP[PhpInterface]" EVALUATE S" FastCGI" COMPARE 0= IF S" FastCgi {HTTP[PhpFastCgiPort]}" ELSE S" Cgi {HTTP[PhpBin]}" THEN EVALUATE THEN EXIT THEN FILENAME S" *.f" ~= IF S" Cgi fs\fs.exe" EVALUATE EXIT THEN FILENAME S" *.fs" ~= IF S" Cgi fs\fs.exe" EVALUATE EXIT THEN FILENAME S" *.fsk" ~= IF S" Cgi fs\fs.exe" EVALUATE EXIT THEN FILENAME S" *.cgi" ~= IF S" Cgi {HTTP[PerlBin]}" EVALUATE EXIT THEN FILENAME S" *.pl" ~= IF S" Cgi {HTTP[PerlBin]}" EVALUATE EXIT THEN FILENAME S" *\\fs.exe" ~= IF Cgi EXIT THEN ACTION S" Dav*" ~= 0= IF HTTP_METHOD S" HEAD" COMPARE IF S" SendFile" SetAction THEN THEN ; : Temp503 " apps{URI}" STR@ 2DUP FILE-EXISTS 0= >R IsDirectory R> OR IF \ " hosts/{HOST}/{URI}" STR@ R/W CREATE-FILE-PATH IF DROP ELSE CLOSE-FILE DROP THEN 503 PostResponse S' text/html' SetContentType S" PageTemplate apps/templ.html" EVALUATE EXIT THEN ACTION S" Dav*" ~= 0= IF HTTP_METHOD S" HEAD" COMPARE IF S" SendFile" SetAction THEN THEN S" apps" DocumentRoot S" DirectoryNotfound: index.e index.php index.jpg index.gif" EVALUATE S" DirectoryIndex: index.html index.php" EVALUATE URI S" *.e" ~= IF NotFound EXIT THEN URI S" *.f" ~= IF NotFound EXIT THEN DefContentTypes ; : LocalPrepro ACTION S" Dav*" ~= IF EXIT THEN URI S" *.e" ~= IF FilenameExists IF ForthScript THEN THEN ; : http\DAV S" text/xml" SetContentType \ 7 LogLevel ! UID @ IF User-Agent 4 MIN S" SVN/" COMPARE 0= \ SVN/neon не указывает "/" в урлах каталогов, и редиректами не заставить IF URI 2DUP TYPE ." ==" " /~{User}*" STR@ 2DUP TYPE CR ~= 0= IF UID 0! S" UNAUTHORIZED" SetAction S" Project members" $REALM S! EXIT THEN ELSE URI 2DUP TYPE ." ==" " /~{User}/*" STR@ 2DUP TYPE CR ~= 0= IF UID 0! S" UNAUTHORIZED" SetAction S" Project members" $REALM S! EXIT THEN THEN HOST 2DUP TYPE ." ===" " *{Domain}" STR@ 2DUP TYPE CR ~= 0= IF UID 0! S" UNAUTHORIZED" SetAction S" Project members" $REALM S! EXIT THEN THEN ; : http\OnRequest \ uCgiDebug ON 7 LogLevel ! ACTION S" Dav*" ~= 0= IF HTTP_METHOD S" HEAD" COMPARE IF S" " SetAction THEN THEN S" E4auth" SetAuthMethod S" " SetRole S" " SetGroup UID 0! $SiteDomain 0! HOST NIP 0= IF " {TIMESTAMP} Unknown vhost. {HTTP_METHOD} {URI?P} from {CLIENT}:{PeerPort}({ALL_HTTP}){CRLF}" STYPE S" unknown vhost" ForbiddenR EXIT THEN HOST S" .." SEARCH NIP NIP IF S" H.." ForbiddenR EXIT THEN \ подозрительные входные данные отказываемся обрабатывать \ URI S" ..txt" SEARCH NIP NIP 0= URI S" ../" SEARCH NIP NIP IF S" U.." ForbiddenR EXIT THEN URI S" ..\" SEARCH NIP NIP IF S" U.." ForbiddenR EXIT THEN HOST S" /" SEARCH NIP NIP IF S" /" ForbiddenR EXIT THEN HOST S" \" SEARCH NIP NIP IF S" \" ForbiddenR EXIT THEN URI S" <" SEARCH NIP NIP IF S" <" ForbiddenR EXIT THEN URI S" >" SEARCH NIP NIP IF S" >" ForbiddenR EXIT THEN \ URI S" /." SEARCH NIP NIP IF S" /." ForbiddenR EXIT THEN \ URI S" \." SEARCH NIP NIP IF S" \." ForbiddenR EXIT THEN URI S" *.db3" ~= IF S" /." ForbiddenR EXIT THEN URI S" ///" SEARCH NIP NIP IF S" ///" ForbiddenR EXIT THEN URI S" /\" SEARCH NIP NIP IF S" /\" ForbiddenR EXIT THEN URI S" \/" SEARCH NIP NIP IF S" \/" ForbiddenR EXIT THEN URI?P S" php?page=http" SEARCH NIP NIP IF S" page" ForbiddenR EXIT THEN HOST 4 MIN S" wpad" COMPARE-U \ Firefox спрашивает именно host wpad, без домена URI 5 MIN S" /e4a/" COMPARE AND \ "/e4a/*" наше в любом случае IF HOST IsMyHostname 0= IF HOST IsWpad 0= IF \ чужие и несуществующие имена хостов отказываемся принимать HOST " wrong host - {s}" STR@ ForbiddenR EXIT THEN THEN THEN \ внутренние скрипты могут выполняться без установки DocumentRoot URI S" /internal/co*" ~= IF S" TFORTH-SCRIPT" SetAction EXIT THEN URI S" /internal/*" ~= IF S" IFORTH-SCRIPT" SetAction EXIT THEN URI S" /RPC2" ~= IF S" IFORTH-SCRIPT" SetAction 7 LogLevel ! EXIT THEN Port MyPORT @ = IF URI S" /" COMPARE 0= IF S" /index.e" SetUri THEN S" debug" FILE-EXISTS IF S" F:\PRO\e4-installer\face" ELSE S" apps" THEN DocumentRoot ACTION S" Dav*" ~= 0= IF HTTP_METHOD S" HEAD" COMPARE IF S" SendFile" SetAction THEN THEN URI S" *.e" ~= IF ForthScript THEN ELSE http\SelectDocumentRoot THEN URI S" /e4a/*" ~= IF StdFileMap THEN S" DirectoryNotfound: 404.php download.php i.php 404.e 404.f 404.cgi 404.pl index.e index.f index.fs index.php index.cgi blosxom.cgi index.jpg index.gif" EVALUATE S" DirectoryIndex: index.e index.f index.fs index.php index.php3 index.cgi index.pl index.html index.htm default.htm blosxom.cgi" EVALUATE 7 IfLogLevel IF ." FILENAME: " FILENAME TYPE SPACE uAddDirCnt @ . uAddIndexCnt @ . uAddNotFoundCnt @ . ." PI:" PATH_INFO TYPE ." :" CR THEN FILENAME 2DROP \ инициализация \ S" text/html" SetContentType User NIP UID @ 0= AND \ пользователь указал пароль, попробуем авторизовать IF " {ROOT_DIR}/OnLogin.rules.txt" STR@ IncludeIfExists UID @ 0= IF LOGIN THEN \ если локальный вход не выполнен, попробуем глобальный (= по умолчанию) THEN URI S" /e4a/auth_http/*" ~= UID @ 0= AND IF S" Unauthorized AUTHOR" EVALUATE EXIT THEN \ URI S" /certified/*" ~= uSSL_CONTEXT @ AND uPEER_CERT @ 0= AND \ IF uSSL_OBJECT @ SslRenegotiate THEN \ на порт управления пускаем только авторизованных \ с остальными правами на этом порту разберутся сами скрипты Port MyPORT @ = IF PeerIP IsMyIP IF \ если локальный IP получился путём прохода через прокси, то \ тоже надо требовать авторизацию Via ( S" ESERV" SEARCH NIP) NIP UID @ 0= AND IF S" Unauthorized ADMIN_VIA_PROXY" EVALUATE EXIT THEN ELSE UID @ 0= IF S" Unauthorized ADMIN" EVALUATE EXIT THEN THEN UID @ IF S" HTTP[AdminUser]" EVALUATE OrigUser COMPARE 0= S" HTTP[AdminUser]" EVALUATE LoggedAs OR 0= IsSupervisor 0= AND IsAdmin 0= AND IF S" Unauthorized TO_ADMIN" EVALUATE EXIT THEN THEN URI S" /e4a/cam.png" ~= IF CamSample EXIT THEN URI S" /e4a/cam.mpng" ~= IF S" CamMpng" SetAction EXIT THEN URI S" /e4a/cam.mjpg" ~= IF S" CamMjpg" SetAction EXIT THEN URI S" /e4a/screen.bmp" ~= IF S" ScreenBmp" SetAction EXIT THEN URI S" /e4a/screen.png" ~= IF S" ScreenPng" SetAction EXIT THEN URI S" /CommonPlugins/*" ~= IF S" DocumentRoot: ..\CommonPlugins Replace /" EVALUATE URI S" */mstat/*.html" ~= IF S" Cgi fs\fs.exe" EVALUATE THEN URI S" *.exe" ~= IF S" Cgi" EVALUATE THEN URI S" */mstat/*.fxml" ~= IF ForthScript THEN EXIT THEN ELSE \ ACL не распространяется на админский интерфейс (выше), \ чтобы админ случайно не закрыл сам себе доступ URI HOST " {s}{s}" STR@ EvalACL IF arR AND 0= \ URL есть в ACL, и права чтения его нет (остальные права проверяют скрипты) IF UID @ 0= IF S" Unauthorized ACL" EVALUATE ELSE S" ACL" ForbiddenR THEN EXIT THEN ELSE DROP THEN URI S" /announce" COMPARE 0= IF S" BtAnnounce" SetAction EXIT THEN \ редиректы с закрытых трекеров не пускаем в wiki URI S" /scrape" COMPARE 0= IF S" BtScrape" SetAction EXIT THEN THEN Port MyPORT @ = 0= IF ROOT_DIR NIP IF " {ROOT_DIR}/OnRequest.rules.txt" STR@ 2DUP FILE-EXISTS IF IncludeIfExists ELSE 2DROP " {ROOT_DIR}/../OnRequest.rules.txt" STR@ IncludeIfExists " {ROOT_DIR}/../../OnRequest.rules.txt" STR@ IncludeIfExists ROOT_DIR S" Dirs[Domains]" EVALUATE SEARCH NIP NIP IF " {Dirs[Root]}/{L2HOST}/OnRequest.rules.txt" STR@ IncludeIfExists THEN THEN ELSE " {Dirs[Root]}/{L2HOST}/OnRequest.rules.txt" STR@ IncludeIfExists THEN THEN ACTION S" Dav*" ~= IF S" http\DAV" EvalRules THEN URI S" /wpad.dat" ~= IF S" WPAD" SetAction THEN \ PAC-скрипт для прокси URI S" /e4a/*" ~= 0= IF ACTION NIP IF LocalPrepro EXIT THEN \ была выполнена локальная обработка THEN http\DefFileHandler \ локальной обработки не было, ищем общий обработчик \ и, возможно, меняем поведение общего обработчика: ROOT_DIR NIP IF " {ROOT_DIR}/Prepro.rules.txt" STR@ 2DUP FILE-EXISTS IF IncludeIfExists ELSE 2DROP " {ROOT_DIR}/../Prepro.rules.txt" STR@ IncludeIfExists " {ROOT_DIR}/../../Prepro.rules.txt" STR@ IncludeIfExists THEN ELSE " {Dirs[Root]}/{L2HOST}/Prepro.rules.txt" STR@ IncludeIfExists THEN FILENAME IsDirectory URI + 1- C@ [CHAR] / <> AND PATH_INFO NIP 0= AND IF S" Redirect {URI}/" EVALUATE EXIT THEN ( URI S" /e4a/*" ~= 0= IF ROOT_DIR NIP 0= IF Temp503 EXIT THEN \ корень не нашелся, ошибка FILENAME FILE-EXIST 0= \ "вычисленный" путь не является ни файлом, ни каталогом и... ACTION S" NOT_FOUND" COMPARE 0<> AND IF Temp503 EXIT THEN \ и не определен как несуществующий, ошибка THEN nRESP_CODE @ 503 = IF EXIT THEN \ если ошибка была установлена раньше, уходим ) \ URI S" *.e" ~= IF S" FORTH-SCRIPT" SetAction S" text/html" SetContentType EXIT THEN (CONTENT-TYPE) NIP 0= IF DefContentTypes THEN URI S" /e4a/*" ~= IF FilenameExists 0= IF S" NOT_FOUND" SetAction S" apps" DocumentRoot THEN THEN ; : http\OnRequestComplete { \ a u } GetTime FILENAME -> u -> a 457 LOG uEntireFile @ IF a u S" *.exe" ~= a u S" *.zip" ~= OR a u S" *.rar" ~= OR a u S" *.7z" ~= OR a u S" *.cer" ~= OR ACTION S" EXEC_CGI" COMPARE AND IF 458 LOG THEN THEN \ POST_BODY ?DUP IF 5000 MIN 459 LOG ELSE DROP THEN \ 448 LOG \ " {DD.MM.YYYY};{hh:mm:ss}; {vCLIENT};{CurrentThreadNumber};{ThreadReuseCnt @};{nQueryCnt @};{UserEmail-};{nRESP_CODE @};{HTTP_METHOD};{WSTAT};{ACTION};{HOST};{URI?P};{FILENAME};{CONTENT-TYPE};{''}{User-Agent}{''};{''}{Referer}{''};{User};{Pass};{bps};{vReqElapsed};{uEntireFile @ ABS}" \ STYPE ; : OnDisconnect EndSession 0 __PROXY__::SetTargetConn vElapsed uOtherWriteStat @ uOtherReadStat @ uClientWriteStat @ uClientReadStat @ 450 LOG ; : OnShutdown ; : http\OnUnknownMethod ; : http\PreAction URI?P HOST ACTION " {s}: {s}{s}" STR@ SetSessionComment ; : OnLogRecv LogRecvAddr LogRecvSize GetTime 2DUP " {YYYY-MM-DD} {hh:mm:ss};{LogPeerIP NtoA}:{LogPeerPort};SYSLOG: {s}{CRLF}" STYPE " :syslog PRIVMSG &logs :{s}{CRLF}" STR@ SyslogBufCopy MSG-CHANNEL2 ; : /internal/coLOG 0 SetTimeout S" " CFPUT S" " CFPUT UID @ IF User $NICK S! ELSE IsLanClient 0= IF EXIT THEN S" admin" 2DUP $NICK S! SetLoggedUser THEN 0 S" &logs" SUBSCRIBE-CHANNEL vWid FGETS EvalCommand ; \ =================================== : FTP\OnThreadConnect ALSO __FTP__ Port [ FTP[SslPort] >NUM ] LITERAL = \ Implicit direct SSL connection IF S" FTP[Certificate]" EVALUATE DUP 0= IF 2DROP S" Server[Certificate]" EVALUATE THEN S" FTP[SslVerifyClient]" EVALUATE >NUM vClientSocket SslServerSocket SetPeerCert SetSslClient SSL_CLIENT 250 LOG uSSL_SOCKET @ 0= IF EXIT THEN \ DebugProtocol THEN " 220 {Server[HostName]} {PV} FTP ready. {DATE}{CRLF}" 220 PostFtpResult ; : ftp\OnRequest \ " .\wwwroot\~{User}" STR@ SetFtpDocumentRoot [ ALSO __FTP__ ] URI S" *..*" ~= IF COMMANDLINE S" CWD .." ~= 0= IF Forbidden EXIT THEN THEN FILENAME S" *::$*" ~= IF Forbidden EXIT THEN URI EvalACL IF DUP arR AND 0= COMMAND S" RETR" COMPARE 0= AND IF DROP Forbidden EXIT THEN DUP arW AND 0= COMMAND S" STOR" COMPARE 0= AND IF DROP Forbidden EXIT THEN DUP arL AND 0= COMMAND S" LIST" COMPARE 0= AND IF DROP Forbidden EXIT THEN DUP arL AND 0= COMMAND S" NLST" COMPARE 0= AND IF DROP Forbidden EXIT THEN DUP arD AND 0= COMMAND S" DELE" COMPARE 0= AND IF DROP Forbidden EXIT THEN arU AND 0= COMMAND S" APPE" COMPARE 0= AND IF Forbidden EXIT THEN ELSE DROP THEN [ PREVIOUS ] ; : ftp\OnRequestComplete 843 LOG OWSTAT IF 456 LOG THEN ; : ftp\OnLogin UID 0! \ сбиваем ip-авторизацию S" E4auth" SetAuthMethod User S" anonymous" ~= User S" ftp" ~= OR IF -1 UID ! ReadOnly S" FTP[DefaultDocumentRoot]" EVALUATE SetFtpDocumentRoot ELSE LOGIN UID @ IF ReadWrite ROOT_DIR SetFtpDocumentRoot ELSE StopProtocol THEN THEN S" /" SetWD ; : ftp\OnStat ( addr u -- ) ( Выполняется при получении команды STAT. На вход подается строка [addr u] с параметрами команды STAT. ) 2DROP " 550 STAT - access denied{CRLF}" FPUTS ; : ftp\SslAuth \ explicit AUTH SSL, AUTH TLS S" FTP[Certificate]" EVALUATE DUP 0= IF 2DROP S" Server[Certificate]" EVALUATE THEN S" FTP[SslVerifyClient]" EVALUATE >NUM vClientSocket SslServerSocket SetPeerCert SetSslClient SSL_CLIENT 250 LOG \ uSSL_SOCKET @ 0= IF EXIT THEN DebugProtocol ; : ftp\SslConnectPort ( socket -- ) S" FTP[Certificate]" EVALUATE ROT 0 SWAP SslServerSocket DROP 250 LOG ; : ftp\SslAcceptPasvConnection ( socket -- ) S" FTP[Certificate]" EVALUATE ROT S" FTP[SslVerifyClient]" EVALUATE >NUM SWAP SslServerSocket DROP 250 LOG ; \ =================================== : SOCKS\OnThreadConnect ALSO __PROXY__ 300000 TIMEOUT ! \ 5 минут на исходящие коннекты S" PROXY[SocksRequireAuth]" EVALUATE >FLAG IF RequireSocksAuth \ требовать авторизацию, будет доступен только Socks5 THEN 1410 LOG \ 25000 uMapSockMaxRead ! 20 uMapSockIntrSleep ! 6 LogLevel ! \ DebugProtocol SelectTPlan ProcessSocks uSOCKS-REP @ 1451 LOG ; : socks\OnRequest 1420 LOG TARGET-PORT MyPORT @ = IF TARGET-IP IsMyIP IF 5 AbortProtocol 1457 LOG EXIT THEN TARGET-HOST GetHostIP DROP IsMyIP IF 5 AbortProtocol 1457 LOG EXIT THEN THEN CheckTPlan ?DUP IF hh:mm:ss TYPE ." Quota exceeded, socks. Reason=" . TPLAN TYPE CR CloseConnection EXIT THEN TARGET-PORT TARGET-HOST " socks://{s}:{n}" STR@ EvalACL 0= IF DROP EXIT THEN ( acl_flags ) ( acl_flags ) arR AND 0= \ TARGET есть в ACL, и права чтения его нет IF 5 AbortProtocol 1458 LOG EXIT ELSE DROP THEN ; : socks\OnRequestComplete uLAST-ERROR @ ?DUP IF 1454 LOG THEN ; : socks\OnDatagram ( -- flag ) \ " Datagramm incomming, SOCKS5_UDP_HDR {TARGET-HOST}:{TARGET-PORT} " STYPE CR TRUE ; : socks\OnLogin S" E4auth" SetAuthMethod LOGIN UID @ IF SelectTPlan THEN ; : HTTP-PROXY\OnThreadConnect ALSO __PROXY__ 300000 TIMEOUT ! \ 5 минут на исходящие коннекты \ 7 LogLevel ! S" PROXY[DebugNtlm]" EVALUATE >FLAG uNtlmDebug ! S" E4auth" SetAuthMethod \ для случая Basic-авторизации SelectTPlan ; : http-proxy\OnRequestBegin ; : http-proxy\OnRequest uNtlmDebug @ IF ." NTLM_UID=" NTLM_UID @ . CR THEN URL SetSessionComment \ если в запросе были поля авторизации, то выполняем авторизацию, \ предварительно сбросив IP-авторизацию, если была UsedAuthMethod S" NTLM" COMPARE 0= IF UID 0! LoginUserNTLM THEN UsedAuthMethod S" Basic" COMPARE 0= IF UID 0! LOGIN THEN UID @ 0= IF S" PROXY[HttpRequireAuth]" EVALUATE >FLAG IF URL EvalACL IF arR AND 0= \ URL есть в ACL, и права чтения его нет ELSE DROP TRUE THEN \ URL нет в ACL IF S" ProxyUnauthorized PROXY" EVALUATE EXIT THEN THEN ELSE SelectTPlan \ переустановить тар.план, если была авторизация THEN CheckTPlan ?DUP IF DUP CLIENT UserEmail TPLAN " {TIMESTAMP} {s},{s},{s}, Quota exceeded, httpp. Reason={n}" STYPE CR " QUOTA_EXCEEDED_{n}" STR@ SetHttppAction EXIT THEN S" PROXY[UseRubricator]" EVALUATE >FLAG IF BsReopen TARGET-HOST GetHostRubric SetRubric RUBRIC NIP 0= IF S" unknown" SetRubric THEN THEN AvScan URL S" *.jpg" ~= IF AvNoScan THEN URL S" *.gif" ~= IF AvNoScan THEN URL S" *.png" ~= IF AvNoScan THEN URL S" *.ico" ~= IF AvNoScan THEN S" PROXY[DefaultCascade]" EVALUATE ?DUP IF \ указан родительский прокси; но к локальным хостам все равно надо обращаться напрямую TARGET-HOST IsMyHostname IF 2DROP ELSE TARGET-HOST IsWpad IF 2DROP ELSE \ внешние EVALUATE \ там строка в стиле E3 - CascadeVia: ... THEN THEN ELSE DROP THEN S" PROXY[UseCache]" EVALUATE >FLAG IF IsCachedFile IF S" FileIsOlderThanHours: {CacheAge}" EVALUATE IF RefreshCache ELSE SendFromCache THEN THEN ELSE NoCache THEN URL EvalACL 0= IF DROP EXIT THEN ( acl_flags ) ( acl_flags ) DUP arR AND 0= \ URL есть в ACL, и права чтения его нет IF UID @ IF arX AND IF UID 0! S" ProxyUnauthorized PROXY_ACL" EVALUATE \ перелогиниться ELSE ProxyAccessDenied THEN ELSE arX AND IF S" ProxyUnauthorized PROXY" EVALUATE ELSE ProxyAccessDenied THEN THEN ELSE DROP THEN ; : http-proxy\OnReplyHeaderEnd CONTENT-TYPE S" image/*" ~= IF AvNoScan THEN CONTENT-TYPE S" text/css" ~= IF AvNoScan THEN ; : http-proxy\OnRequestComplete CloseFileInCache \ иначе если был ACL-запрет, то кэшированный объект может достаться следующему запросу \ 433 LOG \ main.log \ 436 LOG \ log\* S" EStat[UseEstat]" EVALUATE >NUM IF 451 LOG THEN S" MStat[UseMstat]" EVALUATE >NUM IF 3010 S" MSTAT_LOG" EVALUATE THEN __PROXY__::CLIENT-WRITTEN DROP 454 LOG \ advsoft 461 LOG \ mod.squid BsCloseSocket ; : http-proxy\OnConnectError S" Unavailable conf\proxy-conn-err.html" EVALUATE ; : http-proxy\OnSendRequestError S" Unavailable conf\proxy-err.html" EVALUATE ; : http-proxy\OnUnknownMethod ; : http-proxy\OnUnknownProtocol ." http-proxy:" TARGET-PROT ." - unknown" CR ; : http-proxy\OnReadBodyError ; : http-proxy\OnReadHeadersError S" Unavailable conf\proxy-rh-err.html" EVALUATE ; : FTP-PROXY\OnThreadConnect ALSO __PROXY__ S" Timeout: {FtpProxy[Timeout]}" EVALUATE S" FtpProxy[UsePASV]" EVALUATE >FLAG __PROXY__::uUSE-PASV ! " 220 {PROG-NAME} FTP-proxy ready.{CRLF}" FPUTS ; : ftp-proxy\OnRequest ; : ftp-proxy\OnRequestComplete ; : ftp-proxy\OnLogin ; : ftp-proxy\OnTargetConnect ; : plugins\tcpmap\OnRequest ; : plugins\tcpmap\OnRequestComplete ; : plugins\tcpmap\OnThreadConnect \ 7 LogLevel ! ; : OnUdpRecv \ ." UDP packet on port=" Port . ." From IP:port=" \ UdpCLIENT TYPE ." :" UdpPeerPort . ." size:" RecvSize . ." D=" DEPTH . CR \ ." Packet: " RecvAddr RecvSize DUMP CR \ RecvAddr RecvSize Asn1Parse Asn1Dump Port IsUdpMappedPort IF DUP IsUdpMapAllowed IF ForwardPacket ELSE DROP THEN ELSE ForwardReplyPacket \ ." Sent UDP reply to: " UdpCLIENT TYPE ." :" UdpPeerPort . CR THEN ; \ =================================== \ DB3_DEBUG ON \ TP_DEBUG ON \ LDAP_DEBUG ON \ DHCP_DEBUG ON \ db3_shared_cache \ инициализация встроенных plugin'ов CreateSubsDispatcher CacheLogStrInit MlogcInit IniCache StatInit SyslogServerInit \ CreateLogSocket ' 2DROP TO dLOG acFilter[Port] >NUM TO qPopFilePort Dirs[Lists] ACCOUNTS_DB OpenCreateDb ACCOUNTS_SQH ! Dirs[Lists] GUESTS_DB OpenCreateDb GUESTS_SQH ! Dirs[Lists] TPLANS_DB OpenCreateDb TPLANS_SQH ! Dirs[Stat] TOKENS_DB OpenCreateDb TOK_SQH ! Dirs[Stat] EXTREFS_DB OpenCreateDb EREF_SQH ! \ db3_sync_off Dirs[Stat] REFS_DB OpenCreateDb REF_SQH ! \ db3_sync_off Dirs[Stat] VISITS_DB OpenCreateDb VISITS_SQH ! \ db3_sync_off " {Dirs[Domains]}/localhost" STR@ CREATE-DIRECTORY DROP " {Dirs[Domains]}/{Server[DefaultDomain]}" STR@ CREATE-DIRECTORY DROP ServiceMode @ 0= | TrayStartup UPNP[UseUPNP] >FLAG | UpnpInit DHCP[UseDHCP] >FLAG | DHCP[NetworkInterface] =~ LAN [IF] DhcpStartServer [ELSE] DHCP[NetworkInterface] GetHostIP DROP (DhcpStartServer) [THEN] ProxyCacheInit WARNING ON LoadCommonPlugins SchedulerInit MappingsInit AntivirusInit UpdInit Listen: {HTTP[Port]} {HTTP[NetworkInterface]} HTTP {HTTP[AdminPort]} {HTTP[AdminNetworkInterface]} HTTP {HTTP[SslPort]} {HTTP[SslNetworkInterface]} HTTP {HTTP[AdminSslPort]} {HTTP[AdminSslNetworkInterface]} HTTP {IRC[Port]} {IRC[NetworkInterface]} IRC {FTP[Port]} {FTP[NetworkInterface]} FTP {FTP[SslPort]} {FTP[SslNetworkInterface]} FTP {PROXY[SocksPort]} {PROXY[SocksNetworkInterface]} SOCKS {PROXY[FtppPort]} {PROXY[FtppNetworkInterface]} FTP-PROXY {PROXY[HttppPort]} {PROXY[HttppNetworkInterface]} HTTP-PROXY