m
Dc           @   s  d  Z  d k Z d k Z d k Z d k Z d k Z d k Z d k Z d d d d d d d d	 d
 d d d g Z d f  d     YZ	 d f  d     YZ
 e	 d d d d d d d d d d d d d d d d  d! d" d# d$ d% d& g  Z e i d' j p t  e i d( j p t  e	 d) d* d+ d, d- d. d/ d0 d1 d2 d3 d4 g  Z e i d5 j p t  e i d6 j p t  e	 d d7 d8 d9 d: d; g  Z e	 d d< d= d> d: d; d? d@ dA g  Z e	 d d7 dB d: d; g  Z e
 dC d) dD dE dF dG dH dI dJ dK  Z h  d dL <d) dM <dE dN <dO dP <dQ dR <d6 dS <dT dU <dV dW <d' dX <dY dZ <dG d[ <d5 d\ <dI d] <Z d^   Z d_   Z d`   Z da   Z db   Z dc dd  Z de df dg  Z dh   Z d e i f di     YZ  d S(j   sR   
TorCtl0 -- Library to control Tor processes.  See TorCtlDemo.py for example use.
Nt   MSG_TYPEt
   EVENT_TYPEt   CIRC_STATUSt   STREAM_STATUSt   OR_CONN_STATUSt   SIGNALt	   ERR_CODESt   TorCtlErrort   ProtocolErrort
   ErrorReplyt
   Connectiont   EventHandlert   _Enumc           B   s   t  Z d   Z RS(   Nc         C   sK   h  |  _ | } x5 | D]- } t |  | |  | |  i | <| d 7} q Wd  S(   Ni   (   t   selft   nameOft   startt   idxt   namest   namet   setattr(   R   R   R   R   R   (    (    t,   /home/brian/downloads/tor/blossom/TorCtl0.pyt   __init__   s    	 (   t   __name__t
   __module__R   (    (    (    R   R      s   t   _Enum2c           B   s   t  Z d   Z RS(   Nc         K   sG   |  i i |  h  |  _ x' | i   D] \ } } | |  i | <q& Wd  S(   N(   R   t   __dict__t   updatet   argsR   t   itemst   kt   v(   R   R   R   R   (    (    R   R   $   s
    	 (   R   R   R   (    (    (    R   R   "   s   i    t   ERRORt   DONEt   SETCONFt   GETCONFt	   CONFVALUEt	   SETEVENTSt   EVENTt   AUTHt   SAVECONFt
   MAPADDRESSt   GETINFOt	   INFOVALUEt   EXTENDCIRCUITt   ATTACHSTREAMt   POSTDESCRIPTORt   FRAGMENTHEADERt   FRAGMENTt   REDIRECTSTREAMt   CLOSESTREAMt   CLOSECIRCUITi   i   i   t
   CIRCSTATUSt   STREAMSTATUSt   ORCONNSTATUSt	   BANDWIDTHt   OBSOLETE_LOGt   NEWDESCt	   DEBUG_MSGt   INFO_MSGt
   NOTICE_MSGt   WARN_MSGt   ERR_MSGi   i   t   LAUNCHEDt   BUILTt   EXTENDEDt   FAILEDt   CLOSEDt   SENT_CONNECTt   SENT_RESOLVEt	   SUCCEEDEDt   NEW_CONNECTt   NEW_RESOLVEt   DETACHEDt	   CONNECTEDt   HUPt   INTi   t   USR1i
   t   USR2i   t   TERMi   s   Unspecified errors   Internal errors   Unrecognized message typei   s   Syntax errori   s   Unrecognized configuration keys   Invalid configuration valuei   s   Unrecognized byte codei   t   Unauthorizeds   Failed authentication attempti	   s   Resource exhausteds   No such streams   No such circuits
   No such ORc         C   s   t  |   d j  o d d |  f Sn t i d |   \ } } t  |   d | j o$ | |  d d | !|  d | f Sn d d | |  f Sd S(   s   Helper: unpack a single packet.  Return (None, minLength, body-so-far)
       on incomplete packet or (type,body,rest) on somplete packet
    i   s   !HHN(   t   lent   msgt   Nonet   structt   unpackt   lengtht   type(   RQ   RU   RV   (    (    R   t   _unpack_singleton_msg   s     $c         C   sD   t  |  d  \ } } | o | d d d | Sn | d d Sd S(   sC   Return the minimum number of bytes needed to pack the message 'smg'i  i   N(   t   divmodt   bytest   wholet   left(   RY   RZ   R[   (    (    R   t   _minLengthToPack   s
     c         C   s  t  |   \ }	 } } |	 t i j o |	 | | f Sn t |  d j  o t d   n t	 i
 d | d   \ } } t | d  } t |   | j  o d
 | |  f Sn | d g } t |  d }
 x t |  d j o | | j  o t	 i
 d | d   \ } }	 |	 t i j o t d   n | i | d d | ! | | 7} d | t |  j o d } d | t |  } q | d | } d } q W| | j o | d i |  | f SnS | | j o t d	   n6 | | | } t |  } d
 t |   | | |  f Sd
 S(   s$   returns as for _unpack_singleton_msgi   s    FRAGMENTHEADER message too shorts   !HLi   s   !HHs   Missing FRAGMENT messaget    i    s/   Bad fragmentation: message longer than declaredN(   RW   RQ   t   tpt   bodyt   restR    R.   RP   R   RS   RT   t   realTypet
   realLengthR\   t	   minLengthRR   t   soFart   lenSoFarLent   lenSoFart   lnR/   t   appendt   leftInPackett   joint   inOtherPackets(   RQ   R_   Rd   Ra   Rg   Rc   Rb   Ri   R`   R^   Re   Rk   Rf   (    (    R   t   _unpack_msg   s>       
c         C   s   d } |  i d  } | p t i    n t i d |  \ } } | oY xV | t
 |  j o> |  i | t
 |   } | p t i    n | | 7} qN Wn | | | f S(   s,   Read a single packet from the socket s.
    R]   i   s   !HHN(   R_   t   st   recvt   headert   TorCtlt   TorCtlClosedRS   RT   RU   RV   RP   t   more(   Rm   R_   RV   RU   Ro   Rr   (    (    R   t   _receive_singleton_msg   s      c         C   s(  t  |   \ } } } | t i j o | | | f Sn | d j  o t d   n t i	 d | d   \ } } | d g } t | d  } x t  |   \ } } } | t i j o t d   n | | 7} | i |  | | j o | | d i |  f Sq | | j o t d   q q Wd	 S(
   s@   Read a single message (possibly multi-packet) from the socket s.i   s    FRAGMENTHEADER message too shorts   !HLi    i   s   Missing FRAGMENT messageR]   s   FRAGMENT message too long!N(   Rs   Rm   RU   R^   R_   R    R.   R   RS   RT   Ra   Rb   t   dataRP   Rd   R/   Rh   Rj   (   Rm   R_   Ra   Rb   RU   R^   Rd   Rt   (    (    R   t   _receive_message   s(       
R]   c         C   s  t  |  } | d j  o' t i d | |   } d | | f Sn t i d d t i |  |  } | | d d  g } | d d } xu | om t  |  d j o
 d } n t  |  } t i d t i |  } | i |  | i | |   | | } q Wd i |  S(	   s^   Given a message type and optional message body, generate a set of
       packets to send.
    i   s   !HHs   %s%ss   !HHHLi  i   R]   N(   RP   R_   RU   RS   t   packRV   t	   reqheaderR    R.   t
   fragheadert   msgst   flR/   Rh   Rj   (   RV   R_   Rw   Rx   RU   Rz   Ry   (    (    R   t   pack_message   s&     	 
t    s   
c         C   s]   g  } xP |  i |  D]? } | p q n | i | d  \ } } | i | | f  q W| S(   sa   Helper: parse a key/value list of the form [key sep value term]* .
       Return a list of (k,v).i   N(	   t   resR_   t   splitt   termt   linet   sepR   R   Rh   (   R_   R   R   R}   R   R   R   (    (    R   t   _parseKV   s       c         C   s%   |  d d j o |  d  Sn |  Sd S(   s%   Strip trailing NUL characters from s.it    N(   Rm   (   Rm   (    (    R   t   _unterminate	  s     c           B   s   t  Z d  Z d   Z d   Z d   Z d   Z d e i f d  Z	 d d  Z
 d   Z d	   Z d
   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d f  d  Z f  d  Z d   Z RS(   s8   A Connection represents a connection to the Tor process.c         C   s   t  i i |   | |  _ d S(   sc   Create a Connection to communicate with the Tor process over the
           socket 'sock'.
        N(   Rp   t   _ConnectionBaseR   R   t   sockt   _s(   R   R   (    (    R   R     s     c         C   s   | |  _ | i |  _ d S(   sJ   Cause future events from the Tor process to be sent to 'handler'.
        N(   t   handlerR   t   _handlert   handle0t	   _handleFn(   R   R   (    (    R   t   set_event_handler  s     	c         C   s)   | \ } } |  i i t | |   d S(   sI   Helper: Deliver a command of type 'type' and body 'body' to Tor.
        N(   RV   R_   R   R   t   sendallR{   (   R   t   .2RV   R_   (    (    R   t   _doSend  s    c         C   s1   t  |  i  \ } } } | t i j | | f f S(   N(   Ru   R   R   RU   R^   R_   R    R%   (   R   R_   R^   RU   (    (    R   t   _read_reply$  s    R]   c         C   s   |  i |  i | | f  \ } } | | j o | | f Sn | t i j oe t |  d j  o t	 d   n t
 i d | d   \ } t | t i | d  | d f   n t	 d |   d S(   s  Helper: Send a command of type 'tp' and body 'msg' to Tor,
           and wait for a command in response.  If the response type is
           in expectedTypes, return a (tp,body) tuple.  If it is an error,
           raise ErrorReply.  Otherwise, raise ProtocolError.
        i   s   (Truncated error message)s   !Hs   [unrecognized]s   Unexpectd message type 0x%04xN(   R   t   sendImplR   R^   RQ   t   expectedTypesR    R   RP   R   RS   RT   t   errCodeR	   R   t   get(   R   R^   RQ   R   R   (    (    R   t   _sendAndRecv(  s     !)c         C   s   |  i t i |  d S(   s   Send an authenticating secret to Tor.  You'll need to call
           this method before other commands.  You need to use a
           password if Tor expects one.
        N(   R   R   R    R&   t   secret(   R   R   (    (    R   t   authenticate<  s     c         C   sp   t  | t  p2 d i g  } | D] } | d | q! ~  } n |  i t i	 | t i
 g  \ } } t |  S(   s   Get the value of the configuration option named 'name'.  To
           retrieve multiple values, pass a list for 'name' instead of
           a string.  Returns a list of (key,value) pairs.
        R]   s   %s
N(   t
   isinstanceR   t   strRj   t   _[1]Rm   R   R   R    R"   R#   R^   R_   R   (   R   R   R_   R^   R   Rm   (    (    R   t
   get_optionC  s
     2$c         C   s   |  i | | g  d S(   sY   Set the value of the configuration option 'key' to the
           value 'value'.
        N(   R   t   set_optionst   keyt   value(   R   R   R   (    (    R   t
   set_optionM  s     c         C   sG   d i  g  } | D] \ } } | d q ~  } |  i t i	 |  d S(   sY   Given a list of (key,value) pairs, set them as configuration
           options.
        R]   s   %s %s
N(
   Rj   R   t   kvlistR   R   RQ   R   R   R    R!   (   R   R   R   R   RQ   R   (    (    R   R   S  s     0c         C   sA   d i  g  } | D] } | d q ~  } |  i t i |  d  S(   NR]   s   %s
(	   Rj   R   t   keylistR   RQ   R   R   R    R!   (   R   R   R   RQ   R   (    (    R   t   reset_optionsZ  s    *c   	      C   s   t  | t  p2 d i g  } | D] } | d | q! ~  } n |  i t i	 | t i
 g  \ } } | i d  } h  } x: t d t |  d d  D] } | | d | | | <q W| S(   s   Return the value of the internal information field named
           'name'.  To retrieve multiple values, pass a list for
           'name' instead of a string.  Returns a dictionary of
           key->value mappings.
        R]   s   %s
R   i    i   i   N(   R   R   R   Rj   R   Rm   R   R   R    R)   R*   R^   R_   R~   t   kvst   dt   xrangeRP   t   i(	   R   R   R_   R   R^   R   Rm   R   R   (    (    R   t   get_info^  s     2$ c      	   C   s   g  } xN | D]F } t | t i  o  | i t t | i	     q | i |  q W|  i t i d i g  } | D] } | t i d |  qt ~   d S(   s   Change the list of events that the event handler is interested
           in to those in 'events', which is a list of EVENT_TYPE members
           or their corresponding strings.
        R]   s   !HN(   t   evst   eventst   evR   t   typest
   StringTypeRh   t   getattrR   t   upperR   R   R    R$   Rj   R   t   eventRS   Rv   (   R   R   R   R   R   R   (    (    R   t
   set_eventsm  s       c         C   s   |  i t i  d S(   s1   Flush all configuration changes to disk.
        N(   R   R   R    R'   (   R   (    (    R   t	   save_conf{  s     c         C   s   y | i   } Wn t j
 o n Xh  d d <d d <d d <d d <d d <d	 d <d
 d <d d <d d <d d <i | |  } |  i t i t i	 d |   d S(   sy   Send the signal 'sig' to the Tor process; 'sig' must be a member of
           SIGNAL or a corresponding string.
        RJ   i   t   RELOADRK   i   t   SHUTDOWNt   DUMPi
   RL   RM   i   t   DEBUGRN   i   t   HALTt   BN(
   t   sigR   t   AttributeErrorR   R   R   R    R   RS   Rv   (   R   R   (    (    R   t   send_signal  s     lc         C   s_   g  } | D] \ } } | d | | f q ~ } |  i t i d i	 |   \ } } t |  S(   s   Given a list of (old-address,new-address), have Tor redirect
           streams from old-address to new-address.  Old-address can be in a
           special "dont-care" form of "0.0.0.0" or ".".
        s   %s %s
R]   N(   R   t   kvListR   R   RQ   R   R   R    R(   Rj   R^   R_   R   (   R   R   R_   R^   R   R   RQ   R   (    (    R   t   map_address  s     1$c         C   s{   t  i d t |   d i |  d } |  i t	 i
 |  \ } } t |  d j o t d   n t  i d |  d S(   sw   Tell Tor to extend the circuit identified by 'circid' through the
           servers named in the list "hops".
        s   !Lt   ,R   i   s%   Extendcircuit reply too short or longi    N(   RS   Rv   t   longt   circidRj   t   hopsRQ   R   R   R    R+   R^   R_   RP   R   RT   (   R   R   R   R_   R^   RQ   (    (    R   t   extend_circuit  s     )c         C   s7   t  i d t |   | d } |  i t i	 |  d S(   sz   Tell Tor to change the target address of the stream identified by
           'streamid' from its old value to 'newtarget'.s   !LR   N(
   RS   Rv   R   t   streamidt	   newtargetRQ   R   R   R    R0   (   R   R   R   RQ   (    (    R   t   redirect_stream  s      c         C   s8   t  i d t |  t |   } |  i t i	 |  d S(   s9   Tell Tor To attach stream 'streamid' to circuit 'circid'.s   !LLN(
   RS   Rv   R   R   R   RQ   R   R   R    R,   (   R   R   R   RQ   (    (    R   t   attach_stream  s     !i    c         C   s5   t  i d t |  | |  } |  i t	 i
 |  d S(   s   Close the stream 'streamid'. s   !LBBN(   RS   Rv   R   R   t   reasont   flagsRQ   R   R   R    R1   (   R   R   R   R   RQ   (    (    R   t   close_stream  s     c         C   sO   d | j o
 d } n d } t i d t |  |  } |  i t i	 |  d S(   s   Close the circuit 'circid'.t   IFUNUSEDi   i    s   !LBN(
   R   RS   Rv   R   R   RQ   R   R   R    R2   (   R   R   R   RQ   (    (    R   t   close_circuit  s     
c         C   s   |  i t i |  d S(   s0   Tell Tor about a new descriptor in 'descriptor'.N(   R   R   R    R-   t
   descriptor(   R   R   (    (    R   t   post_descriptor  s     (   R   R   t   __doc__R   R   R   R   R    R    R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   R   (    (    (    R   R
     s,    					
										
			(!   R   t   binasciit   ost   shat   socketRS   t   sysRp   t   __all__R   R   R    R'   t   AssertionErrorR2   R   R=   R7   R   R   R   R   R   RW   R\   Rl   Rs   Ru   R{   R   R   R   R
   (   R   R   R   R   R   RS   R   R   R   R   R{   Ru   R   R   Rl   R   R
   R   RW   Rp   R   R    R   R\   Rs   R   (    (    R   t   ?   sF   							*
	H*!
'{			)		
	