Skip to content

Commit

Permalink
Merge branch 'master' into 502-int
Browse files Browse the repository at this point in the history
  • Loading branch information
bitprophet committed Nov 4, 2015
2 parents 94c2018 + 16c106e commit e8142be
Show file tree
Hide file tree
Showing 81 changed files with 4,392 additions and 1,025 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ dist/
paramiko.egg-info/
test.log
docs/
demos/*.log
!sites/docs
_build
.coverage
11 changes: 5 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,23 @@ sudo: false
python:
- "2.6"
- "2.7"
- "3.2"
- "3.3"
- "3.4"
- "3.5"
install:
# Self-install for setup.py-driven deps
- pip install -e .
# Dev (doc/test running) requirements
- pip install coveralls # For coveralls.io specifically
- pip install -r dev-requirements.txt
script:
# Main tests, with coverage!
- invoke coverage
# Main tests, w/ coverage! (but skip coverage on 3.2, coverage.py dropped it)
- "[[ $TRAVIS_PYTHON_VERSION != 3.2 ]] && inv test --coverage || inv test"
# Ensure documentation & invoke pipeline run OK.
# Run 'docs' first since its objects.inv is referred to by 'www'.
# Also force warnings to be errors since most of them tend to be actual
# problems.
# Finally, skip them under Python 3.2 due to sphinx shenanigans
- "[[ $TRAVIS_PYTHON_VERSION != 3.2 ]] && invoke docs -o -W || true"
- "[[ $TRAVIS_PYTHON_VERSION != 3.2 ]] && invoke www -o -W || true"
- invoke docs -o -W www -o -W
notifications:
irc:
channels: "irc.freenode.org#paramiko"
Expand Down
8 changes: 8 additions & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ Bugs & Support
Please file bug reports at https://github.com/paramiko/paramiko/. There is currently no mailing list but we plan to create a new one ASAP.


Kerberos Support
----------------

Paramiko ships with optional Kerberos/GSSAPI support; for info on the extra
dependencies for this, see the 'GSS-API' section on the 'Installation' page of
our main website, http://paramiko.org .


Demo
----

Expand Down
42 changes: 39 additions & 3 deletions demos/demo_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,42 @@ def check_auth_publickey(self, username, key):
if (username == 'robey') and (key == self.good_pub_key):
return paramiko.AUTH_SUCCESSFUL
return paramiko.AUTH_FAILED

def check_auth_gssapi_with_mic(self, username,
gss_authenticated=paramiko.AUTH_FAILED,
cc_file=None):
"""
.. note::
We are just checking in `AuthHandler` that the given user is a
valid krb5 principal! We don't check if the krb5 principal is
allowed to log in on the server, because there is no way to do that
in python. So if you develop your own SSH server with paramiko for
a certain platform like Linux, you should call ``krb5_kuserok()`` in
your local kerberos library to make sure that the krb5_principal
has an account on the server and is allowed to log in as a user.
.. seealso::
`krb5_kuserok() man page
<http://www.unix.com/man-page/all/3/krb5_kuserok/>`_
"""
if gss_authenticated == paramiko.AUTH_SUCCESSFUL:
return paramiko.AUTH_SUCCESSFUL
return paramiko.AUTH_FAILED

def check_auth_gssapi_keyex(self, username,
gss_authenticated=paramiko.AUTH_FAILED,
cc_file=None):
if gss_authenticated == paramiko.AUTH_SUCCESSFUL:
return paramiko.AUTH_SUCCESSFUL
return paramiko.AUTH_FAILED

def enable_auth_gssapi(self):
UseGSSAPI = True
GSSAPICleanupCredentials = False
return UseGSSAPI

def get_allowed_auths(self, username):
return 'password,publickey'
return 'gssapi-keyex,gssapi-with-mic,password,publickey'

def check_channel_shell_request(self, channel):
self.event.set()
Expand All @@ -79,6 +112,8 @@ def check_channel_pty_request(self, channel, term, width, height, pixelwidth,
return True


DoGSSAPIKeyExchange = True

# now connect
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Expand All @@ -101,7 +136,8 @@ def check_channel_pty_request(self, channel, term, width, height, pixelwidth,
print('Got a connection!')

try:
t = paramiko.Transport(client)
t = paramiko.Transport(client, gss_kex=DoGSSAPIKeyExchange)
t.set_gss_host(socket.getfqdn(""))
try:
t.load_server_moduli()
except:
Expand All @@ -123,7 +159,7 @@ def check_channel_pty_request(self, channel, term, width, height, pixelwidth,
print('Authenticated!')

server.event.wait(10)
if not server.event.isSet():
if not server.event.is_set():
print('*** Client never asked for a shell.')
sys.exit(1)

Expand Down
19 changes: 14 additions & 5 deletions demos/demo_sftp.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
# setup logging
paramiko.util.log_to_file('demo_sftp.log')

# Paramiko client configuration
UseGSSAPI = True # enable GSS-API / SSPI authentication
DoGSSAPIKeyExchange = True
Port = 22

# get hostname
username = ''
if len(sys.argv) > 1:
Expand All @@ -45,10 +50,10 @@
if len(hostname) == 0:
print('*** Hostname required.')
sys.exit(1)
port = 22

if hostname.find(':') >= 0:
hostname, portstr = hostname.split(':')
port = int(portstr)
Port = int(portstr)


# get username
Expand All @@ -57,7 +62,10 @@
username = input('Username [%s]: ' % default_username)
if len(username) == 0:
username = default_username
password = getpass.getpass('Password for %s@%s: ' % (username, hostname))
if not UseGSSAPI:
password = getpass.getpass('Password for %s@%s: ' % (username, hostname))
else:
password = None


# get host key, if we know one
Expand All @@ -81,8 +89,9 @@

# now, connect and use paramiko Transport to negotiate SSH2 across the connection
try:
t = paramiko.Transport((hostname, port))
t.connect(username=username, password=password, hostkey=hostkey)
t = paramiko.Transport((hostname, Port))
t.connect(hostkey, username, password, gss_host=socket.getfqdn(hostname),
gss_auth=UseGSSAPI, gss_kex=DoGSSAPIKeyExchange)
sftp = paramiko.SFTPClient.from_transport(t)

# dirlist on remote host
Expand Down
22 changes: 19 additions & 3 deletions demos/demo_simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@

# setup logging
paramiko.util.log_to_file('demo_simple.log')
# Paramiko client configuration
UseGSSAPI = True # enable GSS-API / SSPI authentication
DoGSSAPIKeyExchange = True
port = 22

# get hostname
username = ''
Expand All @@ -48,7 +52,7 @@
if len(hostname) == 0:
print('*** Hostname required.')
sys.exit(1)
port = 22

if hostname.find(':') >= 0:
hostname, portstr = hostname.split(':')
port = int(portstr)
Expand All @@ -60,7 +64,8 @@
username = input('Username [%s]: ' % default_username)
if len(username) == 0:
username = default_username
password = getpass.getpass('Password for %s@%s: ' % (username, hostname))
if not UseGSSAPI or (not UseGSSAPI and not DoGSSAPIKeyExchange):
password = getpass.getpass('Password for %s@%s: ' % (username, hostname))


# now, connect and use paramiko Client to negotiate SSH2 across the connection
Expand All @@ -69,7 +74,18 @@
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.WarningPolicy())
print('*** Connecting...')
client.connect(hostname, port, username, password)
if not UseGSSAPI or (not UseGSSAPI and not DoGSSAPIKeyExchange):
client.connect(hostname, port, username, password)
else:
# SSPI works only with the FQDN of the target host
hostname = socket.getfqdn(hostname)
try:
client.connect(hostname, port, username, gss_auth=UseGSSAPI,
gss_kex=DoGSSAPIKeyExchange)
except Exception:
password = getpass.getpass('Password for %s@%s: ' % (username, hostname))
client.connect(hostname, port, username, password)

chan = client.invoke_shell()
print(repr(client.get_transport()))
print('*** Here we go!\n')
Expand Down
8 changes: 5 additions & 3 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# Older junk
tox>=1.4,<1.5
# For newer tasks like building Sphinx docs.
invoke>=0.7.0,<0.8
invocations>=0.5.0
invoke>=0.11.1
invocations>=0.11.0
sphinx>=1.1.3
alabaster>=0.6.1
releases>=0.5.2
wheel==0.23.0
semantic_version>=2.4,<2.5
wheel==0.24
twine==1.5
1 change: 1 addition & 0 deletions paramiko/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from paramiko.transport import SecurityOptions, Transport
from paramiko.client import SSHClient, MissingHostKeyPolicy, AutoAddPolicy, RejectPolicy, WarningPolicy
from paramiko.auth_handler import AuthHandler
from paramiko.ssh_gss import GSSAuth, GSS_AUTH_AVAILABLE
from paramiko.channel import Channel, ChannelFile
from paramiko.ssh_exception import SSHException, PasswordRequiredException, \
BadAuthenticationType, ChannelException, BadHostKeyException, \
Expand Down
2 changes: 1 addition & 1 deletion paramiko/_version.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
__version_info__ = (1, 13, 3)
__version_info__ = (1, 16, 0)
__version__ = '.'.join(map(str, __version_info__))
Loading

0 comments on commit e8142be

Please sign in to comment.