X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fauth.c;h=0f594e163105f87dc7f0e78d5d844945bc133499;hb=694a3ea878536e2deda1c0168e51837a31b81af7;hp=117ba611c6c34dfec8eb98817336a89a4d4d738b;hpb=566333bb962ea14c19352749d9211a87f05daef9;p=citadel.git diff --git a/webcit/auth.c b/webcit/auth.c index 117ba611c..0f594e163 100644 --- a/webcit/auth.c +++ b/webcit/auth.c @@ -1,131 +1,162 @@ /* - * auth.c - * - * This file contains code which relates to authentication of users to Citadel. - * * $Id$ */ +/** + * + * \defgroup WebcitAuth WebcitAuth; Handles authentication of users to a Citadel server. + * \ingroup CitadelConfig + */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +/*@{*/ #include "webcit.h" -char *axdefs[] = -{ - "Deleted", - "New User", - "Problem User", - "Local User", - "Network User", - "Preferred User", - "Aide" -}; -/* - * Display the login screen +/** + * \brief user states + * the plain text states of a user. filled in at \ function TODO initialize_ax_defs() + * due to NLS + */ +char *axdefs[7]; + +void initialize_axdefs(void) { + axdefs[0] = _("Deleted"); /*!0: an erased user */ + axdefs[1] = _("New User"); /*!1: a new user */ + axdefs[2] = _("Problem User"); /*!2: a trouble maker */ + axdefs[3] = _("Local User"); /*!3: user with normal privileges */ + axdefs[4] = _("Network User"); /*!4: a user that may access network resources */ + axdefs[5] = _("Preferred User");/*!5: a moderator */ + axdefs[6] = _("Aide"); /*!6: chief */ +} + + + + +/** + * \brief Display the login screen + * \param mesg The error message if last attempt failed. */ void display_login(char *mesg) { - char buf[256]; + char buf[SIZ]; - output_headers(3); + output_headers(1, 1, 2, 0, 0, 0); + wprintf("
\n"); - /* Da banner */ - wprintf("
\n"); - wprintf(""); - wprintf("
\n"); + if (mesg != NULL) if (strlen(mesg) > 0) { + stresc(buf, mesg, 0, 0); + svprintf("mesg", WCS_STRING, "%s", buf); + } - if (mesg != NULL) { - wprintf("%s", mesg); - } else { - serv_puts("MESG hello"); - serv_gets(buf); - if (buf[0] == '1') - fmout(NULL); - } - - wprintf("
\n"); - wprintf("
\n"); - - /* Da login box */ - wprintf("
\n"); - wprintf("\n"); - wprintf("\n"); - wprintf("\n"); - wprintf("\n"); - wprintf("\n"); - wprintf("
User Name:\n"); - wprintf("
Password:
\n"); - wprintf("\n"); - wprintf("\n"); - wprintf("\n"); - - /* Da instructions */ - wprintf("
  • If you already have an account on %s,", + svprintf("LOGIN_INSTRUCTIONS", WCS_STRING, + _("
      " + "
    • If you already have an account on %s, " + "enter your user name and password and click "Login." " + "
    • If you are a new user, enter the name and password " + "you wish to use, " + "and click "New User." " + "
    • Please log off properly when finished. " + "
    • You must use a browser that supports frames and " + "cookies. " + "
    • Also keep in mind that if your browser is " + "configured to block pop-up windows, you will not be able " + "to receive any instant messages.
      " + "
    "), + serv_info.serv_humannode + ); + + svprintf("USERNAME_BOX", WCS_STRING, "%s", _("User name:")); + svprintf("PASSWORD_BOX", WCS_STRING, "%s", _("Password:")); + svprintf("LANGUAGE_BOX", WCS_STRING, "%s", _("Language:")); + svprintf("LOGIN_BUTTON", WCS_STRING, "%s", _("Login")); + svprintf("NEWUSER_BUTTON", WCS_STRING, "%s", _("New User")); + svprintf("EXIT_BUTTON", WCS_STRING, "%s", _("Exit")); + svprintf("hello", WCS_SERVCMD, "MESG hello"); + svprintf("BOXTITLE", WCS_STRING, _("%s - powered by Citadel"), serv_info.serv_humannode); - wprintf("
    enter your user name\n"); - wprintf("and password and click \"Login.\"
    \n"); - wprintf("
  • If you are a new user,\n"); - wprintf("enter the name and password you wish to use, and click\n"); - wprintf("\"New User.\"
  • "); - wprintf("Please log off properly when finished."); - wprintf("
  • You must use a browser that supports cookies.
    \n"); - wprintf("\n"); - - wDumpContent(0); /* No menu here; not logged in yet! */ + svcallback("DO_LANGUAGE_BOX", offer_languages); + if (serv_info.serv_newuser_disabled) { + svprintf("NEWUSER_BUTTON_PRE", WCS_STRING, "
    "); + svprintf("NEWUSER_BUTTON_POST", WCS_STRING, "
    "); + } + else { + svprintf("NEWUSER_BUTTON_PRE", WCS_STRING, ""); + svprintf("NEWUSER_BUTTON_POST", WCS_STRING, ""); + } + + do_template("login"); + + wDumpContent(2); } -/* - * This function needs to get called whenever a PASS or NEWU succeeds. +/** \brief Initialize the session + * This function needs to get called whenever the session changes from + * not-logged-in to logged-in, either by an explicit login by the user or + * by a timed-out session automatically re-establishing with a little help + * from the browser cookie. Either way, we need to load access controls and + * preferences from the server. + * + * \param user the username + * \param pass his password + * \param serv_response The parameters returned from a Citadel USER or NEWU command */ void become_logged_in(char *user, char *pass, char *serv_response) { + char buf[SIZ]; + WC->logged_in = 1; - extract(WC->wc_username, &serv_response[4], 0); - strcpy(WC->wc_password, pass); + extract_token(WC->wc_fullname, &serv_response[4], 0, '|', sizeof WC->wc_fullname); + safestrncpy(WC->wc_username, user, sizeof WC->wc_username); + safestrncpy(WC->wc_password, pass, sizeof WC->wc_password); WC->axlevel = extract_int(&serv_response[4], 1); - if (WC->axlevel >= 6) + if (WC->axlevel >= 6) { WC->is_aide = 1; + } + + load_preferences(); + + serv_puts("CHEK"); + serv_getln(buf, sizeof buf); + if (buf[0] == '2') { + WC->new_mail = extract_int(&buf[4], 0); + WC->need_regi = extract_int(&buf[4], 1); + WC->need_vali = extract_int(&buf[4], 2); + extract_token(WC->cs_inet_email, &buf[4], 3, '|', sizeof WC->cs_inet_email); + } + + get_preference("current_iconbar", buf, sizeof buf); + WC->current_iconbar = atoi(buf); + + get_preference("floordiv_expanded", WC->floordiv_expanded, sizeof WC->floordiv_expanded); } +/** + * \brief Login Checks + * the logics to detect invalid passwords not to get on citservers nerves + */ void do_login(void) { - char buf[256]; - int need_regi = 0; + char buf[SIZ]; + if (strlen(bstr("language")) > 0) { + set_selected_language(bstr("language")); + go_selected_language(); + } - if (!strcasecmp(bstr("action"), "Exit")) { + if (strlen(bstr("exit_action")) > 0) { do_logout(); + return; } - if (!strcasecmp(bstr("action"), "Login")) { + if (strlen(bstr("login_action")) > 0) { serv_printf("USER %s", bstr("name")); - serv_gets(buf); + serv_getln(buf, sizeof buf); if (buf[0] == '3') { serv_printf("PASS %s", bstr("pass")); - serv_gets(buf); + serv_getln(buf, sizeof buf); if (buf[0] == '2') { become_logged_in(bstr("name"), bstr("pass"), buf); @@ -138,313 +169,394 @@ void do_login(void) return; } } - if (!strcasecmp(bstr("action"), "New User")) { + if (strlen(bstr("newuser_action")) > 0) { + if (strlen(bstr("pass")) == 0) { + display_login(_("Blank passwords are not allowed.")); + return; + } serv_printf("NEWU %s", bstr("name")); - serv_gets(buf); + serv_getln(buf, sizeof buf); if (buf[0] == '2') { become_logged_in(bstr("name"), bstr("pass"), buf); serv_printf("SETP %s", bstr("pass")); - serv_gets(buf); + serv_getln(buf, sizeof buf); } else { display_login(&buf[4]); return; } } if (WC->logged_in) { - serv_puts("CHEK"); - serv_gets(buf); - if (buf[0] == '2') { - WC->new_mail = extract_int(&buf[4], 0); - need_regi = extract_int(&buf[4], 1); - WC->need_vali = extract_int(&buf[4], 2); - } - if (need_regi) { + if (WC->need_regi) { display_reg(1); } else { do_welcome(); } } else { - display_login("Your password was not accepted."); + display_login(_("Your password was not accepted.")); } } +/** + * \brief display the user a welcome screen. + * if this is the first time login, and the web based setup is enabled, + * lead the user through the setup routines + */ void do_welcome(void) { - smart_goto("_BASEROOM_"); + char buf[SIZ]; +#ifdef XXX_NOT_FINISHED_YET_XXX + FILE *fp; + int i; + + /** + * See if we have to run the first-time setup wizard + */ + if (WC->is_aide) { + if (!setup_wizard) { + sprintf(wizard_filename, "setupwiz.%s.%s", + ctdlhost, ctdlport); + for (i=0; ilogged_in) { + sprintf(buf, "%d", WC->current_iconbar); + set_preference("current_iconbar", buf, 0); + set_preference("floordiv_expanded", WC->floordiv_expanded, 1); + } + + serv_puts("QUIT"); + WC->killthis = 1; + /* close() of citadel socket will be done by do_housekeeping() */ +} + +/** + * execute the logout + */ void do_logout(void) { - char buf[256]; + char buf[SIZ]; - strcpy(WC->wc_username, ""); - strcpy(WC->wc_password, ""); - strcpy(WC->wc_roomname, ""); + safestrncpy(WC->wc_username, "", sizeof WC->wc_username); + safestrncpy(WC->wc_password, "", sizeof WC->wc_password); + safestrncpy(WC->wc_roomname, "", sizeof WC->wc_roomname); + safestrncpy(WC->wc_fullname, "", sizeof WC->wc_fullname); - output_headers(2); /* note "2" causes cookies to be unset */ + /** Calling output_headers() this way causes the cookies to be un-set */ + output_headers(1, 1, 0, 1, 0, 0); - wprintf("
    "); + wprintf("
    "); serv_puts("MESG goodbye"); - serv_gets(buf); + serv_getln(buf, sizeof buf); - if (buf[0] == '1') - fmout(NULL); - else - wprintf("Goodbye\n"); + if (WC->serv_sock >= 0) { + if (buf[0] == '1') { + fmout("CENTER"); + } else { + wprintf("Goodbye\n"); + } + } + else { + wprintf(_("This program was unable to connect or stay " + "connected to the Citadel server. Please report " + "this problem to your system administrator.") + ); + } - wprintf("
    Log in again
    \n"); + wprintf("
    "); + wprintf(_("Log in again")); + wprintf("   " + ""); + wprintf(_("Close window")); + wprintf("
    \n"); wDumpContent(2); - serv_puts("QUIT"); - close(WC->serv_sock); - WC->serv_sock = (-1); - WC->killthis = 1; + end_webcit_session(); } - - - -/* +/* * * validate new users */ void validate(void) { - char cmd[256]; - char user[256]; - char buf[256]; + char cmd[SIZ]; + char user[SIZ]; + char buf[SIZ]; int a; - output_headers(1); - - strcpy(buf, bstr("user")); - if (strlen(buf) > 0) - if (strlen(bstr("WC->axlevel")) > 0) { - serv_printf("VALI %s|%s", buf, bstr("WC->axlevel")); - serv_gets(buf); + output_headers(1, 1, 2, 0, 0, 0); + wprintf("
    \n" + "
    " + ""); + wprintf(_("Validate new users")); + wprintf("
    \n
    \n
    \n"); + + /** If the user just submitted a validation, process it... */ + safestrncpy(buf, bstr("user"), sizeof buf); + if (strlen(buf) > 0) { + if (strlen(bstr("axlevel")) > 0) { + serv_printf("VALI %s|%s", buf, bstr("axlevel")); + serv_getln(buf, sizeof buf); if (buf[0] != '2') { - wprintf("%s
    \n", &buf[4]); + wprintf("%s
    \n", &buf[4]); } } - serv_puts("GNUR"); - serv_gets(buf); + } + /** Now see if any more users require validation. */ + serv_puts("GNUR"); + serv_getln(buf, sizeof buf); + if (buf[0] == '2') { + wprintf(""); + wprintf(_("No users require validation at this time.")); + wprintf("
    \n"); + wDumpContent(1); + return; + } if (buf[0] != '3') { - wprintf("%s
    \n", &buf[4]); + wprintf("%s
    \n", &buf[4]); wDumpContent(1); return; } - strcpy(user, &buf[4]); + + wprintf("
    " + "
    \n"); + wprintf("
    "); + + safestrncpy(user, &buf[4], sizeof user); serv_printf("GREG %s", user); - serv_gets(cmd); + serv_getln(cmd, sizeof cmd); if (cmd[0] == '1') { a = 0; do { - serv_gets(buf); + serv_getln(buf, sizeof buf); ++a; if (a == 1) - wprintf("User #%s

    %s

    ", + wprintf("#%s

    %s

    ", buf, &cmd[4]); if (a == 2) - wprintf("PW: %s
    \n", buf); + wprintf("PW: %s
    \n", buf); if (a == 3) - wprintf("%s
    \n", buf); + wprintf("%s
    \n", buf); if (a == 4) - wprintf("%s
    \n", buf); + wprintf("%s
    \n", buf); if (a == 5) wprintf("%s, ", buf); if (a == 6) wprintf("%s ", buf); if (a == 7) - wprintf("%s
    \n", buf); + wprintf("%s
    \n", buf); if (a == 8) - wprintf("%s
    \n", buf); + wprintf("%s
    \n", buf); if (a == 9) - wprintf("Current access level: %d (%s)\n", + wprintf(_("Current access level: %d (%s)\n"), atoi(buf), axdefs[atoi(buf)]); } while (strcmp(buf, "000")); } else { - wprintf("

    %s

    %s
    \n", user, &cmd[4]); + wprintf("

    %s

    %s
    \n", user, &cmd[4]); } - wprintf("
    "); + wprintf("
    "); + wprintf(_("Select access level for this user:")); + wprintf("
    \n"); for (a = 0; a <= 6; ++a) { - wprintf( - "\n", - urlesc(user), a, axdefs[a]); + wprintf("%s   \n", + a, axdefs[a]); } - wprintf("
    Select access level:"); - wprintf("
    axlevel=%d\">%s

    \n"); + wprintf("
    \n"); + + wprintf("
    \n"); + wprintf("
    \n"); wDumpContent(1); } - - - -/* - * Display form for registration. +/** + * \brief Display form for registration. * (Set during_login to 1 if this registration is being performed during * new user login and will require chaining to the proper screen.) + * \param during_login are we just in the login phase? */ void display_reg(int during_login) { - char buf[256]; - int a; - - output_headers(1); - - wprintf("
    "); - wprintf("Enter registration info\n"); - wprintf("
    \n"); - - wprintf("
    "); - serv_puts("MESG register"); - serv_gets(buf); - if (buf[0] == '1') - fmout(NULL); + long vcard_msgnum; - wprintf("\n"); - wprintf("\n", during_login); - - serv_puts("GREG _SELF_"); - serv_gets(buf); - if (buf[0] != '1') { - wprintf("%s
    \n", &buf[4]); - } else { - - wprintf("

    %s

    \n", &buf[4]); - a = 0; - while (serv_gets(buf), strcmp(buf, "000")) { - ++a; - wprintf("\n"); - } - wprintf("
    "); - switch (a) { - case 3: - wprintf("Real Name:
    \n", buf); - break; - case 4: - wprintf("Street Address:

    \n", buf); - break; - case 5: - wprintf("City/town:

    \n", buf); - break; - case 6: - wprintf("State/province:

    \n", buf); - break; - case 7: - wprintf("ZIP code:

    \n", buf); - break; - case 8: - wprintf("Telephone:

    \n", buf); - break; - case 10: - wprintf("E-Mail:

    \n", buf); - break; - } - wprintf("

    "); + if (goto_config_room() != 0) { + if (during_login) do_welcome(); + else display_main_menu(); + return; } - wprintf("\n"); - wprintf("\n"); - wprintf("

    \n"); - wDumpContent(1); -} - -/* - * register - */ -void register_user(void) -{ - char buf[256]; - if (strcmp(bstr("action"), "Register")) { - display_error("Cancelled. Registration was not saved."); + vcard_msgnum = locate_user_vcard(WC->wc_fullname, -1); + if (vcard_msgnum < 0L) { + if (during_login) do_welcome(); + else display_main_menu(); return; } - serv_puts("REGI"); - serv_gets(buf); - if (buf[0] != '4') { - display_error(&buf[4]); - } - serv_puts(bstr("realname")); - serv_puts(bstr("address")); - serv_puts(bstr("city")); - serv_puts(bstr("state")); - serv_puts(bstr("zip")); - serv_puts(bstr("phone")); - serv_puts(bstr("email")); - serv_puts("000"); - - if (atoi(bstr("during_login"))) { - do_welcome(); - } else { - display_error("Registration information has been saved."); + + if (during_login) { + do_edit_vcard(vcard_msgnum, "1", "do_welcome"); + } + else { + do_edit_vcard(vcard_msgnum, "1", "display_main_menu"); } -} +} -/* +/** * display form for changing your password */ void display_changepw(void) { - char buf[256]; - - output_headers(1); + char buf[SIZ]; + + output_headers(1, 1, 2, 0, 0, 0); + wprintf("
    \n" + "
    " + ""); + wprintf(_("Change your password")); + wprintf("" + "
    \n" + "
    \n
    \n" + ); + + if (strlen(WC->ImportantMessage) > 0) { + do_template("beginbox_nt"); + wprintf("" + "%s
    \n", WC->ImportantMessage); + do_template("endbox"); + safestrncpy(WC->ImportantMessage, "", sizeof WC->ImportantMessage); + } - wprintf("
    "); - wprintf("Change your password\n"); - wprintf("
    \n"); + wprintf("
    " + "
    \n"); - wprintf("
    "); + wprintf("

    "); serv_puts("MESG changepw"); - serv_gets(buf); - if (buf[0] == '1') - fmout(NULL); + serv_getln(buf, sizeof buf); + if (buf[0] == '1') { + fmout("CENTER"); + } - wprintf("\n"); - wprintf("
    \n"); + wprintf("\n"); + wprintf("
    " + "
    Enter new password:
    " + "\n"); wprintf("\n"); - wprintf("\n"); + wprintf("\n"); wprintf("\n"); - wprintf("
    "); + wprintf(_("Enter new password:")); + wprintf("
    Enter it again to confirm:
    "); + wprintf(_("Enter it again to confirm:")); + wprintf("
    \n"); - wprintf("\n"); - wprintf("\n"); - wprintf("
    \n"); + + wprintf("

    \n"); + wprintf("", _("Change password")); + wprintf(" "); + wprintf("\n", _("Cancel")); + wprintf("
  • \n"); + wprintf("
    \n"); wDumpContent(1); } -/* - * change password +/** + * \brief change password + * if passwords match, propagate it to citserver. */ void changepw(void) { - char buf[256]; + char buf[SIZ]; char newpass1[32], newpass2[32]; - if (strcmp(bstr("action"), "Change")) { - display_error("Cancelled. Password was not changed."); + if (strlen(bstr("change_action")) == 0) { + safestrncpy(WC->ImportantMessage, + _("Cancelled. Password was not changed."), + sizeof WC->ImportantMessage); + display_main_menu(); return; } - strcpy(newpass1, bstr("newpass1")); - strcpy(newpass2, bstr("newpass2")); + + safestrncpy(newpass1, bstr("newpass1"), sizeof newpass1); + safestrncpy(newpass2, bstr("newpass2"), sizeof newpass2); if (strcasecmp(newpass1, newpass2)) { - display_error("They don't match. Password was not changed."); + safestrncpy(WC->ImportantMessage, + _("They don't match. Password was not changed."), + sizeof WC->ImportantMessage); + display_changepw(); return; } + + if (strlen(newpass1) == 0) { + safestrncpy(WC->ImportantMessage, + _("Blank passwords are not allowed."), + sizeof WC->ImportantMessage); + display_changepw(); + return; + } + serv_printf("SETP %s", newpass1); - serv_gets(buf); - if (buf[0] == '2') - display_success(&buf[4]); - else - display_error(&buf[4]); + serv_getln(buf, sizeof buf); + sprintf(WC->ImportantMessage, "%s", &buf[4]); + if (buf[0] == '2') { + safestrncpy(WC->wc_password, buf, sizeof WC->wc_password); + display_main_menu(); + } + else { + display_changepw(); + } } + + + +/** @} */