Implement TLS automatic certificate rotation

This commit is contained in:
Alberto Sottile 2019-02-19 09:37:15 +01:00
parent 21e19159e0
commit 890e8ea2ab
2 changed files with 27 additions and 6 deletions

View File

@ -2,6 +2,7 @@
import json import json
import time import time
from functools import wraps from functools import wraps
from os.path import getmtime
from twisted.protocols.basic import LineReceiver from twisted.protocols.basic import LineReceiver
from twisted.internet.interfaces import IHandshakeListener from twisted.internet.interfaces import IHandshakeListener
@ -669,7 +670,9 @@ class SyncServerProtocol(JSONCommandProtocol):
def handleTLS(self, message): def handleTLS(self, message):
inquiry = message["startTLS"] if "startTLS" in message else None inquiry = message["startTLS"] if "startTLS" in message else None
if "send" in inquiry: if "send" in inquiry:
if not self.isLogged() and self._factory.options is not None: if not self.isLogged() and self._factory.serverAcceptsTLS and self._factory.options is not None:
if self._factory.checkLastEditCertTime() > self.lastEditCertTime:
self._factory.updateTLSContextFactory()
self.sendTLS({"startTLS": "true"}) self.sendTLS({"startTLS": "true"})
self.transport.startTLS(self._factory.options) self.transport.startTLS(self._factory.options)
else: else:

View File

@ -208,11 +208,22 @@ class SyncFactory(Factory):
watcher.setPlaylistIndex(room.getName(), room.getPlaylistIndex()) watcher.setPlaylistIndex(room.getName(), room.getPlaylistIndex())
def _allowTLSconnections(self, path): def _allowTLSconnections(self, path):
self.options = self._createTLSContextFactory(path)
if self.options is not None:
self.serverAcceptsTLS = True
else:
self.serverAcceptsTLS = False
self.lastEditCertTime = None
print("TLS support is not enabled.")
def _createTLSContextFactory(self, path):
try: try:
privKey = open(path+'/privkey.pem', 'rt').read() privKey = open(path+'/privkey.pem', 'rt').read()
certif = open(path+'/cert.pem', 'rt').read() certif = open(path+'/cert.pem', 'rt').read()
chain = open(path+'/chain.pem', 'rt').read() chain = open(path+'/chain.pem', 'rt').read()
self.lastEditCertTime = os.path.getmtime(path+'/cert.pem')
privKeyPySSL = crypto.load_privatekey(crypto.FILETYPE_PEM, privKey) privKeyPySSL = crypto.load_privatekey(crypto.FILETYPE_PEM, privKey)
certifPySSL = crypto.load_certificate(crypto.FILETYPE_PEM, certif) certifPySSL = crypto.load_certificate(crypto.FILETYPE_PEM, certif)
chainPySSL = [crypto.load_certificate(crypto.FILETYPE_PEM, chain)] chainPySSL = [crypto.load_certificate(crypto.FILETYPE_PEM, chain)]
@ -225,11 +236,18 @@ class SyncFactory(Factory):
contextFactory = ssl.CertificateOptions(privateKey=privKeyPySSL, certificate=certifPySSL, contextFactory = ssl.CertificateOptions(privateKey=privKeyPySSL, certificate=certifPySSL,
extraCertChain=chainPySSL, acceptableCiphers=accCiphers, extraCertChain=chainPySSL, acceptableCiphers=accCiphers,
raiseMinimumTo=ssl.TLSVersion.TLSv1_2) raiseMinimumTo=ssl.TLSVersion.TLSv1_2)
self.options = contextFactory
except Exception as e: except Exception as e:
self.options = None
print(e) print(e)
print("TLS support is not enabled.") contextFactory = None
return contextFactory
def checkLastEditCertTime(self):
return os.path.getmtime(self.certPath+'/cert.pem')
def updateTLSContextFactory(self):
self.options = self._createTLSContextFactory(self.certPath)
class StatsRecorder(object): class StatsRecorder(object):