Received: from mail-lf1-f49.google.com (mail-lf1-f49.google.com [209.85.167.49]) by nld3-dev1.alpinelinux.org (Postfix) with ESMTPS id 80D90780FD8 for <~alpine/apk-tools@lists.alpinelinux.org>; Fri, 17 Dec 2021 08:18:48 +0000 (UTC) Received: by mail-lf1-f49.google.com with SMTP id g11so3064016lfu.2 for <~alpine/apk-tools@lists.alpinelinux.org>; Fri, 17 Dec 2021 00:18:48 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=7O+EIkw2T8RmxAfuFJylDMc4CjriDOrw3RPfiH1djrc=; b=OFqS3q2BUzOHn2pBG62BwS26ImoCCSlJAsKBakk5G2A9c/MK4gdGtyhGku0ZBOcvD6 r++SZs1aTKZ2E1rsLIpavMDChxv4eVrF2Kf7kS7Bi2o/TypmkMv5QfET7hHWyPalBUG4 De1/PeWjUZM6yMFRjGW29ZTqlujdGLcci9poADKcs79XZoTIpFV+iELO3pbnuqrPWE9z gMeFgTl1EGIFcKEW8Gp/E+to9h39pM8sPdoX75QF7Fq2d0GeBgnM40FPDkgtkT6yvZ6J SNylYQVDW2VFaluWnu+a9RFAG/ftWlWns4+TwTZ0MimbO260Dxq6GCzEkScGNl+dXjVp erCA== X-Gm-Message-State: AOAM533i3AWZT5ZZXwF/bsISnaJg6LjPS+Ndhs5JwI/Qnfgz7Lhn2zYj MWshsWyf79b1zHmh7hQp7W/xoBWzkGKpAQ== X-Google-Smtp-Source: ABdhPJwb9ZcLx84LNse3KrsiSzSL5rvQ8sKR3n8qEqI4bChcaA3jxW7N3M2naPMraq+CpT5cwnJu3w== X-Received: by 2002:a05:6512:12c8:: with SMTP id p8mr2029579lfg.69.1639729127330; Fri, 17 Dec 2021 00:18:47 -0800 (PST) Received: from vostro ([62.183.198.118]) by smtp.gmail.com with ESMTPSA id f12sm75788lfu.51.2021.12.17.00.18.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 17 Dec 2021 00:18:47 -0800 (PST) Date: Fri, 17 Dec 2021 10:18:42 +0200 From: Timo Teras To: "Jan Hendrik Farr" Cc: ~alpine/apk-tools@lists.alpinelinux.org Subject: Re: [PATCH 1/1] libfetch: Allow special characters in http basic auth Message-ID: <20211217101842.5f83dc3d@vostro> In-Reply-To: References: <20211213212929.925-1-git@jfarr.cc> <20211214213430.029b34c5@vostro> <20211215082220.71dbc443@vostro> X-Mailer: Claws Mail 4.0.0 (GTK+ 3.24.30; x86_64-alpine-linux-musl) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Hi! Committed with whitespace fixes. Somehow tabs were converted to spaces in the patch you sent and it did not apply cleanly. Thank you! Timo On Thu, 16 Dec 2021 23:34:38 +0100 "Jan Hendrik Farr" wrote: > Hi, > > this version will allow unencoded colons in the password. I modified > fetch_pctdecode to allow the callee to specify at what characters it > should stop. For the username it stops at ":" or "@" and for the > password just at "@". I prefer this behavior over giving people an > error. While it will allow some invalid credentials this is actually > the same behavior as curl + this won't brake current setups. > > With kind regards, Jan > > > > > > > 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 | 80 > ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 67 > insertions(+), 13 deletions(-) > > diff --git a/libfetch/fetch.c b/libfetch/fetch.c > index 45c92aa..526ba86 100644 > --- a/libfetch/fetch.c > +++ b/libfetch/fetch.c > @@ -354,7 +354,58 @@ fetchCopyURL(const struct url *src) > } > > /* > - * Split an URL into components. URL syntax is: > + * 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 one of the characters contained in brk. Returns a > pointer > + * to the unhandled part of the input string (null terminator, > specified > + * character). No terminator is written to dst (it is the caller's > + * responsibility). > + */ > +static const char * > +fetch_pctdecode(char *dst, const char *src, const char *brk, size_t > dlen) +{ > + int d1, d2; > + char c; > + const char *s; > + > + > + > + for (s = src; *s != '\0' && !strchr(brk, *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) > + return NULL; > + dlen--; > + *dst++ = c; > + } > + return (s); > +} > + > +/* > + * Split a URL into components. URL syntax is: > * [method:/][/[user[:pwd]@]host[:port]/][document] > * This almost, but not quite, RFC1738 URL syntax. > */ > @@ -428,25 +479,28 @@ 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; > } > } > > + if (*q != '@') { > + url_seterr(URL_BAD_AUTH); > + goto ouch; > + } > + > p++; > } else { > p = URL; > -- > 2.34.1