def logon(self, username, password, server_url, proxies=None, no_proxy=None, cert_life_time=86400, ssl_ctx=None): """Obtain a new certificate""" if ssl_ctx is None: ssl_ctx = make_ssl_context(ca_dir=self.ca_cert_dir, verify_peer=True, url=server_url, method=SSL.SSLv3_METHOD) # Create a password manager password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() # Get base URL for setting basic auth scope parsed_url = urlparse(server_url) base_url = urlunparse(parsed_url[0:2] + ('/', '', '', '')) # Add the username and password. # If we knew the realm, we could use it instead of ``None``. password_mgr.add_password(None, base_url, username, password) handlers = [urllib2.HTTPBasicAuthHandler(password_mgr)] key_pair = self.__class__.create_key_pair() cert_req = self.__class__.create_cert_req(key_pair) # Convert plus chars to make it safe for HTTP POST encoded_cert_req = cert_req.replace('+', '%2B') req = "%s=%s\n" % (self.__class__.CERT_REQ_POST_PARAM_KEYNAME, encoded_cert_req) config = Configuration(ssl_ctx, True) res = fetch_stream_from_url(server_url, config, data=req, handlers=handlers) return res
def test02_logon_with_ssl_client_authn(self): # Some cases may require client to pass cert in SSL handshake opt_name = 'WSClientTestCase.test02_logon_with_ssl_client_authn' username = self.cfg.get(opt_name, 'username') try: password = self.cfg.get(opt_name, 'password') except NoOptionError: password = '' server_url = self.cfg.get(opt_name, 'uri') client_cert_filepath = self.cfg.get(opt_name, 'client_cert_filepath') client_key_filepath = self.cfg.get(opt_name, 'client_key_filepath') myproxy_client = MyProxyWSClient() ssl_ctx = make_ssl_context(cert_file=client_cert_filepath, key_file=client_key_filepath, ca_dir=test_ca_dir, verify_peer=True, url=server_url, method=SSL.SSLv3_METHOD) res = myproxy_client.logon(username, password, server_url, ssl_ctx=ssl_ctx) self.assert_(res) pem_out = res.read() cert = crypto.load_certificate(crypto.FILETYPE_PEM, pem_out) subj = cert.get_subject() self.assert_(subj) self.assert_(subj.CN) print("Returned certificate subject CN=%r" % subj)
def _obtain_cert(request): """ Calls to online CA and stores user certificate and key in the session. TOOD: configure client crt and key, CA certs: one-test-ssl-chain.pem put in configuration. """ if 'certificate' in request.session: logger.debug("User has delegated certificate set already."); return HttpResponseRedirect(profile_url(request.user)) if (not settings.ONLINE_CA_USE) and (not settings.ONLINE_OAUTH2_CA_USE): return HttpResponseRedirect(profile_url(request.user)) if settings.ONLINE_OAUTH2_CA_USE: return _get_cert_oauth2(request) ssl_ctx = make_ssl_context(cert_file=settings.FEDERATION_WEB_CERT, key_file=settings.FEDERATION_WEB_KEY, ca_dir=settings.TRUSTSTORE_DIR, verify_peer=True, url=settings.ONLINE_CA_URI, method=SSL.SSLv3_METHOD) myproxy_client = MyProxyWSClient() res = myproxy_client.logon(request.user.id, "nopassword", settings.ONLINE_CA_URI,ssl_ctx=ssl_ctx) pem_out = res.read() cert = crypto.load_certificate(crypto.FILETYPE_PEM, pem_out) cert = DelegatedCertificate(cert,pem_out) cert.write_key_to_file() request.session['certificate']=cert request.session['pkey_file_path']=cert.pkey_file_path logger.debug("Key path: %s " % request.session['pkey_file_path'] ) logger.debug("User has cert %s " % request.user.certificate )
def get(self, environ, url): """Makes a HTTP request to the specified URL using the certificate obtained from the WSGI environ. @type environ: dict @param environ: WSGI environ @type url: basestring @param url: URL of resource to request @rtype: basestring @return: response from HTTP request """ current_token = environ.get(self.token_env_key) if current_token: log.debug("Token ID: %s", current_token) else: log.debug("No token found with environ key: %s", self.token_env_key) if self.token != current_token or not self.user_ssl_context: log.debug("Certificate request needed") if current_token: self.token = current_token # Get credential. log.debug("Making certificate request") (private_key, certificate) = certificate_request.request_certificate( self.token, self.resource_server_url, self.client_ssl_config, self.certificate_request_parameter) # Create SSL context using the resource owner's delegated # credential. self.user_ssl_context = ssl_context_util.make_ssl_context( None, None, self.ca_cert_file, self.ca_dir, True) clientKey = crypto.load_privatekey(crypto.FILETYPE_PEM, private_key) clientCert = crypto.load_certificate(crypto.FILETYPE_PEM, certificate) self.user_ssl_context.use_privatekey(clientKey) self.user_ssl_context.use_certificate(clientCert) log.debug("Created new SSL context") else: log.warn("Certificate needed but no token available") config = httpsclientutils.Configuration(self.user_ssl_context, True) log.debug("Making request to URL: %s", url) response = httpsclientutils.fetch_from_url(url, config) return response
def get(self, environ, url): """Makes a HTTP request to the specified URL using the certificate obtained from the WSGI environ. @type environ: dict @param environ: WSGI environ @type url: basestring @param url: URL of resource to request @rtype: basestring @return: response from HTTP request """ current_token = environ.get(self.token_env_key) if current_token: log.debug("Token ID: %s", current_token) else: log.debug("No token found with environ key: %s", self.token_env_key) if self.token != current_token or not self.user_ssl_context: log.debug("Certificate request needed") if current_token: self.token = current_token # Get credential. log.debug("Making certificate request") (private_key, certificate) = certificate_request.request_certificate( self.token, self.resource_server_url, self.client_ssl_config, self.certificate_request_parameter ) # Create SSL context using the resource owner's delegated # credential. self.user_ssl_context = ssl_context_util.make_ssl_context( None, None, self.ca_cert_file, self.ca_dir, True ) clientKey = crypto.load_privatekey(crypto.FILETYPE_PEM, private_key) clientCert = crypto.load_certificate(crypto.FILETYPE_PEM, certificate) self.user_ssl_context.use_privatekey(clientKey) self.user_ssl_context.use_certificate(clientCert) log.debug("Created new SSL context") else: log.warn("Certificate needed but no token available") config = httpsclientutils.Configuration(self.user_ssl_context, True) log.debug("Making request to URL: %s", url) response = httpsclientutils.fetch_from_url(url, config) return response
def initialise(self, app_conf, prefix=DEFAULT_PARAM_PREFIX, **local_conf): """Initialise attributes from the given local configuration settings @param app_conf: application configuration settings - ignored - this method includes this arg to fit Paste middleware / app function signature @type app_conf: dict @param prefix: optional prefix for parameter names included in the local_conf dict - enables these parameters to be filtered from others which don't apply to this middleware @param local_conf: attribute settings to apply @type local_conf: dict """ if prefix is None: prefix = '' prefixLength = len(prefix) queryPrefix = prefix + self.__class__.ATTRIBUTE_QUERY_PARAMS_PREFIX queryPrefixLength = len(queryPrefix) for k in local_conf: # SSL parameters apply to this class and to the attribute query # client. if k.startswith(queryPrefix): paramName = k[queryPrefixLength:] elif k.startswith(prefix): paramName = k[prefixLength:] if paramName in AttributeRequestMiddleware.PARAM_NAMES: setattr(self, paramName, local_conf[k]) self._attributeQueryClient = AttributeQuerySslSOAPBinding() # Parse authorisation decision query options self._attributeQueryClient.parseKeywords(prefix=queryPrefix, **local_conf) sslContext = ssl_context_util.make_ssl_context(self.sslPriKeyFilePath, self.sslCertFilePath, None, self.sslCACertDir, verify_peer=True) self._httpsClientConfig = httpsclient_utils.Configuration( sslContext, False)
def main(): '''Utility to fetch data using HTTP or HTTPS GET from a specified URL. ''' parser = OptionParser(usage="%prog [options] url") parser.add_option("-c", "--certificate", dest="cert_file", metavar="FILE", default=os.path.expanduser("~/credentials.pem"), help="Certificate file - defaults to $HOME/credentials.pem") parser.add_option("-k", "--private-key", dest="key_file", metavar="FILE", default=None, help="Private key file - defaults to the certificate file") parser.add_option("-t", "--ca-certificate-dir", dest="ca_dir", metavar="PATH", default=None, help="Trusted CA certificate file directory") parser.add_option("-d", "--debug", action="store_true", dest="debug", default=False, help="Print debug information.") parser.add_option("-p", "--post-data-file", dest="data_file", metavar="FILE", default=None, help="POST data file") parser.add_option("-f", "--fetch", dest="output_file", metavar="FILE", default=None, help="Output file") parser.add_option("-n", "--no-verify-peer", action="store_true", dest="no_verify_peer", default=False, help="Skip verification of peer certificate.") parser.add_option("-a", "--basicauth", dest="basicauth", metavar="USER:PASSWD", default=None, help="HTTP authentication credentials") parser.add_option("--header", action="append", dest="headers", metavar="HEADER: VALUE", help="Add HTTP header to request") (options, args) = parser.parse_args() if len(args) != 1: parser.error("Incorrect number of arguments") url = args[0] if options.debug: logging.getLogger().setLevel(logging.DEBUG) if options.key_file and os.path.exists(options.key_file): key_file = options.key_file else: key_file = None if options.cert_file and os.path.exists(options.cert_file): cert_file = options.cert_file else: cert_file = None if options.ca_dir and os.path.exists(options.ca_dir): ca_dir = options.ca_dir else: ca_dir = None verify_peer = not options.no_verify_peer if options.data_file and os.path.exists(options.data_file): data_file = open(options.data_file) data = data_file.read() data_file.close() else: data = None if options.basicauth: http_basicauth = options.basicauth.split(':', 1) else: http_basicauth = None headers = {} if options.headers: for h in options.headers: key, val = h.split(':', 1) headers[key.strip()] = val.lstrip() # If a private key file is not specified, the key is assumed to be stored in # the certificate file. ssl_context = ssl_context_util.make_ssl_context(key_file, cert_file, None, ca_dir, verify_peer, url) config = Configuration(ssl_context, options.debug, http_basicauth=http_basicauth, headers=headers) if options.output_file: return_code, return_message = fetch_from_url_to_file( url, config, options.output_file, data)[:2] raise SystemExit(return_code, return_message) else: data = fetch_from_url(url, config) print(data)