diff options
| author | Stanislav Sedov <stas@FreeBSD.org> | 2011-10-05 07:23:29 +0000 |
|---|---|---|
| committer | Stanislav Sedov <stas@FreeBSD.org> | 2011-10-05 07:23:29 +0000 |
| commit | 7c450da7b446c557e05f34a100b597800967d987 (patch) | |
| tree | 57a48e7e9b592f2d5b713e80a4455820625c2b7b /lib/gssapi/ntlm/init_sec_context.c | |
| parent | b4e3a10e9339a8400197298021d6ca9b8e3aa039 (diff) | |
Diffstat (limited to 'lib/gssapi/ntlm/init_sec_context.c')
| -rw-r--r-- | lib/gssapi/ntlm/init_sec_context.c | 187 |
1 files changed, 90 insertions, 97 deletions
diff --git a/lib/gssapi/ntlm/init_sec_context.c b/lib/gssapi/ntlm/init_sec_context.c index 140dbece8435..bae04e174060 100644 --- a/lib/gssapi/ntlm/init_sec_context.c +++ b/lib/gssapi/ntlm/init_sec_context.c @@ -1,50 +1,49 @@ /* - * Copyright (c) 2006 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 2006 - 2008 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ -#include "ntlm/ntlm.h" - -RCSID("$Id: init_sec_context.c 22382 2007-12-30 12:13:17Z lha $"); +#include "ntlm.h" static int -from_file(const char *fn, const char *target_domain, +from_file(const char *fn, const char *target_domain, char **username, struct ntlm_buf *key) -{ +{ char *str, buf[1024]; FILE *f; f = fopen(fn, "r"); if (f == NULL) return ENOENT; + rk_cloexec_file(f); while (fgets(buf, sizeof(buf), f) != NULL) { char *d, *u, *p; @@ -74,7 +73,7 @@ from_file(const char *fn, const char *target_domain, } static int -get_user_file(const ntlm_name target_name, +get_user_file(const ntlm_name target_name, char **username, struct ntlm_buf *key) { const char *fn; @@ -98,19 +97,18 @@ get_user_file(const ntlm_name target_name, static int get_user_ccache(const ntlm_name name, char **username, struct ntlm_buf *key) { - krb5_principal client; krb5_context context = NULL; - krb5_error_code ret; + krb5_principal client; krb5_ccache id = NULL; - krb5_creds mcreds, creds; + krb5_error_code ret; + char *confname; + krb5_data data; *username = NULL; + krb5_data_zero(&data); key->length = 0; key->data = NULL; - memset(&creds, 0, sizeof(creds)); - memset(&mcreds, 0, sizeof(mcreds)); - ret = krb5_init_context(&context); if (ret) return ret; @@ -126,47 +124,36 @@ get_user_ccache(const ntlm_name name, char **username, struct ntlm_buf *key) ret = krb5_unparse_name_flags(context, client, KRB5_PRINCIPAL_UNPARSE_NO_REALM, username); - if (ret) - goto out; - - ret = krb5_make_principal(context, &mcreds.server, - krb5_principal_get_realm(context, client), - "@ntlm-key", name->domain, NULL); krb5_free_principal(context, client); if (ret) goto out; - mcreds.session.keytype = ENCTYPE_ARCFOUR_HMAC_MD5; - ret = krb5_cc_retrieve_cred(context, id, KRB5_TC_MATCH_KEYTYPE, - &mcreds, &creds); - if (ret) { - char *s = krb5_get_error_message(context, ret); - krb5_free_error_string(context, s); + asprintf(&confname, "ntlm-key-%s", name->domain); + if (confname == NULL) { + krb5_clear_error_message(context); + ret = ENOMEM; goto out; } - key->data = malloc(creds.session.keyvalue.length); - if (key->data == NULL) + ret = krb5_cc_get_config(context, id, NULL, + confname, &data); + if (ret) goto out; - key->length = creds.session.keyvalue.length; - memcpy(key->data, creds.session.keyvalue.data, key->length); - - krb5_free_cred_contents(context, &creds); - return 0; - -out: - if (*username) { - free(*username); - *username = NULL; + key->data = malloc(data.length); + if (key->data == NULL) { + ret = ENOMEM; + goto out; } - krb5_free_cred_contents(context, &creds); - if (mcreds.server) - krb5_free_principal(context, mcreds.server); + key->length = data.length; + memcpy(key->data, data.data, data.length); + + out: + krb5_data_free(&data); if (id) krb5_cc_close(context, id); - if (context) - krb5_free_context(context); + + krb5_free_context(context); return ret; } @@ -177,11 +164,11 @@ _gss_ntlm_get_user_cred(const ntlm_name target_name, { ntlm_cred cred; int ret; - + cred = calloc(1, sizeof(*cred)); if (cred == NULL) return ENOMEM; - + ret = get_user_file(target_name, &cred->username, &cred->key); if (ret) ret = get_user_ccache(target_name, &cred->username, &cred->key); @@ -189,7 +176,7 @@ _gss_ntlm_get_user_cred(const ntlm_name target_name, free(cred); return ret; } - + cred->domain = strdup(target_name->domain); *rcred = cred; @@ -199,7 +186,7 @@ _gss_ntlm_get_user_cred(const ntlm_name target_name, static int _gss_copy_cred(ntlm_cred from, ntlm_cred *to) { - *to = calloc(1, sizeof(*to)); + *to = calloc(1, sizeof(**to)); if (*to == NULL) return ENOMEM; (*to)->username = strdup(from->username); @@ -226,7 +213,7 @@ _gss_copy_cred(ntlm_cred from, ntlm_cred *to) return 0; } -OM_uint32 +OM_uint32 GSSAPI_CALLCONV _gss_ntlm_init_sec_context (OM_uint32 * minor_status, const gss_cred_id_t initiator_cred_handle, @@ -260,7 +247,7 @@ _gss_ntlm_init_sec_context struct ntlm_buf data; uint32_t flags = 0; int ret; - + ctx = calloc(1, sizeof(*ctx)); if (ctx == NULL) { *minor_status = EINVAL; @@ -293,23 +280,23 @@ _gss_ntlm_init_sec_context flags |= NTLM_NEG_KEYEX; memset(&type1, 0, sizeof(type1)); - + type1.flags = flags; type1.domain = name->domain; type1.hostname = NULL; type1.os[0] = 0; type1.os[1] = 0; - + ret = heim_ntlm_encode_type1(&type1, &data); if (ret) { _gss_ntlm_delete_sec_context(minor_status, context_handle, NULL); *minor_status = ret; return GSS_S_FAILURE; } - + output_token->value = data.data; output_token->length = data.length; - + return GSS_S_CONTINUE_NEEDED; } else { krb5_error_code ret; @@ -331,7 +318,7 @@ _gss_ntlm_init_sec_context ctx->flags = type2.flags; - /* XXX check that type2.targetinfo matches `target_name´ */ + /* XXX check that type2.targetinfo matches `target_name´ */ /* XXX check verify targetinfo buffer */ memset(&type3, 0, sizeof(type3)); @@ -352,21 +339,21 @@ _gss_ntlm_init_sec_context unsigned char nonce[8]; if (RAND_bytes(nonce, sizeof(nonce)) != 1) { - _gss_ntlm_delete_sec_context(minor_status, + _gss_ntlm_delete_sec_context(minor_status, context_handle, NULL); *minor_status = EINVAL; return GSS_S_FAILURE; } ret = heim_ntlm_calculate_ntlm2_sess(nonce, - type2.challange, + type2.challenge, ctx->client->key.data, &type3.lm, &type3.ntlm); } else { - ret = heim_ntlm_calculate_ntlm1(ctx->client->key.data, + ret = heim_ntlm_calculate_ntlm1(ctx->client->key.data, ctx->client->key.length, - type2.challange, + type2.challenge, &type3.ntlm); } @@ -376,7 +363,7 @@ _gss_ntlm_init_sec_context return GSS_S_FAILURE; } - ret = heim_ntlm_build_ntlm1_master(ctx->client->key.data, + ret = heim_ntlm_build_ntlm1_master(ctx->client->key.data, ctx->client->key.length, &sessionkey, &type3.sessionkey); @@ -390,7 +377,7 @@ _gss_ntlm_init_sec_context return GSS_S_FAILURE; } - ret = krb5_data_copy(&ctx->sessionkey, + ret = krb5_data_copy(&ctx->sessionkey, sessionkey.data, sessionkey.length); free(sessionkey.data); if (ret) { @@ -402,7 +389,7 @@ _gss_ntlm_init_sec_context *minor_status = ret; return GSS_S_FAILURE; } - ctx->status |= STATUS_SESSIONKEY; + ctx->status |= STATUS_SESSIONKEY; } else { struct ntlm_buf sessionkey; @@ -410,17 +397,17 @@ _gss_ntlm_init_sec_context struct ntlm_targetinfo ti; /* verify infotarget */ - + ret = heim_ntlm_decode_targetinfo(&type2.targetinfo, 1, &ti); if(ret) { - _gss_ntlm_delete_sec_context(minor_status, + _gss_ntlm_delete_sec_context(minor_status, context_handle, NULL); *minor_status = ret; return GSS_S_FAILURE; } if (ti.domainname && strcmp(ti.domainname, name->domain) != 0) { - _gss_ntlm_delete_sec_context(minor_status, + _gss_ntlm_delete_sec_context(minor_status, context_handle, NULL); *minor_status = EINVAL; return GSS_S_FAILURE; @@ -430,12 +417,12 @@ _gss_ntlm_init_sec_context ctx->client->key.length, ctx->client->username, name->domain, - type2.challange, + type2.challenge, &type2.targetinfo, ntlmv2, &type3.ntlm); if (ret) { - _gss_ntlm_delete_sec_context(minor_status, + _gss_ntlm_delete_sec_context(minor_status, context_handle, NULL); *minor_status = ret; return GSS_S_FAILURE; @@ -446,21 +433,27 @@ _gss_ntlm_init_sec_context &type3.sessionkey); memset(ntlmv2, 0, sizeof(ntlmv2)); if (ret) { - _gss_ntlm_delete_sec_context(minor_status, + _gss_ntlm_delete_sec_context(minor_status, context_handle, NULL); *minor_status = ret; return GSS_S_FAILURE; } - + ctx->flags |= NTLM_NEG_NTLM2_SESSION; - ret = krb5_data_copy(&ctx->sessionkey, + ret = krb5_data_copy(&ctx->sessionkey, sessionkey.data, sessionkey.length); free(sessionkey.data); + if (ret) { + _gss_ntlm_delete_sec_context(minor_status, + context_handle, NULL); + *minor_status = ret; + return GSS_S_FAILURE; + } } if (ctx->flags & NTLM_NEG_NTLM2_SESSION) { - ctx->status |= STATUS_SESSIONKEY; + ctx->status |= STATUS_SESSIONKEY; _gss_ntlm_set_key(&ctx->u.v2.send, 0, (ctx->flags & NTLM_NEG_KEYEX), ctx->sessionkey.data, ctx->sessionkey.length); @@ -468,15 +461,15 @@ _gss_ntlm_init_sec_context ctx->sessionkey.data, ctx->sessionkey.length); } else { - ctx->status |= STATUS_SESSIONKEY; - RC4_set_key(&ctx->u.v1.crypto_recv.key, + ctx->status |= STATUS_SESSIONKEY; + RC4_set_key(&ctx->u.v1.crypto_recv.key, ctx->sessionkey.length, ctx->sessionkey.data); - RC4_set_key(&ctx->u.v1.crypto_send.key, + RC4_set_key(&ctx->u.v1.crypto_send.key, ctx->sessionkey.length, ctx->sessionkey.data); } - + ret = heim_ntlm_encode_type3(&type3, &data); |
