Commit a6be7424 authored by Lucas Carvalho's avatar Lucas Carvalho

Created a new library libconnection.

This library aims to handle all the possibles way to do a GET to an http
server.

So, it must contains all the code related to HTTP calls to avoid to
polute the NetworkcacheClient class with this kind of code.

The NetworkcacheClient should use this library to download any kind of
file which is necessary.

Using this library NetworkcacheClient must be able to:
 - download a file under HTTP without authentication
 - download a file under HTTP with basic authentication
 - download a file under HTTPS CA (Certificate Authority)
 - download a file under HTTPS CA with basic authentication
 - download a file under HTTPS with Certification Authentication

So currently, this library only provides a way to:
  - download a file under HTTPS CA (Certificate Authority)
  - download a file under HTTPS CA with basic authentication

(work in progress)
parent 22f48343
##############################################################################
#
# Copyright (c) 2010 ViFiB SARL and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
import httplib
import socket
import ssl
import urllib2
import os
import tempfile
from slapos.libnetworkcacheutils import parseUrl
CERTIFICATE_FILE_LOCATION_LIST = [
'/etc/ssl/certs/ca-certificates.crt', # Debian
'/etc/pki/tls/certs/ca-bundle.crt', # Redhat
'/usr/share/ssl/certs/ca-bundle.crt', # Redhat
'/etc/ssl/cert.pem', # FreeBSD
# Other paths...
'/etc/certs/ca-bundle.crt',
'/usr/local/ssl/certs/ca-bundle.crt',
'/etc/apache/ssl.crt/ca-bundle.crt',
'/usr/share/curl/curl-ca-bundle.crt',
'/usr/lib/ssl/cert.pem',
]
class HTTPSConnectionCertificateVerification(httplib.HTTPSConnection):
""" HTTPSConnection wrapper to check who we are talking to... """
def __init__(self, *args, **kwargs):
"""
Find the certificate file location before calling the init method
from the super class.
"""
self.ssl_cert_path = None
for p in CERTIFICATE_FILE_LOCATION_LIST:
if os.path.exists(p):
self.ssl_cert_path = p
break
if self.ssl_cert_path is None:
raise IOError("CA file not found. "\
"Download it from here: http://curl.haxx.se/ca/cacert.pem")
super(HTTPSConnectionCertificateVerification, self).__init__(*args, **kwargs)
def connect(self):
""" Connect to a host on a given (SSL) port and verify its certificate. """
sock = socket.create_connection((self.host, self.port))
if self._tunnel_host:
self.sock = sock
self._tunnel()
self.sock = ssl.wrap_socket(sock,
ca_certs=self.ssl_cert_path,
cert_reqs=ssl.CERT_REQUIRED)
cert = self.sock.getpeercert()
for field in cert['subject']:
if field[0][0] == 'commonName':
certhost = field[0][1]
if certhost != self.host:
raise ssl.SSLError(\
"Host name '%s' doesn't match with the certificate host '%s'"
% (self.host, certhost))
# XXX(lucas): we should also check the notBefore and notAfter.
# FYI, some hosts does not provides notBefore.
# Then in this only notAfter matters.
class VerifiedHTTPSHandler(urllib2.HTTPSHandler):
def __init__(self, connection_class=HTTPSConnectionCertificateVerification):
self.specialized_conn_class = connection_class
urllib2.HTTPSHandler.__init__(self)
def https_open(self, req):
return self.do_open(self.specialized_conn_class, req)
def install_opener_director(info_dict):
if info_dict.get('schema') in ('https',):
https_handler = VerifiedHTTPSHandler()
url_opener = urllib2.build_opener(https_handler)
urllib2.install_opener(url_opener)
return
def download(url):
info_dict = parseUrl(url)
install_opener_director(info_dict)
request = urllib2.Request(url=info_dict.get('simple_url'), data=None, headers=info_dict.get('header_dict'))
response = urllib2.urlopen(request)
file_descriptor = tempfile.NamedTemporaryFile()
while True:
data = response.read(1<<13)
file_descriptor.write(data)
if not data:
break
file_descriptor.seek(0)
return file_descriptor
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment