U
    
W[d1                     @   s  d Z ddlmZmZ ddlmZ ddlmZ ddlmZ ddlm	Z	 ddl
mZ ddlmZ dd	lmZmZ dd
lmZ ddlmZ ddlmZ eejG dd dZG dd deZG dd deZG dd dejZG dd deZG dd dejZG dd dejZdS )z
Mail protocol support.
    )absolute_importdivision)pop3)smtp)protocol)defer)longversion)log)CramMD5CredentialsUsernamePassword)UnauthorizedLogin)relay)implementerc                   @   s>   e Zd ZdZdZdZejfddZdd Z	dd Z
d	d
 ZdS )DomainDeliveryBaseaN  
    A base class for message delivery using the domains of a mail service.

    @ivar service: See L{__init__}
    @ivar user: See L{__init__}
    @ivar host: See L{__init__}

    @type protocolName: L{bytes}
    @ivar protocolName: The protocol being used to deliver the mail.
        Sub-classes should set this appropriately.
    Nc                 C   s   || _ || _|| _dS )z
        @type service: L{MailService}
        @param service: A mail service.

        @type user: L{bytes} or L{None}
        @param user: The authenticated SMTP user.

        @type host: L{bytes}
        @param host: The hostname.
        N)serviceuserhost)selfr   r   r    r   8/usr/lib/python3/dist-packages/twisted/mail/protocols.py__init__+   s    zDomainDeliveryBase.__init__c           	      C   s   d }}| j rd| j d }|d r2d|d  }d|d  d |d  d	 | | }d
| j d | j d td d }ddtt| d t	  }d| d | d | S )a  
        Generate a received header string for a message.

        @type helo: 2-L{tuple} of (L{bytes}, L{bytes})
        @param helo: The client's identity as sent in the HELO command and its
            IP address.

        @type origin: L{Address}
        @param origin: The origination address of the message.

        @type recipients: L{list} of L{User}
        @param recipients: The destination addresses for the message.

        @rtype: L{bytes}
        @return: A received header string.
            s    auth=Zxtextr   s    helo=s   from s    ([      ]s   by s    with s    (ascii   )s   for <    s   > s
   Received: s   
	)
r   encoder   protocolNamer   joinmapbytesr   Z
rfc822date)	r   helooriginZ
recipientsZauthStrZheloStrZfromUserZbyZforUserr   r   r   receivedHeader;   s2    z!DomainDeliveryBase.receivedHeaderc                 C   sX   | j r:| jjr:| jj|jjd}|dkrJt| jd}n| jj|jj }t	
|j|S )a9  
        Validate the address for which a message is destined.

        @type user: L{User}
        @param user: The destination address.

        @rtype: L{Deferred <defer.Deferred>} which successfully fires with
            no-argument callable which returns L{IMessage <smtp.IMessage>}
            provider.
        @return: A deferred which successfully fires with a no-argument
            callable which returns a message receiver for the destination.

        @raise SMTPBadRcpt: When messages cannot be accepted for the
            destination address.
        NT)r   r   Zqueuedomainsgetdestdomainr   ZDomainQueuerr   ZmaybeDeferredexists)r   r   dr   r   r   
validateTo[   s    zDomainDeliveryBase.validateToc                 C   s8   |st |dd|jdkr4|jdkr4t |dd|S )a  
        Validate the address from which a message originates.

        @type helo: 2-L{tuple} of (L{bytes}, L{bytes})
        @param helo: The client's identity as sent in the HELO command and its
            IP address.

        @type origin: L{Address}
        @param origin: The origination address of the message.

        @rtype: L{Address}
        @return: The origination address.

        @raise SMTPBadSender: When messages cannot be accepted from the
            origination address.
        i  zWho are you?  Say HELO first.r   i  z#Sender address must contain domain.)r   ZSMTPBadSenderZlocalr(   )r   r"   r#   r   r   r   validateFromu   s    zDomainDeliveryBase.validateFrom)__name__
__module____qualname____doc__r   r   r   ZDNSNAMEr   r$   r+   r,   r   r   r   r   r      s    r   c                   @   s   e Zd ZdZdZdS )SMTPDomainDeliveryzA
    A domain delivery base class for use in an SMTP server.
    s   smtpNr-   r.   r/   r0   r   r   r   r   r   r1      s   r1   c                   @   s   e Zd ZdZdZdS )ESMTPDomainDeliveryzB
    A domain delivery base class for use in an ESMTP server.
    s   esmtpNr2   r   r   r   r   r3      s   r3   c                   @   s,   e Zd ZdZejZdZdddZdd Z	dS )SMTPFactorya;  
    An SMTP server protocol factory.

    @ivar service: See L{__init__}
    @ivar portal: See L{__init__}

    @type protocol: no-argument callable which returns a L{Protocol
        <protocol.Protocol>} subclass
    @ivar protocol: A callable which creates a protocol.  The default value is
        L{SMTP}.
    Nc                 C   s   t j|  || _|| _dS )z
        @type service: L{MailService}
        @param service: An email service.

        @type portal: L{Portal <twisted.cred.portal.Portal>} or
            L{None}
        @param portal: A portal to use for authentication.
        N)r   r4   r   r   portal)r   r   r5   r   r   r   r      s    	zSMTPFactory.__init__c                 C   s2   t d|f  tj| |}| j|_| j|_|S )a  
        Create an instance of an SMTP server protocol.

        @type addr: L{IAddress <twisted.internet.interfaces.IAddress>} provider
        @param addr: The address of the SMTP client.

        @rtype: L{SMTP}
        @return: An SMTP protocol.
        zConnection from %s)r	   msgr   r4   buildProtocolr   r5   r   Zaddrpr   r   r   r7      s
    
zSMTPFactory.buildProtocol)N)
r-   r.   r/   r0   r   ZSMTPr   r5   r   r7   r   r   r   r   r4      s
   
r4   c                   @   s*   e Zd ZdZejZdZdd Zdd Z	dS )ESMTPFactorya  
    An ESMTP server protocol factory.

    @type protocol: no-argument callable which returns a L{Protocol
        <protocol.Protocol>} subclass
    @ivar protocol: A callable which creates a protocol.  The default value is
        L{ESMTP}.

    @type context: L{IOpenSSLContextFactory
        <twisted.internet.interfaces.IOpenSSLContextFactory>} or L{None}
    @ivar context: A factory to generate contexts to be used in negotiating
        encrypted communication.

    @type challengers: L{dict} mapping L{bytes} to no-argument callable which
        returns L{ICredentials <twisted.cred.credentials.ICredentials>}
        subclass provider.
    @ivar challengers: A mapping of acceptable authorization mechanism to
        callable which creates credentials to use for authentication.
    Nc                 G   s   t j| f|  dti| _dS )zk
        @param args: Arguments for L{SMTPFactory.__init__}

        @see: L{SMTPFactory.__init__}
        s   CRAM-MD5N)r4   r   r
   challengers)r   argsr   r   r   r      s     zESMTPFactory.__init__c                 C   s    t | |}| j|_| j|_|S )a  
        Create an instance of an ESMTP server protocol.

        @type addr: L{IAddress <twisted.internet.interfaces.IAddress>} provider
        @param addr: The address of the ESMTP client.

        @rtype: L{ESMTP}
        @return: An ESMTP protocol.
        )r4   r7   r;   contextZctxr8   r   r   r   r7      s    
zESMTPFactory.buildProtocol)
r-   r.   r/   r0   r   ZESMTPr   r=   r   r7   r   r   r   r   r:      s
   r:   c                   @   s0   e Zd ZdZdZdZdd Zdd Zdd	 ZdS )
VirtualPOP3a[  
    A virtual hosting POP3 server.

    @type service: L{MailService}
    @ivar service: The email service that created this server.  This must be
        set by the service.

    @type domainSpecifier: L{bytes}
    @ivar domainSpecifier: The character to use to split an email address into
        local-part and domain. The default is '@'.
    N   @c                 C   s`   |  |\}}z| j|}W n  tk
r>   tt  Y S X |t	| j
||dtjS dS )a1  
        Perform APOP authentication.

        Override the default lookup scheme to allow virtual domains.

        @type user: L{bytes}
        @param user: The name of the user attempting to log in.

        @type digest: L{bytes}
        @param digest: The challenge response.

        @rtype: L{Deferred} which successfully results in 3-L{tuple} of
            (L{IMailbox <pop3.IMailbox>}, L{IMailbox <pop3.IMailbox>}
            provider, no-argument callable)
        @return: A deferred which fires when authentication is complete.
            If successful, it returns an L{IMailbox <pop3.IMailbox>} interface,
            a mailbox and a logout function. If authentication fails, the
            deferred fails with an L{UnauthorizedLogin
            <twisted.cred.error.UnauthorizedLogin>} error.
        N)lookupDomainr   lookupPortalKeyErrorr   failr   loginr   ZAPOPCredentialsmagicIMailbox)r   r   Zdigestr(   r5   r   r   r   authenticateUserAPOP  s    z VirtualPOP3.authenticateUserAPOPc                 C   sZ   |  |\}}z| j|}W n  tk
r>   tt  Y S X |t||dt	j
S dS )aY  
        Perform authentication for a username/password login.

        Override the default lookup scheme to allow virtual domains.

        @type user: L{bytes}
        @param user: The name of the user attempting to log in.

        @type password: L{bytes}
        @param password: The password to authenticate with.

        @rtype: L{Deferred} which successfully results in 3-L{tuple} of
            (L{IMailbox <pop3.IMailbox>}, L{IMailbox <pop3.IMailbox>}
            provider, no-argument callable)
        @return: A deferred which fires when authentication is complete.
            If successful, it returns an L{IMailbox <pop3.IMailbox>} interface,
            a mailbox and a logout function. If authentication fails, the
            deferred fails with an L{UnauthorizedLogin
            <twisted.cred.error.UnauthorizedLogin>} error.
        N)r@   r   rA   rB   r   rC   r   rD   r   r   rF   )r   r   Zpasswordr(   r5   r   r   r   authenticateUserPASS7  s    z VirtualPOP3.authenticateUserPASSc                 C   sZ   z| | jd\}}W n tk
r.   d}Y nX || jjkrRtd|d||fS )a  
        Check whether a domain is among the virtual domains supported by the
        mail service.

        @type user: L{bytes}
        @param user: An email address.

        @rtype: 2-L{tuple} of (L{bytes}, L{bytes})
        @return: The local part and the domain part of the email address if the
            domain is supported.

        @raise POP3Error: When the domain is not supported by the mail service.
        r   r   zno such domain {}zutf-8)	splitdomainSpecifier
ValueErrorr   r%   r   Z	POP3Errorformatdecode)r   r   r(   r   r   r   r@   Y  s    
zVirtualPOP3.lookupDomain)	r-   r.   r/   r0   r   rJ   rG   rH   r@   r   r   r   r   r>     s   ""r>   c                   @   s(   e Zd ZdZeZdZdd Zdd ZdS )POP3Factorya  
    A POP3 server protocol factory.

    @ivar service: See L{__init__}

    @type protocol: no-argument callable which returns a L{Protocol
        <protocol.Protocol>} subclass
    @ivar protocol: A callable which creates a protocol.  The default value is
        L{VirtualPOP3}.
    Nc                 C   s
   || _ dS )zY
        @type service: L{MailService}
        @param service: An email service.
        N)r   )r   r   r   r   r   r     s    zPOP3Factory.__init__c                 C   s   t j| |}| j|_|S )a   
        Create an instance of a POP3 server protocol.

        @type addr: L{IAddress <twisted.internet.interfaces.IAddress>} provider
        @param addr: The address of the POP3 client.

        @rtype: L{POP3}
        @return: A POP3 protocol.
        )r   ServerFactoryr7   r   r8   r   r   r   r7     s    
zPOP3Factory.buildProtocol)	r-   r.   r/   r0   r>   r   r   r   r7   r   r   r   r   rN   r  s
   
rN   N) r0   Z
__future__r   r   Ztwisted.mailr   r   Ztwisted.internetr   r   Ztwisted.copyrightr   Ztwisted.pythonr	   Ztwisted.cred.credentialsr
   r   Ztwisted.cred.errorr   r   Zzope.interfacer   ZIMessageDeliveryr   r1   r3   r4   r:   ZPOP3r>   rO   rN   r   r   r   r   <module>   s&   t/4o