First cleanup of SSL connection, not working yet.
This commit is contained in:
parent
006b898e66
commit
2dbae4d8a9
2 changed files with 72 additions and 26 deletions
|
|
@ -7,22 +7,70 @@ from __future__ import print_function
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from twisted.internet import ssl as twisted_ssl
|
|
||||||
try:
|
try:
|
||||||
import OpenSSL
|
import OpenSSL
|
||||||
except ImportError:
|
from twisted.internet import ssl as twisted_ssl
|
||||||
print(" SSL_ENABLED requires PyOpenSSL.")
|
except ImportError as err:
|
||||||
sys.exit(5)
|
raise ImportError("SSL_ENABLED requires PyOpenSSL.")
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
from evennia.server.portal.telnet import TelnetProtocol
|
from evennia.server.portal.telnet import TelnetProtocol
|
||||||
|
|
||||||
|
_GAME_DIR = settings.GAME_DIR
|
||||||
|
|
||||||
|
# messages
|
||||||
|
|
||||||
|
NO_AUTOGEN = """
|
||||||
|
|
||||||
|
{err}
|
||||||
|
Evennia could not auto-generate the SSL private key. If this error
|
||||||
|
persists, create {keyfile} yourself using third-party tools.
|
||||||
|
"""
|
||||||
|
|
||||||
|
NO_AUTOCERT = """
|
||||||
|
|
||||||
|
{err}
|
||||||
|
Evennia's SSL context factory could not automatically, create an SSL
|
||||||
|
certificate {certfile}.
|
||||||
|
|
||||||
|
A private key {keyfile} was already created. Please create {certfile}
|
||||||
|
manually using the commands valid for your operating system, for
|
||||||
|
example (linux, using the openssl program):
|
||||||
|
{exestring}
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class SSLProtocol(TelnetProtocol):
|
class SSLProtocol(TelnetProtocol):
|
||||||
"""
|
"""
|
||||||
Communication is the same as telnet, except data transfer
|
Communication is the same as telnet, except data transfer
|
||||||
is done with encryption.
|
is done with encryption.
|
||||||
"""
|
"""
|
||||||
pass
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(TelnetProtocol, self).__init__(*args, **kwargs)
|
||||||
|
self.protocol_name = "ssl"
|
||||||
|
|
||||||
|
def connectionMade(self):
|
||||||
|
print ("SSL connectionMade")
|
||||||
|
#self.iaw_mode = False
|
||||||
|
#self.no_lb_mode = False
|
||||||
|
#client_address = self.transport.client
|
||||||
|
#client_address = client_address[0] if client_address else None
|
||||||
|
#self.init_session(self.protocol_name, client_address, self.factory.sessionhandler)
|
||||||
|
#self.sessionhandler.connect(self)
|
||||||
|
|
||||||
|
super(SSLProtocol, self).connectionMade()
|
||||||
|
|
||||||
|
def connectionLost(self, reason):
|
||||||
|
print ("SSL connectionLost")
|
||||||
|
super(SSLProtocol, self).connectionLost(reason)
|
||||||
|
|
||||||
|
def dataReceived(self, data):
|
||||||
|
print("SSL dataReceived:", data)
|
||||||
|
super(SSLProtocol, self).dataReceived(data)
|
||||||
|
|
||||||
|
def send_text(self, *args, **kwargs):
|
||||||
|
print("SSL send_text:", args, kwargs)
|
||||||
|
super(SSLProtocol, self).send_text(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def verify_SSL_key_and_cert(keyfile, certfile):
|
def verify_SSL_key_and_cert(keyfile, certfile):
|
||||||
|
|
@ -46,9 +94,8 @@ def verify_SSL_key_and_cert(keyfile, certfile):
|
||||||
rsaKey = Key(RSA.generate(KEY_LENGTH))
|
rsaKey = Key(RSA.generate(KEY_LENGTH))
|
||||||
keyString = rsaKey.toString(type="OPENSSH")
|
keyString = rsaKey.toString(type="OPENSSH")
|
||||||
file(keyfile, 'w+b').write(keyString)
|
file(keyfile, 'w+b').write(keyString)
|
||||||
except Exception as e:
|
except Exception as err:
|
||||||
print("rsaKey error: %(e)s\n WARNING: Evennia could not auto-generate SSL private key." % {'e': e})
|
print(NO_AUTOGEN.format(err=err, keyfile=keyfile))
|
||||||
print("If this error persists, create game/%(keyfile)s yourself using third-party tools." % {'keyfile': keyfile})
|
|
||||||
sys.exit(5)
|
sys.exit(5)
|
||||||
|
|
||||||
# try to create the certificate
|
# try to create the certificate
|
||||||
|
|
@ -57,29 +104,24 @@ def verify_SSL_key_and_cert(keyfile, certfile):
|
||||||
#openssl req -new -x509 -key ssl.key -out ssl.cert -days 7300
|
#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)
|
exestring = "openssl req -new -x509 -key %s -out %s -days %s" % (keyfile, certfile, CERT_EXPIRE)
|
||||||
try:
|
try:
|
||||||
#, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
|
||||||
subprocess.call(exestring)
|
subprocess.call(exestring)
|
||||||
except OSError as e:
|
except OSError as err:
|
||||||
string = "\n".join([
|
raise OSError(NO_AUTOCERT.format(err=err, certfile=certfile, keyfile=keyfile, exestring=exestring))
|
||||||
" %s\n" % e,
|
|
||||||
" Evennia's SSL context factory could not automatically",
|
|
||||||
" create an SSL certificate game/%(cert)s." % {'cert': certfile},
|
|
||||||
" A private key 'ssl.key' was already created. Please",
|
|
||||||
" create %(cert)s manually using the commands valid" % {'cert': certfile},
|
|
||||||
" for your operating system.",
|
|
||||||
" Example (linux, using the openssl program): ",
|
|
||||||
" %s" % exestring])
|
|
||||||
print(string)
|
|
||||||
sys.exit(5)
|
|
||||||
print("done.")
|
print("done.")
|
||||||
|
|
||||||
|
|
||||||
def getSSLContext():
|
def getSSLContext():
|
||||||
"""
|
"""
|
||||||
Returns an SSL context (key and certificate). This function
|
This is called by the portal when creating the SSL context
|
||||||
verifies that key/cert exists before obtaining the context, and if
|
server-side.
|
||||||
not, creates them.
|
|
||||||
|
Returns:
|
||||||
|
ssl_context (tuple): A key and certificate that is either
|
||||||
|
existing previously or or created on the fly.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
keyfile, certfile = "ssl.key", "ssl.cert"
|
keyfile = os.path.join(_GAME_DIR, "server", "ssl.key")
|
||||||
|
certfile = os.path.join(_GAME_DIR, "server", "ssl.cert")
|
||||||
|
|
||||||
verify_SSL_key_and_cert(keyfile, certfile)
|
verify_SSL_key_and_cert(keyfile, certfile)
|
||||||
return twisted_ssl.DefaultOpenSSLContextFactory(keyfile, certfile)
|
return twisted_ssl.DefaultOpenSSLContextFactory(keyfile, certfile)
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,10 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
|
||||||
clients) gets a telnet protocol instance assigned to them. All
|
clients) gets a telnet protocol instance assigned to them. All
|
||||||
communication between game and player goes through here.
|
communication between game and player goes through here.
|
||||||
"""
|
"""
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.protocol_name = "telnet"
|
||||||
|
super(TelnetProtocol, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def connectionMade(self):
|
def connectionMade(self):
|
||||||
"""
|
"""
|
||||||
This is called when the connection is first established.
|
This is called when the connection is first established.
|
||||||
|
|
@ -44,7 +48,7 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
|
||||||
# this number is counted down for every handshake that completes.
|
# this number is counted down for every handshake that completes.
|
||||||
# when it reaches 0 the portal/server syncs their data
|
# when it reaches 0 the portal/server syncs their data
|
||||||
self.handshakes = 7 # naws, ttype, mccp, mssp, msdp, gmcp, mxp
|
self.handshakes = 7 # naws, ttype, mccp, mssp, msdp, gmcp, mxp
|
||||||
self.init_session("telnet", client_address, self.factory.sessionhandler)
|
self.init_session(self.protocol_name, client_address, self.factory.sessionhandler)
|
||||||
|
|
||||||
# negotiate client size
|
# negotiate client size
|
||||||
self.naws = naws.Naws(self)
|
self.naws = naws.Naws(self)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue