]> code.citadel.org Git - citadel.git/blob - webcit/auth.c
* auth.c: localized "User name:" and "Password:" prompts
[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
103
104 void do_login(void)
105 {
106         char buf[SIZ];
107
108         if (strlen(bstr("exit_action")) > 0) {
109                 do_logout();
110                 return;
111         }
112         if (strlen(bstr("login_action")) > 0) {
113                 serv_printf("USER %s", bstr("name"));
114                 serv_getln(buf, sizeof buf);
115                 if (buf[0] == '3') {
116                         serv_printf("PASS %s", bstr("pass"));
117                         serv_getln(buf, sizeof buf);
118                         if (buf[0] == '2') {
119                                 become_logged_in(bstr("name"),
120                                                  bstr("pass"), buf);
121                         } else {
122                                 display_login(&buf[4]);
123                                 return;
124                         }
125                 } else {
126                         display_login(&buf[4]);
127                         return;
128                 }
129         }
130         if (strlen(bstr("newuser_action")) > 0) {
131                 if (strlen(bstr("pass")) == 0) {
132                         display_login(_("Blank passwords are not allowed."));
133                         return;
134                 }
135                 serv_printf("NEWU %s", bstr("name"));
136                 serv_getln(buf, sizeof buf);
137                 if (buf[0] == '2') {
138                         become_logged_in(bstr("name"), bstr("pass"), buf);
139                         serv_printf("SETP %s", bstr("pass"));
140                         serv_getln(buf, sizeof buf);
141                 } else {
142                         display_login(&buf[4]);
143                         return;
144                 }
145         }
146         if (WC->logged_in) {
147                 if (WC->need_regi) {
148                         display_reg(1);
149                 } else {
150                         do_welcome();
151                 }
152         } else {
153                 display_login(_("Your password was not accepted."));
154         }
155
156 }
157
158 void do_welcome(void)
159 {
160         char buf[SIZ];
161 #ifdef XXX_NOT_FINISHED_YET_XXX
162         FILE *fp;
163         int i;
164
165         /*
166          * See if we have to run the first-time setup wizard
167          */
168         if (WC->is_aide) {
169                 if (!setup_wizard) {
170                         sprintf(wizard_filename, "setupwiz.%s.%s",
171                                 ctdlhost, ctdlport);
172                         for (i=0; i<strlen(wizard_filename); ++i) {
173                                 if (    (wizard_filename[i]==' ')
174                                         || (wizard_filename[i] == '/')
175                                 ) {
176                                         wizard_filename[i] = '_';
177                                 }
178                         }
179         
180                         fp = fopen(wizard_filename, "r");
181                         if (fp != NULL) {
182                                 fgets(buf, sizeof buf, fp);
183                                 buf[strlen(buf)-1] = 0;
184                                 fclose(fp);
185                                 if (atoi(buf) == serv_info.serv_rev_level) {
186                                         setup_wizard = 1; /* already run */
187                                 }
188                         }
189                 }
190
191                 if (!setup_wizard) {
192                         http_redirect("setup_wizard");
193                 }
194         }
195 #endif
196
197         /*
198          * Go to the user's preferred start page
199          */
200         get_preference("startpage", buf, sizeof buf);
201         if (strlen(buf)==0) {
202                 safestrncpy(buf, "dotskip&room=_BASEROOM_", sizeof buf);
203                 set_preference("startpage", buf, 1);
204         }
205         if (buf[0] == '/') {
206                 strcpy(buf, &buf[1]);
207         }
208         http_redirect(buf);
209 }
210
211
212 /*
213  * Disconnect from the Citadel server, and end this WebCit session
214  */
215 void end_webcit_session(void) {
216         serv_puts("QUIT");
217         WC->killthis = 1;
218         /* close() of citadel socket will be done by do_housekeeping() */
219 }
220
221
222 void do_logout(void)
223 {
224         char buf[SIZ];
225
226         safestrncpy(WC->wc_username, "", sizeof WC->wc_username);
227         safestrncpy(WC->wc_password, "", sizeof WC->wc_password);
228         safestrncpy(WC->wc_roomname, "", sizeof WC->wc_roomname);
229
230         /* Calling output_headers() this way causes the cookies to be un-set */
231         output_headers(1, 1, 0, 1, 0, 0);
232
233         wprintf("<center>");
234         serv_puts("MESG goodbye");
235         serv_getln(buf, sizeof buf);
236
237         if (WC->serv_sock >= 0) {
238                 if (buf[0] == '1') {
239                         fmout("CENTER");
240                 } else {
241                         wprintf("Goodbye\n");
242                 }
243         }
244         else {
245                 wprintf(_("This program was unable to connect or stay "
246                         "connected to the Citadel server.  Please report "
247                         "this problem to your system administrator.")
248                 );
249         }
250
251         wprintf("<hr /><a href=\".\">Log in again</A>&nbsp;&nbsp;&nbsp;"
252                 "<a href=\"javascript:window.close();\">");
253         wprintf(_("Close window"));
254         wprintf("</a></center>\n");
255         wDumpContent(2);
256         end_webcit_session();
257 }
258
259
260 /* 
261  * validate new users
262  */
263 void validate(void)
264 {
265         char cmd[SIZ];
266         char user[SIZ];
267         char buf[SIZ];
268         int a;
269
270         output_headers(1, 1, 2, 0, 0, 0);
271         wprintf("<div id=\"banner\">\n"
272                 "<TABLE WIDTH=100%% BORDER=0 BGCOLOR=\"#444455\"><TR><TD>"
273                 "<SPAN CLASS=\"titlebar\">");
274         wprintf(_("Validate new users"));
275         wprintf("</SPAN></TD></TR></TABLE>\n</div>\n<div id=\"content\">\n");
276
277         safestrncpy(buf, bstr("user"), sizeof buf);
278         if (strlen(buf) > 0)
279                 if (strlen(bstr("axlevel")) > 0) {
280                         serv_printf("VALI %s|%s", buf, bstr("axlevel"));
281                         serv_getln(buf, sizeof buf);
282                         if (buf[0] != '2') {
283                                 wprintf("<b>%s</b><br />\n", &buf[4]);
284                         }
285                 }
286         serv_puts("GNUR");
287         serv_getln(buf, sizeof buf);
288
289         if (buf[0] != '3') {
290                 wprintf("<b>%s</b><br />\n", &buf[4]);
291                 wDumpContent(1);
292                 return;
293         }
294
295         wprintf("<div id=\"fix_scrollbar_bug\">"
296                 "<table border=0 width=100%% bgcolor=\"#ffffff\"><tr><td>\n");
297         wprintf("<center>");
298
299         safestrncpy(user, &buf[4], sizeof user);
300         serv_printf("GREG %s", user);
301         serv_getln(cmd, sizeof cmd);
302         if (cmd[0] == '1') {
303                 a = 0;
304                 do {
305                         serv_getln(buf, sizeof buf);
306                         ++a;
307                         if (a == 1)
308                                 wprintf("User #%s<br /><H1>%s</H1>",
309                                         buf, &cmd[4]);
310                         if (a == 2)
311                                 wprintf("PW: %s<br />\n", buf);
312                         if (a == 3)
313                                 wprintf("%s<br />\n", buf);
314                         if (a == 4)
315                                 wprintf("%s<br />\n", buf);
316                         if (a == 5)
317                                 wprintf("%s, ", buf);
318                         if (a == 6)
319                                 wprintf("%s ", buf);
320                         if (a == 7)
321                                 wprintf("%s<br />\n", buf);
322                         if (a == 8)
323                                 wprintf("%s<br />\n", buf);
324                         if (a == 9)
325                                 wprintf(_("Current access level: %d (%s)\n"),
326                                         atoi(buf), axdefs[atoi(buf)]);
327                 } while (strcmp(buf, "000"));
328         } else {
329                 wprintf("<H1>%s</H1>%s<br />\n", user, &cmd[4]);
330         }
331
332         wprintf("<hr />");
333         wprintf(_("Select access level for this user:"));
334         wprintf("<br />\n");
335         for (a = 0; a <= 6; ++a) {
336                 wprintf("<a href=\"validate&user=");
337                 urlescputs(user);
338                 wprintf("&axlevel=%d\">%s</A>&nbsp;&nbsp;&nbsp;\n",
339                         a, axdefs[a]);
340         }
341         wprintf("<br />\n");
342
343         wprintf("</CENTER>\n");
344         wprintf("</td></tr></table></div>\n");
345         wDumpContent(1);
346 }
347
348
349
350 /* 
351  * Display form for registration.
352  * (Set during_login to 1 if this registration is being performed during
353  * new user login and will require chaining to the proper screen.)
354  */
355 void display_reg(int during_login)
356 {
357         long vcard_msgnum;
358
359         if (goto_config_room() != 0) {
360                 if (during_login) do_welcome();
361                 else display_main_menu();
362                 return;
363         }
364
365         vcard_msgnum = locate_user_vcard(WC->wc_username, -1);
366         if (vcard_msgnum < 0L) {
367                 if (during_login) do_welcome();
368                 else display_main_menu();
369                 return;
370         }
371
372         if (during_login) {
373                 do_edit_vcard(vcard_msgnum, "1", "do_welcome");
374         }
375         else {
376                 do_edit_vcard(vcard_msgnum, "1", "display_main_menu");
377         }
378
379 }
380
381
382
383
384 /* 
385  * display form for changing your password
386  */
387 void display_changepw(void)
388 {
389         char buf[SIZ];
390
391         output_headers(1, 1, 2, 0, 0, 0);
392         wprintf("<div id=\"banner\">\n"
393                 "<TABLE WIDTH=100%% BORDER=0 BGCOLOR=\"#444455\"><TR><TD>"
394                 "<SPAN CLASS=\"titlebar\">");
395         wprintf(_("Change your password"));
396         wprintf("</SPAN>"
397                 "</TD></TR></TABLE>\n"
398                 "</div>\n<div id=\"content\">\n"
399         );
400
401         if (strlen(WC->ImportantMessage) > 0) {
402                 do_template("beginbox_nt");
403                 wprintf("<SPAN CLASS=\"errormsg\">"
404                         "%s</SPAN><br />\n", WC->ImportantMessage);
405                 do_template("endbox");
406                 safestrncpy(WC->ImportantMessage, "", sizeof WC->ImportantMessage);
407         }
408
409         wprintf("<div id=\"fix_scrollbar_bug\">"
410                 "<table border=0 width=100%% bgcolor=\"#ffffff\"><tr><td>\n");
411
412         wprintf("<CENTER><br />");
413         serv_puts("MESG changepw");
414         serv_getln(buf, sizeof buf);
415         if (buf[0] == '1') {
416                 fmout("CENTER");
417         }
418
419         wprintf("<form name=\"changepwform\" action=\"changepw\" method=\"post\">\n");
420         wprintf("<CENTER>"
421                 "<table border=\"0\" cellspacing=\"5\" cellpadding=\"5\" "
422                 "BGCOLOR=\"#EEEEEE\">"
423                 "<TR><TD>");
424         wprintf(_("Enter new password:"));
425         wprintf("</TD>\n");
426         wprintf("<TD><INPUT TYPE=\"password\" NAME=\"newpass1\" VALUE=\"\" MAXLENGTH=\"20\"></TD></TR>\n");
427         wprintf("<TR><TD>");
428         wprintf(_("Enter it again to confirm:"));
429         wprintf("</TD>\n");
430         wprintf("<TD><INPUT TYPE=\"password\" NAME=\"newpass2\" VALUE=\"\" MAXLENGTH=\"20\"></TD></TR>\n");
431
432         wprintf("</TABLE><br />\n");
433         wprintf("<INPUT type=\"submit\" name=\"change_action\" value=\"%s\">", _("Change password"));
434         wprintf("&nbsp;");
435         wprintf("<INPUT type=\"submit\" name=\"cancel_action\" value=\"%s\">\n", _("Cancel"));
436         wprintf("</form></center>\n");
437         wprintf("</td></tr></table></div>\n");
438         wDumpContent(1);
439 }
440
441 /*
442  * change password
443  */
444 void changepw(void)
445 {
446         char buf[SIZ];
447         char newpass1[32], newpass2[32];
448
449         if (strlen(bstr("change_action")) == 0) {
450                 safestrncpy(WC->ImportantMessage, 
451                         _("Cancelled.  Password was not changed."),
452                         sizeof WC->ImportantMessage);
453                 display_main_menu();
454                 return;
455         }
456
457         safestrncpy(newpass1, bstr("newpass1"), sizeof newpass1);
458         safestrncpy(newpass2, bstr("newpass2"), sizeof newpass2);
459
460         if (strcasecmp(newpass1, newpass2)) {
461                 safestrncpy(WC->ImportantMessage, 
462                         _("They don't match.  Password was not changed."),
463                         sizeof WC->ImportantMessage);
464                 display_changepw();
465                 return;
466         }
467
468         if (strlen(newpass1) == 0) {
469                 safestrncpy(WC->ImportantMessage, 
470                         _("Blank passwords are not allowed."),
471                         sizeof WC->ImportantMessage);
472                 display_changepw();
473                 return;
474         }
475
476         serv_printf("SETP %s", newpass1);
477         serv_getln(buf, sizeof buf);
478         sprintf(WC->ImportantMessage, "%s", &buf[4]);
479         if (buf[0] == '2') {
480                 safestrncpy(WC->wc_password, buf, sizeof WC->wc_password);
481                 display_main_menu();
482         }
483         else {
484                 display_changepw();
485         }
486 }