示例#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 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)
示例#3
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)
示例#4
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)
示例#5
0
def main():
    client = spnego.client('username', 'password', hostname='server')

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

        in_token = exchange_data(out_token)

    print("Negotiated protocol: %s" % client.negotiated_protocol)

    buffer = [
        spnego.iov.BufferType.header,
        b"my secret",
        spnego.iov.BufferType.padding,
    ]
    enc_result = client.wrap_iov(buffer)

    header = enc_result.buffers[0].data
    enc_data = enc_result.buffers[1].data + enc_result.buffers[2].data or b""

    resp = exchange_data(struct.pack("<I", len(header)) + header + enc_data)
    header_len = struct.unpack("<I", resp[:4])[0]
    header = resp[4:4 + header_len]
    enc_data = resp[4 + header_len:]

    buffer = [
        spnego.iov.IOVBuffer(spnego.iov.BufferType.header, header),
        enc_data,
    ]
    dec_result = client.unwrap_iov(buffer)

    print("Server response: %s" % dec_result.buffers[1].data.decode('utf-8'))
示例#6
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)
示例#7
0
def test_token_no_common_mechs(ntlm_cred):
    c = spnego.client(ntlm_cred[0],
                      ntlm_cred[1],
                      options=spnego.NegotiateOptions.use_negotiate)

    with pytest.raises(BadMechanismError,
                       match="Unable to negotiate common mechanism"):
        c.step(NegTokenInit(mech_types=["1.2.3.4"]).pack())
示例#8
0
def test_token_rejected(ntlm_cred):
    c = spnego.client(ntlm_cred[0],
                      ntlm_cred[1],
                      options=spnego.NegotiateOptions.use_negotiate)

    c.step()
    token_resp = NegTokenResp(neg_state=NegState.reject).pack()

    with pytest.raises(
            InvalidTokenError,
            match="Received SPNEGO rejection with no token error message"):
        c.step(token_resp)
示例#9
0
    def generate_request_header(self, response, host, is_preemptive=False):
        """
        Generates the GSSAPI authentication token with kerberos.

        If any GSSAPI step fails, raise KerberosExchangeError
        with failure detail.

        """

        # Flags used by kerberos module.
        gssflags = spnego.ContextReq.sequence_detect
        if self.delegate:
            gssflags |= spnego.ContextReq.delegate
        if self.mutual_authentication != DISABLED:
            gssflags |= spnego.ContextReq.mutual_auth

        try:
            kerb_stage = "ctx init"
            # contexts still need to be stored by host, but hostname_override
            # allows use of an arbitrary hostname for the kerberos exchange
            # (eg, in cases of aliased hosts, internal vs external, CNAMEs
            # w/ name-based HTTP hosting)
            kerb_host = self.hostname_override if self.hostname_override is not None else host

            self._context[host] = ctx = spnego.client(
                username=self.principal,
                hostname=kerb_host,
                service=self.service,
                channel_bindings=self.cbt_struct,
                context_req=gssflags,
                protocol="kerberos",
            )

            # if we have a previous response from the server, use it to continue
            # the auth process, otherwise use an empty value
            negotiate_resp_value = None if is_preemptive else _negotiate_value(
                response)

            kerb_stage = "ctx step"
            gss_response = ctx.step(in_token=negotiate_resp_value)

            return "Negotiate {0}".format(
                base64.b64encode(gss_response).decode())

        except spnego.exceptions.SpnegoError as error:
            log.exception(
                "generate_request_header(): {0} failed:".format(kerb_stage))
            log.exception(error)
            raise KerberosExchangeError("%s failed: %s" %
                                        (kerb_stage, str(error))) from error
示例#10
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())
示例#11
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)
示例#12
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)
示例#13
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
示例#14
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)
示例#15
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
示例#16
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)
示例#17
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)
示例#18
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)
示例#19
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)
示例#20
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)
示例#21
0
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
示例#22
0
def main():
    client = spnego.client('username', 'password', hostname='server')

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

        in_token = exchange_data(out_token)

    print("Negotiated protocol: %s" % client.negotiated_protocol)

    data = b"my secret"
    enc_data = client.wrap(data)

    resp = exchange_data(enc_data.data)
    dec_data = client.unwrap(resp)

    print("Server response: %s" % dec_data.data.decode('utf-8'))
示例#23
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)
示例#24
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)
示例#25
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)
示例#26
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)
示例#27
0
def test_ntlm_custom_time(include_time, expected, ntlm_cred, mocker,
                          monkeypatch):
    c = spnego.client(ntlm_cred[0],
                      ntlm_cred[1],
                      hostname=socket.gethostname(),
                      options=spnego.NegotiateOptions.use_ntlm,
                      protocol='ntlm')

    b_negotiate = c.step()
    negotiate = Negotiate.unpack(b_negotiate)

    flags = negotiate.flags | NegotiateFlags.request_target | NegotiateFlags.ntlm | \
        NegotiateFlags.always_sign | NegotiateFlags.target_info | NegotiateFlags.target_type_server

    server_challenge = os.urandom(8)
    target_name = to_text(socket.gethostname()).upper()

    target_info = TargetInfo()
    target_info[AvId.nb_computer_name] = target_name
    target_info[AvId.nb_domain_name] = u"WORKSTATION"
    target_info[AvId.dns_computer_name] = to_text(socket.getfqdn())

    if include_time:
        target_info[AvId.timestamp] = FileTime.now()

    challenge = Challenge(flags,
                          server_challenge,
                          target_name=target_name,
                          target_info=target_info)

    mock_now = mocker.MagicMock()
    mock_now.side_effect = FileTime.now
    monkeypatch.setattr(FileTime, 'now', mock_now)

    c.step(challenge.pack())
    assert c.complete
    assert mock_now.call_count == expected
示例#28
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)
示例#29
0
def test_ntlm_workstation_override(env_var, expected, ntlm_cred, monkeypatch):
    if env_var is not None:
        monkeypatch.setenv('NETBIOS_COMPUTER_NAME', env_var)

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

    b_negotiate = c.step()
    negotiate = Negotiate.unpack(b_negotiate)

    flags = negotiate.flags | NegotiateFlags.request_target | NegotiateFlags.ntlm | \
        NegotiateFlags.always_sign | NegotiateFlags.target_info | NegotiateFlags.target_type_server

    server_challenge = os.urandom(8)
    target_name = to_text(socket.gethostname()).upper()

    target_info = TargetInfo()
    target_info[AvId.nb_computer_name] = target_name
    target_info[AvId.nb_domain_name] = u"WORKSTATION"
    target_info[AvId.dns_computer_name] = to_text(socket.getfqdn())
    target_info[AvId.timestamp] = FileTime.now()

    version = Version(10, 0, 0, 1)
    challenge = Challenge(flags,
                          server_challenge,
                          target_name=target_name,
                          target_info=target_info,
                          version=version)

    b_auth = c.step(challenge.pack())
    auth = Authenticate.unpack(b_auth)

    assert auth.workstation == expected
示例#30
0
    def handle_401(self, response, **kwargs):
        response_auth_header = kwargs.pop('_pypsrp_auth_provider')
        response_auth_header_l = response_auth_header.lower()
        auth_provider = self.auth_provider

        if response_auth_header_l != self.auth_provider:
            if self.auth_provider == 'negotiate':
                auth_provider = response_auth_header_l

            elif response_auth_header_l != 'negotiate':
                raise ValueError(
                    "Server responded with the auth protocol '%s' which is incompatible with the "
                    "specified auth_provider '%s'" %
                    (response_auth_header, auth_provider))

        host = get_hostname(response.url)
        auth_hostname = self.hostname_override or host

        cbt = None
        if self.send_cbt:
            cbt_app_data = HTTPNegotiateAuth._get_cbt_data(response)
            if cbt_app_data:
                cbt = spnego.channel_bindings.GssChannelBindings(
                    application_data=cbt_app_data)

        context_req = spnego.ContextReq.default
        if self.delegate:
            context_req |= spnego.ContextReq.delegate

        spnego_options = spnego.NegotiateOptions.wrapping_winrm if self.wrap_required else 0
        context = spnego.client(self.username,
                                self.password,
                                hostname=auth_hostname,
                                service=self.service,
                                channel_bindings=cbt,
                                context_req=context_req,
                                protocol=auth_provider,
                                options=spnego_options)
        self.contexts[host] = context

        out_token = context.step()
        while not context.complete or out_token is not None:
            # consume content and release the original connection to allow the
            # new request to reuse the same one.
            response.content
            response.raw.release_conn()

            # create a request with the Negotiate token present
            request = response.request.copy()
            log.debug("Sending http request with new auth token")
            self._set_auth_token(request, out_token, response_auth_header)

            # send the request with the auth token and get the response
            response = response.connection.send(request, **kwargs)

            # attempt to retrieve the auth token response
            in_token = self._get_auth_token(response, self._regex)

            # break if there was no token received from the host and return the
            # last response
            if in_token in [None, b""]:
                log.debug(
                    "Did not receive a http response with an auth response, stopping authentication process"
                )
                break

            out_token = context.step(in_token)

        # This is used by the message encryption to decide the MIME protocol.
        setattr(context, 'response_auth_header', response_auth_header_l)

        return response