From 223def27392c05dcbff7ebcc1986477f2bad87bc Mon Sep 17 00:00:00 2001 From: purplerain Date: Tue, 7 May 2024 21:04:28 +0000 Subject: [PATCH] sync with OpenBSD -current --- distrib/sets/lists/comp/mi | 1 - distrib/sets/lists/man/mi | 1 + lib/libcrypto/lhash/lhash.c | 242 +++++++++++----------- sys/arch/amd64/include/endian.h | 30 +-- sys/arch/arm/include/endian.h | 41 +--- sys/arch/arm64/include/endian.h | 41 +--- sys/arch/i386/include/endian.h | 30 +-- sys/dev/pci/if_bnxt.c | 4 +- sys/dev/pci/if_em.c | 4 +- sys/dev/pci/if_igc.c | 4 +- sys/dev/pci/if_ix.c | 4 +- sys/dev/pci/if_ixl.c | 4 +- sys/dev/pci/if_vmx.c | 4 +- sys/dev/pv/if_vio.c | 4 +- sys/kern/kern_sig.c | 4 +- sys/kern/uipc_socket2.c | 7 +- sys/miscfs/fuse/fuse_vfsops.c | 5 +- usr.bin/ssh/ssh-keyscan.c | 52 +---- usr.bin/tty/tty.c | 6 +- usr.bin/vmstat/dkstats.c | 19 +- usr.sbin/smtpd/makemap.c | 5 +- usr.sbin/smtpd/queue_proc.c | 4 +- usr.sbin/smtpd/scheduler_proc.c | 4 +- usr.sbin/smtpd/smtpd-tables.7 | 272 +++++++++++++++++++++++++ usr.sbin/smtpd/smtpd.c | 7 +- usr.sbin/smtpd/smtpd.h | 6 +- usr.sbin/smtpd/smtpd/Makefile | 6 +- usr.sbin/smtpd/table.c | 63 ++++-- usr.sbin/smtpd/table_proc.c | 342 +++++++++++++++++--------------- 29 files changed, 687 insertions(+), 529 deletions(-) create mode 100644 usr.sbin/smtpd/smtpd-tables.7 diff --git a/distrib/sets/lists/comp/mi b/distrib/sets/lists/comp/mi index c63a18828..ac28d2852 100644 --- a/distrib/sets/lists/comp/mi +++ b/distrib/sets/lists/comp/mi @@ -1448,7 +1448,6 @@ ./usr/include/ufs/ffs ./usr/include/ufs/ffs/ffs_extern.h ./usr/include/ufs/ffs/fs.h -./usr/include/ufs/ffs/softdep.h ./usr/include/ufs/mfs ./usr/include/ufs/mfs/mfs_extern.h ./usr/include/ufs/mfs/mfsnode.h diff --git a/distrib/sets/lists/man/mi b/distrib/sets/lists/man/mi index 82b0e7c7a..228d1aba1 100644 --- a/distrib/sets/lists/man/mi +++ b/distrib/sets/lists/man/mi @@ -2370,6 +2370,7 @@ ./usr/share/man/man7/script.7 ./usr/share/man/man7/securelevel.7 ./usr/share/man/man7/smtpd-filters.7 +./usr/share/man/man7/smtpd-tables.7 ./usr/share/man/man7/sndio.7 ./usr/share/man/man7/symlink.7 ./usr/share/man/man7/tbl.7 diff --git a/lib/libcrypto/lhash/lhash.c b/lib/libcrypto/lhash/lhash.c index ded0d00dd..a7e9b86d5 100644 --- a/lib/libcrypto/lhash/lhash.c +++ b/lib/libcrypto/lhash/lhash.c @@ -1,4 +1,4 @@ -/* $OpenBSD: lhash.c,v 1.24 2024/05/06 14:38:20 jsing Exp $ */ +/* $OpenBSD: lhash.c,v 1.25 2024/05/07 13:40:42 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -110,9 +110,124 @@ #define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */ #define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */ -static void expand(_LHASH *lh); -static void contract(_LHASH *lh); -static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash); +static void +expand(_LHASH *lh) +{ + LHASH_NODE **n, **n1, **n2, *np; + unsigned int p, i, j; + unsigned long hash, nni; + + lh->num_nodes++; + lh->num_expands++; + p = (int)lh->p++; + n1 = &(lh->b[p]); + n2 = &(lh->b[p + (int)lh->pmax]); + *n2 = NULL; /* 27/07/92 - eay - undefined pointer bug */ + nni = lh->num_alloc_nodes; + + for (np = *n1; np != NULL; ) { +#ifndef OPENSSL_NO_HASH_COMP + hash = np->hash; +#else + hash = lh->hash(np->data); + lh->num_hash_calls++; +#endif + if ((hash % nni) != p) { /* move it */ + *n1 = (*n1)->next; + np->next= *n2; + *n2 = np; + } else + n1 = &((*n1)->next); + np= *n1; + } + + if ((lh->p) >= lh->pmax) { + j = (int)lh->num_alloc_nodes * 2; + n = reallocarray(lh->b, j, sizeof(LHASH_NODE *)); + if (n == NULL) { +/* fputs("realloc error in lhash", stderr); */ + lh->error++; + lh->p = 0; + return; + } + /* else */ + for (i = (int)lh->num_alloc_nodes; i < j; i++)/* 26/02/92 eay */ + n[i] = NULL; /* 02/03/92 eay */ + lh->pmax = lh->num_alloc_nodes; + lh->num_alloc_nodes = j; + lh->num_expand_reallocs++; + lh->p = 0; + lh->b = n; + } +} + +static void +contract(_LHASH *lh) +{ + LHASH_NODE **n, *n1, *np; + + np = lh->b[lh->p + lh->pmax - 1]; + lh->b[lh->p+lh->pmax - 1] = NULL; /* 24/07-92 - eay - weird but :-( */ + if (lh->p == 0) { + n = reallocarray(lh->b, lh->pmax, sizeof(LHASH_NODE *)); + if (n == NULL) { +/* fputs("realloc error in lhash", stderr); */ + lh->error++; + return; + } + lh->num_contract_reallocs++; + lh->num_alloc_nodes /= 2; + lh->pmax /= 2; + lh->p = lh->pmax - 1; + lh->b = n; + } else + lh->p--; + + lh->num_nodes--; + lh->num_contracts++; + + n1 = lh->b[(int)lh->p]; + if (n1 == NULL) + lh->b[(int)lh->p] = np; + else { + while (n1->next != NULL) + n1 = n1->next; + n1->next = np; + } +} + +static LHASH_NODE ** +getrn(_LHASH *lh, const void *data, unsigned long *rhash) +{ + LHASH_NODE **ret, *n1; + unsigned long hash, nn; + LHASH_COMP_FN_TYPE cf; + + hash = (*(lh->hash))(data); + lh->num_hash_calls++; + *rhash = hash; + + nn = hash % lh->pmax; + if (nn < lh->p) + nn = hash % lh->num_alloc_nodes; + + cf = lh->comp; + ret = &(lh->b[(int)nn]); + for (n1 = *ret; n1 != NULL; n1 = n1->next) { +#ifndef OPENSSL_NO_HASH_COMP + lh->num_hash_comps++; + if (n1->hash != hash) { + ret = &(n1->next); + continue; + } +#endif + lh->num_comp_calls++; + if (cf(n1->data, data) == 0) + break; + ret = &(n1->next); + } + return (ret); +} _LHASH * lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c) @@ -313,125 +428,6 @@ lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg) } LCRYPTO_ALIAS(lh_doall_arg); -static void -expand(_LHASH *lh) -{ - LHASH_NODE **n, **n1, **n2, *np; - unsigned int p, i, j; - unsigned long hash, nni; - - lh->num_nodes++; - lh->num_expands++; - p = (int)lh->p++; - n1 = &(lh->b[p]); - n2 = &(lh->b[p + (int)lh->pmax]); - *n2 = NULL; /* 27/07/92 - eay - undefined pointer bug */ - nni = lh->num_alloc_nodes; - - for (np = *n1; np != NULL; ) { -#ifndef OPENSSL_NO_HASH_COMP - hash = np->hash; -#else - hash = lh->hash(np->data); - lh->num_hash_calls++; -#endif - if ((hash % nni) != p) { /* move it */ - *n1 = (*n1)->next; - np->next= *n2; - *n2 = np; - } else - n1 = &((*n1)->next); - np= *n1; - } - - if ((lh->p) >= lh->pmax) { - j = (int)lh->num_alloc_nodes * 2; - n = reallocarray(lh->b, j, sizeof(LHASH_NODE *)); - if (n == NULL) { -/* fputs("realloc error in lhash", stderr); */ - lh->error++; - lh->p = 0; - return; - } - /* else */ - for (i = (int)lh->num_alloc_nodes; i < j; i++)/* 26/02/92 eay */ - n[i] = NULL; /* 02/03/92 eay */ - lh->pmax = lh->num_alloc_nodes; - lh->num_alloc_nodes = j; - lh->num_expand_reallocs++; - lh->p = 0; - lh->b = n; - } -} - -static void -contract(_LHASH *lh) -{ - LHASH_NODE **n, *n1, *np; - - np = lh->b[lh->p + lh->pmax - 1]; - lh->b[lh->p+lh->pmax - 1] = NULL; /* 24/07-92 - eay - weird but :-( */ - if (lh->p == 0) { - n = reallocarray(lh->b, lh->pmax, sizeof(LHASH_NODE *)); - if (n == NULL) { -/* fputs("realloc error in lhash", stderr); */ - lh->error++; - return; - } - lh->num_contract_reallocs++; - lh->num_alloc_nodes /= 2; - lh->pmax /= 2; - lh->p = lh->pmax - 1; - lh->b = n; - } else - lh->p--; - - lh->num_nodes--; - lh->num_contracts++; - - n1 = lh->b[(int)lh->p]; - if (n1 == NULL) - lh->b[(int)lh->p] = np; - else { - while (n1->next != NULL) - n1 = n1->next; - n1->next = np; - } -} - -static LHASH_NODE ** -getrn(_LHASH *lh, const void *data, unsigned long *rhash) -{ - LHASH_NODE **ret, *n1; - unsigned long hash, nn; - LHASH_COMP_FN_TYPE cf; - - hash = (*(lh->hash))(data); - lh->num_hash_calls++; - *rhash = hash; - - nn = hash % lh->pmax; - if (nn < lh->p) - nn = hash % lh->num_alloc_nodes; - - cf = lh->comp; - ret = &(lh->b[(int)nn]); - for (n1 = *ret; n1 != NULL; n1 = n1->next) { -#ifndef OPENSSL_NO_HASH_COMP - lh->num_hash_comps++; - if (n1->hash != hash) { - ret = &(n1->next); - continue; - } -#endif - lh->num_comp_calls++; - if (cf(n1->data, data) == 0) - break; - ret = &(n1->next); - } - return (ret); -} - /* The following hash seems to work very well on normal text strings * no collisions on /usr/dict/words and it distributes on %2^n quite * well, not as good as MD5, but still good. diff --git a/sys/arch/amd64/include/endian.h b/sys/arch/amd64/include/endian.h index 3b077cd92..3a2b46d2c 100644 --- a/sys/arch/amd64/include/endian.h +++ b/sys/arch/amd64/include/endian.h @@ -1,4 +1,4 @@ -/* $OpenBSD: endian.h,v 1.7 2018/10/02 21:30:44 naddy Exp $ */ +/* $OpenBSD: endian.h,v 1.8 2024/05/07 14:26:48 naddy Exp $ */ /*- * Copyright (c) 1997 Niklas Hallqvist. All rights reserved. @@ -27,34 +27,6 @@ #ifndef _MACHINE_ENDIAN_H_ #define _MACHINE_ENDIAN_H_ -#ifndef __FROM_SYS__ENDIAN -#include -#endif - -static __inline __uint16_t -__swap16md(__uint16_t _x) -{ - __asm ("rorw $8, %w0" : "+r" (_x)); - return (_x); -} - -static __inline __uint32_t -__swap32md(__uint32_t _x) -{ - __asm ("bswap %0" : "+r" (_x)); - return (_x); -} - -static __inline __uint64_t -__swap64md(__uint64_t _x) -{ - __asm ("bswapq %0" : "+r" (_x)); - return (_x); -} - -/* Tell sys/endian.h we have MD variants of the swap macros. */ -#define __HAVE_MD_SWAP - #define _BYTE_ORDER _LITTLE_ENDIAN #ifndef __FROM_SYS__ENDIAN diff --git a/sys/arch/arm/include/endian.h b/sys/arch/arm/include/endian.h index 739ee04af..1e31015f7 100644 --- a/sys/arch/arm/include/endian.h +++ b/sys/arch/arm/include/endian.h @@ -1,4 +1,4 @@ -/* $OpenBSD: endian.h,v 1.11 2018/10/02 21:30:44 naddy Exp $ */ +/* $OpenBSD: endian.h,v 1.12 2024/05/07 14:26:48 naddy Exp $ */ /* * Copyright (c) 2015 David Gwynne @@ -19,48 +19,11 @@ #ifndef _ARM_ENDIAN_H_ #define _ARM_ENDIAN_H_ -#ifndef __FROM_SYS__ENDIAN -#include -#endif - -static __inline __uint16_t -__swap16md(__uint16_t _x) -{ - __uint16_t _rv; - - __asm ("rev16 %0, %1" : "=r" (_rv) : "r" (_x)); - - return (_rv); -} - -static __inline __uint32_t -__swap32md(__uint32_t _x) -{ - __uint32_t _rv; - - __asm ("rev %0, %1" : "=r" (_rv) : "r" (_x)); - - return (_rv); -} - -static __inline __uint64_t -__swap64md(__uint64_t _x) -{ - __uint64_t _rv; - - _rv = (__uint64_t)__swap32md(_x >> 32) | - (__uint64_t)__swap32md(_x) << 32; - - return (_rv); -} - -/* Tell sys/endian.h we have MD variants of the swap macros. */ -#define __HAVE_MD_SWAP - #define _BYTE_ORDER _LITTLE_ENDIAN #define __STRICT_ALIGNMENT #ifndef __FROM_SYS__ENDIAN #include #endif + #endif /* _ARM_ENDIAN_H_ */ diff --git a/sys/arch/arm64/include/endian.h b/sys/arch/arm64/include/endian.h index 605a4a73a..db5d10fd9 100644 --- a/sys/arch/arm64/include/endian.h +++ b/sys/arch/arm64/include/endian.h @@ -1,4 +1,4 @@ -/* $OpenBSD: endian.h,v 1.3 2018/10/01 17:42:16 naddy Exp $ */ +/* $OpenBSD: endian.h,v 1.4 2024/05/07 14:26:48 naddy Exp $ */ /* * Copyright (c) 2015 David Gwynne @@ -19,48 +19,11 @@ #ifndef _MACHINE_ENDIAN_H_ #define _MACHINE_ENDIAN_H_ -#ifndef __FROM_SYS__ENDIAN -#include -#endif - -static __inline __uint16_t -__swap16md(__uint16_t _x) -{ - __uint16_t _rv; - - __asm ("rev16 %w0, %w1" : "=r" (_rv) : "r"(_x)); - - return (_rv); -} - -static __inline __uint32_t -__swap32md(__uint32_t _x) -{ - __uint32_t _rv; - - __asm ("rev %w0, %w1" : "=r" (_rv) : "r"(_x)); - - return (_rv); -} - -static __inline __uint64_t -__swap64md(__uint64_t _x) -{ - __uint64_t _rv; - - __asm ("rev %x0, %x1" : "=r" (_rv) : "r"(_x)); - - return (_rv); -} - -/* Tell sys/endian.h we have MD variants of the swap macros. */ -#define __HAVE_MD_SWAP - - #define _BYTE_ORDER _LITTLE_ENDIAN #define __STRICT_ALIGNMENT #ifndef __FROM_SYS__ENDIAN #include #endif + #endif /* _MACHINE_ENDIAN_H_ */ diff --git a/sys/arch/i386/include/endian.h b/sys/arch/i386/include/endian.h index b107da44d..248f98473 100644 --- a/sys/arch/i386/include/endian.h +++ b/sys/arch/i386/include/endian.h @@ -1,4 +1,4 @@ -/* $OpenBSD: endian.h,v 1.19 2018/10/02 21:30:44 naddy Exp $ */ +/* $OpenBSD: endian.h,v 1.20 2024/05/07 14:26:48 naddy Exp $ */ /*- * Copyright (c) 1997 Niklas Hallqvist. All rights reserved. @@ -27,34 +27,6 @@ #ifndef _MACHINE_ENDIAN_H_ #define _MACHINE_ENDIAN_H_ -#ifndef __FROM_SYS__ENDIAN -#include -#endif - -static __inline __uint16_t -__swap16md(__uint16_t _x) -{ - __asm ("rorw $8, %w0" : "+r" (_x)); - return (_x); -} - -static __inline __uint32_t -__swap32md(__uint32_t _x) -{ - __asm ("bswap %0" : "+r" (_x)); - return (_x); -} - -static __inline __uint64_t -__swap64md(__uint64_t _x) -{ - return ((__uint64_t)__swap32md(_x >> 32) | - (__uint64_t)__swap32md(_x & 0xffffffff) << 32); -} - -/* Tell sys/endian.h we have MD variants of the swap macros. */ -#define __HAVE_MD_SWAP - #define _BYTE_ORDER _LITTLE_ENDIAN #ifndef __FROM_SYS__ENDIAN diff --git a/sys/dev/pci/if_bnxt.c b/sys/dev/pci/if_bnxt.c index 7177f4684..1158b5c3a 100644 --- a/sys/dev/pci/if_bnxt.c +++ b/sys/dev/pci/if_bnxt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bnxt.c,v 1.48 2024/04/12 19:27:43 jan Exp $ */ +/* $OpenBSD: if_bnxt.c,v 1.49 2024/05/07 18:35:23 jan Exp $ */ /*- * Broadcom NetXtreme-C/E network driver. * @@ -1427,7 +1427,7 @@ bnxt_start(struct ifqueue *ifq) uint32_t paylen; ether_extract_headers(m, &ext); - if (ext.tcp) { + if (ext.tcp && m->m_pkthdr.ph_mss > 0) { lflags |= TX_BD_LONG_LFLAGS_LSO; hdrsize = sizeof(*ext.eh); if (ext.ip4 || ext.ip6) diff --git a/sys/dev/pci/if_em.c b/sys/dev/pci/if_em.c index 6f89b3f07..359956965 100644 --- a/sys/dev/pci/if_em.c +++ b/sys/dev/pci/if_em.c @@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ -/* $OpenBSD: if_em.c,v 1.374 2024/02/16 22:30:54 mglocker Exp $ */ +/* $OpenBSD: if_em.c,v 1.375 2024/05/07 18:35:23 jan Exp $ */ /* $FreeBSD: if_em.c,v 1.46 2004/09/29 18:28:28 mlaier Exp $ */ #include @@ -2452,7 +2452,7 @@ em_tso_setup(struct em_queue *que, struct mbuf *mp, u_int head, #endif ether_extract_headers(mp, &ext); - if (ext.tcp == NULL) + if (ext.tcp == NULL || mp->m_pkthdr.ph_mss == 0) goto out; vlan_macip_lens |= (sizeof(*ext.eh) << E1000_ADVTXD_MACLEN_SHIFT); diff --git a/sys/dev/pci/if_igc.c b/sys/dev/pci/if_igc.c index 880ad03a0..a23036070 100644 --- a/sys/dev/pci/if_igc.c +++ b/sys/dev/pci/if_igc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_igc.c,v 1.22 2024/05/06 04:25:52 dlg Exp $ */ +/* $OpenBSD: if_igc.c,v 1.23 2024/05/07 18:35:23 jan Exp $ */ /*- * SPDX-License-Identifier: BSD-2-Clause * @@ -2093,7 +2093,7 @@ igc_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp, int prod, } if (ISSET(mp->m_pkthdr.csum_flags, M_TCP_TSO)) { - if (ext.tcp) { + if (ext.tcp && mp->m_pkthdr.ph_mss > 0) { uint32_t hdrlen, thlen, paylen, outlen; thlen = ext.tcphlen; diff --git a/sys/dev/pci/if_ix.c b/sys/dev/pci/if_ix.c index 4f79dc58a..ba83d0a53 100644 --- a/sys/dev/pci/if_ix.c +++ b/sys/dev/pci/if_ix.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ix.c,v 1.212 2024/05/01 10:43:42 jan Exp $ */ +/* $OpenBSD: if_ix.c,v 1.213 2024/05/07 18:35:23 jan Exp $ */ /****************************************************************************** @@ -2535,7 +2535,7 @@ ixgbe_tx_offload(struct mbuf *mp, uint32_t *vlan_macip_lens, } if (mp->m_pkthdr.csum_flags & M_TCP_TSO) { - if (ext.tcp) { + if (ext.tcp && mp->m_pkthdr.ph_mss > 0) { uint32_t hdrlen, thlen, paylen, outlen; thlen = ext.tcphlen; diff --git a/sys/dev/pci/if_ixl.c b/sys/dev/pci/if_ixl.c index edb10ff4b..1cb289f6e 100644 --- a/sys/dev/pci/if_ixl.c +++ b/sys/dev/pci/if_ixl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ixl.c,v 1.98 2024/04/12 19:27:43 jan Exp $ */ +/* $OpenBSD: if_ixl.c,v 1.99 2024/05/07 18:35:23 jan Exp $ */ /* * Copyright (c) 2013-2015, Intel Corporation @@ -2848,7 +2848,7 @@ ixl_tx_setup_offload(struct mbuf *m0, struct ixl_tx_ring *txr, } if (ISSET(m0->m_pkthdr.csum_flags, M_TCP_TSO)) { - if (ext.tcp) { + if (ext.tcp && m0->m_pkthdr.ph_mss > 0) { struct ixl_tx_desc *ring, *txd; uint64_t cmd = 0, paylen, outlen; diff --git a/sys/dev/pci/if_vmx.c b/sys/dev/pci/if_vmx.c index 81bb0834c..87e9c926c 100644 --- a/sys/dev/pci/if_vmx.c +++ b/sys/dev/pci/if_vmx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_vmx.c,v 1.83 2024/04/02 20:59:48 jan Exp $ */ +/* $OpenBSD: if_vmx.c,v 1.84 2024/05/07 18:35:23 jan Exp $ */ /* * Copyright (c) 2013 Tsubai Masanari @@ -1463,7 +1463,7 @@ vmxnet3_tx_offload(struct vmxnet3_txdesc *sop, struct mbuf *m) * TCP Segmentation Offload */ - if (ext.tcp == NULL) { + if (ext.tcp == NULL || m->m_pkthdr.ph_mss == 0) { tcpstat_inc(tcps_outbadtso); return; } diff --git a/sys/dev/pv/if_vio.c b/sys/dev/pv/if_vio.c index 9ad8e36e3..919c2aa13 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.32 2024/04/10 19:55:50 jan Exp $ */ +/* $OpenBSD: if_vio.c,v 1.33 2024/05/07 18:35:23 jan Exp $ */ /* * Copyright (c) 2012 Stefan Fritsch, Alexander Fiveg. @@ -777,7 +777,7 @@ vio_tx_offload(struct virtio_net_hdr *hdr, struct mbuf *m) if (!ISSET(m->m_pkthdr.csum_flags, M_TCP_TSO)) return; - if (!ext.tcp) { + if (!ext.tcp || m->m_pkthdr.ph_mss == 0) { tcpstat_inc(tcps_outbadtso); return; } diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 6ee3b7d1a..82e6e2d4b 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sig.c,v 1.325 2024/04/18 09:06:42 claudio Exp $ */ +/* $OpenBSD: kern_sig.c,v 1.326 2024/05/07 10:46:35 claudio Exp $ */ /* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */ /* @@ -1171,7 +1171,7 @@ ptsignal(struct proc *p, int signum, enum signal_type type) atomic_clearbits_int(&p->p_flag, P_SUSPSIG); wakeparent = 1; if (action == SIG_DFL) - atomic_clearbits_int(siglist, mask); + mask = 0; if (action == SIG_CATCH) goto runfast; if (p->p_wchan == NULL) diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c index e8401225f..96e24f8d3 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket2.c,v 1.153 2024/05/03 17:43:09 mvs Exp $ */ +/* $OpenBSD: uipc_socket2.c,v 1.154 2024/05/07 15:54:23 claudio Exp $ */ /* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */ /* @@ -552,7 +552,10 @@ sblock(struct socket *so, struct sockbuf *sb, int flags) if (!(flags & SBL_WAIT)) rwflags |= RW_NOSLEEP; - return rw_enter(&sb->sb_lock, rwflags); + error = rw_enter(&sb->sb_lock, rwflags); + if (error == EBUSY) + error = EWOULDBLOCK; + return error; } soassertlocked(so); diff --git a/sys/miscfs/fuse/fuse_vfsops.c b/sys/miscfs/fuse/fuse_vfsops.c index 5b30b1544..c848894b3 100644 --- a/sys/miscfs/fuse/fuse_vfsops.c +++ b/sys/miscfs/fuse/fuse_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fuse_vfsops.c,v 1.45 2021/05/01 16:18:29 gnezdo Exp $ */ +/* $OpenBSD: fuse_vfsops.c,v 1.46 2024/05/07 14:27:11 mvs Exp $ */ /* * Copyright (c) 2012-2013 Sylvestre Gallon * @@ -114,7 +114,8 @@ fusefs_mount(struct mount *mp, const char *path, void *data, fmp->allow_other = args->allow_other; mp->mnt_data = fmp; - mp->mnt_flag |= MNT_LOCAL; + /* FUSE file system is not truly local. */ + mp->mnt_flag &= ~MNT_LOCAL; vfs_getnewfsid(mp); memset(mp->mnt_stat.f_mntonname, 0, MNAMELEN); diff --git a/usr.bin/ssh/ssh-keyscan.c b/usr.bin/ssh/ssh-keyscan.c index 7fb8c9e33..3dbc64cf1 100644 --- a/usr.bin/ssh/ssh-keyscan.c +++ b/usr.bin/ssh/ssh-keyscan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keyscan.c,v 1.156 2024/04/30 15:40:43 tobias Exp $ */ +/* $OpenBSD: ssh-keyscan.c,v 1.157 2024/05/06 19:26:17 tobias Exp $ */ /* * Copyright 1995, 1996 by David Mazieres . * @@ -96,19 +96,13 @@ typedef struct Connection { u_char c_status; /* State of connection on this file desc. */ #define CS_UNUSED 0 /* File descriptor unused */ #define CS_CON 1 /* Waiting to connect/read greeting */ -#define CS_SIZE 2 /* Waiting to read initial packet size */ -#define CS_KEYS 3 /* Waiting to read public key packet */ int c_fd; /* Quick lookup: c->c_fd == c - fdcon */ - int c_plen; /* Packet length field for ssh packet */ - int c_len; /* Total bytes which must be read. */ - int c_off; /* Length of data read so far. */ int c_keytype; /* Only one of KT_* */ sig_atomic_t c_done; /* SSH2 done */ char *c_namebase; /* Address to free for c_name and c_namelist */ char *c_name; /* Hostname of connection for errors */ char *c_namelist; /* Pointer to other possible addresses */ char *c_output_name; /* Hostname of connection for output */ - char *c_data; /* Data read from this fd */ struct ssh *c_ssh; /* SSH-connection */ struct timespec c_ts; /* Time at which connection gets aborted */ TAILQ_ENTRY(Connection) c_link; /* List of connections in timeout order. */ @@ -397,9 +391,6 @@ conalloc(const char *iname, const char *oname, int keytype) fdcon[s].c_name = name; fdcon[s].c_namelist = namelist; fdcon[s].c_output_name = xstrdup(oname); - fdcon[s].c_data = (char *) &fdcon[s].c_plen; - fdcon[s].c_len = 4; - fdcon[s].c_off = 0; fdcon[s].c_keytype = keytype; monotime_ts(&fdcon[s].c_ts); fdcon[s].c_ts.tv_sec += timeout; @@ -417,8 +408,6 @@ confree(int s) fatal("confree: attempt to free bad fdno %d", s); free(fdcon[s].c_namebase); free(fdcon[s].c_output_name); - if (fdcon[s].c_status == CS_KEYS) - free(fdcon[s].c_data); fdcon[s].c_status = CS_UNUSED; fdcon[s].c_keytype = 0; if (fdcon[s].c_ssh) { @@ -433,15 +422,6 @@ confree(int s) ncon--; } -static void -contouch(int s) -{ - TAILQ_REMOVE(&tq, &fdcon[s], c_link); - monotime_ts(&fdcon[s].c_ts); - fdcon[s].c_ts.tv_sec += timeout; - TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link); -} - static int conrecycle(int s) { @@ -546,35 +526,11 @@ static void conread(int s) { con *c = &fdcon[s]; - size_t n; - if (c->c_status == CS_CON) { - congreet(s); - return; - } - n = atomicio(read, s, c->c_data + c->c_off, c->c_len - c->c_off); - if (n == 0) { - error("read (%s): %s", c->c_name, strerror(errno)); - confree(s); - return; - } - c->c_off += n; + if (c->c_status != CS_CON) + fatal("conread: invalid status %d", c->c_status); - if (c->c_off == c->c_len) - switch (c->c_status) { - case CS_SIZE: - c->c_plen = htonl(c->c_plen); - c->c_len = c->c_plen + 8 - (c->c_plen & 7); - c->c_off = 0; - c->c_data = xmalloc(c->c_len); - c->c_status = CS_KEYS; - break; - default: - fatal("conread: invalid status %d", c->c_status); - break; - } - - contouch(s); + congreet(s); } static void diff --git a/usr.bin/tty/tty.c b/usr.bin/tty/tty.c index 14beca8e9..ae4bc17b9 100644 --- a/usr.bin/tty/tty.c +++ b/usr.bin/tty/tty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty.c,v 1.13 2022/12/04 23:50:50 cheloha Exp $ */ +/* $OpenBSD: tty.c,v 1.14 2024/05/06 16:49:46 cheloha Exp $ */ /* $NetBSD: tty.c,v 1.4 1994/12/07 00:46:57 jtc Exp $ */ /* @@ -57,9 +57,9 @@ main(int argc, char *argv[]) } if (unveil(_PATH_DEVDB, "r") == -1) - err(1, "unveil %s", _PATH_DEVDB); + err(2, "unveil %s", _PATH_DEVDB); if (pledge("stdio rpath", NULL) == -1) - err(1, "pledge"); + err(2, "pledge"); t = ttyname(STDIN_FILENO); if (!sflag) diff --git a/usr.bin/vmstat/dkstats.c b/usr.bin/vmstat/dkstats.c index df4e8d50b..b52825669 100644 --- a/usr.bin/vmstat/dkstats.c +++ b/usr.bin/vmstat/dkstats.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dkstats.c,v 1.41 2019/06/28 13:35:05 deraadt Exp $ */ +/* $OpenBSD: dkstats.c,v 1.42 2024/05/06 16:54:22 cheloha Exp $ */ /* $NetBSD: dkstats.c,v 1.1 1996/05/10 23:19:27 thorpej Exp $ */ /* @@ -101,11 +101,6 @@ int dk_ndrive = 0; int *dk_select; char **dr_name; -/* Missing from */ -#define timerset(tvp, uvp) \ - ((uvp)->tv_sec = (tvp)->tv_sec); \ - ((uvp)->tv_usec = (tvp)->tv_usec) - #define SWAP(fld) tmp = cur.fld; \ cur.fld -= last.fld; \ last.fld = tmp @@ -135,11 +130,9 @@ dkswap(void) SWAP(dk_wbytes[i]); /* Delta Time. */ - timerclear(&tmp_timer); - timerset(&(cur.dk_time[i]), &tmp_timer); - timersub(&tmp_timer, &(last.dk_time[i]), &(cur.dk_time[i])); - timerclear(&(last.dk_time[i])); - timerset(&tmp_timer, &(last.dk_time[i])); + tmp_timer = cur.dk_time[i]; + timersub(&tmp_timer, &last.dk_time[i], &cur.dk_time[i]); + last.dk_time[i] = tmp_timer; } for (i = 0; i < CPUSTATES; i++) { long ltmp; @@ -370,7 +363,7 @@ dkreadstats(void) cur.dk_seek[i] = q[i].ds_seek; cur.dk_rbytes[i] = q[i].ds_rbytes; cur.dk_wbytes[i] = q[i].ds_wbytes; - timerset(&(q[i].ds_time), &(cur.dk_time[i])); + cur.dk_time[i] = q[i].ds_time; } free(q); @@ -408,7 +401,7 @@ dkreadstats(void) cur.dk_seek[i] = cur_disk.dk_seek; cur.dk_rbytes[i] = cur_disk.dk_rbytes; cur.dk_wbytes[i] = cur_disk.dk_wbytes; - timerset(&(cur_disk.dk_time), &(cur.dk_time[i])); + cur.dk_time[i] = cur_disk.dk_time; p = TAILQ_NEXT(&cur_disk, dk_link); } deref_nl(X_CP_TIME, cur.cp_time, sizeof(cur.cp_time)); diff --git a/usr.sbin/smtpd/makemap.c b/usr.sbin/smtpd/makemap.c index b5d88a8bd..d883389b4 100644 --- a/usr.sbin/smtpd/makemap.c +++ b/usr.sbin/smtpd/makemap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: makemap.c,v 1.76 2024/02/11 09:24:26 op Exp $ */ +/* $OpenBSD: makemap.c,v 1.77 2024/05/07 12:10:06 op Exp $ */ /* * Copyright (c) 2008 Gilles Chehade @@ -57,7 +57,8 @@ enum output_type { * Stub functions so that makemap compiles using minimum object files. */ int -fork_proc_backend(const char *backend, const char *conf, const char *procname) +fork_proc_backend(const char *backend, const char *conf, const char *procname, + int do_stdout) { return (-1); } diff --git a/usr.sbin/smtpd/queue_proc.c b/usr.sbin/smtpd/queue_proc.c index a3601e5dd..ff8fe779b 100644 --- a/usr.sbin/smtpd/queue_proc.c +++ b/usr.sbin/smtpd/queue_proc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: queue_proc.c,v 1.10 2024/01/20 09:01:03 claudio Exp $ */ +/* $OpenBSD: queue_proc.c,v 1.11 2024/05/07 12:10:06 op Exp $ */ /* * Copyright (c) 2013 Eric Faurot @@ -287,7 +287,7 @@ queue_proc_init(struct passwd *pw, int server, const char *conf) uint32_t version; int fd; - fd = fork_proc_backend("queue", conf, "queue-proc"); + fd = fork_proc_backend("queue", conf, "queue-proc", 0); if (fd == -1) fatalx("queue-proc: exiting"); diff --git a/usr.sbin/smtpd/scheduler_proc.c b/usr.sbin/smtpd/scheduler_proc.c index 402d36955..b601b905e 100644 --- a/usr.sbin/smtpd/scheduler_proc.c +++ b/usr.sbin/smtpd/scheduler_proc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scheduler_proc.c,v 1.9 2021/06/14 17:58:16 eric Exp $ */ +/* $OpenBSD: scheduler_proc.c,v 1.10 2024/05/07 12:10:06 op Exp $ */ /* * Copyright (c) 2013 Eric Faurot @@ -100,7 +100,7 @@ scheduler_proc_init(const char *conf) int fd, r; uint32_t version; - fd = fork_proc_backend("scheduler", conf, "scheduler-proc"); + fd = fork_proc_backend("scheduler", conf, "scheduler-proc", 0); if (fd == -1) fatalx("scheduler-proc: exiting"); diff --git a/usr.sbin/smtpd/smtpd-tables.7 b/usr.sbin/smtpd/smtpd-tables.7 new file mode 100644 index 000000000..a7f1dc436 --- /dev/null +++ b/usr.sbin/smtpd/smtpd-tables.7 @@ -0,0 +1,272 @@ +.\" $OpenBSD: smtpd-tables.7,v 1.1 2024/05/07 12:13:43 op Exp $ +.\" +.\" Copyright (c) 2008 Janne Johansson +.\" Copyright (c) 2009 Jacek Masiulaniec +.\" Copyright (c) 2012 Gilles Chehade +.\" Copyright (c) 2024 Omar Polo +.\" +.\" 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. +.\" +.\" +.Dd $Mdocdate: May 7 2024 $ +.Dt SMTPD-TABLES 7 +.Os +.Sh NAME +.Nm smtpd-tables +.Nd table API for the smtpd daemon +.Sh DESCRIPTION +The +.Xr smtpd 8 +daemon provides a Simple Mail Transfer Protocol (SMTPD) implementation, +which allows ordinary machines to become Mail eXchangers (MX). +Some features that are commonly used by MX, +such as querying databases for user credentials, +are outside of the scope of SMTP and too complex to fit in +.Xr smtpd 8 . +.Pp +Because an MX may need to provide these features, +.Xr smtpd 8 +provides an API to implement +.Xr table 5 +backends with a simple text-based protocol. +.Sh DESIGN +.Nm +are programs that run as unique standalone processes, +they do not share +.Xr smtpd 8 +address space. +They are executed by +.Xr smtpd 8 +at startup and expected to run in an infinite loop, +reading events and queries from standard input and +writing responses to standard output. +They are not allowed to terminate. +.Pp +Because +.Nm +are standalone programs that communicate with +.Xr smtpd 8 , +they may run as different users than +.Xr smtpd 8 +and may be written in any language. +.Nm +must not use blocking I/O, +they must support answering asynchronously to +.Xr smtpd 8 . +.Sh PROTOCOL +The protocol consist of human-readable lines exchanged between +.Nm +and +.Xr smtpd 8 . +.Pp +The protocol begins with a handshake. +First, +.Xr smtpd 8 +provides +.Nm +with general configuration information in the form of +key-value lines, terminated by +.Ql config|ready . +For example: +.Bd -literal -offset indent +config|smtpd-version|7.5.0 +config|protocol|0.1 +config|tablename|devs +config|ready +.Ed +.Pp +Then, +.Nm +register the supported services, terminating with +.Ql register|ready . +For example: +.Bd -literal -offset indent +register|alias +register|credentials +register|ready +.Ed +.Pp +Finally, +.Xr smtpd 8 +can start querying the table. +For example: +.Bd -literal -offset indent +table|0.1|1713795082.354255|devs|lookup|alias|b72508d|op +.Ed +.Pp +The +.Dq | +character is used to separate the fields and may only appear +verbatim in the last field of the payload, in which case it +should be considered a regular character and not a separator. +No other field may contain a +.Dq | . +.Pp +Each request has a common set of fields, followed by some +other fields that are operation-specific. +The common format consists of a protocol prefix +.Sq table , +the protocol version, the timestamp and the table name. +For example: +.Bd -literal -offset indent +table|0.1|1713795091.202157|devs +.Ed +.Pp +The protocol is inherently asynchronous, so multiple request +may be sent without waiting for the table to reply. +All the replies have a common prefix, followed by the +operation-specific response. +The common format consist of a prefix with the operation name +in followed by +.Sq -result , +and the unique ID of the request. +For example: +.Bd -literal -offset indent +lookup-result|b72508d +.Ed +.Pp +The list of operations, operation-specific parameters and +responses are as follows: +.Bl -tag -width Ds +.It Cm update Ar id +Ask the table to reload its configuration. +The result is either +.Sq ok +on success or +.Sq error +upon a failure to do so. +.It Cm check Ar service id query +Check whether +.Ar query +is present in the table. +The result is +.Sq found +if found, +.Sq not-found +if not, or +.Sq error +upon an error. +.It Cm lookup Ar service id query +Look up a value in the table for given the +.Ar query . +The result is +.Sq found +and the value if found, +.Sq not-found +if not found, or +.Sq error +upon an error. +.It Cm fetch Ar service id +Fetch the next item from the table. +It is only supported for the +.Ic source +and +.Ic relayhost +services. +The result is +.Sq found +and the value if found, +.Sq not-found +if not found, or +.Sq error +upon an error. +.El +.Pp +Each service has a specific format for the result. +The exact syntax for the values and eventually the keys are +described in +.Xr table 5 . +The services and their result format are as follows: +.Pp +.Bl -tag -width mailaddrmap -compact +.It Ic alias +One or more aliases separated by a comma. +.It Ic domain +A domain name. +.\" XXX are wildcards allowed? +.It Ic credentials +The user name, followed by +.Sq \&: +and the encrypted password as per +.Xr smtpctl 8 +.Cm encrypt +subcommand. +.It Ic netaddr +IPv4 and IPv6 address or netmask. +.It Ic userinfo +The user id, followed by +.Sq \&: +then the group id, then +.Sq \&: +and finally the home directory. +.It Ic source +IPv4 and IPv6 address. +.It Ic mailaddr +An username, a domain or a full email address. +.It Ic addrname +Used to map IP addresses to hostnames. +.\" .It Ic mailaddrmap +.\" XXX missing K_RELAYHOST, K_STRING and K_REGEX +.El +.Sh EXAMPLES +Assuming the table is called +.Dq devs , +here's an example of a successful +.Cm update +transaction: +.Bd -literal -offset indent +table|0.1|1713795097.394049|devs|update|478ff0d2 +update-result|478ff0d2|ok +.Ed +.Pp +A +.Cm check +request for the +.Ic netaddr +service for the 192.168.0.7 IPv4 address which is +not in the table: +.Bd -literal -offset indent +table|0.1|1713795103.314423|devs|check|netaddr|e5862859|192.168.0.7 +check-result|e5862859|not-found +.Ed +.Pp +A successful +.Cm lookup +request for the +.Ic userinfo +service for the user +.Sq op : +.Bd -literal -offset indent +table|0.1|1713795110.354921|devs|lookup|userinfo|f993c74|op +lookup-result|f993c74|found|1000:1000:/home/op +.Ed +.Pp +A series of +.Cm fetch +requests for the +.Cm source +service: +.Bd -literal -offset indent +table|0.1|1713795116.227321|devs|fetch|source|189bd3ee +lookup-result|189bd3ee|found|192.168.1.7 +table|0.1|1713795120.162438|devs|fetch|source|9e4c56d4 +lookup-result|9e4c56d4|found|10.0.0.8 +table|0.1|1713795122.930928|devs|fetch|source|f2c8b906 +lookup-result|f2c8b906|not-found +.Ed +.Sh SEE ALSO +.Xr smtpd 8 +.Sh HISTORY +.Nm +first appeared in +.Ox 7.6 . diff --git a/usr.sbin/smtpd/smtpd.c b/usr.sbin/smtpd/smtpd.c index 813dad19e..af471ac46 100644 --- a/usr.sbin/smtpd/smtpd.c +++ b/usr.sbin/smtpd/smtpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.c,v 1.350 2024/04/24 21:31:31 op Exp $ */ +/* $OpenBSD: smtpd.c,v 1.351 2024/05/07 12:10:06 op Exp $ */ /* * Copyright (c) 2008 Gilles Chehade @@ -1127,7 +1127,8 @@ load_pki_keys(void) } int -fork_proc_backend(const char *key, const char *conf, const char *procname) +fork_proc_backend(const char *key, const char *conf, const char *procname, + int do_stdout) { pid_t pid; int sp[2]; @@ -1165,6 +1166,8 @@ fork_proc_backend(const char *key, const char *conf, const char *procname) if (pid == 0) { /* child process */ dup2(sp[0], STDIN_FILENO); + if (do_stdout) + dup2(sp[0], STDOUT_FILENO); if (closefrom(STDERR_FILENO + 1) == -1) exit(1); diff --git a/usr.sbin/smtpd/smtpd.h b/usr.sbin/smtpd/smtpd.h index db7a8bacd..0ab99d7f4 100644 --- a/usr.sbin/smtpd/smtpd.h +++ b/usr.sbin/smtpd/smtpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: smtpd.h,v 1.683 2024/03/02 22:40:28 op Exp $ */ +/* $OpenBSD: smtpd.h,v 1.684 2024/05/07 12:10:06 op Exp $ */ /* * Copyright (c) 2008 Gilles Chehade @@ -1620,7 +1620,7 @@ const char *proc_name(enum smtp_proc_type); const char *proc_title(enum smtp_proc_type); const char *imsg_to_str(int); void log_imsg(int, int, struct imsg *); -int fork_proc_backend(const char *, const char *, const char *); +int fork_proc_backend(const char *, const char *, const char *, int); /* srs.c */ @@ -1640,6 +1640,8 @@ struct stat_value *stat_timespec(struct timespec *); /* table.c */ +const char *table_service_name(enum table_service); +int table_service_from_name(const char *); struct table *table_find(struct smtpd *, const char *); struct table *table_create(struct smtpd *, const char *, const char *, const char *); diff --git a/usr.sbin/smtpd/smtpd/Makefile b/usr.sbin/smtpd/smtpd/Makefile index d914b43f7..146f75bef 100644 --- a/usr.sbin/smtpd/smtpd/Makefile +++ b/usr.sbin/smtpd/smtpd/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.114 2021/11/20 19:11:33 jmc Exp $ +# $OpenBSD: Makefile,v 1.115 2024/05/07 09:10:33 op Exp $ .PATH: ${.CURDIR}/.. @@ -76,7 +76,9 @@ SRCS+= scheduler_proc.c SRCS+= stat_ramstat.c -MAN= sendmail.8 smtpd.8 smtpd-filters.7 smtpd.conf.5 table.5 +MAN= sendmail.8 smtpd.8 smtpd-filters.7 smtpd-tables.7 +MAN+= smtpd.conf.5 table.5 + BINDIR= /usr/sbin LDADD+= -levent -lutil -ltls -lssl -lcrypto -lz diff --git a/usr.sbin/smtpd/table.c b/usr.sbin/smtpd/table.c index 99db7b0a3..d24892ede 100644 --- a/usr.sbin/smtpd/table.c +++ b/usr.sbin/smtpd/table.c @@ -1,4 +1,4 @@ -/* $OpenBSD: table.c,v 1.51 2024/01/04 09:34:03 op Exp $ */ +/* $OpenBSD: table.c,v 1.52 2024/05/07 12:10:06 op Exp $ */ /* * Copyright (c) 2013 Eric Faurot @@ -37,7 +37,6 @@ extern struct table_backend table_backend_db; extern struct table_backend table_backend_getpwnam; extern struct table_backend table_backend_proc; -static const char * table_service_name(enum table_service); static int table_parse_lookup(enum table_service, const char *, const char *, union lookup *); static int parse_sockaddr(struct sockaddr *, int, const char *); @@ -67,27 +66,59 @@ table_backend_lookup(const char *backend) return NULL; } -static const char * +const char * table_service_name(enum table_service s) { switch (s) { - case K_NONE: return "NONE"; - case K_ALIAS: return "ALIAS"; - case K_DOMAIN: return "DOMAIN"; - case K_CREDENTIALS: return "CREDENTIALS"; - case K_NETADDR: return "NETADDR"; - case K_USERINFO: return "USERINFO"; - case K_SOURCE: return "SOURCE"; - case K_MAILADDR: return "MAILADDR"; - case K_ADDRNAME: return "ADDRNAME"; - case K_MAILADDRMAP: return "MAILADDRMAP"; - case K_RELAYHOST: return "RELAYHOST"; - case K_STRING: return "STRING"; - case K_REGEX: return "REGEX"; + case K_NONE: return "none"; + case K_ALIAS: return "alias"; + case K_DOMAIN: return "domain"; + case K_CREDENTIALS: return "credentials"; + case K_NETADDR: return "netaddr"; + case K_USERINFO: return "userinfo"; + case K_SOURCE: return "source"; + case K_MAILADDR: return "mailaddr"; + case K_ADDRNAME: return "addrname"; + case K_MAILADDRMAP: return "mailaddrmap"; + case K_RELAYHOST: return "relayhost"; + case K_STRING: return "string"; + case K_REGEX: return "regex"; } return "???"; } +int +table_service_from_name(const char *service) +{ + if (!strcmp(service, "none")) + return K_NONE; + if (!strcmp(service, "alias")) + return K_ALIAS; + if (!strcmp(service, "domain")) + return K_DOMAIN; + if (!strcmp(service, "credentials")) + return K_CREDENTIALS; + if (!strcmp(service, "netaddr")) + return K_NETADDR; + if (!strcmp(service, "userinfo")) + return K_USERINFO; + if (!strcmp(service, "source")) + return K_SOURCE; + if (!strcmp(service, "mailaddr")) + return K_MAILADDR; + if (!strcmp(service, "addrname")) + return K_ADDRNAME; + if (!strcmp(service, "mailaddrmap")) + return K_MAILADDRMAP; + if (!strcmp(service, "relayhost")) + return K_RELAYHOST; + if (!strcmp(service, "string")) + return K_STRING; + if (!strcmp(service, "regex")) + return K_REGEX; + return (-1); +} + struct table * table_find(struct smtpd *conf, const char *name) { diff --git a/usr.sbin/smtpd/table_proc.c b/usr.sbin/smtpd/table_proc.c index 56893a0fb..bd40bac6b 100644 --- a/usr.sbin/smtpd/table_proc.c +++ b/usr.sbin/smtpd/table_proc.c @@ -1,6 +1,7 @@ -/* $OpenBSD: table_proc.c,v 1.17 2021/06/14 17:58:16 eric Exp $ */ +/* $OpenBSD: table_proc.c,v 1.18 2024/05/07 12:10:06 op Exp $ */ /* + * Copyright (c) 2024 Omar Polo * Copyright (c) 2013 Eric Faurot * * Permission to use, copy, modify, and distribute this software for any @@ -17,87 +18,104 @@ */ #include +#include +#include #include +#include #include "smtpd.h" #include "log.h" +#define PROTOCOL_VERSION "0.1" + struct table_proc_priv { - pid_t pid; - struct imsgbuf ibuf; + FILE *in; + FILE *out; + char *line; + size_t linesize; + + /* + * The last ID used in a request. At the moment the protocol + * is synchronous from our point of view, so it's used to + * assert that the table replied with the correct ID. + */ + char lastid[16]; }; -static struct imsg imsg; -static size_t rlen; -static char *rdata; +static char * +table_proc_nextid(struct table *table) +{ + struct table_proc_priv *priv = table->t_handle; + int r; -extern char **environ; + r = snprintf(priv->lastid, sizeof(priv->lastid), "%lld", + (unsigned long long)arc4random()); + if (r < 0 || (size_t)r >= sizeof(priv->lastid)) + fatal("table-proc: snprintf"); + + return (priv->lastid); +} static void -table_proc_call(struct table_proc_priv *p) +table_proc_send(struct table *table, const char *type, int service, + const char *param) { - ssize_t n; + struct table_proc_priv *priv = table->t_handle; + struct timeval tv; - if (imsg_flush(&p->ibuf) == -1) { - log_warn("warn: table-proc: imsg_flush"); - fatalx("table-proc: exiting"); - } + gettimeofday(&tv, NULL); + fprintf(priv->out, "table|%s|%lld.%06ld|%s|%s", + PROTOCOL_VERSION, (long long)tv.tv_sec, (long)tv.tv_usec, + table->t_name, type); + if (service != -1) { + fprintf(priv->out, "|%s|%s", table_service_name(service), + table_proc_nextid(table)); + if (param) + fprintf(priv->out, "|%s", param); + fputc('\n', priv->out); + } else + fprintf(priv->out, "|%s\n", table_proc_nextid(table)); - while (1) { - if ((n = imsg_get(&p->ibuf, &imsg)) == -1) { - log_warn("warn: table-proc: imsg_get"); - break; - } - if (n) { - rlen = imsg.hdr.len - IMSG_HEADER_SIZE; - rdata = imsg.data; + if (fflush(priv->out) == EOF) + fatal("table-proc: fflush"); +} - if (imsg.hdr.type != PROC_TABLE_OK) { - log_warnx("warn: table-proc: bad response"); - break; - } - return; - } +static const char * +table_proc_recv(struct table *table, const char *type) +{ + struct table_proc_priv *priv = table->t_handle; + const char *l; + ssize_t linelen; + size_t len; - if ((n = imsg_read(&p->ibuf)) == -1 && errno != EAGAIN) { - log_warn("warn: table-proc: imsg_read"); - break; - } + if ((linelen = getline(&priv->line, &priv->linesize, priv->in)) == -1) + fatal("table-proc: getline"); + priv->line[strcspn(priv->line, "\n")] = '\0'; + l = priv->line; - if (n == 0) { - log_warnx("warn: table-proc: pipe closed"); - break; - } - } + len = strlen(type); + if (strncmp(l, type, len) != 0) + goto err; + l += len; + if (*l != '|') + goto err; + l++; + + len = strlen(priv->lastid); + if (strncmp(l, priv->lastid, len) != 0) + goto err; + l += len; + + if (*l != '|') + goto err; + return (++l); + + err: + log_warnx("warn: table-proc: failed to parse reply"); fatalx("table-proc: exiting"); } -static void -table_proc_read(void *dst, size_t len) -{ - if (len > rlen) { - log_warnx("warn: table-proc: bad msg len"); - fatalx("table-proc: exiting"); - } - - if (dst) - memmove(dst, rdata, len); - - rlen -= len; - rdata += len; -} - -static void -table_proc_end(void) -{ - if (rlen) { - log_warnx("warn: table-proc: bogus data"); - fatalx("table-proc: exiting"); - } - imsg_free(&imsg); -} - /* * API */ @@ -106,24 +124,53 @@ static int table_proc_open(struct table *table) { struct table_proc_priv *priv; - struct table_open_params op; - int fd; + const char *s; + ssize_t len; + int service, services = 0; + int fd, fdd; priv = xcalloc(1, sizeof(*priv)); - fd = fork_proc_backend("table", table->t_config, table->t_name); + fd = fork_proc_backend("table", table->t_config, table->t_name, 1); if (fd == -1) fatalx("table-proc: exiting"); + if ((fdd = dup(fd)) == -1) { + log_warnx("warn: table-proc: dup"); + fatalx("table-proc: exiting"); + } + if ((priv->in = fdopen(fd, "r")) == NULL) + fatalx("table-proc: fdopen"); + if ((priv->out = fdopen(fdd, "w")) == NULL) + fatalx("table-proc: fdopen"); - imsg_init(&priv->ibuf, fd); + fprintf(priv->out, "config|smtpd-version|"SMTPD_VERSION"\n"); + fprintf(priv->out, "config|protocol|"PROTOCOL_VERSION"\n"); + fprintf(priv->out, "config|tablename|%s\n", table->t_name); + fprintf(priv->out, "config|ready\n"); + if (fflush(priv->out) == EOF) + fatalx("table-proc: fflush"); - memset(&op, 0, sizeof op); - op.version = PROC_TABLE_API_VERSION; - (void)strlcpy(op.name, table->t_name, sizeof op.name); - imsg_compose(&priv->ibuf, PROC_TABLE_OPEN, 0, 0, -1, &op, sizeof op); + while ((len = getline(&priv->line, &priv->linesize, priv->in)) != -1) { + priv->line[strcspn(priv->line, "\n")] = '\0'; - table_proc_call(priv); - table_proc_end(); + if (strncmp(priv->line, "register|", 9) != 0) + fatalx("table-proc: invalid handshake reply"); + + s = priv->line + 9; + if (!strcmp(s, "ready")) + break; + service = table_service_from_name(s); + if (service == -1 || service == K_NONE) + fatalx("table-proc: unknown service %s", s); + + services |= service; + } + + if (ferror(priv->in)) + fatalx("table-proc: getline"); + + if (services == 0) + fatalx("table-proc: no services registered"); table->t_handle = priv; @@ -133,16 +180,17 @@ table_proc_open(struct table *table) static int table_proc_update(struct table *table) { - struct table_proc_priv *priv = table->t_handle; - int r; + const char *r; - imsg_compose(&priv->ibuf, PROC_TABLE_UPDATE, 0, 0, -1, NULL, 0); + table_proc_send(table, "update", -1, NULL); + r = table_proc_recv(table, "update-result"); + if (!strcmp(r, "ok")) + return (1); + if (!strcmp(r, "error")) + return (0); - table_proc_call(priv); - table_proc_read(&r, sizeof(r)); - table_proc_end(); - - return (r); + log_warnx("warn: table-proc: failed parse reply"); + fatalx("table-proc: exiting"); } static void @@ -150,105 +198,85 @@ table_proc_close(struct table *table) { struct table_proc_priv *priv = table->t_handle; - imsg_compose(&priv->ibuf, PROC_TABLE_CLOSE, 0, 0, -1, NULL, 0); - if (imsg_flush(&priv->ibuf) == -1) - fatal("imsg_flush"); + if (fclose(priv->in) == EOF) + fatal("table-proc: fclose"); + if (fclose(priv->out) == EOF) + fatal("table-proc: fclose"); + free(priv->line); + free(priv); table->t_handle = NULL; } -static int -imsg_add_params(struct ibuf *buf) -{ - size_t count = 0; - - if (imsg_add(buf, &count, sizeof(count)) == -1) - return (-1); - - return (0); -} - static int table_proc_lookup(struct table *table, enum table_service s, const char *k, char **dst) { - struct table_proc_priv *priv = table->t_handle; - struct ibuf *buf; - int r; + const char *req = "lookup", *res = "lookup-result"; + const char *r; - buf = imsg_create(&priv->ibuf, - dst ? PROC_TABLE_LOOKUP : PROC_TABLE_CHECK, 0, 0, - sizeof(s) + strlen(k) + 1); - - if (buf == NULL) - return (-1); - if (imsg_add(buf, &s, sizeof(s)) == -1) - return (-1); - if (imsg_add_params(buf) == -1) - return (-1); - if (imsg_add(buf, k, strlen(k) + 1) == -1) - return (-1); - imsg_close(&priv->ibuf, buf); - - table_proc_call(priv); - table_proc_read(&r, sizeof(r)); - - if (r == 1 && dst) { - if (rlen == 0) { - log_warnx("warn: table-proc: empty response"); - fatalx("table-proc: exiting"); - } - if (rdata[rlen - 1] != '\0') { - log_warnx("warn: table-proc: not NUL-terminated"); - fatalx("table-proc: exiting"); - } - *dst = strdup(rdata); - if (*dst == NULL) - r = -1; - table_proc_read(NULL, rlen); + if (dst == NULL) { + req = "check"; + res = "check-result"; } - table_proc_end(); + table_proc_send(table, req, s, k); + r = table_proc_recv(table, res); - return (r); + /* common replies */ + if (!strcmp(r, "not-found")) + return (0); + if (!strcmp(r, "error")) + return (-1); + + if (dst == NULL) { + /* check op */ + if (!strncmp(r, "found", 5)) + return (1); + log_warnx("warn: table-proc: failed to parse reply"); + fatalx("table-proc: exiting"); + } + + /* lookup op */ + if (strncmp(r, "found|", 6) != 0) { + log_warnx("warn: table-proc: failed to parse reply"); + fatalx("table-proc: exiting"); + } + r += 6; + if (*r == '\0') { + log_warnx("warn: table-proc: empty response"); + fatalx("table-proc: exiting"); + } + if ((*dst = strdup(r)) == NULL) + return (-1); + return (1); } static int table_proc_fetch(struct table *table, enum table_service s, char **dst) { - struct table_proc_priv *priv = table->t_handle; - struct ibuf *buf; - int r; + const char *r; - buf = imsg_create(&priv->ibuf, PROC_TABLE_FETCH, 0, 0, sizeof(s)); - if (buf == NULL) - return (-1); - if (imsg_add(buf, &s, sizeof(s)) == -1) - return (-1); - if (imsg_add_params(buf) == -1) - return (-1); - imsg_close(&priv->ibuf, buf); + table_proc_send(table, "fetch", s, NULL); + r = table_proc_recv(table, "fetch-result"); - table_proc_call(priv); - table_proc_read(&r, sizeof(r)); + if (!strcmp(r, "not-found")) + return (0); + if (!strcmp(r, "error")) + return (-1); - if (r == 1) { - if (rlen == 0) { - log_warnx("warn: table-proc: empty response"); - fatalx("table-proc: exiting"); - } - if (rdata[rlen - 1] != '\0') { - log_warnx("warn: table-proc: not NUL-terminated"); - fatalx("table-proc: exiting"); - } - *dst = strdup(rdata); - if (*dst == NULL) - r = -1; - table_proc_read(NULL, rlen); + if (strncmp(r, "found|", 6) != 0) { + log_warnx("warn: table-proc: failed to parse reply"); + fatalx("table-proc: exiting"); + } + r += 6; + if (*r == '\0') { + log_warnx("warn: table-proc: empty response"); + fatalx("table-proc: exiting"); } - table_proc_end(); - - return (r); + if ((*dst = strdup(r)) == NULL) + return (-1); + return (1); } struct table_backend table_backend_proc = {