ftp-server

編程語言:python
主要模塊:pyftpdlib

代碼格式方面沒有經過整理,根據實際需求修改!

ftphome文件夾是服務器的工作目錄
ftpserver.log是服務器端日誌文件,(啓動時加上‘-l’參數,就會寫入日誌文件)
white.txt是白名單,白名單裏面的IP才被允許訪問

這裏寫圖片描述

#coding=utf-8
from hashlib import md5
import os,sys,logging,getopt
from pyftpdlib.authorizers import DummyAuthorizer,AuthenticationFailed
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.handlers import ThrottledDTPHandler
from pyftpdlib.servers import ThreadedFTPServer

ftp_port=2121
maxcons=100
maxcons_per_ip=5
read_limit=30720
write_limit=30720
flag=0
log=0
logpath='./'
jobpath='./ftphome'

def usage():
    print "FTP-Server"
    print 
    print "-h --help          how to use it"
    print "-p --port          set the ftp port"
    print "-s --stop          stop the ftp_server"
    print "-o --open          start the ftp_server"
    print "-m --maxcon        set a limit for connections"
    print "-u --useradd       add a user"
    print "-r --userdel       remove a user"
    print "-l --log           use logs other than echo on screen"
    print 
    print "Example:"
    print "python ftp_server -o"
    print "python ftp_server -o -p 2121 -m 100"
    sys.exit(0)

class DummyMD5Authorizer(DummyAuthorizer):
    def validate_authentication(self, username, password, handler):
        if sys.version_info >= (3, 0):
            password = md5(password.encode('latin1'))
        hash = md5(password).hexdigest()
        try:
            if self.user_table[username]['pwd'] != hash:
                raise KeyError
        except KeyError:
            raise AuthenticationFailed
class MyHandler(FTPHandler):

    def on_connect(self):
        client_ip=self.remote_ip
        client_port=self.remote_port
        print "%s:%s connected" % (client_ip, client_port)
        state=white_list(client_ip)
        if state!=1:
            print "warnning !! you have no permission "
            try:
                self.close()
                sys.exit(0)
            except Exception:
                print "warnning !! you have no permission "
        else:
            pass

def useradd():
    try:
        username=raw_input("username:")
        password=raw_input("password:")
        permission=raw_input("permission:")
        hash = md5(password).hexdigest()
        os.mkdir('/home/huajian/Desktop/ftp/%s'%(username))
        authorizer = DummyMD5Authorizer()
        # Define a new user having full r/w permissions(r/w : perm='elradfmw')
        authorizer.add_user(username, hash, '/home/huajian/Desktop/ftp/%s'%(username), perm=permission)
        print "please remember your username and the password , have fun !"
    except KeyboardInterrupt:
        print
        print "failed to add a user"
    sys.exit(0)

def userdel(username):
    authorizer = DummyMD5Authorizer()
    authorizer.remove_user(username)
    print "username: %s is removed !"%(username)
    sys.exit(0)

def ftp_log(log):
    if log==1:
        print "[listing on] 127.0.0.1:%s"%(ftp_port)
        print "all behavior is recorded in ftppyftpd.log!" 
        print "road is %s"%(logpath)
        logging.basicConfig(filename='ftpserver.log', level=logging.INFO)
    else:
        print ("if you want to use logging,please use \"-l\"")
def server_loop(flag):
    hash_user = md5('12345').hexdigest()
    authorizer = DummyMD5Authorizer()

    # Define a new user having full r/w permissions
    authorizer.add_user('user', hash_user, jobpath, perm='elradfmw')
    #authorizer.add_anonymous(os.getcwd())                   # add a "#" to ban the anonymous   
    # Instantiate FTP handler class
    ftp_handler = MyHandler
    ftp_handler.authorizer = authorizer
    #ftp_handler.banner = "connection is ok!"    # welcome information

    dtp_handler = ThrottledDTPHandler
    dtp_handler.read_limit = read_limit  # 30 Kb/sec (30 * 1024)
    dtp_handler.write_limit = write_limit  # 30 Kb/sec (30 * 1024)


    # Define a customized banner (string returned when client connects)
    #Maximum number of wrong authentications before disconnecting (default 3)
    ftp_handler.dtp_handler = dtp_handler
    #ftp_handler.max_login_attempts

    #if log=1 ,use log
    ftp_log(log)

    address = ('0.0.0.0', ftp_port)
    server = ThreadedFTPServer(address, ftp_handler)
    # set a limit for connections
    server.max_cons = maxcons
    server.max_cons_per_ip = maxcons_per_ip

    if flag==1:
        server.serve_forever()
    else:
        server.close_all()

def white_list(client_ip):
    ip_state=0
    f=open('white.txt').readlines()
    for ip_ok in f:
        ip_ok=ip_ok.strip('\n')
        if client_ip in ip_ok:
            ip_state=1
    return ip_state

def main():
    global ftp_port
    global maxcons
    global maxcons_per_ip
    global read_limit
    global write_limit
    global flag
    global log
    global jobpath
    global logpath

    if not len(sys.argv[1:]):
        usage()
    try:
        opts,args=getopt.getopt(sys.argv[1:],"hp:osm:url")  #["help","port","stop","open","maxcon","useradd","userdel","log"]
    except getopt.GetoptError as err:
        print str(err)
        usage()
    for o,a in opts:
        if o in ("-h","--help"):
            usage()
        elif o in ("-p","--port"):
            ftp_port=int(a)
        elif o in ("-s","--stop"):
            flag=0
        elif o in ("-o","--open"):
            flag=1
        elif o in ("-m","--maxcon"):
            maxcons=a
        elif o in ("-l","--log"):
            log=1
        elif o in ("-u","--useradd"):
            useradd()
        elif o in ("-r","--userdel"):
            userdel()
        else:
            print "error: can't handle your Option"
    if flag==1:
        try:
            server_loop(1)
        except KeyboardInterrupt:
            sys.exit(0)

if __name__ == '__main__':
    main()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章