📄 gensec_gssapi.c
字号:
if (output_token.length < 4) { return NT_STATUS_INVALID_PARAMETER; } memcpy(maxlength_accepted, output_token.value, 4); gss_release_buffer(&min_stat, &output_token); /* first byte is the proposed security */ security_accepted = maxlength_accepted[0]; maxlength_accepted[0] = '\0'; /* Rest is the proposed max wrap length */ gensec_gssapi_state->max_wrap_buf_size = MIN(RIVAL(maxlength_accepted, 0), gensec_gssapi_state->max_wrap_buf_size); gensec_gssapi_state->sasl_protection = 0; if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { if (security_accepted & NEG_SEAL) { gensec_gssapi_state->sasl_protection |= NEG_SEAL; } } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { if (security_accepted & NEG_SIGN) { gensec_gssapi_state->sasl_protection |= NEG_SIGN; } } else if (security_accepted & NEG_NONE) { gensec_gssapi_state->sasl_protection |= NEG_NONE; } else { DEBUG(1, ("Remote client does not support unprotected connections, but we failed to negotiate anything better")); return NT_STATUS_ACCESS_DENIED; } /* quirk: This changes the value that gensec_have_feature returns, to be that after SASL negotiation */ gensec_gssapi_state->sasl_state = STAGE_DONE; if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographicly sealed\n")); } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographicly signed\n")); } else { DEBUG(5, ("SASL/GSSAPI Connection from client will have no cryptographic protection\n")); } *out = data_blob(NULL, 0); return NT_STATUS_OK; } default: return NT_STATUS_INVALID_PARAMETER; }}static NTSTATUS gensec_gssapi_wrap(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, const DATA_BLOB *in, DATA_BLOB *out){ 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; input_token.length = in->length; input_token.value = in->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_wrap: GSS Wrap failed: %s\n", gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return NT_STATUS_ACCESS_DENIED; } *out = data_blob_talloc(mem_ctx, output_token.value, output_token.length); gss_release_buffer(&min_stat, &output_token); if (gensec_gssapi_state->sasl) { size_t max_wrapped_size = gensec_gssapi_max_wrapped_size(gensec_security); if (max_wrapped_size < out->length) { DEBUG(1, ("gensec_gssapi_wrap: when wrapped, INPUT data (%u) is grew to be larger than SASL negotiated maximum output size (%u > %u)\n", (unsigned)in->length, (unsigned)out->length, (unsigned int)max_wrapped_size)); return NT_STATUS_INVALID_PARAMETER; } } if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) && !conf_state) { return NT_STATUS_ACCESS_DENIED; } return NT_STATUS_OK;}static NTSTATUS gensec_gssapi_unwrap(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, const DATA_BLOB *in, DATA_BLOB *out){ 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; input_token.length = in->length; input_token.value = in->data; if (gensec_gssapi_state->sasl) { size_t max_wrapped_size = gensec_gssapi_max_wrapped_size(gensec_security); if (max_wrapped_size < in->length) { DEBUG(1, ("gensec_gssapi_unwrap: WRAPPED data is larger than SASL negotiated maximum size\n")); return NT_STATUS_INVALID_PARAMETER; } } maj_stat = gss_unwrap(&min_stat, gensec_gssapi_state->gssapi_context, &input_token, &output_token, &conf_state, &qop_state); if (GSS_ERROR(maj_stat)) { DEBUG(1, ("gensec_gssapi_unwrap: GSS UnWrap failed: %s\n", gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return NT_STATUS_ACCESS_DENIED; } *out = data_blob_talloc(mem_ctx, output_token.value, output_token.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;}/* Find out the maximum input size negotiated on this connection */static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security) { struct gensec_gssapi_state *gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); OM_uint32 maj_stat, min_stat; OM_uint32 max_input_size; maj_stat = gss_wrap_size_limit(&min_stat, gensec_gssapi_state->gssapi_context, gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL), GSS_C_QOP_DEFAULT, gensec_gssapi_state->max_wrap_buf_size, &max_input_size); if (GSS_ERROR(maj_stat)) { TALLOC_CTX *mem_ctx = talloc_new(NULL); DEBUG(1, ("gensec_gssapi_max_input_size: determinaing signature size with gss_wrap_size_limit failed: %s\n", gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); talloc_free(mem_ctx); return 0; } return max_input_size;}/* Find out the maximum output size negotiated on this connection */static size_t gensec_gssapi_max_wrapped_size(struct gensec_security *gensec_security) { struct gensec_gssapi_state *gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);; return gensec_gssapi_state->max_wrap_buf_size;}static NTSTATUS gensec_gssapi_seal_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, uint8_t *data, size_t length, const uint8_t *whole_pdu, size_t pdu_length, DATA_BLOB *sig){ 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; 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; } 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; } 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;}static NTSTATUS gensec_gssapi_unseal_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, uint8_t *data, size_t length, const uint8_t *whole_pdu, size_t pdu_length, const DATA_BLOB *sig){ 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); in = data_blob_talloc(mem_ctx, 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); if (GSS_ERROR(maj_stat)) { DEBUG(1, ("gensec_gssapi_unseal_packet: GSS UnWrap failed: %s\n", gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return NT_STATUS_ACCESS_DENIED; } if (output_token.length != length) { return NT_STATUS_INTERNAL_ERROR; } 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;}static NTSTATUS gensec_gssapi_sign_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, const uint8_t *data, size_t length, const uint8_t *whole_pdu, size_t pdu_length, DATA_BLOB *sig){ 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 = 0; input_token.length = length; input_token.value = discard_const_p(uint8_t *, data); maj_stat = gss_wrap(&min_stat, gensec_gssapi_state->gssapi_context, 0, GSS_C_QOP_DEFAULT, &input_token, &conf_state, &output_token); if (GSS_ERROR(maj_stat)) { DEBUG(1, ("GSS Wrap failed: %s\n", gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return NT_STATUS_ACCESS_DENIED; } if (output_token.length < input_token.length) { DEBUG(1, ("gensec_gssapi_sign_packet: GSS Wrap length [%ld] *less* than caller length [%ld]\n", (long)output_token.length, (long)length)); return NT_STATUS_INTERNAL_ERROR; } /* Caller must pad to right boundary */ sig_length = output_token.length - input_token.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); gss_release_buffer(&min_stat, &output_token); return NT_STATUS_OK;}static NTSTATUS gensec_gssapi_check_packet(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, const uint8_t *data, size_t length, const uint8_t *whole_pdu, size_t pdu_length, const DATA_BLOB *sig){ 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_seal_packet: sig\n", sig->data, sig->length); in = data_blob_talloc(mem_ctx, 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); if (GSS_ERROR(maj_stat)) { DEBUG(1, ("GSS UnWrap failed: %s\n", gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); return NT_STATUS_ACCESS_DENIED; } if (output_token.length != length) { return NT_STATUS_INTERNAL_ERROR; } gss_release_buffer(&min_stat, &output_token); return NT_STATUS_OK;}/* Try to figure out what features we actually got on the connection */static bool gensec_gssapi_have_feature(struct gensec_security *gensec_security, uint32_t feature) { struct gensec_gssapi_state *gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); if (feature & GENSEC_FEATURE_SIGN) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -