1b4565c9e7ce71b7df0a4bd9005b428aae28b2b6
[platform/framework/web/crosswalk.git] / src / third_party / pyftpdlib / src / demo / anti_flood_ftpd.py
1 #!/usr/bin/env python
2 # $Id$
3
4 #  pyftpdlib is released under the MIT license, reproduced below:
5 #  ======================================================================
6 #  Copyright (C) 2007-2012 Giampaolo Rodola' <g.rodola@gmail.com>
7 #
8 #                         All Rights Reserved
9 #
10 # Permission is hereby granted, free of charge, to any person
11 # obtaining a copy of this software and associated documentation
12 # files (the "Software"), to deal in the Software without
13 # restriction, including without limitation the rights to use,
14 # copy, modify, merge, publish, distribute, sublicense, and/or sell
15 # copies of the Software, and to permit persons to whom the
16 # Software is furnished to do so, subject to the following
17 # conditions:
18 #
19 # The above copyright notice and this permission notice shall be
20 # included in all copies or substantial portions of the Software.
21 #
22 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
24 # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
27 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
29 # OTHER DEALINGS IN THE SOFTWARE.
30 #
31 #  ======================================================================
32
33 """
34 A FTP server banning clients in case of commands flood.
35
36 If client sends more than 300 requests per-second it will be
37 disconnected and won't be able to re-connect for 1 hour.
38 """
39
40 from pyftpdlib.ftpserver import FTPHandler, FTPServer, DummyAuthorizer, CallEvery
41
42
43 class AntiFloodHandler(FTPHandler):
44
45     cmds_per_second = 300  # max number of cmds per second
46     ban_for = 60 * 60      # 1 hour
47     banned_ips = []
48
49     def __init__(self, *args, **kwargs):
50         super(AntiFloodHandler, self).__init__(*args, **kwargs)
51         self.processed_cmds = 0
52         self.pcmds_callback = CallEvery(1, self.check_processed_cmds)
53
54     def handle(self):
55         # called when client connects.
56         if self.remote_ip in self.banned_ips:
57             self.respond('550 you are banned')
58             self.close()
59         else:
60             super(AntiFloodHandler, self).handle()
61
62     def check_processed_cmds(self):
63         # called every second; checks for the number of commands
64         # sent in the last second.
65         if self.processed_cmds > self.cmds_per_second:
66             self.ban(self.remote_ip)
67         else:
68             self.processed_cmds = 0
69
70     def process_command(self, *args, **kwargs):
71         # increase counter for every received command
72         self.processed_cmds += 1
73         super(AntiFloodHandler, self).process_command(*args, **kwargs)
74
75     def ban(self, ip):
76         # ban ip and schedule next un-ban
77         if ip not in self.banned_ips:
78             self.log('banned IP %s for command flooding' % ip)
79         self.respond('550 you are banned for %s seconds' % self.ban_for)
80         self.close()
81         self.banned_ips.append(ip)
82
83     def unban(self, ip):
84         # unban ip
85         try:
86             self.banned_ips.remove(ip)
87         except ValueError:
88             pass
89         else:
90             self.log('unbanning IP %s' % ip)
91
92     def close(self):
93         super(AntiFloodHandler, self).close()
94         if not self.pcmds_callback.cancelled:
95             self.pcmds_callback.cancel()
96
97
98 def main():
99     authorizer = DummyAuthorizer()
100     authorizer.add_user('user', '12345', '.', perm='elradfmw')
101     authorizer.add_anonymous('.')
102     handler = AntiFloodHandler
103     handler.authorizer = authorizer
104     ftpd = FTPServer(('', 21), handler)
105     ftpd.serve_forever(timeout=1)
106
107 if __name__ == '__main__':
108     main()