* Created IsEmptyStr define to be used rather then using some weird strlen constructs
[citadel.git] / webcit / context_loop.c
index e276383f7342b1b35f9bb702853a19fac1fbd7ba..b693ff992676dd15632bdc45dcc9209fcfedf549 100644 (file)
@@ -155,12 +155,13 @@ int GenerateSessionID(void)
  * \param sock a socket?
  * \param buf some bunch of chars?
  * \param hold hold what?
+ * TODO: get this comment right
  */
 int req_gets(int sock, char *buf, char *hold)
 {
-       int a;
+       int a, b;
 
-       if (strlen(hold) == 0) {
+       if (IsEmptyStr(hold)) {
                strcpy(buf, "");
                a = client_getln(sock, buf, SIZ);
                if (a<1) return(-1);
@@ -170,12 +171,19 @@ int req_gets(int sock, char *buf, char *hold)
        strcpy(hold, "");
 
        if (!strncasecmp(buf, "Cookie: ", 8)) {
-               for (a = 0; a < strlen(buf); ++a)
+               int len;
+               len = strlen(buf);
+               for (a = 0; a < len; ++a)
                        if (buf[a] == ';') {
+                               // we don't refresh len, because of we 
+                               // only exit from here.
                                sprintf(hold, "Cookie: %s", &buf[a + 1]);
                                buf[a] = 0;
-                               while (isspace(hold[8]))
-                                       strcpy(&hold[8], &hold[9]);
+                               b = 8;
+                               while (isspace(hold[b]))
+                                       b++;
+                               
+                               memmove(&hold[8], &hold[b], len - b + 1);
                                return(0);
                        }
        }
@@ -188,6 +196,7 @@ int req_gets(int sock, char *buf, char *hold)
  * \param fd the fd to close??????
  * lingering_close() a`la Apache. see
  * http://www.apache.org/docs/misc/fin_wait_2.html for rationale
+ * TODO: get this comment precise.
  */
 
 int lingering_close(int fd)
@@ -232,18 +241,27 @@ int lingering_close(int fd)
  */
 int is_bogus(char *http_cmd) {
        char *url;
+       int i, max;
 
        url = strstr(http_cmd, " ");
        if (url == NULL) return(1);
        ++url;
 
-       /** Worms and trojans and viruses, oh my! */
-       if (!strncasecmp(url, "/scripts/root.exe", 17)) return(2);
-       if (!strncasecmp(url, "/c/winnt", 8)) return(2);
-       if (!strncasecmp(url, "/MSADC/", 7)) return(2);
+       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 */
+       };
 
-       /** Broken Microsoft DAV implementation */
-       if (!strncasecmp(url, "/_vti", 5)) return(3);
+       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 */
 }
@@ -340,7 +358,7 @@ void context_loop(int sock)
 
                safestrncpy(hptr->line, buf, sizeof hptr->line);
 
-       } while (strlen(buf) > 0);
+       } while (!IsEmptyStr(buf));
 
        /**
         * If the request is prefixed by "/webcit" then chop that off.  This
@@ -416,7 +434,7 @@ void context_loop(int sock)
                for (sptr = SessionList; sptr != NULL; sptr = sptr->next) {
 
                        /** If HTTP-AUTH, look for a session with matching credentials */
-                       if ( (strlen(httpauth_user) > 0)
+                       if ( (!IsEmptyStr(httpauth_user))
                           &&(!strcasecmp(sptr->httpauth_user, httpauth_user))
                           &&(!strcasecmp(sptr->httpauth_pass, httpauth_pass)) ) {
                                TheSession = sptr;
@@ -441,11 +459,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);