diff --git a/master/portbuild/client.py b/master/portbuild/client.py index 8faa7c5..b67574e 100644 --- a/master/portbuild/client.py +++ b/master/portbuild/client.py @@ -36,6 +36,10 @@ class Client: server = 127.0.0.1 port = 8080 user = bapt +usessl = false +[ssl] +certificate_file = /usr/local/portbuild/certificate_file +key_file = /usr/local/portbuild/key_file """) self.config = ConfigParser.ConfigParser() self.config.readfp(default_cfg) @@ -60,7 +64,14 @@ user = bapt auth = base64.encodestring("%s:%s" % (u, p)) headers = {"Authorization" : "Basic %s" % auth} - h = httplib.HTTPConnection(self.config.get("portbuild", "server"), + use_ssl = self.config.get("portbuild", "usessl") + if use_ssl: + cert_file =self.config.get("ssl", "certifcate_file") + key_file = self.config.get("ssl", "key_file") + h = httplib.HTTPSConnection(self.config.get("portbuild", "server"), + key_file=key_file, cert_file=cert_file) + else: + h = httplib.HTTPConnection(self.config.get("portbuild", "server"), self.config.getint("portbuild", "port")) extra = "" if args._get_kwargs(): diff --git a/master/portbuild/master.py b/master/portbuild/master.py index c280e32..0e89ce2 100644 --- a/master/portbuild/master.py +++ b/master/portbuild/master.py @@ -29,6 +29,8 @@ from portbuild import HTTPAuth, ports, jails import ConfigParser import StringIO import httplib +import socket +import ssl import os import cgi @@ -186,6 +188,43 @@ class MasterHttpRequestHandler(BaseHTTPRequestHandler): path = p[0][1:].split("/") getattr(self, "del_"+path[0], self.send_403)() +class MasterHTTPSecureRequestHandler(MasterHttpRequestHandler): + def setup(self): + self.cnx = self.request + self.rfile = socket._fileobject(self.cnx, 'rb', self.rbufsize) + self.wfile = socket._fileobject(self.cnx, 'wb', self.wbufsize) + +class HTTPSecureServer(HTTPServer): + def __init__(self, server_address, config): + HTTPServer.__init__(self, server_address, + MasterHTTPSecureRequestHandler) + cert_file = config.get('ssl', 'certificate_file') + key_file = config.get('ssl', 'key_file') + version = config.get('ssl', 'ssl_version') + ssl_version = getattr(ssl, version) if version is not None else PROTOCOL_TLSv1 + self.ssl_socket = ssl.wrap_socket(socket.socket(self.address_family, + self.socket_type), server_side=True, certfile=cert_file, + keyfile=key_file, ssl_version=ssl_version) + self.socket = self.ssl_socket + self.server_bind() + self.server_activate() + +class MasterHTTPSecureServer(ThreadingMixIn, HTTPSecureServer): + auth = None + config = None + + def __init_(self, server_address, config): + HTTPSecureServer.__init__(self, server_address, MasterHTTPSecureRequestHandler) + self.config = config + self.auth = None + + def get_auth(self): + if self.auth is None: + self.auth = HTTPAuth.BasicAuth(self.config.get("paths", "passwd"), + "portbuild") + + return self.auth + class MasterHTTPServer(ThreadingMixIn, HTTPServer): auth = None config = None @@ -210,6 +249,7 @@ ip = 127.0.0.1 port = 8080 [master] usetmpfs = true +usessl = true [paths] passwd = /usr/local/etc/portmgr.passwd @@ -221,7 +261,11 @@ jailssvn = /usr/local/portsbuilds/jails/svn jailstemp = /usr/local/portbuild/jails/temp jailsstore = /usr/local/portbuild/jails/store svn = /usr/local/bin/svn - """) +[ssl] +certificate_file = /usr/local/portbuild/cert_file +key_file = /usr/local/portbuild/key_file +ssl_version = PROTOCOL_TLSv1 +""") self.config = ConfigParser.ConfigParser() self.config.readfp(default_cfg) if conf is not None and os.path.exists(conf): @@ -230,7 +274,11 @@ svn = /usr/local/bin/svn def run(self): http_conf = (self.config.get("network", "ip"), self.config.getint("network", "port")) - httpd = MasterHTTPServer(http_conf, self.config) + ssl_conf = self.config.get("master", "usessl") + if ssl_conf: + httpd = MasterHTTPSecureServer(http_conf, self.config) + else: + httpd = MasterHTTPServer(http_conf, self.config) try: httpd.serve_forever() except KeyboardInterrupt: