Author: abartlet Date: 2005-06-28 08:27:50 +0000 (Tue, 28 Jun 2005) New Revision: 7978
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=7978 Log: A start again on PAC verification. I have noticed that the kerberos keys appear at the end of the PAC, which I feel is deliberate (it makes this much easier). I still can't make it work, but I'm sure we are closer. Andrew Bartlett Modified: branches/SAMBA_4_0/source/auth/gensec/gensec_gssapi.c branches/SAMBA_4_0/source/auth/kerberos/kerberos.h branches/SAMBA_4_0/source/auth/kerberos/kerberos_pac.c Changeset: Modified: branches/SAMBA_4_0/source/auth/gensec/gensec_gssapi.c =================================================================== --- branches/SAMBA_4_0/source/auth/gensec/gensec_gssapi.c 2005-06-28 02:49:35 UTC (rev 7977) +++ branches/SAMBA_4_0/source/auth/gensec/gensec_gssapi.c 2005-06-28 08:27:50 UTC (rev 7978) @@ -737,6 +737,7 @@ OM_uint32 maj_stat, min_stat; gss_buffer_desc name_token; gss_buffer_desc pac; + krb5_keyblock *keyblock; mem_ctx = talloc_named(gensec_gssapi_state, 0, "gensec_gssapi_session_info context"); NT_STATUS_HAVE_NO_MEMORY(mem_ctx); @@ -768,9 +769,13 @@ } account_name = principal; + maj_stat = gss_krb5_copy_service_keyblock(&min_stat, + gensec_gssapi_state->gssapi_context, + &keyblock); + maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat, gensec_gssapi_state->gssapi_context, - 1, + KRB5_AUTHDATA_IF_RELEVANT, &pac); if (maj_stat == 0) { @@ -780,7 +785,8 @@ /* decode and verify the pac */ nt_status = kerberos_decode_pac(mem_ctx, &logon_info, pac_blob, - gensec_gssapi_state->smb_krb5_context); + gensec_gssapi_state->smb_krb5_context, + keyblock); if (NT_STATUS_IS_OK(nt_status)) { union netr_Validation validation; Modified: branches/SAMBA_4_0/source/auth/kerberos/kerberos.h =================================================================== --- branches/SAMBA_4_0/source/auth/kerberos/kerberos.h 2005-06-28 02:49:35 UTC (rev 7977) +++ branches/SAMBA_4_0/source/auth/kerberos/kerberos.h 2005-06-28 08:27:50 UTC (rev 7978) @@ -101,6 +101,9 @@ int kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc, const char *principal, const char *password, time_t *expire_time, time_t *kdc_time); +int kerberos_kinit_keyblock_cc(krb5_context ctx, krb5_ccache cc, + const char *principal, krb5_keyblock *keyblock, + time_t *expire_time, time_t *kdc_time); krb5_principal kerberos_fetch_salt_princ_for_host_princ(krb5_context context, krb5_principal host_princ, int enctype); @@ -124,5 +127,10 @@ struct cli_credentials *machine_account, struct smb_krb5_context *smb_krb5_context, krb5_keytab *keytab); +NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, + struct PAC_LOGON_INFO **logon_info_out, + DATA_BLOB blob, + struct smb_krb5_context *smb_krb5_context, + krb5_keyblock *keyblock); #endif /* HAVE_KRB5 */ Modified: branches/SAMBA_4_0/source/auth/kerberos/kerberos_pac.c =================================================================== --- branches/SAMBA_4_0/source/auth/kerberos/kerberos_pac.c 2005-06-28 02:49:35 UTC (rev 7977) +++ branches/SAMBA_4_0/source/auth/kerberos/kerberos_pac.c 2005-06-28 08:27:50 UTC (rev 7978) @@ -32,11 +32,12 @@ #include "librpc/gen_ndr/ndr_krb5pac.h" #include "auth/auth.h" -#ifdef KRB5_DO_VERIFY_PAC -static NTSTATUS kerberos_pac_checksum(DATA_BLOB pac_data, - struct PAC_SIGNATURE_DATA *sig, - struct smb_krb5_context *smb_krb5_context, - uint32 keyusage) +static NTSTATUS kerberos_pac_checksum(TALLOC_CTX *mem_ctx, + DATA_BLOB pac_data, + struct PAC_SIGNATURE_DATA *sig, + struct smb_krb5_context *smb_krb5_context, + krb5_keyblock *keyblock, + uint32_t keyusage) { krb5_error_code ret; krb5_crypto crypto; @@ -49,9 +50,9 @@ ret = krb5_crypto_init(smb_krb5_context->krb5_context, - &gensec_krb5_state->keyblock, - 0, - &crypto); + keyblock, + 0, + &crypto); if (ret) { DEBUG(0,("krb5_crypto_init() failed\n")); return NT_STATUS_FOOBAR; @@ -65,10 +66,14 @@ pac_data.length, &cksum); if (!ret) { - DEBUG(0,("PAC Verified: keyusage: %d\n", keyusage)); + DEBUG(0, ("PAC Verified: keyusage: %d\n", keyusage)); break; + } else { + DEBUG(2, ("PAC Verification failed: %s\n", + smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx))); } } + krb5_crypto_destroy(smb_krb5_context->krb5_context, crypto); if (ret) { @@ -80,23 +85,22 @@ return NT_STATUS_OK; } -#endif -NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, + NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx, struct PAC_LOGON_INFO **logon_info_out, DATA_BLOB blob, - struct smb_krb5_context *smb_krb5_context) + struct smb_krb5_context *smb_krb5_context, + krb5_keyblock *keyblock) { NTSTATUS status; struct PAC_SIGNATURE_DATA srv_sig; - struct PAC_SIGNATURE_DATA *srv_sig_ptr; + struct PAC_SIGNATURE_DATA *srv_sig_ptr = NULL; struct PAC_SIGNATURE_DATA kdc_sig; - struct PAC_SIGNATURE_DATA *kdc_sig_ptr; + struct PAC_SIGNATURE_DATA *kdc_sig_ptr = NULL; struct PAC_LOGON_INFO *logon_info = NULL; struct PAC_DATA pac_data; -#ifdef KRB5_DO_VERIFY_PAC - DATA_BLOB tmp_blob = data_blob(NULL, 0); -#endif + DATA_BLOB modified_pac_blob = data_blob_talloc(mem_ctx, blob.data, blob.length); + DATA_BLOB tmp_blob; int i; status = ndr_pull_struct_blob(&blob, mem_ctx, &pac_data, @@ -156,39 +160,11 @@ DEBUG(0,("PAC no kdc_key\n")); return NT_STATUS_FOOBAR; } -#ifdef KRB5_DO_VERIFY_PAC - /* clear the kdc_key */ -/* memset((void *)kdc_sig_ptr , '\0', sizeof(*kdc_sig_ptr));*/ - status = ndr_push_struct_blob(&tmp_blob, mem_ctx, &pac_data, - (ndr_push_flags_fn_t)ndr_push_PAC_DATA); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - status = ndr_pull_struct_blob(&tmp_blob, mem_ctx, &pac_data, - (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("can't parse the PAC\n")); - return status; - } - /*NDR_PRINT_DEBUG(PAC_DATA, &pac_data);*/ + memset(&modified_pac_blob.data[modified_pac_blob.length - 48], + '\0', 48); - /* verify by kdc_key */ - status = kerberos_pac_checksum(tmp_blob, &kdc_sig, smb_krb5_context, 0); - - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - /* clear the service_key */ -/* memset((void *)srv_sig_ptr , '\0', sizeof(*srv_sig_ptr));*/ - - status = ndr_push_struct_blob(&tmp_blob, mem_ctx, &pac_data, - (ndr_push_flags_fn_t)ndr_push_PAC_DATA); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - status = ndr_pull_struct_blob(&tmp_blob, mem_ctx, &pac_data, + status = ndr_pull_struct_blob(&modified_pac_blob, mem_ctx, &pac_data, (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("can't parse the PAC\n")); @@ -197,12 +173,13 @@ NDR_PRINT_DEBUG(PAC_DATA, &pac_data); /* verify by servie_key */ - status = kerberos_pac_checksum(tmp_blob, &srv_sig, smb_krb5_context, 0); + status = kerberos_pac_checksum(mem_ctx, + modified_pac_blob, &srv_sig, + smb_krb5_context, keyblock, 0); if (!NT_STATUS_IS_OK(status)) { return status; } -#endif DEBUG(0,("account_name: %s [%s]\n", logon_info->info3.base.account_name.string, logon_info->info3.base.full_name.string));