summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/Makefile38
-rw-r--r--services/authorized_keys4
-rwxr-xr-xservices/bin/services24
-rw-r--r--services/checkers.py25
-rw-r--r--services/services.txt7
-rw-r--r--services/test.py108
6 files changed, 206 insertions, 0 deletions
diff --git a/services/Makefile b/services/Makefile
new file mode 100644
index 00000000..3ef670a3
--- /dev/null
+++ b/services/Makefile
@@ -0,0 +1,38 @@
+help:;@cat Makefile
+export authorized_keys_file := authorized_keys
+export services_file := services.txt
+export host_key_file := test.key
+export services_home := /opt/services
+
+.PHONY: authorized_keys
+
+service-user: $(services_home)/services.txt $(services_home)/.ssh/authorized_keys
+ @echo 'also make sure that the user is created: make create-service-user'
+
+create-service-user:
+ mkdir -p $(services_home)
+ rmdir $(services_home)
+ useradd -m -r -l -f -1 -d $(services_home) services
+
+$(services_home)/.ssh:
+ mkdir $@
+ chown services:services $@
+
+$(services_home)/.ssh/authorized_keys: $(services_home)/.ssh $(authorized_keys_file)
+ cp $(authorized_keys_file) $(services_home)/.ssh/authorized_keys
+ @echo "restricting authorized_keys..."
+ @sed -i 's#^#command="/bin/cat $(services_home)/services.txt",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty #' $(services_home)/.ssh/authorized_keys
+
+$(services_home)/services.txt:
+ @echo 'make sure to configure the services correctly in $(services_home)/services.txt'
+ cp $(services_file) $(services_home)/services.txt
+
+
+test-client:
+ ssh localhost -p 1337 2>/dev/null
+
+test-server:
+ python test.py
+
+$(host_key_file):
+ ssh-keygen -t rsa -P '' -f $@
diff --git a/services/authorized_keys b/services/authorized_keys
new file mode 100644
index 00000000..2eae1f4d
--- /dev/null
+++ b/services/authorized_keys
@@ -0,0 +1,4 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7YrLdnXDRU2XEdZDu1BmgiT0Vaxplf3bfvSm+5o3g4AcR2yCv7h2D633c9uA0gq52EJ3V5m8B1ZcxqA0zqDptKwx+ZTMUGDls7StH5xpJyk9j5gf8DzyDLQPQG2IYszCH+8esKjo3BOFxfey8NaX+k6gvQsG3lyV0PjLvvIy4gDuMn6dPZfVAlwNYFOUNgwpku3W3A0d+UFyVjt3/sgZxM+8C3y6QE1gwT5/NfBbHM5vaEqjHcVq1ui+7a4iOXFGKkZDcd7EX6cQZSbCzZL7sZ0OmB1WpAsDCvIXfzX1YfNA0sso7ldSF6ZUGNgwEk1LootnQlCK/dfbM+i62SZ+1 tv@iiso
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCv9TTt4FkzT3jlQ0VS2tX/GpQO9Ef0wIQ+g96foe4qSniBwR667T1gIhURrod/p7N9oQcWRrNohjgmSBZRYA0kW6ZyqYJkLvRv54nXv6j/8Xq2nG/KVfDqL0kp8if+JGeFlQElpWJiAbGifYkopFy69QiLYU2ndR7aPbx+5qm/dcwPJ7K+n6dyePynCZadtcabm3PuBFUxGLdT9ImDXMOPfXxPMlN/3eb78byuEuHnhCIvIGLMBGx+8QTXvu7kHpZObvkbsF1xjVs9fDpwVLjh7GWdwf3BZ/agFlI24ffyqCPFnuaxUVyfUZeqf4twRsIZkTTB47lHDhYiVkyGe8gd root@pigstarter.de
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCl3RTOHd5DLiVeUbUr/GSiKoRWknXQnbkIf+uNiFO+XxiqZVojPlumQUVhasY8UzDzj9tSDruUKXpjut50FhIO5UFAgsBeMJyoZbgY/+R+QKU00Q19+IiUtxeFol/9dCO+F4o937MC0OpAC10LbOXN/9SYIXueYk3pJxIycXwUqhYmyEqtDdVh9Rx32LBVqlBoXRHpNGPLiswV2qNe0b5p919IGcslzf1XoUzfE3a3yjk/XbWh/59xnl4V7Oe7+iQheFxOT6rFA30WYwEygs5As//ZYtxvnn0gA02gOnXJsNjOW9irlxOUeP7IOU6Ye3WRKFRR0+7PS+w8IJLag2xb makefu@pornocauster
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7df1RfMGNHPJe0iF6rD9DBs/4VujN6nNr7RbRCFk7HF/JzLXSn9Vcwk+3JefP4/d/bUo0h03rhQaRohDhBScrJidj2YacF6gmZOuTf3AMWprdz9D/1dDkN/ytwzGhADhqbHEWeomIllsa8Up4PvEeDcIHJGzYvuc0BbGqRk0XgxwqIrLAhdpTfEKaTbt7IzmUqEofxThTZ/4k020PKn2WDBWKQYGZJ9Ba2WzlKUXWx842ncW29oxC2faRz4M3eMPy0JMpBLkK9U3dccE75dgT/89/4ofVjM7+J3FOP3dgXzrtk+A5aN5a/veJUViQ9xdGxXvoa++iCr5q/BVRv0Bb sammy@muhbaasu.de
diff --git a/services/bin/services b/services/bin/services
new file mode 100755
index 00000000..c142a363
--- /dev/null
+++ b/services/bin/services
@@ -0,0 +1,24 @@
+#! /bin/sh
+# usage: services [user@]hostname[:port]
+# environment:
+# services_identity_file path to ssh(1) identity_file
+set -euf
+
+user=services
+hostname=${1-localhost}
+port=1337
+
+if test -n "${services_identity_file-}"; then
+ options="${options+$options }-i $services_identity_file"
+fi
+
+if echo $hostname | grep -q @; then
+ user=`echo $hostname | cut -d@ -f1`
+ hostname=`echo $hostname | cut -d@ -f2`
+fi
+if echo $hostname | grep -q :; then
+ port=`echo $hostname | cut -d: -f2`
+ hostname=`echo $hostname | cut -d: -f1`
+fi
+
+ssh $options $user@$hostname -p $port
diff --git a/services/checkers.py b/services/checkers.py
new file mode 100644
index 00000000..dbfe1323
--- /dev/null
+++ b/services/checkers.py
@@ -0,0 +1,25 @@
+
+import base64, binascii
+from twisted.python.filepath import FilePath
+from twisted.conch.checkers import SSHPublicKeyDatabase
+
+
+class PublicKeyChecker(SSHPublicKeyDatabase):
+
+ def __init__(self, filename):
+ self.filepath = FilePath(filename)
+
+ def getAuthorizedKeysFiles(self, credentials):
+ return [self.filepath]
+
+ def checkKey(self, credentials):
+ for line in self.filepath.open():
+ parts = line.split()
+ if len(parts) < 2:
+ continue
+ try:
+ if base64.decodestring(parts[1]) == credentials.blob:
+ return True
+ except binascii.Error:
+ continue
+ return False
diff --git a/services/services.txt b/services/services.txt
new file mode 100644
index 00000000..dc88cbac
--- /dev/null
+++ b/services/services.txt
@@ -0,0 +1,7 @@
+owner:
+type:
+mail:
+expires:
+location:
+services://{{hostname}}:22/
+tinc://{{hostname}}/
diff --git a/services/test.py b/services/test.py
new file mode 100644
index 00000000..06340a54
--- /dev/null
+++ b/services/test.py
@@ -0,0 +1,108 @@
+#! /usr/bin/env python
+
+from os import environ as env
+
+authorized_keys_file = env.get('authorized_keys_file', '/dev/null')
+services_file = env.get('services_file', '/dev/null')
+host_key_file = env.get('host_key_file', '/dev/null')
+host_key_pub_file = host_key_file + '.pub'
+
+
+from checkers import PublicKeyChecker
+from twisted.conch.avatar import ConchUser
+from twisted.conch.ssh.connection import SSHConnection
+from twisted.conch.ssh.factory import SSHFactory
+from twisted.conch.ssh.keys import Key
+from twisted.conch.ssh.session import SSHSession, ISession, wrapProtocol
+from twisted.conch.ssh.userauth import SSHUserAuthServer
+from twisted.cred.error import UnauthorizedLogin
+from twisted.cred.portal import IRealm, Portal
+from twisted.internet.protocol import Protocol
+from twisted.internet.reactor import listenTCP, run
+from twisted.python.components import registerAdapter
+from zope.interface import implements
+
+from twisted.python.log import startLogging
+from sys import stderr
+startLogging(stderr)
+
+
+class MyRealm:
+ implements(IRealm)
+
+ def requestAvatar(self, avatarId, mind, *interfaces):
+ return interfaces[0], MyUser(), lambda: None
+
+
+class MyUser(ConchUser):
+ def __init__(self):
+ ConchUser.__init__(self)
+ self.channelLookup.update({ 'session': SSHSession })
+
+
+class MySession:
+
+ def __init__(self, avatar):
+ pass
+
+ def getPty(self, term, windowSize, attrs):
+ pass
+
+ def execCommand(self, proto, cmd):
+ raise Exception("no executing commands")
+
+ def openShell(self, trans):
+ ep = MyProtocol()
+ ep.makeConnection(trans)
+ trans.makeConnection(wrapProtocol(ep))
+
+ def eofReceived(self):
+ pass
+
+ def closed(self):
+ pass
+
+
+registerAdapter(MySession, MyUser, ISession)
+
+
+def slurpTextfile(filename):
+ file = open(filename, 'r')
+ try:
+ return file.read()
+ finally:
+ file.close()
+
+class MyProtocol(Protocol):
+ def connectionMade(self):
+ data = slurpTextfile(services_file).replace('\n', '\r\n')
+ self.transport.write(data)
+ self.transport.loseConnection()
+
+ #def dataReceived(self, data):
+ # if data == '\r':
+ # data = '\r\n'
+ # elif data == '\x03': #^C
+ # self.transport.loseConnection()
+ # return
+ # self.transport.write(data)
+
+
+class MyFactory(SSHFactory):
+ privateKeys = {
+ 'ssh-rsa': Key.fromFile(filename=host_key_file)
+ }
+ publicKeys = {
+ 'ssh-rsa': Key.fromFile(filename=host_key_pub_file)
+ }
+ services = {
+ 'ssh-userauth': SSHUserAuthServer,
+ 'ssh-connection': SSHConnection
+ }
+
+if __name__ == '__main__':
+ portal = Portal(MyRealm())
+ portal.registerChecker(PublicKeyChecker(authorized_keys_file))
+ MyFactory.portal = portal
+ listenTCP(1337, MyFactory())
+ run()