[X2Go-Commits] [python-x2go] 02/02: Handle injection of PKey (Paramiko SSH key) objects for authentication from the broker session profiles backend.

git-admin at x2go.org git-admin at x2go.org
Thu Mar 20 08:36:33 CET 2014


This is an automated email from the git hooks/post-receive script.

x2go pushed a commit to branch master
in repository python-x2go.

commit ce97f345fb0e8b3d8cd2c2261242961a61b479c1
Author: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
Date:   Thu Mar 20 08:36:28 2014 +0100

    Handle injection of PKey (Paramiko SSH key) objects for authentication from the broker session profiles backend.
---
 debian/changelog                     |    2 ++
 x2go/backends/profiles/base.py       |   20 ++++++++++++++++++
 x2go/backends/profiles/httpbroker.py |   13 ++++++++++++
 x2go/client.py                       |    8 ++++++++
 x2go/registry.py                     |    7 ++++++-
 x2go/session.py                      |    2 +-
 x2go/utils.py                        |   37 ++++++++++++++++++++++++++++++++++
 7 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index d2bb58a..1907a4b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -13,6 +13,8 @@ python-x2go (0.5.0.0-0x2go1) UNRELEASED; urgency=low
     - Make session profile backends more unicode robust.
     - X2GoSessionProfile.get_server_hostname must return unicode objects.
     - Speed-optimize session profile ID <-> name mapping.
+    - Handle injection of PKey (Paramiko SSH key) objects for authentication
+      from the broker session profiles backend.
   * debian/control:
     + Add dependencies: python-requests, python-simplejson.
   * python-x2go.spec:
diff --git a/x2go/backends/profiles/base.py b/x2go/backends/profiles/base.py
index 3aff841..7630a8a 100644
--- a/x2go/backends/profiles/base.py
+++ b/x2go/backends/profiles/base.py
@@ -722,3 +722,23 @@ class X2GoSessionProfiles():
         """
         return 22
 
+    def get_pkey_object(self, profile_id):
+        """\
+        If available, return a PKey (Paramiko/SSH private key) object.
+
+        @param profile_id: the profile's unique ID
+        @type profile_id: C{str}
+
+        @return: a Paramiko/SSH PKey object
+        @rtype: C{obj}
+
+        """
+        return self._get_pkey_object(profile_id)
+
+    def _get_pkey_object(self, profile_id):
+        """\
+        Inherit from this class and provide a way for actually
+        providing such a PKey object.
+
+        """
+        return None
diff --git a/x2go/backends/profiles/httpbroker.py b/x2go/backends/profiles/httpbroker.py
index 569e851..30e9b54 100644
--- a/x2go/backends/profiles/httpbroker.py
+++ b/x2go/backends/profiles/httpbroker.py
@@ -30,6 +30,7 @@ import re
 import requests
 import copy
 import types
+import time
 try: import simplejson as json
 except ImportError: import json
 
@@ -38,6 +39,7 @@ from x2go.defaults import X2GO_SESSIONPROFILE_DEFAULTS as _X2GO_SESSIONPROFILE_D
 from x2go.defaults import CURRENT_LOCAL_USER as _CURRENT_LOCAL_USER
 import x2go.backends.profiles.base as base
 import x2go.log as log
+from x2go.utils import genkeypair
 
 from x2go.x2go_exceptions import X2GoNotImplementedYetException
 
@@ -110,6 +112,9 @@ class X2GoSessionProfiles(base.X2GoSessionProfiles):
 
         self._broker_type = "http"
 
+        # for broker based autologin, we have to be able to provide public/private key pair
+        self.broker_my_pubkey, self.broker_my_privkey = genkeypair(local_username=_CURRENT_LOCAL_USER, client_address='127.0.0.1')
+
     def get_broker_noauth(self):
         return self.broker_noauth
 
@@ -190,6 +195,7 @@ class X2GoSessionProfiles(base.X2GoSessionProfiles):
                     'profile-id': profile_id,
                     'user': self.broker_username,
                     'password': self.broker_password,
+                    'pubkey': self.broker_my_pubkey,
                 }
                 r = requests.post(self.broker_url, data=request_data)
                 if r.status_code == 200 and r.headers['content-type'].startswith("text/json"):
@@ -273,3 +279,10 @@ class X2GoSessionProfiles(base.X2GoSessionProfiles):
     def _get_server_port(self, profile_id):
         selected_session = self.broker_selectsession(profile_id)
         return int(selected_session['port'])
+
+    def _get_pkey_object(self, profile_id):
+        selected_session = self.broker_selectsession(profile_id)
+        if selected_session.has_key('authentication_pubkey') and selected_session['authentication_pubkey'] == 'ACCEPTED':
+            time.sleep(2)
+            return self.broker_my_privkey
+        return None
diff --git a/x2go/client.py b/x2go/client.py
index b1fa978..95fb444 100644
--- a/x2go/client.py
+++ b/x2go/client.py
@@ -924,6 +924,14 @@ class X2GoClient(object):
 
             server = self.session_profiles.get_server_hostname(_profile_id)
             _params['port'] = self.session_profiles.get_server_port(_profile_id)
+            _pkey = self.session_profiles.get_pkey_object(_profile_id)
+            if _pkey is not None:
+                self.logger('received PKey object for authentication, ignoring all other auth mechanisms', log.loglevel_NOTICE, tag=self._logger_tag)
+                _params['pkey'] = _pkey
+                _params['allow_agent'] = False
+                _params['look_for_keys'] = False
+                _params['key_filename'] = []
+
             del _params['server']
             _params['client_instance'] = self
 
diff --git a/x2go/registry.py b/x2go/registry.py
index ffe0708..1625dbd 100644
--- a/x2go/registry.py
+++ b/x2go/registry.py
@@ -533,6 +533,12 @@ class X2GoSessionRegistry(object):
             if _k in kwargs.keys():
                 _params[_k] = kwargs[_k]
 
+        # allow injection of PKey objects (Paramiko's private SSH keys)
+        if kwargs.has_key('pkey'):
+            _params['pkey'] = kwargs['pkey']
+        if kwargs.has_key('sshproxy_pkey'):
+            _params['sshproxy_pkey'] = kwargs['sshproxy_pkey']
+
         # when starting a new session, we will try to use unused registered virgin sessions
         # depending on your application layout, there should either be one or no such virgin session at all
         _virgin_sessions = [ s for s in self.virgin_sessions_of_profile_name(profile_name, return_objects=True) if not s.activated ]
@@ -560,7 +566,6 @@ class X2GoSessionRegistry(object):
         try: del _params['profile_id'] 
         except: pass
 
-        print _params['port']
         s = session.X2GoSession(server=server, control_session=control_session,
                                 profile_id=profile_id, profile_name=profile_name,
                                 session_name=session_name,
diff --git a/x2go/session.py b/x2go/session.py
index ec2cdc9..c7943ae 100644
--- a/x2go/session.py
+++ b/x2go/session.py
@@ -325,7 +325,7 @@ class X2GoSession(object):
 
         if self.logger.get_loglevel() & log.loglevel_DEBUG:
             self.logger('X2Go control session parameters for profile %s:' % profile_name, loglevel=log.loglevel_DEBUG)
-            for p in self.control_params:
+            for p in [ _p for _p in self.control_params if not _p.endswith('pkey') ]:
                 self.logger('    %s: %s' % (p, self.control_params[p]), log.loglevel_DEBUG)
             self.logger('X2Go terminal session parameters for profile %s:' % profile_name, loglevel=log.loglevel_DEBUG)
             for p in self.terminal_params:
diff --git a/x2go/utils.py b/x2go/utils.py
index 7f182ed..78ed642 100644
--- a/x2go/utils.py
+++ b/x2go/utils.py
@@ -34,6 +34,7 @@ import gevent
 import string
 import subprocess
 import distutils.version
+import paramiko
 
 # Python X2Go modules
 from defaults import X2GOCLIENT_OS as _X2GOCLIENT_OS
@@ -843,3 +844,39 @@ def _get_backend_class(backend, class_name):
     else:
         raise x2go_exceptions.X2GoBackendException('unknown backend name %s for class %s' % (backend, class_name))
     return _this_class
+
+def genkeypair(local_username, client_address, key_type='RSA'):
+    """\
+    Generate an SSH pub/priv key pair without writing the private key to file.
+
+    @param local_username: the key is for this user
+    @type local_username: C{unicode}
+    @param client_address: the key is only valid for this client
+    @type client_address: C{unicode}
+    @param key_type: either of: RSA, DSA
+    @type key_type: C{unicode}
+
+    """
+    key = None
+    pubkey = None
+    privkey = None
+
+    # generate key pair
+    if unicode(key_type) == u'RSA':
+        key = paramiko.RSAKey.generate(2048)
+    elif unicode(key_type) == u'DSA':
+        key = paramiko.DSSKey.generate(1024)
+
+    if key:
+
+        # assemble the public key
+        if key_type == "RSA":
+            pubkey_type = 'ssh-rsa'
+        elif key_type == "DSA":
+            pubkey_type = 'ssh-dss'
+
+        # FIXME: the from option does not work properly by some reason. Fix it later
+        #pubkey = "from={client_address},no-X11-forwarding,no-pty,no-user-rc {pubkey_type} {pubkey} {local_username}@{client_address}".format(pubkey=key.get_base64(), pubkey_type=pubkey_type, local_username=local_username, client_address=client_address)
+        pubkey = "no-X11-forwarding,no-pty,no-user-rc {pubkey_type} {pubkey} {local_username}@{client_address}".format(pubkey=key.get_base64(), pubkey_type=pubkey_type, local_username=local_username, client_address=client_address)
+
+    return (pubkey, key)

--
Alioth's /srv/git/_hooks_/post-receive-email on /srv/git/code.x2go.org/python-x2go.git



More information about the x2go-commits mailing list