[PATCH] LuCI: implement TLS client certificate authentication
Luka Logar
luka.logar at cifra.si
Fri Feb 19 15:01:52 EST 2021
When available, pass TLS client certificate data (subject name & cert hash) to the rpcd daemon
for authentication (as username and password). Add an extra mode='cert' parameter, so the rpcd
is aware they come from certificate and are treated accordingly
Signed-off-by: Luka Logar <luka.logar at cifra.si>
---
.../luasrc/controller/admin/index.lua | 3 +++
modules/luci-base/luasrc/dispatcher.lua | 24 +++++++++++++++++--
modules/luci-base/luasrc/view/error401.htm | 6 +++++
modules/luci-base/luasrc/view/logout.htm | 6 +++++
4 files changed, 37 insertions(+), 2 deletions(-)
create mode 100644 modules/luci-base/luasrc/view/error401.htm
create mode 100644 modules/luci-base/luasrc/view/logout.htm
diff --git a/modules/luci-base/luasrc/controller/admin/index.lua b/modules/luci-base/luasrc/controller/admin/index.lua
index 736d0cdcc..5167ea952 100644
--- a/modules/luci-base/luasrc/controller/admin/index.lua
+++ b/modules/luci-base/luasrc/controller/admin/index.lua
@@ -14,6 +14,9 @@ function action_logout()
luci.http.header("Set-Cookie", "sysauth=%s; expires=%s; path=%s" %{
'', 'Thu, 01 Jan 1970 01:00:00 GMT', dsp.build_url()
})
+
+ luci.template.render("logout")
+ return
end
luci.http.redirect(dsp.build_url())
diff --git a/modules/luci-base/luasrc/dispatcher.lua b/modules/luci-base/luasrc/dispatcher.lua
index 44c17c85f..f0229dba9 100644
--- a/modules/luci-base/luasrc/dispatcher.lua
+++ b/modules/luci-base/luasrc/dispatcher.lua
@@ -546,11 +546,12 @@ local function session_retrieve(sid, allowed_users)
return nil, nil, nil
end
-local function session_setup(user, pass)
+local function session_setup(user, pass, mode)
local login = util.ubus("session", "login", {
username = user,
password = pass,
- timeout = tonumber(luci.config.sauth.sessiontime)
+ timeout = tonumber(luci.config.sauth.sessiontime),
+ mode = mode
})
local rp = context.requestpath
@@ -866,6 +867,25 @@ function dispatch(request)
end
end
+ if not (sid and sdat and sacl) and auth.login then
+ local user = http.getenv("HTTPS_CLIENT_CERT_SN")
+ local pass = http.getenv("HTTPS_CLIENT_CERT_SHA256")
+
+ if user and pass then
+ sid, sdat, sacl = session_setup(user, pass, "cert")
+
+ if not sid then
+ http.status(401, "Unauthorized")
+ tpl.render("error401")
+ return
+ end
+
+ http.header("Set-Cookie", 'sysauth=%s; path=%s; SameSite=Strict; HttpOnly; secure' %{
+ sid, build_url()
+ })
+ end
+ end
+
if not (sid and sdat and sacl) and auth.login then
local user = http.getenv("HTTP_AUTH_USER")
local pass = http.getenv("HTTP_AUTH_PASS")
diff --git a/modules/luci-base/luasrc/view/error401.htm b/modules/luci-base/luasrc/view/error401.htm
new file mode 100644
index 000000000..e6e18e5ad
--- /dev/null
+++ b/modules/luci-base/luasrc/view/error401.htm
@@ -0,0 +1,6 @@
+<%#
+ Copyright 2021 Luka Logar <luka.logar at iname.com>
+ Licensed to the public under the Apache License 2.0.
+-%>
+
+<h2 name="content">401 <%:Unauthorized%></h2>
diff --git a/modules/luci-base/luasrc/view/logout.htm b/modules/luci-base/luasrc/view/logout.htm
new file mode 100644
index 000000000..fb38ed51d
--- /dev/null
+++ b/modules/luci-base/luasrc/view/logout.htm
@@ -0,0 +1,6 @@
+<%#
+ Copyright 2021 Luka Logar <luka.logar at iname.com>
+ Licensed to the public under the Apache License 2.0.
+-%>
+
+<h2 name="content"><%:User logged out, please close the browser window%></h2>
--
2.25.1
More information about the openwrt-devel
mailing list