sync with OpenBSD -current

This commit is contained in:
purplerain 2024-04-17 02:49:09 +00:00
parent 382ecd9441
commit 1b576c8ddf
Signed by: purplerain
GPG Key ID: F42C07F07E2E35B7
25 changed files with 517 additions and 395 deletions

View File

@ -1,4 +1,4 @@
/* $OpenBSD: extern.h,v 1.62 2023/12/09 23:00:11 jca Exp $ */ /* $OpenBSD: extern.h,v 1.63 2024/04/16 18:52:43 jca Exp $ */
/* $NetBSD: extern.h,v 1.5 1996/03/26 23:54:16 mrg Exp $ */ /* $NetBSD: extern.h,v 1.5 1996/03/26 23:54:16 mrg Exp $ */
/*- /*-
@ -284,6 +284,7 @@ int tar_wr(ARCHD *);
int ustar_id(char *, int); int ustar_id(char *, int);
int ustar_rd(ARCHD *, char *); int ustar_rd(ARCHD *, char *);
int ustar_wr(ARCHD *); int ustar_wr(ARCHD *);
int pax_id(char *, int);
int pax_wr(ARCHD *); int pax_wr(ARCHD *);
/* /*

View File

@ -1,4 +1,4 @@
/* $OpenBSD: options.c,v 1.109 2024/04/15 22:07:08 caspar Exp $ */ /* $OpenBSD: options.c,v 1.112 2024/04/16 23:09:35 jca Exp $ */
/* $NetBSD: options.c,v 1.6 1996/03/26 23:54:18 mrg Exp $ */ /* $NetBSD: options.c,v 1.6 1996/03/26 23:54:18 mrg Exp $ */
/*- /*-
@ -228,7 +228,7 @@ FSUB fsub[] = {
/* 9: gzip, to detect failure to use -z */ /* 9: gzip, to detect failure to use -z */
{NULL, 0, 4, 0, 0, 0, 0, gzip_id}, {NULL, 0, 4, 0, 0, 0, 0, gzip_id},
/* 10: POSIX PAX */ /* 10: POSIX PAX */
{"pax", 5120, BLKMULT, 0, 1, BLKMULT, 0, ustar_id, no_op, {"pax", 5120, BLKMULT, 0, 1, BLKMULT, 0, pax_id, no_op,
ustar_rd, tar_endrd, no_op, pax_wr, tar_endwr, tar_trail, ustar_rd, tar_endrd, no_op, pax_wr, tar_endwr, tar_trail,
tar_opt}, tar_opt},
#endif #endif
@ -237,10 +237,11 @@ FSUB fsub[] = {
#define F_ACPIO 1 /* format when called as cpio -c */ #define F_ACPIO 1 /* format when called as cpio -c */
#define F_CPIO 3 /* format when called as cpio */ #define F_CPIO 3 /* format when called as cpio */
#define F_OTAR 4 /* format when called as tar -o */ #define F_OTAR 4 /* format when called as tar -o */
#define F_TAR 5 /* format when called as tar */
#ifdef SMALL #ifdef SMALL
# define F_TAR 5 /* default write format when called as tar: ustar */
# define DEFLT 5 /* default write format when called as pax: ustar */ # define DEFLT 5 /* default write format when called as pax: ustar */
#else #else
# define F_TAR 10 /* default write format when called as tar: ustar */
# define DEFLT 10 /* default write format when called as pax: pax */ # define DEFLT 10 /* default write format when called as pax: pax */
#endif #endif
@ -249,7 +250,7 @@ FSUB fsub[] = {
* of archive we are dealing with. This helps to properly id archive formats * of archive we are dealing with. This helps to properly id archive formats
* some formats may be subsets of others.... * some formats may be subsets of others....
*/ */
int ford[] = {5, 4, 9, 8, 7, 6, 3, 2, 1, 0, -1}; int ford[] = {10, 5, 4, 9, 8, 7, 6, 3, 2, 1, 0, -1};
/* /*
* Do we have -C anywhere and what is it? * Do we have -C anywhere and what is it?
@ -725,9 +726,10 @@ static void
tar_options(int argc, char **argv) tar_options(int argc, char **argv)
{ {
int c; int c;
int Oflag = 0;
int nincfiles = 0; int nincfiles = 0;
int incfiles_max = 0; int incfiles_max = 0;
unsigned int i;
unsigned int format = F_TAR;
struct incfile { struct incfile {
char *file; char *file;
char *dir; char *dir;
@ -743,7 +745,7 @@ tar_options(int argc, char **argv)
* process option flags * process option flags
*/ */
while ((c = getoldopt(argc, argv, while ((c = getoldopt(argc, argv,
"b:cef:hjmopqruts:vwxzBC:HI:LNOPXZ014578")) != -1) { "b:cef:hjmopqruts:vwxzBC:F:HI:LNOPXZ014578")) != -1) {
switch (c) { switch (c) {
case 'b': case 'b':
/* /*
@ -792,10 +794,10 @@ tar_options(int argc, char **argv)
pmtime = 0; pmtime = 0;
break; break;
case 'O': case 'O':
Oflag = 1; format = F_OTAR;
break; break;
case 'o': case 'o':
Oflag = 2; format = F_OTAR;
tar_nodir = 1; tar_nodir = 1;
break; break;
case 'p': case 'p':
@ -868,6 +870,24 @@ tar_options(int argc, char **argv)
havechd++; havechd++;
chdname = optarg; chdname = optarg;
break; break;
case 'F':
for (i = 0; i < sizeof(fsub)/sizeof(FSUB); ++i)
if (fsub[i].name != NULL &&
strcmp(fsub[i].name, optarg) == 0)
break;
if (i < sizeof(fsub)/sizeof(FSUB)) {
format = i;
break;
}
paxwarn(1, "Unknown -F format: %s", optarg);
(void)fputs("tar: Known -F formats are:", stderr);
for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i)
if (fsub[i].name != NULL)
(void)fprintf(stderr, " %s",
fsub[i].name);
(void)fputs("\n\n", stderr);
tar_usage();
break;
case 'H': case 'H':
/* /*
* follow command line symlinks only * follow command line symlinks only
@ -1042,7 +1062,7 @@ tar_options(int argc, char **argv)
break; break;
case ARCHIVE: case ARCHIVE:
case APPND: case APPND:
frmt = &(fsub[Oflag ? F_OTAR : F_TAR]); frmt = &fsub[format];
if (chdname != NULL) { /* initial chdir() */ if (chdname != NULL) { /* initial chdir() */
if (ftree_add(chdname, 1) < 0) if (ftree_add(chdname, 1) < 0)
@ -1704,11 +1724,12 @@ void
tar_usage(void) tar_usage(void)
{ {
(void)fputs( (void)fputs(
"usage: tar {crtux}[014578befHhjLmNOoPpqsvwXZz]\n" "usage: tar {crtux}[014578beFfHhjLmNOoPpqsvwXZz]\n"
" [blocking-factor | archive | replstr] [-C directory] [-I file]\n" " [blocking-factor | format | archive | replstr]\n"
" [file ...]\n" " [-C directory] [-I file] [file ...]\n"
" tar {-crtux} [-014578eHhjLmNOoPpqvwXZz] [-b blocking-factor]\n" " tar {-crtux} [-014578eHhjLmNOoPpqvwXZz] [-b blocking-factor]\n"
" [-C directory] [-f archive] [-I file] [-s replstr] [file ...]\n", " [-C directory] [-F format] [-f archive] [-I file]\n"
" [-s replstr] [file ...]\n",
stderr); stderr);
exit(1); exit(1);
} }

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: tar.1,v 1.65 2023/08/03 18:17:54 aisha Exp $ .\" $OpenBSD: tar.1,v 1.67 2024/04/16 23:09:35 jca Exp $
.\" .\"
.\" Copyright (c) 1996 SigmaSoft, Th. Lockert .\" Copyright (c) 1996 SigmaSoft, Th. Lockert
.\" All rights reserved. .\" All rights reserved.
@ -23,7 +23,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd $Mdocdate: August 3 2023 $ .Dd $Mdocdate: April 16 2024 $
.Dt TAR 1 .Dt TAR 1
.Os .Os
.Sh NAME .Sh NAME
@ -32,10 +32,10 @@
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm tar .Nm tar
.Sm off .Sm off
.No { Cm crtux No } Op Cm 014578befHhjLmNOoPpqsvwXZz .No { Cm crtux No } Op Cm 014578beFfHhjLmNOoPpqsvwXZz
.Sm on .Sm on
.Bk -words .Bk -words
.Op Ar blocking-factor | archive | replstr .Op Ar blocking-factor | format | archive | replstr
.Op Fl C Ar directory .Op Fl C Ar directory
.Op Fl I Ar file .Op Fl I Ar file
.Op Ar .Op Ar
@ -46,6 +46,7 @@
.Op Fl 014578eHhjLmNOoPpqvwXZz .Op Fl 014578eHhjLmNOoPpqvwXZz
.Op Fl b Ar blocking-factor .Op Fl b Ar blocking-factor
.Op Fl C Ar directory .Op Fl C Ar directory
.Op Fl F Ar format
.Op Fl f Ar archive .Op Fl f Ar archive
.Op Fl I Ar file .Op Fl I Ar file
.Op Fl s Ar replstr .Op Fl s Ar replstr
@ -141,6 +142,77 @@ the specified directory; when creating, the specified files will be matched
from the directory. from the directory.
.It Fl e .It Fl e
Stop after the first error. Stop after the first error.
.It Fl F Ar format
Specify the output archive format, with the default format being
.Cm pax .
.Nm
currently supports the following formats:
.Bl -tag -width "sv4cpio"
.It Cm bcpio
The old binary cpio format.
The default blocksize for this format is 5120 bytes.
This format is not very portable and should not be used when other formats
are available.
Inode and device information about a file (used for detecting file hard links
by this format), which may be truncated by this format, is detected by
.Nm
and is repaired.
.It Cm cpio
The extended cpio interchange format specified in the
.St -p1003.2
standard.
The default blocksize for this format is 5120 bytes.
Inode and device information about a file (used for detecting file hard links
by this format), which may be truncated by this format, is detected by
.Nm
and is repaired.
.It Cm sv4cpio
The System V release 4 cpio.
The default blocksize for this format is 5120 bytes.
Inode and device information about a file (used for detecting file hard links
by this format), which may be truncated by this format, is detected by
.Nm
and is repaired.
.It Cm sv4crc
The System V release 4 cpio with file CRC checksums.
The default blocksize for this format is 5120 bytes.
Inode and device information about a file (used for detecting file hard links
by this format), which may be truncated by this format, is detected by
.Nm
and is repaired.
.It Cm tar
The old
.Bx
tar format as found in
.Bx 4.3 .
The default blocksize for this format is 10240 bytes.
Pathnames stored by this format must be 100 characters or less in length.
Only regular files, hard links, soft links, and directories
will be archived (other file system types are not supported).
For backwards compatibility with even older tar formats, see the
description for
.Fl o .
.It Cm ustar
The extended tar interchange format specified in the
.St -p1003.2
standard.
The default blocksize for this format is 10240 bytes.
Filenames stored by this format must be 100 characters or less in length;
the total pathname must be 256 characters or less.
.It Cm pax
The pax interchange format specified in the
.St -p1003.1-2001
standard.
The default blocksize for this format is 5120 bytes.
.El
.Pp
.Nm
will detect and report any file that it is unable to store or extract
as the result of any specific archive format restrictions.
The individual archive formats may impose additional restrictions on use.
Typical archive format restrictions include (but are not limited to):
file pathname length, file size, link pathname length, and the type of the
file.
.It Fl f Ar archive .It Fl f Ar archive
Read from or write to Read from or write to
.Ar archive . .Ar archive .

View File

@ -1,4 +1,4 @@
/* $OpenBSD: tar.c,v 1.79 2024/01/20 17:34:50 jca Exp $ */ /* $OpenBSD: tar.c,v 1.84 2024/04/16 22:58:10 jca Exp $ */
/* $NetBSD: tar.c,v 1.5 1995/03/21 09:07:49 cgd Exp $ */ /* $NetBSD: tar.c,v 1.5 1995/03/21 09:07:49 cgd Exp $ */
/*- /*-
@ -62,9 +62,6 @@ struct xheader_record {
/* shortest possible extended record: "5 a=\n" */ /* shortest possible extended record: "5 a=\n" */
#define MINXHDRSZ 5 #define MINXHDRSZ 5
/* longest record we'll accept */
#define MAXXHDRSZ BLKMULT
/* /*
* Routines for reading, writing and header identify of various versions of tar * Routines for reading, writing and header identify of various versions of tar
*/ */
@ -1135,7 +1132,7 @@ wr_ustar_or_pax(ARCHD *arcn, int ustar)
return(1); return(1);
} }
#ifndef SMALL #ifndef SMALL
else if (xheader_add(&xhdr, "linkpath", arcn->name) == -1) { else if (xheader_add(&xhdr, "linkpath", arcn->ln_name) == -1) {
paxwarn(1, "Link name too long for pax %s", paxwarn(1, "Link name too long for pax %s",
arcn->ln_name); arcn->ln_name);
xheader_free(&xhdr); xheader_free(&xhdr);
@ -1391,6 +1388,46 @@ ustar_wr(ARCHD *arcn)
return wr_ustar_or_pax(arcn, 1); return wr_ustar_or_pax(arcn, 1);
} }
/*
* pax_id()
* determine if a block given to us is a valid pax header.
* Return:
* 0 if a pax header, -1 otherwise
*/
#ifndef SMALL
int
pax_id(char *blk, int size)
{
HD_USTAR *hd;
if (size < BLKMULT)
return(-1);
hd = (HD_USTAR *)blk;
/*
* check for block of zero's first, a simple and fast test then check
* ustar magic cookie. We should use TMAGLEN, but some USTAR archive
* programs are fouled up and create archives missing the \0. Last we
* check the checksum and the type flag. If ok we have to assume it is
* a valid pax header.
*/
if (hd->prefix[0] == '\0' && hd->name[0] == '\0')
return(-1);
if (strncmp(hd->magic, TMAGIC, TMAGLEN - 1) != 0)
return(-1);
if (asc_ul(hd->chksum,sizeof(hd->chksum),OCT) != tar_chksm(blk,BLKMULT))
return(-1);
/*
* It is valid for a pax formatted archive not to start with
* a global header nor with an extended header. In that case
* we'll fall back to ustar in append mode.
*/
if (hd->typeflag == XHDRTYPE || hd->typeflag == GHDRTYPE)
return(0);
return (-1);
}
#endif
/* /*
* pax_wr() * pax_wr()
* Write out a pax format archive. * Write out a pax format archive.
@ -1548,7 +1585,11 @@ rd_size(off_t *size, const char *keyword, char *p)
static int static int
rd_xheader(ARCHD *arcn, int global, off_t size) rd_xheader(ARCHD *arcn, int global, off_t size)
{ {
char buf[MAXXHDRSZ]; /*
* The pax format supposedly supports arbitrarily sized extended
* record headers, this implementation doesn't.
*/
char buf[sizeof("30xx linkpath=") - 1 + PAXPATHLEN + sizeof("\n")];
long len; long len;
char *delim, *keyword; char *delim, *keyword;
char *nextp, *p, *end; char *nextp, *p, *end;

View File

@ -2693,8 +2693,8 @@ X509_STORE_add_crl
X509_STORE_add_lookup X509_STORE_add_lookup
X509_STORE_free X509_STORE_free
X509_STORE_get0_objects X509_STORE_get0_objects
X509_STORE_get1_objects
X509_STORE_get0_param X509_STORE_get0_param
X509_STORE_get1_objects
X509_STORE_get_check_issued X509_STORE_get_check_issued
X509_STORE_get_ex_data X509_STORE_get_ex_data
X509_STORE_get_verify X509_STORE_get_verify

View File

@ -1,4 +1,4 @@
/* $OpenBSD: bn_convert.c,v 1.15 2023/07/09 18:37:58 tb Exp $ */ /* $OpenBSD: bn_convert.c,v 1.18 2024/04/16 13:14:46 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved. * All rights reserved.
* *
@ -153,46 +153,69 @@ BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
} }
LCRYPTO_ALIAS(BN_bn2binpad); LCRYPTO_ALIAS(BN_bn2binpad);
BIGNUM * static int
BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) bn_bin2bn_cbs(BIGNUM **bnp, CBS *cbs)
{ {
unsigned int i, m;
unsigned int n;
BN_ULONG l;
BIGNUM *bn = NULL; BIGNUM *bn = NULL;
BN_ULONG w;
uint8_t v;
int b, i;
if (len < 0) if ((bn = *bnp) == NULL)
return (NULL); bn = BN_new();
if (ret == NULL) if (bn == NULL)
ret = bn = BN_new(); goto err;
if (ret == NULL) if (!bn_expand_bytes(bn, CBS_len(cbs)))
return (NULL); goto err;
l = 0;
n = len; b = 0;
if (n == 0) { i = 0;
ret->top = 0; w = 0;
return (ret);
} while (CBS_len(cbs) > 0) {
i = ((n - 1) / BN_BYTES) + 1; if (!CBS_get_last_u8(cbs, &v))
m = ((n - 1) % (BN_BYTES)); goto err;
if (!bn_wexpand(ret, (int)i)) {
BN_free(bn); w |= (BN_ULONG)v << b;
return NULL; b += 8;
}
ret->top = i; if (b == BN_BITS2 || CBS_len(cbs) == 0) {
ret->neg = 0; b = 0;
while (n--) { bn->d[i++] = w;
l = (l << 8L) | *(s++); w = 0;
if (m-- == 0) {
ret->d[--i] = l;
l = 0;
m = BN_BYTES - 1;
} }
} }
/* need to call this due to clear byte at top if avoiding
* having the top bit set (-ve number) */ bn->neg = 0;
bn_correct_top(ret); bn->top = i;
return (ret);
bn_correct_top(bn);
*bnp = bn;
return 1;
err:
if (*bnp == NULL)
BN_free(bn);
return 0;
}
BIGNUM *
BN_bin2bn(const unsigned char *d, int len, BIGNUM *bn)
{
CBS cbs;
if (len < 0)
return NULL;
CBS_init(&cbs, d, len);
if (!bn_bin2bn_cbs(&bn, &cbs))
return NULL;
return bn;
} }
LCRYPTO_ALIAS(BN_bin2bn); LCRYPTO_ALIAS(BN_bin2bn);
@ -431,7 +454,7 @@ bn_dec2bn_cbs(BIGNUM **bnp, CBS *cbs)
bn = BN_new(); bn = BN_new();
if (bn == NULL) if (bn == NULL)
goto err; goto err;
if (!bn_expand(bn, digits * 4)) if (!bn_expand_bits(bn, digits * 4))
goto err; goto err;
if ((d = digits % BN_DEC_NUM) == 0) if ((d = digits % BN_DEC_NUM) == 0)
@ -628,13 +651,13 @@ bn_hex2bn_cbs(BIGNUM **bnp, CBS *cbs)
bn = BN_new(); bn = BN_new();
if (bn == NULL) if (bn == NULL)
goto err; goto err;
if (!bn_expand(bn, digits * 4)) if (!bn_expand_bits(bn, digits * 4))
goto err; goto err;
if (!CBS_get_bytes(cbs, cbs, digits)) if (!CBS_get_bytes(cbs, cbs, digits))
goto err; goto err;
b = BN_BITS2; b = 0;
i = 0; i = 0;
w = 0; w = 0;
@ -652,11 +675,11 @@ bn_hex2bn_cbs(BIGNUM **bnp, CBS *cbs)
else else
goto err; goto err;
w |= (BN_ULONG)v << (BN_BITS2 - b); w |= (BN_ULONG)v << b;
b -= 4; b += 4;
if (b == 0 || digits == 0) { if (b == BN_BITS2 || digits == 0) {
b = BN_BITS2; b = 0;
bn->d[i++] = w; bn->d[i++] = w;
w = 0; w = 0;
} }

View File

@ -1,4 +1,4 @@
/* $OpenBSD: bn_lib.c,v 1.91 2024/04/15 14:35:25 jsing Exp $ */ /* $OpenBSD: bn_lib.c,v 1.93 2024/04/16 13:07:14 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved. * All rights reserved.
* *
@ -219,13 +219,10 @@ bn_expand_internal(BIGNUM *bn, int words)
} }
int int
bn_expand(BIGNUM *bn, int bits) bn_expand_bits(BIGNUM *bn, size_t bits)
{ {
int words; int words;
if (bits < 0)
return 0;
if (bits > (INT_MAX - BN_BITS2 + 1)) if (bits > (INT_MAX - BN_BITS2 + 1))
return 0; return 0;
@ -234,6 +231,19 @@ bn_expand(BIGNUM *bn, int bits)
return bn_wexpand(bn, words); return bn_wexpand(bn, words);
} }
int
bn_expand_bytes(BIGNUM *bn, size_t bytes)
{
int words;
if (bytes > (INT_MAX - BN_BYTES + 1))
return 0;
words = (bytes + BN_BYTES - 1) / BN_BYTES;
return bn_wexpand(bn, words);
}
int int
bn_wexpand(BIGNUM *bn, int words) bn_wexpand(BIGNUM *bn, int words)
{ {

View File

@ -1,4 +1,4 @@
/* $OpenBSD: bn_local.h,v 1.41 2024/04/10 15:09:03 tb Exp $ */ /* $OpenBSD: bn_local.h,v 1.43 2024/04/16 13:07:14 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved. * All rights reserved.
* *
@ -259,7 +259,8 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
const BN_ULONG *np, const BN_ULONG *n0, int num); const BN_ULONG *np, const BN_ULONG *n0, int num);
void bn_correct_top(BIGNUM *a); void bn_correct_top(BIGNUM *a);
int bn_expand(BIGNUM *a, int bits); int bn_expand_bits(BIGNUM *a, size_t bits);
int bn_expand_bytes(BIGNUM *a, size_t bytes);
int bn_wexpand(BIGNUM *a, int words); int bn_wexpand(BIGNUM *a, int words);
BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssl_tlsext.c,v 1.148 2024/04/04 08:02:21 tb Exp $ */ /* $OpenBSD: ssl_tlsext.c,v 1.149 2024/04/16 17:46:30 tb Exp $ */
/* /*
* Copyright (c) 2016, 2017, 2019 Joel Sing <jsing@openbsd.org> * Copyright (c) 2016, 2017, 2019 Joel Sing <jsing@openbsd.org>
* Copyright (c) 2017 Doug Hogan <doug@openbsd.org> * Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
@ -1493,6 +1493,45 @@ tlsext_keyshare_server_process(SSL *s, uint16_t msg_type, CBS *cbs, int *alert)
return 0; return 0;
} }
if (s->s3->hs.tls13.hrr) {
if (!CBS_get_u16_length_prefixed(cbs, &client_shares))
return 0;
/* Unpack client share. */
if (!CBS_get_u16(&client_shares, &group))
return 0;
if (!CBS_get_u16_length_prefixed(&client_shares, &key_exchange))
return 0;
/* There should only be one share. */
if (CBS_len(&client_shares) != 0)
return 0;
if (group != s->s3->hs.tls13.server_group) {
*alert = SSL_AD_ILLEGAL_PARAMETER;
return 0;
}
if (s->s3->hs.key_share != NULL) {
*alert = SSL_AD_INTERNAL_ERROR;
return 0;
}
/* Decode and store the selected key share. */
if ((s->s3->hs.key_share = tls_key_share_new(group)) == NULL) {
*alert = SSL_AD_INTERNAL_ERROR;
return 0;
}
if (!tls_key_share_peer_public(s->s3->hs.key_share,
&key_exchange, &decode_error, NULL)) {
if (!decode_error)
*alert = SSL_AD_INTERNAL_ERROR;
return 0;
}
return 1;
}
/* /*
* XXX similar to tls1_get_supported_group, but client pref * XXX similar to tls1_get_supported_group, but client pref
* only - consider deduping later. * only - consider deduping later.

View File

@ -1,7 +1,7 @@
/* $OpenBSD: spleen32x64.h,v 1.9 2020/07/31 20:14:47 fcambus Exp $ */ /* $OpenBSD: spleen32x64.h,v 1.10 2024/04/16 17:15:15 fcambus Exp $ */
/* /*
* Copyright (c) 2018-2020 Frederic Cambus <fcambus@openbsd.org> * Copyright (c) 2018-2024 Frederic Cambus <fcambus@openbsd.org>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -5616,11 +5616,11 @@ static u_char spleen32x64_data[] = {
0x0f, 0x00, 0x00, 0xf0, /* ....****................****.... */ 0x0f, 0x00, 0x00, 0xf0, /* ....****................****.... */
0x0f, 0x00, 0x00, 0xf0, /* ....****................****.... */ 0x0f, 0x00, 0x00, 0xf0, /* ....****................****.... */
0x0f, 0x80, 0x00, 0xf0, /* ....*****...............****.... */ 0x0f, 0x80, 0x00, 0xf0, /* ....*****...............****.... */
0x0f, 0xc0, 0x00, 0xf0, /* ....******..............****.... */ 0x07, 0xc0, 0x00, 0xf0, /* .....*****..............****.... */
0x07, 0xff, 0xff, 0xf0, /* .....***********************.... */ 0x07, 0xff, 0xff, 0xf0, /* .....***********************.... */
0x03, 0xff, 0xff, 0xf0, /* ......**********************.... */ 0x03, 0xff, 0xff, 0xf0, /* ......**********************.... */
0x01, 0xff, 0xff, 0xf0, /* .......*********************.... */ 0x01, 0xff, 0xff, 0xf0, /* .......*********************.... */
0x00, 0xff, 0xff, 0xf0, /* ........********************.... */ 0x00, 0x7f, 0xff, 0xf0, /* .........*******************.... */
0x00, 0x00, 0x00, 0x00, /* ................................ */ 0x00, 0x00, 0x00, 0x00, /* ................................ */
0x00, 0x00, 0x00, 0x00, /* ................................ */ 0x00, 0x00, 0x00, 0x00, /* ................................ */
0x00, 0x00, 0x00, 0x00, /* ................................ */ 0x00, 0x00, 0x00, 0x00, /* ................................ */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ip_input.c,v 1.392 2024/04/14 20:46:27 bluhm Exp $ */ /* $OpenBSD: ip_input.c,v 1.393 2024/04/16 12:56:39 bluhm Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */ /* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/* /*
@ -138,7 +138,7 @@ extern struct niqueue arpinq;
int ip_ours(struct mbuf **, int *, int, int); int ip_ours(struct mbuf **, int *, int, int);
int ip_dooptions(struct mbuf *, struct ifnet *); int ip_dooptions(struct mbuf *, struct ifnet *);
int in_ouraddr(struct mbuf *, struct ifnet *, struct rtentry **); int in_ouraddr(struct mbuf *, struct ifnet *, struct route *);
int ip_fragcheck(struct mbuf **, int *); int ip_fragcheck(struct mbuf **, int *);
struct mbuf * ip_reass(struct ipqent *, struct ipq *); struct mbuf * ip_reass(struct ipqent *, struct ipq *);
@ -424,9 +424,9 @@ bad:
int int
ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
{ {
struct mbuf *m; struct route ro;
struct rtentry *rt = NULL; struct mbuf *m;
struct ip *ip; struct ip *ip;
int hlen; int hlen;
#if NPF > 0 #if NPF > 0
struct in_addr odst; struct in_addr odst;
@ -435,6 +435,7 @@ ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
KASSERT(*offp == 0); KASSERT(*offp == 0);
ro.ro_rt = NULL;
ipstat_inc(ips_total); ipstat_inc(ips_total);
m = *mp = ipv4_check(ifp, *mp); m = *mp = ipv4_check(ifp, *mp);
if (m == NULL) if (m == NULL)
@ -482,7 +483,7 @@ ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
goto out; goto out;
} }
switch(in_ouraddr(m, ifp, &rt)) { switch(in_ouraddr(m, ifp, &ro)) {
case 2: case 2:
goto bad; goto bad;
case 1: case 1:
@ -584,14 +585,14 @@ ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
} }
#endif /* IPSEC */ #endif /* IPSEC */
ip_forward(m, ifp, rt, pfrdr); ip_forward(m, ifp, &ro, pfrdr);
*mp = NULL; *mp = NULL;
return IPPROTO_DONE; return IPPROTO_DONE;
bad: bad:
nxt = IPPROTO_DONE; nxt = IPPROTO_DONE;
m_freemp(mp); m_freemp(mp);
out: out:
rtfree(rt); rtfree(ro.ro_rt);
return nxt; return nxt;
} }
@ -805,11 +806,10 @@ ip_deliver(struct mbuf **mp, int *offp, int nxt, int af, int shared)
#undef IPSTAT_INC #undef IPSTAT_INC
int int
in_ouraddr(struct mbuf *m, struct ifnet *ifp, struct rtentry **prt) in_ouraddr(struct mbuf *m, struct ifnet *ifp, struct route *ro)
{ {
struct rtentry *rt; struct rtentry *rt;
struct ip *ip; struct ip *ip;
struct sockaddr_in sin;
int match = 0; int match = 0;
#if NPF > 0 #if NPF > 0
@ -826,13 +826,8 @@ in_ouraddr(struct mbuf *m, struct ifnet *ifp, struct rtentry **prt)
ip = mtod(m, struct ip *); ip = mtod(m, struct ip *);
memset(&sin, 0, sizeof(sin)); rt = route_mpath(ro, &ip->ip_dst, &ip->ip_src, m->m_pkthdr.ph_rtableid);
sin.sin_len = sizeof(sin); if (rt != NULL) {
sin.sin_family = AF_INET;
sin.sin_addr = ip->ip_dst;
rt = rtalloc_mpath(sintosa(&sin), &ip->ip_src.s_addr,
m->m_pkthdr.ph_rtableid);
if (rtisvalid(rt)) {
if (ISSET(rt->rt_flags, RTF_LOCAL)) if (ISSET(rt->rt_flags, RTF_LOCAL))
match = 1; match = 1;
@ -848,7 +843,6 @@ in_ouraddr(struct mbuf *m, struct ifnet *ifp, struct rtentry **prt)
m->m_flags |= M_BCAST; m->m_flags |= M_BCAST;
} }
} }
*prt = rt;
if (!match) { if (!match) {
struct ifaddr *ifa; struct ifaddr *ifa;
@ -1527,11 +1521,12 @@ const u_char inetctlerrmap[PRC_NCMDS] = {
* via a source route. * via a source route.
*/ */
void void
ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt) ip_forward(struct mbuf *m, struct ifnet *ifp, struct route *ro, int srcrt)
{ {
struct mbuf mfake, *mcopy; struct mbuf mfake, *mcopy;
struct ip *ip = mtod(m, struct ip *); struct ip *ip = mtod(m, struct ip *);
struct route ro; struct route iproute;
struct rtentry *rt;
int error = 0, type = 0, code = 0, destmtu = 0, fake = 0, len; int error = 0, type = 0, code = 0, destmtu = 0, fake = 0, len;
u_int32_t dest; u_int32_t dest;
@ -1546,19 +1541,16 @@ ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt)
goto done; goto done;
} }
ro.ro_rt = NULL; if (ro == NULL) {
route_cache(&ro, &ip->ip_dst, &ip->ip_src, m->m_pkthdr.ph_rtableid); ro = &iproute;
if (!rtisvalid(rt)) { ro->ro_rt = NULL;
rtfree(rt); }
rt = rtalloc_mpath(&ro.ro_dstsa, &ip->ip_src.s_addr, rt = route_mpath(ro, &ip->ip_dst, &ip->ip_src, m->m_pkthdr.ph_rtableid);
m->m_pkthdr.ph_rtableid); if (rt == NULL) {
if (rt == NULL) { ipstat_inc(ips_noroute);
ipstat_inc(ips_noroute); icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, dest, 0);
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, dest, 0); goto done;
return;
}
} }
ro.ro_rt = rt;
/* /*
* Save at most 68 bytes of the packet in case * Save at most 68 bytes of the packet in case
@ -1609,10 +1601,10 @@ ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt)
} }
} }
error = ip_output(m, NULL, &ro, error = ip_output(m, NULL, ro,
(IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)), (IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)),
NULL, NULL, 0); NULL, NULL, 0);
rt = ro.ro_rt; rt = ro->ro_rt;
if (error) if (error)
ipstat_inc(ips_cantforward); ipstat_inc(ips_cantforward);
else { else {
@ -1680,9 +1672,10 @@ ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt)
icmp_error(mcopy, type, code, dest, destmtu); icmp_error(mcopy, type, code, dest, destmtu);
done: done:
if (ro == &iproute)
rtfree(ro->ro_rt);
if (fake) if (fake)
m_tag_delete_chain(&mfake); m_tag_delete_chain(&mfake);
rtfree(rt);
} }
int int

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ip_var.h,v 1.115 2024/04/14 20:46:27 bluhm Exp $ */ /* $OpenBSD: ip_var.h,v 1.116 2024/04/16 12:56:39 bluhm Exp $ */
/* $NetBSD: ip_var.h,v 1.16 1996/02/13 23:43:20 christos Exp $ */ /* $NetBSD: ip_var.h,v 1.16 1996/02/13 23:43:20 christos Exp $ */
/* /*
@ -260,7 +260,7 @@ void ip_savecontrol(struct inpcb *, struct mbuf **, struct ip *,
struct mbuf *); struct mbuf *);
int ip_input_if(struct mbuf **, int *, int, int, struct ifnet *); int ip_input_if(struct mbuf **, int *, int, int, struct ifnet *);
int ip_deliver(struct mbuf **, int *, int, int, int); int ip_deliver(struct mbuf **, int *, int, int, int);
void ip_forward(struct mbuf *, struct ifnet *, struct rtentry *, int); void ip_forward(struct mbuf *, struct ifnet *, struct route *, int);
int rip_ctloutput(int, struct socket *, int, int, struct mbuf *); int rip_ctloutput(int, struct socket *, int, int, struct mbuf *);
void rip_init(void); void rip_init(void);
int rip_input(struct mbuf **, int *, int, int); int rip_input(struct mbuf **, int *, int, int);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: in6.c,v 1.262 2023/06/28 11:49:49 kn Exp $ */ /* $OpenBSD: in6.c,v 1.263 2024/04/16 14:37:49 florian Exp $ */
/* $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $ */ /* $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $ */
/* /*
@ -565,7 +565,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
* The destination address for a p2p link must have a family * The destination address for a p2p link must have a family
* of AF_UNSPEC or AF_INET6. * of AF_UNSPEC or AF_INET6.
*/ */
if ((ifp->if_flags & IFF_POINTOPOINT) != 0 && if ((ifp->if_flags & IFF_POINTOPOINT) &&
ifra->ifra_dstaddr.sin6_family != AF_INET6 && ifra->ifra_dstaddr.sin6_family != AF_INET6 &&
ifra->ifra_dstaddr.sin6_family != AF_UNSPEC) ifra->ifra_dstaddr.sin6_family != AF_UNSPEC)
return (EAFNOSUPPORT); return (EAFNOSUPPORT);
@ -603,19 +603,18 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
* zone identifier. * zone identifier.
*/ */
dst6 = ifra->ifra_dstaddr; dst6 = ifra->ifra_dstaddr;
if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) != 0 && if ((ifp->if_flags & IFF_POINTOPOINT) &&
(dst6.sin6_family == AF_INET6)) { (dst6.sin6_family == AF_INET6)) {
error = in6_check_embed_scope(&dst6, ifp->if_index); error = in6_check_embed_scope(&dst6, ifp->if_index);
if (error) if (error)
return error; return error;
} }
/* /*
* The destination address can be specified only for a p2p or a * The destination address can be specified only for a p2p interface.
* loopback interface. If specified, the corresponding prefix length * If specified, the corresponding prefix length must be 128.
* must be 128.
*/ */
if (ifra->ifra_dstaddr.sin6_family == AF_INET6) { if (ifra->ifra_dstaddr.sin6_family == AF_INET6) {
if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) == 0) if (!(ifp->if_flags & IFF_POINTOPOINT))
return (EINVAL); return (EINVAL);
if (plen != 128) if (plen != 128)
return (EINVAL); return (EINVAL);
@ -652,7 +651,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
ia6->ia_addr.sin6_family = AF_INET6; ia6->ia_addr.sin6_family = AF_INET6;
ia6->ia_addr.sin6_len = sizeof(ia6->ia_addr); ia6->ia_addr.sin6_len = sizeof(ia6->ia_addr);
ia6->ia6_updatetime = getuptime(); ia6->ia6_updatetime = getuptime();
if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) != 0) { if (ifp->if_flags & IFF_POINTOPOINT) {
/* /*
* XXX: some functions expect that ifa_dstaddr is not * XXX: some functions expect that ifa_dstaddr is not
* NULL for p2p interfaces. * NULL for p2p interfaces.
@ -687,7 +686,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
/* /*
* If a new destination address is specified, scrub the old one and * If a new destination address is specified, scrub the old one and
* install the new destination. Note that the interface must be * install the new destination. Note that the interface must be
* p2p or loopback (see the check above.) * p2p (see the check above.)
*/ */
if ((ifp->if_flags & IFF_POINTOPOINT) && dst6.sin6_family == AF_INET6 && if ((ifp->if_flags & IFF_POINTOPOINT) && dst6.sin6_family == AF_INET6 &&
!IN6_ARE_ADDR_EQUAL(&dst6.sin6_addr, &ia6->ia_dstaddr.sin6_addr)) { !IN6_ARE_ADDR_EQUAL(&dst6.sin6_addr, &ia6->ia_dstaddr.sin6_addr)) {

View File

@ -1,4 +1,4 @@
/* $OpenBSD: in6_proto.c,v 1.113 2024/01/11 14:15:12 bluhm Exp $ */ /* $OpenBSD: in6_proto.c,v 1.114 2024/04/16 12:40:40 bluhm Exp $ */
/* $KAME: in6_proto.c,v 1.66 2000/10/10 15:35:47 itojun Exp $ */ /* $KAME: in6_proto.c,v 1.66 2000/10/10 15:35:47 itojun Exp $ */
/* /*
@ -158,7 +158,7 @@ const struct protosw inet6sw[] = {
.pr_type = SOCK_RAW, .pr_type = SOCK_RAW,
.pr_domain = &inet6domain, .pr_domain = &inet6domain,
.pr_protocol = IPPROTO_RAW, .pr_protocol = IPPROTO_RAW,
.pr_flags = PR_ATOMIC|PR_ADDR, .pr_flags = PR_ATOMIC|PR_ADDR|PR_MPINPUT,
.pr_input = rip6_input, .pr_input = rip6_input,
.pr_ctlinput = rip6_ctlinput, .pr_ctlinput = rip6_ctlinput,
.pr_ctloutput = rip6_ctloutput, .pr_ctloutput = rip6_ctloutput,
@ -322,7 +322,7 @@ const struct protosw inet6sw[] = {
/* raw wildcard */ /* raw wildcard */
.pr_type = SOCK_RAW, .pr_type = SOCK_RAW,
.pr_domain = &inet6domain, .pr_domain = &inet6domain,
.pr_flags = PR_ATOMIC|PR_ADDR, .pr_flags = PR_ATOMIC|PR_ADDR|PR_MPINPUT,
.pr_input = rip6_input, .pr_input = rip6_input,
.pr_ctloutput = rip6_ctloutput, .pr_ctloutput = rip6_ctloutput,
.pr_usrreqs = &rip6_usrreqs, .pr_usrreqs = &rip6_usrreqs,

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ip6_forward.c,v 1.116 2024/02/28 10:57:20 bluhm Exp $ */ /* $OpenBSD: ip6_forward.c,v 1.117 2024/04/16 12:56:39 bluhm Exp $ */
/* $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $ */ /* $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $ */
/* /*
@ -82,11 +82,12 @@
*/ */
void void
ip6_forward(struct mbuf *m, struct rtentry *rt, int srcrt) ip6_forward(struct mbuf *m, struct route *ro, int srcrt)
{ {
struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
struct route iproute;
struct rtentry *rt;
struct sockaddr *dst; struct sockaddr *dst;
struct route ro;
struct ifnet *ifp = NULL; struct ifnet *ifp = NULL;
int error = 0, type = 0, code = 0, destmtu = 0; int error = 0, type = 0, code = 0, destmtu = 0;
struct mbuf *mcopy; struct mbuf *mcopy;
@ -165,25 +166,22 @@ reroute:
} }
#endif /* IPSEC */ #endif /* IPSEC */
ro.ro_rt = NULL; if (ro == NULL) {
route6_cache(&ro, &ip6->ip6_dst, &ip6->ip6_src, ro = &iproute;
m->m_pkthdr.ph_rtableid); ro->ro_rt = NULL;
dst = &ro.ro_dstsa;
if (!rtisvalid(rt)) {
rtfree(rt);
rt = rtalloc_mpath(dst, &ip6->ip6_src.s6_addr32[0],
m->m_pkthdr.ph_rtableid);
if (rt == NULL) {
ip6stat_inc(ip6s_noroute);
if (mcopy != NULL) {
icmp6_error(mcopy, ICMP6_DST_UNREACH,
ICMP6_DST_UNREACH_NOROUTE, 0);
}
m_freem(m);
goto done;
}
} }
ro.ro_rt = rt; rt = route6_mpath(ro, &ip6->ip6_dst, &ip6->ip6_src,
m->m_pkthdr.ph_rtableid);
if (rt == NULL) {
ip6stat_inc(ip6s_noroute);
if (mcopy != NULL) {
icmp6_error(mcopy, ICMP6_DST_UNREACH,
ICMP6_DST_UNREACH_NOROUTE, 0);
}
m_freem(m);
goto done;
}
dst = &ro->ro_dstsa;
/* /*
* Scope check: if a packet can't be delivered to its destination * Scope check: if a packet can't be delivered to its destination
@ -225,8 +223,8 @@ reroute:
*/ */
if (tdb != NULL) { if (tdb != NULL) {
/* Callee frees mbuf */ /* Callee frees mbuf */
error = ip6_output_ipsec_send(tdb, m, &ro, 0, 1); error = ip6_output_ipsec_send(tdb, m, ro, 0, 1);
rt = ro.ro_rt; rt = ro->ro_rt;
if (error) if (error)
goto senderr; goto senderr;
goto freecopy; goto freecopy;
@ -254,7 +252,7 @@ reroute:
ip6_sendredirects && ip6_sendredirects &&
(rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0) { (rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0) {
if ((ifp->if_flags & IFF_POINTOPOINT) && if ((ifp->if_flags & IFF_POINTOPOINT) &&
nd6_is_addr_neighbor(&ro.ro_dstsin6, ifp)) { nd6_is_addr_neighbor(&ro->ro_dstsin6, ifp)) {
/* /*
* If the incoming interface is equal to the outgoing * If the incoming interface is equal to the outgoing
* one, the link attached to the interface is * one, the link attached to the interface is
@ -308,8 +306,9 @@ reroute:
/* tag as generated to skip over pf_test on rerun */ /* tag as generated to skip over pf_test on rerun */
m->m_pkthdr.pf.flags |= PF_TAG_GENERATED; m->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
srcrt = 1; srcrt = 1;
rtfree(rt); if (ro == &iproute)
rt = NULL; rtfree(ro->ro_rt);
ro = NULL;
if_put(ifp); if_put(ifp);
ifp = NULL; ifp = NULL;
goto reroute; goto reroute;
@ -388,7 +387,8 @@ senderr:
freecopy: freecopy:
m_freem(mcopy); m_freem(mcopy);
done: done:
rtfree(rt); if (ro == &iproute)
rtfree(ro->ro_rt);
if_put(ifp); if_put(ifp);
#ifdef IPSEC #ifdef IPSEC
tdb_unref(tdb); tdb_unref(tdb);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ip6_input.c,v 1.260 2024/04/14 20:46:27 bluhm Exp $ */ /* $OpenBSD: ip6_input.c,v 1.261 2024/04/16 12:56:39 bluhm Exp $ */
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */ /* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
/* /*
@ -356,10 +356,10 @@ bad:
int int
ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
{ {
struct route ro;
struct mbuf *m; struct mbuf *m;
struct ip6_hdr *ip6; struct ip6_hdr *ip6;
struct sockaddr_in6 sin6; struct rtentry *rt;
struct rtentry *rt = NULL;
int ours = 0; int ours = 0;
u_int16_t src_scope, dst_scope; u_int16_t src_scope, dst_scope;
#if NPF > 0 #if NPF > 0
@ -369,8 +369,8 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
KASSERT(*offp == 0); KASSERT(*offp == 0);
ro.ro_rt = NULL;
ip6stat_inc(ip6s_total); ip6stat_inc(ip6s_total);
m = *mp = ipv6_check(ifp, *mp); m = *mp = ipv6_check(ifp, *mp);
if (m == NULL) if (m == NULL)
goto bad; goto bad;
@ -516,18 +516,14 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
/* /*
* Unicast check * Unicast check
*/ */
memset(&sin6, 0, sizeof(struct sockaddr_in6)); rt = route6_mpath(&ro, &ip6->ip6_dst, &ip6->ip6_src,
sin6.sin6_len = sizeof(struct sockaddr_in6);
sin6.sin6_family = AF_INET6;
sin6.sin6_addr = ip6->ip6_dst;
rt = rtalloc_mpath(sin6tosa(&sin6), &ip6->ip6_src.s6_addr32[0],
m->m_pkthdr.ph_rtableid); m->m_pkthdr.ph_rtableid);
/* /*
* Accept the packet if the route to the destination is marked * Accept the packet if the route to the destination is marked
* as local. * as local.
*/ */
if (rtisvalid(rt) && ISSET(rt->rt_flags, RTF_LOCAL)) { if (rt != NULL && ISSET(rt->rt_flags, RTF_LOCAL)) {
struct in6_ifaddr *ia6 = ifatoia6(rt->rt_ifa); struct in6_ifaddr *ia6 = ifatoia6(rt->rt_ifa);
if (ip6_forwarding == 0 && rt->rt_ifidx != ifp->if_index && if (ip6_forwarding == 0 && rt->rt_ifidx != ifp->if_index &&
@ -617,14 +613,14 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
} }
#endif /* IPSEC */ #endif /* IPSEC */
ip6_forward(m, rt, pfrdr); ip6_forward(m, &ro, pfrdr);
*mp = NULL; *mp = NULL;
return IPPROTO_DONE; return IPPROTO_DONE;
bad: bad:
nxt = IPPROTO_DONE; nxt = IPPROTO_DONE;
m_freemp(mp); m_freemp(mp);
out: out:
rtfree(rt); rtfree(ro.ro_rt);
return nxt; return nxt;
} }

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ip6_output.c,v 1.289 2024/04/09 11:05:05 bluhm Exp $ */ /* $OpenBSD: ip6_output.c,v 1.290 2024/04/16 12:56:39 bluhm Exp $ */
/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */ /* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
/* /*
@ -391,7 +391,7 @@ reroute:
/* initialize cached route */ /* initialize cached route */
if (ro == NULL) { if (ro == NULL) {
ro = &iproute; ro = &iproute;
bzero((caddr_t)ro, sizeof(*ro)); ro->ro_rt = NULL;
} }
ro_pmtu = ro; ro_pmtu = ro;
if (opt && opt->ip6po_rthdr) if (opt && opt->ip6po_rthdr)

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ip6_var.h,v 1.114 2024/02/14 13:18:21 claudio Exp $ */ /* $OpenBSD: ip6_var.h,v 1.115 2024/04/16 12:56:39 bluhm Exp $ */
/* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */ /* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */
/* /*
@ -320,7 +320,7 @@ int ip6_process_hopopts(struct mbuf **, u_int8_t *, int, u_int32_t *,
void ip6_savecontrol(struct inpcb *, struct mbuf *, struct mbuf **); void ip6_savecontrol(struct inpcb *, struct mbuf *, struct mbuf **);
int ip6_sysctl(int *, u_int, void *, size_t *, void *, size_t); int ip6_sysctl(int *, u_int, void *, size_t *, void *, size_t);
void ip6_forward(struct mbuf *, struct rtentry *, int); void ip6_forward(struct mbuf *, struct route *, int);
void ip6_mloopback(struct ifnet *, struct mbuf *, struct sockaddr_in6 *); void ip6_mloopback(struct ifnet *, struct mbuf *, struct sockaddr_in6 *);
int ip6_output(struct mbuf *, struct ip6_pktopts *, struct route *, int, int ip6_output(struct mbuf *, struct ip6_pktopts *, struct route *, int,

View File

@ -1,4 +1,4 @@
/* $OpenBSD: raw_ip6.c,v 1.182 2024/02/13 12:22:09 bluhm Exp $ */ /* $OpenBSD: raw_ip6.c,v 1.183 2024/04/16 12:40:40 bluhm Exp $ */
/* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */ /* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */
/* /*
@ -155,9 +155,9 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
} else } else
rip6stat_inc(rip6s_ipackets); rip6stat_inc(rip6s_ipackets);
bzero(&rip6src, sizeof(rip6src)); memset(&rip6src, 0, sizeof(rip6src));
rip6src.sin6_len = sizeof(struct sockaddr_in6);
rip6src.sin6_family = AF_INET6; rip6src.sin6_family = AF_INET6;
rip6src.sin6_len = sizeof(rip6src);
/* KAME hack: recover scopeid */ /* KAME hack: recover scopeid */
in6_recoverscope(&rip6src, &ip6->ip6_src); in6_recoverscope(&rip6src, &ip6->ip6_src);
@ -186,7 +186,13 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
TAILQ_FOREACH(inp, &rawin6pcbtable.inpt_queue, inp_queue) { TAILQ_FOREACH(inp, &rawin6pcbtable.inpt_queue, inp_queue) {
KASSERT(ISSET(inp->inp_flags, INP_IPV6)); KASSERT(ISSET(inp->inp_flags, INP_IPV6));
if (inp->inp_socket->so_rcv.sb_state & SS_CANTRCVMORE) /*
* Packet must not be inserted after disconnected wakeup
* call. To avoid race, check again when holding receive
* buffer mutex.
*/
if (ISSET(READ_ONCE(inp->inp_socket->so_rcv.sb_state),
SS_CANTRCVMORE))
continue; continue;
if (rtable_l2(inp->inp_rtableid) != if (rtable_l2(inp->inp_rtableid) !=
rtable_l2(m->m_pkthdr.ph_rtableid)) rtable_l2(m->m_pkthdr.ph_rtableid))
@ -264,7 +270,7 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
n = m_copym(m, 0, M_COPYALL, M_NOWAIT); n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
if (n != NULL) { if (n != NULL) {
struct socket *so = inp->inp_socket; struct socket *so = inp->inp_socket;
int ret; int ret = 0;
if (inp->inp_flags & IN6P_CONTROLOPTS) if (inp->inp_flags & IN6P_CONTROLOPTS)
ip6_savecontrol(inp, n, &opts); ip6_savecontrol(inp, n, &opts);
@ -272,12 +278,14 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
m_adj(n, *offp); m_adj(n, *offp);
mtx_enter(&so->so_rcv.sb_mtx); mtx_enter(&so->so_rcv.sb_mtx);
ret = sbappendaddr(so, &so->so_rcv, if (!ISSET(inp->inp_socket->so_rcv.sb_state,
sin6tosa(&rip6src), n, opts); SS_CANTRCVMORE)) {
ret = sbappendaddr(so, &so->so_rcv,
sin6tosa(&rip6src), n, opts);
}
mtx_leave(&so->so_rcv.sb_mtx); mtx_leave(&so->so_rcv.sb_mtx);
if (ret == 0) { if (ret == 0) {
/* should notify about lost packet */
m_freem(n); m_freem(n);
m_freem(opts); m_freem(opts);
rip6stat_inc(rip6s_fullsock); rip6stat_inc(rip6s_fullsock);
@ -727,7 +735,7 @@ rip6_disconnect(struct socket *so)
if ((so->so_state & SS_ISCONNECTED) == 0) if ((so->so_state & SS_ISCONNECTED) == 0)
return (ENOTCONN); return (ENOTCONN);
so->so_state &= ~SS_ISCONNECTED; /* XXX */ soisdisconnected(so);
mtx_enter(&rawin6pcbtable.inpt_mtx); mtx_enter(&rawin6pcbtable.inpt_mtx);
inp->inp_faddr6 = in6addr_any; inp->inp_faddr6 = in6addr_any;
mtx_leave(&rawin6pcbtable.inpt_mtx); mtx_leave(&rawin6pcbtable.inpt_mtx);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: mfs_vnops.c,v 1.60 2022/06/26 05:20:43 visa Exp $ */ /* $OpenBSD: mfs_vnops.c,v 1.61 2024/04/16 10:04:41 claudio Exp $ */
/* $NetBSD: mfs_vnops.c,v 1.8 1996/03/17 02:16:32 christos Exp $ */ /* $NetBSD: mfs_vnops.c,v 1.8 1996/03/17 02:16:32 christos Exp $ */
/* /*
@ -237,6 +237,9 @@ mfs_reclaim(void *v)
{ {
struct vop_reclaim_args *ap = v; struct vop_reclaim_args *ap = v;
struct vnode *vp = ap->a_vp; struct vnode *vp = ap->a_vp;
struct mfsnode *mfsp = VTOMFS(vp);
bufq_destroy(&mfsp->mfs_bufq);
free(vp->v_data, M_MFSNODE, sizeof(struct mfsnode)); free(vp->v_data, M_MFSNODE, sizeof(struct mfsnode));
vp->v_data = NULL; vp->v_data = NULL;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: uvm_amap.c,v 1.92 2023/04/11 00:45:09 jsg Exp $ */ /* $OpenBSD: uvm_amap.c,v 1.93 2024/04/16 08:53:02 mpi Exp $ */
/* $NetBSD: uvm_amap.c,v 1.27 2000/11/25 06:27:59 chs Exp $ */ /* $NetBSD: uvm_amap.c,v 1.27 2000/11/25 06:27:59 chs Exp $ */
/* /*
@ -662,9 +662,10 @@ amap_copy(struct vm_map *map, struct vm_map_entry *entry, int waitf,
chunk = amap_chunk_get(amap, lcv, 1, PR_NOWAIT); chunk = amap_chunk_get(amap, lcv, 1, PR_NOWAIT);
if (chunk == NULL) { if (chunk == NULL) {
/* amap_wipeout() releases the lock. */ amap_unlock(srcamap);
amap->am_ref = 0; /* Destroy the new amap. */
amap_wipeout(amap); amap->am_ref--;
amap_free(amap);
return; return;
} }

View File

@ -1,4 +1,4 @@
/* $OpenBSD: uvm_swap.c,v 1.169 2024/02/03 18:51:59 beck Exp $ */ /* $OpenBSD: uvm_swap.c,v 1.170 2024/04/16 10:06:37 claudio Exp $ */
/* $NetBSD: uvm_swap.c,v 1.40 2000/11/17 11:39:39 mrg Exp $ */ /* $NetBSD: uvm_swap.c,v 1.40 2000/11/17 11:39:39 mrg Exp $ */
/* /*
@ -1088,6 +1088,7 @@ swap_off(struct proc *p, struct swapdev *sdp)
*/ */
if (sdp->swd_vp->v_type == VREG) { if (sdp->swd_vp->v_type == VREG) {
crfree(sdp->swd_cred); crfree(sdp->swd_cred);
bufq_destroy(&sdp->swd_bufq);
} }
vrele(sdp->swd_vp); vrele(sdp->swd_vp);
if (sdp->swd_vp != rootvp) { if (sdp->swd_vp != rootvp) {

View File

@ -378,85 +378,6 @@ bin_file(int f)
return (bin_count > 5); return (bin_count > 5);
} }
/*
* Read a string from a file.
* Return a pointer to the string in memory.
*/
static char *
readfd(FILE *fd)
{
int len;
int ch;
char *buf;
char *p;
/*
* Make a guess about how many chars in the string
* and allocate a buffer to hold it.
*/
len = 100;
buf = ecalloc(len, sizeof (char));
for (p = buf; ; p++) {
if ((ch = getc(fd)) == '\n' || ch == EOF)
break;
if (p >= buf + len-1) {
/*
* The string is too big to fit in the buffer we have.
* Allocate a new buffer, twice as big.
*/
len *= 2;
*p = '\0';
p = ecalloc(len, sizeof (char));
strlcpy(p, buf, len);
free(buf);
buf = p;
p = buf + strlen(buf);
}
*p = (char)ch;
}
*p = '\0';
return (buf);
}
/*
* Execute a shell command.
* Return a pointer to a pipe connected to the shell command's standard output.
*/
static FILE *
shellcmd(char *cmd)
{
FILE *fd;
char *shell;
shell = lgetenv("SHELL");
if (shell != NULL && *shell != '\0') {
char *scmd;
char *esccmd;
/*
* Read the output of <$SHELL -c cmd>.
* Escape any metacharacters in the command.
*/
esccmd = shell_quote(cmd);
if (esccmd == NULL) {
fd = popen(cmd, "r");
} else {
scmd = easprintf("%s -c %s", shell, esccmd);
free(esccmd);
fd = popen(scmd, "r");
free(scmd);
}
} else {
fd = popen(cmd, "r");
}
/*
* Redirection in `popen' might have messed with the
* standard devices. Restore binary input mode.
*/
return (fd);
}
/* /*
* Expand a filename, doing any system-specific metacharacter substitutions. * Expand a filename, doing any system-specific metacharacter substitutions.
*/ */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: req.c,v 1.28 2023/07/02 07:05:14 tb Exp $ */ /* $OpenBSD: req.c,v 1.29 2024/04/17 01:24:43 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved. * All rights reserved.
* *
@ -1697,6 +1697,7 @@ set_keygen_ctx(BIO * err, const char *gstr, int *pkey_type,
if (EVP_PKEY_keygen_init(gctx) <= 0) { if (EVP_PKEY_keygen_init(gctx) <= 0) {
BIO_puts(err, "Error initializing keygen context\n"); BIO_puts(err, "Error initializing keygen context\n");
ERR_print_errors(err); ERR_print_errors(err);
EVP_PKEY_CTX_free(gctx);
return NULL; return NULL;
} }
if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1)) { if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1)) {

View File

@ -1,4 +1,4 @@
/* $OpenBSD: server_file.c,v 1.78 2024/01/06 11:29:00 espie Exp $ */ /* $OpenBSD: server_file.c,v 1.79 2024/04/16 17:15:50 florian Exp $ */
/* /*
* Copyright (c) 2006 - 2017 Reyk Floeter <reyk@openbsd.org> * Copyright (c) 2006 - 2017 Reyk Floeter <reyk@openbsd.org>
@ -43,12 +43,14 @@
int server_file_access(struct httpd *, struct client *, int server_file_access(struct httpd *, struct client *,
char *, size_t); char *, size_t);
int server_file_request(struct httpd *, struct client *, int server_file_request(struct httpd *, struct client *,
char *, struct timespec *); struct media_type *, int, const struct stat *);
int server_partial_file_request(struct httpd *, struct client *, int server_partial_file_request(struct httpd *, struct client *,
char *, struct timespec *, char *); struct media_type *, int, const struct stat *,
int server_file_index(struct httpd *, struct client *); char *);
int server_file_index(struct httpd *, struct client *, int,
struct stat *);
int server_file_modified_since(struct http_descriptor *, int server_file_modified_since(struct http_descriptor *,
struct timespec *); const struct timespec *);
int server_file_method(struct client *); int server_file_method(struct client *);
int parse_range_spec(char *, size_t, struct range *); int parse_range_spec(char *, size_t, struct range *);
int parse_ranges(struct client *, char *, size_t); int parse_ranges(struct client *, char *, size_t);
@ -62,28 +64,42 @@ server_file_access(struct httpd *env, struct client *clt,
struct server_config *srv_conf = clt->clt_srv_conf; struct server_config *srv_conf = clt->clt_srv_conf;
struct stat st; struct stat st;
struct kv *r, key; struct kv *r, key;
struct media_type *media;
char *newpath, *encodedpath; char *newpath, *encodedpath;
int ret; int ret, fd;
errno = 0; if ((fd = open(path, O_RDONLY)) == -1) {
switch (errno) {
case ENOENT:
case ENOTDIR:
return (404);
case EACCES:
return (403);
default:
return (500);
}
}
if (fstat(fd, &st) == -1) {
close(fd);
return (500);
}
if (stat(path, &st) == -1) { if (S_ISDIR(st.st_mode)) {
goto fail;
} else if (S_ISDIR(st.st_mode)) {
/* Deny access if directory indexing is disabled */ /* Deny access if directory indexing is disabled */
if (srv_conf->flags & SRVFLAG_NO_INDEX) { if (srv_conf->flags & SRVFLAG_NO_INDEX) {
errno = EACCES; close(fd);
goto fail; return (403);
} }
if (desc->http_path_alias != NULL) { if (desc->http_path_alias != NULL) {
/* Recursion - the index "file" is a directory? */ /* Recursion - the index "file" is a directory? */
errno = EINVAL; close(fd);
goto fail; return (500);
} }
/* Redirect to path with trailing "/" */ /* Redirect to path with trailing "/" */
if (path[strlen(path) - 1] != '/') { if (path[strlen(path) - 1] != '/') {
close(fd);
if ((encodedpath = url_encode(desc->http_path)) == NULL) if ((encodedpath = url_encode(desc->http_path)) == NULL)
return (500); return (500);
if (asprintf(&newpath, "%s/", encodedpath) == -1) { if (asprintf(&newpath, "%s/", encodedpath) == -1) {
@ -101,18 +117,21 @@ server_file_access(struct httpd *env, struct client *clt,
/* Append the default index file to the location */ /* Append the default index file to the location */
if (asprintf(&newpath, "%s%s", desc->http_path, if (asprintf(&newpath, "%s%s", desc->http_path,
srv_conf->index) == -1) srv_conf->index) == -1) {
close(fd);
return (500); return (500);
}
desc->http_path_alias = newpath; desc->http_path_alias = newpath;
if (server_getlocation(clt, newpath) != srv_conf) { if (server_getlocation(clt, newpath) != srv_conf) {
/* The location has changed */ /* The location has changed */
close(fd);
return (server_file(env, clt)); return (server_file(env, clt));
} }
/* Otherwise append the default index file to the path */ /* Otherwise append the default index file to the path */
if (strlcat(path, srv_conf->index, len) >= len) { if (strlcat(path, srv_conf->index, len) >= len) {
errno = EACCES; close(fd);
goto fail; return (403);
} }
ret = server_file_access(env, clt, path, len); ret = server_file_access(env, clt, path, len);
@ -124,39 +143,72 @@ server_file_access(struct httpd *env, struct client *clt,
* stat. * stat.
*/ */
if ((srv_conf->flags & SRVFLAG_AUTO_INDEX) == 0) { if ((srv_conf->flags & SRVFLAG_AUTO_INDEX) == 0) {
errno = EACCES; close(fd);
goto fail; return (403);
} }
return (server_file_index(env, clt)); return (server_file_index(env, clt, fd, &st));
} }
close(fd);
return (ret); return (ret);
} else if (!S_ISREG(st.st_mode)) { } else if (!S_ISREG(st.st_mode)) {
/* Don't follow symlinks and ignore special files */ /* Don't follow symlinks and ignore special files */
errno = EACCES; close(fd);
goto fail;
}
key.kv_key = "Range";
r = kv_find(&desc->http_headers, &key);
if (r != NULL)
return (server_partial_file_request(env, clt, path,
&st.st_mtim, r->kv_value));
else
return (server_file_request(env, clt, path, &st.st_mtim));
fail:
switch (errno) {
case ENOENT:
case ENOTDIR:
return (404);
case EACCES:
return (403); return (403);
default:
return (500);
} }
/* NOTREACHED */ media = media_find_config(env, srv_conf, path);
/* Only consider range requests for GET */
if (desc->http_method == HTTP_METHOD_GET) {
key.kv_key = "Range";
r = kv_find(&desc->http_headers, &key);
if (r != NULL)
return (server_partial_file_request(env, clt, media,
fd, &st, r->kv_value));
}
/* change path to path.gz if necessary. */
if (srv_conf->flags & SRVFLAG_GZIP_STATIC) {
struct http_descriptor *req = clt->clt_descreq;
struct http_descriptor *resp = clt->clt_descresp;
struct stat gzst;
int gzfd;
char gzpath[PATH_MAX];
/* check Accept-Encoding header */
key.kv_key = "Accept-Encoding";
r = kv_find(&req->http_headers, &key);
if (r != NULL && strstr(r->kv_value, "gzip") != NULL) {
/* append ".gz" to path and check existence */
ret = snprintf(gzpath, sizeof(gzpath), "%s.gz", path);
if (ret < 0 || (size_t)ret >= sizeof(gzpath)) {
close(fd);
return (500);
}
if ((gzfd = open(gzpath, O_RDONLY)) != -1) {
/* .gz must be a file, and not older */
if (fstat(gzfd, &gzst) != -1 &&
S_ISREG(gzst.st_mode) &&
timespeccmp(&gzst.st_mtim, &st.st_mtim,
>=)) {
kv_add(&resp->http_headers,
"Content-Encoding", "gzip");
/* Use original file timestamp */
gzst.st_mtim = st.st_mtim;
st = gzst;
close(fd);
fd = gzfd;
} else {
close(gzfd);
}
}
}
}
return (server_file_request(env, clt, media, fd, &st));
} }
int int
@ -216,73 +268,30 @@ server_file_method(struct client *clt)
} }
int int
server_file_request(struct httpd *env, struct client *clt, char *path, server_file_request(struct httpd *env, struct client *clt, struct media_type
struct timespec *mtim) *media, int fd, const struct stat *st)
{ {
struct server_config *srv_conf = clt->clt_srv_conf; struct server_config *srv_conf = clt->clt_srv_conf;
struct media_type *media;
const char *errstr = NULL; const char *errstr = NULL;
int fd = -1, ret, code = 500; int ret, code = 500;
struct stat st;
size_t bufsiz; size_t bufsiz;
char gzpath[PATH_MAX];
if ((ret = server_file_method(clt)) != 0) { if ((ret = server_file_method(clt)) != 0) {
code = ret; code = ret;
goto abort; goto abort;
} }
media = media_find_config(env, srv_conf, path); if ((ret = server_file_modified_since(clt->clt_descreq, &st->st_mtim))
if ((ret = server_file_modified_since(clt->clt_descreq, mtim)) != -1) { != -1) {
/* send the header without a body */ /* send the header without a body */
if ((ret = server_response_http(clt, ret, media, -1, if ((ret = server_response_http(clt, ret, media, -1,
MINIMUM(time(NULL), mtim->tv_sec))) == -1) MINIMUM(time(NULL), st->st_mtim.tv_sec))) == -1)
goto fail; goto fail;
goto done; goto done;
} }
/* change path to path.gz if necessary. */ ret = server_response_http(clt, 200, media, st->st_size,
if (srv_conf->flags & SRVFLAG_GZIP_STATIC) { MINIMUM(time(NULL), st->st_mtim.tv_sec));
struct http_descriptor *req = clt->clt_descreq;
struct http_descriptor *resp = clt->clt_descresp;
struct kv *r, key;
/* check Accept-Encoding header */
key.kv_key = "Accept-Encoding";
r = kv_find(&req->http_headers, &key);
if (r != NULL && strstr(r->kv_value, "gzip") != NULL) {
/* append ".gz" to path and check existence */
ret = snprintf(gzpath, sizeof(gzpath), "%s.gz", path);
if (ret < 0 || (size_t)ret >= sizeof(gzpath))
goto abort;
if ((fd = open(gzpath, O_RDONLY)) != -1) {
/* .gz must be a file, and not older */
if (fstat(fd, &st) != -1 &&
S_ISREG(st.st_mode) &&
timespeccmp(&st.st_mtim, mtim, >=)) {
kv_add(&resp->http_headers,
"Content-Encoding", "gzip");
/* Use original file timestamp */
st.st_mtim = *mtim;
} else {
close(fd);
fd = -1;
}
}
}
}
/* Now open the file, should be readable or we have another problem */
if (fd == -1) {
if ((fd = open(path, O_RDONLY)) == -1)
goto abort;
if (fstat(fd, &st) == -1)
goto abort;
}
ret = server_response_http(clt, 200, media, st.st_size,
MINIMUM(time(NULL), st.st_mtim.tv_sec));
switch (ret) { switch (ret) {
case -1: case -1:
goto fail; goto fail;
@ -307,7 +316,7 @@ server_file_request(struct httpd *env, struct client *clt, char *path,
} }
/* Adjust read watermark to the optimal file io size */ /* Adjust read watermark to the optimal file io size */
bufsiz = MAXIMUM(st.st_blksize, 64 * 1024); bufsiz = MAXIMUM(st->st_blksize, 64 * 1024);
bufferevent_setwatermark(clt->clt_srvbev, EV_READ, 0, bufferevent_setwatermark(clt->clt_srvbev, EV_READ, 0,
bufsiz); bufsiz);
@ -333,47 +342,34 @@ server_file_request(struct httpd *env, struct client *clt, char *path,
} }
int int
server_partial_file_request(struct httpd *env, struct client *clt, char *path, server_partial_file_request(struct httpd *env, struct client *clt,
struct timespec *mtim, char *range_str) struct media_type *media, int fd, const struct stat *st, char *range_str)
{ {
struct server_config *srv_conf = clt->clt_srv_conf; struct server_config *srv_conf = clt->clt_srv_conf;
struct http_descriptor *resp = clt->clt_descresp; struct http_descriptor *resp = clt->clt_descresp;
struct http_descriptor *desc = clt->clt_descreq; struct media_type multipart_media;
struct media_type *media, multipart_media;
struct range_data *r = &clt->clt_ranges; struct range_data *r = &clt->clt_ranges;
struct range *range; struct range *range;
size_t content_length = 0, bufsiz; size_t content_length = 0, bufsiz;
struct stat st; int code = 500, i, nranges, ret;
int code = 500, fd = -1, i, nranges, ret;
char content_range[64]; char content_range[64];
const char *errstr = NULL; const char *errstr = NULL;
/* Ignore range request for methods other than GET */ if ((nranges = parse_ranges(clt, range_str, st->st_size)) < 1) {
if (desc->http_method != HTTP_METHOD_GET)
return server_file_request(env, clt, path, mtim);
/* Now open the file, should be readable or we have another problem */
if ((fd = open(path, O_RDONLY)) == -1)
goto abort;
if (fstat(fd, &st) == -1)
goto abort;
if ((nranges = parse_ranges(clt, range_str, st.st_size)) < 1) {
code = 416; code = 416;
(void)snprintf(content_range, sizeof(content_range), (void)snprintf(content_range, sizeof(content_range),
"bytes */%lld", st.st_size); "bytes */%lld", st->st_size);
errstr = content_range; errstr = content_range;
goto abort; goto abort;
} }
media = media_find_config(env, srv_conf, path);
r->range_media = media; r->range_media = media;
if (nranges == 1) { if (nranges == 1) {
range = &r->range[0]; range = &r->range[0];
(void)snprintf(content_range, sizeof(content_range), (void)snprintf(content_range, sizeof(content_range),
"bytes %lld-%lld/%lld", range->start, range->end, "bytes %lld-%lld/%lld", range->start, range->end,
st.st_size); st->st_size);
if (kv_add(&resp->http_headers, "Content-Range", if (kv_add(&resp->http_headers, "Content-Range",
content_range) == NULL) content_range) == NULL)
goto abort; goto abort;
@ -395,7 +391,7 @@ server_partial_file_request(struct httpd *env, struct client *clt, char *path,
"Content-Range: bytes %lld-%lld/%lld\r\n\r\n", "Content-Range: bytes %lld-%lld/%lld\r\n\r\n",
clt->clt_boundary, clt->clt_boundary,
media->media_type, media->media_subtype, media->media_type, media->media_subtype,
range->start, range->end, st.st_size)) < 0) range->start, range->end, st->st_size)) < 0)
goto abort; goto abort;
/* Add data length */ /* Add data length */
@ -420,7 +416,7 @@ server_partial_file_request(struct httpd *env, struct client *clt, char *path,
r->range_toread = TOREAD_HTTP_RANGE; r->range_toread = TOREAD_HTTP_RANGE;
ret = server_response_http(clt, 206, media, content_length, ret = server_response_http(clt, 206, media, content_length,
MINIMUM(time(NULL), st.st_mtim.tv_sec)); MINIMUM(time(NULL), st->st_mtim.tv_sec));
switch (ret) { switch (ret) {
case -1: case -1:
goto fail; goto fail;
@ -445,7 +441,7 @@ server_partial_file_request(struct httpd *env, struct client *clt, char *path,
} }
/* Adjust read watermark to the optimal file io size */ /* Adjust read watermark to the optimal file io size */
bufsiz = MAXIMUM(st.st_blksize, 64 * 1024); bufsiz = MAXIMUM(st->st_blksize, 64 * 1024);
bufferevent_setwatermark(clt->clt_srvbev, EV_READ, 0, bufferevent_setwatermark(clt->clt_srvbev, EV_READ, 0,
bufsiz); bufsiz);
@ -482,21 +478,21 @@ select_visible(const struct dirent *dp)
} }
int int
server_file_index(struct httpd *env, struct client *clt) server_file_index(struct httpd *env, struct client *clt, int fd,
struct stat *st)
{ {
char path[PATH_MAX]; char path[PATH_MAX];
char tmstr[21]; char tmstr[21];
struct http_descriptor *desc = clt->clt_descreq; struct http_descriptor *desc = clt->clt_descreq;
struct server_config *srv_conf = clt->clt_srv_conf; struct server_config *srv_conf = clt->clt_srv_conf;
struct dirent **namelist, *dp; struct dirent **namelist, *dp;
int namesize, i, ret, fd = -1, skip; int namesize, i, ret, skip;
int code = 500; int code = 500;
struct evbuffer *evb = NULL; struct evbuffer *evb = NULL;
struct media_type *media; struct media_type *media;
const char *stripped; const char *stripped;
char *escapeduri, *escapedhtml, *escapedpath; char *escapeduri, *escapedhtml, *escapedpath;
struct tm tm; struct tm tm;
struct stat st;
time_t t, dir_mtime; time_t t, dir_mtime;
char human_size[FMT_SCALED_STRSIZE]; char human_size[FMT_SCALED_STRSIZE];
@ -511,14 +507,8 @@ server_file_index(struct httpd *env, struct client *clt)
srv_conf->root, stripped) >= sizeof(path)) srv_conf->root, stripped) >= sizeof(path))
goto abort; goto abort;
/* Now open the file, should be readable or we have another problem */
if ((fd = open(path, O_RDONLY)) == -1)
goto abort;
if (fstat(fd, &st) == -1)
goto abort;
/* Save last modification time */ /* Save last modification time */
dir_mtime = MINIMUM(time(NULL), st.st_mtim.tv_sec); dir_mtime = MINIMUM(time(NULL), st->st_mtim.tv_sec);
if ((evb = evbuffer_new()) == NULL) if ((evb = evbuffer_new()) == NULL)
goto abort; goto abort;
@ -548,7 +538,7 @@ server_file_index(struct httpd *env, struct client *clt)
free(escapedpath); free(escapedpath);
if ((namesize = scandir(path, &namelist, select_visible, if ((namesize = scandirat(fd, ".", &namelist, select_visible,
alphasort)) == -1) alphasort)) == -1)
goto abort; goto abort;
@ -722,7 +712,8 @@ server_file_error(struct bufferevent *bev, short error, void *arg)
} }
int int
server_file_modified_since(struct http_descriptor *desc, struct timespec *mtim) server_file_modified_since(struct http_descriptor *desc, const struct timespec
*mtim)
{ {
struct kv key, *since; struct kv key, *since;
struct tm tm; struct tm tm;