From 503d0358140fbf56bd83090f143272aeb770baa9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 17 Sep 2009 00:21:01 +0200 Subject: spnego: share spnego_parse. Guenther --- source3/libsmb/cliconnect.c | 1 + source3/libsmb/clifsinfo.c | 1 + source3/libsmb/clispnego.c | 15 +- source3/libsmb/spnego.c | 362 -------------------------------------------- 4 files changed, 10 insertions(+), 369 deletions(-) delete mode 100644 source3/libsmb/spnego.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 600f8d1b4a..2535de2847 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 e0ae948aaf..308a6f7215 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 74dba56aec..5d7e43d941 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 528c7f4009..0000000000 --- a/source3/libsmb/spnego.c +++ /dev/null @@ -1,362 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - RFC2478 Compliant SPNEGO implementation - - Copyright (C) Jim McDonough 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 . -*/ - -#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; -} -- cgit