Enforce safe usernames also when reading public key files from keydir.
Warning: if your keyfiles contain more than just a-z0-9, at sign, dots or dashes, you will likely end up cutting off your access to your gitosis repository with this upgrade.
This commit is contained in:
parent
a5a758a407
commit
cbea1785d0
|
@ -5,7 +5,6 @@ Initialize a user account for use with gitosis.
|
||||||
import errno
|
import errno
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import re
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from pkg_resources import resource_filename
|
from pkg_resources import resource_filename
|
||||||
|
@ -14,6 +13,7 @@ from ConfigParser import RawConfigParser
|
||||||
|
|
||||||
from gitosis import repository
|
from gitosis import repository
|
||||||
from gitosis import run_hook
|
from gitosis import run_hook
|
||||||
|
from gitosis import ssh
|
||||||
from gitosis import util
|
from gitosis import util
|
||||||
from gitosis import app
|
from gitosis import app
|
||||||
|
|
||||||
|
@ -25,8 +25,6 @@ def read_ssh_pubkey(fp=None):
|
||||||
line = fp.readline()
|
line = fp.readline()
|
||||||
return line
|
return line
|
||||||
|
|
||||||
_ACCEPTABLE_USER_RE = re.compile(r'^[a-z][a-z0-9]*(@[a-z][a-z0-9.-]*)?$')
|
|
||||||
|
|
||||||
class InsecureSSHKeyUsername(Exception):
|
class InsecureSSHKeyUsername(Exception):
|
||||||
"""Username contains not allowed characters"""
|
"""Username contains not allowed characters"""
|
||||||
|
|
||||||
|
@ -35,7 +33,7 @@ class InsecureSSHKeyUsername(Exception):
|
||||||
|
|
||||||
def ssh_extract_user(pubkey):
|
def ssh_extract_user(pubkey):
|
||||||
_, user = pubkey.rsplit(None, 1)
|
_, user = pubkey.rsplit(None, 1)
|
||||||
if _ACCEPTABLE_USER_RE.match(user):
|
if ssh.isSafeUsername(user):
|
||||||
return user
|
return user
|
||||||
else:
|
else:
|
||||||
raise InsecureSSHKeyUsername(repr(user))
|
raise InsecureSSHKeyUsername(repr(user))
|
||||||
|
|
|
@ -1,4 +1,13 @@
|
||||||
import os, errno, re
|
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):
|
def readKeys(keydir):
|
||||||
"""
|
"""
|
||||||
|
@ -11,6 +20,10 @@ def readKeys(keydir):
|
||||||
if ext != '.pub':
|
if ext != '.pub':
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if not isSafeUsername(basename):
|
||||||
|
log.warn('Unsafe SSH username in keyfile: %r', filename)
|
||||||
|
continue
|
||||||
|
|
||||||
path = os.path.join(keydir, filename)
|
path = os.path.join(keydir, filename)
|
||||||
f = file(path)
|
f = file(path)
|
||||||
for line in f:
|
for line in f:
|
||||||
|
|
|
@ -74,6 +74,16 @@ class ReadKeys_Test(object):
|
||||||
]))
|
]))
|
||||||
|
|
||||||
def test_multiple_lines(self):
|
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()
|
tmp = maketemp()
|
||||||
keydir = os.path.join(tmp, 'two')
|
keydir = os.path.join(tmp, 'two')
|
||||||
mkdir(keydir)
|
mkdir(keydir)
|
||||||
|
|
Loading…
Reference in a new issue