s3: Correctly unwrap the krb ticket in gss-spnego (cherry picked from commit 547b268c...
authorStefan Metzmacher <metze@samba.org>
Tue, 30 Nov 2010 09:52:52 +0000 (10:52 +0100)
committerKarolin Seeger <kseeger@samba.org>
Sat, 5 Mar 2011 13:34:42 +0000 (14:34 +0100)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
renamed to _spnego_parse_krb5_wrap()

metze
(cherry picked from commit 7cb3d84fc11490c97d7d84a3231e2d9f6b2d69fe)

source3/utils/ntlm_auth.c

index 835c22741763c8ae7677ac2ea409d75501dba376..4384946b880512be9b97ae78f1160318031c6e82 100644 (file)
@@ -1193,6 +1193,45 @@ static void offer_gss_spnego_mechs(void) {
        return;
 }
 
+static bool _spnego_parse_krb5_wrap(TALLOC_CTX *ctx, DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2])
+{
+       bool ret;
+       ASN1_DATA *data;
+       int data_remaining;
+
+       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_KERBEROS5);
+
+       data_remaining = asn1_tag_remaining(data);
+
+       if (data_remaining < 3) {
+               data->has_error = True;
+       } else {
+               asn1_read(data, tok_id, 2);
+               data_remaining -= 2;
+               *ticket = data_blob_talloc(ctx, NULL, data_remaining);
+               asn1_read(data, ticket->data, ticket->length);
+       }
+
+       asn1_end_tag(data);
+
+       ret = !data->has_error;
+
+       if (data->has_error) {
+               data_blob_free(ticket);
+       }
+
+       asn1_free(data);
+
+       return ret;
+}
+
 static void manage_gss_spnego_request(struct ntlm_auth_state *state,
                                        char *buf, int length)
 {
@@ -1338,6 +1377,8 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state,
                        DATA_BLOB ap_rep;
                        DATA_BLOB session_key;
                        struct PAC_DATA *pac_data = NULL;
+                       DATA_BLOB ticket;
+                       uint8_t tok_id[2];
 
                        if ( request.negTokenInit.mechToken.data == NULL ) {
                                DEBUG(1, ("Client did not provide Kerberos data\n"));
@@ -1346,13 +1387,23 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state,
                                return;
                        }
 
+                       dump_data(10, request.negTokenInit.mechToken.data,
+                                 request.negTokenInit.mechToken.length);
+
+                       if (!_spnego_parse_krb5_wrap(ctx, request.negTokenInit.mechToken,
+                                                   &ticket, tok_id)) {
+                               DEBUG(1, ("spnego_parse_krb5_wrap failed\n"));
+                               x_fprintf(x_stdout, "BH spnego_parse_krb5_wrap failed\n");
+                               return;
+                       }
+
                        response.type = SPNEGO_NEG_TOKEN_TARG;
                        response.negTokenTarg.supportedMech = talloc_strdup(ctx, OID_KERBEROS5_OLD);
                        response.negTokenTarg.mechListMIC = data_blob_talloc(ctx, NULL, 0);
                        response.negTokenTarg.responseToken = data_blob_talloc(ctx, NULL, 0);
 
                        status = ads_verify_ticket(mem_ctx, lp_realm(), 0,
-                                                  &request.negTokenInit.mechToken,
+                                                  &ticket,
                                                   &principal, &pac_data, &ap_rep,
                                                   &session_key, True);