The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

pop3 север на AWK (awk example shell)

<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>
Ключевые слова: awk, example, shell,  (найти похожие документы)
Date: Fri, 2 Mar 2001 20:17:26 +0000 (UTC) From: Valentin Davydov <> Newsgroups: Subject: pop3 север на AWK >Как Bourne shell (не bash) вывести такую строку: $ab'cd >echo '$ab\'cd' не работает. Вот, например, как в новой версии поппера сделано: # Copyright (C) Valentin Davydov, 2000-2001. # Version 0.2. # # Thanks to Solar Designer for security testing. # # THIS SOFTWARE IS PROVIDED AS IS, WITHOUT ANY WARRANTY. USE AT YOUR OWN RISK. # # This server is written in GNU awk and implements POP3 protocol (RFC1939). # For the simplicity of the popper itself, some other (than awk) system # utilities and facilities are of heavy usage. They are (attention porters!): # inetd, procfs, sh, hostname, md5, ls, tail, xargs, rm. Don't forget to allow # the server to access them by duly setting paths/permissions/environment. # Also some features (flaws ;-) of the POP3 protocol itself are abused, so # the server is likely to work only with strictly RFC1939-compliant clients. # # The server is normally started by inetd who should manage the TCP # connections and, probably, load balancing. Typical line for /etc/inetd.conf: # # pop3 stream tcp nowait pop:mail /usr/local/bin/gawk awk -f /path/popper.awk # # The user's mailboxes should be organized as follows: # # There is a directory, say, /var/mail/maildrop/ (which should be symlinked # to the /maildrop) with pop/mail ownership and no more than 1770 permissions. # In this directory there are subdirectories with the same ownership and # permissions. The name of each such subdirectory is calculated as MD5 # digest from the respective user id which thus become known to the server. # Note that this userids nothing to do with system users defined in # system /etc/passwd. In each this subdirectory two datasets should reside. # # One dataset is a single file called ".passwd" containing single line of text. # This line should be either user password in clear form (when APOP # authorization is used) or MD5 hash of the string composed from the directory # name (that is, MD5 hash of the user id) followed by a single space # followed by the user password followed by newline (in the case of USER/PASS # authorization). It is recommended to restrict read access to this file to # the popper only. # # The second (possible empty) dataset consists of the mail messages themselves. # Each message should occupy it's own file in the form of some single text line # (for example, "From " line used in Unix mailboxes) followed by a message in # RFC822 format, that is a number of header lines followed by an empty line # followed by a message body. Popper will read and possibly delete this # files during normal operation. # # The name of this file is used in UIDL listing, so only ASCII characters # from 0x21 to 0x7e are allowed in it by RFC1939. This implementation # further restrict this range by excluding characters 0x2e in the first # position (which is specially interpreted by ls) and 0x2f, which is not # allowed in Unix filenames. The convenient way of naming message files # is recommended to set filename equal to the MD5 hash of the file contents. # Besides, this politics provides some protection against duplicate messages. # If the same message is delivered to the several users, hardlinks to the # single file from their directories are OK. # # This implementation is still quite raw and possess some obvious bugs: # - The supplied parameters from client (user name, password, message # number etc.) are not checked for their length. While this is not (?) # harmful for the server itself, the underlaying structures may work # improperly, for example, the Unix filesystem will not allow filenames # longer than 255 characters, commandline for the md5 command is also # limited in length etc. # - The server is not robust with respect to misconfiguration, say, the # absence of some required files or presence of some redundant ones # leads to abnormal functioning. # - The user credentials (password) are seen in clear form as arguments # to the md5 subprocess. I don't know any workaround which will not # affect the multiprocess operation on the same maildrop :-( # - The unnecessarily detailed parsing of the message texts degrades the # performance on the long messages. # - The Unix filesystem implementation degrades the performance on the # maildrops with lots of messages. # - Usage of procfs, ls and so on is not highly portable. # BEGIN{IGNORECASE=1;FS="[[:space:]]+";ORS="\r\n";state="A" getline < "/proc/curproc/status"; close("/proc/curproc/status"); gsub (",","."); x="<" $2 "." $8 "@"; "hostname" | getline; close("hostname"); x=x $1 ">" print "+OK POP3", x;fflush()}; function md5(s, r){gsub("'","'\\''",s); "md5 -q -s '" s "'" | getline r; close ("md5 -q -s '" s "'"); return r} /^QUIT/{if(state=="T")state="U";exit}; /^APOP /&&state=="A"{us=md5($2); user="/maildrop/" us; if(system("cd " user)) {print "-ERR Unknown user"} else {getline i < (user "/.passwd"); close(user "/.passwd"); hash=md5(x i); if(hash==substr($3,1,32)){v=0;n=0; while(x="ls -ltr " user|getline) {if(NF-2){v+=$5;n+=1;mbox[n]=$9;sz[n]=$5;st[n]="N"}} close("ls -ltr " user) print "+OK " user " locked"; state="T"} else{print "-ERR Invalid password"; state="A"}} fflush();next} /^USER /&&state=="A"{us=md5($2); user="/maildrop/" us; if(system("cd " user)) {print "-ERR Unknown user"} else {print "+OK Please supply PASS for " user; state="AU"}; fflush();next}; /^PASS /&&state=="AU"{hash=md5(us " " substr($0,6,length-6) "\n") getline < (user "/.passwd") close(user "/.passwd") if(hash==$0){v=0;n=0; while(x="ls -ltr " user|getline) {if(NF-2){v+=$5;n+=1;mbox[n]=$9;sz[n]=$5;st[n]="N"}} close("ls -ltr " user) print "+OK " user " locked"; state="T"} else{print "-ERR Invalid PASS"; state="A"} fflush();next} /^STAT/&&state=="T"{print "+OK",n,v; fflush();next} /^LIST/&&state=="T"{if(length($2)==0) {print "+OK Listing follows"; for(i in mbox) {if(st[i]~/N|R/)print i,sz[i]}; print "."} else {if(st[$2]~/N|R/){print "+OK",$2,sz[$2]} else{print "-ERR No message",$2}} fflush();next} /^RETR /&&state=="T"{if(st[f=$2]~/N|R/){print "+OK Message",f,"follows" while(x="tail +2 " user "/" mbox[f]|getline){ if(/^\./){$0="." $0};print} print ".";fflush() close("tail +2 " user "/" mbox[f]) st[f]="R"} else{print "-ERR No message",f;fflush()} next} /^DELE /&&state=="T"{if(st[f=$2]~/N|R/){print "+OK Message",$2,"deleted" fflush();st[$2]="D";n-=1;v-=sz[$2]} else{print "-ERR No message", $2;fflush()} next} /^NOOP/&&state=="T"{print "+OK";fflush();next} /^RSET/&&state=="T"{x=0;for(i in mbox){if(st[i]~/D/) {st[i]="R";v+=sz[i];n+=1;x+=1}} print "+OK", x, x-1?"messages":"message", "restored" fflush();next} /^TOP /&&state=="T"{if(st[f=$2]~/N|R/){if((i=$3+1)>1){}else i=0 print "+OK Header and possible", e=i-(i>0), e-1?"lines":"line", "of body follows" e=0 while(x="tail +2 " user "/" mbox[f]|getline){ if(/^\./){$0="." $0} if(/^[[:space:]]*$/){e=1} i-=e if(i>=0) print; else break} close("tail +2 " user "/" mbox[f]) print "."} else{print "-ERR No message",f};fflush();next} /^UIDL/&&state=="T"{if(length($2)==0) {print "+OK Unique-id listing follows"; for(i in mbox) {if(st[i]~/N|R/)print i,mbox[i]}; print "."} else {if(st[$2]~/N|R/){print "+OK",$2,mbox[$2]} else{print "-ERR No message", $2}} fflush();next} {print "-ERR Command `" $1 "' not implemented or invalid";fflush()} END{if(state=="U"){print "+OK Updating " user; fflush(); ORS="\n" for(i in mbox){if(st[i]~/D/){print (user "/" mbox[i]) | "xargs rm"}}}}

<< Предыдущая ИНДЕКС Поиск в статьях src Установить закладку Перейти на закладку Следующая >>

 Добавить комментарий

Inferno Solutions
Hosting by

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру