summaryrefslogtreecommitdiffstats
path: root/lib/authenticator-plaintext.lua
blob: c1db54aab242faa2a42559bcac935f8c3a3c911c (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
--[[ ACF Logon/Logoff authenticator that uses plaintext files
	Copyright (c) 2007 Nathan Angelacos
	GPL2 license

Rather than come up with a way to name fields in the plaintext files, we
create a different file for each field.

]]--

local mymodule = {}

fs = require("acf.fs")
format = require("acf.format")
posix = require("posix")

mymodule.list_fields = function(self, tabl)
	if not self or not tabl or tabl == "" then
		return {}
	end

	local fields = {}
	for file in fs.find(".*"..format.escapemagiccharacters(tabl), self.conf.confdir) do
		local field = string.match(file, self.conf.confdir.."(.*)"..format.escapemagiccharacters(tabl).."$")
		-- We only allow one level of directory traversal
		if field and fs.is_file(file) and not string.find(field, "/.*/") then
			fields[#fields + 1] = field
		end
	end
	return fields
end

mymodule.read_field = function(self, tabl, field)
	if not self or not tabl or tabl == "" or not field or string.find(field, "^..*/.*/") then
		return nil
	end

	local row = {}
	-- open our password file
	local passwd_path = self.conf.confdir .. field .. tabl
	local f = io.open(passwd_path)
	if f then
		local m = (f:read("*all")  or "" ).. "\n"
		f:close()

		for l in string.gmatch(m, "([^\n]+)\n?") do
			local a = {}
			a.id, a.entry = string.match(l, "^([^:=]*)[:=](.*)")
			if a.id then
				table.insert(row, a)
			end
		end
		return row
	else	
		return nil
	end
end

mymodule.delete_field = function(self, tabl, field)
	if not self or not tabl or tabl == "" or not field or string.find(field, "^..*/.*/") then
		return false
	end
	local passwd_path = self.conf.confdir .. field .. tabl
	os.remove(passwd_path)
	return true
end

mymodule.write_entry = function(self, tabl, field, id, entry)
	if not self or not tabl or tabl == "" or not field or string.find(field, "^..*/.*/") or not id or not entry then
		return false
	end

	-- Set path to passwordfile
	local passwd_path = self.conf.confdir .. field .. tabl
	-- Write the newline into the file
	if fs.is_file(passwd_path) == false then fs.create_file(passwd_path) posix.chmod(passwd_path, "rw-------") end
	if fs.is_file(passwd_path) == false then return false end
	local passwdfilecontent = fs.read_file_as_array(passwd_path) or {}
	local output = {id .. ":" .. entry}
	for k,v in pairs(passwdfilecontent) do
		if not ( string.match(v, "^".. format.escapemagiccharacters(id) .. "[:=]") ) and not string.match(v, "^%s*$") then
			table.insert(output, v)
		end
	end
	fs.write_file(passwd_path, table.concat(output, "\n"))
	return true
end

mymodule.read_entry = function(self, tabl, field, id)
	if not self or not tabl or tabl == "" or not field or string.find(field, "^..*/.*/") or not id then
		return nil
	end
	-- Set path to passwordfile
	local passwd_path = self.conf.confdir .. field .. tabl
	local passwdfilecontent = fs.read_file_as_array(passwd_path) or {}
	local entry
	for k,v in pairs(passwdfilecontent) do
		if string.match(v, "^".. format.escapemagiccharacters(id) .. "[:=]") then
			return string.match(v, "^"..format.escapemagiccharacters(id).."[:=](.*)")
		end
	end
	return nil
end

mymodule.delete_entry = function (self, tabl, field, id)
	if not self or not tabl or tabl == "" or not field or string.find(field, "^..*/.*/") or not id then
		return false
	end
	local result = false
	
	local passwd_path = self.conf.confdir .. field .. tabl
	local passwdfilecontent = fs.read_file_as_array(passwd_path) or {}
	local output = {}
	for k,v in pairs(passwdfilecontent) do
		if not ( string.match(v, "^".. format.escapemagiccharacters(id) .. "[:=]") ) and not string.match(v, "^%s*$") then
			table.insert(output, v)
		else
			result = true
		end
	end
	
	--Save the updated table
	if result == true then
		fs.write_file(passwd_path, table.concat(output,"\n"))
	end

	-- If deleting the main field, delete all other fields also
	if field == "" then
		local fields = mymodule.list_fields(self, tabl)
		for i,fld in ipairs(fields) do
			if "" ~= fld then
				mymodule.delete_entry(self, tabl, fld, id)
			end
		end
	end

	return result
end

return mymodule