Current File : //proc/self/root/lib/python3/dist-packages/twisted/mail/__pycache__/smtp.cpython-312.pyc
�

Ϫ�fk��
�dZddlZddlZddlZddlZddlZddlZddlZddlZddl	m
Z
ddlmZddl
mZddlmZddlmZddlmZdd	lmZmZmZmZdd
lmZddlmZmZddlm Z m!Z!m"Z#dd
l$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z6m7Z7ddl8m9Z9m:Z:m;Z;m<Z=ddl>m?Z?m@Z@ddlAmBZBmCZCddlDmEZEmFZFmGZGddlHmIZIgd�ZJeIj��r!ej��j�d�ZNn ej��j�d�ZNePj�eRdd��ZSdDd�ZTd�ZUeU�ZVdd�fd�ZWd�ZXd\ZYZZZ[dZ\Gd�d�Z]Gd �d!�Z^Gd"�d#e?j�e@j��ZaGd$�d%ej��ZcGd&�d'e?j�e@j��ZeGd(�d)ee�ZfGd*�d+ea�ZgGd,�d-�ZhGd.�d/ehee�ZiGd0�d1ej��ZkGd2�d3e#�Z"ee9�Gd4�d5��ZlGd6�d7ehef�ZmGd8�d9ek�Zndd:eddd;d;fd<�ZoddlpZpdEd=�ZqdEd>�ZrGd?�d@epj��ZtGdA�dBepj��ZvdC�Zwepj�ew�y)Fz/
Simple Mail Transfer Protocol implementation.
�N)�	parseaddr)�BytesIO)�Type)�implementer)�cred)�longversion)�defer�error�protocol�reactor)�	_idnaText)�
ISSLTransport�
ITLSTransport)�CramMD5ClientAuthenticator�LOGINAuthenticator�LOGINCredentials)�AddressError�AUTHDeclinedError�AuthenticationError�AUTHRequiredError�EHLORequiredError�ESMTPClientError�SMTPAddressError�SMTPBadRcpt�
SMTPBadSender�SMTPClientError�SMTPConnectError�SMTPDeliveryError�	SMTPError�SMTPProtocolError�SMTPServerError�SMTPTimeoutError�SMTPTLSError�TLSRequiredError)�IClientAuthentication�IMessageDelivery�IMessageDeliveryFactory�IMessageSMTP)�basic�policies)�log�util)�	iterbytes�nativeString�
networkString)�platform)0rrrrrrrrrrrrrr!r"�TLSErrorr$r r%�IMessager&r'rrr�PLAINAuthenticator�Address�User�sendmail�SenderMixin�ESMTP�ESMTPClient�ESMTPSender�ESMTPSenderFactory�SMTP�
SMTPClient�SMTPFactory�
SMTPSender�SMTPSenderFactory�idGenerator�	messageid�	quoteaddr�
rfc822date�xtextStreamReader�xtextStreamWriter�xtext_codec�xtext_decode�xtext_encode�ascii��i,c��|s+|rtj�}ntj�}|rl|drtj}ntj}tt
|�d�\}}|r|tt
|�|z�z}t|d�\}}nd\}}tdgd�|d|dgd	�|d
d
z
|d|d|d
|d||f	z�S)a�
    Format an RFC-2822 compliant date string.

    @param timeinfo: (optional) A sequence as returned by C{time.localtime()}
        or C{time.gmtime()}. Default is now.
    @param local: (optional) Indicates if the supplied time is local or
        universal time, or if no time is given, whether now should be local or
        universal time. Default is local, as suggested (SHOULD) by rfc-2822.

    @returns: A L{bytes} representing the time and date in RFC-2822 format.
    �i�<)rrz)%s, %02d %s %04d %02d:%02d:%02d %+03d%02d)�Mon�Tue�Wed�Thu�Fri�Sat�Sun��)�Jan�Feb�Mar�Apr�May�Jun�Jul�Aug�Sep�Oct�Nov�Dec�r���)	�time�	localtime�gmtime�altzone�timezone�divmod�abs�intr/)�timeinfo�local�tz�tzhr�tzmin�tzsecs      �3/usr/lib/python3/dist-packages/twisted/mail/smtp.pyrDrD�s������~�~�'�H��{�{�}�H���A�;��,�,��B��-�-��B��s�2�w��-�
��u�
��C��B��2�
�&�&�D���r�*�����
��u��3�=�h�q�k�J��Q�K�

��q�k�A�o�

�
�Q�K��Q�K��Q�K��Q�K���-
�	
���c#�$K�d}	|��|dz
}�
�w)Nrrd�)�is rvrArA�s!����	�A�
���	�Q����s�c� �tt�S�N)�next�_genryrwrv�<lambda>r�s
��4��:�rwc	�.�tjdtj��}tj�}tjd�}|�d}nd|z}dj|||||�tj��j�S)z�
    Return a globally unique random string in RFC 2822 Message-ID format

    <datetime.pid.random@host.dom.ain>

    Optional uniq string will be added to strengthen uniqueness if given.
    z%Y%m%d%H%M%Si�����.z<{}.{}.{}{}.{}@{}>)rh�strftimerj�os�getpid�random�	randrange�format�DNSNAME�decode�encode)�uniq�N�datetime�pid�rands     rvrBrB�sx���}�}�^�T�[�[�]�;�H�
�)�)�+�C����I�&�D��|����T�z���&�&��#�t�T�1�3����(8���f�h�rwc��t|t�rdt|�zdzSt|t�r|jd�}t	|�}|dk(rdt|�zdzSd|djd�zdzS)zq
    Turn an email address, possibly with realname part etc, into
    a form suitable for and SMTP envelope.
    �<�>rJ�NNrd)�
isinstancer4�bytesr�rr�)�addr�ress  rvrCrC�s|���$�� ��e�D�k�!�D�(�(��$����{�{�7�#��
�D�/�C�
�l���e�D�k�!�D�(�(��c�!�f�m�m�G�,�,�t�3�3rw)�COMMAND�DATA�AUTHs[-A-Za-z0-9!\#$%&'*+/=?^_`{|}~]c���eZdZdZej
dezdzej�Zej
e�Z	dd�Z
ej
d�Zd�Zde
fd	�Zdefd
�Zde
fd�Zy)
r4aFParse and hold an RFC 2821 address.

    Source routes are stipped and ignored, UUCP-style bang-paths
    and %-style routing are not parsed.

    @type domain: C{bytes}
    @ivar domain: The domain within which this address resides.

    @type local: C{bytes}
    @ivar local: The local ("user") portion of this address.
    s�( # A string of
                           (?:"[^"]*" # quoted string
                           |\\. # backslash-escaped characted
                           |sL # atom character
                           )+|.) # or any single characterNc��t|t�r|j}t|t�r |jj�|_yt|t�st|�jd�}||_	ttd|jj|���}g}g}|r�|ddk(r|ddk7rtd��|dd}n�|ddk(rE|dd}|s-|r|dd	k7r|dd}|r	|dd	k7r�|std
��|dd}n�|rtd��dg}n}t|d�dk(r<|j j#|d�s|dd
k7rtd|d�d||f����|s|j%|d�n|j%|d�|dd}|r��dj'|�|_dj'|�|_|j(dk7r |j*dk(r|�t,}||_yyy)NrJrr����r�z
Unbalanced <>rd�@�:zMalformed source routez
Too many @rw�.zParse error at z of )r�r5�destr4�__dict__�copyr��strr��addrstr�list�filter�tstring�splitr�len�atomre�match�append�joinrq�domainr�)�selfr��
defaultDomain�atlrqr�s      rv�__init__zAddress.__init__s����d�D�!��9�9�D��d�G�$� �M�M�.�.�0�D�M���D�%�(��t�9�#�#�G�,�D�����6�$���� 2� 2�4� 8�9�:��������1�v��~��r�7�d�?�&��7�7��!�B�i���Q��4���!�"�g����#�a�&�D�.�!�!�"�g���#�a�&�D�.��*�+C�D�D��a�b�'�C��&�|�4�4�"�U�F��S��V���!�$�+�+�*;�*;�C��F�*C��A��RV��"�_�S��V�J�d�D�#�;�/�#R�S�S���L�L��Q��(��M�M�#�a�&�)��!�"�g��7�:�X�X�e�_��
��h�h�v�&����:�:�������!3��$� '�
�'�D�K�"4�rws\\(.)c��g}t|t�st|�jd�}t	d|j
j
|��}|D]h}|ddk(r|ddk(r|j|dd��(d|vr,|j|jjd|���X|j|��jd	j|�S)
z6
        Remove RFC-2821 quotes from address.
        rJNr�"r�rd�\s\1rw)r�r�r�r�r�r�r�r��	dequotebs�subr�)r�r�r�r��ts     rv�dequotezAddress.dequoteJs������$��&��t�9�#�#�G�,�D��T�4�<�<�-�-�d�3�4���	�A���t�t�|��"���
��
�
�1�Q�r�7�#�����
�
�4�>�>�-�-�f�a�8�9��
�
�1�
�
	��x�x��}�rw�returnc�@�|j�jd�S�NrJ��	__bytes__r��r�s rv�__str__zAddress.__str___����~�~��&�&�w�/�/rwc��|js|jr'dj|j|jf�Sy)Nr�rw)rqr�r�r�s rvr�zAddress.__bytes__bs.���:�:�����9�9�d�j�j�$�+�+�6�7�7�rwc	��dj|j|jjt	t|���S)Nz	{}.{}({}))r��
__module__�	__class__�__name__�reprr�r�s rv�__repr__zAddress.__repr__hs2���!�!��O�O�T�^�^�4�4�d�3�t�9�o�
�	
rwr|)r�r��__qualname__�__doc__�re�compile�atom�Xr�r�r�r�r�r�r�r�r�r�ryrwrvr4r4�s���
��b�j�j�	 ��		�
>�	>�	���	�G��R�Z�Z��
�F�2(�h��
�
�9�%�I��*0��0��5��
�#�
rwr4c�4�eZdZdZd�Zd�Zdefd�Zdefd�Z	y)r5zu
    Hold information about and SMTP message recipient,
    including information on where the message came from
    c���	|j}t||�|_||_||_t
|t�r||_yt||�|_y#t$rd}Y�VwxYwr|)�host�AttributeErrorr4r��helorr��orig)r��destinationr�rr�r�s      rvr�z
User.__init__tsc��	��=�=�D��K��.��	���	� ��
��d�G�$��D�I���d�+�D�I���	��D�	�s�A�A%�$A%c�L�|j|jd|jd�S)z�
        Helper for pickle.

        protocol isn't picklabe, but we want User to be, so skip it in
        the pickle.
        N)r�r�rr�)r�r�r�r�s rv�__getstate__zUser.__getstate__�s&���I�I��I�I���I�I�	
�	
rwr�c�@�|j�jd�Sr�r�r�s rvr�zUser.__str__�r�rwc�,�t|j�Sr|)r�r�r�s rvr�zUser.__bytes__�s���T�Y�Y��rwN)
r�r�r�r�r�r�r�r�r�r�ryrwrvr5r5ns)���
,�
�0��0� �5� rwr5c��eZdZdZdZdZdZdZdZdZ	d*d�Z
ed��Zejd��Zd�Zd	�Zd
�Zd+d�Zd�Zd
�Zd�Zd�Zd�Zd�Zd�Zd�ZdezdzZej:dezdzezdzej<ej>z�Z ej:dezdzezdzej<ej>z�Z!d�Z"d,d�Z#d�Z$d�Z%d-d�Z&d�Z'd �Z(d!�Z)d"�Z*d#�Z+d$�Z,e,Z-d%�Z.d&�Z/d'�Z0d(�Z1d)�Z2y).r<zp
    SMTP server-side protocol.

    @ivar host: The hostname of this mail server.
    @type host: L{bytes}
    �XNTc�v�t|_d|_d|_g|_||_||_t|_yr|)	r��mode�_from�_helo�_to�delivery�deliveryFactoryr�r�)r�r�r�s   rvr�z
SMTP.__init__�s4����	���
���
���� ��
�.�����	rwc��|jSr|)�_hostr�s rvr�z	SMTP.host�s���z�z�rwc�f�t|t�st|�jd�}||_yr�)r�r�r�r�r�)r��toSets  rvr�z	SMTP.host�s'���%��'���J�%�%�g�.�E���
rwc�z�|jdz}|jd|�|jj�y)Ns' Timeout. Try talking faster next time!i�)r��sendCode�	transport�loseConnection)r��msgs  rv�timeoutConnectionzSMTP.timeoutConnection�s/���i�i�D�D���
�
�c�3�����%�%�'rwc� �|jdzS)Ns NO UCE NO UBE NO RELAY PROBES)r�r�s rv�greetingz
SMTP.greeting�s���y�y�<�<�<rwc��|jj�}	|j}d|f|_|j
d|j��|j|j�y#t$rt	|�}Y�[wxYw�N��)
r��getPeerr�r�r�r�r�r��
setTimeout�timeout)r��peerr�s   rv�connectionMadezSMTP.connectionMade�sm���~�~�%�%�'��	��9�9�D��D�\��
��
�
�c�4�=�=�?�+�������%��	�	��t�9�D�	�s�A-�-B�Bc���|j�}|dd}|ddD]#}|jtd|fz�|z��%|jtd|fz�|xr|dxsdz�y)z3
        Send an SMTP code with a message.
        r�Nz%3.3d-z%3.3d rrw)�
splitlines�sendLiner/)r��code�message�lines�lastline�lines      rvr�z
SMTP.sendCode�s���"�"�$�����:���#�2�J�	D�D��M�M�-��D�7�(:�;�d�B�C�	D��
�
��(�d�W�,�-��1I�h�q�k�1P�S�Q�	
rwc�`�|j�t|d|jz�|�S)N�state_)�resetTimeout�getattrr��r�rs  rv�lineReceivedzSMTP.lineReceived�s+������2�w�t�X��	�	�1�2�4�8�8rwc��|j�}|jdd�}|rE|j|d�xs|j}t	|�dk(r||d�y|d�y|j�y)NrdrrWrw)�stripr��lookupMethod�
do_UNKNOWNr��sendSyntaxError)r�r�parts�methods    rv�
state_COMMANDzSMTP.state_COMMAND�si���z�z�|���
�
�4��#����&�&�u�Q�x�0�C�D�O�O�F��5�z�Q���u�Q�x� ��s��� � �"rwc�(�|jdd�y)N��sError: bad syntax�r�r�s rvrzSMTP.sendSyntaxError�s���
�
�c�/�0rwc�t�t|t�st|�}t|d|j	�zd�S)z�

        @param command: The command to get from this class.
        @type command: L{str}
        @return: The function which executes this command.
        �do_N)r�r�r.r�upper)r��commands  rvr	zSMTP.lookupMethod�s2���'�3�'�"�7�+�G��t�U�W�]�]�_�4�d�;�;rwc��|jtur.|jD]}|j��t|_|`|jdd�y)Nrs
Line too long)r�r��_SMTP__messages�connectionLostr�r�)r�rr�s   rv�lineLengthExceededzSMTP.lineLengthExceeded
sH���9�9����?�?�
)���&�&�(�
)��D�I����
�
�c�+�,rwc�(�|jdd�y)NrsCommand not implementedr�r��rests  rvr
zSMTP.do_UNKNOWNs���
�
�c�5�6rwc�@�|jj�}	|j}t|t�s|jd�}||f|_d|_	g|_
|jd|jdz|zdz�y#t$rt	|�}Y�twxYw)N�idna�� Hello s, nice to meet you)r�r�r�r�r�r�r�r�r�r�r�r�)r�rr�r�s    rv�do_HELOzSMTP.do_HELOs����~�~�%�%�'��	��9�9�D��$��&��;�;�v�&�D��D�\��
���
�����
�
�c�4�9�9�z�1�D�8�;P�P�Q���	��t�9�D�	�s�B�B�Bc�\�|jdd�|jj�y)N��s
See you later)r�r�r�rs  rv�do_QUITzSMTP.do_QUIT$s!���
�
�c�+�,����%�%�'rws
("[^"]*"|\\.|s	|[@.,:])+s>\s*FROM:\s*(?P<path><> # Empty <>
                          |<s&> # <addr>
                          |sq # addr
                          )\s*(\s(?P<opts>.*))? # Optional WS + ESMTP options
                          $s\s*TO:\s*(?P<path><c	��|jr|jdd�yg|_|jj	|�}|s|jdd�y	t|j
d�|j�}tj|j|j|�}|j|j |j"�y#t$r.}|jdtt|���Yd}~yd}~wwxYw)N�s#Only one sender per message, please��Syntax error�path�))r�r�r��mail_rer�r4�groupr�rr/r�r	�
maybeDeferred�validateFromr��addCallbacks�_cbFromValidate�_ebFromValidate)r�r�mr��e�	validateds      rv�do_MAILzSMTP.do_MAILDs����:�:��M�M�#�E�F������L�L���t�$����M�M�#��/��	��1�7�7�6�?�D�I�I�6�D�
�'�'��(9�(9�4�:�:�t�L�	����t�3�3�T�5I�5I�J���	��M�M�#�}�S��V�4�5���	�s�%C�	D�$D�Dc�6�||_|j||�yr|)r�r�)r��	fromEmailr�r�s    rvr0zSMTP._cbFromValidateXs����
��
�
�d�C� rwc��|jt�rj|j|jjdt|jj�zdzt|jj�z�y|jt�rD|j|jjt|jj��ytj|d�|jdd�y)Ns&Cannot receive from specified address �: zSMTP sender validation failure���3Requested action aborted: local error in processing)�checkrr��valuer�rCr�r/�respr!r+�err�r��failures  rvr1zSMTP._ebFromValidate\s����=�=��'��M�M��
�
�"�"�=���
�
� 2� 2�3�4���$�G�M�M�$6�$6�7�8�
��]�]�?�
+��M�M�'�-�-�,�,�m�G�M�M�<N�<N�.O�P��G�G�G�=�>��M�M�#�U�Vrwc	��|js|jdd�y|jj|�}|s|jdd�y	t	|jd�|j||j�}tj|j|�}|j|j|j|f��y#t$r.}|jdtt|���Yd}~yd}~wwxYw)Nr&s!Must have sender before recipientr'r(r)r*)�callbackArgs)r�r��rcpt_rer�r5r,r�rr/r�r	r-�
validateTor/�
_cbToValidate�
_ebToValidate)r�rr2�userr3�ds      rv�do_RCPTzSMTP.do_RCPTms����z�z��M�M�#�C�D���L�L���t�$����M�M�#��/��	����������T�4�:�:�F�D�

�������6��	���t�)�)�4�+=�+=�T�G��T���	��M�M�#�}�S��V�4�5���	�s�1C�	D�$C>�>Dc�j�|�|}|jj||f�|j||�yr|)r�r�r�)r��torHr�r�s     rvrFzSMTP._cbToValidates.���<��D�������r�
�#��
�
�d�C� rwc��|jtt�rD|j|jj
t
|jj��ytj|�|jdd�y)Nr:r;)
r<rr!r�r=r�r/r>r+r?r@s  rvrGzSMTP._ebToValidate�sR���=�=��o�6��M�M�'�-�-�,�,�m�G�M�M�<N�<N�.O�P��G�G�G���M�M�#�U�Vrwc��|D]}	|j��y#t$r,tjd�tj�Y�KwxYw)Nz(msg raised exception from connectionLost)r�
BaseExceptionr+r�r?)r��msgsr�s   rv�_disconnectzSMTP._disconnect�sI���	�C�
��"�"�$�	��!�
����B�C����	�
�s��2A�Ac��|j�|js|jdd�yt|_|j
|j}}|j}d|_g|_d|_g}|D]E\}}	|�}|j|||g�}	|	r|j|	�|j|��G||_dx|_|_|jdd�|j*r9d}t!j,|||D��
cgc]\}}
t/|���c}
}fz�yy#t$rM}
|j|
j|
j�t|_|j|�Yd}
~
yd}
~
wt$rFt!j"�|jdd�t|_|j|�YywxYwcc}
}w)	Nr&s'Must have valid receiver and originator�&sInternal server errorr�bsContinuez-Receiving message for delivery: from=%s to=%s)r�r�r�r�r�r��
datafailed�receivedHeaderrr�r!r�r>r�rQrOr+r?r�_SMTP__inheader�
_SMTP__inbody�noisyr�r�)r�rr��origin�
recipientsrPrH�msgFuncr��rcvdhdrr3�fmt�u�fs              rv�do_DATAzSMTP.do_DATA�s����:�:��d�h�h��M�M�#�I�J����	��z�z�4�:�:�f���X�X�
���
���������'�	�M�D�'�
��i���-�-�d�F�T�F�C����$�$�W�-����C� �
	�$���*+�+���$�-��
�
�c�;�'��:�:�A�C��G�G�C�6��#D�v��1�C��F�#D�E�E�F���!#�
��
�
�a�f�f�a�f�f�-�#��	�� � ��&��� �
����	��
�
�c�#;�<�#��	�� � ��&��
��$Es&�;?D)�G�)	G�2AE:�:AG�Gc�>�|jtur%	|jD]}	|j��|`|jr|j�d|_|jd�y#t$rtj�Y�lwxYw#t$rY�cwxYwr|)
r�r�rrrOr+r?r��	_onLogoutr�)r��reasonr�s   rvrzSMTP.connectionLost�s���
�9�9���
�#���"�G�"��.�.�0�"�
�O��>�>��N�N��!�D�N�������)�"����	�"��"�
��
�s3�B�A-�B�-B
�
B�B
�
B�	B�Bc�D�d|_g|_|jdd�y)NrsI remember nothing.)r�r�r�rs  rv�do_RSETzSMTP.do_RSET�s����
�����
�
�c�1�2rwc�P�|dddk(r�|dk(r�t|_|jr;|j|jj|jj
�y|js|jd�ytj|jD�cgc]}|j���c}d��j|j�|`y|dd}|jry	|jsC|js7d|vrd|_n+|r)|jD]}|jd��d|_
|sd|_
|jD]}|j|��ycc}w#t$r2}||_|jD]}|j!��Yd}~yd}~wwxYw)Nrdr�zthrown awayT)�
consumeErrorsr�rw)r�r�rUr�r�r>r�_messageHandledr	�DeferredList�eomReceived�addCallbackrWrXrr!r)r�rr2r�r3s     rv�dataLineReceivedzSMTP.dataLineReceived�sl�����8�t���t�|�#��	��?�?��M�M�$�/�/�"6�"6����8L�8L�M������(�(��7���"�"�.2�o�o�>��Q�]�]�_�>�d���+�d�2�2�3��O�����8�D��?�?��	)��?�?�4�=�=��4�<�&'�D�O��#'�?�?�2���,�,�S�1�2�$%�D�M�� !��
��?�?�
+���$�$�T�*�
+��1?��4�	)��D�O��?�?�
)���&�&�(�
)��	)�s�E%�*A:E*�*	F%�3(F � F%c���d}|D]"\}}|r�	|dz
}tj|��$|r:d}t|�}|dkDr|d|�d|�d�z
}|jdt	|��y|jdd	�y)
NrrdzCould not send e-mailz (z failures out of z recipients)rSrsDelivery in progress)r+r?r�r�r/)r��
resultList�failures�success�resultr��	resultLens       rvrizSMTP._messageHandleds�����)�	 �O�G�V���A�
�������	 ��)�C��J��I��1�}���H�:�%6�y�k��N�N���M�M�#�}�S�1�2��M�M�#�6�7rwc���|\}}}t|t�r||_d|_n7t|t�rd|_||_nt|j�d���||_d|_y)zR
        Save the state resulting from a successful anonymous cred login.
        Nz is not a supported interface)	�
issubclassr'r�r�r&�RuntimeErrorr�rc�
challenger)r�rr�iface�avatar�logouts     rv�_cbAnonymousAuthenticationzSMTP._cbAnonymousAuthenticationsj��#)������e�4�5�#)�D� � �D�M�
��/�
0�#'�D� �"�D�M��%�.�.�!1�1N�O�P�P������rwc�������j��jj��_�j�+tj�jj
���S�jr}�jjtjj�dtt�}�fd�}|j�j|����fd�}|j|�|St!���)a
        Validate the address from which the message originates.

        @type helo: C{(bytes, bytes)}
        @param helo: The argument to the HELO command and the client's IP
        address.

        @type origin: C{Address}
        @param origin: The address the message is from

        @rtype: C{Deferred} or C{Address}
        @return: C{origin} or a C{Deferred} whose callback will be
        passed C{origin}.

        @raise SMTPBadSender: Raised of messages from this address are
        not to be accepted.
        Nc�
��|jtjj�rt	��}n9|jtjj
�rt	�d��}n|St
j|�S)z�
                Translate cred exceptions into SMTP exceptions so that the
                protocol code which invokes C{validateFrom} can properly report
                the failure.
                z#Unauthenticated senders not allowed)r>)r<rr
�UnauthorizedLoginr�UnhandledCredentialsr	�fail)r?�excrZs  �rv�ebAuthenticationz+SMTP.validateFrom.<locals>.ebAuthenticationDs`����9�9�T�Z�Z�9�9�:�'��/�C��Y�Y�t�z�z�>�>�?�'��%J��C��J��z�z�#��&rwc�(���j���S)zE
                Re-attempt from address validation.
                )r.)�ignoredr�rZr�s ���rv�continueValidationz-SMTP.validateFrom.<locals>.continueValidationVs����(�(��v�6�6rw)r��getMessageDeliveryr�r	r-r.�portal�loginr�credentials�	Anonymousr'r&r/r{rlr)r�r�rZrrr�r�s```   rvr.zSMTP.validateFrom!s����$���+� �0�0�C�C�E�D�M��=�=�$��&�&�t�}�}�'A�'A�4��P�P�
�;�;��[�[�&�&�� � �*�*�,��'� �	�F�
'� 
���� ?� ?�AQ�R�
7�
���1�2��M��F�#�#rwc�f�|j�|jj|�St|��)a
        Validate the address for which the message is destined.

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

        @rtype: no-argument callable
        @return: A C{Deferred} which becomes, or a callable which
        takes no arguments and returns an object implementing C{IMessage}.
        This will be called and the returned object used to deliver the
        message when it arrives.

        @raise SMTPBadRcpt: Raised if messages to the address are
        not to be accepted.
        )r�rEr�r�rHs  rvrEzSMTP.validateToas.�� �=�=�$��=�=�+�+�D�1�1��$��rwc��|j�|jj|||�Sd}|drd|dz}t|jj	�j
�}d|dzdz|dzdz|zdz}d	||jjtfz}d
djtt|��t�fz}d|zd
z|zd
z|zS)Nrwrs helo=sfrom s ([rd�]�)sby %s with %s (%s)s
for %s; %s� s
Received: s
	)
r�rVr/r��getHostr�r�r�rr��mapr�rD)	r�r�rZr[�heloStrr��from_�by�for_s	         rvrVzSMTP.receivedHeaderus����=�=�$��=�=�/�/��f�j�I�I�����7��$�q�'�)�G��t�~�~�5�5�7�<�<�=���4��7�"�V�+�d�1�g�5��<�w�F��M��
"�f�d�n�n�.E�.E�{�%S�
S�������S�*�)=� >�
��M�M���u�$�w�.��3�g�=��D�Drwr�)rw)rsSender address accepted)NrsRecipient address accepted)3r�r�r�r�r�r�rYr�r�rcr��propertyr��setterr�r�r�r�rrrr	rr
r!r$r��qstringr�r��Ir�r+rDr5r0r1rJrFrGrQrarrfrm�
state_DATArir{r.rErVryrwrvr<r<�s�����G�
�F�
�E��O��H��I������
�[�[����
(�
=�	&�

�9�#� 1�
<�-�7�
R�(� �$�&��6�G��b�j�j�	 �
�	��	�
�	��
	�	���r�t�t���G��b�j�j��
�	��	��		�
�	�	���r�t�t��
�G�K�(!�W�"U�$!�W��&G�P�(3�
()�T"�J�
8��">$�@ �(Erwr<c�.�eZdZdZeZdZeZdZ	dd�Z
d�Zy)r>z
    Factory for SMTP.
    r�Nc��||_yr|)r�)r�r�s  rvr�zSMTPFactory.__init__�s	����rwc��tjj||�}|j|_|j|_|Sr|)r�
ServerFactory�
buildProtocolr�r�r��r�r��ps   rvr�zSMTPFactory.buildProtocol�s5���"�"�0�0��t�<���;�;���������rwr|)r�r�r�r�r�r�r�r<rr�r�r�ryrwrvr>r>�s'���
�F��G��H�
�F��rwr>c��eZdZdZdZdZdd�Zd�Zd�Ze	jfd�Zd�Zd	�Z
d
�Zd�Zd�Zd
�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zy)r=a�
    SMTP client for sending emails.

    After the client has connected to the SMTP server, it repeatedly calls
    L{SMTPClient.getMailFrom}, L{SMTPClient.getMailTo} and
    L{SMTPClient.getMailData} and uses this information to send an email.
    It then calls L{SMTPClient.getMailFrom} again; if it returns L{None}, the
    client will disconnect, otherwise it will continue as normal i.e. call
    L{SMTPClient.getMailTo} and L{SMTPClient.getMailData} and send a new email.
    TNc���t|t�r|jd�}|xsd|_g|_g|_d|_g|_d|_tj|�|_y)NrJrwr�)r�r�r��identity�toAddressesResult�successAddressesr�r>r�r,�LineLogr+)r�r��logsizes   rvr�zSMTPClient.__init__�sZ���h��$����w�/�H� ��C��
�!#��� "�����
���	���	��<�<��(��rwc��|jr|jjd|z�tjj||�y)Ns>>> )�debugr+r�r)�LineReceiverr�rs  rvr�zSMTPClient.sendLine�s3���:�:��H�H�O�O�G�d�N�+�
���#�#�D�$�/rwc��|j|j�dg|_|j|_|j
|_yr�)r�r��	_expected�smtpState_helo�_okresponse�smtpConnectionFailed�
_failresponser�s rvr�zSMTPClient.connectionMade�s7��������%������.�.���!�6�6��rwc�4�|jd�d|_y)z,
        We are no longer connected
        N)r��mailFile�r�rds  rvrzSMTPClient.connectionLost�s��	
�������
rwc�l�|jtdd|jj���y)Nr�s(Timeout waiting for SMTP server response)�	sendErrorr"r+r�r�s rvr�zSMTPClient.timeoutConnection�s(�������?�������
�	
rwc	��|j�|jr|jjd|z�d}	t	|dd�|_|dddk(ry|jj|dd�|ddd	k(ry|j
|jvr6|j|j
d
j|j��}n5|j|j
d
j|j��}d|_g|_
|S#t$r:|jtdd|��|jj���YywxYw)Ns<<< rer�z#Invalid response from SMTP server: rrd�0rf�-�
)rr�r+r�ror��
ValueErrorr�r r�r>r�r�r�r�)r�r�whys   rvrzSMTPClient.lineReceived�s1�������:�:��H�H�O�O�G�d�N�+���	��D��!�H�
�D�I���!�9�����	�	����a�b��"���!�9�����9�9����&��"�"�4�9�9�e�j�j����.C�D�C��$�$�T�Y�Y��
�
�4�9�9�0E�F�C���	���	��
��;�
	�
�N�N�!��9�$��@��H�H�L�L�N��
�
�
	�s�D�AE�Ec�l�|jt|||jj���yr|)r�rr+r��r�r�r>s   rvr�zSMTPClient.smtpConnectionFailed�s"�����'��d�D�H�H�L�L�N�C�Drwc��|dkr5|jt|||jj���y|j	||�y)Nr)r�r r+r��smtpState_msgSentr�s   rv�smtpTransferFailedzSMTPClient.smtpTransferFaileds9���!�8��N�N�,�T�4�������H�I��"�"�4��.rwc�x�|jd|jz�t|_|j|_y)NsHELO )r�r��SUCCESSr��smtpState_fromr�r�s   rvr�zSMTPClient.smtpState_helos,���
�
�h����.�/� ����.�.��rwc�
�|j�|_|j|_|j�A|j	dt|j�z�dg|_|j|_y|j�y)Ns
MAIL FROM:r)
�getMailFromr�r�r�r�rCr��smtpState_tor��_disconnectFromServerr�s   rvr�zSMTPClient.smtpState_from
si���%�%�'��
�!�4�4����:�:�!��M�M�-�)�D�J�J�*?�?�@�!�U�D�N�#�0�0�D��
�&�&�(rwc�8�|jj�yr|)r�r�r�s   rv�smtpState_disconnectzSMTPClient.smtpState_disconnects�����%�%�'rwc���t|j��|_g|_g|_|j
|_tdd�|_d|_	|jdd�S)Nr��rw)
�iter�	getMailTo�toAddressesr�r��smtpState_toOrDatar��ranger��lastAddressr�s   rvr�zSMTPClient.smtpState_tos\������ 0�1���!#��� "����2�2����q�$��������&�&�q�#�.�.rwc��|j�U|jj|j||f�|tvr%|jj|j�	t|j�|_|jdt|j�z�y#t$rM|jr,|jd�dg|_
|j|_Yy|j|d�cYSwxYw)NsRCPT TO:sDATArTzNo recipients accepted)r�r�r�r�r�r}r�r�rC�
StopIterationr��smtpState_datar�r�r�s   rvr�zSMTPClient.smtpState_toOrData$s������'��"�"�)�)�4�+;�+;�T�4�*H�I��w���%�%�,�,�T�-=�-=�>�
	E�#�D�$4�$4�5�D��
�M�M�+�	�$�2B�2B�(C�C�D���	N��$�$��
�
�g�&�"%����#'�#6�#6�� ��-�-�d�4L�M�M�
	N�s�#B%�%?C;�&C;�:C;c���tj�}|j�j��j�j
�}�fd�}|j
�j|�t�_	�j�_y)Nc�<���j|j�yr|)r�r=)r?r�s �rv�
ebTransferz-SMTPClient.smtpState_data.<locals>.ebTransfer9s����N�N�3�9�9�%rw)r)�
FileSender�beginFileTransfer�getMailDatar��transformChunkr/�finishedFileTransferr�r�r�r�)r�r�r>�srIr�s`     rvr�zSMTPClient.smtpState_data5sh��������
���� 0� 0� 2�D�N�N�D�DW�DW�X��	&�	
���t�0�0�*�=� ����1�1��rwc�
�|j�<|j||t|j�|j|j
�g|_d|_|j
d�t|_|j|_
y)NsRSET)r��sentMailr�r�r�r+r�r�r�r�r�r�s   rvr�zSMTPClient.smtpState_msgSent@sm���:�:�!��M�M��d�C�� 5� 5�6��8N�8N�PT�PX�PX�
�"$�����
��
�
�g�� ����.�.��rwc�f�|j�|jdd�jdd�S)a

        Perform the necessary local to network newline conversion and escape
        leading periods.

        This method also resets the idle timeout so that as long as process is
        being made sending the message body, the client will not time out.
        r�s
�
.s
..)r�replace)r��chunks  rvr�zSMTPClient.transformChunkOs.��	
�����}�}�U�G�,�4�4�X�y�I�Irwc�:�|dk7rd}nd}|j|�y)Nr�r�r�)r�)r��lastsentrs   rvr�zSMTPClient.finishedFileTransferZs ���u���D��D��
�
�d�rwc��t�)z<
        Return the email address the mail is from.
        ��NotImplementedErrorr�s rvr�zSMTPClient.getMailFromc�
��"�!rwc��t�)z5
        Return a list of emails to send to.
        r�r�s rvr�zSMTPClient.getMailToir�rwc��t�)z�
        Return file-like object containing data of message to be sent.

        Lines in the file should be delimited by '\n'.
        r�r�s rvr�zSMTPClient.getMailDataos
��"�!rwc��t|t�r|js|j�y|j	dd�y)a2
        If an error occurs before a mail message is sent sendError will be
        called.  This base class method sends a QUIT if the error is
        non-fatal and disconnects the connection.

        @param exc: The SMTPClientError (or child class) raised
        @type exc: C{SMTPClientError}
        r�N)r�r�isFatalr�r��r�r�s  rvr�zSMTPClient.sendErrorws2���c�?�+�C�K�K��&�&�(�
�%�%�b�$�/rwc��t�)a�
        Called when an attempt to send an email is completed.

        If some addresses were accepted, code and resp are the response
        to the DATA command. If no addresses were accepted, code is -1
        and resp is an informative message.

        @param code: the code returned by the SMTP Server
        @param resp: The string response returned from the SMTP Server
        @param numOk: the number of addresses accepted by the remote host.
        @param addresses: is a list of tuples (address, code, resp) listing
                          the response to each RCPT command.
        @param log: is the SMTP session log
        r�)r�r�r>�numOk�	addressesr+s      rvr�zSMTPClient.sentMail�s
��"�!rwc�j�tdd�|_|j|_|j	d�y)Nrr�sQUIT)r�r�r�r�r�r�s rvr�z SMTPClient._disconnectFromServer�s)���q�$�����4�4����
�
�g�rw)�
)r�r�r�r�r�r�r�r�r�r�connectionDonerr�rr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�ryrwrvr=r=�s���	�
�E��G�
)�0�7�%-�$;�$;��
�(�TE�/�/�
	)�(�/�E�"	2�
/�	J��"�"�"�0� "�"rwr=c��eZdZdZdZdZdZdZdZdd�Z	d�Z
d�Zdd�Zdd	�Z
dd
�Zdd�Zdd�Zdd
�Zdd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zy)r9a
    A client for sending emails over ESMTP.

    @ivar heloFallback: Whether or not to fall back to plain SMTP if the C{EHLO}
        command is not recognised by the server. If L{requireAuthentication} is
        C{True}, or L{requireTransportSecurity} is C{True} and the connection is
        not over TLS, this fallback flag will not be honored.
    @type heloFallback: L{bool}

    @ivar requireAuthentication: If C{True}, refuse to proceed if authentication
        cannot be performed. Overrides L{heloFallback}.
    @type requireAuthentication: L{bool}

    @ivar requireTransportSecurity: If C{True}, refuse to proceed if the
        transport cannot be secured. If the transport layer is not already
        secured via TLS, this will override L{heloFallback}.
    @type requireAuthentication: L{bool}

    @ivar context: The context factory to use for STARTTLS, if desired.
    @type context: L{IOpenSSLClientConnectionCreator}

    @ivar _tlsMode: Whether or not the connection is over TLS.
    @type _tlsMode: L{bool}
    TFNc�`�tj|g|��i|��g|_||_||_yr|)r=r��authenticators�secret�context)r�r��contextFactory�args�kws     rvr�zESMTPClient.__init__�s0�����D�.�4�.�2�.� ������%��rwc��|dk(r(tjdtd��|jSt	|j
j�d|����)N�tlsMode�StlsMode attribute of twisted.mail.smtp.ESMTPClient is deprecated since Twisted 13.0rW��category�
stacklevelz instance has no attribute )�warnings�warn�DeprecationWarning�_tlsModer�r�r�)r��names  rv�__getattr__zESMTPClient.__getattr__�sQ���9���M�M�3�+��	
��=�=� � ��N�N�+�+����
rwc�t�|dk(r$tjdtd��||_y||j|<y)NrrrWr)rrrrr�)r�r	r=s   rv�__setattr__zESMTPClient.__setattr__�s8���9���M�M�3�+��	
�"�D�M�"'�D�M�M�$�rwc�l�|jtdd|jj���y)a�
        Fail because authentication is required, but the server does not support
        ESMTP, which is required for authentication.

        @param code: The server status code from the most recently received
            server message.
        @type code: L{int}

        @param resp: The server status response from the most recently received
            server message.
        @type resp: L{bytes}
        �s,Server does not support ESMTP AuthenticationN)r�rr+r�r�s   rv�esmtpEHLORequiredzESMTPClient.esmtpEHLORequired�s*��	
�����H�$�(�(�,�,�.�
�	
rwc��g}|jD]/}|j|j�j���1ddj	|�z}|jt
dd|z|jj���y)a�
        Fail because authentication is required, but the server does not support
        any schemes we support.

        @param code: The server status code from the most recently received
            server message.
        @type code: L{int}

        @param resp: The server status response from the most recently received
            server message.
        @type resp: L{bytes}
        s[%s]s, rs8Server does not support Client Authentication schemes %sN)	r�r��getNamerr�r�rr+r�)r�r�r>�tmp�a�auths      rv�esmtpAUTHRequiredzESMTPClient.esmtpAUTHRequired�sz�����$�$�	,�A��J�J�q�y�y�{�(�(�*�+�	,�����C��(�������O�RV�V�������
�	
rwc�l�|jtdd|jj���y)a`
        Fail because TLS is required and the server does not support it.

        @param code: The server status code from the most recently received
            server message.
        @type code: L{int}

        @param resp: The server status response from the most recently received
            server message.
        @type resp: L{bytes}
        rs:Server does not support secure communication via TLS / SSLN)r�r$r+r�r�s   rv�esmtpTLSRequiredzESMTPClient.esmtpTLSRequireds+��	
�����Q�������
�	
rwc�l�|jt|d|jj���y)a[
        Fail because the TLS handshake wasn't able to be completed.

        @param code: The server status code from the most recently received
            server message.
        @type code: L{int}

        @param resp: The server status response from the most recently received
            server message.
        @type resp: L{bytes}
        s(Could not complete the SSL/TLS handshakeN)r�r1r+r�r�s   rv�esmtpTLSFailedzESMTPClient.esmtpTLSFailed%s*��	
�����E�t�x�x�|�|�~�
�	
rwc�l�|jt|||jj���y)aM
        Fail because the authentication was rejected.

        @param code: The server status code from the most recently received
            server message.
        @type code: L{int}

        @param resp: The server status response from the most recently received
            server message.
        @type resp: L{bytes}
        N)r�rr+r�r�s   rv�esmtpAUTHDeclinedzESMTPClient.esmtpAUTHDeclined7s$��	
���(��t�T�X�X�\�\�^�D�Erwc�l�|jtdd|jj���y)ab
        Fail because the server sent a malformed authentication challenge.

        @param code: The server status code from the most recently received
            server message.
        @type code: L{int}

        @param resp: The server status response from the most recently received
            server message.
        @type resp: L{bytes}
        r'sRLogin failed because the SMTP Server returned a malformed Authentication ChallengeN�r�rr+r�r�s   rv�esmtpAUTHMalformedChallengez'ESMTPClient.esmtpAUTHMalformedChallengeEs.��	
�����M�������	
�	
rwc�l�|jt|||jj���y)aP
        Fail because of some other authentication error.

        @param code: The server status code from the most recently received
            server message.
        @type code: L{int}

        @param resp: The server status response from the most recently received
            server message.
        @type resp: L{bytes}
        Nrr�s   rv�esmtpAUTHServerErrorz ESMTPClient.esmtpAUTHServerErrorZs$��	
���*�4��t�x�x�|�|�~�F�Grwc�:�|jj|�y)a�
        Registers an Authenticator with the ESMTPClient. The ESMTPClient will
        attempt to login to the SMTP Server in the order the Authenticators are
        registered. The most secure Authentication mechanism should be
        registered first.

        @param auth: The Authentication mechanism to register
        @type auth: L{IClientAuthentication} implementor

        @return: L{None}
        N)r�r�)r�rs  rv�registerAuthenticatorz!ESMTPClient.registerAuthenticatorhs��	
���"�"�4�(rwc��tj|j�|_tj|�|j|_y)zp
        Called when a connection has been made, and triggers sending an C{EHLO}
        to the server.
        N)r�
providedByr�rr=r��esmtpState_ehlor�r�s rvr�zESMTPClient.connectionMadevs6��
&�0�0����@��
��!�!�$�'��/�/��rwc�&�t|_|j|_|j|_|jrd}n|j}|jr|js|s|j|_|jd|jz�y)a�
        Send an C{EHLO} to the server.

        If L{heloFallback} is C{True}, and there is no requirement for TLS or
        authentication, the client will fall back to basic SMTP.

        @param code: The server status code from the most recently received
            server message.
        @type code: L{int}

        @param resp: The server status response from the most recently received
            server message.
        @type resp: L{bytes}

        @return: L{None}
        FsEHLO N)
r�r��esmtpState_serverConfigr�rr�r�requireTransportSecurity�heloFallback�requireAuthenticationr�r�r�)r�r�r>�needTLSs    rvr%zESMTPClient.esmtpState_ehlost��"!����7�7���!�3�3����=�=��G��3�3�G����T�%?�%?��!%�!4�!4�D���
�
�h����.�/rwc��i}|j�D]6}|jdd�}t|�dkDr|d||d<�/d||d<�8|j|||�y)z�
        Handle a positive response to the I{EHLO} command by parsing the
        capabilities in the server's response and then taking the most
        appropriate next step towards entering a mail transaction.
        Nrdr)r�r�r��tryTLS)r�r�r>�itemsrr3s      rvr'z#ESMTPClient.esmtpState_serverConfig�sj�����O�O�%�	#�D��
�
�4��#�A��1�v��z���d��a��d��"��a��d��	#�	
���D�$��&rwc�(�|j}|jxrd|v}|j}|s|s|s|j|||�y|r<dg|_|j
|_|j|_|jd�y|j�y)a�
        Take a necessary step towards being able to begin a mail transaction.

        The step may be to ask the server to being a TLS session.  If TLS is
        already in use or not necessary and not available then the step may be
        to authenticate with the server.  If TLS is necessary and not available,
        fail the mail transmission attempt.

        This is an internal helper method.

        @param code: The server status code from the most recently received
            server message.
        @type code: L{int}

        @param resp: The server status response from the most recently received
            server message.
        @type resp: L{bytes}

        @param items: A mapping of ESMTP extensions offered by the server.  Keys
            are extension identifiers and values are the associated values.
        @type items: L{dict} mapping L{bytes} to L{bytes}

        @return: L{None}
        �STARTTLSr�N)rr�r(�authenticater��esmtpState_starttlsr�rr�r�r)r�r�r>r.�hasTLS�canTLS�mustTLSs       rvr-zESMTPClient.tryTLS�s���J�������6�+��"6���/�/���&�G����d�D�%�0�
�!�U�D�N�#�7�7�D��!%�!4�!4�D���M�M�+�&��!�!�#rwc���	|jj|j�d|_|j||�y#t$r(tj�|jd�Y�CwxYw)z�
        Handle a positive response to the I{STARTTLS} command by starting a new
        TLS session on C{self.transport}.

        Upon success, re-handshake with the server to discover what capabilities
        it has when TLS is in use.
        Tr:N)	r��startTLSr�rrOr+r?rr%r�s   rvr2zESMTPClient.esmtpState_starttls�s^��	%��N�N�#�#�D�L�L�1� �D�M�	
���T�4�(��
�	%��G�G�I�����$�	%�s�,A�.A2�1A2c���|j�r;|jd��r)|dj�}i}|D]}d||j�<�|jD]�}|j�j�}||vs�&||_|dk(r{|j|_|j|_
dg|_tj|jj|jd��}	|jd||	fz�ydg|_|j |_|j"|_
|jd|z�y|j$r|j'�y|j||�y)N�AUTHrd�PLAIN��s
AUTH %s %s�NsAUTH )r��getr�rr�r�	_authinfor�r��_esmtpState_plainAuthr�r��base64�	b64encode�challengeResponser��esmtpState_challenger r*r)
r�r�r>r.�schemes�
tmpSchemesr�rr�	challenges
          rvr1zESMTPClient.authenticate�s]���;�;�5�9�9�W�-��G�n�*�*�,�G��J��
*��()�
�1�7�7�9�%�
*��(�(�
���y�y�{�(�(�*���:�%�%&�D�N��x�'�+/�+>�+>��(�-1�-G�-G��*�*-����$*�$4�$4� �N�N�<�<�T�[�[�!�L�%�	��
�
�m�t�Y�6G�&G�H��+.����+/�+D�+D��(�.2�-F�-F��*��
�
�h��o�6��/
�2�%�%��"�"�$�����d�+rwc���|j|_|j|_dg|_tj|jj|jd��}|jd|z�y)Nr;rWsAUTH PLAIN )r�r�rr�r�r@rAr>rBr�r�)r�r�r>rFs    rvr?z!ESMTPClient._esmtpState_plainAuths^���.�.���!�3�3��������$�$�T�^�^�%E�%E�d�k�k�ST�%U�V�	��
�
�n�y�0�1rwc�<�|j|j|�yr|)�
_authResponser>r�s   rvrCz ESMTPClient.esmtpState_challenge#s�����4�>�>�4�0rwc��|j|_	tj|�}|j	|j
|�}ddg|_|j|_|jtj|��y#tj$r6|jd�|j|_|j|_YywxYw)Nr;r<�*)rr�r@�	b64decoderBr�r��smtpState_maybeAuthenticatedr�r�rA�binascii�Errorr)r�rrFr>s    rvrIzESMTPClient._authResponse&s���!�3�3���	2��(�(��3�I��)�)�$�+�+�y�A�D�!�3�Z�D�N�#�@�@�D���M�M�&�*�*�4�0�1���~�~�	B��M�M�$��#�?�?�D��!%�!A�!A�D��		B�s�B�AC�Cc�p�|dk(r|`|j||�y|j|j|�y)z�
        Called to handle the next message from the server after sending a
        response to a SASL challenge.  The server response might be another
        challenge or it might indicate authentication has succeeded.
        r;N)r>r�rIr�s   rvrMz(ESMTPClient.smtpState_maybeAuthenticated5s6���3�;�������d�+�
���t�~�~�t�4rwr|)r�N)r�r�r�r�r)r*r(r�rr�r
rrrrrrrr r"r�r%r'r-r2r1r?rCrIrMryrwrvr9r9�s����2�L�!��$���G��H�&��$
(�
�&
�8
�(
�$F�
�*H�)�0�0�@'� 1$�f)�&%,�N2�1�
2�5rwr9c�f�eZdZdZdZdZdZdd�Zd�Zd�Z	d�Z
d�Zd�Zd	�Z
d
�Zd�Zd�Zd
�Zd�Zy)r8NFc�`�tj|�|�i}||_d|_||_y)NF)r<r��challengers�
authenticated�ctx)r��chalr�s   rvr�zESMTP.__init__Ks/���
�
�d���<��D����"���!��rwc��tj|�tj|j�|_|j
xr|jdu|_yr|)r<r�rr$r��canStartTLSrUr�s rvr�zESMTP.connectionMadeSsC�����D�!�(�3�3�D�N�N�C����+�+�F�����1E��rwc�2�tj|�dzS)Ns ESMTP)r<r�r�s rvr�zESMTP.greetingXs���}�}�T�"�Y�.�.rwc��dt|jj��i}|jr|jsd|d<|S)z�
        SMTP service extensions

        @return: the SMTP service extensions that are supported.
        @rtype: L{dict} with L{bytes} keys and a value of either L{None} or a
            L{list} of L{bytes}.
        r9Nr0)r�rS�keysrX�
startedTLS)r��exts  rv�
extensionszESMTP.extensions[s@����T�-�-�2�2�4�5�6�����D�O�O�#�C����
rwc��t|�}tj||�}|�t|d|j	�zd�}|S)N�ext_)r.r<r	rr)r�rr2s   rvr	zESMTP.lookupMethodhsA���w�'�����d�G�,���9���f�w�}�}��6��=�A��rwc���g}|j�j�D]B\}}|�*|s�|j|dzdj|�z��2|j|��Ddj|�S)N� r�)r^r.r�r�)r��r�c�vs    rv�listExtensionszESMTP.listExtensionspsj�����O�O�%�+�+�-�	�D�A�q��}���H�H�Q��X��	�	�!��4�5������
	��z�z�!�}�rwc�(�|jj�j}t|t�s|jd�}||f|_d|_g|_|jd|jdz|zdz|j�z�y)Nrrr s, nice to meet you
)r�r�r�r�r�r�r�r�r�r�rf)r�rr�s   rv�do_EHLOz
ESMTP.do_EHLO|s����~�~�%�%�'�,�,���$��&��;�;�v�&�D��D�\��
���
�����
�
���	�	�����*�*��%�%�'�	(�		
rwc��|jr|jdd�y|jrK|jr?|jdd�|jj|j�d|_y|jdd�y)Nr&sTLS already negotiatedr�sBegin TLS negotiation nowT��sTLS not available)r\r�rUrXr�r7rs  rv�ext_STARTTLSzESMTP.ext_STARTTLS�sb���?�?��M�M�#�8�9�
�X�X�$�*�*��M�M�#�;�<��N�N�#�#�D�H�H�-�"�D�O��M�M�#�3�4rwc��|jr|jdd�y|jdd�}|jj	|dj�d���}|s|jdd�yt|_||_t|�dkDr|j�|d}nd}|j|�y)Nr&sAlready authenticatedrdrc��yr|ryryrwrvrz ESMTP.ext_AUTH.<locals>.<lambda>�s�rwi�s Unrecognized authentication type)rTr�r�rSr=rr�r�rwr��getChallenge�
state_AUTH)r�rrrVs    rv�ext_AUTHzESMTP.ext_AUTH�s�������M�M�#�7�8���
�
�4��#��C�t���#�#�E�!�H�N�N�$4�l�C�E����M�M�#�B�C����	�����u�:��>�������8�D��D�����rwc�@�tj||�}d|_|S)zz
        Save the state resulting from a successful cred login and mark this
        connection as authenticated.
        T)r<r{rT)r��	loginInforrs   rv�_cbAuthenticatedzESMTP._cbAuthenticated�s#��
�0�0��y�A��!����
rwc���d|_|jtjj�r|jdd�yt
j|d�|jdd�y)a
        Handle cred login errors by translating them to the SMTP authenticate
        failed.  Translate all other errors into a generic SMTP error code and
        log the failure for inspection.  Stop all errors from propagating.

        @param reason: Reason for failure.
        NisAuthentication failedzSMTP authentication failurer:r;)rFr<rr
r~r�r+r?r�s  rv�_ebAuthenticatedzESMTP._ebAuthenticated�sN������<�<��
�
�4�4�5��M�M�#�7�8��G�G�F�9�:��M�M�#�U�Vrwc�����j��jdd�t�_y|�B�jj�}t
j|�}�jd|�y|dk(r%�jdd�d�_t�_y	t
j|�}�jj|��jj�rB�jj�}t
j|�}�jd|�yt�_�jj�jdtt �}|j#�j$�|j#�fd	��|j'�j(�y#ttjf$r'�jdd�d�_t�_YywxYw)
a+
        Handle one step of challenge/response authentication.

        @param response: The text of a response. If None, this
        function has been called as a result of an AUTH command with
        no initial response. A response of '*' aborts authentication,
        as per RFC 2554.
        Nrjs Temporary authentication failurer<rKr'sAuthentication aborteds'Syntax error in parameters or argumentsc�(���jdd�S)Nr;sAuthentication successful.r)�ignr�s �rvrz"ESMTP.state_AUTH.<locals>.<lambda>�s����
�
�c�+H�I�rw)r�r�r�r�rwrnr@rArL�	TypeErrorrNrO�setResponse�moreChallengesr�r'r&rlrs�
addErrbackru)r��responserF�encoded�uncoded�codedrrs`      rvrozESMTP.state_AUTH�s�����;�;���M�M�#�B�C��D�I�������4�4�6�I��&�&�y�1�G��M�M�#�w�'���t���M�M�#�8�9�"�D�O��D�I��	��&�&�x�0�G�	
���#�#�G�,��?�?�)�)�+����4�4�6�I��$�$�Y�/�E��M�M�#�u�%����	����"�"��O�O�T�#:�<L�
��	���4�0�0�1����I�	
�	���$�/�/�0��+�8�>�>�*�	��M�M�#�I�J�"�D�O��D�I��		�s�F-�-=G-�,G-r�)r�r�r�rUrXr\rTr�r�r�r^r	rfrhrkrprsruroryrwrvr8r8DsT��
�C��K��J��M�"�G�
/���
�
�(5��*�
W�11rwr8c�2�eZdZdZdZd�Zd�Zd�Zd�Zd�Z	y)	r7zi
    Utility class for sending emails easily.

    Use with SMTPSenderFactory or ESMTPSenderFactory.
    rc�h�|js&d|_t|jj�Sy�Nrd)�doner��factoryr7r�s rvr�zSenderMixin.getMailFroms(���y�y��D�I��t�|�|�-�-�.�.�rwc�.�|jjSr|)r��toEmailr�s rvr�zSenderMixin.getMailTos���|�|�#�#�#rwc�.�|jjSr|)r��filer�s rvr�zSenderMixin.getMailDatas���|�|� � � rwc�&�tj||�|jjdk\s*|jsV|j
dk\r|j
dks7d|j_|jjj|�yyy)Nri�rT)	r=r�r��retries�retryr��sendFinishedrr�errbackr�s  rvr�zSenderMixin.sendErrorsm�����T�3�'��<�<���1�$��	�	�3�8�8�s�?�s�x�x�#�~�(,�D�L�L�%��L�L���'�'��,�8F�	rwc���d|j_|tvr�g}|D]9\}}}	|tvs�|j|dzt	d|fz�zdz|	z��;|j|j
��t
||dj|�|�}
|jjj|
�y|jjj||f�y)NTr9z%03drbr�)r�r�r�r�r/r�rr�rrr��callback)r�r�r>r�r�r+�errlogr��acode�arespr�s           rvr�zSenderMixin.sentMail s���$(����!��w���F�&/�
�"��e�U���'��M�M��u��}�V�u�h�5F�'G�G�$�N�QV�V��
�
�M�M�'�#�'�'�)�$�#�D�$��
�
�6�0B�I�N�C��L�L���'�'��,��L�L���(�(�%��);�<rwN)
r�r�r�r�r�r�r�r�r�r�ryrwrvr7r7�s'���
�D��$�!�
-�=rwr7c��eZdZdZy)r?z|
    SMTP protocol that sends a single email based on information it
    gets from its factory, a L{SMTPSenderFactory}.
    N)r�r�r�r�ryrwrvr?r?3s��rwr?c�V�eZdZUdZeZeZee	e
d<dd�Zd�Zd�Z
d�Zd�Zd	�Zd
�Zy)r@a�
    Utility factory for sending emails easily.

    @type currentProtocol: L{SMTPSender}
    @ivar currentProtocol: The current running protocol returned by
        L{buildProtocol}.

    @type sendFinished: C{bool}
    @ivar sendFinished: When the value is set to True, it means the message has
        been sent or there has been an unrecoverable error or the sending has
        been cancelled. The default value is False.
    rNc��t|t�sJ�t|t�r|jd�g}nQt|t�r|g}n=g}|D]4}t|t�s|jd�}|j|��6|}t
|�|_t|�|_	||_
||_||_|jj|j�d|_d|_||_||_y)ao
        @param fromEmail: The RFC 2821 address from which to send this
        message.

        @param toEmail: A sequence of RFC 2821 addresses to which to
        send this message.

        @param file: A file-like object containing the message to send.

        @param deferred: A Deferred to callback or errback when sending
        of this message completes.
        @type deferred: L{defer.Deferred}

        @param retries: The number of times to retry delivery of this
        message.

        @param timeout: Period, in seconds, for which to wait for
        server responses, or None to wait forever.
        rJFN)r�ror�r�r�r�r4r7r��nEmailsr�r�rr�addBoth�_removeDeferredr��currentProtocolr�r�)	r�r7r�r��deferredr�r��toEmailFinal�_emails	         rvr�zSMTPSenderFactory.__init__Ks���(�'�3�'�'�'��g�s�#��~�~�g�.�/�G�
���
'��i�G��L�!�
,��!�&�%�0�#�]�]�7�3�F��#�#�F�+�	
,�
#�G� ��+����7�|��������	���������D�0�0�1�!���#����x�����rwc�
�|`|Sr|)rr�r�rrs  rvr�z!SMTPSenderFactory._removeDeferredzs���K��
rwc�(�|j||�yr|��_processConnectionError�r��	connectorr?s   rv�clientConnectionFailedz(SMTPSenderFactory.clientConnectionFailed~����$�$�Y��4rwc�(�|j||�yr|r�r�s   rv�clientConnectionLostz&SMTPSenderFactory.clientConnectionLost�r�rwc���d|_|jdkrq|jsetjd|jz�|j
j
dd�|j�|xjdz
c_y|jsV|jtj�rtdd�|_|jj|j�yy)Nrz&SMTP Client retrying server. Retry: %srdr�zUnable to connect to server.)r�r�r�r+r�r��seek�connectr<r
�ConnectionDonerr=rrr�r�s   rvr�z)SMTPSenderFactory._processConnectionError�s���#����L�L�1��t�'8�'8��G�G�<����}�L�M�
�I�I�N�N�1�a� ������L�L�A��L��"�"��y�y��-�-�.�,�R�1O�P��	��K�K����	�	�*�#rwc���|j|j|jdzdz�}||_|j|_||_|jj|j�|S)NrW)	rr�r�r�r�r�rrr��_removeProtocolr�s   rvr�zSMTPSenderFactory.buildProtocol�s[���M�M�$�+�+�t�|�|�a�'7�!�';�<����	��L�L��	� ��������D�0�0�1��rwc�,�|jrd|_|S)z�
        Remove the protocol created in C{buildProtocol}.

        @param result: The result/error passed to the callback/errback of
            L{defer.Deferred}.

        @return: The C{result} untouched.
        N)r�r�s  rvr�z!SMTPSenderFactory._removeProtocol�s�����#'�D� ��
rw)rgN)r�r�r�r�r�r�r?rrr=�__annotations__r�r�r�r�r�r�r�ryrwrvr@r@:sA����F�!+�H�d�:��+�-�^�5�5�+�"�rwr@c��eZdZdZd�Zy)ra&
    L{LOGINCredentials} generates challenges for I{LOGIN} authentication.

    For interoperability with Outlook, the challenge generated does not exactly
    match the one defined in the
    U{draft specification<http://sepp.oetiker.ch/sasl-2.1.19-ds/draft-murchison-sasl-login-00.txt>}.
    c�@�tj|�ddg|_y)Ns	Password:s	Username:)�
_lcredentialsr��
challengesr�s rvr�zLOGINCredentials.__init__�s�����t�$�'��6��rwN)r�r�r�r�r�ryrwrvrr�s���7rwrc� �eZdZd�Zd�Zdd�Zy)r3c��||_yr|�rHr�s  rvr�zPLAINAuthenticator.__init__�s	����	rwc��y)Nr:ryr�s rvrzPLAINAuthenticator.getName�s��rwc�z�|dk(r"|jdz|jzdz|zSd|jzdz|zS)Nrd�r�)r�r�rVs   rvrBz$PLAINAuthenticator.challengeResponse�sD���1�9��9�9�u�$�t�y�y�0�5�8�6�A�A��4�9�9�$�u�,�v�5�5rwN)rd)r�r�r�r�rrBryrwrvr3r3�s����6rwr3c�(�eZdZdZdZdd�Zd�Zd�Zy)r:TNc���d|_||_|jdd�|_|�|j	�}tj|||g|��i|��|j�y)Nr�hostname)r)�username�pop�	_hostname�_getContextFactoryr9r��_registerAuthenticators)r�r�r�r�r�r�s      rvr�zESMTPSender.__init__�s_����� ��
����
�D�1����!�!�4�4�6�N����T�6�>�G�D�G�B�G��$�$�&rwc���|jt|j��|jt|j��|jt	|j��yr|)r"rr�rr3r�s rvr�z#ESMTPSender._registerAuthenticators�sJ���"�"�#=�d�m�m�#L�M��"�"�#5�d�m�m�#D�E��"�"�#5�d�m�m�#D�Erwc��|j�|jS|j�y	ddlm}||j�}|S#t$rYywxYw)Nr)�optionsForClientTLS)r�r��twisted.internet.sslr��ImportError)r�r�r�s   rvr�zESMTPSender._getContextFactory�sT���<�<�#��<�<���>�>�!��	�@�*�$�.�.�9�G��N��	�	��	�s�A�	A
�A
r|)r�r�r�r*r(r�r�r�ryrwrvr:r:�s�� ��#��'�F�rwr:c�0�eZdZdZeZ							dd�Zd�Zy)r;z�
    Utility factory for sending emails easily.

    @type currentProtocol: L{ESMTPSender}
    @ivar currentProtocol: The current running protocol as made by
        L{buildProtocol}.
    Nc	��tj|||||||�||_||_|	|_|
|_||_||_|
|_yr|)	r@r�r��password�_contextFactory�
_heloFallback�_requireAuthentication�_requireTransportSecurityr�)r�r�r�r7r�r�r�r�r�r�r)r*r(r�s              rvr�zESMTPSenderFactory.__init__�sX�� 	�"�"��)�W�d�H�g�w�	
�!��
� ��
�-���)���&;��#�)A��&�!��rwc��|j|j|j|j|j|j
dzdz|j��}|j|_|j|_
|j|_||_
|j|_||_|j j#|j$�|S)a)
        Build an L{ESMTPSender} protocol configured with C{heloFallback},
        C{requireAuthentication}, and C{requireTransportSecurity} as specified
        in L{__init__}.

        This sets L{currentProtocol} on the factory, as well as returning it.

        @rtype: L{ESMTPSender}
        rW)r�)rr�r�r�r�r�r�r�r)r�r*r�r(r�r�r�rrr�r�r�s   rvr�z ESMTPSenderFactory.buildProtocols���
�M�M��M�M��M�M�� � ��K�K��L�L�1��q� ��^�^�

�
���+�+���"&�"=�"=���%)�%C�%C��"���	��L�L��	� ��������D�0�0�1��rw)rgNNFTTN)r�r�r�r�r:rr�r�ryrwrvr;r;�s/����H�����"�!%��"�6rwr;�Fc����t|d�stt|��}��fd�}tj|�}t|t�r|jd�}t|t�r|jd�}|}
t|
t�st|
�}
t||||||d|	|
|
��
�|�t|��_|j||���|S)aR

    Send an email.

    This interface is intended to be a replacement for L{smtplib.SMTP.sendmail}
    and related methods. To maintain backwards compatibility, it will fall back
    to plain SMTP, if ESMTP support is not available. If ESMTP support is
    available, it will attempt to provide encryption via STARTTLS and
    authentication if a secret is provided.

    @param smtphost: The host the message should be sent to.
    @type smtphost: L{bytes}

    @param from_addr: The (envelope) address sending this mail.
    @type from_addr: L{bytes}

    @param to_addrs: A list of addresses to send this mail to.  A string will
        be treated as a list of one address.
    @type to_addrs: L{list} of L{bytes} or L{bytes}

    @param msg: The message, including headers, either as a file or a string.
        File-like objects need to support read() and close(). Lines must be
        delimited by '\n'. If you pass something that doesn't look like a file,
        we try to convert it to a string (so you should be able to pass an
        L{email.message} directly, but doing the conversion with
        L{email.generator} manually will give you more control over the process).

    @param senderDomainName: Name by which to identify. If None, try to pick
        something sane (but this depends on external configuration and may not
        succeed).
    @type senderDomainName: L{bytes}

    @param port: Remote port to which to connect.
    @type port: L{int}

    @param username: The username to use, if wanting to authenticate.
    @type username: L{bytes} or L{unicode}

    @param password: The secret to use, if wanting to authenticate. If you do
        not specify this, SMTP authentication will not occur.
    @type password: L{bytes} or L{unicode}

    @param requireTransportSecurity: Whether or not STARTTLS is required.
    @type requireTransportSecurity: L{bool}

    @param requireAuthentication: Whether or not authentication is required.
    @type requireAuthentication: L{bool}

    @param reactor: The L{reactor} used to make the TCP connection.

    @rtype: L{Deferred}
    @returns: A cancellable L{Deferred}, its callback will be called if a
        message is sent to ANY address, the errback if no message is sent. When
        the C{cancel} method is called, it will stop retrying and disconnect
        the connection immediately.

        The callback will be called with a tuple (numOk, addresses) where numOk
        is the number of successful recipient addresses and addresses is a list
        of tuples (address, code, resp) giving the response to the RCPT command
        for each address.
    �readc���d�_�jr%�jjj�y�j	�y)z�
        Cancel the L{twisted.mail.smtp.sendmail} call, tell the factory not to
        retry and disconnect the connection.

        @param d: The L{defer.Deferred} to be cancelled.
        TN)r�r�r��abortConnection�
disconnect)rIr�r�s ��rv�cancelzsendmail.<locals>.cancel|s<��� $����"�"��#�#�-�-�=�=�?�
� � �"rwzutf-8T)r)r*r(r�)
�hasattrrr�r	�Deferredr�r�r�r
r;r/r��
connectTCP)�smtphost�	from_addr�to_addrsr��senderDomainName�portrr�r�r*r(r�rI�tlsHostnamer�r�s              @@rvr6r6/s����R�3����e�C�j�!��#�	���v��A��(�C� ��?�?�7�+���(�C� ��?�?�7�+���K��k�3�'���,�� ������	��3�!9���G��#�&�'7�8���"��"�"�8�T�7�;�I��Hrwc��g}t|�D][}t|�}|dk(s|dk(s
|dks|dkDr|jtd|d�����A|jt	|f���]dj|�t
|�fS)N�+�=�!�~�02Xrw)r-�ordr�r/r�r�r�)r��errorsrc�ch�os     rvrIrI�s���
�A���l�"����G��
��9��c�	�Q��V�q�3�w�
�H�H�]�Q�q��g�;�/�0�
�H�H�U�A�4�[�!�"�
�H�H�Q�K��Q�� � rwc���g}d}|t|�kr�|||dzdk(r=	|jttt	||dz|dz�d���|dz
}n4|jt	|||dz�jd��|dz
}|t|�kr��dj|�t|�fS#t
$r#|jt
|||dz��Y��wxYw)z�
    Decode the xtext-encoded string C{s}.

    @param s: String to decode.
    @param errors: codec error handling scheme.
    @return: The decoded string.
    rrd�+re�rJr�)	r�r��chrror�r�r�r�r�)r�r�rcrzs    rvrHrH�s���	�A�	�A�
�c�!�f�*��Q��Q��<�4��
,�����S��q��Q���Q��'7�!8�"�=�>�?�
��F�A�
�H�H�U�1�Q��Q��<�(�/�/��8�9�
��F�A��c�!�f�*�
�G�G�A�J��A�����
�
,�����Q�q�1�q�5�\�*�+�
,�s�6B:�:)C&�%C&c��eZdZdd�Zy)rEc��t|�Sr|)rH�r�r�r�s   rvr�zxtextStreamReader.decode�����A��rwN��strict�r�r�r�r�ryrwrvrErE����rwrEc��eZdZdd�Zy)rFc��t|�Sr|)rIr�s   rvr�zxtextStreamWriter.decode�r�rwNr�r�ryrwrvrFrF�r�rwrFc�:�|dk(rttttfSy)N�xtext)rIrHrErF)r	s rvrGrG�s���w���l�,=�?P�Q�Q�rwr�r|)yr�r@rNr�r�r��socketrhr�email.utilsr�ior�typingr�zope.interfacer�twistedr�twisted.copyrightr�twisted.internetr	r
rr�twisted.internet._idnar
�twisted.internet.interfacesrr�twisted.mail._credrrrr��twisted.mail._exceptrrrrrrrrrrrrrr r!r"r#r1r$�twisted.mail.interfacesr%r&r'r(r2�twisted.protocolsr)r*�twisted.pythonr+r,�twisted.python.compatr-r.r/�twisted.python.runtimer0�__all__�isMacOSX�gethostnamer�r��getfqdn�dict�fromkeysr�r�rDrAr~rBrCr�r�r�r�r4r5�LineOnlyReceiver�TimeoutMixinr<r�r>r�r=r9r8r7r?�
ClientFactoryr@r3r:r;r6�codecsrIrH�StreamReaderrE�StreamWriterrFrG�registerryrwrv�<module>rs����
��	�
�	�
���!���&��)�<�<�,�D���
�����(��.�$�H�H�+�1��l�8����!�f� � �"�)�)�'�2�G��f�n�n��%�%�g�.�G��-�-��c�3��
(��9�x��}���-��*4�*0����t�+��p
�p
�f% �% �PkE�5�!�!�8�#8�#8�kE�\�(�(�(��,A��#�#�X�%:�%:�A�Hc5�*�c5�L
t1�D�t1�n5=�5=�p��j��n��.�.�n�b7�}�7�
�
"�#�6�6�$�6�"�+�{�"�J?�*�?�N�	��
�
��"�x
�v�!� �.��+�+��
��+�+��
R�
�����rw
¿Qué es la limpieza dental de perros? - Clínica veterinaria


Es la eliminación del sarro y la placa adherida a la superficie de los dientes mediante un equipo de ultrasonidos que garantiza la integridad de las piezas dentales a la vez que elimina en profundidad cualquier resto de suciedad.

A continuación se procede al pulido de los dientes mediante una fresa especial que elimina la placa bacteriana y devuelve a los dientes el aspecto sano que deben tener.

Una vez terminado todo el proceso, se mantiene al perro en observación hasta que se despierta de la anestesia, bajo la atenta supervisión de un veterinario.

¿Cada cuánto tiempo tengo que hacerle una limpieza dental a mi perro?

A partir de cierta edad, los perros pueden necesitar una limpieza dental anual o bianual. Depende de cada caso. En líneas generales, puede decirse que los perros de razas pequeñas suelen acumular más sarro y suelen necesitar una atención mayor en cuanto a higiene dental.


Riesgos de una mala higiene


Los riesgos más evidentes de una mala higiene dental en los perros son los siguientes:

  • Cuando la acumulación de sarro no se trata, se puede producir una inflamación y retracción de las encías que puede descalzar el diente y provocar caídas.
  • Mal aliento (halitosis).
  • Sarro perros
  • Puede ir a más
  • Las bacterias de la placa pueden trasladarse a través del torrente circulatorio a órganos vitales como el corazón ocasionando problemas de endocarditis en las válvulas. Las bacterias pueden incluso acantonarse en huesos (La osteomielitis es la infección ósea, tanto cortical como medular) provocando mucho dolor y una artritis séptica).

¿Cómo se forma el sarro?

El sarro es la calcificación de la placa dental. Los restos de alimentos, junto con las bacterias presentes en la boca, van a formar la placa bacteriana o placa dental. Si la placa no se retira, al mezclarse con la saliva y los minerales presentes en ella, reaccionará formando una costra. La placa se calcifica y se forma el sarro.

El sarro, cuando se forma, es de color blanquecino pero a medida que pasa el tiempo se va poniendo amarillo y luego marrón.

Síntomas de una pobre higiene dental
La señal más obvia de una mala salud dental canina es el mal aliento.

Sin embargo, a veces no es tan fácil de detectar
Y hay perros que no se dejan abrir la boca por su dueño. Por ejemplo…

Recientemente nos trajeron a la clínica a un perro que parpadeaba de un ojo y decía su dueño que le picaba un lado de la cara. Tenía molestias y dificultad para comer, lo que había llevado a sus dueños a comprarle comida blanda (que suele ser un poco más cara y llevar más contenido en grasa) durante medio año. Después de una exploración oftalmológica, nos dimos cuenta de que el ojo tenía una úlcera en la córnea probablemente de rascarse . Además, el canto lateral del ojo estaba inflamado. Tenía lo que en humanos llamamos flemón pero como era un perro de pelo largo, no se le notaba a simple vista. Al abrirle la boca nos llamó la atención el ver una muela llena de sarro. Le realizamos una radiografía y encontramos una fístula que llegaba hasta la parte inferior del ojo.

Le tuvimos que extraer la muela. Tras esto, el ojo se curó completamente con unos colirios y una lentilla protectora de úlcera. Afortunadamente, la úlcera no profundizó y no perforó el ojo. Ahora el perro come perfectamente a pesar de haber perdido una muela.

¿Cómo mantener la higiene dental de tu perro?
Hay varias maneras de prevenir problemas derivados de la salud dental de tu perro.

Limpiezas de dientes en casa
Es recomendable limpiar los dientes de tu perro semanal o diariamente si se puede. Existe una gran variedad de productos que se pueden utilizar:

Pastas de dientes.
Cepillos de dientes o dedales para el dedo índice, que hacen más fácil la limpieza.
Colutorios para echar en agua de bebida o directamente sobre el diente en líquido o en spray.

En la Clínica Tus Veterinarios enseñamos a nuestros clientes a tomar el hábito de limpiar los dientes de sus perros desde que son cachorros. Esto responde a nuestro compromiso con la prevención de enfermedades caninas.

Hoy en día tenemos muchos clientes que limpian los dientes todos los días a su mascota, y como resultado, se ahorran el dinero de hacer limpiezas dentales profesionales y consiguen una mejor salud de su perro.


Limpiezas dentales profesionales de perros y gatos

Recomendamos hacer una limpieza dental especializada anualmente. La realizamos con un aparato de ultrasonidos que utiliza agua para quitar el sarro. Después, procedemos a pulir los dientes con un cepillo de alta velocidad y una pasta especial. Hacemos esto para proteger el esmalte.

La frecuencia de limpiezas dentales necesaria varía mucho entre razas. En general, las razas grandes tienen buena calidad de esmalte, por lo que no necesitan hacerlo tan a menudo e incluso pueden pasarse la vida sin requerir una limpieza. Sin embargo, razas pequeñas como el Yorkshire o el Maltés, deben hacérselas todos los años desde cachorros si se quiere conservar sus piezas dentales.

Otro factor fundamental es la calidad del pienso. Algunas marcas han diseñado croquetas que limpian la superficie del diente y de la muela al masticarse.

Ultrasonido para perros

¿Se necesita anestesia para las limpiezas dentales de perros y gatos?

La limpieza dental en perros no es una técnica que pueda practicarse sin anestesia general , aunque hay veces que los propietarios no quieren anestesiar y si tiene poco sarro y el perro es muy bueno se puede intentar…… , pero no se va a poder pulir ni acceder a todas la zona de la boca …. Además los limpiadores dentales van a irrigar agua y hay riesgo de aspiración a vías respiratorias si no se realiza una anestesia correcta con intubación traqueal . En resumen , sin anestesia no se va hacer una correcta limpieza dental.

Tampoco sirve la sedación ya que necesitamos que el animal esté totalmente quieto, y el veterinario tenga un acceso completo a todas sus piezas dentales y encías.

Alimentos para la limpieza dental

Hay que tener cierto cuidado a la hora de comprar determinados alimentos porque no todos son saludables. Algunos tienen demasiado contenido graso, que en exceso puede causar problemas cardiovasculares y obesidad.

Los mejores alimentos para los dientes son aquellos que están elaborados por empresas farmacéuticas y llevan componentes químicos con tratamientos específicos para el diente del perro. Esto implica no solo limpieza a través de la acción mecánica de morder sino también un tratamiento antibacteriano para prevenir el sarro.

Conclusión

Si eres como la mayoría de dueños, por falta de tiempo , es probable que no estés prestando la suficiente atención a la limpieza dental de tu perro. Por eso te animamos a que comiences a limpiar los dientes de tu perro y consideres atender a su higiene bucal con frecuencia.

Estas simples medidas pueden conllevar a que tu perro tenga una vida más larga y mucho más saludable.

Si te resulta imposible introducir un cepillo de dientes a tu perro en la boca, pásate con él por clínica Tus Veterinarios y te explicamos cómo hacerlo.

Necesitas hacer una limpieza dental profesional a tu mascota?
Llámanos al 622575274 o contacta con nosotros

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

¡Hola!