diff options
Diffstat (limited to 'third_party/pyftpdlib/demo/unix_ftpd.py')
-rw-r--r-- | third_party/pyftpdlib/demo/unix_ftpd.py | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/third_party/pyftpdlib/demo/unix_ftpd.py b/third_party/pyftpdlib/demo/unix_ftpd.py new file mode 100644 index 0000000..6367b366 --- /dev/null +++ b/third_party/pyftpdlib/demo/unix_ftpd.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python +# unix_ftpd.py + +"""A ftpd using local unix account database to authenticate users +(users must already exist). + +It also provides a mechanism to (temporarily) impersonate the system +users every time they are going to perform filesystem operations. +""" + +import os +import pwd, spwd, crypt + +from pyftpdlib import ftpserver + + +class UnixAuthorizer(ftpserver.DummyAuthorizer): + + # the uid/gid the daemon runs under + PROCESS_UID = os.getuid() + PROCESS_GID = os.getgid() + + def add_user(self, username, homedir=None, **kwargs): + """Add a "real" system user to the virtual users table. + + If no home argument is specified the user's home directory will + be used. + + The keyword arguments in kwargs are the same expected by the + original add_user method: "perm", "msg_login" and "msg_quit". + """ + # get the list of all available users on the system and check + # if provided username exists + users = [entry.pw_name for entry in pwd.getpwall()] + if not username in users: + raise ftpserver.AuthorizerError('No such user "%s".' %username) + if not homedir: + homedir = pwd.getpwnam(username).pw_dir + ftpserver.DummyAuthorizer.add_user(self, username, '', homedir,**kwargs) + + def add_anonymous(self, homedir=None, realuser="nobody", **kwargs): + """Add an anonymous user to the virtual users table. + + If no homedir argument is specified the realuser's home + directory will possibly be determined and used. + + realuser argument specifies the system user to use for managing + anonymous sessions. On many UNIX systems "nobody" is tipically + used but it may change (e.g. "ftp"). + """ + users = [entry.pw_name for entry in pwd.getpwall()] + if not realuser in users: + raise ftpserver.AuthorizerError('No such user "%s".' %realuser) + if not homedir: + homedir = pwd.getpwnam(realuser).pw_dir + ftpserver.DummyAuthorizer.add_anonymous(self, homedir, **kwargs) + self.anon_user = realuser + + def validate_authentication(self, username, password): + if (username == "anonymous") and self.has_user('anonymous'): + username = self.anon_user + pw1 = spwd.getspnam(username).sp_pwd + pw2 = crypt.crypt(password, pw1) + return pw1 == pw2 + + def impersonate_user(self, username, password): + if (username == "anonymous") and self.has_user('anonymous'): + username = self.anon_user + uid = pwd.getpwnam(username).pw_uid + gid = pwd.getpwnam(username).pw_gid + os.setegid(gid) + os.seteuid(uid) + + def terminate_impersonation(self): + os.setegid(self.PROCESS_GID) + os.seteuid(self.PROCESS_UID) + + +if __name__ == "__main__": + authorizer = UnixAuthorizer() + # add a user (note: user must already exists) + authorizer.add_user('user', perm='elradfmw') + authorizer.add_anonymous(os.getcwd()) + ftp_handler = ftpserver.FTPHandler + ftp_handler.authorizer = authorizer + address = ('', 21) + ftpd = ftpserver.FTPServer(address, ftp_handler) + ftpd.serve_forever() |