From 0d83a46769e43f7e685f463f4b8c21c7e437474b Mon Sep 17 00:00:00 2001 From: =?utf-8?q?G=C3=BCnther=20Deschner?= Date: Thu, 15 Oct 2009 16:00:57 +0200 Subject: [PATCH 1/2] s3-spnego: avoid NULL talloc context in read_spnego_data(). Guenther --- source3/include/proto.h | 2 +- source3/libsmb/spnego.c | 30 +++++++++++++++--------------- source3/utils/ntlm_auth.c | 4 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index e489224..d91dbf8 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -3293,7 +3293,7 @@ WERROR map_werror_from_unix(int error); /* The following definitions come from libsmb/spnego.c */ -ssize_t read_spnego_data(DATA_BLOB data, SPNEGO_DATA *token); +ssize_t read_spnego_data(TALLOC_CTX *mem_ctx, DATA_BLOB data, SPNEGO_DATA *token); ssize_t write_spnego_data(DATA_BLOB *blob, SPNEGO_DATA *spnego); bool free_spnego_data(SPNEGO_DATA *spnego); diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c index ee2c3c3..3ef9610 100644 --- a/source3/libsmb/spnego.c +++ b/source3/libsmb/spnego.c @@ -25,7 +25,7 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH -static bool read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) +static bool read_negTokenInit(TALLOC_CTX *mem_ctx, ASN1_DATA *asn1, negTokenInit_t *token) { ZERO_STRUCTP(token); @@ -41,17 +41,17 @@ static bool read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) asn1_start_tag(asn1, ASN1_CONTEXT(0)); asn1_start_tag(asn1, ASN1_SEQUENCE(0)); - token->mechTypes = TALLOC_P(NULL, const char *); + token->mechTypes = TALLOC_P(mem_ctx, const char *); for (i = 0; !asn1->has_error && 0 < asn1_tag_remaining(asn1); i++) { const char *p_oid = NULL; token->mechTypes = - TALLOC_REALLOC_ARRAY(NULL, token->mechTypes, const char *, i + 2); + TALLOC_REALLOC_ARRAY(mem_ctx, token->mechTypes, const char *, i + 2); if (!token->mechTypes) { asn1->has_error = True; return False; } - asn1_read_OID(asn1, NULL, &p_oid); + asn1_read_OID(asn1, mem_ctx, &p_oid); token->mechTypes[i] = p_oid; } token->mechTypes[i] = NULL; @@ -69,14 +69,14 @@ static bool read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) /* Read mechToken */ case ASN1_CONTEXT(2): asn1_start_tag(asn1, ASN1_CONTEXT(2)); - asn1_read_OctetString(asn1, NULL, &token->mechToken); + asn1_read_OctetString(asn1, mem_ctx, &token->mechToken); asn1_end_tag(asn1); break; /* Read mecListMIC */ case ASN1_CONTEXT(3): asn1_start_tag(asn1, ASN1_CONTEXT(3)); if (asn1->data[asn1->ofs] == ASN1_OCTET_STRING) { - asn1_read_OctetString(asn1, NULL, + asn1_read_OctetString(asn1, mem_ctx, &token->mechListMIC); } else { /* RFC 2478 says we have an Octet String here, @@ -84,7 +84,7 @@ static bool read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) char *mechListMIC; asn1_push_tag(asn1, ASN1_SEQUENCE(0)); asn1_push_tag(asn1, ASN1_CONTEXT(0)); - asn1_read_GeneralString(asn1, NULL, &mechListMIC); + asn1_read_GeneralString(asn1, mem_ctx, &mechListMIC); asn1_pop_tag(asn1); asn1_pop_tag(asn1); @@ -169,7 +169,7 @@ static bool write_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) return !asn1->has_error; } -static bool read_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token) +static bool read_negTokenTarg(TALLOC_CTX *mem_ctx, ASN1_DATA *asn1, negTokenTarg_t *token) { ZERO_STRUCTP(token); @@ -188,19 +188,19 @@ static bool read_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token) case ASN1_CONTEXT(1): { const char *mech = NULL; asn1_start_tag(asn1, ASN1_CONTEXT(1)); - asn1_read_OID(asn1, NULL, &mech); + asn1_read_OID(asn1, mem_ctx, &mech); asn1_end_tag(asn1); token->supportedMech = CONST_DISCARD(char *, mech); } break; case ASN1_CONTEXT(2): asn1_start_tag(asn1, ASN1_CONTEXT(2)); - asn1_read_OctetString(asn1, NULL, &token->responseToken); + asn1_read_OctetString(asn1, mem_ctx, &token->responseToken); asn1_end_tag(asn1); break; case ASN1_CONTEXT(3): asn1_start_tag(asn1, ASN1_CONTEXT(3)); - asn1_read_OctetString(asn1, NULL, &token->mechListMIC); + asn1_read_OctetString(asn1, mem_ctx, &token->mechListMIC); asn1_end_tag(asn1); break; default: @@ -250,14 +250,14 @@ static bool write_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token) return !asn1->has_error; } -ssize_t read_spnego_data(DATA_BLOB data, SPNEGO_DATA *token) +ssize_t read_spnego_data(TALLOC_CTX *mem_ctx, DATA_BLOB data, SPNEGO_DATA *token) { ASN1_DATA *asn1; ssize_t ret = -1; ZERO_STRUCTP(token); - asn1 = asn1_init(talloc_tos()); + asn1 = asn1_init(mem_ctx); if (asn1 == NULL) { return -1; } @@ -268,13 +268,13 @@ ssize_t read_spnego_data(DATA_BLOB data, SPNEGO_DATA *token) case ASN1_APPLICATION(0): asn1_start_tag(asn1, ASN1_APPLICATION(0)); asn1_check_OID(asn1, OID_SPNEGO); - if (read_negTokenInit(asn1, &token->negTokenInit)) { + if (read_negTokenInit(mem_ctx, asn1, &token->negTokenInit)) { token->type = SPNEGO_NEG_TOKEN_INIT; } asn1_end_tag(asn1); break; case ASN1_CONTEXT(1): - if (read_negTokenTarg(asn1, &token->negTokenTarg)) { + if (read_negTokenTarg(mem_ctx, asn1, &token->negTokenTarg)) { token->type = SPNEGO_NEG_TOKEN_TARG; } break; diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 7899bd0..595d792 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -1165,7 +1165,7 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, } token = base64_decode_data_blob(buf + 3); - len = read_spnego_data(token, &request); + len = read_spnego_data(talloc_tos(), token, &request); data_blob_free(&token); if (len == -1) { @@ -1646,7 +1646,7 @@ static void manage_gss_spnego_client_request(struct ntlm_auth_state *state, /* So we got a server challenge to generate a SPNEGO client-to-server request... */ - len = read_spnego_data(request, &spnego); + len = read_spnego_data(talloc_tos(), request, &spnego); data_blob_free(&request); if (len == -1) { -- 1.6.2.5 From f97309881c0e3c495549351aae62cb3357e60440 Mon Sep 17 00:00:00 2001 From: =?utf-8?q?G=C3=BCnther=20Deschner?= Date: Thu, 15 Oct 2009 16:01:36 +0200 Subject: [PATCH 2/2] s3-spnego: Fix Bug #6815. Windows 2008 R2 SPNEGO negTokenTarg parsing failure. When parsing a SPNEGO session setup retry (falling back from KRB5 to NTLMSSP), we failed to parse the ASN1_ENUMERATED negResult in the negTokenTarg, thus failing spnego_parse_auth() completely. Guenther --- source3/Makefile.in | 2 +- source3/libsmb/clispnego.c | 35 ++++++++++++++++------------------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/source3/Makefile.in b/source3/Makefile.in index 97b86fc..823c3cb 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -465,7 +465,7 @@ LIBCLI_LDAP_NDR_OBJ = ../libcli/ldap/ldap_ndr.o CLDAP_OBJ = libads/cldap.o $(LIBCLI_LDAP_MESSAGE_OBJ) $(LIBCLI_LDAP_NDR_OBJ) LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \ - libsmb/clikrb5.o libsmb/clispnego.o ../lib/util/asn1.o \ + libsmb/clikrb5.o libsmb/clispnego.o libsmb/spnego.o ../lib/util/asn1.o \ libsmb/clirap.o libsmb/clierror.o libsmb/climessage.o \ libsmb/clireadwrite.o libsmb/clilist.o libsmb/cliprint.o \ libsmb/clitrans.o libsmb/clisecdesc.o libsmb/clidgram.o \ diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index fb95d71..b531c39 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -494,31 +494,28 @@ DATA_BLOB spnego_gen_auth(DATA_BLOB blob) */ bool spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) { - ASN1_DATA *data; + SPNEGO_DATA token; + ssize_t len; - data = asn1_init(talloc_tos()); - if (data == NULL) { + len = read_spnego_data(talloc_tos(), blob, &token); + if (len == -1) { + DEBUG(3,("spnego_parse_auth: read_spnego_data failed\n")); return false; } - asn1_load(data, blob); - asn1_start_tag(data, ASN1_CONTEXT(1)); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - asn1_start_tag(data, ASN1_CONTEXT(2)); - asn1_read_OctetString(data, NULL, auth); - asn1_end_tag(data); - asn1_end_tag(data); - asn1_end_tag(data); - - if (data->has_error) { - DEBUG(3,("spnego_parse_auth failed at %d\n", (int)data->ofs)); - data_blob_free(auth); - asn1_free(data); - return False; + if (token.type != SPNEGO_NEG_TOKEN_TARG) { + DEBUG(3,("spnego_parse_auth: wrong token type: %d\n", + token.type)); + free_spnego_data(&token); + return false; } - asn1_free(data); - return True; + *auth = data_blob_talloc(talloc_tos(), + token.negTokenTarg.responseToken.data, + token.negTokenTarg.responseToken.length); + free_spnego_data(&token); + + return true; } /* -- 1.6.2.5