mirror of
https://github.com/evennia/evennia.git
synced 2026-03-19 22:36:31 +01:00
Added SSL (Secure Sockets Layer) support, inspired by patch by rcaskey (issue 79). The automatic certificate creation does not work well; so the system instead instructs and gives example on how to create your own using third-party tools. I can connect to the server using a twisted-client instance, but not that many regular mud clients seem to support SSL at all (and if they do I don't know to configure them ...)
This commit is contained in:
parent
7c56c69cea
commit
a8a70e9f5e
3 changed files with 103 additions and 12 deletions
|
|
@ -1,11 +1,11 @@
|
|||
"""
|
||||
This module implements the main Evennia server process, the core of
|
||||
the game engine. Don't import this module! If you need to access the
|
||||
server processes from code, instead import sessionhandler.SESSIONS
|
||||
and use its 'server' property.
|
||||
the game engine. Don't import this module directly! If you need to
|
||||
access the server processes from code, instead go via the session-
|
||||
handler: src.sessionhandler.SESSIONS.server
|
||||
|
||||
This module should be started with the 'twistd' executable since it
|
||||
sets up all the networking features. (this is done by automatically
|
||||
sets up all the networking features. (this is done automatically
|
||||
by game/evennia.py).
|
||||
|
||||
"""
|
||||
|
|
@ -39,10 +39,12 @@ SERVERNAME = settings.SERVERNAME
|
|||
VERSION = get_evennia_version()
|
||||
|
||||
TELNET_PORTS = settings.TELNET_PORTS
|
||||
SSL_PORTS = settings.SSL_PORTS
|
||||
SSH_PORTS = settings.SSH_PORTS
|
||||
WEBSERVER_PORTS = settings.WEBSERVER_PORTS
|
||||
|
||||
TELNET_ENABLED = settings.TELNET_ENABLED and TELNET_PORTS
|
||||
SSL_ENABLED = settings.SSL_ENABLED and SSL_PORTS
|
||||
SSH_ENABLED = settings.SSH_ENABLED and SSH_PORTS
|
||||
WEBSERVER_ENABLED = settings.WEBSERVER_ENABLED and WEBSERVER_PORTS
|
||||
WEBCLIENT_ENABLED = settings.WEBCLIENT_ENABLED
|
||||
|
|
@ -101,7 +103,7 @@ class Evennia(object):
|
|||
|
||||
# set a callback if the server is killed abruptly,
|
||||
# by Ctrl-C, reboot etc.
|
||||
reactor.addSystemEventTrigger('before', 'shutdown',self.shutdown, _abrupt=True)
|
||||
reactor.addSystemEventTrigger('before', 'shutdown', self.shutdown, _abrupt=True)
|
||||
|
||||
self.game_running = True
|
||||
|
||||
|
|
@ -153,6 +155,8 @@ class Evennia(object):
|
|||
print " telnet: " + ", ".join([str(port) for port in TELNET_PORTS])
|
||||
if SSH_ENABLED:
|
||||
print " ssh: " + ", ".join([str(port) for port in SSH_PORTS])
|
||||
if SSL_ENABLED:
|
||||
print " ssl: " + ", ".join([str(port) for port in SSL_PORTS])
|
||||
if WEBSERVER_ENABLED:
|
||||
clientstring = ""
|
||||
if WEBCLIENT_ENABLED:
|
||||
|
|
@ -196,32 +200,46 @@ EVENNIA = Evennia(application)
|
|||
|
||||
if TELNET_ENABLED:
|
||||
|
||||
# start telnet game connections
|
||||
# Start telnet game connections
|
||||
|
||||
from src.server import telnet
|
||||
|
||||
for port in TELNET_PORTS:
|
||||
for port in TELNET_PORTS:
|
||||
factory = protocol.ServerFactory()
|
||||
factory.protocol = telnet.TelnetProtocol
|
||||
telnet_service = internet.TCPServer(port, factory)
|
||||
telnet_service.setName('EvenniaTelnet%s' % port)
|
||||
EVENNIA.services.addService(telnet_service)
|
||||
|
||||
if SSL_ENABLED:
|
||||
|
||||
# Start SSL game connection (requires PyOpenSSL).
|
||||
|
||||
from src.server import ssl
|
||||
|
||||
for port in SSL_PORTS:
|
||||
factory = protocol.ServerFactory()
|
||||
factory.protocol = ssl.SSLProtocol
|
||||
ssl_service = internet.SSLServer(port, factory, ssl.getSSLContext())
|
||||
ssl_service.setName('EvenniaSSL%s' % port)
|
||||
EVENNIA.services.addService(ssl_service)
|
||||
|
||||
if SSH_ENABLED:
|
||||
|
||||
# Start SSH game connections. Will create a keypair in evennia/game if necessary.
|
||||
|
||||
from src.server import ssh
|
||||
|
||||
for port in SSH_PORTS:
|
||||
factory = ssh.makeFactory({'protocolFactory':ssh.SshProtocol,
|
||||
'protocolArgs':()})
|
||||
|
||||
'protocolArgs':()})
|
||||
ssh_service = internet.TCPServer(port, factory)
|
||||
ssh_service.setName('EvenniaSSH%s' % port)
|
||||
EVENNIA.services.addService(ssh_service)
|
||||
|
||||
if WEBSERVER_ENABLED:
|
||||
|
||||
# a django-compatible webserver.
|
||||
# Start a django-compatible webserver.
|
||||
|
||||
from twisted.python import threadpool
|
||||
from src.server.webserver import DjangoWebRoot, WSGIWebServer
|
||||
|
|
|
|||
69
src/server/ssl.py
Normal file
69
src/server/ssl.py
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
"""
|
||||
This is a simple context factory for auto-creating
|
||||
SSL keys and certificates.
|
||||
"""
|
||||
|
||||
import os, sys
|
||||
from twisted.internet import ssl as twisted_ssl
|
||||
try:
|
||||
import OpenSSL
|
||||
except ImportError:
|
||||
print " SSL_ENABLED requires PyOpenSSL."
|
||||
sys.exit()
|
||||
|
||||
from src.server.telnet import TelnetProtocol
|
||||
|
||||
class SSLProtocol(TelnetProtocol):
|
||||
"""
|
||||
Communication is the same as telnet, except data transfer
|
||||
is done with encryption.
|
||||
"""
|
||||
pass
|
||||
|
||||
def verify_SSL_key_and_cert(keyfile, certfile):
|
||||
"""
|
||||
This function looks for RSA key and certificate in the current
|
||||
directory. If files ssl.key and ssl.cert does not exist, they
|
||||
are created.
|
||||
"""
|
||||
|
||||
if not (os.path.exists(keyfile) and os.path.exists(certfile)):
|
||||
# key/cert does not exist. Create.
|
||||
import subprocess
|
||||
from Crypto.PublicKey import RSA
|
||||
from twisted.conch.ssh.keys import Key
|
||||
|
||||
print " Creating SSL key and certificate (this need only be done once)."
|
||||
|
||||
# create the RSA key and store it.
|
||||
KEY_LENGTH = 1024
|
||||
rsaKey = Key(RSA.generate(KEY_LENGTH))
|
||||
keyString = rsaKey.toString(type="OPENSSH")
|
||||
file(keyfile, 'w+b').write(keyString)
|
||||
|
||||
# try to create the certificate
|
||||
CERT_EXPIRE = 365 * 20 # twenty years validity
|
||||
# default:
|
||||
#openssl req -new -x509 -key ssl.key -out ssl.cert -days 7300
|
||||
exestring = "openssl req -new -x509 -key %s -out %s -days %s" % (keyfile, certfile, CERT_EXPIRE)
|
||||
#print "exestring:", exestring
|
||||
try:
|
||||
err = subprocess.call(exestring)#, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
except OSError, e:
|
||||
print " %s\n" % e
|
||||
print " Evennia's SSL context factory could not automatically create an SSL certificate game/%s." % certfile
|
||||
print " A private key 'ssl.key' was already created. Please create %s manually using the commands valid " % certfile
|
||||
print " for your operating system."
|
||||
print " Example (linux, using the openssl program): "
|
||||
print " %s" % exestring
|
||||
sys.exit()
|
||||
|
||||
def getSSLContext():
|
||||
"""
|
||||
Returns an SSL context (key and certificate). This function
|
||||
verifies that key/cert exists before obtaining the context, and if
|
||||
not, creates them.
|
||||
"""
|
||||
keyfile, certfile = "ssl.key", "ssl.cert"
|
||||
verify_SSL_key_and_cert(keyfile, certfile)
|
||||
return twisted_ssl.DefaultOpenSSLContextFactory(keyfile, certfile)
|
||||
|
|
@ -36,10 +36,14 @@ WEBSERVER_PORTS = [8000]
|
|||
# Start the evennia ajax client on /webclient
|
||||
# (the webserver must also be running)
|
||||
WEBCLIENT_ENABLED = True
|
||||
# Activate SSH protocol
|
||||
# Activate SSH protocol (SecureShell)
|
||||
SSH_ENABLED = False
|
||||
# Ports to use for SSH
|
||||
# Ports to use for SSH
|
||||
SSH_PORTS = [8022]
|
||||
# Actiave SSL protocol (SecureSocketLibrary)
|
||||
SSL_ENABLED = False
|
||||
# Ports to use for SSL
|
||||
SSL_PORTS = [4001]
|
||||
# Activate full persistence if you want everything in-game to be
|
||||
# stored to the database. With it set, you can do typeclass.attr=value
|
||||
# and value will be saved to the database under the name 'attr'.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue