diff --git a/bin/pax/ar_subs.c b/bin/pax/ar_subs.c
index 172d6847b..a14c2032c 100644
--- a/bin/pax/ar_subs.c
+++ b/bin/pax/ar_subs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ar_subs.c,v 1.52 2024/05/18 05:21:38 guenther Exp $ */
+/* $OpenBSD: ar_subs.c,v 1.53 2024/07/14 14:32:02 jca Exp $ */
/* $NetBSD: ar_subs.c,v 1.5 1995/03/21 09:07:06 cgd Exp $ */
/*-
@@ -172,7 +172,7 @@ cmp_file_times(int mtime_flag, int ctime_flag, ARCHD *arcn, const char *path)
else if (timespeccmp(&arcn->sb.st_mtim, &sb.st_mtim, <=))
return 1;
- /*
+ /*
* If we got here then the target arcn > sb for mtime *and* that's
* the deciding factor. Check whether they're equal after rounding
* down the arcn mtime to the precision of the target path.
diff --git a/bin/pax/file_subs.c b/bin/pax/file_subs.c
index e71f5d4a3..c679edf05 100644
--- a/bin/pax/file_subs.c
+++ b/bin/pax/file_subs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: file_subs.c,v 1.56 2023/11/26 16:04:17 espie Exp $ */
+/* $OpenBSD: file_subs.c,v 1.57 2024/07/14 14:32:02 jca Exp $ */
/* $NetBSD: file_subs.c,v 1.4 1995/03/21 09:07:18 cgd Exp $ */
/*-
diff --git a/distrib/sets/lists/base/mi b/distrib/sets/lists/base/mi
index 66cf604c0..242dacbad 100644
--- a/distrib/sets/lists/base/mi
+++ b/distrib/sets/lists/base/mi
@@ -727,7 +727,7 @@
./usr/lib/crtendS.o
./usr/lib/gcrt0.o
./usr/lib/libagentx.so.1.1
-./usr/lib/libc.so.100.1
+./usr/lib/libc.so.100.2
./usr/lib/libcbor.so.2.0
./usr/lib/libcrypto.so.54.0
./usr/lib/libcurses.so.15.0
@@ -2975,7 +2975,7 @@
./usr/share/relink/usr/bin/ssh-agent
./usr/share/relink/usr/bin/ssh-agent/ssh-agent.tar
./usr/share/relink/usr/lib
-./usr/share/relink/usr/lib/libc.so.100.1.a
+./usr/share/relink/usr/lib/libc.so.100.2.a
./usr/share/relink/usr/lib/libcrypto.so.54.0.a
./usr/share/relink/usr/libexec
./usr/share/relink/usr/libexec/ld.so.a
diff --git a/distrib/sets/lists/comp/md.amd64 b/distrib/sets/lists/comp/md.amd64
index 7ce27d972..55475db23 100644
--- a/distrib/sets/lists/comp/md.amd64
+++ b/distrib/sets/lists/comp/md.amd64
@@ -22,6 +22,7 @@
./usr/include/amd64/disklabel.h
./usr/include/amd64/efifbvar.h
./usr/include/amd64/efivar.h
+./usr/include/amd64/elf.h
./usr/include/amd64/endian.h
./usr/include/amd64/exec.h
./usr/include/amd64/fenv.h
diff --git a/distrib/sets/lists/comp/md.arm64 b/distrib/sets/lists/comp/md.arm64
index 06a454922..34e82a704 100644
--- a/distrib/sets/lists/comp/md.arm64
+++ b/distrib/sets/lists/comp/md.arm64
@@ -17,6 +17,7 @@
./usr/include/arm64/db_machdep.h
./usr/include/arm64/disklabel.h
./usr/include/arm64/efivar.h
+./usr/include/arm64/elf.h
./usr/include/arm64/endian.h
./usr/include/arm64/exec.h
./usr/include/arm64/fdt.h
diff --git a/distrib/sets/lists/comp/md.armv7 b/distrib/sets/lists/comp/md.armv7
index fe9f7b860..fea44cf9a 100644
--- a/distrib/sets/lists/comp/md.armv7
+++ b/distrib/sets/lists/comp/md.armv7
@@ -17,6 +17,7 @@
./usr/include/arm/cpufunc.h
./usr/include/arm/db_machdep.h
./usr/include/arm/disklabel.h
+./usr/include/arm/elf.h
./usr/include/arm/endian.h
./usr/include/arm/exec.h
./usr/include/arm/fdt.h
diff --git a/distrib/sets/lists/comp/md.i386 b/distrib/sets/lists/comp/md.i386
index 30188b382..26289ead5 100644
--- a/distrib/sets/lists/comp/md.i386
+++ b/distrib/sets/lists/comp/md.i386
@@ -23,6 +23,7 @@
./usr/include/i386/cpuvar.h
./usr/include/i386/db_machdep.h
./usr/include/i386/disklabel.h
+./usr/include/i386/elf.h
./usr/include/i386/endian.h
./usr/include/i386/exec.h
./usr/include/i386/fenv.h
diff --git a/distrib/sets/lists/comp/mi b/distrib/sets/lists/comp/mi
index 9d5b37b4a..b7f239f6d 100644
--- a/distrib/sets/lists/comp/mi
+++ b/distrib/sets/lists/comp/mi
@@ -1160,8 +1160,6 @@
./usr/include/openssl/sm4.h
./usr/include/openssl/srtp.h
./usr/include/openssl/ssl.h
-./usr/include/openssl/ssl2.h
-./usr/include/openssl/ssl23.h
./usr/include/openssl/ssl3.h
./usr/include/openssl/stack.h
./usr/include/openssl/tls1.h
@@ -1291,6 +1289,7 @@
./usr/include/sys/ataio.h
./usr/include/sys/atomic.h
./usr/include/sys/audioio.h
+./usr/include/sys/auxv.h
./usr/include/sys/blist.h
./usr/include/sys/buf.h
./usr/include/sys/cdefs.h
@@ -2451,6 +2450,7 @@
./usr/share/man/man3/eddsa_pk_new.3
./usr/share/man/man3/editline.3
./usr/share/man/man3/elf.3
+./usr/share/man/man3/elf_aux_info.3
./usr/share/man/man3/elf_begin.3
./usr/share/man/man3/elf_cntl.3
./usr/share/man/man3/elf_end.3
diff --git a/etc/mtree/BSD.x11.dist b/etc/mtree/BSD.x11.dist
index adc148857..032e884b0 100644
--- a/etc/mtree/BSD.x11.dist
+++ b/etc/mtree/BSD.x11.dist
@@ -1,4 +1,4 @@
-# $OpenBSD: BSD.x11.dist,v 1.56 2021/10/27 21:31:31 matthieu Exp $
+# $OpenBSD: BSD.x11.dist,v 1.57 2024/07/14 09:39:15 matthieu Exp $
/set type=dir uname=root gname=wheel mode=0755
.
@@ -89,6 +89,8 @@
..
pixman-1
..
+ va
+ ..
vulkan
..
xcb
diff --git a/include/wchar.h b/include/wchar.h
index 309f812d6..462ed5e4b 100644
--- a/include/wchar.h
+++ b/include/wchar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wchar.h,v 1.31 2017/09/05 03:16:13 schwarze Exp $ */
+/* $OpenBSD: wchar.h,v 1.32 2024/07/14 10:04:17 jca Exp $ */
/* $NetBSD: wchar.h,v 1.16 2003/03/07 07:11:35 tshiozak Exp $ */
/*-
@@ -166,6 +166,7 @@ int wcscoll_l(const wchar_t *, const wchar_t *, locale_t);
wchar_t *wcsdup(const wchar_t *);
int wcscasecmp(const wchar_t *, const wchar_t *);
int wcscasecmp_l(const wchar_t *, const wchar_t *, locale_t);
+size_t wcsnlen(const wchar_t *, size_t);
int wcsncasecmp(const wchar_t *, const wchar_t *, size_t);
int wcsncasecmp_l(const wchar_t *, const wchar_t *, size_t, locale_t);
size_t wcsxfrm_l(wchar_t *, const wchar_t *, size_t, locale_t);
diff --git a/lib/libc/Symbols.list b/lib/libc/Symbols.list
index eb4d78cc9..6d11dfff1 100644
--- a/lib/libc/Symbols.list
+++ b/lib/libc/Symbols.list
@@ -608,6 +608,7 @@ daemon
devname
dirfd
dirname
+elf_aux_info
endfsent
endgrent
endnetgrent
@@ -1665,6 +1666,7 @@ wcsncasecmp_l
wcsncat
wcsncmp
wcsncpy
+wcsnlen
wcspbrk
wcsrchr
wcsspn
diff --git a/lib/libc/dlfcn/init.c b/lib/libc/dlfcn/init.c
index 9fc63c97f..c7b8fd2bc 100644
--- a/lib/libc/dlfcn/init.c
+++ b/lib/libc/dlfcn/init.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: init.c,v 1.22 2024/01/21 17:18:13 kettenis Exp $ */
+/* $OpenBSD: init.c,v 1.23 2024/07/14 09:48:48 jca Exp $ */
/*
* Copyright (c) 2014,2015 Philip Guenther
*
@@ -49,6 +49,8 @@ char ***_csu_finish(char **_argv, char **_envp, void (*_cleanup)(void));
/* provide definitions for these */
int _pagesize = 0;
struct timekeep *_timekeep;
+unsigned long _hwcap, _hwcap2;
+int _hwcap_avail, _hwcap2_avail;
/*
* In dynamically linked binaries environ and __progname are overridden by
@@ -96,6 +98,14 @@ _libc_preinit(int argc, char **argv, char **envp, dl_cb_cb *cb)
;
for (aux = (void *)envp; aux->au_id != AUX_null; aux++) {
switch (aux->au_id) {
+ case AUX_hwcap:
+ _hwcap = aux->au_v;
+ _hwcap_avail = 1;
+ break;
+ case AUX_hwcap2:
+ _hwcap2 = aux->au_v;
+ _hwcap2_avail = 1;
+ break;
case AUX_pagesz:
_pagesize = aux->au_v;
break;
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
index cf36ead40..f87cc7a89 100644
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.inc,v 1.82 2019/09/02 21:18:40 deraadt Exp $
+# $OpenBSD: Makefile.inc,v 1.83 2024/07/14 09:48:48 jca Exp $
# gen sources
.PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/gen ${LIBCSRCDIR}/gen
@@ -6,8 +6,8 @@
SRCS+= alarm.c assert.c auth_subr.c authenticate.c \
basename.c clock.c clock_getcpuclockid.c \
closedir.c confstr.c ctermid.c ctype_.c \
- daemon.c devname.c dirfd.c dirname.c disklabel.c err.c \
- errc.c errx.c errlist.c errno.c exec.c \
+ daemon.c devname.c dirfd.c dirname.c disklabel.c elf_aux_info.c \
+ err.c errc.c errx.c errlist.c errno.c exec.c \
fdatasync.c fnmatch.c fpclassify.c frexp.c \
fstab.c ftok.c fts.c ftw.c getbsize.c getcap.c getcwd.c \
getdomainname.c getgrent.c getgrouplist.c gethostname.c \
@@ -36,7 +36,7 @@ SRCS+= alarm.c assert.c auth_subr.c authenticate.c \
MAN+= __tfork_thread.3 alarm.3 auth_subr.3 authenticate.3 basename.3 clock.3 \
clock_getcpuclockid.3 confstr.3 \
- ctermid.3 daemon.3 devname.3 opendir.3 dirname.3 err.3 \
+ ctermid.3 daemon.3 devname.3 opendir.3 dirname.3 elf_aux_info.3 err.3 \
execv.3 fabs.3 fnmatch.3 fpclassify.3 fpgetmask.3 frexp.3 ftok.3 fts_open.3 \
ftw.3 getbsize.3 cgetent.3 getcwd.3 getdomainname.3 getdiskbyname.3 \
getfsent.3 getgrent.3 getgrouplist.3 gethostname.3 getloadavg.3 \
diff --git a/lib/libc/gen/elf_aux_info.3 b/lib/libc/gen/elf_aux_info.3
new file mode 100644
index 000000000..1bd1a0923
--- /dev/null
+++ b/lib/libc/gen/elf_aux_info.3
@@ -0,0 +1,74 @@
+.\" $OpenBSD: elf_aux_info.3,v 1.1 2024/07/14 09:48:48 jca Exp $
+.\"
+.\" Origin: FreeBSD auxv.3
+.\"
+.\" Copyright (c) 2019 Ian Lepore
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\"
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (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: July 14 2024 $
+.Dt ELF_AUX_INFO 3
+.Os
+.Sh NAME
+.Nm elf_aux_info
+.Nd extract data from the elf auxiliary vector of the current process
+.Sh SYNOPSIS
+.In sys/auxv.h
+.Ft int
+.Fn elf_aux_info "int aux" "void *buf" "int buflen"
+.Sh DESCRIPTION
+The
+.Fn elf_aux_info
+function retrieves the auxiliary info vector requested in
+.Va aux .
+The information is stored into the provided buffer if it will fit.
+The following values can be requested (corresponding buffer sizes are
+specified in parenthesis):
+.Bl -tag -width AT_HWCAP2
+.It AT_HWCAP
+CPU / hardware feature flags
+.Dv (sizeof(unsigned long)) .
+.It AT_HWCAP2
+CPU / hardware feature flags
+.Dv (sizeof(unsigned long)) .
+.It AT_PAGESZ
+Page size in bytes
+.Dv (sizeof(int)) .
+.El
+.Sh RETURN VALUES
+Returns zero on success, or an error number on failure.
+.Sh ERRORS
+.Bl -tag -width Er
+.It Bq Er EINVAL
+An unknown item was requested.
+.It Bq Er EINVAL
+The provided buffer was not the right size for the requested item.
+.It Bq Er ENOENT
+The requested item is not available.
+.El
+.Sh HISTORY
+The
+.Fn elf_aux_info
+function appeared in
+.Fx 12.0
+and was first available in
+.Ox 7.6 .
diff --git a/lib/libc/gen/elf_aux_info.c b/lib/libc/gen/elf_aux_info.c
new file mode 100644
index 000000000..a4b7667ba
--- /dev/null
+++ b/lib/libc/gen/elf_aux_info.c
@@ -0,0 +1,70 @@
+/* $OpenBSD: elf_aux_info.c,v 1.1 2024/07/14 09:48:48 jca Exp $ */
+
+/*
+ * Copyright (c) 2024 Jeremie Courreges-Anglas
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include
+#include
+
+#include
+
+extern int _pagesize;
+extern unsigned long _hwcap, _hwcap2;
+extern int _hwcap_avail, _hwcap2_avail;
+
+int
+elf_aux_info(int request, void *buf, int buflen)
+{
+ int ret = 0;
+
+ if (buflen < 0)
+ return EINVAL;
+
+ switch (request) {
+ case AT_HWCAP:
+ if (buflen != sizeof(unsigned long))
+ ret = EINVAL;
+ else if (!_hwcap_avail)
+ ret = ENOENT;
+ else
+ *(unsigned long *)buf = _hwcap;
+ break;
+ case AT_HWCAP2:
+ if (buflen != sizeof(unsigned long))
+ ret = EINVAL;
+ else if (!_hwcap2_avail)
+ ret = ENOENT;
+ else
+ *(unsigned long *)buf = _hwcap2;
+ break;
+ case AT_PAGESZ:
+ if (buflen != sizeof(int))
+ ret = EINVAL;
+ else if (!_pagesize)
+ ret = ENOENT;
+ else
+ *(int *)buf = _pagesize;
+ break;
+ default:
+ if (request < 0 || request >= AT_COUNT)
+ ret = EINVAL;
+ else
+ ret = ENOENT;
+ break;
+ }
+
+ return ret;
+}
diff --git a/lib/libc/gen/signal.3 b/lib/libc/gen/signal.3
index a3c4f065c..a36212abd 100644
--- a/lib/libc/gen/signal.3
+++ b/lib/libc/gen/signal.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: signal.3,v 1.58 2024/07/12 11:01:40 deraadt Exp $
+.\" $OpenBSD: signal.3,v 1.59 2024/07/14 03:47:44 jsg Exp $
.\"
.\" Copyright (c) 1980, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -27,7 +27,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd $Mdocdate: July 12 2024 $
+.Dd $Mdocdate: July 14 2024 $
.Dt SIGNAL 3
.Os
.Sh NAME
@@ -248,7 +248,7 @@ which is inspected by an event loop.
Other variables accessed inside the handler must be either const, or
local to the handler.
More complicated global variables (such as strings, structs, or lists)
-will require external methods to gaurantee consistancy, such as
+will require external methods to guarantee consistency, such as
signal-blocking with
.Xr sigprocmask 2 .
.Pp
diff --git a/lib/libc/hidden/sys/auxv.h b/lib/libc/hidden/sys/auxv.h
new file mode 100644
index 000000000..cd566b7b2
--- /dev/null
+++ b/lib/libc/hidden/sys/auxv.h
@@ -0,0 +1,26 @@
+/* $OpenBSD: auxv.h,v 1.1 2024/07/14 09:48:48 jca Exp $ */
+
+/*
+ * Copyright (c) 2024 Jeremie Courreges-Anglas
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _LIBC_SYS_AUXV_H_
+#define _LIBC_SYS_AUXV_H_
+
+#include_next
+
+PROTO_DEPRECATED(elf_aux_info);
+
+#endif /* !_LIBC_SYS_AUXV_H_ */
diff --git a/lib/libc/hidden/wchar.h b/lib/libc/hidden/wchar.h
index 7fb255110..c77dbd695 100644
--- a/lib/libc/hidden/wchar.h
+++ b/lib/libc/hidden/wchar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wchar.h,v 1.4 2017/09/05 03:16:13 schwarze Exp $ */
+/* $OpenBSD: wchar.h,v 1.5 2024/07/14 09:51:18 jca Exp $ */
/*
* Copyright (c) 2015 Philip Guenther
*
@@ -65,6 +65,7 @@ PROTO_NORMAL(wcsncasecmp);
PROTO_NORMAL(wcsncat);
PROTO_NORMAL(wcsncmp);
PROTO_NORMAL(wcsncpy);
+PROTO_DEPRECATED(wcsnlen);
PROTO_NORMAL(wcsnrtombs);
PROTO_NORMAL(wcspbrk);
PROTO_NORMAL(wcsrchr);
diff --git a/lib/libc/shlib_version b/lib/libc/shlib_version
index 670da2562..066d6db01 100644
--- a/lib/libc/shlib_version
+++ b/lib/libc/shlib_version
@@ -1,4 +1,4 @@
major=100
-minor=1
+minor=2
# note: If changes were made to include/thread_private.h or if system calls
# were added/changed then librthread/shlib_version must also be updated.
diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c
index 239dba1ed..aca3d3fe5 100644
--- a/lib/libc/stdio/vfprintf.c
+++ b/lib/libc/stdio/vfprintf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfprintf.c,v 1.82 2023/10/06 16:41:02 millert Exp $ */
+/* $OpenBSD: vfprintf.c,v 1.83 2024/07/14 13:31:50 millert Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
@@ -56,6 +56,10 @@
#include "local.h"
#include "fvwrite.h"
+#define PRINTF_PAGESIZE (1 << _MAX_PAGE_SHIFT)
+#define PRINTF_PAGEMASK (PRINTF_PAGESIZE - 1)
+#define PAGEROUND(x) (((x) + (PRINTF_PAGEMASK)) & ~PRINTF_PAGEMASK)
+
union arg {
int intarg;
unsigned int uintarg;
@@ -153,12 +157,13 @@ __sbprintf(FILE *fp, const char *fmt, va_list ap)
* string is null-terminated.
*/
static char *
-__wcsconv(wchar_t *wcsarg, int prec)
+__wcsconv(wchar_t *wcsarg, int prec, char **convbufp, size_t *convbufsizp)
{
+ char *convbuf = *convbufp;
+ size_t convbufsiz = *convbufsizp;
mbstate_t mbs;
char buf[MB_LEN_MAX];
wchar_t *p;
- char *convbuf;
size_t clen, nbytes;
/* Allocate space for the maximum number of bytes we could output. */
@@ -191,15 +196,26 @@ __wcsconv(wchar_t *wcsarg, int prec)
return (NULL);
}
}
- if ((convbuf = malloc(nbytes + 1)) == NULL)
- return (NULL);
+ if (nbytes + 1 > convbufsiz) {
+ if (convbuf != NULL)
+ munmap(convbuf, convbufsiz);
+ convbufsiz = PAGEROUND(nbytes + 1);
+ convbuf = mmap(NULL, convbufsiz, PROT_WRITE|PROT_READ,
+ MAP_ANON|MAP_PRIVATE, -1, 0);
+ if (convbuf == MAP_FAILED) {
+ *convbufp = NULL;
+ *convbufsizp = 0;
+ return (NULL);
+ }
+ *convbufp = convbuf;
+ *convbufsizp = convbufsiz;
+ }
/* Fill the output buffer. */
p = wcsarg;
memset(&mbs, 0, sizeof(mbs));
if ((nbytes = wcsrtombs(convbuf, (const wchar_t **)&p,
nbytes, &mbs)) == (size_t)-1) {
- free(convbuf);
return (NULL);
}
convbuf[nbytes] = '\0';
@@ -328,6 +344,7 @@ __vfprintf(FILE *fp, const char *fmt0, __va_list ap)
va_list orgap; /* original argument pointer */
#ifdef PRINTF_WIDE_CHAR
char *convbuf; /* buffer for wide to multi-byte conversion */
+ size_t convbufsiz; /* size of convbuf, for munmap() */
#endif
/*
@@ -475,6 +492,7 @@ __vfprintf(FILE *fp, const char *fmt0, __va_list ap)
ret = 0;
#ifdef PRINTF_WIDE_CHAR
convbuf = NULL;
+ convbufsiz = 0;
#endif
/*
@@ -840,8 +858,6 @@ fp_common:
if (flags & LONGINT) {
wchar_t *wcp;
- free(convbuf);
- convbuf = NULL;
if ((wcp = GETARG(wchar_t *)) == NULL) {
struct syslog_data sdata = SYSLOG_DATA_INIT;
int save_errno = errno;
@@ -852,12 +868,12 @@ fp_common:
cp = "(null)";
} else {
- convbuf = __wcsconv(wcp, prec);
- if (convbuf == NULL) {
+ cp = __wcsconv(wcp, prec, &convbuf,
+ &convbufsiz);
+ if (cp == NULL) {
ret = -1;
goto error;
}
- cp = convbuf;
}
} else
#endif /* PRINTF_WIDE_CHAR */
@@ -1072,7 +1088,8 @@ overflow:
finish:
#ifdef PRINTF_WIDE_CHAR
- free(convbuf);
+ if (convbuf != NULL)
+ munmap(convbuf, convbufsiz);
#endif
#ifdef FLOATING_POINT
if (dtoaresult)
diff --git a/lib/libc/string/Makefile.inc b/lib/libc/string/Makefile.inc
index a1b1934aa..204ca1b26 100644
--- a/lib/libc/string/Makefile.inc
+++ b/lib/libc/string/Makefile.inc
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.inc,v 1.39 2017/09/05 03:16:13 schwarze Exp $
+# $OpenBSD: Makefile.inc,v 1.40 2024/07/14 09:51:18 jca Exp $
# string sources
.PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/string ${LIBCSRCDIR}/string
@@ -9,9 +9,9 @@ SRCS+= explicit_bzero.c memccpy.c memmem.c memrchr.c stpcpy.c stpncpy.c \
strndup.c strnlen.c strsignal.c strtok.c strxfrm.c strxfrm_l.c \
timingsafe_bcmp.c timingsafe_memcmp.c \
wcscat.c wcschr.c wcscmp.c wcscpy.c wcscspn.c wcslcat.c wcslcpy.c \
- wcslen.c wcsncat.c wcsncmp.c wcsncpy.c wcspbrk.c wcsrchr.c wcsspn.c \
- wcsstr.c wcstok.c wcswcs.c wcswidth.c wmemchr.c wmemcmp.c wmemcpy.c \
- wmemmove.c wmemset.c wcsdup.c wcscasecmp.c wcscasecmp_l.c
+ wcslen.c wcsncat.c wcsncmp.c wcsncpy.c wcsnlen.c wcspbrk.c wcsrchr.c \
+ wcsspn.c wcsstr.c wcstok.c wcswcs.c wcswidth.c wmemchr.c wmemcmp.c \
+ wmemcpy.c wmemmove.c wmemset.c wcsdup.c wcscasecmp.c wcscasecmp_l.c
# machine-dependent net sources
# ../arch/ARCH/Makefile.inc must include sources for:
diff --git a/lib/libc/string/wcslen.3 b/lib/libc/string/wcslen.3
index 12f81763b..b6d9aafc4 100644
--- a/lib/libc/string/wcslen.3
+++ b/lib/libc/string/wcslen.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: wcslen.3,v 1.3 2013/06/05 03:39:23 tedu Exp $
+.\" $OpenBSD: wcslen.3,v 1.4 2024/07/14 09:51:18 jca Exp $
.\"
.\" Copyright (c) 1990, 1991 The Regents of the University of California.
.\" All rights reserved.
@@ -31,26 +31,50 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd $Mdocdate: June 5 2013 $
+.Dd $Mdocdate: July 14 2024 $
.Dt WCSLEN 3
.Os
.Sh NAME
-.Nm wcslen
+.Nm wcslen ,
+.Nm wcsnlen
.Nd find length of a wide string
.Sh SYNOPSIS
.In wchar.h
.Ft size_t
.Fn wcslen "const wchar_t *s"
+.Ft size_t
+.Fn wcsnlen "const wchar_t *s" "size_t maxlen"
.Sh DESCRIPTION
The
.Fn wcslen
function computes the length of the wide string
.Fa s .
+The
+.Fn wcsnlen
+function computes the length of the wide string
+.Fa s ,
+up to
+.Fa maxlen
+wide characters.
+The
+.Fn wcsnlen
+function will never attempt to address more than
+.Fa maxlen
+wide characters, making it suitable for use with wide character arrays
+that are not guaranteed to be NUL-terminated.
.Sh RETURN VALUES
The
.Fn wcslen
function returns the number of wide characters that precede the terminating
null wide character.
+.Pp
+The
+.Fn wcsnlen
+function returns the number of wide characters that precede the terminating
+null wide character
+or
+.Fa maxlen ,
+whichever is smaller.
.Sh SEE ALSO
.Xr strlen 3 ,
.Xr wcswidth 3
@@ -61,6 +85,10 @@ function conforms to
.St -isoC-99
and was first introduced in
.St -isoC-amd1 .
+The
+.Fn wcsnlen
+function conforms to
+.St -p1003.1-2008 .
.Sh HISTORY
The
.Fn wcslen
@@ -68,3 +96,7 @@ function was ported from
.Nx
and first appeared in
.Ox 3.8 .
+The
+.Fn wcsnlen
+function first appeared in
+.Ox 7.6 .
diff --git a/lib/libc/string/wcsnlen.c b/lib/libc/string/wcsnlen.c
new file mode 100644
index 000000000..eb1d08e85
--- /dev/null
+++ b/lib/libc/string/wcsnlen.c
@@ -0,0 +1,45 @@
+/* $OpenBSD: wcsnlen.c,v 1.1 2024/07/14 09:51:18 jca Exp $ */
+/* $NetBSD: wcslen.c,v 1.2 2001/01/03 14:29:36 lukem Exp $ */
+
+/*-
+ * Copyright (c)1999 Citrus Project,
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * citrus Id: wcslen.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp
+ */
+
+#include
+
+size_t
+wcsnlen(const wchar_t *s, size_t maxlen)
+{
+ const wchar_t *p;
+
+ p = s;
+ while (maxlen-- && *p)
+ p++;
+
+ return p - s;
+}
+
diff --git a/lib/libc/sys/sigaction.2 b/lib/libc/sys/sigaction.2
index edcd3e3ee..044d95747 100644
--- a/lib/libc/sys/sigaction.2
+++ b/lib/libc/sys/sigaction.2
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sigaction.2,v 1.78 2024/07/12 11:01:40 deraadt Exp $
+.\" $OpenBSD: sigaction.2,v 1.79 2024/07/14 03:53:18 jsg Exp $
.\" $NetBSD: sigaction.2,v 1.7 1995/10/12 15:41:16 jtc Exp $
.\"
.\" Copyright (c) 1980, 1990, 1993
@@ -30,7 +30,7 @@
.\"
.\" @(#)sigaction.2 8.2 (Berkeley) 4/3/94
.\"
-.Dd $Mdocdate: July 12 2024 $
+.Dd $Mdocdate: July 14 2024 $
.Dt SIGACTION 2
.Os
.Sh NAME
@@ -479,7 +479,7 @@ which is inspected by an event loop.
Other variables accessed inside the handler must be either const, or
local to the handler.
More complicated global variables (such as strings, structs, or lists)
-will require external methods to gaurantee consistancy, such as
+will require external methods to guarantee consistency, such as
signal-blocking with
.Xr sigprocmask 2 .
.Pp
diff --git a/lib/libcrypto/conf/conf_api.c b/lib/libcrypto/conf/conf_api.c
index b78bd50c2..a94e8c8be 100644
--- a/lib/libcrypto/conf/conf_api.c
+++ b/lib/libcrypto/conf/conf_api.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf_api.c,v 1.18 2024/03/02 11:11:11 tb Exp $ */
+/* $OpenBSD: conf_api.c,v 1.19 2024/07/14 14:32:45 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -69,8 +69,6 @@
#include
#include
-#include "lhash_local.h"
-
static void value_free_hash_doall_arg(CONF_VALUE *a,
LHASH_OF(CONF_VALUE) *conf);
static void value_free_stack_doall(CONF_VALUE *a);
diff --git a/lib/libcrypto/evp/evp_pkey.c b/lib/libcrypto/evp/evp_pkey.c
index 591d066f4..f9100e226 100644
--- a/lib/libcrypto/evp/evp_pkey.c
+++ b/lib/libcrypto/evp/evp_pkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: evp_pkey.c,v 1.28 2024/04/09 13:55:02 beck Exp $ */
+/* $OpenBSD: evp_pkey.c,v 1.30 2024/07/14 16:06:31 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@@ -141,19 +141,63 @@ error:
}
LCRYPTO_ALIAS(EVP_PKEY2PKCS8);
-/* EVP_PKEY attribute functions */
+/*
+ * XXX - This is only used by openssl(1) pkcs12 for the Microsoft-specific
+ * NID_ms_csp_name and NID_LocalKeySet. This turns out to be the only reason
+ * why attributes hangs off the EVP_PKEY struct.
+ */
+int
+EVP_PKEY_add1_attr_by_NID(EVP_PKEY *pkey, int nid, int type,
+ const unsigned char *bytes, int len)
+{
+ STACK_OF(X509_ATTRIBUTE) *attrs = NULL;
+ X509_ATTRIBUTE *attr = NULL;
+ int ret = 0;
+
+ if ((attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type,
+ bytes, len)) == NULL)
+ goto err;
+
+ if ((attrs = pkey->attributes) == NULL)
+ attrs = sk_X509_ATTRIBUTE_new_null();
+ if (attrs == NULL)
+ goto err;
+
+ if (sk_X509_ATTRIBUTE_push(attrs, attr) <= 0)
+ goto err;
+ attr = NULL;
+
+ pkey->attributes = attrs;
+ attrs = NULL;
+
+ ret = 1;
+
+ err:
+ X509_ATTRIBUTE_free(attr);
+ if (attrs != pkey->attributes)
+ sk_X509_ATTRIBUTE_pop_free(attrs, X509_ATTRIBUTE_free);
+
+ return ret;
+}
+LCRYPTO_ALIAS(EVP_PKEY_add1_attr_by_NID);
+
+/*
+ * XXX - delete all the garbage below in the next bump.
+ */
int
EVP_PKEY_get_attr_count(const EVP_PKEY *key)
{
- return X509at_get_attr_count(key->attributes);
+ EVPerror(ERR_R_DISABLED);
+ return 0;
}
LCRYPTO_ALIAS(EVP_PKEY_get_attr_count);
int
EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos)
{
- return X509at_get_attr_by_NID(key->attributes, nid, lastpos);
+ EVPerror(ERR_R_DISABLED);
+ return -1;
}
LCRYPTO_ALIAS(EVP_PKEY_get_attr_by_NID);
@@ -161,29 +205,31 @@ int
EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, const ASN1_OBJECT *obj,
int lastpos)
{
- return X509at_get_attr_by_OBJ(key->attributes, obj, lastpos);
+ EVPerror(ERR_R_DISABLED);
+ return -1;
}
LCRYPTO_ALIAS(EVP_PKEY_get_attr_by_OBJ);
X509_ATTRIBUTE *
EVP_PKEY_get_attr(const EVP_PKEY *key, int loc)
{
- return X509at_get_attr(key->attributes, loc);
+ EVPerror(ERR_R_DISABLED);
+ return NULL;
}
LCRYPTO_ALIAS(EVP_PKEY_get_attr);
X509_ATTRIBUTE *
EVP_PKEY_delete_attr(EVP_PKEY *key, int loc)
{
- return X509at_delete_attr(key->attributes, loc);
+ EVPerror(ERR_R_DISABLED);
+ return NULL;
}
LCRYPTO_ALIAS(EVP_PKEY_delete_attr);
int
EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr)
{
- if (X509at_add1_attr(&key->attributes, attr))
- return 1;
+ EVPerror(ERR_R_DISABLED);
return 0;
}
LCRYPTO_ALIAS(EVP_PKEY_add1_attr);
@@ -192,29 +238,16 @@ int
EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key, const ASN1_OBJECT *obj, int type,
const unsigned char *bytes, int len)
{
- if (X509at_add1_attr_by_OBJ(&key->attributes, obj, type, bytes, len))
- return 1;
+ EVPerror(ERR_R_DISABLED);
return 0;
}
LCRYPTO_ALIAS(EVP_PKEY_add1_attr_by_OBJ);
-int
-EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key, int nid, int type,
- const unsigned char *bytes, int len)
-{
- if (X509at_add1_attr_by_NID(&key->attributes, nid, type, bytes, len))
- return 1;
- return 0;
-}
-LCRYPTO_ALIAS(EVP_PKEY_add1_attr_by_NID);
-
int
EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key, const char *attrname, int type,
const unsigned char *bytes, int len)
{
- if (X509at_add1_attr_by_txt(&key->attributes, attrname, type,
- bytes, len))
- return 1;
+ EVPerror(ERR_R_DISABLED);
return 0;
}
LCRYPTO_ALIAS(EVP_PKEY_add1_attr_by_txt);
diff --git a/lib/libcrypto/hidden/openssl/x509.h b/lib/libcrypto/hidden/openssl/x509.h
index d80a3b257..29abbc5c0 100644
--- a/lib/libcrypto/hidden/openssl/x509.h
+++ b/lib/libcrypto/hidden/openssl/x509.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: x509.h,v 1.7 2024/07/08 17:01:54 beck Exp $ */
+/* $OpenBSD: x509.h,v 1.8 2024/07/15 18:50:42 tb Exp $ */
/*
* Copyright (c) 2022 Bob Beck
*
@@ -442,15 +442,15 @@ LCRYPTO_USED(X509_ocspid_print);
LCRYPTO_USED(X509_CRL_print);
LCRYPTO_USED(X509_REQ_print_ex);
LCRYPTO_USED(X509_REQ_print);
-LCRYPTO_USED(EVP_PKEY_get_attr_count);
-LCRYPTO_USED(EVP_PKEY_get_attr_by_NID);
-LCRYPTO_USED(EVP_PKEY_get_attr_by_OBJ);
-LCRYPTO_USED(EVP_PKEY_get_attr);
-LCRYPTO_USED(EVP_PKEY_delete_attr);
-LCRYPTO_USED(EVP_PKEY_add1_attr);
-LCRYPTO_USED(EVP_PKEY_add1_attr_by_OBJ);
-LCRYPTO_USED(EVP_PKEY_add1_attr_by_NID);
-LCRYPTO_USED(EVP_PKEY_add1_attr_by_txt);
+LCRYPTO_UNUSED(EVP_PKEY_get_attr_count);
+LCRYPTO_UNUSED(EVP_PKEY_get_attr_by_NID);
+LCRYPTO_UNUSED(EVP_PKEY_get_attr_by_OBJ);
+LCRYPTO_UNUSED(EVP_PKEY_get_attr);
+LCRYPTO_UNUSED(EVP_PKEY_delete_attr);
+LCRYPTO_UNUSED(EVP_PKEY_add1_attr);
+LCRYPTO_UNUSED(EVP_PKEY_add1_attr_by_OBJ);
+LCRYPTO_UNUSED(EVP_PKEY_add1_attr_by_NID);
+LCRYPTO_UNUSED(EVP_PKEY_add1_attr_by_txt);
LCRYPTO_USED(PKCS8_PRIV_KEY_INFO_new);
LCRYPTO_USED(PKCS8_PRIV_KEY_INFO_free);
LCRYPTO_USED(d2i_PKCS8_PRIV_KEY_INFO);
diff --git a/lib/libcrypto/lhash/lhash.c b/lib/libcrypto/lhash/lhash.c
index 150831c11..aa532267d 100644
--- a/lib/libcrypto/lhash/lhash.c
+++ b/lib/libcrypto/lhash/lhash.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lhash.c,v 1.27 2024/06/30 14:13:08 jsing Exp $ */
+/* $OpenBSD: lhash.c,v 1.28 2024/07/14 14:32:45 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -65,13 +65,34 @@
#include
#include
-#include "lhash_local.h"
-
#undef MIN_NODES
#define MIN_NODES 16
#define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */
#define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */
+typedef struct lhash_node_st {
+ void *data;
+ struct lhash_node_st *next;
+#ifndef OPENSSL_NO_HASH_COMP
+ unsigned long hash;
+#endif
+} LHASH_NODE;
+
+struct lhash_st {
+ LHASH_NODE **b;
+ LHASH_COMP_FN_TYPE comp;
+ LHASH_HASH_FN_TYPE hash;
+ unsigned int num_nodes;
+ unsigned int num_alloc_nodes;
+ unsigned int p;
+ unsigned int pmax;
+ unsigned long up_load; /* load times 256 */
+ unsigned long down_load; /* load times 256 */
+ unsigned long num_items;
+
+ int error;
+} /* _LHASH */;
+
static void
expand(_LHASH *lh)
{
diff --git a/lib/libcrypto/lhash/lhash_local.h b/lib/libcrypto/lhash/lhash_local.h
deleted file mode 100644
index 1748845c4..000000000
--- a/lib/libcrypto/lhash/lhash_local.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* $OpenBSD: lhash_local.h,v 1.2 2024/06/30 14:13:08 jsing Exp $ */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-/* Header for dynamic hash table routines
- * Author - Eric Young
- */
-
-#include
-
-#ifndef HEADER_LHASH_LOCAL_H
-#define HEADER_LHASH_LOCAL_H
-
-typedef struct lhash_node_st {
- void *data;
- struct lhash_node_st *next;
-#ifndef OPENSSL_NO_HASH_COMP
- unsigned long hash;
-#endif
-} LHASH_NODE;
-
-struct lhash_st {
- LHASH_NODE **b;
- LHASH_COMP_FN_TYPE comp;
- LHASH_HASH_FN_TYPE hash;
- unsigned int num_nodes;
- unsigned int num_alloc_nodes;
- unsigned int p;
- unsigned int pmax;
- unsigned long up_load; /* load times 256 */
- unsigned long down_load; /* load times 256 */
- unsigned long num_items;
-
- int error;
-} /* _LHASH */;
-
-#endif
diff --git a/lib/libcrypto/man/EC_KEY_new.3 b/lib/libcrypto/man/EC_KEY_new.3
index f415b91d6..500db339a 100644
--- a/lib/libcrypto/man/EC_KEY_new.3
+++ b/lib/libcrypto/man/EC_KEY_new.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: EC_KEY_new.3,v 1.19 2024/02/16 06:09:36 tb Exp $
+.\" $OpenBSD: EC_KEY_new.3,v 1.20 2024/07/14 05:53:09 jsg Exp $
.\" full merge up to: OpenSSL 3aef36ff Jan 5 13:06:03 2016 -0500
.\" partial merge up to: OpenSSL e9b77246 Jan 20 19:58:49 2017 +0100
.\"
@@ -49,7 +49,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: February 16 2024 $
+.Dd $Mdocdate: July 14 2024 $
.Dt EC_KEY_NEW 3
.Os
.Sh NAME
@@ -377,7 +377,7 @@ and
.Fn EC_KEY_set_conv_form
get and set the point_conversion_form for the
.Fa key .
-For a description of point_conversion_form please refer to
+For a description of point_conversion_form refer to
.Xr EC_GROUP_copy 3 .
.Pp
.Fn EC_KEY_set_flags
diff --git a/lib/libcrypto/objects/obj_dat.c b/lib/libcrypto/objects/obj_dat.c
index 1ac854449..53ae83784 100644
--- a/lib/libcrypto/objects/obj_dat.c
+++ b/lib/libcrypto/objects/obj_dat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: obj_dat.c,v 1.90 2024/05/08 16:35:05 tb Exp $ */
+/* $OpenBSD: obj_dat.c,v 1.91 2024/07/14 14:32:45 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -71,7 +71,6 @@
#include
#include "asn1_local.h"
-#include "lhash_local.h"
/* obj_dat.h is generated from objects.h by obj_dat.pl */
#include "obj_dat.h"
diff --git a/lib/libcrypto/pkcs12/p12_crt.c b/lib/libcrypto/pkcs12/p12_crt.c
index 3d3ae733c..55fb7fd63 100644
--- a/lib/libcrypto/pkcs12/p12_crt.c
+++ b/lib/libcrypto/pkcs12/p12_crt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: p12_crt.c,v 1.24 2024/03/24 06:48:03 tb Exp $ */
+/* $OpenBSD: p12_crt.c,v 1.25 2024/07/15 15:43:25 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project.
*/
@@ -60,8 +60,11 @@
#include
#include
+#include
+#include "evp_local.h"
#include "pkcs12_local.h"
+#include "x509_local.h"
static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
PKCS12_SAFEBAG *bag);
@@ -69,13 +72,25 @@ static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
static int
copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid)
{
- int idx;
- X509_ATTRIBUTE *attr;
+ X509_ATTRIBUTE *attr = NULL;
+ const ASN1_OBJECT *obj;
+ int i;
- idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1);
- if (idx < 0)
+ if ((obj = OBJ_nid2obj(nid)) == NULL) {
+ /* XXX - this seems wrong but preserves behavior. */
return 1;
- attr = EVP_PKEY_get_attr(pkey, idx);
+ }
+
+ for (i = 0; i < sk_X509_ATTRIBUTE_num(pkey->attributes); i++) {
+ attr = sk_X509_ATTRIBUTE_value(pkey->attributes, i);
+ if (OBJ_cmp(attr->object, obj) == 0)
+ break;
+ attr = NULL;
+ }
+
+ if (attr == NULL)
+ return 1;
+
if (!X509at_add1_attr(&bag->attrib, attr))
return 0;
return 1;
diff --git a/lib/libssl/hidden/openssl/ssl.h b/lib/libssl/hidden/openssl/ssl.h
index aa946ad25..cff250ee7 100644
--- a/lib/libssl/hidden/openssl/ssl.h
+++ b/lib/libssl/hidden/openssl/ssl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl.h,v 1.6 2024/03/02 11:48:55 tb Exp $ */
+/* $OpenBSD: ssl.h,v 1.7 2024/07/14 15:39:36 tb Exp $ */
/*
* Copyright (c) 2023 Bob Beck
*
@@ -377,5 +377,6 @@ LSSL_USED(SSL_get_peer_quic_transport_params);
LSSL_USED(SSL_set_quic_use_legacy_codepoint);
LSSL_USED(ERR_load_SSL_strings);
LSSL_USED(OPENSSL_init_ssl);
+LSSL_USED(SSL_CIPHER_get_handshake_digest);
#endif /* _LIBSSL_SSL_H */
diff --git a/lib/libssl/man/SSL_CIPHER_get_name.3 b/lib/libssl/man/SSL_CIPHER_get_name.3
index 235ff1408..60ef60cff 100644
--- a/lib/libssl/man/SSL_CIPHER_get_name.3
+++ b/lib/libssl/man/SSL_CIPHER_get_name.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: SSL_CIPHER_get_name.3,v 1.14 2022/07/17 08:51:07 jsg Exp $
+.\" $OpenBSD: SSL_CIPHER_get_name.3,v 1.16 2024/07/15 00:11:59 jsg Exp $
.\" full merge up to: OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100
.\" selective merge up to: OpenSSL 61f805c1 Jan 16 01:01:46 2018 +0800
.\"
@@ -52,7 +52,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: July 17 2022 $
+.Dd $Mdocdate: July 15 2024 $
.Dt SSL_CIPHER_GET_NAME 3
.Os
.Sh NAME
@@ -61,6 +61,7 @@
.Nm SSL_CIPHER_get_version ,
.Nm SSL_CIPHER_get_cipher_nid ,
.Nm SSL_CIPHER_get_digest_nid ,
+.Nm SSL_CIPHER_get_handshake_digest ,
.Nm SSL_CIPHER_get_kx_nid ,
.Nm SSL_CIPHER_get_auth_nid ,
.Nm SSL_CIPHER_is_aead ,
@@ -80,6 +81,8 @@
.Fn SSL_CIPHER_get_cipher_nid "const SSL_CIPHER *cipher"
.Ft int
.Fn SSL_CIPHER_get_digest_nid "const SSL_CIPHER *cipher"
+.Ft "const EVP_MD *"
+.Fn SSL_CIPHER_get_handshake_digest "const SSL_CIPHER *cipher"
.Ft int
.Fn SSL_CIPHER_get_kx_nid "const SSL_CIPHER *cipher"
.Ft int
@@ -132,6 +135,14 @@ If there is no digest (e.g. for AEAD cipher suites), then
.Dv NID_undef
is returned.
.Pp
+.Fn SSL_CIPHER_get_handshake_digest
+returns the
+.Vt EVP_MD
+object representing the digest used during a TLS handshake with the cipher
+.Fa c ,
+which may be different to the digest used in the message authentication code
+for encrypted records.
+.Pp
.Fn SSL_CIPHER_get_kx_nid
returns the key exchange NID corresponding to the method used by the
.Fa cipher .
@@ -307,6 +318,12 @@ and
return an NID constant or
.Dv NID_undef
if an error occurred.
+.Fn SSL_CIPHER_get_handshake_digest
+returns a valid
+.Vt EVP_MD
+object or
+.Dv NULL
+if an error occurred.
.Pp
.Fn SSL_CIPHER_is_aead
returns 1 if the
@@ -369,6 +386,9 @@ first appeared in OpenSSL 1.1.0 and have been available since
.Fn SSL_CIPHER_find
first appeared in OpenSSL 1.1.0 and has been available since
.Ox 7.0 .
+.Fn SSL_CIPHER_get_handshake_digest
+first appeared in OpenSSL 1.1.1 and has been available since
+.Ox 7.5 .
.Sh BUGS
If
.Fn SSL_CIPHER_description
diff --git a/lib/libssl/s3_lib.c b/lib/libssl/s3_lib.c
index 0eec6e971..1c1906d9e 100644
--- a/lib/libssl/s3_lib.c
+++ b/lib/libssl/s3_lib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: s3_lib.c,v 1.252 2024/05/10 05:08:05 tb Exp $ */
+/* $OpenBSD: s3_lib.c,v 1.253 2024/07/15 14:45:15 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -183,7 +183,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_MD5,
.algorithm_ssl = SSL_SSLV3,
.algo_strength = SSL_STRONG_NONE,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 0,
.alg_bits = 0,
},
@@ -199,7 +199,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_SSLV3,
.algo_strength = SSL_STRONG_NONE,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 0,
.alg_bits = 0,
},
@@ -215,7 +215,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_MD5,
.algorithm_ssl = SSL_SSLV3,
.algo_strength = SSL_LOW,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -231,7 +231,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_SSLV3,
.algo_strength = SSL_LOW,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -247,7 +247,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_SSLV3,
.algo_strength = SSL_MEDIUM,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 112,
.alg_bits = 168,
},
@@ -267,7 +267,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_SSLV3,
.algo_strength = SSL_MEDIUM,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 112,
.alg_bits = 168,
},
@@ -283,7 +283,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_MD5,
.algorithm_ssl = SSL_SSLV3,
.algo_strength = SSL_LOW,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -299,7 +299,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_SSLV3,
.algo_strength = SSL_MEDIUM,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 112,
.alg_bits = 168,
},
@@ -319,7 +319,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -335,7 +335,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -351,7 +351,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -367,7 +367,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -383,7 +383,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -399,7 +399,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -416,7 +416,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA256,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_STRONG_NONE,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 0,
.alg_bits = 0,
},
@@ -432,7 +432,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA256,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -448,7 +448,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA256,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -467,7 +467,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -483,7 +483,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -499,7 +499,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -517,7 +517,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA256,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -533,7 +533,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA256,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -549,7 +549,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA256,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -565,7 +565,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA256,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -584,7 +584,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -600,7 +600,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -616,7 +616,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -637,7 +637,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_AEAD,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -653,7 +653,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_AEAD,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA384,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -669,7 +669,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_AEAD,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -685,7 +685,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_AEAD,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA384,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -701,7 +701,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_AEAD,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -717,7 +717,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_AEAD,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA384,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -736,7 +736,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA256,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -752,7 +752,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA256,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -768,7 +768,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA256,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -784,7 +784,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA256,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -800,7 +800,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA256,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -816,7 +816,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA256,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -887,7 +887,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_STRONG_NONE,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 0,
.alg_bits = 0,
},
@@ -903,7 +903,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_LOW,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -919,7 +919,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_MEDIUM,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 112,
.alg_bits = 168,
},
@@ -935,7 +935,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -951,7 +951,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -967,7 +967,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_STRONG_NONE,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 0,
.alg_bits = 0,
},
@@ -983,7 +983,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_LOW,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -999,7 +999,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_MEDIUM,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 112,
.alg_bits = 168,
},
@@ -1015,7 +1015,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -1031,7 +1031,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -1047,7 +1047,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_STRONG_NONE,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 0,
.alg_bits = 0,
},
@@ -1063,7 +1063,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_LOW,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -1079,7 +1079,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_MEDIUM,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 112,
.alg_bits = 168,
},
@@ -1095,7 +1095,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -1111,7 +1111,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA1,
.algorithm_ssl = SSL_TLSV1,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT|TLS1_PRF,
+ .algorithm2 = SSL_HANDSHAKE_MAC_DEFAULT,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -1130,7 +1130,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA256,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -1146,7 +1146,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA384,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA384,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -1162,7 +1162,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA256,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -1178,7 +1178,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_SHA384,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA384,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -1196,7 +1196,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_AEAD,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -1212,7 +1212,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_AEAD,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA384,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -1228,7 +1228,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_AEAD,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 128,
.alg_bits = 128,
},
@@ -1244,7 +1244,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_AEAD,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA384|TLS1_PRF_SHA384,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA384,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -1260,7 +1260,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_AEAD,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -1276,7 +1276,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_AEAD,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 256,
.alg_bits = 256,
},
@@ -1292,7 +1292,7 @@ const SSL_CIPHER ssl3_ciphers[] = {
.algorithm_mac = SSL_AEAD,
.algorithm_ssl = SSL_TLSV1_2,
.algo_strength = SSL_HIGH,
- .algorithm2 = SSL_HANDSHAKE_MAC_SHA256|TLS1_PRF_SHA256,
+ .algorithm2 = SSL_HANDSHAKE_MAC_SHA256,
.strength_bits = 256,
.alg_bits = 256,
},
diff --git a/lib/libssl/ssl.h b/lib/libssl/ssl.h
index e63312a12..d8846a485 100644
--- a/lib/libssl/ssl.h
+++ b/lib/libssl/ssl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl.h,v 1.238 2024/07/13 18:33:18 tb Exp $ */
+/* $OpenBSD: ssl.h,v 1.239 2024/07/14 15:39:36 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -1125,6 +1125,9 @@ int SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *c);
int SSL_CIPHER_get_digest_nid(const SSL_CIPHER *c);
int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *c);
int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *c);
+#if defined(LIBRESSL_INTERNAL) || defined(LIBRESSL_NEXT_API)
+const EVP_MD *SSL_CIPHER_get_handshake_digest(const SSL_CIPHER *c);
+#endif
int SSL_CIPHER_is_aead(const SSL_CIPHER *c);
int SSL_get_fd(const SSL *s);
diff --git a/lib/libssl/ssl_ciph.c b/lib/libssl/ssl_ciph.c
index a01465d9e..13790c56b 100644
--- a/lib/libssl/ssl_ciph.c
+++ b/lib/libssl/ssl_ciph.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_ciph.c,v 1.142 2024/05/09 07:55:48 tb Exp $ */
+/* $OpenBSD: ssl_ciph.c,v 1.143 2024/07/14 15:39:36 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -524,6 +524,7 @@ ssl_get_handshake_evp_md(SSL *s, const EVP_MD **md)
handshake_mac = s->s3->hs.cipher->algorithm2 & SSL_HANDSHAKE_MAC_MASK;
+ /* XXX - can we simplify this now that TLSv1.0 and TLSv1.1 are gone? */
/* For TLSv1.2 we upgrade the default MD5+SHA1 MAC to SHA256. */
if (SSL_USE_SHA256_PRF(s) && handshake_mac == SSL_HANDSHAKE_MAC_DEFAULT)
handshake_mac = SSL_HANDSHAKE_MAC_SHA256;
@@ -1624,6 +1625,21 @@ SSL_CIPHER_get_auth_nid(const SSL_CIPHER *c)
}
LSSL_ALIAS(SSL_CIPHER_get_auth_nid);
+const EVP_MD *
+SSL_CIPHER_get_handshake_digest(const SSL_CIPHER *c)
+{
+ switch (c->algorithm2 & SSL_HANDSHAKE_MAC_MASK) {
+ case SSL_HANDSHAKE_MAC_DEFAULT:
+ case SSL_HANDSHAKE_MAC_SHA256:
+ return EVP_sha256();
+ case SSL_HANDSHAKE_MAC_SHA384:
+ return EVP_sha384();
+ default:
+ return NULL;
+ }
+}
+LSSL_ALIAS(SSL_CIPHER_get_handshake_digest);
+
int
SSL_CIPHER_is_aead(const SSL_CIPHER *c)
{
diff --git a/lib/libssl/ssl_err.c b/lib/libssl/ssl_err.c
index 61d72fac6..6498eefd7 100644
--- a/lib/libssl/ssl_err.c
+++ b/lib/libssl/ssl_err.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_err.c,v 1.50 2024/07/13 17:42:13 tb Exp $ */
+/* $OpenBSD: ssl_err.c,v 1.51 2024/07/14 15:56:08 tb Exp $ */
/* ====================================================================
* Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
*
@@ -476,6 +476,7 @@ ERR_load_SSL_strings(void)
{
#ifndef OPENSSL_NO_ERR
if (ERR_func_error_string(SSL_str_functs[0].error) == NULL) {
+ /* TMP UGLY CASTS */
ERR_load_strings(0, (ERR_STRING_DATA *)SSL_str_functs);
ERR_load_strings(0, (ERR_STRING_DATA *)SSL_str_reasons);
}
diff --git a/lib/libssl/ssl_local.h b/lib/libssl/ssl_local.h
index db102212a..74c6ad33e 100644
--- a/lib/libssl/ssl_local.h
+++ b/lib/libssl/ssl_local.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_local.h,v 1.17 2024/06/25 14:10:45 jsing Exp $ */
+/* $OpenBSD: ssl_local.h,v 1.18 2024/07/15 14:45:15 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -255,15 +255,6 @@ __BEGIN_HIDDEN_DECLS
#define SSL3_CK_ID 0x03000000
#define SSL3_CK_VALUE_MASK 0x0000ffff
-#define TLS1_PRF_DGST_MASK (0xff << TLS1_PRF_DGST_SHIFT)
-
-#define TLS1_PRF_DGST_SHIFT 10
-#define TLS1_PRF_MD5 (SSL_HANDSHAKE_MAC_MD5 << TLS1_PRF_DGST_SHIFT)
-#define TLS1_PRF_SHA1 (SSL_HANDSHAKE_MAC_SHA << TLS1_PRF_DGST_SHIFT)
-#define TLS1_PRF_SHA256 (SSL_HANDSHAKE_MAC_SHA256 << TLS1_PRF_DGST_SHIFT)
-#define TLS1_PRF_SHA384 (SSL_HANDSHAKE_MAC_SHA384 << TLS1_PRF_DGST_SHIFT)
-#define TLS1_PRF (TLS1_PRF_MD5 | TLS1_PRF_SHA1)
-
/*
* Cipher strength information.
*/
diff --git a/regress/lib/libc/Makefile b/regress/lib/libc/Makefile
index 8b5e4d450..3cd970e49 100644
--- a/regress/lib/libc/Makefile
+++ b/regress/lib/libc/Makefile
@@ -1,10 +1,11 @@
-# $OpenBSD: Makefile,v 1.58 2021/08/31 09:58:17 jasper Exp $
+# $OpenBSD: Makefile,v 1.59 2024/07/14 09:48:48 jca Exp $
SUBDIR+= _setjmp
SUBDIR+= alloca arc4random-fork atexit
SUBDIR+= basename
SUBDIR+= cephes cxa-atexit
SUBDIR+= db dirname
+SUBDIR+= elf_aux_info
SUBDIR+= env explicit_bzero
SUBDIR+= ffs fmemopen fnmatch fpclassify fread
SUBDIR+= gcvt getaddrinfo getcap getopt getopt_long glob
diff --git a/regress/lib/libc/elf_aux_info/Makefile b/regress/lib/libc/elf_aux_info/Makefile
new file mode 100644
index 000000000..58dc58a83
--- /dev/null
+++ b/regress/lib/libc/elf_aux_info/Makefile
@@ -0,0 +1,5 @@
+PROG=elf_aux_info
+
+WARNINGS=yes
+
+.include
diff --git a/regress/lib/libc/elf_aux_info/elf_aux_info.c b/regress/lib/libc/elf_aux_info/elf_aux_info.c
new file mode 100644
index 000000000..14870e253
--- /dev/null
+++ b/regress/lib/libc/elf_aux_info/elf_aux_info.c
@@ -0,0 +1,53 @@
+#include
+
+#include
+#include
+
+int
+main(void)
+{
+ int ret = 0;
+ int a;
+ unsigned long b;
+
+ /* Should always succeed */
+ if (elf_aux_info(AT_PAGESZ, &a, sizeof(a)))
+ ret |= 1;
+ else
+ fprintf(stderr, "AT_PAGESZ %d\n", a);
+
+ /* Wrong size */
+ if (elf_aux_info(AT_PAGESZ, &b, sizeof(b)) != EINVAL)
+ ret |= 2;
+
+ /* Invalid request */
+ if (elf_aux_info(-1, &a, sizeof(a)) != EINVAL)
+ ret |= 4;
+
+ /* Should either succeed or fail with ENOENT if not supported */
+ switch (elf_aux_info(AT_HWCAP, &b, sizeof(b))) {
+ case 0:
+ fprintf(stderr, "AT_HWCAP %lx\n", b);
+ break;
+ case ENOENT:
+ break;
+ default:
+ ret |= 8;
+ }
+
+ /* Should either succeed or fail with ENOENT if not supported */
+ switch (elf_aux_info(AT_HWCAP2, &b, sizeof(b))) {
+ case 0:
+ fprintf(stderr, "AT_HWCAP2 %lx\n", b);
+ break;
+ case ENOENT:
+ break;
+ default:
+ ret |= 16;
+ }
+
+ if (ret)
+ fprintf(stderr, "FAILED (status %x)\n", ret);
+
+ return ret;
+}
diff --git a/regress/lib/libc/regex/t_exhaust.c b/regress/lib/libc/regex/t_exhaust.c
index 58ac8007f..f54bab18d 100644
--- a/regress/lib/libc/regex/t_exhaust.c
+++ b/regress/lib/libc/regex/t_exhaust.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: t_exhaust.c,v 1.3 2012/12/05 23:20:07 deraadt Exp $ */
+/* $OpenBSD: t_exhaust.c,v 1.4 2024/07/15 10:11:56 anton Exp $ */
/* $NetBSD: t_exhaust.c,v 1.2 2011/10/21 00:41:34 christos Exp $ */
/*-
@@ -158,8 +158,8 @@ static char *(*patterns[])(size_t) = {
p6,
};
-
-main()
+int
+main(void)
{
regex_t re;
int e, ret = 0;
@@ -181,4 +181,3 @@ main()
}
return ret;
}
-
diff --git a/regress/sys/kern/unp-write-closed/Makefile b/regress/sys/kern/unp-write-closed/Makefile
index 832994174..5b73f5eaf 100644
--- a/regress/sys/kern/unp-write-closed/Makefile
+++ b/regress/sys/kern/unp-write-closed/Makefile
@@ -1,5 +1,7 @@
-# $OpenBSD: Makefile,v 1.1.1.1 2024/06/28 21:07:27 bluhm Exp $
+# $OpenBSD: Makefile,v 1.2 2024/07/14 18:49:32 anton Exp $
PROG= unp-write-closed
+WARNINGS= yes
+
.include
diff --git a/regress/sys/kern/unp-write-closed/unp-write-closed.c b/regress/sys/kern/unp-write-closed/unp-write-closed.c
index 51e84ec7c..103ccbff7 100644
--- a/regress/sys/kern/unp-write-closed/unp-write-closed.c
+++ b/regress/sys/kern/unp-write-closed/unp-write-closed.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: unp-write-closed.c,v 1.1.1.1 2024/06/28 21:07:27 bluhm Exp $ */
+/* $OpenBSD: unp-write-closed.c,v 1.2 2024/07/14 18:49:32 anton Exp $ */
/*
* Copyright (c) 2024 Vitaliy Makkoveev
* Copyright (c) 2024 Alenander Bluhm
@@ -27,7 +27,7 @@
sig_atomic_t done = 0;
-void
+static void
handler(int sigraised)
{
done = 1;
diff --git a/sbin/bioctl/bioctl.8 b/sbin/bioctl/bioctl.8
index a187daf36..357baffda 100644
--- a/sbin/bioctl/bioctl.8
+++ b/sbin/bioctl/bioctl.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: bioctl.8,v 1.114 2023/09/02 09:14:47 kn Exp $
+.\" $OpenBSD: bioctl.8,v 1.116 2024/07/15 05:36:08 jmc Exp $
.\"
.\" Copyright (c) 2004, 2005 Marco Peereboom
.\"
@@ -23,12 +23,12 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd $Mdocdate: September 2 2023 $
+.Dd $Mdocdate: July 15 2024 $
.Dt BIOCTL 8
.Os
.Sh NAME
.Nm bioctl
-.Nd RAID management interface
+.Nd storage management interface
.Sh SYNOPSIS
.Nm bioctl
.Op Fl hiqv
@@ -52,33 +52,56 @@
.Op Fl r Ar rounds
.Ar device
.Sh DESCRIPTION
-RAID device drivers which support management functionality can
-register their services with the
-.Xr bio 4
-driver.
.Nm bioctl
-then can be used to maintain RAID volumes.
+is used to interact with device drivers that register with
+.Xr bio 4 .
.Pp
-In the first synopsis,
-RAID controllers are managed.
+The
+.Fl h ,
+.Fl i ,
+.Fl q ,
+and
+.Fl v
+options are used to display information about the specified
+.Ar device :
+.Bl -tag -width disable
+.It Fl h
+Where appropriate, produce
+.Dq human-readable
+output.
+Use unit suffixes: Byte, Kilobyte, Megabyte,
+Gigabyte, Terabyte, Petabyte, Exabyte in order to reduce the number of
+digits to four or less.
+.It Fl i
+Display default information for the specified device.
+For example, for hardware RAID controllers enumerate attached devices.
+This is the default if no options are specified.
+.It Fl q
+If
.Ar device
-specifies either a drive (e.g. sd0) or a RAID controller (e.g. ami0).
-For operations which will be performed against
+is an
+.Xr sd 4 ,
+display its vendor, product, revision, and serial number.
+.It Fl v
+Be more verbose in output.
+.El
+.Pp
+The first synopsis shows options used to manage
+hardware RAID controllers.
+.Ar device
+specifies either a drive (e.g. sd1), a hardware RAID controller (e.g. ami0) or a
.Xr ses 4
or
.Xr safte 4
-enclosures, it is also possible to directly specify the enclosure name
-(e.g. safte0).
+enclosure.
.Pp
-In the second synopsis,
+The second synopsis shows options used to manage
.Xr softraid 4
-volumes are managed.
-.Ar device
-specifies either a volume (e.g. sd0) or the
-.Xr softraid 4
-controller (always softraid0).
+volumes (e.g. sd0)
+or the softraid controller itself
+(always softraid0).
.Pp
-The options for RAID controllers are as follows:
+The options for hardware RAID controllers are as follows:
.Bl -tag -width Ds
.It Fl a Ar alarm-function
Control the RAID card's alarm functionality, if supported.
@@ -116,29 +139,13 @@ is currently marked
.Dq Unused ,
promote it to being a
.Dq Hot Spare .
-.It Fl h
-Where necessary, produce
-.Dq human-readable
-output.
-Use unit suffixes: Byte, Kilobyte, Megabyte,
-Gigabyte, Terabyte, Petabyte, Exabyte in order to reduce the number of
-digits to four or less.
-.It Fl i
-Enumerate the selected RAID devices.
-This is the default if no other option is given.
-.It Fl q
-Show vendor, product, revision, and serial number for the given disk.
.It Fl R Ar chunk | channel : Ns Ar target Ns Op Pf . Ar lun
Manually kick off a rebuild of a degraded RAID volume, using
.Ar chunk
or
.Ar channel : Ns Ar target Ns Op Pf . Ar lun
-as a new chunk (with
-.Xr softraid 4 ,
-a partition of fstype
-.Dq RAID ) ,
-replacing the offline chunk in the volume;
-it is not possible to change the number of chunks.
+as a new chunk replacing the offline chunk in the volume.
+It is not possible to change the number of chunks.
The
.Ar chunk
must be specified as a full path to a device file (e.g. /dev/wd0d).
@@ -174,12 +181,9 @@ to cease blinking, if there is
or
.Xr safte 4
support in the enclosure.
-.It Fl v
-Be more verbose in output.
.El
.Pp
-In addition to the relevant options listed above,
-the options for
+The options for
.Xr softraid 4
devices are as follows:
.Bl -tag -width Ds
@@ -276,6 +280,21 @@ Change the passphrase on the selected crypto volume.
.It Fl p Ar passfile
Passphrase file used when crypto volumes are brought up.
This file must be root owned and have 0600 permissions.
+.It Fl R Ar chunk | channel : Ns Ar target Ns Op Pf . Ar lun
+Manually kick off a rebuild of a degraded volume, using
+.Ar chunk
+or
+.Ar channel : Ns Ar target Ns Op Pf . Ar lun
+as a new chunk,
+replacing the offline chunk in the volume.
+It is not possible to change the number of chunks.
+The
+.Ar chunk
+must be specified as a full path to a device file (e.g. /dev/sd0d) which
+refers to a partition of fstype RAID.
+A
+.Xr softraid 4
+volume rather than softraid0 is expected as the final argument.
.It Fl r Ar rounds
The number of iterations for the KDF algorithm to use when converting a
passphrase into a key, in order to create a new encrypted volume or change the
@@ -336,6 +355,11 @@ using a new chunk on wd0d:
.Bd -literal -offset 3n
# bioctl -R /dev/wd0d sd0
.Ed
+.Pp
+Show detailed information about the nvme0 controller:
+.Bd -literal -offset 3n
+# bioctl -v nvme0
+.Ed
.Sh SEE ALSO
.Xr bio 4 ,
.Xr scsi 4 ,
diff --git a/sbin/bioctl/bioctl.c b/sbin/bioctl/bioctl.c
index ff24ba007..089f6f6f8 100644
--- a/sbin/bioctl/bioctl.c
+++ b/sbin/bioctl/bioctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bioctl.c,v 1.157 2023/10/07 12:20:10 kn Exp $ */
+/* $OpenBSD: bioctl.c,v 1.158 2024/07/15 05:36:08 jmc Exp $ */
/*
* Copyright (c) 2004, 2005 Marco Peereboom
@@ -288,13 +288,12 @@ usage(void)
"[-R chunk | channel:target[.lun]]\n"
"\t[-t patrol-function] "
"[-u channel:target[.lun]] "
- "device\n"
+ "device\n\n"
" %s [-dhiPqsv] "
"[-C flag[,...]] [-c raidlevel] [-k keydisk]\n"
"\t[-l chunk[,...]] "
- "[-O device | channel:target[.lun]]\n"
- "\t[-p passfile] [-R chunk | channel:target[.lun]]\n"
- "\t[-r rounds] "
+ "[-O device | channel:target[.lun]] [-p passfile]\n"
+ "\t[-R chunk | channel:target[.lun]] [-r rounds] "
"device\n", __progname, __progname);
exit(1);
diff --git a/sbin/dhcpleased/log.h b/sbin/dhcpleased/log.h
index eeb9236a9..4cdf833c4 100644
--- a/sbin/dhcpleased/log.h
+++ b/sbin/dhcpleased/log.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: log.h,v 1.4 2024/06/03 17:58:33 deraadt Exp $ */
+/* $OpenBSD: log.h,v 1.5 2024/07/14 08:45:05 florian Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer
@@ -47,7 +47,7 @@ __dead void fatalx(const char *, ...)
#define log_init(x...) do {} while (0)
#define log_procinit(x...) do {} while (0)
#define log_setverbose(x...) do {} while (0)
-#define log_getverbose(x...) (0)
+#define log_getverbose() (0)
#define log_warn(x...) do {} while (0)
#define log_warnx(x...) do {} while (0)
#define log_info(x...) do {} while (0)
diff --git a/sbin/fsck_ext2fs/setup.c b/sbin/fsck_ext2fs/setup.c
index 1b11f10ad..d1508963b 100644
--- a/sbin/fsck_ext2fs/setup.c
+++ b/sbin/fsck_ext2fs/setup.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: setup.c,v 1.33 2019/07/01 07:13:44 kevlo Exp $ */
+/* $OpenBSD: setup.c,v 1.34 2024/07/15 13:32:50 martijn Exp $ */
/* $NetBSD: setup.c,v 1.1 1997/06/11 11:22:01 bouyer Exp $ */
/*
@@ -347,6 +347,10 @@ readsb(int listerr)
asblk.b_un.b_fs->e2fs_features_rocompat &= ~EXT2F_ROCOMPAT_LARGE_FILE;
asblk.b_un.b_fs->e2fs_features_rocompat |=
sblk.b_un.b_fs->e2fs_features_rocompat & EXT2F_ROCOMPAT_LARGE_FILE;
+ memcpy(asblk.b_un.b_fs->e2fs_fsmnt, sblk.b_un.b_fs->e2fs_fsmnt,
+ sizeof(sblk.b_un.b_fs->e2fs_fsmnt));
+ asblk.b_un.b_fs->e2fs_kbytes_written = sblk.b_un.b_fs->e2fs_kbytes_written;
+
if (sblock.e2fs.e2fs_rev > E2FS_REV0 &&
((sblock.e2fs.e2fs_features_incompat & ~EXT2F_INCOMPAT_SUPP) ||
(sblock.e2fs.e2fs_features_rocompat & ~EXT2F_ROCOMPAT_SUPP))) {
diff --git a/sbin/iked/vroute.c b/sbin/iked/vroute.c
index 5ef892d61..1e05d36cf 100644
--- a/sbin/iked/vroute.c
+++ b/sbin/iked/vroute.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vroute.c,v 1.19 2023/06/13 12:34:12 tb Exp $ */
+/* $OpenBSD: vroute.c,v 1.20 2024/07/14 13:13:33 tobhe Exp $ */
/*
* Copyright (c) 2021 Tobias Heider
@@ -631,6 +631,8 @@ vroute_getroute(struct iked *env, struct imsg *imsg)
case IMSG_VROUTE_DEL:
type = RTM_DELETE;
break;
+ default:
+ return (-1);
}
if (type == RTM_ADD)
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index ee5c00f3b..203209562 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.715 2023/11/02 20:47:31 sthen Exp $ */
+/* $OpenBSD: parse.y,v 1.716 2024/07/14 19:51:08 sashan Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -379,6 +379,8 @@ int getservice(char *);
int rule_label(struct pf_rule *, char *);
void mv_rules(struct pf_ruleset *, struct pf_ruleset *);
+void mv_tables(struct pfctl *, struct pfr_ktablehead *,
+ struct pf_anchor *, struct pf_anchor *);
void decide_address_family(struct node_host *, sa_family_t *);
int invalid_redirect(struct node_host *, sa_family_t);
u_int16_t parseicmpspec(char *, sa_family_t);
@@ -827,6 +829,7 @@ anchorname : STRING {
pfa_anchorlist : /* empty */
| pfa_anchorlist '\n'
+ | pfa_anchorlist tabledef '\n'
| pfa_anchorlist pfrule '\n'
| pfa_anchorlist anchorrule '\n'
| pfa_anchorlist include '\n'
@@ -853,7 +856,7 @@ pfa_anchor : '{'
snprintf(ta, PF_ANCHOR_NAME_SIZE, "_%d", pf->bn);
rs = pf_find_or_create_ruleset(ta);
if (rs == NULL)
- err(1, "pfa_anchor: pf_find_or_create_ruleset");
+ err(1, "pfa_anchor: pf_find_or_create_ruleset (%s)", ta);
pf->astack[pf->asd] = rs->anchor;
pf->anchor = rs->anchor;
} '\n' pfa_anchorlist '}'
@@ -899,6 +902,7 @@ anchorrule : ANCHOR anchorname dir quick interface af proto fromto
}
mv_rules(&pf->alast->ruleset,
&r.anchor->ruleset);
+ mv_tables(pf, &pfr_ktables, r.anchor, pf->alast);
}
pf_remove_if_empty_ruleset(&pf->alast->ruleset);
pf->alast = r.anchor;
@@ -3976,6 +3980,7 @@ process_tabledef(char *name, struct table_opts *opts, int popts)
{
struct pfr_buffer ab;
struct node_tinit *ti;
+ struct pfr_uktable *ukt;
bzero(&ab, sizeof(ab));
ab.pfrb_type = PFRB_ADDRS;
@@ -4006,13 +4011,52 @@ process_tabledef(char *name, struct table_opts *opts, int popts)
else if (pf->opts & PF_OPT_VERBOSE)
fprintf(stderr, "%s:%d: skipping duplicate table checks"
" for <%s>\n", file->name, yylval.lineno, name);
+
+ /*
+ * postpone definition of non-root tables to moment
+ * when path is fully resolved.
+ */
+ if (pf->asd > 0) {
+ ukt = calloc(1, sizeof(struct pfr_uktable));
+ if (ukt == NULL) {
+ DBGPRINT(
+ "%s:%d: not enough memory for <%s>\n", file->name,
+ yylval.lineno, name);
+ goto _error;
+ }
+ } else
+ ukt = NULL;
+
if (!(pf->opts & PF_OPT_NOACTION) &&
pfctl_define_table(name, opts->flags, opts->init_addr,
- pf->anchor->path, &ab, pf->anchor->ruleset.tticket)) {
+ pf->anchor->path, &ab, pf->anchor->ruleset.tticket, ukt)) {
yyerror("cannot define table %s: %s", name,
pf_strerror(errno));
goto _error;
}
+
+ if (ukt != NULL) {
+ ukt->pfrukt_init_addr = opts->init_addr;
+ if (RB_INSERT(pfr_ktablehead, &pfr_ktables,
+ &ukt->pfrukt_kt) != NULL) {
+ /*
+ * I think this should not happen, because
+ * pfctl_define_table() above does the same check
+ * effectively.
+ */
+ DBGPRINT(
+ "%s:%d table %s already exists in %s\n",
+ file->name, yylval.lineno,
+ ukt->pfrukt_name, pf->anchor->path);
+ free(ukt);
+ goto _error;
+ }
+ DBGPRINT("%s %s@%s inserted to tree\n",
+ __func__, ukt->pfrukt_name, pf->anchor->path);
+
+ } else
+ DBGPRINT("%s ukt is null\n", __func__);
+
pf->tdirty = 1;
pfr_buf_clear(&ab);
return (0);
@@ -5555,6 +5599,62 @@ mv_rules(struct pf_ruleset *src, struct pf_ruleset *dst)
TAILQ_CONCAT(dst->rules.inactive.ptr, src->rules.inactive.ptr, entries);
}
+void
+mv_tables(struct pfctl *pf, struct pfr_ktablehead *ktables,
+ struct pf_anchor *a, struct pf_anchor *alast)
+{
+
+ struct pfr_ktable *kt, *kt_safe;
+ char new_path[PF_ANCHOR_MAXPATH];
+ char *path_cut;
+ int sz;
+ struct pfr_uktable *ukt;
+ SLIST_HEAD(, pfr_uktable) ukt_list;;
+
+ /*
+ * Here we need to rename anchor path from temporal names such as
+ * _1/_2/foo to _1/bar/foo etc.
+ *
+ * This also means we need to remove and insert table to ktables
+ * tree as anchor path is being updated.
+ */
+ SLIST_INIT(&ukt_list);
+ DBGPRINT("%s [ %s ] (%s)\n", __func__, a->path, alast->path);
+ RB_FOREACH_SAFE(kt, pfr_ktablehead, ktables, kt_safe) {
+ path_cut = strstr(kt->pfrkt_anchor, alast->path);
+ if (path_cut != NULL) {
+ path_cut += strlen(alast->path);
+ if (*path_cut)
+ sz = snprintf(new_path, sizeof (new_path),
+ "%s%s", a->path, path_cut);
+ else
+ sz = snprintf(new_path, sizeof (new_path),
+ "%s", a->path);
+ if (sz >= sizeof (new_path))
+ errx(1, "new path is too long for %s@%s\n",
+ kt->pfrkt_name, kt->pfrkt_anchor);
+
+ DBGPRINT("%s %s@%s -> %s@%s\n", __func__,
+ kt->pfrkt_name, kt->pfrkt_anchor,
+ kt->pfrkt_name, new_path);
+ RB_REMOVE(pfr_ktablehead, ktables, kt);
+ strlcpy(kt->pfrkt_anchor, new_path,
+ sizeof(kt->pfrkt_anchor));
+ SLIST_INSERT_HEAD(&ukt_list, (struct pfr_uktable *)kt,
+ pfrukt_entry);
+ }
+ }
+
+ while ((ukt = SLIST_FIRST(&ukt_list)) != NULL) {
+ SLIST_REMOVE_HEAD(&ukt_list, pfrukt_entry);
+ if (RB_INSERT(pfr_ktablehead, ktables,
+ (struct pfr_ktable *)ukt) != NULL)
+ errx(1, "%s@%s exists already\n",
+ ukt->pfrukt_name,
+ ukt->pfrukt_anchor);
+ }
+}
+
void
decide_address_family(struct node_host *n, sa_family_t *af)
{
@@ -5711,7 +5811,7 @@ parseport(char *port, struct range *r, int extensions)
}
int
-pfctl_load_anchors(int dev, struct pfctl *pf, struct pfr_buffer *trans)
+pfctl_load_anchors(int dev, struct pfctl *pf)
{
struct loadanchors *la;
@@ -5720,7 +5820,7 @@ pfctl_load_anchors(int dev, struct pfctl *pf, struct pfr_buffer *trans)
fprintf(stderr, "\nLoading anchor %s from %s\n",
la->anchorname, la->filename);
if (pfctl_rules(dev, la->filename, pf->opts, pf->optimize,
- la->anchorname, trans) == -1)
+ la->anchorname, pf->trans) == -1)
return (-1);
}
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index 27cc175c8..825bd4cf0 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl.c,v 1.394 2024/02/02 08:23:29 sashan Exp $ */
+/* $OpenBSD: pfctl.c,v 1.395 2024/07/14 19:51:08 sashan Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -1424,6 +1424,41 @@ pfctl_check_qassignments(struct pf_ruleset *rs)
return (errs);
}
+static int
+pfctl_load_tables(struct pfctl *pf, char *path, struct pf_anchor *a)
+{
+ struct pfr_ktable *kt, *ktw;
+ struct pfr_uktable *ukt;
+ uint32_t ticket;
+ char anchor_path[PF_ANCHOR_MAXPATH];
+ int e;
+
+ RB_FOREACH_SAFE(kt, pfr_ktablehead, &pfr_ktables, ktw) {
+ if (strcmp(kt->pfrkt_anchor, a->path) != 0)
+ continue;
+
+ if (path != NULL && *path) {
+ strlcpy(anchor_path, kt->pfrkt_anchor,
+ sizeof (anchor_path));
+ snprintf(kt->pfrkt_anchor, PF_ANCHOR_MAXPATH, "%s/%s",
+ path, anchor_path);
+ }
+ ukt = (struct pfr_uktable *) kt;
+ ticket = pfctl_get_ticket(pf->trans, PF_TRANS_TABLE, path);
+ e = pfr_ina_define(&ukt->pfrukt_t, ukt->pfrukt_addrs.pfrb_caddr,
+ ukt->pfrukt_addrs.pfrb_size, NULL, NULL, ticket,
+ ukt->pfrukt_init_addr ? PFR_FLAG_ADDRSTOO : 0);
+ if (e != 0)
+ err(1, "%s pfr_ina_define() %s@%s", __func__,
+ kt->pfrkt_name, kt->pfrkt_anchor);
+ RB_REMOVE(pfr_ktablehead, &pfr_ktables, kt);
+ pfr_buf_clear(&ukt->pfrukt_addrs);
+ free(ukt);
+ }
+
+ return (0);
+}
+
int
pfctl_load_ruleset(struct pfctl *pf, char *path, struct pf_ruleset *rs,
int depth)
@@ -1469,6 +1504,8 @@ pfctl_load_ruleset(struct pfctl *pf, char *path, struct pf_ruleset *rs,
if ((error = pfctl_load_ruleset(pf, path,
&r->anchor->ruleset, depth + 1)))
goto error;
+ if ((error = pfctl_load_tables(pf, path, r->anchor)))
+ goto error;
} else if (pf->opts & PF_OPT_VERBOSE)
printf("\n");
free(r);
@@ -1495,8 +1532,11 @@ pfctl_load_rule(struct pfctl *pf, char *path, struct pf_rule *r, int depth)
bzero(&pr, sizeof(pr));
/* set up anchor before adding to path for anchor_call */
- if ((pf->opts & PF_OPT_NOACTION) == 0)
+ if ((pf->opts & PF_OPT_NOACTION) == 0) {
+ if (pf->trans == NULL)
+ errx(1, "pfctl_load_rule: no transaction");
pr.ticket = pfctl_get_ticket(pf->trans, PF_TRANS_RULESET, path);
+ }
if (strlcpy(pr.anchor, path, sizeof(pr.anchor)) >= sizeof(pr.anchor))
errx(1, "pfctl_load_rule: strlcpy");
@@ -1535,8 +1575,8 @@ int
pfctl_rules(int dev, char *filename, int opts, int optimize,
char *anchorname, struct pfr_buffer *trans)
{
-#define ERR(x) do { warn(x); goto _error; } while(0)
-#define ERRX(x) do { warnx(x); goto _error; } while(0)
+#define ERR(...) do { warn(__VA_ARGS__); goto _error; } while(0)
+#define ERRX(...) do { warnx(__VA_ARGS__); goto _error; } while(0)
struct pfr_buffer *t, buf;
struct pfctl pf;
@@ -1549,9 +1589,13 @@ pfctl_rules(int dev, char *filename, int opts, int optimize,
RB_INIT(&pf_anchors);
memset(&pf_main_anchor, 0, sizeof(pf_main_anchor));
pf_init_ruleset(&pf_main_anchor.ruleset);
+ memset(&pf, 0, sizeof(pf));
+ memset(&trs, 0, sizeof(trs));
+
if (trans == NULL) {
bzero(&buf, sizeof(buf));
buf.pfrb_type = PFRB_TRANS;
+ pf.trans = &buf;
t = &buf;
osize = 0;
} else {
@@ -1559,20 +1603,18 @@ pfctl_rules(int dev, char *filename, int opts, int optimize,
osize = t->pfrb_size;
}
- memset(&pf, 0, sizeof(pf));
- memset(&trs, 0, sizeof(trs));
if ((path = calloc(1, PATH_MAX)) == NULL)
- ERRX("pfctl_rules: calloc");
+ ERR("%s: calloc", __func__);
if (strlcpy(trs.pfrt_anchor, anchorname,
sizeof(trs.pfrt_anchor)) >= sizeof(trs.pfrt_anchor))
- ERRX("pfctl_rules: strlcpy");
+ ERRX("%s: strlcpy", __func__);
pf.dev = dev;
pf.opts = opts;
pf.optimize = optimize;
/* non-brace anchor, create without resolving the path */
if ((pf.anchor = calloc(1, sizeof(*pf.anchor))) == NULL)
- ERRX("pfctl_rules: calloc");
+ ERR("%s: calloc", __func__);
rs = &pf.anchor->ruleset;
pf_init_ruleset(rs);
rs->anchor = pf.anchor;
@@ -1637,7 +1679,7 @@ pfctl_rules(int dev, char *filename, int opts, int optimize,
/*
* process "load anchor" directives that might have used queues
*/
- if (pfctl_load_anchors(dev, &pf, t) == -1)
+ if (pfctl_load_anchors(dev, &pf) == -1)
ERRX("load anchors");
pfctl_clear_queues(&qspecs);
pfctl_clear_queues(&rootqs);
diff --git a/sbin/pfctl/pfctl.h b/sbin/pfctl/pfctl.h
index 253b8242d..b424192c1 100644
--- a/sbin/pfctl/pfctl.h
+++ b/sbin/pfctl/pfctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl.h,v 1.63 2024/05/19 10:39:40 jsg Exp $ */
+/* $OpenBSD: pfctl.h,v 1.64 2024/07/14 19:51:08 sashan Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -33,6 +33,12 @@
#ifndef _PFCTL_H_
#define _PFCTL_H_
+#ifdef PFCTL_DEBUG
+#define DBGPRINT(...) fprintf(stderr, __VA_ARGS__)
+#else
+#define DBGPRINT(...) (void)(0)
+#endif
+
enum pfctl_show { PFCTL_SHOW_RULES, PFCTL_SHOW_LABELS, PFCTL_SHOW_NOTHING };
enum { PFRB_TABLES = 1, PFRB_TSTATS, PFRB_ADDRS, PFRB_ASTATS,
@@ -54,6 +60,20 @@ struct pfr_anchoritem {
char *pfra_anchorname;
};
+struct pfr_uktable {
+ struct pfr_ktable pfrukt_kt;
+ struct pfr_buffer pfrukt_addrs;
+ int pfrukt_init_addr;
+ SLIST_ENTRY(pfr_uktable)
+ pfrukt_entry;
+};
+
+#define pfrukt_t pfrukt_kt.pfrkt_ts.pfrts_t
+#define pfrukt_name pfrukt_kt.pfrkt_t.pfrt_name
+#define pfrukt_anchor pfrukt_kt.pfrkt_t.pfrt_anchor
+
+extern struct pfr_ktablehead pfr_ktables;
+
SLIST_HEAD(pfr_anchors, pfr_anchoritem);
int pfr_clr_tables(struct pfr_table *, int *, int);
diff --git a/sbin/pfctl/pfctl_optimize.c b/sbin/pfctl/pfctl_optimize.c
index dc93b882b..4c972430d 100644
--- a/sbin/pfctl/pfctl_optimize.c
+++ b/sbin/pfctl/pfctl_optimize.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_optimize.c,v 1.49 2022/01/28 05:24:15 guenther Exp $ */
+/* $OpenBSD: pfctl_optimize.c,v 1.50 2024/07/14 19:51:08 sashan Exp $ */
/*
* Copyright (c) 2004 Mike Frantzen
@@ -1288,7 +1288,8 @@ again:
tablenum++;
if (pfctl_define_table(tbl->pt_name, PFR_TFLAG_CONST | tbl->pt_flags, 1,
- pf->astack[0]->path, tbl->pt_buf, pf->astack[0]->ruleset.tticket)) {
+ pf->astack[0]->path, tbl->pt_buf, pf->astack[0]->ruleset.tticket,
+ NULL)) {
warn("failed to create table %s in %s",
tbl->pt_name, pf->astack[0]->name);
return (1);
diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h
index 146580db2..e7eedfd8e 100644
--- a/sbin/pfctl/pfctl_parser.h
+++ b/sbin/pfctl/pfctl_parser.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_parser.h,v 1.119 2024/01/15 07:23:32 sashan Exp $ */
+/* $OpenBSD: pfctl_parser.h,v 1.120 2024/07/14 19:51:08 sashan Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -85,6 +85,7 @@ struct pfctl {
struct pfioc_queue *pqueue;
struct pfr_buffer *trans;
struct pf_anchor *anchor, *alast;
+ struct pfr_ktablehead pfr_ktlast;
const char *ruleset;
/* 'set foo' options */
@@ -211,6 +212,8 @@ struct pfctl_watermarks {
u_int32_t lo;
};
+struct pfr_uktable;
+
void copy_satopfaddr(struct pf_addr *, struct sockaddr *);
int pfctl_rules(int, char *, int, int, char *, struct pfr_buffer *);
@@ -234,7 +237,7 @@ int pfctl_set_interface_flags(struct pfctl *, char *, int, int);
int parse_config(char *, struct pfctl *);
int parse_flags(char *);
-int pfctl_load_anchors(int, struct pfctl *, struct pfr_buffer *);
+int pfctl_load_anchors(int, struct pfctl *);
int pfctl_load_queues(struct pfctl *);
int pfctl_add_queue(struct pfctl *, struct pf_queuespec *);
@@ -248,7 +251,7 @@ void print_status(struct pf_status *, struct pfctl_watermarks *, int);
void print_queuespec(struct pf_queuespec *);
int pfctl_define_table(char *, int, int, const char *, struct pfr_buffer *,
- u_int32_t);
+ u_int32_t, struct pfr_uktable *);
void pfctl_expand_label_nr(struct pf_rule *, unsigned int);
void pfctl_clear_fingerprints(int, int);
@@ -298,5 +301,8 @@ struct node_host *host(const char *, int);
int append_addr(struct pfr_buffer *, char *, int, int);
int append_addr_host(struct pfr_buffer *,
struct node_host *, int, int);
+int pfr_ktable_compare(struct pfr_ktable *,
+ struct pfr_ktable *);
+RB_PROTOTYPE(pfr_ktablehead, pfr_ktable, pfrkt_tree, pfr_ktable_compare);
#endif /* _PFCTL_PARSER_H_ */
diff --git a/sbin/pfctl/pfctl_radix.c b/sbin/pfctl/pfctl_radix.c
index 446329daf..cd5bf72c0 100644
--- a/sbin/pfctl/pfctl_radix.c
+++ b/sbin/pfctl/pfctl_radix.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_radix.c,v 1.38 2023/09/05 15:37:07 robert Exp $ */
+/* $OpenBSD: pfctl_radix.c,v 1.39 2024/07/14 19:51:08 sashan Exp $ */
/*
* Copyright (c) 2002 Cedric Berger
@@ -55,6 +55,18 @@ extern int dev;
static int pfr_next_token(char buf[BUF_SIZE], FILE *);
+struct pfr_ktablehead pfr_ktables = { 0 };
+RB_GENERATE(pfr_ktablehead, pfr_ktable, pfrkt_tree, pfr_ktable_compare);
+
+int
+pfr_ktable_compare(struct pfr_ktable *p, struct pfr_ktable *q)
+{
+ int d;
+
+ if ((d = strncmp(p->pfrkt_name, q->pfrkt_name, PF_TABLE_NAME_SIZE)))
+ return (d);
+ return (strcmp(p->pfrkt_anchor, q->pfrkt_anchor));
+}
int
pfr_clr_tables(struct pfr_table *filter, int *ndel, int flags)
@@ -352,6 +364,7 @@ pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size,
struct pfioc_table io;
if (tbl == NULL || size < 0 || (size && addr == NULL)) {
+ DBGPRINT("%s %p %d %p\n", __func__, tbl, size, addr);
errno = EINVAL;
return (-1);
}
diff --git a/sbin/pfctl/pfctl_table.c b/sbin/pfctl/pfctl_table.c
index 644312690..0d8c326a8 100644
--- a/sbin/pfctl/pfctl_table.c
+++ b/sbin/pfctl/pfctl_table.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_table.c,v 1.88 2024/05/09 08:35:40 florian Exp $ */
+/* $OpenBSD: pfctl_table.c,v 1.89 2024/07/14 19:51:08 sashan Exp $ */
/*
* Copyright (c) 2002 Cedric Berger
@@ -520,18 +520,48 @@ print_astats(struct pfr_astats *as, int dns)
int
pfctl_define_table(char *name, int flags, int addrs, const char *anchor,
- struct pfr_buffer *ab, u_int32_t ticket)
+ struct pfr_buffer *ab, u_int32_t ticket, struct pfr_uktable *ukt)
{
- struct pfr_table tbl;
+ struct pfr_table tbl_buf;
+ struct pfr_table *tbl;
- bzero(&tbl, sizeof(tbl));
- if (strlcpy(tbl.pfrt_name, name, sizeof(tbl.pfrt_name)) >=
- sizeof(tbl.pfrt_name) || strlcpy(tbl.pfrt_anchor, anchor,
- sizeof(tbl.pfrt_anchor)) >= sizeof(tbl.pfrt_anchor))
- errx(1, "pfctl_define_table: strlcpy");
- tbl.pfrt_flags = flags;
+ if (ukt == NULL) {
+ bzero(&tbl_buf, sizeof(tbl_buf));
+ tbl = &tbl_buf;
+ } else {
+ if (ab->pfrb_size != 0) {
+ /*
+ * copy IP addresses which come with table from
+ * temporal buffer to buffer attached to table.
+ */
+ ukt->pfrukt_addrs = *ab;
+ ab->pfrb_size = 0;
+ ab->pfrb_msize = 0;
+ ab->pfrb_caddr = NULL;
+ } else
+ memset(&ukt->pfrukt_addrs, 0,
+ sizeof(struct pfr_buffer));
- return pfr_ina_define(&tbl, ab->pfrb_caddr, ab->pfrb_size, NULL,
+ tbl = &ukt->pfrukt_t;
+ }
+
+ if (strlcpy(tbl->pfrt_name, name, sizeof(tbl->pfrt_name)) >=
+ sizeof(tbl->pfrt_name) || strlcpy(tbl->pfrt_anchor, anchor,
+ sizeof(tbl->pfrt_anchor)) >= sizeof(tbl->pfrt_anchor))
+ errx(1, "%s: strlcpy", __func__);
+ tbl->pfrt_flags = flags;
+ DBGPRINT("%s %s@%s [%x]\n", __func__, tbl->pfrt_name,
+ tbl->pfrt_anchor, tbl->pfrt_flags);
+
+ /*
+ * non-root anchors processed by parse.y are loaded to kernel later.
+ * Here we load tables, which are either created for root anchor
+ * or by 'pfctl -t ... -T ...' command.
+ */
+ if (ukt != NULL)
+ return (0);
+
+ return pfr_ina_define(tbl, ab->pfrb_caddr, ab->pfrb_size, NULL,
NULL, ticket, addrs ? PFR_FLAG_ADDRSTOO : 0);
}
diff --git a/sbin/slaacd/log.c b/sbin/slaacd/log.c
index 3c75d4119..2334af810 100644
--- a/sbin/slaacd/log.c
+++ b/sbin/slaacd/log.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: log.c,v 1.2 2021/03/20 16:46:03 kn Exp $ */
+/* $OpenBSD: log.c,v 1.3 2024/07/14 08:57:32 florian Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer
@@ -15,7 +15,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#ifndef SMALL
+
#include
#include
#include
@@ -197,4 +197,3 @@ fatalx(const char *emsg, ...)
va_end(ap);
exit(1);
}
-#endif /* SMALL */
diff --git a/sbin/slaacd/log.h b/sbin/slaacd/log.h
index 8e1d7a7f8..7ee991a9e 100644
--- a/sbin/slaacd/log.h
+++ b/sbin/slaacd/log.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: log.h,v 1.3 2021/12/13 18:28:40 deraadt Exp $ */
+/* $OpenBSD: log.h,v 1.5 2024/07/14 08:41:54 florian Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer
@@ -20,6 +20,7 @@
#define LOG_H
#include
+#include
#ifndef SMALL
void log_init(int, int);
@@ -43,15 +44,16 @@ __dead void fatal(const char *, ...)
__dead void fatalx(const char *, ...)
__attribute__((__format__ (printf, 1, 2)));
#else
-#define log_init(x...) do {} while(0)
-#define log_procinit(x...) do {} while(0)
-#define log_setverbose(x...) do {} while(0)
-#define log_warn(x...) do {} while(0)
-#define log_warnx(x...) do {} while(0)
-#define log_info(x...) do {} while(0)
-#define log_debug(x...) do {} while(0)
-#define logit(x...) do {} while(0)
-#define vlog(x...) do {} while(0)
+#define log_init(x...) do {} while (0)
+#define log_procinit(x...) do {} while (0)
+#define log_setverbose(x...) do {} while (0)
+#define log_getverbose() (0)
+#define log_warn(x...) do {} while (0)
+#define log_warnx(x...) do {} while (0)
+#define log_info(x...) do {} while (0)
+#define log_debug(x...) do {} while (0)
+#define logit(x...) do {} while (0)
+#define vlog(x...) do {} while (0)
#define fatal(x...) exit(1)
#define fatalx(x...) exit(1)
#endif /* SMALL */
diff --git a/sys/arch/amd64/amd64/vmm_machdep.c b/sys/arch/amd64/amd64/vmm_machdep.c
index f150569d9..18ef8b757 100644
--- a/sys/arch/amd64/amd64/vmm_machdep.c
+++ b/sys/arch/amd64/amd64/vmm_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmm_machdep.c,v 1.28 2024/06/26 01:40:49 jsg Exp $ */
+/* $OpenBSD: vmm_machdep.c,v 1.29 2024/07/14 07:57:42 dv Exp $ */
/*
* Copyright (c) 2014 Mike Larkin
*
@@ -126,7 +126,7 @@ int svm_fault_page(struct vcpu *, paddr_t);
int vmx_fault_page(struct vcpu *, paddr_t);
int vmx_handle_np_fault(struct vcpu *);
int svm_handle_np_fault(struct vcpu *);
-int vmx_mprotect_ept(vm_map_t, paddr_t, paddr_t, int);
+int vmx_mprotect_ept(struct vcpu *, vm_map_t, paddr_t, paddr_t, int);
pt_entry_t *vmx_pmap_find_pte_ept(pmap_t, paddr_t);
int vmm_alloc_vpid(uint16_t *);
void vmm_free_vpid(uint16_t);
@@ -777,7 +777,8 @@ vm_mprotect_ept(struct vm_mprotect_ept_params *vmep)
}
if (vmm_softc->mode == VMM_MODE_EPT)
- ret = vmx_mprotect_ept(vm->vm_map, sgpa, sgpa + size, prot);
+ ret = vmx_mprotect_ept(vcpu, vm->vm_map, sgpa, sgpa + size,
+ prot);
else if (vmm_softc->mode == VMM_MODE_RVI) {
pmap_write_protect(vm->vm_map->pmap, sgpa, sgpa + size, prot);
/* XXX requires a invlpga */
@@ -799,7 +800,8 @@ out_nolock:
* required.
*/
int
-vmx_mprotect_ept(vm_map_t vm_map, paddr_t sgpa, paddr_t egpa, int prot)
+vmx_mprotect_ept(struct vcpu *vcpu, vm_map_t vm_map, paddr_t sgpa, paddr_t egpa,
+ int prot)
{
struct vmx_invept_descriptor vid;
pmap_t pmap;
@@ -859,7 +861,7 @@ vmx_mprotect_ept(vm_map_t vm_map, paddr_t sgpa, paddr_t egpa, int prot)
vid.vid_eptp = pmap->eptp;
DPRINTF("%s: flushing EPT TLB for EPTP 0x%llx\n", __func__,
vid.vid_eptp);
- invept(IA32_VMX_INVEPT_SINGLE_CTX, &vid);
+ invept(vcpu->vc_vmx_invept_op, &vid);
}
KERNEL_UNLOCK();
@@ -2948,6 +2950,10 @@ vcpu_init_vmx(struct vcpu *vcpu)
ret = EINVAL;
goto exit;
}
+ if (msr & IA32_EPT_VPID_CAP_INVEPT_CONTEXT)
+ vcpu->vc_vmx_invept_op = IA32_VMX_INVEPT_SINGLE_CTX;
+ else
+ vcpu->vc_vmx_invept_op = IA32_VMX_INVEPT_GLOBAL_CTX;
if (msr & IA32_EPT_VPID_CAP_WB) {
/* WB cache type supported */
@@ -3896,6 +3902,7 @@ vcpu_run_vmx(struct vcpu *vcpu, struct vm_run_params *vrp)
struct schedstate_percpu *spc;
struct vmx_msr_store *msr_store;
struct vmx_invvpid_descriptor vid;
+ struct vmx_invept_descriptor vid_ept;
uint64_t cr0, eii, procbased, int_st;
u_long s;
@@ -3940,14 +3947,6 @@ vcpu_run_vmx(struct vcpu *vcpu, struct vm_run_params *vrp)
}
memset(&vcpu->vc_exit, 0, sizeof(vcpu->vc_exit));
- /* Host CR3 */
- cr3 = rcr3();
- if (vmwrite(VMCS_HOST_IA32_CR3, cr3)) {
- printf("%s: vmwrite(0x%04X, 0x%llx)\n", __func__,
- VMCS_HOST_IA32_CR3, cr3);
- return (EINVAL);
- }
-
/* Handle vmd(8) injected interrupts */
/* Is there an interrupt pending injection? */
if (vcpu->vc_inject.vie_type == VCPU_INJECT_INTR) {
@@ -4001,6 +4000,22 @@ vcpu_run_vmx(struct vcpu *vcpu, struct vm_run_params *vrp)
ci = curcpu();
vcpu->vc_last_pcpu = ci;
+ /* Invalidate EPT cache. */
+ vid_ept.vid_reserved = 0;
+ vid_ept.vid_eptp = vcpu->vc_parent->vm_map->pmap->eptp;
+ if (invept(vcpu->vc_vmx_invept_op, &vid_ept)) {
+ printf("%s: invept\n", __func__);
+ return (EINVAL);
+ }
+
+ /* Host CR3 */
+ cr3 = rcr3();
+ if (vmwrite(VMCS_HOST_IA32_CR3, cr3)) {
+ printf("%s: vmwrite(0x%04X, 0x%llx)\n", __func__,
+ VMCS_HOST_IA32_CR3, cr3);
+ return (EINVAL);
+ }
+
setregion(&gdt, ci->ci_gdt, GDT_SIZE - 1);
if (gdt.rd_base == 0) {
printf("%s: setregion\n", __func__);
diff --git a/sys/arch/amd64/include/elf.h b/sys/arch/amd64/include/elf.h
new file mode 100644
index 000000000..1bd15efd8
--- /dev/null
+++ b/sys/arch/amd64/include/elf.h
@@ -0,0 +1,7 @@
+/* $OpenBSD: elf.h,v 1.1 2024/07/14 09:48:48 jca Exp $ */
+
+/*
+ * This file is in the public domain.
+ */
+
+/* Nothing for now */
diff --git a/sys/arch/amd64/include/specialreg.h b/sys/arch/amd64/include/specialreg.h
index 341b1df23..7d1a0804a 100644
--- a/sys/arch/amd64/include/specialreg.h
+++ b/sys/arch/amd64/include/specialreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: specialreg.h,v 1.113 2024/06/24 21:22:14 bluhm Exp $ */
+/* $OpenBSD: specialreg.h,v 1.114 2024/07/14 07:57:42 dv Exp $ */
/* $NetBSD: specialreg.h,v 1.1 2003/04/26 18:39:48 fvdl Exp $ */
/* $NetBSD: x86/specialreg.h,v 1.2 2003/04/25 21:54:30 fvdl Exp $ */
@@ -1117,6 +1117,8 @@
#define IA32_EPT_VPID_CAP_PAGE_WALK_4 (1ULL << 6)
#define IA32_EPT_VPID_CAP_WB (1ULL << 14)
#define IA32_EPT_VPID_CAP_AD_BITS (1ULL << 21)
+#define IA32_EPT_VPID_CAP_INVEPT_CONTEXT (1ULL << 25)
+#define IA32_EPT_VPID_CAP_INVEPT_ALL (1ULL << 26)
#define IA32_EPT_PAGING_CACHE_TYPE_UC 0x0
#define IA32_EPT_PAGING_CACHE_TYPE_WB 0x6
diff --git a/sys/arch/amd64/include/vmmvar.h b/sys/arch/amd64/include/vmmvar.h
index b67d3f0a7..3f35e5209 100644
--- a/sys/arch/amd64/include/vmmvar.h
+++ b/sys/arch/amd64/include/vmmvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmmvar.h,v 1.103 2024/07/10 09:27:32 dv Exp $ */
+/* $OpenBSD: vmmvar.h,v 1.104 2024/07/14 07:57:42 dv Exp $ */
/*
* Copyright (c) 2014 Mike Larkin
*
@@ -886,6 +886,7 @@ struct vcpu {
uint32_t vc_vmx_vmcs_state; /* [a] */
#define VMCS_CLEARED 0
#define VMCS_LAUNCHED 1
+ uint64_t vc_vmx_invept_op;
/* SVM only (all requiring [v]) */
vaddr_t vc_svm_hsa_va;
diff --git a/sys/arch/arm/include/elf.h b/sys/arch/arm/include/elf.h
new file mode 100644
index 000000000..248648e55
--- /dev/null
+++ b/sys/arch/arm/include/elf.h
@@ -0,0 +1,77 @@
+/* $OpenBSD: elf.h,v 1.1 2024/07/14 09:48:48 jca Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2001 David E. O'Brien
+ * Copyright (c) 1996-1997 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_ELF_H_
+#define _MACHINE_ELF_H_
+
+/*
+ * ELF definitions for the ARM architecture.
+ */
+
+#ifdef _KERNEL
+# define __HAVE_CPU_HWCAP
+# define __HAVE_CPU_HWCAP2
+extern unsigned long hwcap, hwcap2;
+#endif /* _KERNEL */
+
+/* Flags passed in AT_HWCAP. */
+#define HWCAP_SWP 0x00000001 /* Unsupported, never set. */
+#define HWCAP_HALF 0x00000002 /* Always set. */
+#define HWCAP_THUMB 0x00000004
+#define HWCAP_26BIT 0x00000008 /* Unsupported, never set. */
+#define HWCAP_FAST_MULT 0x00000010 /* Always set. */
+#define HWCAP_FPA 0x00000020 /* Unsupported, never set. */
+#define HWCAP_VFP 0x00000040
+#define HWCAP_EDSP 0x00000080 /* Always set for ARMv6+. */
+#define HWCAP_JAVA 0x00000100 /* Unsupported, never set. */
+#define HWCAP_IWMMXT 0x00000200 /* Unsupported, never set. */
+#define HWCAP_CRUNCH 0x00000400 /* Unsupported, never set. */
+#define HWCAP_THUMBEE 0x00000800
+#define HWCAP_NEON 0x00001000
+#define HWCAP_VFPv3 0x00002000
+#define HWCAP_VFPv3D16 0x00004000
+#define HWCAP_TLS 0x00008000 /* Always set for ARMv6+. */
+#define HWCAP_VFPv4 0x00010000
+#define HWCAP_IDIVA 0x00020000
+#define HWCAP_IDIVT 0x00040000
+#define HWCAP_VFPD32 0x00080000
+#define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT)
+#define HWCAP_LPAE 0x00100000
+#define HWCAP_EVTSTRM 0x00200000 /* Not implemented yet. */
+
+/* Flags passed in AT_HWCAP2. */
+#define HWCAP2_AES 0x00000001
+#define HWCAP2_PMULL 0x00000002
+#define HWCAP2_SHA1 0x00000004
+#define HWCAP2_SHA2 0x00000008
+#define HWCAP2_CRC32 0x00000010
+
+#endif /* !_MACHINE_ELF_H_ */
diff --git a/sys/arch/arm64/arm64/cpu.c b/sys/arch/arm64/arm64/cpu.c
index 7438390c0..04cfd3cb7 100644
--- a/sys/arch/arm64/arm64/cpu.c
+++ b/sys/arch/arm64/arm64/cpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.c,v 1.125 2024/07/11 12:07:39 kettenis Exp $ */
+/* $OpenBSD: cpu.c,v 1.126 2024/07/14 09:48:48 jca Exp $ */
/*
* Copyright (c) 2016 Dale Rahn
@@ -32,6 +32,7 @@
#include
#include
+#include
#include
#include
@@ -741,6 +742,10 @@ cpu_identify(struct cpu_info *ci)
printf("%sAtomic", sep);
sep = ",";
arm64_has_lse = 1;
+ /*
+ * XXX should be populated and sanitized like cpu_sysctl() does
+ */
+ hwcap |= HWCAP_ATOMICS;
}
if (ID_AA64ISAR0_CRC32(id) >= ID_AA64ISAR0_CRC32_BASE) {
diff --git a/sys/arch/arm64/include/elf.h b/sys/arch/arm64/include/elf.h
new file mode 100644
index 000000000..53be0b910
--- /dev/null
+++ b/sys/arch/arm64/include/elf.h
@@ -0,0 +1,121 @@
+/*-
+ * Copyright (c) 1996-1997 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_ELF_H_
+#define _MACHINE_ELF_H_
+
+/*
+ * ELF definitions for the AArch64 architecture.
+ */
+
+#ifdef _KERNEL
+# define __HAVE_CPU_HWCAP
+# define __HAVE_CPU_HWCAP2
+extern unsigned long hwcap, hwcap2;
+#endif /* _KERNEL */
+
+/* HWCAP */
+#define HWCAP_FP 0x00000001
+#define HWCAP_ASIMD 0x00000002
+#define HWCAP_EVTSTRM 0x00000004
+#define HWCAP_AES 0x00000008
+#define HWCAP_PMULL 0x00000010
+#define HWCAP_SHA1 0x00000020
+#define HWCAP_SHA2 0x00000040
+#define HWCAP_CRC32 0x00000080
+#define HWCAP_ATOMICS 0x00000100
+#define HWCAP_FPHP 0x00000200
+#define HWCAP_ASIMDHP 0x00000400
+#define HWCAP_CPUID 0x00000800
+#define HWCAP_ASIMDRDM 0x00001000
+#define HWCAP_JSCVT 0x00002000
+#define HWCAP_FCMA 0x00004000
+#define HWCAP_LRCPC 0x00008000
+#define HWCAP_DCPOP 0x00010000
+#define HWCAP_SHA3 0x00020000
+#define HWCAP_SM3 0x00040000
+#define HWCAP_SM4 0x00080000
+#define HWCAP_ASIMDDP 0x00100000
+#define HWCAP_SHA512 0x00200000
+#define HWCAP_SVE 0x00400000
+#define HWCAP_ASIMDFHM 0x00800000
+#define HWCAP_DIT 0x01000000
+#define HWCAP_USCAT 0x02000000
+#define HWCAP_ILRCPC 0x04000000
+#define HWCAP_FLAGM 0x08000000
+#define HWCAP_SSBS 0x10000000
+#define HWCAP_SB 0x20000000
+#define HWCAP_PACA 0x40000000
+#define HWCAP_PACG 0x80000000
+
+/* HWCAP2 */
+#define HWCAP2_DCPODP 0x0000000000000001ul
+#define HWCAP2_SVE2 0x0000000000000002ul
+#define HWCAP2_SVEAES 0x0000000000000004ul
+#define HWCAP2_SVEPMULL 0x0000000000000008ul
+#define HWCAP2_SVEBITPERM 0x0000000000000010ul
+#define HWCAP2_SVESHA3 0x0000000000000020ul
+#define HWCAP2_SVESM4 0x0000000000000040ul
+#define HWCAP2_FLAGM2 0x0000000000000080ul
+#define HWCAP2_FRINT 0x0000000000000100ul
+#define HWCAP2_SVEI8MM 0x0000000000000200ul
+#define HWCAP2_SVEF32MM 0x0000000000000400ul
+#define HWCAP2_SVEF64MM 0x0000000000000800ul
+#define HWCAP2_SVEBF16 0x0000000000001000ul
+#define HWCAP2_I8MM 0x0000000000002000ul
+#define HWCAP2_BF16 0x0000000000004000ul
+#define HWCAP2_DGH 0x0000000000008000ul
+#define HWCAP2_RNG 0x0000000000010000ul
+#define HWCAP2_BTI 0x0000000000020000ul
+#define HWCAP2_MTE 0x0000000000040000ul
+#define HWCAP2_ECV 0x0000000000080000ul
+#define HWCAP2_AFP 0x0000000000100000ul
+#define HWCAP2_RPRES 0x0000000000200000ul
+#define HWCAP2_MTE3 0x0000000000400000ul
+#define HWCAP2_SME 0x0000000000800000ul
+#define HWCAP2_SME_I16I64 0x0000000001000000ul
+#define HWCAP2_SME_F64F64 0x0000000002000000ul
+#define HWCAP2_SME_I8I32 0x0000000004000000ul
+#define HWCAP2_SME_F16F32 0x0000000008000000ul
+#define HWCAP2_SME_B16F32 0x0000000010000000ul
+#define HWCAP2_SME_F32F32 0x0000000020000000ul
+#define HWCAP2_SME_FA64 0x0000000040000000ul
+#define HWCAP2_WFXT 0x0000000080000000ul
+#define HWCAP2_EBF16 0x0000000100000000ul
+#define HWCAP2_SVE_EBF16 0x0000000200000000ul
+#define HWCAP2_CSSC 0x0000000400000000ul
+#define HWCAP2_RPRFM 0x0000000800000000ul
+#define HWCAP2_SVE2P1 0x0000001000000000ul
+#define HWCAP2_SME2 0x0000002000000000ul
+#define HWCAP2_SME2P1 0x0000004000000000ul
+#define HWCAP2_SME_I16I32 0x0000008000000000ul
+#define HWCAP2_SME_BI32I32 0x0000010000000000ul
+#define HWCAP2_SME_B16B16 0x0000020000000000ul
+#define HWCAP2_SME_F16F16 0x0000040000000000ul
+#define HWCAP2_MOPS 0x0000080000000000ul
+#define HWCAP2_HBC 0x0000100000000000ul
+
+#endif /* !_MACHINE_ELF_H_ */
diff --git a/sys/arch/armv7/include/elf.h b/sys/arch/armv7/include/elf.h
new file mode 100644
index 000000000..3b40e30ab
--- /dev/null
+++ b/sys/arch/armv7/include/elf.h
@@ -0,0 +1,3 @@
+/* $OpenBSD: elf.h,v 1.1 2024/07/14 19:33:59 miod Exp $ */
+
+#include
diff --git a/sys/arch/i386/include/elf.h b/sys/arch/i386/include/elf.h
new file mode 100644
index 000000000..1bd15efd8
--- /dev/null
+++ b/sys/arch/i386/include/elf.h
@@ -0,0 +1,7 @@
+/* $OpenBSD: elf.h,v 1.1 2024/07/14 09:48:48 jca Exp $ */
+
+/*
+ * This file is in the public domain.
+ */
+
+/* Nothing for now */
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c
index 82098deeb..20aa4b9c2 100644
--- a/sys/dev/acpi/acpi.c
+++ b/sys/dev/acpi/acpi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi.c,v 1.433 2024/07/02 08:27:04 kettenis Exp $ */
+/* $OpenBSD: acpi.c,v 1.435 2024/07/14 13:58:57 jmatthew Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert
* Copyright (c) 2005 Jordan Hargrave
@@ -65,6 +65,7 @@ void acpi_pci_set_powerstate(pci_chipset_tag_t, pcitag_t, int, int);
int acpi_pci_notify(struct aml_node *, int, void *);
int acpi_submatch(struct device *, void *, void *);
+int acpi_noprint(void *, const char *);
int acpi_print(void *, const char *);
void acpi_map_pmregs(struct acpi_softc *);
@@ -756,9 +757,10 @@ acpi_pci_min_powerstate(pci_chipset_tag_t pc, pcitag_t tag)
void
acpi_pci_set_powerstate(pci_chipset_tag_t pc, pcitag_t tag, int state, int pre)
{
-#if NACPIPWRRES > 0
struct acpi_softc *sc = acpi_softc;
+#if NACPIPWRRES > 0
struct acpi_pwrres *pr;
+#endif
struct acpi_pci *pdev;
int bus, dev, fun;
char name[5];
@@ -769,10 +771,15 @@ acpi_pci_set_powerstate(pci_chipset_tag_t pc, pcitag_t tag, int state, int pre)
break;
}
- /* XXX Add a check to discard nodes without Power Resources? */
if (pdev == NULL)
return;
+ if (state != ACPI_STATE_D0 && !pre) {
+ snprintf(name, sizeof(name), "_PS%d", state);
+ aml_evalname(sc, pdev->node, name, 0, NULL, NULL);
+ }
+
+#if NACPIPWRRES > 0
SIMPLEQ_FOREACH(pr, &sc->sc_pwrresdevs, p_next) {
if (pr->p_node != pdev->node)
continue;
@@ -811,6 +818,9 @@ acpi_pci_set_powerstate(pci_chipset_tag_t pc, pcitag_t tag, int state, int pre)
}
#endif /* NACPIPWRRES > 0 */
+
+ if (state == ACPI_STATE_D0 && pre)
+ aml_evalname(sc, pdev->node, "_PS0", 0, NULL, NULL);
}
int
@@ -1307,6 +1317,12 @@ acpi_submatch(struct device *parent, void *match, void *aux)
return ((*cf->cf_attach->ca_match)(parent, match, aux));
}
+int
+acpi_noprint(void *aux, const char *pnp)
+{
+ return (QUIET);
+}
+
int
acpi_print(void *aux, const char *pnp)
{
@@ -3001,6 +3017,12 @@ const char *acpi_isa_hids[] = {
NULL
};
+/* Overly abundant devices to avoid printing details for */
+const char *acpi_quiet_hids[] = {
+ "ACPI0007",
+ NULL
+};
+
void
acpi_attach_deps(struct acpi_softc *sc, struct aml_node *node)
{
@@ -3220,7 +3242,10 @@ acpi_foundhid(struct aml_node *node, void *arg)
if (!node->parent->attached) {
node->parent->attached = 1;
- config_found(self, &aaa, acpi_print);
+ if (acpi_matchhids(&aaa, acpi_quiet_hids, "none"))
+ config_found(self, &aaa, acpi_noprint);
+ else
+ config_found(self, &aaa, acpi_print);
}
return (0);
diff --git a/sys/dev/acpi/acpicpu.c b/sys/dev/acpi/acpicpu.c
index 6a126fadd..f46ff68a8 100644
--- a/sys/dev/acpi/acpicpu.c
+++ b/sys/dev/acpi/acpicpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpicpu.c,v 1.93 2024/06/07 16:53:35 kettenis Exp $ */
+/* $OpenBSD: acpicpu.c,v 1.94 2024/07/14 14:04:16 jmatthew Exp $ */
/*
* Copyright (c) 2005 Marco Peereboom
* Copyright (c) 2015 Philip Guenther
@@ -654,6 +654,9 @@ acpicpu_match(struct device *parent, void *match, void *aux)
struct acpi_attach_args *aa = aux;
struct cfdata *cf = match;
struct acpi_softc *acpi = (struct acpi_softc *)parent;
+ CPU_INFO_ITERATOR cii;
+ struct cpu_info *ci;
+ int64_t uid;
if (acpi_matchhids(aa, acpicpu_hids, cf->cf_driver->cd_name) &&
aa->aaa_node && aa->aaa_node->value &&
@@ -663,7 +666,15 @@ acpicpu_match(struct device *parent, void *match, void *aux)
* so we won't attach any Processor() nodes.
*/
acpi->sc_skip_processor = 1;
- return (1);
+
+ /* Only match if we can find a CPU with the right ID */
+ if (aml_evalinteger(acpi, aa->aaa_node, "_UID", 0,
+ NULL, &uid) == 0)
+ CPU_INFO_FOREACH(cii, ci)
+ if (ci->ci_acpi_proc_id == uid)
+ return (1);
+
+ return (0);
}
/* sanity */
diff --git a/sys/dev/acpi/acpipwrres.c b/sys/dev/acpi/acpipwrres.c
index 27d7965df..05e1a09d1 100644
--- a/sys/dev/acpi/acpipwrres.c
+++ b/sys/dev/acpi/acpipwrres.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpipwrres.c,v 1.13 2023/02/18 14:32:02 dv Exp $ */
+/* $OpenBSD: acpipwrres.c,v 1.14 2024/07/14 10:48:55 kettenis Exp $ */
/*
* Copyright (c) 2013 Martin Pieuchot
@@ -33,6 +33,7 @@
int acpipwrres_match(struct device *, void *, void *);
void acpipwrres_attach(struct device *, struct device *, void *);
+int acpipwrres_activate(struct device *, int);
#ifdef ACPIPWRRES_DEBUG
#define DPRINTF(x) printf x
@@ -66,7 +67,8 @@ struct acpipwrres_consumer {
};
const struct cfattach acpipwrres_ca = {
- sizeof(struct acpipwrres_softc), acpipwrres_match, acpipwrres_attach
+ sizeof(struct acpipwrres_softc), acpipwrres_match, acpipwrres_attach,
+ NULL, acpipwrres_activate
};
struct cfdriver acpipwrres_cd = {
@@ -140,6 +142,23 @@ acpipwrres_attach(struct device *parent, struct device *self, void *aux)
printf("\n");
}
+int
+acpipwrres_activate(struct device *self, int act)
+{
+ struct acpipwrres_softc *sc = (struct acpipwrres_softc *)self;
+
+ switch (act) {
+ case DVACT_SUSPEND:
+ if (sc->sc_cons_ref == 0 && sc->sc_state != ACPIPWRRES_OFF) {
+ aml_evalname(sc->sc_acpi, sc->sc_devnode, "_OFF", 0,
+ NULL, NULL);
+ sc->sc_state = ACPIPWRRES_OFF;
+ }
+ break;
+ }
+ return 0;
+}
+
int
acpipwrres_ref_incr(struct acpipwrres_softc *sc, struct aml_node *node)
{
@@ -149,9 +168,11 @@ acpipwrres_ref_incr(struct acpipwrres_softc *sc, struct aml_node *node)
DPRINTF(("%s: dev %s ON %d\n", DEVNAME(sc), node->name,
sc->sc_cons_ref));
- if (sc->sc_cons_ref++ == 0)
+ if (sc->sc_cons_ref++ == 0) {
aml_evalname(sc->sc_acpi, sc->sc_devnode, "_ON", 0,
NULL, NULL);
+ sc->sc_state = ACPIPWRRES_ON;
+ }
return (0);
}
@@ -165,9 +186,11 @@ acpipwrres_ref_decr(struct acpipwrres_softc *sc, struct aml_node *node)
DPRINTF(("%s: dev %s OFF %d\n", DEVNAME(sc), node->name,
sc->sc_cons_ref));
- if (--sc->sc_cons_ref == 0)
+ if (--sc->sc_cons_ref == 0) {
aml_evalname(sc->sc_acpi, sc->sc_devnode, "_OFF", 0,
NULL, NULL);
+ sc->sc_state = ACPIPWRRES_OFF;
+ }
return (0);
}
diff --git a/sys/dev/acpi/qcgpio.c b/sys/dev/acpi/qcgpio.c
index c9ce00cd5..bf2a6af57 100644
--- a/sys/dev/acpi/qcgpio.c
+++ b/sys/dev/acpi/qcgpio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: qcgpio.c,v 1.10 2024/07/04 18:35:36 patrick Exp $ */
+/* $OpenBSD: qcgpio.c,v 1.11 2024/07/15 15:33:54 mglocker Exp $ */
/*
* Copyright (c) 2022 Mark Kettenis
*
@@ -237,6 +237,8 @@ qcgpio_x1e80100_pin_map(int pin, bus_size_t *off)
return pin;
case 0x180:
return 67;
+ case 0x380:
+ return 33;
case 0x3c0:
return 3;
default:
diff --git a/sys/dev/fdt/dwmshc.c b/sys/dev/fdt/dwmshc.c
index 4497dc4a3..edd274bfe 100644
--- a/sys/dev/fdt/dwmshc.c
+++ b/sys/dev/fdt/dwmshc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dwmshc.c,v 1.7 2024/05/26 22:04:52 kettenis Exp $ */
+/* $OpenBSD: dwmshc.c,v 1.8 2024/07/15 09:56:30 patrick Exp $ */
/*
* Copyright (c) 2023 David Gwynne
@@ -101,6 +101,8 @@
#define EMMC_DLL_TXCLK 0x808
#define EMMC_DLL_TXCLK_TX_TAP_NUM_SHIFT 0
#define EMMC_DLL_TXCLK_TX_TAP_NUM_MASK 0x1f
+#define EMMC_DLL_TXCLK_TX_TAP_NUM_90_DEG 0x8
+#define EMMC_DLL_TXCLK_TX_TAP_NUM_DEFAULT 0x10
#define EMMC_DLL_TXCLK_TX_TAP_VALUE_SHIFT 8
#define EMMC_DLL_TXCLK_TX_TAP_VALUE_MASK 0xff
#define EMMC_DLL_TXCLK_TX_DELAY_SHIFT 16
@@ -112,7 +114,7 @@
#define EMMC_DLL_STRBIN 0x80c
#define EMMC_DLL_STRBIN_TAP_NUM_SHIFT 0
#define EMMC_DLL_STRBIN_TAP_NUM_MASK 0x1f
-#define EMMC_DLL_STRBIN_TAP_NUM_DEFAULT 0x8
+#define EMMC_DLL_STRBIN_TAP_NUM_90_DEG 0x8
#define EMMC_DLL_STRBIN_TAP_VALUE_SHIFT 8
#define EMMC_DLL_STRBIN_TAP_VALUE_MASK 0xff
#define EMMC_DLL_STRBIN_DELAY_NUM_SHIFT 16
@@ -122,6 +124,20 @@
#define EMMC_DLL_STRBIN_TAP_VALUE_SEL (1U << 25)
#define EMMC_DLL_STRBIN_DELAY_NUM_SEL (1U << 26)
#define EMMC_DLL_STRBIN_DELAY_ENA (1U << 27)
+#define EMMC_DLL_CMDOUT 0x810
+#define EMMC_DLL_CMDOUT_TAP_NUM_SHIFT 0
+#define EMMC_DLL_CMDOUT_TAP_NUM_MASK 0x1f
+#define EMMC_DLL_CMDOUT_TAP_NUM_90_DEG 0x8
+#define EMMC_DLL_CMDOUT_TAP_VALUE_SHIFT 8
+#define EMMC_DLL_CMDOUT_TAP_VALUE_MASK 0xff
+#define EMMC_DLL_CMDOUT_DELAY_NUM_SHIFT 16
+#define EMMC_DLL_CMDOUT_DELAY_NUM_MASK 0xff
+#define EMMC_DLL_CMDOUT_TAP_NUM_SEL (1U << 24)
+#define EMMC_DLL_CMDOUT_TAP_VALUE_SEL (1U << 25)
+#define EMMC_DLL_CMDOUT_DELAY_NUM_SEL (1U << 26)
+#define EMMC_DLL_CMDOUT_DELAY_ENA (1U << 27)
+#define EMMC_DLL_CMDOUT_SRC_SEL (1U << 28)
+#define EMMC_DLL_CMDOUT_EN_SRC_SEL (1U << 29)
#define EMMC_DLL_STATUS0 0x840
#define EMMC_DLL_STATUS0_DLL_LOCK_VALUE_SHIFT 0
#define EMMC_DLL_STATUS0_DLL_LOCK_VALUE_MASK 0xff
@@ -182,7 +198,8 @@ dwmshc_match(struct device *parent, void *match, void *aux)
{
struct fdt_attach_args *faa = aux;
- return (OF_is_compatible(faa->fa_node, "rockchip,rk3568-dwcmshc"));
+ return (OF_is_compatible(faa->fa_node, "rockchip,rk3568-dwcmshc") ||
+ OF_is_compatible(faa->fa_node, "rockchip,rk3588-dwcmshc"));
}
static void
dwmshc_attach(struct device *parent, struct device *self, void *aux)
@@ -303,7 +320,7 @@ static void
dwmshc_clock_post(struct sdhc_softc *sdhc, int freq, int timing)
{
struct dwmshc_softc *sc = (struct dwmshc_softc *)sdhc;
- uint32_t txclk_tapnum = EMMC_DLL_STRBIN_DELAY_NUM_DEFAULT;
+ uint32_t txclk_tapnum = EMMC_DLL_TXCLK_TX_TAP_NUM_DEFAULT;
clock_set_frequency(sc->sc_node, 0, freq * 1000);
@@ -324,8 +341,11 @@ dwmshc_clock_post(struct sdhc_softc *sdhc, int freq, int timing)
delay(1);
dwmshc_wr4(sc, EMMC_DLL_CTRL, 0);
- dwmshc_wr4(sc, EMMC_DLL_RXCLK, EMMC_DLL_RXCLK_RX_CLK_OUT_SEL |
- /* rk3568 */ EMMC_DLL_RXCLK_RX_CLK_SRC_SEL);
+ if (OF_is_compatible(sc->sc_node, "rockchip,rk3568-dwcmshc"))
+ dwmshc_wr4(sc, EMMC_DLL_RXCLK, EMMC_DLL_RXCLK_RX_CLK_OUT_SEL |
+ EMMC_DLL_RXCLK_RX_CLK_SRC_SEL);
+ else
+ dwmshc_wr4(sc, EMMC_DLL_RXCLK, EMMC_DLL_RXCLK_RX_CLK_OUT_SEL);
dwmshc_wr4(sc, EMMC_DLL_CTRL, EMMC_DLL_CTRL_DLL_START |
0x5 << EMMC_DLL_CTRL_DLL_START_POINT_SHIFT |
0x2 << EMMC_DLL_CTRL_DLL_INCREMENT_SHIFT);
@@ -341,7 +361,18 @@ dwmshc_clock_post(struct sdhc_softc *sdhc, int freq, int timing)
txclk_tapnum = OF_getpropint(sc->sc_node,
"rockchip,txclk-tapnum", txclk_tapnum);
- /* XXX rk3588 hs400 */
+#ifdef notyet
+ if (OF_is_compatible(sc->sc_node, "rockchip,rk3588-dwcmshc") &&
+ timing == SDMMC_TIMING_MMC_HS400) {
+ txclk_tapnum = EMMC_DLL_TXCLK_TX_TAP_NUM_90_DEG;
+ dwmshc_wr4(sc, EMMC_DLL_CMDOUT,
+ EMMC_DLL_CMDOUT_TAP_NUM_90_DEG |
+ EMMC_DLL_CMDOUT_TAP_NUM_SEL |
+ EMMC_DLL_CMDOUT_DELAY_ENA |
+ EMMC_DLL_CMDOUT_SRC_SEL |
+ EMMC_DLL_CMDOUT_EN_SRC_SEL);
+ }
+#endif
}
dwmshc_wr4(sc, EMMC_DLL_TXCLK, EMMC_DLL_TXCLK_TX_CLK_OUT_SEL |
@@ -349,7 +380,7 @@ dwmshc_clock_post(struct sdhc_softc *sdhc, int freq, int timing)
txclk_tapnum << EMMC_DLL_TXCLK_TX_TAP_NUM_SHIFT);
dwmshc_wr4(sc, EMMC_DLL_STRBIN, EMMC_DLL_STRBIN_DELAY_ENA |
EMMC_DLL_STRBIN_TAP_NUM_SEL |
- (EMMC_DLL_STRBIN_TAP_NUM_DEFAULT <<
+ (EMMC_DLL_STRBIN_TAP_NUM_90_DEG <<
EMMC_DLL_STRBIN_TAP_NUM_SHIFT));
}
diff --git a/sys/dev/fdt/rkclock.c b/sys/dev/fdt/rkclock.c
index 65846ba61..86c829d47 100644
--- a/sys/dev/fdt/rkclock.c
+++ b/sys/dev/fdt/rkclock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rkclock.c,v 1.89 2024/06/11 09:15:33 kettenis Exp $ */
+/* $OpenBSD: rkclock.c,v 1.90 2024/07/15 09:54:38 patrick Exp $ */
/*
* Copyright (c) 2017, 2018 Mark Kettenis
*
@@ -4217,6 +4217,20 @@ const struct rkclock rk3588_clocks[] = {
{ RK3588_CLK_GPU_SRC },
SET_PARENT
},
+ {
+ RK3588_CCLK_EMMC, RK3588_CRU_CLKSEL_CON(77),
+ SEL(15, 14), DIV(13, 8),
+ { RK3588_PLL_GPLL, RK3588_PLL_CPLL, RK3588_XIN24M }
+ },
+ {
+ RK3588_BCLK_EMMC, RK3588_CRU_CLKSEL_CON(78),
+ SEL(5, 5), DIV(4, 0),
+ { RK3588_PLL_GPLL, RK3588_PLL_CPLL }
+ },
+ {
+ RK3588_TMCLK_EMMC, 0, 0, 0,
+ { RK3588_XIN24M }
+ },
{
RK3588_CLK_GMAC_125M, RK3588_CRU_CLKSEL_CON(83),
SEL(15, 15), DIV(14, 8),
@@ -4567,6 +4581,26 @@ rk3588_reset(void *cookie, uint32_t *cells, int on)
reg = RK3588_CRU_SOFTRST_CON(12);
bit = 1;
break;
+ case RK3588_SRST_H_EMMC:
+ reg = RK3588_CRU_SOFTRST_CON(31);
+ bit = 4;
+ break;
+ case RK3588_SRST_A_EMMC:
+ reg = RK3588_CRU_SOFTRST_CON(31);
+ bit = 5;
+ break;
+ case RK3588_SRST_C_EMMC:
+ reg = RK3588_CRU_SOFTRST_CON(31);
+ bit = 6;
+ break;
+ case RK3588_SRST_B_EMMC:
+ reg = RK3588_CRU_SOFTRST_CON(31);
+ bit = 7;
+ break;
+ case RK3588_SRST_T_EMMC:
+ reg = RK3588_CRU_SOFTRST_CON(31);
+ bit = 8;
+ break;
case RK3588_SRST_A_GMAC0:
reg = RK3588_CRU_SOFTRST_CON(32);
bit = 10;
diff --git a/sys/dev/fdt/rkclock_clocks.h b/sys/dev/fdt/rkclock_clocks.h
index c7707355c..927b105ad 100644
--- a/sys/dev/fdt/rkclock_clocks.h
+++ b/sys/dev/fdt/rkclock_clocks.h
@@ -480,6 +480,11 @@
#define RK3588_ACLK_LOW_TOP_ROOT 258
#define RK3588_CLK_GPU_SRC 261
#define RK3588_CLK_GPU 262
+#define RK3588_HCLK_EMMC 298
+#define RK3588_ACLK_EMMC 299
+#define RK3588_CCLK_EMMC 300
+#define RK3588_BCLK_EMMC 301
+#define RK3588_TMCLK_EMMC 302
#define RK3588_CLK_GMAC_125M 310
#define RK3588_CCLK_SRC_SDIO 395
#define RK3588_ACLK_VOP_ROOT 600
@@ -513,6 +518,11 @@
#define RK3588_SRST_P_TSADC 86
#define RK3588_SRST_TSADC 87
+#define RK3588_SRST_H_EMMC 278
+#define RK3588_SRST_A_EMMC 279
+#define RK3588_SRST_C_EMMC 280
+#define RK3588_SRST_B_EMMC 281
+#define RK3588_SRST_T_EMMC 282
#define RK3588_SRST_A_GMAC0 291
#define RK3588_SRST_A_GMAC1 292
#define RK3588_SRST_PCIE0_POWER_UP 294
diff --git a/sys/dev/pci/ichiic.c b/sys/dev/pci/ichiic.c
index 30ffe226b..97a96f3f5 100644
--- a/sys/dev/pci/ichiic.c
+++ b/sys/dev/pci/ichiic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ichiic.c,v 1.55 2024/05/24 06:02:53 jsg Exp $ */
+/* $OpenBSD: ichiic.c,v 1.56 2024/07/16 01:14:23 jsg Exp $ */
/*
* Copyright (c) 2005, 2006 Alexander Yurchenko
@@ -108,6 +108,7 @@ const struct pci_matchid ichiic_ids[] = {
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82801JI_SMB },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_APOLLOLAKE_SMB },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_ATOMC2000_PCU_SMB },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_C3000_SMB_2 },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_BAYTRAIL_SMB },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_BRASWELL_SMB },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_C600_SMB },
diff --git a/sys/kern/exec_elf.c b/sys/kern/exec_elf.c
index 042c71af0..c6a092d91 100644
--- a/sys/kern/exec_elf.c
+++ b/sys/kern/exec_elf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: exec_elf.c,v 1.186 2024/04/02 08:39:16 deraadt Exp $ */
+/* $OpenBSD: exec_elf.c,v 1.188 2024/07/14 11:36:54 jca Exp $ */
/*
* Copyright (c) 1996 Per Fogelstrom
@@ -89,6 +89,7 @@
#include
#include
+#include
int elf_load_file(struct proc *, char *, struct exec_package *,
struct elf_args *);
@@ -923,6 +924,14 @@ bad:
return (error);
}
+#ifdef __HAVE_CPU_HWCAP
+unsigned long hwcap;
+#endif /* __HAVE_CPU_HWCAP */
+
+#ifdef __HAVE_CPU_HWCAP2
+unsigned long hwcap2;
+#endif /* __HAVE_CPU_HWCAP2 */
+
/*
* Phase II of load. It is now safe to load the interpreter. Info collected
* when loading the program is available for setup of the interpreter.
@@ -995,6 +1004,18 @@ exec_elf_fixup(struct proc *p, struct exec_package *epp)
a->au_v = ap->arg_entry;
a++;
+#ifdef __HAVE_CPU_HWCAP
+ a->au_id = AUX_hwcap;
+ a->au_v = hwcap;
+ a++;
+#endif /* __HAVE_CPU_HWCAP */
+
+#ifdef __HAVE_CPU_HWCAP2
+ a->au_id = AUX_hwcap2;
+ a->au_v = hwcap2;
+ a++;
+#endif /* __HAVE_CPU_HWCAP2 */
+
a->au_id = AUX_openbsd_timekeep;
a->au_v = p->p_p->ps_timekeep;
a++;
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index a2dfc0105..a17ac58ea 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_socket.c,v 1.337 2024/07/12 17:20:18 mvs Exp $ */
+/* $OpenBSD: uipc_socket.c,v 1.338 2024/07/14 15:42:23 bluhm Exp $ */
/* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */
/*
@@ -1690,7 +1690,7 @@ somove(struct socket *so, int wait)
* Move only a partial mbuf at maximum splice length or
* if the drain buffer is too small for this large mbuf.
*/
- if (!maxreached && so->so_snd.sb_datacc > 0) {
+ if (!maxreached && sosp->so_snd.sb_datacc > 0) {
len -= size;
break;
}
diff --git a/sys/net/if.c b/sys/net/if.c
index 310048b85..75247d5ac 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.719 2024/06/20 19:25:42 bluhm Exp $ */
+/* $OpenBSD: if.c,v 1.720 2024/07/14 18:53:39 bluhm Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -3353,6 +3353,7 @@ ifnewlladdr(struct ifnet *ifp)
{
#ifdef INET6
struct ifaddr *ifa;
+ int i_am_router = (atomic_load_int(&ip6_forwarding) != 0);
#endif
struct ifreq ifrq;
short up;
@@ -3378,7 +3379,7 @@ ifnewlladdr(struct ifnet *ifp)
* Update the link-local address. Don't do it if we're
* a router to avoid confusing hosts on the network.
*/
- if (ip6_forwarding == 0) {
+ if (!i_am_router) {
ifa = &in6ifa_ifpforlinklocal(ifp, 0)->ia_ifa;
if (ifa) {
in6_purgeaddr(ifa);
diff --git a/sys/net/pf.c b/sys/net/pf.c
index fb278db3b..378bafc21 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.1202 2024/07/12 09:25:27 bluhm Exp $ */
+/* $OpenBSD: pf.c,v 1.1203 2024/07/14 18:53:39 bluhm Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -7988,7 +7988,7 @@ done:
if (pd.dir == PF_IN) {
int flags = IPV6_REDIRECT;
- switch (ip6_forwarding) {
+ switch (atomic_load_int(&ip6_forwarding)) {
case 2:
SET(flags, IPV6_FORWARDING_IPSEC);
/* FALLTHROUGH */
diff --git a/sys/net/pf_norm.c b/sys/net/pf_norm.c
index 4178fe785..2bfad7873 100644
--- a/sys/net/pf_norm.c
+++ b/sys/net/pf_norm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_norm.c,v 1.232 2024/07/04 12:50:08 bluhm Exp $ */
+/* $OpenBSD: pf_norm.c,v 1.233 2024/07/14 18:53:39 bluhm Exp $ */
/*
* Copyright 2001 Niels Provos
@@ -1013,7 +1013,7 @@ pf_refragment6(struct mbuf **m0, struct m_tag *mtag, struct sockaddr_in6 *dst,
if (ifp == NULL) {
int flags = 0;
- switch (ip6_forwarding) {
+ switch (atomic_load_int(&ip6_forwarding)) {
case 2:
SET(flags, IPV6_FORWARDING_IPSEC);
/* FALLTHROUGH */
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index c6e882f0b..26139316c 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_carp.c,v 1.362 2024/06/20 19:25:42 bluhm Exp $ */
+/* $OpenBSD: ip_carp.c,v 1.363 2024/07/14 18:53:39 bluhm Exp $ */
/*
* Copyright (c) 2002 Michael Shalayeff. All rights reserved.
@@ -1287,9 +1287,10 @@ carp_send_na(struct carp_softc *sc)
struct ifaddr *ifa;
struct in6_addr *in6;
static struct in6_addr mcast = IN6ADDR_LINKLOCAL_ALLNODES_INIT;
+ int i_am_router = (atomic_load_int(&ip6_forwarding) != 0);
int flags = ND_NA_FLAG_OVERRIDE;
- if (ip6_forwarding != 0)
+ if (i_am_router)
flags |= ND_NA_FLAG_ROUTER;
TAILQ_FOREACH(ifa, &sc->sc_if.if_addrlist, ifa_list) {
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index baaa9a210..5c5ccde13 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_icmp.c,v 1.195 2024/07/12 09:25:27 bluhm Exp $ */
+/* $OpenBSD: ip_icmp.c,v 1.196 2024/07/14 18:53:39 bluhm Exp $ */
/* $NetBSD: ip_icmp.c,v 1.19 1996/02/13 23:42:22 christos Exp $ */
/*
@@ -588,9 +588,9 @@ reflect:
struct sockaddr_in sgw;
struct sockaddr_in ssrc;
struct rtentry *newrt = NULL;
+ int i_am_router = (atomic_load_int(&ip_forwarding) != 0);
- if (icmp_rediraccept == 0 ||
- atomic_load_int(&ip_forwarding) != 0)
+ if (icmp_rediraccept == 0 || i_am_router)
goto freeit;
if (code > 3)
goto badcode;
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 8797a26b0..1d68e0f61 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_input.c,v 1.398 2024/07/12 09:25:27 bluhm Exp $ */
+/* $OpenBSD: ip_input.c,v 1.399 2024/07/14 18:53:39 bluhm Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
@@ -111,6 +111,10 @@ LIST_HEAD(, ipq) ipq;
int ip_maxqueue = 300;
int ip_frags = 0;
+const struct sysctl_bounded_args ipctl_vars_unlocked[] = {
+ { IPCTL_FORWARDING, &ip_forwarding, 0, 2 },
+};
+
const struct sysctl_bounded_args ipctl_vars[] = {
#ifdef MROUTING
{ IPCTL_MRTPROTO, &ip_mrtproto, SYSCTL_INT_READONLY },
@@ -1799,8 +1803,9 @@ ip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
NET_UNLOCK();
return (error);
case IPCTL_FORWARDING:
- return (sysctl_int_bounded(oldp, oldlenp, newp, newlen,
- &ip_forwarding, 0, 2));
+ return (sysctl_bounded_arr(
+ ipctl_vars_unlocked, nitems(ipctl_vars_unlocked),
+ name, namelen, oldp, oldlenp, newp, newlen));
default:
NET_LOCK();
error = sysctl_bounded_arr(ipctl_vars, nitems(ipctl_vars),
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
index 2a8950d0a..04ad1b3e0 100644
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: icmp6.c,v 1.253 2024/06/20 19:25:42 bluhm Exp $ */
+/* $OpenBSD: icmp6.c,v 1.254 2024/07/14 18:53:39 bluhm Exp $ */
/* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */
/*
@@ -1228,6 +1228,7 @@ icmp6_redirect_input(struct mbuf *m, int off)
char *lladdr = NULL;
int lladdrlen = 0;
struct rtentry *rt = NULL;
+ int i_am_router = (atomic_load_int(&ip6_forwarding) != 0);
int is_router;
int is_onlink;
struct in6_addr src6 = ip6->ip6_src;
@@ -1241,7 +1242,7 @@ icmp6_redirect_input(struct mbuf *m, int off)
return;
/* if we are router, we don't update route by icmp6 redirect */
- if (ip6_forwarding != 0)
+ if (i_am_router)
goto freeit;
if (!(ifp->if_xflags & IFXF_AUTOCONF6))
goto freeit;
@@ -1366,7 +1367,7 @@ icmp6_redirect_input(struct mbuf *m, int off)
/* RFC 2461 8.3 */
nd6_cache_lladdr(ifp, &redtgt6, lladdr, lladdrlen, ND_REDIRECT,
- is_onlink ? ND_REDIRECT_ONLINK : ND_REDIRECT_ROUTER);
+ is_onlink ? ND_REDIRECT_ONLINK : ND_REDIRECT_ROUTER, i_am_router);
if (!is_onlink) { /* better router case. perform rtredirect. */
/* perform rtredirect */
@@ -1438,11 +1439,12 @@ icmp6_redirect_output(struct mbuf *m0, struct rtentry *rt)
size_t maxlen;
u_char *p;
struct sockaddr_in6 src_sa;
+ int i_am_router = (atomic_load_int(&ip6_forwarding) != 0);
icmp6_errcount(ND_REDIRECT, 0);
/* if we are not router, we don't send icmp6 redirect */
- if (ip6_forwarding == 0)
+ if (!i_am_router)
goto fail;
/* sanity check */
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index 6952cf632..4ab7d8c45 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_input.c,v 1.264 2024/07/04 12:50:08 bluhm Exp $ */
+/* $OpenBSD: ip6_input.c,v 1.265 2024/07/14 18:53:39 bluhm Exp $ */
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
/*
@@ -416,7 +416,7 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
SET(flags, IPV6_REDIRECT);
#endif
- switch (ip6_forwarding) {
+ switch (atomic_load_int(&ip6_forwarding)) {
case 2:
SET(flags, IPV6_FORWARDING_IPSEC);
/* FALLTHROUGH */
@@ -1443,12 +1443,15 @@ const u_char inet6ctlerrmap[PRC_NCMDS] = {
extern int ip6_mrtproto;
#endif
+const struct sysctl_bounded_args ipv6ctl_vars_unlocked[] = {
+ { IPV6CTL_FORWARDING, &ip6_forwarding, 0, 2 },
+};
+
const struct sysctl_bounded_args ipv6ctl_vars[] = {
{ IPV6CTL_DAD_PENDING, &ip6_dad_pending, SYSCTL_INT_READONLY },
#ifdef MROUTING
{ IPV6CTL_MRTPROTO, &ip6_mrtproto, SYSCTL_INT_READONLY },
#endif
- { IPV6CTL_FORWARDING, &ip6_forwarding, 0, 2 },
{ IPV6CTL_SENDREDIRECTS, &ip6_sendredirects, 0, 1 },
{ IPV6CTL_DEFHLIM, &ip6_defhlim, 0, 255 },
{ IPV6CTL_MAXFRAGPACKETS, &ip6_maxfragpackets, 0, 1000 },
@@ -1568,6 +1571,10 @@ ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
atomic_inc_long(&rtgeneration);
NET_UNLOCK();
return (error);
+ case IPV6CTL_FORWARDING:
+ return (sysctl_bounded_arr(
+ ipv6ctl_vars_unlocked, nitems(ipv6ctl_vars_unlocked),
+ name, namelen, oldp, oldlenp, newp, newlen));
default:
NET_LOCK();
error = sysctl_bounded_arr(ipv6ctl_vars, nitems(ipv6ctl_vars),
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index 28bc1b91d..fce85be1a 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nd6.c,v 1.281 2024/06/20 19:25:42 bluhm Exp $ */
+/* $OpenBSD: nd6.c,v 1.282 2024/07/14 18:53:39 bluhm Exp $ */
/* $KAME: nd6.c,v 1.280 2002/06/08 19:52:07 itojun Exp $ */
/*
@@ -107,8 +107,8 @@ void nd6_slowtimo(void *);
void nd6_expire(void *);
void nd6_expire_timer(void *);
void nd6_invalidate(struct rtentry *);
-void nd6_free(struct rtentry *);
-int nd6_llinfo_timer(struct rtentry *);
+void nd6_free(struct rtentry *, int);
+int nd6_llinfo_timer(struct rtentry *, int);
struct timeout nd6_timer_to;
struct timeout nd6_slowtimo_ch;
@@ -264,6 +264,7 @@ nd6_timer(void *unused)
{
struct llinfo_nd6 *ln, *nln;
time_t uptime, expire;
+ int i_am_router = (atomic_load_int(&ip6_forwarding) != 0);
int secs;
NET_LOCK();
@@ -276,7 +277,7 @@ nd6_timer(void *unused)
struct rtentry *rt = ln->ln_rt;
if (rt->rt_expire && rt->rt_expire <= uptime)
- if (nd6_llinfo_timer(rt))
+ if (nd6_llinfo_timer(rt, i_am_router))
continue;
if (rt->rt_expire && rt->rt_expire < expire)
@@ -300,7 +301,7 @@ nd6_timer(void *unused)
* Returns 1 if `rt' should no longer be used, 0 otherwise.
*/
int
-nd6_llinfo_timer(struct rtentry *rt)
+nd6_llinfo_timer(struct rtentry *rt, int i_am_router)
{
struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo;
struct sockaddr_in6 *dst = satosin6(rt_key(rt));
@@ -346,7 +347,7 @@ nd6_llinfo_timer(struct rtentry *rt)
} else
atomic_sub_int(&ln_hold_total, len);
- nd6_free(rt);
+ nd6_free(rt, i_am_router);
ln = NULL;
}
break;
@@ -362,7 +363,7 @@ nd6_llinfo_timer(struct rtentry *rt)
case ND6_LLINFO_PURGE:
/* Garbage Collection(RFC 2461 5.3) */
if (!ND6_LLINFO_PERMANENT(ln)) {
- nd6_free(rt);
+ nd6_free(rt, i_am_router);
ln = NULL;
}
break;
@@ -383,7 +384,7 @@ nd6_llinfo_timer(struct rtentry *rt)
nd6_ns_output(ifp, &dst->sin6_addr, &dst->sin6_addr,
&ln->ln_saddr6, 0);
} else {
- nd6_free(rt);
+ nd6_free(rt, i_am_router);
ln = NULL;
}
break;
@@ -477,6 +478,7 @@ void
nd6_purge(struct ifnet *ifp)
{
struct llinfo_nd6 *ln, *nln;
+ int i_am_router = (atomic_load_int(&ip6_forwarding) != 0);
NET_ASSERT_LOCKED_EXCLUSIVE();
@@ -492,7 +494,7 @@ nd6_purge(struct ifnet *ifp)
rt->rt_gateway->sa_family == AF_LINK) {
sdl = satosdl(rt->rt_gateway);
if (sdl->sdl_index == ifp->if_index)
- nd6_free(rt);
+ nd6_free(rt, i_am_router);
}
}
}
@@ -661,7 +663,7 @@ nd6_invalidate(struct rtentry *rt)
* Free an nd6 llinfo entry.
*/
void
-nd6_free(struct rtentry *rt)
+nd6_free(struct rtentry *rt, int i_am_router)
{
struct llinfo_nd6 *ln = (struct llinfo_nd6 *)rt->rt_llinfo;
struct in6_addr in6 = satosin6(rt_key(rt))->sin6_addr;
@@ -671,7 +673,7 @@ nd6_free(struct rtentry *rt)
ifp = if_get(rt->rt_ifidx);
- if (ip6_forwarding == 0) {
+ if (!i_am_router) {
if (ln->ln_router) {
/*
* rt6_flush must be called whether or not the neighbor
@@ -1031,7 +1033,7 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
*/
void
nd6_cache_lladdr(struct ifnet *ifp, const struct in6_addr *from, char *lladdr,
- int lladdrlen, int type, int code)
+ int lladdrlen, int type, int code, int i_am_router)
{
struct rtentry *rt;
struct llinfo_nd6 *ln;
@@ -1080,7 +1082,7 @@ nd6_cache_lladdr(struct ifnet *ifp, const struct in6_addr *from, char *lladdr,
return;
if ((rt->rt_flags & (RTF_GATEWAY | RTF_LLINFO)) != RTF_LLINFO) {
fail:
- nd6_free(rt);
+ nd6_free(rt, i_am_router);
rtfree(rt);
return;
}
diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h
index 293ccbfb6..b65fad009 100644
--- a/sys/netinet6/nd6.h
+++ b/sys/netinet6/nd6.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: nd6.h,v 1.99 2023/05/04 06:56:56 bluhm Exp $ */
+/* $OpenBSD: nd6.h,v 1.100 2024/07/14 18:53:39 bluhm Exp $ */
/* $KAME: nd6.h,v 1.95 2002/06/08 11:31:06 itojun Exp $ */
/*
@@ -134,7 +134,7 @@ void nd6_nud_hint(struct rtentry *);
void nd6_rtrequest(struct ifnet *, int, struct rtentry *);
int nd6_ioctl(u_long, caddr_t, struct ifnet *);
void nd6_cache_lladdr(struct ifnet *, const struct in6_addr *, char *,
- int, int, int);
+ int, int, int, int);
int nd6_resolve(struct ifnet *, struct rtentry *, struct mbuf *,
struct sockaddr *, u_char *);
int nd6_need_cache(struct ifnet *);
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
index b6747312d..2e4913345 100644
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nd6_nbr.c,v 1.152 2024/06/20 19:25:42 bluhm Exp $ */
+/* $OpenBSD: nd6_nbr.c,v 1.153 2024/07/14 18:53:39 bluhm Exp $ */
/* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */
/*
@@ -108,7 +108,7 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
struct ifaddr *ifa = NULL;
int lladdrlen = 0;
int anycast = 0, proxy = 0, tentative = 0;
- int i_am_router = (ip6_forwarding != 0);
+ int i_am_router = (atomic_load_int(&ip6_forwarding) != 0);
int tlladdr;
struct nd_opts ndopts;
struct sockaddr_dl *proxydl = NULL;
@@ -323,7 +323,7 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
}
nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_NEIGHBOR_SOLICIT,
- 0);
+ 0, i_am_router);
nd6_na_output(ifp, &saddr6, &taddr6,
((anycast || proxy || !tlladdr) ? 0 : ND_NA_FLAG_OVERRIDE) |
@@ -559,7 +559,7 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len)
int is_override;
char *lladdr = NULL;
int lladdrlen = 0;
- int i_am_router = (ip6_forwarding != 0);
+ int i_am_router = (atomic_load_int(&ip6_forwarding) != 0);
struct ifaddr *ifa;
struct in6_ifaddr *ifa6;
struct llinfo_nd6 *ln;
diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c
index d68b7a8ef..1d4ec4312 100644
--- a/sys/netinet6/nd6_rtr.c
+++ b/sys/netinet6/nd6_rtr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: nd6_rtr.c,v 1.170 2023/03/31 19:43:33 bluhm Exp $ */
+/* $OpenBSD: nd6_rtr.c,v 1.171 2024/07/14 18:53:39 bluhm Exp $ */
/* $KAME: nd6_rtr.c,v 1.97 2001/02/07 11:09:13 itojun Exp $ */
/*
@@ -73,6 +73,7 @@ nd6_rtr_cache(struct mbuf *m, int off, int icmp6len, int icmp6_type)
struct in6_addr saddr6 = ip6->ip6_src;
char *lladdr = NULL;
int lladdrlen = 0;
+ int i_am_router = (atomic_load_int(&ip6_forwarding) != 0);
struct nd_opts ndopts;
char src[INET6_ADDRSTRLEN], dst[INET6_ADDRSTRLEN];
@@ -157,7 +158,8 @@ nd6_rtr_cache(struct mbuf *m, int off, int icmp6len, int icmp6_type)
goto bad;
}
- nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, icmp6_type, 0);
+ nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, icmp6_type, 0,
+ i_am_router);
if_put(ifp);
freeit:
diff --git a/sys/sys/auxv.h b/sys/sys/auxv.h
new file mode 100644
index 000000000..166dc7174
--- /dev/null
+++ b/sys/sys/auxv.h
@@ -0,0 +1,50 @@
+/* $OpenBSD: auxv.h,v 1.1 2024/07/14 09:48:49 jca Exp $ */
+
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2017 Michal Meloun
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _SYS_AUXV_H_
+#define _SYS_AUXV_H_
+
+#include
+#include
+
+/* Values for a_type. */
+#define AT_NULL 0 /* Terminates the vector. */
+#define AT_IGNORE 1 /* Ignored entry. */
+#define AT_PAGESZ 6 /* Page size in bytes. */
+#define AT_HWCAP 25 /* CPU feature flags. */
+#define AT_HWCAP2 26 /* CPU feature flags 2. */
+
+#define AT_COUNT 27 /* Count of defined aux entry types. */
+
+__BEGIN_DECLS
+int elf_aux_info(int aux, void *buf, int buflen);
+__END_DECLS
+
+#endif /* !_SYS_AUXV_H_ */
diff --git a/sys/sys/exec_elf.h b/sys/sys/exec_elf.h
index 8277043cd..a52023d9c 100644
--- a/sys/sys/exec_elf.h
+++ b/sys/sys/exec_elf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: exec_elf.h,v 1.104 2024/06/22 12:26:17 deraadt Exp $ */
+/* $OpenBSD: exec_elf.h,v 1.105 2024/07/14 09:48:49 jca Exp $ */
/*
* Copyright (c) 1995, 1996 Erik Theisen. All rights reserved.
*
@@ -728,6 +728,8 @@ enum AuxID {
AUX_base = 7, /* base addr for ld.so or static PIE */
AUX_flags = 8, /* processor flags */
AUX_entry = 9, /* a.out entry */
+ AUX_hwcap = 25, /* processor flags */
+ AUX_hwcap2 = 26, /* processor flags (continued) */
AUX_sun_uid = 2000, /* euid */
AUX_sun_ruid = 2001, /* ruid */
AUX_sun_gid = 2002, /* egid */
@@ -821,7 +823,7 @@ extern Elf_Dyn _DYNAMIC[];
/*
* How many entries are in the AuxInfo array we pass to the process?
*/
-#define ELF_AUX_ENTRIES 9
+#define ELF_AUX_ENTRIES 11
#define ELF_AUX_WORDS (sizeof(AuxInfo) * ELF_AUX_ENTRIES / sizeof(char *))
struct exec_package;
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 0a2a3989f..5966c10e8 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proc.h,v 1.362 2024/07/08 13:17:12 claudio Exp $ */
+/* $OpenBSD: proc.h,v 1.363 2024/07/15 07:24:03 jsg Exp $ */
/* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */
/*-
@@ -308,8 +308,8 @@ struct process {
"\013WAITED" "\014COREDUMP" "\015SINGLEEXIT" "\016SINGLEUNWIND" \
"\017NOZOMBIE" "\020STOPPED" "\021SYSTEM" "\022EMBRYO" "\023ZOMBIE" \
"\024NOBROADCASTKILL" "\025PLEDGE" "\026WXNEEDED" "\027EXECPLEDGE" \
- "\030ORPHAN" "\031CHROOT" "\032NOBTCFI" "\033ITIMER")
-
+ "\030ORPHAN" "\031CHROOT" "\032NOBTCFI" "\033ITIMER" "\034PIN" \
+ "\035LIBCPIN")
struct kcov_dev;
struct lock_list_entry;
diff --git a/sys/ufs/ext2fs/ext2fs.h b/sys/ufs/ext2fs/ext2fs.h
index 647270d80..5f87ecd31 100644
--- a/sys/ufs/ext2fs/ext2fs.h
+++ b/sys/ufs/ext2fs/ext2fs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ext2fs.h,v 1.26 2021/03/11 13:31:35 jsg Exp $ */
+/* $OpenBSD: ext2fs.h,v 1.27 2024/07/15 13:27:36 martijn Exp $ */
/* $NetBSD: ext2fs.h,v 1.10 2000/01/28 16:00:23 bouyer Exp $ */
/*
@@ -156,7 +156,48 @@ struct ext2fs {
u_int32_t e2fs_first_meta_bg;
u_int32_t e2fs_mkfs_time;
u_int32_t e2fs_journal_backup[17];
- u_int32_t reserved2[172];
+ u_int32_t e2fs_bcount_hi; /* high bits of blocks count */
+ u_int32_t e2fs_rbcount_hi; /* high bits of reserved blocks count */
+ u_int32_t e2fs_fbcount_hi; /* high bits of free blocks count */
+ u_int16_t e2fs_min_extra_isize; /* all inodes have some bytes */
+ u_int16_t e2fs_want_extra_isize;/* inodes must reserve some bytes */
+ u_int32_t e2fs_flags; /* miscellaneous flags */
+ u_int16_t e2fs_raid_stride; /* RAID stride */
+ u_int16_t e2fs_mmpintv; /* seconds to wait in MMP checking */
+ u_int64_t e2fs_mmpblk; /* block for multi-mount protection */
+ u_int32_t e2fs_raid_stripe_wid; /* blocks on data disks (N * stride) */
+ u_int8_t e2fs_log_gpf; /* FLEX_BG group size */
+ u_int8_t e2fs_chksum_type; /* metadata checksum algorithm used */
+ u_int8_t e2fs_encrypt; /* versioning level for encryption */
+ u_int8_t e2fs_reserved_pad;
+ u_int64_t e2fs_kbytes_written; /* number of lifetime kilobytes */
+ u_int32_t e2fs_snapinum; /* inode number of active snapshot */
+ u_int32_t e2fs_snapid; /* sequential ID of active snapshot */
+ u_int64_t e2fs_snaprbcount; /* rsvd blocks for active snapshot */
+ u_int32_t e2fs_snaplist; /* inode number for on-disk snapshot */
+ u_int32_t e2fs_errcount; /* number of file system errors */
+ u_int32_t e2fs_first_errtime; /* first time an error happened */
+ u_int32_t e2fs_first_errino; /* inode involved in first error */
+ u_int64_t e2fs_first_errblk; /* block involved of first error */
+ u_int8_t e2fs_first_errfunc[32];/* function where error happened */
+ u_int32_t e2fs_first_errline; /* line number where error happened */
+ u_int32_t e2fs_last_errtime; /* most recent time of an error */
+ u_int32_t e2fs_last_errino; /* inode involved in last error */
+ u_int32_t e2fs_last_errline; /* line number where error happened */
+ u_int64_t e2fs_last_errblk; /* block involved of last error */
+ u_int8_t e2fs_last_errfunc[32];/* function where error happened */
+ u_int8_t e2fs_mount_opts[64];
+ u_int32_t e2fs_usrquota_inum; /* inode for tracking user quota */
+ u_int32_t e2fs_grpquota_inum; /* inode for tracking group quota */
+ u_int32_t e2fs_overhead_clusters;/* overhead blocks/clusters */
+ u_int32_t e2fs_backup_bgs[2]; /* groups with sparse_super2 SBs */
+ u_int8_t e2fs_encrypt_algos[4];/* encryption algorithms in use */
+ u_int8_t e2fs_encrypt_pw_salt[16];/* salt used for string2key */
+ u_int32_t e2fs_lpf_ino; /* location of the lost+found inode */
+ u_int32_t e2fs_proj_quota_inum; /* inode for tracking project quota */
+ u_int32_t e2fs_chksum_seed; /* checksum seed */
+ u_int32_t e2fs_reserved[98]; /* padding to the end of the block */
+ u_int32_t e2fs_sbchksum; /* superblock checksum */
};
diff --git a/usr.bin/ssh/ssh_config.5 b/usr.bin/ssh/ssh_config.5
index 10ce6ea31..874874bd0 100644
--- a/usr.bin/ssh/ssh_config.5
+++ b/usr.bin/ssh/ssh_config.5
@@ -33,8 +33,8 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.\" $OpenBSD: ssh_config.5,v 1.397 2024/07/04 22:53:59 djm Exp $
-.Dd $Mdocdate: July 4 2024 $
+.\" $OpenBSD: ssh_config.5,v 1.398 2024/07/14 10:19:23 jsg Exp $
+.Dd $Mdocdate: July 14 2024 $
.Dt SSH_CONFIG 5
.Os
.Sh NAME
@@ -1263,7 +1263,7 @@ and
.It Cm KexAlgorithms
Specifies the permitted KEX (Key Exchange) algorithms that will be used and
their preference order.
-The selected algorithm will the the first algorithm in this list that
+The selected algorithm will be the first algorithm in this list that
the server also supports.
Multiple algorithms must be comma-separated.
.Pp
diff --git a/usr.sbin/npppd/npppd/chap.c b/usr.sbin/npppd/npppd/chap.c
index ac76db5fb..6577b26df 100644
--- a/usr.sbin/npppd/npppd/chap.c
+++ b/usr.sbin/npppd/npppd/chap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: chap.c,v 1.19 2024/07/01 07:09:07 yasuoka Exp $ */
+/* $OpenBSD: chap.c,v 1.20 2024/07/14 10:52:50 yasuoka Exp $ */
/*-
* Copyright (c) 2009 Internet Initiative Japan Inc.
@@ -36,7 +36,7 @@
*
*/
/* RFC 1994, 2433 */
-/* $Id: chap.c,v 1.19 2024/07/01 07:09:07 yasuoka Exp $ */
+/* $Id: chap.c,v 1.20 2024/07/14 10:52:50 yasuoka Exp $ */
#include
#include
#include
@@ -537,14 +537,12 @@ md5chap_authenticate(chap *_this, int id, char *username, u_char *challenge,
MD5_CTX md5ctx;
int rval, passlen;
u_char digest[16];
- char *password, buf[MAX_PASSWORD_LENGTH + 1];
-
- buf[0] = id;
- passlen = sizeof(buf) - 1;
- password = &buf[1];
+ char idpass[1 + MAX_PASSWORD_LENGTH + 1];
+ idpass[0] = id;
+ passlen = MAX_PASSWORD_LENGTH;
rval = npppd_get_user_password(_this->ppp->pppd, _this->ppp, username,
- password, &passlen);
+ idpass + 1, &passlen);
if (rval != 0) {
switch (rval) {
@@ -559,9 +557,9 @@ md5chap_authenticate(chap *_this, int id, char *username, u_char *challenge,
}
goto auth_failed;
}
- passlen = strlen(password);
+ passlen = strlen(idpass + 1);
MD5Init(&md5ctx);
- MD5Update(&md5ctx, buf, passlen + 1);
+ MD5Update(&md5ctx, idpass, 1 + passlen);
MD5Update(&md5ctx, challenge, lchallenge);
MD5Final(digest, &md5ctx);
diff --git a/usr.sbin/radiusctl/radiusctl.8 b/usr.sbin/radiusctl/radiusctl.8
index 0074700e7..58980c9ba 100644
--- a/usr.sbin/radiusctl/radiusctl.8
+++ b/usr.sbin/radiusctl/radiusctl.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: radiusctl.8,v 1.7 2024/07/10 05:41:34 jmc Exp $
+.\" $OpenBSD: radiusctl.8,v 1.8 2024/07/14 03:47:44 jsg Exp $
.\"
.\" Copyright (c) YASUOKA Masahiko
.\"
@@ -15,7 +15,7 @@
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.\"
-.Dd $Mdocdate: July 10 2024 $
+.Dd $Mdocdate: July 14 2024 $
.Dt RADIUSCTL 8
.Os
.Sh NAME
@@ -109,7 +109,7 @@ is specified,
.Nm
shows the sessions in JSON format.
.It Cm ipcp disconnect Ar sequence
-Request to disconnect the session specfied by the
+Request to disconnect the session specified by the
.Ar sequence .
.El
.Sh EXAMPLES
diff --git a/usr.sbin/radiusctl/radiusctl.c b/usr.sbin/radiusctl/radiusctl.c
index 8c46815c0..9caaabe18 100644
--- a/usr.sbin/radiusctl/radiusctl.c
+++ b/usr.sbin/radiusctl/radiusctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: radiusctl.c,v 1.9 2024/07/09 17:26:14 yasuoka Exp $ */
+/* $OpenBSD: radiusctl.c,v 1.10 2024/07/14 11:12:32 yasuoka Exp $ */
/*
* Copyright (c) 2015 YASUOKA Masahiko
*
@@ -307,6 +307,7 @@ radius_test(struct parse_result *res)
u_char resp[1 + MD5_DIGEST_LENGTH]; /* "1 + " for CHAP Id */
MD5_CTX md5ctx;
+ arc4random_buf(chal, sizeof(chal));
arc4random_buf(resp, 1); /* CHAP Id is random */
MD5Init(&md5ctx);
MD5Update(&md5ctx, resp, 1);
diff --git a/usr.sbin/radiusd/Makefile b/usr.sbin/radiusd/Makefile
index 61ba31825..b21d20323 100644
--- a/usr.sbin/radiusd/Makefile
+++ b/usr.sbin/radiusd/Makefile
@@ -1,9 +1,11 @@
-# $OpenBSD: Makefile,v 1.4 2024/07/09 17:26:14 yasuoka Exp $
+# $OpenBSD: Makefile,v 1.6 2024/07/14 16:09:23 yasuoka Exp $
SUBDIR= radiusd
SUBDIR+= radiusd_bsdauth
+SUBDIR+= radiusd_file
SUBDIR+= radiusd_ipcp
SUBDIR+= radiusd_radius
SUBDIR+= radiusd_standard
+SUBDIR+= radiusd_eap2mschap
.include
diff --git a/usr.sbin/radiusd/Makefile.inc b/usr.sbin/radiusd/Makefile.inc
index d5d2462d7..087857ebb 100644
--- a/usr.sbin/radiusd/Makefile.inc
+++ b/usr.sbin/radiusd/Makefile.inc
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.inc,v 1.3 2024/07/02 16:18:11 deraadt Exp $
+# $OpenBSD: Makefile.inc,v 1.4 2024/07/14 16:09:23 yasuoka Exp $
.PATH: ${.CURDIR}/..
CFLAGS+= -I${.CURDIR}/..
@@ -7,5 +7,5 @@ CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
CFLAGS+= -Wmissing-declarations -Wpointer-arith
#DEGUG= -g
-#CFLAGS+= -DRADIUSD_DEBUG
+#CFLAGS+= -DRADIUSD_DEBUG -DEAP2MSCHAP_DEBUG
#CFLAGS+= -Werror
diff --git a/usr.sbin/radiusd/chap_ms.c b/usr.sbin/radiusd/chap_ms.c
new file mode 100644
index 000000000..878fd4fd0
--- /dev/null
+++ b/usr.sbin/radiusd/chap_ms.c
@@ -0,0 +1,375 @@
+/* $OpenBSD: chap_ms.c,v 1.1 2024/07/14 13:44:30 yasuoka Exp $ */
+
+/*
+ * Copyright (c) 2010-2013 Reyk Floeter
+ * Copyright (c) 1997-2001 Brian Somers
+ * Copyright (c) 1997 Gabor Kincses
+ * Copyright (c) 1995 Eric Rosenquist
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include "chap_ms.h"
+
+/*
+ * Documentation & specifications:
+ *
+ * MS-CHAP (CHAP80) RFC2433
+ * MS-CHAP-V2 (CHAP81) RFC2759
+ * MPPE key management RFC3079
+ *
+ * Security analysis:
+ * Schneier/Mudge/Wagner, "MS-CHAP-v2", Oct 99
+ * "It is unclear to us why this protocol is so complicated."
+ */
+
+static u_int8_t sha1_pad1[40] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static u_int8_t sha1_pad2[40] = {
+ 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
+ 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
+ 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
+ 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2
+};
+
+u_int8_t get7bits(u_int8_t *, int);
+void mschap_des_addparity(u_int8_t *, u_int8_t *);
+void mschap_des_encrypt(u_int8_t *, u_int8_t *, u_int8_t *);
+void mschap_challenge_response(u_int8_t *, u_int8_t *, u_int8_t *);
+
+u_int8_t
+get7bits(u_int8_t *in, int start)
+{
+ u_int word;
+
+ word = (u_int)in[start / 8] << 8;
+ word |= (u_int)in[start / 8 + 1];
+ word >>= 15 - (start % 8 + 7);
+
+ return (word & 0xfe);
+}
+
+/* IN 56 bit DES key missing parity bits
+ OUT 64 bit DES key with parity bits added */
+void
+mschap_des_addparity(u_int8_t *key, u_int8_t *des_key)
+{
+ des_key[0] = get7bits(key, 0);
+ des_key[1] = get7bits(key, 7);
+ des_key[2] = get7bits(key, 14);
+ des_key[3] = get7bits(key, 21);
+ des_key[4] = get7bits(key, 28);
+ des_key[5] = get7bits(key, 35);
+ des_key[6] = get7bits(key, 42);
+ des_key[7] = get7bits(key, 49);
+
+ DES_set_odd_parity((DES_cblock *)des_key);
+}
+
+void
+mschap_des_encrypt(u_int8_t *clear, u_int8_t *key, u_int8_t *cipher)
+{
+ DES_cblock des_key;
+ DES_key_schedule key_schedule;
+
+ mschap_des_addparity(key, des_key);
+
+ DES_set_key(&des_key, &key_schedule);
+ DES_ecb_encrypt((DES_cblock *)clear, (DES_cblock *)cipher,
+ &key_schedule, 1);
+}
+
+void
+mschap_challenge_response(u_int8_t *challenge, u_int8_t *pwhash,
+ u_int8_t *response)
+{
+ u_int8_t padpwhash[21 + 1];
+
+ bzero(&padpwhash, sizeof(padpwhash));
+ memcpy(padpwhash, pwhash, MSCHAP_HASH_SZ);
+
+ mschap_des_encrypt(challenge, padpwhash + 0, response + 0);
+ mschap_des_encrypt(challenge, padpwhash + 7, response + 8);
+ mschap_des_encrypt(challenge, padpwhash + 14, response + 16);
+}
+
+void
+mschap_ntpassword_hash(u_int8_t *in, int inlen, u_int8_t *hash)
+{
+ EVP_MD_CTX *ctx;
+ u_int mdlen;
+
+ ctx = EVP_MD_CTX_new();
+ EVP_DigestInit_ex(ctx, EVP_md4(), NULL);
+ EVP_DigestUpdate(ctx, in, inlen);
+ EVP_DigestFinal_ex(ctx, hash, &mdlen);
+ EVP_MD_CTX_free(ctx);
+}
+
+void
+mschap_challenge_hash(u_int8_t *peer_challenge, u_int8_t *auth_challenge,
+ u_int8_t *username, int usernamelen, u_int8_t *challenge)
+{
+ EVP_MD_CTX *ctx;
+ u_int8_t md[SHA_DIGEST_LENGTH];
+ u_int mdlen;
+ u_int8_t *name;
+
+ if ((name = strrchr(username, '\\')) == NULL)
+ name = username;
+ else
+ name++;
+
+ ctx = EVP_MD_CTX_new();
+ EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
+ EVP_DigestUpdate(ctx, peer_challenge, MSCHAPV2_CHALLENGE_SZ);
+ EVP_DigestUpdate(ctx, auth_challenge, MSCHAPV2_CHALLENGE_SZ);
+ EVP_DigestUpdate(ctx, name, strlen(name));
+ EVP_DigestFinal_ex(ctx, md, &mdlen);
+ EVP_MD_CTX_free(ctx);
+
+ memcpy(challenge, md, MSCHAP_CHALLENGE_SZ);
+}
+
+void
+mschap_nt_response(u_int8_t *auth_challenge, u_int8_t *peer_challenge,
+ u_int8_t *username, int usernamelen, u_int8_t *password, int passwordlen,
+ u_int8_t *response)
+{
+ u_int8_t challenge[MSCHAP_CHALLENGE_SZ];
+ u_int8_t password_hash[MSCHAP_HASH_SZ];
+
+ mschap_challenge_hash(peer_challenge, auth_challenge,
+ username, usernamelen, challenge);
+
+ mschap_ntpassword_hash(password, passwordlen, password_hash);
+ mschap_challenge_response(challenge, password_hash, response);
+}
+
+void
+mschap_auth_response(u_int8_t *password, int passwordlen,
+ u_int8_t *ntresponse, u_int8_t *auth_challenge, u_int8_t *peer_challenge,
+ u_int8_t *username, int usernamelen, u_int8_t *auth_response)
+{
+ EVP_MD_CTX *ctx;
+ u_int8_t password_hash[MSCHAP_HASH_SZ];
+ u_int8_t password_hash2[MSCHAP_HASH_SZ];
+ u_int8_t challenge[MSCHAP_CHALLENGE_SZ];
+ u_int8_t md[SHA_DIGEST_LENGTH], *ptr;
+ u_int mdlen;
+ int i;
+ const u_int8_t hex[] = "0123456789ABCDEF";
+ static u_int8_t magic1[39] = {
+ 0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76,
+ 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65,
+ 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67,
+ 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74
+ };
+ static u_int8_t magic2[41] = {
+ 0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B,
+ 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F,
+ 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E,
+ 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F,
+ 0x6E
+ };
+
+ mschap_ntpassword_hash(password, passwordlen, password_hash);
+ mschap_ntpassword_hash(password_hash, MSCHAP_HASH_SZ, password_hash2);
+
+ ctx = EVP_MD_CTX_new();
+ EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
+ EVP_DigestUpdate(ctx, password_hash2, sizeof(password_hash2));
+ EVP_DigestUpdate(ctx, ntresponse, 24);
+ EVP_DigestUpdate(ctx, magic1, 39);
+ EVP_DigestFinal_ex(ctx, md, &mdlen);
+
+ mschap_challenge_hash(peer_challenge, auth_challenge,
+ username, usernamelen, challenge);
+
+ EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
+ EVP_DigestUpdate(ctx, md, sizeof(md));
+ EVP_DigestUpdate(ctx, challenge, sizeof(challenge));
+ EVP_DigestUpdate(ctx, magic2, 41);
+ EVP_DigestFinal_ex(ctx, md, &mdlen);
+ EVP_MD_CTX_free(ctx);
+
+ /*
+ * Encode the value of 'Digest' as "S=" followed by
+ * 40 ASCII hexadecimal digits and return it in
+ * AuthenticatorResponse.
+ * For example,
+ * "S=0123456789ABCDEF0123456789ABCDEF01234567"
+ */
+ ptr = auth_response;
+ *ptr++ = 'S';
+ *ptr++ = '=';
+ for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
+ *ptr++ = hex[md[i] >> 4];
+ *ptr++ = hex[md[i] & 0x0f];
+ }
+}
+
+void
+mschap_masterkey(u_int8_t *password_hash2, u_int8_t *ntresponse,
+ u_int8_t *masterkey)
+{
+ u_int8_t md[SHA_DIGEST_LENGTH];
+ u_int mdlen;
+ EVP_MD_CTX *ctx;
+ static u_int8_t magic1[27] = {
+ 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74,
+ 0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d,
+ 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79
+ };
+
+ ctx = EVP_MD_CTX_new();
+ EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
+ EVP_DigestUpdate(ctx, password_hash2, MSCHAP_HASH_SZ);
+ EVP_DigestUpdate(ctx, ntresponse, 24);
+ EVP_DigestUpdate(ctx, magic1, 27);
+ EVP_DigestFinal_ex(ctx, md, &mdlen);
+ EVP_MD_CTX_free(ctx);
+
+ memcpy(masterkey, md, 16);
+}
+
+void
+mschap_asymetric_startkey(u_int8_t *masterkey, u_int8_t *sessionkey,
+ int sessionkeylen, int issend, int isserver)
+{
+ EVP_MD_CTX *ctx;
+ u_int8_t md[SHA_DIGEST_LENGTH];
+ u_int mdlen;
+ u_int8_t *s;
+ static u_int8_t magic2[84] = {
+ 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
+ 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
+ 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
+ 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79,
+ 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
+ 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65,
+ 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
+ 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
+ 0x6b, 0x65, 0x79, 0x2e
+ };
+ static u_int8_t magic3[84] = {
+ 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
+ 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
+ 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
+ 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
+ 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68,
+ 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73,
+ 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73,
+ 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20,
+ 0x6b, 0x65, 0x79, 0x2e
+ };
+
+ if (issend)
+ s = isserver ? magic3 : magic2;
+ else
+ s = isserver ? magic2 : magic3;
+
+ ctx = EVP_MD_CTX_new();
+ EVP_DigestInit_ex(ctx, EVP_sha1(), NULL);
+ EVP_DigestUpdate(ctx, masterkey, 16);
+ EVP_DigestUpdate(ctx, sha1_pad1, 40);
+ EVP_DigestUpdate(ctx, s, 84);
+ EVP_DigestUpdate(ctx, sha1_pad2, 40);
+ EVP_DigestFinal_ex(ctx, md, &mdlen);
+ EVP_MD_CTX_free(ctx);
+
+ memcpy(sessionkey, md, sessionkeylen);
+}
+
+void
+mschap_msk(u_int8_t *password, int passwordlen,
+ u_int8_t *ntresponse, u_int8_t *msk)
+{
+ u_int8_t password_hash[MSCHAP_HASH_SZ];
+ u_int8_t password_hash2[MSCHAP_HASH_SZ];
+ u_int8_t masterkey[MSCHAP_MASTERKEY_SZ];
+ u_int8_t sendkey[MSCHAP_MASTERKEY_SZ];
+ u_int8_t recvkey[MSCHAP_MASTERKEY_SZ];
+
+ mschap_ntpassword_hash(password, passwordlen, password_hash);
+ mschap_ntpassword_hash(password_hash, MSCHAP_HASH_SZ, password_hash2);
+
+ mschap_masterkey(password_hash2, ntresponse, masterkey);
+ mschap_asymetric_startkey(masterkey, recvkey, sizeof(recvkey), 0, 1);
+ mschap_asymetric_startkey(masterkey, sendkey, sizeof(sendkey), 1, 1);
+
+ /* 16 bytes receive key + 16 bytes send key + 32 bytes 0 padding */
+ bzero(msk, MSCHAP_MSK_SZ);
+ memcpy(msk, &recvkey, sizeof(recvkey));
+ memcpy(msk + sizeof(recvkey), &sendkey, sizeof(sendkey));
+}
+
+void
+mschap_radiuskey(u_int8_t *plain, const u_int8_t *encrypted,
+ const u_int8_t *authenticator, const u_int8_t *secret)
+{
+ EVP_MD_CTX *ctx;
+ u_int8_t b[MD5_DIGEST_LENGTH], p[32];
+ u_int i, mdlen;
+
+ ctx = EVP_MD_CTX_new();
+ EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
+ EVP_DigestUpdate(ctx, secret, strlen(secret));
+ EVP_DigestUpdate(ctx, authenticator, 16);
+ EVP_DigestUpdate(ctx, encrypted, 2);
+ EVP_DigestFinal_ex(ctx, b, &mdlen);
+
+ for (i = 0; i < mdlen; i++) {
+ p[i] = b[i] ^ encrypted[i+2];
+ }
+
+ EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
+ EVP_DigestUpdate(ctx, secret, strlen(secret));
+ EVP_DigestUpdate(ctx, encrypted + 2, mdlen);
+ EVP_DigestFinal_ex(ctx, b, &mdlen);
+ EVP_MD_CTX_free(ctx);
+
+ for (i = 0; i < mdlen; i++) {
+ p[i+16] = b[i] ^ encrypted[i+18];
+ }
+
+ memcpy(plain, p+1, 16);
+}
diff --git a/usr.sbin/radiusd/chap_ms.h b/usr.sbin/radiusd/chap_ms.h
new file mode 100644
index 000000000..b46a88624
--- /dev/null
+++ b/usr.sbin/radiusd/chap_ms.h
@@ -0,0 +1,48 @@
+/* $OpenBSD: chap_ms.h,v 1.1 2024/07/14 13:44:30 yasuoka Exp $ */
+/* $vantronix: chap_ms.h,v 1.6 2010/05/19 09:37:00 reyk Exp $ */
+
+/*
+ * Copyright (c) 2010 Reyk Floeter
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _CHAP_MS_H
+#define _CHAP_MS_H
+
+#define MSCHAP_CHALLENGE_SZ 8
+#define MSCHAPV2_CHALLENGE_SZ 16
+#define MSCHAP_HASH_SZ 16
+#define MSCHAP_MASTERKEY_SZ 16
+#define MSCHAP_MSK_KEY_SZ 32
+#define MSCHAP_MSK_PADDING_SZ 32
+#define MSCHAP_MSK_SZ 64
+
+#define MSCHAP_MAXNTPASSWORD_SZ 255 /* unicode chars */
+
+void mschap_nt_response(u_int8_t *, u_int8_t *, u_int8_t *, int,
+ u_int8_t *, int , u_int8_t *);
+void mschap_auth_response(u_int8_t *, int, u_int8_t *, u_int8_t *,
+ u_int8_t *, u_int8_t *, int, u_int8_t *);
+
+void mschap_ntpassword_hash(u_int8_t *, int, u_int8_t *);
+void mschap_challenge_hash(u_int8_t *, u_int8_t *, u_int8_t *,
+ int, u_int8_t *);
+
+void mschap_asymetric_startkey(u_int8_t *, u_int8_t *, int, int, int);
+void mschap_masterkey(u_int8_t *, u_int8_t *, u_int8_t *);
+void mschap_radiuskey(u_int8_t *, const u_int8_t *, const u_int8_t *,
+ const u_int8_t *);
+void mschap_msk(u_int8_t *, int, u_int8_t *, u_int8_t *);
+
+#endif /* _CHAP_MS_H */
diff --git a/usr.sbin/radiusd/eap2mschap_local.h b/usr.sbin/radiusd/eap2mschap_local.h
new file mode 100644
index 000000000..ff761f275
--- /dev/null
+++ b/usr.sbin/radiusd/eap2mschap_local.h
@@ -0,0 +1,205 @@
+/* $OpenBSD: eap2mschap_local.h,v 1.1 2024/07/14 16:09:23 yasuoka Exp $ */
+
+/*
+ * Copyright (c) 2024 Internet Initiative Japan Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define EAP_CODE_REQUEST 1
+#define EAP_CODE_RESPONSE 2
+#define EAP_CODE_SUCCESS 3
+#define EAP_CODE_FAILURE 4
+
+#define EAP_TYPE_IDENTITY 1
+#define EAP_TYPE_NOTIFICATION 2
+#define EAP_TYPE_NAK 3
+#define EAP_TYPE_MSCHAPV2 0x1a /* [MS-CHAP] MS-EAP-Authentication */
+
+#define CHAP_CHALLENGE 1
+#define CHAP_RESPONSE 2
+#define CHAP_SUCCESS 3
+#define CHAP_FAILURE 4
+
+/* From [MS-CHAP] */
+enum eap_chap_status {
+ EAP_CHAP_NONE,
+ EAP_CHAP_CHALLENGE_SENT,
+ EAP_CHAP_SUCCESS_REQUEST_SENT,
+ EAP_CHAP_FAILURE_REQUEST_SENT,
+ EAP_CHAP_CHANGE_PASSWORD_SENT,
+ EAP_CHAP_FAILED,
+ EAP_CHAP_SUCCESS
+};
+
+struct eap {
+ uint8_t code;
+ uint8_t id;
+ uint16_t length;
+ uint8_t value[0];
+} __packed;
+
+struct chap {
+ uint8_t code;
+ uint8_t id;
+ uint16_t length;
+ int8_t value[0];
+} __packed;
+
+struct eap_chap {
+ struct eap eap;
+ uint8_t eap_type;
+ struct chap chap;
+};
+
+struct eap_mschap_challenge {
+ struct eap eap;
+ uint8_t eap_type;
+ struct chap chap;
+ uint8_t challsiz;
+ uint8_t chall[16];
+ char chap_name[0];
+} __packed;
+static_assert(sizeof(struct eap_mschap_challenge) == 26, "");
+static_assert(offsetof(struct eap_mschap_challenge, chap) == 5, "");
+static_assert(offsetof(struct eap_mschap_challenge, chall) == 10, "");
+
+struct eap_mschap_response {
+ struct eap eap;
+ uint8_t eap_type;
+ struct chap chap;
+ uint8_t challsiz;
+ uint8_t peerchall[16];
+ uint8_t reserved[8];
+ uint8_t ntresponse[24];
+ uint8_t flags;
+ uint8_t chap_name[0];
+} __packed;
+static_assert(sizeof(struct eap_mschap_response) == 59, "");
+static_assert(offsetof(struct eap_mschap_response, chap) == 5, "");
+static_assert(offsetof(struct eap_mschap_response, peerchall) == 10, "");
+
+struct radius_ms_chap2_response {
+ uint8_t ident;
+ uint8_t flags;
+ uint8_t peerchall[16];
+ uint8_t reserved[8];
+ uint8_t ntresponse[24];
+} __packed;
+
+
+struct eap2mschap;
+
+struct access_req {
+ struct eap2mschap *eap2mschap;
+ char *username;
+ u_int q_id;
+ TAILQ_ENTRY(access_req) next;
+ RB_ENTRY(access_req) tree;
+ /* for EAP */
+ enum eap_chap_status eap_chap_status;
+ char state[16];
+ unsigned char chap_id;
+ unsigned char eap_id;
+ time_t eap_time;
+ char chall[16];
+ RADIUS_PACKET *pkt;
+
+};
+TAILQ_HEAD(access_reqq, access_req);
+RB_HEAD(access_reqt, access_req);
+
+#define CHAP_NAME_MAX 40
+
+struct eap2mschap {
+ struct module_base *base;
+ char *secret;
+ char chap_name[CHAP_NAME_MAX + 1];
+ struct access_reqq reqq;
+ struct access_reqt eapt;
+ struct event ev_eapt;
+};
+
+/* Attributes copied from CHAP Access-Accept to EAP Access-Access-Accept */
+struct preserve_attrs {
+ uint8_t type;
+ uint32_t vendor;
+} preserve_attrs[] = {
+ { RADIUS_TYPE_FRAMED_PROTOCOL, 0},
+ { RADIUS_TYPE_FRAMED_IP_ADDRESS, 0},
+ { RADIUS_TYPE_FRAMED_IP_NETMASK, 0},
+ { RADIUS_TYPE_FRAMED_IPV6_ADDRESS, 0},
+ { RADIUS_TYPE_DNS_SERVER_IPV6_ADDRESS, 0},
+ { RADIUS_TYPE_FRAMED_ROUTING, 0},
+ { RADIUS_VTYPE_MS_PRIMARY_DNS_SERVER, RADIUS_VENDOR_MICROSOFT },
+ { RADIUS_VTYPE_MS_SECONDARY_DNS_SERVER, RADIUS_VENDOR_MICROSOFT },
+ { RADIUS_VTYPE_MS_PRIMARY_NBNS_SERVER, RADIUS_VENDOR_MICROSOFT },
+ { RADIUS_VTYPE_MS_SECONDARY_NBNS_SERVER,RADIUS_VENDOR_MICROSOFT },
+ { RADIUS_VTYPE_MPPE_SEND_KEY, RADIUS_VENDOR_MICROSOFT },
+ { RADIUS_VTYPE_MPPE_RECV_KEY, RADIUS_VENDOR_MICROSOFT }
+};
+
+#ifndef EAP2MSCHAP_DEBUG
+#define EAP2MSCHAP_DBG(...)
+#define EAP2MSCHAP_ASSERT(_cond)
+#else
+#define EAP2MSCHAP_DBG(...) logit(LOG_DEBUG, __VA_ARGS__)
+#define EAP2MSCHAP_ASSERT(_cond) \
+ do { \
+ if (!(_cond)) { \
+ log_warnx( \
+ "ASSERT(%s) failed in %s() at %s:%d",\
+ #_cond, __func__, __FILE__, __LINE__);\
+ abort(); \
+ } \
+ } while (0/* CONSTCOND */);
+#endif
+#ifndef nitems
+#define nitems(_x) (sizeof((_x)) / sizeof((_x)[0]))
+#endif
+
+static void eap2mschap_init(struct eap2mschap *);
+static void eap2mschap_start(void *);
+static void eap2mschap_config_set(void *, const char *, int,
+ char * const *);
+static void eap2mschap_stop(void *);
+static void eap2mschap_access_request(void *, u_int, const u_char *,
+ size_t);
+static void eap2mschap_next_response(void *, u_int, const u_char *,
+ size_t);
+
+static void eap2mschap_on_eapt (int, short, void *);
+static void eap2mschap_reset_eaptimer (struct eap2mschap *);
+
+static struct access_req
+ *access_request_new(struct eap2mschap *, u_int);
+static void access_request_free(struct access_req *);
+static int access_request_compar(struct access_req *,
+ struct access_req *);
+
+
+static struct access_req
+ *eap_recv(struct eap2mschap *, u_int, RADIUS_PACKET *);
+static struct access_req
+ *eap_recv_mschap(struct eap2mschap *, struct access_req *,
+ RADIUS_PACKET *, struct eap_chap *);
+static void eap_resp_mschap(struct eap2mschap *, struct access_req *,
+ RADIUS_PACKET *);
+static void eap_send_reject(struct access_req *, RADIUS_PACKET *, u_int);
+static const char
+ *eap_chap_status_string(enum eap_chap_status);
+static const char
+ *hex_string(const char *, size_t, char *, size_t);
+static time_t monotime(void);
+
+RB_PROTOTYPE_STATIC(access_reqt, access_req, tree, access_request_compar);
diff --git a/usr.sbin/radiusd/parse.y b/usr.sbin/radiusd/parse.y
index c1aac39f4..ec062b0f1 100644
--- a/usr.sbin/radiusd/parse.y
+++ b/usr.sbin/radiusd/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.23 2024/07/13 13:06:47 yasuoka Exp $ */
+/* $OpenBSD: parse.y,v 1.26 2024/07/14 16:09:23 yasuoka Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer
@@ -41,7 +41,10 @@ static struct radiusd_authentication authen;
static struct radiusd_module *conf_module = NULL;
static struct radiusd_client client;
-static struct radiusd_module *find_module(const char *);
+static struct radiusd_authentication
+ *create_authen(const char *, char **, int, char **);
+static struct radiusd_module
+ *find_module(const char *);
static void free_str_l(void *);
static struct radiusd_module_ref *create_module_ref(const char *);
static void radiusd_authentication_init(struct radiusd_authentication *);
@@ -92,8 +95,8 @@ typedef struct {
%}
%token INCLUDE LISTEN ON PORT CLIENT SECRET LOAD MODULE MSGAUTH_REQUIRED
-%token ACCOUNT ACCOUNTING AUTHENTICATE AUTHENTICATE_BY BY DECORATE_BY QUICK
-%token SET TO ERROR YES NO
+%token ACCOUNT ACCOUNTING AUTHENTICATE AUTHENTICATE_BY AUTHENTICATION_FILTER
+%token BY DECORATE_BY QUICK SET TO ERROR YES NO
%token STRING
%token NUMBER
%type optport optacct
@@ -385,40 +388,30 @@ key : STRING
;
authenticate : AUTHENTICATE str_l BY STRING optdeco {
- int i;
struct radiusd_authentication *auth;
- struct radiusd_module_ref *modref, *modreft;
- if ((auth = calloc(1,
- sizeof(struct radiusd_authentication))) == NULL) {
- yyerror("Out of memory: %s", strerror(errno));
- goto authenticate_error;
- }
- if ((auth->auth = create_module_ref($4)) == NULL)
- goto authenticate_error;
- auth->username = $2.v;
- TAILQ_INIT(&auth->deco);
- for (i = 0; i < $5.c; i++) {
- if ((modref = create_module_ref($5.v[i]))
- == NULL)
- goto authenticate_error;
- TAILQ_INSERT_TAIL(&auth->deco, modref, next);
- }
- TAILQ_INSERT_TAIL(&conf->authen, auth, next);
- auth = NULL;
- authenticate_error:
- if (auth != NULL) {
- free(auth->auth);
- TAILQ_FOREACH_SAFE(modref, &auth->deco, next,
- modreft) {
- TAILQ_REMOVE(&auth->deco, modref, next);
- free(modref);
- }
- free_str_l(&$2);
- }
- free(auth);
+ auth = create_authen($4, $2.v, $5.c, $5.v);
free($4);
free_str_l(&$5);
+ if (auth == NULL) {
+ free_str_l(&$2);
+ YYERROR;
+ } else
+ TAILQ_INSERT_TAIL(&conf->authen, auth, next);
+ }
+ | AUTHENTICATION_FILTER str_l BY STRING optdeco {
+ struct radiusd_authentication *auth;
+
+ auth = create_authen($4, $2.v, $5.c, $5.v);
+ free($4);
+ free_str_l(&$5);
+ if (auth == NULL) {
+ free_str_l(&$2);
+ YYERROR;
+ } else {
+ auth->isfilter = true;
+ TAILQ_INSERT_TAIL(&conf->authen, auth, next);
+ }
}
/* the followings are for backward compatibilities */
| AUTHENTICATE str_l optnl '{' {
@@ -609,6 +602,7 @@ lookup(char *s)
{ "accounting", ACCOUNTING},
{ "authenticate", AUTHENTICATE},
{ "authenticate-by", AUTHENTICATE_BY},
+ { "authentication-filter", AUTHENTICATION_FILTER},
{ "by", BY},
{ "client", CLIENT},
{ "decorate-by", DECORATE_BY},
@@ -940,6 +934,38 @@ out:
return (errors ? -1 : 0);
}
+static struct radiusd_authentication *
+create_authen(const char *byname, char **username, int decoc, char **deco)
+{
+ int i;
+ struct radiusd_authentication *auth;
+ struct radiusd_module_ref *modref, *modreft;
+
+ if ((auth = calloc(1, sizeof(struct radiusd_authentication)))
+ == NULL) {
+ yyerror("Out of memory: %s", strerror(errno));
+ return (NULL);
+ }
+ if ((auth->auth = create_module_ref(byname)) == NULL)
+ goto on_error;
+
+ auth->username = username;
+ TAILQ_INIT(&auth->deco);
+ for (i = 0; i < decoc; i++) {
+ if ((modref = create_module_ref(deco[i])) == NULL)
+ goto on_error;
+ TAILQ_INSERT_TAIL(&auth->deco, modref, next);
+ }
+ return (auth);
+ on_error:
+ TAILQ_FOREACH_SAFE(modref, &auth->deco, next, modreft) {
+ TAILQ_REMOVE(&auth->deco, modref, next);
+ free(modref);
+ }
+ free(auth);
+ return (NULL);
+}
+
static struct radiusd_module *
find_module(const char *name)
{
@@ -1010,6 +1036,8 @@ default_module_path(const char *name)
const char *path;
} module_paths[] = {
{ "bsdauth", "/usr/libexec/radiusd/radiusd_bsdauth" },
+ { "eap2mschap", "/usr/libexec/radiusd/radiusd_eap2mschap" },
+ { "file", "/usr/libexec/radiusd/radiusd_file" },
{ "ipcp", "/usr/libexec/radiusd/radiusd_ipcp" },
{ "radius", "/usr/libexec/radiusd/radiusd_radius" },
{ "standard", "/usr/libexec/radiusd/radiusd_standard" }
diff --git a/usr.sbin/radiusd/radius_subr.c b/usr.sbin/radiusd/radius_subr.c
new file mode 100644
index 000000000..eae99e396
--- /dev/null
+++ b/usr.sbin/radiusd/radius_subr.c
@@ -0,0 +1,75 @@
+/* $OpenBSD: radius_subr.c,v 1.1 2024/07/14 15:31:49 yasuoka Exp $ */
+
+/*
+ * Copyright (c) 2013, 2023 Internet Initiative Japan Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include
+
+#include
+#include
+
+#include "radius_subr.h"
+
+void
+radius_attr_hide(const char *secret, const char *authenticator,
+ const u_char *salt, u_char *plain, int plainlen)
+{
+ int i, j;
+ u_char b[16];
+ MD5_CTX md5ctx;
+
+ i = 0;
+ do {
+ MD5Init(&md5ctx);
+ MD5Update(&md5ctx, secret, strlen(secret));
+ if (i == 0) {
+ MD5Update(&md5ctx, authenticator, 16);
+ if (salt != NULL)
+ MD5Update(&md5ctx, salt, 2);
+ } else
+ MD5Update(&md5ctx, plain + i - 16, 16);
+ MD5Final(b, &md5ctx);
+
+ for (j = 0; j < 16 && i < plainlen; i++, j++)
+ plain[i] ^= b[j];
+ } while (i < plainlen);
+}
+
+void
+radius_attr_unhide(const char *secret, const char *authenticator,
+ const u_char *salt, u_char *crypt0, int crypt0len)
+{
+ int i, j;
+ u_char b[16];
+ MD5_CTX md5ctx;
+
+ i = 16 * ((crypt0len - 1) / 16);
+ while (i >= 0) {
+ MD5Init(&md5ctx);
+ MD5Update(&md5ctx, secret, strlen(secret));
+ if (i == 0) {
+ MD5Update(&md5ctx, authenticator, 16);
+ if (salt != NULL)
+ MD5Update(&md5ctx, salt, 2);
+ } else
+ MD5Update(&md5ctx, crypt0 + i - 16, 16);
+ MD5Final(b, &md5ctx);
+
+ for (j = 0; j < 16 && i + j < crypt0len; j++)
+ crypt0[i + j] ^= b[j];
+ i -= 16;
+ }
+}
diff --git a/usr.sbin/radiusd/radius_subr.h b/usr.sbin/radiusd/radius_subr.h
new file mode 100644
index 000000000..b3260d141
--- /dev/null
+++ b/usr.sbin/radiusd/radius_subr.h
@@ -0,0 +1,30 @@
+/* $OpenBSD: radius_subr.h,v 1.1 2024/07/14 15:31:49 yasuoka Exp $ */
+
+/*
+ * Copyright (c) 2013, 2023 Internet Initiative Japan Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef RADIUS_UTIL_H
+#define RADIUS_UTIL_H 1
+
+#include
+
+__BEGIN_DECLS
+void radius_attr_hide(const char *, const char *, const u_char *, u_char *,
+ int);
+void radius_attr_unhide(const char *, const char *, const u_char *,
+ u_char *, int);
+
+__END_DECLS
+#endif
diff --git a/usr.sbin/radiusd/radiusd.c b/usr.sbin/radiusd/radiusd.c
index 3409b25f2..31afc0e27 100644
--- a/usr.sbin/radiusd/radiusd.c
+++ b/usr.sbin/radiusd/radiusd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: radiusd.c,v 1.47 2024/07/13 13:06:47 yasuoka Exp $ */
+/* $OpenBSD: radiusd.c,v 1.50 2024/07/14 15:31:49 yasuoka Exp $ */
/*
* Copyright (c) 2013, 2023 Internet Initiative Japan Inc.
@@ -31,7 +31,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -47,6 +46,7 @@
#include "radiusd.h"
#include "radiusd_local.h"
+#include "radius_subr.h"
#include "log.h"
#include "util.h"
#include "imsg_subr.h"
@@ -66,13 +66,13 @@ static void raidus_query_access_request(struct radius_query *);
static void radius_query_access_response(struct radius_query *);
static void raidus_query_accounting_request(
struct radiusd_accounting *, struct radius_query *);
-static void radius_query_accounting_response(struct radius_query *);
+static void radius_query_accounting_response(
+ struct radius_query *);
+static const char *radius_query_client_secret(struct radius_query *);
static const char *radius_code_string(int);
static const char *radius_acct_status_type_string(uint32_t);
-static int radiusd_access_response_fixup (struct radius_query *);
-
-
-
+static int radiusd_access_response_fixup(struct radius_query *,
+ struct radius_query *, bool);
static void radiusd_module_reset_ev_handler(
struct radiusd_module *);
static int radiusd_module_imsg_read(struct radiusd_module *);
@@ -90,6 +90,8 @@ static void radiusd_module_userpass(struct radiusd_module *,
struct radius_query *);
static void radiusd_module_access_request(struct radiusd_module *,
struct radius_query *);
+static void radiusd_module_next_response(struct radiusd_module *,
+ struct radius_query *, RADIUS_PACKET *);
static void radiusd_module_request_decoration(
struct radiusd_module *, struct radius_query *);
static void radiusd_module_response_decoration(
@@ -536,6 +538,7 @@ radiusd_listen_handle_packet(struct radiusd_listen *listn,
strlcpy(q->username, username, sizeof(q->username));
q->id = ++radius_query_id_seq;
+ q->radiusd = listn->radiusd;
q->clientaddrlen = peerlen;
memcpy(&q->clientaddr, peer, peerlen);
q->listen = listn;
@@ -677,9 +680,12 @@ raidus_query_access_request(struct radius_query *q)
static void
radius_query_access_response(struct radius_query *q)
{
- int sz, res_id, res_code;
- char buf[NI_MAXHOST + NI_MAXSERV + 30];
+ int sz, res_id, res_code;
+ char buf[NI_MAXHOST + NI_MAXSERV + 30];
+ struct radius_query *q_last, *q0;
+ q_last = q;
+ next:
/* first or next response decoration */
for (;;) {
if (q->deco == NULL)
@@ -695,7 +701,24 @@ radius_query_access_response(struct radius_query *q)
return;
}
- if (radiusd_access_response_fixup(q) != 0)
+ if (q->prev != NULL) {
+ if (MODULE_DO_NEXTRES(q->prev->authen->auth->module)) {
+ if (radiusd_access_response_fixup(q->prev, q_last, 0)
+ != 0)
+ goto on_error;
+ q0 = q;
+ q = q->prev;
+ radiusd_module_next_response(q->authen->auth->module,
+ q, q_last->res);
+ q0->prev = NULL;
+ radiusd_access_request_aborted(q0);
+ return;
+ }
+ q = q->prev;
+ goto next;
+ }
+
+ if (radiusd_access_response_fixup(q, q_last, 1) != 0)
goto on_error;
res_id = radius_get_id(q->res);
@@ -767,6 +790,21 @@ radius_query_accounting_response(struct radius_query *q)
(struct sockaddr *)&q->clientaddr, q->clientaddrlen)) <= 0)
log_warn("Sending a RADIUS response failed");
}
+
+static const char *
+radius_query_client_secret(struct radius_query *q)
+{
+ struct radius_query *q0;
+ const char *client_secret = NULL;
+
+ for (q0 = q; q0 != NULL && client_secret == NULL; q0 = q0->prev) {
+ if (q0->client != NULL)
+ client_secret = q0->client->secret;
+ }
+ RADIUSD_ASSERT(client_secret != NULL);
+
+ return (client_secret);
+}
/***********************************************************************
* Callback functions from the modules
***********************************************************************/
@@ -805,14 +843,74 @@ on_error:
radiusd_access_request_aborted(q);
}
+void
+radiusd_access_request_next(struct radius_query *q, RADIUS_PACKET *pkt)
+{
+ struct radius_query *q_next = NULL;
+ static char username[256];
+ struct radiusd_authentication *authen;
+ int i;
+
+ RADIUSD_ASSERT(q->deco == NULL);
+
+ if (!q->authen->isfilter) {
+ log_warnx("q=%u `%s' requested next authentication, but it's "
+ "not authentication-filter", q->id,
+ q->authen->auth->module->name);
+ goto on_error;
+ }
+ if (radius_get_string_attr(pkt, RADIUS_TYPE_USER_NAME, username,
+ sizeof(username)) != 0)
+ username[0] = '\0';
+
+ for (authen = TAILQ_NEXT(q->authen, next); authen != NULL;
+ authen = TAILQ_NEXT(authen, next)) {
+ for (i = 0; authen->username[i] != NULL; i++) {
+ if (fnmatch(authen->username[i], username, 0)
+ == 0)
+ goto found;
+ }
+ }
+ found:
+ if (authen == NULL) { /* no more authentication */
+ log_warnx("q=%u module `%s' requested next authentication "
+ "no more `authenticate' matches", q->id,
+ q->authen->auth->module->name);
+ goto on_error;
+ }
+
+ if ((q_next = calloc(1, sizeof(struct radius_query))) == NULL) {
+ log_warn("%s: q=%u calloc: %m", __func__, q->id);
+ goto on_error;
+ }
+ q_next->id = ++radius_query_id_seq;
+ q_next->radiusd = q->radiusd;
+ q_next->req_id = q->req_id;
+ q_next->req = pkt;
+ radius_get_authenticator(pkt, q_next->req_auth);
+ q_next->authen = authen;
+ q_next->prev = q;
+ strlcpy(q_next->username, username, sizeof(q_next->username));
+ TAILQ_INSERT_TAIL(&q->radiusd->query, q_next, next);
+
+ raidus_query_access_request(q_next);
+ return;
+ on_error:
+ RADIUSD_ASSERT(q_next == NULL);
+ radius_delete_packet(pkt);
+ radiusd_access_request_aborted(q);
+}
+
void
radiusd_access_request_aborted(struct radius_query *q)
{
+ if (q->prev != NULL)
+ radiusd_access_request_aborted(q->prev);
if (q->req != NULL)
radius_delete_packet(q->req);
if (q->res != NULL)
radius_delete_packet(q->res);
- TAILQ_REMOVE(&q->listen->radiusd->query, q, next);
+ TAILQ_REMOVE(&q->radiusd->query, q, next);
free(q);
}
@@ -948,132 +1046,86 @@ radiusd_conf_init(struct radiusd *conf)
* Fix some attributes which depend the secret value.
*/
static int
-radiusd_access_response_fixup(struct radius_query *q)
+radiusd_access_response_fixup(struct radius_query *q, struct radius_query *q0,
+ bool islast)
{
- int res_id;
- size_t attrlen;
- u_char req_auth[16], attrbuf[256];
- const char *authen_secret = q->authen->auth->module->secret;
+ int res_id;
+ size_t attrlen;
+ u_char authen_req_auth[16], attrbuf[256];
+ const char *client_req_auth;
+ const char *authen_secret, *client_secret;
- radius_get_authenticator(q->req, req_auth);
+ authen_secret = q0->authen->auth->module->secret;
+ client_secret = (islast)? q->client->secret :
+ q->authen->auth->module->secret;
- if ((authen_secret != NULL &&
- strcmp(authen_secret, q->client->secret) != 0) ||
- timingsafe_bcmp(q->req_auth, req_auth, 16) != 0) {
- const char *olds = q->client->secret;
- const char *news = authen_secret;
-
- if (news == NULL)
- news = olds;
+ radius_get_authenticator(q0->req, authen_req_auth);
+ client_req_auth = q->req_auth;
+ if (client_secret == NULL && authen_secret == NULL)
+ return (0);
+ if (!(authen_secret != NULL && client_secret != NULL &&
+ strcmp(authen_secret, client_secret) == 0 &&
+ timingsafe_bcmp(authen_req_auth, client_req_auth, 16) == 0)) {
/* RFC 2865 Tunnel-Password */
attrlen = sizeof(attrbuf);
- if (radius_get_raw_attr(q->res, RADIUS_TYPE_TUNNEL_PASSWORD,
+ if (radius_get_raw_attr(q0->res, RADIUS_TYPE_TUNNEL_PASSWORD,
attrbuf, &attrlen) == 0) {
- radius_attr_unhide(news, req_auth,
- attrbuf, attrbuf + 3, attrlen - 3);
- radius_attr_hide(olds, q->req_auth,
- attrbuf, attrbuf + 3, attrlen - 3);
-
- radius_del_attr_all(q->res,
+ if (authen_secret != NULL)
+ radius_attr_unhide(authen_secret,
+ authen_req_auth, attrbuf, attrbuf + 3,
+ attrlen - 3);
+ if (client_secret != NULL)
+ radius_attr_hide(client_secret, client_req_auth,
+ attrbuf, attrbuf + 3, attrlen - 3);
+ radius_del_attr_all(q0->res,
RADIUS_TYPE_TUNNEL_PASSWORD);
- radius_put_raw_attr(q->res,
+ radius_put_raw_attr(q0->res,
RADIUS_TYPE_TUNNEL_PASSWORD, attrbuf, attrlen);
}
/* RFC 2548 Microsoft MPPE-{Send,Recv}-Key */
attrlen = sizeof(attrbuf);
- if (radius_get_vs_raw_attr(q->res, RADIUS_VENDOR_MICROSOFT,
+ if (radius_get_vs_raw_attr(q0->res, RADIUS_VENDOR_MICROSOFT,
RADIUS_VTYPE_MPPE_SEND_KEY, attrbuf, &attrlen) == 0) {
-
- /* Re-crypt the KEY */
- radius_attr_unhide(news, req_auth,
- attrbuf, attrbuf + 2, attrlen - 2);
- radius_attr_hide(olds, q->req_auth,
- attrbuf, attrbuf + 2, attrlen - 2);
-
- radius_del_vs_attr_all(q->res, RADIUS_VENDOR_MICROSOFT,
+ if (authen_secret != NULL)
+ radius_attr_unhide(authen_secret,
+ authen_req_auth, attrbuf, attrbuf + 2,
+ attrlen - 2);
+ if (client_secret != NULL)
+ radius_attr_hide(client_secret, client_req_auth,
+ attrbuf, attrbuf + 2, attrlen - 2);
+ radius_del_vs_attr_all(q0->res, RADIUS_VENDOR_MICROSOFT,
RADIUS_VTYPE_MPPE_SEND_KEY);
- radius_put_vs_raw_attr(q->res, RADIUS_VENDOR_MICROSOFT,
+ radius_put_vs_raw_attr(q0->res, RADIUS_VENDOR_MICROSOFT,
RADIUS_VTYPE_MPPE_SEND_KEY, attrbuf, attrlen);
}
attrlen = sizeof(attrbuf);
- if (radius_get_vs_raw_attr(q->res, RADIUS_VENDOR_MICROSOFT,
+ if (radius_get_vs_raw_attr(q0->res, RADIUS_VENDOR_MICROSOFT,
RADIUS_VTYPE_MPPE_RECV_KEY, attrbuf, &attrlen) == 0) {
+ if (authen_secret != NULL)
+ radius_attr_unhide(authen_secret,
+ authen_req_auth, attrbuf, attrbuf + 2,
+ attrlen - 2);
+ if (client_secret != NULL)
+ radius_attr_hide(client_secret, client_req_auth,
+ attrbuf, attrbuf + 2, attrlen - 2);
- /* Re-crypt the KEY */
- radius_attr_unhide(news, req_auth,
- attrbuf, attrbuf + 2, attrlen - 2);
- radius_attr_hide(olds, q->req_auth,
- attrbuf, attrbuf + 2, attrlen - 2);
-
- radius_del_vs_attr_all(q->res, RADIUS_VENDOR_MICROSOFT,
+ radius_del_vs_attr_all(q0->res, RADIUS_VENDOR_MICROSOFT,
RADIUS_VTYPE_MPPE_RECV_KEY);
- radius_put_vs_raw_attr(q->res, RADIUS_VENDOR_MICROSOFT,
+ radius_put_vs_raw_attr(q0->res, RADIUS_VENDOR_MICROSOFT,
RADIUS_VTYPE_MPPE_RECV_KEY, attrbuf, attrlen);
}
}
-
- res_id = radius_get_id(q->res);
+ res_id = radius_get_id(q0->res);
if (res_id != q->req_id) {
/* authentication server change the id */
- radius_set_id(q->res, q->req_id);
+ radius_set_id(q0->res, q->req_id);
}
return (0);
}
-void
-radius_attr_hide(const char *secret, const char *authenticator,
- const u_char *salt, u_char *plain, int plainlen)
-{
- int i, j;
- u_char b[16];
- MD5_CTX md5ctx;
-
- i = 0;
- do {
- MD5Init(&md5ctx);
- MD5Update(&md5ctx, secret, strlen(secret));
- if (i == 0) {
- MD5Update(&md5ctx, authenticator, 16);
- if (salt != NULL)
- MD5Update(&md5ctx, salt, 2);
- } else
- MD5Update(&md5ctx, plain + i - 16, 16);
- MD5Final(b, &md5ctx);
-
- for (j = 0; j < 16 && i < plainlen; i++, j++)
- plain[i] ^= b[j];
- } while (i < plainlen);
-}
-
-void
-radius_attr_unhide(const char *secret, const char *authenticator,
- const u_char *salt, u_char *crypt0, int crypt0len)
-{
- int i, j;
- u_char b[16];
- MD5_CTX md5ctx;
-
- i = 16 * ((crypt0len - 1) / 16);
- while (i >= 0) {
- MD5Init(&md5ctx);
- MD5Update(&md5ctx, secret, strlen(secret));
- if (i == 0) {
- MD5Update(&md5ctx, authenticator, 16);
- if (salt != NULL)
- MD5Update(&md5ctx, salt, 2);
- } else
- MD5Update(&md5ctx, crypt0 + i - 16, 16);
- MD5Final(b, &md5ctx);
-
- for (j = 0; j < 16 && i + j < crypt0len; j++)
- crypt0[i + j] ^= b[j];
- i -= 16;
- }
-}
-
static struct radius_query *
radiusd_find_query(struct radiusd *radiusd, u_int q_id)
{
@@ -1425,12 +1477,13 @@ radiusd_module_imsg(struct radiusd_module *module, struct imsg *imsg)
radius_put_string_attr(q->res,
RADIUS_TYPE_REPLY_MESSAGE, msg);
radius_set_response_authenticator(q->res,
- q->client->secret);
+ radius_query_client_secret(q));
radiusd_access_request_answer(q);
}
break;
}
case IMSG_RADIUSD_MODULE_ACCSREQ_ANSWER:
+ case IMSG_RADIUSD_MODULE_ACCSREQ_NEXT:
case IMSG_RADIUSD_MODULE_REQDECO_DONE:
case IMSG_RADIUSD_MODULE_RESDECO_DONE:
{
@@ -1441,6 +1494,9 @@ radiusd_module_imsg(struct radiusd_module *module, struct imsg *imsg)
case IMSG_RADIUSD_MODULE_ACCSREQ_ANSWER:
typestr = "ACCSREQ_ANSWER";
break;
+ case IMSG_RADIUSD_MODULE_ACCSREQ_NEXT:
+ typestr = "ACCSREQ_NEXT";
+ break;
case IMSG_RADIUSD_MODULE_REQDECO_DONE:
typestr = "REQDECO_DONE";
break;
@@ -1501,6 +1557,15 @@ radiusd_module_imsg(struct radiusd_module *module, struct imsg *imsg)
q->res = radpkt;
radiusd_access_request_answer(q);
break;
+ case IMSG_RADIUSD_MODULE_ACCSREQ_NEXT:
+ if (radpkt == NULL) {
+ log_warnx("q=%u wrong pkt from module",
+ q->id);
+ radiusd_access_request_aborted(q);
+ break;
+ }
+ radiusd_access_request_next(q, radpkt);
+ break;
case IMSG_RADIUSD_MODULE_RESDECO_DONE:
if (q->deco == NULL || q->deco->type !=
IMSG_RADIUSD_MODULE_RESDECO) {
@@ -1695,7 +1760,7 @@ radiusd_module_userpass(struct radiusd_module *module, struct radius_query *q)
userpass.q_id = q->id;
if (radius_get_user_password_attr(q->req, userpass.pass,
- sizeof(userpass.pass), q->client->secret) == 0)
+ sizeof(userpass.pass), radius_query_client_secret(q)) == 0)
userpass.has_pass = true;
else
userpass.has_pass = false;
@@ -1716,8 +1781,8 @@ static void
radiusd_module_access_request(struct radiusd_module *module,
struct radius_query *q)
{
- RADIUS_PACKET *radpkt;
- char pass[256];
+ RADIUS_PACKET *radpkt;
+ char pass[256];
if ((radpkt = radius_convert_packet(radius_get_data(q->req),
radius_get_length(q->req))) == NULL) {
@@ -1743,6 +1808,19 @@ radiusd_module_access_request(struct radiusd_module *module,
radius_delete_packet(radpkt);
}
+static void
+radiusd_module_next_response(struct radiusd_module *module,
+ struct radius_query *q, RADIUS_PACKET *pkt)
+{
+ if (imsg_compose_radius_packet(&module->ibuf,
+ IMSG_RADIUSD_MODULE_NEXTRES, q->id, pkt) == -1) {
+ log_warn("q=%u Could not send NEXTRES to `%s'", q->id,
+ module->name);
+ radiusd_access_request_aborted(q);
+ }
+ radiusd_module_reset_ev_handler(module);
+}
+
static void
radiusd_module_request_decoration(struct radiusd_module *module,
struct radius_query *q)
diff --git a/usr.sbin/radiusd/radiusd.conf.5 b/usr.sbin/radiusd/radiusd.conf.5
index 605132fbb..ef9107159 100644
--- a/usr.sbin/radiusd/radiusd.conf.5
+++ b/usr.sbin/radiusd/radiusd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: radiusd.conf.5,v 1.29 2024/07/10 05:40:08 jmc Exp $
+.\" $OpenBSD: radiusd.conf.5,v 1.32 2024/07/14 18:03:59 jmc Exp $
.\"
.\" Copyright (c) 2014 Esdenera Networks GmbH
.\" Copyright (c) 2014, 2023 Internet Initiative Japan Inc.
@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: July 10 2024 $
+.Dd $Mdocdate: July 14 2024 $
.Dt RADIUSD.CONF 5
.Os
.Sh NAME
@@ -77,12 +77,21 @@ The following modules are predefined:
.It Do bsdauth Dc module
The
.Dq bsdauth
-module
-provides authentication from the local system's
+module provides authentication from the local system's
.Xr authenticate 3
interface.
See
.Xr radiusd_bsdauth 8 .
+.It Do eap2mschap Dc module
+The
+.Dq eap2mschap
+module provides conversion from EAP-MSCHAPv2 to MS-CHAPv2.
+See
+.Xr radiusd_eap2mschap 8 .
+.It Do file Dc module
+The
+.Dq file
+module provides authentication by a local file.
.It Do ipcp Dc module
The
.Dq ipcp
@@ -218,6 +227,8 @@ account * to standard
.Sh SEE ALSO
.Xr radiusd 8 ,
.Xr radiusd_bsdauth 8 ,
+.Xr radiusd_eap2mschap 8 ,
+.Xr radiusd_file 8 ,
.Xr radiusd_ipcp 8 ,
.Xr radiusd_radius 8 ,
.Xr radiusd_standard 8
diff --git a/usr.sbin/radiusd/radiusd.h b/usr.sbin/radiusd/radiusd.h
index 047311aa0..240fcf951 100644
--- a/usr.sbin/radiusd/radiusd.h
+++ b/usr.sbin/radiusd/radiusd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: radiusd.h,v 1.8 2024/07/09 17:26:14 yasuoka Exp $ */
+/* $OpenBSD: radiusd.h,v 1.9 2024/07/14 15:27:57 yasuoka Exp $ */
#ifndef RADIUSD_H
#define RADIUSD_H 1
@@ -41,6 +41,8 @@ enum imsg_type {
/* Check the response's authenticator if the module doesn't */
IMSG_RADIUSD_MODULE_ACCSREQ_ANSWER,
IMSG_RADIUSD_MODULE_ACCSREQ_ABORTED,
+ IMSG_RADIUSD_MODULE_ACCSREQ_NEXT, /* fall through to the next auth */
+ IMSG_RADIUSD_MODULE_NEXTRES, /* receive the respo from tht next */
IMSG_RADIUSD_MODULE_REQDECO,
IMSG_RADIUSD_MODULE_REQDECO_DONE,
IMSG_RADIUSD_MODULE_RESDECO0_REQ, /* request pkt for RESDECO */
@@ -55,13 +57,14 @@ enum imsg_type {
/* Module sends LOAD when it becomes ready */
struct radiusd_module_load_arg {
- uint32_t cap; /* module capabity bits */
+ uint32_t cap; /* module capability bits */
#define RADIUSD_MODULE_CAP_USERPASS 0x01
#define RADIUSD_MODULE_CAP_ACCSREQ 0x02
#define RADIUSD_MODULE_CAP_REQDECO 0x04
#define RADIUSD_MODULE_CAP_RESDECO 0x08
#define RADIUSD_MODULE_CAP_ACCTREQ 0x10
#define RADIUSD_MODULE_CAP_CONTROL 0x20
+#define RADIUSD_MODULE_CAP_NEXTRES 0x40
};
struct radiusd_module_object {
diff --git a/usr.sbin/radiusd/radiusd/Makefile b/usr.sbin/radiusd/radiusd/Makefile
index 1598e9ed3..e2cf0be2e 100644
--- a/usr.sbin/radiusd/radiusd/Makefile
+++ b/usr.sbin/radiusd/radiusd/Makefile
@@ -1,8 +1,9 @@
-# $OpenBSD: Makefile,v 1.2 2024/07/09 17:26:14 yasuoka Exp $
+# $OpenBSD: Makefile,v 1.3 2024/07/14 15:31:49 yasuoka Exp $
PROG= radiusd
BINDIR= /usr/sbin
MAN= radiusd.8 radiusd.conf.5
-SRCS= radiusd.c parse.y log.c util.c imsg_subr.c control.c
+SRCS= radiusd.c radius_subr.c parse.y log.c util.c imsg_subr.c
+SRCS+= control.c
LDADD+= -lradius -lcrypto -levent -lutil
DPADD= ${LIBRADIUS} ${LIBCRYPTO} ${LIBEVENT} ${LIBUTIL}
diff --git a/usr.sbin/radiusd/radiusd_eap2mschap.8 b/usr.sbin/radiusd/radiusd_eap2mschap.8
new file mode 100644
index 000000000..554153a85
--- /dev/null
+++ b/usr.sbin/radiusd/radiusd_eap2mschap.8
@@ -0,0 +1,86 @@
+.\" $OpenBSD: radiusd_eap2mschap.8,v 1.2 2024/07/14 18:09:05 jmc Exp $
+.\"
+.\" Copyright (c) 2024 Internet Initiative Japan Inc.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" The following requests are required for all man pages.
+.\"
+.Dd $Mdocdate: July 14 2024 $
+.Dt RADIUSD_EAP2MSCHAP 8
+.Os
+.Sh NAME
+.Nm radiusd_eap2mschap
+.Nd provides conversion from EAP-MSCHAPv2 to MSCHAPv2
+.Sh SYNOPSIS
+.Nm radiusd_eap2mschap
+.Sh DESCRIPTION
+The
+.Nm
+module is executed by
+.Xr radiusd 8
+as an
+.Dq authentication-filter
+module to provide conversion from EAP-MSCHAPv2 authentication messages to
+MS-CHAPv2 authentication messages.
+.Sh CONFIGURATIONS
+The
+.Nm
+module supports the following configuration key and value:
+.Bl -tag -width Ds
+.It Ic chap-name Ar name
+Specify the name in CHAP.
+The default is
+.Dq radiusd .
+.El
+.Sh FILES
+.Bl -tag -width "/usr/libexec/radiusd/radiusd_eap2mschap" -compact
+.It Pa /usr/libexec/radiusd/radiusd_eap2mschap
+.Dq eap2mschap
+module executable.
+.El
+.Sh EXAMPLES
+An example showing the
+.Nm
+module providing an authentication server that supports EAP-MSCHAPv2.
+Although the
+.Xr radiusd_file 8
+module itself doesn't support any EAP methods,
+when used with the
+.Nm
+module it becomes possible to support EAP-MSCHAPv2.
+.Pp
+.Pa /etc/radiusd.conf :
+.Bd -literal -offset indent
+listen on 192.168.0.1
+client 192.168.0.0/24 {
+ secret SECRET
+}
+
+module file {
+ set path "/etc/npppd/npppd-users"
+}
+module eap2mschap
+
+authentication-filter * by eap2mschap
+authenticate * by file
+.Ed
+.Sh SEE ALSO
+.Xr authenticate 3 ,
+.Xr radiusd.conf 5 ,
+.Xr radiusd 8
+.Sh HISTORY
+The
+.Nm
+daemon first appeared in
+.Ox 7.6 .
diff --git a/usr.sbin/radiusd/radiusd_eap2mschap.c b/usr.sbin/radiusd/radiusd_eap2mschap.c
new file mode 100644
index 000000000..2e0b252e5
--- /dev/null
+++ b/usr.sbin/radiusd/radiusd_eap2mschap.c
@@ -0,0 +1,781 @@
+/* $OpenBSD: radiusd_eap2mschap.c,v 1.1 2024/07/14 16:09:23 yasuoka Exp $ */
+
+/*
+ * Copyright (c) 2024 Internet Initiative Japan Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "radiusd.h"
+#include "radiusd_module.h"
+#include "radius_subr.h"
+#include "log.h"
+
+#define EAP_TIMEOUT 60
+
+#include "eap2mschap_local.h"
+
+int
+main(int argc, char *argv[])
+{
+ struct module_handlers handlers = {
+ .start = eap2mschap_start,
+ .config_set = eap2mschap_config_set,
+ .stop = eap2mschap_stop,
+ .access_request = eap2mschap_access_request,
+ .next_response = eap2mschap_next_response
+ };
+ struct eap2mschap eap2mschap;
+
+ eap2mschap_init(&eap2mschap);
+ if ((eap2mschap.base = module_create(STDIN_FILENO, &eap2mschap,
+ &handlers)) == NULL)
+ err(1, "module_create");
+
+ module_drop_privilege(eap2mschap.base, 0);
+ setproctitle("[main]");
+
+ module_load(eap2mschap.base);
+ event_init();
+ log_init(0);
+
+ if (pledge("stdio", NULL) == -1)
+ err(1, "pledge");
+
+ module_start(eap2mschap.base);
+ event_loop(0);
+ module_destroy(eap2mschap.base);
+
+ exit(EXIT_SUCCESS);
+}
+
+void
+eap2mschap_init(struct eap2mschap *self)
+{
+ memset(self, 0, sizeof(struct eap2mschap));
+ RB_INIT(&self->eapt);
+ TAILQ_INIT(&self->reqq);
+}
+
+void
+eap2mschap_start(void *ctx)
+{
+ struct eap2mschap *self = ctx;
+
+ if (self->chap_name[0] == '\0')
+ strlcpy(self->chap_name, "radiusd", sizeof(self->chap_name));
+
+ module_send_message(self->base, IMSG_OK, NULL);
+
+ evtimer_set(&self->ev_eapt, eap2mschap_on_eapt, self);
+}
+
+void
+eap2mschap_config_set(void *ctx, const char *name, int argc,
+ char * const * argv)
+{
+ struct eap2mschap *self = ctx;
+ const char *errmsg = "none";
+
+ if (strcmp(name, "chap-name") == 0) {
+ SYNTAX_ASSERT(argc == 1,
+ "specify 1 argument for `chap-name'");
+ if (strlcpy(self->chap_name, argv[0], sizeof(self->chap_name))
+ >= sizeof(self->chap_name)) {
+ module_send_message(self->base, IMSG_NG,
+ "chap-name is too long");
+ return;
+ }
+ } else if (strcmp(name, "_debug") == 0)
+ log_init(1);
+ else if (strncmp(name, "_", 1) == 0)
+ /* ignore */;
+
+ module_send_message(self->base, IMSG_OK, NULL);
+ return;
+ syntax_error:
+ module_send_message(self->base, IMSG_NG, "%s", errmsg);
+}
+
+void
+eap2mschap_stop(void *ctx)
+{
+ struct eap2mschap *self = ctx;
+ struct access_req *req, *reqt;
+
+ evtimer_del(&self->ev_eapt);
+
+ RB_FOREACH_SAFE(req, access_reqt, &self->eapt, reqt)
+ access_request_free(req);
+ TAILQ_FOREACH_SAFE(req, &self->reqq, next, reqt)
+ access_request_free(req);
+}
+
+void
+eap2mschap_access_request(void *ctx, u_int q_id, const u_char *reqpkt,
+ size_t reqpktlen)
+{
+ struct eap2mschap *self = ctx;
+ struct access_req *req = NULL;
+ RADIUS_PACKET *pkt;
+
+ if ((pkt = radius_convert_packet(reqpkt, reqpktlen)) == NULL) {
+ log_warn("%s: radius_convert_packet() failed", __func__);
+ goto on_fail;
+ }
+
+ if (radius_has_attr(pkt, RADIUS_TYPE_EAP_MESSAGE)) {
+ if ((req = eap_recv(self, q_id, pkt)) == NULL)
+ return;
+ TAILQ_INSERT_TAIL(&self->reqq, req, next);
+ radius_delete_packet(pkt);
+ return;
+ }
+ if (pkt != NULL)
+ radius_delete_packet(pkt);
+ module_accsreq_next(self->base, q_id, reqpkt, reqpktlen);
+ return;
+ on_fail:
+ if (pkt != NULL)
+ radius_delete_packet(pkt);
+ module_accsreq_aborted(self->base, q_id);
+}
+
+void
+eap2mschap_next_response(void *ctx, u_int q_id, const u_char *respkt,
+ size_t respktlen)
+{
+ struct eap2mschap *self = ctx;
+ struct access_req *req = NULL;
+ RADIUS_PACKET *pkt = NULL;
+
+ TAILQ_FOREACH(req, &self->reqq, next) {
+ if (req->q_id == q_id)
+ break;
+ }
+ if (req == NULL) {
+ module_accsreq_answer(self->base, q_id, respkt, respktlen);
+ return;
+ }
+ TAILQ_REMOVE(&self->reqq, req, next);
+ if ((pkt = radius_convert_packet(respkt, respktlen)) == NULL) {
+ log_warn("%s: q=%u radius_convert_packet() failed", __func__,
+ q_id);
+ goto on_fail;
+ }
+ eap_resp_mschap(self, req, pkt);
+ return;
+ on_fail:
+ if (pkt != NULL)
+ radius_delete_packet(pkt);
+ module_accsreq_aborted(self->base, q_id);
+}
+
+void
+eap2mschap_on_eapt(int fd, short ev, void *ctx)
+{
+ struct eap2mschap *self = ctx;
+ time_t currtime;
+ struct access_req *req, *reqt;
+
+ currtime = monotime();
+ RB_FOREACH_SAFE(req, access_reqt, &self->eapt, reqt) {
+ if (currtime - req->eap_time > EAP_TIMEOUT) {
+ RB_REMOVE(access_reqt, &self->eapt, req);
+ access_request_free(req);
+ }
+ }
+ TAILQ_FOREACH_SAFE(req, &self->reqq, next, reqt) {
+ if (currtime - req->eap_time > EAP_TIMEOUT) {
+ TAILQ_REMOVE(&self->reqq, req, next);
+ access_request_free(req);
+ }
+ }
+
+ eap2mschap_reset_eaptimer(self);
+}
+
+void
+eap2mschap_reset_eaptimer(struct eap2mschap *self)
+{
+ struct timeval tv = { 4, 0 };
+
+ if ((!RB_EMPTY(&self->eapt) || !TAILQ_EMPTY(&self->reqq)) &&
+ evtimer_pending(&self->ev_eapt, NULL) == 0)
+ evtimer_add(&self->ev_eapt, &tv);
+}
+
+struct access_req *
+access_request_new(struct eap2mschap *self, u_int q_id)
+{
+ struct access_req *req = NULL;
+
+ if ((req = calloc(1, sizeof(struct access_req))) == NULL) {
+ log_warn("%s: Out of memory", __func__);
+ return (NULL);
+ }
+ req->eap2mschap = self;
+ req->q_id = q_id;
+
+ EAP2MSCHAP_DBG("%s(%p)", __func__, req);
+ return (req);
+}
+
+void
+access_request_free(struct access_req *req)
+{
+ EAP2MSCHAP_DBG("%s(%p)", __func__, req);
+ free(req->username);
+ if (req->pkt != NULL)
+ radius_delete_packet(req->pkt);
+ free(req);
+}
+
+int
+access_request_compar(struct access_req *a, struct access_req *b)
+{
+ return (memcmp(a->state, b->state, sizeof(a->state)));
+}
+
+RB_GENERATE_STATIC(access_reqt, access_req, tree, access_request_compar);
+
+/***********************************************************************
+ * EAP related functions
+ * Specfication: RFC 3748 [MS-CHAP]
+ ***********************************************************************/
+struct access_req *
+eap_recv(struct eap2mschap *self, u_int q_id, RADIUS_PACKET *pkt)
+{
+ char buf[512], buf2[80];
+ size_t msgsiz = 0;
+ struct eap *eap;
+ int namesiz;
+ struct access_req *req = NULL;
+ char state[16];
+ size_t statesiz;
+ struct access_req key;
+
+ /*
+ * Check the message authenticator. OK if it exists since the check
+ * is done by radiusd(8).
+ */
+ if (!radius_has_attr(pkt, RADIUS_TYPE_MESSAGE_AUTHENTICATOR)) {
+ log_warnx("q=%u Received EAP message but has no message "
+ "authenticator", q_id);
+ goto fail;
+ }
+
+ if (radius_get_raw_attr_cat(pkt, RADIUS_TYPE_EAP_MESSAGE, NULL,
+ &msgsiz) != 0) {
+ log_warnx("q=%u Received EAP message is too big %zu", q_id,
+ msgsiz);
+ goto fail;
+ }
+ msgsiz = sizeof(buf);
+ if (radius_get_raw_attr_cat(pkt, RADIUS_TYPE_EAP_MESSAGE, buf,
+ &msgsiz) != 0) {
+ log_warnx("%s: radius_get_raw_attr_cat() failed", __func__);
+ goto fail;
+ }
+
+ eap = (struct eap *)buf;
+ if (msgsiz < offsetof(struct eap, value[1]) ||
+ ntohs(eap->length) > msgsiz) {
+ log_warnx("q=%u Received EAP message has wrong in size: "
+ "received length %zu eap.length=%u", q_id, msgsiz,
+ ntohs(eap->length));
+ goto fail;
+ }
+
+ EAP2MSCHAP_DBG("q=%u Received EAP code=%d type=%d", q_id,
+ (int)eap->code, (int)eap->value[0]);
+
+ if (eap->code != EAP_CODE_RESPONSE) {
+ log_warnx("q=%u Received EAP message has unexpected code %u",
+ q_id, (unsigned)eap->code);
+ goto fail;
+ }
+
+ if (eap->value[0] == EAP_TYPE_IDENTITY) {
+ /*
+ * Handle EAP-Indentity
+ */
+ struct eap_mschap_challenge *chall;
+ RADIUS_PACKET *radres = NULL;
+
+ if ((req = access_request_new(self, q_id)) == NULL)
+ goto fail;
+ req->eap_time = monotime();
+ arc4random_buf(req->state, sizeof(req->state));
+ arc4random_buf(req->chall, sizeof(req->chall));
+
+ namesiz = ntohs(eap->length) - offsetof(struct eap, value[1]);
+ log_info("q=%u EAP state=%s EAP-Identity %.*s ",
+ q_id, hex_string(req->state, sizeof(req->state),
+ buf2, sizeof(buf2)), namesiz, eap->value + 1);
+ namesiz = strlen(self->chap_name);
+
+ /*
+ * Start MS-CHAP-V2
+ */
+ msgsiz = offsetof(struct eap_mschap_challenge,
+ chap_name[namesiz]);
+ chall = (struct eap_mschap_challenge *)buf;
+ chall->eap.code = EAP_CODE_REQUEST;
+ chall->eap.id = ++req->eap_id;
+ chall->eap.length = htons(msgsiz);
+ chall->eap_type = EAP_TYPE_MSCHAPV2;
+ chall->chap.code = CHAP_CHALLENGE;
+ chall->chap.id = ++req->chap_id;
+ chall->chap.length = htons(msgsiz -
+ offsetof(struct eap_mschap_challenge, chap));
+ chall->challsiz = sizeof(chall->chall);
+ memcpy(chall->chall, req->chall, sizeof(chall->chall));
+ memcpy(chall->chap_name, self->chap_name, namesiz);
+
+ if ((radres = radius_new_response_packet(
+ RADIUS_CODE_ACCESS_CHALLENGE, pkt)) == NULL) {
+ log_warn("%s: radius_new_response_packet() failed",
+ __func__);
+ goto fail;
+ }
+ radius_put_raw_attr(radres, RADIUS_TYPE_EAP_MESSAGE, buf,
+ msgsiz);
+ radius_put_raw_attr(radres, RADIUS_TYPE_STATE, req->state,
+ sizeof(req->state));
+ radius_put_uint32_attr(radres, RADIUS_TYPE_SESSION_TIMEOUT,
+ EAP_TIMEOUT);
+ radius_put_message_authenticator(radres, ""); /* dummy */
+
+ req->eap_chap_status = EAP_CHAP_CHALLENGE_SENT;
+ module_accsreq_answer(self->base, req->q_id,
+ radius_get_data(radres), radius_get_length(radres));
+
+ radius_delete_packet(pkt);
+ radius_delete_packet(radres);
+ RB_INSERT(access_reqt, &self->eapt, req);
+ eap2mschap_reset_eaptimer(self);
+
+ return (NULL);
+ }
+ /* Other than EAP-Identity */
+ statesiz = sizeof(state);
+ if (radius_get_raw_attr(pkt, RADIUS_TYPE_STATE, state, &statesiz) != 0)
+ {
+ log_info("q=%u received EAP message (type=%d) doesn't have a "
+ "proper state attribute", q_id, eap->value[0]);
+ goto fail;
+ }
+
+ memcpy(key.state, state, statesiz);
+ if ((req = RB_FIND(access_reqt, &self->eapt, &key)) == NULL) {
+ log_info("q=%u received EAP message (type=%d) no context for "
+ "the state=%s", q_id, eap->value[0], hex_string(state,
+ statesiz, buf2, sizeof(buf2)));
+ goto fail;
+ }
+ req->eap_time = monotime();
+ req->q_id = q_id;
+ switch (eap->value[0]) {
+ case EAP_TYPE_NAK:
+ log_info("q=%u EAP state=%s NAK received", q_id,
+ hex_string(state, statesiz, buf2, sizeof(buf2)));
+ eap_send_reject(req, pkt, q_id);
+ goto fail;
+ case EAP_TYPE_MSCHAPV2:
+ if (msgsiz < offsetof(struct eap, value[1])) {
+ log_warnx(
+ "q=%u EAP state=%s Received message has wrong in "
+ "size for EAP-MS-CHAPV2: received length %zu "
+ "eap.length=%u", q_id, hex_string(state, statesiz,
+ buf2, sizeof(buf2)), msgsiz, ntohs(eap->length));
+ goto fail;
+ }
+ req = eap_recv_mschap(self, req, pkt, (struct eap_chap *)eap);
+
+ break;
+ default:
+ log_warnx(
+ "q=%u EAP state=%s EAP unknown type=%u receieved.",
+ q_id, hex_string(state, statesiz, buf2, sizeof(buf2)),
+ eap->value[0]);
+ goto fail;
+ }
+
+ return (req);
+ fail:
+ radius_delete_packet(pkt);
+ return (NULL);
+}
+
+struct access_req *
+eap_recv_mschap(struct eap2mschap *self, struct access_req *req,
+ RADIUS_PACKET *pkt, struct eap_chap *chap)
+{
+ size_t eapsiz;
+ char buf[80];
+
+ EAP2MSCHAP_DBG("%s(%p)", __func__, req);
+
+ eapsiz = ntohs(chap->eap.length);
+ switch (chap->chap.code) {
+ case CHAP_RESPONSE:
+ {
+ struct eap_mschap_response *resp;
+ struct radius_ms_chap2_response rr;
+ size_t namelen;
+ bool reset_username = false;
+
+ if (req->eap_chap_status != EAP_CHAP_CHALLENGE_SENT)
+ goto failmsg;
+ resp = (struct eap_mschap_response *)chap;
+ if (eapsiz < sizeof(struct eap_mschap_response) ||
+ htons(resp->chap.length) <
+ sizeof(struct eap_mschap_response) -
+ offsetof(struct eap_mschap_response, chap)) {
+ log_warnx(
+ "q=%u EAP state=%s Received EAP message has wrong "
+ "in size: received length %zu eap.length=%u "
+ "chap.length=%u valuesize=%u", req->q_id,
+ hex_string(req->state, sizeof(req->state), buf,
+ sizeof(buf)), eapsiz, ntohs(resp->eap.length),
+ ntohs(resp->chap.length), resp->chap.value[9]);
+ goto fail;
+ }
+ log_info("q=%u EAP state=%s Received "
+ "CHAP-Response", req->q_id, hex_string(req->state,
+ sizeof(req->state), buf, sizeof(buf)));
+
+ /* Unknown identity in EAP and got the username in CHAP */
+ namelen = ntohs(resp->chap.length) -
+ (offsetof(struct eap_mschap_response, chap_name[0]) -
+ offsetof(struct eap_mschap_response, chap));
+ if ((req->username == NULL || req->username[0] == '\0') &&
+ namelen > 0) {
+ free(req->username);
+ if ((req->username = strndup(resp->chap_name, namelen))
+ == NULL) {
+ log_warn("%s: strndup", __func__);
+ goto fail;
+ }
+ log_info("q=%u EAP state=%s username=%s", req->q_id,
+ hex_string(req->state, sizeof(req->state), buf,
+ sizeof(buf)), req->username);
+ reset_username = true;
+ }
+
+ rr.ident = resp->chap.id;
+ rr.flags = resp->flags;
+ memcpy(rr.peerchall, resp->peerchall, sizeof(rr.peerchall));
+ memcpy(rr.reserved, resp->reserved, sizeof(rr.reserved));
+ memcpy(rr.ntresponse, resp->ntresponse, sizeof(rr.ntresponse));
+
+ radius_del_attr_all(pkt, RADIUS_TYPE_EAP_MESSAGE);
+ radius_del_attr_all(pkt, RADIUS_TYPE_STATE);
+
+ if (reset_username) {
+ radius_del_attr_all(pkt, RADIUS_TYPE_USER_NAME);
+ radius_put_string_attr(pkt, RADIUS_TYPE_USER_NAME,
+ req->username);
+ }
+ radius_put_vs_raw_attr(pkt, RADIUS_VENDOR_MICROSOFT,
+ RADIUS_VTYPE_MS_CHAP_CHALLENGE, req->chall,
+ sizeof(req->chall));
+ radius_put_vs_raw_attr(pkt, RADIUS_VENDOR_MICROSOFT,
+ RADIUS_VTYPE_MS_CHAP2_RESPONSE, &rr, sizeof(rr));
+ req->eap_chap_status = EAP_CHAP_CHALLENGE_SENT;
+ RB_REMOVE(access_reqt, &self->eapt, req);
+ module_accsreq_next(self->base, req->q_id, radius_get_data(pkt),
+ radius_get_length(pkt));
+ return (req);
+ }
+ case CHAP_SUCCESS:
+ {
+ struct eap eapres;
+ RADIUS_PACKET *radres = NULL;
+ unsigned int i;
+ uint8_t attr[256];
+ size_t attrlen;
+
+ /* Receiving Success-Reponse */
+ if (chap->eap.code != EAP_CODE_RESPONSE) {
+ log_info("q=%u EAP state=%s Received "
+ "CHAP-Success but EAP code is wrong %u", req->q_id,
+ hex_string(req->state, sizeof(req->state), buf,
+ sizeof(buf)), chap->eap.code);
+ goto fail;
+ }
+ if (req->eap_chap_status == EAP_CHAP_SUCCESS_REQUEST_SENT)
+ eapres.id = ++req->eap_id;
+ else if (req->eap_chap_status != EAP_CHAP_SUCCESS)
+ goto failmsg;
+
+ req->eap_chap_status = EAP_CHAP_SUCCESS;
+ eapres.code = EAP_CODE_SUCCESS;
+ eapres.length = htons(sizeof(struct eap));
+
+ if ((radres = radius_new_response_packet(
+ RADIUS_CODE_ACCESS_ACCEPT, pkt)) == NULL) {
+ log_warn("%s: radius_new_response_packet failed",
+ __func__);
+ goto fail;
+ }
+
+ radius_put_raw_attr(radres, RADIUS_TYPE_EAP_MESSAGE, &eapres,
+ sizeof(struct eap));
+ radius_put_raw_attr(radres, RADIUS_TYPE_STATE, req->state,
+ sizeof(req->state));
+ /* notice authenticated username */
+ radius_put_string_attr(radres, RADIUS_TYPE_USER_NAME,
+ req->username);
+ radius_put_message_authenticator(radres, ""); /* dummy */
+
+ /* restore attributes */
+ for (i = 0; i < nitems(preserve_attrs); i++) {
+ attrlen = sizeof(attr);
+ if (preserve_attrs[i].vendor == 0) {
+ if (radius_get_raw_attr(req->pkt,
+ preserve_attrs[i].type, &attr, &attrlen)
+ == 0)
+ radius_put_raw_attr(radres,
+ preserve_attrs[i].type, &attr,
+ attrlen);
+ } else {
+ if (radius_get_vs_raw_attr(req->pkt,
+ preserve_attrs[i].vendor,
+ preserve_attrs[i].type, &attr, &attrlen)
+ == 0)
+ radius_put_vs_raw_attr(radres,
+ preserve_attrs[i].vendor,
+ preserve_attrs[i].type, &attr,
+ attrlen);
+ }
+ }
+
+ module_accsreq_answer(self->base, req->q_id,
+ radius_get_data(radres), radius_get_length(radres));
+
+ radius_delete_packet(pkt);
+ radius_delete_packet(radres);
+
+ return (NULL);
+ }
+ break;
+ }
+ failmsg:
+ log_warnx(
+ "q=%u EAP state=%s Can't handle the received EAP-CHAP message "
+ "(chap.code=%d) in EAP CHAP state=%s", req->q_id, hex_string(
+ req->state, sizeof(req->state), buf, sizeof(buf)), chap->chap.code,
+ eap_chap_status_string(req->eap_chap_status));
+ fail:
+ radius_delete_packet(pkt);
+ return (NULL);
+}
+
+void
+eap_resp_mschap(struct eap2mschap *self, struct access_req *req,
+ RADIUS_PACKET *pkt)
+{
+ bool accept = false;
+ int id, code;
+ char resp[256 + 1], buf[80];
+ size_t respsiz = 0, eapsiz;
+ struct {
+ struct eap_chap chap;
+ char space[256];
+ } eap;
+
+ code = radius_get_code(pkt);
+ id = radius_get_id(pkt);
+ EAP2MSCHAP_DBG("id=%d code=%d", id, code);
+ switch (code) {
+ case RADIUS_CODE_ACCESS_ACCEPT:
+ case RADIUS_CODE_ACCESS_REJECT:
+ {
+ RADIUS_PACKET *respkt;
+
+ respsiz = sizeof(resp);
+ if (code == RADIUS_CODE_ACCESS_ACCEPT) {
+ accept = true;
+ if (radius_get_vs_raw_attr(pkt, RADIUS_VENDOR_MICROSOFT,
+ RADIUS_VTYPE_MS_CHAP2_SUCCESS, &resp, &respsiz)
+ != 0) {
+ log_warnx("q=%u EAP state=%s no "
+ "MS-CHAP2-Success attribute", req->q_id,
+ hex_string(req->state, sizeof(req->state),
+ buf, sizeof(buf)));
+ goto fail;
+ }
+ } else {
+ if (radius_get_vs_raw_attr(pkt, RADIUS_VENDOR_MICROSOFT,
+ RADIUS_VTYPE_MS_CHAP_ERROR, &resp, &respsiz)
+ != 0) {
+ resp[0] = ++req->chap_id;
+ snprintf(resp + 1, sizeof(resp) - 1,
+ "E=691 R=0 V=3");
+ respsiz = 1 + strlen(resp + 1);
+ }
+ }
+
+ /* Send EAP-CHAP "Success-Request" or "Failure-Request" */
+ if ((respkt = radius_new_request_packet(accept
+ ? RADIUS_CODE_ACCESS_CHALLENGE
+ : RADIUS_CODE_ACCESS_REJECT)) == NULL) {
+ log_warn("%s: radius_new_request_packet", __func__);
+ goto fail;
+ }
+ radius_set_id(respkt, id);
+
+ eapsiz = offsetof(struct eap_chap, chap.value[respsiz - 1]);
+ eap.chap.eap.code = EAP_CODE_REQUEST;
+ eap.chap.eap.id = ++req->eap_id;
+ eap.chap.eap.length = htons(eapsiz);
+ eap.chap.eap_type = EAP_TYPE_MSCHAPV2;
+ eap.chap.chap.id = resp[0];
+ eap.chap.chap.length = htons(
+ offsetof(struct chap, value[respsiz - 1]));
+ memcpy(eap.chap.chap.value, resp + 1, respsiz - 1);
+ if (accept)
+ eap.chap.chap.code = CHAP_SUCCESS;
+ else
+ eap.chap.chap.code = CHAP_FAILURE;
+
+ radius_put_raw_attr(respkt, RADIUS_TYPE_STATE, req->state,
+ sizeof(req->state));
+ radius_put_raw_attr(respkt, RADIUS_TYPE_EAP_MESSAGE, &eap,
+ eapsiz);
+
+ module_accsreq_answer(req->eap2mschap->base, req->q_id,
+ radius_get_data(respkt), radius_get_length(respkt));
+ radius_delete_packet(respkt);
+ if (accept)
+ req->eap_chap_status = EAP_CHAP_SUCCESS_REQUEST_SENT;
+ else
+ req->eap_chap_status = EAP_CHAP_FAILURE_REQUEST_SENT;
+
+ RB_INSERT(access_reqt, &req->eap2mschap->eapt, req);
+ eap2mschap_reset_eaptimer(self);
+ req->pkt = pkt;
+ pkt = NULL;
+ break;
+ }
+ default:
+ log_warnx("q=%u Received unknown RADIUS packet code=%d",
+ req->q_id, code);
+ goto fail;
+ }
+ return;
+ fail:
+ if (pkt != NULL)
+ radius_delete_packet(pkt);
+ module_accsreq_aborted(self->base, req->q_id);
+ access_request_free(req);
+ return;
+}
+
+void
+eap_send_reject(struct access_req *req, RADIUS_PACKET *reqp, u_int q_id)
+{
+ RADIUS_PACKET *resp;
+ struct {
+ uint8_t code;
+ uint8_t id;
+ uint16_t length;
+ } __packed eap;
+
+ resp = radius_new_response_packet(RADIUS_CODE_ACCESS_REJECT, reqp);
+ if (resp == NULL) {
+ log_warn("%s: radius_new_response_packet() failed", __func__);
+ module_accsreq_aborted(req->eap2mschap->base, q_id);
+ return;
+ }
+ memset(&eap, 0, sizeof(eap)); /* just in case */
+ eap.code = EAP_CODE_REQUEST;
+ eap.id = ++req->eap_id;
+ eap.length = htons(sizeof(eap));
+ radius_put_raw_attr(resp, RADIUS_TYPE_EAP_MESSAGE, &eap,
+ ntohs(eap.length));
+ module_accsreq_answer(req->eap2mschap->base, q_id,
+ radius_get_data(resp), radius_get_length(resp));
+ radius_delete_packet(resp);
+}
+
+const char *
+eap_chap_status_string(enum eap_chap_status status)
+{
+ switch (status) {
+ case EAP_CHAP_NONE: return "None";
+ case EAP_CHAP_CHALLENGE_SENT: return "Challenge-Sent";
+ case EAP_CHAP_SUCCESS_REQUEST_SENT:
+ return "Success-Request-Sent";
+ case EAP_CHAP_FAILURE_REQUEST_SENT:
+ return "Failure-Request-Sent";
+ case EAP_CHAP_CHANGE_PASSWORD_SENT:
+ return "Change-Password-Sent";
+ case EAP_CHAP_SUCCESS: return "Success";
+ case EAP_CHAP_FAILED: return "Failed";
+ }
+ return "Error";
+}
+
+/***********************************************************************
+ * Miscellaneous functions
+ ***********************************************************************/
+const char *
+hex_string(const char *bytes, size_t byteslen, char *buf, size_t bufsiz)
+{
+ const char hexstr[] = "0123456789abcdef";
+ unsigned i, j;
+
+ for (i = 0, j = 0; i < byteslen && j + 2 < bufsiz; i++, j += 2) {
+ buf[j] = hexstr[(bytes[i] & 0xf0) >> 4];
+ buf[j + 1] = hexstr[bytes[i] & 0xf];
+ }
+
+ if (i < byteslen)
+ return (NULL);
+ buf[j] = '\0';
+ return (buf);
+}
+
+time_t
+monotime(void)
+{
+ struct timespec ts;
+
+ if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
+ fatal("clock_gettime(CLOCK_MONOTONIC,) failed");
+
+ return (ts.tv_sec);
+}
diff --git a/usr.sbin/radiusd/radiusd_eap2mschap/Makefile b/usr.sbin/radiusd/radiusd_eap2mschap/Makefile
new file mode 100644
index 000000000..4267c7e8f
--- /dev/null
+++ b/usr.sbin/radiusd/radiusd_eap2mschap/Makefile
@@ -0,0 +1,10 @@
+# $OpenBSD: Makefile,v 1.1 2024/07/14 16:09:23 yasuoka Exp $
+PROG= radiusd_eap2mschap
+BINDIR= /usr/libexec/radiusd
+SRCS= radiusd_eap2mschap.c radiusd_module.c radius_subr.c log.c
+CFLAGS+= -DUSE_LIBEVENT
+LDADD+= -lradius -lutil -lcrypto -levent
+DPADD+= ${LIBRADIUS} ${LIBUTIL} ${LIBCRYPTO} ${LIBEVENT}
+MAN= radiusd_eap2mschap.8
+
+.include
diff --git a/usr.sbin/radiusd/radiusd_file.8 b/usr.sbin/radiusd/radiusd_file.8
new file mode 100644
index 000000000..758933522
--- /dev/null
+++ b/usr.sbin/radiusd/radiusd_file.8
@@ -0,0 +1,62 @@
+.\" $OpenBSD: radiusd_file.8,v 1.2 2024/07/14 18:11:18 jmc Exp $
+.\"
+.\" Copyright (c) 2024 YASUOKA Masahiko
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" The following requests are required for all man pages.
+.\"
+.\" Remove `\&' from the line below.
+.Dd $Mdocdate: July 14 2024 $
+.Dt RADIUSD_FILE 8
+.Os
+.Sh NAME
+.Nm radiusd_file
+.Nd provide authentication by a local file
+.Sh SYNOPSIS
+.\" For a program: program [-abc] file ...
+.Nm radiusd_file
+.Sh DESCRIPTION
+The
+.Nm
+module is executed by
+.Xr radiusd 8
+as a module to provide authentication from a file written in the syntax
+described in
+.Xr npppd-users 5 .
+It supports the PAP, CHAP, and MSCHAPv2 authentication methods.
+.Sh CONFIGURATIONS
+The
+.Nm module
+supports the following configuration key and value:
+.Bl -tag -width Ds
+.It Cm path Ar path
+The path for the
+.Ar file
+written in the syntax described in
+.Xr npppd-users 5 .
+.El
+.Sh FILES
+.Bl -tag -width "/usr/libexec/radiusd/radiusd_file" -compact
+.It Pa /usr/libexec/radiusd/radiusd_file
+.Dq file
+module executable.
+.El
+.Sh SEE ALSO
+.Xr npppd-users 5 ,
+.Xr radiusd 8
+.Sh HISTORY
+The
+.Nm
+daemon first appeared in
+.Ox 7.6 .
diff --git a/usr.sbin/radiusd/radiusd_file.c b/usr.sbin/radiusd/radiusd_file.c
new file mode 100644
index 000000000..1f6e46883
--- /dev/null
+++ b/usr.sbin/radiusd/radiusd_file.c
@@ -0,0 +1,588 @@
+/* $OpenBSD: radiusd_file.c,v 1.2 2024/07/14 15:13:41 yasuoka Exp $ */
+
+/*
+ * Copyright (c) 2024 YASUOKA Masahiko
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "chap_ms.h"
+#include "imsg_subr.h"
+#include "log.h"
+#include "radiusd.h"
+#include "radiusd_module.h"
+
+struct module_file_params {
+ int debug;
+ char path[PATH_MAX];
+};
+
+struct module_file {
+ struct module_base *base;
+ struct imsgbuf ibuf;
+ struct module_file_params
+ params;
+};
+
+struct module_file_userinfo {
+ struct in_addr frame_ip_address;
+ char password[0];
+};
+
+/* IPC between priv and main */
+enum {
+ IMSG_RADIUSD_FILE_OK = 1000,
+ IMSG_RADIUSD_FILE_NG,
+ IMSG_RADIUSD_FILE_PARAMS,
+ IMSG_RADIUSD_FILE_USERINFO
+};
+
+static void parent_dispatch_main(struct module_file_params *,
+ struct imsgbuf *, struct imsg *);
+static void module_file_main(void) __dead;
+static pid_t start_child(char *, int);
+static void module_file_config_set(void *, const char *, int,
+ char * const *);
+static void module_file_start(void *);
+static void module_file_access_request(void *, u_int, const u_char *,
+ size_t);
+static void auth_pap(struct module_file *, u_int, RADIUS_PACKET *, char *,
+ struct module_file_userinfo *);
+static void auth_md5chap(struct module_file *, u_int, RADIUS_PACKET *,
+ char *, struct module_file_userinfo *);
+static void auth_mschapv2(struct module_file *, u_int, RADIUS_PACKET *,
+ char *, struct module_file_userinfo *);
+
+static struct module_handlers module_file_handlers = {
+ .access_request = module_file_access_request,
+ .config_set = module_file_config_set,
+ .start = module_file_start
+};
+
+int
+main(int argc, char *argv[])
+{
+ int ch, pairsock[2], status;
+ pid_t pid;
+ char *saved_argv0;
+ struct imsgbuf ibuf;
+ struct imsg imsg;
+ ssize_t n;
+ size_t datalen;
+ struct module_file_params *paramsp, params;
+
+ while ((ch = getopt(argc, argv, "M")) != -1)
+ switch (ch) {
+ case 'M':
+ module_file_main();
+ /* not reached */
+ break;
+ }
+ saved_argv0 = argv[0];
+
+ argc -= optind;
+ argv += optind;
+
+ if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, PF_UNSPEC,
+ pairsock) == -1)
+ err(EXIT_FAILURE, "socketpair");
+
+ log_init(0);
+
+ pid = start_child(saved_argv0, pairsock[1]);
+
+ /* Privileged process */
+ setproctitle("[priv]");
+ imsg_init(&ibuf, pairsock[0]);
+
+ if (imsg_sync_read(&ibuf, 2000) <= 0 ||
+ (n = imsg_get(&ibuf, &imsg)) <= 0)
+ exit(EXIT_FAILURE);
+ if (imsg.hdr.type != IMSG_RADIUSD_FILE_PARAMS)
+ err(EXIT_FAILURE, "Receieved unknown message type %d",
+ imsg.hdr.type);
+ datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
+ if (datalen < sizeof(params))
+ err(EXIT_FAILURE, "Receieved IMSG_RADIUSD_FILE_PARAMS "
+ "message is wrong size");
+ paramsp = imsg.data;
+ if (paramsp->path[0] != '\0') {
+ if (unveil(paramsp->path, "r") == -1)
+ err(EXIT_FAILURE, "unveil");
+ }
+ if (paramsp->debug)
+ log_init(1);
+
+ if (unveil(NULL, NULL) == -1)
+ err(EXIT_FAILURE, "unveil");
+ if (pledge("stdio rpath", NULL) == -1)
+ err(EXIT_FAILURE, "pledge");
+
+ memcpy(¶ms, paramsp, sizeof(params));
+
+ for (;;) {
+ if ((n = imsg_read(&ibuf)) <= 0 && errno != EAGAIN)
+ break;
+ for (;;) {
+ if ((n = imsg_get(&ibuf, &imsg)) == -1)
+ break;
+ if (n == 0)
+ break;
+ parent_dispatch_main(¶ms, &ibuf, &imsg);
+ imsg_free(&imsg);
+ imsg_flush(&ibuf);
+ }
+ imsg_flush(&ibuf);
+ }
+ imsg_clear(&ibuf);
+
+ while (waitpid(pid, &status, 0) == -1) {
+ if (errno != EINTR)
+ break;
+ }
+ exit(WEXITSTATUS(status));
+}
+
+void
+parent_dispatch_main(struct module_file_params *params, struct imsgbuf *ibuf,
+ struct imsg *imsg)
+{
+ size_t datalen, entsz, passz;
+ const char *username;
+ char *buf, *db[2], *str;
+ int ret;
+ struct module_file_userinfo *ent;
+
+ datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
+ switch (imsg->hdr.type) {
+ case IMSG_RADIUSD_FILE_USERINFO:
+ if (datalen == 0 ||
+ *((char *)imsg->data + datalen - 1) != '\0') {
+ log_warn("%s: received IMSG_RADIUSD_FILE_USERINFO "
+ "is wrong", __func__);
+ goto on_error;
+ }
+ username = imsg->data;
+ db[0] = params->path;
+ db[1] = NULL;
+ if ((ret = cgetent(&buf, db, username)) < 0) {
+ log_info("user `%s' is not configured", username);
+ goto on_error;
+ }
+ if ((ret = cgetstr(buf, "password", &str)) < 0) {
+ log_info("password for `%s' is not configured",
+ username);
+ goto on_error;
+ }
+ passz = strlen(str) + 1;
+ entsz = offsetof(struct module_file_userinfo, password[passz]);
+ if ((ent = calloc(1, entsz)) == NULL) {
+ log_warn("%s; calloc", __func__);
+ goto on_error;
+ }
+ strlcpy(ent->password, str, passz);
+ imsg_compose(ibuf, IMSG_RADIUSD_FILE_USERINFO, 0, -1, -1,
+ ent, entsz);
+ freezero(ent, entsz);
+ break;
+ }
+ return;
+ on_error:
+ imsg_compose(ibuf, IMSG_RADIUSD_FILE_NG, 0, -1, -1, NULL, 0);
+}
+
+/* main process */
+void
+module_file_main(void)
+{
+ struct module_file module_file;
+
+ setproctitle("[main]");
+
+ memset(&module_file, 0, sizeof(module_file));
+ if ((module_file.base = module_create(STDIN_FILENO, &module_file,
+ &module_file_handlers)) == NULL)
+ err(1, "Could not create a module instance");
+
+ module_drop_privilege(module_file.base, 0);
+
+ module_load(module_file.base);
+ imsg_init(&module_file.ibuf, 3);
+
+ if (pledge("stdio", NULL) == -1)
+ err(EXIT_FAILURE, "pledge");
+ while (module_run(module_file.base) == 0)
+ ;
+
+ module_destroy(module_file.base);
+
+ exit(0);
+}
+
+pid_t
+start_child(char *argv0, int fd)
+{
+ char *argv[5];
+ int argc = 0;
+ pid_t pid;
+
+ switch (pid = fork()) {
+ case -1:
+ fatal("cannot fork");
+ case 0:
+ break;
+ default:
+ close(fd);
+ return (pid);
+ }
+
+ if (fd != 3) {
+ if (dup2(fd, 3) == -1)
+ fatal("cannot setup imsg fd");
+ } else if (fcntl(fd, F_SETFD, 0) == -1)
+ fatal("cannot setup imsg fd");
+
+ argv[argc++] = argv0;
+ argv[argc++] = "-M"; /* main proc */
+ argv[argc++] = NULL;
+ execvp(argv0, argv);
+ fatal("execvp");
+}
+
+void
+module_file_config_set(void *ctx, const char *name, int valc,
+ char * const * valv)
+{
+ struct module_file *module = ctx;
+ char *errmsg;
+
+ if (strcmp(name, "path") == 0) {
+ SYNTAX_ASSERT(valc == 1, "`path' must have a argument");
+ if (strlcpy(module->params.path, valv[0], sizeof(
+ module->params.path)) >= sizeof(module->params.path)) {
+ module_send_message(module->base, IMSG_NG,
+ "`path' is too long");
+ return;
+ }
+ module_send_message(module->base, IMSG_OK, NULL);
+ } else if (strcmp(name, "_debug") == 0) {
+ log_init(1);
+ module->params.debug = 1;
+ module_send_message(module->base, IMSG_OK, NULL);
+ } else if (strncmp(name, "_", 1) == 0)
+ /* ignore all internal messages */
+ module_send_message(module->base, IMSG_OK, NULL);
+ else
+ module_send_message(module->base, IMSG_NG,
+ "Unknown config parameter `%s'", name);
+ return;
+ syntax_error:
+ module_send_message(module->base, IMSG_NG, "%s", errmsg);
+ return;
+}
+
+void
+module_file_start(void *ctx)
+{
+ struct module_file *module = ctx;
+
+ if (module->params.path[0] == '\0') {
+ module_send_message(module->base, IMSG_NG,
+ "`path' is not configured");
+ return;
+ }
+ imsg_compose(&module->ibuf, IMSG_RADIUSD_FILE_PARAMS, 0, -1, -1,
+ &module->params, sizeof(module->params));
+ imsg_flush(&module->ibuf);
+
+ module_send_message(module->base, IMSG_OK, NULL);
+}
+
+void
+module_file_access_request(void *ctx, u_int query_id, const u_char *pkt,
+ size_t pktlen)
+{
+ size_t datalen;
+ struct module_file *self = ctx;
+ RADIUS_PACKET *radpkt = NULL;
+ char username[256];
+ ssize_t n;
+ struct imsg imsg;
+ struct module_file_userinfo *ent;
+
+ memset(&imsg, 0, sizeof(imsg));
+
+ if ((radpkt = radius_convert_packet(pkt, pktlen)) == NULL) {
+ log_warn("%s: radius_convert_packet()", __func__);
+ goto on_error;
+ }
+ radius_get_string_attr(radpkt, RADIUS_TYPE_USER_NAME, username,
+ sizeof(username));
+
+ imsg_compose(&self->ibuf, IMSG_RADIUSD_FILE_USERINFO, 0, -1, -1,
+ username, strlen(username) + 1);
+ imsg_flush(&self->ibuf);
+ if ((n = imsg_read(&self->ibuf)) == -1 || n == 0) {
+ log_warn("%s: imsg_read()", __func__);
+ goto on_error;
+ }
+ if ((n = imsg_get(&self->ibuf, &imsg)) <= 0) {
+ log_warn("%s: imsg_get()", __func__);
+ goto on_error;
+ }
+
+ datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
+ if (imsg.hdr.type == IMSG_RADIUSD_FILE_USERINFO) {
+ if (datalen <= offsetof(struct module_file_userinfo,
+ password[0])) {
+ log_warn("%s: received IMSG_RADIUSD_FILE_USERINFO is "
+ "invalid", __func__);
+ goto on_error;
+ }
+ ent = imsg.data;
+ } else
+ goto on_error;
+
+ if (radius_has_attr(radpkt, RADIUS_TYPE_USER_PASSWORD))
+ auth_pap(self, query_id, radpkt, username, ent);
+ else if (radius_has_attr(radpkt, RADIUS_TYPE_CHAP_PASSWORD))
+ auth_md5chap(self, query_id, radpkt, username, ent);
+ else if (radius_has_vs_attr(radpkt, RADIUS_VENDOR_MICROSOFT,
+ RADIUS_VTYPE_MS_CHAP2_RESPONSE))
+ auth_mschapv2(self, query_id, radpkt, username, ent);
+ else {
+ log_info("q=%u unsupported authentication methods", query_id);
+ explicit_bzero(ent->password, strlen(ent->password));
+ }
+ on_error:
+ if (radpkt != NULL)
+ radius_delete_packet(radpkt);
+ imsg_free(&imsg);
+ return;
+}
+
+void
+auth_pap(struct module_file *self, u_int q_id, RADIUS_PACKET *radpkt,
+ char *username, struct module_file_userinfo *ent)
+{
+ RADIUS_PACKET *respkt = NULL;
+ char pass[256];
+ int ret;
+
+ if (radius_get_string_attr(radpkt, RADIUS_TYPE_USER_PASSWORD, pass,
+ sizeof(pass)) != 0) {
+ log_warnx("%s: radius_get_string_attr", __func__);
+ return;
+ }
+ ret = strcmp(ent->password, pass);
+ log_info("%s %s", ent->password, pass);
+ explicit_bzero(ent->password, strlen(ent->password));
+ log_info("q=%u User `%s' authentication %s (PAP)", q_id, username,
+ (ret == 0)? "succeeded" : "failed");
+ if ((respkt = radius_new_response_packet((ret == 0)?
+ RADIUS_CODE_ACCESS_ACCEPT : RADIUS_CODE_ACCESS_REJECT, radpkt))
+ == NULL) {
+ log_warn("%s: radius_new_response_packet()", __func__);
+ return;
+ }
+ module_accsreq_answer(self->base, q_id,
+ radius_get_data(respkt), radius_get_length(respkt));
+ radius_delete_packet(respkt);
+}
+
+void
+auth_md5chap(struct module_file *self, u_int q_id, RADIUS_PACKET *radpkt,
+ char *username, struct module_file_userinfo *ent)
+{
+ RADIUS_PACKET *respkt = NULL;
+ size_t attrlen, challlen;
+ u_char chall[256], idpass[17], digest[16];
+ int ret;
+ MD5_CTX md5;
+
+ attrlen = sizeof(idpass);
+ if (radius_get_raw_attr(radpkt, RADIUS_TYPE_CHAP_PASSWORD, idpass,
+ &attrlen) != 0) {
+ log_warnx("%s: radius_get_string_attr", __func__);
+ return;
+ }
+ challlen = sizeof(chall);
+ if (radius_get_raw_attr(radpkt, RADIUS_TYPE_CHAP_CHALLENGE, chall,
+ &challlen) != 0) {
+ log_warnx("%s: radius_get_string_attr", __func__);
+ return;
+ }
+ MD5Init(&md5);
+ MD5Update(&md5, idpass, 1);
+ MD5Update(&md5, ent->password, strlen(ent->password));
+ MD5Update(&md5, chall, challlen);
+ MD5Final(digest, &md5);
+
+ ret = timingsafe_bcmp(idpass + 1, digest, sizeof(digest));
+ log_info("q=%u User `%s' authentication %s (CHAP)", q_id, username,
+ (ret == 0)? "succeeded" : "failed");
+ if ((respkt = radius_new_response_packet((ret == 0)?
+ RADIUS_CODE_ACCESS_ACCEPT : RADIUS_CODE_ACCESS_REJECT, radpkt))
+ == NULL) {
+ log_warn("%s: radius_new_response_packet()", __func__);
+ return;
+ }
+ module_accsreq_answer(self->base, q_id,
+ radius_get_data(respkt), radius_get_length(respkt));
+ radius_delete_packet(respkt);
+}
+
+void
+auth_mschapv2(struct module_file *self, u_int q_id, RADIUS_PACKET *radpkt,
+ char *username, struct module_file_userinfo *ent)
+{
+ RADIUS_PACKET *respkt = NULL;
+ size_t attrlen;
+ int i, lpass;
+ char *pass = NULL;
+ uint8_t chall[MSCHAPV2_CHALLENGE_SZ];
+ uint8_t ntresponse[24], authenticator[16];
+ uint8_t pwhash[16], pwhash2[16], master[64];
+ struct {
+ uint8_t salt[2];
+ uint8_t len;
+ uint8_t key[16];
+ uint8_t pad[15];
+ } __packed rcvkey, sndkey;
+ struct {
+ uint8_t ident;
+ uint8_t flags;
+ uint8_t peerchall[16];
+ uint8_t reserved[8];
+ uint8_t ntresponse[24];
+ } __packed resp;
+ struct authresp {
+ uint8_t ident;
+ uint8_t authresp[42];
+ } __packed authresp;
+
+
+ attrlen = sizeof(chall);
+ if (radius_get_vs_raw_attr(radpkt, RADIUS_VENDOR_MICROSOFT,
+ RADIUS_VTYPE_MS_CHAP_CHALLENGE, chall, &attrlen) != 0) {
+ log_info("q=%u failed to retribute MS-CHAP-Challenge", q_id);
+ goto on_error;
+ }
+ attrlen = sizeof(resp);
+ if (radius_get_vs_raw_attr(radpkt, RADIUS_VENDOR_MICROSOFT,
+ RADIUS_VTYPE_MS_CHAP2_RESPONSE, &resp, &attrlen) != 0) {
+ log_info("q=%u failed to retribute MS-CHAP2-Response", q_id);
+ goto on_error;
+ }
+
+ /* convert the password to UTF16-LE */
+ lpass = strlen(ent->password);
+ if ((pass = calloc(1, lpass * 2)) == NULL) {
+ log_warn("%s: calloc()", __func__);
+ goto on_error;
+ }
+ for (i = 0; i < lpass; i++) {
+ pass[i * 2] = ent->password[i];
+ pass[i * 2 + 1] = '\0';
+ }
+
+ /* calculate NT-Response by the password */
+ mschap_nt_response(chall, resp.peerchall,
+ username, strlen(username), pass, lpass * 2, ntresponse);
+
+ if (timingsafe_bcmp(ntresponse, resp.ntresponse, 24) != 0) {
+ log_info("q=%u User `%s' authentication failed (MSCHAPv2)",
+ q_id, username);
+ if ((respkt = radius_new_response_packet(
+ RADIUS_CODE_ACCESS_REJECT, radpkt)) == NULL) {
+ log_warn("%s: radius_new_response_packet()", __func__);
+ goto on_error;
+ }
+ authresp.ident = resp.ident;
+ strlcpy(authresp.authresp, "E=691 R=0 V=3",
+ sizeof(authresp.authresp));
+ radius_put_vs_raw_attr(respkt, RADIUS_VENDOR_MICROSOFT,
+ RADIUS_VTYPE_MS_CHAP_ERROR, &authresp,
+ offsetof(struct authresp, authresp[13]));
+ } else {
+ log_info("q=%u User `%s' authentication succeeded (MSCHAPv2)",
+ q_id, username);
+ if ((respkt = radius_new_response_packet(
+ RADIUS_CODE_ACCESS_ACCEPT, radpkt)) == NULL) {
+ log_warn("%s: radius_new_response_packet()", __func__);
+ goto on_error;
+ }
+ mschap_auth_response(pass, lpass * 2, ntresponse, chall,
+ resp.peerchall, username, strlen(username),
+ authresp.authresp);
+ authresp.ident = resp.ident;
+
+ radius_put_vs_raw_attr(respkt, RADIUS_VENDOR_MICROSOFT,
+ RADIUS_VTYPE_MS_CHAP2_SUCCESS, &authresp,
+ offsetof(struct authresp, authresp[42]));
+
+ mschap_ntpassword_hash(pass, lpass * 2, pwhash);
+ mschap_ntpassword_hash(pwhash, sizeof(pwhash), pwhash2);
+ mschap_masterkey(pwhash2, ntresponse, master);
+ radius_get_authenticator(radpkt, authenticator);
+
+ /* MS-MPPE-Recv-Key */
+ memset(&rcvkey, 0, sizeof(rcvkey));
+ arc4random_buf(rcvkey.salt, sizeof(rcvkey.salt));
+ rcvkey.salt[0] |= 0x80;
+ rcvkey.len = 16;
+ mschap_asymetric_startkey(master, rcvkey.key, 16, 0, 1);
+ radius_put_vs_raw_attr(respkt, RADIUS_VENDOR_MICROSOFT,
+ RADIUS_VTYPE_MPPE_RECV_KEY, &rcvkey, sizeof(rcvkey));
+
+ /* MS-MPPE-Send-Key */
+ memset(&sndkey, 0, sizeof(sndkey));
+ arc4random_buf(sndkey.salt, sizeof(sndkey.salt));
+ sndkey.salt[0] |= 0x80;
+ sndkey.len = 16;
+ mschap_asymetric_startkey(master, sndkey.key, 16, 1, 1);
+ radius_put_vs_raw_attr(respkt, RADIUS_VENDOR_MICROSOFT,
+ RADIUS_VTYPE_MPPE_SEND_KEY, &sndkey, sizeof(sndkey));
+ }
+
+ module_accsreq_answer(self->base, q_id,
+ radius_get_data(respkt), radius_get_length(respkt));
+ on_error:
+ /* bzero password */
+ explicit_bzero(ent->password, strlen(ent->password));
+ if (pass != NULL)
+ explicit_bzero(pass, lpass * 2);
+ free(pass);
+ if (respkt != NULL)
+ radius_delete_packet(respkt);
+}
diff --git a/usr.sbin/radiusd/radiusd_file/Makefile b/usr.sbin/radiusd/radiusd_file/Makefile
new file mode 100644
index 000000000..7c15471c2
--- /dev/null
+++ b/usr.sbin/radiusd/radiusd_file/Makefile
@@ -0,0 +1,11 @@
+# $OpenBSD: Makefile,v 1.2 2024/07/14 16:22:59 yasuoka Exp $
+
+PROG= radiusd_file
+BINDIR= /usr/libexec/radiusd
+SRCS= radiusd_file.c radiusd_module.c imsg_subr.c log.c chap_ms.c
+#SRCS+= radius_subr.c
+LDADD+= -lradius -lcrypto -lutil
+DPADD+= ${LIBRADIUS} ${LIBCRYPTO} ${LIBUTIL}
+MAN= radiusd_file.8
+
+.include
diff --git a/usr.sbin/radiusd/radiusd_local.h b/usr.sbin/radiusd/radiusd_local.h
index 4fed590c0..b4ce9b15a 100644
--- a/usr.sbin/radiusd/radiusd_local.h
+++ b/usr.sbin/radiusd/radiusd_local.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: radiusd_local.h,v 1.12 2024/07/09 17:26:14 yasuoka Exp $ */
+/* $OpenBSD: radiusd_local.h,v 1.15 2024/07/14 15:31:49 yasuoka Exp $ */
/*
* Copyright (c) 2013 Internet Initiative Japan Inc.
@@ -97,6 +97,7 @@ struct radiusd_module_ref {
struct radiusd_authentication {
char **username;
struct radiusd_module_ref *auth;
+ bool isfilter;
TAILQ_HEAD(,radiusd_module_ref) deco;
TAILQ_ENTRY(radiusd_authentication) next;
};
@@ -126,6 +127,7 @@ struct radiusd {
struct radius_query {
u_int id;
+ struct radiusd *radiusd;
struct sockaddr_storage clientaddr;
int clientaddrlen;
int req_id;
@@ -139,6 +141,7 @@ struct radius_query {
char username[256]; /* original username */
TAILQ_ENTRY(radius_query) next;
struct radiusd_module_ref *deco;
+ struct radius_query *prev;
};
struct imsgev {
@@ -185,6 +188,9 @@ extern struct radiusd *radiusd_s;
#define MODULE_DO_RESDECO(_m) \
((_m)->fd >= 0 && \
((_m)->capabilities & RADIUSD_MODULE_CAP_RESDECO) != 0)
+#define MODULE_DO_NEXTRES(_m) \
+ ((_m)->fd >= 0 && \
+ ((_m)->capabilities & RADIUSD_MODULE_CAP_NEXTRES) != 0)
int parse_config(const char *, struct radiusd *);
void radiusd_conf_init(struct radiusd *);
@@ -195,13 +201,10 @@ struct radiusd_module *radiusd_module_load(struct radiusd *, const char *,
void radiusd_module_unload(struct radiusd_module *);
void radiusd_access_request_answer(struct radius_query *);
+void radiusd_access_request_next(struct radius_query *, RADIUS_PACKET *);
void radiusd_access_request_aborted(struct radius_query *);
int radiusd_imsg_compose_module(struct radiusd *, const char *,
uint32_t, uint32_t, pid_t, int, void *, size_t);
-void radius_attr_hide(const char *, const char *, const u_char *,
- u_char *, int);
-void radius_attr_unhide(const char *, const char *, const u_char *,
- u_char *, int);
int radiusd_module_set(struct radiusd_module *, const char *, int,
char * const *);
diff --git a/usr.sbin/radiusd/radiusd_module.c b/usr.sbin/radiusd/radiusd_module.c
index 33fe54763..02b383962 100644
--- a/usr.sbin/radiusd/radiusd_module.c
+++ b/usr.sbin/radiusd/radiusd_module.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: radiusd_module.c,v 1.18 2024/07/09 17:26:14 yasuoka Exp $ */
+/* $OpenBSD: radiusd_module.c,v 1.19 2024/07/14 15:27:57 yasuoka Exp $ */
/*
* Copyright (c) 2015 YASUOKA Masahiko
@@ -46,6 +46,8 @@ static void (*module_userpass) (void *, u_int, const char *, const char *)
= NULL;
static void (*module_access_request) (void *, u_int, const u_char *,
size_t) = NULL;
+static void (*module_next_response) (void *, u_int, const u_char *,
+ size_t) = NULL;
static void (*module_request_decoration) (void *, u_int, const u_char *,
size_t) = NULL;
static void (*module_response_decoration) (void *, u_int, const u_char *,
@@ -98,6 +100,7 @@ module_create(int sock, void *ctx, struct module_handlers *handler)
module_userpass = handler->userpass;
module_access_request = handler->access_request;
+ module_next_response = handler->next_response;
module_config_set = handler->config_set;
module_request_decoration = handler->request_decoration;
module_response_decoration = handler->response_decoration;
@@ -157,6 +160,8 @@ module_load(struct module_base *base)
load.cap |= RADIUSD_MODULE_CAP_USERPASS;
if (module_access_request != NULL)
load.cap |= RADIUSD_MODULE_CAP_ACCSREQ;
+ if (module_next_response != NULL)
+ load.cap |= RADIUSD_MODULE_CAP_NEXTRES;
if (module_request_decoration != NULL)
load.cap |= RADIUSD_MODULE_CAP_REQDECO;
if (module_response_decoration != NULL)
@@ -273,6 +278,14 @@ module_accsreq_answer(struct module_base *base, u_int q_id, const u_char *pkt,
q_id, pkt, pktlen));
}
+int
+module_accsreq_next(struct module_base *base, u_int q_id, const u_char *pkt,
+ size_t pktlen)
+{
+ return (module_common_radpkt(base, IMSG_RADIUSD_MODULE_ACCSREQ_NEXT,
+ q_id, pkt, pktlen));
+}
+
int
module_accsreq_aborted(struct module_base *base, u_int q_id)
{
@@ -453,6 +466,7 @@ module_imsg_handler(struct module_base *base, struct imsg *imsg)
break;
}
case IMSG_RADIUSD_MODULE_ACCSREQ:
+ case IMSG_RADIUSD_MODULE_NEXTRES:
case IMSG_RADIUSD_MODULE_REQDECO:
case IMSG_RADIUSD_MODULE_RESDECO0_REQ:
case IMSG_RADIUSD_MODULE_RESDECO:
@@ -469,6 +483,13 @@ module_imsg_handler(struct module_base *base, struct imsg *imsg)
break;
}
typestr = "ACCSREQ";
+ } else if (imsg->hdr.type == IMSG_RADIUSD_MODULE_NEXTRES) {
+ if (module_next_response == NULL) {
+ syslog(LOG_ERR, "Received NEXTRES message, but "
+ "module doesn't support");
+ break;
+ }
+ typestr = "NEXTRES";
} else if (imsg->hdr.type == IMSG_RADIUSD_MODULE_ACCTREQ) {
if (module_accounting_request == NULL) {
syslog(LOG_ERR, "Received ACCTREQ message, but "
@@ -537,6 +558,9 @@ module_imsg_handler(struct module_base *base, struct imsg *imsg)
if (imsg->hdr.type == IMSG_RADIUSD_MODULE_ACCSREQ)
module_access_request(base->ctx, accessreq->q_id,
base->radpkt, base->radpktoff);
+ else if (imsg->hdr.type == IMSG_RADIUSD_MODULE_NEXTRES)
+ module_next_response(base->ctx, accessreq->q_id,
+ base->radpkt, base->radpktoff);
else if (imsg->hdr.type == IMSG_RADIUSD_MODULE_REQDECO)
module_request_decoration(base->ctx, accessreq->q_id,
base->radpkt, base->radpktoff);
diff --git a/usr.sbin/radiusd/radiusd_module.h b/usr.sbin/radiusd/radiusd_module.h
index 9b3b84760..f33c876de 100644
--- a/usr.sbin/radiusd/radiusd_module.h
+++ b/usr.sbin/radiusd/radiusd_module.h
@@ -38,6 +38,9 @@ struct module_handlers {
size_t pktlen);
/* User-Password Attribute is encrypted if the module has the secret */
+ void (*next_response)(void *ctx, u_int query_id, const u_char *pkt,
+ size_t pktlen);
+
void (*request_decoration)(void *ctx, u_int query_id, const u_char *pkt,
size_t pktlen);
@@ -78,6 +81,8 @@ int module_userpass_fail(struct module_base *, u_int,
const char *);
int module_accsreq_answer(struct module_base *, u_int,
const u_char *, size_t);
+int module_accsreq_next(struct module_base *, u_int,
+ const u_char *, size_t);
int module_accsreq_aborted(struct module_base *, u_int);
int module_reqdeco_done(struct module_base *, u_int,
const u_char *, size_t);
diff --git a/usr.sbin/relayd/relayd.conf.5 b/usr.sbin/relayd/relayd.conf.5
index b4fa8398b..c5a380fc1 100644
--- a/usr.sbin/relayd/relayd.conf.5
+++ b/usr.sbin/relayd/relayd.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: relayd.conf.5,v 1.208 2024/06/17 08:02:57 sashan Exp $
+.\" $OpenBSD: relayd.conf.5,v 1.209 2024/07/14 03:58:49 jsg Exp $
.\"
.\" Copyright (c) 2006 - 2016 Reyk Floeter
.\" Copyright (c) 2006, 2007 Pierre-Yves Ritschard
@@ -15,7 +15,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: June 17 2024 $
+.Dd $Mdocdate: July 14 2024 $
.Dt RELAYD.CONF 5
.Os
.Sh NAME
@@ -545,7 +545,8 @@ The optional
.Ic pflog
keyword will add
.Cm log
-to the rule. The logged packets are sent to
+to the rule.
+The logged packets are sent to
.Xr pflog 4 .
.It Xo
.Op Ic match