コード例 #1
0
def test_invalid_protocol():
    expected = "Invalid protocol specified 'fake', must be kerberos, negotiate, or ntlm"

    with pytest.raises(ValueError, match=expected):
        spnego.client(None, None, protocol='fake')

    with pytest.raises(ValueError, match=expected):
        spnego.server(protocol='fake')
コード例 #2
0
def main():
    server = socket.gethostname()
    username = '******'
    password = '******'

    c = spnego.client(username, password, server)
    s = spnego.server(server)

    in_token = None
    while not c.complete:
        out_token = c.step(in_token)
        if not out_token:
            break

        in_token = s.step(out_token)

    print("Client Session key: %s" %
          base64.b64encode(c.session_key).decode('utf-8'))
    print("Server Session key: %s" %
          base64.b64encode(s.session_key).decode('utf-8'))
    print("Authenticated client: %s" % s.client_principal)

    c_enc_msg = c.wrap(b"Hello World")
    s_dec_msg = s.unwrap(c_enc_msg.data)
    s_enc_msg = s.wrap(s_dec_msg.data)
    c_dec_msg = c.unwrap(s_enc_msg.data)

    c_sig = c.sign(b"data")
    s.verify(b"data", c_sig)

    s_sig = s.sign(b"data")
    c.verify(b"data", s_sig)
コード例 #3
0
def test_negotiate_with_raw_ntlm(ntlm_cred):
    c = spnego.client(ntlm_cred[0],
                      ntlm_cred[1],
                      hostname=socket.gethostname(),
                      protocol='ntlm')
    s = spnego.server(options=spnego.NegotiateOptions.use_negotiate)

    negotiate = c.step()
    assert negotiate.startswith(b"NTLMSSP\x00\x01")
    assert not c.complete
    assert not s.complete

    challenge = s.step(negotiate)
    assert challenge.startswith(b"NTLMSSP\x00\x02")
    assert not c.complete
    assert not s.complete

    authenticate = c.step(challenge)
    assert authenticate.startswith(b"NTLMSSP\x00\x03")
    assert c.complete
    assert not s.complete

    final = s.step(authenticate)
    assert final is None
    assert c.complete
    assert s.complete

    _message_test(c, s)
コード例 #4
0
def test_negotiate_with_kerberos(kerb_cred):
    c = spnego.client(kerb_cred.user_princ,
                      None,
                      hostname=socket.getfqdn(),
                      options=spnego.NegotiateOptions.use_negotiate)
    s = spnego.server(options=spnego.NegotiateOptions.use_negotiate)

    token1 = c.step()
    assert isinstance(token1, bytes)

    token2 = s.step(token1)
    assert isinstance(token2, bytes)

    token3 = c.step(token2)
    assert token3 is None

    # Make sure it reports the right protocol
    assert c.negotiated_protocol == 'kerberos'
    assert s.negotiated_protocol == 'kerberos'

    assert isinstance(c.session_key, bytes)
    assert isinstance(s.session_key, bytes)
    assert c.session_key == s.session_key

    assert c.client_principal is None
    assert s.client_principal == kerb_cred.user_princ

    assert c.context_attr & spnego.ContextReq.mutual_auth
    assert s.context_attr & spnego.ContextReq.mutual_auth

    _message_test(c, s)
コード例 #5
0
def test_sspi_ntlm_auth_no_sign_or_seal(client_opt, server_opt, ntlm_cred):
    if client_opt & spnego.NegotiateOptions.use_gssapi or server_opt & spnego.NegotiateOptions.use_gssapi:
        if 'ntlm' not in spnego.gss.GSSAPIProxy.available_protocols():
            pytest.skip('Test requires NTLM to be available through GSSAPI')

    elif client_opt & spnego.NegotiateOptions.use_sspi or server_opt & spnego.NegotiateOptions.use_sspi:
        if 'ntlm' not in spnego.sspi.SSPIProxy.available_protocols():
            pytest.skip('Test requires NTLM to be available through SSPI')

    # Build the initial context and assert the defaults.
    c = spnego.client(ntlm_cred[0],
                      ntlm_cred[1],
                      hostname=socket.gethostname(),
                      options=client_opt,
                      protocol='ntlm',
                      context_req=0)
    s = spnego.server(options=server_opt, protocol='ntlm', context_req=0)

    _ntlm_test(c, s)

    assert c.client_principal is None
    assert s.client_principal == ntlm_cred[0]

    # Client sign, server verify
    plaintext = os.urandom(3)

    c_sig = c.sign(plaintext)
    s.verify(plaintext, c_sig)

    # Server sign, client verify
    plaintext = os.urandom(9)

    s_sig = s.sign(plaintext)
    c.verify(plaintext, s_sig)
コード例 #6
0
def test_ntlm_bad_mic(ntlm_cred):
    c = spnego.client(ntlm_cred[0],
                      ntlm_cred[1],
                      hostname=socket.gethostname(),
                      options=spnego.NegotiateOptions.use_ntlm,
                      protocol='ntlm')
    s = spnego.server(options=spnego.NegotiateOptions.use_ntlm,
                      protocol='ntlm')

    auth = memoryview(bytearray(c.step(s.step(c.step()))))
    auth[64:80] = b"\x01" * 16

    with pytest.raises(InvalidTokenError,
                       match="Invalid MIC in NTLM authentication message"):
        s.step(auth.tobytes())
コード例 #7
0
def test_sspi_ntlm_lm_compat(lm_compat_level, ntlm_cred, monkeypatch):
    monkeypatch.setenv('LM_COMPAT_LEVEL', str(lm_compat_level))
    c = spnego.client(ntlm_cred[0],
                      ntlm_cred[1],
                      hostname=socket.gethostname(),
                      protocol='ntlm',
                      options=spnego.NegotiateOptions.use_ntlm)
    s = spnego.server(options=spnego.NegotiateOptions.use_sspi,
                      protocol='ntlm')

    _ntlm_test(c, s)

    assert c.client_principal is None
    assert s.client_principal == ntlm_cred[0]

    _message_test(c, s)
コード例 #8
0
def test_ntlm_anon_response(ntlm_cred):
    c = spnego.client(ntlm_cred[0],
                      ntlm_cred[1],
                      options=spnego.NegotiateOptions.use_ntlm,
                      protocol='ntlm')
    s = spnego.server(options=spnego.NegotiateOptions.use_ntlm,
                      protocol='ntlm')

    auth = Authenticate.unpack(c.step(s.step(c.step())))
    anon_auth = Authenticate(flags=auth.flags,
                             lm_challenge_response=b"\x00",
                             nt_challenge_response=b"").pack()

    with pytest.raises(OperationNotAvailableError,
                       match="Anonymous user authentication not implemented"):
        s.step(anon_auth)
コード例 #9
0
def test_ntlm_lm_request(ntlm_cred, monkeypatch):
    monkeypatch.setenv('LM_COMPAT_LEVEL', '0')
    c = spnego.client(ntlm_cred[0],
                      ntlm_cred[1],
                      hostname=socket.gethostname(),
                      options=spnego.NegotiateOptions.use_ntlm,
                      protocol='ntlm')
    s = spnego.server(options=spnego.NegotiateOptions.use_ntlm,
                      protocol='ntlm')

    auth = memoryview(bytearray(c.step(s.step(c.step()))))
    auth[20:28] = b"\x00" * 8

    s.step(auth.tobytes())

    assert c.complete
    assert s.complete
コード例 #10
0
def test_ntlm_no_nt_v1_allowed(ntlm_cred, monkeypatch):
    monkeypatch.setenv('LM_COMPAT_LEVEL', '0')
    c = spnego.client(ntlm_cred[0],
                      ntlm_cred[1],
                      hostname=socket.gethostname(),
                      options=spnego.NegotiateOptions.use_ntlm,
                      protocol='ntlm')

    monkeypatch.setenv('LM_COMPAT_LEVEL', '5')
    s = spnego.server(options=spnego.NegotiateOptions.use_ntlm,
                      protocol='ntlm')

    auth = c.step(s.step(c.step()))

    with pytest.raises(
            InvalidTokenError,
            match="Acceptor settings are set to reject NTv1 responses"):
        s.step(auth)
コード例 #11
0
def test_ntlm_nt_v1_request(ntlm_cred, monkeypatch):
    monkeypatch.setenv('LM_COMPAT_LEVEL', '0')
    c = spnego.client(ntlm_cred[0],
                      ntlm_cred[1],
                      hostname=socket.gethostname(),
                      options=spnego.NegotiateOptions.use_ntlm,
                      protocol='ntlm')

    monkeypatch.setenv('LM_COMPAT_LEVEL', '4')
    s = spnego.server(options=spnego.NegotiateOptions.use_ntlm,
                      protocol='ntlm')

    auth = c.step(s.step(c.step()))

    s.step(auth)

    assert c.complete
    assert s.complete
コード例 #12
0
def test_ntlm_auth(lm_compat_level, ntlm_cred, monkeypatch):
    if lm_compat_level is not None:
        monkeypatch.setenv('LM_COMPAT_LEVEL', str(lm_compat_level))

    # Build the initial context and assert the defaults.
    c = spnego.client(ntlm_cred[0],
                      ntlm_cred[1],
                      protocol='ntlm',
                      options=spnego.NegotiateOptions.use_ntlm)
    s = spnego.server(protocol='ntlm',
                      options=spnego.NegotiateOptions.use_ntlm)

    _ntlm_test(c, s)

    assert c.client_principal is None
    assert s.client_principal == ntlm_cred[0]

    _message_test(c, s)
コード例 #13
0
def test_ntlm_no_key_exch(ntlm_cred):
    c = spnego.client(ntlm_cred[0],
                      ntlm_cred[1],
                      hostname=socket.gethostname(),
                      options=spnego.NegotiateOptions.use_ntlm,
                      protocol='ntlm')
    s = spnego.server(options=spnego.NegotiateOptions.use_ntlm,
                      protocol='ntlm')

    c._context_req &= ~0x40000000  # NTLMSSP_NEGOTIATE_KEY_EXCH

    auth = c.step(s.step(c.step()))
    s.step(auth)

    # Make sure EncryptedRandomSessionKeyFields was set to 0 (no KEY_EXCH).
    assert auth[52:54] == b"\x00\x00"

    plaintext = os.urandom(32)

    c_wrap_result = c.wrap(plaintext)
    assert c_wrap_result.encrypted
    assert c_wrap_result.data != plaintext

    s_unwrap_result = s.unwrap(c_wrap_result.data)
    assert s_unwrap_result.data == plaintext
    assert s_unwrap_result.encrypted

    plaintext = os.urandom(17)

    s_wrap_result = s.wrap(plaintext)
    assert s_wrap_result.encrypted
    assert s_wrap_result.data != plaintext

    c_unwrap_result = c.unwrap(s_wrap_result.data)
    assert c_unwrap_result.data == plaintext
    assert c_unwrap_result.encrypted

    plaintext = os.urandom(3)
    c_sig = c.sign(plaintext)
    s.verify(plaintext, c_sig)

    plaintext = os.urandom(9)
    s_sig = s.sign(plaintext)
    c.verify(plaintext, s_sig)
コード例 #14
0
def test_ntlm_no_lm_allowed(ntlm_cred, monkeypatch):
    monkeypatch.setenv('LM_COMPAT_LEVEL', '0')
    c = spnego.client(ntlm_cred[0],
                      ntlm_cred[1],
                      hostname=socket.gethostname(),
                      options=spnego.NegotiateOptions.use_ntlm,
                      protocol='ntlm')

    monkeypatch.setenv('LM_COMPAT_LEVEL', '4')
    s = spnego.server(options=spnego.NegotiateOptions.use_ntlm,
                      protocol='ntlm')

    auth = memoryview(bytearray(c.step(s.step(c.step()))))
    auth[20:28] = b"\x00" * 8

    with pytest.raises(
            InvalidTokenError,
            match="Acceptor settings are set to reject LM responses"):
        s.step(auth)
コード例 #15
0
def test_gssapi_kerberos_auth(kerb_cred):
    c = spnego.client(kerb_cred.user_princ,
                      None,
                      hostname=socket.getfqdn(),
                      protocol='kerberos',
                      options=spnego.NegotiateOptions.use_gssapi)
    s = spnego.server(options=spnego.NegotiateOptions.use_gssapi,
                      protocol='kerberos')

    assert not c.complete
    assert not s.complete
    assert s.negotiated_protocol is None

    with pytest.raises(SpnegoError, match="Retrieving session key"):
        _ = c.session_key

    with pytest.raises(SpnegoError, match="Retrieving session key"):
        _ = s.session_key

    token1 = c.step()
    assert isinstance(token1, bytes)
    assert not c.complete
    assert not s.complete
    assert s.negotiated_protocol is None

    token2 = s.step(token1)
    assert isinstance(token2, bytes)
    assert not c.complete
    assert s.complete
    assert s.negotiated_protocol == 'kerberos'

    token3 = c.step(token2)
    assert token3 is None
    assert c.complete
    assert s.complete
    assert isinstance(c.session_key, bytes)
    assert isinstance(s.session_key, bytes)
    assert c.session_key == s.session_key

    assert c.client_principal is None
    assert s.client_principal == kerb_cred.user_princ

    _message_test(c, s)
コード例 #16
0
def test_gssapi_ntlm_lm_compat(lm_compat_level, ntlm_cred, monkeypatch):
    monkeypatch.setenv('LM_COMPAT_LEVEL', str(lm_compat_level))
    c = spnego.client(ntlm_cred[0],
                      ntlm_cred[1],
                      hostname=socket.gethostname(),
                      protocol='ntlm',
                      options=spnego.NegotiateOptions.use_ntlm)
    s = spnego.server(options=spnego.NegotiateOptions.use_gssapi,
                      protocol='ntlm')

    # gss-ntlmssp version on CI may be too old to test the session key
    test_session_key = 'ntlm' in spnego.gss.GSSAPIProxy.available_protocols(
        spnego.NegotiateOptions.session_key)
    _ntlm_test(c, s, test_session_key=test_session_key)

    assert c.client_principal is None
    assert s.client_principal == ntlm_cred[0]

    _message_test(c, s)
コード例 #17
0
ファイル: test_negotiate.py プロジェクト: yyolk/pyspnego
def test_token_acceptor_first(ntlm_cred):
    c = spnego.client(ntlm_cred[0],
                      ntlm_cred[1],
                      options=spnego.NegotiateOptions.use_negotiate)
    s = spnego.server(options=spnego.NegotiateOptions.use_negotiate)

    assert c._mech_list == []
    assert s._mech_list == []

    token1 = s.step()
    assert isinstance(token1, bytes)
    assert not c.complete
    assert not s.complete
    assert c._mech_list == []
    assert s._mech_list == [GSSMech.ntlm.value]

    negotiate = c.step(token1)
    assert isinstance(negotiate, bytes)
    assert not c.complete
    assert not s.complete
    assert c._mech_list == [GSSMech.ntlm.value]
    assert s._mech_list == [GSSMech.ntlm.value]

    challenge = s.step(negotiate)
    assert isinstance(challenge, bytes)
    assert not c.complete
    assert not s.complete

    authenticate = c.step(challenge)
    assert isinstance(authenticate, bytes)
    assert not c.complete
    assert not s.complete

    mech_list_mic = s.step(authenticate)
    assert isinstance(mech_list_mic, bytes)
    assert not c.complete
    assert s.complete

    final_token = c.step(mech_list_mic)
    assert final_token is None
    assert c.complete
    assert s.complete
コード例 #18
0
def test_ntlm_invalid_password(client_opt, ntlm_cred):
    if client_opt & spnego.NegotiateOptions.use_gssapi:
        if 'ntlm' not in spnego.gss.GSSAPIProxy.available_protocols():
            pytest.skip('Test requires NTLM to be available through GSSAPI')

    elif client_opt & spnego.NegotiateOptions.use_sspi:
        if 'ntlm' not in spnego.sspi.SSPIProxy.available_protocols():
            pytest.skip('Test requires NTLM to be available through SSPI')

    c = spnego.client(ntlm_cred[0],
                      u"Invalid",
                      hostname=socket.gethostname(),
                      options=client_opt,
                      protocol='ntlm')
    s = spnego.server(options=spnego.NegotiateOptions.use_ntlm,
                      protocol='ntlm')

    auth = c.step(s.step(c.step()))

    with pytest.raises(InvalidTokenError,
                       match="Invalid NTLM response from initiator"):
        s.step(auth)
コード例 #19
0
def test_sspi_ntlm_auth(client_opt, server_opt, cbt, ntlm_cred):
    # Build the initial context and assert the defaults.
    kwargs = {
        'protocol': 'ntlm',
    }
    if cbt:
        kwargs[
            'channel_bindings'] = spnego.channel_bindings.GssChannelBindings(
                application_data=b'test_data:\x00\x01')
    c = spnego.client(ntlm_cred[0],
                      ntlm_cred[1],
                      hostname=socket.gethostname(),
                      options=client_opt,
                      **kwargs)
    s = spnego.server(options=server_opt, **kwargs)

    _ntlm_test(c, s)

    assert c.client_principal is None
    assert s.client_principal == ntlm_cred[0]

    _message_test(c, s)
コード例 #20
0
def test_gssapi_ntlm_auth(client_opt, server_opt, ntlm_cred, cbt):
    # Build the initial context and assert the defaults.
    kwargs = {
        'protocol': 'ntlm',
    }
    if cbt:
        kwargs[
            'channel_bindings'] = spnego.channel_bindings.GssChannelBindings(
                application_data=b'test_data:\x00\x01')

    c = spnego.client(ntlm_cred[0], ntlm_cred[1], options=client_opt, **kwargs)
    s = spnego.server(options=server_opt, **kwargs)

    # gss-ntlmssp version on CI may be too old to test the session key
    test_session_key = 'ntlm' in spnego.gss.GSSAPIProxy.available_protocols(
        spnego.NegotiateOptions.session_key)
    _ntlm_test(c, s, test_session_key=test_session_key)

    assert c.client_principal is None
    assert s.client_principal == ntlm_cred[0]

    _message_test(c, s)
コード例 #21
0
def test_ntlm_bad_bindings(client_opt, present, ntlm_cred):
    if client_opt & spnego.NegotiateOptions.use_gssapi:
        if 'ntlm' not in spnego.gss.GSSAPIProxy.available_protocols():
            pytest.skip('Test requires NTLM to be available through GSSAPI')

    elif client_opt & spnego.NegotiateOptions.use_sspi:
        if 'ntlm' not in spnego.sspi.SSPIProxy.available_protocols():
            pytest.skip('Test requires NTLM to be available through SSPI')

    initiator_cbt = None
    if present:
        initiator_cbt = spnego.channel_bindings.GssChannelBindings(
            application_data=b"tls-host-data:bad")

    c = spnego.client(ntlm_cred[0],
                      ntlm_cred[1],
                      hostname=socket.gethostname(),
                      options=client_opt,
                      protocol='ntlm',
                      channel_bindings=initiator_cbt)

    acceptor_cbt = spnego.channel_bindings.GssChannelBindings(
        application_data=b"tls-host-data:test")
    s = spnego.server(options=spnego.NegotiateOptions.use_ntlm,
                      protocol='ntlm',
                      channel_bindings=acceptor_cbt)

    auth = c.step(s.step(c.step()))

    if present:
        expected = "Acceptor bindings do not match initiator bindings"

    else:
        expected = "Acceptor bindings specified but not present in initiator response"

    with pytest.raises(BadBindingsError, match=expected):
        s.step(auth)
コード例 #22
0
def test_ntlm_verify_fail(client_opt, ntlm_cred):
    if client_opt & spnego.NegotiateOptions.use_gssapi:
        if 'ntlm' not in spnego.gss.GSSAPIProxy.available_protocols():
            pytest.skip('Test requires NTLM to be available through GSSAPI')

    elif client_opt & spnego.NegotiateOptions.use_sspi:
        if 'ntlm' not in spnego.sspi.SSPIProxy.available_protocols():
            pytest.skip('Test requires NTLM to be available through SSPI')

    c = spnego.client(ntlm_cred[0],
                      ntlm_cred[1],
                      hostname=socket.gethostname(),
                      options=client_opt,
                      protocol='ntlm')
    s = spnego.server(options=spnego.NegotiateOptions.use_ntlm,
                      protocol='ntlm')

    s.step(c.step(s.step(c.step())))

    c.sign(b"data")
    sig = c.sign(b"data 2")

    with pytest.raises(BadMICError, match="Invalid Message integrity Check"):
        s.verify(b"data", sig)
コード例 #23
0
def test_negotiate_through_python_ntlm(client_opt, server_opt, ntlm_cred,
                                       monkeypatch):
    if client_opt & spnego.NegotiateOptions.use_negotiate and server_opt & spnego.NegotiateOptions.use_negotiate:
        # Make sure we pretend that the system libraries aren't available
        def available_protocols(*args, **kwargs):
            return []

        monkeypatch.setattr(spnego.gss, '_available_protocols',
                            available_protocols)
        monkeypatch.setattr(spnego.sspi, '_available_protocols',
                            available_protocols)

    elif client_opt & spnego.NegotiateOptions.use_gssapi or server_opt & spnego.NegotiateOptions.use_gssapi:
        if 'ntlm' not in spnego.gss.GSSAPIProxy.available_protocols():
            pytest.skip('Test requires NTLM to be available through GSSAPI')

    elif client_opt & spnego.NegotiateOptions.use_sspi or server_opt & spnego.NegotiateOptions.use_sspi:
        if 'ntlm' not in spnego.sspi.SSPIProxy.available_protocols():
            pytest.skip('Test requires NTLM to be available through SSPI')

    # Build the initial context and assert the defaults.
    c = spnego.client(ntlm_cred[0],
                      ntlm_cred[1],
                      protocol='negotiate',
                      options=client_opt,
                      context_req=spnego.ContextReq.delegate
                      | spnego.ContextReq.default)
    s = spnego.server(protocol='negotiate', options=server_opt)

    assert not c.complete
    assert not s.complete

    negotiate = c.step()

    assert isinstance(negotiate, bytes)
    assert not c.complete
    assert not s.complete

    challenge = s.step(negotiate)

    assert isinstance(challenge, bytes)
    assert not c.complete
    assert not s.complete

    authenticate = c.step(challenge)

    assert isinstance(authenticate, bytes)
    assert not c.complete
    assert not s.complete

    mech_list_mic = s.step(authenticate)

    assert isinstance(mech_list_mic, bytes)
    assert not c.complete
    assert s.complete

    assert c.client_principal is None
    assert s.client_principal == ntlm_cred[0]

    mech_list_resp = c.step(mech_list_mic)

    assert mech_list_resp is None
    assert c.complete
    assert s.complete
    assert c.negotiated_protocol == 'ntlm'
    assert s.negotiated_protocol == 'ntlm'

    _message_test(c, s)