sync with OpenBSD -current
This commit is contained in:
parent
382ecd9441
commit
1b576c8ddf
@ -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 $ */
|
||||
|
||||
/*-
|
||||
@ -284,6 +284,7 @@ int tar_wr(ARCHD *);
|
||||
int ustar_id(char *, int);
|
||||
int ustar_rd(ARCHD *, char *);
|
||||
int ustar_wr(ARCHD *);
|
||||
int pax_id(char *, int);
|
||||
int pax_wr(ARCHD *);
|
||||
|
||||
/*
|
||||
|
@ -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 $ */
|
||||
|
||||
/*-
|
||||
@ -228,7 +228,7 @@ FSUB fsub[] = {
|
||||
/* 9: gzip, to detect failure to use -z */
|
||||
{NULL, 0, 4, 0, 0, 0, 0, gzip_id},
|
||||
/* 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,
|
||||
tar_opt},
|
||||
#endif
|
||||
@ -237,10 +237,11 @@ FSUB fsub[] = {
|
||||
#define F_ACPIO 1 /* format when called as cpio -c */
|
||||
#define F_CPIO 3 /* format when called as cpio */
|
||||
#define F_OTAR 4 /* format when called as tar -o */
|
||||
#define F_TAR 5 /* format when called as tar */
|
||||
#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 */
|
||||
#else
|
||||
# define F_TAR 10 /* default write format when called as tar: ustar */
|
||||
# define DEFLT 10 /* default write format when called as pax: pax */
|
||||
#endif
|
||||
|
||||
@ -249,7 +250,7 @@ FSUB fsub[] = {
|
||||
* of archive we are dealing with. This helps to properly id archive formats
|
||||
* 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?
|
||||
@ -725,9 +726,10 @@ static void
|
||||
tar_options(int argc, char **argv)
|
||||
{
|
||||
int c;
|
||||
int Oflag = 0;
|
||||
int nincfiles = 0;
|
||||
int incfiles_max = 0;
|
||||
unsigned int i;
|
||||
unsigned int format = F_TAR;
|
||||
struct incfile {
|
||||
char *file;
|
||||
char *dir;
|
||||
@ -743,7 +745,7 @@ tar_options(int argc, char **argv)
|
||||
* process option flags
|
||||
*/
|
||||
while ((c = getoldopt(argc, argv,
|
||||
"b:cef:hjmopqruts:vwxzBC:HI:LNOPXZ014578")) != -1) {
|
||||
"b:cef:hjmopqruts:vwxzBC:F:HI:LNOPXZ014578")) != -1) {
|
||||
switch (c) {
|
||||
case 'b':
|
||||
/*
|
||||
@ -792,10 +794,10 @@ tar_options(int argc, char **argv)
|
||||
pmtime = 0;
|
||||
break;
|
||||
case 'O':
|
||||
Oflag = 1;
|
||||
format = F_OTAR;
|
||||
break;
|
||||
case 'o':
|
||||
Oflag = 2;
|
||||
format = F_OTAR;
|
||||
tar_nodir = 1;
|
||||
break;
|
||||
case 'p':
|
||||
@ -868,6 +870,24 @@ tar_options(int argc, char **argv)
|
||||
havechd++;
|
||||
chdname = optarg;
|
||||
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':
|
||||
/*
|
||||
* follow command line symlinks only
|
||||
@ -1042,7 +1062,7 @@ tar_options(int argc, char **argv)
|
||||
break;
|
||||
case ARCHIVE:
|
||||
case APPND:
|
||||
frmt = &(fsub[Oflag ? F_OTAR : F_TAR]);
|
||||
frmt = &fsub[format];
|
||||
|
||||
if (chdname != NULL) { /* initial chdir() */
|
||||
if (ftree_add(chdname, 1) < 0)
|
||||
@ -1704,11 +1724,12 @@ void
|
||||
tar_usage(void)
|
||||
{
|
||||
(void)fputs(
|
||||
"usage: tar {crtux}[014578befHhjLmNOoPpqsvwXZz]\n"
|
||||
" [blocking-factor | archive | replstr] [-C directory] [-I file]\n"
|
||||
" [file ...]\n"
|
||||
"usage: tar {crtux}[014578beFfHhjLmNOoPpqsvwXZz]\n"
|
||||
" [blocking-factor | format | archive | replstr]\n"
|
||||
" [-C directory] [-I file] [file ...]\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);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -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
|
||||
.\" All rights reserved.
|
||||
@ -23,7 +23,7 @@
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd $Mdocdate: August 3 2023 $
|
||||
.Dd $Mdocdate: April 16 2024 $
|
||||
.Dt TAR 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -32,10 +32,10 @@
|
||||
.Sh SYNOPSIS
|
||||
.Nm tar
|
||||
.Sm off
|
||||
.No { Cm crtux No } Op Cm 014578befHhjLmNOoPpqsvwXZz
|
||||
.No { Cm crtux No } Op Cm 014578beFfHhjLmNOoPpqsvwXZz
|
||||
.Sm on
|
||||
.Bk -words
|
||||
.Op Ar blocking-factor | archive | replstr
|
||||
.Op Ar blocking-factor | format | archive | replstr
|
||||
.Op Fl C Ar directory
|
||||
.Op Fl I Ar file
|
||||
.Op Ar
|
||||
@ -46,6 +46,7 @@
|
||||
.Op Fl 014578eHhjLmNOoPpqvwXZz
|
||||
.Op Fl b Ar blocking-factor
|
||||
.Op Fl C Ar directory
|
||||
.Op Fl F Ar format
|
||||
.Op Fl f Ar archive
|
||||
.Op Fl I Ar file
|
||||
.Op Fl s Ar replstr
|
||||
@ -141,6 +142,77 @@ the specified directory; when creating, the specified files will be matched
|
||||
from the directory.
|
||||
.It Fl e
|
||||
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
|
||||
Read from or write to
|
||||
.Ar archive .
|
||||
|
@ -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 $ */
|
||||
|
||||
/*-
|
||||
@ -62,9 +62,6 @@ struct xheader_record {
|
||||
/* shortest possible extended record: "5 a=\n" */
|
||||
#define MINXHDRSZ 5
|
||||
|
||||
/* longest record we'll accept */
|
||||
#define MAXXHDRSZ BLKMULT
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
#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",
|
||||
arcn->ln_name);
|
||||
xheader_free(&xhdr);
|
||||
@ -1391,6 +1388,46 @@ ustar_wr(ARCHD *arcn)
|
||||
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()
|
||||
* Write out a pax format archive.
|
||||
@ -1548,7 +1585,11 @@ rd_size(off_t *size, const char *keyword, char *p)
|
||||
static int
|
||||
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;
|
||||
char *delim, *keyword;
|
||||
char *nextp, *p, *end;
|
||||
|
@ -2693,8 +2693,8 @@ X509_STORE_add_crl
|
||||
X509_STORE_add_lookup
|
||||
X509_STORE_free
|
||||
X509_STORE_get0_objects
|
||||
X509_STORE_get1_objects
|
||||
X509_STORE_get0_param
|
||||
X509_STORE_get1_objects
|
||||
X509_STORE_get_check_issued
|
||||
X509_STORE_get_ex_data
|
||||
X509_STORE_get_verify
|
||||
|
@ -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)
|
||||
* All rights reserved.
|
||||
*
|
||||
@ -153,46 +153,69 @@ BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
|
||||
}
|
||||
LCRYPTO_ALIAS(BN_bn2binpad);
|
||||
|
||||
BIGNUM *
|
||||
BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
|
||||
static int
|
||||
bn_bin2bn_cbs(BIGNUM **bnp, CBS *cbs)
|
||||
{
|
||||
unsigned int i, m;
|
||||
unsigned int n;
|
||||
BN_ULONG l;
|
||||
BIGNUM *bn = NULL;
|
||||
BN_ULONG w;
|
||||
uint8_t v;
|
||||
int b, i;
|
||||
|
||||
if (len < 0)
|
||||
return (NULL);
|
||||
if (ret == NULL)
|
||||
ret = bn = BN_new();
|
||||
if (ret == NULL)
|
||||
return (NULL);
|
||||
l = 0;
|
||||
n = len;
|
||||
if (n == 0) {
|
||||
ret->top = 0;
|
||||
return (ret);
|
||||
}
|
||||
i = ((n - 1) / BN_BYTES) + 1;
|
||||
m = ((n - 1) % (BN_BYTES));
|
||||
if (!bn_wexpand(ret, (int)i)) {
|
||||
BN_free(bn);
|
||||
return NULL;
|
||||
}
|
||||
ret->top = i;
|
||||
ret->neg = 0;
|
||||
while (n--) {
|
||||
l = (l << 8L) | *(s++);
|
||||
if (m-- == 0) {
|
||||
ret->d[--i] = l;
|
||||
l = 0;
|
||||
m = BN_BYTES - 1;
|
||||
if ((bn = *bnp) == NULL)
|
||||
bn = BN_new();
|
||||
if (bn == NULL)
|
||||
goto err;
|
||||
if (!bn_expand_bytes(bn, CBS_len(cbs)))
|
||||
goto err;
|
||||
|
||||
b = 0;
|
||||
i = 0;
|
||||
w = 0;
|
||||
|
||||
while (CBS_len(cbs) > 0) {
|
||||
if (!CBS_get_last_u8(cbs, &v))
|
||||
goto err;
|
||||
|
||||
w |= (BN_ULONG)v << b;
|
||||
b += 8;
|
||||
|
||||
if (b == BN_BITS2 || CBS_len(cbs) == 0) {
|
||||
b = 0;
|
||||
bn->d[i++] = w;
|
||||
w = 0;
|
||||
}
|
||||
}
|
||||
/* need to call this due to clear byte at top if avoiding
|
||||
* having the top bit set (-ve number) */
|
||||
bn_correct_top(ret);
|
||||
return (ret);
|
||||
|
||||
bn->neg = 0;
|
||||
bn->top = i;
|
||||
|
||||
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);
|
||||
|
||||
@ -431,7 +454,7 @@ bn_dec2bn_cbs(BIGNUM **bnp, CBS *cbs)
|
||||
bn = BN_new();
|
||||
if (bn == NULL)
|
||||
goto err;
|
||||
if (!bn_expand(bn, digits * 4))
|
||||
if (!bn_expand_bits(bn, digits * 4))
|
||||
goto err;
|
||||
|
||||
if ((d = digits % BN_DEC_NUM) == 0)
|
||||
@ -628,13 +651,13 @@ bn_hex2bn_cbs(BIGNUM **bnp, CBS *cbs)
|
||||
bn = BN_new();
|
||||
if (bn == NULL)
|
||||
goto err;
|
||||
if (!bn_expand(bn, digits * 4))
|
||||
if (!bn_expand_bits(bn, digits * 4))
|
||||
goto err;
|
||||
|
||||
if (!CBS_get_bytes(cbs, cbs, digits))
|
||||
goto err;
|
||||
|
||||
b = BN_BITS2;
|
||||
b = 0;
|
||||
i = 0;
|
||||
w = 0;
|
||||
|
||||
@ -652,11 +675,11 @@ bn_hex2bn_cbs(BIGNUM **bnp, CBS *cbs)
|
||||
else
|
||||
goto err;
|
||||
|
||||
w |= (BN_ULONG)v << (BN_BITS2 - b);
|
||||
b -= 4;
|
||||
w |= (BN_ULONG)v << b;
|
||||
b += 4;
|
||||
|
||||
if (b == 0 || digits == 0) {
|
||||
b = BN_BITS2;
|
||||
if (b == BN_BITS2 || digits == 0) {
|
||||
b = 0;
|
||||
bn->d[i++] = w;
|
||||
w = 0;
|
||||
}
|
||||
|
@ -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)
|
||||
* All rights reserved.
|
||||
*
|
||||
@ -219,13 +219,10 @@ bn_expand_internal(BIGNUM *bn, int words)
|
||||
}
|
||||
|
||||
int
|
||||
bn_expand(BIGNUM *bn, int bits)
|
||||
bn_expand_bits(BIGNUM *bn, size_t bits)
|
||||
{
|
||||
int words;
|
||||
|
||||
if (bits < 0)
|
||||
return 0;
|
||||
|
||||
if (bits > (INT_MAX - BN_BITS2 + 1))
|
||||
return 0;
|
||||
|
||||
@ -234,6 +231,19 @@ bn_expand(BIGNUM *bn, int bits)
|
||||
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
|
||||
bn_wexpand(BIGNUM *bn, int words)
|
||||
{
|
||||
|
@ -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)
|
||||
* 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);
|
||||
|
||||
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);
|
||||
|
||||
BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
|
||||
|
@ -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) 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;
|
||||
}
|
||||
|
||||
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
|
||||
* only - consider deduping later.
|
||||
|
@ -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.
|
||||
*
|
||||
* 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, 0x80, 0x00, 0xf0, /* ....*****...............****.... */
|
||||
0x0f, 0xc0, 0x00, 0xf0, /* ....******..............****.... */
|
||||
0x07, 0xc0, 0x00, 0xf0, /* .....*****..............****.... */
|
||||
0x07, 0xff, 0xff, 0xf0, /* .....***********************.... */
|
||||
0x03, 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, /* ................................ */
|
||||
|
@ -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 $ */
|
||||
|
||||
/*
|
||||
@ -138,7 +138,7 @@ extern struct niqueue arpinq;
|
||||
|
||||
int ip_ours(struct mbuf **, int *, int, int);
|
||||
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 *);
|
||||
struct mbuf * ip_reass(struct ipqent *, struct ipq *);
|
||||
@ -424,9 +424,9 @@ bad:
|
||||
int
|
||||
ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
|
||||
{
|
||||
struct mbuf *m;
|
||||
struct rtentry *rt = NULL;
|
||||
struct ip *ip;
|
||||
struct route ro;
|
||||
struct mbuf *m;
|
||||
struct ip *ip;
|
||||
int hlen;
|
||||
#if NPF > 0
|
||||
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);
|
||||
|
||||
ro.ro_rt = NULL;
|
||||
ipstat_inc(ips_total);
|
||||
m = *mp = ipv4_check(ifp, *mp);
|
||||
if (m == NULL)
|
||||
@ -482,7 +483,7 @@ ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch(in_ouraddr(m, ifp, &rt)) {
|
||||
switch(in_ouraddr(m, ifp, &ro)) {
|
||||
case 2:
|
||||
goto bad;
|
||||
case 1:
|
||||
@ -584,14 +585,14 @@ ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
|
||||
}
|
||||
#endif /* IPSEC */
|
||||
|
||||
ip_forward(m, ifp, rt, pfrdr);
|
||||
ip_forward(m, ifp, &ro, pfrdr);
|
||||
*mp = NULL;
|
||||
return IPPROTO_DONE;
|
||||
bad:
|
||||
nxt = IPPROTO_DONE;
|
||||
m_freemp(mp);
|
||||
out:
|
||||
rtfree(rt);
|
||||
rtfree(ro.ro_rt);
|
||||
return nxt;
|
||||
}
|
||||
|
||||
@ -805,11 +806,10 @@ ip_deliver(struct mbuf **mp, int *offp, int nxt, int af, int shared)
|
||||
#undef IPSTAT_INC
|
||||
|
||||
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 ip *ip;
|
||||
struct sockaddr_in sin;
|
||||
int match = 0;
|
||||
|
||||
#if NPF > 0
|
||||
@ -826,13 +826,8 @@ in_ouraddr(struct mbuf *m, struct ifnet *ifp, struct rtentry **prt)
|
||||
|
||||
ip = mtod(m, struct ip *);
|
||||
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_len = sizeof(sin);
|
||||
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)) {
|
||||
rt = route_mpath(ro, &ip->ip_dst, &ip->ip_src, m->m_pkthdr.ph_rtableid);
|
||||
if (rt != NULL) {
|
||||
if (ISSET(rt->rt_flags, RTF_LOCAL))
|
||||
match = 1;
|
||||
|
||||
@ -848,7 +843,6 @@ in_ouraddr(struct mbuf *m, struct ifnet *ifp, struct rtentry **prt)
|
||||
m->m_flags |= M_BCAST;
|
||||
}
|
||||
}
|
||||
*prt = rt;
|
||||
|
||||
if (!match) {
|
||||
struct ifaddr *ifa;
|
||||
@ -1527,11 +1521,12 @@ const u_char inetctlerrmap[PRC_NCMDS] = {
|
||||
* via a source route.
|
||||
*/
|
||||
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 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;
|
||||
u_int32_t dest;
|
||||
|
||||
@ -1546,19 +1541,16 @@ ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt)
|
||||
goto done;
|
||||
}
|
||||
|
||||
ro.ro_rt = NULL;
|
||||
route_cache(&ro, &ip->ip_dst, &ip->ip_src, m->m_pkthdr.ph_rtableid);
|
||||
if (!rtisvalid(rt)) {
|
||||
rtfree(rt);
|
||||
rt = rtalloc_mpath(&ro.ro_dstsa, &ip->ip_src.s_addr,
|
||||
m->m_pkthdr.ph_rtableid);
|
||||
if (rt == NULL) {
|
||||
ipstat_inc(ips_noroute);
|
||||
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, dest, 0);
|
||||
return;
|
||||
}
|
||||
if (ro == NULL) {
|
||||
ro = &iproute;
|
||||
ro->ro_rt = NULL;
|
||||
}
|
||||
rt = route_mpath(ro, &ip->ip_dst, &ip->ip_src, m->m_pkthdr.ph_rtableid);
|
||||
if (rt == NULL) {
|
||||
ipstat_inc(ips_noroute);
|
||||
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, dest, 0);
|
||||
goto done;
|
||||
}
|
||||
ro.ro_rt = rt;
|
||||
|
||||
/*
|
||||
* 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)),
|
||||
NULL, NULL, 0);
|
||||
rt = ro.ro_rt;
|
||||
rt = ro->ro_rt;
|
||||
if (error)
|
||||
ipstat_inc(ips_cantforward);
|
||||
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);
|
||||
|
||||
done:
|
||||
if (ro == &iproute)
|
||||
rtfree(ro->ro_rt);
|
||||
if (fake)
|
||||
m_tag_delete_chain(&mfake);
|
||||
rtfree(rt);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -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 $ */
|
||||
|
||||
/*
|
||||
@ -260,7 +260,7 @@ void ip_savecontrol(struct inpcb *, struct mbuf **, struct ip *,
|
||||
struct mbuf *);
|
||||
int ip_input_if(struct mbuf **, int *, int, int, struct ifnet *);
|
||||
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 *);
|
||||
void rip_init(void);
|
||||
int rip_input(struct mbuf **, int *, int, int);
|
||||
|
@ -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 $ */
|
||||
|
||||
/*
|
||||
@ -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
|
||||
* 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_UNSPEC)
|
||||
return (EAFNOSUPPORT);
|
||||
@ -603,19 +603,18 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
|
||||
* zone identifier.
|
||||
*/
|
||||
dst6 = ifra->ifra_dstaddr;
|
||||
if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) != 0 &&
|
||||
if ((ifp->if_flags & IFF_POINTOPOINT) &&
|
||||
(dst6.sin6_family == AF_INET6)) {
|
||||
error = in6_check_embed_scope(&dst6, ifp->if_index);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
/*
|
||||
* The destination address can be specified only for a p2p or a
|
||||
* loopback interface. If specified, the corresponding prefix length
|
||||
* must be 128.
|
||||
* The destination address can be specified only for a p2p interface.
|
||||
* If specified, the corresponding prefix length must be 128.
|
||||
*/
|
||||
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);
|
||||
if (plen != 128)
|
||||
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_len = sizeof(ia6->ia_addr);
|
||||
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
|
||||
* 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
|
||||
* 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 &&
|
||||
!IN6_ARE_ADDR_EQUAL(&dst6.sin6_addr, &ia6->ia_dstaddr.sin6_addr)) {
|
||||
|
@ -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 $ */
|
||||
|
||||
/*
|
||||
@ -158,7 +158,7 @@ const struct protosw inet6sw[] = {
|
||||
.pr_type = SOCK_RAW,
|
||||
.pr_domain = &inet6domain,
|
||||
.pr_protocol = IPPROTO_RAW,
|
||||
.pr_flags = PR_ATOMIC|PR_ADDR,
|
||||
.pr_flags = PR_ATOMIC|PR_ADDR|PR_MPINPUT,
|
||||
.pr_input = rip6_input,
|
||||
.pr_ctlinput = rip6_ctlinput,
|
||||
.pr_ctloutput = rip6_ctloutput,
|
||||
@ -322,7 +322,7 @@ const struct protosw inet6sw[] = {
|
||||
/* raw wildcard */
|
||||
.pr_type = SOCK_RAW,
|
||||
.pr_domain = &inet6domain,
|
||||
.pr_flags = PR_ATOMIC|PR_ADDR,
|
||||
.pr_flags = PR_ATOMIC|PR_ADDR|PR_MPINPUT,
|
||||
.pr_input = rip6_input,
|
||||
.pr_ctloutput = rip6_ctloutput,
|
||||
.pr_usrreqs = &rip6_usrreqs,
|
||||
|
@ -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 $ */
|
||||
|
||||
/*
|
||||
@ -82,11 +82,12 @@
|
||||
*/
|
||||
|
||||
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 route iproute;
|
||||
struct rtentry *rt;
|
||||
struct sockaddr *dst;
|
||||
struct route ro;
|
||||
struct ifnet *ifp = NULL;
|
||||
int error = 0, type = 0, code = 0, destmtu = 0;
|
||||
struct mbuf *mcopy;
|
||||
@ -165,25 +166,22 @@ reroute:
|
||||
}
|
||||
#endif /* IPSEC */
|
||||
|
||||
ro.ro_rt = NULL;
|
||||
route6_cache(&ro, &ip6->ip6_dst, &ip6->ip6_src,
|
||||
m->m_pkthdr.ph_rtableid);
|
||||
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;
|
||||
}
|
||||
if (ro == NULL) {
|
||||
ro = &iproute;
|
||||
ro->ro_rt = NULL;
|
||||
}
|
||||
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
|
||||
@ -225,8 +223,8 @@ reroute:
|
||||
*/
|
||||
if (tdb != NULL) {
|
||||
/* Callee frees mbuf */
|
||||
error = ip6_output_ipsec_send(tdb, m, &ro, 0, 1);
|
||||
rt = ro.ro_rt;
|
||||
error = ip6_output_ipsec_send(tdb, m, ro, 0, 1);
|
||||
rt = ro->ro_rt;
|
||||
if (error)
|
||||
goto senderr;
|
||||
goto freecopy;
|
||||
@ -254,7 +252,7 @@ reroute:
|
||||
ip6_sendredirects &&
|
||||
(rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0) {
|
||||
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
|
||||
* one, the link attached to the interface is
|
||||
@ -308,8 +306,9 @@ reroute:
|
||||
/* tag as generated to skip over pf_test on rerun */
|
||||
m->m_pkthdr.pf.flags |= PF_TAG_GENERATED;
|
||||
srcrt = 1;
|
||||
rtfree(rt);
|
||||
rt = NULL;
|
||||
if (ro == &iproute)
|
||||
rtfree(ro->ro_rt);
|
||||
ro = NULL;
|
||||
if_put(ifp);
|
||||
ifp = NULL;
|
||||
goto reroute;
|
||||
@ -388,7 +387,8 @@ senderr:
|
||||
freecopy:
|
||||
m_freem(mcopy);
|
||||
done:
|
||||
rtfree(rt);
|
||||
if (ro == &iproute)
|
||||
rtfree(ro->ro_rt);
|
||||
if_put(ifp);
|
||||
#ifdef IPSEC
|
||||
tdb_unref(tdb);
|
||||
|
@ -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 $ */
|
||||
|
||||
/*
|
||||
@ -356,10 +356,10 @@ bad:
|
||||
int
|
||||
ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
|
||||
{
|
||||
struct route ro;
|
||||
struct mbuf *m;
|
||||
struct ip6_hdr *ip6;
|
||||
struct sockaddr_in6 sin6;
|
||||
struct rtentry *rt = NULL;
|
||||
struct rtentry *rt;
|
||||
int ours = 0;
|
||||
u_int16_t src_scope, dst_scope;
|
||||
#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);
|
||||
|
||||
ro.ro_rt = NULL;
|
||||
ip6stat_inc(ip6s_total);
|
||||
|
||||
m = *mp = ipv6_check(ifp, *mp);
|
||||
if (m == NULL)
|
||||
goto bad;
|
||||
@ -516,18 +516,14 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
|
||||
/*
|
||||
* Unicast check
|
||||
*/
|
||||
memset(&sin6, 0, sizeof(struct sockaddr_in6));
|
||||
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],
|
||||
rt = route6_mpath(&ro, &ip6->ip6_dst, &ip6->ip6_src,
|
||||
m->m_pkthdr.ph_rtableid);
|
||||
|
||||
/*
|
||||
* Accept the packet if the route to the destination is marked
|
||||
* 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);
|
||||
|
||||
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 */
|
||||
|
||||
ip6_forward(m, rt, pfrdr);
|
||||
ip6_forward(m, &ro, pfrdr);
|
||||
*mp = NULL;
|
||||
return IPPROTO_DONE;
|
||||
bad:
|
||||
nxt = IPPROTO_DONE;
|
||||
m_freemp(mp);
|
||||
out:
|
||||
rtfree(rt);
|
||||
rtfree(ro.ro_rt);
|
||||
return nxt;
|
||||
}
|
||||
|
||||
|
@ -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 $ */
|
||||
|
||||
/*
|
||||
@ -391,7 +391,7 @@ reroute:
|
||||
/* initialize cached route */
|
||||
if (ro == NULL) {
|
||||
ro = &iproute;
|
||||
bzero((caddr_t)ro, sizeof(*ro));
|
||||
ro->ro_rt = NULL;
|
||||
}
|
||||
ro_pmtu = ro;
|
||||
if (opt && opt->ip6po_rthdr)
|
||||
|
@ -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 $ */
|
||||
|
||||
/*
|
||||
@ -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 **);
|
||||
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 *);
|
||||
int ip6_output(struct mbuf *, struct ip6_pktopts *, struct route *, int,
|
||||
|
@ -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 $ */
|
||||
|
||||
/*
|
||||
@ -155,9 +155,9 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
|
||||
} else
|
||||
rip6stat_inc(rip6s_ipackets);
|
||||
|
||||
bzero(&rip6src, sizeof(rip6src));
|
||||
rip6src.sin6_len = sizeof(struct sockaddr_in6);
|
||||
memset(&rip6src, 0, sizeof(rip6src));
|
||||
rip6src.sin6_family = AF_INET6;
|
||||
rip6src.sin6_len = sizeof(rip6src);
|
||||
/* KAME hack: recover scopeid */
|
||||
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) {
|
||||
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;
|
||||
if (rtable_l2(inp->inp_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);
|
||||
if (n != NULL) {
|
||||
struct socket *so = inp->inp_socket;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (inp->inp_flags & IN6P_CONTROLOPTS)
|
||||
ip6_savecontrol(inp, n, &opts);
|
||||
@ -272,12 +278,14 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
|
||||
m_adj(n, *offp);
|
||||
|
||||
mtx_enter(&so->so_rcv.sb_mtx);
|
||||
ret = sbappendaddr(so, &so->so_rcv,
|
||||
sin6tosa(&rip6src), n, opts);
|
||||
if (!ISSET(inp->inp_socket->so_rcv.sb_state,
|
||||
SS_CANTRCVMORE)) {
|
||||
ret = sbappendaddr(so, &so->so_rcv,
|
||||
sin6tosa(&rip6src), n, opts);
|
||||
}
|
||||
mtx_leave(&so->so_rcv.sb_mtx);
|
||||
|
||||
if (ret == 0) {
|
||||
/* should notify about lost packet */
|
||||
m_freem(n);
|
||||
m_freem(opts);
|
||||
rip6stat_inc(rip6s_fullsock);
|
||||
@ -727,7 +735,7 @@ rip6_disconnect(struct socket *so)
|
||||
if ((so->so_state & SS_ISCONNECTED) == 0)
|
||||
return (ENOTCONN);
|
||||
|
||||
so->so_state &= ~SS_ISCONNECTED; /* XXX */
|
||||
soisdisconnected(so);
|
||||
mtx_enter(&rawin6pcbtable.inpt_mtx);
|
||||
inp->inp_faddr6 = in6addr_any;
|
||||
mtx_leave(&rawin6pcbtable.inpt_mtx);
|
||||
|
@ -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 $ */
|
||||
|
||||
/*
|
||||
@ -237,6 +237,9 @@ mfs_reclaim(void *v)
|
||||
{
|
||||
struct vop_reclaim_args *ap = v;
|
||||
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));
|
||||
vp->v_data = NULL;
|
||||
|
@ -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 $ */
|
||||
|
||||
/*
|
||||
@ -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);
|
||||
if (chunk == NULL) {
|
||||
/* amap_wipeout() releases the lock. */
|
||||
amap->am_ref = 0;
|
||||
amap_wipeout(amap);
|
||||
amap_unlock(srcamap);
|
||||
/* Destroy the new amap. */
|
||||
amap->am_ref--;
|
||||
amap_free(amap);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -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 $ */
|
||||
|
||||
/*
|
||||
@ -1088,6 +1088,7 @@ swap_off(struct proc *p, struct swapdev *sdp)
|
||||
*/
|
||||
if (sdp->swd_vp->v_type == VREG) {
|
||||
crfree(sdp->swd_cred);
|
||||
bufq_destroy(&sdp->swd_bufq);
|
||||
}
|
||||
vrele(sdp->swd_vp);
|
||||
if (sdp->swd_vp != rootvp) {
|
||||
|
@ -378,85 +378,6 @@ bin_file(int f)
|
||||
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.
|
||||
*/
|
||||
|
@ -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)
|
||||
* 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) {
|
||||
BIO_puts(err, "Error initializing keygen context\n");
|
||||
ERR_print_errors(err);
|
||||
EVP_PKEY_CTX_free(gctx);
|
||||
return NULL;
|
||||
}
|
||||
if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1)) {
|
||||
|
@ -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>
|
||||
@ -43,12 +43,14 @@
|
||||
int server_file_access(struct httpd *, struct client *,
|
||||
char *, size_t);
|
||||
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 *,
|
||||
char *, struct timespec *, char *);
|
||||
int server_file_index(struct httpd *, struct client *);
|
||||
struct media_type *, int, const struct stat *,
|
||||
char *);
|
||||
int server_file_index(struct httpd *, struct client *, int,
|
||||
struct stat *);
|
||||
int server_file_modified_since(struct http_descriptor *,
|
||||
struct timespec *);
|
||||
const struct timespec *);
|
||||
int server_file_method(struct client *);
|
||||
int parse_range_spec(char *, size_t, struct range *);
|
||||
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 stat st;
|
||||
struct kv *r, key;
|
||||
struct media_type *media;
|
||||
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) {
|
||||
goto fail;
|
||||
} else if (S_ISDIR(st.st_mode)) {
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
/* Deny access if directory indexing is disabled */
|
||||
if (srv_conf->flags & SRVFLAG_NO_INDEX) {
|
||||
errno = EACCES;
|
||||
goto fail;
|
||||
close(fd);
|
||||
return (403);
|
||||
}
|
||||
|
||||
if (desc->http_path_alias != NULL) {
|
||||
/* Recursion - the index "file" is a directory? */
|
||||
errno = EINVAL;
|
||||
goto fail;
|
||||
close(fd);
|
||||
return (500);
|
||||
}
|
||||
|
||||
/* Redirect to path with trailing "/" */
|
||||
if (path[strlen(path) - 1] != '/') {
|
||||
close(fd);
|
||||
if ((encodedpath = url_encode(desc->http_path)) == NULL)
|
||||
return (500);
|
||||
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 */
|
||||
if (asprintf(&newpath, "%s%s", desc->http_path,
|
||||
srv_conf->index) == -1)
|
||||
srv_conf->index) == -1) {
|
||||
close(fd);
|
||||
return (500);
|
||||
}
|
||||
desc->http_path_alias = newpath;
|
||||
if (server_getlocation(clt, newpath) != srv_conf) {
|
||||
/* The location has changed */
|
||||
close(fd);
|
||||
return (server_file(env, clt));
|
||||
}
|
||||
|
||||
/* Otherwise append the default index file to the path */
|
||||
if (strlcat(path, srv_conf->index, len) >= len) {
|
||||
errno = EACCES;
|
||||
goto fail;
|
||||
close(fd);
|
||||
return (403);
|
||||
}
|
||||
|
||||
ret = server_file_access(env, clt, path, len);
|
||||
@ -124,39 +143,72 @@ server_file_access(struct httpd *env, struct client *clt,
|
||||
* stat.
|
||||
*/
|
||||
if ((srv_conf->flags & SRVFLAG_AUTO_INDEX) == 0) {
|
||||
errno = EACCES;
|
||||
goto fail;
|
||||
close(fd);
|
||||
return (403);
|
||||
}
|
||||
|
||||
return (server_file_index(env, clt));
|
||||
return (server_file_index(env, clt, fd, &st));
|
||||
}
|
||||
close(fd);
|
||||
return (ret);
|
||||
} else if (!S_ISREG(st.st_mode)) {
|
||||
/* Don't follow symlinks and ignore special files */
|
||||
errno = EACCES;
|
||||
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:
|
||||
close(fd);
|
||||
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
|
||||
@ -216,73 +268,30 @@ server_file_method(struct client *clt)
|
||||
}
|
||||
|
||||
int
|
||||
server_file_request(struct httpd *env, struct client *clt, char *path,
|
||||
struct timespec *mtim)
|
||||
server_file_request(struct httpd *env, struct client *clt, struct media_type
|
||||
*media, int fd, const struct stat *st)
|
||||
{
|
||||
struct server_config *srv_conf = clt->clt_srv_conf;
|
||||
struct media_type *media;
|
||||
const char *errstr = NULL;
|
||||
int fd = -1, ret, code = 500;
|
||||
struct stat st;
|
||||
int ret, code = 500;
|
||||
size_t bufsiz;
|
||||
char gzpath[PATH_MAX];
|
||||
|
||||
if ((ret = server_file_method(clt)) != 0) {
|
||||
code = ret;
|
||||
goto abort;
|
||||
}
|
||||
|
||||
media = media_find_config(env, srv_conf, path);
|
||||
if ((ret = server_file_modified_since(clt->clt_descreq, mtim)) != -1) {
|
||||
if ((ret = server_file_modified_since(clt->clt_descreq, &st->st_mtim))
|
||||
!= -1) {
|
||||
/* send the header without a body */
|
||||
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 done;
|
||||
}
|
||||
|
||||
/* 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 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));
|
||||
ret = server_response_http(clt, 200, media, st->st_size,
|
||||
MINIMUM(time(NULL), st->st_mtim.tv_sec));
|
||||
switch (ret) {
|
||||
case -1:
|
||||
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 */
|
||||
bufsiz = MAXIMUM(st.st_blksize, 64 * 1024);
|
||||
bufsiz = MAXIMUM(st->st_blksize, 64 * 1024);
|
||||
bufferevent_setwatermark(clt->clt_srvbev, EV_READ, 0,
|
||||
bufsiz);
|
||||
|
||||
@ -333,47 +342,34 @@ server_file_request(struct httpd *env, struct client *clt, char *path,
|
||||
}
|
||||
|
||||
int
|
||||
server_partial_file_request(struct httpd *env, struct client *clt, char *path,
|
||||
struct timespec *mtim, char *range_str)
|
||||
server_partial_file_request(struct httpd *env, struct client *clt,
|
||||
struct media_type *media, int fd, const struct stat *st, char *range_str)
|
||||
{
|
||||
struct server_config *srv_conf = clt->clt_srv_conf;
|
||||
struct http_descriptor *resp = clt->clt_descresp;
|
||||
struct http_descriptor *desc = clt->clt_descreq;
|
||||
struct media_type *media, multipart_media;
|
||||
struct media_type multipart_media;
|
||||
struct range_data *r = &clt->clt_ranges;
|
||||
struct range *range;
|
||||
size_t content_length = 0, bufsiz;
|
||||
struct stat st;
|
||||
int code = 500, fd = -1, i, nranges, ret;
|
||||
int code = 500, i, nranges, ret;
|
||||
char content_range[64];
|
||||
const char *errstr = NULL;
|
||||
|
||||
/* Ignore range request for methods other than GET */
|
||||
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) {
|
||||
if ((nranges = parse_ranges(clt, range_str, st->st_size)) < 1) {
|
||||
code = 416;
|
||||
(void)snprintf(content_range, sizeof(content_range),
|
||||
"bytes */%lld", st.st_size);
|
||||
"bytes */%lld", st->st_size);
|
||||
errstr = content_range;
|
||||
goto abort;
|
||||
}
|
||||
|
||||
media = media_find_config(env, srv_conf, path);
|
||||
r->range_media = media;
|
||||
|
||||
if (nranges == 1) {
|
||||
range = &r->range[0];
|
||||
(void)snprintf(content_range, sizeof(content_range),
|
||||
"bytes %lld-%lld/%lld", range->start, range->end,
|
||||
st.st_size);
|
||||
st->st_size);
|
||||
if (kv_add(&resp->http_headers, "Content-Range",
|
||||
content_range) == NULL)
|
||||
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",
|
||||
clt->clt_boundary,
|
||||
media->media_type, media->media_subtype,
|
||||
range->start, range->end, st.st_size)) < 0)
|
||||
range->start, range->end, st->st_size)) < 0)
|
||||
goto abort;
|
||||
|
||||
/* 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;
|
||||
|
||||
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) {
|
||||
case -1:
|
||||
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 */
|
||||
bufsiz = MAXIMUM(st.st_blksize, 64 * 1024);
|
||||
bufsiz = MAXIMUM(st->st_blksize, 64 * 1024);
|
||||
bufferevent_setwatermark(clt->clt_srvbev, EV_READ, 0,
|
||||
bufsiz);
|
||||
|
||||
@ -482,21 +478,21 @@ select_visible(const struct dirent *dp)
|
||||
}
|
||||
|
||||
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 tmstr[21];
|
||||
struct http_descriptor *desc = clt->clt_descreq;
|
||||
struct server_config *srv_conf = clt->clt_srv_conf;
|
||||
struct dirent **namelist, *dp;
|
||||
int namesize, i, ret, fd = -1, skip;
|
||||
int namesize, i, ret, skip;
|
||||
int code = 500;
|
||||
struct evbuffer *evb = NULL;
|
||||
struct media_type *media;
|
||||
const char *stripped;
|
||||
char *escapeduri, *escapedhtml, *escapedpath;
|
||||
struct tm tm;
|
||||
struct stat st;
|
||||
time_t t, dir_mtime;
|
||||
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))
|
||||
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 */
|
||||
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)
|
||||
goto abort;
|
||||
@ -548,7 +538,7 @@ server_file_index(struct httpd *env, struct client *clt)
|
||||
|
||||
free(escapedpath);
|
||||
|
||||
if ((namesize = scandir(path, &namelist, select_visible,
|
||||
if ((namesize = scandirat(fd, ".", &namelist, select_visible,
|
||||
alphasort)) == -1)
|
||||
goto abort;
|
||||
|
||||
@ -722,7 +712,8 @@ server_file_error(struct bufferevent *bev, short error, void *arg)
|
||||
}
|
||||
|
||||
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 tm tm;
|
||||
|
Loading…
Reference in New Issue
Block a user