* Completed HTTP "Basic" authentication, and a stub function for the
authorArt Cancro <ajc@citadel.org>
Tue, 25 Jan 2005 03:12:27 +0000 (03:12 +0000)
committerArt Cancro <ajc@citadel.org>
Tue, 25 Jan 2005 03:12:27 +0000 (03:12 +0000)
  main entry point for GroupDAV functions.

webcit/ChangeLog
webcit/context_loop.c
webcit/groupdav_main.c
webcit/webcit.c
webcit/webcit.h

index 370883887ce2fadcb4fbd7ef18c76130424b44c9..b0ccf7c558018593aa5a35e5bf2de1dc4caec7fb 100644 (file)
@@ -1,4 +1,8 @@
 $Log$
+Revision 528.18  2005/01/25 03:12:27  ajc
+* Completed HTTP "Basic" authentication, and a stub function for the
+  main entry point for GroupDAV functions.
+
 Revision 528.17  2005/01/24 03:37:48  ajc
 * Began laying the groundwork for http-authenticated GroupDAV sessions.
 
@@ -2215,4 +2219,3 @@ Sun Dec  6 19:50:55 EST 1998 Art Cancro <ajc@uncnsrd.mt-kisco.ny.us>
 
 1998-12-03 Nathan Bryant <bryant@cs.usm.maine.edu>
        * webserver.c: warning fix
-
index 9667c7d08b0607122115cd80329aca01192d3219..f0c8e553ba6bc82c674f62f113da6e59ee8b1361 100644 (file)
@@ -263,6 +263,13 @@ void context_loop(int sock)
        int desired_session = 0;
        int got_cookie = 0;
        struct wcsession *TheSession, *sptr;
+       char httpauth_string[SIZ];
+       char httpauth_user[SIZ];
+       char httpauth_pass[SIZ];
+
+       strcpy(httpauth_string, "");
+       strcpy(httpauth_user, "");
+       strcpy(httpauth_pass, "");
 
        /*
         * Find out what it is that the web browser is asking for
@@ -271,12 +278,27 @@ void context_loop(int sock)
        do {
                if (req_gets(sock, buf, hold) < 0) return;
 
+               /*
+                * Browser-based sessions use cookies for session authentication
+                */
                if (!strncasecmp(buf, "Cookie: webcit=", 15)) {
                        cookie_to_stuff(&buf[15], &desired_session,
                                NULL, NULL, NULL);
                        got_cookie = 1;
                }
 
+               /*
+                * GroupDAV-based sessions use HTTP authentication
+                */
+               if (!strncasecmp(buf, "Authorization: Basic ", 21)) {
+                       CtdlDecodeBase64(httpauth_string, &buf[21], strlen(&buf[21]));
+                       extract_token(httpauth_user, httpauth_string, 0, ':');
+                       extract_token(httpauth_pass, httpauth_string, 1, ':');
+               }
+
+               /*
+                * Read in the request
+                */
                hptr = (struct httprequest *)
                        malloc(sizeof(struct httprequest));
                if (req == NULL)
@@ -334,10 +356,22 @@ void context_loop(int sock)
        }
 
        /*
-        * See if there's an existing session open with the desired ID
+        * See if there's an existing session open with the desired ID or user/pass
         */
        TheSession = NULL;
-       if (desired_session != 0) {
+
+       if ( (TheSession == NULL) && (strlen(httpauth_user) > 0) ) {
+               pthread_mutex_lock(&SessionListMutex);
+               for (sptr = SessionList; sptr != NULL; sptr = sptr->next) {
+                       if ( (!strcasecmp(sptr->httpauth_user, httpauth_user))
+                          &&(!strcasecmp(sptr->httpauth_pass, httpauth_pass)) ) {
+                               TheSession = sptr;
+                       }
+               }
+               pthread_mutex_unlock(&SessionListMutex);
+       }
+
+       if ( (TheSession == NULL) && (desired_session != 0) ) {
                pthread_mutex_lock(&SessionListMutex);
                for (sptr = SessionList; sptr != NULL; sptr = sptr->next) {
                        if (sptr->wc_session == desired_session) {
@@ -358,6 +392,8 @@ void context_loop(int sock)
                TheSession->serv_sock = (-1);
                TheSession->chat_sock = (-1);
                TheSession->wc_session = GenerateSessionID();
+               strcpy(TheSession->httpauth_user, httpauth_user);
+               strcpy(TheSession->httpauth_pass, httpauth_pass);
                pthread_mutex_init(&TheSession->SessionMutex, NULL);
 
                pthread_mutex_lock(&SessionListMutex);
index bd7d51d32b579b29e14abe3f32394a8d8f198fa8..81987514dcf97b1a025de38b407f046ed252a39b 100644 (file)
 #include <errno.h>
 #include <stdarg.h>
 #include <time.h>
+#include <pthread.h>
 #include "webcit.h"
 #include "webserver.h"
 
-void groupdav_main(char *cmd) {
+void groupdav_main(struct httprequest *req) {
+
+       struct httprequest *rptr;
 
        if (!WC->logged_in) {
                wprintf(
                        "HTTP/1.1 401 Authorization Required\n"
-                       "WWW-Authenticate: Basic realm=\"GroupDAV\"\n"
-                       "Connection: close\n"
+                       "WWW-Authenticate: Basic realm=\"%s\"\n"
+                       "Connection: close\n",
+                       serv_info.serv_humannode
                );
-               output_headers(0, 0, 0, 0, 0, 0, 0);
                wprintf("Content-Type: text/plain\n");
                wprintf("\n");
                wprintf("GroupDAV sessions require HTTP authentication.\n");
-               wDumpContent(0);
+               return;
        }
 
-       output_static("smiley.gif");    /* FIXME */
+       wprintf(
+               "HTTP/1.1 404 Not found - FIXME\n"
+               "Connection: close\n"
+               "Content-Type: text/plain\n"
+               "\n"
+       );
+       wprintf("You are authenticated, but sent a bogus request.\n");
+       wprintf("WC->httpauth_user=%s\n", WC->httpauth_user);
+       wprintf("WC->httpauth_pass=%s\n", WC->httpauth_pass);   /* FIXME don't display this */
+       wprintf("WC->wc_session   =%d\n", WC->wc_session);
+       
+       for (rptr=req; rptr!=NULL; rptr=rptr->next) {
+               wprintf("> %s\n", rptr->line);
+       }
 }
index 8de0921483d3e8b0161de9e023e4f01aea37789f..1857caead1961f9352f17bef2a79e119453f59ab 100644 (file)
@@ -835,11 +835,17 @@ void session_loop(struct httprequest *req)
        char c_username[SIZ];
        char c_password[SIZ];
        char c_roomname[SIZ];
+       char c_httpauth_string[SIZ];
+       char c_httpauth_user[SIZ];
+       char c_httpauth_pass[SIZ];
        char cookie[SIZ];
 
        strcpy(c_username, "");
        strcpy(c_password, "");
        strcpy(c_roomname, "");
+       strcpy(c_httpauth_string, "");
+       strcpy(c_httpauth_user, "");
+       strcpy(c_httpauth_pass, "");
 
        WC->upload_length = 0;
        WC->upload = NULL;
@@ -864,6 +870,11 @@ void session_loop(struct httprequest *req)
                        cookie_to_stuff(cookie, NULL,
                                      c_username, c_password, c_roomname);
                }
+               else if (!strncasecmp(buf, "Authorization: Basic ", 21)) {
+                       CtdlDecodeBase64(c_httpauth_string, &buf[21], strlen(&buf[21]));
+                       extract_token(c_httpauth_user, c_httpauth_string, 0, ':');
+                       extract_token(c_httpauth_pass, c_httpauth_string, 1, ':');
+               }
                else if (!strncasecmp(buf, "Content-length: ", 16)) {
                        ContentLength = atoi(&buf[16]);
                }
@@ -986,12 +997,31 @@ void session_loop(struct httprequest *req)
                goto SKIP_ALL_THIS_CRAP;
        }
 #endif
+
+       /*
+        * If we're not logged in, but we have HTTP Authentication data,
+        * try logging in to Citadel using that.
+        */
+       if ((!WC->logged_in) && (strlen(c_httpauth_user) > 0) && (strlen(c_httpauth_pass) > 0)) {
+               serv_printf("USER %s", c_httpauth_user);
+               serv_gets(buf);
+               if (buf[0] == '3') {
+                       serv_printf("PASS %s", c_httpauth_pass);
+                       serv_gets(buf);
+                       if (buf[0] == '2') {
+                               become_logged_in(c_httpauth_user, c_httpauth_pass, buf);
+                               strcpy(WC->httpauth_user, c_httpauth_user);
+                               strcpy(WC->httpauth_pass, c_httpauth_pass);
+                       }
+               }
+       }
+
        /* 
         * The GroupDAV stuff relies on HTTP authentication instead of
         * our session's authentication.
         */
        if (!strncasecmp(action, "groupdav", 8)) {
-               groupdav_main(cmd);
+               groupdav_main(req);
                goto SKIP_ALL_THIS_CRAP;
        }
 
index c131e9b815b577682a138ffc2d010a2f335ab270..873354ad3aca3487c8e16aca6621b8f0ee050f1f 100644 (file)
@@ -497,4 +497,4 @@ extern char *ascmonths[];
 #define VIEW_TASKS             4       /* Tasks view */
 #define VIEW_NOTES             5       /* Notes view */
 
-void groupdav_main(char *);
+void groupdav_main(struct httprequest *);