summaryrefslogtreecommitdiff
path: root/source4/auth
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2005-07-09 01:58:38 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:19:25 -0500
commitc0a78453a77fb0aa42d676635778a75204b6869c (patch)
treeb8e6aee36941ffafe9858dbfbcebd93ab33e0f56 /source4/auth
parent37cf22a39eec62a62d5ad30d9419ce4e159dff31 (diff)
downloadsamba-c0a78453a77fb0aa42d676635778a75204b6869c.tar.gz
samba-c0a78453a77fb0aa42d676635778a75204b6869c.tar.bz2
samba-c0a78453a77fb0aa42d676635778a75204b6869c.zip
r8250: More PAC work. We now sucessfully verify the KDC signature from my DC
(I have included the krbtgt key from my test network). It turns out the krbtgt signature is over the 16 (or whatever, enc-type dependent) bytes of the signature, not the entire structure. Also do not even try to use Kerberos or GSSAPI on an IP address, it will only fail. Andrew Bartlett (This used to be commit 3b9558e82fdebb58f240d43f6a594d676eb04daf)
Diffstat (limited to 'source4/auth')
-rw-r--r--source4/auth/gensec/gensec_gssapi.c14
-rw-r--r--source4/auth/gensec/gensec_krb5.c10
-rw-r--r--source4/auth/kerberos/kerberos.h3
-rw-r--r--source4/auth/kerberos/kerberos_pac.c53
4 files changed, 54 insertions, 26 deletions
diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
index 2b7c4ca2cc..e6049edc58 100644
--- a/source4/auth/gensec/gensec_gssapi.c
+++ b/source4/auth/gensec/gensec_gssapi.c
@@ -228,6 +228,16 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
NTSTATUS nt_status;
gss_buffer_desc name_token;
OM_uint32 maj_stat, min_stat;
+ const char *hostname = gensec_get_target_hostname(gensec_security);
+
+ if (!hostname) {
+ DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ if (is_ipaddress(hostname)) {
+ DEBUG(2, ("Cannot do GSSAPI to a IP address"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
nt_status = gensec_gssapi_start(gensec_security);
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -238,7 +248,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
name_token.value = talloc_asprintf(gensec_gssapi_state, "%s@%s",
gensec_get_target_service(gensec_security),
- gensec_get_target_hostname(gensec_security));
+ hostname);
name_token.length = strlen(name_token.value);
maj_stat = gss_import_name (&min_stat,
@@ -786,7 +796,7 @@ 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,
- keyblock);
+ NULL, keyblock);
if (NT_STATUS_IS_OK(nt_status)) {
union netr_Validation validation;
diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c
index 69dae1c8d9..168b6df364 100644
--- a/source4/auth/gensec/gensec_krb5.c
+++ b/source4/auth/gensec/gensec_krb5.c
@@ -138,8 +138,13 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security
const char *hostname = gensec_get_target_hostname(gensec_security);
if (!hostname) {
DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n"));
- return NT_STATUS_ACCESS_DENIED;
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ if (is_ipaddress(hostname)) {
+ DEBUG(2, ("Cannot do GSSAPI to a IP address"));
+ return NT_STATUS_INVALID_PARAMETER;
}
+
nt_status = gensec_krb5_start(gensec_security);
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -444,7 +449,8 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security
/* decode and verify the pac */
nt_status = kerberos_decode_pac(gensec_krb5_state, &logon_info, gensec_krb5_state->pac,
- gensec_krb5_state->smb_krb5_context, (gensec_krb5_state->keyblock));
+ gensec_krb5_state->smb_krb5_context,
+ NULL, gensec_krb5_state->keyblock);
/* IF we have the PAC - otherwise we need to get this
* data from elsewere - local ldb, or (TODO) lookup of some
diff --git a/source4/auth/kerberos/kerberos.h b/source4/auth/kerberos/kerberos.h
index a7c370a1e5..c5b361df5e 100644
--- a/source4/auth/kerberos/kerberos.h
+++ b/source4/auth/kerberos/kerberos.h
@@ -131,7 +131,8 @@ 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);
+ krb5_keyblock *service_keyblock,
+ krb5_keyblock *krbtgt_keyblock);
krb5_error_code kerberos_encode_pac(TALLOC_CTX *mem_ctx,
struct auth_serversupplied_info *server_info,
diff --git a/source4/auth/kerberos/kerberos_pac.c b/source4/auth/kerberos/kerberos_pac.c
index b0844187e5..858f91045c 100644
--- a/source4/auth/kerberos/kerberos_pac.c
+++ b/source4/auth/kerberos/kerberos_pac.c
@@ -53,7 +53,8 @@ static NTSTATUS check_pac_checksum(TALLOC_CTX *mem_ctx,
0,
&crypto);
if (ret) {
- DEBUG(0,("krb5_crypto_init() failed\n"));
+ DEBUG(0,("krb5_crypto_init() failed: %s\n",
+ smb_get_krb5_error_message(context, ret, mem_ctx)));
return NT_STATUS_FOOBAR;
}
ret = krb5_verify_checksum(context,
@@ -77,10 +78,11 @@ static NTSTATUS check_pac_checksum(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,
- krb5_keyblock *keyblock)
+ struct PAC_LOGON_INFO **logon_info_out,
+ DATA_BLOB blob,
+ struct smb_krb5_context *smb_krb5_context,
+ krb5_keyblock *krbtgt_keyblock,
+ krb5_keyblock *service_keyblock)
{
NTSTATUS status;
struct PAC_SIGNATURE_DATA srv_sig;
@@ -159,11 +161,26 @@ static NTSTATUS check_pac_checksum(TALLOC_CTX *mem_ctx,
/* verify by service_key */
status = check_pac_checksum(mem_ctx,
modified_pac_blob, &srv_sig,
- smb_krb5_context->krb5_context, keyblock);
-
+ smb_krb5_context->krb5_context,
+ service_keyblock);
if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("PAC Decode: Failed to verify the service signature\n"));
return status;
}
+
+ if (krbtgt_keyblock) {
+ DATA_BLOB service_checksum_blob
+ = data_blob(srv_sig_ptr->signature, sizeof(srv_sig_ptr->signature));
+
+ status = check_pac_checksum(mem_ctx,
+ service_checksum_blob, &kdc_sig,
+ smb_krb5_context->krb5_context, krbtgt_keyblock);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("PAC Decode: Failed to verify the krbtgt signature\n"));
+ return status;
+ }
+ }
+
DEBUG(0,("account_name: %s [%s]\n",
logon_info->info3.base.account_name.string,
logon_info->info3.base.full_name.string));
@@ -221,13 +238,13 @@ static krb5_error_code make_pac_checksum(TALLOC_CTX *mem_ctx,
struct auth_serversupplied_info *server_info,
krb5_context context,
krb5_keyblock *krbtgt_keyblock,
- krb5_keyblock *server_keyblock,
+ krb5_keyblock *service_keyblock,
DATA_BLOB *pac)
{
NTSTATUS nt_status;
DATA_BLOB zero_blob = data_blob(NULL, 0);
DATA_BLOB tmp_blob = data_blob(NULL, 0);
- DATA_BLOB server_checksum_blob;
+ DATA_BLOB service_checksum_blob;
krb5_error_code ret;
struct PAC_DATA *pac_data = talloc(mem_ctx, struct PAC_DATA);
struct netr_SamInfo3 *sam3;
@@ -335,9 +352,9 @@ static krb5_error_code make_pac_checksum(TALLOC_CTX *mem_ctx,
return ret;
}
- ret = make_pac_checksum(mem_ctx, zero_blob, SRV_CHECKSUM, context, server_keyblock);
+ ret = make_pac_checksum(mem_ctx, zero_blob, SRV_CHECKSUM, context, service_keyblock);
if (ret) {
- DEBUG(2, ("making server PAC checksum failed: %s\n",
+ DEBUG(2, ("making service PAC checksum failed: %s\n",
smb_get_krb5_error_message(context, ret, mem_ctx)));
talloc_free(pac_data);
return ret;
@@ -357,19 +374,13 @@ static krb5_error_code make_pac_checksum(TALLOC_CTX *mem_ctx,
/* Then sign the result of the previous push, where the sig was zero'ed out */
ret = make_pac_checksum(mem_ctx, tmp_blob, SRV_CHECKSUM,
- context, server_keyblock);
+ context, service_keyblock);
- /* Push the Server checksum out */
- nt_status = ndr_push_struct_blob(&server_checksum_blob, mem_ctx, SRV_CHECKSUM,
- (ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA);
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(1, ("PAC_SIGNATURE push failed: %s\n", nt_errstr(nt_status)));
- talloc_free(pac_data);
- return EINVAL;
- }
+ service_checksum_blob
+ = data_blob(SRV_CHECKSUM->signature, sizeof(SRV_CHECKSUM->signature));
/* Then sign Server checksum */
- ret = make_pac_checksum(mem_ctx, server_checksum_blob, KDC_CHECKSUM, context, krbtgt_keyblock);
+ ret = make_pac_checksum(mem_ctx, service_checksum_blob, KDC_CHECKSUM, context, krbtgt_keyblock);
if (ret) {
DEBUG(2, ("making krbtgt PAC checksum failed: %s\n",
smb_get_krb5_error_message(context, ret, mem_ctx)));