diff options
-rw-r--r-- | source3/include/proto.h | 4 | ||||
-rw-r--r-- | source3/libads/sasl.c | 2 | ||||
-rw-r--r-- | source3/libsmb/cliconnect.c | 2 | ||||
-rw-r--r-- | source3/libsmb/clispnego.c | 98 | ||||
-rw-r--r-- | source3/rpc_server/srv_pipe.c | 2 | ||||
-rw-r--r-- | source3/smbd/sesssetup.c | 2 |
6 files changed, 30 insertions, 80 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index d9f9ab96d4..ad0c11fc9f 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2827,9 +2827,9 @@ DATA_BLOB spnego_gen_negTokenInit(char guid[16], DATA_BLOB gen_negTokenInit(const char *OID, DATA_BLOB blob); bool spnego_parse_negTokenInit(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], - char **principal); + char **principal, + DATA_BLOB *secblob); DATA_BLOB gen_negTokenTarg(const char *OIDs[], DATA_BLOB blob); -bool parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *secblob); DATA_BLOB spnego_gen_krb5_wrap(const DATA_BLOB ticket, const uint8 tok_id[2]); bool spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]); int spnego_gen_negTokenTarg(const char *principal, int time_offset, diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index a37d1e8474..aa3acbd9ae 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -779,7 +779,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) /* the server sent us the first part of the SPNEGO exchange in the negprot reply */ - if (!spnego_parse_negTokenInit(blob, OIDs, &given_principal)) { + if (!spnego_parse_negTokenInit(blob, OIDs, &given_principal, NULL)) { data_blob_free(&blob); status = ADS_ERROR(LDAP_OPERATIONS_ERROR); goto failed; diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 8d4c1901c1..7fe359b9ae 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1224,7 +1224,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, * negprot reply. It is WRONG to depend on the principal sent in the * negprot reply, but right now we do it. If we don't receive one, * we try to best guess, then fall back to NTLM. */ - if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) { + if (!spnego_parse_negTokenInit(blob, OIDs, &principal, NULL)) { data_blob_free(&blob); return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); } diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 09efb560c0..1f2081cb03 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -130,7 +130,8 @@ DATA_BLOB gen_negTokenInit(const char *OID, DATA_BLOB blob) */ bool spnego_parse_negTokenInit(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], - char **principal) + char **principal, + DATA_BLOB *secblob) { int i; bool ret; @@ -167,7 +168,12 @@ bool spnego_parse_negTokenInit(DATA_BLOB blob, asn1_end_tag(data); asn1_end_tag(data); - *principal = NULL; + if (principal) { + *principal = NULL; + } + if (secblob) { + *secblob = data_blob_null; + } /* Win7 + Live Sign-in Assistant attaches a mechToken @@ -193,28 +199,33 @@ bool spnego_parse_negTokenInit(DATA_BLOB blob, if (asn1_tag_remaining(data) > 0) { if (asn1_peek_tag(data, ASN1_CONTEXT(2))) { + DATA_BLOB sblob = data_blob_null; /* mechToken [2] OCTET STRING OPTIONAL */ - DATA_BLOB token; asn1_start_tag(data, ASN1_CONTEXT(2)); asn1_read_OctetString(data, talloc_autofree_context(), - &token); + &sblob); asn1_end_tag(data); - /* Throw away the token - not used. */ - data_blob_free(&token); + if (secblob) { + *secblob = sblob; + } } } if (asn1_tag_remaining(data) > 0) { if (asn1_peek_tag(data, ASN1_CONTEXT(3))) { + char *princ = NULL; /* mechListMIC [3] OCTET STRING OPTIONAL */ asn1_start_tag(data, ASN1_CONTEXT(3)); asn1_start_tag(data, ASN1_SEQUENCE(0)); asn1_start_tag(data, ASN1_CONTEXT(0)); asn1_read_GeneralString(data,talloc_autofree_context(), - principal); + &princ); asn1_end_tag(data); asn1_end_tag(data); asn1_end_tag(data); + if (principal) { + *principal = princ; + } } } @@ -226,7 +237,12 @@ bool spnego_parse_negTokenInit(DATA_BLOB blob, ret = !data->has_error; if (data->has_error) { int j; - TALLOC_FREE(*principal); + if (principal) { + TALLOC_FREE(*principal); + } + if (secblob) { + data_blob_free(secblob); + } for(j = 0; j < i && j < ASN1_MAX_OIDS-1; j++) { TALLOC_FREE(OIDs[j]); } @@ -283,72 +299,6 @@ DATA_BLOB gen_negTokenTarg(const char *OIDs[], DATA_BLOB blob) } /* - parse a negTokenTarg packet giving a list of OIDs and a security blob -*/ -bool parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *secblob) -{ - int i; - ASN1_DATA *data; - - data = asn1_init(talloc_tos()); - if (data == NULL) { - return false; - } - - asn1_load(data, blob); - asn1_start_tag(data, ASN1_APPLICATION(0)); - asn1_check_OID(data,OID_SPNEGO); - asn1_start_tag(data, ASN1_CONTEXT(0)); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - - asn1_start_tag(data, ASN1_CONTEXT(0)); - asn1_start_tag(data, ASN1_SEQUENCE(0)); - for (i=0; asn1_tag_remaining(data) > 0 && i < ASN1_MAX_OIDS-1; i++) { - const char *oid_str = NULL; - asn1_read_OID(data,talloc_autofree_context(),&oid_str); - OIDs[i] = CONST_DISCARD(char *, oid_str); - } - OIDs[i] = NULL; - asn1_end_tag(data); - asn1_end_tag(data); - - /* Skip any optional req_flags that are sent per RFC 4178 */ - if (asn1_peek_tag(data, ASN1_CONTEXT(1))) { - uint8 flags; - - asn1_start_tag(data, ASN1_CONTEXT(1)); - asn1_start_tag(data, ASN1_BIT_STRING); - while (asn1_tag_remaining(data) > 0) - asn1_read_uint8(data, &flags); - asn1_end_tag(data); - asn1_end_tag(data); - } - - asn1_start_tag(data, ASN1_CONTEXT(2)); - asn1_read_OctetString(data,talloc_autofree_context(),secblob); - asn1_end_tag(data); - - asn1_end_tag(data); - asn1_end_tag(data); - - asn1_end_tag(data); - - if (data->has_error) { - int j; - data_blob_free(secblob); - for(j = 0; j < i && j < ASN1_MAX_OIDS-1; j++) { - TALLOC_FREE(OIDs[j]); - } - DEBUG(1,("Failed to parse negTokenTarg at offset %d\n", (int)data->ofs)); - asn1_free(data); - return False; - } - - asn1_free(data); - return True; -} - -/* generate a krb5 GSS-API wrapper packet given a ticket */ DATA_BLOB spnego_gen_krb5_wrap(const DATA_BLOB ticket, const uint8 tok_id[2]) diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index a56a6345cc..2a995b318b 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -826,7 +826,7 @@ static bool pipe_spnego_auth_bind_negotiate(pipes_struct *p, } /* parse out the OIDs and the first sec blob */ - if (!parse_negTokenTarg(pauth_info->credentials, OIDs, &secblob)) { + if (!spnego_parse_negTokenInit(pauth_info->credentials, OIDs, NULL, &secblob)) { DEBUG(0,("pipe_spnego_auth_bind_negotiate: Failed to parse the security blob.\n")); goto err; } diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 27eb4f6c48..08119b2be1 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -732,7 +732,7 @@ NTSTATUS parse_spnego_mechanisms(DATA_BLOB blob_in, *kerb_mechOID = NULL; /* parse out the OIDs and the first sec blob */ - if (!parse_negTokenTarg(blob_in, OIDs, pblob_out)) { + if (!spnego_parse_negTokenInit(blob_in, OIDs, NULL, pblob_out)) { return NT_STATUS_LOGON_FAILURE; } |