summaryrefslogtreecommitdiffstats
path: root/cgi-bin/provisioning.cgi
blob: bf7a6a2ea93c715d436d8a04a56ffe08d05fd19c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#!/usr/bin/haserl --shell=lua

<%
require "posix"

local path_info = ENV["PATH_INFO"] or ENV["REQUEST_URI"] or ""
local root = ENV["DOCUMENT_ROOT"] or ""
local request_method = ENV["REQUEST_METHOD"] or ""
local user_agent = ENV["HTTP_USER_AGENT"] or ""
local ip_address = ENV["REMOTE_ADDR"] or ""

local log = io.open("/var/log/provisioning.log", "a+")
log:write("Running provisioning.cgi ".. os.date() .. "\n")
log:write("Processing a "..request_method.." on "..path_info.."\n")
--	for a,b in pairs(ENV) do log:write(a.."=", b,"\n") end

local ACL_FILE = "/etc/provisioning/acl.conf"

function acl_check (...)
	local allowed = false
	local f = io.open(ACL_FILE)
	if f then
		for line in f:lines() do
			if string.match(user_agent, line) or string.match(ip_address, line) then
				log:write("ALLOW MATCH FOUND " .. line .. "\n")
				allowed = true
				break
			end
		end
		f:close()
	end
	if not allowed then
		log:write("ALLOW MATCH NOT FOUND. ACCESS DENIED\n")
	end
	return allowed
end

function http_code (code)
	log:write("HTTP code processed " .. code .. "\n")
	if code == 200 then
		io.stdout:write("Status: 200 OK\n")
		io.stdout:write("Content-Type: \n\n")
	elseif code == 204 then
		io.stdout:write("Status: 204 No Content\n")
		io.stdout:write("Content-Type: \n\n")
	elseif code == 404 then
		io.stdout:write("Status: 404 Not Found\n")
		io.stdout:write("Content-Type: \n\n")
		io.stdout:write("Status: 404 Not Found\n")
		io.stdout:write("\n")
	elseif code == 403 then
		io.stdout:write("Status: 403 Forbidden\n")
		io.stdout:write("Content-Type: \n\n")
		io.stdout:write("Status: 403 Forbidden\n")
		io.stdout:write("\n")
	else
		io.stdout:write("Status: 400 Bad Request\n")
		io.stdout:write("Content-Type: \n\n")
		io.stdout:write("Status: 400 Bad Request\n")
		io.stdout:write("\n")
	end
end

--------------------------------------------------------------------------------------------------------------
-- Code Begins Here --
--------------------------------------------------------------------------------------------------------------
if not acl_check() then
	http_code(403)
	log:close()
	os.exit()
end

local basename = posix.basename(path_info)
local mac = string.match(basename, "%x%x%x%x%x%x%x%x%x%x%x%x")

if ( request_method == "GET" ) then
	-- don't even bother for files that don't contain a MAC
	if mac == nil then 
		http_code(404)
		log:close()
		os.exit()
	end

        -- If it's a Polycom, 404 the MAC.cfg, MAC-directory.xml, MAC-license, MAC-phone.cfg, and MAC-web.cfg files
	local f = string.match(basename, mac.."(.*)")
        if string.match(user_agent, "Polycom") and (f==".cfg" or f=="-directory.xml" or f=="-license.cfg" or f=="-phone.cfg" or f=="-web.cfg" or mac=="000000000000") then
		http_code(404)
		log:close()
		os.exit()
        end

	log:write("Checking PROV Table for results\n")
	-- Load the ACF mvc
	local PATH = package.path
	package.path = "/usr/share/acf/www/cgi-bin/?.lua;" .. package.path
	require("mvc")
	package.path = PATH
	-- We'll use the cli controller, but change the view resolver to call the template
	local pathinfo = ENV.PATH_INFO
	FRAMEWORK=mvc:new()
	FRAMEWORK:read_config("acf")
	APP=FRAMEWORK:new("acf_cli")
	APP.view_resolver = function(self)
		return function (data)
			if not data.errtxt and data.value.values and data.value.values.value.device and data.value.values.value.device.template then
				local func = haserl.loadfile(data.value.values.value.device.template)
				func(data.value.values.value)
			else
				if data.errtxt then
				APP.logevent("data.errtxt")
				elseif not data.value.values then
				APP.logevent("not data.value.values")
				elseif not data.value.values.value.device then
				APP.logevent("not data.value.values.value.device")
				elseif not data.value.values.value.device.template then
				APP.logevent("not data.value.values.value.device.template")
				end
				http_code(404)
			end
		end
	end
	-- Set up the action and parameters
	ENV.PATH_INFO = "/provisioning/provisioning/getfile"
	APP.clientdata = {mac=mac, ip=ip_address, agent=user_agent}
	-- Dispatch the command
	APP:dispatch()
	APP:destroy()
	FRAMEWORK:destroy()

	ENV.PATH_INFO = pathinfo
elseif ( request_method == "PUT" ) then
	local data = io.stdin:read("*all")

	log:write("Checking PROV Table for results\n")
	-- Load the ACF mvc
	local PATH = package.path
	package.path = "/usr/share/acf/www/cgi-bin/?.lua;" .. package.path
	require("mvc")
	package.path = PATH
	-- We'll use the cli controller, but change the view resolver to report HTTP code
	local pathinfo = ENV.PATH_INFO
	FRAMEWORK=mvc:new()
	FRAMEWORK:read_config("acf")
	APP=FRAMEWORK:new("acf_cli")
	APP.view_resolver = function(self)
		return function (data)
			if data.errtxt then
				http_code(400)
			else
				http_code(200)
			end
		end
	end
	-- Set up the action and parameters
	ENV.PATH_INFO = "/provisioning/provisioning/putfile"
	APP.clientdata = {file=path_info, root=root, data=data, ip=ip_address, agent=user_agent}
	-- Dispatch the command
	APP:dispatch()
	APP:destroy()
	FRAMEWORK:destroy()

	ENV.PATH_INFO = pathinfo
end
log:close() 
%>