Skip to content

Commit

Permalink
Merge pull request #135 from jborean93/master
Browse files Browse the repository at this point in the history
* Added support for CredSSP authentication
  • Loading branch information
nitzmahone committed Dec 6, 2016
2 parents 7115b87 + fa8007d commit e83a18f
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 10 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ install:
- pwd
- pip install coveralls
- pip install .[kerberos]
- pip install .[credssp]
- pip install -r requirements-test.txt
script:
- py.test -v --pep8 --cov=winrm --cov-report=term-missing winrm/tests/
Expand Down
43 changes: 37 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ For more information on WinRM, please visit
## Requirements
* Linux, Mac OS X or Windows
* CPython 2.6-2.7, 3.2-3.5 or PyPy 1.9
* [requests-kerberos](http://pypi.python.org/pypi/requests-kerberos) is optional
* [requests-kerberos](http://pypi.python.org/pypi/requests-kerberos) and [requests-credssp](https://github.com/jborean93/requests-credssp) is optional

## Installation
### To install pywinrm with support for basic, certificate, and NTLM auth, simply
Expand All @@ -34,6 +34,12 @@ $ sudo yum install gcc krb5-devel krb5-workstation
$ pip install pywinrm[kerberos]
```

### To use CredSSP authentication you need these optional depdencies

```bash
pip install pywinrm[credssp]
```

## Example Usage
### Run a process on a remote host
```python
Expand Down Expand Up @@ -108,6 +114,30 @@ p.cleanup_command(shell_id, command_id)
p.close_shell(shell_id)
```

### Valid transport options

pywinrm supports various transport methods in order to authenticate with the WinRM server. The options that are supported in the `transport` parameter are;
* `basic`: Basic auth only works for local Windows accounts not domain accounts. Credentials are base64 encoded when sending to the server.
* `plaintext`: Same as basic auth.
* `certificate`: Authentication is done through a certificate that is mapped to a local Windows account on the server.
* `ssl`: When used in conjunction with `cert_pem` and `cert_key_pem` it will use a certificate as above. If not will revert to basic auth over HTTPS.
* `kerberos`: Will use Kerberos authentication for domain accounts which only works when the client is in the same domain as the server and the required dependencies are installed. Currently a Kerberos ticket needs to be initiliased outside of pywinrm using the kinit command.
* `ntlm`: Will use NTLM authentication for both domain and local accounts. Currently no support for NTLMv2 auth and other features included in that version (WIP).
* `credssp`: Will use CredSSP authentication for both domain and local accounts. Allows double hop authentication. This only works over a HTTPS endpoint and not HTTP.

### HTTP or HTTPS endpoint

While either a HTTP or HTTPS endpoint can be used as the transport method, using HTTPS is prefered as the messages are encrypted using SSL. To use HTTPS either a self signed certificate or one from a CA can be used. You can use this [guide](http://www.joseph-streeter.com/?p=1086) to set up a HTTPS endpoint with a self signed certificate.

If you still wish to use a HTTP endpoint and loose confidentiality in your messages you will need to enable unencrypted messages in the server by running the following command
```
# from cmd:
winrm set winrm/config/service @{AllowUnencrypted="true"}
```
As a repeat this should definitely not be used as your credentials and messages will allow anybody to see what is sent over the wire.

There are plans in place to allow message encryption for messages sent with Kerberos or NTLM messages in the future.

### Enabling WinRM on remote host
Enable WinRM over HTTP and HTTPS with self-signed certificate (includes firewall rules):

Expand All @@ -121,22 +151,23 @@ Enable WinRM over HTTP for test usage (includes firewall rules):
winrm quickconfig
```

Enable WinRM basic authentication. For domain users, it is necessary to use NTLM or Kerberos authentication (both are enabled by default).
Enable WinRM basic authentication. For domain users, it is necessary to use NTLM, Kerberos or CredSSP authentication (Kerberos and NTLM authentication are enabled by default CredSSP isn't).
```
# from cmd:
winrm set winrm/config/service/auth @{Basic="true"}
```

Allow unencrypted message passing over WinRM (recommended only for troubleshooting and internal use)
```
# from cmd:
winrm set winrm/config/service @{AllowUnencrypted="true"}
Enable WinRM CredSSP authentication. This allows double hop support so you can authenticate with a network service when running command son the remote host. This command is run in Powershell.
```powershell
Enable-WSManCredSSP -Role Server -Force
Set-Item -Path "WSMan:\localhost\Service\Auth\CredSSP" -Value $true
```

### Contributors (alphabetically)

- Reina Abolofia
- Lukas Bednar
- Jordan Borean
- Chris Church
- Matt Clark
- Nir Cohen
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
packages=('winrm', 'winrm.tests'),
package_data={'winrm.tests': ['*.ps1']},
install_requires=['xmltodict', 'requests>=2.9.1', 'requests_ntlm>=0.3.0', 'six'],
extras_require = dict(kerberos=['requests-kerberos>=0.10.0']),
extras_require = dict(kerberos=['requests-kerberos>=0.10.0'], credssp=['requests-credssp>=0.0.1']),
classifiers=[
'Development Status :: 4 - Beta',
'Environment :: Console',
Expand Down
2 changes: 1 addition & 1 deletion winrm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
# These values can be easily checked for with hasattr(winrm, "FEATURE_X"),
# "'auth_type' in winrm.FEATURE_SUPPORTED_AUTHTYPES", etc for clients to sniff features
# supported by a particular version of pywinrm
FEATURE_SUPPORTED_AUTHTYPES=['basic', 'certificate', 'ntlm', 'kerberos', 'plaintext', 'ssl']
FEATURE_SUPPORTED_AUTHTYPES=['basic', 'certificate', 'ntlm', 'kerberos', 'plaintext', 'ssl', 'credssp']
FEATURE_READ_TIMEOUT=True
FEATURE_OPERATION_TIMEOUT=True

Expand Down
2 changes: 1 addition & 1 deletion winrm/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def __init__(
):
"""
@param string endpoint: the WinRM webservice endpoint
@param string transport: transport type, one of 'plaintext' (default), 'kerberos', 'ssl' # NOQA
@param string transport: transport type, one of 'plaintext' (default), 'kerberos', 'ssl', 'ntlm', 'credssp' # NOQA
@param string username: username
@param string password: password
@param string realm: unused
Expand Down
13 changes: 12 additions & 1 deletion winrm/transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@
except ImportError as ie:
pass

HAVE_CREDSSP = False
try:
from requests_credssp import HttpCredSSPAuth
HAVE_CREDSSP = True
except ImportError as ie:
pass

from winrm.exceptions import BasicAuthDisabledError, InvalidCredentialsError, \
WinRMError, WinRMTransportError, WinRMOperationTimeoutError

Expand Down Expand Up @@ -147,6 +154,10 @@ def build_session(self):
# 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)
Expand All @@ -156,7 +167,7 @@ def build_session(self):
return session

def send_message(self, message):
# TODO support kerberos session with message encryption
# TODO support kerberos/ntlm session with message encryption

if not self.session:
self.session = self.build_session()
Expand Down

0 comments on commit e83a18f

Please sign in to comment.