]> code.citadel.org Git - citadel.git/blobdiff - webcit/auth.c
* check for WC in conditionals...
[citadel.git] / webcit / auth.c
index 0823216041913729645afc310dcff9d5be02d919..22dbcfbf29911dba2adc680d3c004189487f6a80 100644 (file)
@@ -8,6 +8,7 @@
 #include "webserver.h"
 #include <ctype.h>
 
+extern uint32_t hashlittle( const void *key, size_t length, uint32_t initval);
 
 void display_reg(int during_login);
 
@@ -29,7 +30,6 @@ void initialize_axdefs(void) {
 
 
 
-
 /* 
  * Display the login screen
  * mesg = the error message if last attempt failed.
@@ -51,43 +51,10 @@ void display_login(void)
  */
 void display_openid_login(char *mesg)
 {
-       char buf[SIZ];
-
-       output_headers(1, 1, 2, 0, 0, 0);
-       wprintf("<div id=\"login_screen\">\n");
-
-       if ((mesg != NULL) && (!IsEmptyStr(mesg))) {
-               stresc(buf, SIZ,  mesg, 0, 0);
-               svprintf(HKEY("MESG"), WCS_STRING, "%s", buf);
-       }
-
-       svprintf(HKEY("LOGIN_INSTRUCTIONS"), WCS_STRING,
-               _("<ul>"
-               "<li>Enter your OpenID URL and click &quot;Login&quot;."
-               "<li><a href=\"http://www.citadel.org/doku.php/documentation:openid\">"
-               "Click here to learn what OpenID is and how Citadel is using it.</a>"
-               "<li>Please log off properly when finished. "
-               "<li>You must use a browser that supports <i>frames</i> and "
-               "<i>cookies</i>. "
-               "<li>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.<br>"
-               "</ul>")
-       );
-
-       svput("HELLO", WCS_SERVCMD, "MESG hello");
-       
-       svprintf(HKEY("OFFER_CONVENTIONAL_LOGIN"), WCS_STRING,
-               "<div id=\"convlogin\">"
-               "<a href=\"display_login\">"
-               "%s</a>"
-               "</div>"
-               ,
-               "Log in using a user name and password"
-       );
-
-       do_template("openid_login", NULL);
-       wDumpContent(2);
+  begin_burst();
+  output_headers(1, 0, 0, 0, 1, 0);
+  do_template("openid_login", NULL);
+  end_burst();
 }
 
 
@@ -124,7 +91,7 @@ void display_openid_name_request(const StrBuf *claimed_id, const StrBuf *usernam
        svput("EXIT_BUTTON", WCS_STRING, _("Exit"));
 
        svprintf(HKEY("BOXTITLE"), WCS_STRING, _("%s - powered by <a href=\"http://www.citadel.org\">Citadel</a>"),
-                ChrPtr(serv_info.serv_humannode));
+                ChrPtr(WC->serv_info->serv_humannode));
 
        do_template("openid_manual_create", NULL);
        wDumpContent(2);
@@ -147,10 +114,10 @@ void display_openid_name_request(const StrBuf *claimed_id, const StrBuf *usernam
 void become_logged_in(const StrBuf *user, const StrBuf *pass, StrBuf *serv_response)
 {
        wcsession *WCC = WC;
-       char buf[SIZ];
+       StrBuf *Buf;
        StrBuf *FloorDiv;
 
-       WC->logged_in = 1;
+       WCC->logged_in = 1;
 
        if (WCC->wc_fullname == NULL)
                WCC->wc_fullname = NewStrBufPlain(NULL, StrLength(serv_response));
@@ -178,17 +145,23 @@ void become_logged_in(const StrBuf *user, const StrBuf *pass, StrBuf *serv_respo
 
        load_preferences();
 
+       Buf = NewStrBuf();
        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);
+       StrBuf_ServGetln(Buf);
+       if (GetServerStatus(Buf, NULL) == 2) {
+               const char *pch;
+
+               pch = ChrPtr(Buf) + 4;
+               WCC->new_mail  = StrBufExtractNext_long(Buf, &pch, '|');
+               WCC->need_regi = StrBufExtractNext_long(Buf, &pch, '|');
+               WCC->need_vali = StrBufExtractNext_long(Buf, &pch, '|');
+               if (WCC->cs_inet_email == NULL)
+                       WCC->cs_inet_email  = NewStrBuf();
+               StrBufExtract_NextToken(WCC->cs_inet_email, Buf, &pch, '|');
        }
-
        get_preference("floordiv_expanded", &FloorDiv);
-       WC->floordiv_expanded = FloorDiv;
+       WCC->floordiv_expanded = FloorDiv;
+       FreeStrBuf(&Buf);
 }
 
 
@@ -200,6 +173,8 @@ void do_login(void)
        wcsession *WCC = WC;
        StrBuf *Buf;
 
+       lprintf(9, "SELECTED LANGUAGE: '%s'\n", bstr("language"));
+
        if (havebstr("language")) {
                set_selected_language(bstr("language"));
                go_selected_language();
@@ -264,7 +239,6 @@ void do_login(void)
                }
        }
        if (WCC->logged_in) {
-               set_preference("language", NewStrBufPlain(bstr("language"), -1), 1);
                if (WCC->need_regi) {
                        display_reg(1);
                } else if (WCC->need_vali) {
@@ -332,6 +306,7 @@ void openid_manual_create(void)
  */
 void do_openid_login(void)
 {
+       wcsession *WCC = WC;
        char buf[4096];
 
        if (havebstr("language")) {
@@ -347,8 +322,8 @@ void do_openid_login(void)
                snprintf(buf, sizeof buf,
                        "OIDS %s|%s://%s/finalize_openid_login|%s://%s",
                        bstr("openid_url"),
-                       (is_https ? "https" : "http"), WC->http_host,
-                       (is_https ? "https" : "http"), WC->http_host
+                        (is_https ? "https" : "http"), ChrPtr(WCC->Hdr->HR.http_host),
+                        (is_https ? "https" : "http"), ChrPtr(WCC->Hdr->HR.http_host)
                );
 
                serv_puts(buf);
@@ -396,8 +371,8 @@ void finalize_openid_login(void)
                                const char *HKey;
                                HashPos *Cursor;
                                
-                               Cursor = GetNewHashPos (WCC->urlstrings, 0);
-                               while (GetNextHashPos(WCC->urlstrings, Cursor, &HKLen, &HKey, &U)) {
+                               Cursor = GetNewHashPos (WCC->Hdr->urlstrings, 0);
+                               while (GetNextHashPos(WCC->Hdr->urlstrings, Cursor, &HKLen, &HKey, &U)) {
                                        u = (urlcontent*) U;
                                        if (!strncasecmp(u->url_key, "openid.", 7)) {
                                                serv_printf("%s|%s", &u->url_key[7], ChrPtr(u->url_data));
@@ -407,9 +382,7 @@ void finalize_openid_login(void)
                                serv_puts("000");
 
                                linecount = 0;
-                               while (StrBuf_ServGetln(Buf), 
-                                      (StrLength(Buf)==3) && 
-                                      !strcmp(ChrPtr(Buf), "000")) 
+                               while (StrBuf_ServGetln(Buf), strcmp(ChrPtr(Buf), "000")) 
                                {
                                        if (linecount == 0) result = NewStrBufDup(Buf);
                                        if (!strcasecmp(ChrPtr(result), "authenticate")) {
@@ -562,13 +535,18 @@ void end_webcit_session(void) {
  */
 void do_logout(void)
 {
+       wcsession *WCC = WC;
        char buf[SIZ];
 
-       FlushStrBuf(WC->wc_username);
-       FlushStrBuf(WC->wc_password);
-       FlushStrBuf(WC->wc_roomname);
-       FlushStrBuf(WC->wc_fullname);
+       FlushStrBuf(WCC->wc_username);
+       FlushStrBuf(WCC->wc_password);
+       FlushStrBuf(WCC->wc_roomname);
+       FlushStrBuf(WCC->wc_fullname);
 
+       /* FIXME: this is to suppress the iconbar displaying, because we aren't
+          actually logged out yet */
+       WCC->logged_in = 0;
+       
        /** Calling output_headers() this way causes the cookies to be un-set */
        output_headers(1, 1, 0, 1, 0, 0);
 
@@ -580,7 +558,7 @@ void do_logout(void)
        serv_puts("MESG goodbye");
        serv_getln(buf, sizeof buf);
 
-       if (WC->serv_sock >= 0) {
+       if (WCC->serv_sock >= 0) {
                if (buf[0] == '1') {
                        fmout("CENTER");
                } else {
@@ -600,10 +578,18 @@ void do_logout(void)
        wprintf("<hr /><div class=\"buttons\"> "
                "<span class=\"button_link\"><a href=\".\">");
        wprintf(_("Log in again"));
-       wprintf("</a></span>&nbsp;&nbsp;&nbsp;<span class=\"button_link\">"
+       wprintf("</a></span>");
+
+       /* The "close window" link is commented out because some browsers don't
+        * allow it to work.
+        *
+       wprintf("&nbsp;&nbsp;&nbsp;<span class=\"button_link\">"
                "<a href=\"javascript:window.close();\">");
        wprintf(_("Close window"));
-       wprintf("</a></span></div></div></div></div>\n");
+       wprintf("</a></span>");
+        */
+
+       wprintf("</div></div></div></div>\n");
        wDumpContent(2);
        end_webcit_session();
 }
@@ -754,15 +740,21 @@ void validate(void)
  */
 void display_reg(int during_login)
 {
+       StrBuf *Buf;
+       message_summary *VCMsg;
+       wc_mime_attachment *VCAtt;
        long vcard_msgnum;
 
-       if (goto_config_room() != 0) {
+       Buf = NewStrBuf();
+       if (goto_config_room(Buf) != 0) {
                if (during_login) do_welcome();
                else display_main_menu();
+               FreeStrBuf(&Buf);
                return;
        }
 
-       vcard_msgnum = locate_user_vcard_in_this_room();
+       FreeStrBuf(&Buf);
+       vcard_msgnum = locate_user_vcard_in_this_room(&VCMsg, &VCAtt);
        if (vcard_msgnum < 0L) {
                if (during_login) do_welcome();
                else display_main_menu();
@@ -770,10 +762,10 @@ void display_reg(int during_login)
        }
 
        if (during_login) {
-               do_edit_vcard(vcard_msgnum, "1", "do_welcome", USERCONFIGROOM);
+               do_edit_vcard(vcard_msgnum, "1", VCMsg, VCAtt, "do_welcome", USERCONFIGROOM);
        }
        else {
-               do_edit_vcard(vcard_msgnum, "1", "display_main_menu", USERCONFIGROOM);
+               do_edit_vcard(vcard_msgnum, "1", VCMsg, VCAtt, "display_main_menu", USERCONFIGROOM);
        }
 
 }
@@ -890,21 +882,25 @@ void changepw(void)
 
 int ConditionalAide(StrBuf *Target, WCTemplputParams *TP)
 {
-       return (WC->is_aide == 0);
+       wcsession *WCC = WC;
+       return (WCC != NULL)? (WC->is_aide == 0) : 0;
 }
 
 int ConditionalRoomAide(StrBuf *Target, WCTemplputParams *TP)
 {
-       return (WC->is_room_aide == 0);
+       wcsession *WCC = WC;
+       return (WCC != NULL)? (WCC->is_room_aide == 0) : 0;
 }
 
-int ConditionalIsLoggedIn(StrBuf *Target, WCTemplputParams *TP) {
-  return (WC->logged_in == 0);
+int ConditionalIsLoggedIn(StrBuf *Target, WCTemplputParams *TP) 
+{
+       wcsession *WCC = WC;
+       return (WCC != NULL)? (WCC->logged_in == 0) : 0;
 }
 int ConditionalRoomAcessDelete(StrBuf *Target, WCTemplputParams *TP)
 {
        wcsession *WCC = WC;
-       return ( (WCC->is_room_aide) || (WCC->is_mailbox) || (WCC->room_flags2 & QR2_COLLABDEL) );
+       return (WCC != NULL)? ( (WCC->is_room_aide) || (WCC->is_mailbox) || (WCC->room_flags2 & QR2_COLLABDEL) ) : 0;
 }
 
 
@@ -912,18 +908,104 @@ int ConditionalRoomAcessDelete(StrBuf *Target, WCTemplputParams *TP)
 void _display_openid_login(void) {display_openid_login(NULL);}
 void _display_reg(void) {display_reg(0);}
 
+void Header_HandleAuth(StrBuf *Line, ParsedHttpHdrs *hdr)
+{
+       if (hdr->HR.got_auth == NO_AUTH) /* don't override cookie auth... */
+       {
+               if (strncasecmp(ChrPtr(Line), "Basic", 5) == 0) {
+                       StrBufCutLeft(Line, 6);
+                       StrBufDecodeBase64(Line);
+                       hdr->HR.plainauth = Line;
+                       hdr->HR.got_auth = AUTH_BASIC;
+               }
+               else 
+                       lprintf(1, "Authentication scheme not supported! [%s]\n", ChrPtr(Line));
+       }
+}
+
+void CheckAuthBasic(ParsedHttpHdrs *hdr)
+{
+/*
+  todo: enable this if we can have other sessions than authenticated ones.
+       if (hdr->DontNeedAuth)
+               return;
+*/
+       StrBufAppendBufPlain(hdr->HR.plainauth, HKEY(":"), 0);
+       StrBufAppendBuf(hdr->HR.plainauth, hdr->HR.user_agent, 0);
+       hdr->HR.SessionKey = hashlittle(SKEY(hdr->HR.plainauth), 89479832);
+       
+}
+
+void GetAuthBasic(ParsedHttpHdrs *hdr)
+{
+       const char *Pos = NULL;
+       if (hdr->c_username == NULL)
+               hdr->c_username = NewStrBufPlain(HKEY(DEFAULT_HTTPAUTH_USER));
+       if (hdr->c_password == NULL)
+               hdr->c_password = NewStrBufPlain(HKEY(DEFAULT_HTTPAUTH_PASS));
+       StrBufExtract_NextToken(hdr->c_username, hdr->HR.plainauth, &Pos, ':');
+       StrBufExtract_NextToken(hdr->c_password, hdr->HR.plainauth, &Pos, ':');
+}
+
+void Header_HandleCookie(StrBuf *Line, ParsedHttpHdrs *hdr)
+{
+       const char *pch;
+/*
+  todo: enable this if we can have other sessions than authenticated ones.
+       if (hdr->DontNeedAuth)
+               return;
+*/
+       pch = strstr(ChrPtr(Line), "webcit=");
+       if (pch == NULL) {
+               return;
+       }
+
+       hdr->HR.RawCookie = Line;
+       StrBufCutLeft(hdr->HR.RawCookie, (pch - ChrPtr(hdr->HR.RawCookie)) + 7);
+       StrBufDecodeHex(hdr->HR.RawCookie);
+
+       if (hdr->c_username == NULL)
+               hdr->c_username = NewStrBufPlain(HKEY(DEFAULT_HTTPAUTH_USER));
+       if (hdr->c_password == NULL)
+               hdr->c_password = NewStrBufPlain(HKEY(DEFAULT_HTTPAUTH_PASS));
+       if (hdr->c_roomname == NULL)
+               hdr->c_roomname = NewStrBuf();
+       if (hdr->c_language == NULL)
+               hdr->c_language = NewStrBuf();
+       cookie_to_stuff(Line, &hdr->HR.desired_session,
+                       hdr->c_username,
+                       hdr->c_password,
+                       hdr->c_roomname,
+                       hdr->c_language
+       );
+       hdr->HR.got_auth = AUTH_COOKIE;
+}
+
+void 
+HttpDestroyModule_AUTH
+(ParsedHttpHdrs *httpreq)
+{
+       FreeStrBuf(&httpreq->c_username);
+       FreeStrBuf(&httpreq->c_password);
+       FreeStrBuf(&httpreq->c_roomname);
+       FreeStrBuf(&httpreq->c_language);
+}
 
 void 
 InitModule_AUTH
 (void)
 {
-       WebcitAddUrlHandler(HKEY("do_welcome"), do_welcome, ANONYMOUS);
-       WebcitAddUrlHandler(HKEY("login"), do_login, ANONYMOUS);
+       RegisterHeaderHandler(HKEY("COOKIE"), Header_HandleCookie);
+       RegisterHeaderHandler(HKEY("AUTHORIZATION"), Header_HandleAuth);
+
+       WebcitAddUrlHandler(HKEY(""), do_welcome, ANONYMOUS|COOKIEUNNEEDED); /* no url pattern at all? Show login. */
+       WebcitAddUrlHandler(HKEY("do_welcome"), do_welcome, ANONYMOUS|COOKIEUNNEEDED);
+       WebcitAddUrlHandler(HKEY("login"), do_login, ANONYMOUS|COOKIEUNNEEDED);
        WebcitAddUrlHandler(HKEY("display_openid_login"), _display_openid_login, ANONYMOUS);
        WebcitAddUrlHandler(HKEY("openid_login"), do_openid_login, ANONYMOUS);
        WebcitAddUrlHandler(HKEY("finalize_openid_login"), finalize_openid_login, ANONYMOUS);
        WebcitAddUrlHandler(HKEY("openid_manual_create"), openid_manual_create, ANONYMOUS);
-       WebcitAddUrlHandler(HKEY("do_logout"), do_logout, 0);
+       WebcitAddUrlHandler(HKEY("do_logout"), do_logout, ANONYMOUS|COOKIEUNNEEDED|FORCE_SESSIONCLOSE);
        WebcitAddUrlHandler(HKEY("validate"), validate, 0);
        WebcitAddUrlHandler(HKEY("display_reg"), _display_reg, 0);
        WebcitAddUrlHandler(HKEY("display_changepw"), display_changepw, 0);
@@ -937,3 +1019,16 @@ InitModule_AUTH
 
        return ;
 }
+
+
+void 
+SessionDestroyModule_AUTH
+(wcsession *sess)
+{
+       FreeStrBuf(&sess->wc_username);
+       FreeStrBuf(&sess->wc_fullname);
+       FreeStrBuf(&sess->wc_password);
+       FreeStrBuf(&sess->wc_roomname);
+       FreeStrBuf(&sess->httpauth_pass);
+       FreeStrBuf(&sess->cs_inet_email);
+}