From b5356a44afdcff842397ebb858253ec776aa03e0 Mon Sep 17 00:00:00 2001 From: purplerain Date: Tue, 21 May 2024 00:16:53 +0000 Subject: [PATCH] sync with OpenBSD -current --- bin/pax/ar_subs.c | 75 +- bin/ps/ps.c | 8 +- distrib/sets/lists/base/mi | 7 +- etc/daily | 5 +- etc/rc | 5 +- gnu/usr.bin/perl/README.secbsd | 2 + gnu/usr.bin/perl/locale.c | 2 +- include/unistd.h | 5 +- lib/libc/Symbols.list | 2 + lib/libc/hidden/unistd.h | 3 +- lib/libc/shlib_version | 2 +- lib/libc/sys/Makefile.inc | 4 +- lib/libc/sys/pathconf.2 | 93 +- lib/libcrypto/asn1/asn1_gen.c | 5 +- lib/libcrypto/asn1/x_bignum.c | 4 +- lib/libcrypto/asn1/x_long.c | 4 +- lib/libcrypto/man/X509V3_get_d2i.3 | 30 +- lib/libcrypto/x509/x509_v3.c | 78 +- lib/libssl/man/SSL_CTX_set_keylog_callback.3 | 6 +- libexec/ld.so/util.h | 5 +- regress/usr.bin/mandoc/char/unicode/ascii.in | 5 +- .../mandoc/char/unicode/ascii.out_ascii | 3 +- .../mandoc/char/unicode/ascii.out_html | 1 + .../mandoc/char/unicode/ascii.out_utf8 | 3 +- regress/usr.bin/mandoc/char/unicode/input.in | Bin 2684 -> 2964 bytes .../mandoc/char/unicode/input.out_ascii | 7 +- .../mandoc/char/unicode/input.out_lint | 116 +- .../mandoc/char/unicode/input.out_utf8 | 7 +- .../usr.bin/mandoc/char/unicode/nogroff.in | 73 +- .../mandoc/char/unicode/nogroff.out_ascii | 71 +- .../mandoc/char/unicode/nogroff.out_html | 69 + .../mandoc/char/unicode/nogroff.out_utf8 | 71 +- regress/usr.bin/ssh/test-exec.sh | 7 +- sbin/ifconfig/ifconfig.c | 4 +- share/man/man5/bsd.port.arch.mk.5 | 5 +- share/man/man8/bulk.8 | 13 +- share/man/man8/daily.8 | 6 +- sys/dev/fdt/ociic.c | 17 +- sys/dev/fdt/virtio_mmio.c | 13 +- sys/dev/ic/ufshci.c | 41 +- sys/dev/ic/ufshcireg.h | 9 +- sys/dev/ic/ufshcivar.h | 3 +- sys/dev/pci/azalia.c | 68 +- sys/dev/pci/virtio_pci.c | 16 +- sys/dev/pv/if_vio.c | 66 +- sys/dev/pv/virtiovar.h | 6 +- sys/dev/sbus/esp_sbus.c | 10 +- sys/dev/wscons/wsmouse.c | 3 +- sys/kern/init_sysent.c | 8 +- sys/kern/kern_pledge.c | 3 +- sys/kern/syscalls.c | 6 +- sys/kern/syscalls.master | 5 +- sys/kern/uipc_socket.c | 222 ++- sys/kern/uipc_socket2.c | 101 +- sys/kern/vfs_syscalls.c | 37 +- sys/net/pfkeyv2.c | 41 +- sys/netinet/ip_ipip.c | 4 +- sys/netinet/ip_output.c | 7 +- sys/sys/mutex.h | 30 +- sys/sys/socketvar.h | 20 +- sys/sys/syscall.h | 8 +- sys/sys/syscallargs.h | 12 +- usr.bin/dig/dig.h | 3 - usr.bin/dig/lib/dns/dst_internal.h | 3 +- usr.bin/dig/lib/dns/include/dns/compress.h | 22 +- usr.bin/dig/lib/dns/include/dns/message.h | 21 - usr.bin/dig/lib/dns/rdataset.c | 4 +- usr.bin/dig/lib/isc/include/isc/log.h | 24 +- usr.bin/dig/lib/isc/sha2.c | 10 +- usr.bin/kdump/kdump.c | 3 +- usr.bin/less/forwback.c | 2 - usr.bin/mandoc/roff_escape.c | 12 +- usr.bin/netstat/netstat.h | 10 +- usr.bin/openssl/apps.h | 4 +- usr.bin/openssl/progs.h | 3 +- usr.bin/openssl/s_apps.h | 3 +- usr.bin/ssh/Makefile | 5 +- usr.bin/ssh/Makefile.inc | 15 +- usr.bin/ssh/auth-rhosts.c | 3 +- usr.bin/ssh/auth.c | 104 +- usr.bin/ssh/auth.h | 15 +- usr.bin/ssh/auth2-gss.c | 41 +- usr.bin/ssh/auth2-hostbased.c | 15 +- usr.bin/ssh/auth2-kbdint.c | 7 +- usr.bin/ssh/auth2-methods.c | 133 ++ usr.bin/ssh/auth2-none.c | 12 +- usr.bin/ssh/auth2-passwd.c | 9 +- usr.bin/ssh/auth2-pubkey.c | 15 +- usr.bin/ssh/auth2.c | 81 +- usr.bin/ssh/channels.c | 22 +- usr.bin/ssh/channels.h | 3 +- usr.bin/ssh/cipher.c | 4 +- usr.bin/ssh/clientloop.c | 3 +- usr.bin/ssh/clientloop.h | 3 +- usr.bin/ssh/ed25519.sh | 4 +- usr.bin/ssh/kex-names.c | 319 ++++ usr.bin/ssh/kex.c | 260 +--- usr.bin/ssh/kex.h | 9 +- usr.bin/ssh/kexgexs.c | 4 +- usr.bin/ssh/misc.c | 17 +- usr.bin/ssh/misc.h | 10 +- usr.bin/ssh/monitor.c | 51 +- usr.bin/ssh/monitor.h | 6 +- usr.bin/ssh/monitor_wrap.c | 178 ++- usr.bin/ssh/monitor_wrap.h | 17 +- usr.bin/ssh/msg.c | 5 +- usr.bin/ssh/packet.c | 90 +- usr.bin/ssh/packet.h | 5 +- usr.bin/ssh/pathnames.h | 5 +- usr.bin/ssh/readconf.c | 4 +- usr.bin/ssh/servconf.c | 107 +- usr.bin/ssh/servconf.h | 13 +- usr.bin/ssh/serverloop.c | 44 +- usr.bin/ssh/session.c | 23 +- usr.bin/ssh/sftp-client.c | 4 +- usr.bin/ssh/ssh-gss.h | 3 +- usr.bin/ssh/ssh_api.c | 17 +- usr.bin/ssh/sshconnect2.c | 4 +- usr.bin/ssh/sshd-session.c | 1354 +++++++++++++++++ usr.bin/ssh/sshd-session/Makefile | 71 + usr.bin/ssh/sshd.c | 1227 ++------------- usr.bin/ssh/sshd/Makefile | 18 +- usr.bin/ssh/sshkey.h | 3 +- usr.bin/systat/nfs.c | 3 +- usr.bin/systat/pool.c | 3 +- usr.bin/systat/systat.h | 5 +- usr.bin/systat/uvm.c | 3 +- usr.bin/tmux/cmd.c | 4 +- usr.bin/tmux/tmux.h | 8 +- usr.bin/top/display.h | 9 +- usr.sbin/bgpd/bgpd.h | 7 +- usr.sbin/bgpd/rde.h | 7 +- usr.sbin/bgpd/session.c | 11 +- usr.sbin/bgpd/session.h | 3 +- usr.sbin/dvmrpd/dvmrpd.h | 3 +- usr.sbin/dvmrpd/rde.h | 5 +- usr.sbin/dvmrpd/rde_mfc.c | 3 +- usr.sbin/ospf6d/kroute.c | 3 +- usr.sbin/ospf6d/ospf6d.h | 5 +- usr.sbin/ospf6d/ospfe.h | 5 +- usr.sbin/ospf6d/packet.c | 3 +- usr.sbin/ospfd/ospfe.h | 5 +- usr.sbin/rad/frontend.c | 45 +- usr.sbin/rad/parse.y | 8 +- usr.sbin/rad/printconf.c | 4 +- usr.sbin/rad/rad.c | 3 +- usr.sbin/rad/rad.conf.5 | 8 +- usr.sbin/rad/rad.h | 3 +- usr.sbin/relayd/hce.c | 3 +- usr.sbin/relayd/relay_udp.c | 3 +- usr.sbin/relayd/relayd.h | 5 +- usr.sbin/vmctl/main.c | 4 +- usr.sbin/vmctl/vmctl.h | 4 +- usr.sbin/vmd/i8259.h | 5 +- usr.sbin/vmd/mc146818.h | 3 +- usr.sbin/vmd/vmd.c | 3 +- 156 files changed, 3600 insertions(+), 2644 deletions(-) create mode 100644 usr.bin/ssh/auth2-methods.c create mode 100644 usr.bin/ssh/kex-names.c create mode 100644 usr.bin/ssh/sshd-session.c create mode 100644 usr.bin/ssh/sshd-session/Makefile diff --git a/bin/pax/ar_subs.c b/bin/pax/ar_subs.c index c542aa61d..172d6847b 100644 --- a/bin/pax/ar_subs.c +++ b/bin/pax/ar_subs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ar_subs.c,v 1.51 2023/07/10 16:28:33 jeremy Exp $ */ +/* $OpenBSD: ar_subs.c,v 1.52 2024/05/18 05:21:38 guenther Exp $ */ /* $NetBSD: ar_subs.c,v 1.5 1995/03/21 09:07:06 cgd Exp $ */ /*- @@ -146,23 +146,60 @@ list(void) } static int -cmp_file_times(int mtime_flag, int ctime_flag, ARCHD *arcn, struct stat *sbp) +cmp_file_times(int mtime_flag, int ctime_flag, ARCHD *arcn, const char *path) { struct stat sb; + long res; - if (sbp == NULL) { - if (lstat(arcn->name, &sb) != 0) - return (0); - sbp = &sb; + if (path == NULL) + path = arcn->name; + if (lstat(path, &sb) != 0) + return (0); + + /* + * The target (sb) mtime might be rounded down due to the limitations + * of the FS it's on. If it's strictly greater or we don't care about + * mtime, then precision doesn't matter, so check those cases first. + */ + if (ctime_flag && mtime_flag) { + if (timespeccmp(&arcn->sb.st_mtim, &sb.st_mtim, <=)) + return timespeccmp(&arcn->sb.st_ctim, &sb.st_ctim, <=); + if (!timespeccmp(&arcn->sb.st_ctim, &sb.st_ctim, <=)) + return 0; + /* <= ctim, but >= mtim */ + } else if (ctime_flag) + return timespeccmp(&arcn->sb.st_ctim, &sb.st_ctim, <=); + 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. + */ + res = pathconfat(AT_FDCWD, path, _PC_TIMESTAMP_RESOLUTION, + AT_SYMLINK_NOFOLLOW); + if (res == -1) + return 0; + + /* nanosecond resolution? previous comparisons were accurate */ + if (res == 1) + return 0; + + /* common case: second accuracy */ + if (res == 1000000000) + return arcn->sb.st_mtime <= sb.st_mtime; + + if (res < 1000000000) { + struct timespec ts = arcn->sb.st_mtim; + ts.tv_nsec = (ts.tv_nsec / res) * res; + return timespeccmp(&ts, &sb.st_mtim, <=); + } else { + /* not a POSIX compliant FS */ + res /= 1000000000; + return ((arcn->sb.st_mtime / res) * res) <= sb.st_mtime; + return arcn->sb.st_mtime <= ((sb.st_mtime / res) * res); } - - if (ctime_flag && mtime_flag) - return (timespeccmp(&arcn->sb.st_mtim, &sbp->st_mtim, <=) && - timespeccmp(&arcn->sb.st_ctim, &sbp->st_ctim, <=)); - else if (ctime_flag) - return (timespeccmp(&arcn->sb.st_ctim, &sbp->st_ctim, <=)); - else - return (timespeccmp(&arcn->sb.st_mtim, &sbp->st_mtim, <=)); } /* @@ -842,14 +879,12 @@ copy(void) /* * if existing file is same age or newer skip */ - res = lstat(dirbuf, &sb); - *dest_pt = '\0'; - - if (res == 0) { + if (cmp_file_times(uflag, Dflag, arcn, dirbuf)) { + *dest_pt = '\0'; ftree_skipped_newer(arcn); - if (cmp_file_times(uflag, Dflag, arcn, &sb)) - continue; + continue; } + *dest_pt = '\0'; } /* diff --git a/bin/ps/ps.c b/bin/ps/ps.c index fe62dad04..b43765f42 100644 --- a/bin/ps/ps.c +++ b/bin/ps/ps.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ps.c,v 1.80 2023/11/10 09:17:02 kn Exp $ */ +/* $OpenBSD: ps.c,v 1.81 2024/05/18 13:08:09 sobrado Exp $ */ /* $NetBSD: ps.c,v 1.15 1995/05/18 20:33:25 mycroft Exp $ */ /*- @@ -623,9 +623,9 @@ forest_sort(struct pinfo *ki, int items) static void usage(void) { - fprintf(stderr, "usage: %s [-AacefHhjkLlmrSTuvwx] [-M core] [-N system]" - " [-O fmt] [-o fmt] [-p pid]\n", __progname); - fprintf(stderr, "%-*s[-t tty] [-U user] [-W swap]\n", + fprintf(stderr, "usage: %s [[-]AacefHhjkLlmrSTuvwx] [-M core]" + " [-N system] [-O fmt] [-o fmt]\n", __progname); + fprintf(stderr, "%-*s[-p pid] [-t tty] [-U user] [-W swap]\n", (int)strlen(__progname) + 8, ""); exit(1); } diff --git a/distrib/sets/lists/base/mi b/distrib/sets/lists/base/mi index 7ab882b19..ed98bbbaf 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.0 +./usr/lib/libc.so.100.1 ./usr/lib/libcbor.so.2.0 ./usr/lib/libcrypto.so.54.0 ./usr/lib/libcurses.so.15.0 @@ -2528,6 +2528,7 @@ ./usr/libexec/ssh-keysign ./usr/libexec/ssh-pkcs11-helper ./usr/libexec/ssh-sk-helper +./usr/libexec/sshd-session ./usr/libexec/tradcpp ./usr/libexec/vi.recover ./usr/local @@ -2972,10 +2973,12 @@ ./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.0.a +./usr/share/relink/usr/lib/libc.so.100.1.a ./usr/share/relink/usr/lib/libcrypto.so.54.0.a ./usr/share/relink/usr/libexec ./usr/share/relink/usr/libexec/ld.so.a +./usr/share/relink/usr/libexec/sshd-session +./usr/share/relink/usr/libexec/sshd-session/sshd-session.tar ./usr/share/relink/usr/sbin ./usr/share/relink/usr/sbin/sshd ./usr/share/relink/usr/sbin/sshd/sshd.tar diff --git a/etc/daily b/etc/daily index 5d052e323..77210e71e 100644 --- a/etc/daily +++ b/etc/daily @@ -1,5 +1,5 @@ # -# $OpenBSD: daily,v 1.97 2023/03/03 16:22:57 bluhm Exp $ +# $OpenBSD: daily,v 1.98 2024/05/16 11:33:59 solene Exp $ # From: @(#)daily 8.2 (Berkeley) 1/25/94 # # For local additions, create the file /etc/daily.local. @@ -136,6 +136,9 @@ done next_part "Services that should be running but aren't:" rcctl ls failed +next_part "Services that are running but shouldn't:" +rcctl ls rogue + next_part "Filesystems which need to be dumped:" dump w | grep -vB1 ^Dump diff --git a/etc/rc b/etc/rc index 5ee9dcf8e..537a2345d 100644 --- a/etc/rc +++ b/etc/rc @@ -1,4 +1,4 @@ -# $OpenBSD: rc,v 1.574 2024/04/02 08:21:04 deraadt Exp $ +# $OpenBSD: rc,v 1.575 2024/05/17 00:33:43 deraadt Exp $ # System startup script run by init on autoboot or after single-user. # Output and error are redirected to console by init, and the console is the @@ -241,7 +241,8 @@ reorder_libs() { ) || { _error=true; break; } done - for _bin in $_relink/usr/sbin/sshd $_relink/usr/bin/ssh-agent ; do + for _bin in $_relink/usr/sbin/sshd $_relink/usr/libexec/sshd-session \ + $_relink/usr/bin/ssh-agent ; do _tmpdir=$(mktemp -dq $_relink/_rebuild.XXXXXXXXXXXX) && ( set -o errexit diff --git a/gnu/usr.bin/perl/README.secbsd b/gnu/usr.bin/perl/README.secbsd index 2a6ba5ba4..6d2cdd194 100644 --- a/gnu/usr.bin/perl/README.secbsd +++ b/gnu/usr.bin/perl/README.secbsd @@ -1,3 +1,5 @@ +# vim: syntax=pod + If you read this file _as_is_, just ignore the funny characters you see. It is written in the POD format (see pod/perlpod.pod) which is specifically designed to be readable as is. diff --git a/gnu/usr.bin/perl/locale.c b/gnu/usr.bin/perl/locale.c index 92b6c1a6e..59c79b06c 100644 --- a/gnu/usr.bin/perl/locale.c +++ b/gnu/usr.bin/perl/locale.c @@ -2858,7 +2858,7 @@ Perl_setlocale(const int category, const char * locale) /* If the new locale is the same as the current one, nothing is actually * being changed, so do nothing. */ - if ( strEQ(retval, locale) + if ( retval != NULL && strEQ(retval, locale) && ( ! affects_LC_NUMERIC(category) # ifdef USE_LOCALE_NUMERIC diff --git a/include/unistd.h b/include/unistd.h index 295ad1d15..e110e5179 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: unistd.h,v 1.108 2023/12/12 15:30:55 deraadt Exp $ */ +/* $OpenBSD: unistd.h,v 1.109 2024/05/18 05:20:22 guenther Exp $ */ /* $NetBSD: unistd.h,v 1.26.4.1 1996/05/28 02:31:51 mrg Exp $ */ /*- @@ -357,6 +357,9 @@ int isatty(int); int link(const char *, const char *); off_t lseek(int, off_t, int); long pathconf(const char *, int); +#if __BSD_VISIBLE +long pathconfat(int, const char *, int, int); +#endif int pause(void); int pipe(int *); ssize_t read(int, void *, size_t) diff --git a/lib/libc/Symbols.list b/lib/libc/Symbols.list index b1e7e916b..eb4d78cc9 100644 --- a/lib/libc/Symbols.list +++ b/lib/libc/Symbols.list @@ -157,6 +157,7 @@ _thread_sys_nfssvc _thread_sys_open _thread_sys_openat _thread_sys_pathconf +_thread_sys_pathconfat _thread_sys_pipe _thread_sys_pipe2 _thread_sys_pledge @@ -359,6 +360,7 @@ nfssvc open openat pathconf +pathconfat pipe pipe2 pledge diff --git a/lib/libc/hidden/unistd.h b/lib/libc/hidden/unistd.h index 74918f596..f81cece3d 100644 --- a/lib/libc/hidden/unistd.h +++ b/lib/libc/hidden/unistd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: unistd.h,v 1.13 2023/12/12 15:30:55 deraadt Exp $ */ +/* $OpenBSD: unistd.h,v 1.14 2024/05/18 05:20:22 guenther Exp $ */ /* * Copyright (c) 2015 Philip Guenther * @@ -110,6 +110,7 @@ PROTO_NORMAL(mkstemp); PROTO_NORMAL(nfssvc); PROTO_DEPRECATED(nice); PROTO_NORMAL(pathconf); +PROTO_NORMAL(pathconfat); /*PROTO_CANCEL(pause);*/ PROTO_NORMAL(pipe); PROTO_NORMAL(pipe2); diff --git a/lib/libc/shlib_version b/lib/libc/shlib_version index 9a3cbbdfd..670da2562 100644 --- a/lib/libc/shlib_version +++ b/lib/libc/shlib_version @@ -1,4 +1,4 @@ major=100 -minor=0 +minor=1 # 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/sys/Makefile.inc b/lib/libc/sys/Makefile.inc index 07ca0a485..c864693d6 100644 --- a/lib/libc/sys/Makefile.inc +++ b/lib/libc/sys/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.178 2024/03/29 06:48:04 deraadt Exp $ +# $OpenBSD: Makefile.inc,v 1.179 2024/05/18 05:20:22 guenther Exp $ # $NetBSD: Makefile.inc,v 1.35 1995/10/16 23:49:07 jtc Exp $ # @(#)Makefile.inc 8.1 (Berkeley) 6/17/93 @@ -62,7 +62,7 @@ ASM= __semctl.o __thrsigdivert.o \ mknod.o mknodat.o mlock.o mlockall.o mmap.o mount.o mprotect.o \ mquery.o msgctl.o msgget.o munlock.o munlockall.o munmap.o \ nfssvc.o \ - pathconf.o pipe.o pipe2.o pledge.o profil.o \ + pathconf.o pathconfat.o pipe.o pipe2.o pledge.o profil.o \ quotactl.o \ readlink.o readlinkat.o reboot.o \ rename.o renameat.o revoke.o rmdir.o \ diff --git a/lib/libc/sys/pathconf.2 b/lib/libc/sys/pathconf.2 index 099f3bb5b..8be0618a7 100644 --- a/lib/libc/sys/pathconf.2 +++ b/lib/libc/sys/pathconf.2 @@ -1,4 +1,4 @@ -.\" $OpenBSD: pathconf.2,v 1.25 2018/06/21 20:30:36 jmc Exp $ +.\" $OpenBSD: pathconf.2,v 1.26 2024/05/18 05:20:22 guenther Exp $ .\" $NetBSD: pathconf.2,v 1.2 1995/02/27 12:35:22 cgd Exp $ .\" .\" Copyright (c) 1993 @@ -30,11 +30,12 @@ .\" .\" @(#)pathconf.2 8.1 (Berkeley) 6/4/93 .\" -.Dd $Mdocdate: June 21 2018 $ +.Dd $Mdocdate: May 18 2024 $ .Dt PATHCONF 2 .Os .Sh NAME .Nm pathconf , +.Nm pathconfat , .Nm fpathconf .Nd get configurable pathname variables .Sh SYNOPSIS @@ -43,9 +44,13 @@ .Fn pathconf "const char *path" "int name" .Ft long .Fn fpathconf "int fd" "int name" +.In fcntl.h +.Ft long +.Fn pathconfat "int fd" "const char *path" "int name" "int flag" .Sh DESCRIPTION The -.Fn pathconf +.Fn pathconf , +.Fn pathconfat , and .Fn fpathconf functions provide a method for applications to determine the current @@ -132,9 +137,48 @@ Returns 1 if synchronized I/O is supported, otherwise 0. .It Dv _PC_TIMESTAMP_RESOLUTION The resolution in nanoseconds of file timestamps. .El +.Pp +The +.Fn pathconfat +function is equivalent to +.Fn pathconf +except in the case where +.Fa path +specifies a relative path. +In this case the file to be changed is determined relative to the directory +associated with the file descriptor +.Fa fd +instead of the current working directory. +.Pp +If +.Fn pathconfat +is passed the special value +.Dv AT_FDCWD +(defined in +.In fcntl.h ) +in the +.Fa fd +parameter, the current working directory is used. +If +.Fa flag +is also zero, the behavior is identical to a call to +.Fn pathconf . +.Pp +The +.Fa flag +argument is the bitwise OR of zero or more of the following values: +.Pp +.Bl -tag -width AT_SYMLINK_NOFOLLOW -offset indent -compact +.It Dv AT_SYMLINK_NOFOLLOW +If +.Fa path +names a symbolic link, then the system variable for the symbolic +link is queried. +.El .Sh RETURN VALUES If the call to -.Fn pathconf +.Fn pathconf , +.Fn pathconfat , or .Fn fpathconf is not successful, \-1 is returned and @@ -147,7 +191,8 @@ is not modified. Otherwise, the current variable value is returned. .Sh ERRORS If any of the following conditions occur, the -.Fn pathconf +.Fn pathconf , +.Fn pathconfat , and .Fn fpathconf functions shall return \-1 and set @@ -166,6 +211,8 @@ An I/O error occurred while reading from the file system. .El .Pp .Fn pathconf +and +.Fn pathconfat will fail if: .Bl -tag -width Er .It Bq Er ENOTDIR @@ -190,6 +237,38 @@ Too many symbolic links were encountered in translating the pathname. points outside the process's allocated address space. .El .Pp +Additionally, the +.Fn pathconfat +function will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The value of the +.Fa flag +argument was neither zero nor +.Dv AT_SYMLINK_NOFOLLOW . +.It Bq Er EBADF +The +.Fa path +argument specifies a relative path and the +.Fa fd +argument is neither +.Dv AT_FDCWD +nor a valid file descriptor. +.It Bq Er ENOTDIR +The +.Fa path +argument specifies a relative path and the +.Fa fd +argument is a valid file descriptor but it does not reference a directory. +.It Bq Er EACCES +The +.Fa path +argument specifies a relative path but search permission is denied +for the directory which the +.Fa fd +file descriptor references. +.El +.Pp .Fn fpathconf will fail if: .Bl -tag -width Er @@ -214,3 +293,7 @@ and .Fn fpathconf functions first appeared in .Bx 4.4 . +The +.Fn pathconfat +function first appeared in +.Ox 7.6 . diff --git a/lib/libcrypto/asn1/asn1_gen.c b/lib/libcrypto/asn1/asn1_gen.c index 228f236b7..c7eafd726 100644 --- a/lib/libcrypto/asn1/asn1_gen.c +++ b/lib/libcrypto/asn1/asn1_gen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: asn1_gen.c,v 1.21 2023/07/05 21:23:36 beck Exp $ */ +/* $OpenBSD: asn1_gen.c,v 1.22 2024/05/17 02:57:26 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2002. */ @@ -533,7 +533,8 @@ static int asn1_str2tag(const char *tagstr, int len) { unsigned int i; - static const struct tag_name_st *tntmp, tnst [] = { + const struct tag_name_st *tntmp; + static const struct tag_name_st tnst[] = { ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN), ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN), ASN1_GEN_STR("NULL", V_ASN1_NULL), diff --git a/lib/libcrypto/asn1/x_bignum.c b/lib/libcrypto/asn1/x_bignum.c index bfcf94199..35b30da5b 100644 --- a/lib/libcrypto/asn1/x_bignum.c +++ b/lib/libcrypto/asn1/x_bignum.c @@ -1,4 +1,4 @@ -/* $OpenBSD: x_bignum.c,v 1.13 2022/11/26 16:08:50 tb Exp $ */ +/* $OpenBSD: x_bignum.c,v 1.14 2024/05/17 02:47:21 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2000. */ @@ -79,7 +79,7 @@ static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, static int bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx); -static ASN1_PRIMITIVE_FUNCS bignum_pf = { +static const ASN1_PRIMITIVE_FUNCS bignum_pf = { .app_data = NULL, .flags = 0, .prim_new = bn_new, diff --git a/lib/libcrypto/asn1/x_long.c b/lib/libcrypto/asn1/x_long.c index aafdb9c2e..01a0811e7 100644 --- a/lib/libcrypto/asn1/x_long.c +++ b/lib/libcrypto/asn1/x_long.c @@ -1,4 +1,4 @@ -/* $OpenBSD: x_long.c,v 1.19 2022/11/26 16:08:50 tb Exp $ */ +/* $OpenBSD: x_long.c,v 1.20 2024/05/17 02:49:21 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2000. */ @@ -81,7 +81,7 @@ static int long_c2i(ASN1_VALUE **pval, const unsigned char *content, int len, static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx); -static ASN1_PRIMITIVE_FUNCS long_pf = { +static const ASN1_PRIMITIVE_FUNCS long_pf = { .app_data = NULL, .flags = 0, .prim_new = long_new, diff --git a/lib/libcrypto/man/X509V3_get_d2i.3 b/lib/libcrypto/man/X509V3_get_d2i.3 index 6c406190a..f9d1e4675 100644 --- a/lib/libcrypto/man/X509V3_get_d2i.3 +++ b/lib/libcrypto/man/X509V3_get_d2i.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: X509V3_get_d2i.3,v 1.22 2024/05/12 17:44:11 tb Exp $ +.\" $OpenBSD: X509V3_get_d2i.3,v 1.23 2024/05/15 21:15:28 tb Exp $ .\" full merge up to: OpenSSL ff7fbfd5 Nov 2 11:52:01 2015 +0000 .\" selective merge up to: OpenSSL 99d63d46 Oct 26 13:56:48 2016 -0400 .\" @@ -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: May 12 2024 $ +.Dd $Mdocdate: May 15 2024 $ .Dt X509V3_GET_D2I 3 .Os .Sh NAME @@ -155,8 +155,8 @@ .Ft void .Fo X509_get0_uids .Fa "const X509 *x" -.Fa "const ASN1_BIT_STRING **piuid" -.Fa "const ASN1_BIT_STRING **psuid" +.Fa "const ASN1_BIT_STRING **issuerUID" +.Fa "const ASN1_BIT_STRING **subjectUID" .Fc .Sh DESCRIPTION .Fn X509V3_get_d2i @@ -312,14 +312,22 @@ It is possible to determine the precise reason by checking the value of .Pf * Fa crit . .Pp .Fn X509_get0_uids -sets -.Fa *piuid -and -.Fa *psuid -to the issuer and subject unique identifiers of certificate +returns the issuer and subject unique identifiers of the certificate .Fa x -or NULL if the fields are not present. -These fields are rarely used. +in +.Pf * Fa issuerUID +and +.Pf * Fa subjectUID . +If a unique identifier field is not present in +.Fa x , +.Dv NULL +is returned. +Either one of +.Fa issuerUID +and +.Fa subjectUID +can be +.Dv NULL . .Sh SUPPORTED EXTENSIONS The following sections contain a list of all supported extensions including their name and NID. diff --git a/lib/libcrypto/x509/x509_v3.c b/lib/libcrypto/x509/x509_v3.c index 8dddb463c..3dee31e19 100644 --- a/lib/libcrypto/x509/x509_v3.c +++ b/lib/libcrypto/x509/x509_v3.c @@ -1,4 +1,4 @@ -/* $OpenBSD: x509_v3.c,v 1.21 2023/02/16 08:38:17 tb Exp $ */ +/* $OpenBSD: x509_v3.c,v 1.22 2024/05/16 13:19:09 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -72,8 +72,8 @@ int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x) { if (x == NULL) - return (0); - return (sk_X509_EXTENSION_num(x)); + return 0; + return sk_X509_EXTENSION_num(x); } LCRYPTO_ALIAS(X509v3_get_ext_count); @@ -84,8 +84,8 @@ X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid, int lastpos) obj = OBJ_nid2obj(nid); if (obj == NULL) - return (-2); - return (X509v3_get_ext_by_OBJ(x, obj, lastpos)); + return -2; + return X509v3_get_ext_by_OBJ(x, obj, lastpos); } LCRYPTO_ALIAS(X509v3_get_ext_by_NID); @@ -97,7 +97,7 @@ X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk, X509_EXTENSION *ex; if (sk == NULL) - return (-1); + return -1; lastpos++; if (lastpos < 0) lastpos = 0; @@ -105,9 +105,9 @@ X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk, for (; lastpos < n; lastpos++) { ex = sk_X509_EXTENSION_value(sk, lastpos); if (OBJ_cmp(ex->object, obj) == 0) - return (lastpos); + return lastpos; } - return (-1); + return -1; } LCRYPTO_ALIAS(X509v3_get_ext_by_OBJ); @@ -119,18 +119,18 @@ X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit, X509_EXTENSION *ex; if (sk == NULL) - return (-1); + return -1; lastpos++; if (lastpos < 0) lastpos = 0; n = sk_X509_EXTENSION_num(sk); for (; lastpos < n; lastpos++) { ex = sk_X509_EXTENSION_value(sk, lastpos); - if (((ex->critical > 0) && crit) || - ((ex->critical <= 0) && !crit)) - return (lastpos); + if ((ex->critical > 0 && crit) || + (ex->critical <= 0 && !crit)) + return lastpos; } - return (-1); + return -1; } LCRYPTO_ALIAS(X509v3_get_ext_by_critical); @@ -150,9 +150,9 @@ X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc) X509_EXTENSION *ret; if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0) - return (NULL); + return NULL; ret = sk_X509_EXTENSION_delete(x, loc); - return (ret); + return ret; } LCRYPTO_ALIAS(X509v3_delete_ext); @@ -186,16 +186,16 @@ X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, X509_EXTENSION *ex, int loc) goto err; if (*x == NULL) *x = sk; - return (sk); + return sk; err: X509error(ERR_R_MALLOC_FAILURE); err2: if (new_ex != NULL) X509_EXTENSION_free(new_ex); - if (sk != NULL && (x != NULL && sk != *x)) + if (sk != NULL && x != NULL && sk != *x) sk_X509_EXTENSION_free(sk); - return (NULL); + return NULL; } LCRYPTO_ALIAS(X509v3_add_ext); @@ -209,12 +209,12 @@ X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid, int crit, obj = OBJ_nid2obj(nid); if (obj == NULL) { X509error(X509_R_UNKNOWN_NID); - return (NULL); + return NULL; } ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data); if (ret == NULL) ASN1_OBJECT_free(obj); - return (ret); + return ret; } LCRYPTO_ALIAS(X509_EXTENSION_create_by_NID); @@ -224,10 +224,10 @@ X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, const ASN1_OBJECT *obj, { X509_EXTENSION *ret; - if ((ex == NULL) || (*ex == NULL)) { + if (ex == NULL || *ex == NULL) { if ((ret = X509_EXTENSION_new()) == NULL) { X509error(ERR_R_MALLOC_FAILURE); - return (NULL); + return NULL; } } else ret= *ex; @@ -239,22 +239,22 @@ X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, const ASN1_OBJECT *obj, if (!X509_EXTENSION_set_data(ret, data)) goto err; - if ((ex != NULL) && (*ex == NULL)) + if (ex != NULL && *ex == NULL) *ex = ret; - return (ret); + return ret; err: - if ((ex == NULL) || (ret != *ex)) + if (ex == NULL || ret != *ex) X509_EXTENSION_free(ret); - return (NULL); + return NULL; } LCRYPTO_ALIAS(X509_EXTENSION_create_by_OBJ); int X509_EXTENSION_set_object(X509_EXTENSION *ex, const ASN1_OBJECT *obj) { - if ((ex == NULL) || (obj == NULL)) - return (0); + if (ex == NULL || obj == NULL) + return 0; ASN1_OBJECT_free(ex->object); ex->object = OBJ_dup(obj); return ex->object != NULL; @@ -265,9 +265,9 @@ int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit) { if (ex == NULL) - return (0); - ex->critical = (crit) ? 0xFF : -1; - return (1); + return 0; + ex->critical = crit ? 0xFF : -1; + return 1; } LCRYPTO_ALIAS(X509_EXTENSION_set_critical); @@ -277,11 +277,11 @@ X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data) int i; if (ex == NULL) - return (0); + return 0; i = ASN1_STRING_set(ex->value, data->data, data->length); if (!i) - return (0); - return (1); + return 0; + return 1; } LCRYPTO_ALIAS(X509_EXTENSION_set_data); @@ -289,8 +289,8 @@ ASN1_OBJECT * X509_EXTENSION_get_object(X509_EXTENSION *ex) { if (ex == NULL) - return (NULL); - return (ex->object); + return NULL; + return ex->object; } LCRYPTO_ALIAS(X509_EXTENSION_get_object); @@ -298,8 +298,8 @@ ASN1_OCTET_STRING * X509_EXTENSION_get_data(X509_EXTENSION *ex) { if (ex == NULL) - return (NULL); - return (ex->value); + return NULL; + return ex->value; } LCRYPTO_ALIAS(X509_EXTENSION_get_data); @@ -307,7 +307,7 @@ int X509_EXTENSION_get_critical(const X509_EXTENSION *ex) { if (ex == NULL) - return (0); + return 0; if (ex->critical > 0) return 1; return 0; diff --git a/lib/libssl/man/SSL_CTX_set_keylog_callback.3 b/lib/libssl/man/SSL_CTX_set_keylog_callback.3 index 04c94fa83..24b8f9992 100644 --- a/lib/libssl/man/SSL_CTX_set_keylog_callback.3 +++ b/lib/libssl/man/SSL_CTX_set_keylog_callback.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: SSL_CTX_set_keylog_callback.3,v 1.2 2021/10/23 13:17:03 schwarze Exp $ +.\" $OpenBSD: SSL_CTX_set_keylog_callback.3,v 1.3 2024/05/16 08:39:30 tb Exp $ .\" OpenSSL pod checked up to: 61f805c1 Jan 16 01:01:46 2018 +0800 .\" .\" Copyright (c) 2021 Bob Beck @@ -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: October 23 2021 $ +.Dd $Mdocdate: May 16 2024 $ .Dt SSL_CTX_SET_KEYLOG_CALLBACK 3 .Os .Sh NAME @@ -38,7 +38,7 @@ sets the TLS key logging callback. This callback is never called in LibreSSL. .Pp -.Fn SSL_CTX_set_keylog_callback +.Fn SSL_CTX_get_keylog_callback retrieves the previously set TLS key logging callback. .Pp These functions are provided only for compatibility with OpenSSL. diff --git a/libexec/ld.so/util.h b/libexec/ld.so/util.h index 6b4f3aaef..5f9d60631 100644 --- a/libexec/ld.so/util.h +++ b/libexec/ld.so/util.h @@ -1,4 +1,4 @@ -/* $OpenBSD: util.h,v 1.40 2023/12/08 12:58:27 deraadt Exp $ */ +/* $OpenBSD: util.h,v 1.41 2024/05/17 06:11:54 deraadt Exp $ */ /* * Copyright (c) 1998 Todd C. Miller @@ -32,6 +32,7 @@ #define __DL_UTIL_H__ #include +#include #include #include /* for NULL */ @@ -72,7 +73,7 @@ long _dl_strtol(const char *nptr, char **endptr, int base); __dead void _dl_oom(void); __dead void _dl_die(const char *, ...) __attribute__((format (printf, 1, 2))); -#define _dl_diedie() _dl_thrkill(0, 9, NULL) +#define _dl_diedie() _dl_thrkill(0, SIGKILL, NULL) __END_HIDDEN_DECLS #define _dl_round_page(x) \ diff --git a/regress/usr.bin/mandoc/char/unicode/ascii.in b/regress/usr.bin/mandoc/char/unicode/ascii.in index b8e561a8a..cbefe4eee 100644 --- a/regress/usr.bin/mandoc/char/unicode/ascii.in +++ b/regress/usr.bin/mandoc/char/unicode/ascii.in @@ -1,10 +1,11 @@ -.\" $OpenBSD: ascii.in,v 1.4 2017/07/04 14:53:23 schwarze Exp $ -.TH CHAR-UNICODE-ASCII 1 "October 27, 2014" +.\" $OpenBSD: ascii.in,v 1.5 2024/05/16 18:49:00 schwarze Exp $ +.TH CHAR-UNICODE-ASCII 1 "May 16, 2024" .SH NAME char-unicode-ascii \- Unicode characters in the ASCII range .SH DESCRIPTION .nf BEGINTEST +\[u0020]\N'32' SPACE \[u0022]\N'34'\(dq QUOTATION MARK \[u0023]\N'35'\(sh NUMBER SIGN \[u0024]\N'36'\(Do DOLLAR SIGN diff --git a/regress/usr.bin/mandoc/char/unicode/ascii.out_ascii b/regress/usr.bin/mandoc/char/unicode/ascii.out_ascii index 8a6313543..2540bca2a 100644 --- a/regress/usr.bin/mandoc/char/unicode/ascii.out_ascii +++ b/regress/usr.bin/mandoc/char/unicode/ascii.out_ascii @@ -5,6 +5,7 @@ NNAAMMEE DDEESSCCRRIIPPTTIIOONN BEGINTEST + SPACE """ QUOTATION MARK ### NUMBER SIGN $$$ DOLLAR SIGN @@ -27,4 +28,4 @@ DDEESSCCRRIIPPTTIIOONN ~~~~ TILDE ENDTEST -OpenBSD October 27, 2014 CHAR-UNICODE-ASCII(1) +OpenBSD May 16, 2024 CHAR-UNICODE-ASCII(1) diff --git a/regress/usr.bin/mandoc/char/unicode/ascii.out_html b/regress/usr.bin/mandoc/char/unicode/ascii.out_html index 264fa356d..441362abf 100644 --- a/regress/usr.bin/mandoc/char/unicode/ascii.out_html +++ b/regress/usr.bin/mandoc/char/unicode/ascii.out_html @@ -1,3 +1,4 @@ + SPACE """ QUOTATION MARK ### NUMBER SIGN $$$ DOLLAR SIGN diff --git a/regress/usr.bin/mandoc/char/unicode/ascii.out_utf8 b/regress/usr.bin/mandoc/char/unicode/ascii.out_utf8 index 8a6313543..2540bca2a 100644 --- a/regress/usr.bin/mandoc/char/unicode/ascii.out_utf8 +++ b/regress/usr.bin/mandoc/char/unicode/ascii.out_utf8 @@ -5,6 +5,7 @@ NNAAMMEE DDEESSCCRRIIPPTTIIOONN BEGINTEST + SPACE """ QUOTATION MARK ### NUMBER SIGN $$$ DOLLAR SIGN @@ -27,4 +28,4 @@ DDEESSCCRRIIPPTTIIOONN ~~~~ TILDE ENDTEST -OpenBSD October 27, 2014 CHAR-UNICODE-ASCII(1) +OpenBSD May 16, 2024 CHAR-UNICODE-ASCII(1) diff --git a/regress/usr.bin/mandoc/char/unicode/input.in b/regress/usr.bin/mandoc/char/unicode/input.in index 276d7c54d1c9e02bcd2f16ac4d825da43cc33a08..561ae8a3f1ae965f8aa5add798ffbebf350248c2 100644 GIT binary patch delta 331 zcmew(GDUoXw5XYak%5tkzJaN}p_zh_p_P%jm9fP{11%ok#7YH2Gaaz>#3PASW?7H8(Y{L?JmNu_!UQ zB((^l(FLY41**{{_Wl07Rz;q;wYb8xq(Zg0#=hUb&#EZ3EVZaOHAMl begin of second start byte U+CFFF 0xecbfbf end of last normal start byte U+D000 0xed8080 begin of last start byte + U+D7FB 0xed9fbb highest valid public three-byte U+D7FF 0xed9fbf highest public three-byte U+D800 0xeda080 ??? lowest surrogate U+DFFF 0xedbfbf ??? highest surrogate U+E000 0xee8080 lowest private use U+F8FF 0xefa3bf highest private use U+F900 0xefa480 lowest post-private + U+FEFF 0xefbbbf byte-order mark + U+FFFC 0xefbfbc object replacement character + U+FFFD 0xefbfbd replacement character + U+FFFE 0xefbfbe reversed byte-order mark U+FFFF 0xefbfbf highest three-byte FFoouurr--bbyyttee rraannggee @@ -60,4 +65,4 @@ DDEESSCCRRIIPPTTIIOONN U+1FFFFF 0xf7bfbfbf ???? highest invalid four-byte U+200000 0xf888808080 ????? lowest five-byte -OpenBSD June 2, 2021 CHAR-UNICODE-INPUT(1) +OpenBSD May 16, 2024 CHAR-UNICODE-INPUT(1) diff --git a/regress/usr.bin/mandoc/char/unicode/input.out_lint b/regress/usr.bin/mandoc/char/unicode/input.out_lint index fa36f8769..ea22826bb 100644 --- a/regress/usr.bin/mandoc/char/unicode/input.out_lint +++ b/regress/usr.bin/mandoc/char/unicode/input.out_lint @@ -21,61 +21,63 @@ mandoc: input.in:34:19: ERROR: skipping bad character: 0x80 mandoc: input.in:35:17: ERROR: skipping bad character: 0xe0 mandoc: input.in:35:18: ERROR: skipping bad character: 0x9f mandoc: input.in:35:19: ERROR: skipping bad character: 0xbf -mandoc: input.in:42:25: ERROR: skipping bad character: 0xed -mandoc: input.in:42:26: ERROR: skipping bad character: 0xa0 -mandoc: input.in:42:27: ERROR: skipping bad character: 0x80 -mandoc: input.in:42:17: ERROR: invalid special character: \[uD800] -mandoc: input.in:43:25: ERROR: skipping bad character: 0xed -mandoc: input.in:43:26: ERROR: skipping bad character: 0xbf -mandoc: input.in:43:27: ERROR: skipping bad character: 0xbf -mandoc: input.in:43:17: ERROR: invalid special character: \[uDFFF] -mandoc: input.in:53:19: ERROR: skipping bad character: 0xf0 -mandoc: input.in:53:20: ERROR: skipping bad character: 0x80 -mandoc: input.in:53:21: ERROR: skipping bad character: 0x80 -mandoc: input.in:53:22: ERROR: skipping bad character: 0x80 -mandoc: input.in:54:19: ERROR: skipping bad character: 0xf0 -mandoc: input.in:54:20: ERROR: skipping bad character: 0x80 -mandoc: input.in:54:21: ERROR: skipping bad character: 0x81 -mandoc: input.in:54:22: ERROR: skipping bad character: 0xbf -mandoc: input.in:55:19: ERROR: skipping bad character: 0xf0 -mandoc: input.in:55:20: ERROR: skipping bad character: 0x80 -mandoc: input.in:55:21: ERROR: skipping bad character: 0x82 -mandoc: input.in:55:22: ERROR: skipping bad character: 0x80 -mandoc: input.in:56:19: ERROR: skipping bad character: 0xf0 -mandoc: input.in:56:20: ERROR: skipping bad character: 0x80 -mandoc: input.in:56:21: ERROR: skipping bad character: 0x9f -mandoc: input.in:56:22: ERROR: skipping bad character: 0xbf -mandoc: input.in:57:19: ERROR: skipping bad character: 0xf0 -mandoc: input.in:57:20: ERROR: skipping bad character: 0x80 -mandoc: input.in:57:21: ERROR: skipping bad character: 0xa0 -mandoc: input.in:57:22: ERROR: skipping bad character: 0x80 +mandoc: input.in:43:33: ERROR: skipping bad character: 0xed +mandoc: input.in:43:34: ERROR: skipping bad character: 0xa0 +mandoc: input.in:43:35: ERROR: skipping bad character: 0x80 +mandoc: input.in:43:17: ERROR: invalid special character: \[uD800] +mandoc: input.in:43:25: ERROR: invalid special character: \[ud800] +mandoc: input.in:44:33: ERROR: skipping bad character: 0xed +mandoc: input.in:44:34: ERROR: skipping bad character: 0xbf +mandoc: input.in:44:35: ERROR: skipping bad character: 0xbf +mandoc: input.in:44:17: ERROR: invalid special character: \[uDFFF] +mandoc: input.in:44:25: ERROR: invalid special character: \[udfff] mandoc: input.in:58:19: ERROR: skipping bad character: 0xf0 -mandoc: input.in:58:20: ERROR: skipping bad character: 0x8f -mandoc: input.in:58:21: ERROR: skipping bad character: 0xbf -mandoc: input.in:58:22: ERROR: skipping bad character: 0xbf -mandoc: input.in:67:31: ERROR: skipping bad character: 0xf4 -mandoc: input.in:67:32: ERROR: skipping bad character: 0x90 -mandoc: input.in:67:33: ERROR: skipping bad character: 0x80 -mandoc: input.in:67:34: ERROR: skipping bad character: 0x80 -mandoc: input.in:67:21: ERROR: invalid special character: \[u110000] -mandoc: input.in:68:31: ERROR: skipping bad character: 0xf4 -mandoc: input.in:68:32: ERROR: skipping bad character: 0xbf -mandoc: input.in:68:33: ERROR: skipping bad character: 0xbf -mandoc: input.in:68:34: ERROR: skipping bad character: 0xbf -mandoc: input.in:68:21: ERROR: invalid special character: \[u13FFFF] -mandoc: input.in:69:31: ERROR: skipping bad character: 0xf5 -mandoc: input.in:69:32: ERROR: skipping bad character: 0x80 -mandoc: input.in:69:33: ERROR: skipping bad character: 0x80 -mandoc: input.in:69:34: ERROR: skipping bad character: 0x80 -mandoc: input.in:69:21: ERROR: invalid special character: \[u140000] -mandoc: input.in:70:31: ERROR: skipping bad character: 0xf7 -mandoc: input.in:70:32: ERROR: skipping bad character: 0xbf -mandoc: input.in:70:33: ERROR: skipping bad character: 0xbf -mandoc: input.in:70:34: ERROR: skipping bad character: 0xbf -mandoc: input.in:70:21: ERROR: invalid special character: \[u1FFFFF] -mandoc: input.in:71:33: ERROR: skipping bad character: 0xf8 -mandoc: input.in:71:34: ERROR: skipping bad character: 0x88 -mandoc: input.in:71:35: ERROR: skipping bad character: 0x80 -mandoc: input.in:71:36: ERROR: skipping bad character: 0x80 -mandoc: input.in:71:37: ERROR: skipping bad character: 0x80 -mandoc: input.in:71:23: ERROR: invalid special character: \[u200000] +mandoc: input.in:58:20: ERROR: skipping bad character: 0x80 +mandoc: input.in:58:21: ERROR: skipping bad character: 0x80 +mandoc: input.in:58:22: ERROR: skipping bad character: 0x80 +mandoc: input.in:59:19: ERROR: skipping bad character: 0xf0 +mandoc: input.in:59:20: ERROR: skipping bad character: 0x80 +mandoc: input.in:59:21: ERROR: skipping bad character: 0x81 +mandoc: input.in:59:22: ERROR: skipping bad character: 0xbf +mandoc: input.in:60:19: ERROR: skipping bad character: 0xf0 +mandoc: input.in:60:20: ERROR: skipping bad character: 0x80 +mandoc: input.in:60:21: ERROR: skipping bad character: 0x82 +mandoc: input.in:60:22: ERROR: skipping bad character: 0x80 +mandoc: input.in:61:19: ERROR: skipping bad character: 0xf0 +mandoc: input.in:61:20: ERROR: skipping bad character: 0x80 +mandoc: input.in:61:21: ERROR: skipping bad character: 0x9f +mandoc: input.in:61:22: ERROR: skipping bad character: 0xbf +mandoc: input.in:62:19: ERROR: skipping bad character: 0xf0 +mandoc: input.in:62:20: ERROR: skipping bad character: 0x80 +mandoc: input.in:62:21: ERROR: skipping bad character: 0xa0 +mandoc: input.in:62:22: ERROR: skipping bad character: 0x80 +mandoc: input.in:63:19: ERROR: skipping bad character: 0xf0 +mandoc: input.in:63:20: ERROR: skipping bad character: 0x8f +mandoc: input.in:63:21: ERROR: skipping bad character: 0xbf +mandoc: input.in:63:22: ERROR: skipping bad character: 0xbf +mandoc: input.in:72:31: ERROR: skipping bad character: 0xf4 +mandoc: input.in:72:32: ERROR: skipping bad character: 0x90 +mandoc: input.in:72:33: ERROR: skipping bad character: 0x80 +mandoc: input.in:72:34: ERROR: skipping bad character: 0x80 +mandoc: input.in:72:21: ERROR: invalid special character: \[u110000] +mandoc: input.in:73:31: ERROR: skipping bad character: 0xf4 +mandoc: input.in:73:32: ERROR: skipping bad character: 0xbf +mandoc: input.in:73:33: ERROR: skipping bad character: 0xbf +mandoc: input.in:73:34: ERROR: skipping bad character: 0xbf +mandoc: input.in:73:21: ERROR: invalid special character: \[u13FFFF] +mandoc: input.in:74:31: ERROR: skipping bad character: 0xf5 +mandoc: input.in:74:32: ERROR: skipping bad character: 0x80 +mandoc: input.in:74:33: ERROR: skipping bad character: 0x80 +mandoc: input.in:74:34: ERROR: skipping bad character: 0x80 +mandoc: input.in:74:21: ERROR: invalid special character: \[u140000] +mandoc: input.in:75:31: ERROR: skipping bad character: 0xf7 +mandoc: input.in:75:32: ERROR: skipping bad character: 0xbf +mandoc: input.in:75:33: ERROR: skipping bad character: 0xbf +mandoc: input.in:75:34: ERROR: skipping bad character: 0xbf +mandoc: input.in:75:21: ERROR: invalid special character: \[u1FFFFF] +mandoc: input.in:76:33: ERROR: skipping bad character: 0xf8 +mandoc: input.in:76:34: ERROR: skipping bad character: 0x88 +mandoc: input.in:76:35: ERROR: skipping bad character: 0x80 +mandoc: input.in:76:36: ERROR: skipping bad character: 0x80 +mandoc: input.in:76:37: ERROR: skipping bad character: 0x80 +mandoc: input.in:76:23: ERROR: invalid special character: \[u200000] diff --git a/regress/usr.bin/mandoc/char/unicode/input.out_utf8 b/regress/usr.bin/mandoc/char/unicode/input.out_utf8 index 429b427ad..348cb6839 100644 --- a/regress/usr.bin/mandoc/char/unicode/input.out_utf8 +++ b/regress/usr.bin/mandoc/char/unicode/input.out_utf8 @@ -31,12 +31,17 @@ DDEESSCCRRIIPPTTIIOONN U+1000 0xe18080 ကက begin of second start byte U+CFFF 0xecbfbf 쿿쿿 end of last normal start byte U+D000 0xed8080 퀀퀀 begin of last start byte + U+D7FB 0xed9fbb ퟻퟻ highest valid public three-byte U+D7FF 0xed9fbf ퟿퟿ highest public three-byte U+D800 0xeda080 ??? lowest surrogate U+DFFF 0xedbfbf ??? highest surrogate U+E000 0xee8080  lowest private use U+F8FF 0xefa3bf  highest private use U+F900 0xefa480 豈豈 lowest post-private + U+FEFF 0xefbbbf  byte-order mark + U+FFFC 0xefbfbc  object replacement character + U+FFFD 0xefbfbd �� replacement character + U+FFFE 0xefbfbe ￾￾ reversed byte-order mark U+FFFF 0xefbfbf ￿￿ highest three-byte FFoouurr--bbyyttee rraannggee @@ -60,4 +65,4 @@ DDEESSCCRRIIPPTTIIOONN U+1FFFFF 0xf7bfbfbf ???? highest invalid four-byte U+200000 0xf888808080 ????? lowest five-byte -OpenBSD June 2, 2021 CHAR-UNICODE-INPUT(1) +OpenBSD May 16, 2024 CHAR-UNICODE-INPUT(1) diff --git a/regress/usr.bin/mandoc/char/unicode/nogroff.in b/regress/usr.bin/mandoc/char/unicode/nogroff.in index 9e2b595dc..cfeba6f4a 100644 --- a/regress/usr.bin/mandoc/char/unicode/nogroff.in +++ b/regress/usr.bin/mandoc/char/unicode/nogroff.in @@ -1,5 +1,5 @@ -.\" $OpenBSD: nogroff.in,v 1.6 2021/06/02 17:36:59 schwarze Exp $ -.TH CHAR-UNICODE-NOGROFF 1 "June 2, 2021" +.\" $OpenBSD: nogroff.in,v 1.8 2024/05/16 18:49:00 schwarze Exp $ +.TH CHAR-UNICODE-NOGROFF 1 "May 16, 2024" .SH NAME char-unicode-nogroff \- characters handled differently by groff .SH DESCRIPTION @@ -7,6 +7,11 @@ char-unicode-nogroff \- characters handled differently by groff BEGINTEST \[u0000]\N'0' NULL \[u0001]\N'1' START OF HEADING +\[u0002]\N'2' START OF TEXT +\[u0003]\N'3' END OF TEXT +\[u0004]\N'4' END OF TRANSMISSION +\[u0005]\N'5' ENQUIRY +\[u0006]\N'6' ACKNOWLEDGE \[u0007]\N'7' BELL \[u0008]\N'8' BACKSPACE \[u0009]\N'9' CHARACTER TABULATION @@ -14,12 +19,76 @@ BEGINTEST \[u000B]\N'11' LINE TABULATION \[u000C]\N'12' FORM FEED \[u000D]\N'13' CARRIAGE RETURN +\[u000E]\N'14' SHIFT OUT +\[u000F]\N'15' SHIFT IN +\[u0010]\N'16' DATA LINK ESCAPE +\[u0011]\N'17' DEVICE CONTROL ONE +\[u0012]\N'18' DEVICE CONTROL TWO +\[u0013]\N'19' DEVICE CONTROL THREE +\[u0014]\N'20' DEVICE CONTROL FOUR +\[u0015]\N'21' NEGATIVE ACKNOWLEDGE +\[u0016]\N'22' SYNCHRONOUS IDLE +\[u0017]\N'23' END OF TRANSMISSION BLOCK +\[u0018]\N'24' CANCEL +\[u0019]\N'25' END OF MEDIUM +\[u001A]\N'26' SUBSTITUTE \[u001B]\N'27' ESCAPE +\[u001C]\N'28' INFORMATION SEPARATOR FOUR +\[u001D]\N'29' INFORMATION SEPARATOR THREE +\[u001E]\N'30' INFORMATION SEPARATOR TWO +\[u001F]\N'31' INFORMATION SEPARATOR INE +\[u0021]\N'33' EXCLAMATION MARK +\[u0025]\N'37' PERCENT SIGN +\[u0026]\N'38' AMPERSAND +\[u0028]\N'40' LEFT PARENTHESIS +\[u0029]\N'41' RIGHT PARENTHESIS +\[u002A]\N'42' ASTERISK +\[u002C]\N'44' COMMA +\[u002D]\N'45' HYPHEN-MINUS +\[u002E]\N'46' FULL STOP +\[u0030]\N'48' DIGIT ZERO +\[u0031]\N'49' DIGIT ONE +\[u0039]\N'57' DIGIT NINE +\[u003A]\N'58' COLON +\[u003B]\N'59' SEMICOLON +\[u003C]\N'60' LESS-THAN SIGN +\[u003E]\N'62' GREATER-THAN SIGN +\[u003F]\N'63' QUESTION MARK +\[u0041]\N'65' LATIN CAPITAL LETTER A +\[u005A]\N'90' LATIN CAPITAL LETTER Z +\[u0061]\N'97' LATIN SMALL LETTER A +\[u007A]\N'122' LATIN SMALL LETTER Z \[u007F]\N'127' DELETE \[u0080]\N'128' 0x80 \[u0081]\N'129' 0x81 \[u0082]\N'130' BREAK PERMITTED HERE \[u0083]\N'131' NO BREAK HERE +\[u0084]\N'132' 0x84 +\[u0085]\N'133' NEXT LINE (NEL) +\[u0086]\N'134' START OF SELECTED AREA +\[u0087]\N'135' END OF SELECTED AREA +\[u0088]\N'136' CHARACTER TABULATION SET +\[u0089]\N'137' CHARACTER TABULATION WITH JUSTIFICATION +\[u008A]\N'138' LINE TABULATION SET +\[u008B]\N'139' PARTIAL LINE FORWARD +\[u008C]\N'140' PARTIAL LINE BACKWARD +\[u008D]\N'141' REVERSE LINE FEED +\[u008E]\N'142' SINGLE SHIFT TWO +\[u008F]\N'143' SINGLE SHIFT THREE +\[u0090]\N'144' DEVICE CONTROL STRING +\[u0091]\N'145' PRIVATE USE ONE +\[u0092]\N'146' PRIVATE USE TWO +\[u0093]\N'147' SET TRANSMIT STATE +\[u0094]\N'148' CANCEL CHARACTER +\[u0095]\N'149' MESSAGE WAITING +\[u0096]\N'150' START OF GUARDED AREA +\[u0097]\N'151' END OF GUARDED AREA +\[u0098]\N'152' START OF STRING +\[u0099]\N'153' 0x99 +\[u009A]\N'154' SINGLE CHARACTER INTRODUCER +\[u009B]\N'155' CONTROL SEQUENCE INTRODUCER +\[u009C]\N'156' STRING TERMINATOR +\[u009D]\N'157' OPERATING SYSTEM COMMAND \[u009E]\N'158' PRIVACY MESSAGE \[u009F]\N'159' APPLICATION PROGRAM COMMAND \[u226A]\(<< MUCH LESS-THAN diff --git a/regress/usr.bin/mandoc/char/unicode/nogroff.out_ascii b/regress/usr.bin/mandoc/char/unicode/nogroff.out_ascii index d9d53ce2d..3c068797b 100644 --- a/regress/usr.bin/mandoc/char/unicode/nogroff.out_ascii +++ b/regress/usr.bin/mandoc/char/unicode/nogroff.out_ascii @@ -7,6 +7,11 @@ DDEESSCCRRIIPPTTIIOONN BEGINTEST NULL START OF HEADING + START OF TEXT + END OF TEXT + END OF TRANSMISSION + ENQUIRY + ACKNOWLEDGE BELL BACKSPACE CHARACTER TABULATION @@ -14,12 +19,76 @@ DDEESSCCRRIIPPTTIIOONN LINE TABULATION FORM FEED CARRIAGE RETURN + SHIFT OUT + SHIFT IN + DATA LINK ESCAPE + DEVICE CONTROL ONE + DEVICE CONTROL TWO + DEVICE CONTROL THREE + DEVICE CONTROL FOUR + NEGATIVE ACKNOWLEDGE + SYNCHRONOUS IDLE + END OF TRANSMISSION BLOCK + CANCEL + END OF MEDIUM + SUBSTITUTE ESCAPE + INFORMATION SEPARATOR FOUR + INFORMATION SEPARATOR THREE + INFORMATION SEPARATOR TWO + INFORMATION SEPARATOR INE + !! EXCLAMATION MARK + %% PERCENT SIGN + && AMPERSAND + (( LEFT PARENTHESIS + )) RIGHT PARENTHESIS + ** ASTERISK + ,, COMMA + -- HYPHEN-MINUS + .. FULL STOP + 00 DIGIT ZERO + 11 DIGIT ONE + 99 DIGIT NINE + :: COLON + ;; SEMICOLON + << LESS-THAN SIGN + >> GREATER-THAN SIGN + ?? QUESTION MARK + AA LATIN CAPITAL LETTER A + ZZ LATIN CAPITAL LETTER Z + aa LATIN SMALL LETTER A + zz LATIN SMALL LETTER Z DELETE <80><80> 0x80 <81><81> 0x81 <82><82> BREAK PERMITTED HERE <83><83> NO BREAK HERE + <84><84> 0x84 + <85><85> NEXT LINE (NEL) + <86><86> START OF SELECTED AREA + <87><87> END OF SELECTED AREA + <88><88> CHARACTER TABULATION SET + <89><89> CHARACTER TABULATION WITH JUSTIFICATION + <8A><8A> LINE TABULATION SET + <8B><8B> PARTIAL LINE FORWARD + <8C><8C> PARTIAL LINE BACKWARD + <8D><8D> REVERSE LINE FEED + <8E><8E> SINGLE SHIFT TWO + <8F><8F> SINGLE SHIFT THREE + <90><90> DEVICE CONTROL STRING + <91><91> PRIVATE USE ONE + <92><92> PRIVATE USE TWO + <93><93> SET TRANSMIT STATE + <94><94> CANCEL CHARACTER + <95><95> MESSAGE WAITING + <96><96> START OF GUARDED AREA + <97><97> END OF GUARDED AREA + <98><98> START OF STRING + <99><99> 0x99 + <9A><9A> SINGLE CHARACTER INTRODUCER + <9B><9B> CONTROL SEQUENCE INTRODUCER + <9C><9C> STRING TERMINATOR + <9D><9D> OPERATING SYSTEM COMMAND <9E><9E> PRIVACY MESSAGE <9F><9F> APPLICATION PROGRAM COMMAND <<<< MUCH LESS-THAN @@ -50,4 +119,4 @@ DDEESSCCRRIIPPTTIIOONN ENDTEST -OpenBSD June 2, 2021 CHAR-UNICODE-NOGROFF(1) +OpenBSD May 16, 2024 CHAR-UNICODE-NOGROFF(1) diff --git a/regress/usr.bin/mandoc/char/unicode/nogroff.out_html b/regress/usr.bin/mandoc/char/unicode/nogroff.out_html index 78639657e..8f5710988 100644 --- a/regress/usr.bin/mandoc/char/unicode/nogroff.out_html +++ b/regress/usr.bin/mandoc/char/unicode/nogroff.out_html @@ -1,5 +1,10 @@ �� <control> NULL �� <control> START OF HEADING +�� <control> START OF TEXT +�� <control> END OF TEXT +�� <control> END OF TRANSMISSION +�� <control> ENQUIRY +�� <control> ACKNOWLEDGE �� <control> BELL �� <control> BACKSPACE <control> CHARACTER TABULATION @@ -7,12 +12,76 @@ �� <control> LINE TABULATION �� <control> FORM FEED �� <control> CARRIAGE RETURN +�� <control> SHIFT OUT +�� <control> SHIFT IN +�� <control> DATA LINK ESCAPE +�� <control> DEVICE CONTROL ONE +�� <control> DEVICE CONTROL TWO +�� <control> DEVICE CONTROL THREE +�� <control> DEVICE CONTROL FOUR +�� <control> NEGATIVE ACKNOWLEDGE +�� <control> SYNCHRONOUS IDLE +�� <control> END OF TRANSMISSION BLOCK +�� <control> CANCEL +�� <control> END OF MEDIUM +�� <control> SUBSTITUTE �� <control> ESCAPE +�� <control> INFORMATION SEPARATOR FOUR +�� <control> INFORMATION SEPARATOR THREE +�� <control> INFORMATION SEPARATOR TWO +�� <control> INFORMATION SEPARATOR INE +!! EXCLAMATION MARK +%% PERCENT SIGN +&& AMPERSAND +(( LEFT PARENTHESIS +)) RIGHT PARENTHESIS +** ASTERISK +,, COMMA +-- HYPHEN-MINUS +.. FULL STOP +00 DIGIT ZERO +11 DIGIT ONE +99 DIGIT NINE +:: COLON +;; SEMICOLON +<< LESS-THAN SIGN +>> GREATER-THAN SIGN +?? QUESTION MARK +AA LATIN CAPITAL LETTER A +ZZ LATIN CAPITAL LETTER Z +aa LATIN SMALL LETTER A +zz LATIN SMALL LETTER Z �� <control> DELETE �� <control> 0x80 �� <control> 0x81 �� <control> BREAK PERMITTED HERE �� <control> NO BREAK HERE +�� <control> 0x84 +�� <control> NEXT LINE (NEL) +�� <control> START OF SELECTED AREA +�� <control> END OF SELECTED AREA +�� <control> CHARACTER TABULATION SET +�� <control> CHARACTER TABULATION WITH JUSTIFICATION +�� <control> LINE TABULATION SET +�� <control> PARTIAL LINE FORWARD +�� <control> PARTIAL LINE BACKWARD +�� <control> REVERSE LINE FEED +�� <control> SINGLE SHIFT TWO +�� <control> SINGLE SHIFT THREE +�� <control> DEVICE CONTROL STRING +�� <control> PRIVATE USE ONE +�� <control> PRIVATE USE TWO +�� <control> SET TRANSMIT STATE +�� <control> CANCEL CHARACTER +�� <control> MESSAGE WAITING +�� <control> START OF GUARDED AREA +�� <control> END OF GUARDED AREA +�� <control> START OF STRING +�� <control> 0x99 +�� <control> SINGLE CHARACTER INTRODUCER +�� <control> CONTROL SEQUENCE INTRODUCER +�� <control> STRING TERMINATOR +�� <control> OPERATING SYSTEM COMMAND �� <control> PRIVACY MESSAGE �� <control> APPLICATION PROGRAM COMMAND ≪≪ MUCH LESS-THAN diff --git a/regress/usr.bin/mandoc/char/unicode/nogroff.out_utf8 b/regress/usr.bin/mandoc/char/unicode/nogroff.out_utf8 index 98534ec7b..429c53f2a 100644 --- a/regress/usr.bin/mandoc/char/unicode/nogroff.out_utf8 +++ b/regress/usr.bin/mandoc/char/unicode/nogroff.out_utf8 @@ -7,6 +7,11 @@ DDEESSCCRRIIPPTTIIOONN BEGINTEST �� NULL �� START OF HEADING + �� START OF TEXT + �� END OF TEXT + �� END OF TRANSMISSION + �� ENQUIRY + �� ACKNOWLEDGE �� BELL �� BACKSPACE CHARACTER TABULATION @@ -14,12 +19,76 @@ DDEESSCCRRIIPPTTIIOONN �� LINE TABULATION �� FORM FEED �� CARRIAGE RETURN + �� SHIFT OUT + �� SHIFT IN + �� DATA LINK ESCAPE + �� DEVICE CONTROL ONE + �� DEVICE CONTROL TWO + �� DEVICE CONTROL THREE + �� DEVICE CONTROL FOUR + �� NEGATIVE ACKNOWLEDGE + �� SYNCHRONOUS IDLE + �� END OF TRANSMISSION BLOCK + �� CANCEL + �� END OF MEDIUM + �� SUBSTITUTE �� ESCAPE + �� INFORMATION SEPARATOR FOUR + �� INFORMATION SEPARATOR THREE + �� INFORMATION SEPARATOR TWO + �� INFORMATION SEPARATOR INE + !! EXCLAMATION MARK + %% PERCENT SIGN + && AMPERSAND + (( LEFT PARENTHESIS + )) RIGHT PARENTHESIS + ** ASTERISK + ,, COMMA + -- HYPHEN-MINUS + .. FULL STOP + 00 DIGIT ZERO + 11 DIGIT ONE + 99 DIGIT NINE + :: COLON + ;; SEMICOLON + << LESS-THAN SIGN + >> GREATER-THAN SIGN + ?? QUESTION MARK + AA LATIN CAPITAL LETTER A + ZZ LATIN CAPITAL LETTER Z + aa LATIN SMALL LETTER A + zz LATIN SMALL LETTER Z �� DELETE �� 0x80 �� 0x81 �� BREAK PERMITTED HERE �� NO BREAK HERE + �� 0x84 + �� NEXT LINE (NEL) + �� START OF SELECTED AREA + �� END OF SELECTED AREA + �� CHARACTER TABULATION SET + �� CHARACTER TABULATION WITH JUSTIFICATION + �� LINE TABULATION SET + �� PARTIAL LINE FORWARD + �� PARTIAL LINE BACKWARD + �� REVERSE LINE FEED + �� SINGLE SHIFT TWO + �� SINGLE SHIFT THREE + �� DEVICE CONTROL STRING + �� PRIVATE USE ONE + �� PRIVATE USE TWO + �� SET TRANSMIT STATE + �� CANCEL CHARACTER + �� MESSAGE WAITING + �� START OF GUARDED AREA + �� END OF GUARDED AREA + �� START OF STRING + �� 0x99 + �� SINGLE CHARACTER INTRODUCER + �� CONTROL SEQUENCE INTRODUCER + �� STRING TERMINATOR + �� OPERATING SYSTEM COMMAND �� PRIVACY MESSAGE �� APPLICATION PROGRAM COMMAND ≪≪ MUCH LESS-THAN @@ -50,4 +119,4 @@ DDEESSCCRRIIPPTTIIOONN 􏿿 ENDTEST -OpenBSD June 2, 2021 CHAR-UNICODE-NOGROFF(1) +OpenBSD May 16, 2024 CHAR-UNICODE-NOGROFF(1) diff --git a/regress/usr.bin/ssh/test-exec.sh b/regress/usr.bin/ssh/test-exec.sh index ee9be54b5..fc9b2402b 100644 --- a/regress/usr.bin/ssh/test-exec.sh +++ b/regress/usr.bin/ssh/test-exec.sh @@ -1,4 +1,4 @@ -# $OpenBSD: test-exec.sh,v 1.110 2024/04/03 06:01:11 anton Exp $ +# $OpenBSD: test-exec.sh,v 1.111 2024/05/17 01:45:22 djm Exp $ # Placed in the Public Domain. #SUDO=sudo @@ -52,6 +52,7 @@ SSHKEYGEN=ssh-keygen SSHKEYSCAN=ssh-keyscan SFTP=sftp SFTPSERVER=/usr/libexec/sftp-server +SSHD_SESSION=/usr/libexec/sshd-session SCP=scp # Interop testing @@ -73,6 +74,9 @@ OPENSSL_BIN="${OPENSSL_BIN:-openssl}" if [ "x$TEST_SSH_SSH" != "x" ]; then SSH="${TEST_SSH_SSH}" fi +if [ "x$TEST_SSH_SSHD_SESSION" != "x" ]; then + SSHD_SESSION="${TEST_SSH_SSHD_SESSION}" +fi if [ "x$TEST_SSH_SSHD" != "x" ]; then SSHD="${TEST_SSH_SSHD}" fi @@ -422,6 +426,7 @@ cat << EOF > $OBJ/sshd_config AcceptEnv _XXX_TEST_* AcceptEnv _XXX_TEST Subsystem sftp $SFTPSERVER + SshdSessionPath $SSHD_SESSION EOF # This may be necessary if /usr/src and/or /usr/obj are group-writable, diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index eb5a9f2ea..2c257a430 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ifconfig.c,v 1.471 2024/04/23 13:34:50 jsg Exp $ */ +/* $OpenBSD: ifconfig.c,v 1.472 2024/05/18 02:44:22 jsg Exp $ */ /* $NetBSD: ifconfig.c,v 1.40 1997/10/01 02:19:43 enami Exp $ */ /* @@ -711,8 +711,6 @@ void process_join_commands(void); void process_wg_commands(void); -unsigned long get_ts_map(int, int, int); - void in_status(int); void in_getaddr(const char *, int); void in_getprefix(const char *, int); diff --git a/share/man/man5/bsd.port.arch.mk.5 b/share/man/man5/bsd.port.arch.mk.5 index e7092a93a..23f4276cf 100644 --- a/share/man/man5/bsd.port.arch.mk.5 +++ b/share/man/man5/bsd.port.arch.mk.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: bsd.port.arch.mk.5,v 1.13 2019/12/08 12:54:36 espie Exp $ +.\" $OpenBSD: bsd.port.arch.mk.5,v 1.14 2024/05/16 09:52:58 sthen Exp $ .\" .\" Copyright (c) 2011 Marc Espie .\" @@ -24,7 +24,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: December 8 2019 $ +.Dd $Mdocdate: May 16 2024 $ .Dt BSD.PORT.ARCH.MK 5 .Os .Sh NAME @@ -96,6 +96,7 @@ It will set up the following variables for use in the rest of the .It Ev LLD_EMUL .It Ev LLVM_ARCHS .It Ev LP64_ARCHS +.It Ev LUAJIT_ARCHS .It Ev MONO_ARCHS .It Ev OCAML_NATIVE_ARCHS .It Ev OCAML_NATIVE_DYNLINK_ARCHS diff --git a/share/man/man8/bulk.8 b/share/man/man8/bulk.8 index b6c3e1c34..a9cba53b5 100644 --- a/share/man/man8/bulk.8 +++ b/share/man/man8/bulk.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: bulk.8,v 1.8 2024/05/15 11:27:36 sthen Exp $ +.\" $OpenBSD: bulk.8,v 1.10 2024/05/16 10:31:55 sthen Exp $ .\" .\" Copyright (c) 2016 Marc Espie .\" @@ -14,7 +14,7 @@ .\" 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. -.Dd $Mdocdate: May 15 2024 $ +.Dd $Mdocdate: May 16 2024 $ .Dt BULK 8 .Os .Sh NAME @@ -42,7 +42,7 @@ Setup a master machine with enough room for a chroot, say Assuming you are using a cluster of machines, this chroot should contain NFS exportable partitions for distfiles, plists, and packages (one single partition can be used for simplicity). -A full setup currently requires in the order of 100GB for distfiles +A full setup currently requires in the order of 120GB for distfiles and 70GB for packages. Expect these numbers to grow. 150GB for each should last a few years. @@ -59,11 +59,14 @@ for instance .Pp Reserve one "scratch" partition under the chroot for WRKOBJDIR (for instance, mfs, async, or SSD). -This partition should be roughly 40GB if you want to be able to -build all ports using multiple CPU cores. This can often double as .Pa /tmp under the chroot. +The largest ports can take in excess of 20GB each (more for a debug +build) and you may have several of these built at the same time. +50GB is probably a reasonable minimum on an architecture which can build +chromium, though 100GB would not be overkill, especially if you have +many cores. .Pp Alternately, you can setup your whole chroot as a scratch partition, and reserve one more permanent space under it for distfiles, diff --git a/share/man/man8/daily.8 b/share/man/man8/daily.8 index 04d0a27fa..20743edc7 100644 --- a/share/man/man8/daily.8 +++ b/share/man/man8/daily.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: daily.8,v 1.29 2020/10/20 22:42:29 danj Exp $ +.\" $OpenBSD: daily.8,v 1.30 2024/05/16 11:33:59 solene Exp $ .\" .\" Copyright (c) 2003 Jason McIntyre .\" @@ -14,7 +14,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: October 20 2020 $ +.Dd $Mdocdate: May 16 2024 $ .Dt DAILY 8 .Os .Sh NAME @@ -112,7 +112,7 @@ for the mount options, e.g. Checks daemon status. Lists any daemons which are enabled in .Xr rc.conf.local 8 -but which are not actually running. +but which are not actually running (and vice versa). .It Reports on which file systems need to be dumped via .Xr dump 8 . diff --git a/sys/dev/fdt/ociic.c b/sys/dev/fdt/ociic.c index 0f165fb06..3722cf10b 100644 --- a/sys/dev/fdt/ociic.c +++ b/sys/dev/fdt/ociic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ociic.c,v 1.3 2022/04/06 18:59:28 naddy Exp $ */ +/* $OpenBSD: ociic.c,v 1.4 2024/05/15 22:54:03 kettenis Exp $ */ /* * Copyright (c) 2021 Mark Kettenis * @@ -53,6 +53,13 @@ #define I2C_SR_TIP (1 << 1) #define I2C_SR_IF (1 << 0) +/* + * OpenSBI on the SiFive HiFive Unmatched board implements reboot and + * powerdown functionality through the Dialog DA9063 Power Management + * IC over I2C. The code expects the I2C controller to be enabled so + * we have to make sure we leave it in that state. + */ + struct ociic_softc { struct device sc_dev; bus_space_tag_t sc_iot; @@ -156,6 +163,8 @@ ociic_attach(struct device *parent, struct device *self, void *aux) ociic_write(sc, I2C_PRER_HI, div >> 8); } + ociic_set(sc, I2C_CTR, I2C_CTR_EN); + sc->sc_ic.ic_cookie = sc; sc->sc_ic.ic_acquire_bus = ociic_acquire_bus; sc->sc_ic.ic_release_bus = ociic_release_bus; @@ -174,18 +183,12 @@ ociic_attach(struct device *parent, struct device *self, void *aux) int ociic_acquire_bus(void *cookie, int flags) { - struct ociic_softc *sc = cookie; - - ociic_set(sc, I2C_CTR, I2C_CTR_EN); return 0; } void ociic_release_bus(void *cookie, int flags) { - struct ociic_softc *sc = cookie; - - ociic_clr(sc, I2C_CTR, I2C_CTR_EN); } int diff --git a/sys/dev/fdt/virtio_mmio.c b/sys/dev/fdt/virtio_mmio.c index 4d92508f7..5c285470c 100644 --- a/sys/dev/fdt/virtio_mmio.c +++ b/sys/dev/fdt/virtio_mmio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: virtio_mmio.c,v 1.12 2024/01/15 02:35:23 dv Exp $ */ +/* $OpenBSD: virtio_mmio.c,v 1.13 2024/05/17 16:37:10 sf Exp $ */ /* $NetBSD: virtio.c,v 1.3 2011/11/02 23:05:52 njoly Exp $ */ /* @@ -97,6 +97,7 @@ void virtio_mmio_write_device_config_4(struct virtio_softc *, int, uint32_t); void virtio_mmio_write_device_config_8(struct virtio_softc *, int, uint64_t); uint16_t virtio_mmio_read_queue_size(struct virtio_softc *, uint16_t); void virtio_mmio_setup_queue(struct virtio_softc *, struct virtqueue *, uint64_t); +int virtio_mmio_get_status(struct virtio_softc *); void virtio_mmio_set_status(struct virtio_softc *, int); int virtio_mmio_negotiate_features(struct virtio_softc *, const struct virtio_feature_name *); @@ -144,6 +145,7 @@ struct virtio_ops virtio_mmio_ops = { virtio_mmio_write_device_config_8, virtio_mmio_read_queue_size, virtio_mmio_setup_queue, + virtio_mmio_get_status, virtio_mmio_set_status, virtio_mmio_negotiate_features, virtio_mmio_intr, @@ -194,6 +196,15 @@ virtio_mmio_setup_queue(struct virtio_softc *vsc, struct virtqueue *vq, } } +int +virtio_mmio_get_status(struct virtio_softc *vsc) +{ + struct virtio_mmio_softc *sc = (struct virtio_mmio_softc *)vsc; + + return bus_space_read_4(sc->sc_iot, sc->sc_ioh, + VIRTIO_MMIO_STATUS); +} + void virtio_mmio_set_status(struct virtio_softc *vsc, int status) { diff --git a/sys/dev/ic/ufshci.c b/sys/dev/ic/ufshci.c index 8edb3a667..af352c247 100644 --- a/sys/dev/ic/ufshci.c +++ b/sys/dev/ic/ufshci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ufshci.c,v 1.22 2024/05/15 18:01:10 mglocker Exp $ */ +/* $OpenBSD: ufshci.c,v 1.24 2024/05/16 10:52:11 mglocker Exp $ */ /* * Copyright (c) 2022 Marcus Glocker @@ -186,9 +186,6 @@ ufshci_attach(struct ufshci_softc *sc) DPRINTF(1, " BI=0x%04x\n", UFSHCI_REG_HCMID_BI(sc->sc_hcmid)); DPRINTF(1, " MIC=0x%04x\n", UFSHCI_REG_HCMID_MIC(sc->sc_hcmid)); - /* XXX: Using more than one slot currently causes OCS errors */ - sc->sc_nutrs = 1; - if (sc->sc_nutrs > 32) { printf("%s: NUTRS can't be >32 (is %d)!\n", sc->sc_dev.dv_xname, sc->sc_nutrs); @@ -513,7 +510,7 @@ ufshci_utr_cmd_nop(struct ufshci_softc *sc, struct ufshci_ccb *ccb, ucd->cmd.hdr.tc = UPIU_TC_I2T_NOP_OUT; ucd->cmd.hdr.flags = 0; ucd->cmd.hdr.lun = 0; - ucd->cmd.hdr.taskid = 0; + ucd->cmd.hdr.task_tag = slot; ucd->cmd.hdr.cmd_set_type = 0; /* SCSI command */ ucd->cmd.hdr.query = 0; ucd->cmd.hdr.response = 0; @@ -603,7 +600,7 @@ ufshci_utr_cmd_lun(struct ufshci_softc *sc, struct ufshci_ccb *ccb, ucd->cmd.hdr.tc = UPIU_TC_I2T_COMMAND; ucd->cmd.hdr.flags = (1 << 6); /* Bit-5 = Write, Bit-6 = Read */ ucd->cmd.hdr.lun = 0; - ucd->cmd.hdr.taskid = 0; + ucd->cmd.hdr.task_tag = slot; ucd->cmd.hdr.cmd_set_type = 0; /* SCSI command */ ucd->cmd.hdr.query = 0; ucd->cmd.hdr.response = 0; @@ -710,7 +707,7 @@ ufshci_utr_cmd_inquiry(struct ufshci_softc *sc, struct ufshci_ccb *ccb, ucd->cmd.hdr.tc = UPIU_TC_I2T_COMMAND; ucd->cmd.hdr.flags = (1 << 6); /* Bit-5 = Write, Bit-6 = Read */ ucd->cmd.hdr.lun = 0; - ucd->cmd.hdr.taskid = 0; + ucd->cmd.hdr.task_tag = slot; ucd->cmd.hdr.cmd_set_type = 0; /* SCSI command */ ucd->cmd.hdr.query = 0; ucd->cmd.hdr.response = 0; @@ -815,7 +812,7 @@ ufshci_utr_cmd_capacity16(struct ufshci_softc *sc, struct ufshci_ccb *ccb, ucd->cmd.hdr.tc = UPIU_TC_I2T_COMMAND; ucd->cmd.hdr.flags = (1 << 6); /* Bit-5 = Write, Bit-6 = Read */ ucd->cmd.hdr.lun = 0; - ucd->cmd.hdr.taskid = 0; + ucd->cmd.hdr.task_tag = slot; ucd->cmd.hdr.cmd_set_type = 0; /* SCSI command */ ucd->cmd.hdr.query = 0; ucd->cmd.hdr.response = 0; @@ -924,7 +921,7 @@ ufshci_utr_cmd_capacity(struct ufshci_softc *sc, struct ufshci_ccb *ccb, ucd->cmd.hdr.tc = UPIU_TC_I2T_COMMAND; ucd->cmd.hdr.flags = (1 << 6); /* Bit-5 = Write, Bit-6 = Read */ ucd->cmd.hdr.lun = 0; - ucd->cmd.hdr.taskid = 0; + ucd->cmd.hdr.task_tag = slot; ucd->cmd.hdr.cmd_set_type = 0; /* SCSI command */ ucd->cmd.hdr.query = 0; ucd->cmd.hdr.response = 0; @@ -1003,6 +1000,8 @@ ufshci_utr_cmd_io(struct ufshci_softc *sc, struct ufshci_ccb *ccb, struct ufshci_utrd *utrd; struct ufshci_ucd *ucd; bus_dmamap_t dmap = ccb->ccb_dmamap; + uint32_t blocks; + uint64_t lba; /* 7.2.1 Basic Steps when Building a UTP Transfer Request: 1) */ slot = ccb->ccb_slot; @@ -1038,7 +1037,7 @@ ufshci_utr_cmd_io(struct ufshci_softc *sc, struct ufshci_ccb *ccb, else ucd->cmd.hdr.flags = (1 << 5); /* Bit-5 = Write */ ucd->cmd.hdr.lun = 0; - ucd->cmd.hdr.taskid = 0; + ucd->cmd.hdr.task_tag = slot; ucd->cmd.hdr.cmd_set_type = 0; /* SCSI command */ ucd->cmd.hdr.query = 0; ucd->cmd.hdr.response = 0; @@ -1047,7 +1046,16 @@ ufshci_utr_cmd_io(struct ufshci_softc *sc, struct ufshci_ccb *ccb, ucd->cmd.hdr.device_info = 0; ucd->cmd.hdr.ds_len = 0; - ucd->cmd.expected_xfer_len = htobe32(xs->datalen); + /* + * JESD220C-2_1.pdf, page 88, d) Expected Data Transfer Length: + * "When the COMMAND UPIU encodes a SCSI WRITE or SCSI READ command + * (specifically WRITE (6), READ (6), WRITE (10), READ (10), + * WRITE (16), or READ (16)), the value of this field shall be the + * product of the Logical Block Size (bLogicalBlockSize) and the + * TRANSFER LENGTH field of the CDB." + */ + scsi_cmd_rw_decode(&xs->cmd, &lba, &blocks); + ucd->cmd.expected_xfer_len = htobe32(UFSHCI_LBS * blocks); memcpy(ucd->cmd.cdb, &xs->cmd, sizeof(ucd->cmd.cdb)); @@ -1140,7 +1148,7 @@ ufshci_utr_cmd_sync(struct ufshci_softc *sc, struct ufshci_ccb *ccb, ucd->cmd.hdr.tc = UPIU_TC_I2T_COMMAND; ucd->cmd.hdr.flags = 0; /* No data transfer */ ucd->cmd.hdr.lun = 0; - ucd->cmd.hdr.taskid = 0; + ucd->cmd.hdr.task_tag = slot; ucd->cmd.hdr.cmd_set_type = 0; /* SCSI command */ ucd->cmd.hdr.query = 0; ucd->cmd.hdr.response = 0; @@ -1207,16 +1215,19 @@ ufshci_xfer_complete(struct ufshci_softc *sc) { struct ufshci_ccb *ccb; uint32_t reg; - int i; + int i, timeout; mtx_enter(&sc->sc_cmd_mtx); /* Wait for all commands to complete. */ - while ((reg = ufshci_doorbell_read(sc))) { - DPRINTF(3, "%s: doorbell reg=0x%x\n", __func__, reg); + for (timeout = 5000; timeout != 0; timeout--) { + reg = ufshci_doorbell_read(sc); if (reg == 0) break; + delay(10); } + if (timeout == 0) + printf("%s: timeout (reg=0x%x)\n", __func__, reg); for (i = 0; i < sc->sc_nutrs; i++) { ccb = &sc->sc_ccbs[i]; diff --git a/sys/dev/ic/ufshcireg.h b/sys/dev/ic/ufshcireg.h index 688d66962..741ecd1fe 100644 --- a/sys/dev/ic/ufshcireg.h +++ b/sys/dev/ic/ufshcireg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ufshcireg.h,v 1.7 2024/05/09 08:20:22 mglocker Exp $ */ +/* $OpenBSD: ufshcireg.h,v 1.9 2024/05/16 10:52:11 mglocker Exp $ */ /* * Copyright (c) 2022 Marcus Glocker @@ -21,8 +21,11 @@ */ #define UFSHCI_UCD_PRDT_MAX_SEGS 64 #define UFSHCI_UCD_PRDT_MAX_XFER (UFSHCI_UCD_PRDT_MAX_SEGS * PAGE_SIZE) -#define UFSHCI_INTR_AGGR_TIMEOUT 0x64 /* 4ms */ +#define UFSHCI_INTR_AGGR_TIMEOUT 0x08 /* 320us (1 unit = 40us) */ #define UFSHCI_MAX_UNITS 32 +#define UFSHCI_LBS 4096 /* UFS Logical Block Size: + For UFS minimum size shall be + 4096 bytes */ /* * Controller Capabilities Registers @@ -335,7 +338,7 @@ struct upiu_hdr { uint8_t tc; /* Transaction Code */ uint8_t flags; uint8_t lun; - uint8_t taskid; + uint8_t task_tag; uint8_t cmd_set_type; uint8_t query; uint8_t response; diff --git a/sys/dev/ic/ufshcivar.h b/sys/dev/ic/ufshcivar.h index 65b9d6fe0..7a4816a76 100644 --- a/sys/dev/ic/ufshcivar.h +++ b/sys/dev/ic/ufshcivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ufshcivar.h,v 1.4 2024/05/09 08:06:42 mglocker Exp $ */ +/* $OpenBSD: ufshcivar.h,v 1.5 2024/05/15 20:15:33 mglocker Exp $ */ /* * Copyright (c) 2022 Marcus Glocker @@ -68,7 +68,6 @@ struct ufshci_softc { uint8_t sc_nutmrs; uint8_t sc_rtt; uint8_t sc_nutrs; - uint8_t sc_taskid; struct ufshci_dmamem *sc_dmamem_utmrd; struct ufshci_dmamem *sc_dmamem_utrd; diff --git a/sys/dev/pci/azalia.c b/sys/dev/pci/azalia.c index c7223b6a1..ace203bf1 100644 --- a/sys/dev/pci/azalia.c +++ b/sys/dev/pci/azalia.c @@ -1,4 +1,4 @@ -/* $OpenBSD: azalia.c,v 1.286 2024/03/06 00:11:25 jsg Exp $ */ +/* $OpenBSD: azalia.c,v 1.287 2024/05/17 19:43:45 kettenis Exp $ */ /* $NetBSD: azalia.c,v 1.20 2006/05/07 08:31:44 kent Exp $ */ /*- @@ -176,6 +176,7 @@ typedef struct azalia_t { int nistreams, nostreams, nbstreams; stream_t pstream; stream_t rstream; + uint32_t intctl; } azalia_t; #define XNAME(sc) ((sc)->dev.dv_xname) #define AZ_READ_1(z, r) bus_space_read_1((z)->iot, (z)->ioh, HDA_##r) @@ -556,16 +557,6 @@ azalia_pci_attach(struct device *parent, struct device *self, void *aux) azalia_pci_write(sc->pc, sc->tag, ICH_PCI_MMC, reg); } - /* disable MSI for AMD Summit Ridge/Raven Ridge HD Audio */ - if (PCI_VENDOR(sc->pciid) == PCI_VENDOR_AMD) { - switch (PCI_PRODUCT(sc->pciid)) { - case PCI_PRODUCT_AMD_17_HDA: - case PCI_PRODUCT_AMD_17_1X_HDA: - case PCI_PRODUCT_AMD_HUDSON2_HDA: - pa->pa_flags &= ~PCI_FLAGS_MSI_ENABLED; - } - } - /* interrupt */ if (pci_intr_map_msi(pa, &ih) && pci_intr_map(pa, &ih)) { printf(": can't map interrupt\n"); @@ -684,7 +675,6 @@ azalia_pci_detach(struct device *self, int flags) AZ_WRITE_4(az, INTCTL, 0); DPRINTF(("%s: clear interrupts\n", __func__)); - AZ_WRITE_4(az, INTSTS, HDA_INTSTS_CIS | HDA_INTSTS_GIS); AZ_WRITE_2(az, STATESTS, HDA_STATESTS_SDIWAKE); AZ_WRITE_1(az, RIRBSTS, HDA_RIRBSTS_RINTFL | HDA_RIRBSTS_RIRBOIS); } @@ -711,29 +701,27 @@ azalia_intr(void *v) int ret = 0; mtx_enter(&audio_lock); - intsts = AZ_READ_4(az, INTSTS); - if (intsts == 0 || intsts == 0xffffffff) { - mtx_leave(&audio_lock); - return (ret); - } + for (;;) { + intsts = AZ_READ_4(az, INTSTS); + if ((intsts & az->intctl) == 0 || intsts == 0xffffffff) + break; - AZ_WRITE_4(az, INTSTS, intsts); + if (intsts & az->pstream.intr_bit) { + azalia_stream_intr(&az->pstream); + ret = 1; + } - if (intsts & az->pstream.intr_bit) { - azalia_stream_intr(&az->pstream); - ret = 1; - } + if (intsts & az->rstream.intr_bit) { + azalia_stream_intr(&az->rstream); + ret = 1; + } - if (intsts & az->rstream.intr_bit) { - azalia_stream_intr(&az->rstream); - ret = 1; - } - - if ((intsts & HDA_INTSTS_CIS) && - (AZ_READ_1(az, RIRBCTL) & HDA_RIRBCTL_RINTCTL) && - (AZ_READ_1(az, RIRBSTS) & HDA_RIRBSTS_RINTFL)) { - azalia_rirb_intr(az); - ret = 1; + if ((intsts & HDA_INTSTS_CIS) && + (AZ_READ_1(az, RIRBCTL) & HDA_RIRBCTL_RINTCTL) && + (AZ_READ_1(az, RIRBSTS) & HDA_RIRBSTS_RINTFL)) { + azalia_rirb_intr(az); + ret = 1; + } } mtx_leave(&audio_lock); return (ret); @@ -918,7 +906,6 @@ azalia_init(azalia_t *az, int resuming) /* clear interrupt status */ AZ_WRITE_2(az, STATESTS, HDA_STATESTS_SDIWAKE); AZ_WRITE_1(az, RIRBSTS, HDA_RIRBSTS_RINTFL | HDA_RIRBSTS_RIRBOIS); - AZ_WRITE_4(az, INTSTS, HDA_INTSTS_CIS | HDA_INTSTS_GIS); AZ_WRITE_4(az, DPLBASE, 0); AZ_WRITE_4(az, DPUBASE, 0); @@ -932,8 +919,8 @@ azalia_init(azalia_t *az, int resuming) if (err) return(err); - AZ_WRITE_4(az, INTCTL, - AZ_READ_4(az, INTCTL) | HDA_INTCTL_CIE | HDA_INTCTL_GIE); + az->intctl = HDA_INTCTL_CIE | HDA_INTCTL_GIE; + AZ_WRITE_4(az, INTCTL, az->intctl); return(0); } @@ -1421,7 +1408,6 @@ azalia_suspend(azalia_t *az) /* stop interrupts and clear status registers */ AZ_WRITE_4(az, INTCTL, 0); - AZ_WRITE_4(az, INTSTS, HDA_INTSTS_CIS | HDA_INTSTS_GIS); AZ_WRITE_2(az, STATESTS, HDA_STATESTS_SDIWAKE); AZ_WRITE_1(az, RIRBSTS, HDA_RIRBSTS_RINTFL | HDA_RIRBSTS_RIRBOIS); @@ -3723,7 +3709,6 @@ azalia_stream_start(stream_t *this) bdlist_entry_t *bdlist; bus_addr_t dmaaddr, dmaend; int err, index; - uint32_t intctl; uint8_t ctl2; err = azalia_stream_reset(this); @@ -3768,9 +3753,8 @@ azalia_stream_start(stream_t *this) if (err) return EINVAL; - intctl = AZ_READ_4(this->az, INTCTL); - intctl |= this->intr_bit; - AZ_WRITE_4(this->az, INTCTL, intctl); + this->az->intctl |= this->intr_bit; + AZ_WRITE_4(this->az, INTCTL, this->az->intctl); STR_WRITE_1(this, CTL, STR_READ_1(this, CTL) | HDA_SD_CTL_DEIE | HDA_SD_CTL_FEIE | HDA_SD_CTL_IOCE | @@ -3786,8 +3770,8 @@ azalia_stream_halt(stream_t *this) ctl = STR_READ_2(this, CTL); ctl &= ~(HDA_SD_CTL_DEIE | HDA_SD_CTL_FEIE | HDA_SD_CTL_IOCE | HDA_SD_CTL_RUN); STR_WRITE_2(this, CTL, ctl); - AZ_WRITE_4(this->az, INTCTL, - AZ_READ_4(this->az, INTCTL) & ~this->intr_bit); + this->az->intctl &= ~this->intr_bit; + AZ_WRITE_4(this->az, INTCTL, this->az->intctl); azalia_codec_disconnect_stream(this); return (0); diff --git a/sys/dev/pci/virtio_pci.c b/sys/dev/pci/virtio_pci.c index 36a62c13b..a330a49fd 100644 --- a/sys/dev/pci/virtio_pci.c +++ b/sys/dev/pci/virtio_pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: virtio_pci.c,v 1.36 2024/01/15 02:35:23 dv Exp $ */ +/* $OpenBSD: virtio_pci.c,v 1.37 2024/05/17 16:37:10 sf Exp $ */ /* $NetBSD: virtio.c,v 1.3 2011/11/02 23:05:52 njoly Exp $ */ /* @@ -72,6 +72,7 @@ void virtio_pci_write_device_config_4(struct virtio_softc *, int, uint32_t); void virtio_pci_write_device_config_8(struct virtio_softc *, int, uint64_t); uint16_t virtio_pci_read_queue_size(struct virtio_softc *, uint16_t); void virtio_pci_setup_queue(struct virtio_softc *, struct virtqueue *, uint64_t); +int virtio_pci_get_status(struct virtio_softc *); void virtio_pci_set_status(struct virtio_softc *, int); int virtio_pci_negotiate_features(struct virtio_softc *, const struct virtio_feature_name *); int virtio_pci_negotiate_features_10(struct virtio_softc *, const struct virtio_feature_name *); @@ -155,6 +156,7 @@ struct virtio_ops virtio_pci_ops = { virtio_pci_write_device_config_8, virtio_pci_read_queue_size, virtio_pci_setup_queue, + virtio_pci_get_status, virtio_pci_set_status, virtio_pci_negotiate_features, virtio_pci_poll_intr, @@ -275,6 +277,18 @@ virtio_pci_setup_queue(struct virtio_softc *vsc, struct virtqueue *vq, } } +int +virtio_pci_get_status(struct virtio_softc *vsc) +{ + struct virtio_pci_softc *sc = (struct virtio_pci_softc *)vsc; + + if (sc->sc_sc.sc_version_1) + return CREAD(sc, device_status); + else + return bus_space_read_1(sc->sc_iot, sc->sc_ioh, + VIRTIO_CONFIG_DEVICE_STATUS); +} + void virtio_pci_set_status(struct virtio_softc *vsc, int status) { diff --git a/sys/dev/pv/if_vio.c b/sys/dev/pv/if_vio.c index 919c2aa13..7d0e4ec30 100644 --- a/sys/dev/pv/if_vio.c +++ b/sys/dev/pv/if_vio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_vio.c,v 1.33 2024/05/07 18:35:23 jan Exp $ */ +/* $OpenBSD: if_vio.c,v 1.34 2024/05/17 16:37:10 sf Exp $ */ /* * Copyright (c) 2012 Stefan Fritsch, Alexander Fiveg. @@ -252,6 +252,7 @@ struct vio_softc { #define VIRTIO_NET_TX_MAXNSEGS 16 /* for larger chains, defrag */ #define VIRTIO_NET_CTRL_MAC_MC_ENTRIES 64 /* for more entries, use ALLMULTI */ #define VIRTIO_NET_CTRL_MAC_UC_ENTRIES 1 /* one entry for own unicast addr */ +#define VIRTIO_NET_CTRL_TIMEOUT (5*1000*1000*1000ULL) /* 5 seconds */ #define VIO_CTRL_MAC_INFO_SIZE \ (2*sizeof(struct virtio_net_ctrl_mac_tbl) + \ @@ -512,6 +513,17 @@ vio_put_lladdr(struct arpcom *ac, struct virtio_softc *vsc) } } +static int vio_needs_reset(struct vio_softc *sc) +{ + if (virtio_get_status(sc->sc_virtio) & + VIRTIO_CONFIG_DEVICE_STATUS_DEVICE_NEEDS_RESET) { + printf("%s: device needs reset", sc->sc_dev.dv_xname); + vio_ctrl_wakeup(sc, RESET); + return 1; + } + return 0; +} + void vio_attach(struct device *parent, struct device *self, void *aux) { @@ -649,6 +661,7 @@ vio_config_change(struct virtio_softc *vsc) { struct vio_softc *sc = (struct vio_softc *)vsc->sc_child; vio_link_state(&sc->sc_ac.ac_if); + vio_needs_reset(sc); return 1; } @@ -703,7 +716,7 @@ vio_stop(struct ifnet *ifp, int disable) virtio_reset(vsc); vio_rxeof(sc); if (vsc->sc_nvqs >= 3) - vio_ctrleof(&sc->sc_vq[VQCTL]); + vio_ctrl_wakeup(sc, RESET); vio_tx_drain(sc); if (disable) vio_rx_drain(sc); @@ -714,11 +727,8 @@ vio_stop(struct ifnet *ifp, int disable) if (vsc->sc_nvqs >= 3) virtio_start_vq_intr(vsc, &sc->sc_vq[VQCTL]); virtio_reinit_end(vsc); - if (vsc->sc_nvqs >= 3) { - if (sc->sc_ctrl_inuse != FREE) - sc->sc_ctrl_inuse = RESET; - wakeup(&sc->sc_ctrl_inuse); - } + if (vsc->sc_nvqs >= 3) + vio_ctrl_wakeup(sc, FREE); } static inline uint16_t @@ -1230,6 +1240,9 @@ vio_txeof(struct virtqueue *vq) int r = 0; int slot, len; + if (!ISSET(ifp->if_flags, IFF_RUNNING)) + return 0; + while (virtio_dequeue(vsc, vq, &slot, &len) == 0) { struct virtio_net_hdr *hdr = &sc->sc_tx_hdrs[slot]; r++; @@ -1363,32 +1376,15 @@ out: return r; } -/* - * XXXSMP As long as some per-ifp ioctl(2)s are executed with the - * NET_LOCK() deadlocks are possible. So release it here. - */ -static inline int -vio_sleep(struct vio_softc *sc, const char *wmesg) -{ - int status = rw_status(&netlock); - - if (status != RW_WRITE && status != RW_READ) - return tsleep_nsec(&sc->sc_ctrl_inuse, PRIBIO|PCATCH, wmesg, - INFSLP); - - return rwsleep_nsec(&sc->sc_ctrl_inuse, &netlock, PRIBIO|PCATCH, wmesg, - INFSLP); -} - int vio_wait_ctrl(struct vio_softc *sc) { int r = 0; while (sc->sc_ctrl_inuse != FREE) { - r = vio_sleep(sc, "viowait"); - if (r == EINTR) - return r; + if (sc->sc_ctrl_inuse == RESET || vio_needs_reset(sc)) + return ENXIO; + r = tsleep_nsec(&sc->sc_ctrl_inuse, PRIBIO, "viowait", INFSLP); } sc->sc_ctrl_inuse = INUSE; @@ -1400,14 +1396,16 @@ vio_wait_ctrl_done(struct vio_softc *sc) { int r = 0; - while (sc->sc_ctrl_inuse != DONE && sc->sc_ctrl_inuse != RESET) { - if (sc->sc_ctrl_inuse == RESET) { - r = 1; - break; + while (sc->sc_ctrl_inuse != DONE) { + if (sc->sc_ctrl_inuse == RESET || vio_needs_reset(sc)) + return ENXIO; + r = tsleep_nsec(&sc->sc_ctrl_inuse, PRIBIO, "viodone", + VIRTIO_NET_CTRL_TIMEOUT); + if (r == EWOULDBLOCK) { + printf("%s: ctrl queue timeout", sc->sc_dev.dv_xname); + vio_ctrl_wakeup(sc, RESET); + return ENXIO; } - r = vio_sleep(sc, "viodone"); - if (r == EINTR) - break; } return r; } diff --git a/sys/dev/pv/virtiovar.h b/sys/dev/pv/virtiovar.h index 69e0a7466..887bc2363 100644 --- a/sys/dev/pv/virtiovar.h +++ b/sys/dev/pv/virtiovar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: virtiovar.h,v 1.17 2024/05/13 01:15:51 jsg Exp $ */ +/* $OpenBSD: virtiovar.h,v 1.18 2024/05/17 16:37:10 sf Exp $ */ /* $NetBSD: virtiovar.h,v 1.1 2011/10/30 12:12:21 hannken Exp $ */ /* @@ -154,6 +154,7 @@ struct virtio_ops { void (*write_dev_cfg_8)(struct virtio_softc *, int, uint64_t); uint16_t (*read_queue_size)(struct virtio_softc *, uint16_t); void (*setup_queue)(struct virtio_softc *, struct virtqueue *, uint64_t); + int (*get_status)(struct virtio_softc *); void (*set_status)(struct virtio_softc *, int); int (*neg_features)(struct virtio_softc *, const struct virtio_feature_name *); int (*poll_intr)(void *); @@ -197,9 +198,10 @@ struct virtio_softc { #define virtio_setup_queue(sc, i, v) (sc)->sc_ops->setup_queue(sc, i, v) #define virtio_negotiate_features(sc, n) (sc)->sc_ops->neg_features(sc, n) #define virtio_poll_intr(sc) (sc)->sc_ops->poll_intr(sc) +#define virtio_get_status(sc) (sc)->sc_ops->get_status(sc) +#define virtio_set_status(sc, i) (sc)->sc_ops->set_status(sc, i) /* only for transport drivers */ -#define virtio_set_status(sc, i) (sc)->sc_ops->set_status(sc, i) #define virtio_device_reset(sc) virtio_set_status((sc), 0) static inline int diff --git a/sys/dev/sbus/esp_sbus.c b/sys/dev/sbus/esp_sbus.c index fb2f6e0ef..e8fcbe960 100644 --- a/sys/dev/sbus/esp_sbus.c +++ b/sys/dev/sbus/esp_sbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: esp_sbus.c,v 1.26 2022/03/13 13:34:54 mpi Exp $ */ +/* $OpenBSD: esp_sbus.c,v 1.27 2024/05/17 20:03:13 miod Exp $ */ /* $NetBSD: esp_sbus.c,v 1.14 2001/04/25 17:53:37 bouyer Exp $ */ /*- @@ -262,18 +262,14 @@ espattach_sbus(struct device *parent, struct device *self, void *aux) /* * Find the DMA by poking around the dma device structures - * * What happens here is that if the dma driver has not been - * configured, then this returns a NULL pointer. Then when the - * dma actually gets configured, it does the opposing test, and - * if the sc->sc_esp field in its softc is NULL, then tries to - * find the matching esp driver. + * configured, then this returns a NULL pointer. */ esc->sc_dma = (struct lsi64854_softc *) getdevunit("dma", sc->sc_dev.dv_unit - esp_unit_offset); /* - * and a back pointer to us, for DMA + * add a back pointer to us, for DMA */ if (esc->sc_dma) esc->sc_dma->sc_client = sc; diff --git a/sys/dev/wscons/wsmouse.c b/sys/dev/wscons/wsmouse.c index 785e7811c..e0d6cd2ab 100644 --- a/sys/dev/wscons/wsmouse.c +++ b/sys/dev/wscons/wsmouse.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wsmouse.c,v 1.71 2024/03/25 13:01:49 mvs Exp $ */ +/* $OpenBSD: wsmouse.c,v 1.72 2024/05/17 20:11:58 miod Exp $ */ /* $NetBSD: wsmouse.c,v 1.35 2005/02/27 00:27:52 perry Exp $ */ /* @@ -1255,6 +1255,7 @@ wsmouse_matching(int *matrix, int m, int n, int *buffer) for (; p < mc; *p++ = 0) {} for (col = 0; col < n; col++) { delta = INT_MAX; + row = 0; for (i = 0, p = matrix + col; i < m; i++, p += n) { d = *p - red[i]; if (d < delta || (d == delta && r2c[i] < 0)) { diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 97362e95a..17dc1c021 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -1,10 +1,10 @@ -/* $OpenBSD: init_sysent.c,v 1.280 2024/05/10 09:21:41 claudio Exp $ */ +/* $OpenBSD: init_sysent.c,v 1.281 2024/05/18 05:21:02 guenther Exp $ */ /* * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * created from; OpenBSD: syscalls.master,v 1.263 2024/05/10 09:21:01 claudio Exp + * created from; OpenBSD: syscalls.master,v 1.264 2024/05/18 05:20:22 guenther Exp */ #include @@ -417,8 +417,8 @@ const struct sysent sysent[] = { sys_nosys }, /* 188 = obsolete stat35 */ { 0, 0, 0, sys_nosys }, /* 189 = obsolete fstat35 */ - { 0, 0, 0, - sys_nosys }, /* 190 = obsolete lstat35 */ + { 4, s(struct sys_pathconfat_args), 0, + sys_pathconfat }, /* 190 = pathconfat */ { 2, s(struct sys_pathconf_args), 0, sys_pathconf }, /* 191 = pathconf */ { 2, s(struct sys_fpathconf_args), 0, diff --git a/sys/kern/kern_pledge.c b/sys/kern/kern_pledge.c index dce4d91cc..487df5dc2 100644 --- a/sys/kern/kern_pledge.c +++ b/sys/kern/kern_pledge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_pledge.c,v 1.313 2024/04/05 13:55:26 deraadt Exp $ */ +/* $OpenBSD: kern_pledge.c,v 1.314 2024/05/18 05:20:22 guenther Exp $ */ /* * Copyright (c) 2015 Nicholas Marriott @@ -340,6 +340,7 @@ const uint64_t pledge_syscalls[SYS_MAXSYSCALL] = { [SYS_statfs] = PLEDGE_RPATH, [SYS_fstatfs] = PLEDGE_RPATH, [SYS_pathconf] = PLEDGE_RPATH, + [SYS_pathconfat] = PLEDGE_RPATH, [SYS_utimes] = PLEDGE_FATTR, [SYS_futimes] = PLEDGE_FATTR, diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index be5a4be2a..7f690a6fa 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -1,10 +1,10 @@ -/* $OpenBSD: syscalls.c,v 1.278 2024/05/10 09:21:41 claudio Exp $ */ +/* $OpenBSD: syscalls.c,v 1.279 2024/05/18 05:21:02 guenther Exp $ */ /* * System call names. * * DO NOT EDIT-- this file is automatically generated. - * created from; OpenBSD: syscalls.master,v 1.263 2024/05/10 09:21:01 claudio Exp + * created from; OpenBSD: syscalls.master,v 1.264 2024/05/18 05:20:22 guenther Exp */ const char *const syscallnames[] = { @@ -214,7 +214,7 @@ const char *const syscallnames[] = { "#187 (obsolete lfs_segwait)", /* 187 = obsolete lfs_segwait */ "#188 (obsolete stat35)", /* 188 = obsolete stat35 */ "#189 (obsolete fstat35)", /* 189 = obsolete fstat35 */ - "#190 (obsolete lstat35)", /* 190 = obsolete lstat35 */ + "pathconfat", /* 190 = pathconfat */ "pathconf", /* 191 = pathconf */ "fpathconf", /* 192 = fpathconf */ "swapctl", /* 193 = swapctl */ diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 55f484967..ddc1fabf8 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,4 +1,4 @@ -; $OpenBSD: syscalls.master,v 1.263 2024/05/10 09:21:01 claudio Exp $ +; $OpenBSD: syscalls.master,v 1.264 2024/05/18 05:20:22 guenther Exp $ ; $NetBSD: syscalls.master,v 1.32 1996/04/23 10:24:21 mycroft Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 @@ -346,7 +346,8 @@ 187 OBSOL lfs_segwait 188 OBSOL stat35 189 OBSOL fstat35 -190 OBSOL lstat35 +190 STD { long sys_pathconfat(int fd, const char *path, \ + int name, int flag); } 191 STD { long sys_pathconf(const char *path, int name); } 192 STD { long sys_fpathconf(int fd, int name); } 193 STD { int sys_swapctl(int cmd, const void *arg, int misc); } diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index e67882b2d..1097f1602 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket.c,v 1.333 2024/05/03 17:43:09 mvs Exp $ */ +/* $OpenBSD: uipc_socket.c,v 1.335 2024/05/17 19:11:14 mvs Exp $ */ /* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */ /* @@ -66,7 +66,6 @@ void soreaper(void *); void soput(void *); int somove(struct socket *, int); void sorflush(struct socket *); -void sorflush_locked(struct socket *); void filt_sordetach(struct knote *kn); int filt_soread(struct knote *kn, long hint); @@ -166,6 +165,7 @@ soalloc(const struct protosw *prp, int wait) break; } break; + case AF_KEY: case AF_UNIX: so->so_snd.sb_flags |= SB_MTXLOCK; so->so_rcv.sb_flags |= SB_MTXLOCK; @@ -606,11 +606,11 @@ sosend(struct socket *so, struct mbuf *addr, struct uio *uio, struct mbuf *top, #define snderr(errno) { error = errno; goto release; } +restart: + if ((error = sblock(&so->so_snd, SBLOCKWAIT(flags))) != 0) + goto out; if (dosolock) solock_shared(so); -restart: - if ((error = sblock(so, &so->so_snd, SBLOCKWAIT(flags))) != 0) - goto out; sb_mtx_lock(&so->so_snd); so->so_snd.sb_state |= SS_ISSENDING; do { @@ -643,15 +643,12 @@ restart: (atomic || space < so->so_snd.sb_lowat))) { if (flags & MSG_DONTWAIT) snderr(EWOULDBLOCK); - sbunlock(so, &so->so_snd); - - if (so->so_snd.sb_flags & SB_MTXLOCK) - error = sbwait_locked(so, &so->so_snd); - else - error = sbwait(so, &so->so_snd); - + sbunlock(&so->so_snd); + error = sbwait(so, &so->so_snd); so->so_snd.sb_state &= ~SS_ISSENDING; sb_mtx_unlock(&so->so_snd); + if (dosolock) + sounlock_shared(so); if (error) goto out; goto restart; @@ -705,10 +702,10 @@ restart: release: so->so_snd.sb_state &= ~SS_ISSENDING; sb_mtx_unlock(&so->so_snd); - sbunlock(so, &so->so_snd); -out: if (dosolock) sounlock_shared(so); + sbunlock(&so->so_snd); +out: m_freem(top); m_freem(control); return (error); @@ -875,11 +872,11 @@ bad: if (mp) *mp = NULL; +restart: + if ((error = sblock(&so->so_rcv, SBLOCKWAIT(flags))) != 0) + return (error); if (dosolock) solock_shared(so); -restart: - if ((error = sblock(so, &so->so_rcv, SBLOCKWAIT(flags))) != 0) - goto out; sb_mtx_lock(&so->so_rcv); m = so->so_rcv.sb_mb; @@ -944,25 +941,13 @@ restart: SBLASTRECORDCHK(&so->so_rcv, "soreceive sbwait 1"); SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 1"); - if (so->so_rcv.sb_flags & SB_MTXLOCK) { - sbunlock_locked(so, &so->so_rcv); - if (dosolock) - sounlock_shared(so); - error = sbwait_locked(so, &so->so_rcv); - sb_mtx_unlock(&so->so_rcv); - if (error) - return (error); - if (dosolock) - solock_shared(so); - } else { - sb_mtx_unlock(&so->so_rcv); - sbunlock(so, &so->so_rcv); - error = sbwait(so, &so->so_rcv); - if (error) { - sounlock_shared(so); - return (error); - } - } + sbunlock(&so->so_rcv); + error = sbwait(so, &so->so_rcv); + sb_mtx_unlock(&so->so_rcv); + if (dosolock) + sounlock_shared(so); + if (error) + return (error); goto restart; } dontblock: @@ -1202,21 +1187,12 @@ dontblock: break; SBLASTRECORDCHK(&so->so_rcv, "soreceive sbwait 2"); SBLASTMBUFCHK(&so->so_rcv, "soreceive sbwait 2"); - if (dosolock) { + if (sbwait(so, &so->so_rcv)) { sb_mtx_unlock(&so->so_rcv); - error = sbwait(so, &so->so_rcv); - if (error) { - sbunlock(so, &so->so_rcv); + if (dosolock) sounlock_shared(so); - return (0); - } - sb_mtx_lock(&so->so_rcv); - } else { - if (sbwait_locked(so, &so->so_rcv)) { - sb_mtx_unlock(&so->so_rcv); - sbunlock(so, &so->so_rcv); - return (0); - } + sbunlock(&so->so_rcv); + return (0); } if ((m = so->so_rcv.sb_mb) != NULL) nextrecord = m->m_nextpkt; @@ -1258,7 +1234,7 @@ dontblock: (flags & MSG_EOR) == 0 && (so->so_rcv.sb_state & SS_CANTRCVMORE) == 0) { sb_mtx_unlock(&so->so_rcv); - sbunlock(so, &so->so_rcv); + sbunlock(&so->so_rcv); goto restart; } @@ -1269,10 +1245,9 @@ dontblock: *flagsp |= flags; release: sb_mtx_unlock(&so->so_rcv); - sbunlock(so, &so->so_rcv); -out: if (dosolock) sounlock_shared(so); + sbunlock(&so->so_rcv); return (error); } @@ -1302,48 +1277,33 @@ soshutdown(struct socket *so, int how) } void -sorflush_locked(struct socket *so) +sorflush(struct socket *so) { struct sockbuf *sb = &so->so_rcv; struct mbuf *m; const struct protosw *pr = so->so_proto; int error; - if ((sb->sb_flags & SB_MTXLOCK) == 0) - soassertlocked(so); - - error = sblock(so, sb, SBL_WAIT | SBL_NOINTR); + error = sblock(sb, SBL_WAIT | SBL_NOINTR); /* with SBL_WAIT and SLB_NOINTR sblock() must not fail */ KASSERT(error == 0); - if (sb->sb_flags & SB_MTXLOCK) - solock(so); + solock_shared(so); socantrcvmore(so); - if (sb->sb_flags & SB_MTXLOCK) - sounlock(so); - mtx_enter(&sb->sb_mtx); m = sb->sb_mb; memset(&sb->sb_startzero, 0, (caddr_t)&sb->sb_endzero - (caddr_t)&sb->sb_startzero); sb->sb_timeo_nsecs = INFSLP; mtx_leave(&sb->sb_mtx); - sbunlock(so, sb); + sounlock_shared(so); + sbunlock(sb); + if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose) (*pr->pr_domain->dom_dispose)(m); m_purge(m); } -void -sorflush(struct socket *so) -{ - if ((so->so_rcv.sb_flags & SB_MTXLOCK) == 0) - solock_shared(so); - sorflush_locked(so); - if ((so->so_rcv.sb_flags & SB_MTXLOCK) == 0) - sounlock_shared(so); -} - #ifdef SOCKET_SPLICE #define so_splicelen so_sp->ssp_len @@ -1355,7 +1315,7 @@ sorflush(struct socket *so) int sosplice(struct socket *so, int fd, off_t max, struct timeval *tv) { - struct file *fp = NULL; + struct file *fp; struct socket *sosp; struct taskq *tq; int error = 0; @@ -1367,6 +1327,29 @@ sosplice(struct socket *so, int fd, off_t max, struct timeval *tv) if (tv && (tv->tv_sec < 0 || !timerisvalid(tv))) return (EINVAL); + /* If no fd is given, unsplice by removing existing link. */ + if (fd < 0) { + if ((error = sblock(&so->so_rcv, SBL_WAIT)) != 0) + return (error); + solock(so); + if (so->so_options & SO_ACCEPTCONN) { + error = EOPNOTSUPP; + goto out; + } + if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0 && + (so->so_proto->pr_flags & PR_CONNREQUIRED)) { + error = ENOTCONN; + goto out; + } + + if (so->so_sp && so->so_sp->ssp_socket) + sounsplice(so, so->so_sp->ssp_socket, 0); + out: + sounlock(so); + sbunlock(&so->so_rcv); + return (error); + } + if (sosplice_taskq == NULL) { rw_enter_write(&sosplice_lock); if (sosplice_taskq == NULL) { @@ -1386,65 +1369,47 @@ sosplice(struct socket *so, int fd, off_t max, struct timeval *tv) membar_consumer(); } - if (so->so_rcv.sb_flags & SB_MTXLOCK) { - if ((error = sblock(so, &so->so_rcv, SBL_WAIT)) != 0) - return (error); - solock(so); - } else { - solock(so); - if ((error = sblock(so, &so->so_rcv, SBL_WAIT)) != 0) { - sounlock(so); - return (error); - } + /* Find sosp, the drain socket where data will be spliced into. */ + if ((error = getsock(curproc, fd, &fp)) != 0) + return (error); + sosp = fp->f_data; + + if (sosp->so_proto->pr_usrreqs->pru_send != + so->so_proto->pr_usrreqs->pru_send) { + error = EPROTONOSUPPORT; + goto frele; } - if (so->so_options & SO_ACCEPTCONN) { + if ((error = sblock(&so->so_rcv, SBL_WAIT)) != 0) + goto frele; + if ((error = sblock(&sosp->so_snd, SBL_WAIT)) != 0) { + sbunlock(&so->so_rcv); + goto frele; + } + solock(so); + + if ((so->so_options & SO_ACCEPTCONN) || + (sosp->so_options & SO_ACCEPTCONN)) { error = EOPNOTSUPP; - goto out; + goto release; } if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0 && (so->so_proto->pr_flags & PR_CONNREQUIRED)) { error = ENOTCONN; - goto out; - } - if (so->so_sp == NULL) - so->so_sp = pool_get(&sosplice_pool, PR_WAITOK | PR_ZERO); - - /* If no fd is given, unsplice by removing existing link. */ - if (fd < 0) { - if (so->so_sp->ssp_socket) - sounsplice(so, so->so_sp->ssp_socket, 0); - goto out; - } - - /* Find sosp, the drain socket where data will be spliced into. */ - if ((error = getsock(curproc, fd, &fp)) != 0) - goto out; - sosp = fp->f_data; - if (sosp->so_proto->pr_usrreqs->pru_send != - so->so_proto->pr_usrreqs->pru_send) { - error = EPROTONOSUPPORT; - goto out; - } - if (sosp->so_sp == NULL) - sosp->so_sp = pool_get(&sosplice_pool, PR_WAITOK | PR_ZERO); - - if ((error = sblock(sosp, &sosp->so_snd, SBL_WAIT)) != 0) { - goto out; - } - - if (so->so_sp->ssp_socket || sosp->so_sp->ssp_soback) { - error = EBUSY; - goto release; - } - if (sosp->so_options & SO_ACCEPTCONN) { - error = EOPNOTSUPP; goto release; } if ((sosp->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0) { error = ENOTCONN; goto release; } + if (so->so_sp == NULL) + so->so_sp = pool_get(&sosplice_pool, PR_WAITOK | PR_ZERO); + if (sosp->so_sp == NULL) + sosp->so_sp = pool_get(&sosplice_pool, PR_WAITOK | PR_ZERO); + if (so->so_sp->ssp_socket || sosp->so_sp->ssp_soback) { + error = EBUSY; + goto release; + } /* Splice so and sosp together. */ mtx_enter(&so->so_rcv.sb_mtx); @@ -1472,18 +1437,11 @@ sosplice(struct socket *so, int fd, off_t max, struct timeval *tv) } release: - sbunlock(sosp, &sosp->so_snd); - out: - if (so->so_rcv.sb_flags & SB_MTXLOCK) { - sounlock(so); - sbunlock(so, &so->so_rcv); - } else { - sbunlock(so, &so->so_rcv); - sounlock(so); - } - - if (fp) - FRELE(fp, curproc); + sounlock(so); + sbunlock(&sosp->so_snd); + sbunlock(&so->so_rcv); + frele: + FRELE(fp, curproc); return (error); } diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c index 96e24f8d3..df5086c86 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket2.c,v 1.154 2024/05/07 15:54:23 claudio Exp $ */ +/* $OpenBSD: uipc_socket2.c,v 1.155 2024/05/17 19:11:14 mvs Exp $ */ /* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */ /* @@ -511,24 +511,20 @@ sbmtxassertlocked(struct socket *so, struct sockbuf *sb) /* * Wait for data to arrive at/drain from a socket buffer. */ -int -sbwait_locked(struct socket *so, struct sockbuf *sb) -{ - int prio = (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH; - - MUTEX_ASSERT_LOCKED(&sb->sb_mtx); - - sb->sb_flags |= SB_WAIT; - return msleep_nsec(&sb->sb_cc, &sb->sb_mtx, prio, "sbwait", - sb->sb_timeo_nsecs); -} - int sbwait(struct socket *so, struct sockbuf *sb) { uint64_t timeo_nsecs; int prio = (sb->sb_flags & SB_NOINTR) ? PSOCK : PSOCK | PCATCH; + if (sb->sb_flags & SB_MTXLOCK) { + MUTEX_ASSERT_LOCKED(&sb->sb_mtx); + + sb->sb_flags |= SB_WAIT; + return msleep_nsec(&sb->sb_cc, &sb->sb_mtx, prio, "sbwait", + sb->sb_timeo_nsecs); + } + soassertlocked(so); mtx_enter(&sb->sb_mtx); @@ -540,81 +536,26 @@ sbwait(struct socket *so, struct sockbuf *sb) } int -sblock(struct socket *so, struct sockbuf *sb, int flags) +sblock(struct sockbuf *sb, int flags) { - int error = 0, prio = PSOCK; + int rwflags = RW_WRITE, error; - if (sb->sb_flags & SB_MTXLOCK) { - int rwflags = RW_WRITE; - - if (!(flags & SBL_NOINTR || sb->sb_flags & SB_NOINTR)) - rwflags |= RW_INTR; - if (!(flags & SBL_WAIT)) - rwflags |= RW_NOSLEEP; - - error = rw_enter(&sb->sb_lock, rwflags); - if (error == EBUSY) - error = EWOULDBLOCK; - return error; - } - - soassertlocked(so); - - mtx_enter(&sb->sb_mtx); - if ((sb->sb_flags & SB_LOCK) == 0) { - sb->sb_flags |= SB_LOCK; - goto out; - } - if ((flags & SBL_WAIT) == 0) { - error = EWOULDBLOCK; - goto out; - } if (!(flags & SBL_NOINTR || sb->sb_flags & SB_NOINTR)) - prio |= PCATCH; + rwflags |= RW_INTR; + if (!(flags & SBL_WAIT)) + rwflags |= RW_NOSLEEP; - while (sb->sb_flags & SB_LOCK) { - sb->sb_flags |= SB_WANT; - mtx_leave(&sb->sb_mtx); - error = sosleep_nsec(so, &sb->sb_flags, prio, "sblock", INFSLP); - if (error) - return (error); - mtx_enter(&sb->sb_mtx); - } - sb->sb_flags |= SB_LOCK; -out: - mtx_leave(&sb->sb_mtx); + error = rw_enter(&sb->sb_lock, rwflags); + if (error == EBUSY) + error = EWOULDBLOCK; - return (error); + return error; } void -sbunlock_locked(struct socket *so, struct sockbuf *sb) +sbunlock(struct sockbuf *sb) { - if (sb->sb_flags & SB_MTXLOCK) { - rw_exit(&sb->sb_lock); - return; - } - - MUTEX_ASSERT_LOCKED(&sb->sb_mtx); - - sb->sb_flags &= ~SB_LOCK; - if (sb->sb_flags & SB_WANT) { - sb->sb_flags &= ~SB_WANT; - wakeup(&sb->sb_flags); - } -} - -void -sbunlock(struct socket *so, struct sockbuf *sb) -{ - if (sb->sb_flags & SB_MTXLOCK) { - rw_exit(&sb->sb_lock); - return; - } - - mtx_enter(&sb->sb_mtx); - sbunlock_locked(so, sb); - mtx_leave(&sb->sb_mtx); + rw_exit(&sb->sb_lock); } /* @@ -1128,7 +1069,7 @@ void sbflush(struct socket *so, struct sockbuf *sb) { KASSERT(sb == &so->so_rcv || sb == &so->so_snd); - KASSERT((sb->sb_flags & SB_LOCK) == 0); + rw_assert_unlocked(&sb->sb_lock); while (sb->sb_mbcnt) sbdrop(so, sb, (int)sb->sb_cc); diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 40445f251..abd4395bc 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vfs_syscalls.c,v 1.364 2024/03/25 17:57:07 guenther Exp $ */ +/* $OpenBSD: vfs_syscalls.c,v 1.365 2024/05/18 05:20:22 guenther Exp $ */ /* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */ /* @@ -76,6 +76,7 @@ int dosymlinkat(struct proc *, const char *, int, const char *); int dounlinkat(struct proc *, int, const char *, int); int dofaccessat(struct proc *, int, const char *, int, int); int dofstatat(struct proc *, int, const char *, struct stat *, int); +int dopathconfat(struct proc *, int, const char *, int, int, register_t *); int doreadlinkat(struct proc *, int, const char *, char *, size_t, register_t *); int dochflagsat(struct proc *, int, const char *, u_int, int); @@ -2112,16 +2113,42 @@ sys_pathconf(struct proc *p, void *v, register_t *retval) syscallarg(const char *) path; syscallarg(int) name; } */ *uap = v; - int error; + + return dopathconfat(p, AT_FDCWD, SCARG(uap, path), SCARG(uap, name), + 0, retval); +} + +int +sys_pathconfat(struct proc *p, void *v, register_t *retval) +{ + struct sys_pathconfat_args /* { + syscallarg(int) fd; + syscallarg(const char *) path; + syscallarg(int) name; + syscallarg(int) flag; + } */ *uap = v; + + return dopathconfat(p, SCARG(uap, fd), SCARG(uap, path), + SCARG(uap, name), SCARG(uap, flag), retval); +} + +int +dopathconfat(struct proc *p, int fd, const char *path, int name, int flag, + register_t *retval) +{ + int follow, error; struct nameidata nd; - NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, - SCARG(uap, path), p); + if (flag & ~AT_SYMLINK_NOFOLLOW) + return EINVAL; + + follow = (flag & AT_SYMLINK_NOFOLLOW) ? NOFOLLOW : FOLLOW; + NDINITAT(&nd, LOOKUP, follow | LOCKLEAF, UIO_USERSPACE, fd, path, p); nd.ni_pledge = PLEDGE_RPATH; nd.ni_unveil = UNVEIL_READ; if ((error = namei(&nd)) != 0) return (error); - error = VOP_PATHCONF(nd.ni_vp, SCARG(uap, name), retval); + error = VOP_PATHCONF(nd.ni_vp, name, retval); vput(nd.ni_vp); return (error); } diff --git a/sys/net/pfkeyv2.c b/sys/net/pfkeyv2.c index d37803cba..7f63e92fa 100644 --- a/sys/net/pfkeyv2.c +++ b/sys/net/pfkeyv2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfkeyv2.c,v 1.260 2024/01/11 14:15:11 bluhm Exp $ */ +/* $OpenBSD: pfkeyv2.c,v 1.262 2024/05/17 19:02:04 mvs Exp $ */ /* * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995 @@ -443,8 +443,7 @@ pfkey_sendup(struct pkpcb *kp, struct mbuf *m0, int more) { struct socket *so = kp->kcb_socket; struct mbuf *m; - - soassertlocked(so); + int ret; if (more) { if (!(m = m_dup_pkt(m0, 0, M_DONTWAIT))) @@ -452,7 +451,11 @@ pfkey_sendup(struct pkpcb *kp, struct mbuf *m0, int more) } else m = m0; - if (!sbappendaddr(so, &so->so_rcv, &pfkey_addr, m, NULL)) { + mtx_enter(&so->so_rcv.sb_mtx); + ret = sbappendaddr(so, &so->so_rcv, &pfkey_addr, m, NULL); + mtx_leave(&so->so_rcv.sb_mtx); + + if (ret == 0) { m_freem(m); return (ENOBUFS); } @@ -515,9 +518,7 @@ pfkeyv2_sendmessage(void **headers, int mode, struct socket *so, * Send message to the specified socket, plus all * promiscuous listeners. */ - solock(so); pfkey_sendup(sotokeycb(so), packet, 0); - sounlock(so); /* * Promiscuous messages contain the original message @@ -544,10 +545,8 @@ pfkeyv2_sendmessage(void **headers, int mode, struct socket *so, if (kp->kcb_socket == so || kp->kcb_rdomain != rdomain) continue; - keylock(kp); if (kp->kcb_flags & PFKEYV2_SOCKETFLAGS_PROMISC) pfkey_sendup(kp, packet, 1); - keyunlock(kp); } SRPL_LEAVE(&sr); m_freem(packet); @@ -562,18 +561,18 @@ pfkeyv2_sendmessage(void **headers, int mode, struct socket *so, if (kp->kcb_rdomain != rdomain) continue; - keylock(kp); if (kp->kcb_flags & PFKEYV2_SOCKETFLAGS_REGISTERED) { if (!satype) { /* Just send to everyone registered */ pfkey_sendup(kp, packet, 1); } else { + keylock(kp); /* Check for specified satype */ if ((1 << satype) & kp->kcb_reg) pfkey_sendup(kp, packet, 1); + keyunlock(kp); } } - keyunlock(kp); } SRPL_LEAVE(&sr); /* Free last/original copy of the packet */ @@ -595,14 +594,14 @@ pfkeyv2_sendmessage(void **headers, int mode, struct socket *so, /* Send to all registered promiscuous listeners */ SRPL_FOREACH(kp, &sr, &pkptable.pkp_list, kcb_list) { + int flags = READ_ONCE(kp->kcb_flags); + if (kp->kcb_rdomain != rdomain) continue; - keylock(kp); - if ((kp->kcb_flags & PFKEYV2_SOCKETFLAGS_PROMISC) && - !(kp->kcb_flags & PFKEYV2_SOCKETFLAGS_REGISTERED)) + if ((flags & PFKEYV2_SOCKETFLAGS_PROMISC) && + !(flags & PFKEYV2_SOCKETFLAGS_REGISTERED)) pfkey_sendup(kp, packet, 1); - keyunlock(kp); } SRPL_LEAVE(&sr); m_freem(packet); @@ -614,9 +613,7 @@ pfkeyv2_sendmessage(void **headers, int mode, struct socket *so, if (kp->kcb_rdomain != rdomain) continue; - keylock(kp); pfkey_sendup(kp, packet, 1); - keyunlock(kp); } SRPL_LEAVE(&sr); m_freem(packet); @@ -1196,10 +1193,8 @@ pfkeyv2_dosend(struct socket *so, void *message, int len) if (bkp->kcb_rdomain != kp->kcb_rdomain) continue; - keylock(bkp); if (bkp->kcb_flags & PFKEYV2_SOCKETFLAGS_PROMISC) pfkey_sendup(bkp, packet, 1); - keyunlock(bkp); } SRPL_LEAVE(&sr); @@ -2049,14 +2044,13 @@ pfkeyv2_dosend(struct socket *so, void *message, int len) goto ret; SRPL_FOREACH(bkp, &sr, &pkptable.pkp_list, kcb_list) { - if (bkp == kp || bkp->kcb_rdomain != kp->kcb_rdomain) + if (bkp == kp || + bkp->kcb_rdomain != kp->kcb_rdomain) continue; if (!smsg->sadb_msg_seq || (smsg->sadb_msg_seq == kp->kcb_pid)) { - keylock(bkp); pfkey_sendup(bkp, packet, 1); - keyunlock(bkp); } } SRPL_LEAVE(&sr); @@ -2705,7 +2699,10 @@ pfkeyv2_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, if (namelen < 1) return (EINVAL); w.w_op = name[0]; - w.w_satype = name[1]; + if (namelen >= 2) + w.w_satype = name[1]; + else + w.w_satype = SADB_SATYPE_UNSPEC; w.w_where = oldp; w.w_len = oldp ? *oldlenp : 0; diff --git a/sys/netinet/ip_ipip.c b/sys/netinet/ip_ipip.c index 84e9912f0..fdebd0883 100644 --- a/sys/netinet/ip_ipip.c +++ b/sys/netinet/ip_ipip.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_ipip.c,v 1.101 2024/02/11 01:27:45 bluhm Exp $ */ +/* $OpenBSD: ip_ipip.c,v 1.102 2024/05/17 20:44:36 bluhm Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -481,7 +481,7 @@ ipip_output(struct mbuf **mp, struct tdb *tdb) ip6o->ip6_vfc &= ~IPV6_VERSION_MASK; ip6o->ip6_vfc |= IPV6_VERSION; ip6o->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6o)); - ip6o->ip6_hlim = ip_defttl; + ip6o->ip6_hlim = ip6_defhlim; in6_embedscope(&ip6o->ip6_src, &tdb->tdb_src.sin6, NULL, NULL); in6_embedscope(&ip6o->ip6_dst, &tdb->tdb_dst.sin6, NULL, NULL); diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index c5a9b419c..c0aeb7693 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_output.c,v 1.398 2024/04/17 20:48:51 bluhm Exp $ */ +/* $OpenBSD: ip_output.c,v 1.399 2024/05/16 13:01:04 bluhm Exp $ */ /* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */ /* @@ -428,8 +428,9 @@ sendit: #endif #ifdef IPSEC - if (ipsec_in_use && (flags & IP_FORWARDING) && (ipforwarding == 2) && - (m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL) == NULL)) { + if ((flags & IP_FORWARDING) && ipforwarding == 2 && + (!ipsec_in_use || + m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL) == NULL)) { error = EHOSTUNREACH; goto bad; } diff --git a/sys/sys/mutex.h b/sys/sys/mutex.h index cff33404c..960299fa9 100644 --- a/sys/sys/mutex.h +++ b/sys/sys/mutex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mutex.h,v 1.21 2024/03/26 18:18:30 bluhm Exp $ */ +/* $OpenBSD: mutex.h,v 1.22 2024/05/16 09:30:03 kettenis Exp $ */ /* * Copyright (c) 2004 Artur Grabowski @@ -33,6 +33,20 @@ * "mtx_enter(foo); mtx_enter(bar); mtx_leave(foo); mtx_leave(bar);" */ +/* + * To prevent lock ordering problems with the kernel lock, we need to + * make sure we block all interrupts that can grab the kernel lock. + * The simplest way to achieve this is to make sure mutexes always + * raise the interrupt priority level to the highest level that has + * interrupts that grab the kernel lock. + */ +#ifdef MULTIPROCESSOR +#define __MUTEX_IPL(ipl) \ + (((ipl) < IPL_MPFLOOR) ? IPL_MPFLOOR : (ipl)) +#else +#define __MUTEX_IPL(ipl) (ipl) +#endif + #include #ifdef __USE_MI_MUTEX @@ -48,20 +62,6 @@ struct mutex { #endif }; -/* - * To prevent lock ordering problems with the kernel lock, we need to - * make sure we block all interrupts that can grab the kernel lock. - * The simplest way to achieve this is to make sure mutexes always - * raise the interrupt priority level to the highest level that has - * interrupts that grab the kernel lock. - */ -#ifdef MULTIPROCESSOR -#define __MUTEX_IPL(ipl) \ - (((ipl) > IPL_NONE && (ipl) < IPL_MPFLOOR) ? IPL_MPFLOOR : (ipl)) -#else -#define __MUTEX_IPL(ipl) (ipl) -#endif - #ifdef WITNESS #define MUTEX_INITIALIZER_FLAGS(ipl, name, flags) \ { NULL, __MUTEX_IPL((ipl)), IPL_NONE, MTX_LO_INITIALIZER(name, flags) } diff --git a/sys/sys/socketvar.h b/sys/sys/socketvar.h index 65e17e42a..d7587bafb 100644 --- a/sys/sys/socketvar.h +++ b/sys/sys/socketvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: socketvar.h,v 1.130 2024/05/03 17:43:09 mvs Exp $ */ +/* $OpenBSD: socketvar.h,v 1.131 2024/05/17 19:11:14 mvs Exp $ */ /* $NetBSD: socketvar.h,v 1.18 1996/02/09 18:25:38 christos Exp $ */ /*- @@ -128,13 +128,11 @@ struct socket { struct klist sb_klist; /* process selecting read/write */ } so_rcv, so_snd; #define SB_MAX (2*1024*1024) /* default for max chars in sockbuf */ -#define SB_LOCK 0x0001 /* lock on data queue */ -#define SB_WANT 0x0002 /* someone is waiting to lock */ -#define SB_WAIT 0x0004 /* someone is waiting for data/space */ -#define SB_ASYNC 0x0010 /* ASYNC I/O, need signals */ -#define SB_SPLICE 0x0020 /* buffer is splice source or drain */ -#define SB_NOINTR 0x0040 /* operations not interruptible */ -#define SB_MTXLOCK 0x0080 /* sblock() doesn't need solock() */ +#define SB_WAIT 0x0001 /* someone is waiting for data/space */ +#define SB_ASYNC 0x0002 /* ASYNC I/O, need signals */ +#define SB_SPLICE 0x0004 /* buffer is splice source or drain */ +#define SB_NOINTR 0x0008 /* operations not interruptible */ +#define SB_MTXLOCK 0x0010 /* sblock() doesn't need solock() */ void (*so_upcall)(struct socket *so, caddr_t arg, int waitf); caddr_t so_upcallarg; /* Arg for above */ @@ -315,11 +313,10 @@ sbfree(struct socket *so, struct sockbuf *sb, struct mbuf *m) * sleep is interruptible. Returns error without lock if * sleep is interrupted. */ -int sblock(struct socket *, struct sockbuf *, int); +int sblock(struct sockbuf *, int); /* release lock on sockbuf sb */ -void sbunlock(struct socket *, struct sockbuf *); -void sbunlock_locked(struct socket *, struct sockbuf *); +void sbunlock(struct sockbuf *); #define SB_EMPTY_FIXUP(sb) do { \ if ((sb)->sb_mb == NULL) { \ @@ -367,7 +364,6 @@ int sbcheckreserve(u_long, u_long); int sbchecklowmem(void); int sbreserve(struct socket *, struct sockbuf *, u_long); int sbwait(struct socket *, struct sockbuf *); -int sbwait_locked(struct socket *, struct sockbuf *); void soinit(void); void soabort(struct socket *); int soaccept(struct socket *, struct mbuf *); diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index ad0d6148a..efc14f0da 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -1,10 +1,10 @@ -/* $OpenBSD: syscall.h,v 1.277 2024/05/10 09:21:41 claudio Exp $ */ +/* $OpenBSD: syscall.h,v 1.278 2024/05/18 05:21:02 guenther Exp $ */ /* * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * created from; OpenBSD: syscalls.master,v 1.263 2024/05/10 09:21:01 claudio Exp + * created from; OpenBSD: syscalls.master,v 1.264 2024/05/18 05:20:22 guenther Exp */ /* syscall: "exit" ret: "void" args: "int" */ @@ -497,7 +497,9 @@ /* 187 is obsolete lfs_segwait */ /* 188 is obsolete stat35 */ /* 189 is obsolete fstat35 */ - /* 190 is obsolete lstat35 */ +/* syscall: "pathconfat" ret: "long" args: "int" "const char *" "int" "int" */ +#define SYS_pathconfat 190 + /* syscall: "pathconf" ret: "long" args: "const char *" "int" */ #define SYS_pathconf 191 diff --git a/sys/sys/syscallargs.h b/sys/sys/syscallargs.h index bd16d05b2..6fca7bbe4 100644 --- a/sys/sys/syscallargs.h +++ b/sys/sys/syscallargs.h @@ -1,10 +1,10 @@ -/* $OpenBSD: syscallargs.h,v 1.280 2024/05/10 09:21:41 claudio Exp $ */ +/* $OpenBSD: syscallargs.h,v 1.281 2024/05/18 05:21:02 guenther Exp $ */ /* * System call argument lists. * * DO NOT EDIT-- this file is automatically generated. - * created from; OpenBSD: syscalls.master,v 1.263 2024/05/10 09:21:01 claudio Exp + * created from; OpenBSD: syscalls.master,v 1.264 2024/05/18 05:20:22 guenther Exp */ #ifdef syscallarg @@ -828,6 +828,13 @@ struct sys_seteuid_args { syscallarg(uid_t) euid; }; +struct sys_pathconfat_args { + syscallarg(int) fd; + syscallarg(const char *) path; + syscallarg(int) name; + syscallarg(int) flag; +}; + struct sys_pathconf_args { syscallarg(const char *) path; syscallarg(int) name; @@ -1320,6 +1327,7 @@ int sys_pwritev(struct proc *, void *, register_t *); int sys_setgid(struct proc *, void *, register_t *); int sys_setegid(struct proc *, void *, register_t *); int sys_seteuid(struct proc *, void *, register_t *); +int sys_pathconfat(struct proc *, void *, register_t *); int sys_pathconf(struct proc *, void *, register_t *); int sys_fpathconf(struct proc *, void *, register_t *); int sys_swapctl(struct proc *, void *, register_t *); diff --git a/usr.bin/dig/dig.h b/usr.bin/dig/dig.h index 86e7ee65b..feed92369 100644 --- a/usr.bin/dig/dig.h +++ b/usr.bin/dig/dig.h @@ -288,9 +288,6 @@ start_lookup(void); void onrun_callback(isc_task_t *task, isc_event_t *event); -int -dhmain(int argc, char **argv); - void setup_libs(void); diff --git a/usr.bin/dig/lib/dns/dst_internal.h b/usr.bin/dig/lib/dns/dst_internal.h index aee3c62ab..a110676e5 100644 --- a/usr.bin/dig/lib/dns/dst_internal.h +++ b/usr.bin/dig/lib/dns/dst_internal.h @@ -31,7 +31,7 @@ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dst_internal.h,v 1.12 2020/09/15 08:15:59 deraadt Exp $ */ +/* $Id: dst_internal.h,v 1.13 2024/05/17 23:56:19 jsg Exp $ */ #ifndef DST_DST_INTERNAL_H #define DST_DST_INTERNAL_H 1 @@ -133,7 +133,6 @@ isc_result_t dst__hmacsha384_init(struct dst_func **funcp); isc_result_t dst__hmacsha512_init(struct dst_func **funcp); isc_result_t dst__opensslrsa_init(struct dst_func **funcp, unsigned char algorithm); -isc_result_t dst__opensslecdsa_init(struct dst_func **funcp); /*% * Destructors diff --git a/usr.bin/dig/lib/dns/include/dns/compress.h b/usr.bin/dig/lib/dns/include/dns/compress.h index bb00c251e..bab8d5297 100644 --- a/usr.bin/dig/lib/dns/include/dns/compress.h +++ b/usr.bin/dig/lib/dns/include/dns/compress.h @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: compress.h,v 1.5 2020/09/14 08:40:43 florian Exp $ */ +/* $Id: compress.h,v 1.6 2024/05/17 23:56:19 jsg Exp $ */ #ifndef DNS_COMPRESS_H #define DNS_COMPRESS_H 1 @@ -173,16 +173,6 @@ dns_decompress_init(dns_decompress_t *dctx, int edns, *\li 'dctx' to be a valid pointer. */ -void -dns_decompress_invalidate(dns_decompress_t *dctx); - -/*%< - * Invalidates 'dctx'. - * - * Requires: - *\li 'dctx' to be initialized - */ - void dns_decompress_setmethods(dns_decompress_t *dctx, unsigned int allowed); @@ -193,14 +183,4 @@ dns_decompress_setmethods(dns_decompress_t *dctx, unsigned int allowed); *\li 'dctx' to be initialized */ -dns_decompresstype_t -dns_decompress_type(dns_decompress_t *dctx); - -/*%< - * Returns 'dctx->type' - * - * Requires: - *\li 'dctx' to be initialized - */ - #endif /* DNS_COMPRESS_H */ diff --git a/usr.bin/dig/lib/dns/include/dns/message.h b/usr.bin/dig/lib/dns/include/dns/message.h index 7f547411b..6cd42be41 100644 --- a/usr.bin/dig/lib/dns/include/dns/message.h +++ b/usr.bin/dig/lib/dns/include/dns/message.h @@ -985,27 +985,6 @@ dns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer); * dynamically allocated via isc_buffer_allocate(). */ -isc_result_t -dns_message_rechecksig(dns_message_t *msg, dns_view_t *view); -/*%< - * Reset the signature state and then if the message was signed, - * verify the message. - * - * Requires: - * - *\li msg is a valid parsed message. - *\li view is a valid view or NULL - * - * Returns: - * - *\li #ISC_R_SUCCESS - the message was unsigned, or the message - * was signed correctly. - * - *\li #DNS_R_EXPECTEDTSIG - A TSIG was expected, but not seen - *\li #DNS_R_UNEXPECTEDTSIG - A TSIG was seen but not expected - *\li #DNS_R_TSIGVERIFYFAILURE - The TSIG failed to verify - */ - isc_result_t dns_message_buildopt(dns_message_t *msg, dns_rdataset_t **opt, unsigned int version, uint16_t udpsize, diff --git a/usr.bin/dig/lib/dns/rdataset.c b/usr.bin/dig/lib/dns/rdataset.c index 6e6390aa6..9d7f98acc 100644 --- a/usr.bin/dig/lib/dns/rdataset.c +++ b/usr.bin/dig/lib/dns/rdataset.c @@ -198,7 +198,7 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name, dns_rdata_t rdata = DNS_RDATA_INIT; isc_region_t r; isc_result_t result; - unsigned int i, count = 0, added; + unsigned int i, count = 0; isc_buffer_t savedbuffer, rdlen; unsigned int headlen; int question = 0; @@ -287,7 +287,6 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name, savedbuffer = *target; i = 0; - added = 0; do { /* @@ -335,7 +334,6 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name, isc_buffer_putuint16(&rdlen, (uint16_t)(target->used - rdlen.used - 2)); - added++; } if (shuffle) { diff --git a/usr.bin/dig/lib/isc/include/isc/log.h b/usr.bin/dig/lib/isc/include/isc/log.h index 44214d9bf..54471ac1c 100644 --- a/usr.bin/dig/lib/isc/include/isc/log.h +++ b/usr.bin/dig/lib/isc/include/isc/log.h @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: log.h,v 1.8 2020/09/14 08:40:44 florian Exp $ */ +/* $Id: log.h,v 1.9 2024/05/17 23:56:19 jsg Exp $ */ #ifndef ISC_LOG_H #define ISC_LOG_H 1 @@ -551,28 +551,6 @@ isc_log_wouldlog(isc_log_t *lctx, int level); * isc_log_write() calls and possible message preformatting. */ -void -isc_log_closefilelogs(isc_log_t *lctx); -/*%< - * Close all open files used by #ISC_LOG_TOFILE channels. - * - * Notes: - *\li This function is provided for programs that want to use their own - * log rolling mechanism rather than the one provided internally. - * For example, a program that wanted to keep daily logs would define - * a channel which used #ISC_LOG_ROLLNEVER, then once a day would - * rename the log file and call isc_log_closefilelogs(). - * - *\li #ISC_LOG_TOFILEDESC channels are unaffected. - * - * Requires: - *\li lctx is a valid context. - * - * Ensures: - *\li The open files are closed and will be reopened when they are - * next needed. - */ - void isc_log_setcontext(isc_log_t *lctx); /*%< diff --git a/usr.bin/dig/lib/isc/sha2.c b/usr.bin/dig/lib/isc/sha2.c index e1c729d95..1839ecebe 100644 --- a/usr.bin/dig/lib/isc/sha2.c +++ b/usr.bin/dig/lib/isc/sha2.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sha2.c,v 1.4 2020/02/24 13:49:38 jsg Exp $ */ +/* $Id: sha2.c,v 1.5 2024/05/17 09:36:48 tb Exp $ */ /* $FreeBSD: src/sys/crypto/sha2/sha2.c,v 1.2.2.2 2002/03/05 08:36:47 ume Exp $ */ /* $KAME: sha2.c,v 1.8 2001/11/08 01:07:52 itojun Exp $ */ @@ -87,7 +87,7 @@ isc_sha224_update(isc_sha224_t *context, const uint8_t* data, size_t len) { } void -isc_sha224_final(uint8_t digest[], isc_sha224_t *context) { +isc_sha224_final(uint8_t digest[ISC_SHA224_DIGESTLENGTH], isc_sha224_t *context) { /* Sanity check: */ REQUIRE(context != (isc_sha224_t *)0); REQUIRE(context->ctx != (EVP_MD_CTX *)0); @@ -129,7 +129,7 @@ isc_sha256_update(isc_sha256_t *context, const uint8_t *data, size_t len) { } void -isc_sha256_final(uint8_t digest[], isc_sha256_t *context) { +isc_sha256_final(uint8_t digest[ISC_SHA256_DIGESTLENGTH], isc_sha256_t *context) { /* Sanity check: */ REQUIRE(context != (isc_sha256_t *)0); REQUIRE(context->ctx != (EVP_MD_CTX *)0); @@ -169,7 +169,7 @@ void isc_sha512_update(isc_sha512_t *context, const uint8_t *data, size_t len) { (const void *) data, len) == 1); } -void isc_sha512_final(uint8_t digest[], isc_sha512_t *context) { +void isc_sha512_final(uint8_t digest[ISC_SHA512_DIGESTLENGTH], isc_sha512_t *context) { /* Sanity check: */ REQUIRE(context != (isc_sha512_t *)0); REQUIRE(context->ctx != (EVP_MD_CTX *)0); @@ -211,7 +211,7 @@ isc_sha384_update(isc_sha384_t *context, const uint8_t* data, size_t len) { } void -isc_sha384_final(uint8_t digest[], isc_sha384_t *context) { +isc_sha384_final(uint8_t digest[ISC_SHA384_DIGESTLENGTH], isc_sha384_t *context) { /* Sanity check: */ REQUIRE(context != (isc_sha384_t *)0); REQUIRE(context->ctx != (EVP_MD_CTX *)0); diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c index 809193447..c28ad9eb2 100644 --- a/usr.bin/kdump/kdump.c +++ b/usr.bin/kdump/kdump.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kdump.c,v 1.162 2024/03/29 07:53:32 deraadt Exp $ */ +/* $OpenBSD: kdump.c,v 1.163 2024/05/18 05:20:22 guenther Exp $ */ /*- * Copyright (c) 1988, 1993 @@ -866,6 +866,7 @@ static const formatter scargs[][8] = { [SYS_setgid] = { Gidname }, [SYS_setegid] = { Gidname }, [SYS_seteuid] = { Uidname }, + [SYS_pathconfat] = { Atfd, Ppath, Pathconfname, Atflagsname }, [SYS_pathconf] = { Ppath, Pathconfname }, [SYS_fpathconf] = { Pfd, Pathconfname }, [SYS_swapctl] = { Swapctlname, Pptr, Pdecint }, diff --git a/usr.bin/less/forwback.c b/usr.bin/less/forwback.c index 023e93ec9..b71f03043 100644 --- a/usr.bin/less/forwback.c +++ b/usr.bin/less/forwback.c @@ -29,8 +29,6 @@ extern int plusoption; extern int forw_scroll; extern int back_scroll; extern int ignore_eoi; -extern int clear_bg; -extern int final_attr; extern int oldbot; extern char *tagoption; diff --git a/usr.bin/mandoc/roff_escape.c b/usr.bin/mandoc/roff_escape.c index ab4ea7343..4367876e7 100644 --- a/usr.bin/mandoc/roff_escape.c +++ b/usr.bin/mandoc/roff_escape.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roff_escape.c,v 1.14 2022/06/08 13:08:00 schwarze Exp $ */ +/* $OpenBSD: roff_escape.c,v 1.15 2024/05/16 21:21:08 schwarze Exp $ */ /* * Copyright (c) 2011, 2012, 2013, 2014, 2015, 2017, 2018, 2020, 2022 * Ingo Schwarze @@ -467,13 +467,12 @@ roff_escape(const char *buf, const int ln, const int aesc, /* * Unicode escapes are defined in groff as \[u0000] * to \[u10FFFF], where the contained value must be - * a valid Unicode codepoint. Here, however, only - * check the length and range. + * a valid Unicode codepoint. */ if (buf[iarg] != 'u' || argl < 5 || argl > 7) break; - if (argl == 7 && + if (argl == 7 && /* beyond the Unicode range */ (buf[iarg + 1] != '1' || buf[iarg + 2] != '0')) { err = MANDOCERR_ESC_BADCHAR; break; @@ -482,8 +481,9 @@ roff_escape(const char *buf, const int ln, const int aesc, err = MANDOCERR_ESC_BADCHAR; break; } - if (argl == 5 && buf[iarg + 1] == 'D' && - strchr("89ABCDEF", buf[iarg + 2]) != NULL) { + if (argl == 5 && /* UTF-16 surrogate */ + toupper((unsigned char)buf[iarg + 1]) == 'D' && + strchr("89ABCDEFabcdef", buf[iarg + 2]) != NULL) { err = MANDOCERR_ESC_BADCHAR; break; } diff --git a/usr.bin/netstat/netstat.h b/usr.bin/netstat/netstat.h index 34ed48b33..cccce137f 100644 --- a/usr.bin/netstat/netstat.h +++ b/usr.bin/netstat/netstat.h @@ -1,4 +1,4 @@ -/* $OpenBSD: netstat.h,v 1.77 2022/09/08 13:18:47 kn Exp $ */ +/* $OpenBSD: netstat.h,v 1.78 2024/05/18 07:10:16 jsg Exp $ */ /* $NetBSD: netstat.h,v 1.6 1996/05/07 02:55:05 thorpej Exp $ */ /* @@ -90,7 +90,6 @@ void ip_stats(char *); void div_stats(char *); void icmp_stats(char *); void igmp_stats(char *); -void pim_stats(char *); void ah_stats(char *); void ipsec_stats(char *); void esp_stats(char *); @@ -105,19 +104,14 @@ void net80211_ifstats(char *); void mbpr(void); -void hostpr(u_long, u_long); -void impstats(u_long, u_long); - void rt_stats(void); void pr_rthdr(int, int); -void pr_encaphdr(void); void pr_family(int); void rdomainpr(void); void ip6_stats(char *); void icmp6_stats(char *); -void pim6_stats(char *); void div6_stats(char *); void rip6_stats(char *); void mroute6pr(void); @@ -142,8 +136,6 @@ char *netname4(in_addr_t, in_addr_t); char *mpls_op(u_int32_t); void routepr(u_long, u_long, u_long, u_int); -void nsprotopr(u_long, char *); - #define IF_SHOW_FAIL 0 #define IF_SHOW_ERRS 1 #define IF_SHOW_DROP 2 diff --git a/usr.bin/openssl/apps.h b/usr.bin/openssl/apps.h index 8556dc14b..1c0a2ebea 100644 --- a/usr.bin/openssl/apps.h +++ b/usr.bin/openssl/apps.h @@ -1,4 +1,4 @@ -/* $OpenBSD: apps.h,v 1.34 2023/06/11 13:02:10 jsg Exp $ */ +/* $OpenBSD: apps.h,v 1.36 2024/05/18 08:48:31 jsg Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -127,7 +127,6 @@ #endif #include -extern int single_execution; extern CONF *config; extern char *default_config_file; @@ -151,7 +150,6 @@ int ui_write(UI *ui, UI_STRING *uis); int ui_close(UI *ui); int should_retry(int i); -int args_from_file(char *file, int *argc, char **argv[]); int str2fmt(char *s); void program_name(char *in, char *out, int size); #ifdef HEADER_X509_H diff --git a/usr.bin/openssl/progs.h b/usr.bin/openssl/progs.h index 8ccf8123f..2696f2014 100644 --- a/usr.bin/openssl/progs.h +++ b/usr.bin/openssl/progs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: progs.h,v 1.9 2019/11/04 15:25:54 jsing Exp $ */ +/* $OpenBSD: progs.h,v 1.10 2024/05/18 08:47:13 jsg Exp $ */ /* Public domain */ int asn1parse_main(int argc, char **argv); @@ -21,7 +21,6 @@ int gendh_main(int argc, char **argv); int gendsa_main(int argc, char **argv); int genpkey_main(int argc, char **argv); int genrsa_main(int argc, char **argv); -int nseq_main(int argc, char **argv); int ocsp_main(int argc, char **argv); int passwd_main(int argc, char **argv); int pkcs7_main(int argc, char **argv); diff --git a/usr.bin/openssl/s_apps.h b/usr.bin/openssl/s_apps.h index a73c2eb1b..d8217d9ee 100644 --- a/usr.bin/openssl/s_apps.h +++ b/usr.bin/openssl/s_apps.h @@ -1,4 +1,4 @@ -/* $OpenBSD: s_apps.h,v 1.7 2021/12/06 11:06:58 tb Exp $ */ +/* $OpenBSD: s_apps.h,v 1.8 2024/05/18 08:47:13 jsg Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -130,7 +130,6 @@ int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key); #endif int ssl_print_tmp_key(BIO *out, SSL *s); int init_client(int *sock, char *server, char *port, int type, int af); -int should_retry(int i); int extract_port(char *str, short *port_ptr); int extract_host_port(char *str, char **host_ptr, unsigned char *ip, char **p); diff --git a/usr.bin/ssh/Makefile b/usr.bin/ssh/Makefile index 7e3add906..09f8b0ac8 100644 --- a/usr.bin/ssh/Makefile +++ b/usr.bin/ssh/Makefile @@ -1,8 +1,9 @@ -# $OpenBSD: Makefile,v 1.17 2019/10/31 21:22:01 djm Exp $ +# $OpenBSD: Makefile,v 1.18 2024/05/17 00:30:23 djm Exp $ .include -SUBDIR= ssh sshd ssh-add ssh-keygen ssh-agent scp sftp-server \ +SUBDIR= ssh sshd sshd-session \ + ssh-add ssh-keygen ssh-agent scp sftp-server \ ssh-keysign ssh-keyscan sftp ssh-pkcs11-helper ssh-sk-helper distribution: diff --git a/usr.bin/ssh/Makefile.inc b/usr.bin/ssh/Makefile.inc index 84487e7c9..ae7814a28 100644 --- a/usr.bin/ssh/Makefile.inc +++ b/usr.bin/ssh/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.89 2024/01/11 01:45:36 djm Exp $ +# $OpenBSD: Makefile.inc,v 1.90 2024/05/17 00:30:23 djm Exp $ .include @@ -25,7 +25,7 @@ CDIAGFLAGS+= -Wstrict-aliasing=2 CDIAGFLAGS+= -Wold-style-definition .endif -#CDIAGFLAGS+= -Werror +CDIAGFLAGS+= -Werror #CDIAGFLAGS+= -fno-common #DEBUG=-g #INSTALL_STRIP= @@ -111,14 +111,17 @@ SRCS_KEYP+= atomicio.c SRCS_KRL+= bitmap.c SRCS_KRL+= krl.c +SRCS_MAC+= mac.c +SRCS_MAC+= hmac.c +SRCS_MAC+= umac.c +SRCS_MAC+= umac128.c + SRCS_PKT+= canohost.c SRCS_PKT+= dispatch.c -SRCS_PKT+= hmac.c SRCS_PKT+= kex.c -SRCS_PKT+= mac.c +SRCS_PKT+= kex-names.c SRCS_PKT+= packet.c -SRCS_PKT+= umac.c -SRCS_PKT+= umac128.c +SRCS_PKT+= ${SRCS_MAC} SRCS_PROT+= channels.c SRCS_PROT+= monitor_fdpass.c diff --git a/usr.bin/ssh/auth-rhosts.c b/usr.bin/ssh/auth-rhosts.c index 07f75532b..3717e933c 100644 --- a/usr.bin/ssh/auth-rhosts.c +++ b/usr.bin/ssh/auth-rhosts.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-rhosts.c,v 1.57 2022/12/09 00:17:40 dtucker Exp $ */ +/* $OpenBSD: auth-rhosts.c,v 1.58 2024/05/17 00:30:23 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -42,7 +42,6 @@ /* import */ extern ServerOptions options; -extern int use_privsep; /* * This function processes an rhosts-style file (.rhosts, .shosts, or diff --git a/usr.bin/ssh/auth.c b/usr.bin/ssh/auth.c index c58798d4a..3fec9d71b 100644 --- a/usr.bin/ssh/auth.c +++ b/usr.bin/ssh/auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.c,v 1.160 2023/03/05 05:34:09 dtucker Exp $ */ +/* $OpenBSD: auth.c,v 1.161 2024/05/17 00:30:23 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -67,7 +67,6 @@ /* import */ extern ServerOptions options; extern struct include_list includes; -extern int use_privsep; extern struct sshauthopt *auth_opts; /* Debugging messages */ @@ -246,7 +245,7 @@ auth_log(struct ssh *ssh, int authenticated, int partial, const char *authmsg; char *extra = NULL; - if (use_privsep && !mm_is_monitor() && !authctxt->postponed) + if (!mm_is_monitor() && !authctxt->postponed) return; /* Raise logging level */ @@ -420,14 +419,14 @@ getpwnamallow(struct ssh *ssh, const char *user) struct connection_info *ci; u_int i; - ci = get_connection_info(ssh, 1, options.use_dns); + ci = server_get_connection_info(ssh, 1, options.use_dns); ci->user = user; parse_server_match_config(&options, &includes, ci); log_change_level(options.log_level); log_verbose_reset(); for (i = 0; i < options.num_log_verbose; i++) log_verbose_add(options.log_verbose[i]); - process_permitopen(ssh, &options); + server_process_permitopen(ssh); pw = getpwnam(user); if (pw == NULL) { @@ -562,93 +561,6 @@ fakepw(void) return (&fake); } -/* - * Returns the remote DNS hostname as a string. The returned string must not - * be freed. NB. this will usually trigger a DNS query the first time it is - * called. - * This function does additional checks on the hostname to mitigate some - * attacks on based on conflation of hostnames and IP addresses. - */ - -static char * -remote_hostname(struct ssh *ssh) -{ - struct sockaddr_storage from; - socklen_t fromlen; - struct addrinfo hints, *ai, *aitop; - char name[NI_MAXHOST], ntop2[NI_MAXHOST]; - const char *ntop = ssh_remote_ipaddr(ssh); - - /* Get IP address of client. */ - fromlen = sizeof(from); - memset(&from, 0, sizeof(from)); - if (getpeername(ssh_packet_get_connection_in(ssh), - (struct sockaddr *)&from, &fromlen) == -1) { - debug("getpeername failed: %.100s", strerror(errno)); - return xstrdup(ntop); - } - - debug3("Trying to reverse map address %.100s.", ntop); - /* Map the IP address to a host name. */ - if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), - NULL, 0, NI_NAMEREQD) != 0) { - /* Host name not found. Use ip address. */ - return xstrdup(ntop); - } - - /* - * if reverse lookup result looks like a numeric hostname, - * someone is trying to trick us by PTR record like following: - * 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5 - */ - memset(&hints, 0, sizeof(hints)); - hints.ai_socktype = SOCK_DGRAM; /*dummy*/ - hints.ai_flags = AI_NUMERICHOST; - if (getaddrinfo(name, NULL, &hints, &ai) == 0) { - logit("Nasty PTR record \"%s\" is set up for %s, ignoring", - name, ntop); - freeaddrinfo(ai); - return xstrdup(ntop); - } - - /* Names are stored in lowercase. */ - lowercase(name); - - /* - * Map it back to an IP address and check that the given - * address actually is an address of this host. This is - * necessary because anyone with access to a name server can - * define arbitrary names for an IP address. Mapping from - * name to IP address can be trusted better (but can still be - * fooled if the intruder has access to the name server of - * the domain). - */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = from.ss_family; - hints.ai_socktype = SOCK_STREAM; - if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { - logit("reverse mapping checking getaddrinfo for %.700s " - "[%s] failed.", name, ntop); - return xstrdup(ntop); - } - /* Look for the address from the list of addresses. */ - for (ai = aitop; ai; ai = ai->ai_next) { - if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2, - sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 && - (strcmp(ntop, ntop2) == 0)) - break; - } - freeaddrinfo(aitop); - /* If we reached the end of the list, the address was not there. */ - if (ai == NULL) { - /* Address not found for the host name. */ - logit("Address %.100s maps to %.600s, but this does not " - "map back to the address.", ntop, name); - return xstrdup(ntop); - } - return xstrdup(name); -} - /* * Return the canonical name of the host in the other side of the current * connection. The host name is cached, so it is efficient to call this @@ -662,12 +574,10 @@ auth_get_canonical_hostname(struct ssh *ssh, int use_dns) if (!use_dns) return ssh_remote_ipaddr(ssh); - else if (dnsname != NULL) + if (dnsname != NULL) return dnsname; - else { - dnsname = remote_hostname(ssh); - return dnsname; - } + dnsname = ssh_remote_hostname(ssh); + return dnsname; } /* These functions link key/cert options to the auth framework */ diff --git a/usr.bin/ssh/auth.h b/usr.bin/ssh/auth.h index 54c35533c..078f43122 100644 --- a/usr.bin/ssh/auth.h +++ b/usr.bin/ssh/auth.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.h,v 1.106 2022/06/15 16:08:25 djm Exp $ */ +/* $OpenBSD: auth.h,v 1.108 2024/05/17 06:42:04 jsg Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -95,11 +95,15 @@ struct Authctxt { * the client. */ +struct authmethod_cfg { + const char *name; + const char *synonym; + int *enabled; +}; + struct Authmethod { - char *name; - char *synonym; + struct authmethod_cfg *cfg; int (*userauth)(struct ssh *, const char *); - int *enabled; }; /* @@ -142,8 +146,6 @@ void auth2_record_info(Authctxt *authctxt, const char *, ...) void auth2_update_session_info(Authctxt *, const char *, const char *); #ifdef KRB5 -int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *); -int auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt); int auth_krb5_password(Authctxt *authctxt, const char *password); void krb5_cleanup_proc(Authctxt *authctxt); #endif /* KRB5 */ @@ -192,7 +194,6 @@ int sshd_hostkey_sign(struct ssh *, struct sshkey *, struct sshkey *, u_char **, size_t *, const u_char *, size_t, const char *); /* Key / cert options linkage to auth layer */ -const struct sshauthopt *auth_options(struct ssh *); int auth_activate_options(struct ssh *, struct sshauthopt *); void auth_restrict_session(struct ssh *); void auth_log_authopts(const char *, const struct sshauthopt *, int); diff --git a/usr.bin/ssh/auth2-gss.c b/usr.bin/ssh/auth2-gss.c index 7bab9dd1f..16e2de871 100644 --- a/usr.bin/ssh/auth2-gss.c +++ b/usr.bin/ssh/auth2-gss.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-gss.c,v 1.34 2023/03/31 04:22:27 djm Exp $ */ +/* $OpenBSD: auth2-gss.c,v 1.36 2024/05/17 04:42:13 djm Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -46,6 +46,7 @@ #define SSH_GSSAPI_MAX_MECHS 2048 extern ServerOptions options; +extern struct authmethod_cfg methodcfg_gssapi; static int input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh); static int input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh); @@ -111,7 +112,7 @@ userauth_gssapi(struct ssh *ssh, const char *method) return (0); } - if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, &goid)))) { + if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&ctxt, &goid))) { if (ctxt != NULL) ssh_gssapi_delete_ctx(&ctxt); free(doid); @@ -148,7 +149,7 @@ input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh) size_t len; int r; - if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) + if (authctxt == NULL) fatal("No authentication or GSSAPI context"); gssctxt = authctxt->methoddata; @@ -158,8 +159,8 @@ input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh) recv_tok.value = p; recv_tok.length = len; - maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, - &send_tok, &flags)); + maj_status = mm_ssh_gssapi_accept_ctx(gssctxt, &recv_tok, + &send_tok, &flags); free(p); @@ -212,7 +213,7 @@ input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh) u_char *p; size_t len; - if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) + if (authctxt == NULL) fatal("No authentication or GSSAPI context"); gssctxt = authctxt->methoddata; @@ -223,8 +224,8 @@ input_gssapi_errtok(int type, u_int32_t plen, struct ssh *ssh) recv_tok.length = len; /* Push the error token into GSSAPI to see what it says */ - maj_status = PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, - &send_tok, NULL)); + maj_status = mm_ssh_gssapi_accept_ctx(gssctxt, &recv_tok, + &send_tok, NULL); free(recv_tok.value); @@ -249,9 +250,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; int r, authenticated; - const char *displayname; - if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) + if (authctxt == NULL) fatal("No authentication or GSSAPI context"); /* @@ -262,11 +262,7 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) if ((r = sshpkt_get_end(ssh)) != 0) fatal_fr(r, "parse packet"); - authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); - - if ((!use_privsep || mm_is_monitor()) && - (displayname = ssh_gssapi_displayname()) != NULL) - auth2_record_info(authctxt, "%s", displayname); + authenticated = mm_ssh_gssapi_userok(authctxt->user); authctxt->postponed = 0; ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); @@ -285,11 +281,10 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) int r, authenticated = 0; struct sshbuf *b; gss_buffer_desc mic, gssbuf; - const char *displayname; u_char *p; size_t len; - if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep)) + if (authctxt == NULL) fatal("No authentication or GSSAPI context"); gssctxt = authctxt->methoddata; @@ -307,18 +302,14 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) fatal_f("sshbuf_mutable_ptr failed"); gssbuf.length = sshbuf_len(b); - if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) - authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); + if (!GSS_ERROR(mm_ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))) + authenticated = mm_ssh_gssapi_userok(authctxt->user); else logit("GSSAPI MIC check failed"); sshbuf_free(b); free(mic.value); - if ((!use_privsep || mm_is_monitor()) && - (displayname = ssh_gssapi_displayname()) != NULL) - auth2_record_info(authctxt, "%s", displayname); - authctxt->postponed = 0; ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL); @@ -329,9 +320,7 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) } Authmethod method_gssapi = { - "gssapi-with-mic", - NULL, + &methodcfg_gssapi, userauth_gssapi, - &options.gss_authentication }; #endif diff --git a/usr.bin/ssh/auth2-hostbased.c b/usr.bin/ssh/auth2-hostbased.c index 644d7bea8..e22141752 100644 --- a/usr.bin/ssh/auth2-hostbased.c +++ b/usr.bin/ssh/auth2-hostbased.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-hostbased.c,v 1.52 2023/03/05 05:34:09 dtucker Exp $ */ +/* $OpenBSD: auth2-hostbased.c,v 1.53 2024/05/17 00:30:23 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -53,6 +53,7 @@ /* import */ extern ServerOptions options; +extern struct authmethod_cfg methodcfg_hostbased; static int userauth_hostbased(struct ssh *ssh, const char *method) @@ -144,10 +145,10 @@ userauth_hostbased(struct ssh *ssh, const char *method) /* test for allowed key and correct signature */ authenticated = 0; - if (PRIVSEP(hostbased_key_allowed(ssh, authctxt->pw, cuser, - chost, key)) && - PRIVSEP(sshkey_verify(key, sig, slen, - sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat, NULL)) == 0) + if (mm_hostbased_key_allowed(ssh, authctxt->pw, cuser, + chost, key) && + mm_sshkey_verify(key, sig, slen, + sshbuf_ptr(b), sshbuf_len(b), pkalg, ssh->compat, NULL) == 0) authenticated = 1; auth2_record_key(authctxt, authenticated, key); @@ -251,8 +252,6 @@ hostbased_key_allowed(struct ssh *ssh, struct passwd *pw, } Authmethod method_hostbased = { - "hostbased", - NULL, + &methodcfg_hostbased, userauth_hostbased, - &options.hostbased_authentication }; diff --git a/usr.bin/ssh/auth2-kbdint.c b/usr.bin/ssh/auth2-kbdint.c index 034b6eacf..cb1cef7d0 100644 --- a/usr.bin/ssh/auth2-kbdint.c +++ b/usr.bin/ssh/auth2-kbdint.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-kbdint.c,v 1.14 2021/12/19 22:12:07 djm Exp $ */ +/* $OpenBSD: auth2-kbdint.c,v 1.15 2024/05/17 00:30:23 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -40,6 +40,7 @@ /* import */ extern ServerOptions options; +extern struct authmethod_cfg methodcfg_kbdint; static int userauth_kbdint(struct ssh *ssh, const char *method) @@ -63,8 +64,6 @@ userauth_kbdint(struct ssh *ssh, const char *method) } Authmethod method_kbdint = { - "keyboard-interactive", - NULL, + &methodcfg_kbdint, userauth_kbdint, - &options.kbd_interactive_authentication }; diff --git a/usr.bin/ssh/auth2-methods.c b/usr.bin/ssh/auth2-methods.c new file mode 100644 index 000000000..15c69697d --- /dev/null +++ b/usr.bin/ssh/auth2-methods.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2012,2023 Damien Miller + * + * 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 "log.h" +#include "misc.h" +#include "servconf.h" +#include "xmalloc.h" +#include "hostfile.h" +#include "auth.h" + +extern ServerOptions options; + +/* + * Configuration of enabled authentication methods. Separate to the rest of + * auth2-*.c because we want to query it during server configuration validity + * checking in the sshd listener process without pulling all the auth code in + * too. + */ + +/* "none" is allowed only one time and it cleared by userauth_none() later */ +int none_enabled = 1; +struct authmethod_cfg methodcfg_none = { + "none", + NULL, + &none_enabled +}; +struct authmethod_cfg methodcfg_pubkey = { + "publickey", + "publickey-hostbound-v00@openssh.com", + &options.pubkey_authentication +}; +#ifdef GSSAPI +struct authmethod_cfg methodcfg_gssapi = { + "gssapi-with-mic", + NULL, + &options.gss_authentication +}; +#endif +struct authmethod_cfg methodcfg_passwd = { + "password", + NULL, + &options.password_authentication +}; +struct authmethod_cfg methodcfg_kbdint = { + "keyboard-interactive", + NULL, + &options.kbd_interactive_authentication +}; +struct authmethod_cfg methodcfg_hostbased = { + "hostbased", + NULL, + &options.hostbased_authentication +}; + +static struct authmethod_cfg *authmethod_cfgs[] = { + &methodcfg_none, + &methodcfg_pubkey, +#ifdef GSSAPI + &methodcfg_gssapi, +#endif + &methodcfg_passwd, + &methodcfg_kbdint, + &methodcfg_hostbased, + NULL +}; + +/* + * Check a comma-separated list of methods for validity. Is need_enable is + * non-zero, then also require that the methods are enabled. + * Returns 0 on success or -1 if the methods list is invalid. + */ +int +auth2_methods_valid(const char *_methods, int need_enable) +{ + char *methods, *omethods, *method, *p; + u_int i, found; + int ret = -1; + const struct authmethod_cfg *cfg; + + if (*_methods == '\0') { + error("empty authentication method list"); + return -1; + } + omethods = methods = xstrdup(_methods); + while ((method = strsep(&methods, ",")) != NULL) { + for (found = i = 0; !found && authmethod_cfgs[i] != NULL; i++) { + cfg = authmethod_cfgs[i]; + if ((p = strchr(method, ':')) != NULL) + *p = '\0'; + if (strcmp(method, cfg->name) != 0) + continue; + if (need_enable) { + if (cfg->enabled == NULL || + *(cfg->enabled) == 0) { + error("Disabled method \"%s\" in " + "AuthenticationMethods list \"%s\"", + method, _methods); + goto out; + } + } + found = 1; + break; + } + if (!found) { + error("Unknown authentication method \"%s\" in list", + method); + goto out; + } + } + ret = 0; + out: + free(omethods); + return ret; +} diff --git a/usr.bin/ssh/auth2-none.c b/usr.bin/ssh/auth2-none.c index d34f654e2..ae4e8a327 100644 --- a/usr.bin/ssh/auth2-none.c +++ b/usr.bin/ssh/auth2-none.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-none.c,v 1.25 2023/03/05 05:34:09 dtucker Exp $ */ +/* $OpenBSD: auth2-none.c,v 1.26 2024/05/17 00:30:23 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -44,9 +44,9 @@ /* import */ extern ServerOptions options; +extern struct authmethod_cfg methodcfg_none; -/* "none" is allowed only one time */ -static int none_enabled = 1; +extern int none_enabled; static int userauth_none(struct ssh *ssh, const char *method) @@ -57,13 +57,11 @@ userauth_none(struct ssh *ssh, const char *method) if ((r = sshpkt_get_end(ssh)) != 0) fatal_fr(r, "parse packet"); if (options.permit_empty_passwd && options.password_authentication) - return (PRIVSEP(auth_password(ssh, ""))); + return mm_auth_password(ssh, ""); return (0); } Authmethod method_none = { - "none", - NULL, + &methodcfg_none, userauth_none, - &none_enabled }; diff --git a/usr.bin/ssh/auth2-passwd.c b/usr.bin/ssh/auth2-passwd.c index b9feb7168..dffbb4a22 100644 --- a/usr.bin/ssh/auth2-passwd.c +++ b/usr.bin/ssh/auth2-passwd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-passwd.c,v 1.21 2022/05/27 04:29:40 dtucker Exp $ */ +/* $OpenBSD: auth2-passwd.c,v 1.22 2024/05/17 00:30:23 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -45,6 +45,7 @@ /* import */ extern ServerOptions options; +extern struct authmethod_cfg methodcfg_passwd; static int userauth_passwd(struct ssh *ssh, const char *method) @@ -64,15 +65,13 @@ userauth_passwd(struct ssh *ssh, const char *method) if (change) logit("password change not supported"); - else if (PRIVSEP(auth_password(ssh, password)) == 1) + else if (mm_auth_password(ssh, password) == 1) authenticated = 1; freezero(password, len); return authenticated; } Authmethod method_passwd = { - "password", - NULL, + &methodcfg_passwd, userauth_passwd, - &options.password_authentication }; diff --git a/usr.bin/ssh/auth2-pubkey.c b/usr.bin/ssh/auth2-pubkey.c index 1e536b1c6..d459e1041 100644 --- a/usr.bin/ssh/auth2-pubkey.c +++ b/usr.bin/ssh/auth2-pubkey.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-pubkey.c,v 1.119 2023/07/27 22:25:17 djm Exp $ */ +/* $OpenBSD: auth2-pubkey.c,v 1.120 2024/05/17 00:30:23 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -69,6 +69,7 @@ /* import */ extern ServerOptions options; +extern struct authmethod_cfg methodcfg_pubkey; static char * format_key(const struct sshkey *key) @@ -216,11 +217,11 @@ userauth_pubkey(struct ssh *ssh, const char *method) #endif /* test for correct signature */ authenticated = 0; - if (PRIVSEP(user_key_allowed(ssh, pw, key, 1, &authopts)) && - PRIVSEP(sshkey_verify(key, sig, slen, + if (mm_user_key_allowed(ssh, pw, key, 1, &authopts) && + mm_sshkey_verify(key, sig, slen, sshbuf_ptr(b), sshbuf_len(b), (ssh->compat & SSH_BUG_SIGTYPE) == 0 ? pkalg : NULL, - ssh->compat, &sig_details)) == 0) { + ssh->compat, &sig_details) == 0) { authenticated = 1; } if (authenticated == 1 && sig_details != NULL) { @@ -278,7 +279,7 @@ userauth_pubkey(struct ssh *ssh, const char *method) * if a user is not allowed to login. is this an * issue? -markus */ - if (PRIVSEP(user_key_allowed(ssh, pw, key, 0, NULL))) { + if (mm_user_key_allowed(ssh, pw, key, 0, NULL)) { if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_PK_OK)) != 0 || (r = sshpkt_put_cstring(ssh, pkalg)) != 0 || @@ -810,8 +811,6 @@ user_key_allowed(struct ssh *ssh, struct passwd *pw, struct sshkey *key, } Authmethod method_pubkey = { - "publickey", - "publickey-hostbound-v00@openssh.com", + &methodcfg_pubkey, userauth_pubkey, - &options.pubkey_authentication }; diff --git a/usr.bin/ssh/auth2.c b/usr.bin/ssh/auth2.c index 40bd28a47..86ee78742 100644 --- a/usr.bin/ssh/auth2.c +++ b/usr.bin/ssh/auth2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2.c,v 1.168 2023/12/18 14:45:49 djm Exp $ */ +/* $OpenBSD: auth2.c,v 1.169 2024/05/17 00:30:23 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -141,7 +141,7 @@ userauth_banner(struct ssh *ssh) if (options.banner == NULL) return; - if ((banner = PRIVSEP(auth2_read_banner())) == NULL) + if ((banner = mm_auth2_read_banner()) == NULL) goto done; if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_BANNER)) != 0 || @@ -281,7 +281,7 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) auth_maxtries_exceeded(ssh); if (authctxt->attempt++ == 0) { /* setup auth context */ - authctxt->pw = PRIVSEP(getpwnamallow(ssh, user)); + authctxt->pw = mm_getpwnamallow(ssh, user); if (authctxt->pw && strcmp(service, "ssh-connection")==0) { authctxt->valid = 1; debug2_f("setting up authctxt for %s", user); @@ -292,13 +292,11 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) } ssh_packet_set_log_preamble(ssh, "%suser %s", authctxt->valid ? "authenticating " : "invalid ", user); - setproctitle("%s%s", authctxt->valid ? user : "unknown", - use_privsep ? " [net]" : ""); + setproctitle("%s [net]", authctxt->valid ? user : "unknown"); authctxt->user = xstrdup(user); authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; - if (use_privsep) - mm_inform_authserv(service, style); + mm_inform_authserv(service, style); userauth_banner(ssh); if ((r = kex_server_update_ext_info(ssh)) != 0) fatal_fr(r, "kex_server_update_ext_info failed"); @@ -362,7 +360,7 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *packet_method, /* prefer primary authmethod name to possible synonym */ if ((m = authmethod_byname(method)) == NULL) fatal("INTERNAL ERROR: bad method %s", method); - method = m->name; + method = m->cfg->name; } /* Special handling for root */ @@ -453,16 +451,16 @@ authmethods_get(Authctxt *authctxt) if ((b = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); for (i = 0; authmethods[i] != NULL; i++) { - if (strcmp(authmethods[i]->name, "none") == 0) + if (strcmp(authmethods[i]->cfg->name, "none") == 0) continue; - if (authmethods[i]->enabled == NULL || - *(authmethods[i]->enabled) == 0) + if (authmethods[i]->cfg->enabled == NULL || + *(authmethods[i]->cfg->enabled) == 0) continue; - if (!auth2_method_allowed(authctxt, authmethods[i]->name, + if (!auth2_method_allowed(authctxt, authmethods[i]->cfg->name, NULL)) continue; if ((r = sshbuf_putf(b, "%s%s", sshbuf_len(b) ? "," : "", - authmethods[i]->name)) != 0) + authmethods[i]->cfg->name)) != 0) fatal_fr(r, "buffer error"); } if ((list = sshbuf_dup_string(b)) == NULL) @@ -479,9 +477,9 @@ authmethod_byname(const char *name) if (name == NULL) fatal_f("NULL authentication method name"); for (i = 0; authmethods[i] != NULL; i++) { - if (strcmp(name, authmethods[i]->name) == 0 || - (authmethods[i]->synonym != NULL && - strcmp(name, authmethods[i]->synonym) == 0)) + if (strcmp(name, authmethods[i]->cfg->name) == 0 || + (authmethods[i]->cfg->synonym != NULL && + strcmp(name, authmethods[i]->cfg->synonym) == 0)) return authmethods[i]; } debug_f("unrecognized authentication method name: %s", name); @@ -496,11 +494,11 @@ authmethod_lookup(Authctxt *authctxt, const char *name) if ((method = authmethod_byname(name)) == NULL) return NULL; - if (method->enabled == NULL || *(method->enabled) == 0) { + if (method->cfg->enabled == NULL || *(method->cfg->enabled) == 0) { debug3_f("method %s not enabled", name); return NULL; } - if (!auth2_method_allowed(authctxt, method->name, NULL)) { + if (!auth2_method_allowed(authctxt, method->cfg->name, NULL)) { debug3_f("method %s not allowed " "by AuthenticationMethods", name); return NULL; @@ -508,53 +506,6 @@ authmethod_lookup(Authctxt *authctxt, const char *name) return method; } -/* - * Check a comma-separated list of methods for validity. Is need_enable is - * non-zero, then also require that the methods are enabled. - * Returns 0 on success or -1 if the methods list is invalid. - */ -int -auth2_methods_valid(const char *_methods, int need_enable) -{ - char *methods, *omethods, *method, *p; - u_int i, found; - int ret = -1; - - if (*_methods == '\0') { - error("empty authentication method list"); - return -1; - } - omethods = methods = xstrdup(_methods); - while ((method = strsep(&methods, ",")) != NULL) { - for (found = i = 0; !found && authmethods[i] != NULL; i++) { - if ((p = strchr(method, ':')) != NULL) - *p = '\0'; - if (strcmp(method, authmethods[i]->name) != 0) - continue; - if (need_enable) { - if (authmethods[i]->enabled == NULL || - *(authmethods[i]->enabled) == 0) { - error("Disabled method \"%s\" in " - "AuthenticationMethods list \"%s\"", - method, _methods); - goto out; - } - } - found = 1; - break; - } - if (!found) { - error("Unknown authentication method \"%s\" in list", - method); - goto out; - } - } - ret = 0; - out: - free(omethods); - return ret; -} - /* * Prune the AuthenticationMethods supplied in the configuration, removing * any methods lists that include disabled methods. Note that this might diff --git a/usr.bin/ssh/channels.c b/usr.bin/ssh/channels.c index d07232df2..281cecf24 100644 --- a/usr.bin/ssh/channels.c +++ b/usr.bin/ssh/channels.c @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.437 2024/03/06 02:59:59 djm Exp $ */ +/* $OpenBSD: channels.c,v 1.438 2024/05/17 00:30:23 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -85,13 +85,6 @@ /* -- agent forwarding */ #define NUM_SOCKS 10 -/* -- tcp forwarding */ -/* special-case port number meaning allow any port */ -#define FWD_PERMIT_ANY_PORT 0 - -/* special-case wildcard meaning allow any host */ -#define FWD_PERMIT_ANY_HOST "*" - /* -- X11 forwarding */ /* Maximum number of fake X11 displays to try. */ #define MAX_DISPLAYS 1000 @@ -4530,19 +4523,6 @@ channel_update_permission(struct ssh *ssh, int idx, int newport) } } -/* returns port number, FWD_PERMIT_ANY_PORT or -1 on error */ -int -permitopen_port(const char *p) -{ - int port; - - if (strcmp(p, "*") == 0) - return FWD_PERMIT_ANY_PORT; - if ((port = a2port(p)) > 0) - return port; - return -1; -} - /* Try to start non-blocking connect to next host in cctx list */ static int connect_next(struct channel_connect *cctx) diff --git a/usr.bin/ssh/channels.h b/usr.bin/ssh/channels.h index e0893ef86..35e1eb61f 100644 --- a/usr.bin/ssh/channels.h +++ b/usr.bin/ssh/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.154 2023/12/18 14:47:20 djm Exp $ */ +/* $OpenBSD: channels.h,v 1.155 2024/05/17 06:42:04 jsg Exp $ */ /* * Author: Tatu Ylonen @@ -322,7 +322,6 @@ int channel_input_ieof(int, u_int32_t, struct ssh *); int channel_input_oclose(int, u_int32_t, struct ssh *); int channel_input_open_confirmation(int, u_int32_t, struct ssh *); int channel_input_open_failure(int, u_int32_t, struct ssh *); -int channel_input_port_open(int, u_int32_t, struct ssh *); int channel_input_window_adjust(int, u_int32_t, struct ssh *); int channel_input_status_confirm(int, u_int32_t, struct ssh *); diff --git a/usr.bin/ssh/cipher.c b/usr.bin/ssh/cipher.c index 28a7f7bd9..33f559ae7 100644 --- a/usr.bin/ssh/cipher.c +++ b/usr.bin/ssh/cipher.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher.c,v 1.120 2023/10/10 06:49:54 tb Exp $ */ +/* $OpenBSD: cipher.c,v 1.121 2024/05/17 02:39:11 jsg Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -366,7 +366,7 @@ cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest, if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, 1, lastiv)) return SSH_ERR_LIBCRYPTO_ERROR; - /* set tag on decyption */ + /* set tag on decryption */ if (!cc->encrypt && !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_TAG, authlen, (u_char *)src + aadlen + len)) diff --git a/usr.bin/ssh/clientloop.c b/usr.bin/ssh/clientloop.c index b7d4c11f4..2129c151f 100644 --- a/usr.bin/ssh/clientloop.c +++ b/usr.bin/ssh/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.406 2024/05/09 09:46:47 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.407 2024/05/17 06:42:04 jsg Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -184,7 +184,6 @@ TAILQ_HEAD(global_confirms, global_confirm); static struct global_confirms global_confirms = TAILQ_HEAD_INITIALIZER(global_confirms); -void ssh_process_session2_setup(int, int, int, struct sshbuf *); static void quit_message(const char *fmt, ...) __attribute__((__format__ (printf, 1, 2))); diff --git a/usr.bin/ssh/clientloop.h b/usr.bin/ssh/clientloop.h index 31630551b..4bc7bcd7c 100644 --- a/usr.bin/ssh/clientloop.h +++ b/usr.bin/ssh/clientloop.h @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.h,v 1.37 2020/04/03 02:40:32 djm Exp $ */ +/* $OpenBSD: clientloop.h,v 1.38 2024/05/17 06:42:04 jsg Exp $ */ /* * Author: Tatu Ylonen @@ -43,7 +43,6 @@ struct ssh; int client_loop(struct ssh *, int, int, int); int client_x11_get_proto(struct ssh *, const char *, const char *, u_int, u_int, char **, char **); -void client_global_request_reply_fwd(int, u_int32_t, void *); void client_session2_setup(struct ssh *, int, int, int, const char *, struct termios *, int, struct sshbuf *, char **); char *client_request_tun_fwd(struct ssh *, int, int, int, diff --git a/usr.bin/ssh/ed25519.sh b/usr.bin/ssh/ed25519.sh index 8722338db..9e6cbc9c3 100644 --- a/usr.bin/ssh/ed25519.sh +++ b/usr.bin/ssh/ed25519.sh @@ -1,5 +1,5 @@ #!/bin/sh -# $OpenBSD: ed25519.sh,v 1.1 2023/01/15 23:05:32 djm Exp $ +# $OpenBSD: ed25519.sh,v 1.2 2024/05/17 02:39:11 jsg Exp $ # Placed in the Public Domain. # AUTHOR="supercop-20221122/crypto_sign/ed25519/ref/implementors" @@ -74,7 +74,7 @@ for i in $FILES; do sed -e "s/crypto_sign_open/crypto_sign_ed25519_open/g" ;; */crypto_sign/ed25519/ref/fe25519.*) - # avoid a couple of name collions with other files + # avoid a couple of name collisions with other files sed -e "s/reduce_add_sub/fe25519_reduce_add_sub/g" \ -e "s/ equal[(]/ fe25519_equal(/g" \ -e "s/^int /static int /g" diff --git a/usr.bin/ssh/kex-names.c b/usr.bin/ssh/kex-names.c new file mode 100644 index 000000000..7eebc7a56 --- /dev/null +++ b/usr.bin/ssh/kex-names.c @@ -0,0 +1,319 @@ +/* $OpenBSD: kex-names.c,v 1.1 2024/05/17 00:32:32 djm Exp $ */ +/* + * Copyright (c) 2000, 2001 Markus Friedl. 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 ``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. + */ + + +#include +#include +#include +#include +#include + +#ifdef WITH_OPENSSL +#include +#include +#endif + +#include "kex.h" +#include "log.h" +#include "match.h" +#include "digest.h" +#include "misc.h" + +#include "ssherr.h" +#include "xmalloc.h" + +struct kexalg { + char *name; + u_int type; + int ec_nid; + int hash_alg; +}; +static const struct kexalg kexalgs[] = { +#ifdef WITH_OPENSSL + { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, + { KEX_DH14_SHA1, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, + { KEX_DH14_SHA256, KEX_DH_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, + { KEX_DH16_SHA512, KEX_DH_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, + { KEX_DH18_SHA512, KEX_DH_GRP18_SHA512, 0, SSH_DIGEST_SHA512 }, + { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, + { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 }, + { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2, + NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, + { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1, + SSH_DIGEST_SHA384 }, + { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1, + SSH_DIGEST_SHA512 }, +#endif + { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, + { KEX_CURVE25519_SHA256_OLD, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, + { KEX_SNTRUP761X25519_SHA512, KEX_KEM_SNTRUP761X25519_SHA512, 0, + SSH_DIGEST_SHA512 }, + { NULL, 0, -1, -1}, +}; + +char * +kex_alg_list(char sep) +{ + char *ret = NULL, *tmp; + size_t nlen, rlen = 0; + const struct kexalg *k; + + for (k = kexalgs; k->name != NULL; k++) { + if (ret != NULL) + ret[rlen++] = sep; + nlen = strlen(k->name); + if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { + free(ret); + return NULL; + } + ret = tmp; + memcpy(ret + rlen, k->name, nlen + 1); + rlen += nlen; + } + return ret; +} + +static const struct kexalg * +kex_alg_by_name(const char *name) +{ + const struct kexalg *k; + + for (k = kexalgs; k->name != NULL; k++) { + if (strcmp(k->name, name) == 0) + return k; + } + return NULL; +} + +int +kex_name_valid(const char *name) +{ + return kex_alg_by_name(name) != NULL; +} + +u_int +kex_type_from_name(const char *name) +{ + const struct kexalg *k; + + if ((k = kex_alg_by_name(name)) == NULL) + return 0; + return k->type; +} + +int +kex_hash_from_name(const char *name) +{ + const struct kexalg *k; + + if ((k = kex_alg_by_name(name)) == NULL) + return -1; + return k->hash_alg; +} + +int +kex_nid_from_name(const char *name) +{ + const struct kexalg *k; + + if ((k = kex_alg_by_name(name)) == NULL) + return -1; + return k->ec_nid; +} + +/* Validate KEX method name list */ +int +kex_names_valid(const char *names) +{ + char *s, *cp, *p; + + if (names == NULL || strcmp(names, "") == 0) + return 0; + if ((s = cp = strdup(names)) == NULL) + return 0; + for ((p = strsep(&cp, ",")); p && *p != '\0'; + (p = strsep(&cp, ","))) { + if (kex_alg_by_name(p) == NULL) { + error("Unsupported KEX algorithm \"%.100s\"", p); + free(s); + return 0; + } + } + debug3("kex names ok: [%s]", names); + free(s); + return 1; +} + +/* returns non-zero if proposal contains any algorithm from algs */ +int +kex_has_any_alg(const char *proposal, const char *algs) +{ + char *cp; + + if ((cp = match_list(proposal, algs, NULL)) == NULL) + return 0; + free(cp); + return 1; +} + +/* + * Concatenate algorithm names, avoiding duplicates in the process. + * Caller must free returned string. + */ +char * +kex_names_cat(const char *a, const char *b) +{ + char *ret = NULL, *tmp = NULL, *cp, *p; + size_t len; + + if (a == NULL || *a == '\0') + return strdup(b); + if (b == NULL || *b == '\0') + return strdup(a); + if (strlen(b) > 1024*1024) + return NULL; + len = strlen(a) + strlen(b) + 2; + if ((tmp = cp = strdup(b)) == NULL || + (ret = calloc(1, len)) == NULL) { + free(tmp); + return NULL; + } + strlcpy(ret, a, len); + for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { + if (kex_has_any_alg(ret, p)) + continue; /* Algorithm already present */ + if (strlcat(ret, ",", len) >= len || + strlcat(ret, p, len) >= len) { + free(tmp); + free(ret); + return NULL; /* Shouldn't happen */ + } + } + free(tmp); + return ret; +} + +/* + * Assemble a list of algorithms from a default list and a string from a + * configuration file. The user-provided string may begin with '+' to + * indicate that it should be appended to the default, '-' that the + * specified names should be removed, or '^' that they should be placed + * at the head. + */ +int +kex_assemble_names(char **listp, const char *def, const char *all) +{ + char *cp, *tmp, *patterns; + char *list = NULL, *ret = NULL, *matching = NULL, *opatterns = NULL; + int r = SSH_ERR_INTERNAL_ERROR; + + if (listp == NULL || def == NULL || all == NULL) + return SSH_ERR_INVALID_ARGUMENT; + + if (*listp == NULL || **listp == '\0') { + if ((*listp = strdup(def)) == NULL) + return SSH_ERR_ALLOC_FAIL; + return 0; + } + + list = *listp; + *listp = NULL; + if (*list == '+') { + /* Append names to default list */ + if ((tmp = kex_names_cat(def, list + 1)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto fail; + } + free(list); + list = tmp; + } else if (*list == '-') { + /* Remove names from default list */ + if ((*listp = match_filter_denylist(def, list + 1)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto fail; + } + free(list); + /* filtering has already been done */ + return 0; + } else if (*list == '^') { + /* Place names at head of default list */ + if ((tmp = kex_names_cat(list + 1, def)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto fail; + } + free(list); + list = tmp; + } else { + /* Explicit list, overrides default - just use "list" as is */ + } + + /* + * The supplied names may be a pattern-list. For the -list case, + * the patterns are applied above. For the +list and explicit list + * cases we need to do it now. + */ + ret = NULL; + if ((patterns = opatterns = strdup(list)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto fail; + } + /* Apply positive (i.e. non-negated) patterns from the list */ + while ((cp = strsep(&patterns, ",")) != NULL) { + if (*cp == '!') { + /* negated matches are not supported here */ + r = SSH_ERR_INVALID_ARGUMENT; + goto fail; + } + free(matching); + if ((matching = match_filter_allowlist(all, cp)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto fail; + } + if ((tmp = kex_names_cat(ret, matching)) == NULL) { + r = SSH_ERR_ALLOC_FAIL; + goto fail; + } + free(ret); + ret = tmp; + } + if (ret == NULL || *ret == '\0') { + /* An empty name-list is an error */ + /* XXX better error code? */ + r = SSH_ERR_INVALID_ARGUMENT; + goto fail; + } + + /* success */ + *listp = ret; + ret = NULL; + r = 0; + + fail: + free(matching); + free(opatterns); + free(list); + free(ret); + return r; +} diff --git a/usr.bin/ssh/kex.c b/usr.bin/ssh/kex.c index 1e9ad51d8..a99d050bb 100644 --- a/usr.bin/ssh/kex.c +++ b/usr.bin/ssh/kex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.c,v 1.185 2024/01/08 00:34:33 djm Exp $ */ +/* $OpenBSD: kex.c,v 1.186 2024/05/17 00:30:23 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * @@ -76,244 +76,6 @@ static const char * const proposal_names[PROPOSAL_MAX] = { "languages stoc", }; -struct kexalg { - char *name; - u_int type; - int ec_nid; - int hash_alg; -}; -static const struct kexalg kexalgs[] = { -#ifdef WITH_OPENSSL - { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 }, - { KEX_DH14_SHA1, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 }, - { KEX_DH14_SHA256, KEX_DH_GRP14_SHA256, 0, SSH_DIGEST_SHA256 }, - { KEX_DH16_SHA512, KEX_DH_GRP16_SHA512, 0, SSH_DIGEST_SHA512 }, - { KEX_DH18_SHA512, KEX_DH_GRP18_SHA512, 0, SSH_DIGEST_SHA512 }, - { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 }, - { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 }, - { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2, - NID_X9_62_prime256v1, SSH_DIGEST_SHA256 }, - { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1, - SSH_DIGEST_SHA384 }, - { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1, - SSH_DIGEST_SHA512 }, -#endif - { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, - { KEX_CURVE25519_SHA256_OLD, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 }, - { KEX_SNTRUP761X25519_SHA512, KEX_KEM_SNTRUP761X25519_SHA512, 0, - SSH_DIGEST_SHA512 }, - { NULL, 0, -1, -1}, -}; - -char * -kex_alg_list(char sep) -{ - char *ret = NULL, *tmp; - size_t nlen, rlen = 0; - const struct kexalg *k; - - for (k = kexalgs; k->name != NULL; k++) { - if (ret != NULL) - ret[rlen++] = sep; - nlen = strlen(k->name); - if ((tmp = realloc(ret, rlen + nlen + 2)) == NULL) { - free(ret); - return NULL; - } - ret = tmp; - memcpy(ret + rlen, k->name, nlen + 1); - rlen += nlen; - } - return ret; -} - -static const struct kexalg * -kex_alg_by_name(const char *name) -{ - const struct kexalg *k; - - for (k = kexalgs; k->name != NULL; k++) { - if (strcmp(k->name, name) == 0) - return k; - } - return NULL; -} - -/* Validate KEX method name list */ -int -kex_names_valid(const char *names) -{ - char *s, *cp, *p; - - if (names == NULL || strcmp(names, "") == 0) - return 0; - if ((s = cp = strdup(names)) == NULL) - return 0; - for ((p = strsep(&cp, ",")); p && *p != '\0'; - (p = strsep(&cp, ","))) { - if (kex_alg_by_name(p) == NULL) { - error("Unsupported KEX algorithm \"%.100s\"", p); - free(s); - return 0; - } - } - debug3("kex names ok: [%s]", names); - free(s); - return 1; -} - -/* returns non-zero if proposal contains any algorithm from algs */ -static int -has_any_alg(const char *proposal, const char *algs) -{ - char *cp; - - if ((cp = match_list(proposal, algs, NULL)) == NULL) - return 0; - free(cp); - return 1; -} - -/* - * Concatenate algorithm names, avoiding duplicates in the process. - * Caller must free returned string. - */ -char * -kex_names_cat(const char *a, const char *b) -{ - char *ret = NULL, *tmp = NULL, *cp, *p; - size_t len; - - if (a == NULL || *a == '\0') - return strdup(b); - if (b == NULL || *b == '\0') - return strdup(a); - if (strlen(b) > 1024*1024) - return NULL; - len = strlen(a) + strlen(b) + 2; - if ((tmp = cp = strdup(b)) == NULL || - (ret = calloc(1, len)) == NULL) { - free(tmp); - return NULL; - } - strlcpy(ret, a, len); - for ((p = strsep(&cp, ",")); p && *p != '\0'; (p = strsep(&cp, ","))) { - if (has_any_alg(ret, p)) - continue; /* Algorithm already present */ - if (strlcat(ret, ",", len) >= len || - strlcat(ret, p, len) >= len) { - free(tmp); - free(ret); - return NULL; /* Shouldn't happen */ - } - } - free(tmp); - return ret; -} - -/* - * Assemble a list of algorithms from a default list and a string from a - * configuration file. The user-provided string may begin with '+' to - * indicate that it should be appended to the default, '-' that the - * specified names should be removed, or '^' that they should be placed - * at the head. - */ -int -kex_assemble_names(char **listp, const char *def, const char *all) -{ - char *cp, *tmp, *patterns; - char *list = NULL, *ret = NULL, *matching = NULL, *opatterns = NULL; - int r = SSH_ERR_INTERNAL_ERROR; - - if (listp == NULL || def == NULL || all == NULL) - return SSH_ERR_INVALID_ARGUMENT; - - if (*listp == NULL || **listp == '\0') { - if ((*listp = strdup(def)) == NULL) - return SSH_ERR_ALLOC_FAIL; - return 0; - } - - list = *listp; - *listp = NULL; - if (*list == '+') { - /* Append names to default list */ - if ((tmp = kex_names_cat(def, list + 1)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto fail; - } - free(list); - list = tmp; - } else if (*list == '-') { - /* Remove names from default list */ - if ((*listp = match_filter_denylist(def, list + 1)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto fail; - } - free(list); - /* filtering has already been done */ - return 0; - } else if (*list == '^') { - /* Place names at head of default list */ - if ((tmp = kex_names_cat(list + 1, def)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto fail; - } - free(list); - list = tmp; - } else { - /* Explicit list, overrides default - just use "list" as is */ - } - - /* - * The supplied names may be a pattern-list. For the -list case, - * the patterns are applied above. For the +list and explicit list - * cases we need to do it now. - */ - ret = NULL; - if ((patterns = opatterns = strdup(list)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto fail; - } - /* Apply positive (i.e. non-negated) patterns from the list */ - while ((cp = strsep(&patterns, ",")) != NULL) { - if (*cp == '!') { - /* negated matches are not supported here */ - r = SSH_ERR_INVALID_ARGUMENT; - goto fail; - } - free(matching); - if ((matching = match_filter_allowlist(all, cp)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto fail; - } - if ((tmp = kex_names_cat(ret, matching)) == NULL) { - r = SSH_ERR_ALLOC_FAIL; - goto fail; - } - free(ret); - ret = tmp; - } - if (ret == NULL || *ret == '\0') { - /* An empty name-list is an error */ - /* XXX better error code? */ - r = SSH_ERR_INVALID_ARGUMENT; - goto fail; - } - - /* success */ - *listp = ret; - ret = NULL; - r = 0; - - fail: - free(matching); - free(opatterns); - free(list); - free(ret); - return r; -} - /* * Fill out a proposal array with dynamically allocated values, which may * be modified as required for compatibility reasons. @@ -512,11 +274,11 @@ kex_set_server_sig_algs(struct ssh *ssh, const char *allowed_algs) (alg = strsep(&algs, ","))) { if ((sigalg = sshkey_sigalg_by_name(alg)) == NULL) continue; - if (!has_any_alg(sigalg, sigalgs)) + if (!kex_has_any_alg(sigalg, sigalgs)) continue; /* Don't add an algorithm twice. */ if (ssh->kex->server_sig_algs != NULL && - has_any_alg(sigalg, ssh->kex->server_sig_algs)) + kex_has_any_alg(sigalg, ssh->kex->server_sig_algs)) continue; xextendf(&ssh->kex->server_sig_algs, ",", "%s", sigalg); } @@ -1091,20 +853,18 @@ choose_comp(struct sshcomp *comp, char *client, char *server) static int choose_kex(struct kex *k, char *client, char *server) { - const struct kexalg *kexalg; - k->name = match_list(client, server, NULL); debug("kex: algorithm: %s", k->name ? k->name : "(no match)"); if (k->name == NULL) return SSH_ERR_NO_KEX_ALG_MATCH; - if ((kexalg = kex_alg_by_name(k->name)) == NULL) { + if (!kex_name_valid(k->name)) { error_f("unsupported KEX method %s", k->name); return SSH_ERR_INTERNAL_ERROR; } - k->kex_type = kexalg->type; - k->hash_alg = kexalg->hash_alg; - k->ec_nid = kexalg->ec_nid; + k->kex_type = kex_type_from_name(k->name); + k->hash_alg = kex_hash_from_name(k->name); + k->ec_nid = kex_nid_from_name(k->name); return 0; } @@ -1154,7 +914,7 @@ proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX]) static int kexalgs_contains(char **peer, const char *ext) { - return has_any_alg(peer[PROPOSAL_KEX_ALGS], ext); + return kex_has_any_alg(peer[PROPOSAL_KEX_ALGS], ext); } static int @@ -1205,10 +965,10 @@ kex_choose_conf(struct ssh *ssh, uint32_t seq) /* Check whether client supports rsa-sha2 algorithms */ if (kex->server && (kex->flags & KEX_INITIAL)) { - if (has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS], + if (kex_has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS], "rsa-sha2-256,rsa-sha2-256-cert-v01@openssh.com")) kex->flags |= KEX_RSA_SHA2_256_SUPPORTED; - if (has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS], + if (kex_has_any_alg(peer[PROPOSAL_SERVER_HOST_KEY_ALGS], "rsa-sha2-512,rsa-sha2-512-cert-v01@openssh.com")) kex->flags |= KEX_RSA_SHA2_512_SUPPORTED; } diff --git a/usr.bin/ssh/kex.h b/usr.bin/ssh/kex.h index 59aebf3f1..ca8d5aa47 100644 --- a/usr.bin/ssh/kex.h +++ b/usr.bin/ssh/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.122 2024/02/02 00:13:34 djm Exp $ */ +/* $OpenBSD: kex.h,v 1.123 2024/05/17 00:30:23 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -85,7 +85,7 @@ enum kex_modes { }; enum kex_exchange { - KEX_DH_GRP1_SHA1, + KEX_DH_GRP1_SHA1 = 1, KEX_DH_GRP14_SHA1, KEX_DH_GRP14_SHA256, KEX_DH_GRP16_SHA512, @@ -176,9 +176,14 @@ struct kex { struct sshbuf *client_pub; }; +int kex_name_valid(const char *); +u_int kex_type_from_name(const char *); +int kex_hash_from_name(const char *); +int kex_nid_from_name(const char *); int kex_names_valid(const char *); char *kex_alg_list(char); char *kex_names_cat(const char *, const char *); +int kex_has_any_alg(const char *, const char *); int kex_assemble_names(char **, const char *, const char *); void kex_proposal_populate_entries(struct ssh *, char *prop[PROPOSAL_MAX], const char *, const char *, const char *, const char *, const char *); diff --git a/usr.bin/ssh/kexgexs.c b/usr.bin/ssh/kexgexs.c index ea83bb272..1f7e2641c 100644 --- a/usr.bin/ssh/kexgexs.c +++ b/usr.bin/ssh/kexgexs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgexs.c,v 1.46 2023/03/29 01:07:48 dtucker Exp $ */ +/* $OpenBSD: kexgexs.c,v 1.47 2024/05/17 00:30:23 djm Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -91,7 +91,7 @@ input_kex_dh_gex_request(int type, u_int32_t seq, struct ssh *ssh) } /* Contact privileged parent */ - kex->dh = PRIVSEP(choose_dh(min, nbits, max)); + kex->dh = mm_choose_dh(min, nbits, max); if (kex->dh == NULL) { (void)sshpkt_disconnect(ssh, "no matching DH grp found"); r = SSH_ERR_ALLOC_FAIL; diff --git a/usr.bin/ssh/misc.c b/usr.bin/ssh/misc.c index 36b1cbb47..38f987549 100644 --- a/usr.bin/ssh/misc.c +++ b/usr.bin/ssh/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.193 2024/04/02 10:02:08 deraadt Exp $ */ +/* $OpenBSD: misc.c,v 1.195 2024/05/17 06:11:17 deraadt Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005-2020 Damien Miller. All rights reserved. @@ -544,7 +544,7 @@ int convtime(const char *s) { int secs, total = 0, multiplier; - char *p, *os, *np, c; + char *p, *os, *np, c = 0; const char *errstr; if (s == NULL || *s == '\0') @@ -1909,6 +1909,19 @@ forward_equals(const struct Forward *a, const struct Forward *b) return 1; } +/* returns port number, FWD_PERMIT_ANY_PORT or -1 on error */ +int +permitopen_port(const char *p) +{ + int port; + + if (strcmp(p, "*") == 0) + return FWD_PERMIT_ANY_PORT; + if ((port = a2port(p)) > 0) + return port; + return -1; +} + /* returns 1 if process is already daemonized, 0 otherwise */ int daemonized(void) diff --git a/usr.bin/ssh/misc.h b/usr.bin/ssh/misc.h index d460dc7cd..00b8bc5d0 100644 --- a/usr.bin/ssh/misc.h +++ b/usr.bin/ssh/misc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.h,v 1.107 2024/03/04 02:16:11 djm Exp $ */ +/* $OpenBSD: misc.h,v 1.108 2024/05/17 00:30:24 djm Exp $ */ /* * Author: Tatu Ylonen @@ -21,6 +21,12 @@ #include #include +/* special-case port number meaning allow any port */ +#define FWD_PERMIT_ANY_PORT 0 + +/* special-case wildcard meaning allow any host */ +#define FWD_PERMIT_ANY_HOST "*" + /* Data structure for representing a forwarding request. */ struct Forward { char *listen_host; /* Host (address) to listen on. */ @@ -34,6 +40,8 @@ struct Forward { }; int forward_equals(const struct Forward *, const struct Forward *); +int permitopen_port(const char *p); + int daemonized(void); /* Common server and client forwarding options. */ diff --git a/usr.bin/ssh/monitor.c b/usr.bin/ssh/monitor.c index 8746a8e2c..b5bbdf305 100644 --- a/usr.bin/ssh/monitor.c +++ b/usr.bin/ssh/monitor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.c,v 1.237 2023/08/16 16:14:11 djm Exp $ */ +/* $OpenBSD: monitor.c,v 1.239 2024/05/17 06:42:04 jsg Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -110,8 +110,6 @@ int mm_answer_keyverify(struct ssh *, int, struct sshbuf *); int mm_answer_pty(struct ssh *, int, struct sshbuf *); int mm_answer_pty_cleanup(struct ssh *, int, struct sshbuf *); int mm_answer_term(struct ssh *, int, struct sshbuf *); -int mm_answer_sesskey(struct ssh *, int, struct sshbuf *); -int mm_answer_sessid(struct ssh *, int, struct sshbuf *); #ifdef GSSAPI int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *); @@ -641,13 +639,39 @@ mm_answer_sign(struct ssh *ssh, int sock, struct sshbuf *m) fatal_fr(r, "assemble %s", #id); \ } while (0) +void +mm_encode_server_options(struct sshbuf *m) +{ + int r; + u_int i; + + /* XXX this leaks raw pointers to the unpriv child processes */ + if ((r = sshbuf_put_string(m, &options, sizeof(options))) != 0) + fatal_fr(r, "assemble options"); + +#define M_CP_STROPT(x) do { \ + if (options.x != NULL && \ + (r = sshbuf_put_cstring(m, options.x)) != 0) \ + fatal_fr(r, "assemble %s", #x); \ + } while (0) +#define M_CP_STRARRAYOPT(x, nx) do { \ + for (i = 0; i < options.nx; i++) { \ + if ((r = sshbuf_put_cstring(m, options.x[i])) != 0) \ + fatal_fr(r, "assemble %s", #x); \ + } \ + } while (0) + /* See comment in servconf.h */ + COPY_MATCH_STRING_OPTS(); +#undef M_CP_STROPT +#undef M_CP_STRARRAYOPT +} + /* Retrieves the password entry and also checks if the user is permitted */ int mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m) { struct passwd *pwent; int r, allowed = 0; - u_int i; debug3_f("entering"); @@ -692,24 +716,9 @@ mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m) out: ssh_packet_set_log_preamble(ssh, "%suser %s", authctxt->valid ? "authenticating" : "invalid ", authctxt->user); - if ((r = sshbuf_put_string(m, &options, sizeof(options))) != 0) - fatal_fr(r, "assemble options"); -#define M_CP_STROPT(x) do { \ - if (options.x != NULL && \ - (r = sshbuf_put_cstring(m, options.x)) != 0) \ - fatal_fr(r, "assemble %s", #x); \ - } while (0) -#define M_CP_STRARRAYOPT(x, nx) do { \ - for (i = 0; i < options.nx; i++) { \ - if ((r = sshbuf_put_cstring(m, options.x[i])) != 0) \ - fatal_fr(r, "assemble %s", #x); \ - } \ - } while (0) - /* See comment in servconf.h */ - COPY_MATCH_STRING_OPTS(); -#undef M_CP_STROPT -#undef M_CP_STRARRAYOPT + /* Send active options to unpriv */ + mm_encode_server_options(m); /* Create valid auth method lists */ if (auth2_setup_methods_lists(authctxt) != 0) { diff --git a/usr.bin/ssh/monitor.h b/usr.bin/ssh/monitor.h index 15402c409..7049e05db 100644 --- a/usr.bin/ssh/monitor.h +++ b/usr.bin/ssh/monitor.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.h,v 1.23 2019/01/19 21:43:56 djm Exp $ */ +/* $OpenBSD: monitor.h,v 1.24 2024/05/17 00:30:24 djm Exp $ */ /* * Copyright 2002 Niels Provos @@ -59,6 +59,7 @@ enum monitor_reqtype { }; struct ssh; +struct sshbuf; struct monitor { int m_recvfd; @@ -85,4 +86,7 @@ void mm_request_receive(int, struct sshbuf *); void mm_request_receive_expect(int, enum monitor_reqtype, struct sshbuf *); void mm_get_keystate(struct ssh *, struct monitor *); +/* XXX: should be returned via a monitor call rather than config_fd */ +void mm_encode_server_options(struct sshbuf *); + #endif /* _MONITOR_H_ */ diff --git a/usr.bin/ssh/monitor_wrap.c b/usr.bin/ssh/monitor_wrap.c index 3115dfee9..6287a8c71 100644 --- a/usr.bin/ssh/monitor_wrap.c +++ b/usr.bin/ssh/monitor_wrap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.c,v 1.129 2023/12/18 14:45:49 djm Exp $ */ +/* $OpenBSD: monitor_wrap.c,v 1.130 2024/05/17 00:30:24 djm Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -61,7 +61,6 @@ #ifdef GSSAPI #include "ssh-gss.h" #endif -#include "monitor_wrap.h" #include "atomicio.h" #include "monitor_fdpass.h" #include "misc.h" @@ -69,6 +68,7 @@ #include "channels.h" #include "session.h" #include "servconf.h" +#include "monitor_wrap.h" #include "ssherr.h" @@ -143,8 +143,10 @@ mm_request_receive(int sock, struct sshbuf *m) debug3_f("entering"); if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) { - if (errno == EPIPE) + if (errno == EPIPE) { + debug3_f("monitor fd closed"); cleanup_exit(255); + } fatal_f("read: %s", strerror(errno)); } msg_len = PEEK_U32(buf); @@ -239,6 +241,49 @@ mm_sshkey_sign(struct ssh *ssh, struct sshkey *key, u_char **sigp, size_t *lenp, return (0); } +void +mm_decode_activate_server_options(struct ssh *ssh, struct sshbuf *m) +{ + const u_char *p; + size_t len; + u_int i; + ServerOptions *newopts; + int r; + + if ((r = sshbuf_get_string_direct(m, &p, &len)) != 0) + fatal_fr(r, "parse opts"); + if (len != sizeof(*newopts)) + fatal_f("option block size mismatch"); + newopts = xcalloc(sizeof(*newopts), 1); + memcpy(newopts, p, sizeof(*newopts)); + +#define M_CP_STROPT(x) do { \ + if (newopts->x != NULL && \ + (r = sshbuf_get_cstring(m, &newopts->x, NULL)) != 0) \ + fatal_fr(r, "parse %s", #x); \ + } while (0) +#define M_CP_STRARRAYOPT(x, nx) do { \ + newopts->x = newopts->nx == 0 ? \ + NULL : xcalloc(newopts->nx, sizeof(*newopts->x)); \ + for (i = 0; i < newopts->nx; i++) { \ + if ((r = sshbuf_get_cstring(m, \ + &newopts->x[i], NULL)) != 0) \ + fatal_fr(r, "parse %s", #x); \ + } \ + } while (0) + /* See comment in servconf.h */ + COPY_MATCH_STRING_OPTS(); +#undef M_CP_STROPT +#undef M_CP_STRARRAYOPT + + copy_set_server_options(&options, newopts, 1); + log_change_level(options.log_level); + log_verbose_reset(); + for (i = 0; i < options.num_log_verbose; i++) + log_verbose_add(options.log_verbose[i]); + free(newopts); +} + #define GETPW(b, id) \ do { \ if ((r = sshbuf_get_string_direct(b, &p, &len)) != 0) \ @@ -254,8 +299,6 @@ mm_getpwnamallow(struct ssh *ssh, const char *username) struct sshbuf *m; struct passwd *pw; size_t len; - u_int i; - ServerOptions *newopts; int r; u_char ok; const u_char *p; @@ -294,41 +337,10 @@ mm_getpwnamallow(struct ssh *ssh, const char *username) out: /* copy options block as a Match directive may have changed some */ - if ((r = sshbuf_get_string_direct(m, &p, &len)) != 0) - fatal_fr(r, "parse opts"); - if (len != sizeof(*newopts)) - fatal_f("option block size mismatch"); - newopts = xcalloc(sizeof(*newopts), 1); - memcpy(newopts, p, sizeof(*newopts)); - -#define M_CP_STROPT(x) do { \ - if (newopts->x != NULL && \ - (r = sshbuf_get_cstring(m, &newopts->x, NULL)) != 0) \ - fatal_fr(r, "parse %s", #x); \ - } while (0) -#define M_CP_STRARRAYOPT(x, nx) do { \ - newopts->x = newopts->nx == 0 ? \ - NULL : xcalloc(newopts->nx, sizeof(*newopts->x)); \ - for (i = 0; i < newopts->nx; i++) { \ - if ((r = sshbuf_get_cstring(m, \ - &newopts->x[i], NULL)) != 0) \ - fatal_fr(r, "parse %s", #x); \ - } \ - } while (0) - /* See comment in servconf.h */ - COPY_MATCH_STRING_OPTS(); -#undef M_CP_STROPT -#undef M_CP_STRARRAYOPT - - copy_set_server_options(&options, newopts, 1); - log_change_level(options.log_level); - log_verbose_reset(); - for (i = 0; i < options.num_log_verbose; i++) - log_verbose_add(options.log_verbose[i]); - process_permitopen(ssh, &options); - process_channel_timeouts(ssh, &options); + mm_decode_activate_server_options(ssh, m); + server_process_permitopen(ssh); + server_process_channel_timeouts(ssh); kex_set_server_sig_algs(ssh, options.pubkey_accepted_algos); - free(newopts); sshbuf_free(m); return (pw); @@ -807,3 +819,91 @@ mm_ssh_gssapi_userok(char *user) return (authenticated); } #endif /* GSSAPI */ + +/* + * Inform channels layer of permitopen options for a single forwarding + * direction (local/remote). + */ +static void +server_process_permitopen_list(struct ssh *ssh, int listen, + char **opens, u_int num_opens) +{ + u_int i; + int port; + char *host, *arg, *oarg; + int where = listen ? FORWARD_REMOTE : FORWARD_LOCAL; + const char *what = listen ? "permitlisten" : "permitopen"; + + channel_clear_permission(ssh, FORWARD_ADM, where); + if (num_opens == 0) + return; /* permit any */ + + /* handle keywords: "any" / "none" */ + if (num_opens == 1 && strcmp(opens[0], "any") == 0) + return; + if (num_opens == 1 && strcmp(opens[0], "none") == 0) { + channel_disable_admin(ssh, where); + return; + } + /* Otherwise treat it as a list of permitted host:port */ + for (i = 0; i < num_opens; i++) { + oarg = arg = xstrdup(opens[i]); + host = hpdelim(&arg); + if (host == NULL) + fatal_f("missing host in %s", what); + host = cleanhostname(host); + if (arg == NULL || ((port = permitopen_port(arg)) < 0)) + fatal_f("bad port number in %s", what); + /* Send it to channels layer */ + channel_add_permission(ssh, FORWARD_ADM, + where, host, port); + free(oarg); + } +} + +/* + * Inform channels layer of permitopen options from configuration. + */ +void +server_process_permitopen(struct ssh *ssh) +{ + server_process_permitopen_list(ssh, 0, + options.permitted_opens, options.num_permitted_opens); + server_process_permitopen_list(ssh, 1, + options.permitted_listens, options.num_permitted_listens); +} + +void +server_process_channel_timeouts(struct ssh *ssh) +{ + u_int i, secs; + char *type; + + debug3_f("setting %u timeouts", options.num_channel_timeouts); + channel_clear_timeouts(ssh); + for (i = 0; i < options.num_channel_timeouts; i++) { + if (parse_pattern_interval(options.channel_timeouts[i], + &type, &secs) != 0) { + fatal_f("internal error: bad timeout %s", + options.channel_timeouts[i]); + } + channel_add_timeout(ssh, type, secs); + free(type); + } +} + +struct connection_info * +server_get_connection_info(struct ssh *ssh, int populate, int use_dns) +{ + static struct connection_info ci; + + if (ssh == NULL || !populate) + return &ci; + ci.host = use_dns ? ssh_remote_hostname(ssh) : ssh_remote_ipaddr(ssh); + ci.address = ssh_remote_ipaddr(ssh); + ci.laddress = ssh_local_ipaddr(ssh); + ci.lport = ssh_local_port(ssh); + ci.rdomain = ssh_packet_rdomain_in(ssh); + return &ci; +} + diff --git a/usr.bin/ssh/monitor_wrap.h b/usr.bin/ssh/monitor_wrap.h index c020c2c8c..a78099829 100644 --- a/usr.bin/ssh/monitor_wrap.h +++ b/usr.bin/ssh/monitor_wrap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.h,v 1.49 2022/06/15 16:08:25 djm Exp $ */ +/* $OpenBSD: monitor_wrap.h,v 1.51 2024/05/17 06:42:04 jsg Exp $ */ /* * Copyright 2002 Niels Provos @@ -28,9 +28,6 @@ #ifndef _MM_WRAP_H_ #define _MM_WRAP_H_ -extern int use_privsep; -#define PRIVSEP(x) (use_privsep ? mm_##x : x) - enum mm_keytype { MM_NOKEY, MM_HOSTKEY, MM_USERKEY }; struct ssh; @@ -61,6 +58,8 @@ int mm_hostbased_key_allowed(struct ssh *, struct passwd *, const char *, int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, const u_char *, size_t, const char *, u_int, struct sshkey_sig_details **); +void mm_decode_activate_server_options(struct ssh *ssh, struct sshbuf *m); + #ifdef GSSAPI OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, @@ -74,14 +73,16 @@ void mm_terminate(void); int mm_pty_allocate(int *, int *, char *, size_t); void mm_session_pty_cleanup2(struct Session *); -/* Key export functions */ -struct newkeys *mm_newkeys_from_blob(u_char *, int); -int mm_newkeys_to_blob(int, u_char **, u_int *); - void mm_send_keystate(struct ssh *, struct monitor*); /* bsdauth */ int mm_bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **); int mm_bsdauth_respond(void *, u_int, char **); +/* config / channels glue */ +void server_process_permitopen(struct ssh *); +void server_process_channel_timeouts(struct ssh *ssh); +struct connection_info * + server_get_connection_info(struct ssh *, int, int); + #endif /* _MM_WRAP_H_ */ diff --git a/usr.bin/ssh/msg.c b/usr.bin/ssh/msg.c index 907f233d2..3aa2d5d80 100644 --- a/usr.bin/ssh/msg.c +++ b/usr.bin/ssh/msg.c @@ -1,4 +1,4 @@ -/* $OpenBSD: msg.c,v 1.20 2020/10/18 11:32:01 djm Exp $ */ +/* $OpenBSD: msg.c,v 1.21 2024/05/17 00:30:24 djm Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * @@ -45,7 +45,7 @@ ssh_msg_send(int fd, u_char type, struct sshbuf *m) u_char buf[5]; u_int mlen = sshbuf_len(m); - debug3_f("type %u", (unsigned int)type & 0xff); + debug3_f("type %u len %zu", (unsigned int)type & 0xff, sshbuf_len(m)); put_u32(buf, mlen + 1); buf[4] = type; /* 1st byte of payload is mesg-type */ @@ -57,6 +57,7 @@ ssh_msg_send(int fd, u_char type, struct sshbuf *m) error_f("write: %s", strerror(errno)); return (-1); } + debug3_f("done"); return (0); } diff --git a/usr.bin/ssh/packet.c b/usr.bin/ssh/packet.c index 4ac450d3a..33e821c23 100644 --- a/usr.bin/ssh/packet.c +++ b/usr.bin/ssh/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.313 2023/12/18 14:45:17 djm Exp $ */ +/* $OpenBSD: packet.c,v 1.314 2024/05/17 00:30:24 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -514,6 +514,94 @@ ssh_remote_ipaddr(struct ssh *ssh) return ssh->remote_ipaddr; } +/* + * Returns the remote DNS hostname as a string. The returned string must not + * be freed. NB. this will usually trigger a DNS query. Return value is on + * heap and no caching is performed. + * This function does additional checks on the hostname to mitigate some + * attacks on based on conflation of hostnames and addresses and will + * fall back to returning an address on error. + */ + +char * +ssh_remote_hostname(struct ssh *ssh) +{ + struct sockaddr_storage from; + socklen_t fromlen; + struct addrinfo hints, *ai, *aitop; + char name[NI_MAXHOST], ntop2[NI_MAXHOST]; + const char *ntop = ssh_remote_ipaddr(ssh); + + /* Get IP address of client. */ + fromlen = sizeof(from); + memset(&from, 0, sizeof(from)); + if (getpeername(ssh_packet_get_connection_in(ssh), + (struct sockaddr *)&from, &fromlen) == -1) { + debug_f("getpeername failed: %.100s", strerror(errno)); + return xstrdup(ntop); + } + + debug3_f("trying to reverse map address %.100s.", ntop); + /* Map the IP address to a host name. */ + if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), + NULL, 0, NI_NAMEREQD) != 0) { + /* Host name not found. Use ip address. */ + return xstrdup(ntop); + } + + /* + * if reverse lookup result looks like a numeric hostname, + * someone is trying to trick us by PTR record like following: + * 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5 + */ + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + hints.ai_flags = AI_NUMERICHOST; + if (getaddrinfo(name, NULL, &hints, &ai) == 0) { + logit("Nasty PTR record \"%s\" is set up for %s, ignoring", + name, ntop); + freeaddrinfo(ai); + return xstrdup(ntop); + } + + /* Names are stored in lowercase. */ + lowercase(name); + + /* + * Map it back to an IP address and check that the given + * address actually is an address of this host. This is + * necessary because anyone with access to a name server can + * define arbitrary names for an IP address. Mapping from + * name to IP address can be trusted better (but can still be + * fooled if the intruder has access to the name server of + * the domain). + */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = from.ss_family; + hints.ai_socktype = SOCK_STREAM; + if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { + logit("reverse mapping checking getaddrinfo for %.700s " + "[%s] failed.", name, ntop); + return xstrdup(ntop); + } + /* Look for the address from the list of addresses. */ + for (ai = aitop; ai; ai = ai->ai_next) { + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2, + sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 && + (strcmp(ntop, ntop2) == 0)) + break; + } + freeaddrinfo(aitop); + /* If we reached the end of the list, the address was not there. */ + if (ai == NULL) { + /* Address not found for the host name. */ + logit("Address %.100s maps to %.600s, but this does not " + "map back to the address.", ntop, name); + return xstrdup(ntop); + } + return xstrdup(name); +} + /* Returns the port number of the remote host. */ int diff --git a/usr.bin/ssh/packet.h b/usr.bin/ssh/packet.h index 7dbe682af..fc2c3278b 100644 --- a/usr.bin/ssh/packet.h +++ b/usr.bin/ssh/packet.h @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.h,v 1.96 2023/12/18 14:45:17 djm Exp $ */ +/* $OpenBSD: packet.h,v 1.98 2024/05/17 06:42:04 jsg Exp $ */ /* * Author: Tatu Ylonen @@ -118,14 +118,12 @@ int ssh_packet_send2_wrapped(struct ssh *); int ssh_packet_send2(struct ssh *); int ssh_packet_read(struct ssh *); -int ssh_packet_read_poll(struct ssh *); int ssh_packet_read_poll2(struct ssh *, u_char *, u_int32_t *seqnr_p); int ssh_packet_process_incoming(struct ssh *, const char *buf, u_int len); int ssh_packet_process_read(struct ssh *, int); int ssh_packet_read_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p); int ssh_packet_read_poll_seqnr(struct ssh *, u_char *, u_int32_t *seqnr_p); -const void *ssh_packet_get_string_ptr(struct ssh *, u_int *length_ptr); void ssh_packet_disconnect(struct ssh *, const char *fmt, ...) __attribute__((format(printf, 2, 3))) __attribute__((noreturn)); @@ -159,6 +157,7 @@ int ssh_remote_port(struct ssh *); const char *ssh_local_ipaddr(struct ssh *); int ssh_local_port(struct ssh *); const char *ssh_packet_rdomain_in(struct ssh *); +char *ssh_remote_hostname(struct ssh *); void ssh_packet_set_rekey_limits(struct ssh *, u_int64_t, u_int32_t); time_t ssh_packet_get_rekey_timeout(struct ssh *); diff --git a/usr.bin/ssh/pathnames.h b/usr.bin/ssh/pathnames.h index 52d747135..0b170505f 100644 --- a/usr.bin/ssh/pathnames.h +++ b/usr.bin/ssh/pathnames.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pathnames.h,v 1.31 2019/11/12 19:33:08 markus Exp $ */ +/* $OpenBSD: pathnames.h,v 1.32 2024/05/17 00:30:24 djm Exp $ */ /* * Author: Tatu Ylonen @@ -39,6 +39,9 @@ #define _PATH_SSH_PROGRAM "/usr/bin/ssh" +/* Binary paths for the sshd components */ +#define _PATH_SSHD_SESSION "/usr/libexec/sshd-session" + /* * The process id of the daemon listening for connections is saved here to * make it easier to kill the correct daemon when necessary. diff --git a/usr.bin/ssh/readconf.c b/usr.bin/ssh/readconf.c index 101d878d5..2165da6a2 100644 --- a/usr.bin/ssh/readconf.c +++ b/usr.bin/ssh/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.386 2024/03/04 04:13:18 djm Exp $ */ +/* $OpenBSD: readconf.c,v 1.387 2024/05/17 02:39:11 jsg Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -3307,7 +3307,7 @@ parse_ssh_uri(const char *uri, char **userp, char **hostp, int *portp) return r; } -/* XXX the following is a near-vebatim copy from servconf.c; refactor */ +/* XXX the following is a near-verbatim copy from servconf.c; refactor */ static const char * fmt_multistate_int(int val, const struct multistate *m) { diff --git a/usr.bin/ssh/servconf.c b/usr.bin/ssh/servconf.c index 85fb86d92..02ec30553 100644 --- a/usr.bin/ssh/servconf.c +++ b/usr.bin/ssh/servconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.405 2024/03/04 02:16:11 djm Exp $ */ +/* $OpenBSD: servconf.c,v 1.407 2024/05/17 01:17:40 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -64,8 +64,6 @@ static void parse_server_config_depth(ServerOptions *options, const char *filename, struct sshbuf *conf, struct include_list *includes, struct connection_info *connectinfo, int flags, int *activep, int depth); -/* Use of privilege separation or not */ -extern int use_privsep; extern struct sshbuf *cfg; /* Initializes the server options to their default values. */ @@ -179,6 +177,7 @@ initialize_server_options(ServerOptions *options) options->channel_timeouts = NULL; options->num_channel_timeouts = 0; options->unused_connection_timeout = -1; + options->sshd_session_path = NULL; } /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ @@ -422,13 +421,11 @@ fill_default_server_options(ServerOptions *options) options->required_rsa_size = SSH_RSA_MINIMUM_MODULUS_SIZE; if (options->unused_connection_timeout == -1) options->unused_connection_timeout = 0; + if (options->sshd_session_path == NULL) + options->sshd_session_path = xstrdup(_PATH_SSHD_SESSION); assemble_algorithms(options); - /* Turn privilege separation and sandboxing on by default */ - if (use_privsep == -1) - use_privsep = PRIVSEP_ON; - #define CLEAR_ON_NONE(v) \ do { \ if (option_clear_or_none(v)) { \ @@ -503,6 +500,7 @@ typedef enum { sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider, sRequiredRSASize, sChannelTimeout, sUnusedConnectionTimeout, + sSshdSessionPath, sDeprecated, sIgnore, sUnsupported } ServerOpCodes; @@ -649,6 +647,7 @@ static struct { { "requiredrsasize", sRequiredRSASize, SSHCFG_ALL }, { "channeltimeout", sChannelTimeout, SSHCFG_ALL }, { "unusedconnectiontimeout", sUnusedConnectionTimeout, SSHCFG_ALL }, + { "sshdsessionpath", sSshdSessionPath, SSHCFG_GLOBAL }, { NULL, sBadOption, 0 } }; @@ -851,95 +850,6 @@ process_queued_listen_addrs(ServerOptions *options) options->num_queued_listens = 0; } -/* - * Inform channels layer of permitopen options for a single forwarding - * direction (local/remote). - */ -static void -process_permitopen_list(struct ssh *ssh, ServerOpCodes opcode, - char **opens, u_int num_opens) -{ - u_int i; - int port; - char *host, *arg, *oarg; - int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE; - const char *what = lookup_opcode_name(opcode); - - channel_clear_permission(ssh, FORWARD_ADM, where); - if (num_opens == 0) - return; /* permit any */ - - /* handle keywords: "any" / "none" */ - if (num_opens == 1 && strcmp(opens[0], "any") == 0) - return; - if (num_opens == 1 && strcmp(opens[0], "none") == 0) { - channel_disable_admin(ssh, where); - return; - } - /* Otherwise treat it as a list of permitted host:port */ - for (i = 0; i < num_opens; i++) { - oarg = arg = xstrdup(opens[i]); - host = hpdelim(&arg); - if (host == NULL) - fatal_f("missing host in %s", what); - host = cleanhostname(host); - if (arg == NULL || ((port = permitopen_port(arg)) < 0)) - fatal_f("bad port number in %s", what); - /* Send it to channels layer */ - channel_add_permission(ssh, FORWARD_ADM, - where, host, port); - free(oarg); - } -} - -/* - * Inform channels layer of permitopen options from configuration. - */ -void -process_permitopen(struct ssh *ssh, ServerOptions *options) -{ - process_permitopen_list(ssh, sPermitOpen, - options->permitted_opens, options->num_permitted_opens); - process_permitopen_list(ssh, sPermitListen, - options->permitted_listens, - options->num_permitted_listens); -} - -void -process_channel_timeouts(struct ssh *ssh, ServerOptions *options) -{ - int secs; - u_int i; - char *type; - - debug3_f("setting %u timeouts", options->num_channel_timeouts); - channel_clear_timeouts(ssh); - for (i = 0; i < options->num_channel_timeouts; i++) { - if (parse_pattern_interval(options->channel_timeouts[i], - &type, &secs) != 0) { - fatal_f("internal error: bad timeout %s", - options->channel_timeouts[i]); - } - channel_add_timeout(ssh, type, secs); - free(type); - } -} - -struct connection_info * -get_connection_info(struct ssh *ssh, int populate, int use_dns) -{ - static struct connection_info ci; - - if (ssh == NULL || !populate) - return &ci; - ci.host = auth_get_canonical_hostname(ssh, use_dns); - ci.address = ssh_remote_ipaddr(ssh); - ci.laddress = ssh_local_ipaddr(ssh); - ci.lport = ssh_local_port(ssh); - ci.rdomain = ssh_packet_rdomain_in(ssh); - return &ci; -} - /* * The strategy for the Match blocks is that the config file is parsed twice. * @@ -2532,6 +2442,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, } goto parse_time; + case sSshdSessionPath: + charptr = &options->sshd_session_path; + goto parse_filename; + case sDeprecated: case sIgnore: case sUnsupported: @@ -3097,6 +3011,7 @@ dump_config(ServerOptions *o) dump_cfg_string(sHostKeyAlgorithms, o->hostkeyalgorithms); dump_cfg_string(sPubkeyAcceptedAlgorithms, o->pubkey_accepted_algos); dump_cfg_string(sRDomain, o->routing_domain); + dump_cfg_string(sSshdSessionPath, o->sshd_session_path); /* string arguments requiring a lookup */ dump_cfg_string(sLogLevel, log_level_name(o->log_level)); diff --git a/usr.bin/ssh/servconf.h b/usr.bin/ssh/servconf.h index bff6f2686..99754a8a3 100644 --- a/usr.bin/ssh/servconf.h +++ b/usr.bin/ssh/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.160 2023/09/06 23:35:35 djm Exp $ */ +/* $OpenBSD: servconf.h,v 1.162 2024/05/17 06:42:04 jsg Exp $ */ /* * Author: Tatu Ylonen @@ -27,11 +27,6 @@ #define PERMIT_NO_PASSWD 2 #define PERMIT_YES 3 -/* use_privsep */ -#define PRIVSEP_OFF 0 -#define PRIVSEP_ON 1 -#define PRIVSEP_NOSANDBOX 2 - /* PermitOpen */ #define PERMITOPEN_ANY 0 #define PERMITOPEN_NONE -2 @@ -231,6 +226,8 @@ typedef struct { u_int num_channel_timeouts; int unused_connection_timeout; + + char *sshd_session_path; } ServerOptions; /* Information about the incoming connection as used by Match */ @@ -295,20 +292,16 @@ TAILQ_HEAD(include_list, include_item); M_CP_STRARRAYOPT(subsystem_args, num_subsystems); \ } while (0) -struct connection_info *get_connection_info(struct ssh *, int, int); void initialize_server_options(ServerOptions *); void fill_default_server_options(ServerOptions *); int process_server_config_line(ServerOptions *, char *, const char *, int, int *, struct connection_info *, struct include_list *includes); -void process_permitopen(struct ssh *ssh, ServerOptions *options); -void process_channel_timeouts(struct ssh *ssh, ServerOptions *); void load_server_config(const char *, struct sshbuf *); void parse_server_config(ServerOptions *, const char *, struct sshbuf *, struct include_list *includes, struct connection_info *, int); void parse_server_match_config(ServerOptions *, struct include_list *includes, struct connection_info *); int parse_server_match_testspec(struct connection_info *, char *); -int server_match_spec_complete(struct connection_info *); void servconf_merge_subsystems(ServerOptions *, ServerOptions *); void copy_set_server_options(ServerOptions *, ServerOptions *, int); void dump_config(ServerOptions *); diff --git a/usr.bin/ssh/serverloop.c b/usr.bin/ssh/serverloop.c index 2e3101ebf..689d21e52 100644 --- a/usr.bin/ssh/serverloop.c +++ b/usr.bin/ssh/serverloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: serverloop.c,v 1.238 2024/04/30 02:14:10 djm Exp $ */ +/* $OpenBSD: serverloop.c,v 1.239 2024/05/17 00:30:24 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -80,44 +80,23 @@ extern ServerOptions options; /* XXX */ extern Authctxt *the_authctxt; extern struct sshauthopt *auth_opts; -extern int use_privsep; static int no_more_sessions = 0; /* Disallow further sessions. */ static volatile sig_atomic_t child_terminated = 0; /* The child has terminated. */ -/* Cleanup on signals (!use_privsep case only) */ -static volatile sig_atomic_t received_sigterm = 0; - /* prototypes */ static void server_init_dispatch(struct ssh *); /* requested tunnel forwarding interface(s), shared with session.c */ char *tun_fwd_ifnames = NULL; -/* returns 1 if bind to specified port by specified user is permitted */ -static int -bind_permitted(int port, uid_t uid) -{ - if (use_privsep) - return 1; /* allow system to decide */ - if (port < IPPORT_RESERVED && uid != 0) - return 0; - return 1; -} - static void sigchld_handler(int sig) { child_terminated = 1; } -static void -sigterm_handler(int sig) -{ - received_sigterm = sig; -} - static void client_alive_check(struct ssh *ssh) { @@ -348,12 +327,6 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt) connection_in = ssh_packet_get_connection_in(ssh); connection_out = ssh_packet_get_connection_out(ssh); - if (!use_privsep) { - ssh_signal(SIGTERM, sigterm_handler); - ssh_signal(SIGINT, sigterm_handler); - ssh_signal(SIGQUIT, sigterm_handler); - } - server_init_dispatch(ssh); for (;;) { @@ -377,12 +350,6 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt) if (sigprocmask(SIG_SETMASK, &osigset, NULL) == -1) error_f("osigset sigprocmask: %s", strerror(errno)); - if (received_sigterm) { - logit("Exiting on signal %d", (int)received_sigterm); - /* Clean up sessions, utmp, etc. */ - cleanup_exit(255); - } - channel_after_poll(ssh, pfd, npfd_active); if (conn_in_ready && process_input(ssh, connection_in) < 0) @@ -492,7 +459,7 @@ server_request_direct_streamlocal(struct ssh *ssh) /* XXX fine grained permissions */ if ((options.allow_streamlocal_forwarding & FORWARD_LOCAL) != 0 && auth_opts->permit_port_forwarding_flag && - !options.disable_forwarding && (pw->pw_uid == 0 || use_privsep)) { + !options.disable_forwarding) { c = channel_connect_to_path(ssh, target, "direct-streamlocal@openssh.com", "direct-streamlocal"); } else { @@ -781,9 +748,7 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh) (options.allow_tcp_forwarding & FORWARD_REMOTE) == 0 || !auth_opts->permit_port_forwarding_flag || options.disable_forwarding || - (!want_reply && fwd.listen_port == 0) || - (fwd.listen_port != 0 && - !bind_permitted(fwd.listen_port, pw->pw_uid))) { + (!want_reply && fwd.listen_port == 0)) { success = 0; ssh_packet_send_debug(ssh, "Server has disabled port forwarding."); } else { @@ -816,8 +781,7 @@ server_input_global_request(int type, u_int32_t seq, struct ssh *ssh) /* check permissions */ if ((options.allow_streamlocal_forwarding & FORWARD_REMOTE) == 0 || !auth_opts->permit_port_forwarding_flag || - options.disable_forwarding || - (pw->pw_uid != 0 && !use_privsep)) { + options.disable_forwarding) { success = 0; ssh_packet_send_debug(ssh, "Server has disabled " "streamlocal forwarding."); diff --git a/usr.bin/ssh/session.c b/usr.bin/ssh/session.c index 88ebe229a..e0239a28c 100644 --- a/usr.bin/ssh/session.c +++ b/usr.bin/ssh/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.337 2024/02/01 02:37:33 djm Exp $ */ +/* $OpenBSD: session.c,v 1.338 2024/05/17 00:30:24 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -705,8 +705,6 @@ do_login(struct ssh *ssh, Session *s, const char *command) { socklen_t fromlen; struct sockaddr_storage from; - struct passwd * pw = s->pw; - pid_t pid = getpid(); /* * Get IP address of client. If the connection is not a socket, let @@ -722,13 +720,6 @@ do_login(struct ssh *ssh, Session *s, const char *command) } } - /* Record that there was a login on that tty from the remote host. */ - if (!use_privsep) - record_login(pid, s->tty, pw->pw_name, pw->pw_uid, - session_get_remote_name_or_ip(ssh, utmp_len, - options.use_dns), - (struct sockaddr *)&from, fromlen); - if (check_quietlogin(s, command)) return; @@ -1606,8 +1597,7 @@ session_pty_req(struct ssh *ssh, Session *s) /* Allocate a pty and open it. */ debug("Allocating pty."); - if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, - sizeof(s->tty)))) { + if (!mm_pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty))) { free(s->term); s->term = NULL; s->ptyfd = -1; @@ -1622,9 +1612,6 @@ session_pty_req(struct ssh *ssh, Session *s) if ((r = sshpkt_get_end(ssh)) != 0) sshpkt_fatal(ssh, r, "%s: parse packet", __func__); - if (!use_privsep) - pty_setowner(s->pw, s->tty); - /* Set window size from the packet. */ pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); @@ -1840,7 +1827,7 @@ session_signal_req(struct ssh *ssh, Session *s) signame, s->forced ? "forced-command" : "subsystem"); goto out; } - if (!use_privsep || mm_is_monitor()) { + if (mm_is_monitor()) { error_f("session signalling requires privilege separation"); goto out; } @@ -1983,7 +1970,7 @@ session_pty_cleanup2(Session *s) void session_pty_cleanup(Session *s) { - PRIVSEP(session_pty_cleanup2(s)); + mm_session_pty_cleanup2(s); } static char * @@ -2354,7 +2341,7 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) * Cleanup ptys/utmp only if privsep is disabled, * or if running in monitor. */ - if (!use_privsep || mm_is_monitor()) + if (mm_is_monitor()) session_destroy_all(ssh, session_pty_cleanup2); } diff --git a/usr.bin/ssh/sftp-client.c b/usr.bin/ssh/sftp-client.c index f4dc2b011..ed538a697 100644 --- a/usr.bin/ssh/sftp-client.c +++ b/usr.bin/ssh/sftp-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-client.c,v 1.175 2023/11/13 09:18:19 tobhe Exp $ */ +/* $OpenBSD: sftp-client.c,v 1.176 2024/05/17 02:39:11 jsg Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -2415,7 +2415,7 @@ handle_dest_replies(struct sftp_conn *to, const char *to_path, int synchronous, * server not to have reordered replies that could have * inserted holes where none existed in the source file. * - * XXX we could get a more accutate progress bar if we updated + * XXX we could get a more accurate progress bar if we updated * the counter based on the reply from the destination... */ (*nreqsp)--; diff --git a/usr.bin/ssh/ssh-gss.h b/usr.bin/ssh/ssh-gss.h index 271942b44..83fadf598 100644 --- a/usr.bin/ssh/ssh-gss.h +++ b/usr.bin/ssh/ssh-gss.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-gss.h,v 1.15 2021/01/27 10:05:28 djm Exp $ */ +/* $OpenBSD: ssh-gss.h,v 1.16 2024/05/17 06:42:04 jsg Exp $ */ /* * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. * @@ -82,7 +82,6 @@ int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); void ssh_gssapi_set_oid(Gssctxt *, gss_OID); void ssh_gssapi_supported_oids(gss_OID_set *); -ssh_gssapi_mech *ssh_gssapi_get_ctype(Gssctxt *); void ssh_gssapi_prepare_supported_oids(void); OM_uint32 ssh_gssapi_test_oid_supported(OM_uint32 *, gss_OID, int *); diff --git a/usr.bin/ssh/ssh_api.c b/usr.bin/ssh/ssh_api.c index 54f82cfb7..e496403f9 100644 --- a/usr.bin/ssh/ssh_api.c +++ b/usr.bin/ssh/ssh_api.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh_api.c,v 1.28 2024/01/09 21:39:14 djm Exp $ */ +/* $OpenBSD: ssh_api.c,v 1.29 2024/05/17 00:30:24 djm Exp $ */ /* * Copyright (c) 2012 Markus Friedl. All rights reserved. * @@ -25,6 +25,7 @@ #include "log.h" #include "authfile.h" #include "sshkey.h" +#include "dh.h" #include "misc.h" #include "ssh2.h" #include "version.h" @@ -45,10 +46,8 @@ int _ssh_host_key_sign(struct ssh *, struct sshkey *, struct sshkey *, u_char **, size_t *, const u_char *, size_t, const char *); /* - * stubs for the server side implementation of kex. - * disable privsep so our stubs will never be called. + * stubs for privsep calls in the server side implementation of kex. */ -int use_privsep = 0; int mm_sshkey_sign(struct sshkey *, u_char **, u_int *, const u_char *, u_int, const char *, const char *, const char *, u_int); @@ -61,14 +60,20 @@ mm_sshkey_sign(struct sshkey *key, u_char **sigp, u_int *lenp, const u_char *data, u_int datalen, const char *alg, const char *sk_provider, const char *sk_pin, u_int compat) { - return (-1); + size_t slen = 0; + int ret; + + ret = sshkey_sign(key, sigp, &slen, data, datalen, alg, + sk_provider, sk_pin, compat); + *lenp = slen; + return ret; } #ifdef WITH_OPENSSL DH * mm_choose_dh(int min, int nbits, int max) { - return (NULL); + return choose_dh(min, nbits, max); } #endif diff --git a/usr.bin/ssh/sshconnect2.c b/usr.bin/ssh/sshconnect2.c index 020a0f6ef..8e0b07eca 100644 --- a/usr.bin/ssh/sshconnect2.c +++ b/usr.bin/ssh/sshconnect2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect2.c,v 1.372 2024/01/08 00:34:34 djm Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.373 2024/05/17 06:38:00 jsg Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2008 Damien Miller. All rights reserved. @@ -75,8 +75,6 @@ #endif /* import */ -extern char *client_version_string; -extern char *server_version_string; extern Options options; /* diff --git a/usr.bin/ssh/sshd-session.c b/usr.bin/ssh/sshd-session.c new file mode 100644 index 000000000..b800f2b5a --- /dev/null +++ b/usr.bin/ssh/sshd-session.c @@ -0,0 +1,1354 @@ +/* $OpenBSD: sshd-session.c,v 1.2 2024/05/17 02:39:11 jsg Exp $ */ +/* + * SSH2 implementation: + * Privilege Separation: + * + * Copyright (c) 2000, 2001, 2002 Markus Friedl. All rights reserved. + * Copyright (c) 2002 Niels Provos. 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 ``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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef WITH_OPENSSL +#include +#include +#endif + +#include "xmalloc.h" +#include "ssh.h" +#include "ssh2.h" +#include "sshpty.h" +#include "packet.h" +#include "log.h" +#include "sshbuf.h" +#include "misc.h" +#include "match.h" +#include "servconf.h" +#include "uidswap.h" +#include "compat.h" +#include "cipher.h" +#include "digest.h" +#include "sshkey.h" +#include "kex.h" +#include "authfile.h" +#include "pathnames.h" +#include "atomicio.h" +#include "canohost.h" +#include "hostfile.h" +#include "auth.h" +#include "authfd.h" +#include "msg.h" +#include "dispatch.h" +#include "channels.h" +#include "session.h" +#include "monitor.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" +#include "ssh-sandbox.h" +#include "auth-options.h" +#include "version.h" +#include "ssherr.h" +#include "sk-api.h" +#include "srclimit.h" +#include "dh.h" + +/* Re-exec fds */ +#define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) +#define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) +#define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 3) +#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 4) + +extern char *__progname; + +/* Server configuration options. */ +ServerOptions options; + +/* Name of the server configuration file. */ +char *config_file_name = _PATH_SERVER_CONFIG_FILE; + +/* + * Debug mode flag. This can be set on the command line. If debug + * mode is enabled, extra debugging output will be sent to the system + * log, the daemon will not go to background, and will exit after processing + * the first connection. + */ +int debug_flag = 0; + +/* Flag indicating that the daemon is being started from inetd. */ +static int inetd_flag = 0; + +/* debug goes to stderr unless inetd_flag is set */ +static int log_stderr = 0; + +/* Saved arguments to main(). */ +static char **saved_argv; + +/* Daemon's agent connection */ +int auth_sock = -1; +static int have_agent = 0; + +/* + * Any really sensitive data in the application is contained in this + * structure. The idea is that this structure could be locked into memory so + * that the pages do not get written into swap. However, there are some + * problems. The private key contains BIGNUMs, and we do not (in principle) + * have access to the internals of them, and locking just the structure is + * not very useful. Currently, memory locking is not implemented. + */ +struct { + u_int num_hostkeys; + struct sshkey **host_keys; /* all private host keys */ + struct sshkey **host_pubkeys; /* all public host keys */ + struct sshkey **host_certificates; /* all public host certificates */ +} sensitive_data; + +/* record remote hostname or ip */ +u_int utmp_len = HOST_NAME_MAX+1; + +static int startup_pipe = -1; /* in child */ + +/* variables used for privilege separation */ +struct monitor *pmonitor = NULL; +int privsep_is_preauth = 1; + +/* global connection state and authentication contexts */ +Authctxt *the_authctxt = NULL; +struct ssh *the_active_state; + +/* global key/cert auth options. XXX move to permanent ssh->authctxt? */ +struct sshauthopt *auth_opts = NULL; + +/* sshd_config buffer */ +struct sshbuf *cfg; + +/* Included files from the configuration file */ +struct include_list includes = TAILQ_HEAD_INITIALIZER(includes); + +/* message to be displayed after login */ +struct sshbuf *loginmsg; + +/* Prototypes for various functions defined later in this file. */ +void destroy_sensitive_data(void); +void demote_sensitive_data(void); +static void do_ssh2_kex(struct ssh *); + +/* + * Signal handler for the alarm after the login grace period has expired. + */ +static void +grace_alarm_handler(int sig) +{ + /* + * Try to kill any processes that we have spawned, E.g. authorized + * keys command helpers or privsep children. + */ + if (getpgid(0) == getpid()) { + ssh_signal(SIGTERM, SIG_IGN); + kill(0, SIGTERM); + } + + /* Log error and exit. */ + sigdie("Timeout before authentication for %s port %d", + ssh_remote_ipaddr(the_active_state), + ssh_remote_port(the_active_state)); +} + +/* Destroy the host and server keys. They will no longer be needed. */ +void +destroy_sensitive_data(void) +{ + u_int i; + + for (i = 0; i < options.num_host_key_files; i++) { + if (sensitive_data.host_keys[i]) { + sshkey_free(sensitive_data.host_keys[i]); + sensitive_data.host_keys[i] = NULL; + } + if (sensitive_data.host_certificates[i]) { + sshkey_free(sensitive_data.host_certificates[i]); + sensitive_data.host_certificates[i] = NULL; + } + } +} + +/* Demote private to public keys for network child */ +void +demote_sensitive_data(void) +{ + struct sshkey *tmp; + u_int i; + int r; + + for (i = 0; i < options.num_host_key_files; i++) { + if (sensitive_data.host_keys[i]) { + if ((r = sshkey_from_private( + sensitive_data.host_keys[i], &tmp)) != 0) + fatal_r(r, "could not demote host %s key", + sshkey_type(sensitive_data.host_keys[i])); + sshkey_free(sensitive_data.host_keys[i]); + sensitive_data.host_keys[i] = tmp; + } + /* Certs do not need demotion */ + } +} + +static void +privsep_preauth_child(void) +{ + gid_t gidset[1]; + struct passwd *pw; + + /* Enable challenge-response authentication for privilege separation */ + privsep_challenge_enable(); + +#ifdef GSSAPI + /* Cache supported mechanism OIDs for later use */ + ssh_gssapi_prepare_supported_oids(); +#endif + + /* Demote the private keys to public keys. */ + demote_sensitive_data(); + + /* Demote the child */ + if (getuid() == 0 || geteuid() == 0) { + if ((pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) + fatal("Privilege separation user %s does not exist", + SSH_PRIVSEP_USER); + pw = pwcopy(pw); /* Ensure mutable */ + endpwent(); + freezero(pw->pw_passwd, strlen(pw->pw_passwd)); + + /* Change our root directory */ + if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) + fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, + strerror(errno)); + if (chdir("/") == -1) + fatal("chdir(\"/\"): %s", strerror(errno)); + + /* + * Drop our privileges + * NB. Can't use setusercontext() after chroot. + */ + debug3("privsep user:group %u:%u", (u_int)pw->pw_uid, + (u_int)pw->pw_gid); + gidset[0] = pw->pw_gid; + if (setgroups(1, gidset) == -1) + fatal("setgroups: %.100s", strerror(errno)); + permanently_set_uid(pw); + } +} + +static int +privsep_preauth(struct ssh *ssh) +{ + int status, r; + pid_t pid; + struct ssh_sandbox *box = NULL; + + /* Set up unprivileged child process to deal with network data */ + pmonitor = monitor_init(); + /* Store a pointer to the kex for later rekeying */ + pmonitor->m_pkex = &ssh->kex; + + box = ssh_sandbox_init(); + pid = fork(); + if (pid == -1) { + fatal("fork of unprivileged child failed"); + } else if (pid != 0) { + debug2("Network child is on pid %ld", (long)pid); + + pmonitor->m_pid = pid; + if (have_agent) { + r = ssh_get_authentication_socket(&auth_sock); + if (r != 0) { + error_r(r, "Could not get agent socket"); + have_agent = 0; + } + } + if (box != NULL) + ssh_sandbox_parent_preauth(box, pid); + monitor_child_preauth(ssh, pmonitor); + + /* Wait for the child's exit status */ + while (waitpid(pid, &status, 0) == -1) { + if (errno == EINTR) + continue; + pmonitor->m_pid = -1; + fatal_f("waitpid: %s", strerror(errno)); + } + privsep_is_preauth = 0; + pmonitor->m_pid = -1; + if (WIFEXITED(status)) { + if (WEXITSTATUS(status) != 0) + fatal_f("preauth child exited with status %d", + WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) + fatal_f("preauth child terminated by signal %d", + WTERMSIG(status)); + if (box != NULL) + ssh_sandbox_parent_finish(box); + return 1; + } else { + /* child */ + close(pmonitor->m_sendfd); + close(pmonitor->m_log_recvfd); + + /* Arrange for logging to be sent to the monitor */ + set_log_handler(mm_log_handler, pmonitor); + + privsep_preauth_child(); + setproctitle("%s", "[net]"); + if (box != NULL) + ssh_sandbox_child(box); + + return 0; + } +} + +static void +privsep_postauth(struct ssh *ssh, Authctxt *authctxt) +{ + /* New socket pair */ + monitor_reinit(pmonitor); + + pmonitor->m_pid = fork(); + if (pmonitor->m_pid == -1) + fatal("fork of unprivileged child failed"); + else if (pmonitor->m_pid != 0) { + verbose("User child is on pid %ld", (long)pmonitor->m_pid); + sshbuf_reset(loginmsg); + monitor_clear_keystate(ssh, pmonitor); + monitor_child_postauth(ssh, pmonitor); + + /* NEVERREACHED */ + exit(0); + } + + /* child */ + + close(pmonitor->m_sendfd); + pmonitor->m_sendfd = -1; + + /* Demote the private keys to public keys. */ + demote_sensitive_data(); + + /* Drop privileges */ + do_setusercontext(authctxt->pw); + + /* It is safe now to apply the key state */ + monitor_apply_keystate(ssh, pmonitor); + + /* + * Tell the packet layer that authentication was successful, since + * this information is not part of the key state. + */ + ssh_packet_set_authenticated(ssh); +} + +static void +append_hostkey_type(struct sshbuf *b, const char *s) +{ + int r; + + if (match_pattern_list(s, options.hostkeyalgorithms, 0) != 1) { + debug3_f("%s key not permitted by HostkeyAlgorithms", s); + return; + } + if ((r = sshbuf_putf(b, "%s%s", sshbuf_len(b) > 0 ? "," : "", s)) != 0) + fatal_fr(r, "sshbuf_putf"); +} + +static char * +list_hostkey_types(void) +{ + struct sshbuf *b; + struct sshkey *key; + char *ret; + u_int i; + + if ((b = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + for (i = 0; i < options.num_host_key_files; i++) { + key = sensitive_data.host_keys[i]; + if (key == NULL) + key = sensitive_data.host_pubkeys[i]; + if (key == NULL) + continue; + switch (key->type) { + case KEY_RSA: + /* for RSA we also support SHA2 signatures */ + append_hostkey_type(b, "rsa-sha2-512"); + append_hostkey_type(b, "rsa-sha2-256"); + /* FALLTHROUGH */ + case KEY_DSA: + case KEY_ECDSA: + case KEY_ED25519: + case KEY_ECDSA_SK: + case KEY_ED25519_SK: + case KEY_XMSS: + append_hostkey_type(b, sshkey_ssh_name(key)); + break; + } + /* If the private key has a cert peer, then list that too */ + key = sensitive_data.host_certificates[i]; + if (key == NULL) + continue; + switch (key->type) { + case KEY_RSA_CERT: + /* for RSA we also support SHA2 signatures */ + append_hostkey_type(b, + "rsa-sha2-512-cert-v01@openssh.com"); + append_hostkey_type(b, + "rsa-sha2-256-cert-v01@openssh.com"); + /* FALLTHROUGH */ + case KEY_DSA_CERT: + case KEY_ECDSA_CERT: + case KEY_ED25519_CERT: + case KEY_ECDSA_SK_CERT: + case KEY_ED25519_SK_CERT: + case KEY_XMSS_CERT: + append_hostkey_type(b, sshkey_ssh_name(key)); + break; + } + } + if ((ret = sshbuf_dup_string(b)) == NULL) + fatal_f("sshbuf_dup_string failed"); + sshbuf_free(b); + debug_f("%s", ret); + return ret; +} + +static struct sshkey * +get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh) +{ + u_int i; + struct sshkey *key; + + for (i = 0; i < options.num_host_key_files; i++) { + switch (type) { + case KEY_RSA_CERT: + case KEY_DSA_CERT: + case KEY_ECDSA_CERT: + case KEY_ED25519_CERT: + case KEY_ECDSA_SK_CERT: + case KEY_ED25519_SK_CERT: + case KEY_XMSS_CERT: + key = sensitive_data.host_certificates[i]; + break; + default: + key = sensitive_data.host_keys[i]; + if (key == NULL && !need_private) + key = sensitive_data.host_pubkeys[i]; + break; + } + if (key == NULL || key->type != type) + continue; + switch (type) { + case KEY_ECDSA: + case KEY_ECDSA_SK: + case KEY_ECDSA_CERT: + case KEY_ECDSA_SK_CERT: + if (key->ecdsa_nid != nid) + continue; + /* FALLTHROUGH */ + default: + return need_private ? + sensitive_data.host_keys[i] : key; + } + } + return NULL; +} + +struct sshkey * +get_hostkey_public_by_type(int type, int nid, struct ssh *ssh) +{ + return get_hostkey_by_type(type, nid, 0, ssh); +} + +struct sshkey * +get_hostkey_private_by_type(int type, int nid, struct ssh *ssh) +{ + return get_hostkey_by_type(type, nid, 1, ssh); +} + +struct sshkey * +get_hostkey_by_index(int ind) +{ + if (ind < 0 || (u_int)ind >= options.num_host_key_files) + return (NULL); + return (sensitive_data.host_keys[ind]); +} + +struct sshkey * +get_hostkey_public_by_index(int ind, struct ssh *ssh) +{ + if (ind < 0 || (u_int)ind >= options.num_host_key_files) + return (NULL); + return (sensitive_data.host_pubkeys[ind]); +} + +int +get_hostkey_index(struct sshkey *key, int compare, struct ssh *ssh) +{ + u_int i; + + for (i = 0; i < options.num_host_key_files; i++) { + if (sshkey_is_cert(key)) { + if (key == sensitive_data.host_certificates[i] || + (compare && sensitive_data.host_certificates[i] && + sshkey_equal(key, + sensitive_data.host_certificates[i]))) + return (i); + } else { + if (key == sensitive_data.host_keys[i] || + (compare && sensitive_data.host_keys[i] && + sshkey_equal(key, sensitive_data.host_keys[i]))) + return (i); + if (key == sensitive_data.host_pubkeys[i] || + (compare && sensitive_data.host_pubkeys[i] && + sshkey_equal(key, sensitive_data.host_pubkeys[i]))) + return (i); + } + } + return (-1); +} + +/* Inform the client of all hostkeys */ +static void +notify_hostkeys(struct ssh *ssh) +{ + struct sshbuf *buf; + struct sshkey *key; + u_int i, nkeys; + int r; + char *fp; + + /* Some clients cannot cope with the hostkeys message, skip those. */ + if (ssh->compat & SSH_BUG_HOSTKEYS) + return; + + if ((buf = sshbuf_new()) == NULL) + fatal_f("sshbuf_new"); + for (i = nkeys = 0; i < options.num_host_key_files; i++) { + key = get_hostkey_public_by_index(i, ssh); + if (key == NULL || key->type == KEY_UNSPEC || + sshkey_is_cert(key)) + continue; + fp = sshkey_fingerprint(key, options.fingerprint_hash, + SSH_FP_DEFAULT); + debug3_f("key %d: %s %s", i, sshkey_ssh_name(key), fp); + free(fp); + if (nkeys == 0) { + /* + * Start building the request when we find the + * first usable key. + */ + if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 || + (r = sshpkt_put_cstring(ssh, "hostkeys-00@openssh.com")) != 0 || + (r = sshpkt_put_u8(ssh, 0)) != 0) /* want reply */ + sshpkt_fatal(ssh, r, "%s: start request", __func__); + } + /* Append the key to the request */ + sshbuf_reset(buf); + if ((r = sshkey_putb(key, buf)) != 0) + fatal_fr(r, "couldn't put hostkey %d", i); + if ((r = sshpkt_put_stringb(ssh, buf)) != 0) + sshpkt_fatal(ssh, r, "%s: append key", __func__); + nkeys++; + } + debug3_f("sent %u hostkeys", nkeys); + if (nkeys == 0) + fatal_f("no hostkeys"); + if ((r = sshpkt_send(ssh)) != 0) + sshpkt_fatal(ssh, r, "%s: send", __func__); + sshbuf_free(buf); +} + +static void +usage(void) +{ + fprintf(stderr, "%s, %s\n", SSH_VERSION, SSH_OPENSSL_VERSION); + fprintf(stderr, +"usage: sshd [-46DdeGiqTtV] [-C connection_spec] [-c host_cert_file]\n" +" [-E log_file] [-f config_file] [-g login_grace_time]\n" +" [-h host_key_file] [-o option] [-p port] [-u len]\n" + ); + exit(1); +} + +static void +parse_hostkeys(struct sshbuf *hostkeys) +{ + int r; + u_int num_keys = 0; + struct sshkey *k; + struct sshbuf *kbuf; + const u_char *cp; + size_t len; + + while (sshbuf_len(hostkeys) != 0) { + if (num_keys > 2048) + fatal_f("too many hostkeys"); + sensitive_data.host_keys = xrecallocarray( + sensitive_data.host_keys, num_keys, num_keys + 1, + sizeof(*sensitive_data.host_pubkeys)); + sensitive_data.host_pubkeys = xrecallocarray( + sensitive_data.host_pubkeys, num_keys, num_keys + 1, + sizeof(*sensitive_data.host_pubkeys)); + sensitive_data.host_certificates = xrecallocarray( + sensitive_data.host_certificates, num_keys, num_keys + 1, + sizeof(*sensitive_data.host_certificates)); + /* private key */ + k = NULL; + if ((r = sshbuf_froms(hostkeys, &kbuf)) != 0) + fatal_fr(r, "extract privkey"); + if (sshbuf_len(kbuf) != 0 && + (r = sshkey_private_deserialize(kbuf, &k)) != 0) + fatal_fr(r, "parse pubkey"); + sensitive_data.host_keys[num_keys] = k; + sshbuf_free(kbuf); + if (k) + debug2_f("privkey %u: %s", num_keys, sshkey_ssh_name(k)); + /* public key */ + k = NULL; + if ((r = sshbuf_get_string_direct(hostkeys, &cp, &len)) != 0) + fatal_fr(r, "extract pubkey"); + if (len != 0 && (r = sshkey_from_blob(cp, len, &k)) != 0) + fatal_fr(r, "parse pubkey"); + sensitive_data.host_pubkeys[num_keys] = k; + if (k) + debug2_f("pubkey %u: %s", num_keys, sshkey_ssh_name(k)); + /* certificate */ + k = NULL; + if ((r = sshbuf_get_string_direct(hostkeys, &cp, &len)) != 0) + fatal_fr(r, "extract pubkey"); + if (len != 0 && (r = sshkey_from_blob(cp, len, &k)) != 0) + fatal_fr(r, "parse pubkey"); + sensitive_data.host_certificates[num_keys] = k; + if (k) + debug2_f("cert %u: %s", num_keys, sshkey_ssh_name(k)); + num_keys++; + } + sensitive_data.num_hostkeys = num_keys; +} + +static void +recv_rexec_state(int fd, struct sshbuf *conf, uint64_t *timing_secretp) +{ + struct sshbuf *m, *inc, *hostkeys; + u_char *cp, ver; + size_t len; + int r; + struct include_item *item; + + debug3_f("entering fd = %d", fd); + + if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + if (ssh_msg_recv(fd, m) == -1) + fatal_f("ssh_msg_recv failed"); + if ((r = sshbuf_get_u8(m, &ver)) != 0) + fatal_fr(r, "parse version"); + if (ver != 0) + fatal_f("rexec version mismatch"); + if ((r = sshbuf_get_string(m, &cp, &len)) != 0 || /* XXX _direct */ + (r = sshbuf_get_u64(m, timing_secretp)) != 0 || + (r = sshbuf_froms(m, &hostkeys)) != 0 || + (r = sshbuf_get_stringb(m, inc)) != 0) + fatal_fr(r, "parse config"); + + if (conf != NULL && (r = sshbuf_put(conf, cp, len))) + fatal_fr(r, "sshbuf_put"); + + while (sshbuf_len(inc) != 0) { + item = xcalloc(1, sizeof(*item)); + if ((item->contents = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + if ((r = sshbuf_get_cstring(inc, &item->selector, NULL)) != 0 || + (r = sshbuf_get_cstring(inc, &item->filename, NULL)) != 0 || + (r = sshbuf_get_stringb(inc, item->contents)) != 0) + fatal_fr(r, "parse includes"); + TAILQ_INSERT_TAIL(&includes, item, entry); + } + + parse_hostkeys(hostkeys); + + free(cp); + sshbuf_free(m); + sshbuf_free(hostkeys); + sshbuf_free(inc); + + debug3_f("done"); +} + +/* + * If IP options are supported, make sure there are none (log and + * return an error if any are found). Basically we are worried about + * source routing; it can be used to pretend you are somebody + * (ip-address) you are not. That itself may be "almost acceptable" + * under certain circumstances, but rhosts authentication is useless + * if source routing is accepted. Notice also that if we just dropped + * source routing here, the other side could use IP spoofing to do + * rest of the interaction and could still bypass security. So we + * exit here if we detect any IP options. + */ +static void +check_ip_options(struct ssh *ssh) +{ + int sock_in = ssh_packet_get_connection_in(ssh); + struct sockaddr_storage from; + u_char opts[200]; + socklen_t i, option_size = sizeof(opts), fromlen = sizeof(from); + char text[sizeof(opts) * 3 + 1]; + + memset(&from, 0, sizeof(from)); + if (getpeername(sock_in, (struct sockaddr *)&from, + &fromlen) == -1) + return; + if (from.ss_family != AF_INET) + return; + /* XXX IPv6 options? */ + + if (getsockopt(sock_in, IPPROTO_IP, IP_OPTIONS, opts, + &option_size) >= 0 && option_size != 0) { + text[0] = '\0'; + for (i = 0; i < option_size; i++) + snprintf(text + i*3, sizeof(text) - i*3, + " %2.2x", opts[i]); + fatal("Connection from %.100s port %d with IP opts: %.800s", + ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), text); + } + return; +} + +/* Set the routing domain for this process */ +static void +set_process_rdomain(struct ssh *ssh, const char *name) +{ + int rtable, ortable = getrtable(); + const char *errstr; + + if (name == NULL) + return; /* default */ + + if (strcmp(name, "%D") == 0) { + /* "expands" to routing domain of connection */ + if ((name = ssh_packet_rdomain_in(ssh)) == NULL) + return; + } + + rtable = (int)strtonum(name, 0, 255, &errstr); + if (errstr != NULL) /* Shouldn't happen */ + fatal("Invalid routing domain \"%s\": %s", name, errstr); + if (rtable != ortable && setrtable(rtable) != 0) + fatal("Unable to set routing domain %d: %s", + rtable, strerror(errno)); + debug_f("set routing domain %d (was %d)", rtable, ortable); +} + +/* + * Main program for the daemon. + */ +int +main(int ac, char **av) +{ + struct ssh *ssh = NULL; + extern char *optarg; + extern int optind; + int r, opt, on = 1, remote_port; + int sock_in = -1, sock_out = -1, rexeced_flag = 0, have_key = 0; + const char *remote_ip, *rdomain; + char *line, *laddr, *logfile = NULL; + u_int i; + u_int64_t ibytes, obytes; + mode_t new_umask; + Authctxt *authctxt; + struct connection_info *connection_info = NULL; + sigset_t sigmask; + uint64_t timing_secret = 0; + + sigemptyset(&sigmask); + sigprocmask(SIG_SETMASK, &sigmask, NULL); + + /* Save argv. */ + saved_argv = av; + + /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ + sanitise_stdfd(); + + /* Initialize configuration options to their default values. */ + initialize_server_options(&options); + + /* Parse command-line arguments. */ + while ((opt = getopt(ac, av, + "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtV")) != -1) { + switch (opt) { + case '4': + options.address_family = AF_INET; + break; + case '6': + options.address_family = AF_INET6; + break; + case 'f': + config_file_name = optarg; + break; + case 'c': + servconf_add_hostcert("[command-line]", 0, + &options, optarg); + break; + case 'd': + if (debug_flag == 0) { + debug_flag = 1; + options.log_level = SYSLOG_LEVEL_DEBUG1; + } else if (options.log_level < SYSLOG_LEVEL_DEBUG3) + options.log_level++; + break; + case 'D': + /* ignore */ + break; + case 'E': + logfile = optarg; + /* FALLTHROUGH */ + case 'e': + log_stderr = 1; + break; + case 'i': + inetd_flag = 1; + break; + case 'r': + /* ignore */ + break; + case 'R': + rexeced_flag = 1; + break; + case 'Q': + /* ignored */ + break; + case 'q': + options.log_level = SYSLOG_LEVEL_QUIET; + break; + case 'b': + /* protocol 1, ignored */ + break; + case 'p': + options.ports_from_cmdline = 1; + if (options.num_ports >= MAX_PORTS) { + fprintf(stderr, "too many ports.\n"); + exit(1); + } + options.ports[options.num_ports++] = a2port(optarg); + if (options.ports[options.num_ports-1] <= 0) { + fprintf(stderr, "Bad port number.\n"); + exit(1); + } + break; + case 'g': + if ((options.login_grace_time = convtime(optarg)) == -1) { + fprintf(stderr, "Invalid login grace time.\n"); + exit(1); + } + break; + case 'k': + /* protocol 1, ignored */ + break; + case 'h': + servconf_add_hostkey("[command-line]", 0, + &options, optarg, 1); + break; + case 't': + case 'T': + case 'G': + fatal("test/dump modes not supported"); + break; + case 'C': + connection_info = server_get_connection_info(ssh, 0, 0); + if (parse_server_match_testspec(connection_info, + optarg) == -1) + exit(1); + break; + case 'u': + utmp_len = (u_int)strtonum(optarg, 0, HOST_NAME_MAX+1+1, NULL); + if (utmp_len > HOST_NAME_MAX+1) { + fprintf(stderr, "Invalid utmp length.\n"); + exit(1); + } + break; + case 'o': + line = xstrdup(optarg); + if (process_server_config_line(&options, line, + "command-line", 0, NULL, NULL, &includes) != 0) + exit(1); + free(line); + break; + case 'V': + fprintf(stderr, "%s, %s\n", + SSH_VERSION, SSH_OPENSSL_VERSION); + exit(0); + default: + usage(); + break; + } + } + + /* Check that there are no remaining arguments. */ + if (optind < ac) { + fprintf(stderr, "Extra argument %s.\n", av[optind]); + exit(1); + } + + debug("sshd version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION); + + if (!rexeced_flag) + fatal("sshd-session should not be executed directly"); + + closefrom(REEXEC_MIN_FREE_FD); + +#ifdef WITH_OPENSSL + OpenSSL_add_all_algorithms(); +#endif + + /* If requested, redirect the logs to the specified logfile. */ + if (logfile != NULL) { + char *cp, pid_s[32]; + + snprintf(pid_s, sizeof(pid_s), "%ld", (unsigned long)getpid()); + cp = percent_expand(logfile, + "p", pid_s, + "P", "sshd-session", + (char *)NULL); + log_redirect_stderr_to(cp); + free(cp); + } + + /* + * Force logging to stderr until we have loaded the private host + * key (unless started from inetd) + */ + log_init(__progname, + options.log_level == SYSLOG_LEVEL_NOT_SET ? + SYSLOG_LEVEL_INFO : options.log_level, + options.log_facility == SYSLOG_FACILITY_NOT_SET ? + SYSLOG_FACILITY_AUTH : options.log_facility, + log_stderr || !inetd_flag || debug_flag); + + debug("sshd version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION); + + /* Fetch our configuration */ + if ((cfg = sshbuf_new()) == NULL) + fatal("sshbuf_new config buf failed"); + setproctitle("%s", "[rexeced]"); + recv_rexec_state(REEXEC_CONFIG_PASS_FD, cfg, &timing_secret); + close(REEXEC_CONFIG_PASS_FD); + parse_server_config(&options, "rexec", cfg, &includes, NULL, 1); + /* Fill in default values for those options not explicitly set. */ + fill_default_server_options(&options); + options.timing_secret = timing_secret; + + if (!debug_flag) { + startup_pipe = dup(REEXEC_STARTUP_PIPE_FD); + close(REEXEC_STARTUP_PIPE_FD); + /* + * Signal parent that this child is at a point where + * they can go away if they have a SIGHUP pending. + */ + (void)atomicio(vwrite, startup_pipe, "\0", 1); + } + + /* Check that options are sensible */ + if (options.authorized_keys_command_user == NULL && + (options.authorized_keys_command != NULL && + strcasecmp(options.authorized_keys_command, "none") != 0)) + fatal("AuthorizedKeysCommand set without " + "AuthorizedKeysCommandUser"); + if (options.authorized_principals_command_user == NULL && + (options.authorized_principals_command != NULL && + strcasecmp(options.authorized_principals_command, "none") != 0)) + fatal("AuthorizedPrincipalsCommand set without " + "AuthorizedPrincipalsCommandUser"); + + /* + * Check whether there is any path through configured auth methods. + * Unfortunately it is not possible to verify this generally before + * daemonisation in the presence of Match block, but this catches + * and warns for trivial misconfigurations that could break login. + */ + if (options.num_auth_methods != 0) { + for (i = 0; i < options.num_auth_methods; i++) { + if (auth2_methods_valid(options.auth_methods[i], + 1) == 0) + break; + } + if (i >= options.num_auth_methods) + fatal("AuthenticationMethods cannot be satisfied by " + "enabled authentication methods"); + } + +#ifdef WITH_OPENSSL + if (options.moduli_file != NULL) + dh_set_moduli_file(options.moduli_file); +#endif + + if (options.host_key_agent) { + if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME)) + setenv(SSH_AUTHSOCKET_ENV_NAME, + options.host_key_agent, 1); + if ((r = ssh_get_authentication_socket(NULL)) == 0) + have_agent = 1; + else + error_r(r, "Could not connect to agent \"%s\"", + options.host_key_agent); + } + + if (options.num_host_key_files != sensitive_data.num_hostkeys) { + fatal("internal error: hostkeys confused (config %u recvd %u)", + options.num_host_key_files, sensitive_data.num_hostkeys); + } + + for (i = 0; i < options.num_host_key_files; i++) { + if (sensitive_data.host_keys[i] != NULL || + (have_agent && sensitive_data.host_pubkeys[i] != NULL)) { + have_key = 1; + break; + } + } + if (!have_key) + fatal("internal error: monitor received no hostkeys"); + + /* Ensure that umask disallows at least group and world write */ + new_umask = umask(0077) | 0022; + (void) umask(new_umask); + + /* Initialize the log (it is reinitialized below in case we forked). */ + if (debug_flag) + log_stderr = 1; + log_init(__progname, options.log_level, + options.log_facility, log_stderr); + for (i = 0; i < options.num_log_verbose; i++) + log_verbose_add(options.log_verbose[i]); + + /* Reinitialize the log (because of the fork above). */ + log_init(__progname, options.log_level, options.log_facility, log_stderr); + + /* + * Chdir to the root directory so that the current disk can be + * unmounted if desired. + */ + if (chdir("/") == -1) + error("chdir(\"/\"): %s", strerror(errno)); + + /* ignore SIGPIPE */ + ssh_signal(SIGPIPE, SIG_IGN); + + /* Get a connection, either from inetd or rexec */ + if (inetd_flag) { + /* + * NB. must be different fd numbers for the !socket case, + * as packet_connection_is_on_socket() depends on this. + */ + sock_in = dup(STDIN_FILENO); + sock_out = dup(STDOUT_FILENO); + } else { + /* rexec case; accept()ed socket in ancestor listener */ + sock_in = sock_out = dup(STDIN_FILENO); + } + + /* + * We intentionally do not close the descriptors 0, 1, and 2 + * as our code for setting the descriptors won't work if + * ttyfd happens to be one of those. + */ + if (stdfd_devnull(1, 1, !log_stderr) == -1) + error("stdfd_devnull failed"); + debug("network sockets: %d, %d", sock_in, sock_out); + + /* This is the child processing a new connection. */ + setproctitle("%s", "[accepted]"); + + /* Executed child processes don't need these. */ + fcntl(sock_out, F_SETFD, FD_CLOEXEC); + fcntl(sock_in, F_SETFD, FD_CLOEXEC); + + /* We will not restart on SIGHUP since it no longer makes sense. */ + ssh_signal(SIGALRM, SIG_DFL); + ssh_signal(SIGHUP, SIG_DFL); + ssh_signal(SIGTERM, SIG_DFL); + ssh_signal(SIGQUIT, SIG_DFL); + ssh_signal(SIGCHLD, SIG_DFL); + + /* + * Register our connection. This turns encryption off because we do + * not have a key. + */ + if ((ssh = ssh_packet_set_connection(NULL, sock_in, sock_out)) == NULL) + fatal("Unable to create connection"); + the_active_state = ssh; + ssh_packet_set_server(ssh); + + check_ip_options(ssh); + + /* Prepare the channels layer */ + channel_init_channels(ssh); + channel_set_af(ssh, options.address_family); + server_process_channel_timeouts(ssh); + server_process_permitopen(ssh); + + /* Set SO_KEEPALIVE if requested. */ + if (options.tcp_keep_alive && ssh_packet_connection_is_on_socket(ssh) && + setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) == -1) + error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); + + if ((remote_port = ssh_remote_port(ssh)) < 0) { + debug("ssh_remote_port failed"); + cleanup_exit(255); + } + + /* + * The rest of the code depends on the fact that + * ssh_remote_ipaddr() caches the remote ip, even if + * the socket goes away. + */ + remote_ip = ssh_remote_ipaddr(ssh); + + rdomain = ssh_packet_rdomain_in(ssh); + + /* Log the connection. */ + laddr = get_local_ipaddr(sock_in); + verbose("Connection from %s port %d on %s port %d%s%s%s", + remote_ip, remote_port, laddr, ssh_local_port(ssh), + rdomain == NULL ? "" : " rdomain \"", + rdomain == NULL ? "" : rdomain, + rdomain == NULL ? "" : "\""); + free(laddr); + + /* + * We don't want to listen forever unless the other side + * successfully authenticates itself. So we set up an alarm which is + * cleared after successful authentication. A limit of zero + * indicates no limit. Note that we don't set the alarm in debugging + * mode; it is just annoying to have the server exit just when you + * are about to discover the bug. + */ + ssh_signal(SIGALRM, grace_alarm_handler); + if (!debug_flag) + alarm(options.login_grace_time); + + if ((r = kex_exchange_identification(ssh, -1, + options.version_addendum)) != 0) + sshpkt_fatal(ssh, r, "banner exchange"); + + ssh_packet_set_nonblocking(ssh); + + /* allocate authentication context */ + authctxt = xcalloc(1, sizeof(*authctxt)); + ssh->authctxt = authctxt; + + /* XXX global for cleanup, access from other modules */ + the_authctxt = authctxt; + + /* Set default key authentication options */ + if ((auth_opts = sshauthopt_new_with_keys_defaults()) == NULL) + fatal("allocation failed"); + + /* prepare buffer to collect messages to display to user after login */ + if ((loginmsg = sshbuf_new()) == NULL) + fatal("sshbuf_new loginmsg failed"); + auth_debug_reset(); + + if (privsep_preauth(ssh) == 1) + goto authenticated; + + /* perform the key exchange */ + /* authenticate user and start session */ + do_ssh2_kex(ssh); + do_authentication2(ssh); + + /* + * The unprivileged child now transfers the current keystate and exits. + */ + mm_send_keystate(ssh, pmonitor); + ssh_packet_clear_keys(ssh); + exit(0); + + authenticated: + /* + * Cancel the alarm we set to limit the time taken for + * authentication. + */ + alarm(0); + ssh_signal(SIGALRM, SIG_DFL); + authctxt->authenticated = 1; + if (startup_pipe != -1) { + close(startup_pipe); + startup_pipe = -1; + } + + if (options.routing_domain != NULL) + set_process_rdomain(ssh, options.routing_domain); + + /* + * In privilege separation, we fork another child and prepare + * file descriptor passing. + */ + privsep_postauth(ssh, authctxt); + /* the monitor process [priv] will not return */ + + ssh_packet_set_timeout(ssh, options.client_alive_interval, + options.client_alive_count_max); + + /* Try to send all our hostkeys to the client */ + notify_hostkeys(ssh); + + /* Start session. */ + do_authenticated(ssh, authctxt); + + /* The connection has been terminated. */ + ssh_packet_get_bytes(ssh, &ibytes, &obytes); + verbose("Transferred: sent %llu, received %llu bytes", + (unsigned long long)obytes, (unsigned long long)ibytes); + + verbose("Closing connection to %.500s port %d", remote_ip, remote_port); + ssh_packet_close(ssh); + + mm_terminate(); + + exit(0); +} + +int +sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey, + struct sshkey *pubkey, u_char **signature, size_t *slenp, + const u_char *data, size_t dlen, const char *alg) +{ + if (privkey) { + if (mm_sshkey_sign(ssh, privkey, signature, slenp, + data, dlen, alg, options.sk_provider, NULL, + ssh->compat) < 0) + fatal_f("privkey sign failed"); + } else { + if (mm_sshkey_sign(ssh, pubkey, signature, slenp, + data, dlen, alg, options.sk_provider, NULL, + ssh->compat) < 0) + fatal_f("pubkey sign failed"); + } + return 0; +} + +/* SSH2 key exchange */ +static void +do_ssh2_kex(struct ssh *ssh) +{ + char *hkalgs = NULL, *myproposal[PROPOSAL_MAX]; + const char *compression = NULL; + struct kex *kex; + int r; + + if (options.rekey_limit || options.rekey_interval) + ssh_packet_set_rekey_limits(ssh, options.rekey_limit, + options.rekey_interval); + + if (options.compression == COMP_NONE) + compression = "none"; + hkalgs = list_hostkey_types(); + + kex_proposal_populate_entries(ssh, myproposal, options.kex_algorithms, + options.ciphers, options.macs, compression, hkalgs); + + free(hkalgs); + + /* start key exchange */ + if ((r = kex_setup(ssh, myproposal)) != 0) + fatal_r(r, "kex_setup"); + kex_set_server_sig_algs(ssh, options.pubkey_accepted_algos); + kex = ssh->kex; + +#ifdef WITH_OPENSSL + kex->kex[KEX_DH_GRP1_SHA1] = kex_gen_server; + kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_server; + kex->kex[KEX_DH_GRP14_SHA256] = kex_gen_server; + kex->kex[KEX_DH_GRP16_SHA512] = kex_gen_server; + kex->kex[KEX_DH_GRP18_SHA512] = kex_gen_server; + kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; + kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; + kex->kex[KEX_ECDH_SHA2] = kex_gen_server; +#endif + kex->kex[KEX_C25519_SHA256] = kex_gen_server; + kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; + kex->load_host_public_key=&get_hostkey_public_by_type; + kex->load_host_private_key=&get_hostkey_private_by_type; + kex->host_key_index=&get_hostkey_index; + kex->sign = sshd_hostkey_sign; + + ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &kex->done); + kex_proposal_free_entries(myproposal); + +#ifdef DEBUG_KEXDH + /* send 1st encrypted/maced/compressed message */ + if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 || + (r = sshpkt_put_cstring(ssh, "markus")) != 0 || + (r = sshpkt_send(ssh)) != 0 || + (r = ssh_packet_write_wait(ssh)) != 0) + fatal_fr(r, "send test"); +#endif + debug("KEX done"); +} + +/* server specific fatal cleanup */ +void +cleanup_exit(int i) +{ + if (the_active_state != NULL && the_authctxt != NULL) { + do_cleanup(the_active_state, the_authctxt); + if (privsep_is_preauth && + pmonitor != NULL && pmonitor->m_pid > 1) { + debug("Killing privsep child %d", pmonitor->m_pid); + if (kill(pmonitor->m_pid, SIGKILL) != 0 && + errno != ESRCH) { + error_f("kill(%d): %s", pmonitor->m_pid, + strerror(errno)); + } + } + } + _exit(i); +} diff --git a/usr.bin/ssh/sshd-session/Makefile b/usr.bin/ssh/sshd-session/Makefile new file mode 100644 index 000000000..40d5ee270 --- /dev/null +++ b/usr.bin/ssh/sshd-session/Makefile @@ -0,0 +1,71 @@ +# $OpenBSD: Makefile,v 1.3 2024/05/17 14:42:00 naddy Exp $ + +.PATH: ${.CURDIR}/.. + +SRCS= sshd-session.c auth2-methods.c \ + auth-rhosts.c auth-passwd.c sshpty.c sshlogin.c servconf.c \ + serverloop.c auth.c auth2.c auth-options.c session.c auth2-chall.c \ + groupaccess.c auth-bsdauth.c auth2-hostbased.c auth2-kbdint.c \ + auth2-none.c auth2-passwd.c auth2-pubkey.c auth2-pubkeyfile.c \ + monitor.c monitor_wrap.c \ + sftp-server.c sftp-common.c sftp-realpath.c sandbox-pledge.c srclimit.c +SRCS+= authfd.c compat.c dns.c fatal.c hostfile.c readpass.c utf8.c uidswap.c +SRCS+= ${SRCS_BASE} ${SRCS_KEX} ${SRCS_KEXS} ${SRCS_KEY} ${SRCS_KEYP} \ + ${SRCS_KRL} ${SRCS_PROT} ${SRCS_PKT} ${SRCS_UTL} ${SRCS_PKCS11} \ + ${SRCS_SK_CLIENT} + +PROG= sshd-session +BINDIR= /usr/libexec +BINMODE=511 +NOMAN= 1 + +.include # for KERBEROS and AFS + +KERBEROS5=no + +.if (${KERBEROS5:L} == "yes") +CFLAGS+=-DKRB5 -I${DESTDIR}/usr/include/kerberosV -DGSSAPI +SRCS+= auth-krb5.c auth2-gss.c gss-serv.c gss-serv-krb5.c +.endif + +.include + +.if (${KERBEROS5:L} == "yes") +LDADD+= -lgssapi -lkrb5 -lasn1 +LDADD+= -lwind -lroken -lcom_err -lpthread -lheimbase -lkafs +DPADD+= ${LIBGSSAPI} ${LIBKRB5} +.endif + +.if (${OPENSSL:L} == "yes") +LDADD+= -lcrypto +DPADD+= ${LIBCRYPTO} +.endif + +LDADD+= -lutil +DPADD+= ${LIBUTIL} + +.if (${ZLIB:L} == "yes") +LDADD+= -lz +DPADD+= ${LIBZ} +.endif + +# The random relink kit, used on OpenBSD by /etc/rc + +CLEANFILES+= ${PROG}.tar install.sh + +install.sh: Makefile + echo "set -o errexit" > $@ + echo "${CC} ${LDFLAGS} ${LDSTATIC} -o ${PROG}" \ + "\`echo " ${OBJS} "| tr ' ' '\\\n' | sort -R\`" ${LDADD} >> $@ + echo "./${PROG} -V # test it works" >> $@ + echo "install -c -s -o root -g bin -m ${BINMODE} ${PROG} " \ + "${BINDIR}/${PROG}" >> $@ + +${PROG}.tar: ${OBJS} install.sh + tar cf $@ ${OBJS} install.sh + +afterinstall: ${PROG}.tar + install -d -o root -g wheel -m 755 \ + ${DESTDIR}/usr/share/relink/${BINDIR}/${PROG} + install -o ${BINOWN} -g ${BINGRP} -m 640 \ + ${PROG}.tar ${DESTDIR}/usr/share/relink/${BINDIR}/${PROG}/${PROG}.tar diff --git a/usr.bin/ssh/sshd.c b/usr.bin/ssh/sshd.c index a5d56e9fa..683b0b885 100644 --- a/usr.bin/ssh/sshd.c +++ b/usr.bin/ssh/sshd.c @@ -1,23 +1,5 @@ -/* $OpenBSD: sshd.c,v 1.602 2024/01/08 00:34:34 djm Exp $ */ +/* $OpenBSD: sshd.c,v 1.603 2024/05/17 00:30:24 djm Exp $ */ /* - * Author: Tatu Ylonen - * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland - * All rights reserved - * This program is the ssh daemon. It listens for connections from clients, - * and performs authentication, executes use commands or shell, and forwards - * information to/from the application to the user client over an encrypted - * connection. This can also handle forwarding of X11, TCP/IP, and - * authentication agent connections. - * - * As far as I am concerned, the code I have written for this software - * can be used freely for any purpose. Any derived versions of this - * software must be clearly marked as such, and if the derived work is - * incompatible with the protocol description in the RFC file, it must be - * called by a name other than "ssh" or "Secure Shell". - * - * SSH2 implementation: - * Privilege Separation: - * * Copyright (c) 2000, 2001, 2002 Markus Friedl. All rights reserved. * Copyright (c) 2002 Niels Provos. All rights reserved. * @@ -67,47 +49,30 @@ #ifdef WITH_OPENSSL #include +#include #endif #include "xmalloc.h" #include "ssh.h" -#include "ssh2.h" #include "sshpty.h" -#include "packet.h" #include "log.h" #include "sshbuf.h" #include "misc.h" -#include "match.h" #include "servconf.h" -#include "uidswap.h" #include "compat.h" -#include "cipher.h" #include "digest.h" #include "sshkey.h" -#include "kex.h" #include "authfile.h" #include "pathnames.h" -#include "atomicio.h" #include "canohost.h" #include "hostfile.h" #include "auth.h" #include "authfd.h" #include "msg.h" -#include "dispatch.h" -#include "channels.h" -#include "session.h" -#include "monitor.h" -#ifdef GSSAPI -#include "ssh-gss.h" -#endif -#include "monitor_wrap.h" -#include "ssh-sandbox.h" -#include "auth-options.h" #include "version.h" #include "ssherr.h" #include "sk-api.h" #include "srclimit.h" -#include "dh.h" /* Re-exec fds */ #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) @@ -120,9 +85,6 @@ extern char *__progname; /* Server configuration options. */ ServerOptions options; -/* Name of the server configuration file. */ -char *config_file_name = _PATH_SERVER_CONFIG_FILE; - /* * Debug mode flag. This can be set on the command line. If debug * mode is enabled, extra debugging output will be sent to the system @@ -131,32 +93,9 @@ char *config_file_name = _PATH_SERVER_CONFIG_FILE; */ int debug_flag = 0; -/* - * Indicating that the daemon should only test the configuration and keys. - * If test_flag > 1 ("-T" flag), then sshd will also dump the effective - * configuration, optionally using connection information provided by the - * "-C" flag. - */ -static int test_flag = 0; - -/* Flag indicating that the daemon is being started from inetd. */ -static int inetd_flag = 0; - -/* Flag indicating that sshd should not detach and become a daemon. */ -static int no_daemon_flag = 0; - -/* debug goes to stderr unless inetd_flag is set */ -static int log_stderr = 0; - /* Saved arguments to main(). */ static char **saved_argv; -/* re-exec */ -static int rexeced_flag = 0; -static int rexec_flag = 1; -static int rexec_argc = 0; -static char **rexec_argv; - /* * The sockets that the server is listening; this is used in the SIGHUP * signal handler. @@ -165,10 +104,6 @@ static char **rexec_argv; static int listen_socks[MAX_LISTEN_SOCKS]; static int num_listen_socks = 0; -/* Daemon's agent connection */ -int auth_sock = -1; -static int have_agent = 0; - /* * Any really sensitive data in the application is contained in this * structure. The idea is that this structure could be locked into memory so @@ -212,18 +147,6 @@ static int *startup_pipes = NULL; static int *startup_flags = NULL; /* Indicates child closed listener */ static int startup_pipe = -1; /* in child */ -/* variables used for privilege separation */ -int use_privsep = -1; -struct monitor *pmonitor = NULL; -int privsep_is_preauth = 1; - -/* global connection state and authentication contexts */ -Authctxt *the_authctxt = NULL; -struct ssh *the_active_state; - -/* global key/cert auth options. XXX move to permanent ssh->authctxt? */ -struct sshauthopt *auth_opts = NULL; - /* sshd_config buffer */ struct sshbuf *cfg; @@ -233,11 +156,6 @@ struct include_list includes = TAILQ_HEAD_INITIALIZER(includes); /* message to be displayed after login */ struct sshbuf *loginmsg; -/* Prototypes for various functions defined later in this file. */ -void destroy_sensitive_data(void); -void demote_sensitive_data(void); -static void do_ssh2_kex(struct ssh *); - static char *listener_proctitle; /* @@ -321,446 +239,6 @@ main_sigchld_handler(int sig) errno = save_errno; } -/* - * Signal handler for the alarm after the login grace period has expired. - */ -static void -grace_alarm_handler(int sig) -{ - /* - * Try to kill any processes that we have spawned, E.g. authorized - * keys command helpers or privsep children. - */ - if (getpgid(0) == getpid()) { - ssh_signal(SIGTERM, SIG_IGN); - kill(0, SIGTERM); - } - - /* Log error and exit. */ - sigdie("Timeout before authentication for %s port %d", - ssh_remote_ipaddr(the_active_state), - ssh_remote_port(the_active_state)); -} - -/* Destroy the host and server keys. They will no longer be needed. */ -void -destroy_sensitive_data(void) -{ - u_int i; - - for (i = 0; i < options.num_host_key_files; i++) { - if (sensitive_data.host_keys[i]) { - sshkey_free(sensitive_data.host_keys[i]); - sensitive_data.host_keys[i] = NULL; - } - if (sensitive_data.host_certificates[i]) { - sshkey_free(sensitive_data.host_certificates[i]); - sensitive_data.host_certificates[i] = NULL; - } - } -} - -/* Demote private to public keys for network child */ -void -demote_sensitive_data(void) -{ - struct sshkey *tmp; - u_int i; - int r; - - for (i = 0; i < options.num_host_key_files; i++) { - if (sensitive_data.host_keys[i]) { - if ((r = sshkey_from_private( - sensitive_data.host_keys[i], &tmp)) != 0) - fatal_r(r, "could not demote host %s key", - sshkey_type(sensitive_data.host_keys[i])); - sshkey_free(sensitive_data.host_keys[i]); - sensitive_data.host_keys[i] = tmp; - } - /* Certs do not need demotion */ - } -} - -static void -privsep_preauth_child(void) -{ - gid_t gidset[1]; - struct passwd *pw; - - /* Enable challenge-response authentication for privilege separation */ - privsep_challenge_enable(); - -#ifdef GSSAPI - /* Cache supported mechanism OIDs for later use */ - ssh_gssapi_prepare_supported_oids(); -#endif - - /* Demote the private keys to public keys. */ - demote_sensitive_data(); - - /* Demote the child */ - if (getuid() == 0 || geteuid() == 0) { - if ((pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) - fatal("Privilege separation user %s does not exist", - SSH_PRIVSEP_USER); - pw = pwcopy(pw); /* Ensure mutable */ - endpwent(); - freezero(pw->pw_passwd, strlen(pw->pw_passwd)); - - /* Change our root directory */ - if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) - fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, - strerror(errno)); - if (chdir("/") == -1) - fatal("chdir(\"/\"): %s", strerror(errno)); - - /* - * Drop our privileges - * NB. Can't use setusercontext() after chroot. - */ - debug3("privsep user:group %u:%u", (u_int)pw->pw_uid, - (u_int)pw->pw_gid); - gidset[0] = pw->pw_gid; - if (setgroups(1, gidset) == -1) - fatal("setgroups: %.100s", strerror(errno)); - permanently_set_uid(pw); - } -} - -static int -privsep_preauth(struct ssh *ssh) -{ - int status, r; - pid_t pid; - struct ssh_sandbox *box = NULL; - - /* Set up unprivileged child process to deal with network data */ - pmonitor = monitor_init(); - /* Store a pointer to the kex for later rekeying */ - pmonitor->m_pkex = &ssh->kex; - - if (use_privsep == PRIVSEP_ON) - box = ssh_sandbox_init(); - pid = fork(); - if (pid == -1) { - fatal("fork of unprivileged child failed"); - } else if (pid != 0) { - debug2("Network child is on pid %ld", (long)pid); - - pmonitor->m_pid = pid; - if (have_agent) { - r = ssh_get_authentication_socket(&auth_sock); - if (r != 0) { - error_r(r, "Could not get agent socket"); - have_agent = 0; - } - } - if (box != NULL) - ssh_sandbox_parent_preauth(box, pid); - monitor_child_preauth(ssh, pmonitor); - - /* Wait for the child's exit status */ - while (waitpid(pid, &status, 0) == -1) { - if (errno == EINTR) - continue; - pmonitor->m_pid = -1; - fatal_f("waitpid: %s", strerror(errno)); - } - privsep_is_preauth = 0; - pmonitor->m_pid = -1; - if (WIFEXITED(status)) { - if (WEXITSTATUS(status) != 0) - fatal_f("preauth child exited with status %d", - WEXITSTATUS(status)); - } else if (WIFSIGNALED(status)) - fatal_f("preauth child terminated by signal %d", - WTERMSIG(status)); - if (box != NULL) - ssh_sandbox_parent_finish(box); - return 1; - } else { - /* child */ - close(pmonitor->m_sendfd); - close(pmonitor->m_log_recvfd); - - /* Arrange for logging to be sent to the monitor */ - set_log_handler(mm_log_handler, pmonitor); - - privsep_preauth_child(); - setproctitle("%s", "[net]"); - if (box != NULL) - ssh_sandbox_child(box); - - return 0; - } -} - -static void -privsep_postauth(struct ssh *ssh, Authctxt *authctxt) -{ - if (authctxt->pw->pw_uid == 0) { - /* File descriptor passing is broken or root login */ - use_privsep = 0; - goto skip; - } - - /* New socket pair */ - monitor_reinit(pmonitor); - - pmonitor->m_pid = fork(); - if (pmonitor->m_pid == -1) - fatal("fork of unprivileged child failed"); - else if (pmonitor->m_pid != 0) { - verbose("User child is on pid %ld", (long)pmonitor->m_pid); - sshbuf_reset(loginmsg); - monitor_clear_keystate(ssh, pmonitor); - monitor_child_postauth(ssh, pmonitor); - - /* NEVERREACHED */ - exit(0); - } - - /* child */ - - close(pmonitor->m_sendfd); - pmonitor->m_sendfd = -1; - - /* Demote the private keys to public keys. */ - demote_sensitive_data(); - - /* Drop privileges */ - do_setusercontext(authctxt->pw); - - skip: - /* It is safe now to apply the key state */ - monitor_apply_keystate(ssh, pmonitor); - - /* - * Tell the packet layer that authentication was successful, since - * this information is not part of the key state. - */ - ssh_packet_set_authenticated(ssh); -} - -static void -append_hostkey_type(struct sshbuf *b, const char *s) -{ - int r; - - if (match_pattern_list(s, options.hostkeyalgorithms, 0) != 1) { - debug3_f("%s key not permitted by HostkeyAlgorithms", s); - return; - } - if ((r = sshbuf_putf(b, "%s%s", sshbuf_len(b) > 0 ? "," : "", s)) != 0) - fatal_fr(r, "sshbuf_putf"); -} - -static char * -list_hostkey_types(void) -{ - struct sshbuf *b; - struct sshkey *key; - char *ret; - u_int i; - - if ((b = sshbuf_new()) == NULL) - fatal_f("sshbuf_new failed"); - for (i = 0; i < options.num_host_key_files; i++) { - key = sensitive_data.host_keys[i]; - if (key == NULL) - key = sensitive_data.host_pubkeys[i]; - if (key == NULL) - continue; - switch (key->type) { - case KEY_RSA: - /* for RSA we also support SHA2 signatures */ - append_hostkey_type(b, "rsa-sha2-512"); - append_hostkey_type(b, "rsa-sha2-256"); - /* FALLTHROUGH */ - case KEY_DSA: - case KEY_ECDSA: - case KEY_ED25519: - case KEY_ECDSA_SK: - case KEY_ED25519_SK: - case KEY_XMSS: - append_hostkey_type(b, sshkey_ssh_name(key)); - break; - } - /* If the private key has a cert peer, then list that too */ - key = sensitive_data.host_certificates[i]; - if (key == NULL) - continue; - switch (key->type) { - case KEY_RSA_CERT: - /* for RSA we also support SHA2 signatures */ - append_hostkey_type(b, - "rsa-sha2-512-cert-v01@openssh.com"); - append_hostkey_type(b, - "rsa-sha2-256-cert-v01@openssh.com"); - /* FALLTHROUGH */ - case KEY_DSA_CERT: - case KEY_ECDSA_CERT: - case KEY_ED25519_CERT: - case KEY_ECDSA_SK_CERT: - case KEY_ED25519_SK_CERT: - case KEY_XMSS_CERT: - append_hostkey_type(b, sshkey_ssh_name(key)); - break; - } - } - if ((ret = sshbuf_dup_string(b)) == NULL) - fatal_f("sshbuf_dup_string failed"); - sshbuf_free(b); - debug_f("%s", ret); - return ret; -} - -static struct sshkey * -get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh) -{ - u_int i; - struct sshkey *key; - - for (i = 0; i < options.num_host_key_files; i++) { - switch (type) { - case KEY_RSA_CERT: - case KEY_DSA_CERT: - case KEY_ECDSA_CERT: - case KEY_ED25519_CERT: - case KEY_ECDSA_SK_CERT: - case KEY_ED25519_SK_CERT: - case KEY_XMSS_CERT: - key = sensitive_data.host_certificates[i]; - break; - default: - key = sensitive_data.host_keys[i]; - if (key == NULL && !need_private) - key = sensitive_data.host_pubkeys[i]; - break; - } - if (key == NULL || key->type != type) - continue; - switch (type) { - case KEY_ECDSA: - case KEY_ECDSA_SK: - case KEY_ECDSA_CERT: - case KEY_ECDSA_SK_CERT: - if (key->ecdsa_nid != nid) - continue; - /* FALLTHROUGH */ - default: - return need_private ? - sensitive_data.host_keys[i] : key; - } - } - return NULL; -} - -struct sshkey * -get_hostkey_public_by_type(int type, int nid, struct ssh *ssh) -{ - return get_hostkey_by_type(type, nid, 0, ssh); -} - -struct sshkey * -get_hostkey_private_by_type(int type, int nid, struct ssh *ssh) -{ - return get_hostkey_by_type(type, nid, 1, ssh); -} - -struct sshkey * -get_hostkey_by_index(int ind) -{ - if (ind < 0 || (u_int)ind >= options.num_host_key_files) - return (NULL); - return (sensitive_data.host_keys[ind]); -} - -struct sshkey * -get_hostkey_public_by_index(int ind, struct ssh *ssh) -{ - if (ind < 0 || (u_int)ind >= options.num_host_key_files) - return (NULL); - return (sensitive_data.host_pubkeys[ind]); -} - -int -get_hostkey_index(struct sshkey *key, int compare, struct ssh *ssh) -{ - u_int i; - - for (i = 0; i < options.num_host_key_files; i++) { - if (sshkey_is_cert(key)) { - if (key == sensitive_data.host_certificates[i] || - (compare && sensitive_data.host_certificates[i] && - sshkey_equal(key, - sensitive_data.host_certificates[i]))) - return (i); - } else { - if (key == sensitive_data.host_keys[i] || - (compare && sensitive_data.host_keys[i] && - sshkey_equal(key, sensitive_data.host_keys[i]))) - return (i); - if (key == sensitive_data.host_pubkeys[i] || - (compare && sensitive_data.host_pubkeys[i] && - sshkey_equal(key, sensitive_data.host_pubkeys[i]))) - return (i); - } - } - return (-1); -} - -/* Inform the client of all hostkeys */ -static void -notify_hostkeys(struct ssh *ssh) -{ - struct sshbuf *buf; - struct sshkey *key; - u_int i, nkeys; - int r; - char *fp; - - /* Some clients cannot cope with the hostkeys message, skip those. */ - if (ssh->compat & SSH_BUG_HOSTKEYS) - return; - - if ((buf = sshbuf_new()) == NULL) - fatal_f("sshbuf_new"); - for (i = nkeys = 0; i < options.num_host_key_files; i++) { - key = get_hostkey_public_by_index(i, ssh); - if (key == NULL || key->type == KEY_UNSPEC || - sshkey_is_cert(key)) - continue; - fp = sshkey_fingerprint(key, options.fingerprint_hash, - SSH_FP_DEFAULT); - debug3_f("key %d: %s %s", i, sshkey_ssh_name(key), fp); - free(fp); - if (nkeys == 0) { - /* - * Start building the request when we find the - * first usable key. - */ - if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 || - (r = sshpkt_put_cstring(ssh, "hostkeys-00@openssh.com")) != 0 || - (r = sshpkt_put_u8(ssh, 0)) != 0) /* want reply */ - sshpkt_fatal(ssh, r, "%s: start request", __func__); - } - /* Append the key to the request */ - sshbuf_reset(buf); - if ((r = sshkey_putb(key, buf)) != 0) - fatal_fr(r, "couldn't put hostkey %d", i); - if ((r = sshpkt_put_stringb(ssh, buf)) != 0) - sshpkt_fatal(ssh, r, "%s: append key", __func__); - nkeys++; - } - debug3_f("sent %u hostkeys", nkeys); - if (nkeys == 0) - fatal_f("no hostkeys"); - if ((r = sshpkt_send(ssh)) != 0) - sshpkt_fatal(ssh, r, "%s: send", __func__); - sshbuf_free(buf); -} - /* * returns 1 if connection should be dropped, 0 otherwise. * dropping starts at connection #max_startups_begin with a probability @@ -860,17 +338,64 @@ usage(void) exit(1); } +static struct sshbuf * +pack_hostkeys(void) +{ + struct sshbuf *keybuf = NULL, *hostkeys = NULL; + int r; + u_int i; + + if ((keybuf = sshbuf_new()) == NULL || + (hostkeys = sshbuf_new()) == NULL) + fatal_f("sshbuf_new failed"); + + /* pack hostkeys into a string. Empty key slots get empty strings */ + for (i = 0; i < options.num_host_key_files; i++) { + /* private key */ + sshbuf_reset(keybuf); + if (sensitive_data.host_keys[i] != NULL && + (r = sshkey_private_serialize(sensitive_data.host_keys[i], + keybuf)) != 0) + fatal_fr(r, "serialize hostkey private"); + if ((r = sshbuf_put_stringb(hostkeys, keybuf)) != 0) + fatal_fr(r, "compose hostkey private"); + /* public key */ + if (sensitive_data.host_pubkeys[i] != NULL) { + if ((r = sshkey_puts(sensitive_data.host_pubkeys[i], + hostkeys)) != 0) + fatal_fr(r, "compose hostkey public"); + } else { + if ((r = sshbuf_put_string(hostkeys, NULL, 0)) != 0) + fatal_fr(r, "compose hostkey empty public"); + } + /* cert */ + if (sensitive_data.host_certificates[i] != NULL) { + if ((r = sshkey_puts( + sensitive_data.host_certificates[i], + hostkeys)) != 0) + fatal_fr(r, "compose host cert"); + } else { + if ((r = sshbuf_put_string(hostkeys, NULL, 0)) != 0) + fatal_fr(r, "compose host cert empty"); + } + } + + sshbuf_free(keybuf); + return hostkeys; +} + static void send_rexec_state(int fd, struct sshbuf *conf) { - struct sshbuf *m = NULL, *inc = NULL; + struct sshbuf *m = NULL, *inc = NULL, *hostkeys = NULL; struct include_item *item = NULL; - int r; + int r, sz; debug3_f("entering fd = %d config len %zu", fd, sshbuf_len(conf)); - if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL) + if ((m = sshbuf_new()) == NULL || + (inc = sshbuf_new()) == NULL) fatal_f("sshbuf_new failed"); /* pack includes into a string */ @@ -881,9 +406,17 @@ send_rexec_state(int fd, struct sshbuf *conf) fatal_fr(r, "compose includes"); } + hostkeys = pack_hostkeys(); + /* * Protocol from reexec master to child: * string configuration + * uint64 timing_secret + * string host_keys[] { + * string private_key + * string public_key + * string certificate + * } * string included_files[] { * string selector * string filename @@ -891,81 +424,26 @@ send_rexec_state(int fd, struct sshbuf *conf) * } */ if ((r = sshbuf_put_stringb(m, conf)) != 0 || + (r = sshbuf_put_u64(m, options.timing_secret)) != 0 || + (r = sshbuf_put_stringb(m, hostkeys)) != 0 || (r = sshbuf_put_stringb(m, inc)) != 0) fatal_fr(r, "compose config"); + + /* We need to fit the entire message inside the socket send buffer */ + sz = ROUNDUP(sshbuf_len(m) + 5, 16*1024); + if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sz, sizeof sz) == -1) + fatal_f("setsockopt SO_SNDBUF: %s", strerror(errno)); + if (ssh_msg_send(fd, 0, m) == -1) error_f("ssh_msg_send failed"); sshbuf_free(m); sshbuf_free(inc); + sshbuf_free(hostkeys); debug3_f("done"); } -static void -recv_rexec_state(int fd, struct sshbuf *conf) -{ - struct sshbuf *m, *inc; - u_char *cp, ver; - size_t len; - int r; - struct include_item *item; - - debug3_f("entering fd = %d", fd); - - if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL) - fatal_f("sshbuf_new failed"); - if (ssh_msg_recv(fd, m) == -1) - fatal_f("ssh_msg_recv failed"); - if ((r = sshbuf_get_u8(m, &ver)) != 0) - fatal_fr(r, "parse version"); - if (ver != 0) - fatal_f("rexec version mismatch"); - if ((r = sshbuf_get_string(m, &cp, &len)) != 0 || - (r = sshbuf_get_stringb(m, inc)) != 0) - fatal_fr(r, "parse config"); - - if (conf != NULL && (r = sshbuf_put(conf, cp, len))) - fatal_fr(r, "sshbuf_put"); - - while (sshbuf_len(inc) != 0) { - item = xcalloc(1, sizeof(*item)); - if ((item->contents = sshbuf_new()) == NULL) - fatal_f("sshbuf_new failed"); - if ((r = sshbuf_get_cstring(inc, &item->selector, NULL)) != 0 || - (r = sshbuf_get_cstring(inc, &item->filename, NULL)) != 0 || - (r = sshbuf_get_stringb(inc, item->contents)) != 0) - fatal_fr(r, "parse includes"); - TAILQ_INSERT_TAIL(&includes, item, entry); - } - - free(cp); - sshbuf_free(m); - - debug3_f("done"); -} - -/* Accept a connection from inetd */ -static void -server_accept_inetd(int *sock_in, int *sock_out) -{ - if (rexeced_flag) { - close(REEXEC_CONFIG_PASS_FD); - *sock_in = *sock_out = dup(STDIN_FILENO); - } else { - *sock_in = dup(STDIN_FILENO); - *sock_out = dup(STDOUT_FILENO); - } - /* - * We intentionally do not close the descriptors 0, 1, and 2 - * as our code for setting the descriptors won't work if - * ttyfd happens to be one of those. - */ - if (stdfd_devnull(1, 1, !log_stderr) == -1) - error_f("stdfd_devnull failed"); - debug("inetd sockets after dupping: %d, %d", *sock_in, *sock_out); -} - /* * Listen for TCP connections */ @@ -1066,7 +544,8 @@ server_listen(void) * from this function are in a forked subprocess. */ static void -server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) +server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s, + int log_stderr) { struct pollfd *pfd = NULL; int i, j, ret, npfd; @@ -1223,7 +702,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) continue; } - if (rexec_flag && socketpair(AF_UNIX, + if (socketpair(AF_UNIX, SOCK_STREAM, 0, config_s) == -1) { error("reexec socketpair: %s", strerror(errno)); @@ -1259,10 +738,8 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) close(startup_p[1]); startup_pipe = -1; pid = getpid(); - if (rexec_flag) { - send_rexec_state(config_s[0], cfg); - close(config_s[0]); - } + send_rexec_state(config_s[0], cfg); + close(config_s[0]); free(pfd); return; } @@ -1291,19 +768,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) options.log_level, options.log_facility, log_stderr); - if (rexec_flag) - close(config_s[0]); - else { - /* - * Signal parent that the preliminaries - * for this child are complete. For the - * re-exec case, this happens after the - * child has received the rexec state - * from the server. - */ - (void)atomicio(vwrite, startup_pipe, - "\0", 1); - } + close(config_s[0]); free(pfd); return; } @@ -1316,81 +781,14 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) close(startup_p[1]); - if (rexec_flag) { - close(config_s[1]); - send_rexec_state(config_s[0], cfg); - close(config_s[0]); - } + close(config_s[1]); + send_rexec_state(config_s[0], cfg); + close(config_s[0]); close(*newsock); } } } -/* - * If IP options are supported, make sure there are none (log and - * return an error if any are found). Basically we are worried about - * source routing; it can be used to pretend you are somebody - * (ip-address) you are not. That itself may be "almost acceptable" - * under certain circumstances, but rhosts authentication is useless - * if source routing is accepted. Notice also that if we just dropped - * source routing here, the other side could use IP spoofing to do - * rest of the interaction and could still bypass security. So we - * exit here if we detect any IP options. - */ -static void -check_ip_options(struct ssh *ssh) -{ - int sock_in = ssh_packet_get_connection_in(ssh); - struct sockaddr_storage from; - u_char opts[200]; - socklen_t i, option_size = sizeof(opts), fromlen = sizeof(from); - char text[sizeof(opts) * 3 + 1]; - - memset(&from, 0, sizeof(from)); - if (getpeername(sock_in, (struct sockaddr *)&from, - &fromlen) == -1) - return; - if (from.ss_family != AF_INET) - return; - /* XXX IPv6 options? */ - - if (getsockopt(sock_in, IPPROTO_IP, IP_OPTIONS, opts, - &option_size) >= 0 && option_size != 0) { - text[0] = '\0'; - for (i = 0; i < option_size; i++) - snprintf(text + i*3, sizeof(text) - i*3, - " %2.2x", opts[i]); - fatal("Connection from %.100s port %d with IP opts: %.800s", - ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), text); - } - return; -} - -/* Set the routing domain for this process */ -static void -set_process_rdomain(struct ssh *ssh, const char *name) -{ - int rtable, ortable = getrtable(); - const char *errstr; - - if (name == NULL) - return; /* default */ - - if (strcmp(name, "%D") == 0) { - /* "expands" to routing domain of connection */ - if ((name = ssh_packet_rdomain_in(ssh)) == NULL) - return; - } - - rtable = (int)strtonum(name, 0, 255, &errstr); - if (errstr != NULL) /* Shouldn't happen */ - fatal("Invalid routing domain \"%s\": %s", name, errstr); - if (rtable != ortable && setrtable(rtable) != 0) - fatal("Unable to set routing domain %d: %s", - rtable, strerror(errno)); - debug_f("set routing domain %d (was %d)", rtable, ortable); -} - static void accumulate_host_timing_secret(struct sshbuf *server_cfg, struct sshkey *key) @@ -1440,14 +838,8 @@ prepare_proctitle(int ac, char **av) } static void -print_config(struct ssh *ssh, struct connection_info *connection_info) +print_config(struct connection_info *connection_info) { - /* - * If no connection info was provided by -C then use - * use a blank one that will cause no predicate to match. - */ - if (connection_info == NULL) - connection_info = get_connection_info(ssh, 0, 0); connection_info->test = 1; parse_server_match_config(&options, &includes, connection_info); dump_config(&options); @@ -1460,24 +852,24 @@ print_config(struct ssh *ssh, struct connection_info *connection_info) int main(int ac, char **av) { - struct ssh *ssh = NULL; extern char *optarg; extern int optind; - int r, opt, on = 1, do_dump_cfg = 0, already_daemon, remote_port; - int sock_in = -1, sock_out = -1, newsock = -1; - const char *remote_ip, *rdomain; - char *fp, *line, *laddr, *logfile = NULL; - int config_s[2] = { -1 , -1 }; + int log_stderr = 0, inetd_flag = 0, test_flag = 0, no_daemon_flag = 0; + char *config_file_name = _PATH_SERVER_CONFIG_FILE; + int r, opt, do_dump_cfg = 0, keytype, already_daemon, have_agent = 0; + int sock_in = -1, sock_out = -1, newsock = -1, rexec_argc = 0; + int config_s[2] = { -1 , -1 }, have_connection_info = 0; + char *fp, *line, *logfile = NULL, **rexec_argv = NULL; + struct stat sb; u_int i, j; - u_int64_t ibytes, obytes; mode_t new_umask; struct sshkey *key; struct sshkey *pubkey; - int keytype; - Authctxt *authctxt; - struct connection_info *connection_info = NULL; + struct connection_info connection_info; sigset_t sigmask; + memset(&connection_info, 0, sizeof(connection_info)); + sigemptyset(&sigmask); sigprocmask(SIG_SETMASK, &sigmask, NULL); @@ -1531,11 +923,10 @@ main(int ac, char **av) inetd_flag = 1; break; case 'r': - rexec_flag = 0; + /* ignored */ break; case 'R': - rexeced_flag = 1; - inetd_flag = 1; + fatal("-R not supported here"); break; case 'Q': /* ignored */ @@ -1578,10 +969,10 @@ main(int ac, char **av) test_flag = 2; break; case 'C': - connection_info = get_connection_info(ssh, 0, 0); - if (parse_server_match_testspec(connection_info, + if (parse_server_match_testspec(&connection_info, optarg) == -1) exit(1); + have_connection_info = 1; break; case 'u': utmp_len = (u_int)strtonum(optarg, 0, HOST_NAME_MAX+1+1, NULL); @@ -1606,22 +997,27 @@ main(int ac, char **av) break; } } - if (rexeced_flag || inetd_flag) - rexec_flag = 0; - if (!test_flag && !do_dump_cfg && rexec_flag && !path_absolute(av[0])) - fatal("sshd re-exec requires execution with an absolute path"); - if (rexeced_flag) - closefrom(REEXEC_MIN_FREE_FD); - else - closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); + if (!test_flag && !do_dump_cfg && !path_absolute(av[0])) + fatal("sshd requires execution with an absolute path"); + closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); #ifdef WITH_OPENSSL OpenSSL_add_all_algorithms(); #endif /* If requested, redirect the logs to the specified logfile. */ - if (logfile != NULL) - log_redirect_stderr_to(logfile); + if (logfile != NULL) { + char *cp, pid_s[32]; + + snprintf(pid_s, sizeof(pid_s), "%ld", (unsigned long)getpid()); + cp = percent_expand(logfile, + "p", pid_s, + "P", "sshd", + (char *)NULL); + log_redirect_stderr_to(cp); + free(cp); + } + /* * Force logging to stderr until we have loaded the private host * key (unless started from inetd) @@ -1639,35 +1035,18 @@ main(int ac, char **av) * If we're not doing an extended test do not silently ignore connection * test params. */ - if (test_flag < 2 && connection_info != NULL) + if (test_flag < 2 && have_connection_info) fatal("Config test connection parameter (-C) provided without " "test mode (-T)"); /* Fetch our configuration */ if ((cfg = sshbuf_new()) == NULL) - fatal_f("sshbuf_new failed"); - if (rexeced_flag) { - setproctitle("%s", "[rexeced]"); - recv_rexec_state(REEXEC_CONFIG_PASS_FD, cfg); - if (!debug_flag) { - startup_pipe = dup(REEXEC_STARTUP_PIPE_FD); - close(REEXEC_STARTUP_PIPE_FD); - /* - * Signal parent that this child is at a point where - * they can go away if they have a SIGHUP pending. - */ - (void)atomicio(vwrite, startup_pipe, "\0", 1); - } - } else if (strcasecmp(config_file_name, "none") != 0) + fatal("sshbuf_new config failed"); + if (strcasecmp(config_file_name, "none") != 0) load_server_config(config_file_name, cfg); - parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, - cfg, &includes, NULL, rexeced_flag); - -#ifdef WITH_OPENSSL - if (options.moduli_file != NULL) - dh_set_moduli_file(options.moduli_file); -#endif + parse_server_config(&options, config_file_name, cfg, + &includes, NULL, 0); /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); @@ -1687,7 +1066,7 @@ main(int ac, char **av) /* * Check whether there is any path through configured auth methods. * Unfortunately it is not possible to verify this generally before - * daemonisation in the presence of Match block, but this catches + * daemonisation in the presence of Match blocks, but this catches * and warns for trivial misconfigurations that could break login. */ if (options.num_auth_methods != 0) { @@ -1710,7 +1089,7 @@ main(int ac, char **av) debug("sshd version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION); if (do_dump_cfg) - print_config(ssh, connection_info); + print_config(&connection_info); /* load host keys */ sensitive_data.host_keys = xcalloc(options.num_host_key_files, @@ -1862,40 +1241,42 @@ main(int ac, char **av) sshkey_type(key)); } - if (use_privsep) { - struct stat st; - - if (getpwnam(SSH_PRIVSEP_USER) == NULL) - fatal("Privilege separation user %s does not exist", - SSH_PRIVSEP_USER); - endpwent(); - if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) || - (S_ISDIR(st.st_mode) == 0)) - fatal("Missing privilege separation directory: %s", - _PATH_PRIVSEP_CHROOT_DIR); - if (st.st_uid != 0 || (st.st_mode & (S_IWGRP|S_IWOTH)) != 0) - fatal("%s must be owned by root and not group or " - "world-writable.", _PATH_PRIVSEP_CHROOT_DIR); - } + /* Ensure privsep directory is correctly configured. */ + if (getpwnam(SSH_PRIVSEP_USER) == NULL) + fatal("Privilege separation user %s does not exist", + SSH_PRIVSEP_USER); + endpwent(); + if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &sb) == -1) || + (S_ISDIR(sb.st_mode) == 0)) + fatal("Missing privilege separation directory: %s", + _PATH_PRIVSEP_CHROOT_DIR); + if (sb.st_uid != 0 || (sb.st_mode & (S_IWGRP|S_IWOTH)) != 0) + fatal("%s must be owned by root and not group or " + "world-writable.", _PATH_PRIVSEP_CHROOT_DIR); if (test_flag > 1) - print_config(ssh, connection_info); + print_config(&connection_info); /* Configuration looks good, so exit if in test mode. */ if (test_flag) exit(0); - if (rexec_flag) { - if (rexec_argc < 0) - fatal("rexec_argc %d < 0", rexec_argc); - rexec_argv = xcalloc(rexec_argc + 2, sizeof(char *)); - for (i = 0; i < (u_int)rexec_argc; i++) { - debug("rexec_argv[%d]='%s'", i, saved_argv[i]); - rexec_argv[i] = saved_argv[i]; - } - rexec_argv[rexec_argc] = "-R"; - rexec_argv[rexec_argc + 1] = NULL; + /* Prepare arguments for sshd-session */ + if (rexec_argc < 0) + fatal("rexec_argc %d < 0", rexec_argc); + rexec_argv = xcalloc(rexec_argc + 3, sizeof(char *)); + /* Point to the sshd-session binary instead of sshd */ + rexec_argv[0] = options.sshd_session_path; + for (i = 1; i < (u_int)rexec_argc; i++) { + debug("rexec_argv[%d]='%s'", i, saved_argv[i]); + rexec_argv[i] = saved_argv[i]; } + rexec_argv[rexec_argc++] = "-R"; + rexec_argv[rexec_argc] = NULL; + if (stat(rexec_argv[0], &sb) != 0 || !(sb.st_mode & (S_IXOTH|S_IXUSR))) + fatal("%s does not exist or is not executable", rexec_argv[0]); + debug3("using %s for re-exec", rexec_argv[0]); + listener_proctitle = prepare_proctitle(ac, av); /* Ensure that umask disallows at least group and world write */ @@ -1903,7 +1284,7 @@ main(int ac, char **av) (void) umask(new_umask); /* Initialize the log (it is reinitialized below in case we forked). */ - if (debug_flag && (!inetd_flag || rexeced_flag)) + if (debug_flag && !inetd_flag) log_stderr = 1; log_init(__progname, options.log_level, options.log_facility, log_stderr); @@ -1938,7 +1319,11 @@ main(int ac, char **av) /* Get a connection, either from inetd or a listening TCP socket */ if (inetd_flag) { - server_accept_inetd(&sock_in, &sock_out); + /* Send configuration to ancestor sshd-session process */ + if (socketpair(AF_UNIX, SOCK_STREAM, 0, config_s) == -1) + fatal("socketpair: %s", strerror(errno)); + send_rexec_state(config_s[0], cfg); + close(config_s[0]); } else { server_listen(); @@ -1965,7 +1350,7 @@ main(int ac, char **av) /* Accept a connection and return in a forked child */ server_accept_loop(&sock_in, &sock_out, - &newsock, config_s); + &newsock, config_s, log_stderr); } /* This is the child processing a new connection. */ @@ -1979,316 +1364,36 @@ main(int ac, char **av) if (!debug_flag && !inetd_flag && setsid() == -1) error("setsid: %.100s", strerror(errno)); - if (rexec_flag) { - debug("rexec start in %d out %d newsock %d pipe %d sock %d", - sock_in, sock_out, newsock, startup_pipe, config_s[0]); + debug("rexec start in %d out %d newsock %d pipe %d sock %d/%d", + sock_in, sock_out, newsock, startup_pipe, config_s[0], config_s[1]); + if (!inetd_flag) { if (dup2(newsock, STDIN_FILENO) == -1) - debug3_f("dup2 stdin: %s", strerror(errno)); + debug3("dup2 stdin: %s", strerror(errno)); if (dup2(STDIN_FILENO, STDOUT_FILENO) == -1) - debug3_f("dup2 stdout: %s", strerror(errno)); - if (startup_pipe == -1) - close(REEXEC_STARTUP_PIPE_FD); - else if (startup_pipe != REEXEC_STARTUP_PIPE_FD) { - if (dup2(startup_pipe, REEXEC_STARTUP_PIPE_FD) == -1) - debug3_f("dup2 startup_p: %s", strerror(errno)); - close(startup_pipe); - startup_pipe = REEXEC_STARTUP_PIPE_FD; - } - + debug3("dup2 stdout: %s", strerror(errno)); + } + if (config_s[1] != REEXEC_CONFIG_PASS_FD) { if (dup2(config_s[1], REEXEC_CONFIG_PASS_FD) == -1) - debug3_f("dup2 config_s: %s", strerror(errno)); + debug3("dup2 config_s: %s", strerror(errno)); close(config_s[1]); - - ssh_signal(SIGHUP, SIG_IGN); /* avoid reset to SIG_DFL */ - execv(rexec_argv[0], rexec_argv); - - /* Reexec has failed, fall back and continue */ - error("rexec of %s failed: %s", rexec_argv[0], strerror(errno)); - recv_rexec_state(REEXEC_CONFIG_PASS_FD, NULL); - log_init(__progname, options.log_level, - options.log_facility, log_stderr); - - /* Clean up fds */ - close(REEXEC_CONFIG_PASS_FD); - newsock = sock_out = sock_in = dup(STDIN_FILENO); - if (stdfd_devnull(1, 1, 0) == -1) - error_f("stdfd_devnull failed"); - debug("rexec cleanup in %d out %d newsock %d pipe %d sock %d", - sock_in, sock_out, newsock, startup_pipe, config_s[0]); } - - /* Executed child processes don't need these. */ - fcntl(sock_out, F_SETFD, FD_CLOEXEC); - fcntl(sock_in, F_SETFD, FD_CLOEXEC); - - /* We will not restart on SIGHUP since it no longer makes sense. */ - ssh_signal(SIGALRM, SIG_DFL); - ssh_signal(SIGHUP, SIG_DFL); - ssh_signal(SIGTERM, SIG_DFL); - ssh_signal(SIGQUIT, SIG_DFL); - ssh_signal(SIGCHLD, SIG_DFL); - - /* - * Register our connection. This turns encryption off because we do - * not have a key. - */ - if ((ssh = ssh_packet_set_connection(NULL, sock_in, sock_out)) == NULL) - fatal("Unable to create connection"); - the_active_state = ssh; - ssh_packet_set_server(ssh); - - check_ip_options(ssh); - - /* Prepare the channels layer */ - channel_init_channels(ssh); - channel_set_af(ssh, options.address_family); - process_channel_timeouts(ssh, &options); - process_permitopen(ssh, &options); - - /* Set SO_KEEPALIVE if requested. */ - if (options.tcp_keep_alive && ssh_packet_connection_is_on_socket(ssh) && - setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) == -1) - error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); - - if ((remote_port = ssh_remote_port(ssh)) < 0) { - debug("ssh_remote_port failed"); - cleanup_exit(255); - } - - /* - * The rest of the code depends on the fact that - * ssh_remote_ipaddr() caches the remote ip, even if - * the socket goes away. - */ - remote_ip = ssh_remote_ipaddr(ssh); - - rdomain = ssh_packet_rdomain_in(ssh); - - /* Log the connection. */ - laddr = get_local_ipaddr(sock_in); - verbose("Connection from %s port %d on %s port %d%s%s%s", - remote_ip, remote_port, laddr, ssh_local_port(ssh), - rdomain == NULL ? "" : " rdomain \"", - rdomain == NULL ? "" : rdomain, - rdomain == NULL ? "" : "\""); - free(laddr); - - /* - * We don't want to listen forever unless the other side - * successfully authenticates itself. So we set up an alarm which is - * cleared after successful authentication. A limit of zero - * indicates no limit. Note that we don't set the alarm in debugging - * mode; it is just annoying to have the server exit just when you - * are about to discover the bug. - */ - ssh_signal(SIGALRM, grace_alarm_handler); - if (!debug_flag) - alarm(options.login_grace_time); - - if ((r = kex_exchange_identification(ssh, -1, - options.version_addendum)) != 0) - sshpkt_fatal(ssh, r, "banner exchange"); - - ssh_packet_set_nonblocking(ssh); - - /* allocate authentication context */ - authctxt = xcalloc(1, sizeof(*authctxt)); - ssh->authctxt = authctxt; - - /* XXX global for cleanup, access from other modules */ - the_authctxt = authctxt; - - /* Set default key authentication options */ - if ((auth_opts = sshauthopt_new_with_keys_defaults()) == NULL) - fatal("allocation failed"); - - /* prepare buffer to collect messages to display to user after login */ - if ((loginmsg = sshbuf_new()) == NULL) - fatal_f("sshbuf_new failed"); - auth_debug_reset(); - - if (use_privsep) { - if (privsep_preauth(ssh) == 1) - goto authenticated; - } else if (have_agent) { - if ((r = ssh_get_authentication_socket(&auth_sock)) != 0) { - error_r(r, "Unable to get agent socket"); - have_agent = 0; - } - } - - /* perform the key exchange */ - /* authenticate user and start session */ - do_ssh2_kex(ssh); - do_authentication2(ssh); - - /* - * If we use privilege separation, the unprivileged child transfers - * the current keystate and exits - */ - if (use_privsep) { - mm_send_keystate(ssh, pmonitor); - ssh_packet_clear_keys(ssh); - exit(0); - } - - authenticated: - /* - * Cancel the alarm we set to limit the time taken for - * authentication. - */ - alarm(0); - ssh_signal(SIGALRM, SIG_DFL); - authctxt->authenticated = 1; - if (startup_pipe != -1) { + if (startup_pipe == -1) + close(REEXEC_STARTUP_PIPE_FD); + else if (startup_pipe != REEXEC_STARTUP_PIPE_FD) { + if (dup2(startup_pipe, REEXEC_STARTUP_PIPE_FD) == -1) + debug3("dup2 startup_p: %s", strerror(errno)); close(startup_pipe); - startup_pipe = -1; } - if (options.routing_domain != NULL) - set_process_rdomain(ssh, options.routing_domain); + ssh_signal(SIGHUP, SIG_IGN); /* avoid reset to SIG_DFL */ + execv(rexec_argv[0], rexec_argv); - /* - * In privilege separation, we fork another child and prepare - * file descriptor passing. - */ - if (use_privsep) { - privsep_postauth(ssh, authctxt); - /* the monitor process [priv] will not return */ - } - - ssh_packet_set_timeout(ssh, options.client_alive_interval, - options.client_alive_count_max); - - /* Try to send all our hostkeys to the client */ - notify_hostkeys(ssh); - - /* Start session. */ - do_authenticated(ssh, authctxt); - - /* The connection has been terminated. */ - ssh_packet_get_bytes(ssh, &ibytes, &obytes); - verbose("Transferred: sent %llu, received %llu bytes", - (unsigned long long)obytes, (unsigned long long)ibytes); - - verbose("Closing connection to %.500s port %d", remote_ip, remote_port); - ssh_packet_close(ssh); - - if (use_privsep) - mm_terminate(); - - exit(0); -} - -int -sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey, - struct sshkey *pubkey, u_char **signature, size_t *slenp, - const u_char *data, size_t dlen, const char *alg) -{ - int r; - - if (use_privsep) { - if (privkey) { - if (mm_sshkey_sign(ssh, privkey, signature, slenp, - data, dlen, alg, options.sk_provider, NULL, - ssh->compat) < 0) - fatal_f("privkey sign failed"); - } else { - if (mm_sshkey_sign(ssh, pubkey, signature, slenp, - data, dlen, alg, options.sk_provider, NULL, - ssh->compat) < 0) - fatal_f("pubkey sign failed"); - } - } else { - if (privkey) { - if (sshkey_sign(privkey, signature, slenp, data, dlen, - alg, options.sk_provider, NULL, ssh->compat) < 0) - fatal_f("privkey sign failed"); - } else { - if ((r = ssh_agent_sign(auth_sock, pubkey, - signature, slenp, data, dlen, alg, - ssh->compat)) != 0) { - fatal_fr(r, "agent sign failed"); - } - } - } - return 0; -} - -/* SSH2 key exchange */ -static void -do_ssh2_kex(struct ssh *ssh) -{ - char *hkalgs = NULL, *myproposal[PROPOSAL_MAX]; - const char *compression = NULL; - struct kex *kex; - int r; - - if (options.rekey_limit || options.rekey_interval) - ssh_packet_set_rekey_limits(ssh, options.rekey_limit, - options.rekey_interval); - - if (options.compression == COMP_NONE) - compression = "none"; - hkalgs = list_hostkey_types(); - - kex_proposal_populate_entries(ssh, myproposal, options.kex_algorithms, - options.ciphers, options.macs, compression, hkalgs); - - free(hkalgs); - - /* start key exchange */ - if ((r = kex_setup(ssh, myproposal)) != 0) - fatal_r(r, "kex_setup"); - kex_set_server_sig_algs(ssh, options.pubkey_accepted_algos); - kex = ssh->kex; - -#ifdef WITH_OPENSSL - kex->kex[KEX_DH_GRP1_SHA1] = kex_gen_server; - kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_server; - kex->kex[KEX_DH_GRP14_SHA256] = kex_gen_server; - kex->kex[KEX_DH_GRP16_SHA512] = kex_gen_server; - kex->kex[KEX_DH_GRP18_SHA512] = kex_gen_server; - kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; - kex->kex[KEX_DH_GEX_SHA256] = kexgex_server; - kex->kex[KEX_ECDH_SHA2] = kex_gen_server; -#endif - kex->kex[KEX_C25519_SHA256] = kex_gen_server; - kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; - kex->load_host_public_key=&get_hostkey_public_by_type; - kex->load_host_private_key=&get_hostkey_private_by_type; - kex->host_key_index=&get_hostkey_index; - kex->sign = sshd_hostkey_sign; - - ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &kex->done); - kex_proposal_free_entries(myproposal); - -#ifdef DEBUG_KEXDH - /* send 1st encrypted/maced/compressed message */ - if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 || - (r = sshpkt_put_cstring(ssh, "markus")) != 0 || - (r = sshpkt_send(ssh)) != 0 || - (r = ssh_packet_write_wait(ssh)) != 0) - fatal_fr(r, "send test"); -#endif - debug("KEX done"); + fatal("rexec of %s failed: %s", rexec_argv[0], strerror(errno)); } /* server specific fatal cleanup */ void cleanup_exit(int i) { - if (the_active_state != NULL && the_authctxt != NULL) { - do_cleanup(the_active_state, the_authctxt); - if (use_privsep && privsep_is_preauth && - pmonitor != NULL && pmonitor->m_pid > 1) { - debug("Killing privsep child %d", pmonitor->m_pid); - if (kill(pmonitor->m_pid, SIGKILL) != 0 && - errno != ESRCH) { - error_f("kill(%d): %s", pmonitor->m_pid, - strerror(errno)); - } - } - } _exit(i); } diff --git a/usr.bin/ssh/sshd/Makefile b/usr.bin/ssh/sshd/Makefile index 77a0b8d0c..65434360a 100644 --- a/usr.bin/ssh/sshd/Makefile +++ b/usr.bin/ssh/sshd/Makefile @@ -1,17 +1,11 @@ -# $OpenBSD: Makefile,v 1.110 2024/04/01 15:48:16 deraadt Exp $ +# $OpenBSD: Makefile,v 1.111 2024/05/17 00:30:24 djm Exp $ .PATH: ${.CURDIR}/.. -SRCS= sshd.c auth-rhosts.c auth-passwd.c sshpty.c sshlogin.c servconf.c \ - serverloop.c auth.c auth2.c auth-options.c session.c auth2-chall.c \ - groupaccess.c auth-bsdauth.c auth2-hostbased.c auth2-kbdint.c \ - auth2-none.c auth2-passwd.c auth2-pubkey.c auth2-pubkeyfile.c \ - monitor.c monitor_wrap.c \ - sftp-server.c sftp-common.c sftp-realpath.c sandbox-pledge.c srclimit.c -SRCS+= authfd.c compat.c dns.c fatal.c hostfile.c readpass.c utf8.c uidswap.c -SRCS+= ${SRCS_BASE} ${SRCS_KEX} ${SRCS_KEXS} ${SRCS_KEY} ${SRCS_KEYP} \ - ${SRCS_KRL} ${SRCS_PROT} ${SRCS_PKT} ${SRCS_UTL} ${SRCS_PKCS11} \ - ${SRCS_SK_CLIENT} +SRCS= sshd.c servconf.c sshpty.c srclimit.c groupaccess.c auth2-methods.c +SRCS+= dns.c fatal.c compat.c utf8.c authfd.c canohost.c kex-names.c +SRCS+= ${SRCS_BASE} ${SRCS_KEY} ${SRCS_KEYP} ${SRCS_KRL} \ + ${SRCS_MAC} ${SRCS_UTL} ${SRCS_SK_CLIENT} PROG= sshd BINMODE=511 @@ -50,7 +44,7 @@ DPADD+= ${LIBZ} # The random relink kit, used on OpenBSD by /etc/rc -CLEANFILES+= sshd.tar install.sh +CLEANFILES+= ${PROG}.tar install.sh install.sh: Makefile echo "set -o errexit" > $@ diff --git a/usr.bin/ssh/sshkey.h b/usr.bin/ssh/sshkey.h index 2be16d196..e6877becd 100644 --- a/usr.bin/ssh/sshkey.h +++ b/usr.bin/ssh/sshkey.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.h,v 1.62 2023/06/21 05:10:26 djm Exp $ */ +/* $OpenBSD: sshkey.h,v 1.63 2024/05/17 06:42:04 jsg Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -310,7 +310,6 @@ int ssh_rsa_complete_crt_parameters(struct sshkey *, const BIGNUM *); int sshkey_set_filename(struct sshkey *, const char *); int sshkey_enable_maxsign(struct sshkey *, u_int32_t); u_int32_t sshkey_signatures_left(const struct sshkey *); -int sshkey_forward_state(const struct sshkey *, u_int32_t, int); int sshkey_private_serialize_maxsign(struct sshkey *key, struct sshbuf *buf, u_int32_t maxsign, int); diff --git a/usr.bin/systat/nfs.c b/usr.bin/systat/nfs.c index df6c9b9e9..eb740f772 100644 --- a/usr.bin/systat/nfs.c +++ b/usr.bin/systat/nfs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs.c,v 1.9 2023/04/19 12:58:15 jsg Exp $ */ +/* $OpenBSD: nfs.c,v 1.10 2024/05/18 09:02:34 jsg Exp $ */ /* * Copyright (c) 2009 Jasper Lievisse Adriaanse @@ -33,7 +33,6 @@ #include "systat.h" -int check_nfs(void); int select_client(void); int select_server(void); int read_nfs(void); diff --git a/usr.bin/systat/pool.c b/usr.bin/systat/pool.c index 5a87b6ba4..5f43ef834 100644 --- a/usr.bin/systat/pool.c +++ b/usr.bin/systat/pool.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pool.c,v 1.19 2019/06/28 13:35:04 deraadt Exp $ */ +/* $OpenBSD: pool.c,v 1.20 2024/05/18 09:02:34 jsg Exp $ */ /* * Copyright (c) 2008 Can Erkin Acar * @@ -146,7 +146,6 @@ int pool_cache_sort_req_callback(const void *, const void *); int pool_cache_sort_put_callback(const void *, const void *); int pool_cache_sort_lreq_callback(const void *, const void *); int pool_cache_sort_lput_callback(const void *, const void *); -int pool_cache_kbd_cb(int); field_def pool_cache_fields[] = { {"NAME", 12, 32, 1, FLD_ALIGN_LEFT, -1, 0, 0, 0}, diff --git a/usr.bin/systat/systat.h b/usr.bin/systat/systat.h index 776be5a2d..08113a5b7 100644 --- a/usr.bin/systat/systat.h +++ b/usr.bin/systat/systat.h @@ -1,4 +1,4 @@ -/* $OpenBSD: systat.h,v 1.25 2022/12/04 18:01:57 cheloha Exp $ */ +/* $OpenBSD: systat.h,v 1.26 2024/05/18 09:02:34 jsg Exp $ */ /* $NetBSD: systat.h,v 1.2 1995/01/20 08:52:14 jtc Exp $ */ /*- @@ -45,11 +45,8 @@ #define CF_LOADAV 0x2 /* display w/ load average */ #define FIELD_ADDR(struct, x) (&struct[x]) -#define KREAD(addr, buf, len) kvm_ckread((addr), (buf), (len)) #define NVAL(indx) namelist[(indx)].n_value #define NPTR(indx) (void *)NVAL((indx)) -#define NREAD(indx, buf, len) kvm_ckread(NPTR((indx)), (buf), (len)) -int kvm_ckread(void *, void *, size_t); extern char **dr_name; extern char hostname[]; diff --git a/usr.bin/systat/uvm.c b/usr.bin/systat/uvm.c index fbf8d6e2a..401623f52 100644 --- a/usr.bin/systat/uvm.c +++ b/usr.bin/systat/uvm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm.c,v 1.9 2024/05/01 12:54:27 mpi Exp $ */ +/* $OpenBSD: uvm.c,v 1.10 2024/05/18 09:02:34 jsg Exp $ */ /* * Copyright (c) 2008 Can Erkin Acar * Copyright (c) 2018 Kenneth R Westerback @@ -38,7 +38,6 @@ int read_uvm(void); int select_uvm(void); void print_uvmexp_field(field_def *, field_def *, int *, int *, const char *); -void print_uvmexp_line(int); struct uvmexp uvmexp; struct uvmexp last_uvmexp; diff --git a/usr.bin/tmux/cmd.c b/usr.bin/tmux/cmd.c index f5c71fbdd..fbb77b0dc 100644 --- a/usr.bin/tmux/cmd.c +++ b/usr.bin/tmux/cmd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd.c,v 1.175 2023/08/17 14:10:28 nicm Exp $ */ +/* $OpenBSD: cmd.c,v 1.176 2024/05/18 08:50:11 jsg Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -48,7 +48,6 @@ extern const struct cmd_entry cmd_display_menu_entry; extern const struct cmd_entry cmd_display_message_entry; extern const struct cmd_entry cmd_display_popup_entry; extern const struct cmd_entry cmd_display_panes_entry; -extern const struct cmd_entry cmd_down_pane_entry; extern const struct cmd_entry cmd_find_window_entry; extern const struct cmd_entry cmd_has_session_entry; extern const struct cmd_entry cmd_if_shell_entry; @@ -118,7 +117,6 @@ extern const struct cmd_entry cmd_swap_window_entry; extern const struct cmd_entry cmd_switch_client_entry; extern const struct cmd_entry cmd_unbind_key_entry; extern const struct cmd_entry cmd_unlink_window_entry; -extern const struct cmd_entry cmd_up_pane_entry; extern const struct cmd_entry cmd_wait_for_entry; const struct cmd_entry *cmd_table[] = { diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index b59ce5300..305224fc9 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.1215 2024/05/15 09:59:12 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.1216 2024/05/18 08:51:26 jsg Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -2352,7 +2352,6 @@ void tty_cmd_clearstartofscreen(struct tty *, const struct tty_ctx *); void tty_cmd_deletecharacter(struct tty *, const struct tty_ctx *); void tty_cmd_clearcharacter(struct tty *, const struct tty_ctx *); void tty_cmd_deleteline(struct tty *, const struct tty_ctx *); -void tty_cmd_erasecharacter(struct tty *, const struct tty_ctx *); void tty_cmd_insertcharacter(struct tty *, const struct tty_ctx *); void tty_cmd_insertline(struct tty *, const struct tty_ctx *); void tty_cmd_linefeed(struct tty *, const struct tty_ctx *); @@ -2524,7 +2523,6 @@ enum cmd_retval cmd_attach_session(struct cmdq_item *, const char *, int, int, int, const char *, int, const char *); /* cmd-parse.c */ -void cmd_parse_empty(struct cmd_parse_input *); struct cmd_parse_result *cmd_parse_from_file(FILE *, struct cmd_parse_input *); struct cmd_parse_result *cmd_parse_from_string(const char *, struct cmd_parse_input *); @@ -2684,8 +2682,6 @@ void server_client_suspend(struct client *); void server_client_detach(struct client *, enum msgtype); void server_client_exec(struct client *, const char *); void server_client_loop(void); -void server_client_push_stdout(struct client *); -void server_client_push_stderr(struct client *); const char *server_client_get_cwd(struct client *, struct session *); void server_client_set_flags(struct client *, const char *); const char *server_client_get_flags(struct client *); @@ -3246,8 +3242,6 @@ char *session_check_name(const char *); void session_update_activity(struct session *, struct timeval *); struct session *session_next_session(struct session *); struct session *session_previous_session(struct session *); -struct winlink *session_new(struct session *, const char *, int, char **, - const char *, const char *, int, char **); struct winlink *session_attach(struct session *, struct window *, int, char **); int session_detach(struct session *, struct winlink *); diff --git a/usr.bin/top/display.h b/usr.bin/top/display.h index 29a74f8e0..2a123474f 100644 --- a/usr.bin/top/display.h +++ b/usr.bin/top/display.h @@ -1,4 +1,4 @@ -/* $OpenBSD: display.h,v 1.16 2022/09/10 16:58:51 cheloha Exp $ */ +/* $OpenBSD: display.h,v 1.17 2024/05/18 01:51:44 jsg Exp $ */ /* * Top users/processes display for Unix @@ -36,20 +36,13 @@ /* prototypes */ int display_resize(void); void i_loadave(double *); -void u_loadave(int, double *); void i_timeofday(time_t *); void i_procstates(int, int *, int); -void u_procstates(int, int *); void i_cpustates(int64_t *, int *); -void u_cpustates(int64_t *); void i_memory(int *); -void u_memory(int *); void i_message(void); -void u_message(void); void i_header(char *); -void u_header(char *); void i_process(int, char *, int); -void u_process(int, char *, int); void u_endscreen(void); void display_header(int); void new_message(int, const char *, ...); diff --git a/usr.sbin/bgpd/bgpd.h b/usr.sbin/bgpd/bgpd.h index 7939303d2..e0ba7110c 100644 --- a/usr.sbin/bgpd/bgpd.h +++ b/usr.sbin/bgpd/bgpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bgpd.h,v 1.492 2024/04/24 10:41:34 claudio Exp $ */ +/* $OpenBSD: bgpd.h,v 1.493 2024/05/18 11:17:30 jsg Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -1470,7 +1470,6 @@ void log_peer_warnx(const struct peer_config *, const char *, ...) __attribute__((__format__ (printf, 2, 3))); /* mrt.c */ -void mrt_clear_seq(void); void mrt_write(struct mrt *); void mrt_clean(struct mrt *); void mrt_init(struct imsgbuf *, struct imsgbuf *); @@ -1481,10 +1480,6 @@ struct mrt *mrt_get(struct mrt_head *, struct mrt *); void mrt_mergeconfig(struct mrt_head *, struct mrt_head *); /* name2id.c */ -uint16_t rib_name2id(const char *); -const char *rib_id2name(uint16_t); -void rib_unref(uint16_t); -void rib_ref(uint16_t); uint16_t rtlabel_name2id(const char *); const char *rtlabel_id2name(uint16_t); void rtlabel_unref(uint16_t); diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h index 895e73028..8def9f03f 100644 --- a/usr.sbin/bgpd/rde.h +++ b/usr.sbin/bgpd/rde.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.h,v 1.299 2024/01/24 14:51:12 claudio Exp $ */ +/* $OpenBSD: rde.h,v 1.300 2024/05/18 11:17:30 jsg Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker and @@ -564,7 +564,6 @@ re_rib(struct rib_entry *re) } void path_shutdown(void); -uint32_t path_remove_stale(struct rde_aspath *, uint8_t, time_t); struct rde_aspath *path_copy(struct rde_aspath *, const struct rde_aspath *); struct rde_aspath *path_prep(struct rde_aspath *); struct rde_aspath *path_get(void); @@ -581,7 +580,6 @@ struct prefix *prefix_adjout_next(struct rde_peer *, struct prefix *); struct prefix *prefix_adjout_lookup(struct rde_peer *, struct bgpd_addr *, int); struct prefix *prefix_adjout_match(struct rde_peer *, struct bgpd_addr *); -struct prefix *prefix_match(struct rde_peer *, struct bgpd_addr *); int prefix_update(struct rib *, struct rde_peer *, uint32_t, uint32_t, struct filterstate *, struct bgpd_addr *, int); int prefix_withdraw(struct rib *, struct rde_peer *, uint32_t, @@ -609,7 +607,6 @@ int prefix_dump_subtree(struct rde_peer *, struct bgpd_addr *, struct prefix *prefix_bypeer(struct rib_entry *, struct rde_peer *, uint32_t); void prefix_destroy(struct prefix *); -void prefix_relink(struct prefix *, struct rde_aspath *, int); RB_PROTOTYPE(prefix_tree, prefix, entry, prefix_cmp) @@ -690,7 +687,6 @@ int nexthop_unref(struct nexthop *); int nexthop_compare(struct nexthop *, struct nexthop *); /* rde_update.c */ -void up_init(struct rde_peer *); void up_generate_updates(struct rde_peer *, struct rib_entry *); void up_generate_addpath(struct rde_peer *, struct rib_entry *); void up_generate_addpath_all(struct rde_peer *, struct rib_entry *, @@ -713,6 +709,5 @@ int aspa_table_equal(const struct rde_aspa *, const struct rde_aspa *); void aspa_table_unchanged(struct rde_aspa *, const struct rde_aspa *); -void aspa_table_set_generation(struct rde_aspa *, uint8_t); #endif /* __RDE_H__ */ diff --git a/usr.sbin/bgpd/session.c b/usr.sbin/bgpd/session.c index ce613736d..9bd7d608f 100644 --- a/usr.sbin/bgpd/session.c +++ b/usr.sbin/bgpd/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.475 2024/05/15 09:09:38 job Exp $ */ +/* $OpenBSD: session.c,v 1.476 2024/05/16 09:38:21 claudio Exp $ */ /* * Copyright (c) 2003, 2004, 2005 Henning Brauer @@ -1212,13 +1212,8 @@ session_setup_socket(struct peer *p) /* limit bufsize. no biggie if it fails */ bsize = 65535; - while (bsize > 8192 && setsockopt(p->fd, SOL_SOCKET, SO_RCVBUF, - &bsize, sizeof(bsize)) == -1 && errno != EINVAL) - bsize /= 2; - bsize = 65535; - while (bsize > 8192 && setsockopt(p->fd, SOL_SOCKET, SO_SNDBUF, - &bsize, sizeof(bsize)) == -1 && errno != EINVAL) - bsize /= 2; + setsockopt(p->fd, SOL_SOCKET, SO_RCVBUF, &bsize, sizeof(bsize)); + setsockopt(p->fd, SOL_SOCKET, SO_SNDBUF, &bsize, sizeof(bsize)); return (0); } diff --git a/usr.sbin/bgpd/session.h b/usr.sbin/bgpd/session.h index 598ce70a1..815b1242e 100644 --- a/usr.sbin/bgpd/session.h +++ b/usr.sbin/bgpd/session.h @@ -1,4 +1,4 @@ -/* $OpenBSD: session.h,v 1.169 2024/04/22 09:36:04 claudio Exp $ */ +/* $OpenBSD: session.h,v 1.170 2024/05/18 11:17:30 jsg Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -300,7 +300,6 @@ struct rtr_session *rtr_new(uint32_t, char *); struct rtr_session *rtr_get(uint32_t); void rtr_free(struct rtr_session *); void rtr_open(struct rtr_session *, int); -struct roa_tree *rtr_get_roa(struct rtr_session *); void rtr_config_prep(void); void rtr_config_merge(void); void rtr_config_keep(struct rtr_session *); diff --git a/usr.sbin/dvmrpd/dvmrpd.h b/usr.sbin/dvmrpd/dvmrpd.h index 96f02b0cc..36c28afbe 100644 --- a/usr.sbin/dvmrpd/dvmrpd.h +++ b/usr.sbin/dvmrpd/dvmrpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dvmrpd.h,v 1.24 2021/01/19 12:26:38 claudio Exp $ */ +/* $OpenBSD: dvmrpd.h,v 1.25 2024/05/18 11:17:30 jsg Exp $ */ /* * Copyright (c) 2004, 2005, 2006 Esben Norby @@ -171,7 +171,6 @@ struct nbr_msg { }; TAILQ_HEAD(rr_head, rr_entry); -RB_HEAD(src_head, src_node); struct iface { LIST_ENTRY(iface) entry; diff --git a/usr.sbin/dvmrpd/rde.h b/usr.sbin/dvmrpd/rde.h index 659319494..80f323c9e 100644 --- a/usr.sbin/dvmrpd/rde.h +++ b/usr.sbin/dvmrpd/rde.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.h,v 1.16 2009/09/06 09:52:14 michele Exp $ */ +/* $OpenBSD: rde.h,v 1.17 2024/05/18 11:17:30 jsg Exp $ */ /* * Copyright (c) 2005, 2006 Esben Norby @@ -126,12 +126,9 @@ void rt_dump(pid_t); struct rt_node *rt_match_origin(in_addr_t); int srt_check_route(struct route_report *, int); -int src_compare(struct src_node *, struct src_node *); struct ds_nbr *srt_find_ds(struct rt_node *, u_int32_t); void srt_expire_nbr(struct in_addr, unsigned int); void srt_check_downstream_ifaces(struct rt_node *, struct iface *); -RB_PROTOTYPE(src_head, src_node, entry, src_compare); - #endif /* _RDE_H_ */ diff --git a/usr.sbin/dvmrpd/rde_mfc.c b/usr.sbin/dvmrpd/rde_mfc.c index 653dac528..efde74ff6 100644 --- a/usr.sbin/dvmrpd/rde_mfc.c +++ b/usr.sbin/dvmrpd/rde_mfc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_mfc.c,v 1.10 2015/12/07 19:14:49 mmcc Exp $ */ +/* $OpenBSD: rde_mfc.c,v 1.11 2024/05/18 11:17:30 jsg Exp $ */ /* * Copyright (c) 2009 Michele Marchetto @@ -54,7 +54,6 @@ int mfc_start_prune_timer(struct mfc_node *); int mfc_reset_prune_timer(struct mfc_node *); int mfc_compare(struct mfc_node *, struct mfc_node *); -void mfc_invalidate(void); RB_HEAD(mfc_tree, mfc_node) mfc; RB_PROTOTYPE(mfc_tree, mfc_node, entry, mfc_compare) diff --git a/usr.sbin/ospf6d/kroute.c b/usr.sbin/ospf6d/kroute.c index 28ca7fac8..962b3627f 100644 --- a/usr.sbin/ospf6d/kroute.c +++ b/usr.sbin/ospf6d/kroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kroute.c,v 1.68 2023/06/21 09:47:03 sthen Exp $ */ +/* $OpenBSD: kroute.c,v 1.69 2024/05/18 11:17:30 jsg Exp $ */ /* * Copyright (c) 2004 Esben Norby @@ -97,7 +97,6 @@ void if_announce(void *); int send_rtmsg(int, int, struct kroute *); int dispatch_rtmsg(void); int fetchtable(void); -int refetchtable(void); int rtmsg_process(char *, size_t); void kr_fib_reload_timer(int, short, void *); void kr_fib_reload_arm_timer(int); diff --git a/usr.sbin/ospf6d/ospf6d.h b/usr.sbin/ospf6d/ospf6d.h index a8f2a929e..5e2e1d35b 100644 --- a/usr.sbin/ospf6d/ospf6d.h +++ b/usr.sbin/ospf6d/ospf6d.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ospf6d.h,v 1.51 2023/06/21 09:47:03 sthen Exp $ */ +/* $OpenBSD: ospf6d.h,v 1.52 2024/05/18 11:17:30 jsg Exp $ */ /* * Copyright (c) 2004, 2007 Esben Norby @@ -534,9 +534,6 @@ struct iface *if_new(u_short, char *); void if_update(struct iface *, int, int, u_int8_t, u_int8_t, u_int64_t, u_int32_t); -/* in_cksum.c */ -u_int16_t in_cksum(void *, size_t); - /* iso_cksum.c */ u_int16_t iso_cksum(void *, u_int16_t, u_int16_t); diff --git a/usr.sbin/ospf6d/ospfe.h b/usr.sbin/ospf6d/ospfe.h index 7fec5f8df..5b3ac45a6 100644 --- a/usr.sbin/ospf6d/ospfe.h +++ b/usr.sbin/ospf6d/ospfe.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfe.h,v 1.25 2021/01/19 09:43:40 claudio Exp $ */ +/* $OpenBSD: ospfe.h,v 1.26 2024/05/18 11:17:30 jsg Exp $ */ /* * Copyright (c) 2004, 2005 Esben Norby @@ -99,7 +99,6 @@ struct ctl_conn; int send_db_description(struct nbr *); void recv_db_description(struct nbr *, char *, u_int16_t); void db_sum_list_add(struct nbr *, struct lsa_hdr *); -int db_sum_list_del(struct nbr *, struct lsa_hdr *); void db_sum_list_clr(struct nbr *); void db_tx_timer(int, short, void *); void start_db_tx_timer(struct nbr *); @@ -148,7 +147,6 @@ int if_set_ipv6_pktinfo(int, int); int if_set_ipv6_checksum(int); /* lsack.c */ -int delay_lsa_ack(struct iface *, struct lsa_hdr *); int send_direct_ack(struct iface *, struct in6_addr, void *, size_t); void recv_ls_ack(struct nbr *, char *, u_int16_t); int lsa_hdr_check(struct nbr *, struct lsa_hdr *); @@ -164,7 +162,6 @@ void stop_ls_ack_tx_timer(struct iface *); int send_ls_req(struct nbr *); void recv_ls_req(struct nbr *, char *, u_int16_t); void ls_req_list_add(struct nbr *, struct lsa_hdr *); -int ls_req_list_del(struct nbr *, struct lsa_hdr *); struct lsa_entry *ls_req_list_get(struct nbr *, struct lsa_hdr *); void ls_req_list_free(struct nbr *, struct lsa_entry *); void ls_req_list_clr(struct nbr *); diff --git a/usr.sbin/ospf6d/packet.c b/usr.sbin/ospf6d/packet.c index 2ed0e4361..affc66577 100644 --- a/usr.sbin/ospf6d/packet.c +++ b/usr.sbin/ospf6d/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.22 2023/07/03 09:51:38 claudio Exp $ */ +/* $OpenBSD: packet.c,v 1.23 2024/05/18 11:17:30 jsg Exp $ */ /* * Copyright (c) 2004, 2005 Esben Norby @@ -36,7 +36,6 @@ #include "log.h" #include "ospfe.h" -int ip_hdr_sanity_check(const struct ip6_hdr *, u_int16_t); int ospf_hdr_sanity_check(struct ospf_hdr *, u_int16_t, const struct iface *, struct in6_addr *); struct iface *find_iface(struct ospfd_conf *, unsigned int, diff --git a/usr.sbin/ospfd/ospfe.h b/usr.sbin/ospfd/ospfe.h index 9e257e7f8..bc7413937 100644 --- a/usr.sbin/ospfd/ospfe.h +++ b/usr.sbin/ospfd/ospfe.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ospfe.h,v 1.48 2021/01/19 09:33:38 claudio Exp $ */ +/* $OpenBSD: ospfe.h,v 1.49 2024/05/18 11:17:30 jsg Exp $ */ /* * Copyright (c) 2004, 2005 Esben Norby @@ -108,7 +108,6 @@ int md_list_send(struct auth_md_head *, struct imsgev *); int send_db_description(struct nbr *); void recv_db_description(struct nbr *, char *, u_int16_t); void db_sum_list_add(struct nbr *, struct lsa_hdr *); -int db_sum_list_del(struct nbr *, struct lsa_hdr *); void db_sum_list_clr(struct nbr *); void db_tx_timer(int, short, void *); void start_db_tx_timer(struct nbr *); @@ -157,7 +156,6 @@ int if_set_mcast_loop(int); int if_set_ip_hdrincl(int); /* lsack.c */ -int delay_lsa_ack(struct iface *, struct lsa_hdr *); int send_direct_ack(struct iface *, struct in_addr, void *, size_t); void recv_ls_ack(struct nbr *, char *, u_int16_t); int lsa_hdr_check(struct nbr *, struct lsa_hdr *); @@ -173,7 +171,6 @@ void stop_ls_ack_tx_timer(struct iface *); int send_ls_req(struct nbr *); void recv_ls_req(struct nbr *, char *, u_int16_t); void ls_req_list_add(struct nbr *, struct lsa_hdr *); -int ls_req_list_del(struct nbr *, struct lsa_hdr *); struct lsa_entry *ls_req_list_get(struct nbr *, struct lsa_hdr *); void ls_req_list_free(struct nbr *, struct lsa_entry *); void ls_req_list_clr(struct nbr *); diff --git a/usr.sbin/rad/frontend.c b/usr.sbin/rad/frontend.c index 6748e4373..ca8719a4a 100644 --- a/usr.sbin/rad/frontend.c +++ b/usr.sbin/rad/frontend.c @@ -1,4 +1,4 @@ -/* $OpenBSD: frontend.c,v 1.45 2024/04/23 22:11:59 florian Exp $ */ +/* $OpenBSD: frontend.c,v 1.46 2024/05/17 06:50:14 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser @@ -56,6 +56,7 @@ #include #include +#include #include #include @@ -120,6 +121,12 @@ struct nd_opt_pref64 { u_int8_t nd_opt_pref64[12]; }; +struct nd_opt_source_link_addr { + u_int8_t nd_opt_source_link_addr_type; + u_int8_t nd_opt_source_link_addr_len; + struct ether_addr nd_opt_source_link_addr_hw_addr; +}; + TAILQ_HEAD(, ra_iface) ra_interfaces; __dead void frontend_shutdown(void); @@ -1099,6 +1106,7 @@ void build_packet(struct ra_iface *ra_iface) { struct nd_router_advert *ra; + struct nd_opt_source_link_addr *ndopt_source_link_addr; struct nd_opt_mtu *ndopt_mtu; struct nd_opt_prefix_info *ndopt_pi; struct ra_iface_conf *ra_iface_conf; @@ -1110,6 +1118,8 @@ build_packet(struct ra_iface *ra_iface) struct ra_rdnss_conf *ra_rdnss; struct ra_dnssl_conf *ra_dnssl; struct ra_pref64_conf *pref64; + struct ifaddrs *ifap, *ifa; + struct sockaddr_dl *sdl; size_t len, label_len; uint8_t *p, buf[RA_MAX_SIZE]; char *label_start, *label_end; @@ -1119,6 +1129,8 @@ build_packet(struct ra_iface *ra_iface) ra_options_conf = &ra_iface_conf->ra_options; len = sizeof(*ra); + if (ra_iface_conf->ra_options.source_link_addr) + len += sizeof(*ndopt_source_link_addr); if (ra_options_conf->mtu > 0) len += sizeof(*ndopt_mtu); len += sizeof(*ndopt_pi) * ra_iface->prefix_count; @@ -1170,6 +1182,37 @@ build_packet(struct ra_iface *ra_iface) ra->nd_ra_retransmit = htonl(ra_options_conf->retrans_timer); p += sizeof(*ra); + if (ra_iface_conf->ra_options.source_link_addr) { + ndopt_source_link_addr = (struct nd_opt_source_link_addr *)p; + ndopt_source_link_addr->nd_opt_source_link_addr_type = + ND_OPT_SOURCE_LINKADDR; + ndopt_source_link_addr->nd_opt_source_link_addr_len = 1; + if (getifaddrs(&ifap) != 0) { + ifap = NULL; + log_warn("getifaddrs"); + } + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == NULL || + ifa->ifa_addr->sa_family != AF_LINK) + continue; + if (strcmp(ra_iface->name, ifa->ifa_name) != 0) + continue; + sdl = (struct sockaddr_dl *)ifa->ifa_addr; + if (sdl->sdl_type != IFT_ETHER || + sdl->sdl_alen != ETHER_ADDR_LEN) + continue; + memcpy(&ndopt_source_link_addr-> + nd_opt_source_link_addr_hw_addr, + LLADDR(sdl), ETHER_ADDR_LEN); + break; + } + if (ifap != NULL) { + freeifaddrs(ifap); + p += sizeof(*ndopt_source_link_addr); + } else + len -= sizeof(*ndopt_source_link_addr); + } + if (ra_options_conf->mtu > 0) { ndopt_mtu = (struct nd_opt_mtu *)p; ndopt_mtu->nd_opt_mtu_type = ND_OPT_MTU; diff --git a/usr.sbin/rad/parse.y b/usr.sbin/rad/parse.y index 66cc0c0ab..bf6b6e6b8 100644 --- a/usr.sbin/rad/parse.y +++ b/usr.sbin/rad/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.22 2024/04/23 22:11:59 florian Exp $ */ +/* $OpenBSD: parse.y,v 1.23 2024/05/17 06:50:14 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser @@ -122,6 +122,7 @@ typedef struct { %token CONFIGURATION OTHER LIFETIME REACHABLE TIME RETRANS TIMER %token AUTO PREFIX VALID PREFERENCE PREFERRED LIFETIME ONLINK AUTONOMOUS %token ADDRESS_CONFIGURATION DNS NAMESERVER SEARCH MTU NAT64 HIGH MEDIUM LOW +%token SOURCE LINK_LAYER %token STRING %token NUMBER @@ -226,6 +227,9 @@ ra_opt_block : DEFAULT ROUTER yesno { | RETRANS TIMER NUMBER { ra_options->retrans_timer = $3; } + | SOURCE LINK_LAYER ADDRESS yesno { + ra_options->source_link_addr = $4; + } | MTU NUMBER { ra_options->mtu = $2; } @@ -523,6 +527,7 @@ lookup(char *s) {"interface", RA_IFACE}, {"lifetime", LIFETIME}, {"limit", LIMIT}, + {"link-layer", LINK_LAYER}, {"low", LOW}, {"managed", MANAGED}, {"medium", MEDIUM}, @@ -539,6 +544,7 @@ lookup(char *s) {"retrans", RETRANS}, {"router", ROUTER}, {"search", SEARCH}, + {"source", SOURCE}, {"time", TIME}, {"timer", TIMER}, {"valid", VALID}, diff --git a/usr.sbin/rad/printconf.c b/usr.sbin/rad/printconf.c index 184a5df2d..b49a7748a 100644 --- a/usr.sbin/rad/printconf.c +++ b/usr.sbin/rad/printconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printconf.c,v 1.8 2024/04/23 22:11:59 florian Exp $ */ +/* $OpenBSD: printconf.c,v 1.9 2024/05/17 06:50:14 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser @@ -78,6 +78,8 @@ print_ra_options(const char *indent, const struct ra_options_conf *ra_options) printf("%srouter lifetime %d\n", indent, ra_options->router_lifetime); printf("%sreachable time %u\n", indent, ra_options->reachable_time); printf("%sretrans timer %u\n", indent, ra_options->retrans_timer); + printf("%ssource link-layer address %s\n", indent, + yesno(ra_options->source_link_addr)); if (ra_options->mtu > 0) printf("%smtu %u\n", indent, ra_options->mtu); diff --git a/usr.sbin/rad/rad.c b/usr.sbin/rad/rad.c index b283e58fb..a0c317265 100644 --- a/usr.sbin/rad/rad.c +++ b/usr.sbin/rad/rad.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rad.c,v 1.29 2023/04/19 12:58:16 jsg Exp $ */ +/* $OpenBSD: rad.c,v 1.30 2024/05/17 06:50:14 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser @@ -757,6 +757,7 @@ config_new_empty(void) xconf->ra_options.router_lifetime = ADV_DEFAULT_LIFETIME; xconf->ra_options.reachable_time = 0; xconf->ra_options.retrans_timer = 0; + xconf->ra_options.source_link_addr = 1; xconf->ra_options.mtu = 0; xconf->ra_options.rdns_lifetime = DEFAULT_RDNS_LIFETIME; SIMPLEQ_INIT(&xconf->ra_options.ra_rdnss_list); diff --git a/usr.sbin/rad/rad.conf.5 b/usr.sbin/rad/rad.conf.5 index f82ccfd21..87c2b3286 100644 --- a/usr.sbin/rad/rad.conf.5 +++ b/usr.sbin/rad/rad.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: rad.conf.5,v 1.23 2024/04/23 22:17:49 florian Exp $ +.\" $OpenBSD: rad.conf.5,v 1.24 2024/05/17 06:50:14 florian Exp $ .\" .\" Copyright (c) 2018 Florian Obser .\" Copyright (c) 2005 Esben Norby @@ -18,7 +18,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: April 23 2024 $ +.Dd $Mdocdate: May 17 2024 $ .Dt RAD.CONF 5 .Os .Sh NAME @@ -127,6 +127,10 @@ The default is medium. .\" XXX .\" .It Ic retrans timer Ar number .\" XXX +.It Ic source link-layer address Pq Ic yes Ns | Ns Ic no +Add a source link-layer address option to router advertisement messages, to +communicate the link-layer address of the sending interface. +The default is yes. .El .Sh INTERFACES A list of interfaces or interface groups to send advertisements on: diff --git a/usr.sbin/rad/rad.h b/usr.sbin/rad/rad.h index 787e78c7c..442ff00fc 100644 --- a/usr.sbin/rad/rad.h +++ b/usr.sbin/rad/rad.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rad.h,v 1.26 2024/04/23 22:11:59 florian Exp $ */ +/* $OpenBSD: rad.h,v 1.27 2024/05/17 06:50:14 florian Exp $ */ /* * Copyright (c) 2018 Florian Obser @@ -97,6 +97,7 @@ struct ra_options_conf { int router_lifetime; /* default router lifetime */ uint32_t reachable_time; uint32_t retrans_timer; + int source_link_addr; /* source link-layer address */ uint32_t mtu; uint32_t rdns_lifetime; SIMPLEQ_HEAD(, ra_rdnss_conf) ra_rdnss_list; diff --git a/usr.sbin/relayd/hce.c b/usr.sbin/relayd/hce.c index 75b6f3c83..e4db3c96c 100644 --- a/usr.sbin/relayd/hce.c +++ b/usr.sbin/relayd/hce.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hce.c,v 1.81 2022/06/03 13:23:16 tb Exp $ */ +/* $OpenBSD: hce.c,v 1.82 2024/05/18 06:34:46 jsg Exp $ */ /* * Copyright (c) 2006 Pierre-Yves Ritschard @@ -30,7 +30,6 @@ #include "relayd.h" void hce_init(struct privsep *, struct privsep_proc *p, void *); -void hce_sig_handler(int sig, short, void *); void hce_launch_checks(int, short, void *); void hce_setup_events(void); void hce_disable_events(void); diff --git a/usr.sbin/relayd/relay_udp.c b/usr.sbin/relayd/relay_udp.c index e165bd7f5..1a4751d0d 100644 --- a/usr.sbin/relayd/relay_udp.c +++ b/usr.sbin/relayd/relay_udp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: relay_udp.c,v 1.50 2022/12/28 21:30:18 jmc Exp $ */ +/* $OpenBSD: relay_udp.c,v 1.51 2024/05/18 06:34:46 jsg Exp $ */ /* * Copyright (c) 2007 - 2013 Reyk Floeter @@ -45,7 +45,6 @@ struct shuffle relay_shuffle; int relay_udp_socket(struct sockaddr_storage *, in_port_t, struct protocol *); -void relay_udp_request(struct rsession *); void relay_udp_timeout(int, short, void *); void relay_dns_log(struct rsession *, u_int8_t *, size_t); diff --git a/usr.sbin/relayd/relayd.h b/usr.sbin/relayd/relayd.h index ca178871a..b5ac2d111 100644 --- a/usr.sbin/relayd/relayd.h +++ b/usr.sbin/relayd/relayd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: relayd.h,v 1.271 2023/06/25 08:07:39 op Exp $ */ +/* $OpenBSD: relayd.h,v 1.272 2024/05/18 06:34:46 jsg Exp $ */ /* * Copyright (c) 2006 - 2016 Reyk Floeter @@ -1210,7 +1210,6 @@ void hce_notify_done(struct host *, enum host_error); /* relay.c */ void relay(struct privsep *, struct privsep_proc *); int relay_privinit(struct relay *); -void relay_notify_done(struct host *, const char *); int relay_session_cmp(struct rsession *, struct rsession *); void relay_close(struct rsession *, const char *, int); int relay_reset_event(struct rsession *, struct ctl_relay_event *); @@ -1246,8 +1245,6 @@ int relay_test(struct protocol *, struct ctl_relay_event *); void relay_calc_skip_steps(struct relay_rules *); void relay_match(struct kvlist *, struct kv *, struct kv *, struct kvtree *); -void relay_session_insert(struct rsession *); -void relay_session_remove(struct rsession *); void relay_session_publish(struct rsession *); void relay_session_unpublish(struct rsession *); diff --git a/usr.sbin/vmctl/main.c b/usr.sbin/vmctl/main.c index 2b951ea4f..395bc39ef 100644 --- a/usr.sbin/vmctl/main.c +++ b/usr.sbin/vmctl/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.77 2024/05/02 15:46:10 mlarkin Exp $ */ +/* $OpenBSD: main.c,v 1.78 2024/05/18 06:45:00 jsg Exp $ */ /* * Copyright (c) 2015 Reyk Floeter @@ -50,8 +50,6 @@ int stat_rflag; __dead void usage(void); __dead void ctl_usage(struct ctl_command *); -int vmm_action(struct parse_result *); - int ctl_console(struct parse_result *, int, char *[]); int ctl_convert(const char *, const char *, int, size_t); int ctl_create(struct parse_result *, int, char *[]); diff --git a/usr.sbin/vmctl/vmctl.h b/usr.sbin/vmctl/vmctl.h index 95691edc9..94a05168e 100644 --- a/usr.sbin/vmctl/vmctl.h +++ b/usr.sbin/vmctl/vmctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: vmctl.h,v 1.37 2022/05/13 00:17:20 yasuoka Exp $ */ +/* $OpenBSD: vmctl.h,v 1.38 2024/05/18 06:45:00 jsg Exp $ */ /* * Copyright (c) 2015 Reyk Floeter @@ -91,8 +91,6 @@ __dead void int open_imagefile(int, const char *, int, struct virtio_backing *, off_t *); int create_imagefile(int, const char *, const char *, uint64_t, const char **); -int create_raw_imagefile(const char *, long); -int create_qc2_imagefile(const char *, const char *, long); int vm_start(uint32_t, const char *, size_t, int, char **, int, char **, int *, char *, char *, char *, unsigned int); int vm_start_complete(struct imsg *, int *, int); diff --git a/usr.sbin/vmd/i8259.h b/usr.sbin/vmd/i8259.h index f4b759869..47fae8bbc 100644 --- a/usr.sbin/vmd/i8259.h +++ b/usr.sbin/vmd/i8259.h @@ -1,4 +1,4 @@ -/* $OpenBSD: i8259.h,v 1.5 2022/09/01 22:01:40 dv Exp $ */ +/* $OpenBSD: i8259.h,v 1.6 2024/05/18 06:45:00 jsg Exp $ */ /* * Copyright (c) 2016 Mike Larkin * @@ -60,9 +60,6 @@ void i8259_assert_irq(uint8_t); void i8259_deassert_irq(uint8_t); -/* PIC functions called by vcpu run loop code */ -int i8259_get_next_irq(uint8_t *); - /* PIC functions called by the in/out exit handler */ uint8_t vcpu_exit_i8259(struct vm_run_params *); diff --git a/usr.sbin/vmd/mc146818.h b/usr.sbin/vmd/mc146818.h index f6e3509aa..f6a24156e 100644 --- a/usr.sbin/vmd/mc146818.h +++ b/usr.sbin/vmd/mc146818.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mc146818.h,v 1.5 2017/07/09 00:51:40 pd Exp $ */ +/* $OpenBSD: mc146818.h,v 1.6 2024/05/18 06:45:00 jsg Exp $ */ /* * Copyright (c) 2016 Mike Larkin * @@ -17,7 +17,6 @@ void mc146818_init(uint32_t, uint64_t, uint64_t); uint8_t vcpu_exit_mc146818(struct vm_run_params *vrp); -void dump_mc146818(void); int mc146818_dump(int); int mc146818_restore(int, uint32_t); void mc146818_stop(void); diff --git a/usr.sbin/vmd/vmd.c b/usr.sbin/vmd/vmd.c index 665a6b431..4662f76bc 100644 --- a/usr.sbin/vmd/vmd.c +++ b/usr.sbin/vmd/vmd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmd.c,v 1.156 2024/04/08 12:48:26 tobhe Exp $ */ +/* $OpenBSD: vmd.c,v 1.157 2024/05/18 06:45:00 jsg Exp $ */ /* * Copyright (c) 2015 Reyk Floeter @@ -53,7 +53,6 @@ int main(int, char **); int vmd_configure(void); void vmd_sighdlr(int sig, short event, void *arg); void vmd_shutdown(void); -int vmd_control_run(void); int vmd_dispatch_control(int, struct privsep_proc *, struct imsg *); int vmd_dispatch_vmm(int, struct privsep_proc *, struct imsg *); int vmd_dispatch_agentx(int, struct privsep_proc *, struct imsg *);