startTLS: added --tls [file] argument in server

This commit is contained in:
Alberto Sottile 2019-02-04 16:01:27 +01:00
parent 58ccca5766
commit cecd992fa8
5 changed files with 27 additions and 16 deletions

View File

@ -710,7 +710,6 @@ class SyncplayClient(object):
trust_root = Certificate.loadPEM(cert_file.read())
self._endpoint = HostnameEndpoint(reactor, host, port)
self.protocolFactory.options = optionsForClientTLS(hostname=host, trustRoot = trust_root)
def retry(retries):
self._lastGlobalUpdate = None

View File

@ -439,6 +439,7 @@ en = {
"server-chat-maxchars-argument": "Maximum number of characters in a chat message (default is {})", # Default number of characters
"server-maxusernamelength-argument": "Maximum number of characters in a username (default is {})",
"server-stats-db-file-argument": "Enable server stats using the SQLite db file provided",
"server-tls-argument": "Enable TLS connections using the certificate file provided",
"server-messed-up-motd-unescaped-placeholders": "Message of the Day has unescaped placeholders. All $ signs should be doubled ($$).",
"server-messed-up-motd-too-long": "Message of the Day is too long - maximum of {} chars, {} given.",

View File

@ -316,10 +316,12 @@ class SyncClientProtocol(JSONCommandProtocol):
def handleTLS(self, message):
answer = message["startTLS"] if "startTLS" in message else None
if "true" in answer and not self.logged:
if "true" in answer and not self.logged and self._client.protocolFactory.options is not None:
self.transport.startTLS(self._client.protocolFactory.options)
self._client.ui.showMessage("Secure connection established")
self.sendHello()
elif "false" in answer:
self._client.ui.showErrorMessage("This server does not support TLS")
self.sendHello()
class SyncServerProtocol(JSONCommandProtocol):
def __init__(self, factory):
@ -626,9 +628,12 @@ class SyncServerProtocol(JSONCommandProtocol):
def handleTLS(self, message):
inquiry = message["startTLS"] if "startTLS" in message else None
if "send" in inquiry and not self.isLogged():
self.sendTLS({"startTLS": "true"})
self.transport.startTLS(self._factory.options)
if "send" in inquiry:
if not self.isLogged() and self._factory.options is not None:
self.sendTLS({"startTLS": "true"})
self.transport.startTLS(self._factory.options)
else:
self.sendTLS({"startTLS": "false"})
class PingService(object):

View File

@ -7,7 +7,7 @@ import time
from string import Template
from twisted.enterprise import adbapi
from twisted.internet import task, reactor
from twisted.internet import task, reactor, ssl
from twisted.internet.protocol import Factory
import syncplay
@ -20,7 +20,7 @@ from syncplay.utils import RoomPasswordProvider, NotControlledRoom, RandomString
class SyncFactory(Factory):
def __init__(self, port='', password='', motdFilePath=None, isolateRooms=False, salt=None,
disableReady=False, disableChat=False, maxChatMessageLength=constants.MAX_CHAT_MESSAGE_LENGTH,
maxUsernameLength=constants.MAX_USERNAME_LENGTH, statsDbFile=None):
maxUsernameLength=constants.MAX_USERNAME_LENGTH, statsDbFile=None, tlsCert=None):
self.isolateRooms = isolateRooms
print(getMessage("welcome-server-notification").format(syncplay.version))
self.port = port
@ -48,6 +48,16 @@ class SyncFactory(Factory):
self._statsRecorder.startRecorder(statsDelay)
else:
self._statsDbHandle = None
self.options = None
if tlsCert is not None:
try:
with open(tlsCert) as f:
certData = f.read()
cert = ssl.PrivateCertificate.loadPEM(certData).options()
self.options = cert
except Exception as e:
print(e)
print("Cannot import certificate. TLS support not enabled.")
def buildProtocol(self, addr):
return SyncServerProtocol(self)
@ -624,3 +634,4 @@ class ConfigurationGetter(object):
self._argparser.add_argument('--max-chat-message-length', metavar='maxChatMessageLength', type=int, nargs='?', help=getMessage("server-chat-maxchars-argument").format(constants.MAX_CHAT_MESSAGE_LENGTH))
self._argparser.add_argument('--max-username-length', metavar='maxUsernameLength', type=int, nargs='?', help=getMessage("server-maxusernamelength-argument").format(constants.MAX_USERNAME_LENGTH))
self._argparser.add_argument('--stats-db-file', metavar='file', type=str, nargs='?', help=getMessage("server-stats-db-file-argument"))
self._argparser.add_argument('--tls', metavar='file', type=str, nargs='?', help=getMessage("server-tls-argument"))

View File

@ -14,16 +14,11 @@ except AttributeError:
warnings.warn("You must run Syncplay with Python 3.4 or newer!")
from OpenSSL import crypto
from twisted.internet import reactor, ssl
from twisted.internet import reactor
from twisted.internet.endpoints import TCP4ServerEndpoint, TCP6ServerEndpoint
from syncplay.server import SyncFactory, ConfigurationGetter
with open('cert/server.pem') as f:
certData = f.read()
cert = ssl.PrivateCertificate.loadPEM(certData).options()
if __name__ == '__main__':
argsGetter = ConfigurationGetter()
args = argsGetter.getConfiguration()
@ -37,9 +32,9 @@ if __name__ == '__main__':
args.disable_chat,
args.max_chat_message_length,
args.max_username_length,
args.stats_db_file
args.stats_db_file,
args.tls
)
factory.options = cert
endpoint4 = TCP4ServerEndpoint(reactor, int(args.port))
endpoint4.listen(factory)
endpoint6 = TCP6ServerEndpoint(reactor, int(args.port))