summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/Options.py6
-rw-r--r--src/lib/Proxy.py27
-rwxr-xr-xsrc/sbin/bcfg25
3 files changed, 31 insertions, 7 deletions
diff --git a/src/lib/Options.py b/src/lib/Options.py
index add106869..a2d9d46ca 100644
--- a/src/lib/Options.py
+++ b/src/lib/Options.py
@@ -217,6 +217,11 @@ CLIENT_CERT = Option('Path to SSL certificate', default=None, cmd="--ssl-cert",
CLIENT_CA = Option('Path to SSL CA Cert', default=None, cmd="--ca-cert",
cf=('communication', 'ca'), odesc='<ca cert>',
long_arg=True)
+CLIENT_SCNS = Option('list of server commonNames', default=None, cmd="--ssl-cns",
+ cf=('communication', 'serverCommonNames'),
+ odesc='<commonName1:commonName2>', cook=list_split,
+ long_arg=True)
+
SERVER_PASSWORD = Option('Communication Password', cmd='-x', odesc='<password>',
cf=('communication', 'password'), default=False)
INSTALL_PREFIX = Option('Installation location', cf=('server', 'prefix'),
@@ -276,6 +281,7 @@ LOGGING_FILE_PATH = Option('Set path of file log', default=None,
CLIENT_SERVICE_MODE = Option('Set client service mode', default='default',
cmd='-s', odesc='<default|disabled|build>')
+
class OptionParser(OptionSet):
'''
OptionParser bootstraps option parsing,
diff --git a/src/lib/Proxy.py b/src/lib/Proxy.py
index 2dd1b0065..3595b1099 100644
--- a/src/lib/Proxy.py
+++ b/src/lib/Proxy.py
@@ -27,6 +27,10 @@ has_py26 = map(int, version) >= [2, 6]
__all__ = ["ComponentProxy", "RetryMethod", "SSLHTTPConnection", "XMLRPCTransport"]
+class CertificateError(Exception):
+ def __init__(self, commonName):
+ self.commonName = commonName
+
class RetryMethod(_Method):
"""Method with error handling and retries built in"""
log = logging.getLogger('xmlrpc')
@@ -45,6 +49,10 @@ class RetryMethod(_Method):
if retry == 3:
self.log.error("Server failure: %s" % err)
raise xmlrpclib.Fault(20, err)
+ except CertificateError, ce:
+ self.log.error("Got unallowed commonName %s from server" \
+ % ce.commonName)
+ break
except:
self.log.error("Unknown failure", exc_info=1)
break
@@ -56,7 +64,7 @@ xmlrpclib._Method = RetryMethod
class SSLHTTPConnection(httplib.HTTPConnection):
def __init__(self, host, port=None, strict=None, timeout=90, key=None,
- cert=None, ca=None):
+ cert=None, ca=None, scns=None):
if not has_py26:
httplib.HTTPConnection.__init__(self, host, port, strict)
else:
@@ -64,6 +72,7 @@ class SSLHTTPConnection(httplib.HTTPConnection):
self.key = key
self.cert = cert
self.ca = ca
+ self.scns = scns
if self.ca:
self.ca_mode = ssl.CERT_REQUIRED
else:
@@ -77,20 +86,27 @@ class SSLHTTPConnection(httplib.HTTPConnection):
ca_certs=self.ca, suppress_ragged_eofs=True,
keyfile=self.key, certfile=self.cert)
self.sock.connect((self.host, self.port))
+ pc = self.sock.getpeercert()
+ if pc and self.scns:
+ scn = [x[0][1] for x in pc['subject'] if x[0][0] == 'commonName'][0]
+ if scn not in self.scns:
+ raise CertificateError, scn
self.sock.closeSocket = True
class XMLRPCTransport(xmlrpclib.Transport):
- def __init__(self, key=None, cert=None, ca=None, use_datetime=0):
+ def __init__(self, key=None, cert=None, ca=None, scns=None, use_datetime=0):
if hasattr(xmlrpclib.Transport, '__init__'):
xmlrpclib.Transport.__init__(self, use_datetime)
self.key = key
self.cert = cert
self.ca = ca
+ self.scns = scns
def make_connection(self, host):
host = self.get_host_info(host)[0]
- http = SSLHTTPConnection(host, key=self.key, cert=self.cert, ca=self.ca)
+ http = SSLHTTPConnection(host, key=self.key, cert=self.cert, ca=self.ca,
+ scns=self.scns)
https = httplib.HTTP()
https._setup(http)
return https
@@ -134,7 +150,8 @@ class XMLRPCTransport(xmlrpclib.Transport):
return u.close()
-def ComponentProxy (url, user=None, password=None, key=None, cert=None, ca=None):
+def ComponentProxy (url, user=None, password=None, key=None, cert=None, ca=None,
+ allowedServerCNs=None):
"""Constructs proxies to components.
@@ -149,6 +166,6 @@ def ComponentProxy (url, user=None, password=None, key=None, cert=None, ca=None)
newurl = "%s://%s:%s@%s" % (method, user, password, path)
else:
newurl = url
- ssl_trans = XMLRPCTransport(key, cert, ca)
+ ssl_trans = XMLRPCTransport(key, cert, ca, allowedServerCNs)
return xmlrpclib.ServerProxy(newurl, allow_none=True, transport=ssl_trans)
diff --git a/src/sbin/bcfg2 b/src/sbin/bcfg2
index 070561dd9..337bdb888 100755
--- a/src/sbin/bcfg2
+++ b/src/sbin/bcfg2
@@ -46,7 +46,6 @@ class Client:
'quick': Bcfg2.Options.CLIENT_QUICK,
'debug': Bcfg2.Options.DEBUG,
'drivers': Bcfg2.Options.CLIENT_DRIVERS,
- 'fingerprint': Bcfg2.Options.SERVER_FINGERPRINT,
'dryrun': Bcfg2.Options.CLIENT_DRYRUN,
'paranoid': Bcfg2.Options.CLIENT_PARANOID,
'bundle': Bcfg2.Options.CLIENT_BUNDLE,
@@ -72,6 +71,7 @@ class Client:
'key' : Bcfg2.Options.CLIENT_KEY,
'certificate' : Bcfg2.Options.CLIENT_CERT,
'ca' : Bcfg2.Options.CLIENT_CA,
+ 'serverCN' : Bcfg2.Options.CLIENT_SCNS,
}
self.setup = Bcfg2.Options.OptionParser(optinfo)
@@ -161,7 +161,8 @@ class Client:
self.setup['password'],
key = self.setup['key'],
cert = self.setup['certificate'],
- ca = self.setup['ca'])
+ ca = self.setup['ca'],
+ allowedServerCNs = self.setup['serverCN'])
if self.setup['profile']:
try: