1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-23 09:57:40 +03:00

spnego: share spnego_parse.

Guenther
This commit is contained in:
Günther Deschner 2009-09-17 00:21:01 +02:00
parent 83023462f9
commit 503d035814
21 changed files with 71 additions and 496 deletions

View File

@ -1,4 +1,4 @@
/* /*
Unix SMB/CIFS implementation. Unix SMB/CIFS implementation.
RFC2478 Compliant SPNEGO implementation RFC2478 Compliant SPNEGO implementation
@ -9,17 +9,22 @@
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or the Free Software Foundation; either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. 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_DELEG_FLAG 0x01
#define SPNEGO_MUTUAL_FLAG 0x02 #define SPNEGO_MUTUAL_FLAG 0x02
#define SPNEGO_REPLAY_FLAG 0x04 #define SPNEGO_REPLAY_FLAG 0x04
@ -58,7 +63,7 @@ struct spnego_data {
}; };
enum spnego_message_type { enum spnego_message_type {
SPNEGO_NEG_TOKEN_INIT = 0, SPNEGO_NEG_TOKEN_INIT = 0,
SPNEGO_NEG_TOKEN_TARG = 1, SPNEGO_NEG_TOKEN_TARG = 1,
}; };

View File

@ -1,4 +1,4 @@
/* /*
Unix SMB/CIFS implementation. Unix SMB/CIFS implementation.
RFC2478 Compliant SPNEGO implementation RFC2478 Compliant SPNEGO implementation
@ -9,20 +9,19 @@
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or the Free Software Foundation; either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "includes.h" #include "includes.h"
#include "auth/gensec/spnego.h" #include "../libcli/auth/spnego.h"
#include "auth/gensec/gensec.h"
#include "../lib/util/asn1.h" #include "../lib/util/asn1.h"
static bool read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx, 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 *); token->mechTypes = talloc(NULL, const char *);
for (i = 0; !asn1->has_error && for (i = 0; !asn1->has_error &&
0 < asn1_tag_remaining(asn1); i++) { 0 < asn1_tag_remaining(asn1); i++) {
token->mechTypes = talloc_realloc(NULL, token->mechTypes = talloc_realloc(NULL,
token->mechTypes, token->mechTypes,
const char *, i+2); const char *, i+2);
asn1_read_OID(asn1, token->mechTypes, token->mechTypes + i); asn1_read_OID(asn1, token->mechTypes, token->mechTypes + i);
} }
token->mechTypes[i] = NULL; token->mechTypes[i] = NULL;
asn1_end_tag(asn1); asn1_end_tag(asn1);
asn1_end_tag(asn1); asn1_end_tag(asn1);
break; break;
@ -83,7 +82,7 @@ static bool read_negTokenInit(struct asn1_data *asn1, TALLOC_CTX *mem_ctx,
break; break;
} }
if (type_peek == ASN1_OCTET_STRING) { if (type_peek == ASN1_OCTET_STRING) {
asn1_read_OctetString(asn1, mem_ctx, asn1_read_OctetString(asn1, mem_ctx,
&token->mechListMIC); &token->mechListMIC);
} else { } else {
/* RFC 2478 says we have an Octet String here, /* 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); asn1_pop_tag(asn1);
asn1_pop_tag(asn1); asn1_pop_tag(asn1);
#endif #endif
asn1_pop_tag(asn1); asn1_pop_tag(asn1);
} }
@ -175,7 +174,7 @@ static bool write_negTokenInit(struct asn1_data *asn1, struct spnego_negTokenIni
return !asn1->has_error; 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) struct spnego_negTokenTarg *token)
{ {
ZERO_STRUCTP(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) { switch (context) {
case ASN1_APPLICATION(0): case ASN1_APPLICATION(0):
asn1_start_tag(asn1, 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)) { if (read_negTokenInit(asn1, mem_ctx, &token->negTokenInit)) {
token->type = SPNEGO_NEG_TOKEN_INIT; 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) { switch (spnego->type) {
case SPNEGO_NEG_TOKEN_INIT: case SPNEGO_NEG_TOKEN_INIT:
asn1_push_tag(asn1, ASN1_APPLICATION(0)); 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); write_negTokenInit(asn1, &spnego->negTokenInit);
asn1_pop_tag(asn1); asn1_pop_tag(asn1);
break; break;

View File

@ -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_OBJ1 = utils/ntlm_auth.o utils/ntlm_auth_diagnostics.o
NTLM_AUTH_OBJ = ${NTLM_AUTH_OBJ1} $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) \ 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) \ $(LIBADS_SERVER_OBJ) \
$(PASSDB_OBJ) $(LIBTSOCKET_OBJ) $(GROUPDB_OBJ) \ $(PASSDB_OBJ) $(LIBTSOCKET_OBJ) $(GROUPDB_OBJ) \
$(SMBLDAP_OBJ) $(LIBNMB_OBJ) \ $(SMBLDAP_OBJ) $(LIBNMB_OBJ) \

View File

@ -8,6 +8,12 @@
#include "../libds/common/flags.h" #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 { enum wb_posix_mapping {
WB_POSIX_MAP_UNKNOWN = -1, WB_POSIX_MAP_UNKNOWN = -1,
WB_POSIX_MAP_TEMPLATE = 0, WB_POSIX_MAP_TEMPLATE = 0,

View File

@ -688,7 +688,6 @@ struct smb_iconv_convenience *lp_iconv_convenience(void *lp_ctx);
#include "mangle.h" #include "mangle.h"
#include "module.h" #include "module.h"
#include "nsswitch/winbind_client.h" #include "nsswitch/winbind_client.h"
#include "spnego.h"
#include "rpc_client.h" #include "rpc_client.h"
#include "dbwrap.h" #include "dbwrap.h"
#include "packet.h" #include "packet.h"

View File

@ -3297,12 +3297,6 @@ const char *smb_dos_err_class(uint8 e_class);
char *smb_dos_errstr(char *inbuf); char *smb_dos_errstr(char *inbuf);
WERROR map_werror_from_unix(int error); 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 */ /* The following definitions come from libsmb/trustdom_cache.c */
bool trustdom_cache_enable(void); bool trustdom_cache_enable(void);

View File

@ -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

View File

@ -18,6 +18,7 @@
*/ */
#include "includes.h" #include "includes.h"
#include "../libcli/auth/spnego.h"
#ifdef HAVE_LDAP #ifdef HAVE_LDAP

View File

@ -20,6 +20,7 @@
#include "includes.h" #include "includes.h"
#include "../libcli/auth/libcli_auth.h" #include "../libcli/auth/libcli_auth.h"
#include "../libcli/auth/spnego.h"
static const struct { static const struct {
int prot; int prot;

View File

@ -19,6 +19,7 @@
*/ */
#include "includes.h" #include "includes.h"
#include "../libcli/auth/spnego.h"
/**************************************************************************** /****************************************************************************
Get UNIX extensions version info. Get UNIX extensions version info.

View File

@ -20,6 +20,7 @@
*/ */
#include "includes.h" #include "includes.h"
#include "../libcli/auth/spnego.h"
/* /*
generate a negTokenInit packet given a GUID, a list of supported 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; uint8 negResult;
if (NT_STATUS_IS_OK(nt_status)) { 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)) { } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
negResult = SPNEGO_NEG_RESULT_INCOMPLETE; negResult = SPNEGO_ACCEPT_INCOMPLETE;
} else { } else {
negResult = SPNEGO_NEG_RESULT_REJECT; negResult = SPNEGO_REJECT;
} }
data = asn1_init(talloc_tos()); data = asn1_init(talloc_tos());
@ -581,11 +582,11 @@ bool spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status,
uint8 negResult; uint8 negResult;
if (NT_STATUS_IS_OK(nt_status)) { 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)) { } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
negResult = SPNEGO_NEG_RESULT_INCOMPLETE; negResult = SPNEGO_ACCEPT_INCOMPLETE;
} else { } else {
negResult = SPNEGO_NEG_RESULT_REJECT; negResult = SPNEGO_REJECT;
} }
data = asn1_init(talloc_tos()); 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_read_OctetString(data, talloc_autofree_context(), auth);
asn1_end_tag(data); asn1_end_tag(data);
} }
} else if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) { } else if (negResult == SPNEGO_ACCEPT_INCOMPLETE) {
data->has_error = 1; data->has_error = 1;
} }

View File

@ -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;
}

View File

@ -23,6 +23,7 @@
#include "../librpc/gen_ndr/ndr_schannel.h" #include "../librpc/gen_ndr/ndr_schannel.h"
#include "../libcli/auth/schannel.h" #include "../libcli/auth/schannel.h"
#include "../libcli/auth/schannel_proto.h" #include "../libcli/auth/schannel_proto.h"
#include "../libcli/auth/spnego.h"
#undef DBGC_CLASS #undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_CLI #define DBGC_CLASS DBGC_RPC_CLI

View File

@ -32,6 +32,7 @@
#include "../librpc/gen_ndr/ndr_schannel.h" #include "../librpc/gen_ndr/ndr_schannel.h"
#include "../libcli/auth/schannel.h" #include "../libcli/auth/schannel.h"
#include "../libcli/auth/schannel_proto.h" #include "../libcli/auth/schannel_proto.h"
#include "../libcli/auth/spnego.h"
extern struct current_user current_user; extern struct current_user current_user;

View File

@ -20,6 +20,7 @@
#include "includes.h" #include "includes.h"
#include "smbd/globals.h" #include "smbd/globals.h"
#include "../libcli/auth/spnego.h"
extern fstring remote_proto; extern fstring remote_proto;
extern enum protocol_types Protocol; extern enum protocol_types Protocol;

View File

@ -19,6 +19,7 @@
#include "includes.h" #include "includes.h"
#include "smbd/globals.h" #include "smbd/globals.h"
#include "../libcli/auth/spnego.h"
/****************************************************************************** /******************************************************************************
Server side encryption. Server side encryption.

View File

@ -24,6 +24,7 @@
#include "includes.h" #include "includes.h"
#include "smbd/globals.h" #include "smbd/globals.h"
#include "../libcli/auth/spnego.h"
extern enum protocol_types Protocol; extern enum protocol_types Protocol;

View File

@ -21,6 +21,7 @@
#include "includes.h" #include "includes.h"
#include "smbd/globals.h" #include "smbd/globals.h"
#include "../libcli/smb/smb_common.h" #include "../libcli/smb/smb_common.h"
#include "../libcli/auth/spnego.h"
static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req, static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req,
uint64_t in_session_id, uint64_t in_session_id,

View File

@ -26,6 +26,7 @@
#include "includes.h" #include "includes.h"
#include "utils/ntlm_auth.h" #include "utils/ntlm_auth.h"
#include "../libcli/auth/libcli_auth.h" #include "../libcli/auth/libcli_auth.h"
#include "../libcli/auth/spnego.h"
#include <iniparser.h> #include <iniparser.h>
#ifndef PAM_WINBIND_CONFIG_FILE #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) { static void offer_gss_spnego_mechs(void) {
DATA_BLOB token; DATA_BLOB token;
SPNEGO_DATA spnego; struct spnego_data spnego;
ssize_t len; ssize_t len;
char *reply_base64; char *reply_base64;
TALLOC_CTX *ctx = talloc_tos(); TALLOC_CTX *ctx = talloc_tos();
@ -1149,8 +1150,8 @@ static void offer_gss_spnego_mechs(void) {
spnego.negTokenInit.mechListMIC = data_blob(principal, spnego.negTokenInit.mechListMIC = data_blob(principal,
strlen(principal)); strlen(principal));
len = write_spnego_data(&token, &spnego); len = spnego_write_data(ctx, &token, &spnego);
free_spnego_data(&spnego); spnego_free_data(&spnego);
if (len == -1) { if (len == -1) {
DEBUG(1, ("Could not write SPNEGO data blob\n")); 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) char *buf, int length)
{ {
static NTLMSSP_STATE *ntlmssp_state = NULL; static NTLMSSP_STATE *ntlmssp_state = NULL;
SPNEGO_DATA request, response; struct spnego_data request, response;
DATA_BLOB token; DATA_BLOB token;
NTSTATUS status; NTSTATUS status;
ssize_t len; 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); token = base64_decode_data_blob(buf + 3);
len = read_spnego_data(token, &request); len = spnego_read_data(ctx, token, &request);
data_blob_free(&token); data_blob_free(&token);
if (len == -1) { 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)) { if (NT_STATUS_IS_OK(status)) {
response.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED; 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(user);
SAFE_FREE(domain); SAFE_FREE(domain);
len = write_spnego_data(&token, &response); len = spnego_write_data(ctx, &token, &response);
free_spnego_data(&response); spnego_free_data(&response);
if (len == -1) { if (len == -1) {
DEBUG(1, ("Could not write SPNEGO data blob\n")); 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 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; NTSTATUS status;
DATA_BLOB null_blob = data_blob_null; DATA_BLOB null_blob = data_blob_null;
DATA_BLOB to_server; DATA_BLOB to_server;
char *to_server_base64; char *to_server_base64;
const char *my_mechs[] = {OID_NTLMSSP, NULL}; const char *my_mechs[] = {OID_NTLMSSP, NULL};
TALLOC_CTX *ctx = talloc_tos();
DEBUG(10, ("Got spnego negTokenInit with NTLMSSP\n")); DEBUG(10, ("Got spnego negTokenInit with NTLMSSP\n"));
@ -1466,7 +1468,7 @@ static bool manage_client_ntlmssp_init(SPNEGO_DATA spnego)
return False; return False;
} }
write_spnego_data(&to_server, &spnego); spnego_write_data(ctx, &to_server, &spnego);
data_blob_free(&spnego.negTokenInit.mechToken); data_blob_free(&spnego.negTokenInit.mechToken);
to_server_base64 = base64_encode_data_blob(talloc_tos(), to_server); 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; return True;
} }
static void manage_client_ntlmssp_targ(SPNEGO_DATA spnego) static void manage_client_ntlmssp_targ(struct spnego_data spnego)
{ {
NTSTATUS status; NTSTATUS status;
DATA_BLOB null_blob = data_blob_null; DATA_BLOB null_blob = data_blob_null;
DATA_BLOB request; DATA_BLOB request;
DATA_BLOB to_server; DATA_BLOB to_server;
char *to_server_base64; char *to_server_base64;
TALLOC_CTX *ctx = talloc_tos();
DEBUG(10, ("Got spnego negTokenTarg with NTLMSSP\n")); 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.responseToken = request;
spnego.negTokenTarg.mechListMIC = null_blob; spnego.negTokenTarg.mechListMIC = null_blob;
write_spnego_data(&to_server, &spnego); spnego_write_data(ctx, &to_server, &spnego);
data_blob_free(&request); data_blob_free(&request);
to_server_base64 = base64_encode_data_blob(talloc_tos(), to_server); 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 #ifdef HAVE_KRB5
static bool manage_client_krb5_init(SPNEGO_DATA spnego) static bool manage_client_krb5_init(struct spnego_data spnego)
{ {
char *principal; char *principal;
DATA_BLOB tkt, to_server; DATA_BLOB tkt, to_server;
DATA_BLOB session_key_krb5 = data_blob_null; DATA_BLOB session_key_krb5 = data_blob_null;
SPNEGO_DATA reply; struct spnego_data reply;
char *reply_base64; char *reply_base64;
int retval; int retval;
const char *my_mechs[] = {OID_KERBEROS5_OLD, NULL}; const char *my_mechs[] = {OID_KERBEROS5_OLD, NULL};
ssize_t len; ssize_t len;
TALLOC_CTX *ctx = talloc_tos();
if ( (spnego.negTokenInit.mechListMIC.data == NULL) || if ( (spnego.negTokenInit.mechListMIC.data == NULL) ||
(spnego.negTokenInit.mechListMIC.length == 0) ) { (spnego.negTokenInit.mechListMIC.length == 0) ) {
@ -1609,7 +1613,7 @@ static bool manage_client_krb5_init(SPNEGO_DATA spnego)
reply.negTokenInit.mechToken = tkt; reply.negTokenInit.mechToken = tkt;
reply.negTokenInit.mechListMIC = data_blob_null; 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); data_blob_free(&tkt);
if (len == -1) { if (len == -1) {
@ -1626,7 +1630,7 @@ static bool manage_client_krb5_init(SPNEGO_DATA spnego)
return True; 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) { switch (spnego.negTokenTarg.negResult) {
case SPNEGO_ACCEPT_INCOMPLETE: case SPNEGO_ACCEPT_INCOMPLETE:
@ -1654,8 +1658,9 @@ static void manage_gss_spnego_client_request(struct ntlm_auth_state *state,
char *buf, int length) char *buf, int length)
{ {
DATA_BLOB request; DATA_BLOB request;
SPNEGO_DATA spnego; struct spnego_data spnego;
ssize_t len; ssize_t len;
TALLOC_CTX *ctx = talloc_tos();
if (!opt_username || !*opt_username) { if (!opt_username || !*opt_username) {
x_fprintf(x_stderr, "username must be specified!\n\n"); 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 /* So we got a server challenge to generate a SPNEGO
client-to-server request... */ client-to-server request... */
len = read_spnego_data(request, &spnego); len = spnego_read_data(ctx, request, &spnego);
data_blob_free(&request); data_blob_free(&request);
if (len == -1) { if (len == -1) {
@ -1786,7 +1791,7 @@ static void manage_gss_spnego_client_request(struct ntlm_auth_state *state,
return; return;
out: out:
free_spnego_data(&spnego); spnego_free_data(&spnego);
return; return;
} }

View File

@ -58,7 +58,7 @@ PRIVATE_DEPENDENCIES = ASN1_UTIL CREDENTIALS
# End MODULE gensec_spnego # 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))) $(eval $(call proto_header_template,$(gensecsrcdir)/spnego_proto.h,$(gensec_spnego_OBJ_FILES:.o=.c)))

View File

@ -23,7 +23,7 @@
*/ */
#include "includes.h" #include "includes.h"
#include "auth/gensec/spnego.h" #include "../libcli/auth/spnego.h"
#include "librpc/gen_ndr/ndr_dcerpc.h" #include "librpc/gen_ndr/ndr_dcerpc.h"
#include "auth/credentials/credentials.h" #include "auth/credentials/credentials.h"
#include "auth/gensec/gensec.h" #include "auth/gensec/gensec.h"