summaryrefslogtreecommitdiffstats
path: root/auth/shadow.lua
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2012-12-13 21:28:59 +0100
committerNatanael Copa <ncopa@alpinelinux.org>2012-12-13 21:28:59 +0100
commitc7fcfd5a2dfff5bf99ed00515173d2f8917f9c57 (patch)
treeb91bb9f0c562fadc1a23c8da6d1bc7daa7350609 /auth/shadow.lua
parent9b0cffd1c46ebc77430d19fa173a848450512f6a (diff)
downloadprivsep-c7fcfd5a2dfff5bf99ed00515173d2f8917f9c57.tar.bz2
privsep-c7fcfd5a2dfff5bf99ed00515173d2f8917f9c57.tar.xz
auth: add inital authentication modules and a test
Diffstat (limited to 'auth/shadow.lua')
-rw-r--r--auth/shadow.lua70
1 files changed, 70 insertions, 0 deletions
diff --git a/auth/shadow.lua b/auth/shadow.lua
new file mode 100644
index 0000000..3a4a534
--- /dev/null
+++ b/auth/shadow.lua
@@ -0,0 +1,70 @@
+
+local posix = require('posix')
+local db = {}
+
+db.file = "/etc/shadow"
+db.fields = { 'name', 'passwd', 'lastchanged', 'minimum', 'maximum', 'warn', 'inactive', 'expire', 'dummy' }
+
+function db.splitent(line)
+ local ent = {}
+ local i = 1
+ for value in string.gmatch(line or "", "([^:]*):?") do
+ ent[db.fields[i]] = value
+ i = i + 1
+ end
+ return ent
+end
+
+function db.getent(username)
+ local f = io.open(db.file)
+ if f == nil then
+ return nil
+ end
+ for line in f:lines() do
+ local ent = db.splitent(line)
+ if ent.name == username then
+ f:close()
+ return ent
+ end
+ end
+ f:close()
+ return nil, db.file..": user '"..tostring(username).."' not found"
+end
+
+function db.verify_passwd(cleartext, pwhash)
+ --[[
+ from man crypt(3):
+
+ If salt is a character string starting with the characters "$id$" fol-
+ lowed by a string terminated by "$":
+
+ $id$salt$encrypted
+
+ then instead of using the DES machine, id identifies the encryption
+ method used and this then determines how the rest of the password
+ string is interpreted. The following values of id are supported:
+
+ ID | Method
+ ---------------------------------------------------------
+ 1 | MD5
+ 2a | Blowfish (not in mainline glibc; added in some
+ | Linux distributions)
+ 5 | SHA-256 (since glibc 2.7)
+ 6 | SHA-512 (since glibc 2.7)
+ ]]--
+ local algo_salt, hash = string.match(pwhash, "^(%$%d%$[a-zA-Z0-9./]+%$)(.*)")
+ local userhash = posix.crypt(cleartext, algo_salt)
+ print("user hash:", userhash)
+ print("db hash:", pwhash)
+ return (pwhash == userhash)
+end
+
+function db.authenticate(username, cleartextpw)
+ local ent = db.getent(username)
+ if ent == nil then
+ return nil, tostring(username)..": no such user"
+ end
+ return db.verify_passwd(cleartextpw, ent.passwd)
+end
+
+return db