3 # FEX CGI for user registration
 
   5 # Author: Ulli Horlacher <framstag@rus.uni-stuttgart.de>
 
   8 BEGIN { ($ENV{PERLINIT}||'') =~ /(.+)/s and eval $1 }
 
  11 use Fcntl       qw(:flock :seek :mode);
 
  14 our (@local_hosts,@local_domains,@local_rhosts,@local_rdomains);
 
  15 our (@registration_hosts,@registration_domains);
 
  16 our ($usage_conditions);
 
  19 our ($mdomain,@logdir,$spooldir,$fra,$hostname,$sendmail,$admin,$bcc);
 
  21 our $error = "F*EX user registration ERROR";
 
  23 my $ra = $ENV{REMOTE_ADDR}||0;
 
  28 (our $FEXLIB) = $ENV{FEXLIB} =~ /(.+)/;
 
  29 die "$0: no $FEXLIB\n" unless -d $FEXLIB;
 
  31 # load common code, local config: $HOME/lib/fex.ph
 
  32 require "$FEXLIB/fex.pp" or die "$0: cannot load $FEXLIB/fex.pp - $!\n";
 
  35 my $head = "$ENV{SERVER_NAME} F*EX user registration";
 
  37 chdir $spooldir or die "$spooldir - $!\n";
 
  39 my $user = my $id = my $verify = '';
 
  43 unless (@local_domains or @local_rdomains) {
 
  45     "No domains for registrations are defined.",
 
  46     "Contact $ENV{SERVER_ADMIN} for details."
 
  50 unless (@local_hosts and ipin($ra,@local_hosts) or
 
  51         @local_rhosts and ipin($ra,@local_rhosts)) {
 
  53     "Registrations from your host ($ra) are not allowed.",
 
  54     "Contact $ENV{SERVER_ADMIN} for details."
 
  58 # look for CGI parameters
 
  61 foreach my $v (keys %PARAM) {
 
  62   my $vv = despace($PARAM{$v});
 
  63   # debuglog("Param: $v=\"$vv\"");
 
  65     $v =~ /^user$/i     ? $user         = normalize_address($vv):
 
  66     $v =~ /^exuser$/i   ? $exuser       = normalize_address($vv):
 
  67     $v =~ /^demouser$/i ? $demouser     = normalize_address($vv):
 
  68     $v =~ /^verify$/i   ? $verify       = lc(checkchars('URL-parameter',$vv)):
 
  69     $v =~ /^confirm$/i  ? $confirm      = checkchars('URL-parameter',$vv):
 
  70     $v =~ /^domain$/i   ? $domain       = lc(checkchars('URL-parameter',$vv)):
 
  75   if ($confirm =~ /^(\w+)$/i) {
 
  78     http_die("illegal registration key");
 
  80   open $confirm,"<.reg/$confirm" or http_die("no registration key $confirm");
 
  81   $user = untaint(getline($confirm));
 
  82   $id   = getline($confirm);
 
  84   # unlink ".reg/$confirm";
 
  85   unless ($user and $id) {
 
  86     http_die("no registration data for key $confirm");
 
  88   unless (-f "$user/.auto") {
 
  89     http_die("registration expired");
 
  91   # if (-f "$user/@") { http_die("$user is already activated") }
 
  92   open $user,'>',"$user/@" or http_die("open $user/@ - $!\n");
 
  93   print {$user} $id,"\n";
 
  94   close $user or http_die("close $user/@ - $!\n");
 
  96   http_header("200 OK");
 
  97   print html_header($head);
 
  98   my $url = "$ENV{PROTO}://$ENV{HTTP_HOST}/fup/" . b64("from=$user&id=$id");
 
 100     '<h3>Your registration was successful. Your new F*EX account is:</h3>'
 
 102     '<code><a href="$url">$url</a></code>'
 
 104     '(bookmark this URL!)'
 
 109     '  <tr><td>URL:<td><code><b>$ENV{PROTO}://$ENV{HTTP_HOST}/fup/</code></b></tr>'
 
 110     '  <tr><td>Sender:<td><code><b>$user</code></b></tr>'
 
 111     '  <tr><td>auth-ID:<td><code><b>$id</code></b></tr>'
 
 115   furlog("confirm: account $user created");
 
 120 unless ($user or $exuser or $demouser) {
 
 121   http_header("200 OK");
 
 122   print html_header($head);
 
 124     '<form action="$ENV{SCRIPT_NAME}"'
 
 126     '      accept-charset="UTF-8"'
 
 127     '      enctype="multipart/form-data">'
 
 130   if (@local_domains and @local_hosts and ipin($ra,@local_hosts)) {
 
 132     if (grep(/\*/,@local_domains)) {
 
 134         '  new user (may send to internal or external users):<br>'
 
 135         '  <input type="text" name="user" size="80" value="$user">'
 
 137         '  allowed domains are:'
 
 140       foreach my $ld (@local_domains) {
 
 145       if ($mdomain and not grep /^\Q$mdomain\E$/i,@local_domains) {
 
 146         unshift @local_domains,$mdomain;
 
 148       my @mydomains = map { "\t<option>$_</option>\n" } @local_domains;
 
 150         '  new user (may send to internal or external users):<br>'
 
 151         '  <input type="text" name="user" size="40" value="$user">\@<select name="domain" size="1">@mydomains</select>'
 
 156   if (@local_rdomains and @local_rhosts and
 
 157       (not @registration_hosts or ipin($ra,@registration_hosts))) {
 
 158     print "   <p>or<p>\n" if $reg;
 
 161       '  new external user (may send only to internal users):<br>'
 
 162       '  <input type="text" name="exuser" size="80">'
 
 168     print "   <p>or<p>\n" if $reg;
 
 170     local $_ = sprintf "with %d MB quota and %d day%s account life time",
 
 171       @demo,$demo[1]>1 ? 's' : '';
 
 173       '  new demo user ($_):<br>'
 
 174       '  <input type="text" name="demouser" size="80">'
 
 182       '  you must enter your e-mail address and <input type="submit" value="submit">'
 
 186     if (@local_rdomains) {
 
 189         'internal domains are:'
 
 192       foreach my $lrd (@local_rdomains) {
 
 199       '<a href="/users.html">User types overview</a>'
 
 204       "Registrations from your host ($ra) are not allowed.",
 
 205       "Contact $ENV{SERVER_ADMIN} for details."
 
 212   unless (@local_rdomains) {
 
 213     http_die("no \@local_rdomains");
 
 215   if (@registration_hosts and not ipin($ra,@registration_hosts)) {
 
 217       "Registrations from your host ($ra) are not allowed.",
 
 218       "Contact $ENV{SERVER_ADMIN} for details."
 
 221   if ($exuser =~ /\@(.+)/) {
 
 223     if (@registration_domains and
 
 224         not grep /^\Q$exd\E$/i,@registration_domains) {
 
 226         "Your domain <code>$exd</code> is not allowed for registration.",
 
 227         "Contact $ENV{SERVER_ADMIN} for details."
 
 231     html_error($error,"<code>$exuser</code> is not an email address");
 
 234 } elsif ($demouser) {
 
 237   unless (@local_domains) {
 
 239       "No local domains for registration are defined.",
 
 240       "Contact $ENV{SERVER_ADMIN} for details."
 
 243   my $mydomains = join('|',@local_domains);
 
 244   $mydomains =~ s/\./\\./g;
 
 245   $mydomains =~ s/\*/.*/g;
 
 246   $mydomains .= "|$mdomain" if $mdomain;
 
 247   $user .= '@'.$domain if $domain and $user !~ /@/;
 
 248   # $user .= '@'.$mdomain if $mdomain and $user !~ /@/;
 
 250   unless (@local_hosts and ipin($ra,@local_hosts)) {
 
 252       "Registrations from your host ($ra) are not allowed.",
 
 253       "Contact $ENV{SERVER_ADMIN} for details."
 
 256   if ("@local_domains" ne "*" and $user !~ /\@($mydomains)$/i) {
 
 258       "Illegal domain for username.",
 
 259       "Contact $ENV{SERVER_ADMIN} for details."
 
 263   html_error($error,"No user type found.");
 
 266 unless (checkforbidden($user)) {
 
 267   html_error($error,"<code>$user</code> is not allowed");
 
 269 unless (checkaddress($user)) {
 
 270   html_error($error,"<code>$user</code> is not a valid e-mail address");
 
 272 $user = untaint($user);
 
 277     "you are already registered".
 
 278     " (<a href=\"/fup?from=$user&ID_forgotten=1\">I have lost my auth-ID</a>)"
 
 283   mkdir $user,0770 or http_die("mkdir $user - $!\n");
 
 288   # recipients e-mail address restrictions
 
 289   $rf = "$exuser/\@ALLOWED_RECIPIENTS";
 
 290   open $rf,'>',$rf or http_die("cannot write $rf - $!\n");
 
 291   print {$rf} "\@LOCAL_RDOMAINS\n";
 
 292   print {$rf} "# See also file \@ALLOWED_RHOSTS\n";
 
 294   # recipients ip restrictions
 
 295   $rf = "$exuser/\@ALLOWED_RHOSTS";
 
 296   open $rf,'>',$rf or http_die("cannot write $rf - $!\n");
 
 297   print {$rf} "\@LOCAL_RHOSTS\n";
 
 299   if (open $user,'>',"$user/.auto") {
 
 300     print {$user} "fur:external\n";
 
 303 } elsif ($demouser) {
 
 304   my $quota = "$demouser/\@QUOTA";
 
 305   open $quota,'>',$quota or http_die("cannot write $quota - $!\n");
 
 306   printf {$quota} "recipient:%d\n",$demo[0];
 
 307   printf {$quota} "sender:%d\n",$demo[0];
 
 309   if (open $user,'>',"$user/.auto") {
 
 310     print {$user} "fur:demo\n";
 
 313   open $demouser,'>',"$demouser/.demo" and close $demouser;
 
 315   if (open $user,'>',"$user/.auto") {
 
 316     print {$user} "fur:internal\n";
 
 323 if ("@local_domains" eq "*") {
 
 324   open $id,'>',"$user/@" or http_die("open $user/@ - $!\n");
 
 325   print {$id} $id,"\n";
 
 326   close $id or http_die("close $user/@ - $!\n");
 
 327   http_header("200 OK");
 
 328   print html_header($head);
 
 329   $uid = "from=$user&id=$id";
 
 334     '$ENV{PROTO}://$ENV{HTTP_HOST}/fup?$uid'
 
 335     '$ENV{PROTO}://$ENV{HTTP_HOST}/fup/$b64'
 
 343 if ($verify eq 'no') {
 
 344   open $id,'>',"$user/@" or http_die("open $user/@ - $!\n");
 
 345   print {$id} $id,"\n";
 
 346   close $id or http_die("close $user/@ - $!\n");
 
 347   http_header("200 OK",'Content-Type: text/plain');
 
 348   print "$ENV{PROTO}://$ENV{HTTP_HOST}/fup?from=$user&ID=$id\n";
 
 349   furlog("direct: account $user created");
 
 350   if ($bcc and open my $mail,"|$sendmail '$bcc' 2>>$logdir[0]/$log") {
 
 354       'Subject: F*EX user registration'
 
 356       '$user has been auto-registrated with verify=no'
 
 360     furlog("ERROR: cannot run sendmail - $!\n");
 
 366   mkdir '.reg',0770 or http_die("mkdir .reg - $!\n");
 
 368 $reg = randstring(8);
 
 369 open $reg,'>',".reg/$reg" or http_die("open .reg/$reg - $!\n");
 
 370 print {$reg} $user,"\n",$id,"\n";
 
 371 close $reg or http_die("close .reg/$reg - $!\n");
 
 373 open my $mail,'|-',$sendmail,$user,$bcc
 
 374   or http_die("cannot start sendmail - $!\n");
 
 378   'Subject: F*EX user registration request'
 
 380   'To activate your new F*EX account go to this URL:'
 
 382   '$ENV{PROTO}://$ENV{HTTP_HOST}/fur?confirm=$reg'
 
 385 if ($usage_conditions and open $usage_conditions,$usage_conditions) {
 
 386   print {$mail} "The conditions of usage are:\n\n";
 
 387   print {$mail} $_ while <$usage_conditions>;
 
 388   close $usage_conditions;
 
 390 close $mail or http_die("cannot send mail - $!\n");
 
 392 http_header("200 OK");
 
 393 print html_header($head);
 
 394 print "confirmation e-mail has been sent to <code>$user</code>\n";
 
 395 print "</body></html>\n";
 
 396 furlog("confirmation request mailed to $user");
 
 406   $msg = sprintf "%s [%s_%s] %s %s\n",
 
 407                  isodate(time),$$,$ENV{REQUESTCOUNT},$fra,$msg;
 
 412 sub normalize_address {
 
 415   $a = lc(normalize(despace($a)));
 
 416   checkchars('address',$a);