o ]LbXD@sddlmZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl mZddlmZmZddlmZmZmZmZmZddlmZmZmZejrqddlmZmZmZm Z e!eeee fsqJGd d d e j"Z#Gd d d e j"Z$d dZ%ddZ&ddZ'ddZ(ddZ)d;ddZ*d;ddZ+ddZ,ddZ-d)absolute_importN)_)getattropen)encodingerrorpycompatsslutilutil)procutil stringutilurlutil)AnyListTupleUnionc@s$eZdZdZdddZdddZdS) STARTTLSzDerived class to verify the peer certificate for STARTTLS. This class allows to pass any keyword arguments to SSL socket creation. NcKs$tjj|fi|||_||_dSN)smtplibSMTP__init___ui_host)selfuihostkwargsr0/usr/lib/python3/dist-packages/mercurial/mail.pyr5s zSTARTTLS.__init__cCsx|ds d}t||d\}}|dkr8tj|j|||j|jd|_|j d|_ d|_ d|_ i|_ d|_||fS)Nstarttlss*STARTTLS extension not supported by serverrrserverhostnamerbr)has_extnr SMTPExceptiondocmdr wrapsocketsockrrmakefilefile helo_resp ehlo_respesmtp_features does_esmtp)rkeyfilecertfilemsgrespreplyrrrr :s$  zSTARTTLS.starttlsr)NN)__name__ __module__ __qualname____doc__rr rrrrr/s rc@s"eZdZdZdddZddZdS)SMTPSzDerived class to verify the peer certificate for SMTPS. This class allows to pass any keyword arguments to SSL socket creation. NcKs8||_||_tjj|fi|||_tj|_||_dSr) r0r1rrrr SMTP_SSL_PORT default_portr)rrr0r1rrrrrrUs  zSMTPS.__init__cCs\|jdkr|jd||fft||f|}tj||j|j|j|j d}| d|_ |S)Nrs connect: %r r"r$) debuglevelrdebugsocketcreate_connectionr r(r0r1rr*r+)rrporttimeout new_socketrrr _get_socket]s  zSMTPS._get_socket)NNN)r5r6r7r8rrCrrrrr9Os  r9cCs0z ddl}t|ddWdStyYdSw)z9Returns true iff Python has TLS support, false otherwise.rNHAS_TLSFT)sslr ImportError)rErrr _pyhastlsls  rGc s|dd}|dd}|dkpt|}|dk}|s|r'ts'ttd|dd}|s6ttd|rG|td t|||d n|rQt |||d nt j |d |r\d }nd }t |dd|}|td||fj||d|r|td|s|r|tdtjz t|||Wnt jy}ztt|d}~wwfdd} | S)z;build an smtp connection and return a function to send mailsmtpslocal_hostnamestlssstarttlsssmtpss/can't use TLS: Python SSL support not installedhosts+smtp.host not configured - cannot send mails(using smtps) )local_hostnamer)rJisports$sending mail: smtp host %s, port %d )rr@s(using starttls) s(verifying remote certificate) Nc s|z|||WStjy)}zdd|jD}tdd|d}~wtjy=}ztt |d}~ww)NcSsg|]}|dqS)rr).0rrrr sz'_smtp..send.. ) sendmailrSMTPRecipientsRefused recipientsvaluesrAbortjoinr&r forcebytestr)senderrRr2instsrrsendsz_smtp..send)configr parseboolrGrrTrnoter9rrrrgetportconnectehlor r validatesocketr) _smtp_loginr&rV) rrJtlsr smtpsmailhost defaultportmailportrXr[rrYr_smtpxsJ       ricCs|dd}|dd}|r#|rt|}n |}|dur#t|}|r=|r?|td|t|}|||dSdSdS)azA hook for the keyring extension to perform the actual SMTP login. An already connected SMTP object of the proper type is provided, based on the current configuration. The host and port to which the connection was established are provided for accessibility, since the SMTP object doesn't provide an accessor. ``smtplib.SMTPException`` is raised on error. rHsusernamespasswordNs&(authenticating to mail server as %s) )r\r strfromlocalgetpassr^rlogin)rsmtprfrhusernamepasswordrrrrcs     rcc Cs|dd}dd}d|||dt||f}|td|t|d}|t || }|rKt d t jt|d t|fd S) zsend mail using sendmail.emailmethodcSsttt|Sr)r shellquoter emailr strtolocal)xrrrstremailsz_sendmail..stremails %s -f %s %s ssending mail: %s wbs%s %srN)r\rUmapr^rr popenwriter tonativeeolcloserrTospathbasename shellsplit explainexit) rrWrRr2programrvcmdlinefpretrrr _sendmails(  rcCsrt|d*}tdt}|dt|t|f|||dWddS1s2wYdS)zwrite mails to mboxsab+z%a %b %d %H:%M:%S %Ys From %s %s s N)rtimestrftime localtimer{rrt)mboxrWrRr2rdaterrr_mboxs   "rcsBrtdfddSdddkrtSfddS)znmake a mail connection. return a function to send mail. call as sendmail(sender, list-of-recipients, msg).rxct|||Sr)rrZrMmrrrzconnect..rprqrHcrr)rr)rrrrr)rr}r\ri)rrr)rrrr`s   r`cCst||d}||||S)Nr)r`)rrWrRr2rr[rrrrPs  rPcCsR|dd}|dkr|ddsttddSt|s'ttd|dS)z=determine if we have enough config data to try sending email.rprqrHrIs>smtp specified as email transport, but no smtp host configureds0%r specified as email transport, but not in PATHN)r\rrTrr findexe)rmethodrrrvalidateconfigs    rcCs:tj|j}|dr|dsd|ddS|S) isoziso-N)rscharsetCharset input_charsetlower startswith)csrrr codec2ianasrplainFc Csnddttjttjg}|rdg}|D]}z||t||t|WSty0Yqwt||dS)a2Return MIME message suitable for a patch. Charset will be detected by first trying to decode as us-ascii, then utf-8, and finally the global encodings. If all those fail, fall back to ISO-8859-1, an encoding with that allows all byte sequences. Transfer encodings will be used if necessary.us-asciiutf-8z iso-8859-1)r sysstrrfallbackencodingdecode mimetextqprUnicodeDecodeError)rZsubtypedisplayrrrrr mimetextpatchs      rcCs\tj|}tj}|d||D]}t|dkr%tjj|_ nq| |||S)z[Return MIME message. Quoted-printable transfer encoding will be used if necessary. ztext/i) rsrrmessageMessageset_type splitlineslenQP body_encoding set_payload)bodyrrrr2linerrrr3s      rcCsbdd|ddD}ttjttjdg}|D] }||vr)||qdd|DS)z;Obtains charsets to send mail parts not containing patches.cSsg|] }t|qSr)r rrrLrrrrrNPs z_charsets..rpscharsetsrcSsg|] }|ds|qS)ascii)endswithrrrrrN\s) configlistr rrrrappend)rcharsets fallbacksrrrr _charsetsMs  rcCsJ|pt|}t|ts?|D])}z |||fWSty"Yq ty6|tdt |Yq w|dddfSz | dW|dfSt yt j t j fD]H}t|}z| |}Wn t ymYqVw|D]-}z|||fWYStyYqpty|tdt |YqpwqVY|dfSw)aReturns (converted) string, charset tuple. Finds out best charset by cycling through sendcharsets in descending order. Tries both encoding and fallbackencoding for input. Only as last resort send as is in fake ascii. Caveat: Do not use for mail parts containing patches!s!ignoring invalid sendcharset: %s rbackslashreplacer)r isinstancebytesencodeUnicodeEncodeError LookupErrorwarnrr sysbytesrrrrr)rrZr sendcharsetsocsicsurrr_encode_sT          rcCs0|st|||\}}tj||St|S)z4Returns RFC-2047 compliant header from given string.)rrsheaderHeaderrrrjrrZrrrrrr headencodes rc Cst|}t|||}z |d\}}|d|ttjd}d||f}Wn0ty;t t d|t y[z|dWntyXt t d|wYnwt j|t|fS)N@ridnas%s@%ssinvalid email address: %ssinvalid local address: %s)rrtrsplitrr rrrrrTr ValueErrorrsutils formataddrrj)rnameaddrraccdomrrr_addressencodes$      rcCs:|s|s t|p dStjt|\}}t||||S)z-Turns address into RFC-2047 compliant header.)rrjrsr parseaddrr)raddressrrrrrrr addressencodesrc Csg}|D]}t|tsJd||t|q|r#dd|DSg}tj|D]\}}|s3|r?t||||} || q+|S)zTurns a list of addresses into a list of RFC-2047 compliant headers. A single element of input list may contain multiple addresses, but output always has one address per itemz%r unexpectedly not a bytestrcSsg|] }|r|qSr)strip)rLarrrrNsz"addrlistencode..) rrrrrjrsr getaddressesr) raddrsrrstraddrsrresultrrrMrrraddrlistencodes rcCs$d}|s t|||\}}t|d|S)zgcreates mime text object, encodes it if needed, and sets charset and transfer-encoding accordingly.rr)rrrrrr mimeencodes rcCs@tj}tj|ddtdd}z ||W|S|w)Nrsurrogateescape )rerrorsnewline)rsparserParserio TextIOWrapperchrparsedetachreprrrrs   rcCtj}||Sr)rsr BytesParser parsebytesdatarrrrr  rcCrr)rsrrrrrrrrrcCrr)rsrrparsestrrrrrrrc Csg}tj|D]G\}}|dur&z |||Wqttfy%Ynwt|tdr3||qz ||dWqtyFYnw||dqt d |S)zDecodes RFC-2047 headerNzUTF-8z ISO-8859-1r) rsr decode_headerrrrrrtyper unitolocalrU)rZupartspartrrrr headdecodes(  rr)rF)NF)> __future__rrs email.charsetemail.generator email.header email.message email.parserrr~rr>ri18nrr rrrrrr r rr r r TYPE_CHECKINGtypingrrrrallrrr9rGrircrrr`rPrrrrrrrrrrrispy3 generatorBytesGenerator Generatorrrrrrrrs^    4    3