Merged revisions 114600 via svnmerge from
authorRussell Bryant <russell@russellbryant.com>
Wed, 23 Apr 2008 22:53:20 +0000 (22:53 +0000)
committerRussell Bryant <russell@russellbryant.com>
Wed, 23 Apr 2008 22:53:20 +0000 (22:53 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r114600 | russell | 2008-04-23 17:18:12 -0500 (Wed, 23 Apr 2008) | 6 lines

Improve some broken cookie parsing code.  Previously, manager login over HTTP
would only work if the mansession_id cookie was first.  Now, the code builds
a list of all of the cookies in the Cookie header.  This fixes a problem
observed by users of the Asterisk GUI.
(closes AST-20)

........

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@114601 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/http.c

index 8a3792b..42d0db5 100644 (file)
@@ -558,12 +558,49 @@ static int ssl_close(void *cookie)
 }*/
 #endif /* DO_SSL */
 
+static struct ast_variable *parse_cookies(char *cookies)
+{
+       char *cur;
+       struct ast_variable *vars = NULL, *var;
+
+       /* Skip Cookie: */
+       cookies += 8;
+
+       while ((cur = strsep(&cookies, ";"))) {
+               char *name, *val;
+               
+               name = val = cur;
+               strsep(&val, "=");
+
+               if (ast_strlen_zero(name) || ast_strlen_zero(val)) {
+                       continue;
+               }
+
+               name = ast_strip(name);
+               val = ast_strip_quoted(val, "\"", "\"");
+
+               if (ast_strlen_zero(name) || ast_strlen_zero(val)) {
+                       continue;
+               }
+
+               if (option_debug) {
+                       ast_log(LOG_DEBUG, "mmm ... cookie!  Name: '%s'  Value: '%s'\n", name, val);
+               }
+
+               var = ast_variable_new(name, val, __FILE__);
+               var->next = vars;
+               vars = var;
+       }
+
+       return vars;
+}
+
 static void *httpd_helper_thread(void *data)
 {
        char buf[4096];
        char cookie[4096];
        struct ast_tcptls_session_instance *ser = data;
-       struct ast_variable *var, *prev=NULL, *vars=NULL, *headers = NULL;
+       struct ast_variable *vars=NULL, *headers = NULL;
        char *uri, *title=NULL;
        int status = 200, contentlength = 0;
        struct ast_str *out = NULL;
@@ -590,9 +627,6 @@ static void *httpd_helper_thread(void *data)
 
        /* process "Cookie: " lines */
        while (fgets(cookie, sizeof(cookie), ser->f)) {
-               char *vname, *vval;
-               int l;
-
                /* Trim trailing characters */
                ast_trim_blanks(cookie);
                if (ast_strlen_zero(cookie)) {
@@ -600,6 +634,7 @@ static void *httpd_helper_thread(void *data)
                }
                if (strncasecmp(cookie, "Cookie: ", 8)) {
                        char *name, *value;
+                       struct ast_variable *var;
 
                        value = ast_strdupa(cookie);
                        name = strsep(&value, ":");
@@ -620,48 +655,10 @@ static void *httpd_helper_thread(void *data)
                        continue;
                }
 
-               /* TODO - The cookie parsing code below seems to work   
-                  in IE6 and FireFox 1.5.  However, it is not entirely 
-                  correct, and therefore may not work in all           
-                  circumstances.                                       
-                     For more details see RFC 2109 and RFC 2965        */
-       
-               /* FireFox cookie strings look like:                    
-                    Cookie: mansession_id="********"                   
-                  InternetExplorer's look like:                        
-                    Cookie: $Version="1"; mansession_id="********"     */
-               
-               /* If we got a FireFox cookie string, the name's right  
-                   after "Cookie: "                                    */
-               vname = ast_skip_blanks(cookie + 8);
-                       
-               /* If we got an IE cookie string, we need to skip to    
-                   past the version to get to the name                 */
-               if (*vname == '$') {
-                       strsep(&vname, ";");
-                       if (!vname) {   /* no name ? */
-                               continue;
-                       }
-                       vname = ast_skip_blanks(vname);
-               }
-               if (!(vval = strchr(vname, '='))) {
-                       continue;
-               }
-               /* Ditch the = and the quotes */
-               *vval++ = '\0';
-               if (*vval) {
-                       vval++;
-               }
-               if ((l = strlen(vval))) {
-                       vval[l - 1] = '\0';     /* trim trailing quote */
-               }
-               if ((var = ast_variable_new(vname, vval, ""))) {
-                       if (prev)
-                               prev->next = var;
-                       else
-                               vars = var;
-                       prev = var;
+               if (vars) {
+                       ast_variables_destroy(vars);
                }
+               vars = parse_cookies(cookie);
        }
 
        if (!*uri) {