📄 gensec.c
字号:
oid_list = talloc_array(mem_ctx, const char *, 1); if (!oid_list) { return NULL; } for (i=0; wops[i].op; i++) { if (!wops[i].op->oid) { continue; } for (k = 0; wops[i].op->oid[k]; k++) { oid_list = talloc_realloc(mem_ctx, oid_list, const char *, j + 2); if (!oid_list) { return NULL; } oid_list[j] = wops[i].op->oid[k]; j++; } } oid_list[j] = NULL; return oid_list;}/** * Return all the security subsystems currently enabled on a GENSEC context. * * This is taken from a list attached to the cli_credentials, and * skips the OID in 'skip'. (Typically the SPNEGO OID) * */const char **gensec_security_oids(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, const char *skip) { struct gensec_security_ops **ops = gensec_security_mechs(gensec_security, mem_ctx); return gensec_security_oids_from_ops(mem_ctx, ops, skip);}/** Start the GENSEC system, returning a context pointer. @param mem_ctx The parent TALLOC memory context. @param gensec_security Returned GENSEC context pointer. @note The mem_ctx is only a parent and may be NULL.*/static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, struct event_context *ev, struct loadparm_context *lp_ctx, struct messaging_context *msg, struct gensec_security **gensec_security){ if (ev == NULL) { DEBUG(0, ("No event context available!\n")); return NT_STATUS_INTERNAL_ERROR; } (*gensec_security) = talloc(mem_ctx, struct gensec_security); NT_STATUS_HAVE_NO_MEMORY(*gensec_security); (*gensec_security)->ops = NULL; ZERO_STRUCT((*gensec_security)->target); ZERO_STRUCT((*gensec_security)->peer_addr); ZERO_STRUCT((*gensec_security)->my_addr); (*gensec_security)->subcontext = false; (*gensec_security)->want_features = 0; (*gensec_security)->event_ctx = ev; (*gensec_security)->msg_ctx = msg; (*gensec_security)->lp_ctx = lp_ctx; return NT_STATUS_OK;}/** * Start a GENSEC subcontext, with a copy of the properties of the parent * @param mem_ctx The parent TALLOC memory context. * @param parent The parent GENSEC context * @param gensec_security Returned GENSEC context pointer. * @note Used by SPNEGO in particular, for the actual implementation mechanism */_PUBLIC_ NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx, struct gensec_security *parent, struct gensec_security **gensec_security){ (*gensec_security) = talloc(mem_ctx, struct gensec_security); NT_STATUS_HAVE_NO_MEMORY(*gensec_security); (**gensec_security) = *parent; (*gensec_security)->ops = NULL; (*gensec_security)->private_data = NULL; (*gensec_security)->subcontext = true; (*gensec_security)->event_ctx = parent->event_ctx; (*gensec_security)->msg_ctx = parent->msg_ctx; (*gensec_security)->lp_ctx = parent->lp_ctx; return NT_STATUS_OK;}/** Start the GENSEC system, in client mode, returning a context pointer. @param mem_ctx The parent TALLOC memory context. @param gensec_security Returned GENSEC context pointer. @note The mem_ctx is only a parent and may be NULL.*/_PUBLIC_ NTSTATUS gensec_client_start(TALLOC_CTX *mem_ctx, struct gensec_security **gensec_security, struct event_context *ev, struct loadparm_context *lp_ctx){ NTSTATUS status; status = gensec_start(mem_ctx, ev, lp_ctx, NULL, gensec_security); if (!NT_STATUS_IS_OK(status)) { return status; } (*gensec_security)->gensec_role = GENSEC_CLIENT; return status;}/** Start the GENSEC system, in server mode, returning a context pointer. @param mem_ctx The parent TALLOC memory context. @param gensec_security Returned GENSEC context pointer. @note The mem_ctx is only a parent and may be NULL.*/_PUBLIC_ NTSTATUS gensec_server_start(TALLOC_CTX *mem_ctx, struct event_context *ev, struct loadparm_context *lp_ctx, struct messaging_context *msg, struct gensec_security **gensec_security){ NTSTATUS status; if (!ev) { DEBUG(0,("gensec_server_start: no event context given!\n")); return NT_STATUS_INTERNAL_ERROR; } if (!msg) { DEBUG(0,("gensec_server_start: no messaging context given!\n")); return NT_STATUS_INTERNAL_ERROR; } status = gensec_start(mem_ctx, ev, lp_ctx, msg, gensec_security); if (!NT_STATUS_IS_OK(status)) { return status; } (*gensec_security)->gensec_role = GENSEC_SERVER; return status;}static NTSTATUS gensec_start_mech(struct gensec_security *gensec_security) { NTSTATUS status; DEBUG(5, ("Starting GENSEC %smechanism %s\n", gensec_security->subcontext ? "sub" : "", gensec_security->ops->name)); switch (gensec_security->gensec_role) { case GENSEC_CLIENT: if (gensec_security->ops->client_start) { status = gensec_security->ops->client_start(gensec_security); if (!NT_STATUS_IS_OK(status)) { DEBUG(2, ("Failed to start GENSEC client mech %s: %s\n", gensec_security->ops->name, nt_errstr(status))); } return status; } break; case GENSEC_SERVER: if (gensec_security->ops->server_start) { status = gensec_security->ops->server_start(gensec_security); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start GENSEC server mech %s: %s\n", gensec_security->ops->name, nt_errstr(status))); } return status; } break; } return NT_STATUS_INVALID_PARAMETER;}/** * Start a GENSEC sub-mechanism by DCERPC allocated 'auth type' number * @param gensec_security GENSEC context pointer. * @param auth_type DCERPC auth type * @param auth_level DCERPC auth level */_PUBLIC_ NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_security, uint8_t auth_type, uint8_t auth_level) { gensec_security->ops = gensec_security_by_authtype(gensec_security, auth_type); if (!gensec_security->ops) { DEBUG(3, ("Could not find GENSEC backend for auth_type=%d\n", (int)auth_type)); return NT_STATUS_INVALID_PARAMETER; } gensec_want_feature(gensec_security, GENSEC_FEATURE_DCE_STYLE); gensec_want_feature(gensec_security, GENSEC_FEATURE_ASYNC_REPLIES); if (auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) { gensec_want_feature(gensec_security, GENSEC_FEATURE_SIGN); } else if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { gensec_want_feature(gensec_security, GENSEC_FEATURE_SIGN); gensec_want_feature(gensec_security, GENSEC_FEATURE_SEAL); } else if (auth_level == DCERPC_AUTH_LEVEL_CONNECT) { /* Default features */ } else { DEBUG(2,("auth_level %d not supported in DCE/RPC authentication\n", auth_level)); return NT_STATUS_INVALID_PARAMETER; } return gensec_start_mech(gensec_security);}_PUBLIC_ const char *gensec_get_name_by_authtype(uint8_t authtype) { const struct gensec_security_ops *ops; ops = gensec_security_by_authtype(NULL, authtype); if (ops) { return ops->name; } return NULL;} _PUBLIC_ const char *gensec_get_name_by_oid(const char *oid_string) { const struct gensec_security_ops *ops; ops = gensec_security_by_oid(NULL, oid_string); if (ops) { return ops->name; } return oid_string;} /** * Start a GENSEC sub-mechanism with a specifed mechansim structure, used in SPNEGO * */NTSTATUS gensec_start_mech_by_ops(struct gensec_security *gensec_security, const struct gensec_security_ops *ops) { gensec_security->ops = ops; return gensec_start_mech(gensec_security);}/** * Start a GENSEC sub-mechanism by OID, used in SPNEGO * * @note This should also be used when you wish to just start NLTMSSP (for example), as it uses a * well-known #define to hook it in. */_PUBLIC_ NTSTATUS gensec_start_mech_by_oid(struct gensec_security *gensec_security, const char *mech_oid) { gensec_security->ops = gensec_security_by_oid(gensec_security, mech_oid); if (!gensec_security->ops) { DEBUG(3, ("Could not find GENSEC backend for oid=%s\n", mech_oid)); return NT_STATUS_INVALID_PARAMETER; } return gensec_start_mech(gensec_security);}/** * Start a GENSEC sub-mechanism by a well know SASL name * */_PUBLIC_ NTSTATUS gensec_start_mech_by_sasl_name(struct gensec_security *gensec_security, const char *sasl_name) { gensec_security->ops = gensec_security_by_sasl_name(gensec_security, sasl_name); if (!gensec_security->ops) { DEBUG(3, ("Could not find GENSEC backend for sasl_name=%s\n", sasl_name)); return NT_STATUS_INVALID_PARAMETER; } return gensec_start_mech(gensec_security);}/** * Start a GENSEC sub-mechanism with the preferred option from a SASL name list * */_PUBLIC_ NTSTATUS gensec_start_mech_by_sasl_list(struct gensec_security *gensec_security, const char **sasl_names) { NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER; TALLOC_CTX *mem_ctx = talloc_new(gensec_security); const struct gensec_security_ops **ops; int i; if (!mem_ctx) { return NT_STATUS_NO_MEMORY; } ops = gensec_security_by_sasl_list(gensec_security, mem_ctx, sasl_names); if (!ops || !*ops) { DEBUG(3, ("Could not find GENSEC backend for any of sasl_name = %s\n", str_list_join(mem_ctx, sasl_names, ' '))); talloc_free(mem_ctx); return NT_STATUS_INVALID_PARAMETER; } for (i=0; ops[i]; i++) { nt_status = gensec_start_mech_by_ops(gensec_security, ops[i]); if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_PARAMETER)) { break; } } talloc_free(mem_ctx); return nt_status;}/** * Start a GENSEC sub-mechanism by an internal name * */_PUBLIC_ NTSTATUS gensec_start_mech_by_name(struct gensec_security *gensec_security, const char *name) { gensec_security->ops = gensec_security_by_name(gensec_security, name); if (!gensec_security->ops) { DEBUG(3, ("Could not find GENSEC backend for name=%s\n", name)); return NT_STATUS_INVALID_PARAMETER; } return gensec_start_mech(gensec_security);}/* wrappers for the gensec function pointers*/_PUBLIC_ NTSTATUS gensec_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){ if (!gensec_security->ops->unseal_packet) { return NT_STATUS_NOT_IMPLEMENTED; } if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { return NT_STATUS_INVALID_PARAMETER; } return gensec_security->ops->unseal_packet(gensec_security, mem_ctx, data, length, whole_pdu, pdu_length, sig);}_PUBLIC_ NTSTATUS gensec_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){ if (!gensec_security->ops->check_packet) { return NT_STATUS_NOT_IMPLEMENTED; } if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { return NT_STATUS_INVALID_PARAMETER; } return gensec_security->ops->check_packet(gensec_security, mem_ctx, data, length, whole_pdu, pdu_length, sig);}_PUBLIC_ NTSTATUS gensec_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){ if (!gensec_security->ops->seal_packet) { return NT_STATUS_NOT_IMPLEMENTED; } if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) { return NT_STATUS_INVALID_PARAMETER; } return gensec_security->ops->seal_packet(gensec_security, mem_ctx, data, length, whole_pdu, pdu_length, sig);}_PUBLIC_ NTSTATUS gensec_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){ if (!gensec_security->ops->sign_packet) { return NT_STATUS_NOT_IMPLEMENTED; } if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { return NT_STATUS_INVALID_PARAMETER; } return gensec_security->ops->sign_packet(gensec_security, mem_ctx, data, length, whole_pdu, pdu_length, sig);}_PUBLIC_ size_t gensec_sig_size(struct gensec_security *gensec_security, size_t data_size) { if (!gensec_security->ops->sig_size) { return 0; } if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) { return 0; } return gensec_security->ops->sig_size(gensec_security, data_size);}size_t gensec_max_wrapped_size(struct gensec_security *gensec_security) { if (!gensec_security->ops->max_wrapped_size) { return (1 << 17);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -