I thought the port numbers would be inclusive when looking at the config file. But using range like this won't include the max port number in the resulting list.

Suggestion:

            passive_port_min=None, passive_port_max=None):
    ...
    if passive_port_min and passive_port_max:
        handler.passive_ports = range(passive_port_min, passive_port_max + 1)


Additionally, read_configuration_file should be updated to return these values as ints. They'll be strings at the moment.

Suggestion:

    def read_configuration_file(path):
        config = {
        ...
        int_values = ('listen_port', 'passive_port_min', 'passive_port_max')
                ...
                        if key in int_values:
                            value = int(value)