mirror of
https://gitlab.archlinux.org/archlinux/aurweb.git
synced 2025-02-03 10:43:03 +01:00
fix: support multiple SSHPubKey records per user
There was one blazing issue with the previous implementation regardless of the multiple records: we were generating fingerprints by storing the key into a file and reading it with ssh-keygen. This is absolutely terrible and was not meant to be left around (it was forgotten, my bad). Took this opportunity to clean up a few things: - simplify pubkey validation - centralize things a bit better Signed-off-by: Kevin Morris <kevr@0cost.org>
This commit is contained in:
parent
660d57340a
commit
4c14a10b91
11 changed files with 162 additions and 108 deletions
|
@ -577,10 +577,13 @@ def test_post_register_error_ssh_pubkey_taken(client: TestClient, user: User):
|
|||
# Read in the public key, then delete the temp dir we made.
|
||||
pk = open(f"{tmpdir}/test.ssh.pub").read().rstrip()
|
||||
|
||||
prefix, key, loc = pk.split()
|
||||
norm_pk = prefix + " " + key
|
||||
|
||||
# Take the sha256 fingerprint of the ssh public key, create it.
|
||||
fp = get_fingerprint(pk)
|
||||
fp = get_fingerprint(norm_pk)
|
||||
with db.begin():
|
||||
create(SSHPubKey, UserID=user.ID, PubKey=pk, Fingerprint=fp)
|
||||
create(SSHPubKey, UserID=user.ID, PubKey=norm_pk, Fingerprint=fp)
|
||||
|
||||
with client as request:
|
||||
response = post_register(request, PK=pk)
|
||||
|
@ -1080,22 +1083,16 @@ def test_post_account_edit_missing_ssh_pubkey(client: TestClient, user: User):
|
|||
def test_post_account_edit_invalid_ssh_pubkey(client: TestClient, user: User):
|
||||
pubkey = "ssh-rsa fake key"
|
||||
|
||||
request = Request()
|
||||
sid = user.login(request, "testPassword")
|
||||
|
||||
post_data = {
|
||||
data = {
|
||||
"U": "test",
|
||||
"E": "test@example.org",
|
||||
"P": "newPassword",
|
||||
"C": "newPassword",
|
||||
"PK": pubkey,
|
||||
"passwd": "testPassword"
|
||||
}
|
||||
|
||||
cookies = {"AURSID": user.login(Request(), "testPassword")}
|
||||
with client as request:
|
||||
response = request.post("/account/test/edit", cookies={
|
||||
"AURSID": sid
|
||||
}, data=post_data, allow_redirects=False)
|
||||
response = request.post("/account/test/edit", data=data,
|
||||
cookies=cookies, allow_redirects=False)
|
||||
|
||||
assert response.status_code == int(HTTPStatus.BAD_REQUEST)
|
||||
|
||||
|
|
|
@ -53,4 +53,4 @@ def test_adduser_ssh_pk():
|
|||
"--ssh-pubkey", TEST_SSH_PUBKEY])
|
||||
test = db.query(User).filter(User.Username == "test").first()
|
||||
assert test is not None
|
||||
assert TEST_SSH_PUBKEY.startswith(test.ssh_pub_key.PubKey)
|
||||
assert TEST_SSH_PUBKEY.startswith(test.ssh_pub_keys.first().PubKey)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from subprocess import PIPE, Popen
|
||||
|
||||
import pytest
|
||||
|
||||
from aurweb import db
|
||||
|
@ -61,8 +63,12 @@ def test_pubkey_cs(user: User):
|
|||
|
||||
|
||||
def test_pubkey_fingerprint():
|
||||
assert get_fingerprint(TEST_SSH_PUBKEY) is not None
|
||||
proc = Popen(["ssh-keygen", "-l", "-f", "-"], stdin=PIPE, stdout=PIPE)
|
||||
out, _ = proc.communicate(TEST_SSH_PUBKEY.encode())
|
||||
expected = out.decode().split()[1].split(":", 1)[1]
|
||||
assert get_fingerprint(TEST_SSH_PUBKEY) == expected
|
||||
|
||||
|
||||
def test_pubkey_invalid_fingerprint():
|
||||
assert get_fingerprint("ssh-rsa fake and invalid") is None
|
||||
with pytest.raises(ValueError):
|
||||
get_fingerprint("invalid-prefix some-fake-content")
|
||||
|
|
|
@ -183,14 +183,14 @@ def test_user_has_credential(user: User):
|
|||
|
||||
|
||||
def test_user_ssh_pub_key(user: User):
|
||||
assert user.ssh_pub_key is None
|
||||
assert user.ssh_pub_keys.first() is None
|
||||
|
||||
with db.begin():
|
||||
ssh_pub_key = db.create(SSHPubKey, UserID=user.ID,
|
||||
Fingerprint="testFingerprint",
|
||||
PubKey="testPubKey")
|
||||
|
||||
assert user.ssh_pub_key == ssh_pub_key
|
||||
assert user.ssh_pub_keys.first() == ssh_pub_key
|
||||
|
||||
|
||||
def test_user_credential_types(user: User):
|
||||
|
|
|
@ -60,3 +60,53 @@ def test_valid_homepage():
|
|||
assert not util.valid_homepage("https://[google.com/broken-ipv6")
|
||||
|
||||
assert not util.valid_homepage("gopher://gopher.hprc.utoronto.ca/")
|
||||
|
||||
|
||||
def test_parse_ssh_key():
|
||||
# Test a valid key.
|
||||
pk = """ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyN\
|
||||
TYAAABBBEURnkiY6JoLyqDE8Li1XuAW+LHmkmLDMW/GL5wY7k4/A+Ta7bjA3MOKrF9j4EuUTvCuNX\
|
||||
ULxvpfSqheTFWZc+g="""
|
||||
prefix, key = util.parse_ssh_key(pk)
|
||||
e_prefix, e_key = pk.split()
|
||||
assert prefix == e_prefix
|
||||
assert key == e_key
|
||||
|
||||
# Test an invalid key with just one word in it.
|
||||
with pytest.raises(ValueError):
|
||||
util.parse_ssh_key("ssh-rsa")
|
||||
|
||||
# Test a valid key with extra words in it (after the PK).
|
||||
pk = pk + " blah blah"
|
||||
prefix, key = util.parse_ssh_key(pk)
|
||||
assert prefix == e_prefix
|
||||
assert key == e_key
|
||||
|
||||
# Test an invalid prefix.
|
||||
with pytest.raises(ValueError):
|
||||
util.parse_ssh_key("invalid-prefix fake-content")
|
||||
|
||||
|
||||
def test_parse_ssh_keys():
|
||||
pks = """ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyN\
|
||||
TYAAABBBEURnkiY6JoLyqDE8Li1XuAW+LHmkmLDMW/GL5wY7k4/A+Ta7bjA3MOKrF9j4EuUTvCuNX\
|
||||
ULxvpfSqheTFWZc+g=
|
||||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDmqEapFMh/ajPHnm1dBweYPeLOUjC0Ydp6uw7rB\
|
||||
S5KCggUVQR8WfIm+sRYTj2+smGsK6zHMBjFnbzvV11vnMqcnY+Sa4LhIAdwkbt/b8HlGaLj1hCWSh\
|
||||
a5b5/noeK7L+CECGHdvfJhpxBbhq38YEdFnCGbslk/4NriNcUp/DO81CXb1RzJ9GBFH8ivPW1mbe9\
|
||||
YbxDwGimZZslg0OZu9UzoAT6xEGyiZsqJkTMbRp1ZYIOv9jHCJxRuxxuN3fzxyT3xE69+vhq2/NJX\
|
||||
8aRsxGPL9G/XKcaYGS6y6LW4quIBCz/XsTZfx1GmkQeZPYHH8FeE+XC/+toXL/kamxdOQKFYEEpWK\
|
||||
vTNJCD6JtMClxbIXW9q74nNqG+2SD/VQNMUz/505TK1PbY/4uyFfq5HquHJXQVCBll03FRerNHH2N\
|
||||
schFne6BFHpa48PCoZNH45wLjFXwUyrGU1HrNqh6ZPdRfBTrTOkgs+BKBxGNeV45aYUPu/cFBSPcB\
|
||||
fRSo6OFcejKc="""
|
||||
keys = util.parse_ssh_keys(pks)
|
||||
assert len(keys) == 2
|
||||
|
||||
pfx1, key1, pfx2, key2 = pks.split()
|
||||
k1, k2 = keys
|
||||
|
||||
assert pfx1 == k1[0]
|
||||
assert key1 == k1[1]
|
||||
|
||||
assert pfx2 == k2[0]
|
||||
assert key2 == k2[1]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue