Beispiel #1
0
    def _build_auth_credssp(self, session: requests.Session) -> None:
        if self.username is None:
            raise ValueError("For credssp auth, the username must be specified")
        if self.password is None:
            raise ValueError("For credssp auth, the password must be specified")

        kwargs = self._get_auth_kwargs("credssp")
        session.auth = HttpCredSSPAuth(username=self.username, password=self.password, **kwargs)
    def test_verify_public_key_good(self, mock_unwrap):
        test_credssp_context = HttpCredSSPAuth('', '')
        test_ntlm_context = ntlm.Ntlm()
        test_ntlm_context.session_security = session_security.SessionSecurity(1, 'key'.encode())
        test_credssp_context.context = test_ntlm_context
        test_ts_request = TSRequest()
        test_ts_request.parse_data(public_key_ts_request)
        test_public_key = hex_to_byte('00') + server_pub_key_token[1:]

        test_credssp_context._verify_public_keys(test_public_key, test_ts_request)
Beispiel #3
0
def test(host: str):
    session = requests.Session()
    session.verify = False

    _host = CFG_HOSTS.get(host, None)
    if not _host:
        pyshellrm.error("Invalid host name")
        return False

    server    = _host.get("server", None)
    port      = _host.get("port", 5985)
    path      = _host.get("path", "wsman")
    username  = _host.get("username" , r'')
    password  = _host.get("password" , r'')
    auth      = _host.get("auth", "ntlm")
    ssl       = _host.get("ssl", False)

    req_url  = "http://" if not ssl else "https://"
    req_url += f"{server}:{port}/{path}"

    if auth == "ntlm":
        session.auth = HttpNtlmAuth(username, password)
    elif auth == "kerberos":
        if not HAS_KERBEROS:
            pyshellrm.error(
                f"{auth} auth attempt without requests-kerberos installed"
            )
            return False
        session.auth = HTTPKerberosAuth()
    elif auth == "credssp":
        if not HAS_CREDSSP:
            pyshellrm.error(
                f"{auth} auth attempt without requests-credssp installed"
            )
            return False
        session.auth = HttpCredSSPAuth(f'{username}', f'{password}',
                               auth_mechanism='auto')

    try:
        if not session.post(req_url).ok:
            pyshellrm.error(
                f"Failed to auth with {host} using {username}:{password}"
            )
            return False
    except requests.exceptions.ConnectionError:
        pyshellrm.error(
            f"Failed to establish a connection to {host}"
        )
        return False

    pyshellrm.success(
        f"Successfully connected to {host} with {username}:{password}"
    )
    return True
Beispiel #4
0
    def build_session(self):
        session = requests.Session()

        session.verify = self.server_cert_validation == 'validate'

        # configure proxies from HTTP/HTTPS_PROXY envvars
        session.trust_env = True
        settings = session.merge_environment_settings(url=self.endpoint, proxies={}, stream=None,
                                                      verify=None, cert=None)

        # we're only applying proxies from env, other settings are ignored
        session.proxies = settings['proxies']

        # We override the environment with passed values when they're defined
        if self.http_proxy: session.proxies['http'] = self.http_proxy
        if self.https_proxy: session.proxies['https'] = self.https_proxy
        
        if self.auth_method == 'kerberos':
            if not HAVE_KERBEROS:
                raise WinRMError("requested auth method is kerberos, but requests_kerberos is not installed")
            # TODO: do argspec sniffing on extensions to ensure we're not setting bogus kwargs on older versions
            session.auth = HTTPKerberosAuth(mutual_authentication=REQUIRED, delegate=self.kerberos_delegation,
                                            force_preemptive=True, principal=self.username,
                                            hostname_override=self.kerberos_hostname_override,
                                            sanitize_mutual_error_response=False)
        elif self.auth_method in ['certificate','ssl']:
            if self.auth_method == 'ssl' and not self.cert_pem and not self.cert_key_pem:
                # 'ssl' was overloaded for HTTPS with optional certificate auth,
                # fall back to basic auth if no cert specified
                session.auth = requests.auth.HTTPBasicAuth(username=self.username, password=self.password)
            else:
                session.cert = (self.cert_pem, self.cert_key_pem)
                session.headers['Authorization'] = \
                    "http://schemas.dmtf.org/wbem/wsman/1/wsman/secprofile/https/mutual"
        elif self.auth_method == 'ntlm':
            if not HAVE_NTLM:
                raise WinRMError("requested auth method is ntlm, but requests_ntlm is not installed")
            session.auth = HttpNtlmAuth(username=self.username, password=self.password)
        # TODO: ssl is not exactly right here- should really be client_cert
        elif self.auth_method in ['basic','plaintext']:
            session.auth = requests.auth.HTTPBasicAuth(username=self.username, password=self.password)
        elif self.auth_method == 'credssp':
            if not HAVE_CREDSSP:
                raise WinRMError("requests auth method is credssp, but requests-credssp is not installed")
            session.auth = HttpCredSSPAuth(username=self.username, password=self.password)

        else:
            raise WinRMError("unsupported auth method: %s" % self.auth_method)

        session.headers.update(self.default_headers)

        return session
    def test_verify_public_key_invalid(self, mock_unwrap):
        test_credssp_context = HttpCredSSPAuth('', '')
        test_ntlm_context = ntlm.Ntlm()
        test_ntlm_context.session_security = session_security.SessionSecurity(1, 'key'.encode())
        test_credssp_context.context = test_ntlm_context
        test_ts_request = TSRequest()
        test_ts_request.parse_data(public_key_ts_request)

        # Use the wrong first byte to ensure the keys don't match
        test_public_key = hex_to_byte('01') + server_pub_key_token[1:]

        with self.assertRaises(AssertionError) as context:
            test_credssp_context._verify_public_keys(test_public_key, test_ts_request)

        assert context.exception.args[0] == 'Could not verify key sent from the server, possibly man in the middle attack'
Beispiel #6
0
    def _build_auth_credssp(self, session):
        if not HAS_CREDSSP:
            raise ImportError("Cannot use CredSSP auth as requests-credssp is "
                              "not installed: %s" % str(CREDSSP_IMP_ERR))

        if self.username is None:
            raise ValueError("For credssp auth, the username must be "
                             "specified")
        if self.password is None:
            raise ValueError("For credssp auth, the password must be "
                             "specified")

        kwargs = self._get_auth_kwargs('credssp')
        session.auth = HttpCredSSPAuth(username=self.username,
                                       password=self.password,
                                       **kwargs)
Beispiel #7
0
    def build_session(self):
        session = requests.Session()
        proxies = dict()

        if self.proxy is None:
            proxies['no_proxy'] = '*'
        elif self.proxy != 'legacy_requests':
            # If there was a proxy specified then use it
            proxies['http'] = self.proxy
            proxies['https'] = self.proxy

        # Merge proxy environment variables
        settings = session.merge_environment_settings(url=self.endpoint,
                      proxies=proxies, stream=None, verify=None, cert=None)

        global DISPLAYED_PROXY_WARNING

        # We want to eventually stop reading proxy information from the environment.
        # Also only display the warning once. This method can be called many times during an application's runtime.
        if not DISPLAYED_PROXY_WARNING and self.proxy == 'legacy_requests' and (
                'http' in settings['proxies'] or 'https' in settings['proxies']):
            message = "'pywinrm' will use an environment defined proxy. This feature will be disabled in " \
                      "the future, please specify it explicitly."
            if 'http' in settings['proxies']:
                message += " HTTP proxy {proxy} discovered.".format(proxy=settings['proxies']['http'])
            if 'https' in settings['proxies']:
                message += " HTTPS proxy {proxy} discovered.".format(proxy=settings['proxies']['https'])

            DISPLAYED_PROXY_WARNING = True
            warnings.warn(message, DeprecationWarning)

        session.proxies = settings['proxies']

        # specified validation mode takes precedence
        session.verify = self.server_cert_validation == 'validate'

        # patch in CA path override if one was specified in init or env
        if session.verify:
            if self.ca_trust_path == 'legacy_requests' and settings['verify'] is not None:
                # We will
                session.verify = settings['verify']

                global DISPLAYED_CA_TRUST_WARNING

                # We want to eventually stop reading proxy information from the environment.
                # Also only display the warning once. This method can be called many times during an application's runtime.
                if not DISPLAYED_CA_TRUST_WARNING and session.verify is not True:
                    message = "'pywinrm' will use an environment variable defined CA Trust. This feature will be disabled in " \
                              "the future, please specify it explicitly."
                    if os.environ.get('REQUESTS_CA_BUNDLE') is not None:
                        message += " REQUESTS_CA_BUNDLE contains {ca_path}".format(ca_path=os.environ.get('REQUESTS_CA_BUNDLE'))
                    elif os.environ.get('CURL_CA_BUNDLE') is not None:
                        message += " CURL_CA_BUNDLE contains {ca_path}".format(ca_path=os.environ.get('CURL_CA_BUNDLE'))

                    DISPLAYED_CA_TRUST_WARNING = True
                    warnings.warn(message, DeprecationWarning)

            elif session.verify and self.ca_trust_path is not None:
                # session.verify can be either a bool or path to a CA store; prefer passed-in value over env if both are present
                session.verify = self.ca_trust_path

        encryption_available = False

        if self.auth_method == 'kerberos':
            if not HAVE_KERBEROS:
                raise WinRMError("requested auth method is kerberos, but requests_kerberos is not installed")

            man_args = dict(
                mutual_authentication=REQUIRED,
            )
            opt_args = dict(
                delegate=self.kerberos_delegation,
                force_preemptive=True,
                principal=self.username,
                hostname_override=self.kerberos_hostname_override,
                sanitize_mutual_error_response=False,
                service=self.service,
                send_cbt=self.send_cbt
            )
            kerb_args = self._get_args(man_args, opt_args, HTTPKerberosAuth.__init__)
            session.auth = HTTPKerberosAuth(**kerb_args)
            encryption_available = hasattr(session.auth, 'winrm_encryption_available') and session.auth.winrm_encryption_available
        elif self.auth_method in ['certificate', 'ssl']:
            if self.auth_method == 'ssl' and not self.cert_pem and not self.cert_key_pem:
                # 'ssl' was overloaded for HTTPS with optional certificate auth,
                # fall back to basic auth if no cert specified
                session.auth = requests.auth.HTTPBasicAuth(username=self.username, password=self.password)
            else:
                session.cert = (self.cert_pem, self.cert_key_pem)
                session.headers['Authorization'] = \
                    "http://schemas.dmtf.org/wbem/wsman/1/wsman/secprofile/https/mutual"
        elif self.auth_method == 'ntlm':
            if not HAVE_NTLM:
                raise WinRMError("requested auth method is ntlm, but requests_ntlm is not installed")
            man_args = dict(
                username=self.username,
                password=self.password
            )
            opt_args = dict(
                send_cbt=self.send_cbt
            )
            ntlm_args = self._get_args(man_args, opt_args, HttpNtlmAuth.__init__)
            session.auth = HttpNtlmAuth(**ntlm_args)
            # check if requests_ntlm has the session_security attribute available for encryption
            encryption_available = hasattr(session.auth, 'session_security')
        # TODO: ssl is not exactly right here- should really be client_cert
        elif self.auth_method in ['basic', 'plaintext']:
            session.auth = requests.auth.HTTPBasicAuth(username=self.username, password=self.password)
        elif self.auth_method == 'credssp':
            if not HAVE_CREDSSP:
                raise WinRMError("requests auth method is credssp, but requests-credssp is not installed")

            man_args = dict(
                username=self.username,
                password=self.password
            )
            opt_args = dict(
                disable_tlsv1_2=self.credssp_disable_tlsv1_2,
                auth_mechanism=self.credssp_auth_mechanism,
                minimum_version=self.credssp_minimum_version
            )
            credssp_args = self._get_args(man_args, opt_args, HttpCredSSPAuth.__init__)
            session.auth = HttpCredSSPAuth(**credssp_args)
            encryption_available = True
        else:
            raise WinRMError("unsupported auth method: %s" % self.auth_method)

        session.headers.update(self.default_headers)
        self.session = session

        # Will check the current config and see if we need to setup message encryption
        if self.message_encryption == 'always' and not encryption_available:
            raise WinRMError(
                "message encryption is set to 'always' but the selected auth method %s does not support it" % self.auth_method)
        elif encryption_available:
            if self.message_encryption == 'always':
                self.setup_encryption()
            elif self.message_encryption == 'auto' and not self.endpoint.lower().startswith('https'):
                self.setup_encryption()
Beispiel #8
0
    def build_session(self):
        session = requests.Session()

        # allow some settings to be merged from env
        session.trust_env = True
        settings = session.merge_environment_settings(url=self.endpoint,
                                                      proxies={},
                                                      stream=None,
                                                      verify=None,
                                                      cert=None)

        # get proxy settings from env
        # FUTURE: allow proxy to be passed in directly to supersede this value
        session.proxies = settings['proxies']

        # specified validation mode takes precedence
        session.verify = self.server_cert_validation == 'validate'

        # patch in CA path override if one was specified in init or env
        if session.verify and (self.ca_trust_path is not None
                               or settings['verify'] is not None):
            # session.verify can be either a bool or path to a CA store; prefer passed-in value over env if both are present
            session.verify = self.ca_trust_path or settings['verify']

        encryption_available = False

        if self.auth_method == 'kerberos':
            if not HAVE_KERBEROS:
                raise WinRMError(
                    "requested auth method is kerberos, but requests_kerberos is not installed"
                )

            man_args = dict(mutual_authentication=REQUIRED, )
            opt_args = dict(delegate=self.kerberos_delegation,
                            force_preemptive=True,
                            principal=self.username,
                            hostname_override=self.kerberos_hostname_override,
                            sanitize_mutual_error_response=False,
                            service=self.service,
                            send_cbt=self.send_cbt)
            kerb_args = self._get_args(man_args, opt_args,
                                       HTTPKerberosAuth.__init__)
            session.auth = HTTPKerberosAuth(**kerb_args)
            encryption_available = hasattr(
                session.auth, 'winrm_encryption_available'
            ) and session.auth.winrm_encryption_available
        elif self.auth_method in ['certificate', 'ssl']:
            if self.auth_method == 'ssl' and not self.cert_pem and not self.cert_key_pem:
                # 'ssl' was overloaded for HTTPS with optional certificate auth,
                # fall back to basic auth if no cert specified
                session.auth = requests.auth.HTTPBasicAuth(
                    username=self.username, password=self.password)
            else:
                session.cert = (self.cert_pem, self.cert_key_pem)
                session.headers['Authorization'] = \
                    "http://schemas.dmtf.org/wbem/wsman/1/wsman/secprofile/https/mutual"
        elif self.auth_method == 'ntlm':
            if not HAVE_NTLM:
                raise WinRMError(
                    "requested auth method is ntlm, but requests_ntlm is not installed"
                )
            man_args = dict(username=self.username, password=self.password)
            opt_args = dict(send_cbt=self.send_cbt)
            ntlm_args = self._get_args(man_args, opt_args,
                                       HttpNtlmAuth.__init__)
            session.auth = HttpNtlmAuth(**ntlm_args)
            # check if requests_ntlm has the session_security attribute available for encryption
            encryption_available = hasattr(session.auth, 'session_security')
        # TODO: ssl is not exactly right here- should really be client_cert
        elif self.auth_method in ['basic', 'plaintext']:
            session.auth = requests.auth.HTTPBasicAuth(username=self.username,
                                                       password=self.password)
        elif self.auth_method == 'credssp':
            if not HAVE_CREDSSP:
                raise WinRMError(
                    "requests auth method is credssp, but requests-credssp is not installed"
                )

            man_args = dict(username=self.username, password=self.password)
            opt_args = dict(disable_tlsv1_2=self.credssp_disable_tlsv1_2,
                            auth_mechanism=self.credssp_auth_mechanism,
                            minimum_version=self.credssp_minimum_version)
            credssp_args = self._get_args(man_args, opt_args,
                                          HttpCredSSPAuth.__init__)
            session.auth = HttpCredSSPAuth(**credssp_args)
            encryption_available = True
        else:
            raise WinRMError("unsupported auth method: %s" % self.auth_method)

        session.headers.update(self.default_headers)
        self.session = session

        # Will check the current config and see if we need to setup message encryption
        if self.message_encryption == 'always' and not encryption_available:
            raise WinRMError(
                "message encryption is set to 'always' but the selected auth method %s does not support it"
                % self.auth_method)
        elif encryption_available:
            if self.message_encryption == 'always':
                self.setup_encryption()
            elif self.message_encryption == 'auto' and not self.endpoint.lower(
            ).startswith('https'):
                self.setup_encryption()
Beispiel #9
0
    def build_session(self):
        session = requests.Session()

        session.verify = self.server_cert_validation == 'validate'

        # configure proxies from HTTP/HTTPS_PROXY envvars
        session.trust_env = True
        settings = session.merge_environment_settings(url=self.endpoint, proxies={}, stream=None,
                                                      verify=None, cert=None)

        # we're only applying proxies from env, other settings are ignored
        session.proxies = settings['proxies']

        encryption_available = False
        if self.auth_method == 'kerberos':
            if not HAVE_KERBEROS:
                raise WinRMError("requested auth method is kerberos, but requests_kerberos is not installed")
            # TODO: do argspec sniffing on extensions to ensure we're not setting bogus kwargs on older versions
            session.auth = HTTPKerberosAuth(mutual_authentication=REQUIRED, delegate=self.kerberos_delegation,
                                            force_preemptive=True, principal=self.username,
                                            hostname_override=self.kerberos_hostname_override,
                                            sanitize_mutual_error_response=False)
        elif self.auth_method in ['certificate', 'ssl']:
            if self.auth_method == 'ssl' and not self.cert_pem and not self.cert_key_pem:
                # 'ssl' was overloaded for HTTPS with optional certificate auth,
                # fall back to basic auth if no cert specified
                session.auth = requests.auth.HTTPBasicAuth(username=self.username, password=self.password)
            else:
                session.cert = (self.cert_pem, self.cert_key_pem)
                session.headers['Authorization'] = \
                    "http://schemas.dmtf.org/wbem/wsman/1/wsman/secprofile/https/mutual"
        elif self.auth_method == 'ntlm':
            if not HAVE_NTLM:
                raise WinRMError("requested auth method is ntlm, but requests_ntlm is not installed")
            session.auth = HttpNtlmAuth(username=self.username, password=self.password)
            # check if requests_ntlm has the session_security attribute available for encryption
            encryption_available = hasattr(session.auth, 'session_security')
        # TODO: ssl is not exactly right here- should really be client_cert
        elif self.auth_method in ['basic', 'plaintext']:
            session.auth = requests.auth.HTTPBasicAuth(username=self.username, password=self.password)
        elif self.auth_method == 'credssp':
            if not HAVE_CREDSSP:
                raise WinRMError("requests auth method is credssp, but requests-credssp is not installed")
            session.auth = HttpCredSSPAuth(username=self.username, password=self.password,
                                               disable_tlsv1_2=self.credssp_disable_tlsv1_2)
            encryption_available = hasattr(session.auth, 'wrap') and hasattr(session.auth, 'unwrap')
        else:
            raise WinRMError("unsupported auth method: %s" % self.auth_method)

        session.headers.update(self.default_headers)
        self.session = session

        # Will check the current config and see if we need to setup message encryption
        if self.message_encryption == 'always' and not encryption_available:
            raise WinRMError(
                "message encryption is set to 'always' but the selected auth method %s does not support it" % self.auth_method)
        elif encryption_available:
            if self.message_encryption == 'always':
                self.setup_encryption()
            elif self.message_encryption == 'auto' and not self.endpoint.lower().startswith('https'):
                self.setup_encryption()
 def test_tlsv1_2_disabled(self, tls_version, tls_options, cipher_assert):
     # The testing is actually happening in the mocking functions
     HttpCredSSPAuth('', '', disable_tlsv1_2=True)
 def test_tls1_2_option_default(self, tls_version, cipher_assert):
     # The testing is actually happening in the mocking functions
     HttpCredSSPAuth('', '')
    def test_auth_mechanism_unknown(self):
        with self.assertRaises(InvalidConfigurationException) as context:
            HttpCredSSPAuth('', '', auth_mechanism='unknown')

        self.assertTrue('Unknown auth mechanism unknown, please specify ntlm', context.exception.args)
    def test_auth_mechanism_kerberos(self):
        with self.assertRaises(InvalidConfigurationException) as context:
            HttpCredSSPAuth('', '', auth_mechanism='kerberos')

        self.assertTrue('Kerberos auth not yet implemented, please use NTLM instead', context.exception.args)
    def test_auth_mechanism_ntlm(self):
        test_mechanism = 'ntlm'
        actual_object = HttpCredSSPAuth('', '', auth_mechanism=test_mechanism)
        actual = actual_object.context

        assert isinstance(actual, ntlm.Ntlm)