From patchwork Fri Jan 29 12:53:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Sommerseth X-Patchwork-Id: 1585 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director12.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id oDDqIU6gFGBvbgAAIUCqbw (envelope-from ) for ; Fri, 29 Jan 2021 18:54:54 -0500 Received: from proxy9.mail.ord1d.rsapps.net ([172.30.191.6]) by director12.mail.ord1d.rsapps.net with LMTP id OHsRIk6gFGCGTAAAIasKDg (envelope-from ) for ; Fri, 29 Jan 2021 18:54:54 -0500 Received: from smtp5.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy9.mail.ord1d.rsapps.net with LMTPS id uHXJIU6gFGDGDAAA7h+8OQ (envelope-from ) for ; Fri, 29 Jan 2021 18:54:54 -0500 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp5.gate.ord1d.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dkim=fail (signature verification failed) header.d=sf.lists.topphemmelig.net; dmarc=fail (p=none; dis=none) header.from=sf.lists.topphemmelig.net X-Suspicious-Flag: YES X-Classification-ID: 6101127c-628d-11eb-bfc9-525400d73c44-1-1 Received: from [216.105.38.7] ([216.105.38.7:52428] helo=lists.sourceforge.net) by smtp5.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 71/A4-11705-C40A4106; Fri, 29 Jan 2021 18:54:52 -0500 Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1l5daf-0001SH-CL; Fri, 29 Jan 2021 23:54:13 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1l5dad-0001S8-95 for openvpn-devel@lists.sourceforge.net; Fri, 29 Jan 2021 23:54:11 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=E1fRsRwPU37tdc7FxYv2oFUlvekLQnw+RuidqYK5s74=; b=Vv/jZjjkltlSTgPbwtU0xrM1aj 18b7oBNuR2yCMZz4UJ8xzxvDz8PN6FBf3Yp/X9IPMJV7/IFe3FMhnWg0JaeJ88Td4aIixj3U5ng4X z3ZlRG1CWIleHeY9ctnlzlH92oIHE9LyTZ3brZNXibOzaDQOufvltmdKfv7b8ipplOy4=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:Message-Id:Date:Subject:Cc:To:From :Sender:Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post: List-Owner:List-Archive; bh=E1fRsRwPU37tdc7FxYv2oFUlvekLQnw+RuidqYK5s74=; b=N ay6TELnaG12rg9y0dTq8m6tJ+dQS6v9d5vR/iiaAj/Lx5k0bHDa+D//tOPxBTbsqcC5PlJlsjc3ND jGTDk0X4Iwk3qhMFpwCDsm3kR3eEC3OMG07QcrXicqDJwpFujSK6VgZtAc6xJwk54Ho7ECOYgFZ5R x3LvLqg+Xs7X23nY=; Received: from mx1.basenordic.cloud ([217.170.196.134]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1l5daR-0036K0-NG for openvpn-devel@lists.sourceforge.net; Fri, 29 Jan 2021 23:54:11 +0000 Received: from localhost (unknown [127.0.0.1]) by mx1.basenordic.cloud (Postfix) with ESMTP id B7658E714; Fri, 29 Jan 2021 23:53:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sf.lists.topphemmelig.net; s=inouz9eefah2too5; t=1611964430; bh=E1fRsRwPU37tdc7FxYv2oFUlvekLQnw+RuidqYK5s74=; h=From:To:Cc:Subject:Date:From; b=lF72adEM9UKwY0og4V+HX5EOKGbALHrMVv2Z2kh36TrYQzJ6P1Mk2C0P89e8LL2Ml wDFfSNSSwBE2+cRDbTn/do4blsx9yahnZneAzqlKfT01cVeKG+BMuMrVB9GMuBSpvm 4P6qf/vpq6gHyKXQzZI/+bGzywJfOMc/aHLiL7mV424/jzLu5FXBbDjBziJ4R7IiIY 7FVJZLaZfDuLIXf9ht42C42aloPNCMNlY2s5KomiWCIEHAJ8KcPE2YXvpMpTLX0fha g5/jILR+Jsfo5iXpdUPbQb65wCPldNC5mQyZCXVMuG7bK6MqaYjeJKlNId5sOg1Sxk s0ZBq7buypAcQ== Received: from mx1.basenordic.cloud ([127.0.0.1]) by localhost (mx1.basenordic.cloud [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id oYq8kOaueBjP; Sat, 30 Jan 2021 00:53:49 +0100 (CET) Received: from xplorer.net (unknown [10.35.7.11]) by mx1.basenordic.cloud (Postfix) with ESMTP id 9E40CE709; Sat, 30 Jan 2021 00:53:49 +0100 (CET) From: David Sommerseth To: openvpn-devel@lists.sourceforge.net Date: Sat, 30 Jan 2021 00:53:40 +0100 Message-Id: <20210129235340.59785-1-openvpn@sf.lists.topphemmelig.net> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -0.0 SPF_HELO_PASS SPF: HELO matches SPF record 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: openvpn.net] -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-Headers-End: 1l5daR-0036K0-NG Subject: [Openvpn-devel] [PATCH] sample-plugin/defer: Add simple test case for additional web-auth X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: David Sommerseth Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox From: David Sommerseth Extend the defer/simple sample-plugin supporting test_defer_timeout and test_defer_openurl environment variables to trigger an additional web based authentication. Both variables are required to enable this feature. Since this plug-in will require clients to use --auth-user-pass, this may seem like an odd feature. But in real life scenarious this can be useful for opening up a web page with terms of services which needs to be accepted or other kinds of MFA based authentications which are triggered via web calls. In a proper plug-in, the real authentication must then ensure it sends a proper URL to the client which can be used to map this user with a reference it can use to identify the proper client in the web authentication. The external authentication service will also need to provide a response back to the OpenVPN authentication plug-in via some back-channel, which the OpenVPN plug-in can pick up to evaluate if the authentication result. Signed-off-by: David Sommerseth --- sample/sample-plugins/defer/simple.c | 78 +++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/sample/sample-plugins/defer/simple.c b/sample/sample-plugins/defer/simple.c index 22bc2276..b74de77e 100644 --- a/sample/sample-plugins/defer/simple.c +++ b/sample/sample-plugins/defer/simple.c @@ -39,6 +39,29 @@ * seconds after the initial TLS negotiation, using * {common-name}.pf as the source. * + * Additional web based authentication is also partly + * demonstrated if adding these two lines: + * + * setenv test_deferred_openurl https://auth.example.org/ + * setenv test_deferred_timeout 30 + * + * This will NOT do any real authentication, but will send + * the URL to the client which can open the authentication + * page. If the test_deferred_timeout is higher than + * test_deferred_auth, the authentication will pass (regardless + * of username/password provided and what ever happens on the + * authentication URL). If the test_deferred_timeout is lower + * than test_deferred_auth, the authentication will fail. + * For the fail or pass to work properly make sure there are + * at least 10-15 seconds difference between test_deferred_auth + * and test_deferred_timeout. + * + * This kind of additional web authentication can be useful + * in real life scenarios for various types of 2FA methods + * triggered via web; or to open a page with disclaimers and + * terms of service needed to be accepted before getting a + * connection. + * * Sample packet filter configuration: * * [CLIENTS DROP] @@ -72,6 +95,8 @@ static plugin_log_t plugin_log = NULL; struct plugin_context { int test_deferred_auth; int test_packet_filter; + int test_deferred_timeout; + char *test_deferred_openurl; }; struct plugin_per_client_context { @@ -169,6 +194,23 @@ openvpn_plugin_open_v3(const int v3structver, context->test_deferred_auth = atoi_null0(get_env("test_deferred_auth", envp)); plugin_log(PLOG_NOTE, MODULE, "TEST_DEFERRED_AUTH %d", context->test_deferred_auth); + context->test_deferred_timeout = atoi_null0(get_env("test_deferred_timeout", envp)); + plugin_log(PLOG_NOTE, MODULE, "TEST_DEFERRED_TIMEOUT %d", context->test_deferred_timeout); + + const char *openurl = get_env("test_deferred_openurl", envp); + if (openurl) + { + if (context->test_deferred_timeout < 1) + { + plugin_log(PLOG_ERR, MODULE, "test_deferred_timeout also requires test_deferred_openurl"); + goto error; + } + size_t len = strlen(openurl); + context->test_deferred_openurl = calloc(1, len+1); + strncpy(context->test_deferred_openurl, openurl, len); + plugin_log(PLOG_NOTE, MODULE, "TEST_DEFERRED_OPENURL %s", openurl); + } + context->test_packet_filter = atoi_null0(get_env("test_packet_filter", envp)); plugin_log(PLOG_NOTE, MODULE, "TEST_PACKET_FILTER %d", context->test_packet_filter); @@ -222,11 +264,13 @@ auth_user_pass_verify(struct plugin_context *context, /* get auth_control_file filename from envp string array*/ const char *auth_control_file = get_env("auth_control_file", envp); + const char *auth_pending_file = get_env("auth_pending_file", envp); - plugin_log(PLOG_NOTE, MODULE, "DEFER u='%s' p='%s' acf='%s'", + plugin_log(PLOG_NOTE, MODULE, "DEFER u='%s' p='%s' acf='%s' apf='%s'", np(username), np(password), - np(auth_control_file)); + np(auth_control_file), + np(auth_pending_file)); /* Authenticate asynchronously in n seconds */ if (!auth_control_file) @@ -234,6 +278,32 @@ auth_user_pass_verify(struct plugin_context *context, return OPENVPN_PLUGIN_FUNC_ERROR; } + if (auth_pending_file && context->test_deferred_openurl) + { + /* + * This will make OpenVPN clients capable of web authentication open the + * the provided URL - but this plug-in does not provide any side-channel + * authentication services. This is purely for demonstration how to + * make a client open an URL for authentication, NOT the web authentication + * impelementation itself. + * + * Remember, this plug-in will NOT do any real authentication. Any + * username/password is considered valid. It only demonstrates various + * deferred authentication mechanisms. + * + */ + FILE *pfd = fopen(auth_pending_file, "w"); + if (!pfd) + { + plugin_log(PLOG_ERR|PLOG_ERRNO, MODULE, "auth_pending_file open('%s') failed", auth_pending_file); + return OPENVPN_PLUGIN_FUNC_ERROR; + } + fprintf(pfd, "%d\n", context->test_deferred_timeout); + fprintf(pfd, "openurl\n"); + fprintf(pfd, "OPEN_URL:%s\n", context->test_deferred_openurl); + fclose(pfd); + } + /* we do not want to complicate our lives with having to wait() * for child processes (so they are not zombiefied) *and* we MUST NOT * fiddle with signal handlers (= shared with openvpn main), so @@ -513,5 +583,9 @@ openvpn_plugin_close_v1(openvpn_plugin_handle_t handle) { struct plugin_context *context = (struct plugin_context *) handle; plugin_log(PLOG_NOTE, MODULE, "FUNC: openvpn_plugin_close_v1"); + if (context->test_deferred_openurl) + { + free(context->test_deferred_openurl); + } free(context); }