2009-09-17 02:21:01 +04:00
/*
2004-06-20 04:58:09 +04:00
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
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2004-06-20 04:58:09 +04:00
( at your option ) any later version .
2009-09-17 02:21:01 +04:00
2004-06-20 04:58:09 +04:00
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 .
2009-09-17 02:21:01 +04:00
2004-06-20 04:58:09 +04:00
You should have received a copy of the GNU General Public License
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2004-06-20 04:58:09 +04:00
*/
# include "includes.h"
2009-09-17 02:21:01 +04:00
# include "../libcli/auth/spnego.h"
2008-10-11 23:31:42 +04:00
# include "../lib/util/asn1.h"
2004-06-20 04:58:09 +04:00
2007-10-07 02:16:19 +04:00
static bool read_negTokenInit ( struct asn1_data * asn1 , TALLOC_CTX * mem_ctx ,
2007-05-21 10:12:06 +04:00
struct spnego_negTokenInit * token )
2004-06-20 04:58:09 +04:00
{
ZERO_STRUCTP ( token ) ;
2014-09-20 00:42:39 +04:00
if ( ! asn1_start_tag ( asn1 , ASN1_CONTEXT ( 0 ) ) ) return false ;
if ( ! asn1_start_tag ( asn1 , ASN1_SEQUENCE ( 0 ) ) ) return false ;
2004-06-20 04:58:09 +04:00
2016-01-02 20:11:00 +03:00
while ( ! asn1_has_error ( asn1 ) & & 0 < asn1_tag_remaining ( asn1 ) ) {
2004-06-20 04:58:09 +04:00
int i ;
2004-07-06 05:28:12 +04:00
uint8_t context ;
2014-09-20 00:42:39 +04:00
2004-07-06 05:28:12 +04:00
if ( ! asn1_peek_uint8 ( asn1 , & context ) ) {
2016-01-04 23:51:07 +03:00
asn1_set_error ( asn1 ) ;
2004-07-06 05:28:12 +04:00
break ;
}
2004-06-20 04:58:09 +04:00
2004-07-06 05:28:12 +04:00
switch ( context ) {
2004-06-20 04:58:09 +04:00
/* Read mechTypes */
2013-08-05 12:46:47 +04:00
case ASN1_CONTEXT ( 0 ) : {
const char * * mechTypes ;
2014-09-20 00:42:39 +04:00
if ( ! asn1_start_tag ( asn1 , ASN1_CONTEXT ( 0 ) ) ) return false ;
if ( ! asn1_start_tag ( asn1 , ASN1_SEQUENCE ( 0 ) ) ) return false ;
2004-06-20 04:58:09 +04:00
2013-08-05 12:46:47 +04:00
mechTypes = talloc ( mem_ctx , const char * ) ;
if ( mechTypes = = NULL ) {
2016-01-04 23:51:07 +03:00
asn1_set_error ( asn1 ) ;
2013-08-05 12:43:38 +04:00
return false ;
}
2016-01-02 20:11:00 +03:00
for ( i = 0 ; ! asn1_has_error ( asn1 ) & &
2004-06-20 04:58:09 +04:00
0 < asn1_tag_remaining ( asn1 ) ; i + + ) {
2010-12-15 19:17:09 +03:00
char * oid ;
2013-08-05 12:43:38 +04:00
const char * * p ;
p = talloc_realloc ( mem_ctx ,
2013-08-05 12:46:47 +04:00
mechTypes ,
2013-08-05 12:43:38 +04:00
const char * , i + 2 ) ;
if ( p = = NULL ) {
2013-08-05 12:46:47 +04:00
talloc_free ( mechTypes ) ;
2016-01-04 23:51:07 +03:00
asn1_set_error ( asn1 ) ;
2013-08-05 12:43:38 +04:00
return false ;
}
2013-08-05 12:46:47 +04:00
mechTypes = p ;
2014-09-20 00:42:39 +04:00
if ( ! asn1_read_OID ( asn1 , mechTypes , & oid ) ) return false ;
2013-08-05 12:46:47 +04:00
mechTypes [ i ] = oid ;
2004-06-20 04:58:09 +04:00
}
2013-08-05 12:46:47 +04:00
mechTypes [ i ] = NULL ;
token - > mechTypes = mechTypes ;
2009-09-17 02:21:01 +04:00
2004-06-20 04:58:09 +04:00
asn1_end_tag ( asn1 ) ;
asn1_end_tag ( asn1 ) ;
break ;
2013-08-05 12:46:47 +04:00
}
2004-06-20 04:58:09 +04:00
/* Read reqFlags */
case ASN1_CONTEXT ( 1 ) :
2014-09-20 00:42:39 +04:00
if ( ! asn1_start_tag ( asn1 , ASN1_CONTEXT ( 1 ) ) ) return false ;
if ( ! asn1_read_BitString ( asn1 , mem_ctx , & token - > reqFlags ,
& token - > reqFlagsPadding ) ) return false ;
if ( ! asn1_end_tag ( asn1 ) ) return false ;
2004-06-20 04:58:09 +04:00
break ;
/* Read mechToken */
case ASN1_CONTEXT ( 2 ) :
2014-09-20 00:42:39 +04:00
if ( ! asn1_start_tag ( asn1 , ASN1_CONTEXT ( 2 ) ) ) return false ;
if ( ! asn1_read_OctetString ( asn1 , mem_ctx , & token - > mechToken ) ) return false ;
if ( ! asn1_end_tag ( asn1 ) ) return false ;
2004-06-20 04:58:09 +04:00
break ;
/* Read mecListMIC */
case ASN1_CONTEXT ( 3 ) :
2004-07-06 05:28:12 +04:00
{
uint8_t type_peek ;
2014-09-20 00:42:39 +04:00
if ( ! asn1_start_tag ( asn1 , ASN1_CONTEXT ( 3 ) ) ) return false ;
2004-07-06 05:28:12 +04:00
if ( ! asn1_peek_uint8 ( asn1 , & type_peek ) ) {
2016-01-04 23:51:07 +03:00
asn1_set_error ( asn1 ) ;
2004-07-06 05:28:12 +04:00
break ;
}
if ( type_peek = = ASN1_OCTET_STRING ) {
2014-09-20 00:42:39 +04:00
if ( ! asn1_read_OctetString ( asn1 , mem_ctx ,
& token - > mechListMIC ) ) return false ;
2004-06-20 04:58:09 +04:00
} else {
/* RFC 2478 says we have an Octet String here,
but W2k sends something different . . . */
char * mechListMIC ;
2014-09-20 00:42:39 +04:00
if ( ! asn1_start_tag ( asn1 , ASN1_SEQUENCE ( 0 ) ) ) return false ;
if ( ! asn1_start_tag ( asn1 , ASN1_CONTEXT ( 0 ) ) ) return false ;
if ( ! asn1_read_GeneralString ( asn1 , mem_ctx , & mechListMIC ) ) return false ;
if ( ! asn1_end_tag ( asn1 ) ) return false ;
if ( ! asn1_end_tag ( asn1 ) ) return false ;
2004-06-20 04:58:09 +04:00
2004-07-11 14:20:42 +04:00
token - > targetPrincipal = mechListMIC ;
2004-06-20 04:58:09 +04:00
}
2014-09-20 00:42:39 +04:00
if ( ! asn1_end_tag ( asn1 ) ) return false ;
2004-06-20 04:58:09 +04:00
break ;
2004-07-06 05:28:12 +04:00
}
2004-06-20 04:58:09 +04:00
default :
2016-01-04 23:51:07 +03:00
asn1_set_error ( asn1 ) ;
2004-06-20 04:58:09 +04:00
break ;
}
}
2014-09-20 00:42:39 +04:00
if ( ! asn1_end_tag ( asn1 ) ) return false ;
if ( ! asn1_end_tag ( asn1 ) ) return false ;
2004-06-20 04:58:09 +04:00
2016-01-02 20:11:00 +03:00
return ! asn1_has_error ( asn1 ) ;
2004-06-20 04:58:09 +04:00
}
2007-10-07 02:16:19 +04:00
static bool write_negTokenInit ( struct asn1_data * asn1 , struct spnego_negTokenInit * token )
2004-06-20 04:58:09 +04:00
{
2014-09-20 00:42:39 +04:00
if ( ! asn1_push_tag ( asn1 , ASN1_CONTEXT ( 0 ) ) ) return false ;
if ( ! asn1_push_tag ( asn1 , ASN1_SEQUENCE ( 0 ) ) ) return false ;
2004-06-20 04:58:09 +04:00
/* Write mechTypes */
if ( token - > mechTypes & & * token - > mechTypes ) {
int i ;
2014-09-20 00:42:39 +04:00
if ( ! asn1_push_tag ( asn1 , ASN1_CONTEXT ( 0 ) ) ) return false ;
if ( ! asn1_push_tag ( asn1 , ASN1_SEQUENCE ( 0 ) ) ) return false ;
2004-06-20 04:58:09 +04:00
for ( i = 0 ; token - > mechTypes [ i ] ; i + + ) {
2014-09-20 00:42:39 +04:00
if ( ! asn1_write_OID ( asn1 , token - > mechTypes [ i ] ) ) return false ;
2004-06-20 04:58:09 +04:00
}
2014-09-20 00:42:39 +04:00
if ( ! asn1_pop_tag ( asn1 ) ) return false ;
if ( ! asn1_pop_tag ( asn1 ) ) return false ;
2004-06-20 04:58:09 +04:00
}
/* write reqFlags */
2009-08-13 10:12:01 +04:00
if ( token - > reqFlags . length > 0 ) {
2014-09-20 00:42:39 +04:00
if ( ! asn1_push_tag ( asn1 , ASN1_CONTEXT ( 1 ) ) ) return false ;
if ( ! asn1_write_BitString ( asn1 , token - > reqFlags . data ,
2009-08-13 10:12:01 +04:00
token - > reqFlags . length ,
2014-09-20 00:42:39 +04:00
token - > reqFlagsPadding ) ) return false ;
if ( ! asn1_pop_tag ( asn1 ) ) return false ;
2004-06-20 04:58:09 +04:00
}
/* write mechToken */
if ( token - > mechToken . data ) {
2014-09-20 00:42:39 +04:00
if ( ! asn1_push_tag ( asn1 , ASN1_CONTEXT ( 2 ) ) ) return false ;
if ( ! asn1_write_OctetString ( asn1 , token - > mechToken . data ,
token - > mechToken . length ) ) return false ;
if ( ! asn1_pop_tag ( asn1 ) ) return false ;
2004-06-20 04:58:09 +04:00
}
/* write mechListMIC */
if ( token - > mechListMIC . data ) {
2014-09-20 00:42:39 +04:00
if ( ! asn1_push_tag ( asn1 , ASN1_CONTEXT ( 3 ) ) ) return false ;
2004-06-20 04:58:09 +04:00
#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 */
2014-09-20 00:42:39 +04:00
if ( ! asn1_push_tag ( asn1 , ASN1_SEQUENCE ( 0 ) ) ) return false ;
if ( ! asn1_push_tag ( asn1 , ASN1_CONTEXT ( 0 ) ) ) return false ;
if ( ! asn1_push_tag ( asn1 , ASN1_GENERAL_STRING ) ) return false ;
if ( ! asn1_write ( asn1 , token - > mechListMIC . data ,
token - > mechListMIC . length ) ) return false ;
if ( ! asn1_pop_tag ( asn1 ) ) return false ;
if ( ! asn1_pop_tag ( asn1 ) ) return false ;
if ( ! asn1_pop_tag ( asn1 ) ) return false ;
2009-09-17 02:21:01 +04:00
# endif
2014-09-20 00:42:39 +04:00
if ( ! asn1_pop_tag ( asn1 ) ) return false ;
2004-06-20 04:58:09 +04:00
}
2014-09-20 00:42:39 +04:00
if ( ! asn1_pop_tag ( asn1 ) ) return false ;
if ( ! asn1_pop_tag ( asn1 ) ) return false ;
2004-06-20 04:58:09 +04:00
2016-01-02 20:11:00 +03:00
return ! asn1_has_error ( asn1 ) ;
2004-06-20 04:58:09 +04:00
}
2009-09-17 02:21:01 +04:00
static bool read_negTokenTarg ( struct asn1_data * asn1 , TALLOC_CTX * mem_ctx ,
2007-05-21 10:12:06 +04:00
struct spnego_negTokenTarg * token )
2004-06-20 04:58:09 +04:00
{
ZERO_STRUCTP ( token ) ;
2014-09-20 00:42:39 +04:00
if ( ! asn1_start_tag ( asn1 , ASN1_CONTEXT ( 1 ) ) ) return false ;
if ( ! asn1_start_tag ( asn1 , ASN1_SEQUENCE ( 0 ) ) ) return false ;
2004-06-20 04:58:09 +04:00
2016-01-02 20:11:00 +03:00
while ( ! asn1_has_error ( asn1 ) & & 0 < asn1_tag_remaining ( asn1 ) ) {
2004-07-06 05:28:12 +04:00
uint8_t context ;
2010-12-15 19:17:09 +03:00
char * oid ;
2004-07-06 05:28:12 +04:00
if ( ! asn1_peek_uint8 ( asn1 , & context ) ) {
2016-01-04 23:51:07 +03:00
asn1_set_error ( asn1 ) ;
2004-07-06 05:28:12 +04:00
break ;
}
switch ( context ) {
2004-06-20 04:58:09 +04:00
case ASN1_CONTEXT ( 0 ) :
2014-09-20 00:42:39 +04:00
if ( ! asn1_start_tag ( asn1 , ASN1_CONTEXT ( 0 ) ) ) return false ;
if ( ! asn1_start_tag ( asn1 , ASN1_ENUMERATED ) ) return false ;
if ( ! asn1_read_uint8 ( asn1 , & token - > negResult ) ) return false ;
if ( ! asn1_end_tag ( asn1 ) ) return false ;
if ( ! asn1_end_tag ( asn1 ) ) return false ;
2004-06-20 04:58:09 +04:00
break ;
case ASN1_CONTEXT ( 1 ) :
2014-09-20 00:42:39 +04:00
if ( ! asn1_start_tag ( asn1 , ASN1_CONTEXT ( 1 ) ) ) return false ;
if ( ! asn1_read_OID ( asn1 , mem_ctx , & oid ) ) return false ;
2010-12-15 19:17:09 +03:00
token - > supportedMech = oid ;
2014-09-20 00:42:39 +04:00
if ( ! asn1_end_tag ( asn1 ) ) return false ;
2004-06-20 04:58:09 +04:00
break ;
case ASN1_CONTEXT ( 2 ) :
2014-09-20 00:42:39 +04:00
if ( ! asn1_start_tag ( asn1 , ASN1_CONTEXT ( 2 ) ) ) return false ;
if ( ! asn1_read_OctetString ( asn1 , mem_ctx , & token - > responseToken ) ) return false ;
if ( ! asn1_end_tag ( asn1 ) ) return false ;
2004-06-20 04:58:09 +04:00
break ;
case ASN1_CONTEXT ( 3 ) :
2014-09-20 00:42:39 +04:00
if ( ! asn1_start_tag ( asn1 , ASN1_CONTEXT ( 3 ) ) ) return false ;
if ( ! asn1_read_OctetString ( asn1 , mem_ctx , & token - > mechListMIC ) ) return false ;
if ( ! asn1_end_tag ( asn1 ) ) return false ;
2004-06-20 04:58:09 +04:00
break ;
default :
2016-01-04 23:51:07 +03:00
asn1_set_error ( asn1 ) ;
2004-06-20 04:58:09 +04:00
break ;
}
}
2014-09-20 00:42:39 +04:00
if ( ! asn1_end_tag ( asn1 ) ) return false ;
if ( ! asn1_end_tag ( asn1 ) ) return false ;
2004-06-20 04:58:09 +04:00
2016-01-02 20:11:00 +03:00
return ! asn1_has_error ( asn1 ) ;
2004-06-20 04:58:09 +04:00
}
2007-10-07 02:16:19 +04:00
static bool write_negTokenTarg ( struct asn1_data * asn1 , struct spnego_negTokenTarg * token )
2004-06-20 04:58:09 +04:00
{
2014-09-20 00:42:39 +04:00
if ( ! asn1_push_tag ( asn1 , ASN1_CONTEXT ( 1 ) ) ) return false ;
if ( ! asn1_push_tag ( asn1 , ASN1_SEQUENCE ( 0 ) ) ) return false ;
2004-06-20 04:58:09 +04:00
2004-10-27 16:59:41 +04:00
if ( token - > negResult ! = SPNEGO_NONE_RESULT ) {
2014-09-20 00:42:39 +04:00
if ( ! asn1_push_tag ( asn1 , ASN1_CONTEXT ( 0 ) ) ) return false ;
if ( ! asn1_write_enumerated ( asn1 , token - > negResult ) ) return false ;
if ( ! asn1_pop_tag ( asn1 ) ) return false ;
2004-10-27 16:59:41 +04:00
}
2004-06-20 04:58:09 +04:00
if ( token - > supportedMech ) {
2014-09-20 00:42:39 +04:00
if ( ! asn1_push_tag ( asn1 , ASN1_CONTEXT ( 1 ) ) ) return false ;
if ( ! asn1_write_OID ( asn1 , token - > supportedMech ) ) return false ;
if ( ! asn1_pop_tag ( asn1 ) ) return false ;
2004-06-20 04:58:09 +04:00
}
if ( token - > responseToken . data ) {
2014-09-20 00:42:39 +04:00
if ( ! asn1_push_tag ( asn1 , ASN1_CONTEXT ( 2 ) ) ) return false ;
if ( ! asn1_write_OctetString ( asn1 , token - > responseToken . data ,
token - > responseToken . length ) ) return false ;
if ( ! asn1_pop_tag ( asn1 ) ) return false ;
2004-06-20 04:58:09 +04:00
}
if ( token - > mechListMIC . data ) {
2014-09-20 00:42:39 +04:00
if ( ! asn1_push_tag ( asn1 , ASN1_CONTEXT ( 3 ) ) ) return false ;
if ( ! asn1_write_OctetString ( asn1 , token - > mechListMIC . data ,
token - > mechListMIC . length ) ) return false ;
if ( ! asn1_pop_tag ( asn1 ) ) return false ;
2004-06-20 04:58:09 +04:00
}
2014-09-20 00:42:39 +04:00
if ( ! asn1_pop_tag ( asn1 ) ) return false ;
if ( ! asn1_pop_tag ( asn1 ) ) return false ;
2004-06-20 04:58:09 +04:00
2016-01-02 20:11:00 +03:00
return ! asn1_has_error ( asn1 ) ;
2004-06-20 04:58:09 +04:00
}
2007-05-21 10:12:06 +04:00
ssize_t spnego_read_data ( TALLOC_CTX * mem_ctx , DATA_BLOB data , struct spnego_data * token )
2004-06-20 04:58:09 +04:00
{
2007-05-21 16:47:18 +04:00
struct asn1_data * asn1 ;
2004-06-20 04:58:09 +04:00
ssize_t ret = - 1 ;
2004-07-10 03:38:13 +04:00
uint8_t context ;
2004-06-20 04:58:09 +04:00
ZERO_STRUCTP ( token ) ;
2004-07-06 05:01:39 +04:00
if ( data . length = = 0 ) {
return ret ;
}
2007-05-21 16:47:18 +04:00
asn1 = asn1_init ( mem_ctx ) ;
if ( asn1 = = NULL ) {
return - 1 ;
}
2014-09-20 00:42:39 +04:00
if ( ! asn1_load ( asn1 , data ) ) goto err ;
2004-06-20 04:58:09 +04:00
2007-05-21 10:12:06 +04:00
if ( ! asn1_peek_uint8 ( asn1 , & context ) ) {
2016-01-04 23:51:07 +03:00
asn1_set_error ( asn1 ) ;
2004-07-06 05:28:12 +04:00
} else {
switch ( context ) {
case ASN1_APPLICATION ( 0 ) :
2014-09-20 00:42:39 +04:00
if ( ! asn1_start_tag ( asn1 , ASN1_APPLICATION ( 0 ) ) ) goto err ;
if ( ! asn1_check_OID ( asn1 , OID_SPNEGO ) ) goto err ;
2007-05-21 10:12:06 +04:00
if ( read_negTokenInit ( asn1 , mem_ctx , & token - > negTokenInit ) ) {
2004-07-06 05:28:12 +04:00
token - > type = SPNEGO_NEG_TOKEN_INIT ;
}
2014-09-20 00:42:39 +04:00
if ( ! asn1_end_tag ( asn1 ) ) goto err ;
2004-07-06 05:28:12 +04:00
break ;
case ASN1_CONTEXT ( 1 ) :
2007-05-21 10:12:06 +04:00
if ( read_negTokenTarg ( asn1 , mem_ctx , & token - > negTokenTarg ) ) {
2004-07-06 05:28:12 +04:00
token - > type = SPNEGO_NEG_TOKEN_TARG ;
}
break ;
default :
2016-01-04 23:51:07 +03:00
asn1_set_error ( asn1 ) ;
2004-07-06 05:28:12 +04:00
break ;
2004-06-20 04:58:09 +04:00
}
}
2016-01-02 20:11:00 +03:00
if ( ! asn1_has_error ( asn1 ) ) ret = asn1 - > ofs ;
2014-09-20 00:42:39 +04:00
err :
2007-05-21 10:12:06 +04:00
asn1_free ( asn1 ) ;
2004-06-20 04:58:09 +04:00
return ret ;
}
2004-06-23 19:32:44 +04:00
ssize_t spnego_write_data ( TALLOC_CTX * mem_ctx , DATA_BLOB * blob , struct spnego_data * spnego )
2004-06-20 04:58:09 +04:00
{
2007-05-21 10:12:06 +04:00
struct asn1_data * asn1 = asn1_init ( mem_ctx ) ;
2004-06-20 04:58:09 +04:00
ssize_t ret = - 1 ;
2007-05-21 16:47:18 +04:00
if ( asn1 = = NULL ) {
return - 1 ;
}
2004-06-20 04:58:09 +04:00
switch ( spnego - > type ) {
case SPNEGO_NEG_TOKEN_INIT :
2014-09-20 00:42:39 +04:00
if ( ! asn1_push_tag ( asn1 , ASN1_APPLICATION ( 0 ) ) ) goto err ;
if ( ! asn1_write_OID ( asn1 , OID_SPNEGO ) ) goto err ;
if ( ! write_negTokenInit ( asn1 , & spnego - > negTokenInit ) ) goto err ;
if ( ! asn1_pop_tag ( asn1 ) ) goto err ;
2004-06-20 04:58:09 +04:00
break ;
case SPNEGO_NEG_TOKEN_TARG :
2007-05-21 10:12:06 +04:00
write_negTokenTarg ( asn1 , & spnego - > negTokenTarg ) ;
2004-06-20 04:58:09 +04:00
break ;
default :
2016-01-04 23:51:07 +03:00
asn1_set_error ( asn1 ) ;
2004-06-20 04:58:09 +04:00
break ;
}
2016-01-02 22:10:53 +03:00
if ( ! asn1_extract_blob ( asn1 , mem_ctx , blob ) ) {
goto err ;
2004-06-20 04:58:09 +04:00
}
2014-09-20 00:42:39 +04:00
2016-01-02 22:10:53 +03:00
ret = asn1 - > ofs ;
2014-09-20 00:42:39 +04:00
err :
2007-05-21 10:12:06 +04:00
asn1_free ( asn1 ) ;
2004-06-20 04:58:09 +04:00
return ret ;
}
2007-10-07 02:16:19 +04:00
bool spnego_free_data ( struct spnego_data * spnego )
2004-06-20 04:58:09 +04:00
{
2007-10-07 02:16:19 +04:00
bool ret = true ;
2004-06-20 04:58:09 +04:00
if ( ! spnego ) goto out ;
switch ( spnego - > type ) {
case SPNEGO_NEG_TOKEN_INIT :
if ( spnego - > negTokenInit . mechTypes ) {
2013-08-05 12:46:47 +04:00
talloc_free ( discard_const ( spnego - > negTokenInit . mechTypes ) ) ;
2004-06-20 04:58:09 +04:00
}
2009-08-13 10:12:01 +04:00
data_blob_free ( & spnego - > negTokenInit . reqFlags ) ;
2004-06-20 04:58:09 +04:00
data_blob_free ( & spnego - > negTokenInit . mechToken ) ;
data_blob_free ( & spnego - > negTokenInit . mechListMIC ) ;
2004-08-25 06:25:48 +04:00
talloc_free ( spnego - > negTokenInit . targetPrincipal ) ;
2004-06-20 04:58:09 +04:00
break ;
case SPNEGO_NEG_TOKEN_TARG :
if ( spnego - > negTokenTarg . supportedMech ) {
2004-11-02 14:17:06 +03:00
talloc_free ( discard_const ( spnego - > negTokenTarg . supportedMech ) ) ;
2004-06-20 04:58:09 +04:00
}
data_blob_free ( & spnego - > negTokenTarg . responseToken ) ;
data_blob_free ( & spnego - > negTokenTarg . mechListMIC ) ;
break ;
default :
2007-10-07 02:16:19 +04:00
ret = false ;
2004-06-20 04:58:09 +04:00
break ;
}
ZERO_STRUCTP ( spnego ) ;
out :
return ret ;
}
2008-08-12 16:26:21 +04:00
bool spnego_write_mech_types ( TALLOC_CTX * mem_ctx ,
2013-08-05 12:46:47 +04:00
const char * const * mech_types ,
2008-08-12 16:26:21 +04:00
DATA_BLOB * blob )
{
2014-09-20 00:42:39 +04:00
bool ret = false ;
2008-08-12 16:26:21 +04:00
struct asn1_data * asn1 = asn1_init ( mem_ctx ) ;
2010-12-02 02:40:01 +03:00
if ( asn1 = = NULL ) {
return false ;
}
2008-08-12 16:26:21 +04:00
/* Write mechTypes */
if ( mech_types & & * mech_types ) {
int i ;
2014-09-20 00:42:39 +04:00
if ( ! asn1_push_tag ( asn1 , ASN1_SEQUENCE ( 0 ) ) ) goto err ;
2008-08-12 16:26:21 +04:00
for ( i = 0 ; mech_types [ i ] ; i + + ) {
2014-09-20 00:42:39 +04:00
if ( ! asn1_write_OID ( asn1 , mech_types [ i ] ) ) goto err ;
2008-08-12 16:26:21 +04:00
}
2014-09-20 00:42:39 +04:00
if ( ! asn1_pop_tag ( asn1 ) ) goto err ;
2008-08-12 16:26:21 +04:00
}
2016-01-02 20:11:00 +03:00
if ( asn1_has_error ( asn1 ) ) {
2014-09-20 00:42:39 +04:00
goto err ;
2008-08-12 16:26:21 +04:00
}
2016-01-02 22:10:53 +03:00
if ( ! asn1_extract_blob ( asn1 , mem_ctx , blob ) ) {
2014-09-20 00:42:39 +04:00
goto err ;
2008-08-12 16:26:21 +04:00
}
2014-09-20 00:42:39 +04:00
ret = true ;
err :
2008-08-12 16:26:21 +04:00
asn1_free ( asn1 ) ;
2014-09-20 00:42:39 +04:00
return ret ;
2008-08-12 16:26:21 +04:00
}