U
    ÓZjå  ã                   @   s  d Z ddlZddl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
mZ ddl
mZ ddlmZmZmZmZmZmZmZ ddlmZ ddlmZ dd	lmZ dd
lmZ e e¡ZerÎeejeej  f Z!G dd„ de"ƒZ#e	j$ %ej&¡e	j$ 'ej(¡G dd„ dej)ƒƒƒZ*dd„ Z+dS )zStandalone Authenticator.é    N)Úerrno)Ú
challenges)Ú
standalone)ÚDefaultDictÚDictÚSetÚTupleÚListÚTypeÚTYPE_CHECKING)Úachallenges)Úerrors)Ú
interfaces)Úcommonc                   @   s2   e Zd ZdZdd„ Zddd„Zdd„ Zd	d
„ ZdS )ÚServerManagera§  Standalone servers manager.

    Manager for `ACMEServer` and `ACMETLSServer` instances.

    `certs` and `http_01_resources` correspond to
    `acme.crypto_util.SSLSocket.certs` and
    `acme.crypto_util.SSLSocket.http_01_resources` respectively. All
    created servers share the same certificates and resources, so if
    you're running both TLS and non-TLS instances, HTTP01 handlers
    will serve the same URLs!

    c                 C   s   i | _ || _|| _d S ©N)Ú
_instancesÚcertsÚhttp_01_resources)Úselfr   r   © r   ú]/var/www/html/TRUCKING_PROJECT/venv/lib/python3.8/site-packages/certbot/plugins/standalone.pyÚ__init__,   s    zServerManager.__init__Ú c              
   C   s”   |t jkst‚|| jkr"| j| S ||f}zt || j¡}W n0 tjk
rl } zt	 
||¡‚W 5 d}~X Y nX | ¡  | ¡ d d }|| j|< |S )a  Run ACME server on specified ``port``.

        This method is idempotent, i.e. all calls with the same pair of
        ``(port, challenge_type)`` will reuse the same server.

        :param int port: Port to run the server on.
        :param challenge_type: Subclass of `acme.challenges.Challenge`,
            currently only `acme.challenge.HTTP01`.
        :param str listenaddr: (optional) The address to listen on. Defaults to all addrs.

        :returns: DualNetworkedServers instance.
        :rtype: ACMEServerMixin

        Nr   é   )r   ÚHTTP01ÚAssertionErrorr   Úacme_standaloneZHTTP01DualNetworkedServersr   ÚsocketÚerrorr   ÚStandaloneBindErrorÚserve_foreverÚgetsocknames)r   ÚportZchallenge_typeÚ
listenaddrÚaddressÚserversr   Z	real_portr   r   r   Úrun1   s    

 ÿ
zServerManager.runc                 C   sB   | j | }| ¡ D ]}tjd|dd… žŽ  q| ¡  | j |= dS )zWStop ACME server running on the specified ``port``.

        :param int port:

        úStopping server at %s:%d...Né   )r(   )r   r"   ÚloggerÚdebugZshutdown_and_server_close)r   r#   ÚinstanceZsocknamer   r   r   ÚstopT   s    

ÿzServerManager.stopc                 C   s
   | j  ¡ S )zÉReturn all running instances.

        Once the server is stopped using `stop`, it will not be
        returned.

        :returns: Mapping from ``port`` to ``servers``.
        :rtype: tuple

        )r   Úcopy©r   r   r   r   Úrunninga   s    
zServerManager.runningN)r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r'   r-   r0   r   r   r   r   r      s
   
#r   c                       sp   e Zd ZdZdZ‡ fdd„Ze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d„ Z‡  ZS )ÚAuthenticatora  Standalone Authenticator.

    This authenticator creates its own ephemeral TCP listener on the
    necessary port in order to respond to incoming http-01
    challenges from the certificate authority. Therefore, it does not
    rely on any existing server program.
    zSpin up a temporary webserverc                    s@   t t| ƒj||Ž t t¡| _i | _tƒ | _t	| j| jƒ| _
d S r   )Úsuperr5   r   ÚcollectionsÚdefaultdictÚsetÚservedr   r   r   r&   )r   ÚargsÚkwargs©Ú	__class__r   r   r   {   s
    zAuthenticator.__init__c                 C   s   d S r   r   )ÚclsÚaddr   r   r   Úadd_parser_argumentsŠ   s    z"Authenticator.add_parser_argumentsc                 C   s   dS )NzÞThis authenticator creates its own ephemeral TCP listener on the necessary port in order to respond to incoming http-01 challenges from the certificate authority. Therefore, it does not rely on any existing server program.r   r/   r   r   r   Ú	more_infoŽ   s    zAuthenticator.more_infoc                 C   s   d S r   r   r/   r   r   r   Úprepare”   s    zAuthenticator.preparec                 C   s   t jgS r   )r   r   )r   Údomainr   r   r   Úget_chall_pref—   s    zAuthenticator.get_chall_prefc                    s   ‡ fdd„|D ƒS )Nc                    s   g | ]}ˆ   |¡‘qS r   )Ú_try_perform_single)Ú.0Úachallr/   r   r   Ú
<listcomp>œ   s     z)Authenticator.perform.<locals>.<listcomp>r   )r   Úachallsr   r/   r   Úperform›   s    zAuthenticator.performc              
   C   s@   z|   |¡W S  tjk
r8 } zt|ƒ W 5 d }~X Y q X q d S r   )Ú_perform_singler   r    Ú_handle_perform_error)r   rH   r   r   r   r   rF   ž   s    z!Authenticator._try_perform_singlec                 C   s"   |   |¡\}}| j|  |¡ |S r   )Ú_perform_http_01r:   r@   )r   rH   r&   Úresponser   r   r   rL   ¥   s    zAuthenticator._perform_singlec                 C   sX   | j j}| j j}| jj|tj|d�}| ¡ \}}tj	j
|j||d�}| j |¡ ||fS )N)r$   )ÚchallrO   Ú
validation)ÚconfigZhttp01_portZhttp01_addressr&   r'   r   r   Zresponse_and_validationr   ZHTTP01RequestHandlerZHTTP01ResourcerP   r   r@   )r   rH   r#   Úaddrr&   rO   rQ   Úresourcer   r   r   rN   ª   s      ÿzAuthenticator._perform_http_01c                 C   sd   | j  ¡ D ]$\}}|D ]}||kr| |¡ qq
t | j ¡ ¡D ]\}}| j | s@| j |¡ q@d S r   )r:   ÚitemsÚremoveÚsixÚ	iteritemsr&   r0   r-   )r   rJ   Zunused_serversZserver_achallsrH   r#   r&   r   r   r   Úcleanup´   s    
zAuthenticator.cleanup)r1   r2   r3   r4   Údescriptionr   ÚclassmethodrA   rB   rC   rE   rK   rF   rL   rN   rY   Ú__classcell__r   r   r=   r   r5   n   s   

r5   c                 C   st   | j jtjkr"t d | j¡¡‚nN| j jtjkrlt	j
 tj¡}d | j¡}|j|dddd�}|spt |¡‚n| ‚d S )Nz†Could not bind TCP port {0} because you don't have the appropriate permissions (for example, you aren't running this program as root).zªCould not bind TCP port {0} because it is already in use by another process on this system (such as a web server). Please stop the program in question and then try again.ÚRetryZCancelF)Údefault)Úsocket_errorr   Úsocket_errorsÚEACCESr   ZPluginErrorÚformatr#   Z
EADDRINUSEÚzopeÚ	componentZ
getUtilityr   ZIDisplayZyesno)r   ÚdisplayÚmsgZshould_retryr   r   r   rM   ¿   s&    ýÿýÿ ÿrM   ),r4   r7   Úloggingr   r   r`   ZOpenSSLrW   Zzope.interfacerc   Zacmer   r   r   Zacme.magic_typingr   r   r   r   r	   r
   r   Zcertbotr   r   r   Zcertbot.pluginsr   Ú	getLoggerr1   r*   ZBaseDualNetworkedServersZ"KeyAuthorizationAnnotatedChallengeZ
ServedTypeÚobjectr   Z	interfaceZimplementerZIAuthenticatorÚproviderZIPluginFactoryZPluginr5   rM   r   r   r   r   Ú<module>   s4   $
ÿÿOO