← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~pappacena/turnip:enable-protocol-v2-on-ssh into turnip:master

 

Thiago F. Pappacena has proposed merging ~pappacena/turnip:enable-protocol-v2-on-ssh into turnip:master with ~pappacena/turnip:enable-protocol-v2-on-http as a prerequisite.

Commit message:
Allowing git SSH client to set protocol version env variable

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~pappacena/turnip/+git/turnip/+merge/389505
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~pappacena/turnip:enable-protocol-v2-on-ssh into turnip:master.
diff --git a/requirements.txt b/requirements.txt
index 32291f9..aaf42a8 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -62,7 +62,12 @@ testscenarios==0.5.0
 testtools==2.4.0
 traceback2==1.4.0
 translationstring==1.3
-Twisted[conch]==20.3.0
+# XXX 2020-08-18 pappacena: This feature is already merged to Twisted trunk, so
+# we should be able to get rid of this backport soon.
+# Backport of SSH session env variables setter from
+# https://github.com/twisted/twisted/pull/1173 to Twisted version 20.3.0.
+# See https://code.launchpad.net/~pappacena/twisted/+git/twisted/+ref/pr-1173
+Twisted[conch]==20.3.0-pr1173
 unittest2==1.1.0
 vine==1.3.0
 venusian==2.1.0
diff --git a/turnip/pack/ssh.py b/turnip/pack/ssh.py
index 3526bb9..e6a73b3 100644
--- a/turnip/pack/ssh.py
+++ b/turnip/pack/ssh.py
@@ -16,7 +16,11 @@ from lazr.sshserver.auth import (
     )
 from lazr.sshserver.service import SSHService
 from lazr.sshserver.session import DoNothingSession
-from twisted.conch.interfaces import ISession
+import six
+from twisted.conch.interfaces import (
+    ISession,
+    ISessionSetEnv,
+    )
 from twisted.cred.portal import (
     IRealm,
     Portal,
@@ -127,6 +131,13 @@ class SmartSSHSession(DoNothingSession):
         super(SmartSSHSession, self).__init__(*args, **kwargs)
         self.pack_protocol = None
 
+    def setEnv(self, name, value):
+        """Set an environment variable for this SSH session.v"""
+        self.avatar.setEnv(name, value)
+
+    def getProtocolVersion(self):
+        return self.avatar.getProtocolVersion()
+
     @defer.inlineCallbacks
     def connectToBackend(self, factory, service, path, ssh_protocol):
         """Establish a pack connection to the backend.
@@ -138,6 +149,7 @@ class SmartSSHSession(DoNothingSession):
             b'turnip-authenticated-user': self.avatar.username.encode('utf-8'),
             b'turnip-authenticated-uid': str(self.avatar.user_id),
             b'turnip-request-id': str(uuid.uuid4()),
+            b'version': self.getProtocolVersion(),
             }
         d = defer.Deferred()
         client_factory = factory(service, path, params, ssh_protocol, d)
@@ -186,11 +198,22 @@ class SmartSSHAvatar(LaunchpadAvatar):
 
     def __init__(self, user_dict, service):
         LaunchpadAvatar.__init__(self, user_dict)
+        self.env = {}
         self.service = service
 
         # Disable SFTP.
         self.subsystemLookup = {}
 
+    def setEnv(self, name, value):
+        self.env[name] = value
+
+    def getProtocolVersion(self):
+        version = self.env.get('GIT_PROTOCOL', b'version=0')
+        try:
+            return six.ensure_binary(version.split(b'version=', 1)[1])
+        except IndexError:
+            return b'0'
+
 
 @implementer(IRealm)
 class SmartSSHRealm:
@@ -225,3 +248,4 @@ class SmartSSHService(SSHService):
 
 
 components.registerAdapter(SmartSSHSession, SmartSSHAvatar, ISession)
+components.registerAdapter(SmartSSHSession, SmartSSHAvatar, ISessionSetEnv)