gyn

Win32下的Perl,无用的select,停滞的Tk,结束吧....

利用pyftpdlib和pysqlite3建立可存储用户信息FTP服务

前一段时间因为版权的原因,停用了SERV-U服务。但是ftp的服务不能停止,所以不得不自己动手写一个。但是由于时间原因,无法完全认真去看协议,所以希望利用现有的模块。这类模块在perl和python中都有,不过我差不多有半年没碰perl了,自然选择了python。除了几个无关紧要的bug,这个模块基本能满足日常使用。只是用户信息的存储不是很保险,如果存到数据库中总能好一些。密码则参照范例中的md5码例子进行加密。这个程序暂时还凑或使用,之后还需加入按用户的流控和空间分配。这个程序的cpu使用率有一点高,将近15%的样子-_-!

  1 #  -*- coding: gbk -*-
  2
  3 import  md5, os
  4 from  pyftpdlib  import  ftpserver
  5 from  pysqlite2  import  dbapi2 as sqlite
  6
  7 class  Perm(object):
  8      # 建立用于存储用户权限的类
  9      def   __init__ (self, r  =   '' , w  =   '' ):
 10         self.r, self.w  =  str(r), str(w)
 11         
 12      def   __repr__ (self):
 13          if  self.w:
 14              return   " %c;%c "   %  (self.r, self.w)
 15          else :
 16              return   " %c; "   %  (self.r, )
 17         
 18 def  adapt_perm(perm):
 19      # 这个函数将权限类转换为sqlite支持的数据类型
 20      if  perm.w:
 21          return   " %c;%c "   %  (perm.r, perm.w)
 22      else :
 23          return   " %c; "   %  (perm.r, )
 24     
 25 sqlite.register_adapter(Perm, adapt_perm)  # 注册以上这个函数
 26
 27 class  DummyMD5Authorizer(ftpserver.DummyAuthorizer):
 28     
 29     users_table  =  { }  # ftp运行时维护的用户信息表
 30     
 31      def   __init__ (self):
 32          # 初始化ftp用户管理类,并从sqlite数据库中读入用户信息
 33         ftpserver.DummyAuthorizer. __init__ (self)
 34         self.sqlite_fetch_all()
 35         
 36      def  sqlite_conn(self):
 37          # 返回sqlite数据库连接对象,如未检测到数据库,则新建一个
 38         dbpath  =   ' %s\\users.db '   %  os.getcwd()
 39          if  os.path.isfile(dbpath):
 40              return  sqlite.connect(dbpath, isolation_level  =  None)
 41          else :
 42             conn  =  sqlite.connect(dbpath, isolation_level  =  None, detect_types = sqlite.PARSE_DECLTYPES)
 43             cursor  =  conn.cursor()
 44              # 建立名为users的表,用来存储用户信息
 45             cursor.execute( """ CREATE TABLE users(
 46                             username text primary key,
 47                             password text,
 48                             home text,
 49                             perm perm,
 50                             msg_login text,
 51                             msg_quit text
 52                             ) """ )    
 53             cursor.close()
 54              return  conn
 55             
 56      def  sqlite_fetch_all(self):
 57          # 提取用户信息
 58         conn  =  self.sqlite_conn()
 59         cursor  =  conn.cursor()
 60         cursor.execute( ' select * from users ' )
 61          for  eachresult  in  cursor.fetchall():
 62             username, password, home, perm, msg_login, msg_quit  =  eachresult
 63             perm  =  perm.split( " ; " )
 64             ftpserver.DummyAuthorizer.add_user(self, username, password, home, perm, msg_login, msg_quit)
 65         cursor.close()
 66         conn.close()        
 67     
 68      def  add_user(self, username, password, homedir, perm = ( ' r ' ), 
 69                     msg_login = " Login successful. " , msg_quit = " Goodbye. " ):
 70          # 增加用户,分别添加到数据库和ftp运行过程中维护的用户信息表
 71          try :
 72             password  =  md5.new(password).hexdigest()
 73             ftpserver.DummyAuthorizer.add_user(self, username, password, homedir, perm, msg_login, msg_quit)
 74          except  Exception, e:
 75              print  e
 76              return  
 77         self.sqlite_insert_user(username, password, homedir, perm, msg_login, msg_quit)
 78     
 79      def  sqlite_insert_user(self, username, password, homedir, perm = ( ' r ' ),
 80                              msg_login = " Login successful. " , msg_quit = " Goodbye. " ):
 81          # 将用户信息插入sqlite数据库
 82         conn  =  self.sqlite_conn()
 83         cursor  =  conn.cursor()
 84         cursor.execute( ' insert into users values(?, ?, ?, ?, ?, ?) '  
 85                         , (username, password, homedir, Perm( * perm), msg_login, msg_quit))
 86         cursor.close()
 87         conn.close()
 88     
 89      def  validate_authentication(self, username, password):
 90          # 使用md5骂验证用户密码
 91         hash  =  md5.new(password).hexdigest()
 92          return  self.user_table[username][ ' pwd ' ==  hash
 93
 94 def  user_info():
 95      # 在该函数中填入用户信息,使用后删除即可。当然一个更好的办法是建立一个
 96      # 可填入用户信息的GUI界面,这个我已着手写了。
 97      pass
 98
 99
100 # 测试代码
101 if   __name__   ==   ' __main__ ' :
102     authorizer  =  DummyMD5Authorizer()
103     authorizer.add_anonymous( ' E:\\FTPSite\\share ' )
104      # for eachuser,eachpwd, eachdir, eachperm in user_info():
105      #     authorizer.add_user(eachuser,eachpwd, eachdir, eachperm)
106     ftp_handler  =  ftpserver.FTPHandler
107     ftp_handler.authorizer  =  authorizer
108     ftp_handler.banner  =   ' pyftpdlib %s based ftpd ready '   %  ftpserver. __ver__
109     addr  =  ( '' 21 )
110     ftpd  =  ftpserver.FTPServer(addr, ftp_handler)
111     ftpd.max_cons  =   256
112     ftpd.max_cons_per_ip  =   5
113     ftpd.serve_forever()
114     

做了一些小修改
 1import md5, os
 2from pyftpdlib import ftpserver
 3from pysqlite2 import dbapi2 as sqlite
 4
 5class DummyMD5Authorizer(ftpserver.DummyAuthorizer):
 6    
 7    users_table = { }
 8    
 9    def __init__(self):
10        ftpserver.DummyAuthorizer.__init__(self)
11        self.sqlite_fetch_all()
12        
13    def sqlite_conn(self):
14        dbpath = '%s\\users.db' % os.getcwd()
15        if os.path.isfile(dbpath):
16            return sqlite.connect(dbpath, isolation_level = None)
17        else:
18            conn = sqlite.connect(dbpath, isolation_level = None, detect_types=sqlite.PARSE_DECLTYPES)
19            cursor = conn.cursor()
20            cursor.execute("""CREATE TABLE users(
21                            username text primary key,
22                            password text,
23                            home text,
24                            perm text,
25                            msg_login text,
26                            msg_quit text
27                            )""")    
28            cursor.close()
29            return conn
30            
31    def sqlite_fetch_all(self):
32        conn = self.sqlite_conn()
33        cursor = conn.cursor()
34        cursor.execute('select * from users')
35        for eachresult in cursor.fetchall():
36            username, password, home, perm, msg_login, msg_quit = eachresult
37            perm = perm.split(";")
38            ftpserver.DummyAuthorizer.add_user(self, username, password, home, perm, msg_login, msg_quit)
39        cursor.close()
40        conn.close()        
41    
42    def add_user(self, username, password, homedir, perm = 'r;'
43                    msg_login = "Login successful.", msg_quit = "Goodbye."):
44        try:
45            password = md5.new(password).hexdigest()
46            ftpserver.DummyAuthorizer.add_user(self, username, password, homedir, perm.split(';'), msg_login, msg_quit)
47        except Exception, e:
48            print e
49            return 
50        self.sqlite_insert_user(username, password, homedir, perm, msg_login, msg_quit)
51    
52    def sqlite_insert_user(self, username, password, homedir, perm = 'r;' ,
53                             msg_login="Login successful.", msg_quit="Goodbye."):
54        conn = self.sqlite_conn()
55        cursor = conn.cursor()
56        cursor.execute('insert into users values(?, ?, ?, ?, ?, ?)' 
57                        , (username, password, homedir, perm, msg_login, msg_quit))
58        cursor.close()
59        conn.close()
60    
61    def validate_authentication(self, username, password):
62        hash = md5.new(password).hexdigest()
63        return self.user_table[username]['pwd'== hash
64
65if __name__ == '__main__':
66    authorizer = DummyMD5Authorizer()
67    ftp_handler = ftpserver.FTPHandler
68    ftp_handler.authorizer = authorizer
69    ftp_handler.banner = 'pyftpdlib %s based ftpd ready' % ftpserver.__ver__
70    addr = (''21)
71    ftpd = ftpserver.FTPServer(addr, ftp_handler)
72    ftpd.max_cons = 256
73    ftpd.max_cons_per_ip = 5
74    ftpd.serve_forever()
75    

posted on 2007-11-10 11:15 gyn_tadao 阅读(1276) 评论(0)  编辑 收藏 引用 所属分类: Python

只有注册用户登录后才能发表评论。
<2006年4月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

导航

统计

常用链接

留言簿(15)

随笔分类(126)

随笔档案(108)

相册

搜索

最新评论

阅读排行榜

评论排行榜