ó
Ú"wTc           @   sl  d  Z  d d d d d d d d d	 d
 d d d d d d d d d d d d d d g Z d d l Z d d l Z d d l Z d d l Z d d l Z d d l Z d d l Z d d l	 Z	 d d l
 Z
 d d l Z d d l Z d d l Z d d l Z d d l Z y d d l Z Wn e k
 r%d Z n Xy d d l Z Wn e k
 rOd Z n Xy% d d l Z e j ƒ  std Z n  Wn e k
 rŽd Z n Xd d l Td Z i e d 6e d 6e d 6e d  6e d! 6e d" 6e d# 6e d$ 6Z d% Z d& „  Z d' „  Z d( d) „ Z d e f d* „  ƒ  YZ  d e f d+ „  ƒ  YZ! dF dG d- „ Z" d. „  Z# d/ „  Z$ d d( d0 „ Z% d1 „  Z& d2 „  Z' d3 „  Z( d4 „  Z) d5 „  Z* d d d d6 „ Z+ d d d d7 „ Z, d8 „  Z- d9 „  Z. d: „  Z/ d; „  Z0 d< „  Z1 d= „  Z2 d> „  Z3 d? „  Z4 d@ „  Z5 d Z6 e j7 dA k rGe j8 j9 e ƒ r2dB „  Z6 qGe rGdC „  Z6 qGn  e6 d k r_dD „  Z6 n  dE „  Z: d S(H   s+   Utility classes and functions for getmail.
t   address_no_bracketst   change_usergroupt   change_uidgidt   decode_crappy_textt   format_headert   check_ssl_key_and_certt   check_ca_certst   check_ssl_versiont   check_ssl_fingerprintst   check_ssl_cipherst   deliver_maildirt	   eval_boolt   expand_user_varst
   is_maildirt   localhostnamet	   lock_filet   logfilet   mbox_from_escapet	   safe_opent   unlock_filet
   gid_of_uidt   uid_of_usert
   updatefilet   get_passwordiÿÿÿÿN(   t   *s   %Y-%m-%d %H:%M:%St   truet   yest   ont   1t   falset   not   offt   0s   /usr/bin/securityc         C   sd   | d k s t  d | ƒ ‚ | d k r> t j |  t j ƒ n" | d k r` t j |  t j ƒ n  d S(   s   Do file locking.t   lockft   flocks   unknown lock type %sN(   s   lockfs   flock(   t   AssertionErrort   fcntlR!   t   LOCK_EXR"   (   t   filet   locktype(    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR   U   s
    c         C   sd   | d k s t  d | ƒ ‚ | d k r> t j |  t j ƒ n" | d k r` t j |  t j ƒ n  d S(   s   Do file unlocking.R!   R"   s   unknown lock type %sN(   s   lockfs   flock(   R#   R$   R!   t   LOCK_UNR"   (   R&   R'   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR   ^   s
    i€  c         C   sˆ   t  j d k r t |  | ƒ Sy< t  j |  t  j t  j Bt  j B| ƒ } t  j | | ƒ } Wn) t k
 rƒ } t d |  | f ƒ ‚ n X| S(   s   Open a file path safely.
    t   posixs   failure opening %s (%s)(	   t   ost   namet   opent   O_RDWRt   O_CREATt   O_EXCLt   fdopent   OSErrort   getmailDeliveryError(   t   patht   modet   permissionst   fdR&   t   o(    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR   g   s    &c           B   s2   e  Z d  Z d „  Z d „  Z d „  Z d „  Z RS(   s7  A class for atomically updating files.

    A new, temporary file is created when this class is instantiated. When the
    object's close() method is called, the file is synced to disk and atomically
    renamed to replace the original file.  close() is automatically called when
    the object is deleted.
    c         C   sÜ   t  |  _ | |  _ | d t j ƒ  |  _ x@ t j j | ƒ rk t j j t j j	 | ƒ t j
 | ƒ ƒ } q, Wy t |  j d ƒ } Wn2 t k
 r¶ \ } } t d | |  j f ƒ ‚ n X| |  _ | j |  _ | j |  _ d  S(   Ns   .tmp.%dt   wbs   %s, opening output file "%s"(   t   Falset   closedt   filenameR*   t   getpidt   tmpnameR3   t   islinkt   joint   dirnamet   readlinkR   t   IOErrorR&   t   writet   flush(   t   selfR;   t   ft   codet   msg(    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyt   __init__|   s    			c         C   s   |  j  ƒ  d  S(   N(   t   close(   RE   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyt   __del__   s    c         C   sD   y# t  |  d ƒ r" |  j j ƒ  n  Wn t k
 r6 n Xt |  _ d  S(   NR&   (   t   hasattrR&   RJ   RB   t   TrueR:   (   RE   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyt   abort’   s    c         C   sp   |  j  s t |  d ƒ r d  S|  j j ƒ  t j |  j j ƒ  ƒ |  j j ƒ  t j |  j	 |  j
 ƒ t |  _  d  S(   NR&   (   R:   RL   R&   RD   R*   t   fsynct   filenoRJ   t   renameR=   R;   RM   (   RE   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyRJ   š   s    (   t   __name__t
   __module__t   __doc__RI   RK   RN   RJ   (    (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR   t   s
   			c           B   s;   e  Z d  Z d „  Z d „  Z d „  Z d „  Z d „  Z RS(   sL   A class for locking and appending timestamped data lines to a log file.
    c         C   sj   t  |  _ | |  _ y t t |  j ƒ d ƒ |  _ Wn2 t k
 re \ } } t d | |  j f ƒ ‚ n Xd  S(   Nt   abs   %s, opening file "%s"(   R9   R:   R;   R,   R   R&   RB   (   RE   R;   RG   RH   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyRI   §   s    		c         C   s   |  j  ƒ  d  S(   N(   RJ   (   RE   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyRK   ¯   s    c         C   s   d |  j  S(   Ns   logfile(filename="%s")(   R;   (   RE   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyt   __str__²   s    c         C   s4   |  j  r d  S|  j j ƒ  |  j j ƒ  t |  _  d  S(   N(   R:   R&   RD   RJ   RM   (   RE   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyRJ   µ   s
    	c         C   sƒ   zk t  |  j d ƒ |  j j d d ƒ |  j j t j t t j ƒ  ƒ d | j ƒ  t	 j
 ƒ |  j j ƒ  Wd  t |  j d ƒ Xd  S(   NR"   i    i   t    (   R   R&   t   seekRC   t   timet   strftimet   logtimeformatt	   localtimet   rstripR*   t   linesepRD   R   (   RE   t   s(    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyRC   ¼   s    	.(   RR   RS   RT   RI   RK   RV   RJ   RC   (    (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR   ¤   s   				t   passwordc         C   s‹   d } |  j  ƒ  } | j ƒ  xh | D]` } | | k r; q# n  | rN | d 7} n  | | k rk | d | 7} q# | d | |  | f 7} q# W| S(   sA   Take a dictionary of parameters and return a string summary.
    t    t   ,s   %s=*s   %s="%s"(   t   keyst   sort(   t   dt	   maskitemst	   skipitemsR_   Rc   t   key(    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyt   format_paramsÈ   s    
c          G   s   t  d ƒ ‚ d S(   sG   Handle an alarm during maildir delivery.

    Should never happen.
    s   Delivery timeoutN(   R2   (   t   unused(    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyt   alarm_handlerÚ   s    c         C   sù   t  j j |  j d ƒ r" |  d  p% |  ƒ } t  j | t  j ƒ sS t d |  ƒ ‚ n  t  j j |  ƒ si t St  j |  t  j ƒ s‘ t d |  ƒ ‚ n  xa d	 D]Y } t  j j	 |  | ƒ } t  j j | ƒ sÉ t St  j | t  j
 ƒ s˜ t d |  ƒ ‚ q˜ q˜ Wt S(
   s    Verify a path is a maildir.
    t   /iÿÿÿÿsP   cannot read contents of parent directory of %s - check permissions and ownershipsF   cannot read contents of directory %s - check permissions and ownershipt   tmpt   curt   news<   cannot write to maildir %s - check permissions and ownership(   Rm   Rn   s   new(   R*   R3   R@   t   endswitht   accesst   X_OKt   getmailConfigurationErrort   isdirR9   R?   t   W_OKRM   (   Re   t
   dir_parentt   subt   subdir(    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR   â   s(    +c         C   s™  t  |  ƒ s t d |  ƒ ‚ n  t j t j t ƒ t j d& ƒ i | d 6| j d ƒ d j d d ƒ j d	 d
 ƒ d 6t j	 ƒ  d 6} t j
 j |  d ƒ } t j
 j |  d ƒ } xžt d ƒ D]w} t j ƒ  }	 t |	 ƒ | d <t |	 t |	 ƒ d ƒ | d <d | | d <| d d' k	 r1| d c d | 7<n  yP | d c d d j g  t d d ƒ j d ƒ D] }
 d t |
 ƒ ^ q`ƒ 7<Wn t k
 r”n Xd | } t j
 j | | ƒ } t j
 j | | ƒ } t j
 j | ƒ rît j d ƒ q¼ n  t j
 j |  d | ƒ d } t j | ƒ } | r2t d  | ƒ ‚ n  Pq¼ Wt j d ƒ t d! ƒ ‚ t j |  ƒ } yJ t | d" | ƒ } | j | ƒ | j ƒ  t j | j ƒ  ƒ | j ƒ  Wn6 t k
 rá} t j d ƒ t d# | | f ƒ ‚ n Xy! t j | | ƒ t j  | ƒ Wnl t! k
 rqt j d ƒ y t j  | ƒ Wn$ t" k
 rG‚  n t k
 rWn Xt d$ | | f ƒ ‚ n Xt j d ƒ t j t j t j# ƒ | S((   s0  Reliably deliver a mail message into a Maildir.  Uses Dan Bernstein's
    documented rules for maildir delivery, and the updated naming convention
    for new files (modern delivery identifiers).  See
    http://cr.yp.to/proto/maildir.html and
    http://qmail.org/man/man5/maildir.html for details.
    s   not a Maildir (%s)i   i<   t   deliverycountt   .i    Rl   s   \057t   :s   \072t   hostnamet   pidRm   Ro   i   t   secsi@B t   usecss   M%(usecs)dP%(pid)st   uniques   Q%(deliverycount)ss   R%sRa   s   /dev/urandomt   rbi   s   %02xs    %(secs)s.%(unique)s.%(hostname)si   Rn   s   :*s   collision with %ss"   failed to allocate file in maildirR8   s   failure writing file %s (%s)s   failure renaming "%s" to "%s"i   i€Q N($   R   R2   t   signalt   SIGALRMRk   t   alarmt   splitt   replaceR*   R<   R3   R?   t   rangeRY   t   intt   NoneR,   t   readt   ordt   StandardErrort   existst   sleept   globt   statR   RC   RD   RO   RP   RJ   RB   t   linkt   unlinkR1   t   KeyboardInterruptt   SIG_DFL(   t   maildirpatht   dataR|   t   dcountt   filemodet   infot   dir_tmpt   dir_newRj   t   tt   charR;   t	   fname_tmpt	   fname_newt   curpatt	   collisiont	   s_maildirRF   R7   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR
   þ   s€    :

c         C   s8   d j  g  |  D] } | d k r% d p( | ^ q ƒ p7 d S(   sA   Escape spaces, tabs, and newlines in the envelope sender address.Ra   RW   s   	s   
t   -s   <>(   RW   s   	s   
(   R?   (   R_   t   c(    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR   g  s    c         C   s1   |  j  d ƒ r) |  j d ƒ r) |  d d !S|  Sd S(   s5   Strip surrounding <> on an email address, if present.t   <t   >i   iÿÿÿÿN(   t
   startswithRp   (   t   addr(    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR    l  s    c         C   s@   y t  t |  ƒ j ƒ  SWn! t k
 r; t d |  ƒ ‚ n Xd S(   s)   Handle boolean values intelligently.
    sE   boolean parameter requires value to be one of true or false, not "%s"N(   t   _bool_valuest   strt   lowert   KeyErrorRs   (   R_   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR   t  s    c         C   s>   y t  j |  ƒ j SWn# t k
 r9 } t d | ƒ ‚ n Xd  S(   Ns   no such specified uid (%s)(   t   pwdt   getpwuidt   pw_gidR¬   Rs   (   t   uidR7   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR   €  s    c         C   s>   y t  j |  ƒ j SWn# t k
 r9 } t d | ƒ ‚ n Xd  S(   Ns   no such specified user (%s)(   R­   t   getpwnamt   pw_uidR¬   Rs   (   t   userR7   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR   ‡  s    c         C   s®   d } d } | rk |  r, |  j d | ƒ n  y t j | ƒ j } Wqk t k
 rg } t d | ƒ ‚ qk Xn  | rš |  r‹ |  j d | ƒ n  t | ƒ } n  t |  | | ƒ d S(   s]   
    Change the current effective GID and UID to those specified by user and
    _group.
    s#   Getting GID for specified group %s
s   no such specified group (%s)s"   Getting UID for specified user %s
N(	   R‰   t   debugt   grpt   getgrnamt   gr_gidR¬   Rs   R   R   (   t   loggerR³   t   _groupR°   t   gidR7   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR   Ž  s    c         C   sÇ   y” | rK t  j ƒ  | k rK |  r5 |  j d | ƒ n  t  j | | ƒ qK n  | r“ t  j ƒ  | k r“ |  r} |  j d | ƒ n  t  j | | ƒ q“ n  Wn, t k
 rÂ } t d | | | f ƒ ‚ n Xd S(   sY   
    Change the current effective GID and UID to those specified by uid
    and gid.
    s   Setting egid to %d
s   Setting euid to %d
s#   change UID/GID to %s/%s failed (%s)N(   R*   t   getegidR´   t   setregidt   geteuidt   setreuidR1   R2   (   R¸   R°   Rº   R7   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR   ¤  s    c         C   s¨   t  j j d ƒ } | r] y& | j d ƒ \ } } |  j | ƒ SWq] t t f k
 rY } q] Xn  x8 d D]0 } y |  j | ƒ SWqd t k
 r“ } qd qd Xqd W|  j d d ƒ S(	   s   Take a line of text in arbitrary and possibly broken bytestring encoding
    and return an ASCII or unicode version of it.
    t   LANGRz   t   asciis   utf-8s   latin-1s   utf-16R†   (   s   asciis   utf-8s   latin-1s   utf-16(   R*   t   environt   getR…   t   decodet   UnicodeErrort
   ValueError(   R_   t   langt   encodingR7   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR   ¹  s    c         C   s  d } |  j  ƒ  d d j g  | j ƒ  D] } | j  ƒ  ^ q& ƒ } x— | rÛ t | ƒ d k rÛ | j d d d ƒ } | d k r  | j d ƒ } | d k r  Pq  n  | rº | t j d 7} n  | | |  7} | | j ƒ  } qE W| rö | t j d 7} n  | r| | j  ƒ  t j 7} n  | S(   s?   Take a long line and return rfc822-style multiline header.
    Ra   s   : RW   iN   i    iÿÿÿÿs     (   t   stripR?   t
   splitlinest   lent   rfindR*   R^   t   lstrip(   R+   t   linet   headert   partt   i(    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR   Ð  s"    <c         C   s   t  j j t  j j |  ƒ ƒ S(   s‰   Return a string expanded for both leading "~/" or "~username/" and
    environment variables in the form "$varname" or "${varname}".
    (   R*   R3   t
   expandusert
   expandvars(   R_   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR   ë  s    c          C   s&   t  j ƒ  }  d |  k r |  St  j ƒ  S(   sI   Return a name for localhost which is (hopefully) the "correct" FQDN.
    Rz   (   t   sockett   gethostnamet   getfqdn(   t   n(    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR   ò  s    c         C   sÉ   |  d } | d  k	 r% t | ƒ } n  |  d } | d  k	 rJ t | ƒ } n  | rr t j j | ƒ rr t d ƒ ‚ n  | rš t j j | ƒ rš t d ƒ ‚ n  | d  k | d  k Ar¿ t d ƒ ‚ n  | | f S(   Nt   keyfilet   certfiles-   optional keyfile must be path to a valid files.   optional certfile must be path to a valid files7   optional certfile and keyfile must be supplied together(   R‰   R   R*   R3   t   isfileRs   (   t   confR×   RØ   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR   û  s     

c         C   sl   |  d } | d  k	 r@ t | ƒ } t d  k r@ t d ƒ ‚ q@ n  | rh t j j | ƒ rh t d ƒ ‚ n  | S(   Nt   ca_certssU   specifying ca_certs not supported by this installation of Python; requires Python 2.6s.   optional ca_certs must be path to a valid file(   R‰   R   t   sslRs   R*   R3   RÙ   (   RÚ   RÛ   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR     s    
c         C   sÔ   |  d } | d  k r d  St d  k r5 t d ƒ ‚ n  | j ƒ  } | d k rT t j S| d k rg t j S| d k rz t j S| d k rŸ d t t ƒ k rŸ t j S| d k rÄ d	 t t ƒ k rÄ t j	 St d
 ƒ ‚ d  S(   Nt   ssl_versionsX   specifying ssl_version not supported by this installation of Python; requires Python 2.6t   sslv23t   sslv3t   tlsv1t   tlsv1_1t   PROTOCOL_TLSv1_1t   tlsv1_2t   PROTOCOL_TLSv1_2s"   unknown or unsupported ssl_version(
   R‰   RÜ   Rs   R«   t   PROTOCOL_SSLv23t   PROTOCOL_SSLv3t   PROTOCOL_TLSv1t   dirRâ   Rä   (   RÚ   RÝ   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR   !  s&    
c         C   s¢   |  d } | d k r d St  d  k s2 t d  k rA t d ƒ ‚ n  g  } xT | D]L } | j ƒ  j d d ƒ } t | ƒ d k r t d ƒ ‚ n  | j | ƒ qN W| S(	   Nt   ssl_fingerprintss]   specifying ssl_fingerprints not supported by this installation of Python; requires Python 2.6R{   Ra   i@   sY   ssl_fingerprints must each be the SHA256 certificate hash in hex (with or without colons)(    (    (   RÜ   R‰   t   hashlibRs   R«   R†   RÊ   t   append(   RÚ   Ré   t   normalized_fprst   fpr(    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR   ;  s    
c         C   sV   |  d } | rR t  j d k  r. t d ƒ ‚ n  t j d | ƒ rR t d ƒ ‚ qR n  | S(	   Nt   ssl_ciphersi   i   i    sX   specifying ssl_ciphers not supported by this installation of Python; requires Python 2.7s   [^a-zA-z0-9, :!\-+@]s    invalid character in ssl_ciphers(   i   i   i    (   t   syst   version_infoRs   t   ret   search(   RÚ   Rî   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR	   P  s    
R)   c   
      C   s  | j  ƒ  } d | k r! d } n d | k r6 d } n d } d t |  | | f } t j | ƒ \ } } | t j k s} | r› | j d | | | f ƒ d Sd } xA | j d ƒ D]0 } t	 j
 d | ƒ }	 |	 r± |	 j d	 ƒ } q± q± W| d k r| j d
 |  | | f ƒ n  | S(   sk   Mac OSX: return a keychain password, if it exists.  Otherwise, return
         
         None.
            t   imapt   popt   pop3s   ????s4   %s find-internet-password -g -a '%s' -s '%s' -r '%s's!   keychain command %s failed: %s %ss   
s   password: "([^"]+)"i   s'   No keychain password found for %s %s %sN(   R«   t   osx_keychain_binaryt   commandst   getstatusoutputR*   t   EX_OKt   errorR‰   R…   Rñ   t   matcht   groupR´   (
   R³   t   servert   protocolR¸   t   cmdt   statust   outputR`   RÍ   Rû   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyt   keychain_passwordb  s,    				c         C   s}   y% t  j |  d | d | d d ƒ } Wn/ t  j k
 rV | j d |  | | f ƒ d SX| ry d | d k ry | d d Sd S(   sa   Gnome: return a keyring password, if it exists.  Otherwise, return
            None.
            i    s1   gnome-keyring does not know password for %s %s %sR`   N(   t   gnomekeyringt   find_network_password_syncR‰   t   NoMatchErrorR´   (   R³   Rý   Rþ   R¸   t   secret(    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR  …  s    	c         C   s   d S(   sZ   Neither Mac OSX keychain or Gnome keyring available: always return 
        None.
        N(   R‰   (   R³   Rý   Rþ   R¸   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR  ¥  s    c         C   sB   t  | | | | ƒ } | r+ | j d ƒ n t j d |  ƒ } | S(   Ns$   using password from keychain/keyrings   Enter password for %s:  (   R  R´   t   getpass(   t   labelR³   Rý   Rþ   R¸   R`   (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyR   ­  s
    (   s   password(    (;   RT   t   __all__R*   t   os.pathRÓ   R‚   R   RY   R   Rñ   R$   R­   Rµ   R  R÷   Rï   RÜ   t   ImportErrorR‰   Rê   R  t   is_availablet   getmailcore.exceptionsR[   RM   R9   R©   Rö   R   R   R   t   objectR   R   Ri   Rk   R   R
   R   R    R   R   R   R   R   R   R   R   R   R   R   R   R   R	   R  R+   R3   RÙ   R   (    (    (    s9   /usr/lib/python2.7/dist-packages/getmailcore/utilities.pyt   <module>   sÄ   	




				0$		i															"