diff options
author | Günther Deschner <gd@samba.org> | 2009-09-17 00:21:01 +0200 |
---|---|---|
committer | Günther Deschner <gd@samba.org> | 2009-09-17 01:12:20 +0200 |
commit | 503d0358140fbf56bd83090f143272aeb770baa9 (patch) | |
tree | 32cf6fdb58c62599602d6d1ce9e48d4fee9fee19 | |
parent | 83023462f95f60ecfd3019abe896cca1d2aed771 (diff) | |
download | samba-503d0358140fbf56bd83090f143272aeb770baa9.tar.gz |
spnego: share spnego_parse.
Guenther
-rw-r--r-- | libcli/auth/spnego.h (renamed from source4/auth/gensec/spnego.h) | 13 | ||||
-rw-r--r-- | libcli/auth/spnego_parse.c (renamed from source4/auth/gensec/spnego_parse.c) | 25 | ||||
-rw-r--r-- | source3/Makefile.in | 2 | ||||
-rw-r--r-- | source3/include/ads.h | 6 | ||||
-rw-r--r-- | source3/include/includes.h | 1 | ||||
-rw-r--r-- | source3/include/proto.h | 6 | ||||
-rw-r--r-- | source3/include/spnego.h | 81 | ||||
-rw-r--r-- | source3/libads/sasl.c | 1 | ||||
-rw-r--r-- | source3/libsmb/cliconnect.c | 1 | ||||
-rw-r--r-- | source3/libsmb/clifsinfo.c | 1 | ||||
-rw-r--r-- | source3/libsmb/clispnego.c | 15 | ||||
-rw-r--r-- | source3/libsmb/spnego.c | 362 | ||||
-rw-r--r-- | source3/rpc_client/cli_pipe.c | 1 | ||||
-rw-r--r-- | source3/rpc_server/srv_pipe.c | 1 | ||||
-rw-r--r-- | source3/smbd/negprot.c | 1 | ||||
-rw-r--r-- | source3/smbd/seal.c | 1 | ||||
-rw-r--r-- | source3/smbd/sesssetup.c | 1 | ||||
-rw-r--r-- | source3/smbd/smb2_sesssetup.c | 1 | ||||
-rw-r--r-- | source3/utils/ntlm_auth.c | 43 | ||||
-rw-r--r-- | source4/auth/gensec/config.mk | 2 | ||||
-rw-r--r-- | source4/auth/gensec/spnego.c | 2 |
21 files changed, 71 insertions, 496 deletions
diff --git a/source4/auth/gensec/spnego.h b/libcli/auth/spnego.h index 24e80ecb0bc..250ffed20d6 100644 --- a/source4/auth/gensec/spnego.h +++ b/libcli/auth/spnego.h @@ -1,4 +1,4 @@ -/* +/* Unix SMB/CIFS implementation. RFC2478 Compliant SPNEGO implementation @@ -9,17 +9,22 @@ 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/>. */ +#define OID_SPNEGO "1.3.6.1.5.5.2" +#define OID_NTLMSSP "1.3.6.1.4.1.311.2.2.10" +#define OID_KERBEROS5_OLD "1.2.840.48018.1.2.2" +#define OID_KERBEROS5 "1.2.840.113554.1.2.2" + #define SPNEGO_DELEG_FLAG 0x01 #define SPNEGO_MUTUAL_FLAG 0x02 #define SPNEGO_REPLAY_FLAG 0x04 @@ -58,7 +63,7 @@ struct spnego_data { }; enum spnego_message_type { - SPNEGO_NEG_TOKEN_INIT = 0, + SPNEGO_NEG_TOKEN_INIT = 0, SPNEGO_NEG_TOKEN_TARG = 1, }; diff --git a/source4/auth/gensec/spnego_parse.c b/libcli/auth/spnego_parse.c index a79f15b8eeb..27e57740dc2 100644 --- a/source4/auth/gensec/spnego_parse.c +++ b/libcli/auth/spnego_parse.c @@ -1,4 +1,4 @@ -/* +/* Unix SMB/CIFS implementation. RFC2478 Compliant SPNEGO implementation @@ -9,20 +9,19 @@ 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/gensec/spnego.h" -#include "auth/gensec/gensec.h" +#include "../libcli/auth/spnego.h" #include "../lib/util/asn1.h" static bool read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, @@ -50,13 +49,13 @@ static bool read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, token->mechTypes = talloc(NULL, const char *); for (i = 0; !asn1->has_error && 0 < asn1_tag_remaining(asn1); i++) { - token->mechTypes = talloc_realloc(NULL, - token->mechTypes, + token->mechTypes = talloc_realloc(NULL, + token->mechTypes, const char *, i+2); asn1_read_OID(asn1, token->mechTypes, token->mechTypes + i); } token->mechTypes[i] = NULL; - + asn1_end_tag(asn1); asn1_end_tag(asn1); break; @@ -83,7 +82,7 @@ static bool read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, break; } if (type_peek == ASN1_OCTET_STRING) { - asn1_read_OctetString(asn1, mem_ctx, + asn1_read_OctetString(asn1, mem_ctx, &token->mechListMIC); } else { /* RFC 2478 says we have an Octet String here, @@ -165,7 +164,7 @@ static bool write_negTokenInit(struct asn1_data *asn1, struct spnego_negTokenIni asn1_pop_tag(asn1); asn1_pop_tag(asn1); asn1_pop_tag(asn1); -#endif +#endif asn1_pop_tag(asn1); } @@ -175,7 +174,7 @@ static bool write_negTokenInit(struct asn1_data *asn1, struct spnego_negTokenIni return !asn1->has_error; } -static bool read_negTokenTarg(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, +static bool read_negTokenTarg(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, struct spnego_negTokenTarg *token) { ZERO_STRUCTP(token); @@ -287,7 +286,7 @@ ssize_t spnego_read_data(TALLOC_CTX *mem_ctx, DATA_BLOB data, struct spnego_data switch (context) { case ASN1_APPLICATION(0): asn1_start_tag(asn1, ASN1_APPLICATION(0)); - asn1_check_OID(asn1, GENSEC_OID_SPNEGO); + asn1_check_OID(asn1, OID_SPNEGO); if (read_negTokenInit(asn1, mem_ctx, &token->negTokenInit)) { token->type = SPNEGO_NEG_TOKEN_INIT; } @@ -322,7 +321,7 @@ ssize_t spnego_write_data(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, struct spnego_da switch (spnego->type) { case SPNEGO_NEG_TOKEN_INIT: asn1_push_tag(asn1, ASN1_APPLICATION(0)); - asn1_write_OID(asn1, GENSEC_OID_SPNEGO); + asn1_write_OID(asn1, OID_SPNEGO); write_negTokenInit(asn1, &spnego->negTokenInit); asn1_pop_tag(asn1); break; diff --git a/source3/Makefile.in b/source3/Makefile.in index 65feb8446bf..1b936312ea5 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -1297,7 +1297,7 @@ TDBTORTURE_OBJ = @tdbdir@/tools/tdbtorture.o $(LIBREPLACE_OBJ) \ NTLM_AUTH_OBJ1 = utils/ntlm_auth.o utils/ntlm_auth_diagnostics.o NTLM_AUTH_OBJ = ${NTLM_AUTH_OBJ1} $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) \ - ../lib/util/asn1.o libsmb/spnego.o libsmb/clikrb5.o libads/kerberos.o \ + ../lib/util/asn1.o ../libcli/auth/spnego_parse.o libsmb/clikrb5.o libads/kerberos.o \ $(LIBADS_SERVER_OBJ) \ $(PASSDB_OBJ) $(LIBTSOCKET_OBJ) $(GROUPDB_OBJ) \ $(SMBLDAP_OBJ) $(LIBNMB_OBJ) \ diff --git a/source3/include/ads.h b/source3/include/ads.h index 9761d540866..6d9b0eebac1 100644 --- a/source3/include/ads.h +++ b/source3/include/ads.h @@ -8,6 +8,12 @@ #include "../libds/common/flags.h" +#define TOK_ID_KRB_AP_REQ ((const uint8_t *)"\x01\x00") +#define TOK_ID_KRB_AP_REP ((const uint8_t *)"\x02\x00") +#define TOK_ID_KRB_ERROR ((const uint8_t *)"\x03\x00") +#define TOK_ID_GSS_GETMIC ((const uint8_t *)"\x01\x01") +#define TOK_ID_GSS_WRAP ((const uint8_t *)"\x02\x01") + enum wb_posix_mapping { WB_POSIX_MAP_UNKNOWN = -1, WB_POSIX_MAP_TEMPLATE = 0, diff --git a/source3/include/includes.h b/source3/include/includes.h index d1be3b06a87..71125140bec 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -688,7 +688,6 @@ struct smb_iconv_convenience *lp_iconv_convenience(void *lp_ctx); #include "mangle.h" #include "module.h" #include "nsswitch/winbind_client.h" -#include "spnego.h" #include "rpc_client.h" #include "dbwrap.h" #include "packet.h" diff --git a/source3/include/proto.h b/source3/include/proto.h index 4b80ef1cb0a..81cb5ef6e1d 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -3297,12 +3297,6 @@ const char *smb_dos_err_class(uint8 e_class); char *smb_dos_errstr(char *inbuf); WERROR map_werror_from_unix(int error); -/* The following definitions come from libsmb/spnego.c */ - -ssize_t read_spnego_data(DATA_BLOB data, SPNEGO_DATA *token); -ssize_t write_spnego_data(DATA_BLOB *blob, SPNEGO_DATA *spnego); -bool free_spnego_data(SPNEGO_DATA *spnego); - /* The following definitions come from libsmb/trustdom_cache.c */ bool trustdom_cache_enable(void); diff --git a/source3/include/spnego.h b/source3/include/spnego.h deleted file mode 100644 index f777969d3af..00000000000 --- a/source3/include/spnego.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - RFC2478 Compliant SPNEGO implementation - - Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003 - - 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/>. -*/ - -#ifndef SAMBA_SPNEGO_H -#define SAMBA_SPNEGO_H - -#define SPNEGO_DELEG_FLAG 0x01 -#define SPNEGO_MUTUAL_FLAG 0x02 -#define SPNEGO_REPLAY_FLAG 0x04 -#define SPNEGO_SEQUENCE_FLAG 0x08 -#define SPNEGO_ANON_FLAG 0x10 -#define SPNEGO_CONF_FLAG 0x20 -#define SPNEGO_INTEG_FLAG 0x40 -#define SPNEGO_REQ_FLAG 0x80 - -#define SPNEGO_NEG_TOKEN_INIT 0 -#define SPNEGO_NEG_TOKEN_TARG 1 - -/* some well known object IDs */ -#define OID_SPNEGO "1.3.6.1.5.5.2" -#define OID_NTLMSSP "1.3.6.1.4.1.311.2.2.10" -#define OID_KERBEROS5_OLD "1.2.840.48018.1.2.2" -#define OID_KERBEROS5 "1.2.840.113554.1.2.2" - -#define SPNEGO_NEG_RESULT_ACCEPT 0 -#define SPNEGO_NEG_RESULT_INCOMPLETE 1 -#define SPNEGO_NEG_RESULT_REJECT 2 - -/* not really ASN.1, but RFC 1964 */ -#define TOK_ID_KRB_AP_REQ (uchar*)"\x01\x00" -#define TOK_ID_KRB_AP_REP (uchar*)"\x02\x00" -#define TOK_ID_KRB_ERROR (uchar*)"\x03\x00" -#define TOK_ID_GSS_GETMIC (uchar*)"\x01\x01" -#define TOK_ID_GSS_WRAP (uchar*)"\x02\x01" - -typedef enum _spnego_negResult { - SPNEGO_ACCEPT_COMPLETED = 0, - SPNEGO_ACCEPT_INCOMPLETE = 1, - SPNEGO_REJECT = 2 -} negResult_t; - -typedef struct spnego_negTokenInit { - const char **mechTypes; - int reqFlags; - DATA_BLOB mechToken; - DATA_BLOB mechListMIC; -} negTokenInit_t; - -typedef struct spnego_negTokenTarg { - uint8 negResult; - char *supportedMech; - DATA_BLOB responseToken; - DATA_BLOB mechListMIC; -} negTokenTarg_t; - -typedef struct spnego_spnego { - int type; - negTokenInit_t negTokenInit; - negTokenTarg_t negTokenTarg; -} SPNEGO_DATA; - -#endif diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 3182b936e01..9b4d8bd2d44 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -18,6 +18,7 @@ */ #include "includes.h" +#include "../libcli/auth/spnego.h" #ifdef HAVE_LDAP diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 600f8d1b4ad..2535de28474 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -20,6 +20,7 @@ #include "includes.h" #include "../libcli/auth/libcli_auth.h" +#include "../libcli/auth/spnego.h" static const struct { int prot; diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index e0ae948aaf4..308a6f7215f 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "../libcli/auth/spnego.h" /**************************************************************************** Get UNIX extensions version info. diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 74dba56aecc..5d7e43d941f 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "../libcli/auth/spnego.h" /* generate a negTokenInit packet given a GUID, a list of supported @@ -532,11 +533,11 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status, uint8 negResult; if (NT_STATUS_IS_OK(nt_status)) { - negResult = SPNEGO_NEG_RESULT_ACCEPT; + negResult = SPNEGO_ACCEPT_COMPLETED; } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - negResult = SPNEGO_NEG_RESULT_INCOMPLETE; + negResult = SPNEGO_ACCEPT_INCOMPLETE; } else { - negResult = SPNEGO_NEG_RESULT_REJECT; + negResult = SPNEGO_REJECT; } data = asn1_init(talloc_tos()); @@ -581,11 +582,11 @@ bool spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, uint8 negResult; if (NT_STATUS_IS_OK(nt_status)) { - negResult = SPNEGO_NEG_RESULT_ACCEPT; + negResult = SPNEGO_ACCEPT_COMPLETED; } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - negResult = SPNEGO_NEG_RESULT_INCOMPLETE; + negResult = SPNEGO_ACCEPT_INCOMPLETE; } else { - negResult = SPNEGO_NEG_RESULT_REJECT; + negResult = SPNEGO_REJECT; } data = asn1_init(talloc_tos()); @@ -612,7 +613,7 @@ bool spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, asn1_read_OctetString(data, talloc_autofree_context(), auth); asn1_end_tag(data); } - } else if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) { + } else if (negResult == SPNEGO_ACCEPT_INCOMPLETE) { data->has_error = 1; } diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c deleted file mode 100644 index 528c7f40090..00000000000 --- a/source3/libsmb/spnego.c +++ /dev/null @@ -1,362 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - RFC2478 Compliant SPNEGO implementation - - Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003 - - 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" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - -static bool read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) -{ - ZERO_STRUCTP(token); - - asn1_start_tag(asn1, ASN1_CONTEXT(0)); - asn1_start_tag(asn1, ASN1_SEQUENCE(0)); - - while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) { - int i; - - switch (asn1->data[asn1->ofs]) { - /* Read mechTypes */ - case ASN1_CONTEXT(0): - asn1_start_tag(asn1, ASN1_CONTEXT(0)); - asn1_start_tag(asn1, ASN1_SEQUENCE(0)); - - token->mechTypes = TALLOC_P(talloc_autofree_context(), const char *); - for (i = 0; !asn1->has_error && - 0 < asn1_tag_remaining(asn1); i++) { - const char *p_oid = NULL; - token->mechTypes = - TALLOC_REALLOC_ARRAY(talloc_autofree_context(), - token->mechTypes, const char *, i + 2); - if (!token->mechTypes) { - asn1->has_error = True; - return False; - } - asn1_read_OID(asn1, talloc_autofree_context(), &p_oid); - token->mechTypes[i] = p_oid; - } - token->mechTypes[i] = NULL; - - asn1_end_tag(asn1); - asn1_end_tag(asn1); - break; - /* Read reqFlags */ - case ASN1_CONTEXT(1): - asn1_start_tag(asn1, ASN1_CONTEXT(1)); - asn1_read_Integer(asn1, &token->reqFlags); - token->reqFlags |= SPNEGO_REQ_FLAG; - asn1_end_tag(asn1); - break; - /* Read mechToken */ - case ASN1_CONTEXT(2): - asn1_start_tag(asn1, ASN1_CONTEXT(2)); - asn1_read_OctetString(asn1, - talloc_autofree_context(), &token->mechToken); - asn1_end_tag(asn1); - break; - /* Read mecListMIC */ - case ASN1_CONTEXT(3): - asn1_start_tag(asn1, ASN1_CONTEXT(3)); - if (asn1->data[asn1->ofs] == ASN1_OCTET_STRING) { - asn1_read_OctetString(asn1, talloc_autofree_context(), - &token->mechListMIC); - } else { - /* RFC 2478 says we have an Octet String here, - but W2k sends something different... */ - char *mechListMIC; - asn1_push_tag(asn1, ASN1_SEQUENCE(0)); - asn1_push_tag(asn1, ASN1_CONTEXT(0)); - asn1_read_GeneralString(asn1, - talloc_autofree_context(), &mechListMIC); - asn1_pop_tag(asn1); - asn1_pop_tag(asn1); - - token->mechListMIC = - data_blob(mechListMIC, strlen(mechListMIC)); - TALLOC_FREE(mechListMIC); - } - asn1_end_tag(asn1); - break; - default: - asn1->has_error = True; - break; - } - } - - asn1_end_tag(asn1); - asn1_end_tag(asn1); - - return !asn1->has_error; -} - -static bool write_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) -{ - asn1_push_tag(asn1, ASN1_CONTEXT(0)); - asn1_push_tag(asn1, ASN1_SEQUENCE(0)); - - /* Write mechTypes */ - if (token->mechTypes && *token->mechTypes) { - int i; - - asn1_push_tag(asn1, ASN1_CONTEXT(0)); - asn1_push_tag(asn1, ASN1_SEQUENCE(0)); - for (i = 0; token->mechTypes[i]; i++) { - asn1_write_OID(asn1, token->mechTypes[i]); - } - asn1_pop_tag(asn1); - asn1_pop_tag(asn1); - } - - /* write reqFlags */ - if (token->reqFlags & SPNEGO_REQ_FLAG) { - int flags = token->reqFlags & ~SPNEGO_REQ_FLAG; - - asn1_push_tag(asn1, ASN1_CONTEXT(1)); - asn1_write_Integer(asn1, flags); - asn1_pop_tag(asn1); - } - - /* write mechToken */ - if (token->mechToken.data) { - asn1_push_tag(asn1, ASN1_CONTEXT(2)); - asn1_write_OctetString(asn1, token->mechToken.data, - token->mechToken.length); - asn1_pop_tag(asn1); - } - - /* write mechListMIC */ - if (token->mechListMIC.data) { - asn1_push_tag(asn1, ASN1_CONTEXT(3)); -#if 0 - /* This is what RFC 2478 says ... */ - asn1_write_OctetString(asn1, token->mechListMIC.data, - token->mechListMIC.length); -#else - /* ... but unfortunately this is what Windows - sends/expects */ - asn1_push_tag(asn1, ASN1_SEQUENCE(0)); - asn1_push_tag(asn1, ASN1_CONTEXT(0)); - asn1_push_tag(asn1, ASN1_GENERAL_STRING); - asn1_write(asn1, token->mechListMIC.data, - token->mechListMIC.length); - asn1_pop_tag(asn1); - asn1_pop_tag(asn1); - asn1_pop_tag(asn1); -#endif - asn1_pop_tag(asn1); - } - - asn1_pop_tag(asn1); - asn1_pop_tag(asn1); - - return !asn1->has_error; -} - -static bool read_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token) -{ - ZERO_STRUCTP(token); - - asn1_start_tag(asn1, ASN1_CONTEXT(1)); - asn1_start_tag(asn1, ASN1_SEQUENCE(0)); - - while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) { - switch (asn1->data[asn1->ofs]) { - case ASN1_CONTEXT(0): - asn1_start_tag(asn1, ASN1_CONTEXT(0)); - asn1_start_tag(asn1, ASN1_ENUMERATED); - asn1_read_uint8(asn1, &token->negResult); - asn1_end_tag(asn1); - asn1_end_tag(asn1); - break; - case ASN1_CONTEXT(1): { - const char *mech = NULL; - asn1_start_tag(asn1, ASN1_CONTEXT(1)); - asn1_read_OID(asn1, talloc_autofree_context(), &mech); - asn1_end_tag(asn1); - token->supportedMech = CONST_DISCARD(char *, mech); - } - break; - case ASN1_CONTEXT(2): - asn1_start_tag(asn1, ASN1_CONTEXT(2)); - asn1_read_OctetString(asn1, - talloc_autofree_context(), &token->responseToken); - asn1_end_tag(asn1); - break; - case ASN1_CONTEXT(3): - asn1_start_tag(asn1, ASN1_CONTEXT(3)); - asn1_read_OctetString(asn1, - talloc_autofree_context(), &token->mechListMIC); - asn1_end_tag(asn1); - break; - default: - asn1->has_error = True; - break; - } - } - - asn1_end_tag(asn1); - asn1_end_tag(asn1); - - return !asn1->has_error; -} - -static bool write_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token) -{ - asn1_push_tag(asn1, ASN1_CONTEXT(1)); - asn1_push_tag(asn1, ASN1_SEQUENCE(0)); - - asn1_push_tag(asn1, ASN1_CONTEXT(0)); - asn1_write_enumerated(asn1, token->negResult); - asn1_pop_tag(asn1); - - if (token->supportedMech) { - asn1_push_tag(asn1, ASN1_CONTEXT(1)); - asn1_write_OID(asn1, token->supportedMech); - asn1_pop_tag(asn1); - } - - if (token->responseToken.data) { - asn1_push_tag(asn1, ASN1_CONTEXT(2)); - asn1_write_OctetString(asn1, token->responseToken.data, - token->responseToken.length); - asn1_pop_tag(asn1); - } - - if (token->mechListMIC.data) { - asn1_push_tag(asn1, ASN1_CONTEXT(3)); - asn1_write_OctetString(asn1, token->mechListMIC.data, - token->mechListMIC.length); - asn1_pop_tag(asn1); - } - - asn1_pop_tag(asn1); - asn1_pop_tag(asn1); - - return !asn1->has_error; -} - -ssize_t read_spnego_data(DATA_BLOB data, SPNEGO_DATA *token) -{ - ASN1_DATA *asn1; - ssize_t ret = -1; - - ZERO_STRUCTP(token); - - asn1 = asn1_init(talloc_tos()); - if (asn1 == NULL) { - return -1; - } - - asn1_load(asn1, data); - - switch (asn1->data[asn1->ofs]) { - case ASN1_APPLICATION(0): - asn1_start_tag(asn1, ASN1_APPLICATION(0)); - asn1_check_OID(asn1, OID_SPNEGO); - if (read_negTokenInit(asn1, &token->negTokenInit)) { - token->type = SPNEGO_NEG_TOKEN_INIT; - } - asn1_end_tag(asn1); - break; - case ASN1_CONTEXT(1): - if (read_negTokenTarg(asn1, &token->negTokenTarg)) { - token->type = SPNEGO_NEG_TOKEN_TARG; - } - break; - default: - break; - } - - if (!asn1->has_error) ret = asn1->ofs; - asn1_free(asn1); - - return ret; -} - -ssize_t write_spnego_data(DATA_BLOB *blob, SPNEGO_DATA *spnego) -{ - ASN1_DATA *asn1; - ssize_t ret = -1; - - asn1 = asn1_init(talloc_tos()); - if (asn1 == NULL) { - return -1; - } - - switch (spnego->type) { - case SPNEGO_NEG_TOKEN_INIT: - asn1_push_tag(asn1, ASN1_APPLICATION(0)); - asn1_write_OID(asn1, OID_SPNEGO); - write_negTokenInit(asn1, &spnego->negTokenInit); - asn1_pop_tag(asn1); - break; - case SPNEGO_NEG_TOKEN_TARG: - write_negTokenTarg(asn1, &spnego->negTokenTarg); - break; - default: - asn1->has_error = True; - break; - } - - if (!asn1->has_error) { - *blob = data_blob(asn1->data, asn1->length); - ret = asn1->ofs; - } - asn1_free(asn1); - - return ret; -} - -bool free_spnego_data(SPNEGO_DATA *spnego) -{ - bool ret = True; - - if (!spnego) goto out; - - switch(spnego->type) { - case SPNEGO_NEG_TOKEN_INIT: - if (spnego->negTokenInit.mechTypes) { - int i; - for (i = 0; spnego->negTokenInit.mechTypes[i]; i++) { - talloc_free(CONST_DISCARD(char *,spnego->negTokenInit.mechTypes[i])); - } - talloc_free(spnego->negTokenInit.mechTypes); - } - data_blob_free(&spnego->negTokenInit.mechToken); - data_blob_free(&spnego->negTokenInit.mechListMIC); - break; - case SPNEGO_NEG_TOKEN_TARG: - if (spnego->negTokenTarg.supportedMech) { - talloc_free(spnego->negTokenTarg.supportedMech); - } - data_blob_free(&spnego->negTokenTarg.responseToken); - data_blob_free(&spnego->negTokenTarg.mechListMIC); - break; - default: - ret = False; - break; - } - ZERO_STRUCTP(spnego); -out: - return ret; -} diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 186696fbbcf..5392d1f78fe 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -23,6 +23,7 @@ #include "../librpc/gen_ndr/ndr_schannel.h" #include "../libcli/auth/schannel.h" #include "../libcli/auth/schannel_proto.h" +#include "../libcli/auth/spnego.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_CLI diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 627dac0f821..8611be49e31 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -32,6 +32,7 @@ #include "../librpc/gen_ndr/ndr_schannel.h" #include "../libcli/auth/schannel.h" #include "../libcli/auth/schannel_proto.h" +#include "../libcli/auth/spnego.h" extern struct current_user current_user; diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c index 85dc32447db..372f38eb574 100644 --- a/source3/smbd/negprot.c +++ b/source3/smbd/negprot.c @@ -20,6 +20,7 @@ #include "includes.h" #include "smbd/globals.h" +#include "../libcli/auth/spnego.h" extern fstring remote_proto; extern enum protocol_types Protocol; diff --git a/source3/smbd/seal.c b/source3/smbd/seal.c index 0d5415b5f48..2d738cbd129 100644 --- a/source3/smbd/seal.c +++ b/source3/smbd/seal.c @@ -19,6 +19,7 @@ #include "includes.h" #include "smbd/globals.h" +#include "../libcli/auth/spnego.h" /****************************************************************************** Server side encryption. diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 2d2e5141eeb..16ea2ebfa91 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -24,6 +24,7 @@ #include "includes.h" #include "smbd/globals.h" +#include "../libcli/auth/spnego.h" extern enum protocol_types Protocol; diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c index 4724516f2e4..dc24124b547 100644 --- a/source3/smbd/smb2_sesssetup.c +++ b/source3/smbd/smb2_sesssetup.c @@ -21,6 +21,7 @@ #include "includes.h" #include "smbd/globals.h" #include "../libcli/smb/smb_common.h" +#include "../libcli/auth/spnego.h" static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req, uint64_t in_session_id, diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 6de5ea67e43..a607cb06587 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -26,6 +26,7 @@ #include "includes.h" #include "utils/ntlm_auth.h" #include "../libcli/auth/libcli_auth.h" +#include "../libcli/auth/spnego.h" #include <iniparser.h> #ifndef PAM_WINBIND_CONFIG_FILE @@ -1113,7 +1114,7 @@ static void manage_squid_basic_request(struct ntlm_auth_state *state, static void offer_gss_spnego_mechs(void) { DATA_BLOB token; - SPNEGO_DATA spnego; + struct spnego_data spnego; ssize_t len; char *reply_base64; TALLOC_CTX *ctx = talloc_tos(); @@ -1149,8 +1150,8 @@ static void offer_gss_spnego_mechs(void) { spnego.negTokenInit.mechListMIC = data_blob(principal, strlen(principal)); - len = write_spnego_data(&token, &spnego); - free_spnego_data(&spnego); + len = spnego_write_data(ctx, &token, &spnego); + spnego_free_data(&spnego); if (len == -1) { DEBUG(1, ("Could not write SPNEGO data blob\n")); @@ -1171,7 +1172,7 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, char *buf, int length) { static NTLMSSP_STATE *ntlmssp_state = NULL; - SPNEGO_DATA request, response; + struct spnego_data request, response; DATA_BLOB token; NTSTATUS status; ssize_t len; @@ -1219,7 +1220,7 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, } token = base64_decode_data_blob(buf + 3); - len = read_spnego_data(token, &request); + len = spnego_read_data(ctx, token, &request); data_blob_free(&token); if (len == -1) { @@ -1367,7 +1368,7 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, } } - free_spnego_data(&request); + spnego_free_data(&request); if (NT_STATUS_IS_OK(status)) { response.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED; @@ -1393,8 +1394,8 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, SAFE_FREE(user); SAFE_FREE(domain); - len = write_spnego_data(&token, &response); - free_spnego_data(&response); + len = spnego_write_data(ctx, &token, &response); + spnego_free_data(&response); if (len == -1) { DEBUG(1, ("Could not write SPNEGO data blob\n")); @@ -1415,13 +1416,14 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, static NTLMSSP_STATE *client_ntlmssp_state = NULL; -static bool manage_client_ntlmssp_init(SPNEGO_DATA spnego) +static bool manage_client_ntlmssp_init(struct spnego_data spnego) { NTSTATUS status; DATA_BLOB null_blob = data_blob_null; DATA_BLOB to_server; char *to_server_base64; const char *my_mechs[] = {OID_NTLMSSP, NULL}; + TALLOC_CTX *ctx = talloc_tos(); DEBUG(10, ("Got spnego negTokenInit with NTLMSSP\n")); @@ -1466,7 +1468,7 @@ static bool manage_client_ntlmssp_init(SPNEGO_DATA spnego) return False; } - write_spnego_data(&to_server, &spnego); + spnego_write_data(ctx, &to_server, &spnego); data_blob_free(&spnego.negTokenInit.mechToken); to_server_base64 = base64_encode_data_blob(talloc_tos(), to_server); @@ -1476,13 +1478,14 @@ static bool manage_client_ntlmssp_init(SPNEGO_DATA spnego) return True; } -static void manage_client_ntlmssp_targ(SPNEGO_DATA spnego) +static void manage_client_ntlmssp_targ(struct spnego_data spnego) { NTSTATUS status; DATA_BLOB null_blob = data_blob_null; DATA_BLOB request; DATA_BLOB to_server; char *to_server_base64; + TALLOC_CTX *ctx = talloc_tos(); DEBUG(10, ("Got spnego negTokenTarg with NTLMSSP\n")); @@ -1525,7 +1528,7 @@ static void manage_client_ntlmssp_targ(SPNEGO_DATA spnego) spnego.negTokenTarg.responseToken = request; spnego.negTokenTarg.mechListMIC = null_blob; - write_spnego_data(&to_server, &spnego); + spnego_write_data(ctx, &to_server, &spnego); data_blob_free(&request); to_server_base64 = base64_encode_data_blob(talloc_tos(), to_server); @@ -1537,17 +1540,18 @@ static void manage_client_ntlmssp_targ(SPNEGO_DATA spnego) #ifdef HAVE_KRB5 -static bool manage_client_krb5_init(SPNEGO_DATA spnego) +static bool manage_client_krb5_init(struct spnego_data spnego) { char *principal; DATA_BLOB tkt, to_server; DATA_BLOB session_key_krb5 = data_blob_null; - SPNEGO_DATA reply; + struct spnego_data reply; char *reply_base64; int retval; const char *my_mechs[] = {OID_KERBEROS5_OLD, NULL}; ssize_t len; + TALLOC_CTX *ctx = talloc_tos(); if ( (spnego.negTokenInit.mechListMIC.data == NULL) || (spnego.negTokenInit.mechListMIC.length == 0) ) { @@ -1609,7 +1613,7 @@ static bool manage_client_krb5_init(SPNEGO_DATA spnego) reply.negTokenInit.mechToken = tkt; reply.negTokenInit.mechListMIC = data_blob_null; - len = write_spnego_data(&to_server, &reply); + len = spnego_write_data(ctx, &to_server, &reply); data_blob_free(&tkt); if (len == -1) { @@ -1626,7 +1630,7 @@ static bool manage_client_krb5_init(SPNEGO_DATA spnego) return True; } -static void manage_client_krb5_targ(SPNEGO_DATA spnego) +static void manage_client_krb5_targ(struct spnego_data spnego) { switch (spnego.negTokenTarg.negResult) { case SPNEGO_ACCEPT_INCOMPLETE: @@ -1654,8 +1658,9 @@ static void manage_gss_spnego_client_request(struct ntlm_auth_state *state, char *buf, int length) { DATA_BLOB request; - SPNEGO_DATA spnego; + struct spnego_data spnego; ssize_t len; + TALLOC_CTX *ctx = talloc_tos(); if (!opt_username || !*opt_username) { x_fprintf(x_stderr, "username must be specified!\n\n"); @@ -1700,7 +1705,7 @@ static void manage_gss_spnego_client_request(struct ntlm_auth_state *state, /* So we got a server challenge to generate a SPNEGO client-to-server request... */ - len = read_spnego_data(request, &spnego); + len = spnego_read_data(ctx, request, &spnego); data_blob_free(&request); if (len == -1) { @@ -1786,7 +1791,7 @@ static void manage_gss_spnego_client_request(struct ntlm_auth_state *state, return; out: - free_spnego_data(&spnego); + spnego_free_data(&spnego); return; } diff --git a/source4/auth/gensec/config.mk b/source4/auth/gensec/config.mk index 84314f54e2e..105a58b4aeb 100644 --- a/source4/auth/gensec/config.mk +++ b/source4/auth/gensec/config.mk @@ -58,7 +58,7 @@ PRIVATE_DEPENDENCIES = ASN1_UTIL CREDENTIALS # End MODULE gensec_spnego ################################################ -gensec_spnego_OBJ_FILES = $(addprefix $(gensecsrcdir)/, spnego.o spnego_parse.o) +gensec_spnego_OBJ_FILES = $(addprefix $(gensecsrcdir)/, spnego.o) ../libcli/auth/spnego_parse.o $(eval $(call proto_header_template,$(gensecsrcdir)/spnego_proto.h,$(gensec_spnego_OBJ_FILES:.o=.c))) diff --git a/source4/auth/gensec/spnego.c b/source4/auth/gensec/spnego.c index b3567202c16..8f06eab8bbe 100644 --- a/source4/auth/gensec/spnego.c +++ b/source4/auth/gensec/spnego.c @@ -23,7 +23,7 @@ */ #include "includes.h" -#include "auth/gensec/spnego.h" +#include "../libcli/auth/spnego.h" #include "librpc/gen_ndr/ndr_dcerpc.h" #include "auth/credentials/credentials.h" #include "auth/gensec/gensec.h" |