From patchwork Fri Feb 19 20:01:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luka Logar X-Patchwork-Id: 1442440 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.openwrt.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=WcuTPKJh; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=cifra.si header.i=@cifra.si header.a=rsa-sha256 header.s=dkim header.b=khXcMmI5; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Dj2bd3ttdz9sW3 for ; Sat, 20 Feb 2021 07:04:28 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:To:From: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Owner; bh=PVnKYCIlgr+S79ZDBzGbhyriqXeJW2v1v4t2CNJHJA4=; b=WcuTPKJh1aefnDaS584jvKha3H qQItTmTwY1vcftvcAWTSXRyJnk1mJy1EGl2GTZ8iTioJTmuY/J7TJvSeDE9QKfjA5wJvevPbsWJE5 20mC5IYfUUByoiFR///EDGjj6FR4tuNo/lsY8x2r0Mf8BVWzzbRgOZ0kfF645qBV+J9MxT3NqgNaF RZjZNr4bEpNVipddP4aOt8LAskGgqXVriRBA3cUTc5D+XGYkNNwPDXh7R2mrK4n0pwAdxx4wXErLc EO0V+bC+WdM0uauTb/7tz68spm31ZSGnk4BVYLqk07c0eoHAt80AjdTZxKNRcHbAyCn2shAeRkF9b OvP7NXhw==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1lDByh-000143-5m; Fri, 19 Feb 2021 20:02:15 +0000 Received: from cifra.si ([84.255.231.188] helo=mail.cifra.si) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1lDByc-00012k-Uu for openwrt-devel@lists.openwrt.org; Fri, 19 Feb 2021 20:02:12 +0000 dkim-signature: v=1; a=rsa-sha256; d=cifra.si; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From:Subject:Date:Message-ID:To:CC:MIME-Version:Content-Transfer-Encoding; bh=836IgrcmaVJI6GAb5daBVM/4Y8f6eeWPoJNyouLcpLE=; b=khXcMmI5itfBE4rqIsAIwZDT2KEL4YWqvz9hCQtGxyXPshZdQnaUJcP0nP/7Y+/t9TpRO5sB/nu4FDe6bHueDs8wFJ9zVo+54coim6W0I0tSlvpPZJ0zRjUpubUNiBZkP6a16E+oFkQ///Jl9itl9u+R6AkXvlttr1QCmWcyEbE= Received: from localhost.localdomain (vm2.cifra.si [10.0.0.208]) by mail.cifra.si with ESMTP ; Fri, 19 Feb 2021 21:01:52 +0100 From: Luka Logar To: openwrt-devel@lists.openwrt.org Subject: [PATCH] LuCI: implement TLS client certificate authentication Date: Fri, 19 Feb 2021 21:01:52 +0100 Message-Id: <20210219200152.1346055-1-luka.logar@cifra.si> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210219_150211_418449_01DC3E46 X-CRM114-Status: GOOD ( 13.46 ) X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Luka Logar Sender: "openwrt-devel" Errors-To: openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org 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 --- .../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 + Licensed to the public under the Apache License 2.0. +-%> + +

401 <%:Unauthorized%>

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 + Licensed to the public under the Apache License 2.0. +-%> + +

<%:User logged out, please close the browser window%>