
    hj                        d Z ddl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	m
Z
mZmZmZmZmZmZmZmZ ddlmZmZ dZdZej.                  Zej2                  Zej6                  Zej:                  ej<                  ej>                  ej@                  ejB                  ejD                  ejF                  fZ$ejJ                  ejL                  ejN                  ejP                  ejR                  ejT                  ejV                  fZ, G d d	e-      Z. G d
 de.      Z/ G d de.      Z0 G d de/      Z1 G d de/      Z2 G d de/      Z3 G d de/      Z4 G d de/      Z5 G d de/      Z6 G d de.      Z7 G d de.      Z8 G d de/      Z9 G d  d!e/      Z: G d" d#e.      Z; G d$ d%e.      Z< G d& d'e.      Z= G d( d)e.      Z> G d* d+e.      Z? G d, d-e.      Z@ G d. d/e.      ZAy)0a  
Messages communicated over a Tor relay's ORPort.

.. versionadded:: 1.7.0

**Module Overview:**

::

  Cell - Base class for ORPort messages.
    |- CircuitCell - Circuit management.
    |  |- CreateCell - Create a circuit.              (section 5.1)
    |  |- CreatedCell - Acknowledge create.           (section 5.1)
    |  |- RelayCell - End-to-end data.                (section 6.1)
    |  |- DestroyCell - Stop using a circuit.         (section 5.4)
    |  |- CreateFastCell - Create a circuit, no PK.   (section 5.1)
    |  |- CreatedFastCell - Circuit created, no PK.   (section 5.1)
    |  |- RelayEarlyCell - End-to-end data; limited.  (section 5.6)
    |  |- Create2Cell - Extended CREATE cell.         (section 5.1)
    |  +- Created2Cell - Extended CREATED cell.       (section 5.1)
    |
    |- PaddingCell - Padding negotiation.             (section 7.2)
    |- VersionsCell - Negotiate proto version.        (section 4)
    |- NetinfoCell - Time and address info.           (section 4.5)
    |- PaddingNegotiateCell - Padding negotiation.    (section 7.2)
    |- VPaddingCell - Variable-length padding.        (section 7.2)
    |- CertsCell - Relay certificates.                (section 4.2)
    |- AuthChallengeCell - Challenge value.           (section 4.3)
    |- AuthenticateCell - Client authentication.      (section 4.5)
    |- AuthorizeCell - Client authorization.          (not yet used)
    |
    |- pack - encodes cell into bytes
    |- unpack - decodes series of cells
    +- pop - decodes cell with remainder
    N)	UNDEFINED)	HASH_LENZEROLinkProtocolAddressCertificateCloseReasonRelayCommandSizesplit)datetime_to_unix	str_toolsi      c                        e Zd ZdZdZdZdZd fd	Zed        Z	ed        Z
d Zed	        Zed
        Zedd       Zed        Zd Zd Z xZS )Cella  
  Metadata for ORPort cells.

  Unused padding are **not** used in equality checks or hashing. If two cells
  differ only in their *unused* attribute they are functionally equal.

  The following cell types explicitly don't have *unused* content:
    * PaddingCell (we consider all content part of payload)
    * VersionsCell (all content is unpacked and treated as a version specification)
    * VPaddingCell (we consider all content part of payload)

  :var bytes unused: unused filler that padded the cell to the expected size
  UNKNOWNFc                 8    t         t        |           || _        y N)superr   __init__unused)selfr   	__class__s     Z/var/www/betterdocs.net/sherlock_api/venv/lib/python3.12/site-packages/stem/client/cell.pyr   zCell.__init__c   s    	$ DK    c                     t        j                  t        j                  t                 D ]  \  }}| t        |dt              k(  s|c S  t        d| z        )z
    Provides cell attributes by its name.

    :param str name: cell command to fetch

    :raises: **ValueError** if cell type is invalid
    NAMEz'%s' isn't a valid cell typeinspect
getmemberssysmodules__name__getattrr   
ValueError)name_clss      r   by_namezCell.by_nameg   sT     $$S[[%:; 3	fi0	0
 3d:
;;r   c                     t        j                  t        j                  t                 D ]  \  }}| t        |dt              k(  s|c S  t        d| z        )z
    Provides cell attributes by its value.

    :param int value: cell value to fetch

    :raises: **ValueError** if cell type is invalid
    VALUEz'%s' isn't a valid cell valuer   )valuer(   r)   s      r   by_valuezCell.by_valuew   sT     $$S[[%:; 3	'#w	2	2
 4u<
==r   c                 D    t        dt        |       j                  z        )Nz(Packing not yet implemented for %s cells)NotImplementedErrortyper   r   link_protocols     r   packz	Cell.pack   s    
H4PT:??Z
[[r   c              #   R   K   | r!t         j                  | |      \  }} | | r yyw)aE  
    Unpacks all cells from a response.

    :param bytes content: payload to decode
    :param int link_protocol: link protocol version

    :returns: :class:`~stem.client.cell.Cell` generator

    :raises:
      * ValueError if content is malformed
      * NotImplementedError if unable to unpack any of the cell types
    N)r   pop)contentr3   cells      r   unpackzCell.unpack   s)      hhw6mdGj s   "''c                    t        |      }|j                  j                  |       \  }} t        j                  |       \  }} t        j                  |      }|j                  rt        }nt        j                  |       \  }} t        |       |k  r$t        d|j                  |t        |       fz        t        | |      \  }} |j                  |||      | fS )a<  
    Unpacks the first cell.

    :param bytes content: payload to decode
    :param int link_protocol: link protocol version

    :returns: (:class:`~stem.client.cell.Cell`, remainder) tuple

    :raises:
      * ValueError if content is malformed
      * NotImplementedError if unable to unpack this cell type
    z:%s cell should have a payload of %i bytes, but only had %i)r   circ_id_sizer6   CELL_TYPE_SIZEr   r.   IS_FIXED_SIZEFIXED_PAYLOAD_LENPAYLOAD_LEN_SIZElenr&   r   r   _unpack)r7   r3   circ_idcommandr)   payload_lenpayloads          r   r6   zCell.pop   s     !/M$1155g>GW%))'2GW
--
 C
%k-11':k7
7|k!SWZW_W_alnqrynzV{{||Wk2GW;;w7@@r   c           	      "   t        | t              r-|t        d| j                  z        |dk  r*t        d|z        |t        d| j                  z        d}t	        |      }t               }||j                  j                  |      z  }|t        j                  j                  | j                        z  }|| j                  rdn3t        j                  j                  t        |      t        |      z         z  }||z  }||z  }| j                  rrt        |      |j                  kD  r8t        d| j                  t        |      |j                  t        |      fz        |t        |j                  t        |      z
  z  z  }t!        |      S )ab  
    Provides bytes that can be used on the wire for these cell attributes.
    Format of a properly packed cell depends on if it's fixed or variable
    sized...

    ::

      Fixed:    [ CircuitID ][ Command ][ Payload ][ Padding ]
      Variable: [ CircuitID ][ Command ][ Size ][ Payload ]

    :param str name: cell command
    :param int link_protocol: link protocol version
    :param bytes payload: cell payload
    :param int circ_id: circuit id, if a CircuitCell

    :returns: **bytes** with the encoded payload

    :raises: **ValueError** if cell type invalid or payload makes cell too large
    z%%s cells require a circuit identifier   z3Circuit identifiers must a positive integer, not %sz0%s cells should not specify a circuit identifierr   r   zdCell of type %s is too large (%i bytes), must not be more than %i. Check payload size (was %i bytes))
issubclassCircuitCellr&   r   r   	bytearrayr;   r4   r   CHARr,   r=   SHORTr@   fixed_cell_lengthr   bytes)r)   r3   rE   r   rB   r8   s         r   _packz
Cell._pack   s   , #{#	@388KLLQ;NQXXYY		KchhVWWg /M;DM&&++G44DDIINN399%%D3$$C$**//#g,V:T*UUDGOD 	FND 	T]44	4  DG  DL  DL  NQ  RV  NW  Yf  Yx  Yx  z}  ~E  zF  CG  G  H  	H
dm55D	ABBd;r   c                 2    t        d| j                  z        )aJ  
    Subclass implementation for unpacking cell content.

    :param bytes content: payload to decode
    :param stem.client.datatype.LinkProtocol link_protocol: link protocol version
    :param int circ_id: circuit id cell is for

    :returns: instance of this cell type

    :raises: **ValueError** if content is malformed
    z*Unpacking not yet implemented for %s cells)r0   r   r)   r7   rB   r3   s       r   rA   zCell._unpack   s     JSXXU
VVr   c                 T    t        |t              rt        |       t        |      k(  S dS )NF)
isinstancer   hashr   others     r   __eq__zCell.__eq__  s#    (25$(?4:e$JUJr   c                     | |k(   S r    rU   s     r   __ne__zCell.__ne__  s    u}r   r   )r   N)r$   
__module____qualname____doc__r   r,   r=   r   staticmethodr*   r.   r4   r9   r6   classmethodrO   rA   rW   rZ   __classcell__r   s   @r   r   r   P   s     
$
%- < < > >\  $ A A> 3 3j W WKr   r   c                   $     e Zd ZdZd fd	Z xZS )rI   z?
  Cell concerning circuits.

  :var int circ_id: circuit id
  c                 :    t         t        |   |       || _        y r   )r   rI   r   rB   )r   rB   r   r   s      r   r   zCircuitCell.__init__  s    	+t%f-DLr   r[   )r$   r\   r]   r^   r   ra   rb   s   @r   rI   rI   
  s     r   rI   c                   L     e Zd ZdZdZdZdZd	 fd	Zd Ze	d        Z
d Z xZS )
PaddingCellzn
  Randomized content to either keep activity going on a circuit.

  :var bytes payload: randomized payload
  PADDINGr   Tc                     |st        j                  t              }n/t        |      t        k7  rt	        dt        t        |      fz        t
        t        |           || _        y )Nz.Padding payload should be %i bytes, but was %i)	osurandomr>   r@   r&   r   rf   r   rE   )r   rE   r   s     r   r   zPaddingCell.__init__!  sT    

,-g	W*	*GK\^abi^jJkkll	+t%'DLr   c                 B    t         j                  || j                        S r   )rf   rO   rE   r2   s     r   r4   zPaddingCell.pack*  s    ]DLL99r   c                     t        |      S r   )rf   rQ   s       r   rA   zPaddingCell._unpack-  s    wr   c                 F    t         j                  j                  | dd      S NrE   Tcachestemutil
_hash_attrr   s    r   __hash__zPaddingCell.__hash__1      99i>>r   r   r$   r\   r]   r^   r   r,   r=   r   r4   r`   rA   rv   ra   rb   s   @r   rf   rf     s<     
$
%-:    ?r   rf   c                   *     e Zd ZdZdZdZ fdZ xZS )
CreateCellCREATErG   Tc                 *    t         t        |           y r   )r   rz   r   r   r   s    r   r   zCreateCell.__init__:  s    	*d$&r   r$   r\   r]   r   r,   r=   r   ra   rb   s   @r   rz   rz   5  s    	$
%-' 'r   rz   c                   *     e Zd ZdZdZdZ fdZ xZS )CreatedCellCREATED   Tc                 *    t         t        |           y r   )r   r   r   r}   s    r   r   zCreatedCell.__init__C      	+t%'r   r~   rb   s   @r   r   r   >  s    	$
%-( (r   r   c                   b     e Zd ZdZdZdZdZd fd	Zd Ze	d        Z
d Zed	        Zd
 Z xZS )	RelayCella  
  Command concerning a relay circuit.

  Our 'recognized' attribute provides a cheap (but incomplete) check for if our
  cell payload is encrypted. If non-zero our payload *IS* encrypted, but if
  zero we're *PROBABLY* fully decrypted. This uncertainty is because encrypted
  cells have a small chance of coincidently producing zero for this value as
  well.

  :var stem.client.RelayCommand command: command to be issued
  :var int command_int: integer value of our command
  :var bytes data: payload of the cell
  :var int recognized: non-zero if payload is encrypted
  :var int digest: running digest held with the relay
  :var int stream_id: specific stream this concerns
  RELAY   Tc                 V   dt        t        |            j                         v r7|j                         d t        j
                   }t        j                  |      }nt        j                  j                  |      r)|d t        j
                   }t        j                  |      }nAt        j                  j                  |      rn!t        dt        |      j                  z        t        t        | ?  ||       t!        j"                  |      \  | _        | _        || _        || _        || _        t-        j.                  |      | _        |dk(  rZ|s*| j$                  t2        v rt        d| j$                  z        |r+| j$                  t4        v rt        d| j$                  z        y y y )NrT   z=RELAY cell digest must be a hash, string, or int but was a %sr   z"%s relay cells require a stream idzE%s relay cells concern the circuit itself and cannot have a stream id)strr1   lowerdigestRELAY_DIGEST_SIZEsizer9   rr   rs   _is_str_is_intr&   r$   r   r   r   r
   getrC   command_int
recognized	stream_idr   	_to_bytesdataSTREAM_ID_REQUIREDSTREAM_ID_DISALLOWED)
r   rB   rC   r   r   r   r   r   digest_packedr   s
            r   r   zRelayCell.__init__]  sb   T&\"((**
 mmo&='8'='=>m ''6f			6	"4/445m ''6f			6	"
VY]^dYeYnYnnoo	)T#GV4%1%5%5g%>"DL$" DODNDK##D)DI{4<<+===LMM)==`cgcocoopp >9 r   c                 h   t               }|t        j                  j                  | j                        z  }|t        j
                  j                  | j                        z  }|t        j
                  j                  | j                        z  }|t        j                  j                  | j                        z  }|t        j
                  j                  t        | j                              z  }|| j                  z  }t        j                  |t        |      | j                  | j                         S r   )rJ   r   rK   r4   r   rL   r   r   LONGr   r@   r   r   rO   rN   r   rB   )r   r3   rE   s      r   r4   zRelayCell.packz  s    kGtyy~~d..//Gtzzt//Gtzzt~~..Gtyy~~dkk**Gtzzs499~..GtyyG??=%.$++t||TTr   c                    t        j                   |      }|j                         }t        |      | j                  k7  r-t        j                  d| j                  t        |      fz        | j
                  j                  |      \  }}t        j                  j                  |      \  }}|t        j                  k7  rt        j                  d|z        |j                  |      }	t        j                  |	||       }
|
||fS )a  
    Decrypts content as a relay cell addressed to us. This provides back a
    tuple of the form...

    ::

      (cell (RelayCell), new_key (CipherContext), new_digest (HASH))

    :param int link_protocol: link protocol version
    :param bytes content: cell content to be decrypted
    :param cryptography.hazmat.primitives.ciphers.CipherContext key:
      key established with the relay we received this cell from
    :param hashlib.HASH digest: running digest held with the relay

    :returns: **tuple** with our decrypted cell and updated key/digest

    :raises: :class:`stem.ProtocolError` if content doesn't belong to a relay
      cell
    z/RELAY cells should be %i bytes, but received %iz<Cannot decrypt as a RELAY cell. This had command %i instead.)copyr@   rM   rr   ProtocolErrorr;   r6   r   rK   r   r,   updaterA   )r3   r7   keyr   new_key
new_digestrB   rC   encrypted_payloadrE   r8   s              r   decryptzRelayCell.decrypt  s    , iinGJ
7|}666PTaTsTsux  zA  vB  TC   C  D  D$1155g>GW!%w!7G)//!]`gghhnn./GWg}=D" *$$r   c           	         t        j                   |      }|j                         }|j                  j                  dz   }| j                  |      |d }|j	                  |       t        | j                  | j                  | j                  || j                  | j                  | j                        }t        |j                  |      |      \  }	}
|	|j	                  |
      z   ||fS )a  
    Encrypts our cell content to be sent with the given key. This provides back
    a tuple of the form...

    ::

      (payload (bytes), new_key (CipherContext), new_digest (HASH))

    :param int link_protocol: link protocol version
    :param cryptography.hazmat.primitives.ciphers.CipherContext key:
      key established with the relay we're sending this cell to
    :param hashlib.HASH digest: running digest held with the relay

    :returns: **tuple** with our encrypted payload and updated key/digest
    rG   N)r   r;   r   r4   r   r   rB   rC   r   r   r   r   r   )r   r3   r   r   r   r   header_sizepayload_without_digestr8   headerrE   s              r   encryptzRelayCell.encrypt  s    " iinGJ
  ,,11A5K!YY}5klC,-
 T\\4<<JX\XgXgimitituDDIIm4kBOFGGNN7++Wj@@r   c           	         t         j                  j                  |      \  }}t         j                  j                  |      \  }}t         j                  j                  |      \  }}t         j                  j                  |      \  }}t         j                  j                  |      \  }}t        ||      \  }	}
t        |	      |k7  r$t        d| j                  |t        |	      fz        t        |||	||||
      S )Nz5%s cell said it had %i bytes of data, but only had %i)
r   rK   r6   rL   r   r   r@   r&   r   r   )r)   r7   rB   r3   rC   r   r   r   data_lenr   r   s              r   rA   zRelayCell._unpack  s    yy}}W-GW**..1J0IwiimmG,OFG

w/Hg(+LD&
4yHNRURZRZ\dfijnfoQppqqWgtVY
FSSr   c                 L    t         j                  j                  | ddddd      S )Nr   r   r   r   Tro   rq   ru   s    r   rv   zRelayCell.__hash__  s%    99m[(F\`aar   )r   r   r   r   )r$   r\   r]   r^   r   r,   r=   r   r4   r_   r   r   r`   rA   rv   ra   rb   s   @r   r   r   G  s]    " 
$
%-q:	U 4% 4%l!AF T Tbr   r   c                   d     e Zd ZdZdZdZdZej                  df fd	Z	d Z
ed        Zd	 Z xZS )
DestroyCellz
  Closes the given circuit.

  :var stem.client.CloseReason reason: reason the circuit is being closed
  :var int reason_int: integer value of our closure reason
  DESTROY   Tr   c                 r    t         t        |   ||       t        j                  |      \  | _        | _        y r   )r   r   r   r	   r   reason
reason_int)r   rB   r   r   r   s       r   r   zDestroyCell.__init__  s+    	+t%gv6#.??6#: DKr   c                     t         j                  |t        j                  j	                  | j
                        | j                  | j                        S r   )r   rO   r   rK   r4   r   r   rB   r2   s     r   r4   zDestroyCell.pack  s5    ]DIINN4??,KT[[Z^ZfZfggr   c                 `    t         j                  j                  |      \  }}t        |||      S r   )r   rK   r6   r   )r)   r7   rB   r3   r   r   s         r   rA   zDestroyCell._unpack  s'    YY]]7+NFFw//r   c                 H    t         j                  j                  | ddd      S )NrB   r   Tro   rq   ru   s    r   rv   zDestroyCell.__hash__	  s     99itLLr   )r$   r\   r]   r^   r   r,   r=   r	   NONEr   r4   r`   rA   rv   ra   rb   s   @r   r   r     sI     
$
%-'2'7'7# ;h 0 0Mr   r   c                   L     e Zd ZdZdZdZdZd	 fd	Zd Ze	d        Z
d Z xZS )
CreateFastCellz
  Create a circuit with our first hop. This is lighter weight than further hops
  because we've already established the relay's identity and secret key.

  :var bytes key_material: randomized key material
  CREATE_FAST   Tc                     |st        j                  t              }n/t        |      t        k7  rt	        dt        t        |      fz        t
        t        |   ||       || _        y N+Key material should be %i bytes, but was %i)	ri   rj   r   r@   r&   r   r   r   key_material)r   rB   r   r   r   s       r   r   zCreateFastCell.__init__  sW    ZZ)l	\	h	&DRUVbRcGddee	.$(&9$Dr   c                 n    t         j                  || j                  | j                  | j                        S r   )r   rO   r   r   rB   r2   s     r   r4   zCreateFastCell.pack"  s'    t/@/@$++t||\\r   c                     t        |t              \  }}t        |      t        k7  rt        dt        t        |      fz        t	        |||      S r   )r   r   r@   r&   r   )r)   r7   rB   r3   r   r   s         r   rA   zCreateFastCell._unpack%  sL     (3L&
<H$DRUVbRcGddee'<88r   c                 H    t         j                  j                  | ddd      S )NrB   r   Tro   rq   ru   s    r   rv   zCreateFastCell.__hash__.  s     99iNNr   Nr   rx   rb   s   @r   r   r     s>     
$
%-%] 9 9Or   r   c                   L     e Zd ZdZdZdZdZd	 fd	Zd Ze	d        Z
d Z xZS )
CreatedFastCellz
  CREATE_FAST reply.

  :var bytes key_material: randomized key material
  :var bytes derivative_key: hash proving the relay knows our shared key
  CREATED_FAST   Tc                 >   |st        j                  t              }n/t        |      t        k7  rt	        dt        t        |      fz        t        |      t        k7  rt	        dt        t        |      fz        t
        t        |   ||       || _        || _	        y )Nr   z.Derivatived key should be %i bytes, but was %i)
ri   rj   r   r@   r&   r   r   r   r   derivative_key)r   rB   r   r   r   r   s        r   r   zCreatedFastCell.__init__>  s    ZZ)l	\	h	&DRUVbRcGddee
>h&G8UXYgUhJiijj	/4)'6:$D(Dr   c                     t         j                  || j                  | j                  z   | j                  | j
                        S r   )r   rO   r   r   r   rB   r2   s     r   r4   zCreatedFastCell.packK  s8      0A0ADDWDW0WY]YdYdfjfrfrssr   c                     t        |      t        dz  k  r t        dt        dz  t        |      fz        t        |t              \  }}t        |t              \  }}t	        ||||      S )Nr   z?Key material and derivatived key should be %i bytes, but was %i)r@   r   r&   r   r   )r)   r7   rB   r3   r   r   s         r   rA   zCreatedFastCell._unpackN  si    
7|hl"X\dgh\hjmnujv[wwxx!'84L'#GX6NG7NL'JJr   c                 J    t         j                  j                  | dddd      S )NrB   r   r   Tro   rq   ru   s    r   rv   zCreatedFastCell.__hash__X  s$    99i1A>[_``r   r   rx   rb   s   @r   r   r   2  s@     
$
%-)t K Kar   r   c                   J     e Zd ZdZdZdZdZ fdZd Ze	d        Z
d Z xZS )	VersionsCellzI
  Link version negotiation cell.

  :var list versions: link versions
  VERSIONS   Fc                 8    t         t        |           || _        y r   )r   r   r   versions)r   r   r   s     r   r   zVersionsCell.__init__g  s    	,&(DMr   c                     dj                  | j                  D cg c]!  }t        j                  j	                  |      # c}      }t
        j                  ||      S c c}w r   )joinr   r   rL   r4   r   rO   )r   r3   vrE   s       r   r4   zVersionsCell.packk  sE    hhDMMBq

*BCGmW55 Cs   &Ac                     g }|r6t         j                  j                  |      \  }}|j                  |       |r6t	        |      S r   )r   rL   r6   appendr   )r)   r7   rB   r3   link_protocolsversions         r   rA   zVersionsCell._unpacko  sA    N
0gwG$  ''r   c                 F    t         j                  j                  | dd      S )Nr   Tro   rq   ru   s    r   rv   zVersionsCell.__hash__y  s    99j$??r   rx   rb   s   @r   r   r   \  s=     
$
%-6 ( (@r   r   c                   L     e Zd ZdZdZdZdZd	 fd	Zd Ze	d        Z
d Z xZS )
NetinfoCellz
  Information relays exchange about each other.

  :var datetime timestamp: current time
  :var stem.client.datatype.Address receiver_address: receiver's OR address
  :var list sender_addresses: sender's OR addresses
  NETINFO   Tc                     t         t        |   |       |r|nt        j                  j	                         | _        || _        || _        y r   )r   r   r   datetimenow	timestampreceiver_addresssender_addresses)r   r   r   r   r   r   s        r   r   zNetinfoCell.__init__  s<    	+t%f-"+Y1B1B1F1F1HDN,D,Dr   c                    t               }|t        j                  j                  t	        t        | j                                    z  }|| j                  j                         z  }|t        j                  j                  t        | j                              z  }| j                  D ]  }||j                         z  } t        j                  |t        |      | j                        S r   )rJ   r   r   r4   intr   r   r   rK   r@   r   r   rO   rN   r   )r   r3   rE   addrs       r   r4   zNetinfoCell.pack  s    kGtyy~~c"24>>"BCDDGt$$))++Gtyy~~c$"7"7899G%% g ]E'NDKKHHr   c                    t         j                  j                  |      \  }}t        j                  |      \  }}g }t         j                  j                  |      \  }}t        |      D ]+  }t        j                  |      \  }	}|j                  |	       - t        ||t        j                  j                  |      |      S )Nr   )
r   r   r6   r   rK   ranger   r   r   utcfromtimestamp)
r)   r7   rB   r3   r   r   r   sender_addr_countir   s
             r   rA   zNetinfoCell._unpack  s    w/Iw 'G 4g!%w!7w$% $kk'*mdGd#$ ')98;L;L;];]^g;hsz{{r   c                 J    t         j                  j                  | dddd      S )Nr   r   r   Tro   rq   ru   s    r   rv   zNetinfoCell.__hash__  s%    99k3EGYcghhr   r   rx   rb   s   @r   r   r   }  s@     
$
%--	I | |ir   r   c                   *     e Zd ZdZdZdZ fdZ xZS )RelayEarlyCellRELAY_EARLY	   Tc                 *    t         t        |           y r   )r   r   r   r}   s    r   r   zRelayEarlyCell.__init__  s    	.$(*r   r~   rb   s   @r   r   r     s    	$
%-+ +r   r   c                   *     e Zd ZdZdZdZ fdZ xZS )Create2CellCREATE2
   Tc                 *    t         t        |           y r   )r   r   r   r}   s    r   r   zCreate2Cell.__init__  r   r   r~   rb   s   @r   r   r     s    	$
%-( (r   r   c                   *     e Zd ZdZdZdZ fdZ xZS )Created2CellCREATED2   Tc                 *    t         t        |           y r   )r   r   r   r}   s    r   r   zCreated2Cell.__init__  s    	,&(r   r~   rb   s   @r   r   r     s    	$
%-) )r   r   c                   *     e Zd ZdZdZdZ fdZ xZS )PaddingNegotiateCellPADDING_NEGOTIATE   Tc                 *    t         t        |           y r   )r   r   r   r}   s    r   r   zPaddingNegotiateCell.__init__  s    	
.0r   r~   rb   s   @r   r   r     s    	$
%-1 1r   r   c                   L     e Zd ZdZdZdZdZd	 fd	Zd Ze	d        Z
d Z xZS )
VPaddingCellz~
  Variable length randomized content to either keep activity going on a circuit.

  :var bytes payload: randomized payload
  VPADDING   Fc                    ||t        d      ||dk  rt        d|z        |)|'|t        |      k7  rt        d|t        |      fz        t        t        |           ||| _        y t        j                  |      | _        y )Nz5VPaddingCell constructor must specify payload or sizer   z)VPaddingCell size (%s) cannot be negativezRVPaddingCell constructor specified both a size of %i bytes and payload of %i bytes)r&   r@   r   r  r   ri   rj   rE   )r   r   rE   r   s      r   r   zVPaddingCell.__init__  s    |NOO		dQhBTIJJ		g1dc'l6Jkosux  zA  vB  oC  C  D  D	,&(%17DLrzz$7GDLr   c                 B    t         j                  || j                        S r   )r  rO   rE   r2   s     r   r4   zVPaddingCell.pack  s    mT\\::r   c                     t        |      S )N)rE   )r  rQ   s       r   rA   zVPaddingCell._unpack  s    '**r   c                 F    t         j                  j                  | dd      S rn   rq   ru   s    r   rv   zVPaddingCell.__hash__  rw   r   )NNrx   rb   s   @r   r  r    s=     
$
%-	H; + +?r   r  c                   L     e Zd ZdZdZdZdZd	 fd	Zd Ze	d        Z
d Z xZS )
	CertsCellz
  Certificate held by the relay we're communicating with.

  :var list certificates: :class:`~stem.client.Certificate` of the relay
  CERTS   Fc                 :    t         t        |   |       || _        y r   )r   r  r   certificates)r   certsr   r   s      r   r   zCertsCell.__init__  s    	)T#F+Dr   c                    t         j                  |t        j                  j	                  t        | j                              dj                  | j                  D cg c]  }|j	                          c}      z   | j                        S c c}w r   )	r  rO   r   rK   r4   r@   r  r   r   )r   r3   certs      r   r4   zCertsCell.pack  s    ??=$))..T=N=N9O*PSVS[S[uy  vG  vG  ]Hmq]a]f]f]h  ]H  TI  +I  KO  KV  KV  W  W  ]Hs   B
c                    t         j                  j                  |      \  }}g }t        |      D ]F  }|st	        d|t        |      fz        t        j                  |      \  }}|j                  |       H t        ||      S )NzJCERTS cell indicates it should have %i certificates, but only contained %ir   )	r   rK   r6   r   r&   r@   r   r   r  )r)   r7   rB   r3   
cert_countr  r   r  s           r   rA   zCertsCell._unpack  s    ))--0JE: eisuxy~u  iA  A  B  	B!oog.mdGll4 UW--r   c                 F    t         j                  j                  | dd      S )Nr  Tro   rq   ru   s    r   rv   zCertsCell.__hash__  s    99ndCCr   r[   rx   rb   s   @r   r  r    s>     
$
%-W . .Dr   r  c                   L     e Zd ZdZdZdZdZd	 fd	Zd Ze	d        Z
d Z xZS )
AuthChallengeCellz
  First step of the authentication handshake.

  :var bytes challenge: random bytes for us to sign to authenticate
  :var list methods: authentication methods supported by the relay we're
    communicating with
  AUTH_CHALLENGE   Fc                     |st        j                  t              }n/t        |      t        k7  rt	        dt        t        |      fz        t
        t        |   |       || _        || _	        y )Nz+AUTH_CHALLENGE must be %i bytes, but was %i)
ri   rj   AUTH_CHALLENGE_SIZEr@   r&   r   r  r   	challengemethods)r   r  r  r   r   s       r   r   zAuthChallengeCell.__init__#  s^    **01i	Y.	.DH[]`aj]kGllmm	
T+F3DNDLr   c                 X   t               }|| j                  z  }|t        j                  j	                  t        | j                              z  }| j                  D ]$  }|t        j                  j	                  |      z  }& t        j                  |t        |      | j                        S r   )rJ   r  r   rL   r4   r@   r  r  rO   rN   r   )r   r3   rE   methods       r   r4   zAuthChallengeCell.pack-  s    kGt~~Gtzzs4<<011G,, )((g) ""=%.$++NNr   c                 &   t         t        j                  j                  z   }t	        |      |k  rt        d|t	        |      fz        t        |t               \  }}t        j                  j                  |      \  }}t	        |      |t        j                  j                  z  k  rt        d|t	        |      fz        g }t        |      D ]5  }t        j                  j                  |      \  }	}|j                  |	       7 t        |||      S )Nz>AUTH_CHALLENGE payload should be at least %i bytes, but was %izCAUTH_CHALLENGE should have %i methods, but only had %i bytes for itr   )r  r   rL   r   r@   r&   r   r6   r   r   r  )
r)   r7   rB   r3   min_sizer  method_countr  r   r   s
             r   rA   zAuthChallengeCell._unpack7  s    "TZZ__4H
7|hW[cehipeqZrrssw(;<Iw JJNN73L'
7|lTZZ__44\`lnqrynz_{{||G<  

w/ofgnnV Wi'BBr   c                 H    t         j                  j                  | ddd      S )Nr  r  Tro   rq   ru   s    r   rv   zAuthChallengeCell.__hash__K  s     99k9dKKr   r   rx   rb   s   @r   r  r    s@     
$
%-O C C&Lr   r  c                   *     e Zd ZdZdZdZ fdZ xZS )AuthenticateCellAUTHENTICATE   Fc                 *    t         t        |           y r   )r   r&  r   r}   s    r   r   zAuthenticateCell.__init__T  s    	
D*,r   r~   rb   s   @r   r&  r&  O  s    	$
%-- -r   r&  c                   *     e Zd ZdZdZdZ fdZ xZS )AuthorizeCell	AUTHORIZE   Fc                 *    t         t        |           y r   )r   r+  r   r}   s    r   r   zAuthorizeCell.__init__]  s    	-')r   r~   rb   s   @r   r+  r+  X  s    	$
%-* *r   r+  )Br^   r   r   r    ri   r"   	stem.utilrr   r   stem.client.datatyper   r   r   r   r   r	   r
   r   r   r   r   r>   r  rK   r<   rL   r?   r   r   BEGINDATAEND	CONNECTEDRESOLVERESOLVED	BEGIN_DIRr   EXTENDEXTENDEDTRUNCATE	TRUNCATEDDROPEXTEND2	EXTENDED2r   objectr   rI   rf   rz   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r&  r+  rY   r   r   <module>r@     s  "H    	 
   { { { 1  :: II     w6 wt	$ 	?$ ?>' '(+ (gb gbTM+ M8"O[ "OJ'ak 'aT@4 @B-i$ -i`+[ +(+ ()4 )14 1?4 ?B!D !DH6L 6Lr-t -*D *r   