a oe<@s2dZddlZddlZejZGdddeZGdddeZGdddeZed kr.d Z ej ej Bej Bej BejBZede ejdd\ZZeejZed eee eed Zee ed ZedejdejdfdZdZdZejreedj rbed7Ze!e\Z"Zedeejr>eedj dkr>qbed7Ze!e\Z"Zedeqedej#edej$d%dZ&e'e&Z(e)e&e(e*e&\Z+Z(e,e+e(Z-e-e&ksJe.e&Z/e0e/\Z1Z2ede2e&e1ksJej.e&ddZ/e0e/\Z1Z2ede2e&e1ks&JeddS)a6 Helper classes for SSPI authentication via the win32security module. SSPI authentication involves a token-exchange "dance", the exact details of which depends on the authentication provider used. There are also a number of complex flags and constants that need to be used - in most cases, there are reasonable defaults. These classes attempt to hide these details from you until you really need to know. They are not designed to handle all cases, just the common ones. If you need finer control than offered here, just use the win32security functions directly. Nc@s^eZdZddZddZddZddZd d Zd d Zd dZ ddZ dddZ ddZ dS) _BaseAuthcCs |dS)N)resetselfr/C:\Program Files\Certbot\pkgs\win32\lib\sspi.py__init__sz_BaseAuth.__init__cCs"d|_d|_d|_d|_d|_dS)z)Reset everything to an unauthorized stateNFr)ctxt authenticatedinitiator_name service_name next_seq_numrrrrrs z_BaseAuth.resetcCs|j}|jd|_|S)zsGet the next sequence number for a transmission. Default implementation is to increment a counter )r )rretrrr_get_next_seq_num$s z_BaseAuth._get_next_seq_numcCs||jtj}|d}t}|tt|tj |t|tj ||d_ |j d|| |dj |dj fS)zEncrypt a string, returning a tuple of (encrypted_data, trailer). These can be passed to decrypt to get back the original string. SecurityTrailerrr)r QueryContextAttributessspiconSECPKG_ATTR_SIZES win32securityPySecBufferDescTypeappendPySecBufferTypelenSECBUFFER_DATASECBUFFER_TOKENBufferEncryptMessager)rdata pkg_size_infoZ trailersizeencbufrrrencrypt,s  z_BaseAuth.encryptcCsht}|tt|tj|tt|tj||d_||d_|j || |djS)zADecrypt a previously encrypted string, returning the orignal datarr) rrrrrrrrrr DecryptMessager)rrZtrailerr rrrdecrypt<s  z_BaseAuth.decryptcCsr|jtj}|d}t}|tt|tj |t|tj ||d_ |j d|| |dj S)zsign a string suitable for transmission, returning the signature. Passing the data and signature to verify will determine if the data is unchanged. Z MaxSignaturerr)r rrrrrrrrrrrZ MakeSignaturer)rrrZsigsizesigbufrrrsignHs z_BaseAuth.signcCsbt}|tt|tj|tt|tj||d_||d_|j || dS)zgVerifies data and its signature. If verification fails, an sspi.error will be raised. rrN) rrrrrrrrrr ZVerifySignaturer)rrsigr$rrrverifyWs   z_BaseAuth.verifycCsjt}|tt|tj||d_|tdtj|j || }|dj}||tj k fS)a; GSSAPI's unwrap with SSPI. https://docs.microsoft.com/en-us/windows/win32/secauthn/sspi-kerberos-interoperability-with-gssapi Usable mainly with Kerberos SSPI package, but this is not enforced. Return the clear text, and a boolean that is True if the token was encrypted. rr) rrrrrrZSECBUFFER_STREAMrrr r"rSECQOP_WRAP_NO_ENCRYPT)rtokenbufferZpfQOPrrrrunwrapcs   z_BaseAuth.unwrapFc Cs|jtj}|d}|d}t}|tt|tj ||d_ |t|tj |t|tj |rxdntj }|j||||dj |dj |dj }|S)a6 GSSAPI's wrap with SSPI. https://docs.microsoft.com/en-us/windows/win32/secauthn/sspi-kerberos-interoperability-with-gssapi Usable mainly with Kerberos SSPI package, but this is not enforced. Wrap a message to be sent to the other side. Encrypted if encrypt is True. rZ BlockSizerr)r rrrrrrrrrrrZSECBUFFER_PADDINGr(rr) rmsgr!Z size_infoZ trailer_sizeZ block_sizer*ZfQOPr+rrrwrap|s    z_BaseAuth.wrapcCsD|jstdz|jtj}Wnty2Yn0|\|_|_dS)zHAdds initiator and service names in the security context for ease of usez+Sec context is not completely authenticatedN) r ValueErrorr rrZSECPKG_ATTR_NATIVE_NAMESerrorr r )rnamesrrr_amend_ctx_names z_BaseAuth._amend_ctx_nameN)F) __name__ __module__ __qualname__rrrr!r#r%r'r,r/r3rrrrrs    %rc@s.eZdZdZddddejfddZddZdS) ClientAuthz;Manages the client side of an SSPI authentication handshakeNcCsn|dur tjtjBtjBtjB}||_||_||_t ||_ t ||j dtj d|\|_ |_t|dSNName)rISC_REQ_INTEGRITYISC_REQ_SEQUENCE_DETECTISC_REQ_REPLAY_DETECTISC_REQ_CONFIDENTIALITYscflagsdatarep targetspnrQuerySecurityPackageInfopkg_infoAcquireCredentialsHandleZSECPKG_CRED_OUTBOUND credentialscredentials_expiryrr)rpkg_nameZ client_nameZ auth_infor@r>r?rrrrs0  zClientAuth.__init__c Cs|durFt|tjkrFt}t|jdtj}||_|||}t}t|jdtj}|||j }|j durt |_ t |j ||j |j|j||j |\}}}||_||_|tjtjfvr|j ||dk|_|jr|||fS)zVPerform *one* step of the client authentication process. Pass None for the first roundNMaxTokenr)typerrrrBrrrrr PyCtxtHandleTypeZInitializeSecurityContextrDr@r>r? ctxt_attr ctxt_expirySEC_I_COMPLETE_NEEDEDSEC_I_COMPLETE_AND_CONTINUECompleteAuthTokenr r3 rZ sec_buffer_inZsec_buffer_newZtokenbufZsec_buffer_outZctxtinerrattrexprrr authorizesJ          zClientAuth.authorizer4r5r6__doc__rZSECURITY_NETWORK_DREPrrSrrrrr7s r7c@s*eZdZdZddejfddZddZdS) ServerAuthz;Manages the server side of an SSPI authentication handshakeNcCsn||_||_|dur,tjtjBtjBtjB}||_t ||_ t ||j dtj dd\|_ |_t|dSr8)spnr?rZASC_REQ_INTEGRITYZASC_REQ_SEQUENCE_DETECTZASC_REQ_REPLAY_DETECTZASC_REQ_CONFIDENTIALITYr>rrArBrCSECPKG_CRED_INBOUNDrDrErr)rrFrWr>r?rrrrs( zServerAuth.__init__c Cs|durFt|tjkrFt}t|jdtj}||_|||}t}t|jdtj}|||j }|j durt |_ t |j |||j |j|j |\}}}||_||_|tjtjfvr|j ||dk|_|jr|||fS)z8Perform *one* step of the server authentication process.NrGr)rHrrrrBrrrrr rIZAcceptSecurityContextrDr>r?rJrKrLrMrNr r3rOrrrrS sH          zServerAuth.authorizerTrrrrrVs rV__main__ZKerberoszWe are:)r>r@)r>z SSP : %s (%s)r9CommentrzClient step %szServer step %sz%Initiator name from the service side:z%Service name from the client side: Zhelloasciiz encrypted ?T)r!zcool!)3rUrrr1objectrr7rVr4ZsspZISC_REQ_MUTUAL_AUTHr:r;r=r<flagsrCrXZ cred_handlerRZQueryCredentialsAttributesZSECPKG_CRED_ATTR_NAMESZcredprintZ sspiclientZ sspiserverrBZ sec_bufferZ client_stepZ server_stepr rrrSrPr r encoderr%r&r'r!Z encryptedr#Z decryptedr/wrappedr,Z unwrappedZ was_encryptedrrrrstSO