mirror of
				https://github.com/Telecominfraproject/wlan-ap.git
				synced 2025-10-31 10:28:06 +00:00 
			
		
		
		
	uspot: refactor code
* add a common.uc class * add ucode ubus calls Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
		
							
								
								
									
										137
									
								
								feeds/ucentral/uspot/files/usr/share/uspot/common.uc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								feeds/ucentral/uspot/files/usr/share/uspot/common.uc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,137 @@ | |||||||
|  | 'use strict'; | ||||||
|  |  | ||||||
|  | let ubus = require('ubus'); | ||||||
|  | let fs = require('fs'); | ||||||
|  | let uci = require('uci').cursor(); | ||||||
|  | let config = uci.get_all('uspot'); | ||||||
|  |  | ||||||
|  | let file = fs.open(config.config.web_root == 1 ? '/tmp/ucentral/www-uspot/header.html' : '/usr/share/uspot/header', 'r'); | ||||||
|  | let header = file.read('all'); | ||||||
|  | file.close(); | ||||||
|  |  | ||||||
|  | file = fs.open(config.config.web_root == 1 ? '/tmp/ucentral/www-uspot/footer.html' : '/usr/share/uspot/footer', 'r'); | ||||||
|  | let footer = file.read('all'); | ||||||
|  | file.close(); | ||||||
|  |  | ||||||
|  | function PO(id, english) { | ||||||
|  | 	return english; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | return { | ||||||
|  | 	fs, | ||||||
|  | 	rtnl: require('rtnl'), | ||||||
|  | 	uam: require('uam'), | ||||||
|  | 	uci, | ||||||
|  | 	config, | ||||||
|  | 	header, | ||||||
|  | 	footer, | ||||||
|  |  | ||||||
|  | 	// wrapper for scraping external tools stdout | ||||||
|  | 	fs_popen: function(cmd) { | ||||||
|  | 		let stdout = fs.popen(cmd); | ||||||
|  | 	        if (!stdout) | ||||||
|  | 			return null; | ||||||
|  |  | ||||||
|  | 		let reply = null; | ||||||
|  | 		try { | ||||||
|  | 			reply = json(stdout.read('all')); | ||||||
|  | 		} catch(e) { | ||||||
|  |  | ||||||
|  | 		} | ||||||
|  | 		stdout.close(); | ||||||
|  | 		return reply; | ||||||
|  | 	}, | ||||||
|  |  | ||||||
|  | 	// give a client access to the internet | ||||||
|  | 	allow_client: function(ctx) { | ||||||
|  | 		ctx.ubus.call('spotfilter', 'client_set', { | ||||||
|  | 			"interface": "hotspot", | ||||||
|  | 			"address": replace(ctx.mac, '-', ':'), | ||||||
|  | 			"state": 1, | ||||||
|  | 			"dns_state": 1, | ||||||
|  | 			"accounting": [ "dl", "ul"], | ||||||
|  | 			"data": { | ||||||
|  | 				"connect": time() | ||||||
|  | 			} | ||||||
|  | 		}); | ||||||
|  | 		if (ctx.query_string.userurl) | ||||||
|  | 			include('redir.uc', { redir_location: ctx.query_string.userurl }); | ||||||
|  | 		else | ||||||
|  | 			include('allow.uc', ctx); | ||||||
|  | 	}, | ||||||
|  |  | ||||||
|  | 	// generate the default radius auth payload | ||||||
|  | 	radius_init: function(ctx) { | ||||||
|  | 		return { | ||||||
|  | 			server: sprintf('%s:%s:%s', this.config.radius.auth_server, this.config.radius.auth_port, this.config.radius.auth_secret), | ||||||
|  | 			acct_session: "0123456789", | ||||||
|  | 			client_ip: ctx.env.REMOTE_ADDR, | ||||||
|  | 			called_station: ctx.mac, | ||||||
|  | 			calling_station: this.config.uam.nasmac, | ||||||
|  | 			nas_ip: ctx.env.SERVER_ADDR, | ||||||
|  | 			nas_id: this.config.uam.nasid | ||||||
|  | 		}; | ||||||
|  | 	}, | ||||||
|  |  | ||||||
|  | 	radius_call: function(ctx, payload) { | ||||||
|  | 		let cfg = fs.open('/tmp/' + ctx.mac + '.json', 'w'); | ||||||
|  | 		cfg.write(payload); | ||||||
|  | 		cfg.close(); | ||||||
|  |  | ||||||
|  | 		return this.fs_popen('/usr/bin/radius-client /tmp/' + ctx.mac + '.json'); | ||||||
|  | 	}, | ||||||
|  |  | ||||||
|  | 	handle_request: function(env) { | ||||||
|  | 		let mac; | ||||||
|  | 		let form_data = {}; | ||||||
|  | 		let query_string = {}; | ||||||
|  | 		let post_data = ''; | ||||||
|  | 		let ctx = { env, header: this.header, footer: this.footer, mac, form_data, post_data, query_string, config: this.config, PO }; | ||||||
|  |  | ||||||
|  | 		// lookup the peers MAC | ||||||
|  | 		let macs = this.rtnl.request(this.rtnl.const.RTM_GETNEIGH, this.rtnl.const.NLM_F_DUMP, { }); | ||||||
|  | 		for (let m in macs) | ||||||
|  | 			if (m.dst == env.REMOTE_HOST) | ||||||
|  | 				ctx.mac = replace(m.lladdr, ':', '-'); | ||||||
|  |  | ||||||
|  | 		// if the MAC lookup failed, go to the error page | ||||||
|  | 		if (!ctx.mac) { | ||||||
|  | 			include('error.uc', ctx); | ||||||
|  | 			return NULL; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// check if a client is already connected | ||||||
|  | 		ctx.ubus = ubus.connect(); | ||||||
|  | 		let connected = ctx.ubus.call('spotfilter', 'client_get', { | ||||||
|  | 			'interface': 'hotspot', | ||||||
|  | 			'address': ctx.mac | ||||||
|  | 		}); | ||||||
|  | 		if (connected?.state) { | ||||||
|  | 			include('connected.uc', ctx); | ||||||
|  | 			return NULL; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// split QUERY_STRING | ||||||
|  | 		if (env.QUERY_STRING) | ||||||
|  | 			for (let chunk in split(env.QUERY_STRING, '&')) { | ||||||
|  | 				let m = match(chunk, /^([^=]+)=(.*)$/); | ||||||
|  | 				if (!m) continue; | ||||||
|  | 				ctx.query_string[m[1]] = replace(m[2], /%([[:xdigit:]][[:xdigit:]])/g, (m, h) => chr(hex(h) || 0x20)); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 		// recv POST data | ||||||
|  | 		if (env.CONTENT_LENGTH > 0) | ||||||
|  | 			for (let chunk = uhttpd.recv(64); chunk != null; chunk = uhttpd.recv(64)) | ||||||
|  | 				post_data += replace(chunk, /[^[:graph:]]/g, '.'); | ||||||
|  |  | ||||||
|  | 		// split POST data into an array | ||||||
|  | 		if (post_data) | ||||||
|  | 			for (let chunk in split(post_data, '&')) { | ||||||
|  | 				let var = split(chunk, '='); | ||||||
|  | 				if (length(var) != 2) | ||||||
|  | 					continue; | ||||||
|  | 				ctx.form_data[var[0]] = var[1]; | ||||||
|  | 			} | ||||||
|  | 		return ctx; | ||||||
|  | 	} | ||||||
|  | }; | ||||||
| @@ -2,103 +2,44 @@ | |||||||
|  |  | ||||||
| 'use strict'; | 'use strict'; | ||||||
|  |  | ||||||
| let fs = require('fs'); | push(REQUIRE_SEARCH_PATH, "/usr/share/uspot/*.uc"); | ||||||
| let rtnl = require('rtnl'); |  | ||||||
|  |  | ||||||
| let file = fs.open('/usr/share/uspot/header', 'r'); |  | ||||||
| let header = file.read('all'); |  | ||||||
| file.close(); |  | ||||||
|  |  | ||||||
| file = fs.open('/usr/share/uspot/footer', 'r'); |  | ||||||
| let footer = file.read('all'); |  | ||||||
| file.close(); |  | ||||||
|  |  | ||||||
| let uci = require('uci').cursor(); |  | ||||||
| let config = uci.get_all('uspot'); |  | ||||||
|  |  | ||||||
|  | let portal = require('common'); | ||||||
| let uam = require('uam'); | let uam = require('uam'); | ||||||
|  |  | ||||||
| // give a client access to the internet |  | ||||||
| function allow_client(ctx) { |  | ||||||
| 	system('ubus call spotfilter client_set \'{ "interface": "hotspot", "address": "' + replace(ctx.mac, '-', ':') + '", "state": 1, "dns_state": 1}\''); |  | ||||||
| 	if (ctx.query_string.userurl) |  | ||||||
| 		include('uam.uc', { uam_location: ctx.query_string.userurl }); |  | ||||||
| 	else |  | ||||||
| 		include('allow.uc', ctx); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // log the client in via radius | // log the client in via radius | ||||||
| function auth_client(ctx) { | function auth_client(ctx) { | ||||||
| 	let password; | 	let password; | ||||||
| 	let payload = { | 	let payload = portal.radius_init(ctx); | ||||||
| 		server: sprintf('%s:%s:%s',config.radius.auth_server, config.radius.auth_port, config.radius.auth_secret), |  | ||||||
| 		acct_session: "0123456789", |  | ||||||
| 		client_ip: ctx.env.REMOTE_ADDR, |  | ||||||
| 		called_station: ctx.mac, |  | ||||||
| 		calling_station: config.uam.nasmac, |  | ||||||
| 		nas_ip: ctx.env.SERVER_ADDR, |  | ||||||
| 		nas_id: config.uam.nasid |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	if (ctx.query_string.username && ctx.query_string.response) { | 	if (ctx.query_string.username && ctx.query_string.response) { | ||||||
| 		let challenge = uam.md5(config.uam.challenge, ctx.mac); | 		let challenge = uam.md5(portal.config.uam.challenge, ctx.mac); | ||||||
|  |  | ||||||
| 		payload.type = 'uam-chap-auth'; | 		payload.type = 'uam-chap-auth'; | ||||||
| 		payload.username = ctx.query_string.username; | 		payload.username = ctx.query_string.username; | ||||||
| 		payload.chap_password = ctx.query_string.response; | 		payload.chap_password = ctx.query_string.response; | ||||||
| 		if (config.uam.secret) | 		if (portal.config.uam.secret) | ||||||
| 			payload.chap_challenge = uam.chap_challenge(challenge, config.uam.uam_secret); | 			payload.chap_challenge = uam.chap_challenge(challenge, portal.config.uam.uam_secret); | ||||||
| 		else | 		else | ||||||
| 			payload.chap_challenge = challenge; | 			payload.chap_challenge = challenge; | ||||||
| 	} else if (ctx.query_string.username && ctx.query_string.password) { | 	} else if (ctx.query_string.username && ctx.query_string.password) { | ||||||
| 		payload.type = 'uam-auth'; | 		payload.type = 'uam-auth'; | ||||||
| 		payload.username = ctx.mac; | 		payload.username = ctx.mac; | ||||||
| 		payload.password = uam.password(uam.md5(config.uam.challenge, ctx.mac), ctx.query_string.password, config.uam.uam_secret); | 		payload.password = uam.password(uam.md5(portal.config.uam.challenge, ctx.mac), ctx.query_string.password, portal.config.uam.uam_secret); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	let cfg = fs.open('/tmp/' + ctx.mac + '.json', 'w'); |         let reply = portal.radius_call(ctx, payload); | ||||||
| 	cfg.write(payload); |  | ||||||
| 	cfg.close(); |  | ||||||
|  |  | ||||||
| 	let stdout = fs.popen('/usr/bin/radius-client /tmp/' + ctx.mac + '.json'); |  | ||||||
|         let reply; |  | ||||||
|         if (!stdout) { |  | ||||||
| 		request_start({ ...ctx, error: 1 }); |  | ||||||
| 		return; |  | ||||||
|         } |  | ||||||
| 	reply = json(stdout.read('all')); |  | ||||||
| 	stdout.close(); |  | ||||||
| 	if (reply['access-accept']) { | 	if (reply['access-accept']) { | ||||||
|                 allow_client(ctx); |                 portal.allow_client(ctx); | ||||||
|                 return; |                 return; | ||||||
|         } |         } | ||||||
| 	include('error.uc', ctx); | 	include('error.uc', ctx); | ||||||
| } | } | ||||||
|  |  | ||||||
| global.handle_request = function(env) { | global.handle_request = function(env) { | ||||||
| 	let mac; | 	let ctx = portal.handle_request(env); | ||||||
| 	let form_data = {}; |  | ||||||
| 	let query_string = {}; |  | ||||||
| 	let post_data = ''; |  | ||||||
| 	let ctx = { env, header, footer, mac, form_data, post_data, query_string, config }; |  | ||||||
|  |  | ||||||
| 	// lookup the peers MAC | 	if (ctx) | ||||||
| 	let macs = rtnl.request(rtnl.const.RTM_GETNEIGH, rtnl.const.NLM_F_DUMP, { }); |  | ||||||
| 	for (let m in macs) |  | ||||||
| 		if (m.dst == env.REMOTE_HOST) |  | ||||||
| 			ctx.mac = replace(m.lladdr, ':', '-'); |  | ||||||
|  |  | ||||||
| 	// if the MAC lookup failed, go to the error page |  | ||||||
| 	if (!ctx.mac) |  | ||||||
| 		include('error.uc', ctx); |  | ||||||
|  |  | ||||||
| 	// split QUERY_STRING |  | ||||||
| 	if (env.QUERY_STRING) |  | ||||||
| 		for (let chunk in split(env.QUERY_STRING, '&')) { |  | ||||||
| 			let m = match(chunk, /^([^=]+)=(.*)$/); |  | ||||||
| 			if (!m) continue; |  | ||||||
| 			ctx.query_string[m[1]] = replace(m[2], /%([[:xdigit:]][[:xdigit:]])/g, (m, h) => chr(hex(h) || 0x20)); |  | ||||||
| 		} |  | ||||||
| 		auth_client(ctx); | 		auth_client(ctx); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2,46 +2,12 @@ | |||||||
|  |  | ||||||
| 'use strict'; | 'use strict'; | ||||||
|  |  | ||||||
| let fs = require('fs'); | push(REQUIRE_SEARCH_PATH, "/usr/share/uspot/*.uc"); | ||||||
| let rtnl = require('rtnl'); | let portal = require('common'); | ||||||
| let uam = require('uam'); |  | ||||||
|  |  | ||||||
| let uci = require('uci').cursor(); |  | ||||||
| let config = uci.get_all('uspot'); |  | ||||||
|  |  | ||||||
| let file = fs.open(config.config.web_root == 1 ? '/tmp/ucentral/www-uspot/header.html' : '/usr/share/uspot/header', 'r'); |  | ||||||
| let header = file.read('all'); |  | ||||||
| file.close(); |  | ||||||
|  |  | ||||||
| file = fs.open(config.config.web_root == 1 ? '/tmp/ucentral/www-uspot/footer.html' : '/usr/share/uspot/footer', 'r'); |  | ||||||
| let footer = file.read('all'); |  | ||||||
| file.close(); |  | ||||||
|  |  | ||||||
| // fs.open wrapper |  | ||||||
| function fs_open(cmd) { |  | ||||||
| 	let stdout = fs.popen(cmd); |  | ||||||
|         if (!stdout) |  | ||||||
| 		return null; |  | ||||||
|  |  | ||||||
| 	let reply = null; |  | ||||||
| 	try { |  | ||||||
| 		reply = json(stdout.read('all')); |  | ||||||
| 	} catch(e) { |  | ||||||
|  |  | ||||||
| 	} |  | ||||||
| 	stdout.close(); |  | ||||||
| 	return reply; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // give a client access to the internet |  | ||||||
| function allow_client(ctx) { |  | ||||||
| 	system('ubus call spotfilter client_set \'{ "interface": "hotspot", "address": "' + replace(ctx.mac, '-', ':') + '", "state": 1, "dns_state": 1}\''); |  | ||||||
| 	include('allow.uc', ctx); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // delegate an initial connection to the correct handler | // delegate an initial connection to the correct handler | ||||||
| function request_start(ctx) { | function request_start(ctx) { | ||||||
| 	switch (config?.config?.auth_mode) { | 	switch (portal.config?.config?.auth_mode) { | ||||||
| 	case 'click-to-continue': | 	case 'click-to-continue': | ||||||
| 		include('click.uc', ctx); | 		include('click.uc', ctx); | ||||||
| 		return; | 		return; | ||||||
| @@ -52,17 +18,17 @@ function request_start(ctx) { | |||||||
| 		include('radius.uc', ctx); | 		include('radius.uc', ctx); | ||||||
| 		return; | 		return; | ||||||
| 	case 'uam': | 	case 'uam': | ||||||
| 		ctx.uam_location = config.uam.uam_server + | 		ctx.redir_location = portal.config.uam.uam_server + | ||||||
| 			'?res=notyet' + | 			'?res=notyet' + | ||||||
| 			'&uamip=' + ctx.env.SERVER_ADDR + | 			'&uamip=' + ctx.env.SERVER_ADDR + | ||||||
| 			'&uamport=' + config.uam.uam_port + | 			'&uamport=' + portal.config.uam.uam_port + | ||||||
| 			'&challenge=' + uam.md5(config.uam.challenge, ctx.mac) + | 			'&challenge=' + portal.uam.md5(portal.config.uam.challenge, ctx.mac) + | ||||||
| 			'&mac=' + replace(ctx.mac, ':', '-') + | 			'&mac=' + replace(ctx.mac, ':', '-') + | ||||||
| 			'&ip=' + ctx.env.REMOTE_ADDR + | 			'&ip=' + ctx.env.REMOTE_ADDR + | ||||||
| 			'&called=' + config.uam.nasmac + | 			'&called=' + portal.config.uam.nasmac + | ||||||
| 			'&nasid=' + config.uam.nasid; | 			'&nasid=' + portal.config.uam.nasid; | ||||||
| 		ctx.uam_location += '&md=' + uam.md5(ctx.uam_location, config.uam.uam_secret); | 		ctx.redir_location += '&md=' + portal.uam.md5(ctx.uam_location, portal.config.uam.uam_secret); | ||||||
| 		include('uam.uc', ctx); | 		include('redir.uc', ctx); | ||||||
| 		return; | 		return; | ||||||
| 	default: | 	default: | ||||||
| 		include('error.uc', ctx); | 		include('error.uc', ctx); | ||||||
| @@ -73,7 +39,7 @@ function request_start(ctx) { | |||||||
| // delegate a local click-to-continue authentication | // delegate a local click-to-continue authentication | ||||||
| function request_click(ctx) { | function request_click(ctx) { | ||||||
| 	// make sure this is the right auth_mode | 	// make sure this is the right auth_mode | ||||||
| 	if (config?.config?.auth_mode != 'click-to-continue') { | 	if (portal.config?.config?.auth_mode != 'click-to-continue') { | ||||||
| 		include('error.uc', ctx); | 		include('error.uc', ctx); | ||||||
|                 return; |                 return; | ||||||
| 	} | 	} | ||||||
| @@ -83,13 +49,13 @@ function request_click(ctx) { | |||||||
| 		request_start({ ...ctx, error: 1 }); | 		request_start({ ...ctx, error: 1 }); | ||||||
|                 return; |                 return; | ||||||
| 	} | 	} | ||||||
| 	allow_client(ctx); | 	portal.allow_client(ctx); | ||||||
| } | } | ||||||
|  |  | ||||||
| // delegate a local username/password authentication | // delegate a local username/password authentication | ||||||
| function request_credentials(ctx) { | function request_credentials(ctx) { | ||||||
| 	// make sure this is the right auth_mode | 	// make sure this is the right auth_mode | ||||||
| 	if (config?.config?.auth_mode != 'credentials') { | 	if (portal/config?.config?.auth_mode != 'credentials') { | ||||||
| 		include('error.uc', ctx); | 		include('error.uc', ctx); | ||||||
|                 return; |                 return; | ||||||
| 	} | 	} | ||||||
| @@ -101,8 +67,8 @@ function request_credentials(ctx) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// check if the credentials are valid | 	// check if the credentials are valid | ||||||
| 	for (let k in config) { | 	for (let k in portal.config) { | ||||||
| 		let cred = config[k]; | 		let cred = portal.config[k]; | ||||||
|  |  | ||||||
| 		if (cred['.type'] != 'credentials') | 		if (cred['.type'] != 'credentials') | ||||||
| 			continue; | 			continue; | ||||||
| @@ -110,7 +76,7 @@ function request_credentials(ctx) { | |||||||
| 		    ctx.form_data.password != cred.password) | 		    ctx.form_data.password != cred.password) | ||||||
| 			continue; | 			continue; | ||||||
|  |  | ||||||
| 		allow_client(ctx); | 		portal.allow_client(ctx); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -121,7 +87,7 @@ function request_credentials(ctx) { | |||||||
| // delegate a radius username/password authentication | // delegate a radius username/password authentication | ||||||
| function request_radius(ctx) { | function request_radius(ctx) { | ||||||
| 	// make sure this is the right auth_mode | 	// make sure this is the right auth_mode | ||||||
| 	if (config?.config?.auth_mode != 'radius') { | 	if (portal.config?.config?.auth_mode != 'radius') { | ||||||
| 		include('error.uc', ctx); | 		include('error.uc', ctx); | ||||||
|                 return; |                 return; | ||||||
| 	} | 	} | ||||||
| @@ -132,29 +98,15 @@ function request_radius(ctx) { | |||||||
|                 return; |                 return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	let cfg = fs.open('/tmp/' + ctx.mac + '.json', 'w'); | 	// trigger the radius auth | ||||||
| 	cfg.write({ | 	let payload = radius_init(ctx); | ||||||
| 		type: 'auth', | 	payload.type = 'auth'; | ||||||
| 		server: sprintf('%s:%s:%s',config.radius.auth_server, config.radius.auth_port, config.radius.auth_secret), | 	payload.username = ctx.form_data.username; | ||||||
| 		username: ctx.form_data.username, | 	payload.password = ctx.form_data.password; | ||||||
| 		password: ctx.form_data.password, |  | ||||||
| 		acct_session: "0123456789", |  | ||||||
| 		client_ip: ctx.env.REMOTE_ADDR, |  | ||||||
| 		called_station: ctx.mac, |  | ||||||
| 		nas_ip: ctx.env.SERVER_ADDR, |  | ||||||
| 	}); |  | ||||||
| 	cfg.close(); |  | ||||||
|  |  | ||||||
| 	let stdout = fs.popen('/usr/bin/radius-client /tmp/' + ctx.mac + '.json'); |         let reply = portal.radius_call(ctx, payload); | ||||||
|         let reply; |  | ||||||
|         if (!stdout) { |  | ||||||
| 		request_start({ ...ctx, error: 1 }); |  | ||||||
| 		return; |  | ||||||
|         } |  | ||||||
| 	reply = json(stdout.read('all')); |  | ||||||
| 	stdout.close(); |  | ||||||
| 	if (reply['access-accept']) { | 	if (reply['access-accept']) { | ||||||
|                 allow_client(ctx); |                 portal.allow_client(ctx); | ||||||
|                 return; |                 return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -162,56 +114,10 @@ function request_radius(ctx) { | |||||||
| 	request_start({ ...ctx, error: 1 }); | 	request_start({ ...ctx, error: 1 }); | ||||||
| } | } | ||||||
|  |  | ||||||
| function PO(id, english) { |  | ||||||
| 	return english; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| global.handle_request = function(env) { | global.handle_request = function(env) { | ||||||
| 	let mac; | 	let ctx = portal.handle_request(env); | ||||||
| 	let form_data = {}; |  | ||||||
| 	let query_string = {}; |  | ||||||
| 	let post_data = ''; |  | ||||||
| 	let ctx = { env, header, footer, mac, form_data, post_data, query_string, config, PO }; |  | ||||||
|  |  | ||||||
| 	// lookup the peers MAC |  | ||||||
| 	let macs = rtnl.request(rtnl.const.RTM_GETNEIGH, rtnl.const.NLM_F_DUMP, { }); |  | ||||||
| 	for (let m in macs) |  | ||||||
| 		if (m.dst == env.REMOTE_HOST) |  | ||||||
| 			ctx.mac = replace(m.lladdr, ':', '-'); |  | ||||||
|  |  | ||||||
| 	// if the MAC lookup failed, go to the error page |  | ||||||
| 	if (!ctx.mac) |  | ||||||
| 		include('error.uc', ctx); |  | ||||||
|  |  | ||||||
| 	// check if a client is already connected |  | ||||||
| 	let connected = fs_open('ubus call spotfilter client_get \'{"interface": "hotspot", "address": "' + ctx.mac + '"}\''); |  | ||||||
| 	if (connected?.state) { |  | ||||||
| 		include('connected.uc', ctx); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// split QUERY_STRING |  | ||||||
| 	if (env.QUERY_STRING) |  | ||||||
| 		for (let chunk in split(env.QUERY_STRING, '&')) { |  | ||||||
| 			let m = match(chunk, /^([^=]+)=(.*)$/); |  | ||||||
| 			if (!m) continue; |  | ||||||
| 			ctx.query_string[m[1]] = replace(m[2], /%([[:xdigit:]][[:xdigit:]])/g, (m, h) => chr(hex(h) || 0x20)); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 	// recv POST data |  | ||||||
| 	if (env.CONTENT_LENGTH > 0) |  | ||||||
| 		for (let chunk = uhttpd.recv(64); chunk != null; chunk = uhttpd.recv(64)) |  | ||||||
| 			post_data += replace(chunk, /[^[:graph:]]/g, '.'); |  | ||||||
|  |  | ||||||
| 	// split POST data into an array |  | ||||||
| 	if (post_data) |  | ||||||
| 		for (let chunk in split(post_data, '&')) { |  | ||||||
| 			let var = split(chunk, '='); |  | ||||||
| 			if (length(var) != 2) |  | ||||||
| 				continue; |  | ||||||
| 			ctx.form_data[var[0]] = var[1]; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
|  | 	if (ctx) | ||||||
| 		switch (ctx.form_data.action) { | 		switch (ctx.form_data.action) { | ||||||
| 		case 'credentials': | 		case 'credentials': | ||||||
| 			request_credentials(ctx); | 			request_credentials(ctx); | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| Status: 302 Found | Status: 302 Found | ||||||
| Location: {{ uam_location }} | Location: {{ redir_location }} | ||||||
| Content-Type: text/html | Content-Type: text/html | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
		Reference in New Issue
	
	Block a user
	 John Crispin
					John Crispin