
uNc           @   s~  d  d k  l Z l Z l Z l Z d  d k l Z d  d k l Z l	 Z	 l
 Z
 l Z l Z d  d k l Z d  d k Z  d  d k Z d  d k Z d  d k Z d  d k Z d  d k Z d  d k l Z d  d k l Z y d  d k l Z l Z Wn e j
 o e Z n Xy3 e Z d  d k Z d	 e  e  j o
 e! Z n Wn e j
 o n Xd
 f  d     YZ" d e# f d     YZ$ d S(   i(   t   imaplibutilt   imaputilt
   threadutilt   OfflineImapError(   t   getglobalui(   t   Lockt   BoundedSemaphoret   Threadt   Eventt   currentThread(   t	   get_identN(   t   exc_info(   t   gaierror(   t   SSLErrort   cert_time_to_secondst   authGSSClientWrapt
   IMAPServerc           B   s   e  Z d  Z d Z d Z d   Z d   Z d   Z d   Z e	 d  Z
 d   Z d	   Z d
   Z d   Z d   Z d   Z d   Z d   Z RS(   s   Initializes all variables from an IMAPRepository() instance

    Various functions, such as acquireconnection() return an IMAP4
    object on which we can operate.i    i   c         C   s  t    |  _ | |  _ | i   |  _ | i   |  _ | i   |  _ |  i o d  n
 | i
   |  _ d  |  _ d  |  _ d  |  _ |  i o d  n
 | i   |  _ | i   |  _ |  i d  j o |  i o d n d |  _ n | i   |  _ | i   |  _ | i   |  _ |  i d  j o d  |  _ n d  |  _ d  |  _ | i   |  _ g  |  _ g  |  _ h  |  _  t! |  i  |  _" t#   |  _$ | i%   |  _& | i'   |  _( |  i) |  _* d  |  _+ t, |  _- d  S(   Ni  i   (.   R   t   uit   repost	   getconfigt   configt   getpreauthtunnelt   tunnelt   getsslt   usesslt   Nonet   getusert   usernamet   passwordt   passworderrort   goodpasswordt   gethostt   hostnamet   getportt   portt   getsslclientcertt   sslclientcertt   getsslclientkeyt   sslclientkeyt   getsslcacertfilet   sslcacertfilet
   verifycertt   delimt   roott   getmaxconnectionst   maxconnectionst   availableconnectionst   assignedconnectionst	   lastownerR   t	   semaphoreR   t   connectionlockt   getreferencet	   referencet   getidlefolderst   idlefolderst   GSS_STATE_STEPt   gss_stept   gss_vct   Falset   gssapi(   t   selfR   (    (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyt   __init__4   s>    	 			 						c         C   s   |  i  d j o |  i  S|  i d j o |  i d j o |  i S|  i i   p% |  i i |  i i   |  i	 |  i  |  _ d |  _ |  i S(   s#   Returns the server password or NoneN(
   R   R   R   R   R   t   getpasswordR   t   getpasst   getnameR   (   R<   (    (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyR>   U   s     	c         C   s   |  i  S(   sq   Returns this server's folder delimiter.  Can only be called
        after one or more calls to acquireconnection.(   R*   (   R<   (    (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyt   getdelimd   s    c         C   s   |  i  S(   sl   Returns this server's folder root.  Can only be called after one
        or more calls to acquireconnection.(   R+   (   R<   (    (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyt   getrooti   s    c         C   s|   | d j o d S|  i i   |  i i |  | i p | o | i   n |  i i |  |  i i	   |  i
 i	   d S(   s   Releases a connection, returning it to the pool.

        :param drop_conn: If True, the connection will be released and
           not be reused. This can be used to indicate broken connections.N(   R   R2   t   acquireR/   t   removet	   Terminatet   logoutR.   t   appendt   releaseR1   (   R<   t
   connectiont	   drop_conn(    (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyt   releaseconnectiono   s     c         C   sm   | i    } |  i i d d |  |  i   } |  i d t i | |  i   } |  i i d d |  | S(   Nt   imaps   md5handler: got challenge %st    s   md5handler: returning %s(   t   stripR   t   debugR>   R   t   hmact   newt	   hexdigest(   R<   t   responset	   challenget   passwdt   retval(    (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyt
   md5handler   s    #c         C   s0   |  i  i d d  | i |  i |  i    d  S(   NRL   s   Attempting plain authentication(   R   RO   t   loginR   R>   (   R<   t   imapobj(    (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyt	   plainauth   s    c         C   sp  t  i |  } y |  i |  i j ox |  i p5 t i d |  i  \ } |  _ t i |  i  } n t i	 |  i |  } | t i
 j o |  i |  _ q nZ |  i |  i j oF t i |  i |  } t i |  i  } t i |  i | |  i  } n t i |  i  } WnF t i j
 o7 } |  i i d d | d d | d d f  d  SX| p
 d } n t  i |  S(   Ns   imap@RL   s   %s: %si    i   t    (   t   base64t	   b64encodeR8   R7   R9   t   kerberost   authGSSClientInitR    t   authGSSClientResponset   authGSSClientStept   AUTH_GSS_CONTINUEt   GSS_STATE_WRAPt   authGSSClientUnwrapR   R   t   GSSErrorR   RO   R   t	   b64decode(   R<   RS   t   datat   rct   err(    (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyt   gssauth   s,    
	-
c         C   sF  |  i  i   |  i i   d } t |  i  o d } x` t t |  i  d d d  D]? } |  i | } |  i | t   j o | } |  i | =PqV qV W| p |  i d } |  i d =n |  i	 i
 |  t   |  i | <|  i i   | S|  i i   d } yx| p|  i o> |  i i d |  i  t i |  i d t i   } d } n |  i on |  i i |  i |  i  |  i i   } t i |  i |  i |  i |  i |  i |  i d t i   d | } n> |  i i |  i |  i  t i |  i |  i d t i   } |  i pyd | i j o t o |  i i   |  i i  d d	  y | i! d
 |  i"  Wn4 | i# j
 o% } t$ |  _% |  i i  d d  n0 Xt& |  _% t' i( |  i)  d |  _) |  i* |  _+ |  i i   n |  i% p d | i j o, |  i o! |  i i  d d  | i,   n d | i j oV |  i i  d d  y | i! d |  i-  Wq| i# j
 o } |  i. |  qXqd | i j o t/ d t/ i0 i1   n |  i. |  n d } |  i2 |  _3 Wq| i# j
 o } t4 |  |  _5   qXqqW| i6   \ } } | d g j o# t7 | d i8   i9    | _ n |  i: d j o | i; |  i< d  d }	 |	 d g j p |	 d j o | i; |  i< d  d }	 n |	 d g j p |	 d j o< d |  i i=   |  i< f }
 |  i i> |
  t? |
   n t@ iA |	 d  d \ |  _: |  _B t@ iC |  i:  |  _: t@ iC |  iB  |  _B n |  i i   |  i	 i
 |  t   |  i | <|  i i   | SWnt? j
 o} |  i  i   |  i iD   o |  i i   n t/ i0 i1 } tE |  tF j o) d |  i |  i f } t/ | |   n tG ov tH | tG  of | iI d j oV |  i d j o d |  i |  i f } n d |  i |  i | f } t/ | |   nZ tH | t i#  oF | iJ d tI iK j o/ d |  i |  i |  iL f } t/ | |   n t4 |  d  d j o) t/ d |  i |  i f t/ i0 i1   qB  n Xd S(   s   Fetches a connection from the pool, making sure to create a new one
        if needed, to obey the maximum connection limits, etc.
        Opens a connection to the server and returns an appropriate
        object.i   ii    R   t   timeoutt   fingerprints   AUTH=GSSAPIRL   s    Attempting GSSAPI authenticationt   GSSAPIs   GSSAPI Authentication failedt   STARTTLSs   Using STARTTLS connections   AUTH=CRAM-MD5s"   Attempting CRAM-MD5 authentications   CRAM-MD5t   LOGINDISABLEDs4   Plaintext login disabled by server. Need to use SSL?s   ""s   "*"s'   Server '%s' returned no folders in '%s's   Could not resolve name '%s' for repository '%s'. Make sure you have configured the server name correctly and that you are online.i  sz   Could not connect via SSL to host '%s' and non-standard ssl port %d configured. Make sure you connect to the correct port.sV   Unknown SSL protocol connecting to host '%s' forrepository '%s'. OpenSSL responded:
%ss   Connection to host '%s:%d' for repository '%s' was refused. Make sure you have the right host and port configured and that you are actually able to access the network.i   s   can't open socket; errorsT   Could not connect to remote server '%s' for repository '%s'. Remote does not answer.N(M   R1   RC   R2   R   t   lenR.   t   rangeR0   R
   R/   RG   RH   R   R   t
   connectingR    t   IMAP4_Tunnelt   sockett   getdefaulttimeoutR   R    R"   R   t   get_ssl_fingerprintt   WrappedIMAP4_SSLR&   R$   R(   R)   t   WrappedIMAP4t   capabilitiest   have_gssRO   t   authenticateRj   t   errorR:   R;   t   TrueR^   t   authGSSClientCleanR9   R7   R8   t   starttlsRW   RZ   R   t   ERRORt   REPOR   R   t   strR   t
   capabilityt   tuplet   uppert   splitR*   t   listR4   R@   t   warnt	   ExceptionR   t	   imapsplitR+   t   dequotet   lockedt   typeR   R   t
   isinstancet   errnot   argst   ECONNREFUSEDt	   reposname(   R<   RY   t   it   tryobjt   successRl   t   valt   typt   datt   listresRi   t   et   severityt   reason(    (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyt   acquireconnection   s      
	 


	
			
	##'*c         C   s   |  i  i   |  i  i   d S(   s  Waits until there is a connection available.  Note that between
        the time that a connection becomes available and the time it is
        requested, another thread may have grabbed it.  This function is
        mainly present as a way to avoid spawning thousands of threads
        to copy messages, then have them all wait for 3 available connections.
        It's OK if we have maxconnections + 1 or 2 threads, which is what
        this will help us do.N(   R1   RC   RH   (   R<   (    (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyt   connectionwaitg  s    c         C   s   |  i  i   t i |  i |  i  x" |  i |  i D] } | i   q4 Wg  |  _ g  |  _ h  |  _	 |  i
 |  _ d  |  _ t |  _ |  i  i   d  S(   N(   R2   RC   R   t   semaphoreresetR1   R-   R/   R.   RF   R0   R7   R8   R   R9   R:   R;   RH   (   R<   RY   (    (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyt   closer  s     					c         C   s  |  i  i d d  x|  i  i d d  | i   o |  i  i d d  d S|  i  i d d  |  i i   t |  i  t |  i  } |  i i   |  i  i d d  g  } x t	 |  D] } |  i  i d d | | f  t |  i
  | j o t |  |  i
 |  } n t |   } | i   | i |  |  i  i d d	  q W|  i  i d d
  | i |  |  i  i d d  |  i  i d d  x" | D] } | i   | i   qW|  i  i d d  q d S(   s<  Sends a NOOP to each connection recorded.   It will wait a maximum
        of timeout seconds between doing this, and will continue to do so
        until the Event object as passed is true.  This method is expected
        to be invoked in a separate thread, which should be join()'d after
        the event is set.RL   s   keepalive thread starteds   keepalive: top of loops    keepalive: event is set; exitingNs#   keepalive: acquiring connectionlocks"   keepalive: connectionlock releaseds)   keepalive: processing connection %d of %ds   keepalive: thread starteds   keepalive: waiting for timeouts   keepalive: after waits   keepalive: joining threadss   keepalive: bottom of loop(   R   RO   t   isSetR2   RC   Rp   R/   R.   RH   Rq   R6   t
   IdleThreadt   startRG   t   waitt   stopt   join(   R<   Rk   t   eventt   numconnectionst   threadsR   t   idler(    (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyt	   keepalive  s>     
 
c      
   C   sw  d } | p	 d | S| i    } g  } | i d  } | o, t i   t |  j o d | | f Sn xN | i d g   D]: } | d \ } }	 | d j o | i |	 i     q} q} Wt |  d j o	 d | SxD | i d	 g   D]0 \ } }	 | d
 j o | i |	 i     q q WxN | D]F }
 |
 | j p. d | j o& |
 d | i d d  d j o d Sq%Wd | S(   s   Verify that cert (in socket.getpeercert() format) matches hostname.
        CRLs are not handled.
        
        Returns error message if any problems are found and None on success.
        s   CA Cert verifying failed: s   %s no certificate receivedt   notAfters   %s certificate expired %st   subjecti    t
   commonNames%   %s no commonName found in certificatet   subjectAltNamet   DNSt   .s   *.i   s/   %s no matching domain name found in certificateN(   t   lowert   gett   timeR   RG   Rp   R   R   (   R<   t   certR    t   errstrt   dnsnamet	   certnamest   notaftert   st   keyt   valuet   certname(    (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyR)     s4    	 	  .	(   t   __name__t
   __module__t   __doc__R7   Rc   R=   R>   RA   RB   R:   RK   RW   RZ   Rj   R   R   R   R   R)   (    (    (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyR   -   s    	!											,R   c           B   sJ   e  Z d d   Z d   Z d   Z d   Z d   Z d   Z d   Z	 RS(   c         C   sy   | |  _  | |  _ t   |  _ t   |  _ | d j o t d |  i  |  _	 n t d |  i
  |  _	 |  i	 i d  d S(   s   If invoked without 'folder', perform a NOOP and wait for
        self.stop() to be called. If invoked with folder, switch to IDLE
        mode and synchronize once we have a new messaget   targeti   N(   t   parentt   folderR   t   stop_sigR   R   R   R   t   noopt   threadt   idlet	   setDaemon(   R<   R   R   (    (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyR=     s    		c         C   s   |  i  i   d  S(   N(   R   R   (   R<   (    (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyR     s    c         C   s   |  i  i   d  S(   N(   R   t   set(   R<   (    (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyR     s    c         C   s   |  i  i   d  S(   N(   R   R   (   R<   (    (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyR     s    c         C   s:   |  i  i   } | i   |  i i   |  i  i |  d  S(   N(   R   R   R   R   R   RK   (   R<   RY   (    (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyR     s    
c         C   s   |  i  i } | i } | i } | i } | i } | i |  i  } t i	 i
 | i | | | | d t t   } | i t    d  S(   Nt   quick(   R   R   t   accountt
   localrepost   remoterepost   statusrepost	   getfolderR   t   offlineimapt   accountst
   syncfoldert   nameR:   R   t   unregisterthreadR	   (   R<   R   R   R   R   t   remotefolderR   (    (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyt   dosync  s    				%	c            s    f d   } x  i  i   pt   _ t } x | p   i i   } y | i   i  Wnb t j
 oV } | i	 t i
 i j o1   i i | t   d    i i | t  q |  q4 Xt } q4 Wd | i j o | i d |  n"   i i d | i  | i     i  i   y | i   Wn@ | i j
 o1   i i d | i    i i | t  n X  i i |    i o   i  i     i   q q Wd S(   s8   Invoke IDLE mode until timeout or self.stop() is invokedc            sK   |  \ } } } | d j o   i i   o t   _ n   i i   d S(   s  IDLE callback function invoked by imaplib2

            This is invoked when a) The IMAP server tells us something
            while in IDLE mode, b) we get an Exception (e.g. on dropped
            connections, or c) the standard imaplib IDLE timeout of 29
            minutes kicks in.N(   R   R   R   R}   t   needsyncR   (   R   t   resultt   cb_argt   exc_data(   R<   (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyt   callback  s    i   t   IDLER   sF   IMAP IDLE not supported on server '%s'.Sleep until next refresh cycle.s(   Attempting NOOP on dropped connection %sN(   R   R   R:   R   R   R   t   selectR   R   R   R   t   FOLDER_RETRYR   R|   R   RK   R}   Ry   R   R   t
   identifierR   R   t   abortt   clearR   (   R<   R   R   RY   R   (    (   R<   sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyR     s@     	 

N(
   R   R   R   R=   R   R   R   R   R   R   (    (    (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyR     s   					(%   R   R    R   R   R   t   offlineimap.uiR   t	   threadingR   R   R   R   R	   R   R
   t   offlineimap.accountsRP   Rt   R\   R   R   t   sysR   R   t   sslR   R   t   ImportErrorR   R:   Rz   R^   t   dirR}   R   t   objectR   (    (    (    sz   /projectLibrary/707976 EPBuoyPrototypeAndTesting/SpotWatchCircleAlarm/spaetz-offlineimap-5f3ac2c/offlineimap/imapserver.pyt   <module>   s2   "( 