diff options
Diffstat (limited to 'libpathod')
-rw-r--r-- | libpathod/pathoc.py | 18 | ||||
-rw-r--r-- | libpathod/pathod.py | 44 |
2 files changed, 47 insertions, 15 deletions
diff --git a/libpathod/pathoc.py b/libpathod/pathoc.py index 4e807002..56708696 100644 --- a/libpathod/pathoc.py +++ b/libpathod/pathoc.py @@ -6,14 +6,21 @@ import language, utils class PathocError(Exception): pass +class SSLInfo: + def __init__(self, certchain): + self.certchain = certchain + + class Response: - def __init__(self, httpversion, status_code, msg, headers, content): + def __init__(self, httpversion, status_code, msg, headers, content, sslinfo): self.httpversion, self.status_code, self.msg = httpversion, status_code, msg self.headers, self.content = headers, content + self.sslinfo = sslinfo def __repr__(self): return "Response(%s - %s)"%(self.status_code, self.msg) + class Pathoc(tcp.TCPClient): def __init__(self, address, ssl=None, sni=None, sslversion=1, clientcert=None, ciphers=None): tcp.TCPClient.__init__(self, address) @@ -48,6 +55,7 @@ class Pathoc(tcp.TCPClient): tcp.TCPClient.connect(self) if connect_to: self.http_connect(connect_to) + self.sslinfo = None if self.ssl: try: self.convert_to_ssl( @@ -58,6 +66,10 @@ class Pathoc(tcp.TCPClient): ) except tcp.NetLibError, v: raise PathocError(str(v)) + self.sslinfo = SSLInfo( + self.connection.get_peer_cert_chain() + ) + def request(self, spec): """ @@ -69,7 +81,9 @@ class Pathoc(tcp.TCPClient): r = language.parse_request(self.settings, spec) language.serve(r, self.wfile, self.settings, self.address.host) self.wfile.flush() - return Response(*http.read_response(self.rfile, r.method, None)) + ret = list(http.read_response(self.rfile, r.method, None)) + ret.append(self.sslinfo) + return Response(*ret) def _show_summary(self, fp, httpversion, code, msg, headers, content): print >> fp, "<< %s %s: %s bytes"%(code, utils.xrepr(msg), len(content)) diff --git a/libpathod/pathod.py b/libpathod/pathod.py index a8c2a29f..c0c89ff1 100644 --- a/libpathod/pathod.py +++ b/libpathod/pathod.py @@ -1,24 +1,37 @@ -import urllib, threading, re, logging +import urllib, threading, re, logging, os from netlib import tcp, http, wsgi, certutils import netlib.utils import version, app, language, utils + +DEFAULT_CERT_DOMAIN = "pathod.net" +CONFDIR = "~/.mitmproxy" +CA_CERT_NAME = "mitmproxy-ca.pem" + logger = logging.getLogger('pathod') class PathodError(Exception): pass class SSLOptions: - def __init__(self, certfile=None, keyfile=None, not_after_connect=None, request_client_cert=False, sslversion=tcp.SSLv23_METHOD, ciphers=None): - self.keyfile = keyfile or utils.data.path("resources/server.key") - self.certfile = certfile or utils.data.path("resources/server.crt") - self.cert = certutils.SSLCert.from_pem(file(self.certfile, "rb").read()) + def __init__(self, confdir=CONFDIR, cn=None, certfile=None, + not_after_connect=None, request_client_cert=False, + sslversion=tcp.SSLv23_METHOD, ciphers=None): + self.confdir = confdir + self.cn = cn + cacert = os.path.join(confdir, CA_CERT_NAME) + self.cacert = os.path.expanduser(cacert) + if not os.path.exists(self.cacert): + certutils.dummy_ca(self.cacert) + self.certstore = certutils.CertStore(self.cacert) + self.certfile = certfile self.not_after_connect = not_after_connect self.request_client_cert = request_client_cert self.ciphers = ciphers self.sslversion = sslversion + class PathodHandler(tcp.BaseHandler): wbufsize = 0 sni = None @@ -78,8 +91,8 @@ class PathodHandler(tcp.BaseHandler): if not self.server.ssloptions.not_after_connect: try: self.convert_to_ssl( - self.server.ssloptions.cert, - self.server.ssloptions.keyfile, + self.server.ssloptions.certstore.get_cert(DEFAULT_CERT_DOMAIN, []), + self.server.ssloptions.cacert, handle_sni = self.handle_sni, request_client_cert = self.server.ssloptions.request_client_cert, cipher_list = self.server.ssloptions.ciphers, @@ -186,8 +199,11 @@ class PathodHandler(tcp.BaseHandler): if self.server.ssl: try: self.convert_to_ssl( - self.server.ssloptions.cert, - self.server.ssloptions.keyfile, + self.server.ssloptions.certstore.get_cert( + self.server.ssloptions.cn or DEFAULT_CERT_DOMAIN, + [] + ), + self.server.ssloptions.cacert, handle_sni = self.handle_sni, request_client_cert = self.server.ssloptions.request_client_cert, cipher_list = self.server.ssloptions.ciphers, @@ -224,10 +240,12 @@ class PathodHandler(tcp.BaseHandler): class Pathod(tcp.TCPServer): LOGBUF = 500 - def __init__( self, - addr, ssl=False, ssloptions=None, craftanchor="/p/", staticdir=None, anchors=None, - sizelimit=None, noweb=False, nocraft=False, noapi=False, nohang=False, - timeout=None, logreq=False, logresp=False, explain=False, hexdump=False + def __init__( + self, addr, confdir=CONFDIR, ssl=False, ssloptions=None, + craftanchor="/p/", staticdir=None, anchors=None, + sizelimit=None, noweb=False, nocraft=False, noapi=False, + nohang=False, timeout=None, logreq=False, logresp=False, + explain=False, hexdump=False ): """ addr: (address, port) tuple. If port is 0, a free port will be |