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;
|
goto out;
|
||||||
|
|
||||||
ret = EINVAL;
|
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);
|
p = krb5_principal_get_comp_string(context, principal, 0);
|
||||||
|
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
krb5_free_principal(context, principal);
|
krb5_free_principal(context, principal);
|
||||||
goto out;
|
goto out;
|
||||||
@@ -152,7 +151,7 @@ _kdc_do_digest(krb5_context context,
|
|||||||
|
|
||||||
if (client->entry.flags.allow_digest == 0) {
|
if (client->entry.flags.allow_digest == 0) {
|
||||||
krb5_set_error_string(context,
|
krb5_set_error_string(context,
|
||||||
"server is not permitted to use digest");
|
"Client is not permitted to use digest");
|
||||||
ret = KRB5KDC_ERR_POLICY;
|
ret = KRB5KDC_ERR_POLICY;
|
||||||
_kdc_free_ent (context, client);
|
_kdc_free_ent (context, client);
|
||||||
goto out;
|
goto out;
|
||||||
@@ -167,6 +166,11 @@ _kdc_do_digest(krb5_context context,
|
|||||||
ret = krb5_auth_con_getremotesubkey(context, ac, &key);
|
ret = krb5_auth_con_getremotesubkey(context, ac, &key);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
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);
|
ret = krb5_crypto_init(context, key, 0, &crypto);
|
||||||
krb5_free_keyblock (context, key);
|
krb5_free_keyblock (context, key);
|
||||||
@@ -183,8 +187,10 @@ _kdc_do_digest(krb5_context context,
|
|||||||
|
|
||||||
ret = decode_DigestReqInner(buf.data, buf.length, &ireq, NULL);
|
ret = decode_DigestReqInner(buf.data, buf.length, &ireq, NULL);
|
||||||
krb5_data_free(&buf);
|
krb5_data_free(&buf);
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
krb5_set_error_string(context, "Failed to decode digest inner request");
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Process the inner request
|
* Process the inner request
|
||||||
@@ -192,8 +198,7 @@ _kdc_do_digest(krb5_context context,
|
|||||||
|
|
||||||
switch (ireq.element) {
|
switch (ireq.element) {
|
||||||
case choice_DigestReqInner_init: {
|
case choice_DigestReqInner_init: {
|
||||||
unsigned char server_nonce[16];
|
unsigned char server_nonce[16], identifier;
|
||||||
char identifier;
|
|
||||||
|
|
||||||
RAND_pseudo_bytes(&identifier, sizeof(identifier));
|
RAND_pseudo_bytes(&identifier, sizeof(identifier));
|
||||||
RAND_pseudo_bytes(&server_nonce, sizeof(server_nonce));
|
RAND_pseudo_bytes(&server_nonce, sizeof(server_nonce));
|
||||||
@@ -481,7 +486,6 @@ _kdc_do_digest(krb5_context context,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* just support CHAP for now */
|
|
||||||
if (strcasecmp(ireq.u.digestRequest.type, "CHAP") == 0) {
|
if (strcasecmp(ireq.u.digestRequest.type, "CHAP") == 0) {
|
||||||
MD5_CTX ctx;
|
MD5_CTX ctx;
|
||||||
char md[MD5_DIGEST_LENGTH];
|
char md[MD5_DIGEST_LENGTH];
|
||||||
@@ -513,6 +517,102 @@ _kdc_do_digest(krb5_context context,
|
|||||||
ret = ENOMEM;
|
ret = ENOMEM;
|
||||||
goto out;
|
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 {
|
} else {
|
||||||
r.element = choice_DigestRepInner_error;
|
r.element = choice_DigestRepInner_error;
|
||||||
asprintf(&r.u.error.reason, "unsupported digest type %s",
|
asprintf(&r.u.error.reason, "unsupported digest type %s",
|
||||||
|
Reference in New Issue
Block a user