aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gitosis/init.py6
-rw-r--r--gitosis/ssh.py13
-rw-r--r--gitosis/test/test_ssh.py10
3 files changed, 25 insertions, 4 deletions
diff --git a/gitosis/init.py b/gitosis/init.py
index c7443b1..87ad9a7 100644
--- a/gitosis/init.py
+++ b/gitosis/init.py
@@ -5,7 +5,6 @@ Initialize a user account for use with gitosis.
import errno
import logging
import os
-import re
import sys
from pkg_resources import resource_filename
@@ -14,6 +13,7 @@ from ConfigParser import RawConfigParser
from gitosis import repository
from gitosis import run_hook
+from gitosis import ssh
from gitosis import util
from gitosis import app
@@ -25,8 +25,6 @@ def read_ssh_pubkey(fp=None):
line = fp.readline()
return line
-_ACCEPTABLE_USER_RE = re.compile(r'^[a-z][a-z0-9]*(@[a-z][a-z0-9.-]*)?$')
-
class InsecureSSHKeyUsername(Exception):
"""Username contains not allowed characters"""
@@ -35,7 +33,7 @@ class InsecureSSHKeyUsername(Exception):
def ssh_extract_user(pubkey):
_, user = pubkey.rsplit(None, 1)
- if _ACCEPTABLE_USER_RE.match(user):
+ if ssh.isSafeUsername(user):
return user
else:
raise InsecureSSHKeyUsername(repr(user))
diff --git a/gitosis/ssh.py b/gitosis/ssh.py
index 3eb5c37..9e8d258 100644
--- a/gitosis/ssh.py
+++ b/gitosis/ssh.py
@@ -1,4 +1,13 @@
import os, errno, re
+import logging
+
+log = logging.getLogger('gitosis.ssh')
+
+_ACCEPTABLE_USER_RE = re.compile(r'^[a-z][a-z0-9]*(@[a-z][a-z0-9.-]*)?$')
+
+def isSafeUsername(user):
+ match = _ACCEPTABLE_USER_RE.match(user)
+ return (match is not None)
def readKeys(keydir):
"""
@@ -11,6 +20,10 @@ def readKeys(keydir):
if ext != '.pub':
continue
+ if not isSafeUsername(basename):
+ log.warn('Unsafe SSH username in keyfile: %r', filename)
+ continue
+
path = os.path.join(keydir, filename)
f = file(path)
for line in f:
diff --git a/gitosis/test/test_ssh.py b/gitosis/test/test_ssh.py
index 16650c6..fc6ecbc 100644
--- a/gitosis/test/test_ssh.py
+++ b/gitosis/test/test_ssh.py
@@ -75,6 +75,16 @@ class ReadKeys_Test(object):
def test_multiple_lines(self):
tmp = maketemp()
+ keydir = os.path.join(tmp, 'keys')
+ mkdir(keydir)
+ writeFile(os.path.join(keydir, 'jd"oe.pub'), KEY_1+'\n')
+
+ gen = ssh.readKeys(keydir=keydir)
+ got = frozenset(gen)
+ eq(got, frozenset([]))
+
+ def test_bad_filename(self):
+ tmp = maketemp()
keydir = os.path.join(tmp, 'two')
mkdir(keydir)
writeFile(os.path.join(keydir, 'jdoe.pub'), KEY_1+'\n'+KEY_2+'\n')