Fixes, plus base64 what you don't trust
authorPaul Crowley <paul@lshift.net>
Mon, 12 Oct 2009 16:25:02 +0100
changeset 107 84e9e33d866b
parent 106 0519745e7a57
child 108 00b48d7bdfa0
Fixes, plus base64 what you don't trust
src/hg-ssh
src/mercurialserver/refreshauth.py
--- a/src/hg-ssh	Mon Oct 12 16:04:07 2009 +0100
+++ b/src/hg-ssh	Mon Oct 12 16:25:02 2009 +0100
@@ -34,13 +34,14 @@
 from mercurial import dispatch
 
 import sys, os, os.path
+import base64
 from mercurialserver import ruleset, paths
 
 def fail(message):
     sys.stderr.write("mercurial-server: %s\n" % message)
     sys.exit(-1)
 
-def checkpath(path)
+def checkpath(path):
     path = os.path.dirname(path)
     if path == "":
         return
@@ -65,13 +66,16 @@
 #logfile = open("/tmp/hg-ssh.%d.txt" % os.getpid(), "w")
 #logfile.write("Started: %s\n" % sys.argv)
 
-if len(sys.argv) != 2:
+paths.setExePath()
+
+if len(sys.argv) == 3 and sys.argv[1] == "--base64":
+    ruleset.rules.set(user = base64.b64decode(sys.argv[2]))
+elif len(sys.argv) == 2:
+    ruleset.rules.set(user = sys.argv[1])
+else:
     fail("hg-ssh wrongly called, is authorized_keys corrupt? (%s)" 
         % sys.argv)
 
-paths.setExePath()
-ruleset.rules.set(user = sys.argv[1])
-
 # Use a different hgrc for remote pulls - this way you can set
 # up access.py for everything at once without affecting local operations
 
@@ -89,7 +93,7 @@
 try:
     if cmd.startswith('hg -R ') and cmd.endswith(' serve --stdio'):
         repo = getrepo("read", cmd[6:-14])
-        if not os.path.isdir(repo + "/.hg")
+        if not os.path.isdir(repo + "/.hg"):
             fail("no such repository %s" % repo)
         dispatch.dispatch(['-R', repo, 'serve', '--stdio'])
     elif cmd.startswith('hg init '):
--- a/src/mercurialserver/refreshauth.py	Mon Oct 12 16:04:07 2009 +0100
+++ b/src/mercurialserver/refreshauth.py	Mon Oct 12 16:25:02 2009 +0100
@@ -6,13 +6,14 @@
 # WARNING
 
 import re
+import base64
 import os
 import os.path
 import pwd
 import subprocess
 from mercurialserver import paths
 
-goodkey = re.compile("[A-Za-z0-9._-]+$")
+goodkey = re.compile("[/A-Za-z0-9._-]+$")
 
 def refreshAuth(pw_dir):
     akeyfile = pw_dir + "/.ssh/authorized_keys"
@@ -40,11 +41,9 @@
                     raise Exception("Inconsistent behaviour in os.walk, bailing")
                 #print "Processing file", ffn
                 keyname = ffn[len(kr):]
-                # FIXME: still too strict
-                if not goodkey.match(keyname)
-                    # ignore any path that contains dodgy characters
-                    print "Ignoring key that contains banned character:", ffn
-                    continue
+                if not goodkey.match(keyname):
+                    # Encode it for safe quoting
+                    keyname = "--base64 " + base64.b64encode(keyname)
                 p = subprocess.Popen(("ssh-keygen", "-i", "-f", ffn), 
                     stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                 newkey = p.communicate()[0]