From nobody Wed Jun 14 13:39:04 2023 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Qh62w68Cxz4djD1; Wed, 14 Jun 2023 13:39:04 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (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 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Qh62w59s0z3wlB; Wed, 14 Jun 2023 13:39:04 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1686749944; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=7/UCm2XPztLB4Rp1FNpxzxgYNQyQm4NfJ9+ruHzOHck=; b=bQFUA/95rkgu4764jZgtgot5pDZJ+48nM/FlPsAuK5fc+Bt9s2X9oy7HE1LXaRqT3nHvUD QZWLv/SJeVxx9mEqxhnEy4PSu/WkPqOhM2ij8MZRpwouWMFe9vBhAvKCtpCTIkYoZAAyJW Lrhp5xDi02VclExugcYNZ5PW/3kv0wm26JvggzeFL1gJ7r0iSHla7ZKgbdK6HORBVNA1jW QqX5nasEYdPQtQ9yfeFA7FItNIUCaZVoIWcY3SzUcf1ns7ZsVOTT47V7YRVjFVIFRG34rA CyOQYKlxFeanRdmQIB7EDoEMYxPkxXCoZl9iBqeLAzAsFF8lQDOrhNhvI7xq5A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1686749944; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=7/UCm2XPztLB4Rp1FNpxzxgYNQyQm4NfJ9+ruHzOHck=; b=wfMpSPQh3aisybbYsRNRjjcCyY+qZ3+/NQXjKbBA84U5UvsliaClr2J8DSAwlW/YpUnfOx Syg+ycmp7PVFTiDjtspjueTQX/XDFvLRGKjXp/3UvdJv6evaV1m0dqNTGk+onoKPYBXS6q RZyxjwVpyP8pNSUUvPd2WLrIwrPLALPsgZj6sXaWY8Do66ro65oRb/rOCVL/PSOysPbLEV qoHFtW0nHFwYdP/tHaT2XhIgGAZbqyx2UED40FewPLAjf6NU5DFtW2SiRDXXK+sKjJJuT9 oW8XSNmsdTytMIIpTesx7dAuo+lTLO2XhgqPvdfx3uvGL51hoVB/k9rQlhOLhw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1686749944; a=rsa-sha256; cv=none; b=YcpnDC/QjP5V0QYh2sAU2vhLpBtPMnn05finu23EHrdGPbdjvw2D2lweRAdeDMdXdcLXxu MEsQNdnuFRuDd4Ckoq1C92eh3IsU5qzOh7Vh62/3xvcpqb/qxSDxpP/zvH/KUS/hW5cIfk L7WG1fYZ9jXW9jUQN5IfJJlnoESGz0lFvXUQhSQFgTL0Exj7loSiqNXmv8EdF2ynDUG8np fjDcIHRWYSqmdDCauoUcL4gTACPxX52SDdDCRqRL/Asp5XpciGh1SEdb62ArXo9EIcFuUi UDb26wl3V/Wvgl/5iFLr/xjMhXzWgMNm45gD9KODY10uEgqLXOuC/SL1x04L4g== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (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) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4Qh62w4DlJz15T6; Wed, 14 Jun 2023 13:39:04 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 35EDd4UF015950; Wed, 14 Jun 2023 13:39:04 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 35EDd450015949; Wed, 14 Jun 2023 13:39:04 GMT (envelope-from git) Date: Wed, 14 Jun 2023 13:39:04 GMT Message-Id: <202306141339.35EDd450015949@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Ed Maste Subject: git: ba129c571660 - stable/12 - Allow a comma-separated list in login class capabilities, by adding a version of strcspn that allows quoting. List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: emaste X-Git-Repository: src X-Git-Refname: refs/heads/stable/12 X-Git-Reftype: branch X-Git-Commit: ba129c57166057690be0e146aefd8b3636eced7d Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch stable/12 has been updated by emaste: URL: https://cgit.FreeBSD.org/src/commit/?id=ba129c57166057690be0e146aefd8b3636eced7d commit ba129c57166057690be0e146aefd8b3636eced7d Author: Sean Eric Fagan AuthorDate: 2023-01-14 18:37:31 +0000 Commit: Ed Maste CommitDate: 2023-06-14 13:38:26 +0000 Allow a comma-separated list in login class capabilities, by adding a version of strcspn that allows quoting. PR: 236204 Differential Revision: https://reviews.freebsd.org/D25368 (cherry picked from commit f32db406504ece1b28f43dc816736e081fe22826) (cherry picked from commit f122e552354e84f18b82d11e40c6f8f214ed8abc) --- lib/libutil/login_cap.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 2 deletions(-) diff --git a/lib/libutil/login_cap.c b/lib/libutil/login_cap.c index cea7630698af..ffefb865ed5e 100644 --- a/lib/libutil/login_cap.c +++ b/lib/libutil/login_cap.c @@ -94,6 +94,101 @@ allocarray(size_t sz) } +/* + * This is a variant of strcspn, which checks for quoted + * strings. That is,: + * strcspn_quote("how 'now, brown' cow", ",", NULL); + * will return the index for the nul, rather than the comma, because + * the string is quoted. It does not handle escaped characters + * at this time. + */ +static size_t +strcspn_quote(const char *str, const char *exclude, int *is_quoted) +{ + size_t indx = 0; + char quote = 0; + + if (str == NULL) + return 0; + + if (is_quoted) + *is_quoted = 0; + + for (indx = 0; str[indx] != 0; indx++) { + if (quote && str[indx] == quote) { + if (is_quoted) + *is_quoted = 1; + quote = 0; + continue; + } + if (quote == 0 && + (str[indx] == '\'' || str[indx] == '"')) { + quote = str[indx]; + continue; + } + if (quote == 0 && + strchr(exclude, str[indx]) != NULL) + return indx; + } + return indx; +} + +/* + * Remove quotes from the given string. + * It's a very simplistic approach: the first + * single or double quote it finds, it looks for + * the next one, and if it finds it, moves the + * entire string backwards in two chunks + * (first quote + 1 to first quote, length + * rest of string, and then second quote + 1 + * to second quote, length rest of the string). + */ +static void +remove_quotes(char *str) +{ + static const char *quote_chars = "'\""; + char qc = 0; + int found = 0; + + do { + char *loc = NULL; + + found = 0; + /* + * If qc is 0, then we haven't found + * a quote yet, so do a strcspn search. + */ + if (qc == 0) { + size_t indx; + indx = strcspn(str, quote_chars); + if (str[indx] == '\0') + return; /* We're done */ + loc = str + indx; + qc = str[indx]; + } else { + /* + * We've found a quote character, + * so use strchr to find the next one. + */ + loc = strchr(str, qc); + if (loc == NULL) + return; + qc = 0; + } + if (loc) { + /* + * This gives us the location of the + * quoted character. We need to move + * the entire string down, from loc+1 + * to loc. + */ + size_t len = strlen(loc + 1) + 1; + memmove(loc, loc + 1, len); + found = 1; + } + } while (found != 0); +} + /* * arrayize() * Turn a simple string separated by any of @@ -112,7 +207,7 @@ arrayize(const char *str, const char *chars, int *size) /* count the sub-strings */ for (i = 0, cptr = str; *cptr; i++) { - int count = strcspn(cptr, chars); + int count = strcspn_quote(cptr, chars, NULL); cptr += count; if (*cptr) ++cptr; @@ -126,11 +221,21 @@ arrayize(const char *str, const char *chars, int *size) /* now split the string */ i = 0; while (*ptr) { - int count = strcspn(ptr, chars); + int quoted = 0; + int count = strcspn_quote(ptr, chars, "ed); + char *base = ptr; res[i++] = ptr; ptr += count; if (*ptr) *ptr++ = '\0'; + /* + * If the string contains a quoted element, we + * need to remove the quotes. + */ + if (quoted) { + remove_quotes(base); + } + } res[i] = NULL; }