3

I'm running a script for an FTP server in Python with PyFTPdLib like this:

from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer

def main():
    authorizer = DummyAuthorizer()

    authorizer.add_user('user', '12345', '.', perm='elradfmwM')

    handler = FTPHandler
    handler.authorizer = authorizer

    address = ('localhost', 2121)
    server = FTPServer(address, handler)

    # start ftp server
    server.serve_forever()

if __name__ == '__main__':
    main()

Whenever I call this code, it keeps the command line busy with running the "server.serve_forever()", it doesn't keep running through the if loop.

So my question is, how do you add a user while the server is running without shutting down the server?

Do I need to create another script to call this one and then another to add a user? Will it need to be threaded so both can run without locking up on this one?

I've tried to look through the tutorials on this module, but I haven't found any examples or seen any solutions. I'm willing to switch to a different module to run a FTP server if needed, so long as I can control everything.

I'm going to be adding users a lot from a database, then removing them. So I don't want to take the server down and restart it every time I need to add someone.

PyFire
  • 101
  • 1
  • 8

2 Answers2

2

In case anyone was interested in this topic, I think I have found a solution.

What I did was save the above code in a file called "create_ftp_server.py" and changed "main" from a def to a class.

#First .py module
class ftp_server:
   def __init__(self):
       self.authorizer = DummyAuthorizer()
       self.authorizer.add_user('admin', 'password', '.', perm='elradfmwM')

   def run(self):
       self.handler = FTPHandler
       self.handler.authorizer = self.authorizer
       self.address = ('localhost', 21)
       self.server = FTPServer(self.address, self.handler)
       logging.basicConfig(filename='pyftpd.log', level=logging.INFO)
       self.server.serve_forever()

   def add_user(self,user,passwd,loc,privi):
       self.authorizer.add_user(str(user), str(passwd), str(loc), perm=str(privi))

Then I made another module to call and run this file (really this is just for my personal taste, as you could just add this to the same module)

#Second .py module
import thread
import create_ftp_server

this_ftp = create_ftp_server.ftp_server()

thread.start_new_thread(this_ftp.run,())
thread.start_new_thread(this_ftp.add_user,('user','password',".",'elradfmwM'))

All you have to do now is decide how you want to call the thread to add the user.

Note: I tried to use the newer Threading module but I couldn't get any real results with that. This option will work well for me, though.

PyFire
  • 101
  • 1
  • 8
  • Is there an example how to get this running using the multithreaded mode the pyftpd lib supports now out of the box? – wichtel Apr 01 '17 at 17:59
0

You can do it, with the SITE Command like this:

proto_cmds = FTPHandler.proto_cmds.copy()
#Define SITE ADDUSER USERNAME PASSWORT HOME PRIVS
proto_cmds.update(
    {'SITE ADDUSER': dict(perm='m', auth=True, arg=True, help='Syntax: SITE <SP> ADDUSER USERNAME PASSWORT HOME PRIVS <SP>.')}
)

class siteadd(TLS_FTPHandler):
    proto_cmds = proto_cmds

    def ftp_SITE_ADDUSER(self,user,passwd,loc,privi):
        self.authorizer.add_user(str(user), str(passwd), str(loc), perm=str(privi))

and change the handle line from

self.handler = FTPHandler

to

self.handler = siteadd

Check if this works.

Connect to your FTP and run SITE HELP command you see all available commands.

You can run the FTPd in daemon mode, too. Look here for an example

Draken
  • 3,134
  • 13
  • 34
  • 54