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