| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 #!/usr/bin/env python | 
|  | 2 # unix_ftpd.py | 
|  | 3 | 
|  | 4 """A ftpd using local unix account database to authenticate users | 
|  | 5 (users must already exist). | 
|  | 6 | 
|  | 7 It also provides a mechanism to (temporarily) impersonate the system | 
|  | 8 users every time they are going to perform filesystem operations. | 
|  | 9 """ | 
|  | 10 | 
|  | 11 import os | 
|  | 12 import pwd, spwd, crypt | 
|  | 13 | 
|  | 14 from pyftpdlib import ftpserver | 
|  | 15 | 
|  | 16 | 
|  | 17 class UnixAuthorizer(ftpserver.DummyAuthorizer): | 
|  | 18 | 
|  | 19     # the uid/gid the daemon runs under | 
|  | 20     PROCESS_UID = os.getuid() | 
|  | 21     PROCESS_GID = os.getgid() | 
|  | 22 | 
|  | 23     def add_user(self, username, homedir=None, **kwargs): | 
|  | 24         """Add a "real" system user to the virtual users table. | 
|  | 25 | 
|  | 26         If no home argument is specified the user's home directory will | 
|  | 27         be used. | 
|  | 28 | 
|  | 29         The keyword arguments in kwargs are the same expected by the | 
|  | 30         original add_user method: "perm", "msg_login" and "msg_quit". | 
|  | 31         """ | 
|  | 32         # get the list of all available users on the system and check | 
|  | 33         # if provided username exists | 
|  | 34         users = [entry.pw_name for entry in pwd.getpwall()] | 
|  | 35         if not username in users: | 
|  | 36             raise ftpserver.AuthorizerError('No such user "%s".' %username) | 
|  | 37         if not homedir: | 
|  | 38             homedir = pwd.getpwnam(username).pw_dir | 
|  | 39         ftpserver.DummyAuthorizer.add_user(self, username, '', homedir,**kwargs) | 
|  | 40 | 
|  | 41     def add_anonymous(self, homedir=None, realuser="nobody", **kwargs): | 
|  | 42         """Add an anonymous user to the virtual users table. | 
|  | 43 | 
|  | 44         If no homedir argument is specified the realuser's home | 
|  | 45         directory will possibly be determined and used. | 
|  | 46 | 
|  | 47         realuser argument specifies the system user to use for managing | 
|  | 48         anonymous sessions.  On many UNIX systems "nobody" is tipically | 
|  | 49         used but it may change (e.g. "ftp"). | 
|  | 50         """ | 
|  | 51         users = [entry.pw_name for entry in pwd.getpwall()] | 
|  | 52         if not realuser in users: | 
|  | 53             raise ftpserver.AuthorizerError('No such user "%s".' %realuser) | 
|  | 54         if not homedir: | 
|  | 55             homedir = pwd.getpwnam(realuser).pw_dir | 
|  | 56         ftpserver.DummyAuthorizer.add_anonymous(self, homedir, **kwargs) | 
|  | 57         self.anon_user = realuser | 
|  | 58 | 
|  | 59     def validate_authentication(self, username, password): | 
|  | 60         if (username == "anonymous") and self.has_user('anonymous'): | 
|  | 61             username = self.anon_user | 
|  | 62         pw1 = spwd.getspnam(username).sp_pwd | 
|  | 63         pw2 = crypt.crypt(password, pw1) | 
|  | 64         return pw1 == pw2 | 
|  | 65 | 
|  | 66     def impersonate_user(self, username, password): | 
|  | 67         if (username == "anonymous") and self.has_user('anonymous'): | 
|  | 68             username = self.anon_user | 
|  | 69         uid = pwd.getpwnam(username).pw_uid | 
|  | 70         gid = pwd.getpwnam(username).pw_gid | 
|  | 71         os.setegid(gid) | 
|  | 72         os.seteuid(uid) | 
|  | 73 | 
|  | 74     def terminate_impersonation(self): | 
|  | 75         os.setegid(self.PROCESS_GID) | 
|  | 76         os.seteuid(self.PROCESS_UID) | 
|  | 77 | 
|  | 78 | 
|  | 79 if __name__ == "__main__": | 
|  | 80     authorizer = UnixAuthorizer() | 
|  | 81     # add a user (note: user must already exists) | 
|  | 82     authorizer.add_user('user', perm='elradfmw') | 
|  | 83     authorizer.add_anonymous(os.getcwd()) | 
|  | 84     ftp_handler = ftpserver.FTPHandler | 
|  | 85     ftp_handler.authorizer = authorizer | 
|  | 86     address = ('', 21) | 
|  | 87     ftpd = ftpserver.FTPServer(address, ftp_handler) | 
|  | 88     ftpd.serve_forever() | 
| OLD | NEW | 
|---|