tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Shipping SSL certificates in the base system



On Tue, Jul 11, 2017 at 10:31:59PM -0400, Thor Lancelot Simon wrote:
> Captive-portal login is a very real problem.  How best to solve it otherwise?
> Remember, small embedded systems (easily supported by adding additional sets
> using our existing framework) are within scope.

If anyone wants to try it out, I don't have a captive portal at home
(thankfully), fetch pkgsrc/*/lua-socket and try the attached.

Some tinkering may be needed.
#!/usr/pkg/bin/lua5.2

-- if a captive portal exists
--   extract first action url
--   submit it a username & password

-- CAVEATS:
-- assumes the first 'action' url is the right one
-- assumes the fields are called 'username' and 'password'

-- Public domain

local io = require("io")
local http = require("socket.http")
local ltn12 = require("ltn12")
local url = require("socket.url")

function usage()
	print("Usage: captive_portal username password [url]")
end

-- Captive portals redirect normal URL accesses
function find_captive(test_url)
	local response_body = {}
	local res, code, headers = http.request {
		url = test_url,
		redirect = false,
		sink = ltn12.sink.table(response_body)
	}

	if (tonumber(code) ~= nil) and (type(headers.location) == "string") and (code < 400) and (code >= 300) then
		return headers.location
	else
		return nil
	end
end

-- Given a portal page, return the form submit URL
-- XXX assumes the first action="" is the valid one.
function find_action_page(portal_url)
	local portal_html = http.request(portal_url)
	print("html")
	print(html)
	local action_url = portal_html:match('[Aa][Cc][Tt][Ii][Oo][Nn]%s*=%s*"([^"]*)"')

	if action_url == nil then
		return nil
	end

	print("DEBUG action url: " .. action_url)
	print("DEBUG absolute url: " ..url.absolute(portal_url, action_url))
	return url.absolute(portal_url, action_url)
end

function submit_credentials(username, password, action_url)
	local request_body = "login=" .. url.escape(username) .. "&password=" .. url.escape(password)
	local response_body = { }

	local res, code, response_headers = http.request {
		url = action_url;
		method = "POST";
		headers = {
		  ["Content-Type"] = "application/x-www-form-urlencoded";
		  ["Content-Length"] = #request_body;
		};
		source = ltn12.source.string(request_body);
		sink = ltn12.sink.table(response_body)
	}
	print(response_body[1])
end

function main()

	if (#arg < 2) then
		usage()
		os.exit()
	end

	local username = arg[1]
	local password = arg[2]
	local normally_working_url = "http://www.google.com";

	if (#arg > 2) then
		normally_working_url = arg[3]
	end

	local portal_url = find_captive(normally_working_url)

	if portal_url == nil then
		print("Not a captive portal")
		os.exit()
	end

	local action_url = find_action_page(portal_url)

	if action_url == nil then
		print("Didn't find a submit URL")
		os.exit()
	end

	submit_credentials(username, password, action_url)
end

main()


Home | Main Index | Thread Index | Old Index