Esempio n. 1
0
def main():
    syslog.syslog(syslog.LOG_ERR, 'starting captiveportal background process')
    # handle to ipfw, arp and the config
    ipfw = IPFW()
    arp = ARP()
    cnf = Config()
    while True:
        try:
            # construct objects
            db = DB()

            # update accounting info
            db.update_accounting_info(ipfw.list_accounting_info())

            # process sessions per zone
            arp.reload()
            cpzones = cnf.get_zones()
            for zoneid in cpzones:
                registered_addresses = ipfw.list_table(zoneid)
                registered_add_accounting = ipfw.list_accounting_info()
                expected_clients = db.list_clients(zoneid)
                # handle connected clients, timeouts, address changes, etc.
                for db_client in expected_clients:
                    # fetch ip address (or network) from database
                    cpnet = db_client['ipAddress'].strip()

                    # there are different reasons why a session should be removed, check for all reasons and
                    # use the same method for the actual removal
                    drop_session = False

                    # todo, static ip and addresses shouldn't be affected by the timeout rules below.
                    # check if hardtimeout is set and overrun for this session
                    if 'hardtimeout' in cpzones[zoneid] and str(cpzones[zoneid]['hardtimeout']).isdigit():
                        # hardtimeout should be set and we should have collected some session data from the client
                        if int(cpzones[zoneid]['hardtimeout']) > 0  and float(db_client['startTime']) > 0:
                            if (time.time() - float(db_client['startTime'])) / 60 > int(cpzones[zoneid]['hardtimeout']):
                                drop_session = True

                    # check if idletimeout is set and overrun for this session
                    if 'idletimeout' in cpzones[zoneid] and str(cpzones[zoneid]['idletimeout']).isdigit():
                        # idletimeout should be set and we should have collected some session data from the client
                        if int(cpzones[zoneid]['idletimeout']) > 0 and float(db_client['last_accessed']) > 0:
                            if (time.time() - float(db_client['last_accessed'])) / 60 > int(cpzones[zoneid]['idletimeout']):
                                drop_session = True

                    # check session, if it should be active, validate its properties
                    if not drop_session:
                        # registered client, but not active according to ipfw (after reboot)
                        if cpnet not in registered_addresses:
                            ipfw.add_to_table(zoneid, cpnet)

                        # is accounting rule still available? need to reapply after reload / reboot
                        if cpnet not in registered_add_accounting and db_client['ipAddress'] not in registered_add_accounting:
                            ipfw.add_accounting(cpnet)
                    else:
                        # remove session
                        db.del_client(zoneid, db_client['sessionId'])
                        ipfw.delete_from_table(zoneid, cpnet)
                        ipfw.del_accounting(cpnet)

            # cleanup, destruct
            del db

            # sleep
            time.sleep(5)
        except KeyboardInterrupt:
            break
        except SystemExit:
            break
        except:
            syslog.syslog(syslog.LOG_ERR, traceback.format_exc())