#! perl # # script to implement Netscape Roaming access # note that you'll need to change $root and $PWDfile. # The scripts PWDCHANGE.CGI and PWDCREATE.CGI can be used # to help manage the password file # # Author: C. Lane lane@duphy4.physics.drexel.edu # use MIME::Base64; use Digest::MD5 qw(md5_hex); $CRINOID::Reuse = 1; $Verbose = 0; $PWDfile = 'sys$login:roaming_access.pwd'; $root = '../netscape_roam'; $method = $ENV{'REQUEST_METHOD'}; $what = $root.$ENV{'PATH_INFO'}; process_request(); print STDERR "ROAM.CGI: request completed\n" if $Verbose; done: $x = 1; sub process_request { my $authorized = 0; my $t = $ENV{'HTTP_AUTHORIZATION'}; my ($up, $CTL, $TSPECIALS, $user, $pass, $u, $p, $d); local *FH; if ($t =~ /^Basic\s+(\w+)/i) { $up = MIME::Base64::decode_base64($1); $CTL = '\000-\017\177'; $TSPECIALS = '\(\)\<\>\@\,\;\:\\\"\/\[\]\?\=\}\{\s'; if ($up =~ /^([^$CTL$TSPECIALS]*)\:/) { $user = lc($1); $pass = md5_hex(lc($')); if (open(FH,"<$PWDfile")) { while () { chomp; s/#.*//; s/^\s+//; s/\s+$//; s/\s+/ /; next if $_ eq ''; ($u,$p,$d) = split; $u =~ tr/[a-zA-Z0-9\_\-\$\.]/\?/c; next if (index($u,'?') != -1); next if (lc($u) ne $user); if ($p eq $pass) { $authorized = 1; } last; } close(FH); } } } if (!$authorized) { print "Status: 401 need authorization\n"; print "WWW-Authenticate: Basic realm=\"Roam\"\n\n"; return; } $what = $root.$d.$ENV{'PATH_INFO'}; my (@s); @dow = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'); @mon = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'); if ($method eq 'GET' || $method eq 'HEAD') { if (!-e $what) { print "Status: 404 File not found\n\n"; return; } @s = stat($what); print "Status: 200 OK\n"; print "Content-Type: text/plain\n"; print "Content-Length: $s[7]\n"; @g = gmtime($s[9]); $when = $dow[$g[6]].' '.$g[3].' '.$mon[$g[4]].' '; $when .= sprintf("%4.4d %2.2d:%2.2d:%2.2d",$g[5]+1900,$g[2],$g[1],$g[0]); print "Last-Modified: $when GMT\n\n"; if ($method eq 'GET') { open(FILE,"<$what") || return; $sent = 0; while(1) { $got = read(FILE,$buf,1024,0); if ($got > 0) { print $buf; $sent += $got; } else { last; } } print STDERR "ROAM.CGI: GET $what ($sent bytes)\n" if $Verbose; close FILE; } else { print STDERR "ROAM.CGI: HEAD $what\n" if $Verbose; } } elsif ($method eq 'DELETE') { if (-e $what) { while (-e $what) {unlink $what;} print STDERR "ROAM.CGI: DELETE $what (OK)\n" if $Verbose; } else { print "Status: 404 File not found\n"; print "Content-type: text/plain\n\n"; print "Attemp to delete non-existant file\n"; print STDERR "ROAM.CGI: DELETE $what (ERR)\n" if $Verbose; } } elsif ($method eq 'PUT') { $old = -e $what; $stat = "200: OK"; $stat = "201: Created"; # if !$old; unlink($what) if $old; if (open(FILE,">$what")) { $remain = $ENV{'CONTENT_LENGTH'}; $j = 0; while ($remain > 0) { $n = $remain > 1024 ? 1024 : $remain; $got = read(STDIN,$buf,$n, 0); $remain -= $got; print FILE $buf; } close FILE; print "Status: $stat\n\n"; print STDERR "ROAM.CGI: PUT $what ($j bytes)\n" if $Verbose; } else { print "Status: 500 Error opening file\n\n"; } } elsif ($method eq 'MOVE') { if (!-e $what) { print "Status: 404 file not found\n"; print "Content-type: text/plain\n\n"; print "Error 404: file not found\n"; return; } $new = $ENV{'HTTP_NEW_URI'}; # '/cgi/~lane/roam.pl/cookies' @x = split('/',$new); $new = pop(@x); if (index($new,'.') == -1) { $new .= '.'; } $new = $root.$d.'/'.$new; while (-e $new) {unlink($new);} if (rename($what,$new)) { print "Status: 200 OK\n\n"; print STDERR "ROAM.CGI: MOVE $what -> $new (OK)\n" if $Verbose; } else { print "Status: 500 Rename error\n"; print "Content-Type: text/plain\n\n"; print "Error renaming from $what to $new\n"; print STDERR "ROAM.CGI: MOVE $what -> $new (ERR)\n" if $Verbose; } } else { print "Status: 405 Method not implemented\n\n"; } }