7a00800a02e51844601c213e5f60ea520955a193
[citadel.git] / webcit / auth.c
1 /*
2  * auth.c
3  *
4  * This file contains code which relates to authentication of users to Citadel.
5  *
6  * $Id$
7  */
8
9 #include <stdlib.h>
10 #ifdef HAVE_UNISTD_H
11 #include <unistd.h>
12 #endif
13 #include <stdio.h>
14 #include <ctype.h>
15 #include <string.h>
16 #include <errno.h>
17 #include "webcit.h"
18 #include "child.h"
19
20 char *axdefs[] = {
21         "Deleted",
22         "New User",
23         "Problem User",
24         "Local User",
25         "Network User",
26         "Preferred User",
27         "Aide"
28         };
29
30 /*
31  * Display the login screen
32  */
33 void display_login(char *mesg) {
34         char buf[256];
35
36         printf("HTTP/1.0 200 OK\n");
37         output_headers(1, "_top");
38
39         /* Da banner */
40         wprintf("<CENTER><TABLE border=0 width=100%><TR><TD>\n");
41         wprintf("<IMG SRC=\"/image&name=hello\">");
42         wprintf("</TD><TD><CENTER>\n");
43
44         if (mesg != NULL) {
45                 wprintf("<font size=+1><b>%s</b></font>", mesg);
46                 }
47         else {
48                 serv_puts("MESG hello");
49                 serv_gets(buf);
50                 if (buf[0]=='1') fmout(NULL);
51                 }
52
53         wprintf("</CENTER></TD></TR></TABLE></CENTER>\n");
54         wprintf("<HR>\n");
55
56         /* Da login box */
57         wprintf("<CENTER><FORM ACTION=\"/login\" METHOD=\"POST\">\n");
58         wprintf("<TABLE border><TR>\n");
59         wprintf("<TD>User Name:</TD>\n");
60         wprintf("<TD><INPUT TYPE=\"text\" NAME=\"name\" MAXLENGTH=\"25\">\n");
61         wprintf("</TD></TR><TR>\n");
62         wprintf("<TD>Password:</TD>\n");
63         wprintf("<TD><INPUT TYPE=\"password\" NAME=\"pass\" MAXLENGTH=\"20\"></TD>\n");
64         wprintf("</TR></TABLE>\n");
65         wprintf("<INPUT type=\"submit\" NAME=\"action\" VALUE=\"Login\">\n");
66         wprintf("<INPUT type=\"submit\" NAME=\"action\" VALUE=\"New User\">\n");
67         wprintf("<INPUT type=\"submit\" NAME=\"action\" VALUE=\"Exit\">\n");
68         
69         wprintf("<BR><INPUT TYPE=\"checkbox\" NAME=\"noframes\">");
70         wprintf("<FONT SIZE=-1>Check here to disable frames</FONT>\n");
71         wprintf("</FORM></CENTER>\n");
72
73         /* Da instructions */
74         wprintf("<LI><EM>If you already have an account on %s,",
75                 serv_info.serv_humannode);
76         wprintf("</EM> enter your user name\n");
77         wprintf("and password and click \"<TT>Login</TT>.\"<BR>\n");
78         wprintf("<LI><EM>If you are a new user,</EM>\n");
79         wprintf("enter the name and password you wish to use, and click\n");
80         wprintf("\"New User.\"<BR><LI>");
81         wprintf("<EM>Please log off properly when finished.</EM>");
82         wprintf("<LI>You must use a browser that supports <i>frames</i> ");
83         wprintf("and <i>cookies</i>.\n");
84         wprintf("</EM></UL>\n");
85
86         wprintf("</BODY></HTML>\n");
87         wDumpContent();
88         }
89
90
91
92
93 /*
94  * This function needs to get called whenever a PASS or NEWU succeeds.
95  */
96 void become_logged_in(char *user, char *pass, char *serv_response) {
97         logged_in = 1;
98         extract(wc_username, &serv_response[4], 0);
99         strcpy(wc_password, pass);
100         axlevel = extract_int(&serv_response[4], 1);
101         if (axlevel >=6) is_aide = 1;
102         }
103
104
105 void do_login(void) {
106         char buf[256];
107         int need_regi = 0;
108
109
110         if (!strcasecmp(bstr("noframes"), "on"))
111                 noframes = 1;
112         else
113                 noframes = 0;
114
115         if (!strcasecmp(bstr("action"), "Exit")) {
116                 do_logout();
117                 }
118
119         if (!strcasecmp(bstr("action"), "Login")) {
120                 serv_printf("USER %s", bstr("name"));
121                 serv_gets(buf);
122                 if (buf[0]=='3') {
123                         serv_printf("PASS %s", bstr("pass"));
124                         serv_gets(buf);
125                         if (buf[0]=='2') {
126                                 become_logged_in(bstr("name"),
127                                         bstr("pass"), buf);
128                                 }
129                         else {
130                                 display_login(&buf[4]);
131                                 return;
132                                 }
133                         }
134                 else {
135                         display_login(&buf[4]);
136                         return;
137                         }
138                 }
139
140         if (!strcasecmp(bstr("action"), "New User")) {
141                 serv_printf("NEWU %s", bstr("name"));
142                 serv_gets(buf);
143                 if (buf[0]=='2') {
144                         become_logged_in(bstr("name"), bstr("pass"), buf);
145                         serv_printf("SETP %s", bstr("pass"));
146                         serv_gets(buf);
147                         }
148                 else {
149                         display_login(&buf[4]);
150                         return;
151                         }
152                 }
153
154         if (logged_in) {
155                 serv_puts("CHEK");
156                 serv_gets(buf);
157                 if (buf[0]=='2') {
158                         need_regi = extract_int(&buf[4], 1);
159                         /* FIX also check for new mail etc. here */
160                         }
161                 if (need_regi) {
162                         display_reg(1);
163                         }
164                 else {
165                         do_welcome();
166                         }
167                 }
168         else {
169                 display_login("Your password was not accepted.");
170                 }
171
172         }
173
174 void do_welcome(void) {
175
176
177         fprintf(stderr, "DO_WELCOME CALLED, NOFRAMES=%d\n", noframes);
178
179         if (noframes) {
180                 printf("HTTP/1.0 200 OK\n");
181                 output_headers(1, "_top");
182                 wprintf("<CENTER><H1>");
183                 escputs(wc_username);
184                 wprintf("</H1>\n");
185                 /* FIX add user stats here */
186         
187                 wprintf("<HR>");
188                 embed_main_menu();
189         
190                 wprintf("</BODY></HTML>\n");
191                 wDumpContent();
192                 }
193
194         else {
195                 output_static("frameset.html");
196                 }
197         }
198
199
200 void do_logout(void) {
201         char buf[256];
202
203         strcpy(wc_username, "");
204         strcpy(wc_password, "");
205         strcpy(wc_roomname, "");
206
207         printf("HTTP/1.0 200 OK\n");
208         output_headers(2, "_top");      /* note "2" causes cookies to be unset */
209
210         wprintf("<CENTER>");    
211         serv_puts("MESG goodbye");
212         serv_gets(buf);
213
214         if (buf[0]=='1') fmout(NULL);
215         else wprintf("Goodbye\n");
216
217         wprintf("<HR><A HREF=\"/\">Log in again</A>\n");
218         wprintf("</CENTER></BODY></HTML>\n");
219         wDumpContent();
220         serv_puts("QUIT");
221         exit(0);
222         }
223
224
225
226
227
228 /* 
229  * validate new users
230  */
231 void validate(void) {
232         char cmd[256];
233         char user[256];
234         char buf[256];
235         int a;
236
237         printf("HTTP/1.0 200 OK\n");
238         output_headers(1, "bottom");
239
240         strcpy(buf,bstr("user"));
241         if (strlen(buf)>0) if (strlen(bstr("axlevel"))>0) {
242                 serv_printf("VALI %s|%s",buf,bstr("axlevel"));
243                 serv_gets(buf);
244                 if (buf[0]!='2') {
245                         wprintf("<EM>%s</EM><BR>\n", &buf[4]);
246                         }
247                 }
248         
249         serv_puts("GNUR");
250         serv_gets(buf);
251
252         if (buf[0]!='3') {
253                 wprintf("<EM>%s</EM><BR></BODY></HTML>\n", &buf[4]);
254                 wDumpContent();
255                 return;
256                 }
257
258         strcpy(user,&buf[4]);
259         serv_printf("GREG %s",user);
260         serv_gets(cmd);
261         if (cmd[0]=='1') {
262                 a = 0;
263                 do {
264                         serv_gets(buf);
265                         ++a;
266                         if (a==1) wprintf("User #%s<BR><H1>%s</H1>",
267                                 buf,&cmd[4]);
268                         if (a==2) wprintf("PW: %s<BR>\n",buf);
269                         if (a==3) wprintf("%s<BR>\n",buf);
270                         if (a==4) wprintf("%s<BR>\n",buf);
271                         if (a==5) wprintf("%s, ",buf);
272                         if (a==6) wprintf("%s ",buf);
273                         if (a==7) wprintf("%s<BR>\n",buf);
274                         if (a==8) wprintf("%s<BR>\n",buf);
275                         if (a==9) wprintf("Current access level: %d (%s)\n",
276                                 atoi(buf),axdefs[atoi(buf)]);
277                         } while(strcmp(buf,"000"));
278                 }
279         else {
280                 wprintf("<H1>%s</H1>%s<BR>\n",user,&cmd[4]);
281                 }
282
283         wprintf("<CENTER><TABLE border><CAPTION>Select access level:");
284         wprintf("</CAPTION><TR>");
285         for (a=0; a<=6; ++a) {
286                 wprintf(
287                 "<TD><A HREF=\"/validate&user=%s&axlevel=%d\">%s</A></TD>\n",
288                         urlesc(user), a, axdefs[a]);
289                 }
290         wprintf("</TR></TABLE><CENTER><BR>\n");
291         wDumpContent();
292         }
293
294
295
296
297
298
299 /* 
300  * Display form for registration.
301  * (Set during_login to 1 if this registration is being performed during
302  * new user login and will require chaining to the proper screen.)
303  */
304 void display_reg(int during_login) {
305         char buf[256];
306         int a;
307
308         printf("HTTP/1.0 200 OK\n");
309         output_headers(1, "bottom");
310
311         wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=007700><TR><TD>");
312         wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
313         wprintf("<B>Enter registration info</B>\n");
314         wprintf("</FONT></TD></TR></TABLE>\n");
315
316         wprintf("<CENTER>");
317         serv_puts("MESG register");
318         serv_gets(buf);
319         if (buf[0]=='1') fmout(NULL);
320
321         wprintf("<FORM ACTION=\"/register\" METHOD=\"POST\">\n");
322         wprintf("<INPUT TYPE=\"hidden\" NAME=\"during_login\" VALUE=\"%d\">\n", during_login);
323
324         serv_puts("GREG _SELF_");
325         serv_gets(buf);
326         if (buf[0]!='1') {
327                 wprintf("<EM>%s</EM><BR>\n",&buf[4]);
328                 }
329         else {
330         
331                 wprintf("<H1>%s</H1><TABLE border>\n",&buf[4]);
332                 a = 0;
333                 while (serv_gets(buf), strcmp(buf,"000")) {
334                         ++a;
335                         wprintf("<TR><TD>");
336                         switch(a) {
337                                 case 3: wprintf("Real Name:</TD><TD><INPUT TYPE=\"text\" NAME=\"realname\" VALUE=\"%s\" MAXLENGTH=\"29\"><BR>\n",buf);
338                                         break;
339                                 case 4: wprintf("Street Address:</TD><TD><INPUT TYPE=\"text\" NAME=\"address\" VALUE=\"%s\" MAXLENGTH=\"24\"><BR>\n",buf);
340                                         break;
341                                 case 5: wprintf("City/town:</TD><TD><INPUT TYPE=\"text\" NAME=\"city\" VALUE=\"%s\" MAXLENGTH=\"14\"><BR>\n",buf);
342                                         break;
343                                 case 6: wprintf("State/province:</TD><TD><INPUT TYPE=\"text\" NAME=\"state\" VALUE=\"%s\" MAXLENGTH=\"2\"><BR>\n",buf);
344                                         break;
345                                 case 7: wprintf("ZIP code:</TD><TD><INPUT TYPE=\"text\" NAME=\"zip\" VALUE=\"%s\" MAXLENGTH=\"10\"><BR>\n",buf);
346                                         break;
347                                 case 8: wprintf("Telephone:</TD><TD><INPUT TYPE=\"text\" NAME=\"phone\" VALUE=\"%s\" MAXLENGTH=\"14\"><BR>\n",buf);
348                                         break;
349                                 case 9: wprintf("E-Mail:</TD><TD><INPUT TYPE=\"text\" NAME=\"email\" VALUE=\"%s\" MAXLENGTH=\"31\"><BR>\n",buf);
350                                         break;
351                                 }
352                         wprintf("</TD></TR>\n");
353                         }
354                 wprintf("</TABLE><P>");
355                 }
356         wprintf("<INPUT type=\"submit\" NAME=\"action\" VALUE=\"Register\">\n");
357         wprintf("<INPUT type=\"submit\" NAME=\"action\" VALUE=\"Cancel\">\n");
358         wprintf("</CENTER></BODY></HTML>\n");
359         wDumpContent();
360         }
361
362 /*
363  * register
364  */
365 void register_user(void) {
366         char buf[256];
367         
368         if (strcmp(bstr("action"),"Register")) {
369                 display_error("Cancelled.  Registration was not saved.");
370                 return;
371                 }
372
373         serv_puts("REGI");
374         serv_gets(buf);
375         if (buf[0]!='4') {
376                 display_error(&buf[4]);
377                 }
378
379         serv_puts(bstr("realname"));
380         serv_puts(bstr("address"));
381         serv_puts(bstr("city"));
382         serv_puts(bstr("state"));
383         serv_puts(bstr("zip"));
384         serv_puts(bstr("phone"));
385         serv_puts(bstr("email"));
386         serv_puts("000");
387         
388         if (atoi(bstr("during_login"))) {
389                 do_welcome();
390                 }
391         else {
392                 display_error("Registration information has been saved.");
393                 }
394         }
395
396
397
398
399
400 /* 
401  * display form for changing your password
402  */
403 void display_changepw(void) {
404         char buf[256];
405
406         printf("HTTP/1.0 200 OK\n");
407         output_headers(1, "bottom");
408
409         wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
410         wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
411         wprintf("<B>Change your password</B>\n");
412         wprintf("</FONT></TD></TR></TABLE>\n");
413
414         wprintf("<CENTER>");
415         serv_puts("MESG changepw");
416         serv_gets(buf);
417         if (buf[0]=='1') fmout(NULL);
418
419         wprintf("<FORM ACTION=\"changepw\" METHOD=\"POST\">\n");
420         wprintf("<CENTER><TABLE border><TR><TD>Enter new password:</TD>\n");
421         wprintf("<TD><INPUT TYPE=\"password\" NAME=\"newpass1\" VALUE=\"\" MAXLENGTH=\"20\"></TD></TR>\n");
422         wprintf("<TR><TD>Enter it again to confirm:</TD>\n");
423         wprintf("<TD><INPUT TYPE=\"password\" NAME=\"newpass2\" VALUE=\"\" MAXLENGTH=\"20\"></TD></TR>\n");
424         wprintf("</TABLE>\n");  
425         wprintf("<INPUT type=\"submit\" NAME=\"action\" VALUE=\"Change\">\n");
426         wprintf("<INPUT type=\"submit\" NAME=\"action\" VALUE=\"Cancel\">\n");
427         wprintf("</CENTER></BODY></HTML>\n");
428         wDumpContent();
429         }
430
431 /*
432  * change password
433  */
434 void changepw(void) {
435         char buf[256];
436         char newpass1[32], newpass2[32];
437         
438         if (strcmp(bstr("action"),"Change")) {
439                 display_error("Cancelled.  Password was not changed.");
440                 return;
441                 }
442
443         strcpy(newpass1, bstr("newpass1"));
444         strcpy(newpass2, bstr("newpass2"));
445
446         if (strcasecmp(newpass1, newpass2)) {
447                 display_error("They don't match.  Password was not changed.");
448                 return;
449                 }
450
451         serv_printf("SETP %s", newpass1);
452         serv_gets(buf);
453         if (buf[0]=='2') display_success(&buf[4]);
454         else display_error(&buf[4]);
455         }