Catch more error, add SASL DIGEST MD5.
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@17945 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
		
							
								
								
									
										114
									
								
								kdc/digest.c
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								kdc/digest.c
									
									
									
									
									
								
							| @@ -100,9 +100,8 @@ _kdc_do_digest(krb5_context context, | ||||
| 	    goto out; | ||||
|  | ||||
| 	ret = EINVAL; | ||||
| 	krb5_clear_error_string(context); | ||||
| 	krb5_set_error_string(context, "Wrong digest server principal used"); | ||||
| 	p = krb5_principal_get_comp_string(context, principal, 0); | ||||
|  | ||||
| 	if (p == NULL) { | ||||
| 	    krb5_free_principal(context, principal); | ||||
| 	    goto out; | ||||
| @@ -152,7 +151,7 @@ _kdc_do_digest(krb5_context context, | ||||
|  | ||||
| 	if (client->entry.flags.allow_digest == 0) { | ||||
| 	    krb5_set_error_string(context,  | ||||
| 				  "server is not permitted to use digest"); | ||||
| 				  "Client is not permitted to use digest"); | ||||
| 	    ret = KRB5KDC_ERR_POLICY; | ||||
| 	    _kdc_free_ent (context, client); | ||||
| 	    goto out; | ||||
| @@ -167,6 +166,11 @@ _kdc_do_digest(krb5_context context, | ||||
| 	ret = krb5_auth_con_getremotesubkey(context, ac, &key); | ||||
| 	if (ret) | ||||
| 	    goto out; | ||||
| 	if (key == NULL) { | ||||
| 	    krb5_set_error_string(context, "digest: remote subkey not found"); | ||||
| 	    ret = EINVAL; | ||||
| 	    goto out; | ||||
| 	} | ||||
|  | ||||
| 	ret = krb5_crypto_init(context, key, 0, &crypto); | ||||
| 	krb5_free_keyblock (context, key); | ||||
| @@ -183,8 +187,10 @@ _kdc_do_digest(krb5_context context, | ||||
| 	    | ||||
|     ret = decode_DigestReqInner(buf.data, buf.length, &ireq, NULL); | ||||
|     krb5_data_free(&buf); | ||||
|     if (ret) | ||||
|     if (ret) { | ||||
| 	krb5_set_error_string(context, "Failed to decode digest inner request"); | ||||
| 	goto out; | ||||
|     } | ||||
|  | ||||
|     /* | ||||
|      * Process the inner request | ||||
| @@ -192,8 +198,7 @@ _kdc_do_digest(krb5_context context, | ||||
|  | ||||
|     switch (ireq.element) { | ||||
|     case choice_DigestReqInner_init: { | ||||
| 	unsigned char server_nonce[16]; | ||||
| 	char identifier; | ||||
| 	unsigned char server_nonce[16], identifier; | ||||
|  | ||||
| 	RAND_pseudo_bytes(&identifier, sizeof(identifier)); | ||||
| 	RAND_pseudo_bytes(&server_nonce, sizeof(server_nonce)); | ||||
| @@ -481,7 +486,6 @@ _kdc_do_digest(krb5_context context, | ||||
| 	    goto out; | ||||
| 	} | ||||
|  | ||||
| 	/* just support CHAP for now */ | ||||
| 	if (strcasecmp(ireq.u.digestRequest.type, "CHAP") == 0) { | ||||
| 	    MD5_CTX ctx; | ||||
| 	    char md[MD5_DIGEST_LENGTH]; | ||||
| @@ -513,6 +517,102 @@ _kdc_do_digest(krb5_context context, | ||||
| 		ret = ENOMEM; | ||||
| 		goto out; | ||||
| 	    } | ||||
| 	} else if (strcasecmp(ireq.u.digestRequest.type, "SASL-DIGEST-MD5") == 0) { | ||||
| 	    MD5_CTX ctx; | ||||
| 	    char md[MD5_DIGEST_LENGTH]; | ||||
| 	    char *A1, *A2; | ||||
|  | ||||
| 	    if (ireq.u.digestRequest.nonceCount == NULL)  | ||||
| 		goto out; | ||||
| 	    if (ireq.u.digestRequest.clientNonce == NULL)  | ||||
| 		goto out; | ||||
| 	    if (ireq.u.digestRequest.qop == NULL)  | ||||
| 		goto out; | ||||
| 	    if (ireq.u.digestRequest.realm == NULL)  | ||||
| 		goto out; | ||||
| 	     | ||||
| 	    MD5_Init(&ctx); | ||||
| 	    MD5_Update(&ctx, ireq.u.digestRequest.username, | ||||
| 		       strlen(ireq.u.digestRequest.username)); | ||||
| 	    MD5_Update(&ctx, ":", 1); | ||||
| 	    MD5_Update(&ctx, *ireq.u.digestRequest.realm, | ||||
| 		       strlen(*ireq.u.digestRequest.realm)); | ||||
| 	    MD5_Update(&ctx, ":", 1); | ||||
| 	    MD5_Update(&ctx, password, strlen(password)); | ||||
| 	    MD5_Final(md, &ctx); | ||||
| 	     | ||||
| 	    MD5_Init(&ctx); | ||||
| 	    MD5_Update(&ctx, md, sizeof(md)); | ||||
| 	    MD5_Update(&ctx, ":", 1); | ||||
| 	    MD5_Update(&ctx, ireq.u.digestRequest.serverNonce, | ||||
| 		       strlen(ireq.u.digestRequest.serverNonce)); | ||||
| 	    MD5_Update(&ctx, ":", 1); | ||||
| 	    MD5_Update(&ctx, *ireq.u.digestRequest.nonceCount, | ||||
| 		       strlen(*ireq.u.digestRequest.nonceCount)); | ||||
| 	    if (ireq.u.digestRequest.authid) { | ||||
| 		MD5_Update(&ctx, ":", 1); | ||||
| 		MD5_Update(&ctx, *ireq.u.digestRequest.authid, | ||||
| 			   strlen(*ireq.u.digestRequest.authid)); | ||||
| 	    } | ||||
| 	    MD5_Final(md, &ctx); | ||||
| 	    hex_encode(md, sizeof(md), &A1); | ||||
| 	    if (A1 == NULL) { | ||||
| 		krb5_set_error_string(context, "out of memory"); | ||||
| 		ret = ENOMEM; | ||||
| 		goto out; | ||||
| 	    } | ||||
| 	     | ||||
| 	    MD5_Init(&ctx); | ||||
| 	    MD5_Update(&ctx, "AUTHENTICATE:", sizeof("AUTHENTICATE:") - 1); | ||||
| 	    MD5_Update(&ctx, *ireq.u.digestRequest.uri, | ||||
| 		       strlen(*ireq.u.digestRequest.uri)); | ||||
| 	 | ||||
| 	    /* conf|int */ | ||||
| 	    if (strcmp(ireq.u.digestRequest.digest, "clear") != 0) { | ||||
| 		static char conf_zeros[] = ":00000000000000000000000000000000"; | ||||
| 		MD5_Update(&ctx, conf_zeros, sizeof(conf_zeros) - 1); | ||||
| 	    } | ||||
| 	     | ||||
| 	    MD5_Final(md, &ctx); | ||||
| 	    hex_encode(md, sizeof(md), &A2); | ||||
| 	    if (A2 == NULL) { | ||||
| 		krb5_set_error_string(context, "out of memory"); | ||||
| 		ret = ENOMEM; | ||||
| 		free(A1); | ||||
| 		goto out; | ||||
| 	    } | ||||
|  | ||||
| 	    MD5_Init(&ctx); | ||||
| 	    MD5_Update(&ctx, A1, strlen(A2)); | ||||
| 	    MD5_Update(&ctx, ":", 1); | ||||
| 	    MD5_Update(&ctx, ireq.u.digestRequest.serverNonce, | ||||
| 		       strlen(ireq.u.digestRequest.serverNonce)); | ||||
| 	    MD5_Update(&ctx, ":", 1); | ||||
| 	    MD5_Update(&ctx, *ireq.u.digestRequest.nonceCount, | ||||
| 		       strlen(*ireq.u.digestRequest.nonceCount)); | ||||
| 	    MD5_Update(&ctx, ":", 1); | ||||
| 	    MD5_Update(&ctx, *ireq.u.digestRequest.clientNonce, | ||||
| 		       strlen(*ireq.u.digestRequest.clientNonce)); | ||||
| 	    MD5_Update(&ctx, ":", 1); | ||||
| 	    MD5_Update(&ctx, *ireq.u.digestRequest.qop, | ||||
| 		       strlen(*ireq.u.digestRequest.qop)); | ||||
| 	    MD5_Update(&ctx, ":", 1); | ||||
| 	    MD5_Update(&ctx, A2, strlen(A2)); | ||||
|  | ||||
| 	    MD5_Final(md, &ctx); | ||||
|  | ||||
| 	    r.element = choice_DigestRepInner_response; | ||||
| 	    hex_encode(md, sizeof(md), &r.u.response.responseData); | ||||
|  | ||||
| 	    free(A1); | ||||
| 	    free(A2); | ||||
|  | ||||
| 	    if (r.u.response.responseData == NULL) { | ||||
| 		krb5_set_error_string(context, "out of memory"); | ||||
| 		ret = ENOMEM; | ||||
| 		goto out; | ||||
| 	    } | ||||
|  | ||||
| 	} else { | ||||
| 	    r.element = choice_DigestRepInner_error; | ||||
| 	    asprintf(&r.u.error.reason, "unsupported digest type %s",  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Love Hörnquist Åstrand
					Love Hörnquist Åstrand