]> code.citadel.org Git - citadel.git/blobdiff - webcit/context_loop.c
Nearly all <FORM> blocks now contain a hidden input
[citadel.git] / webcit / context_loop.c
index 11a997c1bbb2527a28225ba06bd2fe7cc13877cc..cb1a907f62771e01c281dd84139fbaba86025ab3 100644 (file)
@@ -7,6 +7,7 @@
  * up HTTP requests with the sessions they belong to, using HTTP cookies to
  * keep track of things.  If the HTTP request doesn't belong to any currently
  * active session, a new session is started.
+ * \ingroup WebcitHttpServer 
  *
  */
 /*@{*/
@@ -95,6 +96,7 @@ void do_housekeeping(void)
                        free(sessions_to_kill->cache_fold);
                }
                free_attachments(sessions_to_kill);
+               free_march_list(sessions_to_kill);
                pthread_mutex_unlock(&sessions_to_kill->SessionMutex);
                sptr = sessions_to_kill->next;
                free(sessions_to_kill);
@@ -223,18 +225,34 @@ int lingering_close(int fd)
 
 
 /**
- * \brief sanity requests
- * Check for bogus requests coming from (for example) brain-dead
- * Windoze boxes that are infected with the latest worm-of-the-week.
- * If we detect one of these, bail out without bothering our Citadel
- * server.
- * \param http_cmd the cmd to check
+ * \brief      sanity requests
+ *             Check for bogus requests coming from brain-dead Windows boxes.
+ *
+ * \param      http_cmd        The HTTP request to check
  */
 int is_bogus(char *http_cmd) {
-
-       if (!strncasecmp(http_cmd, "GET /scripts/root.exe", 21)) return(1);
-       if (!strncasecmp(http_cmd, "GET /c/winnt", 12)) return(2);
-       if (!strncasecmp(http_cmd, "GET /MSADC/", 11)) return(3);
+       char *url;
+       int i, max;
+
+       url = strstr(http_cmd, " ");
+       if (url == NULL) return(1);
+       ++url;
+
+       char *bogus_prefixes[] = {
+               "/scripts/root.exe",    /**< Worms and trojans and viruses, oh my! */
+               "/c/winnt",
+               "/MSADC/",
+               "/_vti",                /**< Broken Microsoft DAV implementation */
+               "/MSOffice"             /**< Stoopid MSOffice thinks everyone is IIS */
+       };
+
+       max = sizeof(bogus_prefixes) / sizeof(char *);
+
+       for (i=0; i<max; ++i) {
+               if (!strncasecmp(url, bogus_prefixes[i], strlen(bogus_prefixes[i]))) {
+                       return(2);
+               }
+       }
 
        return(0);      /* probably ok */
 }
@@ -355,7 +373,10 @@ void context_loop(int sock)
        lprintf(5, "HTTP: %s\n", buf);
 
        /** Check for bogus requests */
-       if (is_bogus(buf)) goto bail;
+       if (is_bogus(buf)) {
+               strcpy(req->line, "GET /404 HTTP/1.1");
+               strcpy(buf, "GET /404 HTTP/1.1");
+       }
 
        /**
         * Strip out the method, leaving the URL up front...
@@ -388,6 +409,7 @@ void context_loop(int sock)
                && (strncasecmp(buf, "/groupdav", 9))
                && (strncasecmp(buf, "/static", 7))
                && (strncasecmp(buf, "/rss", 4))
+               && (strncasecmp(buf, "/404", 4))
                && (got_cookie == 0)) {
                strcpy(req->line, "GET /static/nocookies.html"
                                "?force_close_session=yes HTTP/1.1");
@@ -428,11 +450,25 @@ void context_loop(int sock)
                memset(TheSession, 0, sizeof(struct wcsession));
                TheSession->serv_sock = (-1);
                TheSession->chat_sock = (-1);
-               TheSession->wc_session = GenerateSessionID();
+       
+               /* If we're recreating a session that expired, it's best to give it the same
+                * session number that it had before.  The client browser ought to pick up
+                * the new session number and start using it, but in some rare situations it
+                * doesn't, and that's a Bad Thing because it causes lots of spurious sessions
+                * to get created.
+                */     
+               if (desired_session == 0) {
+                       TheSession->wc_session = GenerateSessionID();
+               }
+               else {
+                       TheSession->wc_session = desired_session;
+               }
+
                strcpy(TheSession->httpauth_user, httpauth_user);
                strcpy(TheSession->httpauth_pass, httpauth_pass);
                pthread_mutex_init(&TheSession->SessionMutex, NULL);
                pthread_mutex_lock(&SessionListMutex);
+               TheSession->nonce = rand();
                TheSession->next = SessionList;
                SessionList = TheSession;
                pthread_mutex_unlock(&SessionListMutex);
@@ -465,7 +501,7 @@ void context_loop(int sock)
        pthread_mutex_unlock(&TheSession->SessionMutex);        /*< unbind */
 
        /** Free the request buffer */
-bail:  while (req != NULL) {
+       while (req != NULL) {
                hptr = req->next;
                free(req);
                req = hptr;