#!/usr/bin/perl # $passfile = 'secure/.htpasswd'; $userfile = 'secure/.userinfo'; # for the userfile, ideally you should put it outside of the web # tree, so it can't be fetched via a browser - or, if you put it # in the same directory, be sure to protect it in the .htaccess # file with the directive. print "Content-type:text/html\n\n"; # first see if the files are writable - if not, there's no point # in proceeding further... if (! (-w $passfile)) { &dienice("Can't write to passfile $passfile: $!"); } if (! (-w $userfile)) { &dienice("Can't write to userfile '$userfile': $!"); } read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); @pairs = split(/&/, $buffer); @keys = (); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; push(@keys, $name); $FORM{$name} = $value; } $username = $FORM{'username'}; $password = $FORM{'password'}; $realname = $FORM{'realname'}; $email = $FORM{'email'}; # First, do some data validation. # be sure the username is alphanumeric - no spaces or funny characters if ($username !~ /^\w*$/) { &dienice("Please use an alphanumeric username, with no spaces."); } # be sure their real name isn't blank if ($realname eq "") { &dienice("Please enter your real name."); } # be sure the password isn't blank or shorter than 6 chars if (length($password) < 6) { &dienice("Please enter a password at least 6 characters long."); } # be sure they gave a valid e-mail address # (this uses the email-address pattern match from chapter 14) if ($email !~ /[\w\-]+\@[\w\-]+\.[\w\-]+/) { &dienice("Please enter a valid e-mail address."); } # now encrypt the password $encpass = &encrypt($password); open(INF,$passfile) or &dienice("Can't open password file."); @passf = ; close(INF); # the structure of the htpasswd file is: # username:passwd # username:passwd # ...etc., with each user's record on a separate line. # here we're going to loop through and make sure the new username # doesn't already exist in the htpasswd file. foreach $i (@passf) { chomp($i); ($u,$p) = split(/:/,$i); if ($u eq $username) { &dienice("The username `$username' is already in use. Please choose another."); } } # everything seems clear now, so write the info to the data files. open(PASSF,">>$passfile") or &dienice("Can't write to password file: $!"); print PASSF "$username:$encpass\n"; close(PASSF); open(USRF,">>$userfile") or &dienice("Can't write to user info file: $!"); print USRF "$username:$realname:$email\n"; close(USRF); print <Registration Successful! You're now registered! Your username is $username, and your password is $password. Login here.

EndHTML sub encrypt { my($plain) = @_; my(@salt); @salt = ('a'..'z', 'A'..'Z', '0'..'9', '.', '/'); srand(time() ^ ($$ + ($$ << 15)) ); return crypt($plain, $salt[int(rand(@salt))] . $salt[int(rand(@salt))] ); } sub dienice { my($msg) = @_; print "

Error

\n"; print $msg; exit; }