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