summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2005-06-28 08:27:50 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:18:55 -0500
commit99777452f0d191461bf7b92397bb44378cdb4cfb (patch)
treef75b9bf8292ed9f9e2634d177ef1e6ba24d0a19f
parent8dde165d0f95858a73f4b000196f5a43caeb3526 (diff)
downloadsamba-99777452f0d191461bf7b92397bb44378cdb4cfb.tar.gz
samba-99777452f0d191461bf7b92397bb44378cdb4cfb.tar.bz2
samba-99777452f0d191461bf7b92397bb44378cdb4cfb.zip
r7978: 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 (This used to be commit 6f0e1c80ae7b1e31e7a3fbff84f07442ee5a31cf)
-rw-r--r--source4/auth/gensec/gensec_gssapi.c10
-rw-r--r--source4/auth/kerberos/kerberos.h8
-rw-r--r--source4/auth/kerberos/kerberos_pac.c77
3 files changed, 43 insertions, 52 deletions
diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
index a95805f9fa..2b7c4ca2cc 100644
--- a/source4/auth/gensec/gensec_gssapi.c
+++ b/source4/auth/gensec/gensec_gssapi.c
@@ -737,6 +737,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
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 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
}
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 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
/* 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;
diff --git a/source4/auth/kerberos/kerberos.h b/source4/auth/kerberos/kerberos.h
index 0f8fd28155..ca0bbbed0e 100644
--- a/source4/auth/kerberos/kerberos.h
+++ b/source4/auth/kerberos/kerberos.h
@@ -101,6 +101,9 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx,
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 @@ NTSTATUS create_memory_keytab(TALLOC_CTX *parent_ctx,
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 */
diff --git a/source4/auth/kerberos/kerberos_pac.c b/source4/auth/kerberos/kerberos_pac.c
index 8f3d2cd72c..84a7c56cc9 100644
--- a/source4/auth/kerberos/kerberos_pac.c
+++ b/source4/auth/kerberos/kerberos_pac.c
@@ -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 @@ static NTSTATUS kerberos_pac_checksum(DATA_BLOB pac_data,
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 @@ static NTSTATUS kerberos_pac_checksum(DATA_BLOB pac_data,
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 @@ static NTSTATUS kerberos_pac_checksum(DATA_BLOB pac_data,
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 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx,
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);*/
-
- /* verify by kdc_key */
- status = kerberos_pac_checksum(tmp_blob, &kdc_sig, smb_krb5_context, 0);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
+ memset(&modified_pac_blob.data[modified_pac_blob.length - 48],
+ '\0', 48);
- /* 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 @@ NTSTATUS kerberos_decode_pac(TALLOC_CTX *mem_ctx,
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));