Received: from out4-smtp.messagingengine.com (out4-smtp.messagingengine.com [66.111.4.28]) by nld3-dev1.alpinelinux.org (Postfix) with ESMTPS id 9BB6A7810E5 for <~alpine/apk-tools@lists.alpinelinux.org>; Mon, 13 Dec 2021 21:35:53 +0000 (UTC) Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailout.nyi.internal (Postfix) with ESMTP id 541515C02A2; Mon, 13 Dec 2021 16:29:45 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute3.internal (MEProxy); Mon, 13 Dec 2021 16:29:45 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jfarr.cc; h=from :to:cc:subject:date:message-id:mime-version :content-transfer-encoding; s=fm2; bh=einK5Ov3HaDJRjSM6TJdVrrx3D 5wyRpTLtqPpSwY27A=; b=r5/WqkNUak2wEzFa+nmrzrPSehCPyztdh9KJ7WYtSL MoJ5QF7/9HDwd35CINkFyFlzLt7VrVySb3MmJ9BN+ZPg7eSQ7w0gzzXTGz5cCQ4A 5bJBvKKYuODBUBsfVh/pe18jRLB8lFdZFZ5eqxhyF11S/tqKvmG1nXKqgLc3hUTA zKTLjcJPjpDOtcqx/Cs3jHCvhpeqspDBhgpBwVtjPJVDvVjFmSXebYXOPWCXDfto JyV6WVyWtCN2UMtTMdnYyzmwJqhBQwPeJBISbANoepB8Q12/JEyXiLl+70VngRKb TDs4j13x2FpfoddQfO2Lrvnc/uSbQ5xI8QgeMArNdlqg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :message-id:mime-version:subject:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=einK5Ov3HaDJRjSM6 TJdVrrx3D5wyRpTLtqPpSwY27A=; b=AASXZMv4ubMsrVkeOpQz97obkphv8uQOu 3/wIUlVs/7kZ7QFjbJBv/D6mKR+YyBwrcNnPwOUWvjqWgE2IEQS3+CpRnXI8DGg6 yaWqlnigZtGFVxB+wvFWMRbdluaa49av8xEjSba7MET1zG5aRIU/Fyc+8eKB2xes xPVs+csb+X3Gc1rdFv5Y/cuu3vreAqXCI58vxOcr2G146rhYU9ZmPIIOmM37WZqy 4lAocmYqgjtxj/gh2m9AlgYrUt5xfTaiM9KqgRM1c+ygHcxP8gvUxkaPaas0cTgD t6lekTIZRm/3MBBGsrJPP1F7/cfbUhBs3tNvleY97Znp2oQfZhINA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvuddrkeekgdduheduucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucgfrhhlucfvnfffucdlfedtmdenucfjughrpefhvf fufffkofgggfestdekredtredttdenucfhrhhomheplfgrnhcujfgvnhgurhhikhcuhfgr rhhruceoghhithesjhhfrghrrhdrtggtqeenucggtffrrghtthgvrhhnpedtgfejgfekhe eiudelkeevgfffvdeugeduleetgeeiieeuvdfhfeekgeekieejkeenucevlhhushhtvghr ufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehgihhtsehjfhgrrhhrrdgttg X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 13 Dec 2021 16:29:43 -0500 (EST) Received: by 5f8a72a08181 (sSMTP sendmail emulation); Mon, 13 Dec 2021 21:29:42 +0000 From: Jan Hendrik Farr To: ~alpine/apk-tools@lists.alpinelinux.org Cc: Jan Hendrik Farr Subject: [PATCH 1/1] libfetch: Allow special characters in http basic auth Date: Mon, 13 Dec 2021 21:29:29 +0000 Message-Id: <20211213212929.925-1-git@jfarr.cc> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Currently, special characters in the username or password are not handled correctly (when set in $http_proxy and $https_proxy). They should be percent encoded in the environment variables then decoded by libfetch and reencoded using base64. This implementation is mainly taken from the current FreeBSD source and adapted to the apk-tools version of libfetch. --- libfetch/fetch.c | 69 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 12 deletions(-) diff --git a/libfetch/fetch.c b/libfetch/fetch.c index 45c92aa..ced8411 100644 --- a/libfetch/fetch.c +++ b/libfetch/fetch.c @@ -353,6 +353,54 @@ fetchCopyURL(const struct url *src) return dst; } +/* + * Return value of the given hex digit. + */ +static int +fetch_hexval(char ch) +{ + + if (ch >= '0' && ch <= '9') + return (ch - '0'); + else if (ch >= 'a' && ch <= 'f') + return (ch - 'a' + 10); + else if (ch >= 'A' && ch <= 'F') + return (ch - 'A' + 10); + return (-1); +} + +/* + * Decode percent-encoded URL component from src into dst, stopping at end + * of string, or at @ or : separators. Returns a pointer to the unhandled + * part of the input string (null terminator, @, or :). No terminator is + * written to dst (it is the caller's responsibility). + */ +static const char * +fetch_pctdecode(char *dst, const char *src, size_t dlen) +{ + int d1, d2; + char c; + const char *s; + + for (s = src; *s != '\0' && *s != '@' && *s != ':'; s++) { + if (s[0] == '%' && (d1 = fetch_hexval(s[1])) >= 0 && + (d2 = fetch_hexval(s[2])) >= 0 && (d1 > 0 || d2 > 0)) { + c = d1 << 4 | d2; + s += 2; + } else if (s[0] == '%') { + /* Invalid escape sequence. */ + return (NULL); + } else { + c = *s; + } + if (dlen-- > 0) + *dst++ = c; + else + return (NULL); + } + return (s); +} + /* * Split an URL into components. URL syntax is: * [method:/][/[user[:pwd]@]host[:port]/][document] @@ -428,22 +476,19 @@ find_user: p = strpbrk(URL, "/@"); if (p != NULL && *p == '@') { /* username */ - for (q = URL, i = 0; (*q != ':') && (*q != '@'); q++) { - if (i >= URL_USERLEN) { - url_seterr(URL_BAD_AUTH); - goto ouch; - } - u->user[i++] = *q; + q = URL; + q = fetch_pctdecode(u->user, q, URL_USERLEN); + if (q == NULL) { + url_seterr(URL_BAD_AUTH); + goto ouch; } /* password */ if (*q == ':') { - for (q++, i = 0; (*q != '@'); q++) { - if (i >= URL_PWDLEN) { - url_seterr(URL_BAD_AUTH); - goto ouch; - } - u->pwd[i++] = *q; + q = fetch_pctdecode(u->pwd, q + 1, URL_PWDLEN); + if (q == NULL) { + url_seterr(URL_BAD_AUTH); + goto ouch; } } -- 2.34.1