2009-09-26 21:41:59 +04:00
# Unix SMB/CIFS implementation.
# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2009
2010-09-23 00:57:07 +04:00
#
2009-09-26 21:41:59 +04:00
# 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.
2010-09-23 00:57:07 +04:00
#
2009-09-26 21:41:59 +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.
2010-09-23 00:57:07 +04:00
#
2009-09-26 21:41:59 +04:00
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
""" Tests for GENSEC.
2012-09-27 20:30:47 +04:00
Note that this just tests the bindings work . It does not intend to test
2009-09-26 21:41:59 +04:00
the functionality , that ' s already done in other tests.
"""
2011-01-18 11:14:45 +03:00
from samba . credentials import Credentials
2011-12-29 06:51:55 +04:00
from samba import gensec , auth
2010-06-19 20:58:18 +04:00
import samba . tests
2009-09-26 21:41:59 +04:00
2018-07-30 09:20:39 +03:00
2011-01-18 11:14:45 +03:00
class GensecTests ( samba . tests . TestCase ) :
2009-09-26 21:41:59 +04:00
def setUp ( self ) :
2011-01-18 11:14:45 +03:00
super ( GensecTests , self ) . setUp ( )
self . settings = { }
self . settings [ " lp_ctx " ] = self . lp_ctx = samba . tests . env_loadparm ( )
self . settings [ " target_hostname " ] = self . lp_ctx . get ( " netbios name " )
2017-06-12 05:12:53 +03:00
self . lp_ctx . set ( " spnego:simulate_w2k " , " no " )
2011-01-18 11:14:45 +03:00
""" This is just for the API tests """
self . gensec = gensec . Security . start_client ( self . settings )
2009-09-26 21:41:59 +04:00
2010-09-23 00:57:07 +04:00
def test_start_mech_by_unknown_name ( self ) :
self . assertRaises ( RuntimeError , self . gensec . start_mech_by_name , " foo " )
2010-09-23 02:35:36 +04:00
def test_start_mech_by_name ( self ) :
self . gensec . start_mech_by_name ( " spnego " )
2010-09-23 00:57:07 +04:00
def test_info_uninitialized ( self ) :
self . assertRaises ( RuntimeError , self . gensec . session_info )
2011-01-18 11:14:45 +03:00
2019-10-11 00:20:16 +03:00
def _test_update ( self , mech , client_mech = None , client_only_opt = None ) :
2011-01-18 11:14:45 +03:00
""" Test GENSEC by doing an exchange with ourselves using GSSAPI against a KDC """
""" Start up a client and server GENSEC instance to test things with """
2019-10-11 00:20:16 +03:00
if client_only_opt :
orig_client_opt = self . lp_ctx . get ( client_only_opt )
if not orig_client_opt :
orig_client_opt = ' '
self . lp_ctx . set ( client_only_opt , " yes " )
2011-01-18 11:14:45 +03:00
self . gensec_client = gensec . Security . start_client ( self . settings )
self . gensec_client . set_credentials ( self . get_credentials ( ) )
self . gensec_client . want_feature ( gensec . FEATURE_SEAL )
2017-06-12 05:27:53 +03:00
if client_mech is not None :
self . gensec_client . start_mech_by_name ( client_mech )
else :
self . gensec_client . start_mech_by_sasl_name ( mech )
2011-01-18 11:14:45 +03:00
2019-10-11 00:20:16 +03:00
if client_only_opt :
self . lp_ctx . set ( client_only_opt , " no " )
2012-09-27 20:30:47 +04:00
self . gensec_server = gensec . Security . start_server ( settings = self . settings ,
2011-12-29 06:51:55 +04:00
auth_context = auth . AuthContext ( lp_ctx = self . lp_ctx ) )
2011-01-18 11:14:45 +03:00
creds = Credentials ( )
creds . guess ( self . lp_ctx )
creds . set_machine_account ( self . lp_ctx )
self . gensec_server . set_credentials ( creds )
self . gensec_server . want_feature ( gensec . FEATURE_SEAL )
2017-06-12 05:12:53 +03:00
self . gensec_server . start_mech_by_sasl_name ( mech )
2011-01-18 11:14:45 +03:00
client_finished = False
server_finished = False
2017-01-17 15:20:38 +03:00
server_to_client = b " "
2017-06-12 05:12:53 +03:00
client_to_server = b " "
2012-09-16 16:18:51 +04:00
2011-01-18 11:14:45 +03:00
""" Run the actual call loop """
2017-06-12 05:12:53 +03:00
while True :
2011-01-18 11:14:45 +03:00
if not client_finished :
2019-10-11 00:20:16 +03:00
if client_only_opt :
self . lp_ctx . set ( client_only_opt , " yes " )
2017-01-17 15:20:38 +03:00
print ( " running client gensec_update " )
2019-10-11 14:23:17 +03:00
try :
( client_finished , client_to_server ) = self . gensec_client . update ( server_to_client )
except samba . NTSTATUSError as nt :
raise AssertionError ( nt )
2019-10-11 00:20:16 +03:00
if client_only_opt :
self . lp_ctx . set ( client_only_opt , " no " )
2011-01-18 11:14:45 +03:00
if not server_finished :
2017-01-17 15:20:38 +03:00
print ( " running server gensec_update " )
2019-10-11 14:23:17 +03:00
try :
( server_finished , server_to_client ) = self . gensec_server . update ( client_to_server )
except samba . NTSTATUSError as nt :
raise AssertionError ( nt )
2017-06-12 05:12:53 +03:00
if client_finished and server_finished :
break
2019-10-11 00:20:16 +03:00
if client_only_opt :
self . lp_ctx . set ( client_only_opt , orig_client_opt )
2017-06-12 05:12:53 +03:00
self . assertTrue ( server_finished )
self . assertTrue ( client_finished )
2011-01-18 11:14:45 +03:00
session_info = self . gensec_server . session_info ( )
2017-01-17 15:20:38 +03:00
test_bytes = b " Hello Server "
2017-06-12 05:12:53 +03:00
try :
test_wrapped = self . gensec_client . wrap ( test_bytes )
test_unwrapped = self . gensec_server . unwrap ( test_wrapped )
except samba . NTSTATUSError as e :
self . fail ( str ( e ) )
2017-01-17 15:20:38 +03:00
self . assertEqual ( test_bytes , test_unwrapped )
test_bytes = b " Hello Client "
test_wrapped = self . gensec_server . wrap ( test_bytes )
2011-01-18 11:14:45 +03:00
test_unwrapped = self . gensec_client . unwrap ( test_wrapped )
2017-01-17 15:20:38 +03:00
self . assertEqual ( test_bytes , test_unwrapped )
2012-01-04 23:49:08 +04:00
client_session_key = self . gensec_client . session_key ( )
server_session_key = self . gensec_server . session_key ( )
self . assertEqual ( client_session_key , server_session_key )
2012-01-11 19:00:59 +04:00
2017-06-12 05:12:53 +03:00
def test_update ( self ) :
self . _test_update ( " GSSAPI " )
def test_update_spnego ( self ) :
self . _test_update ( " GSS-SPNEGO " )
2019-10-11 00:20:16 +03:00
def test_update_spnego_downgrade ( self ) :
self . _test_update ( " GSS-SPNEGO " , " spnego " , " gensec:gssapi_krb5 " )
def test_update_no_optimistic_spnego ( self ) :
self . _test_update ( " GSS-SPNEGO " , " spnego " , " spnego:client_no_optimistic " )
2017-06-12 05:12:53 +03:00
def test_update_w2k_spnego_client ( self ) :
self . lp_ctx . set ( " spnego:simulate_w2k " , " yes " )
# Re-start the client with this set
self . gensec = gensec . Security . start_client ( self . settings )
# Unset it for the server
self . lp_ctx . set ( " spnego:simulate_w2k " , " no " )
self . _test_update ( " GSS-SPNEGO " )
def test_update_w2k_spnego_server ( self ) :
# Re-start the client with this set
self . gensec = gensec . Security . start_client ( self . settings )
# Unset it for the server
self . lp_ctx . set ( " spnego:simulate_w2k " , " yes " )
self . _test_update ( " GSS-SPNEGO " )
def test_update_w2k_spnego ( self ) :
self . lp_ctx . set ( " spnego:simulate_w2k " , " no " )
# Re-start the client with this set
self . gensec = gensec . Security . start_client ( self . settings )
self . _test_update ( " GSS-SPNEGO " )
2017-06-12 05:27:53 +03:00
def test_update_gss_krb5_to_spnego ( self ) :
self . _test_update ( " GSS-SPNEGO " , " gssapi_krb5 " )
def test_update_ntlmssp_to_spnego ( self ) :
self . _test_update ( " GSS-SPNEGO " , " ntlmssp " )
2012-01-11 19:00:59 +04:00
def test_max_update_size ( self ) :
""" Test GENSEC by doing an exchange with ourselves using GSSAPI against a KDC """
""" Start up a client and server GENSEC instance to test things with """
self . gensec_client = gensec . Security . start_client ( self . settings )
self . gensec_client . set_credentials ( self . get_credentials ( ) )
self . gensec_client . want_feature ( gensec . FEATURE_SIGN )
self . gensec_client . set_max_update_size ( 5 )
self . gensec_client . start_mech_by_name ( " spnego " )
self . gensec_server = gensec . Security . start_server ( settings = self . settings ,
auth_context = auth . AuthContext ( lp_ctx = self . lp_ctx ) )
creds = Credentials ( )
creds . guess ( self . lp_ctx )
creds . set_machine_account ( self . lp_ctx )
self . gensec_server . set_credentials ( creds )
self . gensec_server . want_feature ( gensec . FEATURE_SIGN )
self . gensec_server . set_max_update_size ( 5 )
self . gensec_server . start_mech_by_name ( " spnego " )
client_finished = False
server_finished = False
2017-01-17 15:20:38 +03:00
server_to_client = b " "
2012-01-11 19:00:59 +04:00
""" Run the actual call loop """
i = 0
2012-09-27 20:30:47 +04:00
while not client_finished or not server_finished :
2012-01-11 19:00:59 +04:00
i + = 1
if not client_finished :
2017-01-17 15:20:38 +03:00
print ( " running client gensec_update: %d : %r " % ( len ( server_to_client ) , server_to_client ) )
2012-01-11 19:00:59 +04:00
( client_finished , client_to_server ) = self . gensec_client . update ( server_to_client )
if not server_finished :
2017-01-17 15:20:38 +03:00
print ( " running server gensec_update: %d : %r " % ( len ( client_to_server ) , client_to_server ) )
2012-01-11 19:00:59 +04:00
( server_finished , server_to_client ) = self . gensec_server . update ( client_to_server )
""" Here we expect a lot more than the typical 1 or 2 roundtrips """
self . assertTrue ( i > 10 )
session_info = self . gensec_server . session_info ( )
2017-01-17 15:20:38 +03:00
test_bytes = b " Hello Server "
test_wrapped = self . gensec_client . wrap ( test_bytes )
2012-01-11 19:00:59 +04:00
test_unwrapped = self . gensec_server . unwrap ( test_wrapped )
2017-01-17 15:20:38 +03:00
self . assertEqual ( test_bytes , test_unwrapped )
test_bytes = b " Hello Client "
test_wrapped = self . gensec_server . wrap ( test_bytes )
2012-01-11 19:00:59 +04:00
test_unwrapped = self . gensec_client . unwrap ( test_wrapped )
2017-01-17 15:20:38 +03:00
self . assertEqual ( test_bytes , test_unwrapped )
2012-01-11 19:00:59 +04:00
client_session_key = self . gensec_client . session_key ( )
server_session_key = self . gensec_server . session_key ( )
self . assertEqual ( client_session_key , server_session_key )