Skip to content

Commit cc19308

Browse files
committed
lib/fetch: sync again
1 parent fdf9462 commit cc19308

File tree

3 files changed

+82
-24
lines changed

3 files changed

+82
-24
lines changed

lib/fetch/common.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -233,13 +233,19 @@ conn_t *
233233
fetch_reopen(int sd)
234234
{
235235
conn_t *conn;
236+
#ifdef SO_NOSIGPIPE
237+
int opt = 1;
238+
#endif
236239

237240
/* allocate and fill connection structure */
238241
if ((conn = calloc(1, sizeof(*conn))) == NULL)
239242
return (NULL);
240-
conn->next_buf = NULL;
241-
conn->next_len = 0;
243+
fcntl(sd, F_SETFD, FD_CLOEXEC);
244+
#ifdef SO_NOSIGPIPE
245+
setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof opt);
246+
#endif
242247
conn->sd = sd;
248+
++conn->ref;
243249
return (conn);
244250
}
245251

@@ -932,7 +938,7 @@ fetch_ssl_tolower(char in)
932938
* conversions.
933939
*/
934940
static int
935-
fetch_ssl_isalpha(unsigned char in)
941+
fetch_ssl_isalpha(char in)
936942
{
937943
return ((in >= 'A' && in <= 'Z') || (in >= 'a' && in <= 'z'));
938944
}
@@ -970,7 +976,7 @@ fetch_ssl_is_trad_domain_label(const char *l, size_t len, int wcok)
970976
return (0);
971977
for (i = 0; i < len; ++i) {
972978
if (!isdigit((unsigned char)l[i]) &&
973-
!fetch_ssl_isalpha((unsigned char)l[i]) &&
979+
!fetch_ssl_isalpha(l[i]) &&
974980
!(l[i] == '*' && wcok) &&
975981
!(l[i] == '-' && l[i - 1] != '-'))
976982
return (0);
@@ -1269,7 +1275,7 @@ fetch_ssl_setup_transport_layer(SSL_CTX *ctx, int verbose)
12691275
{
12701276
long ssl_ctx_options;
12711277

1272-
ssl_ctx_options = SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_TICKET;
1278+
ssl_ctx_options = SSL_OP_ALL | SSL_OP_NO_SSLv3 | SSL_OP_NO_TICKET;
12731279
if (getenv("SSL_ALLOW_SSL3") == NULL)
12741280
ssl_ctx_options |= SSL_OP_NO_SSLv3;
12751281
if (getenv("SSL_NO_TLS1") != NULL)
@@ -1622,7 +1628,7 @@ fetch_read(conn_t *conn, char *buf, size_t len)
16221628
}
16231629
timersub(&timeout, &now, &delta);
16241630
deltams = delta.tv_sec * 1000 +
1625-
delta.tv_usec / 1000;;
1631+
delta.tv_usec / 1000;
16261632
}
16271633
errno = 0;
16281634
pfd.revents = 0;
@@ -1657,6 +1663,7 @@ fetch_getln(conn_t *conn)
16571663
conn->bufsize = MIN_BUF_SIZE;
16581664
}
16591665

1666+
conn->buf[0] = '\0';
16601667
conn->buflen = 0;
16611668
next = NULL;
16621669

@@ -1676,7 +1683,7 @@ fetch_getln(conn_t *conn)
16761683
conn->buflen += len;
16771684
if (conn->buflen == conn->bufsize && next == NULL) {
16781685
tmp = conn->buf;
1679-
tmpsize = conn->bufsize * 2;
1686+
tmpsize = conn->bufsize * 2 + 1;
16801687
if (tmpsize < conn->bufsize) {
16811688
errno = ENOMEM;
16821689
return (-1);

lib/fetch/fetch.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
/* $FreeBSD: rev 252375 $ */
22
/* $NetBSD: fetch.c,v 1.19 2009/08/11 20:48:06 joerg Exp $ */
33
/*-
4-
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørav
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*
6+
* Copyright (c) 1998-2004 Dag-Erling Smørgrav
57
* Copyright (c) 2008 Joerg Sonnenberger <joerg@NetBSD.org>
68
* All rights reserved.
79
*
@@ -31,8 +33,8 @@
3133

3234
#include "compat.h"
3335

34-
#include <ctype.h>
3536
#include <errno.h>
37+
#include <ctype.h>
3638
#include <stdio.h>
3739
#include <stdlib.h>
3840
#include <string.h>
@@ -294,6 +296,9 @@ fetch_pctdecode(char *dst, const char *src, size_t dlen)
294296
(d2 = fetch_hexval(s[2])) >= 0 && (d1 > 0 || d2 > 0)) {
295297
c = d1 << 4 | d2;
296298
s += 2;
299+
} else if (s[0] == '%') {
300+
/* Invalid escape sequence. */
301+
return (NULL);
297302
} else {
298303
c = *s;
299304
}
@@ -366,7 +371,7 @@ fetchParseURL(const char *URL)
366371

367372
/* hostname */
368373
if (*p == '[') {
369-
q = p + 1 + strspn(p + 1, ":0123456789ABCDEFabcdef");
374+
q = p + 1 + strspn(p + 1, ":0123456789ABCDEFabcdef.");
370375
if (*q++ != ']')
371376
goto ouch;
372377
} else {
@@ -419,7 +424,10 @@ fetchParseURL(const char *URL)
419424
goto ouch;
420425
}
421426
u->doc = doc;
422-
while (*p != '\0') {
427+
/* fragments are reserved for client-side processing, see
428+
* https://www.rfc-editor.org/rfc/rfc9110.html#section-7.1
429+
*/
430+
while (*p != '\0' && *p != '#') {
423431
if (!isspace((unsigned char)*p)) {
424432
*doc++ = *p++;
425433
} else {
@@ -458,12 +466,10 @@ fetchParseURL(const char *URL)
458466
void
459467
fetchFreeURL(struct url *u)
460468
{
461-
if (!u) {
469+
if (!u)
462470
return;
463-
}
464-
if (u->doc) {
471+
if (u->doc)
465472
free(u->doc);
466-
}
467473
free(u);
468474
}
469475

lib/fetch/http.c

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
#include <locale.h>
7171
#include <netdb.h>
7272
#include <stdarg.h>
73+
#include <stdbool.h>
7374
#include <stdio.h>
7475
#include <stdlib.h>
7576
#include <string.h>
@@ -1310,8 +1311,7 @@ http_digest_auth(conn_t *conn, const char *hdr, http_auth_challenge_t *c,
13101311
http_auth_params_t *parms, struct url *url)
13111312
{
13121313
HASHHEX HA1;
1313-
HASHHEX digest;
1314-
HASHHEX empty = {0};
1314+
HASHHEX digest, null;
13151315
int r;
13161316
char noncecount[10];
13171317
char cnonce[40];
@@ -1343,8 +1343,9 @@ http_digest_auth(conn_t *conn, const char *hdr, http_auth_challenge_t *c,
13431343
DigestCalcHA1(c->algo, parms->user, c->realm,
13441344
parms->password, c->nonce, cnonce, HA1);
13451345
DEBUGF("HA1: [%s]\n", HA1);
1346+
memset(null, 0, sizeof(null));
13461347
DigestCalcResponse(HA1, c->nonce, noncecount, cnonce, c->qop,
1347-
"GET", url->doc, empty, digest);
1348+
"GET", url->doc, null, digest);
13481349

13491350
if (c->qop[0]) {
13501351
r = http_cmd(conn, "%s: Digest username=\"%s\",realm=\"%s\","
@@ -1449,6 +1450,8 @@ http_connect(struct url *URL, struct url *purl, const char *flags)
14491450
int val;
14501451
#endif
14511452
int serrno;
1453+
bool isproxyauth = false;
1454+
http_auth_challenges_t proxy_challenges;
14521455

14531456
#ifdef INET6
14541457
af = AF_UNSPEC;
@@ -1466,21 +1469,63 @@ http_connect(struct url *URL, struct url *purl, const char *flags)
14661469

14671470
curl = (purl != NULL) ? purl : URL;
14681471

1472+
14691473
if ((conn = fetch_cache_get(curl, af)) != NULL)
14701474
return (conn);
14711475

1476+
retry:
14721477
if ((conn = fetch_connect(curl, af, verbose)) == NULL)
14731478
/* fetch_connect() has already set an error code */
14741479
return (NULL);
14751480
init_http_headerbuf(&headerbuf);
14761481
if (strcmp(URL->scheme, SCHEME_HTTPS) == 0 && purl) {
1477-
http_cmd(conn, "CONNECT %s:%d HTTP/1.1",
1478-
URL->host, URL->port);
1479-
http_cmd(conn, "Host: %s:%d",
1480-
URL->host, URL->port);
1482+
int httpreply;
1483+
init_http_auth_challenges(&proxy_challenges);
1484+
http_cmd(conn, "CONNECT %s:%d HTTP/1.1", URL->host, URL->port);
1485+
http_cmd(conn, "Host: %s:%d", URL->host, URL->port);
1486+
if (isproxyauth) {
1487+
http_auth_params_t aparams;
1488+
init_http_auth_params(&aparams);
1489+
if (*purl->user || *purl->pwd) {
1490+
aparams.user = strdup(purl->user);
1491+
aparams.password = strdup(purl->pwd);
1492+
} else if ((p = getenv("HTTP_PROXY_AUTH")) != NULL &&
1493+
*p != '\0') {
1494+
if (http_authfromenv(p, &aparams) < 0) {
1495+
http_seterr(HTTP_NEED_PROXY_AUTH);
1496+
fetch_syserr();
1497+
goto ouch;
1498+
}
1499+
} else if (fetch_netrc_auth(purl) == 0) {
1500+
aparams.user = strdup(purl->user);
1501+
aparams.password = strdup(purl->pwd);
1502+
} else {
1503+
/*
1504+
* No auth information found in system - exiting
1505+
* with warning.
1506+
*/
1507+
http_seterr(HTTP_NEED_PROXY_AUTH);
1508+
fetch_syserr();
1509+
goto ouch;
1510+
}
1511+
http_authorize(conn, "Proxy-Authorization",
1512+
&proxy_challenges, &aparams, purl);
1513+
clean_http_auth_params(&aparams);
1514+
}
14811515
http_cmd(conn, "%s", "");
1482-
if (http_get_reply(conn, NULL) != HTTP_OK) {
1483-
http_seterr(conn->err);
1516+
/* Get reply from CONNECT Tunnel attempt */
1517+
httpreply = http_get_reply(conn, NULL);
1518+
if (httpreply != HTTP_OK) {
1519+
http_seterr(httpreply);
1520+
/* If the error is a 407/HTTP_NEED_PROXY_AUTH */
1521+
if (httpreply == HTTP_NEED_PROXY_AUTH &&
1522+
! isproxyauth) {
1523+
/* Try again with authentication. */
1524+
clean_http_headerbuf(&headerbuf);
1525+
fetch_close(conn);
1526+
isproxyauth = true;
1527+
goto retry;
1528+
}
14841529
goto ouch;
14851530
}
14861531
/* Read and discard the rest of the proxy response */

0 commit comments

Comments
 (0)