From 76691f813a844e8c18d8de5fd2cc2d0117a9602e Mon Sep 17 00:00:00 2001 From: "Robin H. Johnson" Date: Sat, 22 Dec 2007 22:52:44 -0800 Subject: Move the SSH username extraction to the ssh class, and the tests over as well. --- gitosis/init.py | 16 +------- gitosis/ssh.py | 14 +++++++ gitosis/test/test_init.py | 82 ------------------------------------- gitosis/test/test_ssh.py | 101 ++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 103 insertions(+), 110 deletions(-) diff --git a/gitosis/init.py b/gitosis/init.py index 94be4e1..f1f8121 100644 --- a/gitosis/init.py +++ b/gitosis/init.py @@ -27,20 +27,6 @@ def read_ssh_pubkey(fp=None): #pragma: no cover line = fp.readline() return line -class InsecureSSHKeyUsername(Exception): - """Username contains not allowed characters""" - - def __str__(self): - return '%s: %s' % (self.__doc__, ': '.join(self.args)) - -def ssh_extract_user(pubkey): - """Find the username for a given SSH public key line.""" - _, user = pubkey.rsplit(None, 1) - if ssh.isSafeUsername(user): - return user - else: - raise InsecureSSHKeyUsername(repr(user)) - def initial_commit(git_dir, cfg, pubkey, user): """Import the initial files into the gitosis-admin repository.""" repository.fast_import( @@ -126,7 +112,7 @@ class Main(app.App): log.info('Reading SSH public key...') pubkey = read_ssh_pubkey() - user = ssh_extract_user(pubkey) + user = ssh.extract_user(pubkey) if user is None: log.error('Cannot parse user from SSH public key.') sys.exit(1) diff --git a/gitosis/ssh.py b/gitosis/ssh.py index f552255..10784fa 100644 --- a/gitosis/ssh.py +++ b/gitosis/ssh.py @@ -17,6 +17,20 @@ def isSafeUsername(user): match = _ACCEPTABLE_USER_RE.match(user) return (match is not None) +class InsecureSSHKeyUsername(Exception): + """Username contains not allowed characters""" + + def __str__(self): + return '%s: %s' % (self.__doc__, ': '.join(self.args)) + +def extract_user(pubkey): + """Find the username for a given SSH public key line.""" + _, user = pubkey.rsplit(None, 1) + if isSafeUsername(user): + return user + else: + raise InsecureSSHKeyUsername(repr(user)) + def readKeys(keydir): """ Read SSH public keys from ``keydir/*.pub`` diff --git a/gitosis/test/test_init.py b/gitosis/test/test_init.py index fb6b286..acfe8ff 100644 --- a/gitosis/test/test_init.py +++ b/gitosis/test/test_init.py @@ -9,88 +9,6 @@ from gitosis import repository from gitosis.test import util -def test_ssh_extract_user_simple(): - got = init.ssh_extract_user( - 'ssh-somealgo ' - +'0123456789ABCDEFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= fakeuser@fakehost') - eq(got, 'fakeuser@fakehost') - -def test_ssh_extract_user_domain(): - got = init.ssh_extract_user( - 'ssh-somealgo ' - +'0123456789ABCDEFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= fakeuser@fakehost.example.com') - eq(got, 'fakeuser@fakehost.example.com') - -def test_ssh_extract_user_domain_dashes(): - got = init.ssh_extract_user( - 'ssh-somealgo ' - +'0123456789ABCDEFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= fakeuser@ridiculously-long.example.com') - eq(got, 'fakeuser@ridiculously-long.example.com') - -def test_ssh_extract_user_underscore(): - got = init.ssh_extract_user( - 'ssh-somealgo ' - +'0123456789ABCDEFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= fake_user@example.com') - eq(got, 'fake_user@example.com') - -def test_ssh_extract_user_dot(): - got = init.ssh_extract_user( - 'ssh-somealgo ' - +'0123456789ABCDEFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= fake.u.ser@example.com') - eq(got, 'fake.u.ser@example.com') - -def test_ssh_extract_user_dash(): - got = init.ssh_extract_user( - 'ssh-somealgo ' - +'0123456789ABCDEFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= fake.u-ser@example.com') - eq(got, 'fake.u-ser@example.com') - -def test_ssh_extract_user_no_at(): - got = init.ssh_extract_user( - 'ssh-somealgo ' - +'0123456789ABCDEFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= fakeuser') - eq(got, 'fakeuser') - -def test_ssh_extract_user_caps(): - got = init.ssh_extract_user( - 'ssh-somealgo ' - +'0123456789ABCDEFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= Fake.User@Domain.Example.Com') - eq(got, 'Fake.User@Domain.Example.Com') - -def test_ssh_extract_user_bad(): - e = assert_raises( - init.InsecureSSHKeyUsername, - init.ssh_extract_user, - 'ssh-somealgo AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' - +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= ER3%#@e%') - eq(str(e), "Username contains not allowed characters: 'ER3%#@e%'") - def test_init_admin_repository(): tmp = maketemp() admin_repository = os.path.join(tmp, 'admin.git') diff --git a/gitosis/test/test_ssh.py b/gitosis/test/test_ssh.py index fc6ecbc..d9ec2bd 100644 --- a/gitosis/test/test_ssh.py +++ b/gitosis/test/test_ssh.py @@ -1,4 +1,4 @@ -from nose.tools import eq_ as eq, assert_raises +from nose.tools import eq_ as eq, assert_raises, raises import os from cStringIO import StringIO @@ -13,15 +13,13 @@ KEY_1 = _key(""" ssh-rsa +v5XLsUrLsHOKy7Stob1lHZM17YCCNXplcKfbpIztS2PujyixOaBev1ku6H6ny gUXfuYVzY+PmfTLviSwD3UETxEkR/jlBURACDQARJdUxpgt9XG2Lbs8bhOjonAPapxrH0o 9O8R0Y6Pm1Vh+H2U0B4UBhPgEframpeJYedijBxBV5aq3yUvHkXpcjM/P0gsKqr036k= j -unk@gunk -""") +unk@gunk""") KEY_2 = _key(""" ssh-rsa 4BX2TxZoD3Og2zNjHwaMhVEa5/NLnPcw+Z02TDR0IGJrrqXk7YlfR3oz+Wb/Eb Ctli20SoWY0Ur8kBEF/xR4hRslZ2U8t0PAJhr8cq5mifhok/gAdckmSzjD67QJ68uZbga8 ZwIAo7y/BU7cD3Y9UdVZykG34NiijHZLlCBo/TnobXjFIPXvFbfgQ3y8g+akwocFVcQ= f -roop@snoop -""") +roop@snoop""") class ReadKeys_Test(object): def test_empty(self): @@ -191,11 +189,88 @@ baz path=path, keydir=keydir) got = readFile(path) - eq(got, '''\ -# foo -bar -baz -### autogenerated by gitosis, DO NOT EDIT -command="gitosis-serve jdoe",no-port-forwarding,\ -no-X11-forwarding,no-agent-forwarding,no-pty %(key_1)s -''' % dict(key_1=KEY_1)) + eq(got, '''# foo\nbar\nbaz\n### autogenerated by gitosis, DO NOT EDIT\ncommand="gitosis-serve jdoe",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty %(key_1)s\n''' % dict(key_1=KEY_1)) + +def test_ssh_extract_user_simple(): + got = ssh.extract_user( + 'ssh-somealgo ' + +'0123456789ABCDEFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= fakeuser@fakehost') + eq(got, 'fakeuser@fakehost') + +def test_ssh_extract_user_domain(): + got = ssh.extract_user( + 'ssh-somealgo ' + +'0123456789ABCDEFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= fakeuser@fakehost.example.com') + eq(got, 'fakeuser@fakehost.example.com') + +def test_ssh_extract_user_domain_dashes(): + got = ssh.extract_user( + 'ssh-somealgo ' + +'0123456789ABCDEFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= fakeuser@ridiculously-long.example.com') + eq(got, 'fakeuser@ridiculously-long.example.com') + +def test_ssh_extract_user_underscore(): + got = ssh.extract_user( + 'ssh-somealgo ' + +'0123456789ABCDEFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= fake_user@example.com') + eq(got, 'fake_user@example.com') + +def test_ssh_extract_user_dot(): + got = ssh.extract_user( + 'ssh-somealgo ' + +'0123456789ABCDEFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= fake.u.ser@example.com') + eq(got, 'fake.u.ser@example.com') + +def test_ssh_extract_user_dash(): + got = ssh.extract_user( + 'ssh-somealgo ' + +'0123456789ABCDEFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= fake.u-ser@example.com') + eq(got, 'fake.u-ser@example.com') + +def test_ssh_extract_user_no_at(): + got = ssh.extract_user( + 'ssh-somealgo ' + +'0123456789ABCDEFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= fakeuser') + eq(got, 'fakeuser') + +def test_ssh_extract_user_caps(): + got = ssh.extract_user( + 'ssh-somealgo ' + +'0123456789ABCDEFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= Fake.User@Domain.Example.Com') + eq(got, 'Fake.User@Domain.Example.Com') + +@raises(ssh.InsecureSSHKeyUsername) +def test_ssh_extract_user_bad(): + try: + ssh.extract_user( + 'ssh-somealgo AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' + +'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= ER3%#@e%') + except ssh.InsecureSSHKeyUsername, e: + eq(str(e), "Username contains not allowed characters: 'ER3%#@e%'") + raise e -- cgit v1.2.3