From 82bafdd0b32d49aa6ce6fa26b751a819f52d3277 Mon Sep 17 00:00:00 2001 From: purplerain Date: Sat, 24 Jun 2023 02:57:55 +0000 Subject: [PATCH] sync --- lib/libc/stdlib/malloc.3 | 26 +--- lib/libc/stdlib/malloc.c | 15 +- lib/libcrypto/bn/bn_convert.c | 11 +- lib/libcrypto/ec/ec_print.c | 4 +- lib/libcrypto/x509/x509_set.c | 34 ++--- regress/lib/libcrypto/bn/bn_convert.c | 12 +- sys/dev/pci/ksmn.c | 6 +- sys/kern/uipc_mbuf.c | 4 +- usr.bin/vi/ex/ex.c | 12 +- usr.bin/vi/ex/ex_subst.c | 6 +- usr.sbin/rpki-client/cert.c | 56 ++++++- usr.sbin/rpki-client/extern.h | 15 +- usr.sbin/rpki-client/main.c | 18 +-- usr.sbin/rpki-client/repo.c | 150 ++++++++++++++----- usr.sbin/rpki-client/rrdp.c | 66 ++++---- usr.sbin/rpki-client/rrdp_notification.c | 182 ++++++++++++++++++++--- usr.sbin/rpki-client/x509.c | 94 +++++++++--- usr.sbin/smtpd/smtp_session.c | 16 +- 18 files changed, 514 insertions(+), 213 deletions(-) diff --git a/lib/libc/stdlib/malloc.3 b/lib/libc/stdlib/malloc.3 index 855f217c2..79e85f39e 100644 --- a/lib/libc/stdlib/malloc.3 +++ b/lib/libc/stdlib/malloc.3 @@ -30,9 +30,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $OpenBSD: malloc.3,v 1.134 2023/06/22 11:04:16 otto Exp $ +.\" $OpenBSD: malloc.3,v 1.135 2023/06/23 05:26:45 otto Exp $ .\" -.Dd $Mdocdate: June 22 2023 $ +.Dd $Mdocdate: June 23 2023 $ .Dt MALLOC 3 .Os .Sh NAME @@ -294,17 +294,6 @@ To record the dump: To view the leak report: .Pp .Dl $ kdump -u malloc ... -.Pp -By default, the immediate caller of a -.Nm -function will be recorded. -Use malloc options -.Cm 2 -or -.Cm 3 -to record the caller one or two stack frames deeper instead. -These malloc options imply -.Cm D . .It Cm F .Dq Freecheck . Enable more extensive double free and use after free detection. @@ -824,14 +813,3 @@ and .Fn realloc to avoid these problems on .Ox . -.Pp -The mechanism to record caller functions when using malloc options -.Cm 2 -or -.Cm 3 -is not guaranteed to work for all platforms, compilers or compilation -options, -and might even crash your program. -Use -.Em only -for debugging purposes. diff --git a/lib/libc/stdlib/malloc.c b/lib/libc/stdlib/malloc.c index 7bc660525..34b2bb5e6 100644 --- a/lib/libc/stdlib/malloc.c +++ b/lib/libc/stdlib/malloc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: malloc.c,v 1.287 2023/06/22 11:04:16 otto Exp $ */ +/* $OpenBSD: malloc.c,v 1.288 2023/06/23 05:26:45 otto Exp $ */ /* * Copyright (c) 2008, 2010, 2011, 2016, 2023 Otto Moerbeek * Copyright (c) 2012 Matthew Dempsky @@ -255,11 +255,7 @@ void malloc_dump(void); PROTO_NORMAL(malloc_dump); static void malloc_exit(void); #endif -#define CALLER ( \ - DO_STATS == 0 ? NULL : (__builtin_extract_return_addr( \ - DO_STATS == 1 ? __builtin_return_address(0) : \ - DO_STATS == 2 ? __builtin_return_address(1) : \ - DO_STATS == 3 ? __builtin_return_address(2) : NULL))) +#define CALLER (DO_STATS ? __builtin_return_address(0) : NULL) /* low bits of r->p determine size: 0 means >= page size and r->size holding * real size, otherwise low bits is the bucket + 1 @@ -369,15 +365,8 @@ omalloc_parseopt(char opt) mopts.malloc_stats = 0; break; case 'D': - case '1': mopts.malloc_stats = 1; break; - case '2': - mopts.malloc_stats = 2; - break; - case '3': - mopts.malloc_stats = 3; - break; #endif /* MALLOC_STATS */ case 'f': mopts.malloc_freecheck = 0; diff --git a/lib/libcrypto/bn/bn_convert.c b/lib/libcrypto/bn/bn_convert.c index 1a3abbc60..4736099cd 100644 --- a/lib/libcrypto/bn/bn_convert.c +++ b/lib/libcrypto/bn/bn_convert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_convert.c,v 1.9 2023/05/28 10:34:17 jsing Exp $ */ +/* $OpenBSD: bn_convert.c,v 1.12 2023/06/23 10:48:40 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -281,7 +281,7 @@ BN_asc2bn(BIGNUM **bnp, const char *s) return 0; } - /* Try parsing as hexidecimal with a 0x prefix. */ + /* Try parsing as hexadecimal with a 0x prefix. */ CBS_dup(&cbs, &cbs_hex); if (!CBS_get_u8(&cbs_hex, &v)) goto decimal; @@ -291,17 +291,18 @@ BN_asc2bn(BIGNUM **bnp, const char *s) goto decimal; if (v != 'X' && v != 'x') goto decimal; - if (!bn_hex2bn_cbs(bnp, &cbs_hex)) + if (bn_hex2bn_cbs(bnp, &cbs_hex) == 0) return 0; goto done; decimal: - if (!bn_dec2bn_cbs(bnp, &cbs)) + if (bn_dec2bn_cbs(bnp, &cbs) == 0) return 0; done: - BN_set_negative(*bnp, neg); + if (bnp != NULL && *bnp != NULL) + BN_set_negative(*bnp, neg); return 1; } diff --git a/lib/libcrypto/ec/ec_print.c b/lib/libcrypto/ec/ec_print.c index 2aa0aa66a..da33c4ecc 100644 --- a/lib/libcrypto/ec/ec_print.c +++ b/lib/libcrypto/ec/ec_print.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ec_print.c,v 1.11 2023/03/08 05:45:31 jsing Exp $ */ +/* $OpenBSD: ec_print.c,v 1.12 2023/06/23 10:34:16 tb Exp $ */ /* ==================================================================== * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. * @@ -167,7 +167,7 @@ EC_POINT_hex2point(const EC_GROUP *group, const char *buf, EC_POINT *ret = NULL; BIGNUM *tmp_bn = NULL; - if (!BN_hex2bn(&tmp_bn, buf)) + if (BN_hex2bn(&tmp_bn, buf) == 0) return NULL; ret = EC_POINT_bn2point(group, tmp_bn, point, ctx); diff --git a/lib/libcrypto/x509/x509_set.c b/lib/libcrypto/x509/x509_set.c index cd12c9ec2..b56d30aec 100644 --- a/lib/libcrypto/x509/x509_set.c +++ b/lib/libcrypto/x509/x509_set.c @@ -1,4 +1,4 @@ -/* $OpenBSD: x509_set.c,v 1.25 2023/04/25 10:18:39 job Exp $ */ +/* $OpenBSD: x509_set.c,v 1.26 2023/06/23 08:00:28 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -106,7 +106,7 @@ X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial) ASN1_INTEGER *in; if (x == NULL) - return (0); + return 0; in = x->cert_info->serialNumber; if (in != serial) { in = ASN1_INTEGER_dup(serial); @@ -116,17 +116,17 @@ X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial) x->cert_info->serialNumber = in; } } - return (in != NULL); + return in != NULL; } LCRYPTO_ALIAS(X509_set_serialNumber); int X509_set_issuer_name(X509 *x, X509_NAME *name) { - if ((x == NULL) || (x->cert_info == NULL)) - return (0); + if (x == NULL || x->cert_info == NULL) + return 0; x->cert_info->enc.modified = 1; - return (X509_NAME_set(&x->cert_info->issuer, name)); + return X509_NAME_set(&x->cert_info->issuer, name); } LCRYPTO_ALIAS(X509_set_issuer_name); @@ -134,9 +134,9 @@ int X509_set_subject_name(X509 *x, X509_NAME *name) { if (x == NULL || x->cert_info == NULL) - return (0); + return 0; x->cert_info->enc.modified = 1; - return (X509_NAME_set(&x->cert_info->subject, name)); + return X509_NAME_set(&x->cert_info->subject, name); } LCRYPTO_ALIAS(X509_set_subject_name); @@ -151,7 +151,7 @@ ASN1_TIME * X509_getm_notBefore(const X509 *x) { if (x == NULL || x->cert_info == NULL || x->cert_info->validity == NULL) - return (NULL); + return NULL; return x->cert_info->validity->notBefore; } LCRYPTO_ALIAS(X509_getm_notBefore); @@ -162,7 +162,7 @@ X509_set_notBefore(X509 *x, const ASN1_TIME *tm) ASN1_TIME *in; if (x == NULL || x->cert_info->validity == NULL) - return (0); + return 0; in = x->cert_info->validity->notBefore; if (in != tm) { in = ASN1_STRING_dup(tm); @@ -172,7 +172,7 @@ X509_set_notBefore(X509 *x, const ASN1_TIME *tm) x->cert_info->validity->notBefore = in; } } - return (in != NULL); + return in != NULL; } LCRYPTO_ALIAS(X509_set_notBefore); @@ -194,7 +194,7 @@ ASN1_TIME * X509_getm_notAfter(const X509 *x) { if (x == NULL || x->cert_info == NULL || x->cert_info->validity == NULL) - return (NULL); + return NULL; return x->cert_info->validity->notAfter; } LCRYPTO_ALIAS(X509_getm_notAfter); @@ -205,7 +205,7 @@ X509_set_notAfter(X509 *x, const ASN1_TIME *tm) ASN1_TIME *in; if (x == NULL || x->cert_info->validity == NULL) - return (0); + return 0; in = x->cert_info->validity->notAfter; if (in != tm) { in = ASN1_STRING_dup(tm); @@ -215,7 +215,7 @@ X509_set_notAfter(X509 *x, const ASN1_TIME *tm) x->cert_info->validity->notAfter = in; } } - return (in != NULL); + return in != NULL; } LCRYPTO_ALIAS(X509_set_notAfter); @@ -229,10 +229,10 @@ LCRYPTO_ALIAS(X509_set1_notAfter); int X509_set_pubkey(X509 *x, EVP_PKEY *pkey) { - if ((x == NULL) || (x->cert_info == NULL)) - return (0); + if (x == NULL || x->cert_info == NULL) + return 0; x->cert_info->enc.modified = 1; - return (X509_PUBKEY_set(&(x->cert_info->key), pkey)); + return X509_PUBKEY_set(&x->cert_info->key, pkey); } LCRYPTO_ALIAS(X509_set_pubkey); diff --git a/regress/lib/libcrypto/bn/bn_convert.c b/regress/lib/libcrypto/bn/bn_convert.c index 147bb6839..69f7da43b 100644 --- a/regress/lib/libcrypto/bn/bn_convert.c +++ b/regress/lib/libcrypto/bn/bn_convert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_convert.c,v 1.2 2023/05/27 15:50:56 jsing Exp $ */ +/* $OpenBSD: bn_convert.c,v 1.3 2023/06/23 10:50:47 tb Exp $ */ /* * Copyright (c) 2023 Joel Sing * @@ -214,6 +214,16 @@ test_bn_asc2bn(void) } } + /* + * While it makes little sense to call BN_asc2bn() with a NULL bn, + * check for consistent behavior. + */ + if (!BN_asc2bn(NULL, "1") || !BN_asc2bn(NULL, "-1") || + !BN_asc2bn(NULL, "0x1") || !BN_asc2bn(NULL, "-0x1")) { + fprintf(stderr, "FAIL: BN_asc2bn() with NULL BIGNUM failed\n"); + goto failure; + } + failed = 0; failure: diff --git a/sys/dev/pci/ksmn.c b/sys/dev/pci/ksmn.c index 608908be4..004d10514 100644 --- a/sys/dev/pci/ksmn.c +++ b/sys/dev/pci/ksmn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ksmn.c,v 1.7 2022/04/25 16:17:19 claudio Exp $ */ +/* $OpenBSD: ksmn.c,v 1.8 2023/06/23 03:47:10 mlarkin Exp $ */ /* * Copyright (c) 2019 Bryan Steele @@ -105,6 +105,7 @@ static const struct pci_matchid ksmn_devices[] = { { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_17_1X_RC }, { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_17_3X_RC }, { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_17_6X_RC }, + { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_19_6X_RC }, }; int @@ -172,6 +173,9 @@ ksmn_attach(struct device *parent, struct device *self, void *aux) (m >= 0xa0 && m <= 0xaf)) sc->sc_ccd_offset = 0x300; + if (m >= 0x60 && m <= 0x6f) + sc->sc_ccd_offset = 0x308; + if ((m >= 0x10 && m <= 0x1f) || (m >= 0xa0 && m <= 0xaf)) ksmn_ccd_attach(sc, 12); diff --git a/sys/kern/uipc_mbuf.c b/sys/kern/uipc_mbuf.c index 440a1ec5e..ba59f13a9 100644 --- a/sys/kern/uipc_mbuf.c +++ b/sys/kern/uipc_mbuf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_mbuf.c,v 1.286 2023/05/16 20:09:27 mvs Exp $ */ +/* $OpenBSD: uipc_mbuf.c,v 1.287 2023/06/23 04:36:49 gnezdo Exp $ */ /* $NetBSD: uipc_mbuf.c,v 1.15.4.1 1996/06/13 17:11:44 cgd Exp $ */ /* @@ -214,7 +214,7 @@ nmbclust_update(long newval) { int i; - if (newval < 0 || newval > LONG_MAX / MCLBYTES) + if (newval <= 0 || newval > LONG_MAX / MCLBYTES) return ERANGE; /* update the global mbuf memory limit */ nmbclust = newval; diff --git a/usr.bin/vi/ex/ex.c b/usr.bin/vi/ex/ex.c index 357aa8607..9aa31ad29 100644 --- a/usr.bin/vi/ex/ex.c +++ b/usr.bin/vi/ex/ex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ex.c,v 1.22 2022/02/20 19:45:51 tb Exp $ */ +/* $OpenBSD: ex.c,v 1.23 2023/06/23 15:06:45 millert Exp $ */ /*- * Copyright (c) 1992, 1993, 1994 @@ -1454,8 +1454,14 @@ addr_verify: LF_INIT(FL_ISSET(ecp->iflags, E_C_HASH | E_C_LIST | E_C_PRINT)); if (!LF_ISSET(E_C_HASH | E_C_LIST | E_C_PRINT | E_NOAUTO) && !F_ISSET(sp, SC_EX_GLOBAL) && - O_ISSET(sp, O_AUTOPRINT) && F_ISSET(ecp, E_AUTOPRINT)) - LF_INIT(E_C_PRINT); + O_ISSET(sp, O_AUTOPRINT) && F_ISSET(ecp, E_AUTOPRINT)) { + + /* Honor the number option if autoprint is set. */ + if (F_ISSET(ecp, E_OPTNUM)) + LF_INIT(E_C_HASH); + else + LF_INIT(E_C_PRINT); + } if (LF_ISSET(E_C_HASH | E_C_LIST | E_C_PRINT)) { cur.lno = sp->lno; diff --git a/usr.bin/vi/ex/ex_subst.c b/usr.bin/vi/ex/ex_subst.c index 9a152c6df..8598b6888 100644 --- a/usr.bin/vi/ex/ex_subst.c +++ b/usr.bin/vi/ex/ex_subst.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ex_subst.c,v 1.30 2017/04/18 01:45:35 deraadt Exp $ */ +/* $OpenBSD: ex_subst.c,v 1.31 2023/06/23 15:06:45 millert Exp $ */ /*- * Copyright (c) 1992, 1993, 1994 @@ -633,7 +633,9 @@ nextmatch: match[0].rm_so = offset; goto lquit; } } else { - if (ex_print(sp, cmdp, &from, &to, 0) || + const int flags = + O_ISSET(sp, O_NUMBER) ? E_C_HASH : 0; + if (ex_print(sp, cmdp, &from, &to, flags) || ex_scprint(sp, &from, &to)) goto lquit; if (ex_txt(sp, &tiq, 0, TXT_CR)) diff --git a/usr.sbin/rpki-client/cert.c b/usr.sbin/rpki-client/cert.c index b166ed063..e9ca4840c 100644 --- a/usr.sbin/rpki-client/cert.c +++ b/usr.sbin/rpki-client/cert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cert.c,v 1.109 2023/06/20 12:28:08 job Exp $ */ +/* $OpenBSD: cert.c,v 1.112 2023/06/23 20:05:30 tb Exp $ */ /* * Copyright (c) 2022 Theo Buehler * Copyright (c) 2021 Job Snijders @@ -204,6 +204,11 @@ sbgp_assysnum(struct parse *p, X509_EXTENSION *ext) goto out; } + if (asz == 0) { + warnx("%s: RFC 6487 section 4.8.11: empty asIdsOrRanges", + p->fn); + goto out; + } if (asz >= MAX_AS_SIZE) { warnx("%s: too many AS number entries: limit %d", p->fn, MAX_AS_SIZE); @@ -371,6 +376,11 @@ sbgp_ipaddrblk(struct parse *p, X509_EXTENSION *ext) p->fn, af->ipAddressChoice->type); goto out; } + if (ipsz == p->res->ipsz) { + warnx("%s: RFC 6487 section 4.8.10: " + "empty ipAddressesOrRanges", p->fn); + goto out; + } if (ipsz >= MAX_IP_SIZE) goto out; @@ -412,6 +422,11 @@ sbgp_ipaddrblk(struct parse *p, X509_EXTENSION *ext) } } + if (p->res->ipsz == 0) { + warnx("%s: RFC 6487 section 4.8.10: empty ipAddrBlock", p->fn); + goto out; + } + rc = 1; out: sk_IPAddressFamily_pop_free(addrblk, IPAddressFamily_free); @@ -648,7 +663,6 @@ cert_parse_pre(const char *fn, const unsigned char *der, size_t len) { const unsigned char *oder; int extsz; - int sia_present = 0; size_t i; X509 *x = NULL; X509_EXTENSION *ext = NULL; @@ -658,7 +672,10 @@ cert_parse_pre(const char *fn, const unsigned char *der, size_t len) ASN1_OBJECT *obj; EVP_PKEY *pkey; struct parse p; - int nid; + int nid, ip, as, sia, cp, crldp, aia, aki, ski, + eku, bc, ku; + + nid = ip = as = sia = cp = crldp = aia = aki = ski = eku = bc = ku = 0; /* just fail for empty buffers, the warning was printed elsewhere */ if (der == NULL) @@ -721,38 +738,58 @@ cert_parse_pre(const char *fn, const unsigned char *der, size_t len) obj = X509_EXTENSION_get_object(ext); assert(obj != NULL); - switch (OBJ_obj2nid(obj)) { + switch ((nid = OBJ_obj2nid(obj))) { case NID_sbgp_ipAddrBlock: + if (ip++ >= 1) + goto dup; if (!sbgp_ipaddrblk(&p, ext)) goto out; break; case NID_sbgp_autonomousSysNum: + if (as++ > 0) + goto dup; if (!sbgp_assysnum(&p, ext)) goto out; break; case NID_sinfo_access: - sia_present = 1; + if (sia++ > 0) + goto dup; if (!sbgp_sia(&p, ext)) goto out; break; case NID_certificate_policies: + if (cp++ > 0) + goto dup; if (!certificate_policies(&p, ext)) goto out; break; case NID_crl_distribution_points: - /* ignored here, handled later */ + if (crldp++ > 0) + goto dup; break; case NID_info_access: + if (aia++ > 0) + goto dup; break; case NID_authority_key_identifier: + if (aki++ > 0) + goto dup; break; case NID_subject_key_identifier: + if (ski++ > 0) + goto dup; break; case NID_ext_key_usage: + if (eku++ > 0) + goto dup; break; case NID_basic_constraints: + if (bc++ > 0) + goto dup; break; case NID_key_usage: + if (ku++ > 0) + goto dup; break; default: /* unexpected extensions warrant investigation */ @@ -831,7 +868,7 @@ cert_parse_pre(const char *fn, const unsigned char *der, size_t len) goto out; } } - if (sia_present) { + if (sia) { warnx("%s: unexpected SIA extension in BGPsec cert", p.fn); goto out; @@ -850,7 +887,10 @@ cert_parse_pre(const char *fn, const unsigned char *der, size_t len) p.res->x509 = x; return p.res; -out: + dup: + warnx("%s: RFC 5280 section 4.2: duplicate %s extension", fn, + OBJ_nid2sn(nid)); + out: cert_free(p.res); X509_free(x); return NULL; diff --git a/usr.sbin/rpki-client/extern.h b/usr.sbin/rpki-client/extern.h index ec6c257e9..abc945c41 100644 --- a/usr.sbin/rpki-client/extern.h +++ b/usr.sbin/rpki-client/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.184 2023/06/07 10:46:34 job Exp $ */ +/* $OpenBSD: extern.h,v 1.185 2023/06/23 11:36:24 claudio Exp $ */ /* * Copyright (c) 2019 Kristaps Dzonsons * @@ -486,6 +486,9 @@ enum rrdp_msg { RRDP_ABORT, }; +/* Maximum number of delta files per RRDP notification file. */ +#define MAX_RRDP_DELTAS 300 + /* * RRDP session state, needed to pickup at the right spot on next run. */ @@ -493,6 +496,7 @@ struct rrdp_session { char *last_mod; char *session_id; long long serial; + char *deltas[MAX_RRDP_DELTAS]; }; /* @@ -759,7 +763,11 @@ void proc_rrdp(int) __attribute__((noreturn)); /* Repository handling */ int filepath_add(struct filepath_tree *, char *, time_t); void rrdp_clear(unsigned int); -void rrdp_save_state(unsigned int, struct rrdp_session *); +void rrdp_session_save(unsigned int, struct rrdp_session *); +void rrdp_session_free(struct rrdp_session *); +void rrdp_session_buffer(struct ibuf *, + const struct rrdp_session *); +struct rrdp_session *rrdp_session_read(struct ibuf *); int rrdp_handle_file(unsigned int, enum publish_type, char *, char *, size_t, char *, size_t); char *repo_basedir(const struct repo *, int); @@ -944,9 +952,6 @@ int mkpathat(int, const char *); /* Maximum number of delegated hosting locations (repositories) for each TAL. */ #define MAX_REPO_PER_TAL 1000 -/* Maximum number of delta files per RRDP notification file. */ -#define MAX_RRDP_DELTAS 300 - /* * Time - Evaluation time is used as the current time if it is * larger than X509_TIME_MIN, otherwise the system time is used. diff --git a/usr.sbin/rpki-client/main.c b/usr.sbin/rpki-client/main.c index 39fd2931c..771b8cfc7 100644 --- a/usr.sbin/rpki-client/main.c +++ b/usr.sbin/rpki-client/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.242 2023/06/20 15:15:14 claudio Exp $ */ +/* $OpenBSD: main.c,v 1.243 2023/06/23 11:36:24 claudio Exp $ */ /* * Copyright (c) 2021 Claudio Jeker * Copyright (c) 2019 Kristaps Dzonsons @@ -280,9 +280,8 @@ rrdp_fetch(unsigned int id, const char *uri, const char *local, io_simple_buffer(b, &id, sizeof(id)); io_str_buffer(b, local); io_str_buffer(b, uri); - io_str_buffer(b, s->session_id); - io_simple_buffer(b, &s->serial, sizeof(s->serial)); - io_str_buffer(b, s->last_mod); + + rrdp_session_buffer(b, s); io_close_buffer(&rrdpq, b); } @@ -679,7 +678,7 @@ rrdp_process(struct ibuf *b) { enum rrdp_msg type; enum publish_type pt; - struct rrdp_session s; + struct rrdp_session *s; char *uri, *last_mod, *data; char hash[SHA256_DIGEST_LENGTH]; size_t dsz; @@ -700,12 +699,9 @@ rrdp_process(struct ibuf *b) rrdp_http_fetch(id, uri, last_mod); break; case RRDP_SESSION: - io_read_str(b, &s.session_id); - io_read_buf(b, &s.serial, sizeof(s.serial)); - io_read_str(b, &s.last_mod); - rrdp_save_state(id, &s); - free(s.session_id); - free(s.last_mod); + s = rrdp_session_read(b); + rrdp_session_save(id, s); + rrdp_session_free(s); break; case RRDP_FILE: io_read_buf(b, &pt, sizeof(pt)); diff --git a/usr.sbin/rpki-client/repo.c b/usr.sbin/rpki-client/repo.c index 009ce2546..ecaefc400 100644 --- a/usr.sbin/rpki-client/repo.c +++ b/usr.sbin/rpki-client/repo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: repo.c,v 1.47 2023/05/30 16:02:28 job Exp $ */ +/* $OpenBSD: repo.c,v 1.48 2023/06/23 11:36:24 claudio Exp $ */ /* * Copyright (c) 2021 Claudio Jeker * Copyright (c) 2019 Kristaps Dzonsons @@ -619,22 +619,26 @@ repo_alloc(int talid) * Parse the RRDP state file if it exists and set the session struct * based on that information. */ -static void -rrdp_parse_state(const struct rrdprepo *rr, struct rrdp_session *state) +static struct rrdp_session * +rrdp_session_parse(const struct rrdprepo *rr) { FILE *f; - int fd, ln = 0; + struct rrdp_session *state; + int fd, ln = 0, deltacnt = 0; const char *errstr; char *line = NULL, *file; size_t len = 0; ssize_t n; + if ((state = calloc(1, sizeof(*state))) == NULL) + err(1, NULL); + file = rrdp_state_filename(rr, 0); if ((fd = open(file, O_RDONLY)) == -1) { if (errno != ENOENT) warn("%s: open state file", rr->basedir); free(file); - return; + return state; } free(file); f = fdopen(fd, "r"); @@ -655,39 +659,47 @@ rrdp_parse_state(const struct rrdprepo *rr, struct rrdp_session *state) goto fail; break; case 2: + if (strcmp(line, "-") == 0) + break; if ((state->last_mod = strdup(line)) == NULL) err(1, NULL); break; default: - goto fail; + if (deltacnt >= MAX_RRDP_DELTAS) + goto fail; + if ((state->deltas[deltacnt++] = strdup(line)) == NULL) + err(1, NULL); + break; } ln++; } - free(line); if (ferror(f)) goto fail; fclose(f); - return; + free(line); + return state; -fail: + fail: warnx("%s: troubles reading state file", rr->basedir); fclose(f); + free(line); free(state->session_id); free(state->last_mod); memset(state, 0, sizeof(*state)); + return state; } /* * Carefully write the RRDP session state file back. */ void -rrdp_save_state(unsigned int id, struct rrdp_session *state) +rrdp_session_save(unsigned int id, struct rrdp_session *state) { struct rrdprepo *rr; char *temp, *file; - FILE *f; - int fd; + FILE *f = NULL; + int fd, i; rr = rrdp_find(id); if (rr == NULL) @@ -696,10 +708,8 @@ rrdp_save_state(unsigned int id, struct rrdp_session *state) file = rrdp_state_filename(rr, 0); temp = rrdp_state_filename(rr, 1); - if ((fd = mkostemp(temp, O_CLOEXEC)) == -1) { - warn("mkostemp %s", temp); + if ((fd = mkostemp(temp, O_CLOEXEC)) == -1) goto fail; - } (void)fchmod(fd, 0644); f = fdopen(fd, "w"); if (f == NULL) @@ -707,37 +717,94 @@ rrdp_save_state(unsigned int id, struct rrdp_session *state) /* write session state file out */ if (fprintf(f, "%s\n%lld\n", state->session_id, - state->serial) < 0) { - fclose(f); - goto fail; - } - if (state->last_mod != NULL) { - if (fprintf(f, "%s\n", state->last_mod) < 0) { - fclose(f); - goto fail; - } - } - if (fclose(f) != 0) + state->serial) < 0) goto fail; - if (rename(temp, file) == -1) - warn("%s: rename state file", rr->basedir); + if (state->last_mod != NULL) { + if (fprintf(f, "%s\n", state->last_mod) < 0) + goto fail; + } else { + if (fprintf(f, "-\n") < 0) + goto fail; + } + for (i = 0; state->deltas[i] != NULL; i++) { + if (fprintf(f, "%s\n", state->deltas[i]) < 0) + goto fail; + } + if (fclose(f) != 0) { + f = NULL; + goto fail; + } + + if (rename(temp, file) == -1) { + warn("%s: rename %s to %s", rr->basedir, temp, file); + unlink(temp); + } free(temp); free(file); return; -fail: - warnx("%s: failed to save state", rr->basedir); + fail: + warn("%s: save state to %s", rr->basedir, temp); + if (f != NULL) + fclose(f); unlink(temp); free(temp); free(file); } +/* + * Free an rrdp_session pointer. Safe to call with NULL. + */ +void +rrdp_session_free(struct rrdp_session *s) +{ + size_t i; + + if (s == NULL) + return; + free(s->session_id); + free(s->last_mod); + for (i = 0; i < sizeof(s->deltas) / sizeof(s->deltas[0]); i++) + free(s->deltas[i]); + free(s); +} + +void +rrdp_session_buffer(struct ibuf *b, const struct rrdp_session *s) +{ + size_t i; + + io_str_buffer(b, s->session_id); + io_simple_buffer(b, &s->serial, sizeof(s->serial)); + io_str_buffer(b, s->last_mod); + for (i = 0; i < sizeof(s->deltas) / sizeof(s->deltas[0]); i++) + io_str_buffer(b, s->deltas[i]); +} + +struct rrdp_session * +rrdp_session_read(struct ibuf *b) +{ + struct rrdp_session *s; + size_t i; + + if ((s = calloc(1, sizeof(*s))) == NULL) + err(1, NULL); + + io_read_str(b, &s->session_id); + io_read_buf(b, &s->serial, sizeof(s->serial)); + io_read_str(b, &s->last_mod); + for (i = 0; i < sizeof(s->deltas) / sizeof(s->deltas[0]); i++) + io_read_str(b, &s->deltas[i]); + + return s; +} + static struct rrdprepo * rrdp_get(const char *uri) { - struct rrdp_session state = { 0 }; + struct rrdp_session *state; struct rrdprepo *rr; SLIST_FOREACH(rr, &rrdprepos, entry) @@ -767,10 +834,9 @@ rrdp_get(const char *uri) } /* parse state and start the sync */ - rrdp_parse_state(rr, &state); - rrdp_fetch(rr->id, rr->notifyuri, rr->notifyuri, &state); - free(state.session_id); - free(state.last_mod); + state = rrdp_session_parse(rr); + rrdp_fetch(rr->id, rr->notifyuri, rr->notifyuri, state); + rrdp_session_free(state); logx("%s: pulling from %s", rr->notifyuri, "network"); @@ -1232,7 +1298,7 @@ repo_proto(const struct repo *rp) if (rp->ta != NULL) { const struct tarepo *tr = rp->ta; - if (tr->uriidx < tr->urisz && + if (tr->uriidx < tr->urisz && strncasecmp(tr->uri[tr->uriidx], "rsync://", 8) == 0) return "rsync"; else @@ -1667,14 +1733,14 @@ repo_cleanup_entry(FTSENT *e, struct filepath_tree *tree, int cachefd) logx("deleted superfluous %s", path); if (fts_state.rp != NULL) fts_state.rp->repostats.del_extra_files++; - else + else stats.repo_stats.del_extra_files++; } else { if (verbose > 1) logx("deleted %s", path); if (fts_state.rp != NULL) fts_state.rp->repostats.del_files++; - else + else stats.repo_stats.del_files++; } } @@ -1728,7 +1794,7 @@ repo_cleanup_entry(FTSENT *e, struct filepath_tree *tree, int cachefd) warn("rmdir %s", path); if (fts_state.rp != NULL) fts_state.rp->repostats.del_dirs++; - else + else stats.repo_stats.del_dirs++; } break; @@ -1795,7 +1861,8 @@ repo_free(void) } /* - * Remove all files and directories under base but do not remove base itself. + * Remove all files and directories under base. + * Do not remove base directory itself and the .state file. */ static void remove_contents(char *base) @@ -1812,6 +1879,9 @@ remove_contents(char *base) case FTS_NSOK: case FTS_SL: case FTS_SLNONE: + if (e->fts_level == 1 && + strcmp(e->fts_name, ".state") == 0) + break; if (unlink(e->fts_accpath) == -1) warn("unlink %s", e->fts_path); break; diff --git a/usr.sbin/rpki-client/rrdp.c b/usr.sbin/rpki-client/rrdp.c index 08a861a4e..d7814c0c6 100644 --- a/usr.sbin/rpki-client/rrdp.c +++ b/usr.sbin/rpki-client/rrdp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rrdp.c,v 1.31 2023/06/20 15:15:14 claudio Exp $ */ +/* $OpenBSD: rrdp.c,v 1.32 2023/06/23 11:36:24 claudio Exp $ */ /* * Copyright (c) 2020 Nils Fisher * Copyright (c) 2021 Claudio Jeker @@ -65,8 +65,8 @@ struct rrdp { char hash[SHA256_DIGEST_LENGTH]; SHA256_CTX ctx; - struct rrdp_session repository; - struct rrdp_session current; + struct rrdp_session *repository; + struct rrdp_session *current; XML_Parser parser; struct notification_xml *nxml; struct snapshot_xml *sxml; @@ -135,9 +135,7 @@ rrdp_state_send(struct rrdp *s) b = io_new_buffer(); io_simple_buffer(b, &type, sizeof(type)); io_simple_buffer(b, &s->id, sizeof(s->id)); - io_str_buffer(b, s->current.session_id); - io_simple_buffer(b, &s->current.serial, sizeof(s->current.serial)); - io_str_buffer(b, s->current.last_mod); + rrdp_session_buffer(b, s->current); io_close_buffer(&msgq, b); } @@ -182,8 +180,7 @@ rrdp_publish_file(struct rrdp *s, struct publish_xml *pxml, } static void -rrdp_new(unsigned int id, char *local, char *notify, char *session_id, - long long serial, char *last_mod) +rrdp_new(unsigned int id, char *local, char *notify, struct rrdp_session *state) { struct rrdp *s; @@ -194,15 +191,15 @@ rrdp_new(unsigned int id, char *local, char *notify, char *session_id, s->id = id; s->local = local; s->notifyuri = notify; - s->repository.session_id = session_id; - s->repository.serial = serial; - s->repository.last_mod = last_mod; + s->repository = state; + if ((s->current = calloc(1, sizeof(*s->current))) == NULL) + err(1, NULL); s->state = RRDP_STATE_REQ; if ((s->parser = XML_ParserCreate("US-ASCII")) == NULL) err(1, "XML_ParserCreate"); - s->nxml = new_notification_xml(s->parser, &s->repository, &s->current, + s->nxml = new_notification_xml(s->parser, s->repository, s->current, notify); TAILQ_INSERT_TAIL(&states, s, entry); @@ -227,10 +224,8 @@ rrdp_free(struct rrdp *s) free(s->notifyuri); free(s->local); free(s->last_mod); - free(s->repository.last_mod); - free(s->repository.session_id); - free(s->current.last_mod); - free(s->current.session_id); + rrdp_session_free(s->repository); + rrdp_session_free(s->current); free(s); } @@ -259,7 +254,7 @@ rrdp_failed(struct rrdp *s) free_delta_xml(s->dxml); s->dxml = NULL; rrdp_clear_repo(s); - s->sxml = new_snapshot_xml(s->parser, &s->current, s); + s->sxml = new_snapshot_xml(s->parser, s->current, s); s->task = SNAPSHOT; s->state = RRDP_STATE_REQ; logx("%s: delta sync failed, fallback to snapshot", s->local); @@ -322,26 +317,26 @@ rrdp_finished(struct rrdp *s) switch (s->task) { case NOTIFICATION: logx("%s: repository not modified (%s#%lld)", - s->local, s->repository.session_id, - s->repository.serial); + s->local, s->repository->session_id, + s->repository->serial); rrdp_state_send(s); rrdp_free(s); rrdp_done(id, 1); break; case SNAPSHOT: logx("%s: downloading snapshot (%s#%lld)", - s->local, s->current.session_id, - s->current.serial); + s->local, s->current->session_id, + s->current->serial); rrdp_clear_repo(s); - s->sxml = new_snapshot_xml(p, &s->current, s); + s->sxml = new_snapshot_xml(p, s->current, s); s->state = RRDP_STATE_REQ; break; case DELTA: logx("%s: downloading %lld deltas (%s#%lld)", s->local, - s->repository.serial - s->current.serial, - s->current.session_id, s->current.serial); - s->dxml = new_delta_xml(p, &s->current, s); + s->repository->serial - s->current->serial, + s->current->session_id, s->current->serial); + s->dxml = new_delta_xml(p, s->current, s); s->state = RRDP_STATE_REQ; break; } @@ -360,14 +355,14 @@ rrdp_finished(struct rrdp *s) } else { /* reset delta parser for next delta */ free_delta_xml(s->dxml); - s->dxml = new_delta_xml(p, &s->current, s); + s->dxml = new_delta_xml(p, s->current, s); s->state = RRDP_STATE_REQ; } break; } } else if (s->res == HTTP_NOT_MOD && s->task == NOTIFICATION) { logx("%s: notification file not modified (%s#%lld)", s->local, - s->repository.session_id, s->repository.serial); + s->repository->session_id, s->repository->serial); /* no need to update state file */ rrdp_free(s); rrdp_done(id, 1); @@ -408,12 +403,12 @@ static void rrdp_input_handler(int fd) { static struct ibuf *inbuf; - char *local, *notify, *session_id, *last_mod; + struct rrdp_session *state; + char *local, *notify, *last_mod; struct ibuf *b; struct rrdp *s; enum rrdp_msg type; enum http_result res; - long long serial; unsigned int id; int ok; @@ -426,15 +421,12 @@ rrdp_input_handler(int fd) switch (type) { case RRDP_START: - io_read_str(b, &local); - io_read_str(b, ¬ify); - io_read_str(b, &session_id); - io_read_buf(b, &serial, sizeof(serial)); - io_read_str(b, &last_mod); if (ibuf_fd_avail(b)) errx(1, "received unexpected fd"); - - rrdp_new(id, local, notify, session_id, serial, last_mod); + io_read_str(b, &local); + io_read_str(b, ¬ify); + state = rrdp_session_read(b); + rrdp_new(id, local, notify, state); break; case RRDP_HTTP_INI: s = rrdp_get(id); @@ -569,7 +561,7 @@ proc_rrdp(int fd) switch (s->task) { case NOTIFICATION: rrdp_http_req(s->id, s->notifyuri, - s->repository.last_mod); + s->repository->last_mod); break; case SNAPSHOT: case DELTA: diff --git a/usr.sbin/rpki-client/rrdp_notification.c b/usr.sbin/rpki-client/rrdp_notification.c index b135ecaf3..dec5f2140 100644 --- a/usr.sbin/rpki-client/rrdp_notification.c +++ b/usr.sbin/rpki-client/rrdp_notification.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rrdp_notification.c,v 1.17 2023/01/04 14:22:43 claudio Exp $ */ +/* $OpenBSD: rrdp_notification.c,v 1.18 2023/06/23 11:36:24 claudio Exp $ */ /* * Copyright (c) 2020 Nils Fisher * Copyright (c) 2021 Claudio Jeker @@ -60,6 +60,7 @@ struct notification_xml { char snapshot_hash[SHA256_DIGEST_LENGTH]; struct delta_q delta_q; long long serial; + long long min_serial; int version; enum notification_scope scope; }; @@ -101,6 +102,21 @@ add_delta(struct notification_xml *nxml, const char *uri, return 1; } +/* check that there are no holes in the list */ +static int +check_delta(struct notification_xml *nxml) +{ + struct delta_item *d; + long long serial = 0; + + TAILQ_FOREACH(d, &nxml->delta_q, q) { + if (serial != 0 && serial + 1 != d->serial) + return 0; + serial = d->serial; + } + return 1; +} + static void free_delta(struct delta_item *d) { @@ -108,6 +124,36 @@ free_delta(struct delta_item *d) free(d); } +/* + * Parse a delta serial and hash line at idx from the rrdp session state. + * Return the serial or 0 on error. If hash is non-NULL, it is set to the + * start of the hash string on success. + */ +static long long +delta_parse(struct rrdp_session *s, size_t idx, char **hash) +{ + long long serial; + char *line, *ep; + + if (hash != NULL) + *hash = NULL; + if (idx < 0 || idx >= sizeof(s->deltas) / sizeof(s->deltas[0])) + return 0; + if ((line = s->deltas[idx]) == NULL) + return 0; + + errno = 0; + serial = strtoll(line, &ep, 10); + if (line[0] == '\0' || *ep != ' ') + return 0; + if (serial <= 0 || (errno == ERANGE && serial == LLONG_MAX)) + return 0; + + if (hash != NULL) + *hash = ep + 1; + return serial; +} + static void start_notification_elem(struct notification_xml *nxml, const char **attr) { @@ -149,6 +195,10 @@ start_notification_elem(struct notification_xml *nxml, const char **attr) PARSE_FAIL(p, "parse failed - incomplete " "notification attributes"); + /* Limit deltas to the ones which matter for us. */ + if (nxml->min_serial == 0 && nxml->serial > MAX_RRDP_DELTAS) + nxml->min_serial = nxml->serial - MAX_RRDP_DELTAS; + nxml->scope = NOTIFICATION_SCOPE_NOTIFICATION; } @@ -161,6 +211,9 @@ end_notification_elem(struct notification_xml *nxml) PARSE_FAIL(p, "parse failed - exited notification " "elem unexpectedely"); nxml->scope = NOTIFICATION_SCOPE_END; + + if (!check_delta(nxml)) + PARSE_FAIL(p, "parse failed - delta list has holes"); } static void @@ -247,11 +300,12 @@ start_delta_elem(struct notification_xml *nxml, const char **attr) if (hasUri != 1 || hasHash != 1 || delta_serial == 0) PARSE_FAIL(p, "parse failed - incomplete delta attributes"); + /* Delta serial must be smaller or equal to the notification serial */ + if (nxml->serial < delta_serial) + PARSE_FAIL(p, "parse failed - bad delta serial"); + /* optimisation, add only deltas that could be interesting */ - if (nxml->repository->serial != 0 && - nxml->repository->serial < delta_serial && - nxml->repository->session_id != NULL && - strcmp(nxml->session_id, nxml->repository->session_id) == 0) { + if (nxml->min_serial < delta_serial) { if (add_delta(nxml, delta_uri, delta_hash, delta_serial) == 0) PARSE_FAIL(p, "parse failed - adding delta failed"); } @@ -333,6 +387,7 @@ new_notification_xml(XML_Parser p, struct rrdp_session *repository, nxml->repository = repository; nxml->current = current; nxml->notifyuri = notifyuri; + nxml->min_serial = delta_parse(repository, 0, NULL); XML_SetElementHandler(nxml->parser, notification_xml_elem_start, notification_xml_elem_end); @@ -343,6 +398,16 @@ new_notification_xml(XML_Parser p, struct rrdp_session *repository, return nxml; } +static void +free_delta_queue(struct notification_xml *nxml) +{ + while (!TAILQ_EMPTY(&nxml->delta_q)) { + struct delta_item *d = TAILQ_FIRST(&nxml->delta_q); + TAILQ_REMOVE(&nxml->delta_q, d, q); + free_delta(d); + } +} + void free_notification_xml(struct notification_xml *nxml) { @@ -351,14 +416,88 @@ free_notification_xml(struct notification_xml *nxml) free(nxml->session_id); free(nxml->snapshot_uri); - while (!TAILQ_EMPTY(&nxml->delta_q)) { - struct delta_item *d = TAILQ_FIRST(&nxml->delta_q); - TAILQ_REMOVE(&nxml->delta_q, d, q); - free_delta(d); - } + free_delta_queue(nxml); free(nxml); } +/* + * Collect a list of deltas to store in the repository state. + */ +static void +notification_collect_deltas(struct notification_xml *nxml) +{ + struct delta_item *d; + long long keep_serial = 0; + size_t cur_idx = 0, max_deltas; + char *hash; + + max_deltas = + sizeof(nxml->current->deltas) / sizeof(nxml->current->deltas[0]); + + if (nxml->serial > (long long)max_deltas) + keep_serial = nxml->serial - max_deltas + 1; + + TAILQ_FOREACH(d, &nxml->delta_q, q) { + if (d->serial >= keep_serial) { + assert(cur_idx < max_deltas); + hash = hex_encode(d->hash, sizeof(d->hash)); + if (asprintf(&nxml->current->deltas[cur_idx++], + "%lld %s", d->serial, hash) == -1) + err(1, NULL); + free(hash); + } + } +} + +/* + * Validate the delta list with the information from the repository state. + * Remove all obsolete deltas so that the list starts with the delta with + * serial nxml->repository->serial + 1. + * Returns 1 if all deltas were valid and 0 on failure. + */ +static int +notification_check_deltas(struct notification_xml *nxml) +{ + struct delta_item *d, *nextd; + char *hash, *exp_hash; + long long exp_serial, new_serial; + size_t exp_idx = 0; + + exp_serial = delta_parse(nxml->repository, exp_idx++, &exp_hash); + new_serial = nxml->repository->serial + 1; + + /* compare hash of delta against repository state info */ + TAILQ_FOREACH_SAFE(d, &nxml->delta_q, q, nextd) { + while (exp_serial != 0 && exp_serial < d->serial) { + exp_serial = delta_parse(nxml->repository, + exp_idx++, &exp_hash); + } + + if (d->serial == exp_serial) { + hash = hex_encode(d->hash, sizeof(d->hash)); + if (strcmp(hash, exp_hash) != 0) { + warnx("%s: %s#%lld unexpected delta " + "mutation (expected %s, got %s)", + nxml->notifyuri, nxml->session_id, + exp_serial, hash, exp_hash); + free(hash); + return 0; + } + free(hash); + exp_serial = delta_parse(nxml->repository, + exp_idx++, &exp_hash); + } + + /* is this delta needed? */ + if (d->serial < new_serial) { + TAILQ_REMOVE(&nxml->delta_q, d, q); + free_delta(d); + } + } + + return 1; +} + /* * Finalize notification step, decide if a delta update is possible * if either the session_id changed or the delta files fail to cover @@ -369,11 +508,9 @@ free_notification_xml(struct notification_xml *nxml) enum rrdp_task notification_done(struct notification_xml *nxml, char *last_mod) { - struct delta_item *d; - long long s, last_s = 0; - nxml->current->last_mod = last_mod; nxml->current->session_id = xstrdup(nxml->session_id); + notification_collect_deltas(nxml); /* check the that the session_id was valid and still the same */ if (nxml->repository->session_id == NULL || @@ -384,6 +521,10 @@ notification_done(struct notification_xml *nxml, char *last_mod) if (nxml->repository->serial == 0) goto snapshot; + /* check that all needed deltas are available and valid */ + if (!notification_check_deltas(nxml)) + goto snapshot; + if (nxml->repository->serial > nxml->serial) warnx("%s: serial number decreased from %lld to %lld", nxml->notifyuri, nxml->repository->serial, nxml->serial); @@ -399,14 +540,12 @@ notification_done(struct notification_xml *nxml, char *last_mod) if (nxml->serial - nxml->repository->serial > MAX_RRDP_DELTAS) goto snapshot; - /* check that all needed deltas are available */ - s = nxml->repository->serial + 1; - TAILQ_FOREACH(d, &nxml->delta_q, q) { - if (d->serial != s++) - goto snapshot; - last_s = d->serial; - } - if (last_s != nxml->serial) + /* no deltas queued */ + if (TAILQ_EMPTY(&nxml->delta_q)) + goto snapshot; + + /* first possible delta is no match */ + if (nxml->repository->serial + 1 != TAILQ_FIRST(&nxml->delta_q)->serial) goto snapshot; /* update via delta possible */ @@ -416,6 +555,7 @@ notification_done(struct notification_xml *nxml, char *last_mod) snapshot: /* update via snapshot download */ + free_delta_queue(nxml); nxml->current->serial = nxml->serial; return SNAPSHOT; } diff --git a/usr.sbin/rpki-client/x509.c b/usr.sbin/rpki-client/x509.c index db1d21cde..5d63a8fb4 100644 --- a/usr.sbin/rpki-client/x509.c +++ b/usr.sbin/rpki-client/x509.c @@ -1,4 +1,4 @@ -/* $OpenBSD: x509.c,v 1.72 2023/06/20 11:06:47 job Exp $ */ +/* $OpenBSD: x509.c,v 1.73 2023/06/23 15:32:15 tb Exp $ */ /* * Copyright (c) 2022 Theo Buehler * Copyright (c) 2021 Claudio Jeker @@ -146,8 +146,14 @@ x509_get_aki(X509 *x, const char *fn, char **aki) *aki = NULL; akid = X509_get_ext_d2i(x, NID_authority_key_identifier, &crit, NULL); - if (akid == NULL) + if (akid == NULL) { + if (crit != -1) { + warnx("%s: RFC 6487 section 4.8.3: error parsing AKI", + fn); + return 0; + } return 1; + } if (crit != 0) { warnx("%s: RFC 6487 section 4.8.3: " "AKI: extension not non-critical", fn); @@ -200,8 +206,14 @@ x509_get_ski(X509 *x, const char *fn, char **ski) *ski = NULL; os = X509_get_ext_d2i(x, NID_subject_key_identifier, &crit, NULL); - if (os == NULL) + if (os == NULL) { + if (crit != -1) { + warnx("%s: RFC 6487 section 4.8.2: error parsing SKI", + fn); + return 0; + } return 1; + } if (crit != 0) { warnx("%s: RFC 6487 section 4.8.2: " "SKI: extension not non-critical", fn); @@ -258,6 +270,20 @@ x509_get_purpose(X509 *x, const char *fn) if (X509_check_ca(x) == 1) { bc = X509_get_ext_d2i(x, NID_basic_constraints, &crit, NULL); + if (bc == NULL) { + if (crit != -1) + warnx("%s: RFC 6487 section 4.8.1: " + "error parsing basic constraints", fn); + else + warnx("%s: RFC 6487 section 4.8.1: " + "missing basic constraints", fn); + goto out; + } + if (crit != 1) { + warnx("%s: RFC 6487 section 4.8.1: Basic Constraints " + "must be marked critical", fn); + goto out; + } if (bc->pathlen != NULL) { warnx("%s: RFC 6487 section 4.8.1: Path Length " "Constraint must be absent", fn); @@ -274,7 +300,10 @@ x509_get_purpose(X509 *x, const char *fn) eku = X509_get_ext_d2i(x, NID_ext_key_usage, &crit, NULL); if (eku == NULL) { - warnx("%s: EKU: extension missing", fn); + if (crit != -1) + warnx("%s: error parsing EKU", fn); + else + warnx("%s: EKU: extension missing", fn); goto out; } if (crit != 0) { @@ -372,13 +401,13 @@ x509_get_aia(X509 *x, const char *fn, char **aia) *aia = NULL; info = X509_get_ext_d2i(x, NID_info_access, &crit, NULL); - if (info == NULL) + if (info == NULL) { + if (crit != -1) { + warnx("%s: RFC 6487 section 4.8.7: error parsing AIA", + fn); + return 0; + } return 1; - - if ((X509_get_extension_flags(x) & EXFLAG_SS) != 0) { - warnx("%s: RFC 6487 section 4.8.7: AIA must be absent from " - "a self-signed certificate", fn); - goto out; } if (crit != 0) { @@ -387,6 +416,12 @@ x509_get_aia(X509 *x, const char *fn, char **aia) goto out; } + if ((X509_get_extension_flags(x) & EXFLAG_SS) != 0) { + warnx("%s: RFC 6487 section 4.8.7: AIA must be absent from " + "a self-signed certificate", fn); + goto out; + } + if (sk_ACCESS_DESCRIPTION_num(info) != 1) { warnx("%s: RFC 6487 section 4.8.7: AIA: " "want 1 element, have %d", fn, @@ -428,8 +463,13 @@ x509_get_sia(X509 *x, const char *fn, char **sia) *sia = NULL; info = X509_get_ext_d2i(x, NID_sinfo_access, &crit, NULL); - if (info == NULL) + if (info == NULL) { + if (crit != -1) { + warnx("%s: error parsing SIA", fn); + return 0; + } return 1; + } if (crit != 0) { warnx("%s: RFC 6487 section 4.8.8: " @@ -546,11 +586,14 @@ x509_inherits(X509 *x) STACK_OF(IPAddressFamily) *addrblk = NULL; ASIdentifiers *asidentifiers = NULL; const IPAddressFamily *af; - int i, rc = 0; + int crit, i, rc = 0; - addrblk = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL); - if (addrblk == NULL) + addrblk = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, &crit, NULL); + if (addrblk == NULL) { + if (crit != -1) + warnx("error parsing ipAddrBlock"); goto out; + } /* * Check by hand, since X509v3_addr_inherits() success only means that @@ -564,8 +607,11 @@ x509_inherits(X509 *x) asidentifiers = X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum, NULL, NULL); - if (asidentifiers == NULL) + if (asidentifiers == NULL) { + if (crit != -1) + warnx("error parsing asIdentifiers"); goto out; + } /* We need to have AS numbers and don't want RDIs. */ if (asidentifiers->asnum == NULL || asidentifiers->rdi != NULL) @@ -590,14 +636,18 @@ x509_any_inherits(X509 *x) { STACK_OF(IPAddressFamily) *addrblk = NULL; ASIdentifiers *asidentifiers = NULL; - int rc = 0; + int crit, rc = 0; - addrblk = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL); + addrblk = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, &crit, NULL); + if (addrblk == NULL && crit != -1) + warnx("error parsing ipAddrBlock"); if (X509v3_addr_inherits(addrblk)) rc = 1; - asidentifiers = X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum, NULL, + asidentifiers = X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum, &crit, NULL); + if (asidentifiers == NULL && crit != -1) + warnx("error parsing asIdentifiers"); if (X509v3_asid_inherits(asidentifiers)) rc = 1; @@ -624,8 +674,14 @@ x509_get_crl(X509 *x, const char *fn, char **crl) *crl = NULL; crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, &crit, NULL); - if (crldp == NULL) + if (crldp == NULL) { + if (crit != -1) { + warnx("%s: RFC 6487 section 4.8.6: failed to parse " + "CRL distribution points", fn); + return 0; + } return 1; + } if (crit != 0) { warnx("%s: RFC 6487 section 4.8.6: " diff --git a/usr.sbin/smtpd/smtp_session.c b/usr.sbin/smtpd/smtp_session.c index 222d87579..21e02f27c 100644 --- a/usr.sbin/smtpd/smtp_session.c +++ b/usr.sbin/smtpd/smtp_session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: smtp_session.c,v 1.434 2023/05/31 16:51:46 op Exp $ */ +/* $OpenBSD: smtp_session.c,v 1.435 2023/06/23 18:32:28 op Exp $ */ /* * Copyright (c) 2008 Gilles Chehade @@ -212,6 +212,7 @@ static int smtp_check_starttls(struct smtp_session *, const char *); static int smtp_check_mail_from(struct smtp_session *, const char *); static int smtp_check_rcpt_to(struct smtp_session *, const char *); static int smtp_check_data(struct smtp_session *, const char *); +static int smtp_check_noop(struct smtp_session *, const char *); static int smtp_check_noparam(struct smtp_session *, const char *); static void smtp_filter_phase(enum filter_phase, struct smtp_session *, const char *); @@ -276,7 +277,7 @@ static struct { { CMD_DATA, FILTER_DATA, "DATA", smtp_check_data, smtp_proceed_data }, { CMD_RSET, FILTER_RSET, "RSET", smtp_check_rset, smtp_proceed_rset }, { CMD_QUIT, FILTER_QUIT, "QUIT", smtp_check_noparam, smtp_proceed_quit }, - { CMD_NOOP, FILTER_NOOP, "NOOP", smtp_check_noparam, smtp_proceed_noop }, + { CMD_NOOP, FILTER_NOOP, "NOOP", smtp_check_noop, smtp_proceed_noop }, { CMD_HELP, FILTER_HELP, "HELP", smtp_check_noparam, smtp_proceed_help }, { CMD_WIZ, FILTER_WIZ, "WIZ", smtp_check_noparam, smtp_proceed_wiz }, { CMD_COMMIT, FILTER_COMMIT, ".", smtp_check_noparam, smtp_proceed_commit }, @@ -1343,8 +1344,13 @@ smtp_command(struct smtp_session *s, char *line) break; case CMD_NOOP: +<<<<<<< smtp_session.c if (!smtp_check_noparam(s, args)) break; +======= + if (!smtp_check_noop(s, args)) + break; +>>>>>>> 1.435 smtp_filter_phase(FILTER_NOOP, s, NULL); break; @@ -1630,6 +1636,12 @@ smtp_check_data(struct smtp_session *s, const char *args) return 1; } +static int +smtp_check_noop(struct smtp_session *s, const char *args) +{ + return 1; +} + static int smtp_check_noparam(struct smtp_session *s, const char *args) {