diff options
-rw-r--r-- | paramiko/auth_handler.py | 6 | ||||
-rw-r--r-- | paramiko/kex_gss.py | 100 | ||||
-rw-r--r-- | paramiko/server.py | 80 | ||||
-rw-r--r-- | paramiko/ssh_gss.py | 295 | ||||
-rw-r--r-- | paramiko/transport.py | 43 | ||||
-rw-r--r-- | sites/docs/api/kex_gss.rst | 5 | ||||
-rw-r--r-- | sites/docs/api/ssh_gss.rst | 14 | ||||
-rw-r--r-- | sites/docs/index.rst | 2 |
8 files changed, 248 insertions, 297 deletions
diff --git a/paramiko/auth_handler.py b/paramiko/auth_handler.py index 9c431c45..8532d1f9 100644 --- a/paramiko/auth_handler.py +++ b/paramiko/auth_handler.py @@ -295,7 +295,7 @@ class AuthHandler (object): """ RFC 4462 says we are not required to implement GSS-API error messages. - @see: U{RFC 4462 Section 3.8<www.ietf.org/rfc/rfc4462.txt>} + :see: `RFC 4462 Section 3.8 <http://www.ietf.org/rfc/rfc4462.txt>`_ """ raise SSHException("Server returned an error token") elif ptype == MSG_USERAUTH_GSSAPI_ERROR: @@ -481,7 +481,7 @@ class AuthHandler (object): """ RFC 4462 says we are not required to implement GSS-API error messages. - @see: U{RFC 4462 Section 3.8 <www.ietf.org/rfc/rfc4462.txt>} + :see: `RFC 4462 Section 3.8 <http://www.ietf.org/rfc/rfc4462.txt>`_ """ while True: m = Message() @@ -524,7 +524,7 @@ class AuthHandler (object): raise if retval == 0: """ - @todo: Implement client credential saving + :todo: Implement client credential saving The OpenSSH server is able to create a TGT with the delegated client credentials, but this is not supported by GSS-API. """ diff --git a/paramiko/kex_gss.py b/paramiko/kex_gss.py index 1a810b8b..02f943ba 100644 --- a/paramiko/kex_gss.py +++ b/paramiko/kex_gss.py @@ -25,20 +25,20 @@ This module provides GSS-API / SSPI Key Exchange for Paramiko as defined in RFC 4462 with the following restrictions: Credential delegation is not supported in server mode, To Use this module, you need the following additional python packages: -U{pyasn1 >= 0.1.7 <https://pypi.python.org/pypi/pyasn1>}, -U{python-gssapi >= 0.4.0 (Unix) <https://pypi.python.org/pypi/python-gssapi>}, -U{pywin32 2.1.8 (Windows) <sourceforge.net/projects/pywin32/>}. - -@summary: SSH2 GSS-API / SSPI Authenticated Diffie-Hellman Key Exchange Module -@version: 0.1 -@author: Sebastian Deiss -@contact: U{https://github.com/SebastianDeiss/paramiko/issues} -@organization: science + computing ag - (U{EMail<mailto:a.kruis@science-computing.de>}) -@copyright: (C) 2003-2007 Robey Pointer, (C) 2013-2014 U{science + computing ag - <https://www.science-computing.de>} -@license: GNU Lesser General Public License (LGPL) -@see: L{ssh_gss} +`pyasn1 >= 0.1.7 <https://pypi.python.org/pypi/pyasn1>`_, +`python-gssapi >= 0.4.0 (Unix) <https://pypi.python.org/pypi/python-gssapi>`_, +`pywin32 2.1.8 (Windows) <http://sourceforge.net/projects/pywin32/>`_. + +:summary: SSH2 GSS-API / SSPI Authenticated Diffie-Hellman Key Exchange Module +:version: 0.1 +:author: Sebastian Deiss +:contact: https://github.com/SebastianDeiss/paramiko/issues +:organization: science + computing ag + `EMail <mailto:a.kruis@science-computing.de>`_ +:copyright: (C) 2003-2007 Robey Pointer, (C) 2013-2014 `science + computing ag + <https://www.science-computing.de>`_ +:license: GNU Lesser General Public License (LGPL) +:see: `.ssh_gss` Created on 12.12.2013 """ @@ -63,13 +63,13 @@ c_MSG_KEXGSS_GROUPREQ, c_MSG_KEXGSS_GROUP = [byte_chr(c) for c in range(40, 42)] class KexGSSGroup1(object): """ GSS-API / SSPI Authenticated Diffie-Hellman Key Exchange - as defined in U{RFC 4462 Section 2 <www.ietf.org/rfc/rfc4462.txt>} + as defined in `RFC 4462 Section 2 <http://www.ietf.org/rfc/rfc4462.txt>`_ - @note: RFC 4462 says we are not required to implement GSS-API error + :note: RFC 4462 says we are not required to implement GSS-API error messages. If an error occurs an exception will be thrown and the connection will be terminated. - @see: U{RFC 4462 Section 2.2 <www.ietf.org/rfc/rfc4462.txt>} + :see: `RFC 4462 Section 2.2 <http://www.ietf.org/rfc/rfc4462.txt>`_ """ # draft-ietf-secsh-transport-09.txt, page 17 P = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF @@ -115,10 +115,8 @@ class KexGSSGroup1(object): """ Parse the next packet. - @param ptype: The type of the incomming packet - @type ptype: Char - @param m: The paket content - @type m: L{Message} + :param char ptype: The type of the incomming packet + :param `.Message` m: The paket content """ if self.transport.server_mode and (ptype == MSG_KEXGSS_INIT): return self._parse_kexgss_init(m) @@ -155,8 +153,7 @@ class KexGSSGroup1(object): """ Parse the SSH2_MSG_KEXGSS_HOSTKEY message (client mode). - @param m: The content of the SSH2_MSG_KEXGSS_HOSTKEY message - @type m: L{Message} + :param `.Message` m: The content of the SSH2_MSG_KEXGSS_HOSTKEY message """ # client mode host_key = m.get_string() @@ -170,8 +167,7 @@ class KexGSSGroup1(object): """ Parse the SSH2_MSG_KEXGSS_CONTINUE message. - @param m: The content of the SSH2_MSG_KEXGSS_CONTINUE message - @type m: L{Message} + :param `.Message` m: The content of the SSH2_MSG_KEXGSS_CONTINUE message """ if not self.transport.server_mode: srv_token = m.get_string() @@ -190,8 +186,7 @@ class KexGSSGroup1(object): """ Parse the SSH2_MSG_KEXGSS_COMPLETE message (client mode). - @param m: The content of the SSH2_MSG_KEXGSS_COMPLETE message - @type m: L{Message} + :param `.Message` m: The content of the SSH2_MSG_KEXGSS_COMPLETE message """ # client mode if self.transport.host_key is None: @@ -232,8 +227,7 @@ class KexGSSGroup1(object): """ Parse the SSH2_MSG_KEXGSS_INIT message (server mode). - @param m: The content of the SSH2_MSG_KEXGSS_INIT message - @type m: L{Message} + :param `.Message` m: The content of the SSH2_MSG_KEXGSS_INIT message """ # server mode client_token = m.get_string() @@ -283,9 +277,8 @@ class KexGSSGroup1(object): The server may send a GSS-API error message. if it does, we display the error by throwing an exception (client mode). - @param m: The content of the SSH2_MSG_KEXGSS_ERROR message - @type m: L{Message} - @raise SSHException: Contains GSS-API major and minor status as well as + :param `.Message` m: The content of the SSH2_MSG_KEXGSS_ERROR message + :raise SSHException: Contains GSS-API major and minor status as well as the error message and the language tag of the message """ @@ -302,13 +295,13 @@ class KexGSSGroup1(object): class KexGSSGroup14(KexGSSGroup1): """ GSS-API / SSPI Authenticated Diffie-Hellman Group14 Key Exchange - as defined in U{RFC 4462 Section 2 <www.ietf.org/rfc/rfc4462.txt>} + as defined in `RFC 4462 Section 2 <http://www.ietf.org/rfc/rfc4462.txt>`_ - @note: RFC 4462 says we are not required to implement GSS-API error + :note: RFC 4462 says we are not required to implement GSS-API error messages. If an error occurs an exception will be thrown and the connection will be terminated. - @see: U{RFC 4462 Section 2.2 <www.ietf.org/rfc/rfc4462.txt>} + :see: `RFC 4462 Section 2.2 <http://www.ietf.org/rfc/rfc4462.txt>`_ """ P = 0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF G = 2 @@ -318,13 +311,13 @@ class KexGSSGroup14(KexGSSGroup1): class KexGSSGex(object): """ GSS-API / SSPI Authenticated Diffie-Hellman Group Exchange - as defined in U{RFC 4462 Section 2 <www.ietf.org/rfc/rfc4462.txt>} + as defined in `RFC 4462 Section 2 <http://www.ietf.org/rfc/rfc4462.txt>`_ - @note: RFC 4462 says we are not required to implement GSS-API error + :note: RFC 4462 says we are not required to implement GSS-API error messages. If an error occurs an exception will be thrown and the connection will be terminated. - @see: U{RFC 4462 Section 2.2 <www.ietf.org/rfc/rfc4462.txt>} + :see: `RFC 4462 Section 2.2 <http://www.ietf.org/rfc/rfc4462.txt>`_ """ NAME = "gss-gex-sha1-toWM5Slw5Ew8Mqkay+al2g==" min_bits = 1024 @@ -367,10 +360,8 @@ class KexGSSGex(object): """ Parse the next packet. - @param ptype: The type of the incomming packet - @type ptype: Char - @param m: The paket content - @type m: L{Message} + :param char ptype: The type of the incomming packet + :param `.Message` m: The paket content """ if ptype == MSG_KEXGSS_GROUPREQ: return self._parse_kexgss_groupreq(m) @@ -412,8 +403,7 @@ class KexGSSGex(object): """ Parse the SSH2_MSG_KEXGSS_GROUPREQ message (server mode). - @param m: The content of the SSH2_MSG_KEXGSS_GROUPREQ message - @type m: L{Message} + :param `.Message` m: The content of the SSH2_MSG_KEXGSS_GROUPREQ message """ minbits = m.get_int() preferredbits = m.get_int() @@ -451,8 +441,7 @@ class KexGSSGex(object): """ Parse the SSH2_MSG_KEXGSS_GROUP message (client mode). - @param m: The content of the SSH2_MSG_KEXGSS_GROUP message - @type m: L{Message} + :param `Message` m: The content of the SSH2_MSG_KEXGSS_GROUP message """ self.p = m.get_mpint() self.g = m.get_mpint() @@ -478,8 +467,7 @@ class KexGSSGex(object): """ Parse the SSH2_MSG_KEXGSS_INIT message (server mode). - @param m: The content of the SSH2_MSG_KEXGSS_INIT message - @type m: L{Message} + :param `Message` m: The content of the SSH2_MSG_KEXGSS_INIT message """ client_token = m.get_string() self.e = m.get_mpint() @@ -533,8 +521,7 @@ class KexGSSGex(object): """ Parse the SSH2_MSG_KEXGSS_HOSTKEY message (client mode). - @param m: The content of the SSH2_MSG_KEXGSS_HOSTKEY message - @type m: L{Message} + :param `Message` m: The content of the SSH2_MSG_KEXGSS_HOSTKEY message """ # client mode host_key = m.get_string() @@ -548,8 +535,7 @@ class KexGSSGex(object): """ Parse the SSH2_MSG_KEXGSS_CONTINUE message. - @param m: The content of the SSH2_MSG_KEXGSS_CONTINUE message - @type m: L{Message} + :param `Message` m: The content of the SSH2_MSG_KEXGSS_CONTINUE message """ if not self.transport.server_mode: srv_token = m.get_string() @@ -568,8 +554,7 @@ class KexGSSGex(object): """ Parse the SSH2_MSG_KEXGSS_COMPLETE message (client mode). - @param m: The content of the SSH2_MSG_KEXGSS_COMPLETE message - @type m: L{Message} + :param `Message` m: The content of the SSH2_MSG_KEXGSS_COMPLETE message """ if self.transport.host_key is None: self.transport.host_key = NullHostKey() @@ -619,9 +604,8 @@ class KexGSSGex(object): The server may send a GSS-API error message. if it does, we display the error by throwing an exception (client mode). - @param m: The content of the SSH2_MSG_KEXGSS_ERROR message - @type m: L{Message} - @raise SSHException: Contains GSS-API major and minor status as well as + :param `Message` m: The content of the SSH2_MSG_KEXGSS_ERROR message + :raise SSHException: Contains GSS-API major and minor status as well as the error message and the language tag of the message """ @@ -638,7 +622,7 @@ class KexGSSGex(object): class NullHostKey(object): """ This class represents the Null Host Key for GSS-API Key Exchange - as defined in U{RFC 4462 Section 5 <www.ietf.org/rfc/rfc4462.txt>} + as defined in `RFC 4462 Section 5 <http://www.ietf.org/rfc/rfc4462.txt>`_ """ def __init__(self): self.key = "" diff --git a/paramiko/server.py b/paramiko/server.py index 25c39063..cf396b15 100644 --- a/paramiko/server.py +++ b/paramiko/server.py @@ -237,26 +237,23 @@ class ServerInterface (object): Authenticate the given user to the server if he is a valid krb5 principal. - @param username: The username of the authenticating client - @type username: String - @param gss_authenticated: The result of the krb5 authentication - @type gss_authenticated: Integer - @param cc_filename: The krb5 client credentials cache filename - @type cc_filename: String - @return: L{AUTH_FAILED} if the user is not authenticated otherwise - L{AUTH_SUCCESSFUL} - @rtype: Integer - @note: Kerberos credential delegation is not supported. - @see: L{ssh_gss} - @note: We are just checking in L{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 cetain - plattform like Linux, you should call C{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. - @see: U{http://www.unix.com/man-page/all/3/krb5_kuserok/} + :param str username: The username of the authenticating client + :param int gss_authenticated: The result of the krb5 authentication + :param str cc_filename: The krb5 client credentials cache filename + :return: `.AUTH_FAILED` if the user is not authenticated otherwise + `.AUTH_SUCCESSFUL` + :rtype: int + :note: Kerberos credential delegation is not supported. + :see: `.ssh_gss` + :note: : We are just checking in L{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 cetain + plattform like Linux, you should call C{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. + :see: `http://www.unix.com/man-page/all/3/krb5_kuserok/` """ if gss_authenticated == AUTH_SUCCESSFUL: return AUTH_SUCCESSFUL @@ -271,26 +268,23 @@ class ServerInterface (object): If GSS-API Key Exchange was not performed, this authentication method won't be available. - @param username: The username of the authenticating client - @type username: String - @param gss_authenticated: The result of the krb5 authentication - @type gss_authenticated: Integer - @param cc_filename: The krb5 client credentials cache filename - @type cc_filename: String - @return: L{AUTH_FAILED} if the user is not authenticated otherwise - L{AUTH_SUCCESSFUL} - @rtype: Integer - @note: Kerberos credential delegation is not supported. - @see: L{ssh_gss}, L{kex_gss} - @note: We are just checking in L{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 C{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. - @see: U{http://www.unix.com/man-page/all/3/krb5_kuserok/} + :param str username: The username of the authenticating client + :param int gss_authenticated: The result of the krb5 authentication + :param str cc_filename: The krb5 client credentials cache filename + :return: `.AUTH_FAILED` if the user is not authenticated otherwise + `.AUTH_SUCCESSFUL` + :rtype: int + :note: Kerberos credential delegation is not supported. + :see: `.ssh_gss` `.kex_gss` + :note: : We are just checking in L{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 cetain + plattform like Linux, you should call C{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. + :see: `http://www.unix.com/man-page/all/3/krb5_kuserok/` """ if gss_authenticated == AUTH_SUCCESSFUL: return AUTH_SUCCESSFUL @@ -302,9 +296,9 @@ class ServerInterface (object): authentication. The default implementation always returns false. - @return: True if GSSAPI authentication is enabled otherwise false - @rtype: Boolean - @see: ssh_gss + :return: True if GSSAPI authentication is enabled otherwise false + :rtype: Boolean + :see: : `.ssh_gss` """ UseGSSAPI = False GSSAPICleanupCredentials = False diff --git a/paramiko/ssh_gss.py b/paramiko/ssh_gss.py index 35d654af..4dfdec11 100644 --- a/paramiko/ssh_gss.py +++ b/paramiko/ssh_gss.py @@ -24,20 +24,20 @@ RFC 4462 with the following restrictions: Credential delegation is not supported in server mode, GSS-API key exchange is supported, but not implemented in Paramiko. To Use this module, you need the following additional python packages: -U{pyasn1 >= 0.1.7 <https://pypi.python.org/pypi/pyasn1>}, -U{python-gssapi >= 0.4.0 (Unix) <https://pypi.python.org/pypi/python-gssapi>}, -U{pywin32 2.1.8 (Windows) <sourceforge.net/projects/pywin32/>}. - -@summary: SSH2 GSS-API / SSPI authentication module -@version: 0.1 -@author: Sebastian Deiss -@contact: U{https://github.com/SebastianDeiss/paramiko/issues} -@organization: science + computing ag - (U{EMail<mailto:a.kruis@science-computing.de>}) -@copyright: (C) 2013-2014 U{science + computing ag - <https://www.science-computing.de>} -@license: GNU Lesser General Public License (LGPL) -@see: L{kex_gss} +`pyasn1 >= 0.1.7 <https://pypi.python.org/pypi/pyasn1>`_, +`python-gssapi >= 0.4.0 (Unix) <https://pypi.python.org/pypi/python-gssapi>`_, +`pywin32 2.1.8 (Windows) <http://sourceforge.net/projects/pywin32/>`_. + +:summary: SSH2 GSS-API / SSPI authentication module +:version: 0.1 +:author: Sebastian Deiss +:contact: https://github.com/SebastianDeiss/paramiko/issues +:organization: science + computing ag + `EMail <mailto:a.kruis@science-computing.de>`_ +:copyright: (C) 2013-2014 `science + computing ag + <https://www.science-computing.de>`_ +:license: GNU Lesser General Public License (LGPL) +:see: `.kex_gss` Created on 07.11.2013 """ @@ -47,9 +47,8 @@ import os import sys ''' -@var GSS_AUTH_AVAILABLE: Constraint that indicates if GSS-API / SSPI is +:var bool GSS_AUTH_AVAILABLE: Constraint that indicates if GSS-API / SSPI is Available. -@type GSS_AUTH_AVAILABLE: Boolean ''' GSS_AUTH_AVAILABLE = True @@ -74,8 +73,7 @@ from paramiko.common import MSG_USERAUTH_REQUEST from paramiko.ssh_exception import SSHException """ -@var _API: Constraint for the used API -@type _API: String +:var str _API: Constraint for the used API """ _API = "MIT" @@ -95,25 +93,23 @@ def GSSAuth(auth_method, gss_deleg_creds=True): """ Provide SSH2 GSS-API / SSPI authentication for Paramiko. - @param auth_method: The name of the SSH authentication mechanism - (gssapi-with-mic or gss-keyex) - @type auth_method: String - @param gss_deleg_creds: Delegate client credentials or not. - We delegate credentials by default. - @type gss_deleg_creds: Boolean - @return: Either an L{_SSH_GSSAPI} (Unix) object or an - L{_SSH_SSPI} (Windows) object - @rtype: Object - - @raise ImportError: If no GSS-API / SSPI module could be imported. - - @see: U{RFC 4462 <www.ietf.org/rfc/rfc4462.txt>} - @note: Check for the available API and return either an L{_SSH_GSSAPI} - (MIT GSSAPI) object or an L{_SSH_SSPI} (MS SSPI) object. If you + :param str auth_method: The name of the SSH authentication mechanism + (gssapi-with-mic or gss-keyex) + :param bool gss_deleg_creds: Delegate client credentials or not. + We delegate credentials by default. + :return: Either an `._SSH_GSSAPI` (Unix) object or an + `_SSH_SSPI` (Windows) object + :rtype: Object + + :raise ImportError: If no GSS-API / SSPI module could be imported. + + :see: `RFC 4462 <http://www.ietf.org/rfc/rfc4462.txt>`_ + :note: Check for the available API and return either an `._SSH_GSSAPI` + (MIT GSSAPI) object or an `._SSH_SSPI` (MS SSPI) object. If you get python-gssapi working on Windows, python-gssapi - will be used and a L{_SSH_GSSAPI} object will be returned. + will be used and a `._SSH_GSSAPI` object will be returned. If there is no supported API available, - C{None} will be returned. + ``None`` will be returned. """ if _API == "MIT": return _SSH_GSSAPI(auth_method, gss_deleg_creds) @@ -125,16 +121,14 @@ def GSSAuth(auth_method, gss_deleg_creds=True): class _SSH_GSSAuth(object): """ - Contains the shared variables and methods of L{_SSH_GSSAPI} and - L{_SSH_SSPI}. + Contains the shared variables and methods of `._SSH_GSSAPI` and + `._SSH_SSPI`. """ def __init__(self, auth_method, gss_deleg_creds): """ - @param auth_method: The name of the SSH authentication mechanism - (gssapi-with-mic or gss-keyex) - @type auth_method: String - @param gss_deleg_creds: Delegate client credentials or not - @type gss_deleg_creds: Boolean + :param str auth_method: The name of the SSH authentication mechanism + (gssapi-with-mic or gss-keyex) + :param bool gss_deleg_creds: Delegate client credentials or not """ self._auth_method = auth_method self._gss_deleg_creds = gss_deleg_creds @@ -163,9 +157,8 @@ class _SSH_GSSAuth(object): I added this method, because RFC 4462 doesn't specify "ssh-connection" as the only service value. - @param service: The desired SSH service - @type service: String - @rtype: Void + :param str service: The desired SSH service + :rtype: Void """ if service.find("ssh-"): self._service = service @@ -175,9 +168,8 @@ class _SSH_GSSAuth(object): Setter for C{username}. If GSS-API Key Exchange is performed, the username is not set by C{ssh_init_sec_context}. - @param username: The name of the user who attempts to login - @type username: String - @rtype: Void + :param str username: The name of the user who attempts to login + :rtype: Void """ self._username = username @@ -186,14 +178,13 @@ class _SSH_GSSAuth(object): This method returns a single OID, because we only support the Kerberos V5 mechanism. - @param mode: Client for client mode and server for server mode - @param mode: String - @return: A byte sequence containing the number of supported + :param str mode: Client for client mode and server for server mode + :return: A byte sequence containing the number of supported OIDs, the length of the OID and the actual OID encoded with DER - @note: In server mode we just return the OID length and the DER encoded + :rtype: Bytes + :note: In server mode we just return the OID length and the DER encoded OID. - @rtype: Bytes """ OIDs = self._make_uint32(1) krb5_OID = encoder.encode(ObjectIdentifier(self._krb5_mech)) @@ -206,10 +197,9 @@ class _SSH_GSSAuth(object): """ Check if the given OID is the Kerberos V5 OID (server mode). - @param desired_mech: The desired GSS-API mechanism of the client - @type desired_mech: String - @return: C{True} if the given OID is supported, otherwise C{False} - @rtype: Boolean + :param str desired_mech: The desired GSS-API mechanism of the client + :return: ``True`` if the given OID is supported, otherwise C{False} + :rtype: Boolean """ mech, __ = decoder.decode(desired_mech) if mech.__str__() != self._krb5_mech: @@ -222,10 +212,9 @@ class _SSH_GSSAuth(object): """ Create a 32 bit unsigned integer (The byte sequence of an integer). - @param integer: The integer value to convert - @type integer: Integer - @return: The byte sequence of an 32 bit integer - @rtype: Bytes + :param int integer: The integer value to convert + :return: The byte sequence of an 32 bit integer + :rtype: Bytes """ return struct.pack("!I", integer) @@ -233,15 +222,11 @@ class _SSH_GSSAuth(object): """ Create the SSH2 MIC filed for gssapi-with-mic. - @param session_id: The SSH session ID - @type session_id: String - @param username: The name of the user who attempts to login - @type username: String - @param service: The requested SSH service - @type service: String - @param auth_method: The requested SSH authentication mechanism - @type auth_method: String - @return: The MIC as defined in RFC 4462. The contents of the + :param str session_id: The SSH session ID + :param str username: The name of the user who attempts to login + :param str service: The requested SSH service + :param str auth_method: The requested SSH authentication mechanism + :return: The MIC as defined in RFC 4462. The contents of the MIC field are: string session_identifier, byte SSH_MSG_USERAUTH_REQUEST, @@ -249,7 +234,7 @@ class _SSH_GSSAuth(object): string service (ssh-connection), string authentication-method (gssapi-with-mic or gssapi-keyex) - @rtype: Bytes + :rtype: Bytes """ mic = self._make_uint32(len(session_id)) mic += session_id @@ -267,15 +252,13 @@ class _SSH_GSSAPI(_SSH_GSSAuth): """ Implementation of the GSS-API MIT Kerberos Authentication for SSH2. - @see: L{GSSAuth} + :see: `.GSSAuth` """ def __init__(self, auth_method, gss_deleg_creds): """ - @param auth_method: The name of the SSH authentication mechanism - (gssapi-with-mic or gss-keyex) - @type auth_method: String - @param gss_deleg_creds: Delegate client credentials or not - @type gss_deleg_creds: Boolean + :param str auth_method: The name of the SSH authentication mechanism + (gssapi-with-mic or gss-keyex) + :param bool gss_deleg_creds: Delegate client credentials or not """ _SSH_GSSAuth.__init__(self, auth_method, gss_deleg_creds) @@ -294,21 +277,17 @@ class _SSH_GSSAPI(_SSH_GSSAuth): """ Initialize a GSS-API context. - @param username: The name of the user who attempts to login - @type username: String - @param target: The hostname of the target to connect to - @type target: String - @param desired_mech: The negotiated GSS-API mechanism - ("pseudo negotiated" mechanism, because we - support just the krb5 mechanism :-)) - @type desired_mech: String - @param recv_token: The GSS-API token received from the Server - @type recv_token: String - @raise SSHException: Is raised if the desired mechanism of the client + :param str username: The name of the user who attempts to login + :param str target: The hostname of the target to connect to + :param str desired_mech: The negotiated GSS-API mechanism + ("pseudo negotiated" mechanism, because we + support just the krb5 mechanism :-)) + :param str recv_token: The GSS-API token received from the Server + :raise SSHException: Is raised if the desired mechanism of the client is not supported - @return: A C{String} if the GSS-API has returned a token or C{None} if + :return: A ``String`` if the GSS-API has returned a token or ``None`` if no token was returned - @rtype: String or None + :rtype: String or None """ self._username = username self._gss_host = target @@ -343,18 +322,16 @@ class _SSH_GSSAPI(_SSH_GSSAuth): """ Create the MIC token for a SSH2 message. - @param session_id: The SSH session ID - @type session_id: String - @param gss_kex: Generate the MIC for GSS-API Key Exchange or not - @type gss_kex: Boolean - @return: gssapi-with-mic: + :param str session_id: The SSH session ID + :param bool gss_kex: Generate the MIC for GSS-API Key Exchange or not + :return: gssapi-with-mic: Returns the MIC token from GSS-API for the message we created - with C{_ssh_build_mic}. + with ``_ssh_build_mic``. gssapi-keyex: Returns the MIC token from GSS-API with the SSH session ID as message. - @rtype: String - @see: L{_ssh_build_mic} + :rtype: String + :see: `._ssh_build_mic` """ self._session_id = session_id if not gss_kex: @@ -372,16 +349,13 @@ class _SSH_GSSAPI(_SSH_GSSAuth): """ Accept a GSS-API context (server mode). - @param hostname: The servers hostname - @type hostname: String - @param username: The name of the user who attempts to login - @type username: String - @param recv_token: The GSS-API Token received from the server, if it's - not the initial call - @type recv_token: String - @return: A C{String} if the GSS-API has returned a token or C{None} if - no token was returned - @rtype: String or None + :param str hostname: The servers hostname + :param str username: The name of the user who attempts to login + :param str recv_token: The GSS-API Token received from the server, + if it's not the initial call. + :return: A ``String`` if the GSS-API has returned a token or ``None`` + if no token was returned + :rtype: String or None """ # hostname and username are not required for GSSAPI, but for SSPI self._gss_host = hostname @@ -396,14 +370,11 @@ class _SSH_GSSAPI(_SSH_GSSAuth): """ Verify the MIC token for a SSH2 message. - @param mic_token: The MIC token received from the client - @type mic_token: String - @param session_id: The SSH session ID - @type session_id: String - @param username: The name of the user who attempts to login - @type username: String - @return: 0 if the MIC check was successful and 1 if it fails - @rtype: Integer + :param str mic_token: The MIC token received from the client + :param str session_id: The SSH session ID + :param str username: The name of the user who attempts to login + :return: 0 if the MIC check was successful and 1 if it fails + :rtype: int """ self._session_id = session_id self._username = username @@ -427,8 +398,8 @@ class _SSH_GSSAPI(_SSH_GSSAuth): """ Checks if credentials are delegated (server mode). - @return: C{True} if credentials are delegated, otherwise C{False} - @rtype: Boolean + :return: ``True`` if credentials are delegated, otherwise ``False`` + :rtype: bool """ if self._gss_srv_ctxt.delegated_cred is not None: return True @@ -440,9 +411,8 @@ class _SSH_GSSAPI(_SSH_GSSAuth): to store the client credentials if credentials are delegated (server mode). - @param client_token: The GSS-API token received form the client - @type client_token: String - @raise NotImplementedError: Credential delegation is currently not + :param str client_token: The GSS-API token received form the client + :raise NotImplementedError: Credential delegation is currently not supported in server mode """ raise NotImplementedError @@ -452,15 +422,13 @@ class _SSH_SSPI(_SSH_GSSAuth): """ Implementation of the Microsoft SSPI Kerberos Authentication for SSH2. - @see: L{GSSAuth} + :see: `.GSSAuth` """ def __init__(self, auth_method, gss_deleg_creds): """ - @param auth_method: The name of the SSH authentication mechanism - (gssapi-with-mic or gss-keyex) - @type auth_method: String - @param gss_deleg_creds: Delegate client credentials or not - @type gss_deleg_creds: Boolean + :param str auth_method: The name of the SSH authentication mechanism + (gssapi-with-mic or gss-keyex) + :param bool gss_deleg_creds: Delegate client credentials or not """ _SSH_GSSAuth.__init__(self, auth_method, gss_deleg_creds) @@ -477,21 +445,17 @@ class _SSH_SSPI(_SSH_GSSAuth): """ Initialize a SSPI context. - @param username: The name of the user who attempts to login - @type username: String - @param target: The FQDN of the target to connect to - @type target: String - @param desired_mech: The negotiated SSPI mechanism - ("pseudo negotiated" mechanism, because we - support just the krb5 mechanism :-)) - @type desired_mech: String - @param recv_token: The SSPI token received from the Server - @type recv_token: String - @raise SSHException: Is raised if the desired mechanism of the client + :param str username: The name of the user who attempts to login + :param str target: The FQDN of the target to connect to + :param str desired_mech: The negotiated SSPI mechanism + ("pseudo negotiated" mechanism, because we + support just the krb5 mechanism :-)) + :param recv_token: The SSPI token received from the Server + :raise SSHException: Is raised if the desired mechanism of the client is not supported - @return: A C{String} if the SSPI has returned a token or C{None} if + :return: A ``String`` if the SSPI has returned a token or ``None`` if no token was returned - @rtype: String or None + :rtype: String or None """ self._username = username self._gss_host = target @@ -528,18 +492,16 @@ class _SSH_SSPI(_SSH_GSSAuth): """ Create the MIC token for a SSH2 message. - @param session_id: The SSH session ID - @type session_id: String - @param gss_kex: Generate the MIC for Key Exchange with SSPI or not - @type gss_kex: Boolean - @return: gssapi-with-mic: + :param str session_id: The SSH session ID + :param bool gss_kex: Generate the MIC for Key Exchange with SSPI or not + :return: gssapi-with-mic: Returns the MIC token from SSPI for the message we created - with C{_ssh_build_mic}. + with ``_ssh_build_mic``. gssapi-keyex: Returns the MIC token from SSPI with the SSH session ID as message. - @rtype: String - @see: L{_ssh_build_mic} + :rtype: String + :see: `._ssh_build_mic` """ self._session_id = session_id if not gss_kex: @@ -557,16 +519,13 @@ class _SSH_SSPI(_SSH_GSSAuth): """ Accept a SSPI context (server mode). - @param hostname: The servers FQDN - @type hostname: String - @param username: The name of the user who attempts to login - @type username: String - @param recv_token: The SSPI Token received from the server, if it's not - the initial call - @type recv_token: String - @return: A C{String} if the SSPI has returned a token or C{None} if + :param str hostname: The servers FQDN + :param str username: The name of the user who attempts to login + :param str recv_token: The SSPI Token received from the server, + if it's not the initial call. + :return: A ``String`` if the SSPI has returned a token or ``None`` if no token was returned - @rtype: String or None + :rtype: String or None """ self._gss_host = hostname self._username = username @@ -583,14 +542,11 @@ class _SSH_SSPI(_SSH_GSSAuth): """ Verify the MIC token for a SSH2 message. - @param mic_token: The MIC token received from the client - @type mic_token: String - @param session_id: The SSH session ID - @type session_id: String - @param username: The name of the user who attempts to login - @type username: String - @return: 0 if the MIC check was successful - @rtype: Integer + :param str mic_token: The MIC token received from the client + :param str session_id: The SSH session ID + :param str username: The name of the user who attempts to login + :return: 0 if the MIC check was successful + :rtype: int """ self._session_id = session_id self._username = username @@ -620,8 +576,8 @@ class _SSH_SSPI(_SSH_GSSAuth): """ Checks if credentials are delegated (server mode). - @return: C{True} if credentials are delegated, otherwise C{False} - @rtype: Boolean + :return: ``True`` if credentials are delegated, otherwise ``False`` + :rtype: Boolean """ return ( self._gss_flags & sspicon.ISC_REQ_DELEGATE @@ -635,9 +591,8 @@ class _SSH_SSPI(_SSH_GSSAuth): to store the client credentails if credentials are delegated (server mode). - @param client_token: The SSPI token received form the client - @type client_token: String - @raise NotImplementedError: Credential delegation is currently not + :param str client_token: The SSPI token received form the client + :raise NotImplementedError: Credential delegation is currently not supported in server mode """ raise NotImplementedError diff --git a/paramiko/transport.py b/paramiko/transport.py index 393b1d35..86b5e7e4 100644 --- a/paramiko/transport.py +++ b/paramiko/transport.py @@ -326,10 +326,9 @@ class Transport (threading.Thread): """ Setter for C{gss_host} if GSS-API Key Exchange is performed. - @param gss_host: The targets name in the kerberos database - Default: The name of the host to connect to - @type gss_host: String - @rtype: Void + :param str gss_host: The targets name in the kerberos database + Default: The name of the host to connect to + :rtype: Void """ # We need the FQDN to get this working with SSPI self.gss_host = socket.getfqdn(gss_host) @@ -1226,20 +1225,17 @@ class Transport (threading.Thread): """ Authenticate to the Server using GSS-API / SSPI. - @param username: The username to authenticate as - @type username: String - @param gss_host: The target host - @type gss_host: String - @param gss_deleg_creds: Delegate credentials or not - @type gss_deleg_creds: Boolean - @return: list of auth types permissible for the next stage of + :param str username: The username to authenticate as + :param str gss_host: The target host + :param bool gss_deleg_creds: Delegate credentials or not + :return: list of auth types permissible for the next stage of authentication (normally empty) - @rtype: list - @raise BadAuthenticationType: if gssapi-with-mic isn't + :rtype: list + :raise BadAuthenticationType: if gssapi-with-mic isn't allowed by the server (and no event was passed in) - @raise AuthenticationException: if the authentication failed (and no + :raise AuthenticationException: if the authentication failed (and no event was passed in) - @raise SSHException: if there was a network error + :raise SSHException: if there was a network error """ if (not self.active) or (not self.initial_kex_done): # we should never try to authenticate unless we're on a secure link @@ -1254,16 +1250,17 @@ class Transport (threading.Thread): Authenticate to the Server with GSS-API / SSPI if GSS-API Key Exchange was the used key exchange method. - @param username: The username to authenticate as - @type username: String - @return: list of auth types permissible for the next stage of - authentication (normally empty) - @rtype: list - @raise BadAuthenticationType: if GSS-API Key Exchange was not performed + :param str username: The username to authenticate as + :param str gss_host: The target host + :param bool gss_deleg_creds: Delegate credentials or not + :return: list of auth types permissible for the next stage of + authentication (normally empty) + :rtype: list + :raise BadAuthenticationType: if GSS-API Key Exchange was not performed (and no event was passed in) - @raise AuthenticationException: if the authentication failed (and no + :raise AuthenticationException: if the authentication failed (and no event was passed in) - @raise SSHException: if there was a network error + :raise SSHException: if there was a network error """ if (not self.active) or (not self.initial_kex_done): # we should never try to authenticate unless we're on a secure link diff --git a/sites/docs/api/kex_gss.rst b/sites/docs/api/kex_gss.rst new file mode 100644 index 00000000..a662be01 --- /dev/null +++ b/sites/docs/api/kex_gss.rst @@ -0,0 +1,5 @@ +GSS-API Key Exchange Module +=========================== + +.. automodule:: paramiko.kex_gss + :member-order: bysource diff --git a/sites/docs/api/ssh_gss.rst b/sites/docs/api/ssh_gss.rst new file mode 100644 index 00000000..1b08c7f8 --- /dev/null +++ b/sites/docs/api/ssh_gss.rst @@ -0,0 +1,14 @@ +Paramiko GSS-API Interface +========================== + +.. automodule:: paramiko.ssh_gss + :member-order: bysource + +.. autoclass:: _SSH_GSSAuth + :member-order: bysource + +.. autoclass:: _SSH_GSSAPI + :member-order: bysource + +.. autoclass:: _SSH_SSPI + :member-order: bysource diff --git a/sites/docs/index.rst b/sites/docs/index.rst index f336b393..87265d95 100644 --- a/sites/docs/index.rst +++ b/sites/docs/index.rst @@ -50,6 +50,8 @@ Authentication & keys api/agent api/hostkeys api/keys + api/ssh_gss + api/kex_gss Other primary functions |