def append_pool(msg): pool_id = msg['pool_id'].replace(' ', '') prefix = msg['prefix'] with dbw() as conn: with conn.cursor() as crsr: bulk = [] network = ip_network(prefix) size = network.num_addresses if size >= 65536: chunk = 65536 else: chunk = size i = 1 for ip in network: bulk.append('(uuid(), "%s", 0x%s)' % ( pool_id, ip.packed.hex(), )) if i == chunk: try: crsr.execute('INSERT INTO calabiyau_ippool' + ' (id, pool_id, framedipaddress)' + ' VALUES' + ' %s' % ", ".join(bulk)) crsr.commit() except SQLIntegrityError as e: log.warning(e) i = 1 bulk = [] i += 1
def post_processing(queue): while True: pkt = queue.get(queue) with MBClient('subscriber') as mb: mb.send( 'radius_accounting', { 'attributes': encode_packet(pkt), 'datetime': str(datetime.utcnow()) }) with db() as dbro: with dbro.cursor() as crsr: client = pkt.get('NAS-IP-Address')[0] user = get_user(crsr, client, pkt.source[0], pkt.get('User-Name')[0]) if user: status = pkt.get('Acct-Status-Type', [''])[0].lower() if not user['static_ip4'] and user['pool_id']: with dbw() as dbwr: update_ip(dbwr, status, user, pkt) duplicate_to = g.app.config.get('radius', 'duplicate', fallback=None) if duplicate_to: with dbro.cursor() as crsr: client = pkt.get('NAS-IP-Address')[0] user = get_user(crsr, client, pkt.source[0], pkt.get('User-Name')[0]) if user: pkt['Class'] = user['package'].encode('utf-8') duplicates = duplicate_to.split(',') for duplicate_to in duplicates: duplicate_to = duplicate_to.strip() duplicate(pkt.raw_packet, duplicate_to, 1813)
def acct(msg): fr = parse_fr(msg.get('fr', ())) status = fr.get('Acct-Status-Type', 'start').lower() dt = utc(parse_datetime(msg.get('datetime', None))) diff = (now() - dt).total_seconds() if diff > 60: log.error('Processing radius accounting message older' + ' than 60 seconds. Age(%s)' % diff) if not require_attributes('accounting', fr, [ 'User-Name', 'NAS-IP-Address', 'Acct-Status-Type', 'Acct-Session-Id', 'Acct-Unique-Session-Id', 'Acct-Input-Octets64', 'Acct-Output-Octets64' ]): return False with db() as conn: with dbw() as connw: user = get_user(conn, fr['NAS-IP-Address'], fr['User-Name']) if not user: log.debug("user '%s' not found" % (fr['User-Name'], )) return False input_octets, output_octets = do_acct(connw, fr, dt, user, status) usage(connw, fr, user, input_octets, output_octets, status) if not user['static_ip4'] and user['pool_id']: update_ip(connw, user, fr) return True
def acct(msg): try: pkt = msg['attributes'] except KeyError: return try: pkt = decode_packet(pkt) except Exception: return try: nas_session_id = pkt.get('Acct-Session-Id', [None])[0] unique_session_id = pkt.get('Acct-Unique-Session-Id')[0] status = pkt.get('Acct-Status-Type', [''])[0].lower() username = pkt.get('User-Name', [None])[0] client = pkt.get('Client-IP-Address')[0] nas = pkt.get('NAS-IP-Address', ['0.0.0.0'])[0] except IndexError: return True dt = utc(parse_datetime(msg.get('datetime', None))) diff = (now()-dt).total_seconds() if diff > 60: log.error('Processing radius accounting message older' + ' than 60 seconds. Age(%s)' % diff) with db() as conn: with dbw() as connw: with conn.cursor() as crsr: user = get_user(crsr, client, nas, username) crsr.commit() if not user: log.debug("user '%s' not found" % username) return False input_octets, output_octets = do_acct(connw, pkt, client, nas, nas_session_id, unique_session_id, dt, user, status) usage(connw, pkt, client, nas, nas_session_id, unique_session_id, user, input_octets, output_octets, status) return True
def purge_sessions(): with dbw() as conn: with conn.cursor() as crsr: while True: log.info('Purging old stop sessions') crsr.execute("DELETE FROM calabiyau_session WHERE" + " processed < (NOW() - INTERVAL 24 HOUR)" + " AND accttype = 'stop'") crsr.commit() time.sleep(60)
def delete_pool(msg): pool_id = msg['pool_id'] prefix = msg['prefix'] with dbw() as conn: with conn.cursor() as crsr: network = ip_network(prefix) size = network.num_addresses start = network[0].packed end = network[size - 1].packed crsr.execute( 'DELETE FROM calabiyau_ippool' + ' WHERE pool_id = "%s"' % pool_id + ' AND framedipaddress BETWEEN %s AND %s', ( start, end, )) crsr.commit()
def delete_pool(msg): log = MPLogger(__name__) pool_id = msg['pool_id'] prefix = msg['prefix'] with dbw() as conn: with conn.cursor() as crsr: for ip in ip_network(prefix): try: crsr.execute( 'DELETE FROM calabiyau_ippool' + ' WHERE pool_id = %s' + ' and framedipaddress = %s', ( pool_id, str(ip), )) except SQLIntegrityError as e: log.warning(e) crsr.commit()
def append_pool(msg): log = MPLogger(__name__) pool_id = msg['pool_id'] prefix = msg['prefix'] with dbw() as conn: with conn.cursor() as crsr: for ip in ip_network(prefix): try: crsr.execute( 'INSERT INTO calabiyau_ippool' + ' (id, pool_id, framedipaddress)' + ' VALUES' + ' (uuid(), %s, %s)', ( pool_id, str(ip), )) except SQLIntegrityError as e: log.warning(e) crsr.commit()
def auth(self, pkt, queue, debug): with db() as dbro: with dbro.cursor() as crsr: client = pkt.get('NAS-IP-Address')[0] user = get_user(crsr, client, pkt.source[0], pkt.get('User-Name')[0]) if user: if not user['enabled']: log.warning('Subscriber account disabled (%s)' % user['username']) dbro.commit() return else: log.warning('User not found (%s)' % pkt.get('User-Name')[0]) dbro.commit() return if ('User-Password' in pkt): if pkt['User-Password'][0] != user['password']: # Check for Legacy MD5 hashed passwords. hashed = md5(pkt['User-Password'][0].encode( 'utf-8')).hexdigest() if str(hashed) != user['password']: dbro.commit() log.warning('Password mismatch (%s)' % user['username']) return elif ('CHAP-Password' in pkt and not validate_chap_password(pkt, user['password'])): dbro.commit() log.warning('Password mismatch (%s)' % user['username']) return elif ('User-Password' not in pkt and 'CHAP-Password' not in pkt): dbro.commit() log.warning('No password supplied (%s)' % user['username']) return ctx = ctx_values[usage(crsr, user)] attributes = get_attributes(crsr, user, ctx) if ctx == 'deactivate-login' and not attributes: return if (user['static_ip4'] or not user['simultaneous']): if has_session(crsr, user): log.warning('Subscriber duplicate session (%s)' % user['username']) dbro.commit() return elif user['static_ip4']: attributes['Framed-IP-Address'] = user['static_ip4'] elif user['pool_id']: with dbw() as dbwr: ip = get_ip(dbwr, user) if ip: attributes['Framed-IP-Address'] = ip else: pool_name = get_pool_name(crsr, user) log.critical("IP Pool Empty user '%s' pool '%s'" % ( user['username'], pool_name, )) dbro.commit() return dbro.commit() return (RAD_ACCESSACCEPT, attributes)