o
    �õ±j¬S  ã                   @  sâ   d dl mZ d dlZd dlZd dlZd dlZd dlZd dlmZ d dl	Z	d dl
mZ d dlmZ d dlmZmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ dddd„ZG dd„ dƒZdS )é    )ÚannotationsN)ÚList)Úhashlib)ÚKerberosSecretType)Ústring_to_keyÚEnctype)ÚEncryptionType)ÚCCACHE)ÚKeytab)ÚKirbi)Úcms)Úalgos)ÚDirtyDHÚfileÚdataúbytes or strÚreturnÚbytesc                 C  s¤   |dkrt | dƒ�}| ¡ W  d   ƒ S 1 sw   Y  n.|dkr't | ¡S |dks/|dkr=t| tƒr8|  ¡ } t | ¡S |dkrLt| tƒrJ|  ¡ } | S t	d| ƒ‚)Nr   ÚrbÚhexÚb64Úbase64ÚrawzUnknown encoding "%s"!)
ÚopenÚreadr   ÚfromhexÚ
isinstanceÚstrÚencoder   Ú	b64decodeÚ	Exception)r   ÚencodingÚkf© r#   úŒ/root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/minikerberos/common/creds.pyÚget_encoded_data   s   "ÿ



r%   c                   @  s@  e Zd Zdd„ ZdTdd„ZdUd	d
„ZdVdWdd„ZdXdYdd„ZedZd[dd„ƒZ	ed\d]dd„ƒZ
ed\d[dd„ƒZed^d_d%d&„ƒZed`d[d'd(„ƒZedad+d,„ƒZd`dbd-d.„Zedcddd1d2„ƒZedcded5d6„ƒZedfdgd:d;„ƒZedcdhd<d=„ƒZedcdid?d@„ƒZdAdB„ ZdjdDdE„ZdjdFdG„ZdkdKdL„Zedg dM¢fdldPdQ„ƒZdRdS„ ZdS )mÚKerberosCredentialc                 C  s‚   d | _ d | _d | _d | _d | _d | _d | _d | _d | _d | _	d | _
d | _d | _d| _d | _d | _d | _d | _d| _d| _g | _d S )NF)ÚusernameÚdomainÚpasswordÚnt_hashÚlm_hashÚkerberos_key_aes_256Úkerberos_key_aes_128Úkerberos_key_desÚkerberos_key_rc4Úkerberos_key_des3ÚcertificateÚprivate_keyÚ_KerberosCredential__hcertÚ*_KerberosCredential__use_windows_certstoreÚ
commonnameÚcertstore_nameÚdhparamsÚccacheÚccache_spn_strict_checkÚ	nopreauthÚoverride_etypes)Úselfr#   r#   r$   Ú__init__,   s*   
zKerberosCredential.__init__Úserver_enctypesúList[EncryptionType]r   c                 C  sj   | j dd�}ttdd„ |D ƒƒt|ƒ@ ƒ}t|ƒdkr3tdd dd„ |D ƒ¡d d	d„ |D ƒ¡f ƒ‚|S )
NF©Úas_intc                 S  ó   g | ]}|‘qS r#   r#   ©Ú.0Ú	s_enctyper#   r#   r$   Ú
<listcomp>E   ó    z:KerberosCredential.get_common_enctypes.<locals>.<listcomp>r   z3No common supported enctypes! Server: %s Client: %sz, c                 S  ó   g | ]}|j ‘qS r#   ©ÚnamerC   r#   r#   r$   rF   H   ó    c                 S  rH   r#   rI   )rD   Ú	c_enctyper#   r#   r$   rF   I   rK   )Úget_supported_enctypesÚlistÚsetÚlenr    Újoin)r<   r>   Úclient_enctypesÚcommon_enctypesr#   r#   r$   Úget_common_enctypesC   s   þz&KerberosCredential.get_common_enctypesr   c                 C  s4   | j dd�}|  |¡}|D ]
}||v r|  S qd S )NFr@   )rM   rT   )r<   r>   rR   rS   rL   r#   r#   r$   Úget_preferred_enctypeN   s   
ÿÿz(KerberosCredential.get_preferred_enctypeNÚetypeÚsaltr   c                 C  sÈ  |t jkr,| jrt | j¡S | jdur(|s| j ¡ | j  	¡ }t
tj| j|ƒjS tdƒ‚|t jkrX| jr:t | j¡S | jdurT|sK| j ¡ | j  	¡ }t
tj| j|ƒjS tdƒ‚|t jkr¦| jrft | j¡S | jrot | j¡S | jr¢t| jtƒr| j 	d¡}nt| jtƒr‰| j}n	tdt| jƒ ƒ‚t |¡ ¡  ¡ | _t | j¡S tdƒ‚|t jkrÐ| jr´t | j¡S | jrÌ|sÃ| j ¡ | j  	¡ }t
tj| j|ƒjS tdƒ‚|t jkrú| jrÞt | j¡S | jrö|sí| j ¡ | j  	¡ }t
tj | j|ƒjS tdƒ‚|t j!k�r]| j�rt | j¡dd	… S | j�rt | j¡dd	… S | j�rY| j}t| jtƒ�r1| j 	d¡}nt| jtƒ�r<| j}n	tdt| jƒ ƒ‚t |¡ ¡  ¡ | _t | j¡dd	… S tdƒ‚td
|j" ƒ‚)z@
		Returns the encryption key bytes for the enctryption type.
		Nz%There is no key for AES256 encryptionz%There is no key for AES128 encryptionz	utf-16-lezUnknown password type: %sz"There is no key for RC4 encryptionz#There is no key for DES3 encryptionz"There is no key for DES encryptioné   zUnsupported encryption type: %s)#r   ÚAES256_CTS_HMAC_SHA1_96r,   r   r   r)   r(   Úupperr'   r   r   r   ÚAES256Úcontentsr    ÚAES128_CTS_HMAC_SHA1_96r-   ÚAES128ÚARCFOUR_HMAC_MD5r/   r*   r   r   Útyper   Úmd4Ú	hexdigestÚDES3_CBC_SHA1r0   ÚDES3ÚDES_CBC_MD5r.   ÚDES_MD5ÚARCFOUR_MD4rJ   )r<   rV   rW   Úpwr#   r#   r$   Úget_key_for_enctypeV   s|   






z&KerberosCredential.get_key_for_enctypeTc                 C  sÄ  t  ¡ }| jdur$t| jƒdkr$| jD ]}t|tƒrt|ƒ}d||< qn–| jdu rQd|tj< d|tj	< d|tj
< d|tj< d|tj< d|tj< d|tj< d|tj< | jrYd|tj< | jrad|tj< | jrŒd|tj< d|tj	< d|tj
< d|tj< d|tj< d|tj< d|tj< d|tj< | js•| js•| jrŸd|tj< d|tj< | jr§d|tj< | jdurºt  ¡ }d|tj< d|tj< | jdurÐt|ƒdkrÐtjdtjdtjdi}|dkrÛdd„ |D ƒS dd„ |D ƒS )zW
		Returns a list of all EncryptionTypes this credentials can use for authentication
		Nr   é   Tc                 S  rH   r#   )Úvalue©rD   rV   r#   r#   r$   rF   à   rK   z=KerberosCredential.get_supported_enctypes.<locals>.<listcomp>c                 S  rB   r#   r#   rl   r#   r#   r$   rF   á   rG   )ÚcollectionsÚOrderedDictr;   rP   r   Úintr   r:   ÚDES_CBC_CRCÚDES_CBC_MD4re   rc   r_   rg   rY   r]   r,   r-   r)   r*   r/   r.   r1   r8   )r<   rA   Úsupp_enctypesrV   r#   r#   r$   rM   £   s\   


ý
























ýz)KerberosCredential.get_supported_enctypesr   Úkeytab_file_pathr   Ú	principalÚrealmc                 C  s,   t ƒ }||_||_t| |d�}t  |||¡S )z:Returns a kerberos credential object from Keytab file/data©r!   )r&   r'   r(   r%   Úfrom_keytab_string)rs   rt   ru   r!   Úcredr   r#   r#   r$   Úfrom_keytabã   s
   zKerberosCredential.from_keytabc                 C  sV   | du rt j d¡}|du rtdƒ‚|} t| |d�} tƒ }||_||_t 	| ¡|_
|S )z9Returns a kerberos credential object with CCACHE databaseNÚ
KRB5CCNAMEz No CCACHE data or path provided!rv   )ÚosÚenvironÚgetr    r%   r&   r'   r(   r	   Ú
from_bytesr8   )r   rt   ru   r!   Úccache_pathÚkr#   r#   r$   Úfrom_ccacheì   s   zKerberosCredential.from_ccachec                 C  s~   |dkrt | |d�}t |¡}nt | ¡}tƒ }|dur|n| ¡ |_|dur)|n	|jj	d d d |_
t |¡|_d|_|S )z5Returns a kerberos credential object from .kirbi fileÚkirbirv   NÚticketsr   ru   F)r%   r   r~   ÚcopyÚdeepcopyr&   Úget_usernamer'   ÚkirbiobjÚnativer(   r	   Ú
from_kirbir8   r9   )rs   rt   ru   r!   r   r‚   rx   r#   r#   r$   r‰   û   s   
"zKerberosCredential.from_kirbir   r)   r7   r   r'   r(   c                 C  s    t | |d�} tj| ||||d�S )z‰
		Retruns a credential object from data found in the PFX file
		Username and domain will override the values found in the certificate
		rv   ©r7   r'   r(   )r%   r&   Úfrom_pfx_string)r   r)   r7   r'   r(   r!   r#   r#   r$   Úfrom_pfx
  s   zKerberosCredential.from_pfxc                 C  s   t  | ||¡S ©N)r&   r‰   )rs   rt   ru   r#   r#   r$   Úfrom_krbcred  s   zKerberosCredential.from_krbcredÚ
keytabdataústr or bytesc                 C  sŠ  t ƒ }|d u rtdƒ‚|d u rtdƒ‚||_||_t| tƒr9t |  dd¡ dd¡ dd¡ dd¡ dd¡ 	¡ ¡} t
 | ¡}t|jƒdkrItd	ƒ‚t|jƒd
krV|jd }n|jD ]}|j ¡  ¡  | ¡ ¡dkrm|} nqY|jd }tj|jkr}tj}n;tj|jkr‡tj}n1tj|jkr‘tj}n'tj|jkr›tj}ntj|jkr¥tj}ntj|jkr¯tj}n	tj|jkr¸tj}|rÃ| ||j ¡ ¡ |S )NzPrincipal is requiredzRealm is requiredú Ú úÚ
ú	r   zNo entries found in keytabrj   éÿÿÿÿ) r&   r    r'   r(   r   r   r   r   Úreplacer   r
   r~   rP   Úentriesrt   Úto_pnameÚlowerÚfindr   r[   Úenctyper   r^   rd   ÚDES_CRCÚDESÚDES_MD4rf   ÚRC4Ú
add_secretÚkey_contentsr   )r�   rt   ru   rx   ÚkeytabÚkeytab_entryÚentryrœ   r#   r#   r$   rw     sJ   
6

þ
z%KerberosCredential.from_keytab_stringc                 C  s¢   || _ |du r| jjjd  dd¡d | _ || _|du rOd}d| jjjv r,| jjjd }d| jjjv r:| jjjd }|durKd |ddd… ¡| _dS td	ƒ‚dS )
z‹
		Tries to guess the correct username and domain from the current certificate,
		if 'username' and/or 'domain' is set it will set those
		NÚcommon_nameú@rj   r   Údomain_componentÚ.r–   zKCould't find proper domain name in the certificate! Please set it manually!)	r'   r1   Úsubjectrˆ   Úrsplitr(   ÚissuerrQ   r    )r<   r'   r(   Údcr#   r#   r$   Úset_user_and_domain_from_certF  s   ÷z0KerberosCredential.set_user_and_domain_from_certÚcertdataÚkeydatac                 C  s®   ddl m}m} t| tƒr"t |  dd¡ dd¡ dd¡ dd¡¡} t|tƒr<t | dd¡ dd¡ dd¡ dd¡¡}tƒ }|| ƒ|_	||ƒ|_
|j||d� | |¡ |S )	Nr   )Úparse_certificateÚparse_privater‘   r’   r“   r”   r•   ©r'   r(   )Úoscrypto.keysr±   r²   r   r   r   r   r—   r&   r1   r2   r®   Úset_dhparams)r¯   r°   r7   r'   r(   r±   r²   r€   r#   r#   r$   Úfrom_pem_dataZ  s   
*
*


z KerberosCredential.from_pem_dataÚcertpathÚkeypathc                 C  sx   t | dƒ�}| ¡ }W d   ƒ n1 sw   Y  t |dƒ�}| ¡ }W d   ƒ n1 s-w   Y  tj|||||d�S )Nr   rŠ   )r   r   r&   r¶   )r·   r¸   r7   r'   r(   Úfr¯   r°   r#   r#   r$   Úfrom_pem_filei  s   
ÿ
ÿz KerberosCredential.from_pem_fileÚMYr5   r6   c                 C  s‚   t  ¡  ¡ dkrtdƒ‚ddlm}m}m} tƒ }| |_	||_
|| |ƒ\|_}	}
||	ƒ ||
ƒ d|_|j||d� | |¡ |S )NÚwindowsz!Only works on windows (obviously)r   )Úfind_cert_by_cnÚCertCloseStoreÚCertFreeCertificateContextTr³   )ÚplatformÚsystemrš   r    Ú#minikerberos.common.windows.crypt32r½   r¾   r¿   r&   r5   r6   r1   r4   r®   rµ   )r5   r6   r7   r'   r(   r½   r¾   r¿   r€   ÚchandleÚshandler#   r#   r$   Úfrom_windows_certstoreu  s   
z)KerberosCredential.from_windows_certstorec                 C  s’   ddl m} tƒ }|d u rd}t|tƒr| ¡ }t| tƒr0t |  dd¡ dd¡ dd¡ ¡ ¡} || |d�\|_	|_
}|j||d	� | |¡ |S )
Nr   )Úparse_pkcs12ó    r‘   r’   r“   r”   )r)   r³   )r´   rÆ   r&   r   r   r   r   r   r—   r2   r1   r®   rµ   )r   r)   r7   r'   r(   rÆ   r€   Úextra_certsr#   r#   r$   r‹   ‡  s   

&
z"KerberosCredential.from_pfx_stringÚfilepathc                 C  sF   t | dƒ�}| ¡ }W d  ƒ n1 sw   Y  tj|||||d�S )zK
		Username and domain will override the values found in the certificate
		r   NrŠ   )r   r   r&   r‹   )rÉ   r)   r7   r'   r(   r¹   r   r#   r#   r$   Úfrom_pfx_filež  s   
ÿz KerberosCredential.from_pfx_filec                 C  st   t  tddƒddœ¡| _|d ur8t|tƒrt  |¡| _d S t|tƒr*t  |¡| _d S t|t ƒr4|| _d S tdƒ‚d S )NÁ  00ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f24117c4b1fe649286651ece65381ffffffffffffffffé   é   )ÚpÚgz.DH params must be either a bytearray or a dict)	r   Ú	from_dictro   r7   r   Údictr   Ú	from_asn1r    )r<   r7   r#   r#   r$   rµ   §  s   
þ



øzKerberosCredential.set_dhparamsFc                 C  s`   | j du r*ddlm}m}m}m} || j| jƒ\}}}	|||ƒ}
||ƒ ||	ƒ |
S |  ||¡S )NTr   )Ú
pkcs7_signr¾   r½   r¿   )	r4   rÂ   rÓ   r¾   r½   r¿   r5   r6   Úsign_authpack_native)r<   r   Úwrap_signedrÓ   r¾   r½   r¿   Ú_rÃ   rÄ   Úresr#   r#   r$   Úsign_authpack¹  s   

z KerberosCredential.sign_authpackc           
      C  s^  ddl m}m} i }t d¡|d< i }d|d< t | jj| jj	dœ¡|d< t 
|¡|d	< t d
dgdœ¡t dt |¡ ¡ gdœ¡g|d< t ddi¡|d< ||| jƒt |d ¡ ¡ dƒ|d< i }d|d
< ||d< i }d|d< t 
|¡g|d< t |¡|d< | jg|d< t t |¡g¡|d< |du r¨i }	d|	d
< t |¡|	d< t |	¡ ¡ S t |¡ ¡ S )a  
		Creating PKCS7 blob which contains the following things:

		1. 'data' blob which is an ASN1 encoded "AuthPack" structure
		2. the certificate used to sign the data blob
		3. the singed 'signed_attrs' structure (ASN1) which points to the "data" structure (in point 1)
		r   )Úrsa_pkcs1v15_signÚload_private_keyz1.3.14.3.2.26Ú	algorithmÚv1Úversion)r¬   Úserial_numberÚsidÚdigest_algorithmÚcontent_typez1.3.6.1.5.2.3.1)r`   ÚvaluesÚmessage_digestÚsigned_attrsz1.2.840.113549.1.1.1Úsignature_algorithmÚsha1Ú	signatureÚcontentÚv3Údigest_algorithmsÚencap_content_infoÚcertificatesÚsigner_infosTz1.2.840.113549.1.7.2)Úoscrypto.asymmetricrÙ   rÚ   r   ÚDigestAlgorithmIdr   ÚIssuerAndSerialNumberr1   r¬   rÞ   ÚDigestAlgorithmÚCMSAttributer   ræ   ÚdigestÚSignedDigestAlgorithmr2   ÚCMSAttributesÚdumpÚEncapsulatedContentInfoÚSignerInfosÚ
SignerInfoÚ
SignedDataÚContentInfo)
r<   r   rÕ   rÙ   rÚ   ÚdaÚsiÚecÚsdÚcir#   r#   r$   rÔ   Ã  s<   þþ$z'KerberosCredential.sign_authpack_nativeÚstr   Úsecretc                 C  s,  |t jks|t jks|t jkr$|dks|d u rt d¡| _d S || _d S |t jks.|t jkr6|| _|| _	d S |t j
kr@|| _d S |t jkrJ|| _d S |t jkrnt |¡ t|ƒdkr_|| _d S t|ƒdkrj|| _d S tdƒ‚|t jkrx|| _d S |t jks‚|t jkr‡|| _d S |t jkr”t |¡| _d S d S )Nr’   z#Enter Kerberos credential password:é    é@   zAES key incorrect length!)r   ÚPASSWORDÚPWÚPASSÚgetpassr)   ÚNTr    r*   r/   r^   r-   r[   r,   ÚAESr   r   rP   r    rž   r.   rd   ÚTDESr0   r	   Ú	from_filer8   )r<   r  r  r#   r#   r$   r¡   ô  s2   













ÿzKerberosCredential.add_secret)é   é   é   r;   ú	List[int]c                 C  s|   t ƒ }| d d d |_t| d d ƒdkr| d d d |_| d |_|dur+||_|dur<|D ]
}|j t|ƒ¡ q1|S )zBReturns a new KerberosCredential object with user matching the TGTÚcnamezname-stringr   rj   ÚcrealmN)r&   r'   rP   r(   r;   Úappendr   )ÚtgtÚoverride_realmr;   Únew_credrV   r#   r#   r$   Úfrom_tgt  s   
zKerberosCredential.from_tgtc              	   C  sb   d}| j D ])}t| j | tƒr#|d|d dd„ | j | D ƒ¡f 7 }q|d|| j | f 7 }q|S )Nz===KerberosCredential===
z%s: %s
ú,c                 S  s   g | ]}t |ƒ‘qS r#   )r   )rD   Úxr#   r#   r$   rF   #  s    z.KerberosCredential.__str__.<locals>.<listcomp>)Ú__dict__r   rN   rQ   )r<   Útr€   r#   r#   r$   Ú__str__  s   
(zKerberosCredential.__str__)r>   r?   r   r?   )r>   r?   r   r   r�   )rV   r   rW   r   r   r   )T)r   r?   ©r   )rs   r   rt   r   ru   r   r   r&   )NNr   )rt   r   ru   r   r   r&   )NNNr   )r   r   r)   r   r7   r   r'   r   r(   r   r   r&   )NN)r�   r�   rt   r   ru   r   r   r&   )r'   r   r(   r   )NNN)r¯   r�   r°   r�   r7   r   r'   r   r(   r   r   r&   )r·   r   r¸   r   r7   r   r'   r   r(   r   r   r&   )r»   NNN)r5   r   r6   r   r7   r   r'   r   r(   r   r   r&   )r   r�   r)   r   r7   r   r'   r   r(   r   r   r&   )rÉ   r   r)   r   r7   r   r'   r   r(   r   r   r&   )F)r  r   r  r   )r;   r  )Ú__name__Ú
__module__Ú__qualname__r=   rT   rU   ri   rM   Ústaticmethodry   r�   r‰   rŒ   rŽ   rw   r®   r¶   rº   rÅ   r‹   rÊ   rµ   rØ   rÔ   r¡   r  r  r#   r#   r#   r$   r&   +   sH    

M@.



1r&   r  )r   r   r   r   ) Ú
__future__r   r  rm   r   rÀ   r„   Útypingr   r{   Ú	unicryptor   Úminikerberos.common.constantsr   Ú minikerberos.protocol.encryptionr   r   Úminikerberos.protocol.constantsr   Úminikerberos.common.ccacher	   Úminikerberos.common.keytabr
   Úminikerberos.common.kirbir   Ú
asn1cryptor   r   Úminikerberos.protocol.dirtydhr   r%   r&   r#   r#   r#   r$   Ú<module>   s(    