o
    ֬^9                     @   s
  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ej	 r&ddl
mZ nddlmZ i ZedZd`ddZe dd	 ZG d
d deZG dd deZe Zeeded eed ejjjg defdedfdedfdedfdedfdedfdedfdedfd ed!fd"ed#fd$ed%fd&ed'fd(ed)fd*ed+fd,ed-fd.ed/fd0ed)fd1ed2fd3ed4fd5ed6fd7ed6fd8ed6fd9ed6fd:ed6fd;ed<fd=ed>fd?ed>fd@edfdAedBfdCedDfdEedDfdFedGfdHed'fdIedJfdKed'fdLed'fdMedNfdOedPfdQed+fdRedSfdTedUfdVedfdWedXfdYedZfd[ed/fd\ed]fd^ed_fR  ZdS )aa  
Tor versioning information and requirements for its features. These can be
easily parsed and compared, for instance...

::

  >>> from stem.version import get_system_tor_version, Requirement
  >>> my_version = get_system_tor_version()
  >>> print(my_version)
  0.2.1.30
  >>> my_version >= Requirement.TORRC_CONTROL_SOCKET
  True

**Module Overview:**

::

  get_system_tor_version - gets the version of our system's tor installation

  Version - Tor versioning information

.. data:: Requirement (enum)

  Enumerations for the version requirements of features.

  .. deprecated:: 1.6.0
     Requirement entries belonging to tor versions which have been obsolete for
     at least six months will be removed when we break backward compatibility
     in the 2.x stem release.

  ===================================== ===========
  Requirement                           Description
  ===================================== ===========
  **AUTH_SAFECOOKIE**                   SAFECOOKIE authentication method
  **DESCRIPTOR_COMPRESSION**            `Expanded compression support for ZSTD and LZMA <https://gitweb.torproject.org/torspec.git/commit/?id=1cb56afdc1e55e303e3e6b69e90d983ee217d93f>`_
  **DORMANT_MODE**                      **DORMANT** and **ACTIVE** :data:`~stem.Signal`
  **DROPGUARDS**                        DROPGUARDS requests
  **EVENT_AUTHDIR_NEWDESCS**            AUTHDIR_NEWDESC events
  **EVENT_BUILDTIMEOUT_SET**            BUILDTIMEOUT_SET events
  **EVENT_CIRC_MINOR**                  CIRC_MINOR events
  **EVENT_CLIENTS_SEEN**                CLIENTS_SEEN events
  **EVENT_CONF_CHANGED**                CONF_CHANGED events
  **EVENT_DESCCHANGED**                 DESCCHANGED events
  **EVENT_GUARD**                       GUARD events
  **EVENT_HS_DESC_CONTENT**             HS_DESC_CONTENT events
  **EVENT_NETWORK_LIVENESS**            NETWORK_LIVENESS events
  **EVENT_NEWCONSENSUS**                NEWCONSENSUS events
  **EVENT_NS**                          NS events
  **EVENT_SIGNAL**                      SIGNAL events
  **EVENT_STATUS**                      STATUS_GENERAL, STATUS_CLIENT, and STATUS_SERVER events
  **EVENT_STREAM_BW**                   STREAM_BW events
  **EVENT_TRANSPORT_LAUNCHED**          TRANSPORT_LAUNCHED events
  **EVENT_CONN_BW**                     CONN_BW events
  **EVENT_CIRC_BW**                     CIRC_BW events
  **EVENT_CELL_STATS**                  CELL_STATS events
  **EVENT_TB_EMPTY**                    TB_EMPTY events
  **EVENT_HS_DESC**                     HS_DESC events
  **EXTENDCIRCUIT_PATH_OPTIONAL**       EXTENDCIRCUIT queries can omit the path if the circuit is zero
  **FEATURE_EXTENDED_EVENTS**           'EXTENDED_EVENTS' optional feature
  **FEATURE_VERBOSE_NAMES**             'VERBOSE_NAMES' optional feature
  **GETINFO_CONFIG_TEXT**               'GETINFO config-text' query
  **GETINFO_GEOIP_AVAILABLE**           'GETINFO ip-to-country/ipv4-available' query and its ipv6 counterpart
  **GETINFO_MICRODESCRIPTORS**          'GETINFO md/all' query
  **GETINFO_UPTIME**                    'GETINFO uptime' query
  **HIDDEN_SERVICE_V3**                 Support for v3 hidden services
  **HSFETCH**                           HSFETCH requests
  **HSFETCH_V3**                        HSFETCH for version 3 hidden services
  **HSPOST**                            HSPOST requests
  **ADD_ONION**                         ADD_ONION and DEL_ONION requests
  **ADD_ONION_BASIC_AUTH**              ADD_ONION supports basic authentication
  **ADD_ONION_NON_ANONYMOUS**           ADD_ONION supports non-anonymous mode
  **ADD_ONION_MAX_STREAMS**             ADD_ONION support for MaxStreamsCloseCircuit
  **LOADCONF**                          LOADCONF requests
  **MICRODESCRIPTOR_IS_DEFAULT**        Tor gets microdescriptors by default rather than server descriptors
  **SAVECONF_FORCE**                    Added the 'FORCE' flag to SAVECONF
  **TAKEOWNERSHIP**                     TAKEOWNERSHIP requests
  **TORRC_CONTROL_SOCKET**              'ControlSocket <path>' config option
  **TORRC_PORT_FORWARDING**             'PortForwarding' config option
  **TORRC_DISABLE_DEBUGGER_ATTACHMENT** 'DisableDebuggerAttachment' config option
  **TORRC_VIA_STDIN**                   Allow torrc options via 'tor -f -' (:trac:`13865`)
  ===================================== ===========
    N)	lru_cachez=^([0-9]+)\.([0-9]+)\.([0-9]+)(\.[0-9]+)?(-\S*)?(( \(\S*\))*)$torc                 C   s   | t vrxd|  }z	tjj|}W n( ty9 } zdt|v r1tj	| r-d|  }t
|d| }t
|d}~ww |D ],}|drh|drhz|dd	 }t|t | < W  n tyg } zt
|d}~ww q<| t vrxt
d
|d|f t |  S )a  
  Queries tor for its version. This is os dependent, only working on linux,
  osx, and bsd.

  :param str tor_cmd: command used to run tor

  :returns: :class:`~stem.version.Version` provided by the tor command

  :raises: **IOError** if unable to query or parse the version
  z%s --versionzNo such file or directoryz2Unable to check tor's version. '%s' doesn't exist.z1Unable to run '%s'. Maybe tor isn't in your PATH?NzTor version .   z,'%s' didn't provide a parseable version:

%s
)VERSION_CACHEstemutilsystemcallOSErrorstrospathisabsIOError
startswithendswithVersion
ValueErrorjoin)Ztor_cmdZversion_cmdZversion_outputexclineversion_str r   ./usr/lib/python3/dist-packages/stem/version.pyget_system_tor_versionj   s6   r   c                 C   s   t | S N)r   r   r   r   r   _get_version   s   r    c                   @   sP   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd ZdS )r   a  
  Comparable tor version. These are constructed from strings that conform to
  the 'new' style in the `tor version-spec
  <https://gitweb.torproject.org/torspec.git/tree/version-spec.txt>`_,
  such as "0.1.4" or "0.2.2.23-alpha (git-7dcd105be34a4f44)".

  .. versionchanged:: 1.6.0
     Added all_extra parameter.

  :var int major: major version
  :var int minor: minor version
  :var int micro: micro version
  :var int patch: patch level (**None** if undefined)
  :var str status: status tag such as 'alpha' or 'beta-dev' (**None** if undefined)
  :var str extra: first extra information without its parentheses such as
    'git-8be6058d8f31e578' (**None** if undefined)
  :var list all_extra: all extra information entries, without their parentheses
  :var str git_commit: git commit id (**None** if it wasn't provided)

  :param str version_str: version to be parsed

  :raises: **ValueError** if input isn't a valid tor version
  c                 C   s   || _ t|}|rt| \}}}}}}}	|rt|dd  }|r'|dd  }t|| _t|| _t|| _|| _|| _	|rIdd |
  D ng | _| jrT| jd nd | _d | _| jD ]}
|
rqtd|
rq|
dd  | _ d S q]d S td| )N   c                 S   s   g | ]}|d d qS )r!   r   r   ).0entryr   r   r   
<listcomp>   s    z$Version.__init__.<locals>.<listcomp>r   z^git-[0-9a-f]{16}$   z+'%s' isn't a properly formatted tor version)r   VERSION_PATTERNmatchgroupsintmajorminormicropatchstatusstripsplitZ	all_extraextraZ
git_commitrer   )selfr   Zversion_partsr*   r+   r,   r-   r.   Z	extra_str_r1   r   r   r   __init__   s.   



 
zVersion.__init__c                 C   s   | j S )z<
    Provides the string used to construct the version.
    r   r3   r   r   r   __str__   s   zVersion.__str__c                 C   s   t |tsdS dD ]#}t| |}t||}|du rd}|du r!d}||kr,|||  S q	| jr3| jnd}|jr;|jnd}|||S )z:
    Compares version ordering according to the spec.
    F)r*   r+   r,   r-   Nr    )
isinstancer   getattrr.   )r3   othermethodattrZ
my_versionZother_versionZ	my_statusZother_statusr   r   r   _compare   s   



zVersion._comparec              	   C   s   t jj| dddddddS )Nr*   r+   r,   r-   r.   T)cache)r	   r
   Z
_hash_attrr6   r   r   r   __hash__   s   zVersion.__hash__c                 C   s   |  |dd S )Nc                 S   s   | |kS r   r   sor   r   r   <lambda>      z Version.__eq__.<locals>.<lambda>)r>   r3   r;   r   r   r   __eq__   s   zVersion.__eq__c                 C   s
   | |k S r   r   rF   r   r   r   __ne__     
zVersion.__ne__c                 C   8   t |tr|jD ]	}|| r dS qdS | |dd S )z
    Checks if this version meets the requirements for a given feature. We can
    be compared to either a :class:`~stem.version.Version` or
    :class:`~stem.version._VersionRequirements`.
    TFc                 S   s   | |kS r   r   rA   r   r   r   rD     rE   z Version.__gt__.<locals>.<lambda>r9   _VersionRequirementsrulesr>   r3   r;   Zruler   r   r   __gt__  s   

zVersion.__gt__c                 C   rJ   )NTFc                 S   s   | |kS r   r   rA   r   r   r   rD     rE   z Version.__ge__.<locals>.<lambda>rK   rN   r   r   r   __ge__  s   

zVersion.__ge__N)__name__
__module____qualname____doc__r5   r7   r>   r@   rG   rH   rO   rP   r   r   r   r   r      s     r   c                   @   s6   e Zd ZdZdd ZdddZdddZdd
dZdS )rL   a  
  Series of version constraints that can be compared to. For instance, this
  allows for comparisons like 'if I'm greater than version X in the 0.2.2
  series, or greater than version Y in the 0.2.3 series'.

  This is a logical 'or' of the series of rules.
  c                 C   s
   g | _ d S r   )rM   r6   r   r   r   r5   *  rI   z_VersionRequirements.__init__Tc                    4   |r| j  fdd dS | j  fdd dS )z
    Adds a constraint that we're greater than the given version.

    :param stem.version.Version version: version we're checking against
    :param bool inclusive: if comparison is inclusive or not
    c                    s    | kS r   r   vversionr   r   rD   6  rE   z3_VersionRequirements.greater_than.<locals>.<lambda>c                    s    | k S r   r   rV   rX   r   r   rD   8  rE   NrM   appendr3   rY   Z	inclusiver   rX   r   greater_than-     z!_VersionRequirements.greater_thanc                    rU   )z
    Adds a constraint that we're less than the given version.

    :param stem.version.Version version: version we're checking against
    :param bool inclusive: if comparison is inclusive or not
    c                    s    | kS r   r   rV   rX   r   r   rD   C  rE   z0_VersionRequirements.less_than.<locals>.<lambda>c                    s    | kS r   r   rV   rX   r   r   rD   E  rE   NrZ   r\   r   rX   r   	less_than:  r^   z_VersionRequirements.less_thanFc                    s"    fdd}| j | dS )a  
    Adds constraint that we're within the range from one version to another.

    :param stem.version.Version from_version: beginning of the comparison range
    :param stem.version.Version to_version: end of the comparison range
    :param bool from_inclusive: if comparison is inclusive with the starting version
    :param bool to_inclusive: if comparison is inclusive with the ending version
    c                    sT    rr|   kokS   S  r|   kok S   S |   k o'k S   S r   r   rV   from_inclusivefrom_versionto_inclusive
to_versionr   r   new_ruleQ  s
   z/_VersionRequirements.in_range.<locals>.new_ruleNrZ   )r3   rb   rd   ra   rc   re   r   r`   r   in_rangeG  s   
z_VersionRequirements.in_rangeN)T)TF)rQ   rR   rS   rT   r5   r]   r_   rf   r   r   r   r   rL   !  s    

rL   z0.2.2.36z0.2.3.0z0.2.3.13ZAUTH_SAFECOOKIEZDESCRIPTOR_COMPRESSIONz0.3.1.1-alphaZDORMANT_MODEz0.4.0.1-alphaZ
DROPGUARDSz0.2.5.1-alphaZEVENT_AUTHDIR_NEWDESCSz0.1.1.10-alphaZEVENT_BUILDTIMEOUT_SETz0.2.2.7-alphaZEVENT_CIRC_MINORz0.2.3.11-alphaZEVENT_CLIENTS_SEENz0.2.1.10-alphaZEVENT_CONF_CHANGEDz0.2.3.3-alphaZEVENT_DESCCHANGEDz0.1.2.2-alphaZEVENT_GUARDz0.1.2.5-alphaZEVENT_HS_DESC_CONTENTz0.2.7.1-alphaZEVENT_NSz0.1.2.3-alphaZEVENT_NETWORK_LIVENESSz0.2.7.2-alphaZEVENT_NEWCONSENSUSz0.2.1.13-alphaZEVENT_SIGNALz0.2.3.1-alphaZEVENT_STATUSZEVENT_STREAM_BWz0.1.2.8-betaZEVENT_TRANSPORT_LAUNCHEDz0.2.5.0-alphaZEVENT_CONN_BWz0.2.5.2-alphaZEVENT_CIRC_BWZEVENT_CELL_STATSZEVENT_TB_EMPTYZEVENT_HS_DESCZEXTENDCIRCUIT_PATH_OPTIONALz0.2.2.9ZFEATURE_EXTENDED_EVENTSz0.2.2.1-alphaZFEATURE_VERBOSE_NAMESZGETINFO_CONFIG_TEXTZGETINFO_GEOIP_AVAILABLEz0.3.2.1-alphaZGETINFO_MICRODESCRIPTORSz0.3.5.1-alphaZGETINFO_UPTIMEZHIDDEN_SERVICE_V3z0.3.3.1-alphaZHSFETCHZ
HSFETCH_V3z0.4.1.1-alphaZHSPOSTZ	ADD_ONIONZADD_ONION_BASIC_AUTHz0.2.9.1-alphaZADD_ONION_NON_ANONYMOUSz0.2.9.3-alphaZADD_ONION_MAX_STREAMSZLOADCONFz0.2.1.1ZMICRODESCRIPTOR_IS_DEFAULTz0.2.3.3ZSAVECONF_FORCEZTAKEOWNERSHIPz0.2.2.28-betaZTORRC_CONTROL_SOCKETz0.2.0.30ZTORRC_PORT_FORWARDINGZ!TORRC_DISABLE_DEBUGGER_ATTACHMENTz0.2.3.9ZTORRC_VIA_STDINz0.2.6.3-alpha)r   )rT   r   r2   Zstem.prereqr	   Z	stem.utilZstem.util.enumZstem.util.systemZprereqZ_is_lru_cache_available	functoolsr   Zstem.util.lru_cacher   compiler&   r   r    objectr   rL   Zsafecookie_reqrf   r]   r
   enumEnumZRequirementr   r   r   r   <module>   s   S


/
 ;








	























 
!
"
#
$
%
&
'
(
)
*
+
,
-
.
/