📄 gensec.c
字号:
/* Unix SMB/CIFS implementation. Generic Authentication Interface Copyright (C) Andrew Tridgell 2003 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2006 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.*/#include "includes.h"#include "auth/auth.h"#include "lib/events/events.h"#include "librpc/rpc/dcerpc.h"#include "auth/credentials/credentials.h"#include "auth/gensec/gensec.h"#include "auth/gensec/gensec_proto.h"#include "param/param.h"/* the list of currently registered GENSEC backends */static struct gensec_security_ops **generic_security_ops;static int gensec_num_backends;/* Return all the registered mechs. Don't modify the return pointer, * but you may talloc_reference it if convient */_PUBLIC_ struct gensec_security_ops **gensec_security_all(void){ return generic_security_ops;}/* Sometimes we want to force only kerberos, sometimes we want to * force it's avoidance. The old list could be either * gensec_security_all(), or from cli_credentials_gensec_list() (ie, * an existing list we have trimmed down) */_PUBLIC_ struct gensec_security_ops **gensec_use_kerberos_mechs(TALLOC_CTX *mem_ctx, struct gensec_security_ops **old_gensec_list, struct cli_credentials *creds){ struct gensec_security_ops **new_gensec_list; int i, j, num_mechs_in; enum credentials_use_kerberos use_kerberos = CRED_AUTO_USE_KERBEROS; if (creds) { use_kerberos = cli_credentials_get_kerberos_state(creds); } if (use_kerberos == CRED_AUTO_USE_KERBEROS) { if (!talloc_reference(mem_ctx, old_gensec_list)) { return NULL; } return old_gensec_list; } for (num_mechs_in=0; old_gensec_list && old_gensec_list[num_mechs_in]; num_mechs_in++) { /* noop */ } new_gensec_list = talloc_array(mem_ctx, struct gensec_security_ops *, num_mechs_in + 1); if (!new_gensec_list) { return NULL; } j = 0; for (i=0; old_gensec_list && old_gensec_list[i]; i++) { int oid_idx; for (oid_idx = 0; old_gensec_list[i]->oid && old_gensec_list[i]->oid[oid_idx]; oid_idx++) { if (strcmp(old_gensec_list[i]->oid[oid_idx], GENSEC_OID_SPNEGO) == 0) { new_gensec_list[j] = old_gensec_list[i]; j++; break; } } switch (use_kerberos) { case CRED_DONT_USE_KERBEROS: if (old_gensec_list[i]->kerberos == false) { new_gensec_list[j] = old_gensec_list[i]; j++; } break; case CRED_MUST_USE_KERBEROS: if (old_gensec_list[i]->kerberos == true) { new_gensec_list[j] = old_gensec_list[i]; j++; } break; default: /* Can't happen or invalid parameter */ return NULL; } } new_gensec_list[j] = NULL; return new_gensec_list;}struct gensec_security_ops **gensec_security_mechs(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx) { struct gensec_security_ops **backends; backends = gensec_security_all(); if (!gensec_security) { if (!talloc_reference(mem_ctx, backends)) { return NULL; } return backends; } else { struct cli_credentials *creds = gensec_get_credentials(gensec_security); if (!creds) { if (!talloc_reference(mem_ctx, backends)) { return NULL; } return backends; } return gensec_use_kerberos_mechs(mem_ctx, backends, creds); }}static const struct gensec_security_ops *gensec_security_by_authtype(struct gensec_security *gensec_security, uint8_t auth_type){ int i; struct gensec_security_ops **backends; const struct gensec_security_ops *backend; TALLOC_CTX *mem_ctx = talloc_new(gensec_security); if (!mem_ctx) { return NULL; } backends = gensec_security_mechs(gensec_security, mem_ctx); for (i=0; backends && backends[i]; i++) { if (backends[i]->auth_type == auth_type) { backend = backends[i]; talloc_free(mem_ctx); return backend; } } talloc_free(mem_ctx); return NULL;}const struct gensec_security_ops *gensec_security_by_oid(struct gensec_security *gensec_security, const char *oid_string){ int i, j; struct gensec_security_ops **backends; const struct gensec_security_ops *backend; TALLOC_CTX *mem_ctx = talloc_new(gensec_security); if (!mem_ctx) { return NULL; } backends = gensec_security_mechs(gensec_security, mem_ctx); for (i=0; backends && backends[i]; i++) { if (backends[i]->oid) { for (j=0; backends[i]->oid[j]; j++) { if (backends[i]->oid[j] && (strcmp(backends[i]->oid[j], oid_string) == 0)) { backend = backends[i]; talloc_free(mem_ctx); return backend; } } } } talloc_free(mem_ctx); return NULL;}const struct gensec_security_ops *gensec_security_by_sasl_name(struct gensec_security *gensec_security, const char *sasl_name){ int i; struct gensec_security_ops **backends; const struct gensec_security_ops *backend; TALLOC_CTX *mem_ctx = talloc_new(gensec_security); if (!mem_ctx) { return NULL; } backends = gensec_security_mechs(gensec_security, mem_ctx); for (i=0; backends && backends[i]; i++) { if (backends[i]->sasl_name && (strcmp(backends[i]->sasl_name, sasl_name) == 0)) { backend = backends[i]; talloc_free(mem_ctx); return backend; } } talloc_free(mem_ctx); return NULL;}static const struct gensec_security_ops *gensec_security_by_name(struct gensec_security *gensec_security, const char *name){ int i; struct gensec_security_ops **backends; const struct gensec_security_ops *backend; TALLOC_CTX *mem_ctx = talloc_new(gensec_security); if (!mem_ctx) { return NULL; } backends = gensec_security_mechs(gensec_security, mem_ctx); for (i=0; backends && backends[i]; i++) { if (backends[i]->name && (strcmp(backends[i]->name, name) == 0)) { backend = backends[i]; talloc_free(mem_ctx); return backend; } } talloc_free(mem_ctx); return NULL;}/** * Return a unique list of security subsystems from those specified in * the list of SASL names. * * Use the list of enabled GENSEC mechanisms from the credentials * attached to the gensec_security, and return in our preferred order. */const struct gensec_security_ops **gensec_security_by_sasl_list(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, const char **sasl_names){ const struct gensec_security_ops **backends_out; struct gensec_security_ops **backends; int i, k, sasl_idx; int num_backends_out = 0; if (!sasl_names) { return NULL; } backends = gensec_security_mechs(gensec_security, mem_ctx); backends_out = talloc_array(mem_ctx, const struct gensec_security_ops *, 1); if (!backends_out) { return NULL; } backends_out[0] = NULL; /* Find backends in our preferred order, by walking our list, * then looking in the supplied list */ for (i=0; backends && backends[i]; i++) { for (sasl_idx = 0; sasl_names[sasl_idx]; sasl_idx++) { if (!backends[i]->sasl_name || !(strcmp(backends[i]->sasl_name, sasl_names[sasl_idx]) == 0)) { continue; } for (k=0; backends_out[k]; k++) { if (backends_out[k] == backends[i]) { break; } } if (k < num_backends_out) { /* already in there */ continue; } backends_out = talloc_realloc(mem_ctx, backends_out, const struct gensec_security_ops *, num_backends_out + 2); if (!backends_out) { return NULL; } backends_out[num_backends_out] = backends[i]; num_backends_out++; backends_out[num_backends_out] = NULL; } } return backends_out;}/** * Return a unique list of security subsystems from those specified in * the OID list. That is, where two OIDs refer to the same module, * return that module only once. * * Use the list of enabled GENSEC mechanisms from the credentials * attached to the gensec_security, and return in our preferred order. */const struct gensec_security_ops_wrapper *gensec_security_by_oid_list(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, const char **oid_strings, const char *skip){ struct gensec_security_ops_wrapper *backends_out; struct gensec_security_ops **backends; int i, j, k, oid_idx; int num_backends_out = 0; if (!oid_strings) { return NULL; } backends = gensec_security_mechs(gensec_security, gensec_security); backends_out = talloc_array(mem_ctx, struct gensec_security_ops_wrapper, 1); if (!backends_out) { return NULL; } backends_out[0].op = NULL; backends_out[0].oid = NULL; /* Find backends in our preferred order, by walking our list, * then looking in the supplied list */ for (i=0; backends && backends[i]; i++) { if (!backends[i]->oid) { continue; } for (oid_idx = 0; oid_strings[oid_idx]; oid_idx++) { if (strcmp(oid_strings[oid_idx], skip) == 0) { continue; } for (j=0; backends[i]->oid[j]; j++) { if (!backends[i]->oid[j] || !(strcmp(backends[i]->oid[j], oid_strings[oid_idx]) == 0)) { continue; } for (k=0; backends_out[k].op; k++) { if (backends_out[k].op == backends[i]) { break; } } if (k < num_backends_out) { /* already in there */ continue; } backends_out = talloc_realloc(mem_ctx, backends_out, struct gensec_security_ops_wrapper, num_backends_out + 2); if (!backends_out) { return NULL; } backends_out[num_backends_out].op = backends[i]; backends_out[num_backends_out].oid = backends[i]->oid[j]; num_backends_out++; backends_out[num_backends_out].op = NULL; backends_out[num_backends_out].oid = NULL; } } } return backends_out;}/** * Return OIDS from the security subsystems listed */const char **gensec_security_oids_from_ops(TALLOC_CTX *mem_ctx, struct gensec_security_ops **ops, const char *skip) { int i; int j = 0; int k; const char **oid_list; if (!ops) { return NULL; } oid_list = talloc_array(mem_ctx, const char *, 1); if (!oid_list) { return NULL; } for (i=0; ops && ops[i]; i++) { if (!ops[i]->oid) { continue; } for (k = 0; ops[i]->oid[k]; k++) { if (skip && strcmp(skip, ops[i]->oid[k])==0) { } else { oid_list = talloc_realloc(mem_ctx, oid_list, const char *, j + 2); if (!oid_list) { return NULL; } oid_list[j] = ops[i]->oid[k]; j++; } } } oid_list[j] = NULL; return oid_list;}/** * Return OIDS from the security subsystems listed */const char **gensec_security_oids_from_ops_wrapped(TALLOC_CTX *mem_ctx, const struct gensec_security_ops_wrapper *wops){ int i; int j = 0; int k; const char **oid_list; if (!wops) { return NULL; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -