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_rdomains and @local_rhosts and
52 (not @registration_hosts or ipin($ra,@registration_hosts))) {
54 "Registrations from your host ($ra) are not allowed.",
55 "Contact $ENV{SERVER_ADMIN} for details."
59 # look for CGI parameters
62 foreach my $v (keys %PARAM) {
63 my $vv = despace($PARAM{$v});
64 # debuglog("Param: $v=\"$vv\"");
66 $v =~ /^user$/i ? $user = normalize_address($vv):
67 $v =~ /^exuser$/i ? $exuser = normalize_address($vv):
68 $v =~ /^demouser$/i ? $demouser = normalize_address($vv):
69 $v =~ /^verify$/i ? $verify = lc(checkchars('URL-parameter',$vv)):
70 $v =~ /^confirm$/i ? $confirm = checkchars('URL-parameter',$vv):
71 $v =~ /^domain$/i ? $domain = lc(checkchars('URL-parameter',$vv)):
76 if ($confirm =~ /^(\w+)$/i) {
79 http_die("illegal registration key");
81 open $confirm,"<.reg/$confirm" or http_die("no registration key $confirm");
82 $user = untaint(getline($confirm));
83 $id = getline($confirm);
85 # unlink ".reg/$confirm";
86 unless ($user and $id) {
87 http_die("no registration data for key $confirm");
89 unless (-f "$user/.auto") {
90 http_die("registration expired");
92 # if (-f "$user/@") { http_die("$user is already activated") }
93 open $user,'>',"$user/@" or http_die("open $user/@ - $!\n");
94 print {$user} $id,"\n";
95 close $user or http_die("close $user/@ - $!\n");
97 http_header("200 OK");
98 print html_header($head);
99 my $url = "$ENV{PROTO}://$ENV{HTTP_HOST}/fup/" . b64("from=$user&id=$id");
101 '<h3>Your registration was successful. Your new F*EX account is:</h3>'
103 '<code><a href="$url">$url</a></code>'
105 '(bookmark this URL!)'
110 ' <tr><td>URL:<td><code><b>$ENV{PROTO}://$ENV{HTTP_HOST}/fup/</code></b></tr>'
111 ' <tr><td>Sender:<td><code><b>$user</code></b></tr>'
112 ' <tr><td>auth-ID:<td><code><b>$id</code></b></tr>'
116 furlog("confirm: account $user created");
121 unless ($user or $exuser or $demouser) {
122 http_header("200 OK");
123 print html_header($head);
125 '<form action="$ENV{SCRIPT_NAME}"'
127 ' accept-charset="UTF-8"'
128 ' enctype="multipart/form-data">'
131 if (@local_domains and @local_hosts and ipin($ra,@local_hosts)) {
133 if (grep(/\*/,@local_domains)) {
135 ' new user (may send to internal or external users):<br>'
136 ' <input type="text" name="user" size="80" value="$user">'
138 ' allowed domains are:'
141 foreach my $ld (@local_domains) {
146 if ($mdomain and not grep /^\Q$mdomain\E$/i,@local_domains) {
147 unshift @local_domains,$mdomain;
149 my @mydomains = map { "\t<option>$_</option>\n" } @local_domains;
151 ' new user (may send to internal or external users):<br>'
152 ' <input type="text" name="user" size="40" value="$user">\@<select name="domain" size="1">@mydomains</select>'
157 if (@local_rdomains and @local_rhosts and
158 (not @registration_hosts or ipin($ra,@registration_hosts))) {
159 print " <p>or<p>\n" if $reg;
162 ' new external user (may send only to internal users):<br>'
163 ' <input type="text" name="exuser" size="80">'
169 print " <p>or<p>\n" if $reg;
171 local $_ = sprintf "with %d MB quota and %d day%s account life time",
172 @demo,$demo[1]>1 ? 's' : '';
174 ' new demo user ($_):<br>'
175 ' <input type="text" name="demouser" size="80">'
183 ' you must enter your e-mail address and <input type="submit" value="submit">'
187 if (@local_rdomains) {
190 'internal domains are:'
193 foreach my $lrd (@local_rdomains) {
200 '<a href="/users.html">User types overview</a>'
205 "Registrations from your host ($ra) are not allowed.",
206 "Contact $ENV{SERVER_ADMIN} for details."
213 unless (@local_rdomains) {
214 http_die("no \@local_rdomains");
216 if (@registration_hosts and not ipin($ra,@registration_hosts)) {
218 "Registrations from your host ($ra) are not allowed.",
219 "Contact $ENV{SERVER_ADMIN} for details."
222 if ($exuser =~ /\@(.+)/) {
224 if (@registration_domains and
225 not grep /^\Q$exd\E$/i,@registration_domains) {
227 "Your domain <code>$exd</code> is not allowed for registration.",
228 "Contact $ENV{SERVER_ADMIN} for details."
232 html_error($error,"<code>$exuser</code> is not an email address");
235 } elsif ($demouser) {
238 unless (@local_domains) {
240 "No local domains for registration are defined.",
241 "Contact $ENV{SERVER_ADMIN} for details."
244 my $mydomains = join('|',@local_domains);
245 $mydomains =~ s/\./\\./g;
246 $mydomains =~ s/\*/.*/g;
247 $mydomains .= "|$mdomain" if $mdomain;
248 $user .= '@'.$domain if $domain and $user !~ /@/;
249 # $user .= '@'.$mdomain if $mdomain and $user !~ /@/;
251 unless (@local_hosts and ipin($ra,@local_hosts)) {
253 "Registrations from your host ($ra) are not allowed.",
254 "Contact $ENV{SERVER_ADMIN} for details."
257 if ("@local_domains" ne "*" and $user !~ /\@($mydomains)$/i) {
259 "Illegal domain for username.",
260 "Contact $ENV{SERVER_ADMIN} for details."
264 html_error($error,"No user type found.");
267 unless (checkforbidden($user)) {
268 html_error($error,"<code>$user</code> is not allowed");
270 unless (checkaddress($user)) {
271 html_error($error,"<code>$user</code> is not a valid e-mail address");
273 $user = untaint($user);
278 "you are already registered".
279 " (<a href=\"/fup?from=$user&ID_forgotten=1\">I have lost my auth-ID</a>)"
284 mkdir $user,0770 or http_die("mkdir $user - $!\n");
289 # recipients e-mail address restrictions
290 $rf = "$exuser/\@ALLOWED_RECIPIENTS";
291 open $rf,'>',$rf or http_die("cannot write $rf - $!\n");
292 print {$rf} "\@LOCAL_RDOMAINS\n";
293 print {$rf} "# See also file \@ALLOWED_RHOSTS\n";
295 # recipients ip restrictions
296 $rf = "$exuser/\@ALLOWED_RHOSTS";
297 open $rf,'>',$rf or http_die("cannot write $rf - $!\n");
298 print {$rf} "\@LOCAL_RHOSTS\n";
300 if (open $user,'>',"$user/.auto") {
301 print {$user} "fur:external\n";
304 } elsif ($demouser) {
305 my $quota = "$demouser/\@QUOTA";
306 open $quota,'>',$quota or http_die("cannot write $quota - $!\n");
307 printf {$quota} "recipient:%d\n",$demo[0];
308 printf {$quota} "sender:%d\n",$demo[0];
310 if (open $user,'>',"$user/.auto") {
311 print {$user} "fur:demo\n";
314 open $demouser,'>',"$demouser/.demo" and close $demouser;
316 if (open $user,'>',"$user/.auto") {
317 print {$user} "fur:internal\n";
324 if ("@local_domains" eq "*") {
325 open $id,'>',"$user/@" or http_die("open $user/@ - $!\n");
326 print {$id} $id,"\n";
327 close $id or http_die("close $user/@ - $!\n");
328 http_header("200 OK");
329 print html_header($head);
330 $uid = "from=$user&id=$id";
335 '$ENV{PROTO}://$ENV{HTTP_HOST}/fup?$uid'
336 '$ENV{PROTO}://$ENV{HTTP_HOST}/fup/$b64'
344 if ($verify eq 'no') {
345 open $id,'>',"$user/@" or http_die("open $user/@ - $!\n");
346 print {$id} $id,"\n";
347 close $id or http_die("close $user/@ - $!\n");
348 http_header("200 OK",'Content-Type: text/plain');
349 print "$ENV{PROTO}://$ENV{HTTP_HOST}/fup?from=$user&ID=$id\n";
350 furlog("direct: account $user created");
351 if ($bcc and open my $mail,"|$sendmail '$bcc' 2>>$logdir[0]/$log") {
355 'Subject: F*EX user registration'
357 '$user has been auto-registrated with verify=no'
361 furlog("ERROR: cannot run sendmail - $!\n");
367 mkdir '.reg',0770 or http_die("mkdir .reg - $!\n");
369 $reg = randstring(8);
370 open $reg,'>',".reg/$reg" or http_die("open .reg/$reg - $!\n");
371 print {$reg} $user,"\n",$id,"\n";
372 close $reg or http_die("close .reg/$reg - $!\n");
374 open my $mail,'|-',$sendmail,$user,$bcc
375 or http_die("cannot start sendmail - $!\n");
379 'Subject: F*EX user registration request'
381 'To activate your new F*EX account go to this URL:'
383 '$ENV{PROTO}://$ENV{HTTP_HOST}/fur?confirm=$reg'
386 if ($usage_conditions and open $usage_conditions,$usage_conditions) {
387 print {$mail} "The conditions of usage are:\n\n";
388 print {$mail} $_ while <$usage_conditions>;
389 close $usage_conditions;
391 close $mail or http_die("cannot send mail - $!\n");
393 http_header("200 OK");
394 print html_header($head);
395 print "confirmation e-mail has been sent to <code>$user</code>\n";
396 print "</body></html>\n";
397 furlog("confirmation request mailed to $user");
407 $msg = sprintf "%s [%s_%s] %s %s\n",
408 isodate(time),$$,$ENV{REQUESTCOUNT},$fra,$msg;
413 sub normalize_address {
416 $a = lc(normalize(despace($a)));
417 checkchars('address',$a);