Sophie

Sophie

distrib > Mandriva > 10.0-com > i586 > by-pkgid > ad910ee9d1fef55426428029d6b32ead > files > 2

cyrus-sasl-2.1.15-10.2.100mdk.src.rpm

--- cyrus-sasl-2.1.15/plugins/digestmd5.c.can-2005-0373	2003-03-30 15:17:06.000000000 -0700
+++ cyrus-sasl-2.1.15/plugins/digestmd5.c	2005-03-11 09:32:38.855599311 -0700
@@ -133,6 +133,10 @@
 #define SP	(32)
 #define DEL	(127)
 
+#define NEED_ESCAPING	"\"\\"
+
+static char *quote (char *str);
+
 struct context;
 
 /* function definitions for cipher encode/decode */
@@ -183,6 +187,11 @@
     reauth_entry_t *e;		/* fixed-size hash table of entries */
 } reauth_cache_t;
 
+/* global context for reauth use */
+typedef struct digest_glob_context { 
+   reauth_cache_t *reauth; 
+} digest_glob_context_t;
+
 /* context that stores info */
 typedef struct context {
     int state;			/* state in the authentication we are in */
@@ -491,21 +500,42 @@
     ret = _plug_buf_alloc(utils, str, buflen,
 			  *curlen + 1 + namesize + 2 + valuesize + 2);
     if(ret != SASL_OK) return ret;
-    
-    *curlen = *curlen + 1 + namesize + 2 + valuesize + 2;
-    
-    strcat(*str, ",");
-    strcat(*str, name);
+
+    if (*curlen > 0) {
+	strcat(*str, ",");
+	strcat(*str, name);
+    } else {
+	strcpy(*str, name);
+    }
     
     if (need_quotes) {
 	strcat(*str, "=\"");
-	strcat(*str, (char *) value);	/* XXX. What about quoting??? */
+
+	/* Check if the value needs quoting */
+	if (strpbrk ((char *)value, NEED_ESCAPING) != NULL) {
+	    char * quoted = quote ((char *) value);
+	    valuesize = strlen(quoted);
+	    /* As the quoted string is bigger, make sure we have enough
+	       space now */
+	    ret = _plug_buf_alloc(utils, str, buflen,
+			  *curlen + 1 + namesize + 2 + valuesize + 2);
+	    if (ret == SASL_OK) {
+		strcat(*str, quoted);
+		free (quoted);
+	    } else {
+		free (quoted);
+		return ret;
+	    }
+	} else {
+	    strcat(*str, (char *) value);
+	}
 	strcat(*str, "\"");
     } else {
 	strcat(*str, "=");
 	strcat(*str, (char *) value);
     }
     
+    *curlen = *curlen + 1 + namesize + 2 + valuesize + 2;
     return SASL_OK;
 }
 
@@ -544,7 +574,8 @@
 }
 
 /* NULL - error (unbalanced quotes), 
-   otherwise pointer to the first character after value */
+   otherwise pointer to the first character after the value.
+   The function performs work in place. */
 static char *unquote (char *qstr)
 {
     char *endvalue;
@@ -585,11 +616,48 @@
 	endvalue++;
     }
     else { /* not qouted value (token) */
+	/* qstr already contains output */
 	endvalue = skip_token(qstr,0);
     };
     
     return endvalue;  
-} 
+}
+
+/* Unlike unquote, this function returns an allocated quoted copy */
+static char *quote (char *str)
+{
+    char *p;
+    char *outp;
+    char *result;
+    int num_to_escape;		/* How many characters need escaping */
+    
+    if (!str) return NULL;
+
+    num_to_escape = 0;
+    p = strpbrk (str, NEED_ESCAPING);
+    while (p != NULL) {
+	num_to_escape++;
+	p = strpbrk (p + 1, NEED_ESCAPING);
+    }
+
+    if (num_to_escape == 0) {
+	return (strdup (str));
+    }
+
+    result = malloc (strlen(str) + num_to_escape + 1);
+    for (p = str, outp = result; *p; p++) {
+	if (*p == '"' || *p == '\\') {
+	    *outp = '\\';
+	    outp++;
+	}
+	*outp = *p;
+	outp++;
+    }
+
+    *outp = '\0';
+    
+    return (result);
+}
 
 static void get_pair(char **in, char **name, char **value)
 {
@@ -1738,7 +1806,9 @@
 static void
 digestmd5_common_mech_free(void *glob_context, const sasl_utils_t *utils)
 {
-    reauth_cache_t *reauth_cache = (reauth_cache_t *) glob_context;
+    digest_glob_context_t *my_glob_context =
+	(digest_glob_context_t *) glob_context;
+    reauth_cache_t *reauth_cache = my_glob_context->reauth;
     size_t n;
     
     if (!reauth_cache) return;
@@ -1750,6 +1820,7 @@
     if (reauth_cache->mutex) utils->mutex_free(reauth_cache->mutex);
 
     utils->free(reauth_cache);
+    my_glob_context->reauth = NULL;
 }
 
 /*****************************  Server Section  *****************************/
@@ -1762,6 +1833,8 @@
     sasl_ssf_t limitssf, requiressf;	/* application defined bounds */
 } server_context_t;
 
+static digest_glob_context_t server_glob_context;
+
 static void
 DigestCalcHA1FromSecret(context_t * text,
 			const sasl_utils_t * utils,
@@ -1953,7 +2026,7 @@
     
     text->state = 1;
     text->i_am = SERVER;
-    text->reauth = glob_context;
+    text->reauth = ((digest_glob_context_t *) glob_context)->reauth;
     
     *conn_context = text;
     return SASL_OK;
@@ -2032,13 +2105,17 @@
 	return SASL_FAIL;
     }
     
-    resplen = strlen(nonce) + strlen("nonce") + 5;
-    result = _plug_buf_alloc(sparams->utils, &(text->out_buf),
-			     &(text->out_buf_len), resplen);
-    if(result != SASL_OK) return result;
-    
-    sprintf(text->out_buf, "nonce=\"%s\"", nonce);
-    
+    resplen = 0;
+    text->out_buf = NULL;
+    text->out_buf_len = 0;
+    if (add_to_challenge(sparams->utils,
+				  &text->out_buf, &text->out_buf_len, &resplen,
+				  "nonce", (unsigned char *) nonce,
+				  TRUE) != SASL_OK) {
+	SETERROR(sparams->utils, "internal error: add_to_challenge failed");
+	return SASL_FAIL;
+    }
+
     /* add to challenge; if we chose not to specify a realm, we won't
      * send one to the client */
     if (realm && add_to_challenge(sparams->utils,
@@ -2830,7 +2907,7 @@
 	| SASL_SEC_NOANONYMOUS
 	| SASL_SEC_MUTUAL_AUTH,		/* security_flags */
 	SASL_FEAT_ALLOWS_PROXY,		/* features */
-	NULL,				/* glob_context */
+	&server_glob_context,		/* glob_context */
 	&digestmd5_server_mech_new,	/* mech_new */
 	&digestmd5_server_mech_step,	/* mech_step */
 	&digestmd5_server_mech_dispose,	/* mech_dispose */
@@ -2886,7 +2963,7 @@
 	memset(reauth_cache->e, 0, reauth_cache->size * sizeof(reauth_entry_t));
     }
 
-    digestmd5_server_plugins[0].glob_context = reauth_cache;
+    ((digest_glob_context_t *) digestmd5_server_plugins[0].glob_context)->reauth = reauth_cache;
 
     *out_version = SASL_SERVER_PLUG_VERSION;
     *pluglist = digestmd5_server_plugins;
@@ -2908,6 +2985,8 @@
     unsigned int server_maxbuf;
 } client_context_t;
 
+static digest_glob_context_t client_glob_context;
+
 /* calculate H(A1) as per spec */
 static void
 DigestCalcHA1(context_t * text,
@@ -3054,7 +3133,7 @@
     char           maxbufstr[64];
     char           *response = NULL;
     unsigned        resplen = 0;
-    int result;
+    int result = SASL_OK;
 
     switch (ctext->protection) {
     case DIGEST_PRIVACY:
@@ -3116,14 +3195,17 @@
 			   &text->response_value);
     
     
-    resplen = strlen(oparams->authid) + strlen("username") + 5;
-    result =_plug_buf_alloc(params->utils, &(text->out_buf),
-			    &(text->out_buf_len),
-			    resplen);
-    if (result != SASL_OK) goto FreeAllocatedMem;
-    
-    sprintf(text->out_buf, "username=\"%s\"", oparams->authid);
-    
+    resplen = 0;
+    text->out_buf = NULL;
+    text->out_buf_len = 0;
+    if (add_to_challenge(params->utils,
+			 &text->out_buf, &text->out_buf_len, &resplen,
+			 "username", (unsigned char *) oparams->authid,
+			 TRUE) != SASL_OK) {
+	result = SASL_FAIL;
+	goto FreeAllocatedMem;
+    }
+
     if (add_to_challenge(params->utils,
 			 &text->out_buf, &text->out_buf_len, &resplen,
 			 "realm", (unsigned char *) text->realm,
@@ -3712,7 +3794,7 @@
     
     text->state = 1;
     text->i_am = CLIENT;
-    text->reauth = glob_context;
+    text->reauth = ((digest_glob_context_t *) glob_context)->reauth;
     
     *conn_context = text;
 
@@ -3896,7 +3978,7 @@
 	    if (strcmp(text->response_value, value) != 0) {
 		params->utils->seterror(params->utils->conn, 0,
 					"DIGEST-MD5: This server wants us to believe that he knows shared secret");
-		result = SASL_FAIL;
+		result = SASL_BADSERV;
 	    } else {
 		oparams->doneflag = 1;
 		oparams->param_version = 0;
@@ -4070,7 +4152,7 @@
 	| SASL_SEC_MUTUAL_AUTH,		/* security_flags */
 	SASL_FEAT_ALLOWS_PROXY, 	/* features */
 	NULL,				/* required_prompts */
-	NULL,				/* glob_context */
+	&client_glob_context,		/* glob_context */
 	&digestmd5_client_mech_new,	/* mech_new */
 	&digestmd5_client_mech_step,	/* mech_step */
 	&digestmd5_client_mech_dispose,	/* mech_dispose */
@@ -4112,7 +4194,7 @@
 	return SASL_NOMEM;
     memset(reauth_cache->e, 0, reauth_cache->size * sizeof(reauth_entry_t));
 
-    digestmd5_client_plugins[0].glob_context = reauth_cache;
+    ((digest_glob_context_t *) digestmd5_client_plugins[0].glob_context)->reauth = reauth_cache;
 
     *out_version = SASL_CLIENT_PLUG_VERSION;
     *pluglist = digestmd5_client_plugins;