3 \���@sZddlZddlZddlZddlZddlZddlZddlZddlZddlZddl m Z ddl m Z m Z dddddgZejdZd ZGd d �d �Ze�ad Zd ZdZd$dd�ZGdd�dej�ZGdd�dej�ZGdd�de�ZGdd�de�ZGdd�de�ZGdd�d�Zdd�Z e!dk�rVe �Z"e"j#Z#de#k�rle#j$d�Z%e&e#de%�e'�e(�dg�Z)e#e%dd�Z#nddl*Z)e+e)e#�Z,e,e"j-e"j.fe"j/e"j0fe"j1e"j2d�Z3e"j4�r2y ddl5Z5Wn.e6k �r�e7dej8d �ej9d�YnXe5j:d!�d"Z;yej4e;�Wn.ek �rTYnXdS)%�N)�warn)� get_addr_spec�get_angle_addr� SMTPChannel� SMTPServer�DebuggingServer� PureProxy� MailmanProxyzPython SMTP proxy version 0.3c@seZdZdd�Zdd�ZdS)�DevnullcCsdS)N�)�self�msgr r �/usr/lib64/python3.6/smtpd.py�writefsz Devnull.writecCsdS)Nr )r r r r�flushgsz Devnull.flushN)�__name__� __module__� __qualname__rrr r r rr esr � z, i�cCs4ttt�tjd�|r&t|tjd�tj|�dS)N)�file)�print�__doc__�globals�sys�stderr�exit)�coder r r r�usagepsrc@s�eZdZdZdZdZejefdd��Ze dd��Z e dd d fd d �Z d d �Z dd�Ze dd��Zejdd��Ze dd��Zejdd��Ze dd��Zejdd��Ze dd��Zejdd��Ze dd��Zejdd��Ze dd ��Zejd!d ��Ze d"d#��Zejd$d#��Ze d%d&��Zejd'd&��Ze d(d)��Zejd*d)��Ze d+d,��Zejd-d,��Ze d.d/��Zejd0d/��Zd1d2�Zd3d4�Zd5d6�Zd7d8�Zd9d:�Zd;d<�Z d=d>�Z!d?d@�Z"dAdB�Z#dCdD�Z$dEdF�Z%dGdH�Z&dIdJ�Z'dKdL�Z(dMdN�Z)dOdP�Z*dQdR�Z+dS)Srr�icCs|S)Nr )�xr r r�|szSMTPChannel.c Cs*yt|jj��Stk r$|jSXdS)N)�max�command_size_limits�values� ValueError�command_size_limit)r r r r�max_command_size_limit~sz"SMTPChannel.max_command_size_limitNFc Cstjj|||d�||_||_||_||_||_||_|rF|rFt d��|rdd|_ d|_ d|_ t |_nd|_ d|_ td�|_ d |_|j�d|_d |_|jj�tj�|_y|j�|_Wn:tk r�}z|j�|jd tjkr�dSd}~XnXtd t |j�t!d �|j"d|jt#f�dS)N)�mapzFdecode_data and enable_SMTPUTF8 cannot be set to True at the same timerz �.�s �.� FrzPeer:)rz 220 %s %s)$�asynchat� async_chat�__init__� smtp_server�conn�addr�data_size_limit�enable_SMTPUTF8� _decode_datar%� _emptystring�_linesep�_dotsep�NEWLINE�_newline�ord�_set_rset_state� seen_greeting� extended_smtpr#�clear�socketZgetfqdn�fqdnZ getpeername�peer�OSError�close�args�errnoZENOTCONNr�repr� DEBUGSTREAM�push� __version__) r Zserverr1r2r3r(r4� decode_data�errr r rr/�s@   zSMTPChannel.__init__cCs.|j|_d|_g|_d|_d|_|jd�dS)NFrs )�COMMAND� smtp_state�mailfrom�rcpttos�require_SMTPUTF8� num_bytes�set_terminator)r r r r�_set_post_data_state�s z SMTPChannel._set_post_data_statecCs|j�d|_g|_dS)Nr)rT� received_data�received_lines)r r r rr<�szSMTPChannel._set_rset_statecCstdtd�|jS)NzTAccess to __server attribute on SMTPChannel is deprecated, use 'smtp_server' instead�)r�DeprecationWarningr0)r r r r�__server�szSMTPChannel.__servercCstdtd�||_dS)NzRSetting __server attribute on SMTPChannel is deprecated, set 'smtp_server' insteadrW)rrXr0)r �valuer r rrY�scCstdtd�|jS)NzUAccess to __line attribute on SMTPChannel is deprecated, use 'received_lines' insteadrW)rrXrV)r r r r�__line�szSMTPChannel.__linecCstdtd�||_dS)NzSSetting __line attribute on SMTPChannel is deprecated, set 'received_lines' insteadrW)rrXrV)r rZr r rr[�scCstdtd�|jS)NzRAccess to __state attribute on SMTPChannel is deprecated, use 'smtp_state' insteadrW)rrXrN)r r r r�__state�szSMTPChannel.__statecCstdtd�||_dS)NzPSetting __state attribute on SMTPChannel is deprecated, set 'smtp_state' insteadrW)rrXrN)r rZr r rr\�scCstdtd�|jS)NzXAccess to __greeting attribute on SMTPChannel is deprecated, use 'seen_greeting' insteadrW)rrXr=)r r r r� __greeting�szSMTPChannel.__greetingcCstdtd�||_dS)NzVSetting __greeting attribute on SMTPChannel is deprecated, set 'seen_greeting' insteadrW)rrXr=)r rZr r rr]�scCstdtd�|jS)NzSAccess to __mailfrom attribute on SMTPChannel is deprecated, use 'mailfrom' insteadrW)rrXrO)r r r r� __mailfrom�szSMTPChannel.__mailfromcCstdtd�||_dS)NzQSetting __mailfrom attribute on SMTPChannel is deprecated, set 'mailfrom' insteadrW)rrXrO)r rZr r rr^�scCstdtd�|jS)NzQAccess to __rcpttos attribute on SMTPChannel is deprecated, use 'rcpttos' insteadrW)rrXrP)r r r r� __rcpttos�szSMTPChannel.__rcpttoscCstdtd�||_dS)NzOSetting __rcpttos attribute on SMTPChannel is deprecated, set 'rcpttos' insteadrW)rrXrP)r rZr r rr_�scCstdtd�|jS)NzTAccess to __data attribute on SMTPChannel is deprecated, use 'received_data' insteadrW)rrXrU)r r r r�__data�szSMTPChannel.__datacCstdtd�||_dS)NzRSetting __data attribute on SMTPChannel is deprecated, set 'received_data' insteadrW)rrXrU)r rZr r rr`scCstdtd�|jS)NzKAccess to __fqdn attribute on SMTPChannel is deprecated, use 'fqdn' insteadrW)rrXrA)r r r r�__fqdn szSMTPChannel.__fqdncCstdtd�||_dS)NzISetting __fqdn attribute on SMTPChannel is deprecated, set 'fqdn' insteadrW)rrXrA)r rZr r rrascCstdtd�|jS)NzKAccess to __peer attribute on SMTPChannel is deprecated, use 'peer' insteadrW)rrXrB)r r r r�__peerszSMTPChannel.__peercCstdtd�||_dS)NzISetting __peer attribute on SMTPChannel is deprecated, set 'peer' insteadrW)rrXrB)r rZr r rrbscCstdtd�|jS)NzKAccess to __conn attribute on SMTPChannel is deprecated, use 'conn' insteadrW)rrXr1)r r r r�__conn szSMTPChannel.__conncCstdtd�||_dS)NzISetting __conn attribute on SMTPChannel is deprecated, set 'conn' insteadrW)rrXr1)r rZr r rrc%scCstdtd�|jS)NzKAccess to __addr attribute on SMTPChannel is deprecated, use 'addr' insteadrW)rrXr2)r r r r�__addr+szSMTPChannel.__addrcCstdtd�||_dS)NzISetting __addr attribute on SMTPChannel is deprecated, set 'addr' insteadrW)rrXr2)r rZr r rrd0scCs&tjj|t|d|jrdnd��dS)Nz zutf-8�ascii)r-r.rI�bytesrQ)r r r r rrI7s zSMTPChannel.pushcCs|d}|j|jkr|j}n|j|jkr*|j}|r<|j|krr#r&�getattrrgr3�splitr7r8rir:rUrBrOrProrpr0�process_messagerT) r �lineZsz�i�command�argZmax_sz�methodrk�textrE�kwargsZstatusr r r�found_terminatorLsd        zSMTPChannel.found_terminatorcCsH|s|jd�dS|jr&|jd�dS|j�||_|jd|j�dS)Nz501 Syntax: HELO hostnamez503 Duplicate HELO/EHLOz250 %s)rIr=r<rA)r r{r r r� smtp_HELO�s  zSMTPChannel.smtp_HELOcCs�|s|jd�dS|jr&|jd�dS|j�||_d|_|jd|j�|jrr|jd|j�|jdd7<|js�|jd�|jr�|jd �|jdd 7<|jd �dS) Nz501 Syntax: EHLO hostnamez503 Duplicate HELO/EHLOTz250-%sz 250-SIZE %s�MAIL�z 250-8BITMIMEz 250-SMTPUTF8� z250 HELP) rIr=r<r>rAr3r#r5r4)r r{r r r� smtp_EHLO�s&    zSMTPChannel.smtp_EHLOcCs|r|jd�n |jd�dS)Nz501 Syntax: NOOPz250 OK)rI)r r{r r r� smtp_NOOP�s zSMTPChannel.smtp_NOOPcCs|jd�|j�dS)Nz221 Bye)rIZclose_when_done)r r{r r r� smtp_QUIT�s zSMTPChannel.smtp_QUITcCs0t|�}|d|�j�|kr,||d�j�SdS)Nr)rhrsrt)r �keywordr{Zkeylenr r r�_strip_command_keyword�sz"SMTPChannel._strip_command_keywordcCsF|sdS|j�jd�r$t|�\}}n t|�\}}|s<||fS|j|fS)Nr�<)rr)�lstrip� startswithrrZ addr_spec)r r{�address�restr r r�_getaddr�s zSMTPChannel._getaddrcCsNi}xD|D]<}|jd�\}}}|j� s2|r6| r6dS|r>|nd||<q W|S)N�=T)� partition�isalnum)r �params�resultZparam�eqrZr r r� _getparams�s zSMTPChannel._getparamscCs|r�d}|j�}|dkr$|jd�q�|dkr8|jd�q�|dkr^d}|jrR||7}|j|�q�|dkr�d }|jrx||7}|j|�q�|d kr�|jd �q�|d kr�|jd �q�|dkr�|jd�q�|dkr�|jd�q�|dkr�|jd�q�|jd�n |jd�dS)Nz [SP ]ZEHLOz250 Syntax: EHLO hostnameZHELOz250 Syntax: HELO hostnamer�z 250 Syntax: MAIL FROM:
ZRCPTz250 Syntax: RCPT TO:
rgz250 Syntax: DATAZRSETz250 Syntax: RSETZNOOPz250 Syntax: NOOPZQUITz250 Syntax: QUITZVRFYz250 Syntax: VRFY
zD501 Supported commands: EHLO HELO MAIL RCPT DATA RSET NOOP QUIT VRFYzD250 Supported commands: EHLO HELO MAIL RCPT DATA RSET NOOP QUIT VRFY)rsrIr>)r r{ZextendedZlc_argr r r r� smtp_HELP�s:          zSMTPChannel.smtp_HELPcCs@|r2|j|�\}}|r"|jd�q<|jd|�n |jd�dS)NzB252 Cannot VRFY user, but will accept message and attempt deliveryz502 Could not VRFY %sz501 Syntax: VRFY
)r�rI)r r{r�r�r r r� smtp_VRFY�s  zSMTPChannel.smtp_VRFYcCs�|js|jd�dStd|td�d}|jr4|d7}|dkrJ|j|�dS|jd|�}|j|�\}}|sv|j|�dS|j r�|r�|j|�dS|jr�|jd�dS|j�j �|_ |j |j �}|dkr�|j|�dS|j �s|j dd �}|dk�r|jd �dS|j�r>|j d d �}|dk�r&d|_n|d k �r>|jd�dS|j dd�}|�r�|j��sh|j|�dS|j�r�t|�|jk�r�|jd�dSt|j��dk�r�|jd�dS||_td|jtd�|jd�dS)Nz503 Error: send HELO firstz ===> MAIL)rz 501 Syntax: MAIL FROM:
z [SP ]zFROM:z503 Error: nested MAIL commandZBODY�7BIT�8BITMIMEz1501 Error: BODY can only be one of 7BIT, 8BITMIMEZSMTPUTF8FTz&501 Error: SMTPUTF8 takes no argumentsZSIZEz:552 Error: message size exceeds fixed maximum message sizerz:555 MAIL FROM parameters not recognized or not implementedzsender:z250 OK)r�r�)r=rIrrHr>r�r�rOrsrvror�r5�popr4rQ�isdigitr3�intrh�keys)r r{� syntaxerrr�r�Zbody�smtputf8�sizer r r� smtp_MAILsh                     zSMTPChannel.smtp_MAILcCs|js|jd�dStd|td�|js6|jd�dSd}|jrH|d7}|dkr^|j|�dS|jd|�}|j|�\}}|s�|j|�dS|j r�|r�|j|�dS|j�j �|_ |j |j �}|dkr�|j|�dSt |j ��dkr�|jd �dS|jj|�td |jtd�|jd �dS) Nz503 Error: send HELO firstz ===> RCPT)rz503 Error: need MAIL commandz501 Syntax: RCPT TO:
z [SP ]zTO:rz8555 RCPT TO parameters not recognized or not implementedzrecips:z250 OK)r=rIrrHrOr>r�r�rsrvrpr�rhr�rPri)r r{r�r�r�r r r� smtp_RCPT7s@           zSMTPChannel.smtp_RCPTcCs(|r|jd�dS|j�|jd�dS)Nz501 Syntax: RSETz250 OK)rIr<)r r{r r r� smtp_RSETZs  zSMTPChannel.smtp_RSETcCsZ|js|jd�dS|js(|jd�dS|r:|jd�dS|j|_|jd�|jd�dS)Nz503 Error: send HELO firstz503 Error: need RCPT commandz501 Syntax: DATAs . z#354 End data with .)r=rIrPrgrNrS)r r{r r r� smtp_DATAas    zSMTPChannel.smtp_DATAcCs|jd�dS)Nz502 EXPN not implemented)rI)r r{r r r� smtp_EXPNpszSMTPChannel.smtp_EXPN),rrrrMrgr&� collections� defaultdictr#�propertyr'�DATA_SIZE_DEFAULTr/rTr<Z_SMTPChannel__server�setterZ_SMTPChannel__lineZ_SMTPChannel__stateZ_SMTPChannel__greetingZ_SMTPChannel__mailfromZ_SMTPChannel__rcpttosZ_SMTPChannel__dataZ_SMTPChannel__fqdnZ_SMTPChannel__peerZ_SMTPChannel__connZ_SMTPChannel__addrrIrmrr�r�r�r�r�r�r�r�r�r�r�r�r�r�r r r rrws` &            >   # 6#c@s2eZdZeZedddfdd�Zdd�Zdd�ZdS) rNFc Cs�||_||_||_||_||_|r.|r.td��tjj||d�yNt j |dt j i�}|j |dd|dd�|j �|j|�|jd�Wn|j��Yn(Xtd|jjtjtj��||ftd�dS) NzFdecode_data and enable_SMTPUTF8 cannot be set to True at the same time)r(�typerr�z0%s started at %s Local addr: %s Remote addr:%s)r)Z _localaddr� _remoteaddrr3r4r5r%�asyncore� dispatcherr/r@Z getaddrinfoZ SOCK_STREAMZ create_socketZset_reuse_addrZbindZlistenrDr� __class__r�time�ctimerH)r Z localaddrZ remoteaddrr3r(r4rKZ gai_resultsr r rr/xs*  zSMTPServer.__init__cCs6tdt|�td�|j||||j|j|j|j�}dS)NzIncoming connection from %s)r)rrGrH� channel_classr3Z_mapr4r5)r r1r2Zchannelr r r�handle_accepted�szSMTPServer.handle_acceptedcKst�dS)N)�NotImplementedError)r rBrOrPrkr~r r rrw�szSMTPServer.process_message) rrrrr�r�r/r�rwr r r rrts  c@seZdZdd�Zdd�ZdS)rcCsrd}|j�}x`|D]X}|rP| rPd|d}t|t�sDt|jd��}t|�d}t|t�sbt|�}t|�qWdS)NrzX-Peer: rzutf-8)� splitlines� isinstancerjrG�encoder)r rBrkZ inheaders�linesrxZ peerheaderr r r�_print_message_content�s     z&DebuggingServer._print_message_contentcKsXtd�|r@|jd�r&td|d�|jd�r@td|d�|j||�td�dS)Nz%---------- MESSAGE FOLLOWS ----------rozmail options: %srpzrcpt options: %s z%------------ END MESSAGE ------------)r�getr�)r rBrOrPrkr~r r rrw�s   zDebuggingServer.process_messageN)rrrr�rwr r r rr�scs,eZdZ�fdd�Zdd�Zdd�Z�ZS)rcs.d|kr|drtd��tt|�j||�dS)Nr4z$PureProxy does not support SMTPUTF8.)r%�superrr/)r rEr~)r�r rr/�szPureProxy.__init__c Csh|jd�}d}x|D]}|sP|d7}qW|j|d|d�tj|�}|j|||�}td|td�dS)Nrrrz X-Peer: %szwe got some refusals:)r)rv�insertr9rq�_deliverrrH) r rBrOrPrkr�ryrx�refusedr r rrw�s    zPureProxy.process_messagec Cs�ddl}i}yB|j�}|j|jd|jd�z|j|||�}Wd|j�XWn�|jk r�}ztdtd�|j }WYdd}~Xnjt |j fk r�}zHtd|j td�t |dd �}t |dd�} x|D]} || f|| <q�WWYdd}~XnX|S) Nrrzgot SMTPRecipientsRefused)rZgotZ smtp_codeZ smtp_error�ignore�����)�smtplibZSMTPZconnectr�Zsendmail�quitZSMTPRecipientsRefusedrrHZ recipientsrCZ SMTPExceptionr�ru) r rOrPrkr�r��s�eZerrcode�errmsg�rr r rr��s$    "zPureProxy._deliver)rrrr/rwr�� __classcell__r r )r�rr�s cs$eZdZ�fdd�Zdd�Z�ZS)r cs.d|kr|drtd��tt|�j||�dS)Nr4z'MailmanProxy does not support SMTPUTF8.)r%r�rr/)r rEr~)r�r rr/ szMailmanProxy.__init__cCs:ddlm}ddlm}ddlm}ddlm}g} x~|D]v} | j�jd�d} | jd�} t| �dkrhq:| d} t| �dkr�| d }nd }|j | � s:|d!kr�q:| j | | |f�q:Wx| D]\} } }|j | �q�Wt ddj |�td�|�r|j|||�}t d|td�i}||�}|j|�}|jd��s2||d<|jd��sPtjtj��|d<x�| D]�\} } }t d| td�|j| �}|�s�|j| dd�}||| <|d k�r�|j|d d�n�|d k�r�|j|d d�nh|d k�r�|j|d d�nN|d k�r�|j|d d�n4|d"k�rV|dk�rd|d<nd |d<|j|d d��qVWdS)#Nr)�StringIO)�Utils)�Message)�MailList�@�-rWrr�admin�owner�requestrq�leavezforwarding recips:rn)rzwe got refusals:�fromZFromZdateZDatezsending message to)�lock)�tolist)Ztoadmin)Ztoowner)Z torequestZ subscribeZSubjectZ unsubscribe)rr�r�r�rqr�)rqr�)�ior�ZMailmanr�r�r��lowerrvrhZ list_existsri�removerrqrHr�r�r�r�ZEnqueue)r rBrOrPrkr�r�r�r�Z listnamesZrcptZlocal�partsZlistnamerzr�Zmlistsr�r Zmlistr r rrwsd                    zMailmanProxy.process_message)rrrr/rwr�r r )r�rr s c@seZdZdZdZdZdZdS)�OptionsTrNF)rrr�setuid� classname� size_limitr4r r r rr�_sr�c !Csty.tjtjdd�dddddddd g�\}}Wn.tjk r\}ztd|�WYdd}~XnXt�}x�|D]�\}}|d'kr�td �qj|d(kr�tt�tjd �qj|d)kr�d|_ qj|d*kr�||_ qj|d+kr�tj a qj|d,kr�d|_ qj|d-krjyt|�}||_Wqjtd|tj d�tjd�YqjXqjWt|�dk�r@d}d}nPt|�dk�r\|d }d}n4t|�d k�r||d }|d}ntdd!tj|��|jd"�} | d k�r�tdd#|�|d| �|_yt|| dd��|_Wn$tk �r�tdd$|�YnX|jd"�} | d k�r"tdd%|�|d| �|_yt|| dd��|_Wn$tk �rntdd&|�YnX|S).Nrz nVhc:s:duzclass=Znosetuid�version�helpzsize=�debugr��-h�--helpr�-V� --version�-n� --nosetuidF�-c�--class�-d�--debug�-u� --smtputf8T�-s�--sizezInvalid size: )rzlocalhost:8025z localhost:25rW�zInvalid arguments: %s�:zBad local spec: %szBad local port: %szBad remote spec: %szBad remote port: %s)r�r�)r�r�)r�r�)r�r�)r�r�)r�r�)r�r�)�getoptr�argv�errorrr�rrJrr�r�rrHr4r�r�rh� COMMASPACErqrr� localhost� localportr%� remotehost� remoteport) ZoptsrEr��options�optr{Zint_sizeZ localspecZ remotespecryr r r� parseargsfsp         r��__main__r)r)r4z7Cannot import module "pwd"; try running with -n option.)r�nobodyrWz3Cannot setuid "nobody"; try running with -n option.)r)?r�osrFr�r�r@r�r-r��warningsrZemail._header_value_parserrr�__all__r�ZprogramrJr rHr9r�r�rr.rr�rrrr r�r�rr�r��rfindZlastdot� __import__r�locals�modr�ruZclass_r�r�r�r�r�r4�proxyr��pwd� ImportErrorrrr�getpwnamr��PermissionErrorZloop�KeyboardInterruptr r r r�Psv   M-SB