Blob Blame History Raw
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
--- src/sasl/plugins/digestmd5.c	2006/11/27 20:41:55	1.183
+++ src/sasl/plugins/digestmd5.c	2007/02/14 17:16:14	1.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) {