o
    jS                     @  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rt| 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rt| jS | jr|s| j | j 	 }t
tj| j|jS td|t jkr| jrt| 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rd|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rd|tj< d|tj< | jrd|tj< | jdurt  }d|tj< d|tj< | jdurt|dkrtjdtjdtjdi}|dkrd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rtj}n1tj|jkrtj}n'tj|jkrtj}ntj|jkrtj}ntj|jkrtj}n	tj|jkrt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 ri }	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rt|| _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(    