From patchwork Sat Dec 30 14:32:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gert Doering X-Patchwork-Id: 3537 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7301:2791:b0:100:d2e5:60d with SMTP id hm17csp588723dyb; Sat, 30 Dec 2023 06:43:50 -0800 (PST) X-Google-Smtp-Source: AGHT+IEGBxa8PmyyGvLUO048h06jOUVgarGUt5irx0VRISmqL+aO6SHD1l/I/Js5vDn7i8uv7s/1 X-Received: by 2002:a17:90a:8a89:b0:28b:cfa3:8f0e with SMTP id x9-20020a17090a8a8900b0028bcfa38f0emr20304604pjn.3.1703947430093; Sat, 30 Dec 2023 06:43:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1703947430; cv=none; d=google.com; s=arc-20160816; b=OWtw1uxBw4h0JroBKulTTIa5FDfw7ESvIzbSFzHyIpvcFVGZ7Reth11ob2b2gHKF23 qwoB9JMBCewbS+EaWlj/rvohbIJ4WW0AbqNzKqwZXOcI5lWCiBlLsMsOoZCWrwSkxRoJ Wt1q2xRK3oYRrRsJ6X4KJgw7puNriJmFT7WjxkrEwgdnOUu1dSKs8AzQdivLgQNBKhye w1hUWY0MsTfUcosGAW3Or57ZmCCMQnHMkBbcvPU1Houf9sRNVmtdYS3eiI8cqQOYqlOA 2VHpDTpSzfu13gC8bk/uU7ieTSwtUhxZ6u8avJhkQLXuQB/MKt2Le/FJYlMVq/h0x62B aGgw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature:dkim-signature; bh=i7f7FbSLew0RZmtXQovzAdhfbN7NzgPD5de/c/+iyrA=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=G5gp+Pi75FzJNRyQQs9/EGbruP7+Tj7p9n+unQwZ6wloSumshFulPxMpBKRTYpA0bL 4aQ8q0V2rxjmx8IBy186FnEbWDEljVlKwNi1KxEykDjQxc1TW8RZjK2eArnmqVZ8IT5n uJlggwsn5li76cQb2FaBjGLtCtROuvzNZ+kxNQZOlB7KwYumoFoaypSUvPXNke4rS0O3 M/c4S9E7XtfX7rs2FmjKb7g3J18DG0da7awTHMk735fyKpWCzjpHWxGfXOJAGAUO3XfY MZ8VM4jmH0WbEqkbsyKRGUfC+tmeuycC0DFy295BtqYN19eywSFVGHf6QlbH9nZBa0q/ AZug== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=AkDLugE1; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b="NQ7/fGCM"; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=muc.de Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id t18-20020a170902e85200b001d4ade8f6cfsi295760plg.608.2023.12.30.06.43.49 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 30 Dec 2023 06:43:50 -0800 (PST) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=AkDLugE1; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b="NQ7/fGCM"; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=muc.de Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1rJaYi-0003vJ-B0; Sat, 30 Dec 2023 14:43:28 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1rJaYg-0003vD-FX for openvpn-devel@lists.sourceforge.net; Sat, 30 Dec 2023 14:43:26 +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:References: In-Reply-To:Message-ID:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=x1WOrHh3Jm8nw0DVs85q2++cnfkWc9QjnTXUDPaouFQ=; b=AkDLugE1Tt9EqtefEvJPZtTfA8 AJVgxLuQ07dterSWp1tuhdB876HxyZXYASX+ZOH7Kegsu0BX/3q9twmACzaa4CaFwjANv0enZsQ+A UL7zOdp1OwE0F0ZwS9p+PyVprfFhIHcAmT273Ub3V/IWW2oo7c2BaIQG8VFiP/ihBQf4=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=x1WOrHh3Jm8nw0DVs85q2++cnfkWc9QjnTXUDPaouFQ=; b=NQ7/fGCMoq7GbuCLMEx6b7kawm DXk9u/qaDV9F97B67PKRvJdtkC9EWj6PD9vsV0rqDiys7zbmJ1s4rmZFowspJRxy33UQ2IgI7rwCF /npOPHMwqz3tPdJd2IKptXs5xheUIb401asgu5AGihwseAi33pUloRyvds434e9c8mpg=; Received: from dhcp-174.greenie.muc.de ([193.149.48.174] helo=blue.greenie.muc.de) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1rJaYf-0007cl-BW for openvpn-devel@lists.sourceforge.net; Sat, 30 Dec 2023 14:43:26 +0000 Received: from blue.greenie.muc.de (localhost [127.0.0.1]) by blue.greenie.muc.de (8.17.1.9/8.17.1.9) with ESMTP id 3BUEWnFB001635 for ; Sat, 30 Dec 2023 15:32:49 +0100 Received: (from gert@localhost) by blue.greenie.muc.de (8.17.1.9/8.17.1.9/Submit) id 3BUEWnD8001634 for openvpn-devel@lists.sourceforge.net; Sat, 30 Dec 2023 15:32:49 +0100 From: Gert Doering To: openvpn-devel@lists.sourceforge.net Date: Sat, 30 Dec 2023 15:32:48 +0100 Message-ID: <20231230143248.1625-1-gert@greenie.muc.de> X-Mailer: git-send-email 2.41.0 In-Reply-To: References: MIME-Version: 1.0 X-Spam-Score: -0.0 (/) X-Spam-Report: Spam detection software, running on the system "util-spamd-1.v13.lw.sourceforge.com", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: From: Frank Lichtenheld Not used outside of misc.c. Rename to parse_auth_challenge since it really just parses the string that you put in into the struct. Content analysis details: (-0.0 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record -0.0 T_SCC_BODY_TEXT_LINE No description available. X-Headers-End: 1rJaYf-0007cl-BW Subject: [Openvpn-devel] [PATCH v5] misc: make get_auth_challenge static 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: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1786718380711251663?= X-GMAIL-MSGID: =?utf-8?q?1786718380711251663?= From: Frank Lichtenheld Not used outside of misc.c. Rename to parse_auth_challenge since it really just parses the string that you put in into the struct. Add doxygen documentation. v2: - change if(auth_challenge) to ASSERT(auth_challenge) Change-Id: I0abeec9f862aea1f6a8fdf350fa0008cf2e5d613 Signed-off-by: Frank Lichtenheld Acked-by: Gert Doering --- This change was reviewed on Gerrit and approved by at least one developer. I request to merge it to master. Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/476 This mail reflects revision 5 of this Change. Acked-by according to Gerrit (reflected above): Gert Doering diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c index bce63ed..08f274d 100644 --- a/src/openvpn/misc.c +++ b/src/openvpn/misc.c @@ -124,6 +124,83 @@ } return true; } + +/** + * Parses an authentication challenge string and returns an auth_challenge_info structure. + * The authentication challenge string should follow the dynamic challenge/response protocol. + * + * See doc/management-notes.txt for more info on the the dynamic challenge/response protocol + * implemented here. + * + * @param auth_challenge The authentication challenge string to parse. Can't be NULL. + * @param gc The gc_arena structure for memory allocation. + * + * @return A pointer to the parsed auth_challenge_info structure, or NULL if parsing fails. + */ +static struct auth_challenge_info * +parse_auth_challenge(const char *auth_challenge, struct gc_arena *gc) +{ + ASSERT(auth_challenge); + + struct auth_challenge_info *ac; + const int len = strlen(auth_challenge); + char *work = (char *) gc_malloc(len+1, false, gc); + char *cp; + + struct buffer b; + buf_set_read(&b, (const uint8_t *)auth_challenge, len); + + ALLOC_OBJ_CLEAR_GC(ac, struct auth_challenge_info, gc); + + /* parse prefix */ + if (!buf_parse(&b, ':', work, len)) + { + return NULL; + } + if (strcmp(work, "CRV1")) + { + return NULL; + } + + /* parse flags */ + if (!buf_parse(&b, ':', work, len)) + { + return NULL; + } + for (cp = work; *cp != '\0'; ++cp) + { + const char c = *cp; + if (c == 'E') + { + ac->flags |= CR_ECHO; + } + else if (c == 'R') + { + ac->flags |= CR_RESPONSE; + } + } + + /* parse state ID */ + if (!buf_parse(&b, ':', work, len)) + { + return NULL; + } + ac->state_id = string_alloc(work, gc); + + /* parse user name */ + if (!buf_parse(&b, ':', work, len)) + { + return NULL; + } + ac->user = (char *) gc_malloc(strlen(work)+1, true, gc); + openvpn_base64_decode(work, (void *)ac->user, -1); + + /* parse challenge text */ + ac->challenge_text = string_alloc(BSTR(&b), gc); + + return ac; +} + #endif /* ifdef ENABLE_MANAGEMENT */ /* @@ -287,7 +364,7 @@ #ifdef ENABLE_MANAGEMENT if (auth_challenge && (flags & GET_USER_PASS_DYNAMIC_CHALLENGE) && response_from_stdin) { - struct auth_challenge_info *ac = get_auth_challenge(auth_challenge, &gc); + struct auth_challenge_info *ac = parse_auth_challenge(auth_challenge, &gc); if (ac) { char *response = (char *) gc_malloc(USER_PASS_LEN, false, &gc); @@ -392,83 +469,6 @@ return true; } -#ifdef ENABLE_MANAGEMENT - -/* - * See management/management-notes.txt for more info on the - * the dynamic challenge/response protocol implemented here. - */ -struct auth_challenge_info * -get_auth_challenge(const char *auth_challenge, struct gc_arena *gc) -{ - if (auth_challenge) - { - struct auth_challenge_info *ac; - const int len = strlen(auth_challenge); - char *work = (char *) gc_malloc(len+1, false, gc); - char *cp; - - struct buffer b; - buf_set_read(&b, (const uint8_t *)auth_challenge, len); - - ALLOC_OBJ_CLEAR_GC(ac, struct auth_challenge_info, gc); - - /* parse prefix */ - if (!buf_parse(&b, ':', work, len)) - { - return NULL; - } - if (strcmp(work, "CRV1")) - { - return NULL; - } - - /* parse flags */ - if (!buf_parse(&b, ':', work, len)) - { - return NULL; - } - for (cp = work; *cp != '\0'; ++cp) - { - const char c = *cp; - if (c == 'E') - { - ac->flags |= CR_ECHO; - } - else if (c == 'R') - { - ac->flags |= CR_RESPONSE; - } - } - - /* parse state ID */ - if (!buf_parse(&b, ':', work, len)) - { - return NULL; - } - ac->state_id = string_alloc(work, gc); - - /* parse user name */ - if (!buf_parse(&b, ':', work, len)) - { - return NULL; - } - ac->user = (char *) gc_malloc(strlen(work)+1, true, gc); - openvpn_base64_decode(work, (void *)ac->user, -1); - - /* parse challenge text */ - ac->challenge_text = string_alloc(BSTR(&b), gc); - - return ac; - } - else - { - return NULL; - } -} - -#endif /* ifdef ENABLE_MANAGEMENT */ - void purge_user_pass(struct user_pass *up, const bool force) { diff --git a/src/openvpn/misc.h b/src/openvpn/misc.h index 70a24dd..5ae61b5 100644 --- a/src/openvpn/misc.h +++ b/src/openvpn/misc.h @@ -86,8 +86,6 @@ const char *challenge_text; }; -struct auth_challenge_info *get_auth_challenge(const char *auth_challenge, struct gc_arena *gc); - /* * Challenge response info on client as pushed by server. */ @@ -120,12 +118,31 @@ #define GET_USER_PASS_INLINE_CREDS (1<<10) /* indicates that auth_file is actually inline creds */ +/** + * Retrieves the user credentials from various sources depending on the flags. + * + * @param up The user_pass structure to store the retrieved credentials. + * @param auth_file The path to the authentication file. Might be NULL. + * @param prefix The prefix to prepend to user prompts. + * @param flags Additional flags to control the behavior of the function. + * @param auth_challenge The authentication challenge string. + * @return true if the user credentials were successfully retrieved, false otherwise. + */ bool get_user_pass_cr(struct user_pass *up, const char *auth_file, const char *prefix, const unsigned int flags, const char *auth_challenge); +/** + * Retrieves the user credentials from various sources depending on the flags. + * + * @param up The user_pass structure to store the retrieved credentials. + * @param auth_file The path to the authentication file. Might be NULL. + * @param prefix The prefix to prepend to user prompts. + * @param flags Additional flags to control the behavior of the function. + * @return true if the user credentials were successfully retrieved, false otherwise. + */ static inline bool get_user_pass(struct user_pass *up, const char *auth_file, diff --git a/src/openvpn/ssl.h b/src/openvpn/ssl.h index 6ba6ff8..71b99db 100644 --- a/src/openvpn/ssl.h +++ b/src/openvpn/ssl.h @@ -410,11 +410,7 @@ bool ssl_clean_auth_token(void); #ifdef ENABLE_MANAGEMENT -/* - * ssl_get_auth_challenge will parse the server-pushed auth-failed - * reason string and return a dynamically allocated - * auth_challenge_info struct. - */ + void ssl_purge_auth_challenge(void); void ssl_put_auth_challenge(const char *cr_str);