Главная страница


ru.unix

 
 - RU.UNIX ----------------------------------------------------------------------
 From : Valentin Davydov                     2:5020/400     03 Mar 2001  00:17:26
 To : All
 Subject : Hовый поппер (Re: escaping)
 -------------------------------------------------------------------------------- 
 
 >   From: Eugene Grosbein <Eugene.Grosbein@f1.n5006.z2.fidonet.org>
 >   Date: Fri, 02 Mar 2001 11:08:56 +0300
 >
 >Как 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"}}}}
 --- ifmail v.2.15dev5
  * Origin: St. Petersburg State University (2:5020/400)
 
 

Вернуться к списку тем, сортированных по: возрастание даты  уменьшение даты  тема  автор 

 Тема:    Автор:    Дата:  
 Hовый поппер (Re: escaping)   Valentin Davydov   03 Mar 2001 00:17:26 
Архивное /ru.unix/4417310562a8.html, оценка 3 из 5, голосов 10
Яндекс.Метрика
Valid HTML 4.01 Transitional