From: Brian Warner Date: Mon, 23 Feb 2009 00:24:26 +0000 (-0700) Subject: ftpd/sftpd: stop using RuntimeError, for #639 X-Git-Tag: allmydata-tahoe-1.4.0~143 X-Git-Url: https://git.rkrishnan.org/about.html?a=commitdiff_plain;h=d95b01a214b0acb1e0c3caaacd188ed4847a06df;p=tahoe-lafs%2Ftahoe-lafs.git ftpd/sftpd: stop using RuntimeError, for #639 --- diff --git a/src/allmydata/frontends/auth.py b/src/allmydata/frontends/auth.py index 6adbebb2..82ef1c65 100644 --- a/src/allmydata/frontends/auth.py +++ b/src/allmydata/frontends/auth.py @@ -5,6 +5,11 @@ from twisted.internet import defer from twisted.cred import error, checkers, credentials from allmydata.util import base32 +class NeedRootcapLookupScheme(Exception): + """Accountname+Password-based access schemes require some kind of + mechanism to translate name+passwd pairs into a rootcap, either a file of + name/passwd/rootcap tuples, or a server to do the translation.""" + class FTPAvatarID: def __init__(self, username, rootcap): self.username = username diff --git a/src/allmydata/frontends/ftpd.py b/src/allmydata/frontends/ftpd.py index 598c8db0..c187d86a 100644 --- a/src/allmydata/frontends/ftpd.py +++ b/src/allmydata/frontends/ftpd.py @@ -267,7 +267,7 @@ class Handler: d.addCallback(_got_parent) return d -from auth import AccountURLChecker, AccountFileChecker +from auth import AccountURLChecker, AccountFileChecker, NeedRootcapLookupScheme class Dispatcher: @@ -303,7 +303,7 @@ class FTPServer(service.MultiService): p.registerChecker(c) if not accountfile and not accounturl: # we could leave this anonymous, with just the /uri/CAP form - raise RuntimeError("must provide some translation") + raise NeedRootcapLookupScheme("must provide some translation") f = ftp.FTPFactory(p) s = strports.service(ftp_portstr, f) diff --git a/src/allmydata/frontends/sftpd.py b/src/allmydata/frontends/sftpd.py index d29aa8a6..aa15bbba 100644 --- a/src/allmydata/frontends/sftpd.py +++ b/src/allmydata/frontends/sftpd.py @@ -116,6 +116,9 @@ class StoppableList: class FakeStat: pass +class BadRemoveRequest(Exception): + pass + class SFTPHandler: implements(ISFTPServer) def __init__(self, user): @@ -259,9 +262,9 @@ class SFTPHandler: d = parent.get(childname) def _got_child(child): if must_be_directory and not IDirectoryNode.providedBy(child): - raise RuntimeError("rmdir called on a file") + raise BadRemoveRequest("rmdir called on a file") if must_be_file and IDirectoryNode.providedBy(child): - raise RuntimeError("rmfile called on a directory") + raise BadRemoveRequest("rmfile called on a directory") return parent.delete(childname) d.addCallback(_got_child) d.addErrback(self._convert_error) @@ -421,7 +424,7 @@ class SFTPHandler: # then you get SFTPHandler(user) components.registerAdapter(SFTPHandler, SFTPUser, ISFTPServer) -from auth import AccountURLChecker, AccountFileChecker +from auth import AccountURLChecker, AccountFileChecker, NeedRootcapLookupScheme class Dispatcher: implements(portal.IRealm) @@ -452,7 +455,7 @@ class SFTPServer(service.MultiService): p.registerChecker(c) if not accountfile and not accounturl: # we could leave this anonymous, with just the /uri/CAP form - raise RuntimeError("must provide some translation") + raise NeedRootcapLookupScheme("must provide some translation") pubkey = keys.Key.fromFile(pubkey_file) privkey = keys.Key.fromFile(privkey_file)