a
    W×a:  ã                   @   s¨   d dl mZ d dlmZ d dlmZmZ d dlmZm	Z	 d dlm
Z
 d dlZd dlmZ d dlZd dlZd dlZd dlZd dlmZ G dd	„ d	eƒZG d
d„ deƒZdS )é    )Úprint_function)ÚTestCaseInTempDir)ÚdnsÚdnsp)ÚgensecÚtests)ÚcredentialsN)Úbinary_typec                       sŽ   e Zd Z‡ fdd„Zdd„ Zdd„ Zdd„ Zd	d
„ Zddd„Zdd„ Z	dd„ Z
dd„ Zdd„ Zd dd„Zd!dd„Zd"dd„Zd#dd„Z‡  ZS )$ÚDNSTestc                    s   t t| ƒ ¡  d | _d S ©N)Úsuperr
   ÚsetUpÚtimeout©Úself©Ú	__class__© ú6/usr/lib/python3/dist-packages/samba/tests/dns_base.pyr   #   s    zDNSTest.setUpc                 C   s   g d¢}|| S )zReturn a readable error code)ZOKZFORMERRZSERVFAILZNXDOMAINZNOTIMPZREFUSEDZYXDOMAINZYXRRSETZNXRRSETZNOTAUTHZNOTZONEZ0x0BZ0x0CZ0x0DZ0x0EZ0x0FZBADSIGZBADKEYr   )r   ZerrcodeZstring_codesr   r   r   Úerrstr'   s    zDNSTest.errstrc              	   C   s&   |   ||d|  |¡|  |¡f ¡ dS ©z$Helper function to check return codezExpected RCODE %s, got %sN)ÚassertEqualr   )r   ÚrcodeZexpectedr   r   r   Úassert_rcode_equals@   s    
ÿzDNSTest.assert_rcode_equalsc              	   C   s2   |j tj@ }|  ||d|  |¡|  |¡f ¡ dS r   )Ú	operationr   Z	DNS_RCODEr   r   )r   Úpacketr   Z	p_errcoder   r   r   Úassert_dns_rcode_equalsE   s    
ÿzDNSTest.assert_dns_rcode_equalsc                 C   s&   |j tj@ }|  ||d||f ¡ dS )zHelper function to check opcodezExpected OPCODE %s, got %sN)r   r   Z
DNS_OPCODEr   )r   r   ÚopcodeZp_opcoder   r   r   Úassert_dns_opcode_equalsK   s    
ÿz DNSTest.assert_dns_opcode_equalsNc                 C   s4   t  ¡ }|du rt dd¡|_||_g |_g |_|S )z!Helper creating a dns.name_packetNr   i ÿ  )r   Úname_packetÚrandomZrandintÚidr   Ú	questionsÚ
additional)r   r   ZqidÚpr   r   r   Úmake_name_packetQ   s    zDNSTest.make_name_packetc                 C   s   t |ƒ|_||_dS )z$Helper to finalize a dns.name_packetN)ÚlenZqdcountr"   )r   r   r"   r   r   r   Úfinish_name_packet[   s    
zDNSTest.finish_name_packetc                 C   s   t  ¡ }||_||_||_|S )z#Helper creating a dns.name_question)r   Zname_questionÚnameZquestion_typeZquestion_class)r   r(   ZqtypeZqclassÚqr   r   r   Úmake_name_question`   s
    zDNSTest.make_name_questionc                 C   s*   t  ¡ }t ¡ }t|ƒ|_||_||_|S r   )r   Z
txt_recordr   Zstring_listr&   ÚcountÚstrÚtxt)r   ZrecordsZ	rdata_txtZs_listr   r   r   Úmake_txt_recordh   s    
zDNSTest.make_txt_recordc                 C   s   | j  ¡  ¡ S )zHelper to get dns domain)ÚcredsZ	get_realmÚlowerr   r   r   r   Úget_dns_domainp   s    zDNSTest.get_dns_domainFc           	      C   sÄ   d}|du r| j }zšt |¡}|r0t|  |¡ƒ t tjtjd¡}| |¡ | 	|df¡ | 
|d¡ | dd¡}|r„t|  |¡ƒ t tj|¡}||fW |durª| ¡  S n|dur¾| ¡  0 dS )z#send a DNS query and read the replyNr   é5   i   )r   ÚndrÚndr_packÚprintÚhexdumpÚsocketÚAF_INETZ
SOCK_DGRAMÚ
settimeoutÚconnectÚsendallÚrecvÚ
ndr_unpackr   r   Úclose)	r   r   ÚhostÚdumpr   ÚsÚsend_packetÚrecv_packetÚresponser   r   r   Údns_transaction_udpt   s.    

ý ÿzDNSTest.dns_transaction_udpc                 C   s  d}|du r| j }z°t |¡}|r0t|  |¡ƒ t tjtjd¡}| |¡ | 	|df¡ t
 dt|ƒ¡}||7 }| |¡ | dd¡}|ršt|  |¡ƒ t tj|dd… ¡}	W |durÖ| ¡  n|durÔ| ¡  0 t |	¡}
|  |
|dd… ¡ |	|dd… fS )z?send a DNS query and read the reply, also return the raw packetNr   r2   z!Hi  é   )r   r3   r4   r5   r6   r7   r8   ZSOCK_STREAMr9   r:   ÚstructZpackr&   r;   r<   r=   r   r   r>   r   )r   r   r?   r@   r   rA   rB   Z
tcp_packetrC   rD   Z	my_packetr   r   r   Údns_transaction_tcp‹   s0    



ÿ

zDNSTest.dns_transaction_tcpc           
      C   s¨   |   tj¡}g }|p|  ¡ }|  |tjtj¡}| |¡ |  ||¡ g }t 	¡ }d||f |_
tj|_tj|_d|_d|_|  |¡}	|	|_| |¡ t|ƒ|_||_|S )Nú%s.%sé„  éÿÿ  )r%   r   ÚDNS_OPCODE_UPDATEr1   r*   ÚDNS_QTYPE_SOAÚDNS_QCLASS_INÚappendr'   Úres_recr(   ÚDNS_QTYPE_TXTÚrr_typeÚrr_classÚttlÚlengthr.   Úrdatar&   ÚnscountÚnsrecs)
r   ÚprefixÚ	txt_arrayZdomainr$   Úupdatesr(   ÚuÚrrV   r   r   r   Úmake_txt_updateª   s&    



zDNSTest.make_txt_updatec           
      C   s˜   d||p|   ¡ f }|  tj¡}g }|  |tjtj¡}| |¡ |  ||¡ | j	|| j
d\}}	|  |tj¡ |  |jd¡ |  |jd jjj|¡ d S )NrI   )r?   é   r   )r1   r%   r   ÚDNS_OPCODE_QUERYr*   rQ   rN   rO   r'   rE   Ú	server_ipr   ÚDNS_RCODE_OKr   ZancountÚanswersrV   r-   r,   )
r   rY   rZ   Zzoner(   r$   r"   r)   rD   Úresponse_packetr   r   r   Úcheck_query_txtÂ   s    
ÿzDNSTest.check_query_txt)N)FN)FN)N)N)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r%   r'   r*   r.   r1   rE   rH   r^   re   Ú__classcell__r   r   r   r   r
   !   s    

 ÿ
 ÿ

r
   c                       sR   e Zd Z‡ fdd„Zddd„Zddd„Zd	d
„ Zdd„ Zdd„ Zddd„Z	‡  Z
S )ÚDNSTKeyTestc                    s   t t| ƒ ¡  i | _t ¡  | jd< | _| j| jd< t 	¡ | _
| j
 | j¡ | j
 t d¡¡ | j
 t d¡¡ | j
 tj¡ d|  ¡  | _d S )NÚlp_ctxZtarget_hostnameZUSERNAMEZPASSWORDztkeytsig.%s)r   rj   r   Úsettingsr   Zenv_loadparmrk   Úserverr   ZCredentialsr/   ZguessZset_usernameZenv_get_var_valueZset_passwordZset_kerberos_stateZMUST_USE_KERBEROSr1   Ú
newrecnamer   r   r   r   r   Ó   s    
zDNSTKeyTest.setUpNc                 C   sÜ  |du r| j }dt ¡ |  ¡ f | _|  tj¡}|  | jtj	tj
¡}g }| |¡ |  ||¡ t ¡ }| j|_tj	|_tj
|_d|_d|_t ¡ }d|_tt ¡ ƒ|_tt ¡ ƒd |_tj|_d|_d|_tj | j ¡| _!| j! "|¡ | j! #d¡ | j! $| j%¡ | j! &tj'¡ | j! (d¡ d	}d
}| j! )|¡\}}	|  *|¡ dd„ t+|	ƒD ƒ}
|
|_,t-|
ƒ|_.||_/|g}d|_0||_1|  2|| j3¡\}}|  4|tj5¡ |j6d j/}t7t8|j,ƒƒ}	| j! )|	¡\}}|  9|¡ |  :||¡ dS )z4Do a TKEY transaction and establish a gensec contextNrI   r   rK   úgss-tsigi  r   ZspnegoFó    c                 S   s"   g | ]}t |tƒr|nt|ƒ‘qS r   ©Ú
isinstanceÚintÚord©Ú.0Úxr   r   r   Ú
<listcomp>  rp   z*DNSTKeyTest.tkey_trans.<locals>.<listcomp>r_   );r/   ÚuuidZuuid4r1   Úkey_namer%   r   r`   r*   ZDNS_QTYPE_TKEYrN   rO   r'   rP   r(   rR   rS   rT   rU   Útkey_recordÚ	algorithmrs   ÚtimeZ	inceptionZ
expirationZDNS_TKEY_MODE_GSSAPIÚmodeÚerrorÚ
other_sizer   ZSecurityZstart_clientrl   ÚgZset_credentialsZset_target_serviceZset_target_hostnamerm   Zwant_featureZFEATURE_SIGNZstart_mech_by_nameÚupdateZassertFalseÚlistZkey_datar&   Zkey_sizerV   Úarcountr#   rH   ra   r   rb   rc   r	   Ú	bytearrayZ
assertTrueÚverify_packet)r   r/   r$   r)   r"   r]   rV   ZfinishedZclient_to_serverZserver_to_clientÚdatar#   rD   rd   r{   r   r   r   Ú
tkey_transà   sb    þ


ÿ
zDNSTKeyTest.tkey_transrp   c                 C   s  |   |jd jtj¡ |jd j}tt|jƒƒ}t	| j
ƒd }t	t |¡ƒ| d }dd„ |D ƒ}|| d …= t|d tƒr†d|d< ntdƒ|d< tt|ƒƒ}	t ¡ }
| j
|
_tj|
_d|
_|j|
_|j|
_|j|
_|j|
_d|
_d|
_t |
¡}||	 | }| j |||¡ d S )Nr   rF   é
   c                 S   s"   g | ]}t |tƒr|nt|ƒ‘qS r   rq   ru   r   r   r   rx   ,  rp   z-DNSTKeyTest.verify_packet.<locals>.<listcomp>é   )r   r#   rR   r   ÚDNS_QTYPE_TSIGrV   r	   r…   Úmacr&   rz   r3   r4   rr   rs   ÚchrÚfake_tsig_recr(   ÚDNS_QCLASS_ANYrS   rT   Útime_prefixr}   Úalgorithm_nameÚfudger   r€   r   Zcheck_packet)r   rD   rd   Zrequest_macÚtsig_recordrŒ   Zkey_name_lenZtsig_record_lenZresponse_packet_listZresponse_packet_wo_tsigÚ	fake_tsigÚfake_tsig_packetr‡   r   r   r   r†     s0    

zDNSTKeyTest.verify_packetc                 C   s  t  |¡}t ¡ }||_tj|_d|_d|_t	t
 
¡ ƒ|_
d|_d|_d|_d|_t  |¡}|| }| j ||¡}dd„ t|ƒD ƒ}t ¡ }	d|	_d|	_|j
|	_
d|	_|j|	_d|	_d|	_||	_t|ƒ|	_t ¡ }
||
_tj|
_tj|
_d|
_d|
_|	|
_|
g}||_d|_|S )z2Sign a packet, calculate a MAC and add TSIG recordr   ro   é,  c                 S   s"   g | ]}t |tƒr|nt|ƒ‘qS r   rq   ru   r   r   r   rx   W  rp   z+DNSTKeyTest.sign_packet.<locals>.<listcomp>rK   r_   )r3   r4   r   rŽ   r(   r   rS   rT   r   rs   r}   r‘   r’   r   r€   r   Úsign_packetrƒ   r“   r!   Úoriginal_idrŒ   r&   Úmac_sizerP   r‹   rR   rU   rV   r#   r„   )r   r   rz   Zpacket_datar”   r•   r‡   rŒ   Úmac_listrV   r]   r#   r   r   r   r—   E  sH    


zDNSTKeyTest.sign_packetc                 C   s¤   dd„ t dƒD ƒ}t ¡ }d|_d|_tt ¡ ƒ|_d|_|j|_	d|_
d|_||_t|ƒ|_t ¡ }||_tj|_tj|_d|_d|_||_|g}||_d|_d	S )
zOAdd bad signature for a packet by bitflipping
        the final byte in the MACc                 S   s"   g | ]}t |tƒr|nt|ƒ‘qS r   rq   ru   r   r   r   rx   v  rp   z/DNSTKeyTest.bad_sign_packet.<locals>.<listcomp>Zbadmacro   r   r–   rK   r_   N)rƒ   r   r“   r‘   r   rs   r}   r’   r!   r˜   r   r€   rŒ   r&   r™   rP   r(   r‹   rR   r   rS   rT   rU   rV   r#   r„   )r   r   rz   rš   rV   r]   r#   r   r   r   Úbad_sign_packetr  s*    
zDNSTKeyTest.bad_sign_packetc                 C   sT   |   tj¡}g }|  |tjtj¡}| |¡ |  ||¡ |  || j	¡\}}|j
d@ S )Né   )r%   r   r`   r*   rQ   rN   rO   r'   rE   ra   r   )r   r(   r$   r"   r)   rD   rd   r   r   r   Úsearch_record  s    
ÿzDNSTKeyTest.search_recordFc           
      C   s²   t j}d}|rt j}d}|  t j¡}|  |  ¡ t jt j¡}g }| |¡ |  	||¡ g }t  
¡ }| j|_t j|_||_||_d|_|  dg¡}	|	|_| |¡ t|ƒ|_||_|S )zCreate a DNS update requestrJ   r   rK   z"This is a test")r   rN   ZDNS_QCLASS_NONEr%   rL   r*   r1   rM   rO   r'   rP   rn   r(   rQ   rR   rS   rT   rU   r.   rV   r&   rW   rX   )
r   ÚdeleterS   rT   r$   r)   r"   r[   r]   rV   r   r   r   Úmake_update_request›  s4    
þ


zDNSTKeyTest.make_update_request)N)rp   )F)rf   rg   rh   r   rˆ   r†   r—   r›   r   rŸ   ri   r   r   r   r   rj   Ò   s   
?
&-rj   )Z
__future__r   Zsamba.testsr   Zsamba.dcerpcr   r   Zsambar   r   r   rG   Z	samba.ndrr3   r    r7   ry   r}   Zsamba.compatr	   r
   rj   r   r   r   r   Ú<module>   s    2