Import upstream version 0.4.3
Kali Janitor
1 year, 5 months ago
0 | name: Test pywinrm | |
1 | on: | |
2 | push: | |
3 | branches: | |
4 | - master | |
5 | ||
6 | pull_request: | |
7 | branches: | |
8 | - master | |
9 | ||
10 | # env: | |
11 | # WINRM_USERNAME: pywinrm-test | |
12 | # WINRM_PASSWORD: Password123! | |
13 | ||
14 | jobs: | |
15 | test: | |
16 | runs-on: ${{ matrix.os }} | |
17 | strategy: | |
18 | fail-fast: false | |
19 | matrix: | |
20 | os: | |
21 | - macos-latest | |
22 | - ubuntu-latest | |
23 | - windows-latest | |
24 | python-version: | |
25 | - 2.7 | |
26 | - 3.6 | |
27 | - 3.7 | |
28 | - 3.8 | |
29 | - 3.9 | |
30 | - '3.10' | |
31 | - pypy-2.7 | |
32 | - pypy-3.7 | |
33 | arch: | |
34 | - x86 | |
35 | - x64 | |
36 | ||
37 | exclude: | |
38 | - os: macos-latest | |
39 | arch: x86 | |
40 | - os: macos-latest | |
41 | python-version: pypy-2.7 | |
42 | - os: macos-latest | |
43 | python-version: pypy-3.7 | |
44 | - os: ubuntu-latest | |
45 | arch: x86 | |
46 | - os: windows-latest | |
47 | python-version: pypy-2.7 | |
48 | - os: windows-latest | |
49 | python-version: pypy-3.7 | |
50 | ||
51 | steps: | |
52 | - uses: actions/checkout@v2 | |
53 | ||
54 | - name: set up python | |
55 | uses: actions/setup-python@v2 | |
56 | with: | |
57 | python-version: ${{ matrix.python-version }} | |
58 | architecture: ${{ matrix.arch }} | |
59 | ||
60 | # - name: Remove extra modules to speed up PowerShell startup module due to slow WinRM issue | |
61 | # if: startsWith(matrix.os, 'windows') | |
62 | # shell: bash | |
63 | # run: | | |
64 | # rm -rf "/c/Program Files/WindowsPowerShell/Modules/AWSPowerShell" | |
65 | # rm -rf "/c/Program Files/WindowsPowerShell/Modules/Microsoft.Graph*" | |
66 | ||
67 | # - name: set up Windows integration tests | |
68 | # if: startsWith(matrix.os, 'windows') | |
69 | # shell: pwsh | |
70 | # run: | | |
71 | # Write-Host 'Create local admin user' | |
72 | # $userParams = @{ | |
73 | # Name = $env:WINRM_USERNAME | |
74 | # Password = (ConvertTo-SecureString -AsPlainText -Force -String $env:WINRM_PASSWORD) | |
75 | # AccountNeverExpires = $true | |
76 | # PasswordNeverExpires = $true | |
77 | # } | |
78 | # $null = New-LocalUser @userParams | |
79 | # Add-LocalGroupMember -Group Administrators -Member $userParams.Name | |
80 | ||
81 | # Write-Host 'Setting up WinRM settings' | |
82 | # Enable-PSRemoting -Force -SkipNetworkProfileCheck | |
83 | # Enable-WSManCredSSP -Role Server -Force | |
84 | # Set-Item WSMan:\localhost\Service\Auth\Basic $true | |
85 | # Set-Item WSMan:\localhost\Service\Auth\CredSSP $true | |
86 | # Set-Item WSMan:\localhost\Service\AllowUnencrypted $true | |
87 | ||
88 | - name: set up Linux dependencies | |
89 | if: startsWith(matrix.os, 'ubuntu') | |
90 | run: >- | |
91 | sudo apt-get install -y | |
92 | gcc | |
93 | python-dev | |
94 | libkrb5-dev | |
95 | env: | |
96 | DEBIAN_FRONTEND: noninteractive | |
97 | ||
98 | - name: install dependencies | |
99 | run: | | |
100 | pip install coveralls | |
101 | pip install .[credssp,kerberos] | |
102 | pip install -r requirements-test.txt | |
103 | ||
104 | - name: run test - non Windows | |
105 | if: "!startsWith(matrix.os, 'windows')" | |
106 | run: | | |
107 | pytest -v --flake8 --cov=winrm --cov-report=term-missing winrm/tests/ | |
108 | ||
109 | - name: run test - Windows | |
110 | if: startsWith(matrix.os, 'windows') | |
111 | run: | | |
112 | pytest -v --flake8 --cov=winrm --cov-report=term-missing winrm/tests/ | |
113 | # env: | |
114 | # WINRM_TRANSPORT: basic | |
115 | # WINRM_ENDPOINT: http://localhost:5985/wsman | |
116 | ||
117 | - name: upload coverage data | |
118 | if: "!endsWith(matrix.python-version, '2.7')" # Uses an older coverals version that doesn't support GHA | |
119 | run: coveralls --service=github | |
120 | env: | |
121 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
122 | ||
123 | # - name: run integration with NTLM | |
124 | # if: startsWith(matrix.os, 'windows') | |
125 | # run: | | |
126 | # Set-Item WSMan:\localhost\Service\AllowUnencrypted $false | |
127 | # py.test -v winrm/tests/test_integration_protocol.py winrm/tests/test_integration_session.py | |
128 | # env: | |
129 | # WINRM_TRANSPORT: ntlm | |
130 | # WINRM_ENDPOINT: http://localhost:5985/wsman | |
131 | ||
132 | # - name: run integration with CredSSP | |
133 | # if: startsWith(matrix.os, 'windows') | |
134 | # run: | | |
135 | # Set-Item WSMan:\localhost\Service\AllowUnencrypted $false | |
136 | # py.test -v winrm/tests/test_integration_protocol.py winrm/tests/test_integration_session.py | |
137 | # env: | |
138 | # WINRM_TRANSPORT: credssp | |
139 | # WINRM_ENDPOINT: http://localhost:5985/wsman |
0 | # http://travis-ci.org/#!/diyan/pywinrm | |
1 | # pyenv used instead of native Python support in Travis CI to: | |
2 | # - Make build steps exactly the same on both Linux and Mac OS workers | |
3 | # - Make possible to debug build steps on local workstation | |
4 | # - Integrate new Python / PyPy releases earlier; pyenv does it with less lag than Travis | |
5 | language: generic | |
6 | cache: | |
7 | directories: | |
8 | - $HOME/.cache/pip | |
9 | - $HOME/.cache/pyenv | |
10 | matrix: | |
11 | include: | |
12 | # Define 'sudo: false' to run on container-based workers | |
13 | - { os: linux, dist: xenial, sudo: false, env: UBUNTU=16.04 PYENV=2.7.16 } | |
14 | - { os: linux, dist: xenial, sudo: false, env: UBUNTU=16.04 PYENV=3.5.7 } | |
15 | - { os: linux, dist: xenial, sudo: false, env: UBUNTU=16.04 PYENV=3.6.8 } | |
16 | - { os: linux, dist: xenial, sudo: false, env: UBUNTU=16.04 PYENV=3.7.3 } | |
17 | - { os: linux, dist: xenial, sudo: false, env: UBUNTU=16.04 PYENV=3.8-dev } | |
18 | - { os: linux, dist: xenial, sudo: false, env: UBUNTU=16.04 PYENV=pypy2.7-7.1.1 } | |
19 | ||
20 | # pyenv won't build on current Mac versions without some extra conditional help, try to fix this later... | |
21 | # - { os: osx, osx_image: xcode10.2, language: generic, env: OSX=10.14 PYENV=2.7.16 } | |
22 | # - { os: osx, osx_image: xcode10.2, language: generic, env: OSX=10.14 PYENV=3.7.3 } | |
23 | ||
24 | install: | |
25 | # Always use latest pyenv but keep installed Python versions in cache | |
26 | - rm -rf ~/.pyenv | |
27 | - git clone https://github.com/pyenv/pyenv.git ~/.pyenv | |
28 | - mkdir -p ~/.cache/pyenv/versions | |
29 | - which pyenv | |
30 | - printenv | |
31 | - ln -s ~/.cache/pyenv/versions ~/.pyenv/versions | |
32 | - export PATH="$HOME/.pyenv/shims:$HOME/.pyenv/bin:$PATH" | |
33 | - export PYENV_ROOT="$HOME/.pyenv" | |
34 | - pyenv --version | |
35 | - pyenv install --skip-existing $PYENV | |
36 | - pyenv global $PYENV | |
37 | - pyenv rehash | |
38 | - python --version | |
39 | - pip --version | |
40 | - pip install virtualenv | |
41 | - python -m virtualenv ~/.venv | |
42 | - source ~/.venv/bin/activate | |
43 | - pip install coveralls | |
44 | - pip install .[credssp] | |
45 | - pip install .[kerberos] | |
46 | - pip install -r requirements-test.txt | |
47 | script: | |
48 | - pytest -v --flake8 --cov=winrm --cov-report=term-missing winrm/tests/ | |
49 | ||
50 | after_success: | |
51 | - coveralls |
0 | 0 | # Changelog |
1 | 1 | |
2 | ### Version 0.4.3 | |
3 | - Fix invalid regex escape sequences. | |
4 | - Decoding CLIXML failures for `run_ps` will create a `UserWarning` rather than printing the warning. | |
5 | - Remove usage of deprecated Python API to support Python 3.11 | |
6 | ||
7 | ### Version 0.4.2 | |
8 | - Dropped Python 3.5 from support matrix as it is EOL. | |
9 | - Remove dependency on `distutils` that is deprecated in Python 3.10. | |
10 | ||
2 | 11 | ### Version 0.4.1 |
3 | - HOT FIX: Fixing an issue with `requests_kerbose` not imported correctly from the changes in `0.4.0`. | |
12 | - HOT FIX: Fixing an issue with `requests_kerberos` not imported correctly from the changes in `0.4.0`. | |
4 | 13 | |
5 | 14 | ### Version 0.4.0 |
6 | 15 | - Ensure `server_cert_validation=ignore` supersedes ca_trust_path/env overrides |
3 | 3 | that can run Python. |
4 | 4 | |
5 | 5 | [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/diyan/pywinrm/blob/master/LICENSE) |
6 | [![Travis Build](https://travis-ci.org/diyan/pywinrm.svg)](https://travis-ci.org/diyan/pywinrm) | |
7 | [![AppVeyor Build](https://ci.appveyor.com/api/projects/status/github/diyan/pywinrm?svg=true)](https://ci.appveyor.com/project/diyan/pywinrm) [![Coverage](https://coveralls.io/repos/diyan/pywinrm/badge.svg)](https://coveralls.io/r/diyan/pywinrm) | |
6 | [![Test workflow](https://github.com/diyan/pywinrm/workflows/Test%20pywinrm/badge.svg)](https://github.com/diyan/pywinrm/actions/workflows/ci.yml) | |
7 | [![Coverage](https://coveralls.io/repos/diyan/pywinrm/badge.svg)](https://coveralls.io/r/diyan/pywinrm) | |
8 | 8 | [![PyPI](https://img.shields.io/pypi/dm/pywinrm.svg)](https://pypi.python.org/pypi/pywinrm) |
9 | 9 | |
10 | 10 | WinRM allows you to perform various management tasks remotely. These include, |
0 | environment: | |
1 | global: | |
2 | # SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the | |
3 | # /E:ON and /V:ON options are not enabled in the batch script intepreter | |
4 | # See: http://stackoverflow.com/a/13751649/163740 | |
5 | WITH_COMPILER: "cmd /E:ON /V:ON /C .\\scripts\\run_with_compiler.cmd" | |
6 | matrix: | |
7 | # https://www.appveyor.com/docs/installed-software/#python | |
8 | # NOTE Python 2.6 for Windows is no longer supported by the Python core team | |
9 | - PYTHON: Python27 | |
10 | - PYTHON: Python27-x64 | |
11 | - PYTHON: Python35 | |
12 | - PYTHON: Python35-x64 | |
13 | - PYTHON: Python36 | |
14 | - PYTHON: Python36-x64 | |
15 | - PYTHON: Python37 | |
16 | - PYTHON: Python37-x64 | |
17 | ||
18 | init: | |
19 | - ps: | | |
20 | $ErrorActionPreference = "Stop" | |
21 | # Override default Python version/architecture | |
22 | $env:Path="C:\$env:PYTHON;C:\$env:PYTHON\Scripts;$env:PATH" | |
23 | # disable "Python 2.7 is going away soon" warnings | |
24 | $env:PYTHONWARNINGS="ignore:DEPRECATION" | |
25 | python -c "import platform; print('Python', platform.python_version(), platform.architecture()[0])" | |
26 | # always install latest pip | |
27 | $(curl -UseBasicParsing https://bootstrap.pypa.io/get-pip.py).Content | python | |
28 | pip --version | |
29 | ||
30 | install: | |
31 | - ps: | | |
32 | Enable-WSManCredSSP -Role Server -Force | |
33 | Set-Item WSMan:\localhost\Service\Auth\Basic $true | |
34 | Set-Item WSMan:\localhost\Service\Auth\CredSSP $true | |
35 | Set-Item WSMan:\localhost\Service\AllowUnencrypted $true | |
36 | Invoke-Expression $($env:WITH_COMPILER + " pip install cffi coveralls") | |
37 | pip install . | |
38 | pip install -r requirements-test.txt | |
39 | pip install .[credssp] | |
40 | ||
41 | build: off # Do not run MSBuild, build stuff at install step | |
42 | ||
43 | build_script: | |
44 | - echo build_script | |
45 | ||
46 | test_script: | |
47 | # configure winrm envvars for tests | |
48 | - ps: | | |
49 | $ErrorActionPreference = "Stop" | |
50 | $env:WINRM_USERNAME=$($env:USERNAME) | |
51 | $env:WINRM_PASSWORD=[Microsoft.Win32.Registry]::GetValue("HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon", "DefaultPassword", '') | |
52 | $env:WINRM_TRANSPORT="basic" | |
53 | $env:WINRM_ENDPOINT="http://localhost:5985/wsman" | |
54 | ||
55 | py.test -v --cov-report=term-missing --cov=. | |
56 | ||
57 | # Run integration tests with NTLM to check message encryption | |
58 | $env:WINRM_TRANSPORT="ntlm" | |
59 | Set-Item WSMan:\localhost\Service\AllowUnencrypted $false | |
60 | py.test -v winrm/tests/test_integration_protocol.py winrm/tests/test_integration_session.py | |
61 | ||
62 | # Run integration tests with CredSSP to check message encryption | |
63 | $env:WINRM_TRANSPORT="credssp" | |
64 | py.test -v winrm/tests/test_integration_protocol.py winrm/tests/test_integration_session.py | |
65 | ||
66 | after_test: | |
67 | - echo after_test |
0 | 0 | # this assumes the base requirements have been satisfied via setup.py |
1 | # pin specific versions to keep things more stable over time; only pin sub-packages if necessary | |
2 | pytest==4.4.2 | |
3 | pytest-cov==2.7.1 | |
4 | pytest-flake8==1.0.4 | |
5 | mock==3.0.5 | |
1 | pytest | |
2 | pytest-cov | |
3 | pytest-flake8==1.0.7 | |
4 | mock |
0 | :: To build extensions for 64 bit Python 3, we need to configure environment | |
1 | :: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of: | |
2 | :: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1) | |
3 | :: | |
4 | :: To build extensions for 64 bit Python 2, we need to configure environment | |
5 | :: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of: | |
6 | :: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0) | |
7 | :: | |
8 | :: 32 bit builds do not require specific environment configurations. | |
9 | :: | |
10 | :: Note: this script needs to be run with the /E:ON and /V:ON flags for the | |
11 | :: cmd interpreter, at least for (SDK v7.0) | |
12 | :: | |
13 | :: More details at: | |
14 | :: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows | |
15 | :: http://stackoverflow.com/a/13751649/163740 | |
16 | :: | |
17 | :: Author: Olivier Grisel | |
18 | :: License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/ | |
19 | @ECHO OFF | |
20 | ||
21 | SET COMMAND_TO_RUN=%* | |
22 | SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows | |
23 | ||
24 | SET MAJOR_PYTHON_VERSION="%PYTHON_VERSION:~0,1%" | |
25 | IF %MAJOR_PYTHON_VERSION% == "2" ( | |
26 | SET WINDOWS_SDK_VERSION="v7.0" | |
27 | ) ELSE IF %MAJOR_PYTHON_VERSION% == "3" ( | |
28 | SET WINDOWS_SDK_VERSION="v7.1" | |
29 | ) ELSE ( | |
30 | ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%" | |
31 | EXIT 1 | |
32 | ) | |
33 | ||
34 | IF "%PYTHON_ARCH%"=="64" ( | |
35 | ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture | |
36 | SET DISTUTILS_USE_SDK=1 | |
37 | SET MSSdk=1 | |
38 | "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION% | |
39 | "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release | |
40 | ECHO Executing: %COMMAND_TO_RUN% | |
41 | call %COMMAND_TO_RUN% || EXIT 1 | |
42 | ) ELSE ( | |
43 | ECHO Using default MSVC build environment for 32 bit architecture | |
44 | ECHO Executing: %COMMAND_TO_RUN% | |
45 | call %COMMAND_TO_RUN% || EXIT 1 | |
46 | ) |
0 | 0 | from setuptools import setup, find_packages |
1 | 1 | |
2 | __version__ = '0.4.1' | |
2 | __version__ = '0.4.3' | |
3 | 3 | project_name = 'pywinrm' |
4 | 4 | |
5 | 5 | # PyPi supports only reStructuredText, so pandoc should be installed |
22 | 22 | license='MIT license', |
23 | 23 | packages=find_packages(), |
24 | 24 | package_data={'winrm.tests': ['*.ps1']}, |
25 | install_requires=['xmltodict', 'requests>=2.9.1', 'requests_ntlm>=0.3.0', 'six'], | |
25 | install_requires=['xmltodict', 'requests>=2.9.1', 'requests_ntlm>=1.1.0', 'six'], | |
26 | 26 | extras_require={ |
27 | 27 | 'credssp': ['requests-credssp>=1.0.0'], |
28 | 28 | 'kerberos:sys_platform=="win32"': ['winkerberos>=0.5.0'], |
39 | 39 | 'Programming Language :: Python :: 2', |
40 | 40 | 'Programming Language :: Python :: 2.7', |
41 | 41 | 'Programming Language :: Python :: 3', |
42 | 'Programming Language :: Python :: 3.5', | |
43 | 42 | 'Programming Language :: Python :: 3.6', |
44 | 43 | 'Programming Language :: Python :: 3.7', |
45 | 44 | 'Programming Language :: Python :: 3.8', |
45 | 'Programming Language :: Python :: 3.9', | |
46 | 'Programming Language :: Python :: 3.10', | |
46 | 47 | 'Programming Language :: Python :: Implementation :: PyPy', |
47 | 48 | 'Topic :: Software Development :: Libraries :: Python Modules', |
48 | 49 | 'Topic :: System :: Clustering', |
1 | 1 | import re |
2 | 2 | from base64 import b64encode |
3 | 3 | import xml.etree.ElementTree as ET |
4 | import warnings | |
4 | 5 | |
5 | 6 | from winrm.protocol import Protocol |
6 | 7 | |
77 | 78 | new_msg += s.text.replace("_x000D__x000A_", "\n") |
78 | 79 | except Exception as e: |
79 | 80 | # if any of the above fails, the msg was not true xml |
80 | # print a warning and return the orignal string | |
81 | # TODO do not print, raise user defined error instead | |
82 | print("Warning: there was a problem converting the Powershell" | |
83 | " error message: %s" % (e)) | |
81 | # print a warning and return the original string | |
82 | warnings.warn( | |
83 | "There was a problem converting the Powershell error " | |
84 | "message: %s" % (e)) | |
84 | 85 | else: |
85 | 86 | # if new_msg was populated, that's our error message |
86 | 87 | # otherwise the original error message will be used |
103 | 104 | @staticmethod |
104 | 105 | def _build_url(target, transport): |
105 | 106 | match = re.match( |
106 | '(?i)^((?P<scheme>http[s]?)://)?(?P<host>[0-9a-z-_.]+)(:(?P<port>\d+))?(?P<path>(/)?(wsman)?)?', target) # NOQA | |
107 | r'(?i)^((?P<scheme>http[s]?)://)?(?P<host>[0-9a-z-_.]+)(:(?P<port>\d+))?(?P<path>(/)?(wsman)?)?', target) # NOQA | |
107 | 108 | scheme = match.group('scheme') |
108 | 109 | if not scheme: |
109 | 110 | # TODO do we have anything other than HTTP/HTTPS |
91 | 91 | """ |
92 | 92 | Takes in the encrypted response from the server and decrypts it |
93 | 93 | |
94 | :param response: The response that needs to be decrytped | |
94 | :param response: The response that needs to be decrypted | |
95 | 95 | :return: The unencrypted message from the server |
96 | 96 | """ |
97 | 97 | content_type = response.headers['Content-Type'] |
6 | 6 | |
7 | 7 | |
8 | 8 | class WinRMTransportError(Exception): |
9 | """WinRM errors specific to transport-level problems (unexpcted HTTP error codes, etc)""" | |
9 | """WinRM errors specific to transport-level problems (unexpected HTTP error codes, etc)""" | |
10 | 10 | |
11 | 11 | @property |
12 | 12 | def protocol(self): |
55 | 55 | Any other value will be considered the CA trust path to use. |
56 | 56 | @param string cert_pem: client authentication certificate file path in PEM format # NOQA |
57 | 57 | @param string cert_key_pem: client authentication certificate key file path in PEM format # NOQA |
58 | @param string server_cert_validation: whether server certificate should be validated on Python versions that suppport it; one of 'validate' (default), 'ignore' #NOQA | |
58 | @param string server_cert_validation: whether server certificate should be validated on Python versions that support it; one of 'validate' (default), 'ignore' #NOQA | |
59 | 59 | @param bool kerberos_delegation: if True, TGT is sent to target server to allow multiple hops # NOQA |
60 | 60 | @param int read_timeout_sec: maximum seconds to wait before an HTTP connect/read times out (default 30). This value should be slightly higher than operation_timeout_sec, as the server can block *at least* that long. # NOQA |
61 | 61 | @param int operation_timeout_sec: maximum allowed time in seconds for any single wsman HTTP operation (default 20). Note that operation timeouts while receiving output (the only wsman operation that should take any significant time, and where these timeouts are expected) will be silently retried indefinitely. # NOQA |
435 | 435 | @param string command_id: The command id on the remote machine. |
436 | 436 | See #run_command |
437 | 437 | #@return [Hash] Returns a Hash with a key :exitcode and :data. |
438 | Data is an Array of Hashes where the cooresponding key | |
438 | Data is an Array of Hashes where the corresponding key | |
439 | 439 | # is either :stdout or :stderr. The reason it is in an Array so so |
440 | we can get the output in the order it ocurrs on | |
440 | we can get the output in the order it occurs on | |
441 | 441 | # the console. |
442 | 442 | """ |
443 | 443 | stdout_buffer, stderr_buffer = [], [] |
0 | import pytest | |
1 | ||
0 | 2 | from winrm import Session |
1 | 3 | |
2 | 4 | |
77 | 79 | expected = msg |
78 | 80 | actual = s._clean_error_msg(msg) |
79 | 81 | assert actual == expected |
82 | ||
83 | ||
84 | def test_decode_clixml_invalid_xml(): | |
85 | s = Session('windows-host.example.com', auth=('john.smith', 'secret')) | |
86 | msg = b'#< CLIXML\r\n<in >dasf<?dsfij>' | |
87 | ||
88 | with pytest.warns(UserWarning, match="There was a problem converting the Powershell error message"): | |
89 | actual = s._clean_error_msg(msg) | |
90 | ||
91 | assert actual == msg |
0 | 0 | from __future__ import unicode_literals |
1 | 1 | import sys |
2 | 2 | import os |
3 | import inspect | |
4 | 3 | import requests |
5 | 4 | import requests.auth |
6 | 5 | import warnings |
7 | 6 | |
8 | from distutils.util import strtobool | |
9 | 7 | from winrm.exceptions import InvalidCredentialsError, WinRMError, WinRMTransportError |
10 | 8 | from winrm.encryption import Encryption |
11 | 9 | |
45 | 43 | pass |
46 | 44 | |
47 | 45 | __all__ = ['Transport'] |
46 | ||
47 | ||
48 | def strtobool(value): | |
49 | value = value.lower() | |
50 | if value in ('true', 't', 'yes', 'y', 'on', '1'): | |
51 | return True | |
52 | ||
53 | elif value in ('false', 'f', 'no', 'n', 'off', '0'): | |
54 | return False | |
55 | ||
56 | else: | |
57 | raise ValueError("invalid truth value '%s'" % value) | |
48 | 58 | |
49 | 59 | |
50 | 60 | class UnsupportedAuthArgument(Warning): |
216 | 226 | |
217 | 227 | if self.auth_method == 'kerberos': |
218 | 228 | if not HAVE_KERBEROS: |
219 | raise WinRMError("requested auth method is kerberos, but requests_kerberos is not installed") | |
220 | ||
221 | man_args = dict( | |
229 | raise WinRMError("requested auth method is kerberos, but pykerberos is not installed") | |
230 | ||
231 | session.auth = HTTPKerberosAuth( | |
222 | 232 | mutual_authentication=REQUIRED, |
223 | ) | |
224 | opt_args = dict( | |
225 | 233 | delegate=self.kerberos_delegation, |
226 | 234 | force_preemptive=True, |
227 | 235 | principal=self.username, |
230 | 238 | service=self.service, |
231 | 239 | send_cbt=self.send_cbt |
232 | 240 | ) |
233 | kerb_args = self._get_args(man_args, opt_args, HTTPKerberosAuth.__init__) | |
234 | session.auth = HTTPKerberosAuth(**kerb_args) | |
235 | 241 | encryption_available = hasattr(session.auth, 'winrm_encryption_available') and session.auth.winrm_encryption_available |
236 | 242 | elif self.auth_method in ['certificate', 'ssl']: |
237 | 243 | if self.auth_method == 'ssl' and not self.cert_pem and not self.cert_key_pem: |
245 | 251 | elif self.auth_method == 'ntlm': |
246 | 252 | if not HAVE_NTLM: |
247 | 253 | raise WinRMError("requested auth method is ntlm, but requests_ntlm is not installed") |
248 | man_args = dict( | |
254 | ||
255 | session.auth = HttpNtlmAuth( | |
249 | 256 | username=self.username, |
250 | password=self.password | |
257 | password=self.password, | |
258 | send_cbt=self.send_cbt, | |
251 | 259 | ) |
252 | opt_args = dict( | |
253 | send_cbt=self.send_cbt | |
254 | ) | |
255 | ntlm_args = self._get_args(man_args, opt_args, HttpNtlmAuth.__init__) | |
256 | session.auth = HttpNtlmAuth(**ntlm_args) | |
257 | 260 | # check if requests_ntlm has the session_security attribute available for encryption |
258 | 261 | encryption_available = hasattr(session.auth, 'session_security') |
259 | 262 | # TODO: ssl is not exactly right here- should really be client_cert |
263 | 266 | if not HAVE_CREDSSP: |
264 | 267 | raise WinRMError("requests auth method is credssp, but requests-credssp is not installed") |
265 | 268 | |
266 | man_args = dict( | |
269 | session.auth = HttpCredSSPAuth( | |
267 | 270 | username=self.username, |
268 | password=self.password | |
269 | ) | |
270 | opt_args = dict( | |
271 | password=self.password, | |
271 | 272 | disable_tlsv1_2=self.credssp_disable_tlsv1_2, |
272 | 273 | auth_mechanism=self.credssp_auth_mechanism, |
273 | 274 | minimum_version=self.credssp_minimum_version |
274 | 275 | ) |
275 | credssp_args = self._get_args(man_args, opt_args, HttpCredSSPAuth.__init__) | |
276 | session.auth = HttpCredSSPAuth(**credssp_args) | |
277 | 276 | encryption_available = True |
278 | 277 | else: |
279 | 278 | raise WinRMError("unsupported auth method: %s" % self.auth_method) |
343 | 342 | else: |
344 | 343 | response_text = response.content |
345 | 344 | return response_text |
346 | ||
347 | def _get_args(self, mandatory_args, optional_args, function): | |
348 | argspec = set(inspect.getargspec(function).args) | |
349 | function_args = dict() | |
350 | for name, value in mandatory_args.items(): | |
351 | if name in argspec: | |
352 | function_args[name] = value | |
353 | else: | |
354 | raise Exception("Function %s does not contain mandatory arg " | |
355 | "%s, check installed version with pip list" | |
356 | % (str(function), name)) | |
357 | ||
358 | for name, value in optional_args.items(): | |
359 | if name in argspec: | |
360 | function_args[name] = value | |
361 | else: | |
362 | warnings.warn("Function %s does not contain optional arg %s, " | |
363 | "check installed version with pip list" | |
364 | % (str(function), name)) | |
365 | ||
366 | return function_args |
97 | 97 | else: |
98 | 98 | # There's no need to re-compile this EVERY time it is called. Compile |
99 | 99 | # it once and you won't have the performance hit of the compilation. |
100 | regex = re.compile('(?:.*,)*\s*Negotiate\s*([^,]*),?', re.I) | |
100 | regex = re.compile(r'(?:.*,)*\s*Negotiate\s*([^,]*),?', re.I) | |
101 | 101 | _negotiate_value.regex = regex |
102 | 102 | |
103 | 103 | authreq = response.headers.get('www-authenticate', None) |