grthtrhthjhtyjytjytkergtrhtrjytjerhrfh3 «Ú²j+ã@sXddlmZddlZddlZddlZddlZddlZddlZddlZGdd„de ƒZ dS)é)Ú OrderedDictNc@sleZdZdZdddddddœZd d „Zd d „Zddd„Zdd„Zdd„Z dd„Z dd„Z dd„Z dd„Z dS)ÚrndczRNDC protocol client libraryé�é¡é¢é£é¤é¥)Úmd5Zsha1Zsha224Zsha256Zsha384Zsha512cCsb||_|jƒ}|jdƒr$|dd…}||_tt|ƒ|_tj|ƒ|_ t j ddƒ|_ d|_ |jƒdS)zþCreates a persistent connection to RNDC and logs in host - (ip, port) tuple algo - HMAC algorithm: one of md5, sha1, sha224, sha256, sha384, sha512 (with optional prefix 'hmac-') secret - HMAC secret, base64 encodedzhmac-éNrééi)ÚhostÚlowerÚ startswithÚalgoÚgetattrÚhashlibÚhlalgoÚbase64Ú b64decodeÚsecretÚrandomZrandintÚserÚnonceÚ_rndc__connect_login)Úselfrrr©rú/usr/lib/python3.6/rndc.pyÚ__init__$s    z rndc.__init__cCst|j|d�dƒS)z’Call a RNDC command, all parsing is done on the server side cmd - a complete string with a command (eg 'reload zone example.com') )ÚtypeÚ_data)ÚdictÚ_rndc__command)rÚcmdrrrÚcall5sz rndc.callFcCstƒ}�x|jƒD]ô\}}|r(|dkr(q|tjdt|ƒƒ|jdƒ7}t|ƒtkrt|tjddt|ƒƒ|jdƒ7}qt|ƒtkrœ|tjddt|ƒƒ|7}qt|ƒtkrÄ|tjddt|ƒƒ|7}qt|ƒt krö|j |ƒ}|tjddt|ƒƒ|7}qt dt|ƒƒ‚qW|S)NÚ_authÚBÚasciiz>BIr éz#Cannot serialize element of type %s) Ú bytearrayÚitemsÚstructÚpackÚlenÚencoder ÚstrÚbytesrÚ_rndc__serialize_dictÚNotImplementedError)rÚdataÚ ignore_authÚrvÚkÚvZsdrrrZ__serialize_dict;s"  "    zrndc.__serialize_dictc Os,|jd7_ttjƒƒ}t||Ž}tƒ}tƒ|d<tƒ|d<t|jƒ|dd<t|ƒ|dd<t|dƒ|dd<|jdk rŒ|j|dd<||d <|j|d d �}tj|j ||j ƒj ƒ}t j |ƒ}|jd krâtjd |ƒ|dd<n"ttjd|j|j|ƒƒ|dd<|j|ƒ}tjdt|ƒddƒ|}|S)Nr r&Ú_ctrlZ_serZ_timé<Z_expÚ_noncer!T)r5r Z22sÚhmd5ZB88sÚhshaz>IIé)rÚintÚtimerr0rr2ÚhmacÚnewrrÚdigestrZ b64encoderr,r-r*Ú _rndc__algosr.) rÚargsÚkwargsZnowr4ÚdÚmsgÚhashÚbhashrrrZ__prep_messageOs,        zrndc.__prep_messagecCs°|jdk r |dd|jkr dS|jdkr8|dd}n|dddd…}t|ƒtkrb|jd ƒ}|d d t|ƒd 7}tj|ƒ}|j|d d �}t j |j ||j ƒj ƒ}||kS)Nr9r;Fr r&r<r=r r(ú=r>T)r5)rrr r1Údecoder.rrr2rArBrrrC)rrHrJZ remote_hashZmy_msgZmy_hashrrrZ __verify_msgjs    zrndc.__verify_msgc OsÐ|j||Ž}|jj|ƒ}|t|ƒkr,tdƒ‚|jjdƒ}t|ƒdkrLtdƒ‚tjd|ƒ\}}|dkrptd|ƒ‚|d8}|jj|tj ƒ}t|ƒ|krœtdƒ‚t |ƒt kr°t |ƒ}|j |ƒ}|j|ƒsÌtd ƒ‚|S) NzCannot send the messageézCan't read response headerz>IIr zWrong message version %dr>zCan't read response datazAuthentication failure)Ú_rndc__prep_messageÚsocketÚsendr.ÚIOErrorZrecvr,Úunpackr3Z MSG_WAITALLr r0r*Ú_rndc__parse_messageÚ_rndc__verify_msg) rrErFrHZsentÚheaderZlengthÚversionr4rrrZ __commandys(          zrndc.__commandcCs2tj|jƒ|_d|_|jdd�}|dd|_dS)NZnull)r r9r;)rOZcreate_connectionrrr#)rrHrrrZ__connect_login–s zrndc.__connect_loginc Csîd}||}|d7}||||…jdƒ}||7}||}|d7}tjd|||d…ƒd}|d7}||||…}||7}||d…}|dkrœ|||fS|dkrÞtƒ} x(t|ƒdkrÒ|j|ƒ\} } }| | | <q¬W|| |fStd|ƒ‚dS)Nrr r(z>Ir>r)zUnknown element type %d)rLr,rRrr.Ú_rndc__parse_elementr3) rÚinputÚposZlabellenÚlabelr Zdatalenr4ÚrestrGZilabelÚvaluerrrZ__parse_elementœs*    zrndc.__parse_elementcCs8tƒ}d}x(t|ƒdkr2|j|ƒ\}}}|||<q W|S)Nr)rr.rW)rrXr6ZhdatarZr\rrrZ__parse_message¶s  zrndc.__parse_messageN)F)Ú__name__Ú __module__Ú __qualname__Ú__doc__rDrr%r2rNrTr#rrWrSrrrrrs  r) Ú collectionsrr@r,rrArrrOÚobjectrrrrrÚs