|
@@ -30,8 +30,8 @@ import hostname
|
|
|
|
|
|
logger = logging.getLogger()
|
|
logger = logging.getLogger()
|
|
|
|
|
|
-GEN_AGENT_KEY="openssl req -new -newkey rsa:1024 -nodes -keyout %(keysdir)s/%(hostname)s.key\
|
|
|
|
- -subj /OU=%(hostname)s/\
|
|
|
|
|
|
+GEN_AGENT_KEY = "openssl req -new -newkey rsa:1024 -nodes -keyout %(keysdir)s/%(hostname)s.key\
|
|
|
|
+ -subj /OU=%(hostname)s/\
|
|
-out %(keysdir)s/%(hostname)s.csr"
|
|
-out %(keysdir)s/%(hostname)s.csr"
|
|
|
|
|
|
|
|
|
|
@@ -39,30 +39,34 @@ class VerifiedHTTPSConnection(httplib.HTTPSConnection):
|
|
""" Connecting using ssl wrapped sockets """
|
|
""" Connecting using ssl wrapped sockets """
|
|
def __init__(self, host, port=None, config=None):
|
|
def __init__(self, host, port=None, config=None):
|
|
httplib.HTTPSConnection.__init__(self, host, port=port)
|
|
httplib.HTTPSConnection.__init__(self, host, port=port)
|
|
- self.config=config
|
|
|
|
- self.two_way_ssl_required=False
|
|
|
|
|
|
+ self.two_way_ssl_required = False
|
|
|
|
+ self.config = config
|
|
|
|
|
|
def connect(self):
|
|
def connect(self):
|
|
|
|
+ self.two_way_ssl_required = self.config.isTwoWaySSLConnection()
|
|
|
|
+ logger.debug("Server two-way SSL authentication required: %s" % str(self.two_way_ssl_required))
|
|
|
|
+ if self.two_way_ssl_required is True:
|
|
|
|
+ logger.info('Server require two-way SSL authentication. Use it instead of one-way...')
|
|
|
|
|
|
if not self.two_way_ssl_required:
|
|
if not self.two_way_ssl_required:
|
|
try:
|
|
try:
|
|
- sock=self.create_connection()
|
|
|
|
|
|
+ sock = self.create_connection()
|
|
self.sock = ssl.wrap_socket(sock, cert_reqs=ssl.CERT_NONE)
|
|
self.sock = ssl.wrap_socket(sock, cert_reqs=ssl.CERT_NONE)
|
|
logger.info('SSL connection established. Two-way SSL authentication is '
|
|
logger.info('SSL connection established. Two-way SSL authentication is '
|
|
'turned off on the server.')
|
|
'turned off on the server.')
|
|
except (ssl.SSLError, AttributeError):
|
|
except (ssl.SSLError, AttributeError):
|
|
- self.two_way_ssl_required=True
|
|
|
|
|
|
+ self.two_way_ssl_required = True
|
|
logger.info('Insecure connection to https://' + self.host + ':' + self.port +
|
|
logger.info('Insecure connection to https://' + self.host + ':' + self.port +
|
|
'/ failed. Reconnecting using two-way SSL authentication..')
|
|
'/ failed. Reconnecting using two-way SSL authentication..')
|
|
|
|
|
|
if self.two_way_ssl_required:
|
|
if self.two_way_ssl_required:
|
|
- self.certMan=CertificateManager(self.config)
|
|
|
|
|
|
+ self.certMan = CertificateManager(self.config)
|
|
self.certMan.initSecurity()
|
|
self.certMan.initSecurity()
|
|
agent_key = self.certMan.getAgentKeyName()
|
|
agent_key = self.certMan.getAgentKeyName()
|
|
agent_crt = self.certMan.getAgentCrtName()
|
|
agent_crt = self.certMan.getAgentCrtName()
|
|
server_crt = self.certMan.getSrvrCrtName()
|
|
server_crt = self.certMan.getSrvrCrtName()
|
|
|
|
|
|
- sock=self.create_connection()
|
|
|
|
|
|
+ sock = self.create_connection()
|
|
|
|
|
|
try:
|
|
try:
|
|
self.sock = ssl.wrap_socket(sock,
|
|
self.sock = ssl.wrap_socket(sock,
|
|
@@ -88,41 +92,40 @@ class VerifiedHTTPSConnection(httplib.HTTPSConnection):
|
|
self.sock.close()
|
|
self.sock.close()
|
|
logger.info("SSL Connect being called.. connecting to the server")
|
|
logger.info("SSL Connect being called.. connecting to the server")
|
|
sock = socket.create_connection((self.host, self.port), 60)
|
|
sock = socket.create_connection((self.host, self.port), 60)
|
|
- sock.setsockopt( socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
|
|
|
|
|
|
+ sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
|
|
if self._tunnel_host:
|
|
if self._tunnel_host:
|
|
self.sock = sock
|
|
self.sock = sock
|
|
self._tunnel()
|
|
self._tunnel()
|
|
|
|
|
|
return sock
|
|
return sock
|
|
|
|
|
|
|
|
+
|
|
class CachedHTTPSConnection:
|
|
class CachedHTTPSConnection:
|
|
""" Caches a ssl socket and uses a single https connection to the server. """
|
|
""" Caches a ssl socket and uses a single https connection to the server. """
|
|
-
|
|
|
|
|
|
+
|
|
def __init__(self, config):
|
|
def __init__(self, config):
|
|
- self.connected = False;
|
|
|
|
|
|
+ self.connected = False
|
|
self.config = config
|
|
self.config = config
|
|
self.server = config.get('server', 'hostname')
|
|
self.server = config.get('server', 'hostname')
|
|
self.port = config.get('server', 'secured_url_port')
|
|
self.port = config.get('server', 'secured_url_port')
|
|
self.connect()
|
|
self.connect()
|
|
-
|
|
|
|
|
|
+
|
|
def connect(self):
|
|
def connect(self):
|
|
- if not self.connected:
|
|
|
|
|
|
+ if not self.connected:
|
|
self.httpsconn = VerifiedHTTPSConnection(self.server, self.port, self.config)
|
|
self.httpsconn = VerifiedHTTPSConnection(self.server, self.port, self.config)
|
|
self.httpsconn.connect()
|
|
self.httpsconn.connect()
|
|
self.connected = True
|
|
self.connected = True
|
|
# possible exceptions are caught and processed in Controller
|
|
# possible exceptions are caught and processed in Controller
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
def forceClear(self):
|
|
def forceClear(self):
|
|
self.httpsconn = VerifiedHTTPSConnection(self.server, self.port, self.config)
|
|
self.httpsconn = VerifiedHTTPSConnection(self.server, self.port, self.config)
|
|
self.connect()
|
|
self.connect()
|
|
-
|
|
|
|
- def request(self, req):
|
|
|
|
|
|
+
|
|
|
|
+ def request(self, req):
|
|
self.connect()
|
|
self.connect()
|
|
try:
|
|
try:
|
|
- self.httpsconn.request(req.get_method(), req.get_full_url(),
|
|
|
|
- req.get_data(), req.headers)
|
|
|
|
|
|
+ self.httpsconn.request(req.get_method(), req.get_full_url(),
|
|
|
|
+ req.get_data(), req.headers)
|
|
response = self.httpsconn.getresponse()
|
|
response = self.httpsconn.getresponse()
|
|
readResponse = response.read()
|
|
readResponse = response.read()
|
|
except Exception as ex:
|
|
except Exception as ex:
|
|
@@ -133,59 +136,60 @@ class CachedHTTPSConnection:
|
|
self.connected = False
|
|
self.connected = False
|
|
raise IOError("Error occured during connecting to the server: " + str(ex))
|
|
raise IOError("Error occured during connecting to the server: " + str(ex))
|
|
return readResponse
|
|
return readResponse
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+
|
|
class CertificateManager():
|
|
class CertificateManager():
|
|
def __init__(self, config):
|
|
def __init__(self, config):
|
|
self.config = config
|
|
self.config = config
|
|
self.keysdir = self.config.get('security', 'keysdir')
|
|
self.keysdir = self.config.get('security', 'keysdir')
|
|
- self.server_crt=self.config.get('security', 'server_crt')
|
|
|
|
|
|
+ self.server_crt = self.config.get('security', 'server_crt')
|
|
self.server_url = 'https://' + self.config.get('server', 'hostname') + ':' \
|
|
self.server_url = 'https://' + self.config.get('server', 'hostname') + ':' \
|
|
+ self.config.get('server', 'url_port')
|
|
+ self.config.get('server', 'url_port')
|
|
-
|
|
|
|
|
|
+
|
|
def getAgentKeyName(self):
|
|
def getAgentKeyName(self):
|
|
keysdir = self.config.get('security', 'keysdir')
|
|
keysdir = self.config.get('security', 'keysdir')
|
|
- return keysdir + os.sep + hostname.hostname() + ".key"
|
|
|
|
|
|
+ return keysdir + os.sep + hostname.hostname(self.config) + ".key"
|
|
|
|
|
|
def getAgentCrtName(self):
|
|
def getAgentCrtName(self):
|
|
keysdir = self.config.get('security', 'keysdir')
|
|
keysdir = self.config.get('security', 'keysdir')
|
|
- return keysdir + os.sep + hostname.hostname() + ".crt"
|
|
|
|
|
|
+ return keysdir + os.sep + hostname.hostname(self.config) + ".crt"
|
|
|
|
|
|
def getAgentCrtReqName(self):
|
|
def getAgentCrtReqName(self):
|
|
keysdir = self.config.get('security', 'keysdir')
|
|
keysdir = self.config.get('security', 'keysdir')
|
|
- return keysdir + os.sep + hostname.hostname() + ".csr"
|
|
|
|
|
|
+ return keysdir + os.sep + hostname.hostname(self.config) + ".csr"
|
|
|
|
|
|
def getSrvrCrtName(self):
|
|
def getSrvrCrtName(self):
|
|
keysdir = self.config.get('security', 'keysdir')
|
|
keysdir = self.config.get('security', 'keysdir')
|
|
return keysdir + os.sep + "ca.crt"
|
|
return keysdir + os.sep + "ca.crt"
|
|
-
|
|
|
|
|
|
+
|
|
def checkCertExists(self):
|
|
def checkCertExists(self):
|
|
-
|
|
|
|
|
|
+
|
|
s = self.config.get('security', 'keysdir') + os.sep + "ca.crt"
|
|
s = self.config.get('security', 'keysdir') + os.sep + "ca.crt"
|
|
|
|
|
|
server_crt_exists = os.path.exists(s)
|
|
server_crt_exists = os.path.exists(s)
|
|
-
|
|
|
|
|
|
+
|
|
if not server_crt_exists:
|
|
if not server_crt_exists:
|
|
logger.info("Server certicate not exists, downloading")
|
|
logger.info("Server certicate not exists, downloading")
|
|
self.loadSrvrCrt()
|
|
self.loadSrvrCrt()
|
|
else:
|
|
else:
|
|
logger.info("Server certicate exists, ok")
|
|
logger.info("Server certicate exists, ok")
|
|
-
|
|
|
|
|
|
+
|
|
agent_key_exists = os.path.exists(self.getAgentKeyName())
|
|
agent_key_exists = os.path.exists(self.getAgentKeyName())
|
|
-
|
|
|
|
|
|
+
|
|
if not agent_key_exists:
|
|
if not agent_key_exists:
|
|
logger.info("Agent key not exists, generating request")
|
|
logger.info("Agent key not exists, generating request")
|
|
self.genAgentCrtReq()
|
|
self.genAgentCrtReq()
|
|
else:
|
|
else:
|
|
logger.info("Agent key exists, ok")
|
|
logger.info("Agent key exists, ok")
|
|
-
|
|
|
|
|
|
+
|
|
agent_crt_exists = os.path.exists(self.getAgentCrtName())
|
|
agent_crt_exists = os.path.exists(self.getAgentCrtName())
|
|
-
|
|
|
|
|
|
+
|
|
if not agent_crt_exists:
|
|
if not agent_crt_exists:
|
|
logger.info("Agent certificate not exists, sending sign request")
|
|
logger.info("Agent certificate not exists, sending sign request")
|
|
self.reqSignCrt()
|
|
self.reqSignCrt()
|
|
else:
|
|
else:
|
|
logger.info("Agent certificate exists, ok")
|
|
logger.info("Agent certificate exists, ok")
|
|
-
|
|
|
|
|
|
+
|
|
def loadSrvrCrt(self):
|
|
def loadSrvrCrt(self):
|
|
get_ca_url = self.server_url + '/cert/ca/'
|
|
get_ca_url = self.server_url + '/cert/ca/'
|
|
logger.info("Downloading server cert from " + get_ca_url)
|
|
logger.info("Downloading server cert from " + get_ca_url)
|
|
@@ -196,15 +200,15 @@ class CertificateManager():
|
|
stream.close()
|
|
stream.close()
|
|
srvr_crt_f = open(self.getSrvrCrtName(), 'w+')
|
|
srvr_crt_f = open(self.getSrvrCrtName(), 'w+')
|
|
srvr_crt_f.write(response)
|
|
srvr_crt_f.write(response)
|
|
-
|
|
|
|
|
|
+
|
|
def reqSignCrt(self):
|
|
def reqSignCrt(self):
|
|
- sign_crt_req_url = self.server_url + '/certs/' + hostname.hostname()
|
|
|
|
|
|
+ sign_crt_req_url = self.server_url + '/certs/' + hostname.hostname(self.config)
|
|
agent_crt_req_f = open(self.getAgentCrtReqName())
|
|
agent_crt_req_f = open(self.getAgentCrtReqName())
|
|
agent_crt_req_content = agent_crt_req_f.read()
|
|
agent_crt_req_content = agent_crt_req_f.read()
|
|
passphrase_env_var = self.config.get('security', 'passphrase_env_var_name')
|
|
passphrase_env_var = self.config.get('security', 'passphrase_env_var_name')
|
|
passphrase = os.environ[passphrase_env_var]
|
|
passphrase = os.environ[passphrase_env_var]
|
|
- register_data = {'csr' : agent_crt_req_content,
|
|
|
|
- 'passphrase' : passphrase}
|
|
|
|
|
|
+ register_data = {'csr': agent_crt_req_content,
|
|
|
|
+ 'passphrase': passphrase}
|
|
data = json.dumps(register_data)
|
|
data = json.dumps(register_data)
|
|
proxy_handler = urllib2.ProxyHandler({})
|
|
proxy_handler = urllib2.ProxyHandler({})
|
|
opener = urllib2.build_opener(proxy_handler)
|
|
opener = urllib2.build_opener(proxy_handler)
|
|
@@ -219,9 +223,9 @@ class CertificateManager():
|
|
except Exception:
|
|
except Exception:
|
|
logger.warn("Malformed response! data: " + str(data))
|
|
logger.warn("Malformed response! data: " + str(data))
|
|
data = {'result': 'ERROR'}
|
|
data = {'result': 'ERROR'}
|
|
- result=data['result']
|
|
|
|
|
|
+ result = data['result']
|
|
if result == 'OK':
|
|
if result == 'OK':
|
|
- agentCrtContent=data['signedCa']
|
|
|
|
|
|
+ agentCrtContent = data['signedCa']
|
|
agentCrtF = open(self.getAgentCrtName(), "w")
|
|
agentCrtF = open(self.getAgentCrtName(), "w")
|
|
agentCrtF.write(agentCrtContent)
|
|
agentCrtF.write(agentCrtContent)
|
|
else:
|
|
else:
|
|
@@ -235,11 +239,11 @@ class CertificateManager():
|
|
raise ssl.SSLError
|
|
raise ssl.SSLError
|
|
|
|
|
|
def genAgentCrtReq(self):
|
|
def genAgentCrtReq(self):
|
|
- generate_script = GEN_AGENT_KEY % {'hostname': hostname.hostname(),
|
|
|
|
- 'keysdir' : self.config.get('security', 'keysdir')}
|
|
|
|
|
|
+ generate_script = GEN_AGENT_KEY % {'hostname': hostname.hostname(self.config),
|
|
|
|
+ 'keysdir': self.config.get('security', 'keysdir')}
|
|
logger.info(generate_script)
|
|
logger.info(generate_script)
|
|
p = subprocess.Popen([generate_script], shell=True, stdout=subprocess.PIPE)
|
|
p = subprocess.Popen([generate_script], shell=True, stdout=subprocess.PIPE)
|
|
p.communicate()
|
|
p.communicate()
|
|
-
|
|
|
|
|
|
+
|
|
def initSecurity(self):
|
|
def initSecurity(self):
|
|
self.checkCertExists()
|
|
self.checkCertExists()
|