ó
Y[c           @   s†   d  Z  d d l Z d d l Z d d l m Z m Z d d l m Z d d l m Z e j	 e
 ƒ Z d e f d „  ƒ  YZ d „  Z d S(	   s*   Tools for checking certificate revocation.iÿÿÿÿN(   t   Popent   PIPE(   t   errors(   t   utilt   RevocationCheckerc           B   s)   e  Z d  Z d „  Z d „  Z d „  Z RS(   sE   This class figures out OCSP checking on this system, and performs it.c         C   sœ   t  |  _ t j d ƒ s2 t j d ƒ t |  _ d  St d d d d d g d t d t d	 t ƒ} | j	 ƒ  \ } } d
 | k rŒ d „  |  _
 n d „  |  _
 d  S(   Nt   openssls-   openssl not installed, can't check revocationt   ocsps   -headert   vart   valt   stdoutt   stderrt   universal_newliness	   Missing =c         S   s   d |  g S(   Ns   Host=(    (   t   host(    (    s0   /usr/lib/python2.7/dist-packages/certbot/ocsp.pyt   <lambda>   s    c         S   s
   d |  g S(   Nt   Host(    (   R   (    (    s0   /usr/lib/python2.7/dist-packages/certbot/ocsp.pyR      s    (   t   Falset   brokenR   t
   exe_existst   loggert   infot   TrueR    R   t   communicatet	   host_args(   t   selft   test_host_formatt   _outt   err(    (    s0   /usr/lib/python2.7/dist-packages/certbot/ocsp.pyt   __init__   s    		c         C   sì   |  j  r t S|  j | ƒ \ } } | s, t Sd d d d | d | d | d | d | d	 d
 g |  j | ƒ } t j d | ƒ t j d j | ƒ ƒ y" t j | d t j ƒ\ } } Wn% t	 j
 k
 rÛ t j d | ƒ t SXt | | | ƒ S(   s;  Get revoked status for a particular cert version.

        .. todo:: Make this a non-blocking call

        :param str cert_path: Path to certificate
        :param str chain_path: Path to intermediate cert
        :rtype bool or None:
        :returns: True if revoked; False if valid or the check failed

        R   R   s	   -no_nonces   -issuers   -certs   -urls   -CAfiles   -verify_others   -trust_others   -headers   Querying OCSP for %st    t   logs*   OCSP check failed for %s (are we offline?)(   R   R   t   determine_ocsp_serverR   R   t   debugt   joinR   t
   run_scriptR   t   SubprocessErrorR   t   _translate_ocsp_query(   R   t	   cert_patht
   chain_patht   urlR   t   cmdt   outputR   (    (    s0   /usr/lib/python2.7/dist-packages/certbot/ocsp.pyt   ocsp_revoked!   s,    	"c         C   s¯   y4 t  j d d d | d d g d t j ƒ\ } } Wn% t j k
 r[ t j d | ƒ d SX| j ƒ  } | j	 d ƒ d	 j d
 ƒ } | r” | | f St j d | | ƒ d Sd S(   sÞ   Extract the OCSP server host from a certificate.

        :param str cert_path: Path to the cert we're checking OCSP for
        :rtype tuple:
        :returns: (OCSP server URL or None, OCSP server host or None)

        R   t   x509s   -ins   -noouts	   -ocsp_uriR   s   Cannot extract OCSP URI from %ss   ://i   t   /s4   Cannot process OCSP host from URL (%s) in cert at %sN(   NN(   NN(
   R   R!   R   R   R   R"   R   t   Nonet   rstript	   partition(   R   R$   R&   t   _errR   (    (    s0   /usr/lib/python2.7/dist-packages/certbot/ocsp.pyR   H   s    
(   t   __name__t
   __module__t   __doc__R   R)   R   (    (    (    s0   /usr/lib/python2.7/dist-packages/certbot/ocsp.pyR      s   		'c   
         s  d } g  | D] } d j  |  | ƒ ^ q } ‡  f d †  | Dƒ \ } } } | r_ | j d ƒ n d }	 d | k sƒ | r} |	 sƒ | rª t j d |  ƒ t j d	 ˆ  | ƒ t S| r» |	 r» t S| rí | j d ƒ }	 |	 ré t j d
 |	 ƒ n  t St j d ˆ  | ƒ t Sd S(   s7   Parse openssl's weird output to work out what it means.t   goodt   revokedt   unknowns   {0}: (WARNING.*)?{1}c         3   s*   |  ]  } t  j | ˆ  d  t  j ƒVq d S(   t   flagsN(   t   ret   searcht   DOTALL(   t   .0t   p(   t   ocsp_output(    s0   /usr/lib/python2.7/dist-packages/certbot/ocsp.pys	   <genexpr>e   s    i   s   Response verify OKs#   Revocation status for %s is unknowns   Uncertain output:
%s
stderr:
%ss   OCSP revocation warning: %ss2   Unable to properly parse OCSP output: %s
stderr:%sN(   s   goods   revokeds   unknown(	   t   formatt   groupR,   R   R   R   R   R   t   warn(
   R$   R<   t   ocsp_errorst   statest   st   patternsR3   R4   R5   t   warning(    (   R<   s0   /usr/lib/python2.7/dist-packages/certbot/ocsp.pyR#   `   s$    %	
(   R2   t   loggingR7   t
   subprocessR    R   t   certbotR   R   t	   getLoggerR0   R   t   objectR   R#   (    (    (    s0   /usr/lib/python2.7/dist-packages/certbot/ocsp.pyt   <module>   s   T