Index: third_party/pyftpdlib/demo/unix_ftpd.py |
=================================================================== |
--- third_party/pyftpdlib/demo/unix_ftpd.py (revision 0) |
+++ third_party/pyftpdlib/demo/unix_ftpd.py (revision 0) |
@@ -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() |