CaptivePortal, convert scripts from python 2 --> 3

This commit is contained in:
Ad Schellevis 2019-05-13 19:29:06 +02:00
parent 64186cca48
commit 1dfc0e250a
13 changed files with 77 additions and 68 deletions

View File

@ -1,7 +1,7 @@
#!/usr/local/bin/python2.7
#!/usr/local/bin/python3
"""
Copyright (c) 2015 Ad Schellevis <ad@opnsense.org>
Copyright (c) 2015-2019 Ad Schellevis <ad@opnsense.org>
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -75,6 +75,6 @@ else:
# output result as plain text or json
if parameters['output_type'] != 'json':
for item in response:
print '%20s %s' % (item, response[item])
print ('%20s %s' % (item, response[item]))
else:
print(ujson.dumps(response))

View File

@ -1,7 +1,7 @@
#!/usr/local/bin/python2.7
#!/usr/local/bin/python3
"""
Copyright (c) 2015 Ad Schellevis <ad@opnsense.org>
Copyright (c) 2015-2019 Ad Schellevis <ad@opnsense.org>
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@ -1,7 +1,7 @@
#!/usr/local/bin/python2.7
#!/usr/local/bin/python3
"""
Copyright (c) 2015 Ad Schellevis <ad@opnsense.org>
Copyright (c) 2015-2019 Ad Schellevis <ad@opnsense.org>
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -46,18 +46,16 @@ for param in sys.argv[1:]:
# disconnect client
response = {'terminateCause': 'UNKNOWN'}
if parameters['sessionid'] is not None and parameters['zoneid'] is not None:
cp_db = DB()
# remove client
client_session_info = cp_db.del_client(parameters['zoneid'], parameters['sessionid'])
client_session_info = DB().del_client(parameters['zoneid'], parameters['sessionid'])
if client_session_info is not None:
cpIPFW = IPFW()
cpIPFW.delete(parameters['zoneid'], client_session_info['ip_address'])
IPFW().delete(parameters['zoneid'], client_session_info['ip_address'])
client_session_info['terminateCause'] = 'User-Request'
response = client_session_info
# output result as plain text or json
if parameters['output_type'] != 'json':
for item in response:
print '%20s %s' % (item, response[item])
print ('%20s %s' % (item, response[item]))
else:
print(ujson.dumps(response))

View File

@ -1,7 +1,7 @@
#!/usr/local/bin/python2.7
#!/usr/local/bin/python3
"""
Copyright (c) 2015 Ad Schellevis <ad@opnsense.org>
Copyright (c) 2015-2019 Ad Schellevis <ad@opnsense.org>
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -33,13 +33,14 @@ import sys
import ujson
import binascii
import zipfile
import StringIO
import base64
from io import BytesIO
from lib import OPNsenseConfig
response = dict()
source_directory = '/usr/local/opnsense/scripts/OPNsense/CaptivePortal/htdocs_default'
output_data = StringIO.StringIO()
output_data = BytesIO()
with zipfile.ZipFile(output_data, mode='w', compression=zipfile.ZIP_DEFLATED) as zf:
# overlay user template data
@ -52,7 +53,7 @@ with zipfile.ZipFile(output_data, mode='w', compression=zipfile.ZIP_DEFLATED) as
template_content = cnf.get_template(sys.argv[1])
if template_content is not None:
try:
input_data = StringIO.StringIO(template_content.decode('base64'))
input_data = BytesIO(base64.b64decode(template_content))
with zipfile.ZipFile(input_data, mode='r', compression=zipfile.ZIP_DEFLATED) as zf_in:
for zf_info in zf_in.infolist():
user_filenames.append(zf_info.filename)
@ -70,8 +71,9 @@ with zipfile.ZipFile(output_data, mode='w', compression=zipfile.ZIP_DEFLATED) as
filename = '%s/%s' % (root, filename)
output_filename = filename[len(source_directory)+1:]
if output_filename not in user_filenames:
zf.writestr(output_filename, open(filename, 'rb').read())
tmp = open(filename, 'rb').read()
zf.writestr(output_filename, tmp)
response['payload'] = output_data.getvalue().encode('base64')
response['payload'] = base64.b64encode(output_data.getvalue()).decode()
response['size'] = len(response['payload'])
print(ujson.dumps(response))

View File

@ -1,5 +1,5 @@
"""
Copyright (c) 2015 Ad Schellevis <ad@opnsense.org>
Copyright (c) 2015-2019 Ad Schellevis <ad@opnsense.org>
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -27,7 +27,7 @@
import os.path
import stat
import xml.etree.ElementTree
from ConfigParser import ConfigParser
from configparser import ConfigParser
class Config(object):
@ -67,12 +67,12 @@ class Config(object):
# convert allowed(MAC)addresses string to list
if 'allowedaddresses' in result[zoneid] and result[zoneid]['allowedaddresses'].strip() != '':
result[zoneid]['allowedaddresses'] = \
map(lambda x: x.strip(), result[zoneid]['allowedaddresses'].split(','))
[x.strip() for x in result[zoneid]['allowedaddresses'].split(',')]
else:
result[zoneid]['allowedaddresses'] = list()
if 'allowedmacaddresses' in result[zoneid] and result[zoneid]['allowedmacaddresses'].strip() != '':
result[zoneid]['allowedmacaddresses'] = \
map(lambda x: x.strip(), result[zoneid]['allowedmacaddresses'].split(','))
[x.strip() for x in result[zoneid]['allowedmacaddresses'].split(',')]
else:
result[zoneid]['allowedmacaddresses'] = list()
return result

View File

@ -1,5 +1,5 @@
"""
Copyright (c) 2015 Ad Schellevis <ad@opnsense.org>
Copyright (c) 2015-2019 Ad Schellevis <ad@opnsense.org>
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -50,13 +50,12 @@ class ARP(object):
with tempfile.NamedTemporaryFile() as output_stream:
subprocess.check_call(['/usr/sbin/arp', '-an'], stdout=output_stream, stderr=subprocess.STDOUT)
output_stream.seek(0)
for line in output_stream.read().split('\n'):
line_parts = line.split()
for line in output_stream:
line_parts = line.decode().split()
if len(line_parts) < 6 or line_parts[2] != 'at' or line_parts[4] != 'on':
continue
if len(line_parts[1]) < 2 or line_parts[1][0] != '(' or line_parts[1][-1] != ')':
elif len(line_parts[1]) < 2 or line_parts[1][0] != '(' or line_parts[1][-1] != ')':
continue
address = line_parts[1][1:-1]

View File

@ -1,5 +1,3 @@
#!/usr/local/bin/python2.7
# original source from https://github.com/thesharp/daemonize
import fcntl

View File

@ -1,5 +1,5 @@
"""
Copyright (c) 2015 Ad Schellevis <ad@opnsense.org>
Copyright (c) 2015-2019 Ad Schellevis <ad@opnsense.org>
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -84,9 +84,14 @@ class DB(object):
:return: active status (boolean)
"""
cur = self._connection.cursor()
request = {'zoneid': zoneid, 'ip_address': ip_address, 'mac_address': mac_address}
request = {
'zoneid': zoneid,
'ip_address': ip_address,
'mac_address': mac_address
}
cur.execute("""select cc.sessionid sessionId
, cc.authenticated_via authenticated_via
, cc.ip_address
from cp_clients cc
where cc.deleted = 0
and cc.zoneid = :zoneid
@ -117,7 +122,7 @@ class DB(object):
response['ipAddress'] = ip_address
response['macAddress'] = mac_address
response['startTime'] = time.time() # record creation = sign-in time
response['sessionId'] = base64.b64encode(os.urandom(16)) # generate a new random session id
response['sessionId'] = base64.b64encode(os.urandom(16)).decode() # generate a new random session id
cur = self._connection.cursor()
# set cp_client as deleted in case there's already a user logged-in at this ip address.
@ -139,6 +144,8 @@ class DB(object):
def update_client_ip(self, zoneid, sessionid, ip_address):
""" change client ip address
"""
if type(sessionid) == bytes:
sessionid = sessionid.decode()
cur = self._connection.cursor()
cur.execute("""update cp_clients
set ip_address = :ip_address
@ -154,6 +161,8 @@ class DB(object):
:param sessionid: session id
:return: client info before removal or None if client not found
"""
if type(sessionid) == bytes:
sessionid = sessionid.decode()
cur = self._connection.cursor()
cur.execute(""" select *
from cp_clients

View File

@ -1,5 +1,5 @@
"""
Copyright (c) 2015 Ad Schellevis <ad@opnsense.org>
Copyright (c) 2015-2019 Ad Schellevis <ad@opnsense.org>
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -46,7 +46,8 @@ class IPFW(object):
stdout=output_stream,
stderr=devnull)
output_stream.seek(0)
for line in output_stream.read().split('\n'):
for line in output_stream:
line = line.decode()
if line.split(' ')[0].strip() != "":
# process / 32 nets as single addresses to align better with the rule syntax
# and local administration.
@ -103,8 +104,8 @@ class IPFW(object):
stdout=output_stream,
stderr=devnull)
output_stream.seek(0)
for line in output_stream.read().split('\n'):
parts = line.split()
for line in output_stream:
parts = line.decode().split()
if len(parts) > 5:
if 30001 <= int(parts[0]) <= 50000 and parts[4] == 'count':
line_pkts = int(parts[1])

View File

@ -1,7 +1,7 @@
#!/usr/local/bin/python2.7
#!/usr/local/bin/python3
"""
Copyright (c) 2015 Ad Schellevis <ad@opnsense.org>
Copyright (c) 2015-2019 Ad Schellevis <ad@opnsense.org>
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -45,22 +45,22 @@ for param in sys.argv[1:]:
current_param = None
if parameters['zoneid'] is not None:
cpDB = DB()
response = cpDB.list_clients(parameters['zoneid'])
response = DB().list_clients(parameters['zoneid'])
else:
response = []
# output result as plain text or json
if parameters['output_type'] != 'json':
heading = {'sessionId': 'sessionid',
'userName': 'username',
'ipAddress': 'ip_address',
'macAddress': 'mac_address',
'total_bytes': 'total_bytes',
'idletime': 'idletime',
'totaltime': 'totaltime',
'acc_timeout': 'acc_session_timeout'
}
heading = {
'sessionId': 'sessionid',
'userName': 'username',
'ipAddress': 'ip_address',
'macAddress': 'mac_address',
'total_bytes': 'total_bytes',
'idletime': 'idletime',
'totaltime': 'totaltime',
'acc_timeout': 'acc_session_timeout'
}
heading_format = '%(sessionId)-30s %(userName)-25s %(ipAddress)-20s %(macAddress)-20s '\
+ '%(total_bytes)-15s %(idletime)-10s %(totaltime)-10s %(acc_timeout)-10s'
print (heading_format % heading)

View File

@ -1,7 +1,7 @@
#!/usr/local/bin/python2.7
#!/usr/local/bin/python3
"""
Copyright (c) 2015 Ad Schellevis <ad@opnsense.org>
Copyright (c) 2015-2019 Ad Schellevis <ad@opnsense.org>
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -32,7 +32,8 @@
import os
import sys
import zipfile
import StringIO
import base64
from io import BytesIO
from lib import Config
if len(sys.argv) > 1:
@ -42,8 +43,8 @@ if len(sys.argv) > 1:
template_data = cnf.fetch_template_data(sys.argv[1])
if template_data is not None and len(template_data) > 20:
print ('overlay user template package for zone %s' % zoneid)
zip_content = template_data.decode('base64')
input_data = StringIO.StringIO(zip_content)
zip_content = base64.b64decode(template_data)
input_data = BytesIO(zip_content)
with zipfile.ZipFile(input_data, mode='r', compression=zipfile.ZIP_DEFLATED) as zf_in:
for zf_info in zf_in.infolist():
if zf_info.filename[-1] != '/':
@ -53,11 +54,11 @@ if len(sys.argv) > 1:
os.makedirs(file_target_directory)
with open(target_filename, 'wb') as f_out:
f_out.write(zf_in.read(zf_info.filename))
os.chmod(target_filename, 0444)
os.chmod(target_filename, 0o444)
# write zone settings
filename = '%sjs/zone.js' % target_directory
with open(filename, 'wb') as f_out:
f_out.write('var zoneid = %s' % zoneid)
os.chmod(filename, 0444)
f_out.write(('var zoneid = %s' % zoneid).encode())
os.chmod(filename, 0o444)
sys.exit(0)

View File

@ -1,6 +1,6 @@
#!/usr/local/bin/python2.7
#!/usr/local/bin/python3
"""
Copyright (c) 2015 Ad Schellevis <ad@opnsense.org>
Copyright (c) 2015-2019 Ad Schellevis <ad@opnsense.org>
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -49,6 +49,6 @@ if parameters['zoneid'] is not None and parameters['sessionid'] is not None:
# output result as plain text or json
if parameters['output_type'] != 'json':
for item in response:
print '%20s %s' % (item, response[item])
print ('%20s %s' % (item, response[item]))
else:
print(ujson.dumps(response))

View File

@ -1,7 +1,7 @@
#!/usr/local/bin/python2.7
#!/usr/local/bin/python3
"""
Copyright (c) 2015 Ad Schellevis <ad@opnsense.org>
Copyright (c) 2015-2019 Ad Schellevis <ad@opnsense.org>
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -33,9 +33,10 @@
import sys
import os.path
import binascii
import StringIO
import zipfile
import ujson
import base64
from io import BytesIO
from hashlib import md5
htdocs_default_root = '/usr/local/opnsense/scripts/OPNsense/CaptivePortal/htdocs_default'
@ -60,7 +61,7 @@ if len(sys.argv) < 2:
else:
input_filename = '/tmp/%s' % os.path.basename(sys.argv[1])
try:
zip_content = open(input_filename, 'r').read().decode('base64')
zip_content = base64.b64decode(open(input_filename, 'rb').read())
except binascii.Error:
# not in base64
response['error'] = 'Not a base64 encoded file'
@ -70,8 +71,8 @@ else:
if 'error' not in response:
exclude_list = load_exclude_list()
input_data = StringIO.StringIO(zip_content)
output_data = StringIO.StringIO()
input_data = BytesIO(zip_content)
output_data = BytesIO()
with zipfile.ZipFile(input_data, mode='r', compression=zipfile.ZIP_DEFLATED) as zf_in:
with zipfile.ZipFile(output_data, mode='w', compression=zipfile.ZIP_DEFLATED) as zf_out:
# the zip content may be in a folder, use index to track actual location
@ -101,7 +102,7 @@ if 'error' not in response:
# new file, always write
zf_out.writestr(filename, file_data)
if 'error' not in response:
response['payload'] = output_data.getvalue().encode('base64').strip().replace('\n', '')
response['payload'] = base64.b64encode(output_data.getvalue()).decode().replace('\n', '')
response['size'] = len(response['payload'])
print(ujson.dumps(response))