Switch to modern (circa 2014!) Conch API.

This commit is contained in:
Itamar Turner-Trauring 2021-01-08 13:32:11 -05:00
parent 3764e3b6b1
commit 7a15f7e11d
1 changed files with 8 additions and 29 deletions

View File

@ -6,6 +6,7 @@ from twisted.internet import defer
from twisted.cred import error, checkers, credentials from twisted.cred import error, checkers, credentials
from twisted.conch import error as conch_error from twisted.conch import error as conch_error
from twisted.conch.ssh import keys from twisted.conch.ssh import keys
from twisted.conch.checkers import SSHPublicKeyChecker, InMemorySSHKeyDB
from allmydata.util import base32 from allmydata.util import base32
from allmydata.util.fileutil import abspath_expanduser_unicode from allmydata.util.fileutil import abspath_expanduser_unicode
@ -29,7 +30,7 @@ class AccountFileChecker(object):
def __init__(self, client, accountfile): def __init__(self, client, accountfile):
self.client = client self.client = client
self.passwords = {} self.passwords = {}
self.pubkeys = {} pubkeys = {}
self.rootcaps = {} self.rootcaps = {}
with open(abspath_expanduser_unicode(accountfile), "r") as f: with open(abspath_expanduser_unicode(accountfile), "r") as f:
for line in f: for line in f:
@ -40,12 +41,14 @@ class AccountFileChecker(object):
if passwd.startswith("ssh-"): if passwd.startswith("ssh-"):
bits = rest.split() bits = rest.split()
keystring = " ".join([passwd] + bits[:-1]) keystring = " ".join([passwd] + bits[:-1])
key = keys.Key.fromString(keystring)
rootcap = bits[-1] rootcap = bits[-1]
self.pubkeys[name] = keystring pubkeys[name] = [key]
else: else:
self.passwords[name] = passwd self.passwords[name] = passwd
rootcap = rest rootcap = rest
self.rootcaps[name] = rootcap self.rootcaps[name] = rootcap
self._pubkeychecker = SSHPublicKeyChecker(InMemorySSHKeyDB(pubkeys))
def _avatarId(self, username): def _avatarId(self, username):
return FTPAvatarID(username, self.rootcaps[username]) return FTPAvatarID(username, self.rootcaps[username])
@ -57,11 +60,9 @@ class AccountFileChecker(object):
def requestAvatarId(self, creds): def requestAvatarId(self, creds):
if credentials.ISSHPrivateKey.providedBy(creds): if credentials.ISSHPrivateKey.providedBy(creds):
# Re-using twisted.conch.checkers.SSHPublicKeyChecker here, rather d = defer.maybeDeferred(self._pubkeychecker.requestAvatarId, creds)
# than re-implementing all of the ISSHPrivateKey checking logic, d.addCallback(self._avatarId)
# would be better. That would require Twisted 14.1.0 or newer, return d
# though.
return self._checkKey(creds)
elif credentials.IUsernameHashedPassword.providedBy(creds): elif credentials.IUsernameHashedPassword.providedBy(creds):
return self._checkPassword(creds) return self._checkPassword(creds)
elif credentials.IUsernamePassword.providedBy(creds): elif credentials.IUsernamePassword.providedBy(creds):
@ -86,28 +87,6 @@ class AccountFileChecker(object):
d.addCallback(self._cbPasswordMatch, str(creds.username)) d.addCallback(self._cbPasswordMatch, str(creds.username))
return d return d
def _checkKey(self, creds):
"""
Determine whether some key-based credentials correctly authenticates a
user.
Returns a Deferred that fires with the username if so or with an
UnauthorizedLogin failure otherwise.
"""
# Is the public key indicated by the given credentials allowed to
# authenticate the username in those credentials?
if creds.blob == self.pubkeys.get(creds.username):
if creds.signature is None:
return defer.fail(conch_error.ValidPublicKey())
# Is the signature in the given credentials the correct
# signature for the data in those credentials?
key = keys.Key.fromString(creds.blob)
if key.verify(creds.signature, creds.sigData):
return defer.succeed(self._avatarId(creds.username))
return defer.fail(error.UnauthorizedLogin())
@implementer(checkers.ICredentialsChecker) @implementer(checkers.ICredentialsChecker)
class AccountURLChecker(object): class AccountURLChecker(object):