<s> """<STR_LIT>""" <EOL> import datetime <EOL> import httplib <EOL> import logging <EOL> import mimetools <EOL> import os <EOL> import platform <EOL> import subprocess <EOL> import sys <EOL> import tempfile <EOL> import time <EOL> import urllib <EOL> import urlparse <EOL> import warnings <EOL> from M2Crypto import SSL <EOL> from M2Crypto . SSL import Checker <EOL> from simian . auth import x509 <EOL> from simian import auth <EOL> from simian import settings <EOL> from simian . auth import client as auth_client <EOL> from simian . auth import util <EOL> warnings . filterwarnings ( <EOL> '<STR_LIT:ignore>' , '<STR_LIT>' , DeprecationWarning , '<STR_LIT>' , <NUM_LIT:0> ) <EOL> if sys . version_info [ <NUM_LIT:0> ] <= <NUM_LIT:2> and sys . version_info [ <NUM_LIT:1> ] <= <NUM_LIT:4> : <EOL> warnings . filterwarnings ( <EOL> '<STR_LIT:ignore>' , '<STR_LIT>' , DeprecationWarning , '<STR_LIT>' , <NUM_LIT:0> ) <EOL> import posixfile as _stdio <EOL> else : <EOL> import os as _stdio <EOL> DEFAULT_HTTP_ATTEMPTS = <NUM_LIT:4> <EOL> DEFAULT_RETRY_HTTP_STATUS_CODES = frozenset ( [ <NUM_LIT> , <NUM_LIT> , <NUM_LIT> , <NUM_LIT> ] ) <EOL> SERVER_HOSTNAME = settings . SERVER_HOSTNAME <EOL> SERVER_PORT = settings . SERVER_PORT <EOL> AUTH_DOMAIN = settings . AUTH_DOMAIN <EOL> CLIENT_SSL_PATH = settings . CLIENT_SSL_PATH <EOL> SEEK_SET = _stdio . SEEK_SET <EOL> SEEK_CUR = _stdio . SEEK_CUR <EOL> SEEK_END = _stdio . SEEK_END <EOL> DEBUG = False <EOL> if DEBUG : <EOL> logging . getLogger ( ) . setLevel ( logging . DEBUG ) <EOL> URL_UPLOADPKG = '<STR_LIT>' <EOL> _CIPHER_LIST = '<STR_LIT::>' . join ( [ <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> '<STR_LIT>' , <EOL> ] ) <EOL> _SSL_VERSION = '<STR_LIT>' <EOL> class Error ( Exception ) : <EOL> """<STR_LIT>""" <EOL> class HTTPError ( Error ) : <EOL> """<STR_LIT>""" <EOL> class SimianServerError ( Error ) : <EOL> """<STR_LIT>""" <EOL> class SimianClientError ( Error ) : <EOL> """<STR_LIT>""" <EOL> class SudoExecError ( Error ) : <EOL> """<STR_LIT>""" <EOL> class PuppetSslCertError ( Error ) : <EOL> """<STR_LIT>""" <EOL> class FacterError ( Error ) : <EOL> """<STR_LIT>""" <EOL> class Response ( object ) : <EOL> """<STR_LIT>""" <EOL> status = None <EOL> reason = None <EOL> headers = None <EOL> body = None <EOL> body_len = None <EOL> def __init__ ( <EOL> self , status , reason = None , body = None , headers = None , body_len = None ) : <EOL> """<STR_LIT>""" <EOL> self . status = status <EOL> self . reason = reason <EOL> self . body = body <EOL> self . body_len = body_len <EOL> if type ( headers ) is dict : <EOL> self . headers = headers <EOL> elif type ( headers ) is list : <EOL> headers_dict = { } <EOL> for k , v in headers : <EOL> headers_dict [ k ] = v <EOL> self . headers = headers_dict <EOL> def IsSuccess ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . status >= <NUM_LIT:200> and self . status <= <NUM_LIT> <EOL> def IsRedirect ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . status >= <NUM_LIT> and self . status <= <NUM_LIT> <EOL> def IsClientError ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . status >= <NUM_LIT> and self . status <= <NUM_LIT> <EOL> def IsServerError ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . status >= <NUM_LIT> and self . status <= <NUM_LIT> <EOL> def IsError ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . status >= <NUM_LIT> and self . status <= <NUM_LIT> <EOL> class MultiBodyConnection : <EOL> """<STR_LIT>""" <EOL> DIRECT_SEND_TYPES = [ str ] <EOL> def SetProgressCallback ( self , fn ) : <EOL> """<STR_LIT>""" <EOL> if not callable ( fn ) : <EOL> raise Error ( '<STR_LIT>' ) <EOL> self . _progress_callback = fn <EOL> def _ProgressCallback ( self , bytes_sent , bytes_total ) : <EOL> """<STR_LIT>""" <EOL> if hasattr ( self , '<STR_LIT>' ) : <EOL> self . _progress_callback ( bytes_sent , bytes_total ) <EOL> def request ( self , method , url , body = None , headers = None ) : <EOL> """<STR_LIT>""" <EOL> if headers is None : <EOL> headers = { } <EOL> if body is not None : <EOL> if type ( body ) is list : <EOL> multibody = body <EOL> else : <EOL> multibody = [ body ] <EOL> content_length = <NUM_LIT:0> <EOL> for body in multibody : <EOL> if type ( body ) in self . DIRECT_SEND_TYPES : <EOL> content_length += len ( body ) <EOL> elif hasattr ( body , '<STR_LIT>' ) and hasattr ( <EOL> body , '<STR_LIT>' ) and hasattr ( body , '<STR_LIT>' ) : <EOL> orig_pos = body . tell ( ) <EOL> body . seek ( <NUM_LIT:0> , SEEK_END ) <EOL> content_length += body . tell ( ) - orig_pos <EOL> body . seek ( orig_pos , SEEK_SET ) <EOL> else : <EOL> raise NotImplementedError ( '<STR_LIT>' % type ( body ) ) <EOL> headers [ '<STR_LIT>' ] = content_length <EOL> else : <EOL> multibody = [ ] <EOL> content_length = <NUM_LIT:0> <EOL> if self . _is_https and self . port == <NUM_LIT> : <EOL> headers [ '<STR_LIT>' ] = self . host <EOL> httplib . HTTPConnection . request ( <EOL> self , method , url , headers = headers ) <EOL> bytes_sent = <NUM_LIT:0> <EOL> self . _ProgressCallback ( bytes_sent , content_length ) <EOL> for body in multibody : <EOL> if type ( body ) in self . DIRECT_SEND_TYPES : <EOL> if body != '<STR_LIT>' : <EOL> self . send ( body ) <EOL> bytes_sent += len ( body ) <EOL> self . _ProgressCallback ( bytes_sent , content_length ) <EOL> else : <EOL> buf = body . read ( <NUM_LIT> ) <EOL> while buf != '<STR_LIT>' : <EOL> self . send ( buf ) <EOL> bytes_sent += len ( buf ) <EOL> self . _ProgressCallback ( bytes_sent , content_length ) <EOL> buf = body . read ( <NUM_LIT> ) <EOL> self . _ProgressCallback ( bytes_sent , content_length ) <EOL> class HTTPMultiBodyConnection ( MultiBodyConnection , httplib . HTTPConnection ) : <EOL> """<STR_LIT>""" <EOL> _is_https = False <EOL> class HTTPSMultiBodyConnection ( MultiBodyConnection , httplib . HTTPSConnection ) : <EOL> """<STR_LIT>""" <EOL> _is_https = True <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> httplib . HTTPSConnection . __init__ ( self , * args , ** kwargs ) <EOL> @ classmethod <EOL> def SetCACertChain ( cls , certs ) : <EOL> """<STR_LIT>""" <EOL> cls . _ca_cert_chain = certs <EOL> def _IsValidCert ( self , ok , store ) : <EOL> """<STR_LIT>""" <EOL> if ok != <NUM_LIT:1> : <EOL> subject = str ( store . get_current_cert ( ) . get_subject ( ) ) <EOL> logging . debug ( <EOL> '<STR_LIT>' , str ( ok ) , subject ) <EOL> return ( ok == <NUM_LIT:1> ) * <NUM_LIT:1> <EOL> def _LoadCACertChain ( self , ctx ) : <EOL> """<STR_LIT>""" <EOL> if not hasattr ( self , '<STR_LIT>' ) : <EOL> raise SimianClientError ( '<STR_LIT>' ) <EOL> tf = tempfile . NamedTemporaryFile ( ) <EOL> tf . write ( self . _ca_cert_chain ) <EOL> tf . flush ( ) <EOL> if ctx . load_verify_locations ( cafile = tf . name ) != <NUM_LIT:1> : <EOL> tf . close ( ) <EOL> raise SimianClientError ( '<STR_LIT>' ) <EOL> ctx . set_verify ( <EOL> SSL . verify_peer | SSL . verify_fail_if_no_peer_cert , <EOL> depth = <NUM_LIT:9> , <EOL> callback = self . _IsValidCert ) <EOL> tf . close ( ) <EOL> logging . debug ( <EOL> '<STR_LIT>' , <EOL> len ( self . _ca_cert_chain ) ) <EOL> def connect ( self ) : <EOL> """<STR_LIT>""" <EOL> server_address = ( ( self . host , self . port ) ) <EOL> ctx = SSL . Context ( _SSL_VERSION ) <EOL> ctx . set_cipher_list ( _CIPHER_LIST ) <EOL> if hasattr ( self , '<STR_LIT>' ) : <EOL> self . _LoadCACertChain ( ctx ) <EOL> else : <EOL> raise SimianClientError ( '<STR_LIT>' ) <EOL> logging . debug ( '<STR_LIT>' ) <EOL> sock = SSL . Connection ( ctx ) <EOL> logging . debug ( '<STR_LIT>' , server_address ) <EOL> try : <EOL> sock . connect ( server_address ) <EOL> except SSL . SSLError , e : <EOL> raise SimianClientError ( '<STR_LIT>' % str ( e ) ) <EOL> except Checker . SSLVerificationError , e : <EOL> raise SimianClientError ( '<STR_LIT>' % str ( e ) ) <EOL> logging . debug ( '<STR_LIT>' , server_address ) <EOL> self . sock = sock <EOL> class HttpsClient ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , hostname , port = None , proxy = None ) : <EOL> self . _LoadHost ( hostname , port , proxy ) <EOL> self . _progress_callback = None <EOL> self . _ca_cert_chain = None <EOL> def SetProgressCallback ( self , fn ) : <EOL> self . _progress_callback = fn <EOL> def SetCACertChain ( self , certs ) : <EOL> """<STR_LIT>""" <EOL> self . _ca_cert_chain = certs <EOL> def _LoadHost ( self , hostname , port = None , proxy = None ) : <EOL> """<STR_LIT>""" <EOL> logging . debug ( '<STR_LIT>' , hostname , port ) <EOL> hostname = str ( hostname ) <EOL> if proxy is not None : <EOL> proxy = str ( proxy ) <EOL> elif proxy is None : <EOL> if os . environ . get ( '<STR_LIT>' ) : <EOL> proxy = str ( os . environ [ '<STR_LIT>' ] ) <EOL> elif os . environ . get ( '<STR_LIT>' ) : <EOL> proxy = str ( os . environ [ '<STR_LIT>' ] ) <EOL> if not hostname . startswith ( '<STR_LIT:http>' ) : <EOL> hostname = '<STR_LIT>' % hostname <EOL> ( scheme , netloc , unused_path , unused_query , unused_frag <EOL> ) = urlparse . urlsplit ( hostname ) <EOL> ( hostname , tmp_port ) = urllib . splitport ( netloc ) <EOL> if tmp_port : <EOL> port = tmp_port <EOL> use_https = False <EOL> if scheme == '<STR_LIT>' : <EOL> use_https = True <EOL> if port : <EOL> try : <EOL> port = int ( port ) <EOL> except TypeError : <EOL> raise Error ( '<STR_LIT>' % str ( port ) ) <EOL> if port == <NUM_LIT> and not use_https : <EOL> port = None <EOL> if port == <NUM_LIT> and use_https : <EOL> port = None <EOL> self . hostname = hostname <EOL> self . port = port <EOL> self . netloc = self . hostname <EOL> self . use_https = use_https <EOL> if self . port and self . port != <NUM_LIT> and self . port != <NUM_LIT> : <EOL> self . netloc = '<STR_LIT>' % ( self . netloc , self . port ) <EOL> logging . debug ( '<STR_LIT>' , <EOL> self . hostname , self . port , self . use_https ) <EOL> self . proxy_hostname = None <EOL> self . proxy_port = None <EOL> self . proxy_use_https = False <EOL> if proxy : <EOL> u = urlparse . urlparse ( proxy ) <EOL> if u . scheme in [ '<STR_LIT>' , '<STR_LIT:http>' ] : <EOL> self . proxy_use_https = u . scheme == '<STR_LIT>' <EOL> ( self . proxy_hostname , self . proxy_port ) = urllib . splitport ( u . netloc ) <EOL> else : <EOL> ( self . proxy_hostname , self . proxy_port ) = urllib . splitport ( proxy ) <EOL> if not self . proxy_port : <EOL> raise Error ( '<STR_LIT>' , proxy ) <EOL> self . proxy_port = int ( self . proxy_port ) <EOL> logging . debug ( '<STR_LIT>' , <EOL> self . proxy_hostname , self . proxy_port ) <EOL> def _AdjustHeaders ( self , unused_headers ) : <EOL> """<STR_LIT>""" <EOL> return <EOL> def _Connect ( self ) : <EOL> """<STR_LIT>""" <EOL> conn_args = ( self . hostname , self . port ) <EOL> if self . proxy_hostname : <EOL> conn_args = ( self . proxy_hostname , self . proxy_port ) <EOL> use_https = self . proxy_use_https <EOL> else : <EOL> use_https = self . use_https <EOL> if use_https : <EOL> conn = HTTPSMultiBodyConnection ( * conn_args ) <EOL> else : <EOL> conn = HTTPMultiBodyConnection ( * conn_args ) <EOL> if self . _progress_callback is not None : <EOL> conn . SetProgressCallback ( self . _progress_callback ) <EOL> if use_https : <EOL> if self . _ca_cert_chain is not None : <EOL> conn . SetCACertChain ( self . _ca_cert_chain ) <EOL> try : <EOL> conn . connect ( ) <EOL> except httplib . socket . error , e : <EOL> raise SimianClientError ( '<STR_LIT>' % str ( e ) ) <EOL> return conn <EOL> def _GetResponse ( self , conn , output_file = None ) : <EOL> """<STR_LIT>""" <EOL> response = conn . getresponse ( ) <EOL> headers = response . getheaders ( ) <EOL> status = response . status <EOL> reason = response . reason <EOL> body_len = <NUM_LIT:0> <EOL> read_len = <NUM_LIT> <EOL> if output_file : <EOL> buf = response . read ( read_len ) <EOL> while buf : <EOL> body_len += len ( buf ) <EOL> output_file . write ( buf ) <EOL> buf = response . read ( read_len ) <EOL> body = None <EOL> else : <EOL> body = response . read ( ) <EOL> body_len = len ( body ) <EOL> return Response ( <EOL> status = status , reason = reason , <EOL> headers = headers , body = body , body_len = body_len ) <EOL> def _Request ( self , method , conn , url , body = None , headers = None ) : <EOL> """<STR_LIT>""" <EOL> if body is not None and type ( body ) is dict : <EOL> body = urllib . urlencode ( body ) <EOL> if headers is None : <EOL> headers = { } <EOL> if '<STR_LIT>' not in headers : <EOL> headers [ '<STR_LIT>' ] = '<STR_LIT>' <EOL> self . _AdjustHeaders ( headers ) <EOL> conn . request ( method , str ( url ) , body = body , headers = headers ) <EOL> def _DoRequestResponse ( <EOL> self , method , url , body = None , headers = None , output_file = None ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> suffix = self . use_https * '<STR_LIT:s>' <EOL> logging . debug ( '<STR_LIT>' , <EOL> suffix , self . hostname , self . port ) <EOL> conn = self . _Connect ( ) <EOL> if self . proxy_hostname : <EOL> url = '<STR_LIT>' % ( self . use_https * '<STR_LIT:s>' , self . netloc , url ) <EOL> logging . debug ( '<STR_LIT>' , method , url ) <EOL> self . _Request ( method , conn , url , body = body , headers = headers ) <EOL> logging . debug ( '<STR_LIT>' ) <EOL> response = self . _GetResponse ( conn , output_file = output_file ) <EOL> logging . debug ( '<STR_LIT>' , response . status ) <EOL> return response <EOL> except httplib . HTTPException , e : <EOL> raise HTTPError ( str ( e ) ) <EOL> def Do ( <EOL> self , method , url , <EOL> body = None , headers = None , output_filename = None , <EOL> retry_on_status = DEFAULT_RETRY_HTTP_STATUS_CODES , <EOL> attempt_times = DEFAULT_HTTP_ATTEMPTS , _open = open ) : <EOL> """<STR_LIT>""" <EOL> if method not in [ '<STR_LIT:GET>' , '<STR_LIT:POST>' , '<STR_LIT>' , '<STR_LIT>' ] : <EOL> raise NotImplementedError ( '<STR_LIT>' % method ) <EOL> if headers is None : <EOL> headers = { } <EOL> if output_filename : <EOL> output_file = _open ( output_filename , '<STR_LIT:w>' ) <EOL> else : <EOL> output_file = None <EOL> n = <NUM_LIT:0> <EOL> while n < attempt_times : <EOL> time . sleep ( n * <NUM_LIT:5> ) <EOL> n += <NUM_LIT:1> <EOL> logging . debug ( '<STR_LIT>' , method , url , n ) <EOL> try : <EOL> response = self . _DoRequestResponse ( <EOL> method , url , body = body , headers = headers , output_file = output_file ) <EOL> except HTTPError : <EOL> logging . warning ( '<STR_LIT>' , method , url ) <EOL> if n == attempt_times : <EOL> raise <EOL> else : <EOL> if response . status not in retry_on_status : <EOL> break <EOL> logging . warning ( '<STR_LIT>' , method , url ) <EOL> if output_filename : <EOL> output_file . close ( ) <EOL> return response <EOL> def DoMultipart ( <EOL> self , url , params , filename , input_filename = None , input_file = None ) : <EOL> """<STR_LIT>""" <EOL> if not input_filename and not input_file : <EOL> raise Error ( '<STR_LIT>' ) <EOL> boundary = mimetools . choose_boundary ( ) <EOL> content_type = '<STR_LIT>' <EOL> headers = { <EOL> '<STR_LIT:Content-Type>' : '<STR_LIT>' % boundary , <EOL> } <EOL> close_input_file = False <EOL> if input_file is None : <EOL> close_input_file = True <EOL> input_file = open ( input_filename , '<STR_LIT:r>' ) <EOL> crlf = '<STR_LIT:\r\n>' <EOL> body = [ ] <EOL> tmp_body = [ ] <EOL> tmp_body . append ( '<STR_LIT>' % boundary ) <EOL> tmp_body . append ( <EOL> ( '<STR_LIT>' <EOL> '<STR_LIT>' % filename ) ) <EOL> tmp_body . append ( '<STR_LIT>' % content_type ) <EOL> tmp_body . append ( '<STR_LIT>' ) <EOL> body . append ( crlf . join ( tmp_body ) ) <EOL> body . append ( crlf ) <EOL> body . append ( input_file ) <EOL> body . append ( crlf ) <EOL> tmp_body = [ ] <EOL> for k , v in params . iteritems ( ) : <EOL> tmp_body . append ( '<STR_LIT>' % boundary ) <EOL> tmp_body . append ( <EOL> '<STR_LIT>' % k ) <EOL> tmp_body . append ( '<STR_LIT>' ) <EOL> tmp_body . append ( '<STR_LIT>' ) <EOL> tmp_body . append ( v ) <EOL> body . append ( crlf . join ( tmp_body ) ) <EOL> body . append ( '<STR_LIT>' % ( crlf , boundary , crlf ) ) <EOL> body . append ( crlf ) <EOL> try : <EOL> response = self . Do ( '<STR_LIT:POST>' , url , body = body , headers = headers ) <EOL> except : <EOL> if close_input_file : <EOL> input_file . close ( ) <EOL> raise <EOL> if close_input_file : <EOL> input_file . close ( ) <EOL> return response <EOL> class HttpsAuthClient ( HttpsClient ) : <EOL> """<STR_LIT>""" <EOL> CLIENT_SSL_PATH = CLIENT_SSL_PATH <EOL> PUPPET_CERTS = '<STR_LIT>' <EOL> PUPPET_PRIVATE_KEYS = '<STR_LIT>' <EOL> PUPPET_CA_CERT = '<STR_LIT>' <EOL> FACTER_CACHE_OSX_PATH = '<STR_LIT>' <EOL> FACTER_CACHE_DEFAULT_PATH = None <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> super ( HttpsAuthClient , self ) . __init__ ( * args , ** kwargs ) <EOL> self . _auth1 = None <EOL> self . _cookie_token = None <EOL> self . _LoadRootCertChain ( ) <EOL> self . _PlatformSetup ( ) <EOL> self . _LoadCaParameters ( ) <EOL> def _LoadRootCertChain ( self ) : <EOL> """<STR_LIT>""" <EOL> logging . debug ( '<STR_LIT>' ) <EOL> certs = self . GetSystemRootCACertChain ( ) <EOL> self . SetCACertChain ( certs ) <EOL> def _PlatformSetup ( self ) : <EOL> """<STR_LIT>""" <EOL> if platform . system ( ) == '<STR_LIT>' : <EOL> self . facter_cache_path = self . FACTER_CACHE_OSX_PATH <EOL> else : <EOL> self . facter_cache_path = self . FACTER_CACHE_DEFAULT_PATH <EOL> def _LoadCaParameters ( self ) : <EOL> """<STR_LIT>""" <EOL> logging . debug ( '<STR_LIT>' ) <EOL> self . _ca_params = util . GetCaParameters ( <EOL> settings , omit_server_private_key = True ) <EOL> logging . debug ( '<STR_LIT>' ) <EOL> def _AdjustHeaders ( self , headers ) : <EOL> """<STR_LIT>""" <EOL> if self . _cookie_token and headers is not None : <EOL> headers [ '<STR_LIT>' ] = self . _cookie_token <EOL> def GetSystemRootCACertChain ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> f = open ( settings . ROOT_CA_CERT_CHAIN_PEM_PATH , '<STR_LIT:r>' ) <EOL> contents = f . read ( ) <EOL> except ( AttributeError , IOError ) : <EOL> contents = None <EOL> if contents : <EOL> logging . debug ( '<STR_LIT>' , contents ) <EOL> return contents <EOL> else : <EOL> logging . warning ( '<STR_LIT>' ) <EOL> return '<STR_LIT>' <EOL> def _SudoExec ( self , argv , expect_rc = None ) : <EOL> """<STR_LIT>""" <EOL> if not argv [ <NUM_LIT:0> ] . startswith ( '<STR_LIT:/>' ) : <EOL> raise SudoExecError ( <EOL> '<STR_LIT>' % argv [ <NUM_LIT:0> ] ) <EOL> _argv = [ '<STR_LIT>' ] <EOL> _argv . extend ( argv ) <EOL> logging . info ( '<STR_LIT>' , '<STR_LIT:U+0020>' . join ( _argv ) ) <EOL> p = subprocess . Popen ( <EOL> _argv , shell = False , <EOL> stdout = subprocess . PIPE , stderr = subprocess . PIPE ) <EOL> ( stdout , stderr ) = p . communicate ( ) <EOL> rc = p . wait ( ) <EOL> if expect_rc is not None : <EOL> if rc != expect_rc : <EOL> raise SudoExecError ( <EOL> '<STR_LIT>' % ( _argv , rc , expect_rc ) ) <EOL> return ( stdout , stderr ) <EOL> def _LoadFile ( self , filename , requires_root = False , sudo_ok = False ) : <EOL> """<STR_LIT>""" <EOL> if requires_root and os . getuid ( ) != <NUM_LIT:0> and sudo_ok : <EOL> ( s , unused_stderr ) = self . _SudoExec ( [ '<STR_LIT>' , filename ] , expect_rc = <NUM_LIT:0> ) <EOL> else : <EOL> f = open ( filename , '<STR_LIT:r>' ) <EOL> s = f . read ( ) <EOL> f . close ( ) <EOL> return s <EOL> def _IsFile ( self , filename , requires_root = False , sudo_ok = False ) : <EOL> """<STR_LIT>""" <EOL> if requires_root and os . getuid ( ) != <NUM_LIT:0> and sudo_ok : <EOL> try : <EOL> self . _SudoExec ( <EOL> [ '<STR_LIT>' , '<STR_LIT:-c>' , '<STR_LIT>' % filename ] , <EOL> expect_rc = <NUM_LIT:0> ) <EOL> return True <EOL> except SudoExecError : <EOL> return False <EOL> else : <EOL> return os . path . isfile ( filename ) <EOL> def GetFacter ( self , open_fn = open ) : <EOL> """<STR_LIT>""" <EOL> if self . facter_cache_path is None : <EOL> return { } <EOL> if not os . path . isfile ( self . facter_cache_path ) : <EOL> logging . info ( '<STR_LIT>' ) <EOL> return { } <EOL> facter = { } <EOL> use_facter_cache = False <EOL> try : <EOL> st = os . stat ( self . facter_cache_path ) <EOL> if ( os . geteuid ( ) == <NUM_LIT:0> and st . st_uid != <NUM_LIT:0> ) or ( <EOL> os . geteuid ( ) != <NUM_LIT:0> and st . st_uid != <NUM_LIT:0> and os . geteuid ( ) != st . st_uid ) : <EOL> logging . info ( '<STR_LIT>' ) <EOL> use_facter_cache = False <EOL> else : <EOL> use_facter_cache = True <EOL> cache_mtime = datetime . datetime . fromtimestamp ( st . st_mtime ) <EOL> logging . debug ( '<STR_LIT>' , cache_mtime ) <EOL> except OSError , e : <EOL> logging . info ( '<STR_LIT>' , str ( e ) ) <EOL> use_facter_cache = False <EOL> if use_facter_cache : <EOL> try : <EOL> logging . debug ( '<STR_LIT>' ) <EOL> f = open_fn ( self . facter_cache_path , '<STR_LIT:r>' ) <EOL> facter = { } <EOL> line = f . readline ( ) <EOL> while line : <EOL> try : <EOL> ( key , unused_sep , value ) = line . split ( '<STR_LIT:U+0020>' , <NUM_LIT:2> ) <EOL> value = value . strip ( ) <EOL> facter [ key ] = value <EOL> except ValueError : <EOL> logging . info ( '<STR_LIT>' , line ) <EOL> line = f . readline ( ) <EOL> f . close ( ) <EOL> logging . debug ( '<STR_LIT>' , len ( facter ) ) <EOL> except ( EOFError , IOError ) , e : <EOL> logging . warning ( '<STR_LIT>' , str ( e ) ) <EOL> facter = { } <EOL> return facter <EOL> def _GetPuppetSslDetails ( self , cert_fname = None , interactive_user = False ) : <EOL> """<STR_LIT>""" <EOL> logging . debug ( '<STR_LIT>' , cert_fname ) <EOL> certs_path = os . path . join ( self . CLIENT_SSL_PATH , self . PUPPET_CERTS ) <EOL> best_cert = None <EOL> priv_key = False <EOL> output = { } <EOL> cert_name = None <EOL> if not cert_fname : <EOL> try : <EOL> facts = self . GetFacter ( ) <EOL> except FacterError : <EOL> facts = { } <EOL> cert_name = facts . get ( '<STR_LIT>' , None ) <EOL> if cert_name : <EOL> cert_name = cert_name . strip ( ) <EOL> logging . debug ( '<STR_LIT>' , cert_name ) <EOL> cert_name = cert_name . lower ( ) <EOL> cert_fname = '<STR_LIT>' % cert_name <EOL> else : <EOL> logging . debug ( '<STR_LIT>' ) <EOL> cert_fname = None <EOL> if cert_fname : <EOL> try : <EOL> self . _ValidatePuppetSslCert ( certs_path , cert_fname ) <EOL> best_cert = cert_fname <EOL> except PuppetSslCertError : <EOL> logging . error ( '<STR_LIT>' ) <EOL> if not best_cert : <EOL> best_cert = self . _GetNewestPuppetSslCert ( ) <EOL> if best_cert : <EOL> cn = best_cert . rsplit ( '<STR_LIT:.>' , <NUM_LIT:1> ) [ <NUM_LIT:0> ] <EOL> priv_key = os . path . join ( <EOL> self . CLIENT_SSL_PATH , self . PUPPET_PRIVATE_KEYS , best_cert ) <EOL> logging . debug ( '<STR_LIT>' , priv_key ) <EOL> if self . _IsFile ( priv_key , requires_root = True , sudo_ok = interactive_user ) : <EOL> output [ '<STR_LIT>' ] = cn <EOL> output [ '<STR_LIT>' ] = self . _LoadFile ( os . path . join ( <EOL> self . CLIENT_SSL_PATH , self . PUPPET_CERTS , best_cert ) ) <EOL> output [ '<STR_LIT>' ] = self . _LoadFile ( <EOL> priv_key , requires_root = True , sudo_ok = interactive_user ) <EOL> else : <EOL> logging . debug ( '<STR_LIT>' , priv_key ) <EOL> if '<STR_LIT>' in output : <EOL> logging . info ( '<STR_LIT>' , output [ '<STR_LIT>' ] ) <EOL> return output <EOL> def _ValidatePuppetSslCert ( self , cert_dir_path , cert_fname ) : <EOL> """<STR_LIT>""" <EOL> required_issuer = self . _ca_params . required_issuer <EOL> logging . debug ( <EOL> '<STR_LIT>' , required_issuer ) <EOL> try : <EOL> cert_path = os . path . join ( cert_dir_path , cert_fname ) <EOL> logging . debug ( '<STR_LIT>' , cert_path ) <EOL> f = open ( cert_path , '<STR_LIT:r>' ) <EOL> s = f . read ( ) <EOL> f . close ( ) <EOL> x = x509 . LoadCertificateFromPEM ( s ) <EOL> issuer = x . GetIssuer ( ) <EOL> logging . debug ( '<STR_LIT>' , issuer ) <EOL> if issuer != required_issuer : <EOL> msg = '<STR_LIT>' % cert_fname <EOL> logging . warning ( msg ) <EOL> logging . warning ( <EOL> '<STR_LIT>' , required_issuer , issuer ) <EOL> raise PuppetSslCertError ( msg ) <EOL> except IOError , e : <EOL> logging . debug ( '<STR_LIT>' , cert_fname , str ( e ) ) <EOL> raise PuppetSslCertError ( str ( e ) ) <EOL> except OSError , e : <EOL> logging . debug ( '<STR_LIT>' , cert_fname , str ( e ) ) <EOL> raise PuppetSslCertError ( str ( e ) ) <EOL> except x509 . Error , e : <EOL> logging . debug ( '<STR_LIT>' , cert_fname , str ( e ) ) <EOL> raise PuppetSslCertError ( str ( e ) ) <EOL> return True <EOL> def _GetNewestPuppetSslCert ( self ) : <EOL> """<STR_LIT>""" <EOL> newest_cert = None <EOL> newest_cert_timestamp = None <EOL> certs_path = os . path . join ( self . CLIENT_SSL_PATH , self . PUPPET_CERTS ) <EOL> certs = os . listdir ( certs_path ) <EOL> logging . debug ( <EOL> '<STR_LIT>' , '<STR_LIT:U+0020>' . join ( certs ) ) <EOL> for cert_fname in certs : <EOL> if cert_fname != self . PUPPET_CA_CERT and cert_fname . endswith ( '<STR_LIT>' ) : <EOL> try : <EOL> self . _ValidatePuppetSslCert ( certs_path , cert_fname ) <EOL> except PuppetSslCertError : <EOL> continue <EOL> cert_timestamp = os . path . getmtime ( os . path . join ( certs_path , cert_fname ) ) <EOL> if not newest_cert_timestamp or cert_timestamp > newest_cert_timestamp : <EOL> logging . debug ( <EOL> '<STR_LIT>' , <EOL> cert_fname , cert_timestamp ) <EOL> newest_cert_timestamp = cert_timestamp <EOL> newest_cert = cert_fname <EOL> else : <EOL> logging . debug ( <EOL> '<STR_LIT>' , <EOL> cert_fname , cert_timestamp ) <EOL> return newest_cert <EOL> def _InitializeAuthClass ( self , interactive_user = False , puppet_ssl = True ) : <EOL> """<STR_LIT>""" <EOL> if self . _auth1 is not None : <EOL> return <EOL> auth1 = auth_client . AuthSimianClient ( ) <EOL> if puppet_ssl : <EOL> o = self . _GetPuppetSslDetails ( interactive_user = interactive_user ) <EOL> if not o : <EOL> raise SimianClientError ( '<STR_LIT>' ) <EOL> auth1 . LoadCaParameters ( settings ) <EOL> auth1 . LoadSelfKey ( o [ '<STR_LIT>' ] ) <EOL> auth1 . LoadSelfCert ( o [ '<STR_LIT>' ] ) <EOL> else : <EOL> auth1 . LoadCaParameters ( settings ) <EOL> self . _auth1 = auth1 <EOL> def DoSimianAuth ( self , interactive_user = None ) : <EOL> """<STR_LIT>""" <EOL> if interactive_user is None : <EOL> interactive_user = os . isatty ( sys . stdin . fileno ( ) ) <EOL> self . _InitializeAuthClass ( interactive_user ) <EOL> self . _auth1 . Input ( ) <EOL> cn = self . _auth1 . Output ( ) <EOL> auth_url = '<STR_LIT>' <EOL> if self . _ca_params . ca_id : <EOL> auth_url = '<STR_LIT>' % ( auth_url , self . _ca_params . ca_id ) <EOL> response = self . Do ( '<STR_LIT:POST>' , auth_url , { '<STR_LIT:n>' : cn } ) <EOL> if response . status != <NUM_LIT:200> : <EOL> raise SimianServerError ( <EOL> '<STR_LIT>' % ( response . status , response . body ) ) <EOL> self . _auth1 . Input ( m = response . body ) <EOL> o = self . _auth1 . Output ( ) <EOL> if not o : <EOL> raise SimianClientError ( '<STR_LIT>' % ( <EOL> '<STR_LIT:U+0020>' . join ( self . _auth1 . ErrorOutput ( ) ) ) ) <EOL> response = self . Do ( '<STR_LIT:POST>' , auth_url , { '<STR_LIT:s>' : o [ '<STR_LIT:s>' ] , '<STR_LIT:m>' : o [ '<STR_LIT:m>' ] } ) <EOL> if response . status != <NUM_LIT:200> : <EOL> raise SimianServerError ( '<STR_LIT>' ) <EOL> self . _auth1 . Input ( t = response . body ) <EOL> if not self . _auth1 . AuthStateOK ( ) : <EOL> raise SimianClientError ( '<STR_LIT>' % ( <EOL> '<STR_LIT:U+0020>' . join ( self . _auth1 . ErrorOutput ( ) ) ) ) <EOL> sanitized_headers = response . headers . copy ( ) <EOL> del sanitized_headers [ '<STR_LIT>' ] <EOL> logging . info ( '<STR_LIT>' , sanitized_headers ) <EOL> tokens = response . headers . get ( '<STR_LIT>' , None ) <EOL> if tokens is None : <EOL> raise SimianClientError ( '<STR_LIT>' ) <EOL> tokens = tokens . split ( '<STR_LIT:U+002C>' ) <EOL> for token in tokens : <EOL> if token . startswith ( auth . AUTH_TOKEN_COOKIE ) : <EOL> self . _cookie_token = token <EOL> logging . debug ( '<STR_LIT>' ) <EOL> break <EOL> if self . _cookie_token is None : <EOL> raise SimianClientError ( '<STR_LIT>' ) <EOL> class SimianClient ( HttpsAuthClient ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , hostname = None , port = None , root_ok = False ) : <EOL> if hostname is None : <EOL> hostname = SERVER_HOSTNAME <EOL> self . _default_hostname = True <EOL> else : <EOL> self . _default_hostname = False <EOL> if port is None : <EOL> port = SERVER_PORT <EOL> logging . debug ( <EOL> '<STR_LIT>' , <EOL> hostname , self . _default_hostname , port , root_ok ) <EOL> self . _user = self . _GetLoggedOnUser ( ) <EOL> if self . _user == '<STR_LIT:root>' and not root_ok : <EOL> raise SimianClientError ( '<STR_LIT>' ) <EOL> super ( SimianClient , self ) . __init__ ( hostname , port ) <EOL> def IsDefaultHostClient ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . _default_hostname <EOL> def _SimianRequest ( <EOL> self , method , url , body = None , headers = None , output_filename = None , <EOL> full_response = False ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> response = self . Do ( <EOL> method , url , body = body , headers = headers , <EOL> output_filename = output_filename ) <EOL> except HTTPError , e : <EOL> raise SimianServerError ( str ( e ) ) <EOL> if response . IsSuccess ( ) : <EOL> if not full_response : <EOL> return response . body <EOL> else : <EOL> return response <EOL> else : <EOL> raise SimianServerError ( response . status , response . reason , response . body ) <EOL> def _GetLoggedOnUser ( self ) : <EOL> """<STR_LIT>""" <EOL> if sys . platform == '<STR_LIT:win32>' : <EOL> return os . getenv ( '<STR_LIT>' ) <EOL> else : <EOL> return os . getenv ( '<STR_LIT>' ) <EOL> def _SimianFormUpload ( self , url , name , params , input_filename , input_file ) : <EOL> """<STR_LIT>""" <EOL> name = str ( name . encode ( '<STR_LIT:utf-8>' ) ) <EOL> new_params = params . copy ( ) <EOL> new_params [ '<STR_LIT:name>' ] = name <EOL> new_params [ '<STR_LIT:user>' ] = '<STR_LIT>' % ( self . _user , AUTH_DOMAIN ) <EOL> for k , v in new_params . iteritems ( ) : <EOL> if type ( v ) is unicode : <EOL> new_params [ k ] = str ( v . encode ( '<STR_LIT:utf-8>' ) ) <EOL> response = self . DoMultipart ( <EOL> url , new_params , <EOL> name , <EOL> input_filename = input_filename , <EOL> input_file = input_file ) <EOL> if not response . IsError ( ) : <EOL> return response <EOL> else : <EOL> raise SimianServerError ( response . status , response . body ) <EOL> def GetCatalog ( self , name ) : <EOL> """<STR_LIT>""" <EOL> return self . _SimianRequest ( '<STR_LIT:GET>' , '<STR_LIT>' % name ) <EOL> def GetManifest ( self , name ) : <EOL> """<STR_LIT>""" <EOL> return self . _SimianRequest ( '<STR_LIT:GET>' , '<STR_LIT>' % name ) <EOL> def GetPackage ( self , name , output_filename = None ) : <EOL> """<STR_LIT>""" <EOL> return self . _SimianRequest ( <EOL> '<STR_LIT:GET>' , '<STR_LIT>' % urllib . quote ( name ) , <EOL> output_filename = output_filename ) <EOL> def PutPackage ( self , filename , params , input_filename = None , input_file = None ) : <EOL> """<STR_LIT>""" <EOL> if not input_file and not input_filename : <EOL> raise Error ( '<STR_LIT>' ) <EOL> logging . debug ( '<STR_LIT>' ) <EOL> post_url = self . _SimianRequest ( '<STR_LIT:GET>' , URL_UPLOADPKG ) <EOL> logging . debug ( '<STR_LIT>' , post_url ) <EOL> ( unused_scheme , netloc , path , unused_query , unused_fragment <EOL> ) = urlparse . urlsplit ( post_url ) <EOL> if netloc != self . netloc : <EOL> raise SimianClientError ( <EOL> '<STR_LIT>' % ( <EOL> netloc , self . netloc ) ) <EOL> logging . debug ( '<STR_LIT>' ) <EOL> post_url = path <EOL> response = self . _SimianFormUpload ( <EOL> post_url , filename , params , <EOL> input_file = input_file , input_filename = input_filename ) <EOL> redirect_url = response . headers . get ( '<STR_LIT:location>' , None ) <EOL> ( unused_scheme , unused_netloc , path , query , unused_fragment <EOL> ) = urlparse . urlsplit ( redirect_url ) <EOL> redirect_url = '<STR_LIT>' % ( path , query ) <EOL> if not response . IsRedirect ( ) or not redirect_url : <EOL> raise SimianClientError ( <EOL> ( '<STR_LIT>' % str ( response ) ) ) <EOL> result = self . _SimianRequest ( '<STR_LIT:GET>' , redirect_url ) <EOL> return result <EOL> def GetPackageInfo ( self , filename , get_hash = False ) : <EOL> """<STR_LIT>""" <EOL> url = '<STR_LIT>' % urllib . quote ( filename ) <EOL> if get_hash : <EOL> url = '<STR_LIT>' % url <EOL> response = self . _SimianRequest ( '<STR_LIT:GET>' , url , full_response = True ) <EOL> if get_hash : <EOL> if '<STR_LIT>' not in response . headers : <EOL> logging . debug ( <EOL> '<STR_LIT>' , url , str ( response . headers ) ) <EOL> raise SimianServerError ( '<STR_LIT>' ) <EOL> return response . headers [ '<STR_LIT>' ] , response . body <EOL> else : <EOL> return response . body <EOL> def PutPackageInfo ( <EOL> self , filename , pkginfo , catalogs = None , manifests = None , <EOL> install_types = None , got_hash = None ) : <EOL> """<STR_LIT>""" <EOL> filename = urllib . quote ( filename ) <EOL> pkginfo = pkginfo . encode ( '<STR_LIT:utf-8>' ) <EOL> opts = [ ] <EOL> if catalogs is not None : <EOL> opts . append ( '<STR_LIT>' % '<STR_LIT:U+002C>' . join ( catalogs ) ) <EOL> if manifests is not None : <EOL> opts . append ( '<STR_LIT>' % '<STR_LIT:U+002C>' . join ( manifests ) ) <EOL> if install_types is not None : <EOL> opts . append ( '<STR_LIT>' % '<STR_LIT:U+002C>' . join ( install_types ) ) <EOL> if got_hash is not None : <EOL> opts . append ( '<STR_LIT>' % got_hash ) <EOL> url = '<STR_LIT>' % ( <EOL> filename , '<STR_LIT:&>' . join ( opts ) ) <EOL> return self . _SimianRequest ( '<STR_LIT>' , url , pkginfo ) <EOL> def DeletePackage ( self , filename ) : <EOL> """<STR_LIT>""" <EOL> return self . _SimianRequest ( '<STR_LIT:POST>' , '<STR_LIT>' , { '<STR_LIT:filename>' : filename } ) <EOL> def DownloadPackage ( self , filename ) : <EOL> """<STR_LIT>""" <EOL> return self . _SimianRequest ( <EOL> '<STR_LIT:GET>' , '<STR_LIT>' % urllib . quote ( filename ) , <EOL> output_filename = filename ) <EOL> def _IsPackageUploadNecessary ( self , filename , upload_pkginfo ) : <EOL> """<STR_LIT>""" <EOL> return True <EOL> def UploadPackage ( <EOL> self , filename , description , display_name , catalogs , manifests , <EOL> install_types , pkginfo ) : <EOL> """<STR_LIT>""" <EOL> file_path = filename <EOL> filename = os . path . basename ( filename ) <EOL> if not manifests : <EOL> manifests = [ ] <EOL> if self . _IsPackageUploadNecessary ( file_path , pkginfo ) : <EOL> params = { <EOL> '<STR_LIT>' : pkginfo , <EOL> '<STR_LIT>' : '<STR_LIT:U+002C>' . join ( catalogs ) , <EOL> '<STR_LIT>' : '<STR_LIT:U+002C>' . join ( manifests ) , <EOL> '<STR_LIT>' : '<STR_LIT:U+002C>' . join ( install_types ) , <EOL> } <EOL> response = self . PutPackage ( filename , params , input_filename = file_path ) <EOL> else : <EOL> response = self . PutPackageInfo ( <EOL> filename , pkginfo , catalogs , manifests , install_types ) <EOL> return response , filename , catalogs , manifests <EOL> def GetPackageMetadata ( <EOL> self , install_types = None , catalogs = None , filename = None ) : <EOL> """<STR_LIT>""" <EOL> query = [ ] <EOL> if install_types : <EOL> query . append ( '<STR_LIT>' % install_types ) <EOL> if catalogs : <EOL> query . append ( '<STR_LIT>' % catalogs ) <EOL> if filename : <EOL> query . append ( '<STR_LIT>' % filename ) <EOL> query = '<STR_LIT:&>' . join ( query ) <EOL> return self . _SimianRequest ( '<STR_LIT:GET>' , '<STR_LIT>' % query ) <EOL> def PostReport ( self , report_type , params , feedback = False ) : <EOL> """<STR_LIT>""" <EOL> body = urllib . urlencode ( params , doseq = True ) <EOL> body = '<STR_LIT>' % ( report_type , body ) <EOL> if feedback : <EOL> body = '<STR_LIT>' % ( body ) <EOL> return self . _SimianRequest ( '<STR_LIT:POST>' , '<STR_LIT>' , str ( body ) ) <EOL> def PostReportBody ( self , body , feedback = False ) : <EOL> """<STR_LIT>""" <EOL> url = '<STR_LIT>' <EOL> if feedback : <EOL> body = '<STR_LIT>' % str ( body ) <EOL> else : <EOL> body = str ( body ) <EOL> return self . _SimianRequest ( '<STR_LIT:POST>' , url , body ) <EOL> def UploadFile ( self , file_path , file_type , _open = open ) : <EOL> """<STR_LIT>""" <EOL> if os . path . isfile ( file_path ) : <EOL> logging . debug ( '<STR_LIT>' , file_path ) <EOL> file_handle = _open ( file_path , '<STR_LIT:r>' ) <EOL> file_name = os . path . basename ( file_path ) <EOL> url = '<STR_LIT>' % ( file_type , file_name ) <EOL> try : <EOL> self . Do ( '<STR_LIT>' , url , file_handle ) <EOL> finally : <EOL> file_handle . close ( ) <EOL> else : <EOL> logging . error ( '<STR_LIT>' , file_path ) <EOL> class SimianAuthClient ( SimianClient ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , hostname = None , port = None , root_ok = None ) : <EOL> super ( SimianAuthClient , self ) . __init__ ( hostname , port , root_ok = True ) <EOL> def GetAuthToken ( self ) : <EOL> """<STR_LIT>""" <EOL> self . DoSimianAuth ( ) <EOL> return self . _cookie_token <EOL> def SetAuthToken ( self , token ) : <EOL> """<STR_LIT>""" <EOL> self . _cookie_token = str ( '<STR_LIT>' % ( auth . AUTH_TOKEN_COOKIE , token ) ) <EOL> def LogoutAuthToken ( self ) : <EOL> """<STR_LIT>""" <EOL> url = '<STR_LIT>' <EOL> try : <EOL> self . _SimianRequest ( '<STR_LIT:GET>' , url ) <EOL> return True <EOL> except SimianServerError : <EOL> return False </s>
