| Pulled from CVS, Ident strings removed to let the patch apply pretty cleanly. |
| |
| |
| RCS file: /afs/andrew.cmu.edu/system/cvs/src/sasl/plugins/digestmd5.c,v |
| retrieving revision 1.183 |
| retrieving revision 1.184 |
| diff -u -r1.183 -r1.184 |
| |
| |
| @@ -556,12 +556,17 @@ |
| return SASL_OK; |
| } |
| |
| +static int is_lws_char (char c) |
| +{ |
| + return (c == ' ' || c == HT || c == CR || c == LF); |
| +} |
| + |
| static char *skip_lws (char *s) |
| { |
| if (!s) return NULL; |
| |
| /* skipping spaces: */ |
| - while (s[0] == ' ' || s[0] == HT || s[0] == CR || s[0] == LF) { |
| + while (is_lws_char(s[0])) { |
| if (s[0] == '\0') break; |
| s++; |
| } |
| @@ -750,17 +755,30 @@ |
| static void get_pair(char **in, char **name, char **value) |
| { |
| char *endpair; |
| - /* int inQuotes; */ |
| char *curp = *in; |
| *name = NULL; |
| *value = NULL; |
| |
| if (curp == NULL) return; |
| - if (curp[0] == '\0') return; |
| - |
| - /* skipping spaces: */ |
| - curp = skip_lws(curp); |
| - |
| + |
| + while (curp[0] != '\0') { |
| + /* skipping spaces: */ |
| + curp = skip_lws(curp); |
| + |
| + /* 'LWS "," LWS "," ...' is allowed by the DIGEST-MD5 ABNF */ |
| + if (curp[0] == ',') { |
| + curp++; |
| + } else { |
| + break; |
| + } |
| + } |
| + |
| + if (curp[0] == '\0') { |
| + /* End of the string is not an error */ |
| + *name = ""; |
| + return; |
| + } |
| + |
| *name = curp; |
| |
| curp = skip_token(curp,1); |
| @@ -787,22 +805,24 @@ |
| endpair = unquote (curp); |
| if (endpair == NULL) { /* Unbalanced quotes */ |
| *name = NULL; |
| + *value = NULL; |
| return; |
| } |
| - if (endpair[0] != ',') { |
| - if (endpair[0]!='\0') { |
| - *endpair++ = '\0'; |
| - } |
| + |
| + /* An optional LWS is allowed after the value. Skip it. */ |
| + if (is_lws_char (endpair[0])) { |
| + /* Remove the trailing LWS from the value */ |
| + *endpair++ = '\0'; |
| + endpair = skip_lws(endpair); |
| } |
| - |
| - endpair = skip_lws(endpair); |
| - |
| + |
| /* syntax check: MUST be '\0' or ',' */ |
| if (endpair[0] == ',') { |
| endpair[0] = '\0'; |
| endpair++; /* skipping <,> */ |
| } else if (endpair[0] != '\0') { |
| *name = NULL; |
| + *value = NULL; |
| return; |
| } |
| |
| @@ -2090,9 +2110,17 @@ |
| char *name = NULL, *value = NULL; |
| get_pair(&in, &name, &value); |
| |
| - if (name == NULL) |
| - break; |
| + if (name == NULL) { |
| + SETERROR(sparams->utils, |
| + "Parse error"); |
| + result = SASL_BADAUTH; |
| + goto FreeAllMem; |
| + } |
| |
| + if (*name == '\0') { |
| + break; |
| + } |
| + |
| /* Extracting parameters */ |
| |
| /* |
| @@ -3222,10 +3250,14 @@ |
| /* if parse error */ |
| if (name == NULL) { |
| params->utils->seterror(params->utils->conn, 0, "Parse error"); |
| - result = SASL_FAIL; |
| + result = SASL_BADAUTH; |
| goto FreeAllocatedMem; |
| } |
| |
| + if (*name == '\0') { |
| + break; |
| + } |
| + |
| if (strcasecmp(name, "realm") == 0) { |
| nrealm++; |
| |
| @@ -3887,9 +3919,14 @@ |
| if (name == NULL) { |
| params->utils->seterror(params->utils->conn, 0, |
| "DIGEST-MD5 Received Garbage"); |
| + result = SASL_BADAUTH; |
| break; |
| } |
| |
| + if (*name == '\0') { |
| + break; |
| + } |
| + |
| if (strcasecmp(name, "rspauth") == 0) { |
| |
| if (strcmp(text->response_value, value) != 0) { |