]> code.citadel.org Git - citadel.git/blob - webcit/auth.c
6ba3d95e4b0b5fc7f0a6ddfd83ec44328a8f3423
[citadel.git] / webcit / auth.c
1 /*
2  * $Id$
3  *
4  * Handles authentication of users to a Citadel server.
5  *
6  */
7
8 #include "webcit.h"
9
10 char *axdefs[7];
11
12 void initialize_axdefs(void) {
13         axdefs[0] = _("Deleted");
14         axdefs[1] = _("New User");
15         axdefs[2] = _("Problem User");
16         axdefs[3] = _("Local User");
17         axdefs[4] = _("Network User");
18         axdefs[5] = _("Preferred User");
19         axdefs[6] = _("Aide");
20 }
21
22
23 /*
24  * Display the login screen
25  */
26 void display_login(char *mesg)
27 {
28         char buf[SIZ];
29
30         output_headers(1, 1, 2, 0, 0, 0);
31         wprintf("<div style=\"position:absolute; top:20px; left:20px; right:20px\">\n");
32
33         if (mesg != NULL) if (strlen(mesg) > 0) {
34                 stresc(buf, mesg, 0, 0);
35                 svprintf("mesg", WCS_STRING, "%s", buf);
36         }
37
38         svprintf("LOGIN_INSTRUCTIONS", WCS_STRING,
39                 _("<ul>"
40                 "<li><b>If you already have an account on %s</b>, "
41                 "enter your user name and password and click &quot;Login.&quot; "
42                 "<li><b>If you are a new user</b>, enter the name and password "
43                 "you wish to use, "
44                 "and click &quot;New User.&quot; "
45                 "<li>Please log off properly when finished. "
46                 "<li>You must use a browser that supports <i>frames</i> and "
47                 "<i>cookies</i>. "
48                 "<li>Also keep in mind that if your browser is "
49                 "configured to block pop-up windows, you will not be able "
50                 "to receive any instant messages.<br />"
51                 "</ul>"),
52                 serv_info.serv_humannode
53         );
54
55         svprintf("USERNAME_BOX", WCS_STRING, "%s", _("User name:"));
56         svprintf("PASSWORD_BOX", WCS_STRING, "%s", _("Password:"));
57         svprintf("LOGIN_BUTTON", WCS_STRING, "%s", _("Login"));
58         svprintf("NEWUSER_BUTTON", WCS_STRING, "%s", _("New User"));
59         svprintf("EXIT_BUTTON", WCS_STRING, "%s", _("Exit"));
60         svprintf("hello", WCS_SERVCMD, "MESG hello");
61         svprintf("BOXTITLE", WCS_STRING, _("%s - powered by Citadel"),
62                 serv_info.serv_humannode);
63
64         do_template("login");
65
66         wDumpContent(2);
67 }
68
69
70
71
72 /*
73  * This function needs to get called whenever the session changes from
74  * not-logged-in to logged-in, either by an explicit login by the user or
75  * by a timed-out session automatically re-establishing with a little help
76  * from the browser cookie.  Either way, we need to load access controls and
77  * preferences from the server.
78  */
79 void become_logged_in(char *user, char *pass, char *serv_response)
80 {
81         char buf[SIZ];
82
83         WC->logged_in = 1;
84         extract_token(WC->wc_username, &serv_response[4], 0, '|', sizeof WC->wc_username);
85         safestrncpy(WC->wc_password, pass, sizeof WC->wc_password);
86         WC->axlevel = extract_int(&serv_response[4], 1);
87         if (WC->axlevel >= 6) {
88                 WC->is_aide = 1;
89         }
90
91         load_preferences();
92
93         serv_puts("CHEK");
94         serv_getln(buf, sizeof buf);
95         if (buf[0] == '2') {
96                 WC->new_mail = extract_int(&buf[4], 0);
97                 WC->need_regi = extract_int(&buf[4], 1);
98                 WC->need_vali = extract_int(&buf[4], 2);
99                 extract_token(WC->cs_inet_email, &buf[4], 3, '|', sizeof WC->cs_inet_email);
100         }
101
102         get_preference("current_iconbar", buf, sizeof buf);
103         WC->current_iconbar = atoi(buf);
104
105         get_preference("floordiv_expanded", WC->floordiv_expanded, sizeof WC->floordiv_expanded);
106 }
107
108
109 void do_login(void)
110 {
111         char buf[SIZ];
112
113         if (strlen(bstr("exit_action")) > 0) {
114                 do_logout();
115                 return;
116         }
117         if (strlen(bstr("login_action")) > 0) {
118                 serv_printf("USER %s", bstr("name"));
119                 serv_getln(buf, sizeof buf);
120                 if (buf[0] == '3') {
121                         serv_printf("PASS %s", bstr("pass"));
122                         serv_getln(buf, sizeof buf);
123                         if (buf[0] == '2') {
124                                 become_logged_in(bstr("name"),
125                                                  bstr("pass"), buf);
126                         } else {
127                                 display_login(&buf[4]);
128                                 return;
129                         }
130                 } else {
131                         display_login(&buf[4]);
132                         return;
133                 }
134         }
135         if (strlen(bstr("newuser_action")) > 0) {
136                 if (strlen(bstr("pass")) == 0) {
137                         display_login(_("Blank passwords are not allowed."));
138                         return;
139                 }
140                 serv_printf("NEWU %s", bstr("name"));
141                 serv_getln(buf, sizeof buf);
142                 if (buf[0] == '2') {
143                         become_logged_in(bstr("name"), bstr("pass"), buf);
144                         serv_printf("SETP %s", bstr("pass"));
145                         serv_getln(buf, sizeof buf);
146                 } else {
147                         display_login(&buf[4]);
148                         return;
149                 }
150         }
151         if (WC->logged_in) {
152                 if (WC->need_regi) {
153                         display_reg(1);
154                 } else {
155                         do_welcome();
156                 }
157         } else {
158                 display_login(_("Your password was not accepted."));
159         }
160
161 }
162
163 void do_welcome(void)
164 {
165         char buf[SIZ];
166 #ifdef XXX_NOT_FINISHED_YET_XXX
167         FILE *fp;
168         int i;
169
170         /*
171          * See if we have to run the first-time setup wizard
172          */
173         if (WC->is_aide) {
174                 if (!setup_wizard) {
175                         sprintf(wizard_filename, "setupwiz.%s.%s",
176                                 ctdlhost, ctdlport);
177                         for (i=0; i<strlen(wizard_filename); ++i) {
178                                 if (    (wizard_filename[i]==' ')
179                                         || (wizard_filename[i] == '/')
180                                 ) {
181                                         wizard_filename[i] = '_';
182                                 }
183                         }
184         
185                         fp = fopen(wizard_filename, "r");
186                         if (fp != NULL) {
187                                 fgets(buf, sizeof buf, fp);
188                                 buf[strlen(buf)-1] = 0;
189                                 fclose(fp);
190                                 if (atoi(buf) == serv_info.serv_rev_level) {
191                                         setup_wizard = 1; /* already run */
192                                 }
193                         }
194                 }
195
196                 if (!setup_wizard) {
197                         http_redirect("setup_wizard");
198                 }
199         }
200 #endif
201
202         /*
203          * Go to the user's preferred start page
204          */
205         get_preference("startpage", buf, sizeof buf);
206         if (strlen(buf)==0) {
207                 safestrncpy(buf, "dotskip&room=_BASEROOM_", sizeof buf);
208                 set_preference("startpage", buf, 1);
209         }
210         if (buf[0] == '/') {
211                 strcpy(buf, &buf[1]);
212         }
213         http_redirect(buf);
214 }
215
216
217 /*
218  * Disconnect from the Citadel server, and end this WebCit session
219  */
220 void end_webcit_session(void) {
221         char buf[256];
222
223         if (WC->logged_in) {
224                 sprintf(buf, "%d", WC->current_iconbar);
225                 set_preference("current_iconbar", buf, 0);
226                 set_preference("floordiv_expanded", WC->floordiv_expanded, 1);
227         }
228
229         serv_puts("QUIT");
230         WC->killthis = 1;
231         /* close() of citadel socket will be done by do_housekeeping() */
232 }
233
234
235 void do_logout(void)
236 {
237         char buf[SIZ];
238
239         safestrncpy(WC->wc_username, "", sizeof WC->wc_username);
240         safestrncpy(WC->wc_password, "", sizeof WC->wc_password);
241         safestrncpy(WC->wc_roomname, "", sizeof WC->wc_roomname);
242
243         /* Calling output_headers() this way causes the cookies to be un-set */
244         output_headers(1, 1, 0, 1, 0, 0);
245
246         wprintf("<center>");
247         serv_puts("MESG goodbye");
248         serv_getln(buf, sizeof buf);
249
250         if (WC->serv_sock >= 0) {
251                 if (buf[0] == '1') {
252                         fmout("CENTER");
253                 } else {
254                         wprintf("Goodbye\n");
255                 }
256         }
257         else {
258                 wprintf(_("This program was unable to connect or stay "
259                         "connected to the Citadel server.  Please report "
260                         "this problem to your system administrator.")
261                 );
262         }
263
264         wprintf("<hr /><a href=\".\">Log in again</A>&nbsp;&nbsp;&nbsp;"
265                 "<a href=\"javascript:window.close();\">");
266         wprintf(_("Close window"));
267         wprintf("</a></center>\n");
268         wDumpContent(2);
269         end_webcit_session();
270 }
271
272
273 /* 
274  * validate new users
275  */
276 void validate(void)
277 {
278         char cmd[SIZ];
279         char user[SIZ];
280         char buf[SIZ];
281         int a;
282
283         output_headers(1, 1, 2, 0, 0, 0);
284         wprintf("<div id=\"banner\">\n"
285                 "<TABLE WIDTH=100%% BORDER=0 BGCOLOR=\"#444455\"><TR><TD>"
286                 "<SPAN CLASS=\"titlebar\">");
287         wprintf(_("Validate new users"));
288         wprintf("</SPAN></TD></TR></TABLE>\n</div>\n<div id=\"content\">\n");
289
290         safestrncpy(buf, bstr("user"), sizeof buf);
291         if (strlen(buf) > 0)
292                 if (strlen(bstr("axlevel")) > 0) {
293                         serv_printf("VALI %s|%s", buf, bstr("axlevel"));
294                         serv_getln(buf, sizeof buf);
295                         if (buf[0] != '2') {
296                                 wprintf("<b>%s</b><br />\n", &buf[4]);
297                         }
298                 }
299         serv_puts("GNUR");
300         serv_getln(buf, sizeof buf);
301
302         if (buf[0] != '3') {
303                 wprintf("<b>%s</b><br />\n", &buf[4]);
304                 wDumpContent(1);
305                 return;
306         }
307
308         wprintf("<div id=\"fix_scrollbar_bug\">"
309                 "<table border=0 width=100%% bgcolor=\"#ffffff\"><tr><td>\n");
310         wprintf("<center>");
311
312         safestrncpy(user, &buf[4], sizeof user);
313         serv_printf("GREG %s", user);
314         serv_getln(cmd, sizeof cmd);
315         if (cmd[0] == '1') {
316                 a = 0;
317                 do {
318                         serv_getln(buf, sizeof buf);
319                         ++a;
320                         if (a == 1)
321                                 wprintf("User #%s<br /><H1>%s</H1>",
322                                         buf, &cmd[4]);
323                         if (a == 2)
324                                 wprintf("PW: %s<br />\n", buf);
325                         if (a == 3)
326                                 wprintf("%s<br />\n", buf);
327                         if (a == 4)
328                                 wprintf("%s<br />\n", buf);
329                         if (a == 5)
330                                 wprintf("%s, ", buf);
331                         if (a == 6)
332                                 wprintf("%s ", buf);
333                         if (a == 7)
334                                 wprintf("%s<br />\n", buf);
335                         if (a == 8)
336                                 wprintf("%s<br />\n", buf);
337                         if (a == 9)
338                                 wprintf(_("Current access level: %d (%s)\n"),
339                                         atoi(buf), axdefs[atoi(buf)]);
340                 } while (strcmp(buf, "000"));
341         } else {
342                 wprintf("<H1>%s</H1>%s<br />\n", user, &cmd[4]);
343         }
344
345         wprintf("<hr />");
346         wprintf(_("Select access level for this user:"));
347         wprintf("<br />\n");
348         for (a = 0; a <= 6; ++a) {
349                 wprintf("<a href=\"validate&user=");
350                 urlescputs(user);
351                 wprintf("&axlevel=%d\">%s</A>&nbsp;&nbsp;&nbsp;\n",
352                         a, axdefs[a]);
353         }
354         wprintf("<br />\n");
355
356         wprintf("</CENTER>\n");
357         wprintf("</td></tr></table></div>\n");
358         wDumpContent(1);
359 }
360
361
362
363 /* 
364  * Display form for registration.
365  * (Set during_login to 1 if this registration is being performed during
366  * new user login and will require chaining to the proper screen.)
367  */
368 void display_reg(int during_login)
369 {
370         long vcard_msgnum;
371
372         if (goto_config_room() != 0) {
373                 if (during_login) do_welcome();
374                 else display_main_menu();
375                 return;
376         }
377
378         vcard_msgnum = locate_user_vcard(WC->wc_username, -1);
379         if (vcard_msgnum < 0L) {
380                 if (during_login) do_welcome();
381                 else display_main_menu();
382                 return;
383         }
384
385         if (during_login) {
386                 do_edit_vcard(vcard_msgnum, "1", "do_welcome");
387         }
388         else {
389                 do_edit_vcard(vcard_msgnum, "1", "display_main_menu");
390         }
391
392 }
393
394
395
396
397 /* 
398  * display form for changing your password
399  */
400 void display_changepw(void)
401 {
402         char buf[SIZ];
403
404         output_headers(1, 1, 2, 0, 0, 0);
405         wprintf("<div id=\"banner\">\n"
406                 "<TABLE WIDTH=100%% BORDER=0 BGCOLOR=\"#444455\"><TR><TD>"
407                 "<SPAN CLASS=\"titlebar\">");
408         wprintf(_("Change your password"));
409         wprintf("</SPAN>"
410                 "</TD></TR></TABLE>\n"
411                 "</div>\n<div id=\"content\">\n"
412         );
413
414         if (strlen(WC->ImportantMessage) > 0) {
415                 do_template("beginbox_nt");
416                 wprintf("<SPAN CLASS=\"errormsg\">"
417                         "%s</SPAN><br />\n", WC->ImportantMessage);
418                 do_template("endbox");
419                 safestrncpy(WC->ImportantMessage, "", sizeof WC->ImportantMessage);
420         }
421
422         wprintf("<div id=\"fix_scrollbar_bug\">"
423                 "<table border=0 width=100%% bgcolor=\"#ffffff\"><tr><td>\n");
424
425         wprintf("<CENTER><br />");
426         serv_puts("MESG changepw");
427         serv_getln(buf, sizeof buf);
428         if (buf[0] == '1') {
429                 fmout("CENTER");
430         }
431
432         wprintf("<form name=\"changepwform\" action=\"changepw\" method=\"post\">\n");
433         wprintf("<CENTER>"
434                 "<table border=\"0\" cellspacing=\"5\" cellpadding=\"5\" "
435                 "BGCOLOR=\"#EEEEEE\">"
436                 "<TR><TD>");
437         wprintf(_("Enter new password:"));
438         wprintf("</TD>\n");
439         wprintf("<TD><INPUT TYPE=\"password\" NAME=\"newpass1\" VALUE=\"\" MAXLENGTH=\"20\"></TD></TR>\n");
440         wprintf("<TR><TD>");
441         wprintf(_("Enter it again to confirm:"));
442         wprintf("</TD>\n");
443         wprintf("<TD><INPUT TYPE=\"password\" NAME=\"newpass2\" VALUE=\"\" MAXLENGTH=\"20\"></TD></TR>\n");
444
445         wprintf("</TABLE><br />\n");
446         wprintf("<INPUT type=\"submit\" name=\"change_action\" value=\"%s\">", _("Change password"));
447         wprintf("&nbsp;");
448         wprintf("<INPUT type=\"submit\" name=\"cancel_action\" value=\"%s\">\n", _("Cancel"));
449         wprintf("</form></center>\n");
450         wprintf("</td></tr></table></div>\n");
451         wDumpContent(1);
452 }
453
454 /*
455  * change password
456  */
457 void changepw(void)
458 {
459         char buf[SIZ];
460         char newpass1[32], newpass2[32];
461
462         if (strlen(bstr("change_action")) == 0) {
463                 safestrncpy(WC->ImportantMessage, 
464                         _("Cancelled.  Password was not changed."),
465                         sizeof WC->ImportantMessage);
466                 display_main_menu();
467                 return;
468         }
469
470         safestrncpy(newpass1, bstr("newpass1"), sizeof newpass1);
471         safestrncpy(newpass2, bstr("newpass2"), sizeof newpass2);
472
473         if (strcasecmp(newpass1, newpass2)) {
474                 safestrncpy(WC->ImportantMessage, 
475                         _("They don't match.  Password was not changed."),
476                         sizeof WC->ImportantMessage);
477                 display_changepw();
478                 return;
479         }
480
481         if (strlen(newpass1) == 0) {
482                 safestrncpy(WC->ImportantMessage, 
483                         _("Blank passwords are not allowed."),
484                         sizeof WC->ImportantMessage);
485                 display_changepw();
486                 return;
487         }
488
489         serv_printf("SETP %s", newpass1);
490         serv_getln(buf, sizeof buf);
491         sprintf(WC->ImportantMessage, "%s", &buf[4]);
492         if (buf[0] == '2') {
493                 safestrncpy(WC->wc_password, buf, sizeof WC->wc_password);
494                 display_main_menu();
495         }
496         else {
497                 display_changepw();
498         }
499 }