diff options
author | Stefan Metzmacher <metze@samba.org> | 2015-06-23 12:32:34 +0200 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2015-06-24 04:00:43 +0200 |
commit | fa4f4fed2ea20166f48fc40b895ef57aa608ace9 (patch) | |
tree | 0b42753c654f88fc08584fe48e0282c85a0f5246 /source4/auth | |
parent | f643677d3fe62978b6ca7f1da9ec8b1e450b7bcb (diff) | |
download | samba-fa4f4fed2ea20166f48fc40b895ef57aa608ace9.tar.gz |
s4:gensec/gssapi: make use of add gssapi_get_sig_size() and gssapi_{seal,unseal,sign,check}_packet() helper functions
This way are able to support GENSEC_FEATURE_SIGN_PKT_HEADER also together with
GENSEC_FEATURE_SEAL.
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Autobuild-User(master): Andrew Bartlett <abartlet@samba.org>
Autobuild-Date(master): Wed Jun 24 04:00:43 CEST 2015 on sn-devel-104
Diffstat (limited to 'source4/auth')
-rw-r--r-- | source4/auth/gensec/gensec_gssapi.c | 284 | ||||
-rw-r--r-- | source4/auth/gensec/gensec_gssapi.h | 1 |
2 files changed, 71 insertions, 214 deletions
diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index c010f7c1c32..899dcfd1453 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -54,6 +54,7 @@ _PUBLIC_ NTSTATUS gensec_gssapi_init(void); static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security); static size_t gensec_gssapi_max_wrapped_size(struct gensec_security *gensec_security); +static size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, size_t data_size); static int gensec_gssapi_destructor(struct gensec_gssapi_state *gensec_gssapi_state) { @@ -79,44 +80,9 @@ static int gensec_gssapi_destructor(struct gensec_gssapi_state *gensec_gssapi_st &gensec_gssapi_state->client_name); } - if (gensec_gssapi_state->lucid) { - gss_krb5_free_lucid_sec_context(&min_stat, gensec_gssapi_state->lucid); - } - return 0; } -static NTSTATUS gensec_gssapi_init_lucid(struct gensec_gssapi_state *gensec_gssapi_state) -{ - OM_uint32 maj_stat, min_stat; - - if (gensec_gssapi_state->lucid) { - return NT_STATUS_OK; - } - - maj_stat = gss_krb5_export_lucid_sec_context(&min_stat, - &gensec_gssapi_state->gssapi_context, - 1, - (void **)&gensec_gssapi_state->lucid); - if (maj_stat != GSS_S_COMPLETE) { - DEBUG(0,("gensec_gssapi_init_lucid: %s\n", - gssapi_error_string(gensec_gssapi_state, - maj_stat, min_stat, - gensec_gssapi_state->gss_oid))); - return NT_STATUS_INTERNAL_ERROR; - } - - if (gensec_gssapi_state->lucid->version != 1) { - DEBUG(0,("gensec_gssapi_init_lucid: lucid version[%d] != 1\n", - gensec_gssapi_state->lucid->version)); - gss_krb5_free_lucid_sec_context(&min_stat, gensec_gssapi_state->lucid); - gensec_gssapi_state->lucid = NULL; - return NT_STATUS_INTERNAL_ERROR; - } - - return NT_STATUS_OK; -} - static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) { struct gensec_gssapi_state *gensec_gssapi_state; @@ -194,8 +160,6 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->client_cred = NULL; gensec_gssapi_state->server_cred = NULL; - gensec_gssapi_state->lucid = NULL; - gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL; gensec_gssapi_state->sasl = false; @@ -1033,53 +997,30 @@ static NTSTATUS gensec_gssapi_seal_packet(struct gensec_security *gensec_securit { struct gensec_gssapi_state *gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); - OM_uint32 maj_stat, min_stat; - gss_buffer_desc input_token, output_token; - int conf_state; - ssize_t sig_length; + bool hdr_signing = false; + size_t sig_size = 0; + NTSTATUS status; if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) { - DEBUG(1, ("gensec_gssapi_seal_packet: " - "GENSEC_FEATURE_SIGN_PKT_HEADER not supported\n")); - return NT_STATUS_ACCESS_DENIED; + hdr_signing = true; } - input_token.length = length; - input_token.value = data; - - maj_stat = gss_wrap(&min_stat, - gensec_gssapi_state->gssapi_context, - gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL), - GSS_C_QOP_DEFAULT, - &input_token, - &conf_state, - &output_token); - if (GSS_ERROR(maj_stat)) { - DEBUG(1, ("gensec_gssapi_seal_packet: GSS Wrap failed: %s\n", - gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); - return NT_STATUS_ACCESS_DENIED; - } + sig_size = gensec_gssapi_sig_size(gensec_security, length); - if (output_token.length < input_token.length) { - DEBUG(1, ("gensec_gssapi_seal_packet: GSS Wrap length [%ld] *less* than caller length [%ld]\n", - (long)output_token.length, (long)length)); - return NT_STATUS_INTERNAL_ERROR; + status = gssapi_seal_packet(gensec_gssapi_state->gssapi_context, + gensec_gssapi_state->gss_oid, + hdr_signing, sig_size, + data, length, + whole_pdu, pdu_length, + mem_ctx, sig); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("gssapi_seal_packet(hdr_signing=%u,sig_size=%ju," + "data=%ju,pdu=%ju) failed: %s\n", + hdr_signing, sig_size, length, pdu_length, + nt_errstr(status))); + return status; } - sig_length = output_token.length - input_token.length; - - memcpy(data, ((uint8_t *)output_token.value) + sig_length, length); - *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, sig_length); - - dump_data_pw("gensec_gssapi_seal_packet: sig\n", sig->data, sig->length); - dump_data_pw("gensec_gssapi_seal_packet: clear\n", data, length); - dump_data_pw("gensec_gssapi_seal_packet: sealed\n", ((uint8_t *)output_token.value) + sig_length, output_token.length - sig_length); - - gss_release_buffer(&min_stat, &output_token); - if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) - && !conf_state) { - return NT_STATUS_ACCESS_DENIED; - } return NT_STATUS_OK; } @@ -1090,55 +1031,27 @@ static NTSTATUS gensec_gssapi_unseal_packet(struct gensec_security *gensec_secur { struct gensec_gssapi_state *gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); - OM_uint32 maj_stat, min_stat; - gss_buffer_desc input_token, output_token; - int conf_state; - gss_qop_t qop_state; - DATA_BLOB in; - - dump_data_pw("gensec_gssapi_unseal_packet: sig\n", sig->data, sig->length); + bool hdr_signing = false; + NTSTATUS status; if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) { - DEBUG(1, ("gensec_gssapi_unseal_packet: " - "GENSEC_FEATURE_SIGN_PKT_HEADER not supported\n")); - return NT_STATUS_ACCESS_DENIED; - } - - in = data_blob_talloc(gensec_security, NULL, sig->length + length); - - memcpy(in.data, sig->data, sig->length); - memcpy(in.data + sig->length, data, length); - - input_token.length = in.length; - input_token.value = in.data; - - maj_stat = gss_unwrap(&min_stat, - gensec_gssapi_state->gssapi_context, - &input_token, - &output_token, - &conf_state, - &qop_state); - talloc_free(in.data); - if (GSS_ERROR(maj_stat)) { - char *error_string = gssapi_error_string(NULL, maj_stat, min_stat, gensec_gssapi_state->gss_oid); - DEBUG(1, ("gensec_gssapi_unseal_packet: GSS UnWrap failed: %s\n", - error_string)); - talloc_free(error_string); - return NT_STATUS_ACCESS_DENIED; + hdr_signing = true; } - if (output_token.length != length) { - return NT_STATUS_INTERNAL_ERROR; + status = gssapi_unseal_packet(gensec_gssapi_state->gssapi_context, + gensec_gssapi_state->gss_oid, + hdr_signing, + data, length, + whole_pdu, pdu_length, + sig); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("gssapi_unseal_packet(hdr_signing=%u,sig_size=%ju," + "data=%ju,pdu=%ju) failed: %s\n", + hdr_signing, sig->length, length, pdu_length, + nt_errstr(status))); + return status; } - memcpy(data, output_token.value, length); - - gss_release_buffer(&min_stat, &output_token); - - if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) - && !conf_state) { - return NT_STATUS_ACCESS_DENIED; - } return NT_STATUS_OK; } @@ -1150,34 +1063,27 @@ static NTSTATUS gensec_gssapi_sign_packet(struct gensec_security *gensec_securit { struct gensec_gssapi_state *gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); - OM_uint32 maj_stat, min_stat; - gss_buffer_desc input_token, output_token; + bool hdr_signing = false; + NTSTATUS status; if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) { - input_token.length = pdu_length; - input_token.value = discard_const_p(uint8_t *, whole_pdu); - } else { - input_token.length = length; - input_token.value = discard_const_p(uint8_t *, data); + hdr_signing = true; } - maj_stat = gss_get_mic(&min_stat, - gensec_gssapi_state->gssapi_context, - GSS_C_QOP_DEFAULT, - &input_token, - &output_token); - if (GSS_ERROR(maj_stat)) { - DEBUG(1, ("GSS GetMic failed: %s\n", - gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); - return NT_STATUS_ACCESS_DENIED; + status = gssapi_sign_packet(gensec_gssapi_state->gssapi_context, + gensec_gssapi_state->gss_oid, + hdr_signing, + data, length, + whole_pdu, pdu_length, + mem_ctx, sig); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("gssapi_sign_packet(hdr_signing=%u," + "data=%ju,pdu=%ju) failed: %s\n", + hdr_signing, length, pdu_length, + nt_errstr(status))); + return status; } - *sig = data_blob_talloc(mem_ctx, (uint8_t *)output_token.value, output_token.length); - - dump_data_pw("gensec_gssapi_sign_packet: sig\n", sig->data, sig->length); - - gss_release_buffer(&min_stat, &output_token); - return NT_STATUS_OK; } @@ -1188,35 +1094,25 @@ static NTSTATUS gensec_gssapi_check_packet(struct gensec_security *gensec_securi { struct gensec_gssapi_state *gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); - OM_uint32 maj_stat, min_stat; - gss_buffer_desc input_token; - gss_buffer_desc input_message; - gss_qop_t qop_state; - - dump_data_pw("gensec_gssapi_check_packet: sig\n", sig->data, sig->length); + bool hdr_signing = false; + NTSTATUS status; if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) { - input_message.length = pdu_length; - input_message.value = discard_const(whole_pdu); - } else { - input_message.length = length; - input_message.value = discard_const(data); + hdr_signing = true; } - input_token.length = sig->length; - input_token.value = sig->data; - - maj_stat = gss_verify_mic(&min_stat, - gensec_gssapi_state->gssapi_context, - &input_message, - &input_token, - &qop_state); - if (GSS_ERROR(maj_stat)) { - char *error_string = gssapi_error_string(NULL, maj_stat, min_stat, gensec_gssapi_state->gss_oid); - DEBUG(1, ("GSS VerifyMic failed: %s\n", error_string)); - talloc_free(error_string); - - return NT_STATUS_ACCESS_DENIED; + status = gssapi_check_packet(gensec_gssapi_state->gssapi_context, + gensec_gssapi_state->gss_oid, + hdr_signing, + data, length, + whole_pdu, pdu_length, + sig); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("gssapi_check_packet(hdr_signing=%u,sig_size=%ju," + "data=%ju,pdu=%ju) failed: %s\n", + hdr_signing, sig->length, length, pdu_length, + nt_errstr(status))); + return status; } return NT_STATUS_OK; @@ -1299,8 +1195,7 @@ static bool gensec_gssapi_have_feature(struct gensec_security *gensec_security, } if (feature & GENSEC_FEATURE_SIGN_PKT_HEADER) { if (gensec_security->want_features & GENSEC_FEATURE_SEAL) { - /* TODO: implement this using gss_wrap_iov() */ - return false; + return true; } if (gensec_security->want_features & GENSEC_FEATURE_SIGN) { @@ -1452,55 +1347,18 @@ static size_t gensec_gssapi_sig_size(struct gensec_security *gensec_security, si { struct gensec_gssapi_state *gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); - NTSTATUS status; + size_t sig_size; - if (gensec_gssapi_state->sig_size) { + if (gensec_gssapi_state->sig_size > 0) { return gensec_gssapi_state->sig_size; } - if (gensec_gssapi_state->gss_got_flags & GSS_C_CONF_FLAG) { - gensec_gssapi_state->sig_size = 45; - } else { - gensec_gssapi_state->sig_size = 37; - } - - status = gensec_gssapi_init_lucid(gensec_gssapi_state); - if (!NT_STATUS_IS_OK(status)) { - return gensec_gssapi_state->sig_size; - } - - if (gensec_gssapi_state->lucid->protocol == 1) { - if (gensec_gssapi_state->gss_got_flags & GSS_C_CONF_FLAG) { - gensec_gssapi_state->sig_size = 60; - if (gensec_gssapi_state->gss_got_flags & GSS_C_DCE_STYLE) { - gensec_gssapi_state->sig_size += 16; - } - } else { - gensec_gssapi_state->sig_size = 28; - } - } else if (gensec_gssapi_state->lucid->protocol == 0) { - switch (gensec_gssapi_state->lucid->rfc1964_kd.ctx_key.type) { - case ENCTYPE_DES_CBC_CRC: - case ENCTYPE_ARCFOUR_HMAC: - case ENCTYPE_ARCFOUR_HMAC_EXP: - if (gensec_gssapi_state->gss_got_flags & GSS_C_CONF_FLAG) { - gensec_gssapi_state->sig_size = 45; - } else { - gensec_gssapi_state->sig_size = 37; - } - break; -#ifdef SAMBA4_USES_HEIMDAL - case ENCTYPE_OLD_DES3_CBC_SHA1: - if (gensec_gssapi_state->gss_got_flags & GSS_C_CONF_FLAG) { - gensec_gssapi_state->sig_size = 57; - } else { - gensec_gssapi_state->sig_size = 49; - } - break; -#endif - } - } + sig_size = gssapi_get_sig_size(gensec_gssapi_state->gssapi_context, + gensec_gssapi_state->gss_oid, + gensec_gssapi_state->gss_want_flags, + data_size); + gensec_gssapi_state->sig_size = sig_size; return gensec_gssapi_state->sig_size; } diff --git a/source4/auth/gensec/gensec_gssapi.h b/source4/auth/gensec/gensec_gssapi.h index b7429b5f48d..cf0e3a8d914 100644 --- a/source4/auth/gensec/gensec_gssapi.h +++ b/source4/auth/gensec/gensec_gssapi.h @@ -46,7 +46,6 @@ struct gensec_gssapi_state { NTTIME expire_time; /* gensec_gssapi only */ - gss_krb5_lucid_context_v1_t *lucid; gss_OID gss_oid; struct gss_channel_bindings_struct *input_chan_bindings; |