o
    �õ±jOk  ã                   @   sD  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mZm	Z	m
Z
mZmZmZmZ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 G dd„ dƒZG dd„ dƒZ G dd„ dƒZ!G dd„ dƒZ"G dd„ dƒZ#G dd„ dƒZ$G dd„ dƒZ%G dd„ dƒZ&G dd„ dƒZ'G dd„ dƒZ(dS )é    N)ÚList)ÚTicketÚEncryptedDataÚ	krb5_pvnoÚKrbCredInfoÚEncryptionKeyÚKRBCREDÚTicketFlagsÚEncKrbCredPart)Údt_to_kerbtime)ÚEncryptionTypeÚMESSAGE_TYPE)Úlogger)Úcore)Úhashlib)ÚKirbi)ÚKerberosSPNc                   @   sB   e Zd Zdd„ Zedd„ ƒZdd„ Zedefdd	„ƒZd
d„ Z	dS )ÚHeaderc                 C   s   d | _ d | _d | _d S ©N©ÚtagÚtaglenÚtagdata©Úself© r   ú�/root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/minikerberos/common/ccache.pyÚ__init__   s   
zHeader.__init__c                 C   s€   t  | ¡}g }| ¡ t| ƒk r>tƒ }tj| d¡ddd�|_tj| d¡ddd�|_	| |j	¡|_
| |¡ | ¡ t| ƒk s|S )z#
		returns a list of header tags
		é   ÚbigF©Ú	byteorderÚsigned)ÚioÚBytesIOÚtellÚlenr   ÚintÚ
from_bytesÚreadr   r   r   Úappend)ÚdataÚreaderÚheadersÚhr   r   r   Úparse   s   

ûzHeader.parsec                 C   s:   | j jdddd�}|t| jƒjdddd�7 }|| j7 }|S ©Nr   r   Fr    )r   Úto_bytesr&   r   ©r   Útr   r   r   r1   *   s   
zHeader.to_bytesr+   c                 C   s
   t  | ¡S r   )r   r/   ©r+   r   r   r   r(   0   s   
zHeader.from_bytesc                 C   s*   d| j  }|d| j 7 }|d| j 7 }|S )Nztag: %s
ztaglen: %s
ztagdata: %s
r   r2   r   r   r   Ú__str__4   s   
zHeader.__str__N)
Ú__name__Ú
__module__Ú__qualname__r   Ústaticmethodr/   r1   Úbytesr(   r5   r   r   r   r   r      s    
r   c                   @   sB   e Zd Zdd„ Zedejfdd„ƒZdd„ Zede	fd	d
„ƒZ
dS )ÚDateTimec                 C   ó   d | _ d | _d S r   )Útime_offsetÚusec_offsetr   r   r   r   r   ;   ó   
zDateTime.__init__r,   c                 C   s:   t ƒ }tj|  d¡ddd�|_tj|  d¡ddd�|_|S ©Né   r   Fr    )r;   r'   r(   r)   r=   r>   )r,   Údr   r   r   r/   ?   s   zDateTime.parsec                 C   s,   | j jdddd�}|| jjdddd�7 }|S r@   )r=   r1   r>   r2   r   r   r   r1   F   s   zDateTime.to_bytesr+   c                 C   ó   t  t | ¡¡S r   )r;   r/   r#   r$   r4   r   r   r   r(   K   ó   zDateTime.from_bytesN©r6   r7   r8   r   r9   r#   r$   r/   r1   r:   r(   r   r   r   r   r;   :   s    r;   c                   @   sz   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zede	fdd„ƒZ
edd„ ƒZedd„ ƒZedd„ ƒZdd„ Zdd„ ZdS )Ú
Credentialc                 C   sL   d | _ d | _d | _d | _d | _d | _d | _g | _d | _g | _	d | _
d | _d S r   )ÚclientÚserverÚkeyÚtimeÚis_skeyÚtktflagsÚnum_addressÚaddrsÚnum_authdataÚauthdataÚticketÚsecond_ticketr   r   r   r   r   R   s   
zCredential.__init__c                 C   sô   t  | j ¡ ¡j}t|d d ƒ}t|d d ƒ}|dkr&|d d d }n|d d d }|d }|tjj	krY|d d d	d … }|d d d d	… }d
|||| 
¡ | 
¡ f S |d d d d… }|d d dd … }d|||| 
¡ | 
¡ f S )Núenc-partÚetypeÚsnameúname-stringé   r   ÚrealmÚcipheriôÿÿÿz$krb5tgs$%s$%s$%s$%s$%sé   z$krb5tgs$%s$*%s$%s$spn*$%s$%s)r   ÚloadrQ   Úto_asn1Únativer'   r&   r   ÚAES256_CTS_HMAC_SHA1_96ÚvalueÚhex)r   ÚresÚtgs_encryption_typer3   Útgs_name_stringÚ	tgs_realmÚtgs_checksumÚtgs_encrypted_data2r   r   r   Úto_hash`   s   zCredential.to_hashc                 C   ó€   t dddœƒ}i }t|d< tjj|d< | jj ¡ |d< | j ¡ d |d< t	 
| j ¡ ¡j|d	< |j|d
< t| j ¡ ƒj}||fS ©zf
		Returns the native format of an AS_REP message and the sessionkey in EncryptionKey native format
		rW   ó    ©rT   rY   Úpvnoúmsg-typeÚcrealmr   ÚcnamerQ   rS   ©r   r   r   Ú
KRB_AS_REPr_   rG   rX   Ú	to_stringr\   r   r[   rQ   r]   r   rI   ©r   Úenc_partÚtgt_repr3   r   r   r   Úto_tgtr   ó   
zCredential.to_tgtc                 C   rh   ri   rp   rs   r   r   r   Úto_tgs„   rw   zCredential.to_tgsc                 C   s¬  d| j  ¡ | j ¡ t | j ¡ ¡ ¡ d d… f }i }t| j	 ¡ ƒ|d< | j j
 ¡ |d< | j  ¡ d |d< t | j¡ t¡|d< | jjdkrStj | jjtjj¡|d< | jjdkrftj | jjtjj¡|d	< | jjdkrytj | jjtjj¡|d
< | jjdkrŒtj | jjtjj¡|d< | jj
 ¡ |d< | j ¡ d |d< i }t|ƒg|d< i }t|d< tjj|d< t | j ¡ ¡g|d< t t!j"jt#|ƒ $¡ dœƒ|d< t%t&|ƒƒ}||fS )Nz%s@%s_%sé   rI   Úprealmr   ÚpnameÚflagsÚauthtimeÚ	starttimeÚendtimeú
renew-tillÚsrealmrU   úticket-inforl   rm   Úticketsrk   rS   )'rG   rr   rH   r   Úsha1rQ   r\   Ú	hexdigestr   rI   rX   r   ÚIntegerBitStringrL   Úcastr	   rJ   r}   ÚdatetimeÚfromtimestampÚtimezoneÚutcr~   r   Ú
renew_tillr   r   r   ÚKRB_CREDr_   r   r[   r   r   ÚNULLr
   Údumpr   r   )r   ÚfilenameÚkrbcredinfoÚenc_krbcredÚkrbcredÚkirbir   r   r   Úto_kirbi–   s2   2zCredential.to_kirbir”   c                 C   s8  | j j}tƒ }t |d d ¡j}|d d }t |d |d ¡|_t|d d ƒd	krY|d d d
  	¡ |d  	¡ krYt
 d¡ |d }|d d d
… |d< t ||d ¡|_nt |d |d ¡|_t |¡|_t |d ¡|_d|_t|d ƒ tj¡j|_d|_d|_t t|d d ƒ ¡ ¡|_t ¡ |_|S )NrS   rY   r‚   r   r{   rz   rU   rV   r   éÿÿÿÿr�   z-SNAME contains the realm as well, trimming itrI   r|   rƒ   )Úkirbiobjr]   rF   r
   r[   ÚCCACHEPrincipalÚ	from_asn1rG   r&   Úupperr   ÚdebugrH   ÚTimesrJ   ÚKeyblockrI   rK   r	   r‡   r   r†   rL   rM   rO   ÚCCACHEOctetStringr   r�   rQ   ÚemptyrR   )r”   r“   ÚcÚenc_credinfoÚticket_infor3   r   r   r   Ú
from_kirbi´   s(   4

zCredential.from_kirbic                 C   sŽ   t ƒ }t |d |d ¡|_t |d |d ¡|_t |d ¡|_d|_t|d ƒ 	t
j¡j|_d|_d|_t | d d	 ¡|_t ¡ |_|S )
Nr{   rz   rU   r�   rI   r   r|   rS   rY   )rF   r˜   r™   rG   rH   r�   rI   rK   r	   r‡   r   r†   r]   rL   rM   rO   rž   rQ   rŸ   rR   )rQ   r+   r    r   r   r   r™   Ó   s   
zCredential.from_asn1c                 C   sö   t ƒ }t | ¡|_t | ¡|_t | ¡|_t | ¡|_t	j
|  d¡ddd�|_t	j
|  d¡ddd�|_t	j
|  d¡ddd�|_t|jƒD ]}|j t | ¡¡ qDt	j
|  d¡ddd�|_t|jƒD ]}|j t | ¡¡ qat | ¡|_t | ¡|_|S ©NrW   r   Fr    rA   Úlittle)rF   r˜   r/   rG   rH   r�   rI   rœ   rJ   r'   r(   r)   rK   rL   rM   ÚrangerN   r*   ÚAddressrO   rP   ÚAuthdatarž   rQ   rR   )r,   r    Ú_r   r   r   r/   å   s    zCredential.parsec                   C   s   g d¢S )N)rG   rH   r~   r   r€   r   r   r   r   r   Úsummary_headerø   s   zCredential.summary_headerc                 C   s¤   d| j jdd�| j j ¡ f d| jjdd�| jj ¡ f | jjdkr,tj | jj¡ ¡ nd| jj	dkr=tj | jj	¡ ¡ nd| jj
dkrOtj | jj
¡ ¡ gS dgS )Nz%s@%sú/©Ú	separatorr   zN/A)rG   rr   rX   rH   rJ   r~   rˆ   r‰   Ú	isoformatr   rŒ   r   r   r   r   Úsummaryü   s   ""ûûzCredential.summaryc                 C   sÜ   | j  ¡ }|| j ¡ 7 }|| j ¡ 7 }|| j ¡ 7 }|| jjdddd�7 }|| jjdddd�7 }|| jjdddd�7 }| jD ]}|| ¡ 7 }q>|| j	jdddd�7 }| j
D ]}|| ¡ 7 }qU|| j ¡ 7 }|| j ¡ 7 }|S r¤   )rG   r1   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   )r   r3   ÚaddrÚadr   r   r   r1     s   


zCredential.to_bytesN)r6   r7   r8   r   rg   rv   rx   r•   r9   r   r£   r™   r/   rª   r¯   r1   r   r   r   r   rF   Q   s     



rF   c                   @   s<   e Zd Zdd„ Zedd„ ƒZdd„ Zedd„ ƒZd	d
„ ZdS )r�   c                 C   ó   d | _ d | _d | _d | _d S r   )ÚkeytyperT   ÚkeylenÚkeyvaluer   r   r   r   r     ó   
zKeyblock.__init__c                 C   s2   t ƒ }| d |_d|_t| d ƒ|_| d |_|S )Nr³   r   rµ   )r�   r³   rT   r&   r´   rµ   )r+   Úkr   r   r   r™     s   

zKeyblock.from_asn1c                 C   s   i }| j |d< | j|d< |S )Nr³   rµ   )r³   rµ   r2   r   r   r   r\   (  s   

zKeyblock.to_asn1c                 C   s`   t ƒ }tj|  d¡ddd�|_tj|  d¡ddd�|_tj|  d¡ddd�|_|  |j¡|_|S ©Nr   r   Tr    F)r�   r'   r(   r)   r³   rT   r´   rµ   )r,   r·   r   r   r   r/   /  s   zKeyblock.parsec                 C   sL   | j jdddd�}|| jjdddd�7 }|| jjdddd�7 }|| j7 }|S r¸   )r³   r1   rT   r´   rµ   r2   r   r   r   r1   8  s
   
zKeyblock.to_bytesN)	r6   r7   r8   r   r9   r™   r\   r/   r1   r   r   r   r   r�     s    
	
r�   c                   @   sb   e Zd Zdd„ Zedd„ ƒZeej ejj	¡fdd„ƒZ
edd„ ƒZd	d
„ Zedefdd„ƒZdS )rœ   c                 C   r²   r   )r}   r~   r   rŒ   r   r   r   r   r   A  r¶   zTimes.__init__c                 C   s˜   t ƒ }d| v r| d rt| d ƒnd|_d| v r"| d r"t| d ƒnd|_d| v r3| d r3t| d ƒnd|_d| v rG| d rGt| d ƒ|_|S d|_|S )Nr}   r   r~   r   rŒ   )rœ   r   r}   r~   r   rŒ   )Úenc_as_rep_partr3   r   r   r   r™   G  s&   ÿÿÿÿÿÿÿÿÿzTimes.from_asn1c                 C   sJ   t ƒ }t| ƒ|_t| ƒ|_t| tjdd� ƒ|_t| tjdd� ƒ|_|S )NrW   )Údaysr   )rœ   r   r}   r~   rˆ   Ú	timedeltar   rŒ   )Ústartr3   r   r   r   Ú
dummy_timeT  s   

zTimes.dummy_timec                 C   sj   t ƒ }tj|  d¡ddd�|_tj|  d¡ddd�|_tj|  d¡ddd�|_tj|  d¡ddd�|_|S r@   )rœ   r'   r(   r)   r}   r~   r   rŒ   )r,   r3   r   r   r   r/   ]  s   zTimes.parsec                 C   sX   | j jdddd�}|| jjdddd�7 }|| jjdddd�7 }|| jjdddd�7 }|S r@   )r}   r1   r~   r   rŒ   r2   r   r   r   r1   f  s
   zTimes.to_bytesr+   c                 C   rC   r   )rœ   r/   r#   r$   r4   r   r   r   r(   m  rD   zTimes.from_bytesN)r6   r7   r8   r   r9   r™   rˆ   ÚnowrŠ   r‹   r½   r/   r1   r:   r(   r   r   r   r   rœ   @  s    

rœ   c                   @   s6   e Zd Zdd„ Zedd„ ƒZdd„ Zdefdd	„Zd
S )r§   c                 C   r<   r   )ÚaddrtypeÚaddrdatar   r   r   r   r   r  r?   zAddress.__init__c                 C   ó.   t ƒ }tj|  d¡ddd�|_t | ¡|_|S r0   )r§   r'   r(   r)   r¿   rž   r/   rÀ   ©r,   Úar   r   r   r/   v  ó   zAddress.parsec                 C   ó$   | j jdddd�}|| j ¡ 7 }|S r0   )r¿   r1   rÀ   r2   r   r   r   r1   }  ó   zAddress.to_bytesr+   c                 C   rC   r   )r§   r/   r#   r$   r4   r   r   r   r(   ‚  ó   zAddress.from_bytesN)	r6   r7   r8   r   r9   r/   r1   r:   r(   r   r   r   r   r§   q  s    
r§   c                   @   s>   e Zd Zdd„ Zedejfdd„ƒZdd„ Zde	fd	d
„Z
dS )r¨   c                 C   r<   r   )ÚauthtyperP   r   r   r   r   r   †  r?   zAuthdata.__init__r,   c                 C   rÁ   r0   )r¨   r'   r(   r)   rÈ   rž   r/   rP   rÂ   r   r   r   r/   Š  rÄ   zAuthdata.parsec                 C   rÅ   r0   )rÈ   r1   rP   r2   r   r   r   r1   ‘  rÆ   zAuthdata.to_bytesr+   c                 C   rC   r   )r¨   r/   r#   r$   r4   r   r   r   r(   –  rÇ   zAuthdata.from_bytesNrE   r   r   r   r   r¨   …  s    r¨   c                   @   sb   e Zd Zdd„ Zedd„ ƒZedd„ ƒZddd	„Zd
d„ Zdd„ Z	edd„ ƒZ
dd„ Zdd„ ZdS )r˜   c                 C   s   d | _ d | _d | _g | _d S r   )Ú	name_typeÚnum_componentsrX   Ú
componentsr   r   r   r   r   š  r¶   zCCACHEPrincipal.__init__c                 C   sN   t ƒ }| d |_t| d ƒ|_t |¡|_| d D ]}|j t 	|¡¡ q|S )Nú	name-typerV   )
r˜   rÉ   r&   rÊ   rž   Úfrom_stringrX   rË   r*   r™   )Ú	principalrX   ÚpÚcompr   r   r   r™      s   
zCCACHEPrincipal.from_asn1c                  C   sB   t ƒ } d| _d| _t d¡| _tdƒD ]}| j t d¡¡ q| S )NrW   z
kerbi.corpÚkerbi)	r˜   rÉ   rÊ   rž   rÍ   rX   r¦   rË   r*   )rÏ   r©   r   r   r   rŸ   «  s   zCCACHEPrincipal.emptyú-c                 C   s   |  dd„ | jD ƒ¡S )Nc                 S   ó   g | ]}|  ¡ ‘qS r   ©rr   ©Ú.0r    r   r   r   Ú
<listcomp>·  ó    z-CCACHEPrincipal.to_string.<locals>.<listcomp>)ÚjoinrË   )r   r­   r   r   r   rr   ¶  s   zCCACHEPrincipal.to_stringc                 C   s&   | j dd„ | jD ƒdœ}|| j ¡ fS )Nc                 S   rÓ   r   rÔ   ©rÖ   Únamer   r   r   r×   º  rØ   z+CCACHEPrincipal.to_asn1.<locals>.<listcomp>)rÌ   rV   )rÉ   rË   rX   rr   r2   r   r   r   r\   ¹  s   zCCACHEPrincipal.to_asn1c                 C   s$   d  dd„ | jD ƒ¡d | j ¡  S )Nr«   c                 S   rÓ   r   rÔ   rÚ   r   r   r   r×   ¾  rØ   z*CCACHEPrincipal.to_spn.<locals>.<listcomp>ú@)rÙ   rË   rX   rr   r   r   r   r   Úto_spn½  s   $zCCACHEPrincipal.to_spnc                 C   sh   t ƒ }tj|  d¡ddd�|_tj|  d¡ddd�|_t | ¡|_t	|jƒD ]}|j
 t | ¡¡ q&|S r@   )r˜   r'   r(   r)   rÉ   rÊ   rž   r/   rX   r¦   rË   r*   )r,   rÏ   r©   r   r   r   r/   À  s   zCCACHEPrincipal.parsec                 C   sV   | j jdddd�}|t| jƒjdddd�7 }|| j ¡ 7 }| jD ]}|| ¡ 7 }q |S r@   )rÉ   r1   r&   rË   rX   )r   r3   Úcomr   r   r   r1   Ê  s   
zCCACHEPrincipal.to_bytesc                 C   s,   | j  ¡ d }|d dd„ | jD ƒ¡7 }|S )Nr«   c                 S   rÓ   r   rÔ   rÕ   r   r   r   r×   Ô  rØ   z+CCACHEPrincipal.__str__.<locals>.<listcomp>)rX   rr   rÙ   rË   r2   r   r   r   r5   Ò  s   zCCACHEPrincipal.__str__N)rÒ   )r6   r7   r8   r   r9   r™   rŸ   rr   r\   rÝ   r/   r1   r5   r   r   r   r   r˜   ™  s    





	r˜   c                   @   sn   e Zd Zdd„ Zedd„ ƒZdd„ Zdd„ Zed	d
„ ƒZedd„ ƒZ	edd„ ƒZ
dd„ Zdedefdd„ZdS )rž   c                 C   r<   r   )Úlengthr+   r   r   r   r   r   Ù  r?   zCCACHEOctetString.__init__c                  C   s   t ƒ } d| _d| _| S )Nr   rj   )rž   rß   r+   )Úor   r   r   rŸ   Ý  s   zCCACHEOctetString.emptyc                 C   s   | j S r   r4   r   r   r   r   r\   ä  s   zCCACHEOctetString.to_asn1c                 C   s
   | j  ¡ S r   )r+   Údecoder   r   r   r   rr   ç  s   
zCCACHEOctetString.to_stringc                 C   s    t ƒ }|  ¡ |_t|jƒ|_|S r   )rž   Úencoder+   r&   rß   ©r+   rà   r   r   r   rÍ   ê  s   
zCCACHEOctetString.from_stringc                 C   s2   t ƒ }t| ƒ|_t| tƒr|  ¡ |_|S | |_|S r   )rž   r&   rß   Ú
isinstanceÚstrrâ   r+   rã   r   r   r   r™   ñ  s   


ÿzCCACHEOctetString.from_asn1c                 C   s0   t ƒ }tj|  d¡ddd�|_|  |j¡|_|S r@   )rž   r'   r(   r)   rß   r+   )r,   rà   r   r   r   r/   û  s   zCCACHEOctetString.parsec                 C   sH   t | jtƒr| j ¡ | _t| jƒ| _t| jƒjdddd�}|| j7 }|S r@   )rä   r+   rå   râ   r&   rß   r1   r2   r   r   r   r1     s   
zCCACHEOctetString.to_bytesÚ_CCACHEOctetString__oÚreturnc                 C   s   t |tƒr|  ¡ | ¡ kS dS ©NF)rä   rž   r1   )r   ræ   r   r   r   Ú__eq__
  s   
zCCACHEOctetString.__eq__N)r6   r7   r8   r   r9   rŸ   r\   rr   rÍ   r™   r/   r1   ÚobjectÚboolré   r   r   r   r   rž   Ø  s    


	
rž   c                   @   s<  e Zd ZdZd@dd„Zdd„ Zdd„ ZdAd
d„Zd@dd„ZdAde	fdd„Z
dd„ Zdd„ Zd@dedefdd„ZdBdefdd„Zdd„ Zdd„ Zed ejfd!d"„ƒZd#d$„ Zd%d&„ Zed'e	fd(d)„ƒZed*efd+d,„ƒZed-d.„ ƒZd/efd0d1„Zed2d3„ ƒZd4d5„ Zed6d7„ ƒZ ed8d9„ ƒZ!d:d;„ Z"d<d=„ Z#ed>d?„ ƒZ$dS )CÚCCACHEz‘
	As the header is rarely used -mostly static- you'd need to init this object with empty = True to get an object without header already present
	Fc                 C   s0   d | _ g | _d | _g | _|dkr|  ¡  d S d S rè   )Úfile_format_versionr-   Úprimary_principalÚcredentialsÚ_CCACHE__setup)r   rŸ   r   r   r   r     s   ÿzCCACHE.__init__c                 C   s8   d| _ tƒ }d|_d|_d|_| j |¡ t ¡ | _	d S )Ni  rW   ry   s           )
rí   r   r   r   r   r-   r*   r˜   rŸ   rî   )r   Úheaderr   r   r   Ú__setup  s   zCCACHE.__setupc                 C   s<   d}|d| j  7 }| jD ]}|d| 7 }q|d| j 7 }|S )Nz== CCACHE ==
zfile_format_version : %s
z%s
zprimary_principal : %s
)rí   r-   rî   )r   r3   rñ   r   r   r   r5   '  s   
zCCACHE.__str__Tc                 C   óº   t ƒ }t |d |d ¡|_|dkr|j| _t |d |d ¡|_t |¡|_t |d ¡|_	d|_
t|d ƒ tj¡j|_d|_d|_t t|d	 ƒ ¡ ¡|_t ¡ |_| j |¡ d
S )aÙ  
		Creates credential object from the TGT and adds to the ccache file
		The TGT is basically the native representation of the asn1 encoded AS_REP data that the AD sends upon a succsessful TGT request.
		
		This function doesn't do decryption of the encrypted part of the as_rep object, it is expected that the decrypted XXX is supplied in enc_as_rep_part
		
		override_pp: bool to determine if client principal should be used as the primary principal for the ccache file
		ro   rn   TrU   r�   rI   r   r|   rQ   N©rF   r˜   r™   rG   rî   rH   rœ   rJ   r�   rI   rK   r	   r‡   r   r†   r]   rL   rM   rO   rž   r   r�   rQ   rŸ   rR   rï   r*   )r   Úas_repr¹   Úoverride_ppr    r   r   r   Úadd_tgt/  ó   	
zCCACHE.add_tgtc                 C   ró   )aí  
		Creates credential object from the TGS and adds to the ccache file
		The TGS is the native representation of the asn1 encoded TGS_REP data when the user requests a tgs to a specific service principal with a valid TGT
		
		This function doesn't do decryption of the encrypted part of the tgs_rep object, it is expected that the decrypted XXX is supplied in enc_as_rep_part
		
		override_pp: bool to determine if client principal should be used as the primary principal for the ccache file
		ro   rn   TrU   r�   rI   r   r|   rQ   Nrô   )r   Útgs_repÚenc_tgs_rep_partrö   r    r   r   r   Úadd_tgsI  rø   zCCACHE.add_tgsr”   c                 C   s*   t  |¡}|dkr|j| _| j |¡ d S )NT)rF   r£   rG   rî   rï   r*   )r   r”   rö   r    r   r   r   Ú	add_kirbid  s   
zCCACHE.add_kirbic                 C   sB   g }| j D ]}|jjdd� ¡  d¡dkr| | ¡ d ¡ q|S )z¤
		Returns a list of AS_REP tickets in kirbi format (Kirbi). 
		To determine which ticket are AP_REP we check for the server principal to be the kerberos service
		r«   r¬   Úkrbtgtr–   r   )rï   rH   rr   ÚlowerÚfindr*   r•   ©r   ÚtgtsÚcredr   r   r   Úget_all_tgt_kirbisj  s   
€zCCACHE.get_all_tgt_kirbisc                 C   s>   g }| j D ]}|jjdd� ¡  d¡dkr| | ¡ ¡ q|S )z¤
		Returns a list of AS_REP tickets in native format (dict). 
		To determine which ticket are AP_REP we check for the server principal to be the kerberos service
		r«   r¬   rý   r–   )rï   rH   rr   rþ   rÿ   r*   rv   r   r   r   r   Úget_all_tgtv  s   
€zCCACHE.get_all_tgtÚspnÚstrictc                 C   s    |   ¡ }|D ]/\}}d |d d d ¡d |d d  }| ¡ t|ƒ ¡ kr5t d| ¡ ||d f  S q|du rCd d td	| ƒfS |d
 d
 |d
 d d fS )Nr«   rQ   rU   rV   rÜ   rX   zFound TGS for SPN %sTzNo TGS found for SPN %sr   rW   )Úget_all_tgsrÙ   rš   rå   r   r›   Ú	Exception)r   r  r  ÚtgssÚtgsÚ	keystructÚ
ticket_forr   r   r   Úget_tgs‚  s   &þzCCACHE.get_tgsNc           	      C   sz  dd„ |   ¡ D ƒ}t|ƒdkrd d tdƒfS |du rh|d u r0t d¡ |d d |d d d fS |d u rh|D ]\}}|d d	  t|ƒ¡d
krUt d| ¡ ||d f  S q6t d¡ |d d |d d d fS |D ]3\}}t|ƒd t|ƒ }d |d d	 ¡d |d  }| ¡ | ¡ kr�t d| ¡ ||d f  S qj|du r´t d¡ |d d |d d d fS d d td| ƒfS )Nc                 S   s   g | ]}|‘qS r   r   )rÖ   Úxr   r   r   r×   “  s    z"CCACHE.get_tgt.<locals>.<listcomp>r   zNo TGT found in CCACHE fileFz0Missing username, returning first availabla TGT!rW   ro   rV   r–   zFound TGT for user %sz>Missing domain, user not found, returning first availabla TGT!rÜ   r«   rn   z;domain+user combo not found, returning first availabla TGT!zNo TGT found for user %s)	r  r&   r  r   r›   rÿ   rå   rÙ   rš   )	r   ÚusernameÚdomainr  r  Útgtr  Úour_userr  r   r   r   Úget_tgt’  s4   
þ
þ
zCCACHE.get_tgtc                 C   s>   g }| j D ]}|jjdd� ¡  d¡dkr| | ¡ ¡ q|S )Nr«   r¬   rý   r–   )rï   rH   rr   rþ   rÿ   r*   rx   )r   r	  r  r   r   r   r  º  s   
€zCCACHE.get_all_tgsc                 C   s"   g }| j D ]	}| | ¡ ¡ q|S )zÄ
		Returns a list of hashes in hashcat-firendly format for tickets with encryption type 23 (which is RC4)
		all_hashes: overrides the encryption type filtering and returns hash for all tickets

		)rï   r*   rg   )r   Úhashesr  r   r   r   Ú
get_hashesÂ  s   
zCCACHE.get_hashesr,   c                 C   sâ   t dƒ}tj|  d¡ddd�|_tj|  d¡ddd�}t |  |¡¡|_t | ¡|_	|  
¡ }|  dd¡ |  
¡ }|  |d¡ |  
¡ |k rot | ¡}t|jjƒdkrc|jjd  ¡ dkrc|jj ¡ d	ksi|j |¡ |  
¡ |k sD|S )
NTr   r   Fr    r–   r   Úkrb5_ccache_conf_datazX-CACHECONF:)rì   r'   r(   r)   rí   r   r/   r-   r˜   rî   r%   ÚseekrF   r&   rH   rË   rr   rX   rï   r*   )r,   r    Úhdr_sizeÚposÚeofr  r   r   r   r/   Î  s    
$üzCCACHE.parsec                 C   sx   | j jdddd�}d}| jD ]}|| ¡ 7 }q|t|ƒjdddd�7 }||7 }|| j ¡ 7 }| jD ]}|| ¡ 7 }q1|S )Nr   r   Fr    rj   )rí   r1   r-   r&   rî   rï   )r   r3   Út_hdrrñ   r  r   r   r   r1   ç  s   

zCCACHE.to_bytesc                 c   s"   � | j D ]
}|j}| ¡ V  qd S r   )rï   rH   rÝ   )r   r  Útargetr   r   r   Úlist_targetsö  s
   €
þzCCACHE.list_targetsÚ	kirbidatac                 C   s2   t | tƒdu rt | ¡}n| }tƒ }| |¡ |S rè   )rä   r   r(   rì   rü   )r  r”   Úccr   r   r   r£   û  s   
zCCACHE.from_kirbiÚkirbi_filenamec                 C   st   t j | ¡}d }t|dƒ�}| ¡ }W d   ƒ n1 sw   Y  zt |¡}W |S    t |¡}t |¡}Y |S )NÚrb)	ÚosÚpathÚabspathÚopenr)   rì   r£   r   Úfrom_b64)r   Úkf_absr  ÚfÚccacher”   r   r   r   Úfrom_kirbifile  s   
ÿû
zCCACHE.from_kirbifilec                 C   sD   t ƒ }tj tj | ¡d¡}t |¡D ]}t |¡}| |¡ q|S )zk
		Iterates trough all .kirbi files in a given directory and converts all of them into one CCACHE object
		z*.kirbi)	rì   r"  r#  rÙ   r$  Úglobr   Ú	from_filerü   )Údirectory_pathr  Údir_pathr�   r”   r   r   r   Úfrom_kirbidir  s   
zCCACHE.from_kirbidirr-  c                 C   sP   t j |¡}| jD ]}| ¡ \}}d| dd¡ }t j ||¡}| |¡ q	dS )a  
		Converts all credential object in the CCACHE object to the kirbi file format used by mimikatz.
		The kirbi file format supports one credential per file, so prepare for a lot of files being generated.
		
		directory_path: str the directory to write the kirbi files to
		z%s.kirbiz..ú!N)r"  r#  r$  rï   r•   ÚreplacerÙ   Úto_file)r   r-  r'  r  r”   r�   Úfilepathr   r   r   Úto_kirbidir!  s   
üzCCACHE.to_kirbidirc                 C   s8   t | dƒ�}t |¡W  d  ƒ S 1 sw   Y  dS )z8
		Parses the ccache file and returns a CCACHE object
		r!  N)r%  rì   r/   )r�   r(  r   r   r   r,  /  s   $ÿzCCACHE.from_filec                 C   s>   t |dƒ�}| |  ¡ ¡ W d  ƒ dS 1 sw   Y  dS )z8
		Writes the contents of the CCACHE object to a file
		ÚwbN)r%  Úwriter1   )r   r�   r(  r   r   r   r2  7  s   "ÿzCCACHE.to_filec                 C   rC   r   )rì   r/   r#   r$   r4   r   r   r   r(   >  rD   zCCACHE.from_bytesc                 C   rC   r   )rì   r(   r:   Úfromhex)Úhexdatar   r   r   Úfrom_hexB  rD   zCCACHE.from_hexc                 C   s   |   ¡  ¡ S r   )r1   r`   r   r   r   r   Úto_hexF  s   zCCACHE.to_hexc                 C   s   t  |  ¡ ¡ d¡S )NÚascii)Úbase64Ú	b64encoder1   rá   r   r   r   r   Úto_b64I  s   zCCACHE.to_b64c                 C   rC   r   )rì   r(   r<  Ú	b64decode)Úb64datar   r   r   r&  L  rD   zCCACHE.from_b64)F)Trè   )%r6   r7   r8   Ú__doc__r   rð   r5   r÷   rû   r   rü   r  r  r   rë   r  r  r  r  r9   r#   r$   r/   r1   r  r£   rå   r*  r/  r4  r,  r2  r(   r9  r:  r>  r&  r   r   r   r   rì     sH    
	


(	



rì   ))r"  r#   rˆ   r+  r<  Útypingr   Ú"minikerberos.protocol.asn1_structsr   r   r   r   r   r   r	   r
   Úminikerberos.common.utilsr   Úminikerberos.protocol.constantsr   r   Úminikerberosr   Ú
asn1cryptor   Ú	unicryptor   Úminikerberos.common.kirbir   Úminikerberos.common.spnr   r   r;   rF   r�   rœ   r§   r¨   r˜   rž   rì   r   r   r   r   Ú<module>   s2    (% G)1?8