Exemple #1
0
def kerb_cred(monkeypatch):
    test_kerberos = os.environ.get('PYSPNEGO_TEST_KERBEROS', None)
    if not test_kerberos or not HAS_K5TEST:
        pytest.skip("Cannot create Kerberos credential without PYSPNEGO_TEST_REALM being set")

    realm = K5Realm()
    try:
        for k, v in realm.env.items():
            monkeypatch.setenv(to_native(k), to_native(v))

        yield realm

    finally:
        realm.stop()
        del realm
Exemple #2
0
def test_win_nt_auth_identity_set_domain():
    identity = sspi.WinNTAuthIdentity(None, u"original", None)

    test_domain = u"domain" + to_text(b"\xF0\x9D\x84\x9E")
    identity.domain = test_domain
    assert identity.domain == test_domain
    assert str(identity) == to_native(test_domain) + "\\"
Exemple #3
0
def test_win_nt_auth_identity_set_username():
    identity = sspi.WinNTAuthIdentity(u"original", None, None)

    test_user = u"user" + to_text(b"\xF0\x9D\x84\x9E")
    identity.username = test_user
    assert identity.username == test_user
    assert str(identity) == to_native(test_user)
Exemple #4
0
def test_get_credential_file_env_var_missing_file(tmpdir, monkeypatch):
    tmp_creds = os.path.join(to_text(tmpdir), u'pÿspᴞӛgӫ TÈ$' '.creds')

    monkeypatch.setenv('NTLM_USER_FILE', to_native(tmp_creds))

    actual = ntlm._get_credential_file()
    assert actual is None
Exemple #5
0
def ntlm_cred(tmpdir, monkeypatch):
    cleanup = None
    try:
        # Use unicode credentials to test out edge cases when dealing with non-ascii chars.
        username = u'ÜseӜ'
        password = u'Pӓ$sw0r̈d'

        if HAS_SSPI:
            domain = to_text(socket.gethostname())

            # Can only test this out with Windows due to issue with gss-ntlmssp when dealing with surrogate pairs.
            # https://github.com/gssapi/gss-ntlmssp/issues/20
            clef = to_text(b"\xF0\x9D\x84\x9E")
            username += clef
            password += clef

            buff = {
                'name': username,
                'password': password,
                'priv': win32netcon.USER_PRIV_USER,
                'comment': 'Test account for pypsnego tests',
                'flags': win32netcon.UF_NORMAL_ACCOUNT,
            }
            try:
                win32net.NetUserAdd(None, 1, buff)
            except win32net.error as err:
                if err.winerror != 2224:  # Account already exists
                    raise

            def cleanup():
                win32net.NetUserDel(None, username)
        else:
            domain = u'Dȫm̈Ąiᴞ'

            # gss-ntlmssp does a string comparison of the user/domain part using the current process locale settings.
            # To ensure it matches the credentials we specify with the non-ascii chars we need to ensure the locale is
            # something that can support UTF-8 character comparison. macOS can fail with unknown locale on getlocale(),
            # just default to env vars if this get fails.
            try:
                original_locale = locale.getlocale(locale.LC_CTYPE)
            except ValueError:
                original_locale = (None, None)

            def cleanup():
                locale.setlocale(locale.LC_CTYPE, original_locale)

            locale.setlocale(locale.LC_CTYPE, 'en_US.UTF-8')

        tmp_creds = os.path.join(to_text(tmpdir), u'pÿspᴞӛgӫ TÈ$''.creds')
        with open(tmp_creds, mode='wb') as fd:
            fd.write(to_bytes(u'%s:%s:%s' % (domain, username, password)))

        monkeypatch.setenv('NTLM_USER_FILE', to_native(tmp_creds))

        yield u"%s\\%s" % (domain, username), password

    finally:
        if cleanup:
            cleanup()
Exemple #6
0
def test_get_credential_file(tmpdir, monkeypatch):
    tmp_creds = os.path.join(to_text(tmpdir), u'pÿspᴞӛgӫ TÈ$' '.creds')
    with open(tmp_creds, mode='wb') as fd:
        fd.write(b"data")

    monkeypatch.setenv('NTLM_USER_FILE', to_native(tmp_creds))

    actual = ntlm._get_credential_file()
    assert actual == to_text(tmp_creds)
Exemple #7
0
def test_get_credential_from_file_no_matches(tmpdir, monkeypatch):
    tmp_creds = os.path.join(to_text(tmpdir), u'pÿspᴞӛgӫ TÈ$' '.creds')
    monkeypatch.setenv('NTLM_USER_FILE', to_native(tmp_creds))
    with open(tmp_creds, mode='wb') as fd:
        fd.write(b'domain:username:password')

    with pytest.raises(
            SpnegoError,
            match="Failed to find any matching credential in NTLM_USER_FILE "
            "credential store."):
        ntlm._NTLMCredential("fake", "username")
Exemple #8
0
    def __init__(self, username, password, hostname, service, channel_bindings,
                 context_req, usage, protocol, options, _is_wrapped):
        # type: (Optional[text_type], Optional[text_type], Optional[text_type], Optional[text_type], Optional[GssChannelBindings], ContextReq, str, text_type, NegotiateOptions, bool) -> None  # noqa
        self.usage = usage.lower()
        if self.usage not in ['initiate', 'accept']:
            raise ValueError("Invalid usage '%s', must be initiate or accept" %
                             self.usage)

        self.protocol = protocol.lower()
        if self.protocol not in [u'ntlm', u'kerberos', u'negotiate']:
            raise ValueError(
                to_native(
                    u"Invalid protocol '%s', must be ntlm, kerberos, or negotiate"
                    % self.protocol))

        if self.protocol not in self.available_protocols(options=options):
            raise ValueError("Protocol %s is not available" % self.protocol)

        self.username = to_text(username, nonstring='passthru')
        self.password = to_text(password, nonstring='passthru')

        self.spn = None
        if service or hostname:
            self.spn = to_text(
                "%s/%s" % (service.upper() if service else "HOST", hostname
                           or "unspecified"))

        self.channel_bindings = channel_bindings
        self.options = NegotiateOptions(options)

        self.context_req = context_req  # Generic context requirements.
        self._context_req = 0  # Provider specific context requirements.
        for generic, provider in self._context_attr_map:
            if context_req & generic:
                self._context_req |= provider

        self._context_attr = 0  # Provider specific context attributes, set by self.step().

        # Whether the context is wrapped inside another context.
        self._is_wrapped = _is_wrapped  # type: bool

        if options & NegotiateOptions.negotiate_kerberos and (
                self.protocol == 'negotiate'
                and 'kerberos' not in self.available_protocols()):
            raise FeatureMissingError(NegotiateOptions.negotiate_kerberos)

        if options & NegotiateOptions.wrapping_iov and not self.iov_available(
        ):
            raise FeatureMissingError(NegotiateOptions.wrapping_iov)
Exemple #9
0
def test_get_credential_from_file(line, username, domain, lm_hash, nt_hash,
                                  explicit, tmpdir, monkeypatch):
    tmp_creds = os.path.join(to_text(tmpdir), u'pÿspᴞӛgӫ TÈ$' '.creds')
    monkeypatch.setenv('NTLM_USER_FILE', to_native(tmp_creds))
    with open(tmp_creds, mode='wb') as fd:
        fd.write(to_bytes(line))

    if explicit:
        actual = ntlm._NTLMCredential(domain, username)

    else:
        actual = ntlm._NTLMCredential()

    assert actual.username == username
    assert actual.domain == domain
    assert actual.lm_hash == base64.b16decode(lm_hash)
    assert actual.nt_hash == base64.b16decode(nt_hash)
Exemple #10
0
    else:
        assert actual == r"SecBuffer(cbBuffer=4, BufferType=1, pvBuffer=b'\x01\x02\x03\x04')"


@pytest.mark.skipif(
    SKIP, reason='Can only test Cython code on Windows with compiled code.')
@pytest.mark.parametrize(
    'username, domain, expected',
    [(u"username", u"domain", "domain\\username"),
     (u"username@DOMAIN", u"", "username@DOMAIN"),
     (u"username@DOMAIN", None, "username@DOMAIN"),
     (None, u"domain", "domain\\"), (None, None, u""), (u"", u"", u""),
     (u"user" + to_text(b"\xF0\x9D\x84\x9E"),
      u"domain" + to_text(b"\xF0\x9D\x84\x9E"),
      to_native(u"domain{0}\\user{0}".format(to_text(b"\xF0\x9D\x84\x9E"))))])
def test_win_nt_auth_identity(username, domain, expected):
    identity = sspi.WinNTAuthIdentity(username, domain, u"password")

    assert repr(
        identity) == "<spnego._sspi_raw.sspi.WinNTAuthIdentity %s>" % expected
    assert str(identity) == expected


@pytest.mark.skipif(
    SKIP, reason='Can only test Cython code on Windows with compiled code.')
def test_win_nt_auth_identity_set_username():
    identity = sspi.WinNTAuthIdentity(u"original", None, None)

    test_user = u"user" + to_text(b"\xF0\x9D\x84\x9E")
    identity.username = test_user
Exemple #11
0
def test_invalid_lm_compat_level(level, monkeypatch):
    monkeypatch.setenv('LM_COMPAT_LEVEL', to_native(level))

    expected = "Invalid LM_COMPAT_LEVEL %s, must be between 0 and 5" % level
    with pytest.raises(SpnegoError, match=re.escape(expected)):
        ntlm.NTLMProxy("user", "pass")
Exemple #12
0
 def negotiated_protocol(self):
     # FIXME: Try and replicate GSSAPI. Will return None for acceptor until the first token is returned. Negotiate
     # for both iniator and acceptor until the context is established.
     package_info = query_context_attributes(self._context,
                                             SecPkgAttr.package_info)
     return to_native(package_info.name).lower()