aboutsummaryrefslogtreecommitdiff
path: root/okupy
diff options
context:
space:
mode:
authorMichał Górny <mgorny@gentoo.org>2013-08-20 16:07:57 +0200
committerMichał Górny <mgorny@gentoo.org>2013-08-25 10:51:02 +0200
commit4711bf5f1288d701962b91a471e084d554d18345 (patch)
tree5cd5b3f8013cebdf11af698341c3be684c2b60f3 /okupy
parentMerge pull request #79 from tampakrap/tests_v3 (diff)
downloadidentity.gentoo.org-4711bf5f1288d701962b91a471e084d554d18345.tar.gz
identity.gentoo.org-4711bf5f1288d701962b91a471e084d554d18345.tar.bz2
identity.gentoo.org-4711bf5f1288d701962b91a471e084d554d18345.zip
Initial SSH server support.
Diffstat (limited to 'okupy')
-rw-r--r--okupy/common/ssh.py78
-rw-r--r--okupy/settings/__init__.py4
-rw-r--r--okupy/settings/local.py.sample9
-rw-r--r--okupy/tests/settings.py18
-rw-r--r--okupy/wsgi.py6
5 files changed, 114 insertions, 1 deletions
diff --git a/okupy/common/ssh.py b/okupy/common/ssh.py
new file mode 100644
index 0000000..bde138b
--- /dev/null
+++ b/okupy/common/ssh.py
@@ -0,0 +1,78 @@
+# vim:fileencoding=utf8:et:ts=4:sts=4:sw=4:ft=python
+
+from django.conf import settings
+
+import paramiko
+
+from io import BytesIO
+
+import asyncore
+import socket
+import threading
+
+
+LISTEN_BACKLOG = 20
+
+
+class SSHServer(paramiko.ServerInterface):
+ def get_allowed_auths(self, username):
+ return 'publickey'
+
+ def check_auth_publickey(self, username, key):
+ return paramiko.AUTH_SUCCESSFUL
+
+ def check_channel_request(self, kind, chanid):
+ if kind == 'session':
+ return paramiko.OPEN_SUCCEEDED
+ return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
+
+ def check_channel_subsystem_request(self, channel, name):
+ return False
+
+ def check_channel_exec_request(self, channel, command):
+ channel.send('Not yet implemented, sorry.\r\n')
+ channel.shutdown(2)
+ channel.close()
+ return True
+
+ def check_channel_shell_request(self, channel):
+ channel.send('Not yet implemented, sorry.\r\n')
+ channel.shutdown(2)
+ channel.close()
+ return True
+
+ def check_channel_pty_request(self, channel, term, width, height,
+ pixelwidth, pixelheight, modes):
+ return True
+
+
+class SSHDispatcher(asyncore.dispatcher):
+ def __init__(self, server_key):
+ asyncore.dispatcher.__init__(self)
+ self._server_key = server_key
+
+ self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.set_reuse_addr()
+ self.bind(settings.SSH_BIND)
+ self.listen(LISTEN_BACKLOG)
+
+ def handle_accepted(self, conn, addr):
+ t = paramiko.Transport(conn)
+ t.add_server_key(self._server_key)
+ # we need a dummy Event to make it non-blocking
+ # but we don't really need to play with it
+ t.start_server(event=threading.Event(), server=SSHServer())
+
+ # python<3.2 compat
+ def handle_accept(self):
+ ret = self.accept()
+ if ret is not None:
+ self.handle_accepted(*ret)
+
+
+def ssh_main():
+ server_key = paramiko.RSAKey(file_obj=BytesIO(settings.SSH_SERVER_KEY))
+
+ disp = SSHDispatcher(server_key)
+ asyncore.loop()
+ raise SystemError('SSH server loop exited')
diff --git a/okupy/settings/__init__.py b/okupy/settings/__init__.py
index 767bb22..e88939b 100644
--- a/okupy/settings/__init__.py
+++ b/okupy/settings/__init__.py
@@ -143,6 +143,10 @@ LOGGING = {
'handlers': ['console' if DEBUG else 'syslog'],
'level': 'DEBUG' if DEBUG else 'INFO',
},
+ 'paramiko': {
+ 'handlers': ['console' if DEBUG else 'syslog'],
+ 'level': 'DEBUG' if DEBUG else 'INFO',
+ }
}
}
diff --git a/okupy/settings/local.py.sample b/okupy/settings/local.py.sample
index 245d48a..172b78f 100644
--- a/okupy/settings/local.py.sample
+++ b/okupy/settings/local.py.sample
@@ -79,3 +79,12 @@ AUTH_LDAP_USER_OBJECTCLASS = ['top', 'person', 'organizationalPerson',
'inetOrgPerson', 'posixAccount', 'shadowAccount']
# additional objectClasses that are used by developers
AUTH_LDAP_DEV_OBJECTCLASS = ['developerAccount']
+
+# replace with your preferred port
+SSH_BIND = ('0.0.0.0', 8022)
+# paste your *server* private key here
+SSH_SERVER_KEY = '''
+-----BEGIN RSA PRIVATE KEY-----
+...
+-----END RSA PRIVATE KEY-----
+'''
diff --git a/okupy/tests/settings.py b/okupy/tests/settings.py
index 316f165..b626ca5 100644
--- a/okupy/tests/settings.py
+++ b/okupy/tests/settings.py
@@ -290,3 +290,21 @@ DATABASES['ldap'] = {
DATABASE_ROUTERS = ['ldapdb.router.Router']
TEST_RUNNER = 'discover_runner.DiscoverRunner'
+
+# replace with your preferred port
+SSH_BIND = ('0.0.0.0', 8022)
+# paste your *server* private key here
+SSH_SERVER_KEY = '''
+-----BEGIN RSA PRIVATE KEY-----
+MIIBywIBAAJhANlKTt3/R+xVCgQbUNfqVWt28iHXJ+OCtqqVHaiLp9syBEGNiowK
+KQZ3swwuaa5WSPFwrsmd1/+REm2HdnQITSF/HSAPtOpbv4xaJ45iX1S4JhOK88c+
+UuBrg+lOeclIHQIDAQABAmEAm9fr0NTzJNGpKWDeDr4HHdhluVezSD3L/XSNnQDt
+Fw08eDeoEuCGpBjd1fLD4UIIJHBzc+8ybLZCTgE8JebokHGJxkk8tRt7NgVwnUws
+arTKHqb4nOCu6s0re9IkSL0RAjEA9SV9PWk6J+smQQvVWIh6K+PnLrSV9C3LSisK
+U8Zfrffly03j5sanjV5ZKx7bRJsXAjEA4ukYNYz3GPqQaYzDP/OObRZwQ2Iema2B
+fCbBiokfh4w5Hio+UvbgDD+cBYCjcqbrAjAwjYBEjXbLOTOWZnWW11D7KGQ9R977
+QaalxeiBtyR0HEkS/xZIOsgso6cddzsOV3kCMQCpxK4JOsuRE77CSb+3dDkmYvhh
+YeL1JbxQMArz5H4DgyUk7YQtvGmKoHjSIRmo6TsCMH+7CSP/hnzR1GXLwpeQ+dgp
+IwszrV7pBZ5anBHnmPqwqBWF/I/0IIrtouUHzs9XHg==
+-----END RSA PRIVATE KEY-----
+'''
diff --git a/okupy/wsgi.py b/okupy/wsgi.py
index 306104d..da73254 100644
--- a/okupy/wsgi.py
+++ b/okupy/wsgi.py
@@ -41,9 +41,13 @@ except ImportError:
# we're probably running from django's built-in server
pass
else:
- from uwsgidecorators import timer
+ from uwsgidecorators import postfork, thread, timer
from django.utils import autoreload
+ from okupy.common.ssh import ssh_main
+
+ postfork(thread(ssh_main))
+
@timer(5)
def change_code_gracefull_reload(sig):
if autoreload.code_changed():