3 L]p@sLdZddlZddlZddlZdZfZdZyDddlZeedrTej dkrTdZej fZndZej j ej jjfZWn^eefk ry(ddlZddlZddlZdZejfZWnek rd ZdZYnXYnXdd lmZdd lmZdd lmZdd dZGdddeZGdddeZedkr(eZ GdddeZ!GdddeZ"dS)z This module provides GSS-API / SSPI authentication as defined in :rfc:`4462`. .. note:: Credential delegation is not supported in server mode. .. seealso:: :doc:`/api/kex_gss` .. versionadded:: 1.15 NT __title__z python-gssapiMITzPYTHON-GSSAPI-NEWSSPIF)MSG_USERAUTH_REQUEST) SSHException)__version_info__cCsLtdkrt||Stdkr$t||Stdkr@tjdkr@t||StddS)a Provide SSH2 GSS-API / SSPI authentication. :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_OLD` or `._SSH_GSSAPI_NEW` (Unix) object or an `_SSH_SSPI` (Windows) object :rtype: object :raises: ``ImportError`` -- If no GSS-API / SSPI module could be imported. :see: `RFC 4462 `_ :note: Check for the available API and return either an `._SSH_GSSAPI_OLD` (MIT GSSAPI using python-gssapi package) object, an `._SSH_GSSAPI_NEW` (MIT GSSAPI using gssapi package) object or an `._SSH_SSPI` (MS SSPI) object. If there is no supported API available, ``None`` will be returned. rzPYTHON-GSSAPI-NEWrntz)Unable to import a GSS-API / SSPI module!N)_API_SSH_GSSAPI_OLD_SSH_GSSAPI_NEWosname _SSH_SSPI ImportError) auth_methodgss_deleg_credsr6/tmp/pip-install-wfra5znf/paramiko/paramiko/ssh_gss.pyGSSAuthNs   rc@sJeZdZdZddZddZddZdd d Zd d Zd dZ ddZ dS) _SSH_GSSAuthzs Contains the shared variables and methods of `._SSH_GSSAPI_OLD`, `._SSH_GSSAPI_NEW` and `._SSH_SSPI`. cCsL||_||_d|_d|_d|_d|_d|_d|_d|_d|_ d|_ d|_ dS)z :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 Nzssh-connectionz1.2.840.113554.1.2.2F) _auth_method_gss_deleg_creds _gss_host _username _session_id_service _krb5_mech _gss_ctxt_gss_ctxt_status _gss_srv_ctxt_gss_srv_ctxt_statusZcc_file)selfrrrrr__init__tsz_SSH_GSSAuth.__init__cCs|jdr||_dS)z This is just a setter to use a non default service. I added this method, because RFC 4462 doesn't specify "ssh-connection" as the only service value. :param str service: The desired SSH service zssh-N)findr)r!servicerrr set_services z_SSH_GSSAuth.set_servicecCs ||_dS)z Setter for C{username}. If GSS-API Key Exchange is performed, the username is not set by C{ssh_init_sec_context}. :param str username: The name of the user who attempts to login N)r)r!usernamerrr set_usernamesz_SSH_GSSAuth.set_usernameclientcCs\ddlm}ddlm}|jd}|j||j}|jt|}|dkrP||S|||S)a This method returns a single OID, because we only support the Kerberos V5 mechanism. :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 OID. r)ObjectIdentifier)encoderserver)Zpyasn1.type.univr)pyasn1.codec.derr* _make_uint32encoderlen)r!moder)r*ZOIDsZkrb5_OIDZOID_lenrrr ssh_gss_oidss   z_SSH_GSSAuth.ssh_gss_oidscCs0ddlm}|j|\}}|j|jkr,dSdS)z Check if the given OID is the Kerberos V5 OID (server mode). :param str desired_mech: The desired GSS-API mechanism of the client :return: ``True`` if the given OID is supported, otherwise C{False} r)decoderFT)r-r3decode__str__r)r! desired_mechr3mech__rrrssh_check_mechs  z_SSH_GSSAuth.ssh_check_mechcCs tjd|S)z Create a 32 bit unsigned integer (The byte sequence of an integer). :param int integer: The integer value to convert :return: The byte sequence of an 32 bit integer z!I)structpack)r!integerrrrr.sz_SSH_GSSAuth._make_uint32cCs|jt|}||7}|tjdt7}||jt|7}||j7}||jt|7}||j7}||jt|7}||j7}|S)a Create the SSH2 MIC filed for gssapi-with-mic. :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, string user-name, string service (ssh-connection), string authentication-method (gssapi-with-mic or gssapi-keyex) B)r.r0r:r;rr/)r! session_idr&r$rZmicrrr_ssh_build_mics   z_SSH_GSSAuth._ssh_build_micN)r() __name__ __module__ __qualname____doc__r"r%r'r2r9r.r?rrrrrns   rc@sTeZdZdZddZdddZddd Zdd d Zdd d Ze ddZ ddZ dS)r z Implementation of the GSS-API MIT Kerberos Authentication for SSH2, using the older (unmaintained) python-gssapi package. :see: `.GSSAuth` cCsBtj||||jr,tjtjtjtjf|_ntjtjtjf|_dS)z :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 N) rr"rgssapiZC_PROT_READY_FLAGZ C_INTEG_FLAGZ C_MUTUAL_FLAGZ C_DELEG_FLAG _gss_flags)r!rrrrrr"s z_SSH_GSSAPI_OLD.__init__Nc Cs ddlm}||_||_tjd|jtj}tj}|j|_ |dkrTtj j |j }n4|j |\} } | j|j krztdntj j |j }d} y:|dkrtj|||j d|_|jj| } n |jj|} Wn6tjk rdjtjd|j} tj| YnX|jj|_| S) a Initialize a GSS-API context. :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 :raises: `.SSHException` -- Is raised if the desired mechanism of the client is not supported :return: A ``String`` if the GSS-API has returned a token or ``None`` if no token was returned r)r3zhost@NzUnsupported mechanism OID.)Z peer_nameZ mech_typeZ req_flagsz {} Target: {}r+)r-r3rrrDNameZC_NT_HOSTBASED_SERVICEContextrEflagsZOIDZmech_from_stringrr4r5rZ InitContextrstep GSSExceptionformatsysexc_info establishedr) r!targetr6r& recv_tokenr3 targ_namectx krb5_mechr7r8tokenmessagerrrssh_init_sec_context s6    z$_SSH_GSSAPI_OLD.ssh_init_sec_contextFcCsB||_|s0|j|j|j|j|j}|jj|}n|jj|j}|S)a Create the MIC token for a SSH2 message. :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 ``_ssh_build_mic``. gssapi-keyex: Returns the MIC token from GSS-API with the SSH session ID as message. )rr?rrrrZget_micr)r!r>gss_kex mic_field mic_tokenrrr ssh_get_micAs z_SSH_GSSAPI_OLD.ssh_get_miccCs:||_||_|jdkr tj|_|jj|}|jj|_|S)a Accept a GSS-API context (server mode). :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 N)rrrrDZ AcceptContextrIrNr )r!hostnamerPr&rTrrrssh_accept_sec_context\s     z&_SSH_GSSAPI_OLD.ssh_accept_sec_contextcCsR||_||_|jdk r>|j|j|j|j|j}|jj||n|jj|j|dS)at Verify the MIC token for a SSH2 message. :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: None if the MIC check was successful :raises: ``gssapi.GSSException`` -- if the MIC check failed N)rrr?rrrZ verify_micr)r!rYr>r&rXrrr ssh_check_micps  z_SSH_GSSAPI_OLD.ssh_check_miccCs|jjdk rdSdS)z Checks if credentials are delegated (server mode). :return: ``True`` if credentials are delegated, otherwise ``False`` NTF)rZdelegated_cred)r!rrrcredentials_delegateds z%_SSH_GSSAPI_OLD.credentials_delegatedcCstdS)a~ Save the Client token in a file. This is used by the SSH server to store the client credentials if credentials are delegated (server mode). :param str client_token: The GSS-API token received form the client :raises: ``NotImplementedError`` -- Credential delegation is currently not supported in server mode N)NotImplementedError)r! client_tokenrrrsave_client_credss z!_SSH_GSSAPI_OLD.save_client_creds)NNN)F)N)N) r@rArBrCr"rVrZr\r]propertyr^rarrrrr s 3    r c@sTeZdZdZddZdddZddd Zdd d Zdd d Ze ddZ ddZ dS)r z Implementation of the GSS-API MIT Kerberos Authentication for SSH2, using the newer, currently maintained gssapi package. :see: `.GSSAuth` cCsPtj||||jr4tjjtjjtjjtjjf|_ ntjjtjjtjjf|_ dS)z :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 N) rr"rrDZRequirementFlagZprotection_readyZ integrityZmutual_authenticationZdelegate_to_peerrE)r!rrrrrr"sz_SSH_GSSAPI_NEW.__init__Nc Csddlm}||_||_tjd|jtjjd}|dk r\|j|\}}|j |j kr\t dtj j } d} |dkrtj||j| dd|_|jj| } n |jj|} |jj|_| S) ae Initialize a GSS-API context. :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 :raises: `.SSHException` -- Is raised if the desired mechanism of the client is not supported :raises: ``gssapi.exceptions.GSSError`` if there is an error signaled by the GSS-API implementation :return: A ``String`` if the GSS-API has returned a token or ``None`` if no token was returned r)r3zhost@)Z name_typeNzUnsupported mechanism OID.Zinitiate)r rHr7usage)r-r3rrrDrFZNameTypeZhostbased_servicer4r5rrZMechTypeZkerberosSecurityContextrErrIcompleter) r!rOr6r&rPr3rQr7r8rSrTrrrrVs,     z$_SSH_GSSAPI_NEW.ssh_init_sec_contextFcCsB||_|s0|j|j|j|j|j}|jj|}n|jj|j}|S)a Create the MIC token for a SSH2 message. :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 ``_ssh_build_mic``. gssapi-keyex: Returns the MIC token from GSS-API with the SSH session ID as message. :rtype: str )rr?rrrrZ get_signaturer)r!r>rWrXrYrrrrZsz_SSH_GSSAPI_NEW.ssh_get_miccCs>||_||_|jdkr$tjdd|_|jj|}|jj|_|S)a Accept a GSS-API context (server mode). :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 Naccept)re)rrrrDrfrIrgr )r!r[rPr&rTrrrr\s    z&_SSH_GSSAPI_NEW.ssh_accept_sec_contextcCsR||_||_|jdk r>|j|j|j|j|j}|jj||n|jj|j|dS)a{ Verify the MIC token for a SSH2 message. :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: None if the MIC check was successful :raises: ``gssapi.exceptions.GSSError`` -- if the MIC check failed N)rrr?rrrZverify_signaturer)r!rYr>r&rXrrrr]$s  z_SSH_GSSAPI_NEW.ssh_check_miccCs|jjdk rdSdS)z Checks if credentials are delegated (server mode). :return: ``True`` if credentials are delegated, otherwise ``False`` :rtype: bool NTF)rZdelegated_creds)r!rrrr^>s z%_SSH_GSSAPI_NEW.credentials_delegatedcCstdS)aw Save the Client token in a file. This is used by the SSH server to store the client credentials if credentials are delegated (server mode). :param str client_token: The GSS-API token received form the client :raises: ``NotImplementedError`` -- Credential delegation is currently not supported in server mode N)r_)r!r`rrrraJs z!_SSH_GSSAPI_NEW.save_client_creds)NNN)F)N)N) r@rArBrCr"rVrZr\r]rbr^rarrrrr s -    r c@sReZdZdZddZdddZddd Zd d Zdd d Ze ddZ ddZ dS)rzf Implementation of the Microsoft SSPI Kerberos Authentication for SSH2. :see: `.GSSAuth` cCs<tj||||jr*tjtjBtjB|_ntjtjB|_dS)z :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 N)rr"rsspiconZISC_REQ_INTEGRITYZISC_REQ_MUTUAL_AUTHISC_REQ_DELEGATErE)r!rrrrrr"^sz_SSH_SSPI.__init__Nc Csddlm}||_||_d}d|j}|dk rR|j|\}} |j|jkrRtdy:|dkrptj d|j |d|_ |j j |\}} | dj } Wn>tjk r} z | jdj| |j7_WYdd} ~ XnX|dkrd |_d} | S) a Initialize a SSPI context. :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 :raises: `.SSHException` -- Is raised if the desired mechanism of the client is not supported :return: A ``String`` if the SSPI has returned a token or ``None`` if no token was returned r)r3zhost/NzUnsupported mechanism OID.Kerberos)ZscflagsZ targetspnz , Target: {}T)r-r3rrr4r5rrsspiZ ClientAuthrEr authorizeBuffer pywintypeserrorstrerrorrKr) r!rOr6r&rPr3rprQr7r8rTerrrrVqs,  z_SSH_SSPI.ssh_init_sec_contextFcCsB||_|s0|j|j|j|j|j}|jj|}n|jj|j}|S)a Create the MIC token for a SSH2 message. :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 ``_ssh_build_mic``. gssapi-keyex: Returns the MIC token from SSPI with the SSH session ID as message. )rr?rrrrsignr)r!r>rWrXrYrrrrZs z_SSH_SSPI.ssh_get_miccCsV||_||_d|j}tjd|d|_|jj|\}}|dj}|dkrRd|_d}|S)a Accept a SSPI context (server mode). :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 zhost/rk)ZspnrTN)rrrlZ ServerAuthrrmrnr )r!r[r&rPrQrprTrrrr\s   z _SSH_SSPI.ssh_accept_sec_contextcCsP||_||_|dk r<|j|j|j|j|j}|jj||n|jj|j|dS)ak Verify the MIC token for a SSH2 message. :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: None if the MIC check was successful :raises: ``sspi.error`` -- if the MIC check failed N)rrr?rrrverifyr)r!rYr>r&rXrrrr]s z_SSH_SSPI.ssh_check_miccCs|jtj@o|jp|jS)z Checks if credentials are delegated (server mode). :return: ``True`` if credentials are delegated, otherwise ``False`` )rErirjr )r!rrrr^s z_SSH_SSPI.credentials_delegatedcCstdS)a{ Save the Client token in a file. This is used by the SSH server to store the client credentails if credentials are delegated (server mode). :param str client_token: The SSPI token received form the client :raises: ``NotImplementedError`` -- Credential delegation is currently not supported in server mode N)r_)r!r`rrrras z_SSH_SSPI.save_client_creds)NNN)F)N) r@rArBrCr"rVrZr\r]rbr^rarrrrrWs 3   r)T)rcrd)#rCr:r rLZGSS_AUTH_AVAILABLEZGSS_EXCEPTIONSr rDhasattrrrJ exceptionsZ GeneralErrorrawmiscZGSSErrorrOSErrorrorirlrpZparamiko.commonrZparamiko.ssh_exceptionrZparamiko._versionrrobjectrr Z _SSH_GSSAPIr rrrrrsJ      5 0