]> code.citadel.org Git - citadel.git/blob - webcit/auth.c
* Added in some of the missing localizations
[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         /* If the user just submitted a validation, process it... */
311         safestrncpy(buf, bstr("user"), sizeof buf);
312         if (strlen(buf) > 0) {
313                 if (strlen(bstr("axlevel")) > 0) {
314                         serv_printf("VALI %s|%s", buf, bstr("axlevel"));
315                         serv_getln(buf, sizeof buf);
316                         if (buf[0] != '2') {
317                                 wprintf("<b>%s</b><br />\n", &buf[4]);
318                         }
319                 }
320         }
321
322         /* Now see if any more users require validation. */
323         serv_puts("GNUR");
324         serv_getln(buf, sizeof buf);
325         if (buf[0] == '2') {
326                 wprintf("<b>");
327                 wprintf(_("No users require validation at this time."));
328                 wprintf("</b><br />\n");
329                 wDumpContent(1);
330                 return;
331         }
332         if (buf[0] != '3') {
333                 wprintf("<b>%s</b><br />\n", &buf[4]);
334                 wDumpContent(1);
335                 return;
336         }
337
338         wprintf("<div id=\"fix_scrollbar_bug\">"
339                 "<table border=0 width=100%% bgcolor=\"#ffffff\"><tr><td>\n");
340         wprintf("<center>");
341
342         safestrncpy(user, &buf[4], sizeof user);
343         serv_printf("GREG %s", user);
344         serv_getln(cmd, sizeof cmd);
345         if (cmd[0] == '1') {
346                 a = 0;
347                 do {
348                         serv_getln(buf, sizeof buf);
349                         ++a;
350                         if (a == 1)
351                                 wprintf("#%s<br /><H1>%s</H1>",
352                                         buf, &cmd[4]);
353                         if (a == 2)
354                                 wprintf("PW: %s<br />\n", buf);
355                         if (a == 3)
356                                 wprintf("%s<br />\n", buf);
357                         if (a == 4)
358                                 wprintf("%s<br />\n", buf);
359                         if (a == 5)
360                                 wprintf("%s, ", buf);
361                         if (a == 6)
362                                 wprintf("%s ", buf);
363                         if (a == 7)
364                                 wprintf("%s<br />\n", buf);
365                         if (a == 8)
366                                 wprintf("%s<br />\n", buf);
367                         if (a == 9)
368                                 wprintf(_("Current access level: %d (%s)\n"),
369                                         atoi(buf), axdefs[atoi(buf)]);
370                 } while (strcmp(buf, "000"));
371         } else {
372                 wprintf("<H1>%s</H1>%s<br />\n", user, &cmd[4]);
373         }
374
375         wprintf("<hr />");
376         wprintf(_("Select access level for this user:"));
377         wprintf("<br />\n");
378         for (a = 0; a <= 6; ++a) {
379                 wprintf("<a href=\"validate&user=");
380                 urlescputs(user);
381                 wprintf("&axlevel=%d\">%s</A>&nbsp;&nbsp;&nbsp;\n",
382                         a, axdefs[a]);
383         }
384         wprintf("<br />\n");
385
386         wprintf("</CENTER>\n");
387         wprintf("</td></tr></table></div>\n");
388         wDumpContent(1);
389 }
390
391
392
393 /* 
394  * Display form for registration.
395  * (Set during_login to 1 if this registration is being performed during
396  * new user login and will require chaining to the proper screen.)
397  */
398 void display_reg(int during_login)
399 {
400         long vcard_msgnum;
401
402         if (goto_config_room() != 0) {
403                 if (during_login) do_welcome();
404                 else display_main_menu();
405                 return;
406         }
407
408         vcard_msgnum = locate_user_vcard(WC->wc_username, -1);
409         if (vcard_msgnum < 0L) {
410                 if (during_login) do_welcome();
411                 else display_main_menu();
412                 return;
413         }
414
415         if (during_login) {
416                 do_edit_vcard(vcard_msgnum, "1", "do_welcome");
417         }
418         else {
419                 do_edit_vcard(vcard_msgnum, "1", "display_main_menu");
420         }
421
422 }
423
424
425
426
427 /* 
428  * display form for changing your password
429  */
430 void display_changepw(void)
431 {
432         char buf[SIZ];
433
434         output_headers(1, 1, 2, 0, 0, 0);
435         wprintf("<div id=\"banner\">\n"
436                 "<TABLE WIDTH=100%% BORDER=0 BGCOLOR=\"#444455\"><TR><TD>"
437                 "<SPAN CLASS=\"titlebar\">");
438         wprintf(_("Change your password"));
439         wprintf("</SPAN>"
440                 "</TD></TR></TABLE>\n"
441                 "</div>\n<div id=\"content\">\n"
442         );
443
444         if (strlen(WC->ImportantMessage) > 0) {
445                 do_template("beginbox_nt");
446                 wprintf("<SPAN CLASS=\"errormsg\">"
447                         "%s</SPAN><br />\n", WC->ImportantMessage);
448                 do_template("endbox");
449                 safestrncpy(WC->ImportantMessage, "", sizeof WC->ImportantMessage);
450         }
451
452         wprintf("<div id=\"fix_scrollbar_bug\">"
453                 "<table border=0 width=100%% bgcolor=\"#ffffff\"><tr><td>\n");
454
455         wprintf("<CENTER><br />");
456         serv_puts("MESG changepw");
457         serv_getln(buf, sizeof buf);
458         if (buf[0] == '1') {
459                 fmout("CENTER");
460         }
461
462         wprintf("<form name=\"changepwform\" action=\"changepw\" method=\"post\">\n");
463         wprintf("<CENTER>"
464                 "<table border=\"0\" cellspacing=\"5\" cellpadding=\"5\" "
465                 "BGCOLOR=\"#EEEEEE\">"
466                 "<TR><TD>");
467         wprintf(_("Enter new password:"));
468         wprintf("</TD>\n");
469         wprintf("<TD><INPUT TYPE=\"password\" NAME=\"newpass1\" VALUE=\"\" MAXLENGTH=\"20\"></TD></TR>\n");
470         wprintf("<TR><TD>");
471         wprintf(_("Enter it again to confirm:"));
472         wprintf("</TD>\n");
473         wprintf("<TD><INPUT TYPE=\"password\" NAME=\"newpass2\" VALUE=\"\" MAXLENGTH=\"20\"></TD></TR>\n");
474
475         wprintf("</TABLE><br />\n");
476         wprintf("<INPUT type=\"submit\" name=\"change_action\" value=\"%s\">", _("Change password"));
477         wprintf("&nbsp;");
478         wprintf("<INPUT type=\"submit\" name=\"cancel_action\" value=\"%s\">\n", _("Cancel"));
479         wprintf("</form></center>\n");
480         wprintf("</td></tr></table></div>\n");
481         wDumpContent(1);
482 }
483
484 /*
485  * change password
486  */
487 void changepw(void)
488 {
489         char buf[SIZ];
490         char newpass1[32], newpass2[32];
491
492         if (strlen(bstr("change_action")) == 0) {
493                 safestrncpy(WC->ImportantMessage, 
494                         _("Cancelled.  Password was not changed."),
495                         sizeof WC->ImportantMessage);
496                 display_main_menu();
497                 return;
498         }
499
500         safestrncpy(newpass1, bstr("newpass1"), sizeof newpass1);
501         safestrncpy(newpass2, bstr("newpass2"), sizeof newpass2);
502
503         if (strcasecmp(newpass1, newpass2)) {
504                 safestrncpy(WC->ImportantMessage, 
505                         _("They don't match.  Password was not changed."),
506                         sizeof WC->ImportantMessage);
507                 display_changepw();
508                 return;
509         }
510
511         if (strlen(newpass1) == 0) {
512                 safestrncpy(WC->ImportantMessage, 
513                         _("Blank passwords are not allowed."),
514                         sizeof WC->ImportantMessage);
515                 display_changepw();
516                 return;
517         }
518
519         serv_printf("SETP %s", newpass1);
520         serv_getln(buf, sizeof buf);
521         sprintf(WC->ImportantMessage, "%s", &buf[4]);
522         if (buf[0] == '2') {
523                 safestrncpy(WC->wc_password, buf, sizeof WC->wc_password);
524                 display_main_menu();
525         }
526         else {
527                 display_changepw();
528         }
529 }