sync
This commit is contained in:
parent
be633fa56a
commit
82bafdd0b3
@ -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.
|
||||
|
@ -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 <otto@drijf.net>
|
||||
* Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org>
|
||||
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 <jsing@openbsd.org>
|
||||
*
|
||||
@ -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:
|
||||
|
@ -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 <brynet@openbsd.org>
|
||||
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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))
|
||||
|
@ -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 <tb@openbsd.org>
|
||||
* Copyright (c) 2021 Job Snijders <job@openbsd.org>
|
||||
@ -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;
|
||||
|
@ -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 <kristaps@bsd.lv>
|
||||
*
|
||||
@ -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.
|
||||
|
@ -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 <claudio@openbsd.org>
|
||||
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
@ -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));
|
||||
|
@ -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 <claudio@openbsd.org>
|
||||
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
@ -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;
|
||||
|
@ -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 <nils_fisher@hotmail.com>
|
||||
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
|
||||
@ -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:
|
||||
|
@ -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 <nils_fisher@hotmail.com>
|
||||
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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 <tb@openbsd.org>
|
||||
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
|
||||
@ -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: "
|
||||
|
@ -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 <gilles@poolp.org>
|
||||
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user