New upstream version 7.5
Marco d'Itri
2 years ago
0 | 0 | #! /bin/sh |
1 | 1 | # Guess values for system-dependent variables and create Makefiles. |
2 | # Generated by GNU Autoconf 2.69 for rpki-client 7.4. | |
2 | # Generated by GNU Autoconf 2.69 for rpki-client 7.5. | |
3 | 3 | # |
4 | 4 | # |
5 | 5 | # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. |
586 | 586 | # Identity of this package. |
587 | 587 | PACKAGE_NAME='rpki-client' |
588 | 588 | PACKAGE_TARNAME='rpki-client' |
589 | PACKAGE_VERSION='7.4' | |
590 | PACKAGE_STRING='rpki-client 7.4' | |
589 | PACKAGE_VERSION='7.5' | |
590 | PACKAGE_STRING='rpki-client 7.5' | |
591 | 591 | PACKAGE_BUGREPORT='' |
592 | 592 | PACKAGE_URL='' |
593 | 593 | |
1398 | 1398 | # Omit some internal or obsolete options to make the list less imposing. |
1399 | 1399 | # This message is too long to be a string in the A/UX 3.1 sh. |
1400 | 1400 | cat <<_ACEOF |
1401 | \`configure' configures rpki-client 7.4 to adapt to many kinds of systems. | |
1401 | \`configure' configures rpki-client 7.5 to adapt to many kinds of systems. | |
1402 | 1402 | |
1403 | 1403 | Usage: $0 [OPTION]... [VAR=VALUE]... |
1404 | 1404 | |
1469 | 1469 | |
1470 | 1470 | if test -n "$ac_init_help"; then |
1471 | 1471 | case $ac_init_help in |
1472 | short | recursive ) echo "Configuration of rpki-client 7.4:";; | |
1472 | short | recursive ) echo "Configuration of rpki-client 7.5:";; | |
1473 | 1473 | esac |
1474 | 1474 | cat <<\_ACEOF |
1475 | 1475 | |
1596 | 1596 | test -n "$ac_init_help" && exit $ac_status |
1597 | 1597 | if $ac_init_version; then |
1598 | 1598 | cat <<\_ACEOF |
1599 | rpki-client configure 7.4 | |
1599 | rpki-client configure 7.5 | |
1600 | 1600 | generated by GNU Autoconf 2.69 |
1601 | 1601 | |
1602 | 1602 | Copyright (C) 2012 Free Software Foundation, Inc. |
1961 | 1961 | This file contains any messages produced by compilers while |
1962 | 1962 | running configure, to aid debugging if configure makes a mistake. |
1963 | 1963 | |
1964 | It was created by rpki-client $as_me 7.4, which was | |
1964 | It was created by rpki-client $as_me 7.5, which was | |
1965 | 1965 | generated by GNU Autoconf 2.69. Invocation command line was |
1966 | 1966 | |
1967 | 1967 | $ $0 $@ |
2891 | 2891 | |
2892 | 2892 | # Define the identity of the package. |
2893 | 2893 | PACKAGE='rpki-client' |
2894 | VERSION='7.4' | |
2894 | VERSION='7.5' | |
2895 | 2895 | |
2896 | 2896 | |
2897 | 2897 | cat >>confdefs.h <<_ACEOF |
14238 | 14238 | # report actual input values of CONFIG_FILES etc. instead of their |
14239 | 14239 | # values after options handling. |
14240 | 14240 | ac_log=" |
14241 | This file was extended by rpki-client $as_me 7.4, which was | |
14241 | This file was extended by rpki-client $as_me 7.5, which was | |
14242 | 14242 | generated by GNU Autoconf 2.69. Invocation command line was |
14243 | 14243 | |
14244 | 14244 | CONFIG_FILES = $CONFIG_FILES |
14295 | 14295 | cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 |
14296 | 14296 | ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" |
14297 | 14297 | ac_cs_version="\\ |
14298 | rpki-client config.status 7.4 | |
14298 | rpki-client config.status 7.5 | |
14299 | 14299 | configured by $0, generated by GNU Autoconf 2.69, |
14300 | 14300 | with options \\"\$ac_cs_config\\" |
14301 | 14301 |
0 | /* $OpenBSD: cert.c,v 1.43 2021/10/28 09:02:19 beck Exp $ */ | |
0 | /* $OpenBSD: cert.c,v 1.47 2021/11/05 10:50:41 claudio Exp $ */ | |
1 | 1 | /* |
2 | 2 | * Copyright (c) 2021 Job Snijders <job@openbsd.org> |
3 | 3 | * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> |
1083 | 1083 | goto out; |
1084 | 1084 | } |
1085 | 1085 | if (p.res->ipsz > 0) { |
1086 | warnx("%s: unexpected IP resources in BGPsec cert", p.fn); | |
1086 | warnx("%s: unexpected IP resources in BGPsec cert", | |
1087 | p.fn); | |
1087 | 1088 | goto out; |
1088 | 1089 | } |
1089 | 1090 | if (sia_present) { |
1090 | warnx("%s: unexpected SIA extension in BGPsec cert", p.fn); | |
1091 | warnx("%s: unexpected SIA extension in BGPsec cert", | |
1092 | p.fn); | |
1093 | goto out; | |
1094 | } | |
1095 | if (ta) { | |
1096 | warnx("%s: BGPsec cert can not be a trust anchor", | |
1097 | p.fn); | |
1091 | 1098 | goto out; |
1092 | 1099 | } |
1093 | 1100 | break; |
1212 | 1219 | free(p->aia); |
1213 | 1220 | free(p->aki); |
1214 | 1221 | free(p->ski); |
1215 | free(p->tal); | |
1216 | 1222 | free(p->pubkey); |
1217 | 1223 | X509_free(p->x509); |
1218 | 1224 | free(p); |
1219 | 1225 | } |
1220 | 1226 | |
1221 | static void | |
1222 | cert_ip_buffer(struct ibuf *b, const struct cert_ip *p) | |
1223 | { | |
1224 | io_simple_buffer(b, &p->afi, sizeof(enum afi)); | |
1225 | io_simple_buffer(b, &p->type, sizeof(enum cert_ip_type)); | |
1226 | ||
1227 | if (p->type != CERT_IP_INHERIT) { | |
1228 | io_simple_buffer(b, &p->min, sizeof(p->min)); | |
1229 | io_simple_buffer(b, &p->max, sizeof(p->max)); | |
1230 | } | |
1231 | ||
1232 | if (p->type == CERT_IP_RANGE) | |
1233 | ip_addr_range_buffer(b, &p->range); | |
1234 | else if (p->type == CERT_IP_ADDR) | |
1235 | ip_addr_buffer(b, &p->ip); | |
1236 | } | |
1237 | ||
1238 | static void | |
1239 | cert_as_buffer(struct ibuf *b, const struct cert_as *p) | |
1240 | { | |
1241 | io_simple_buffer(b, &p->type, sizeof(enum cert_as_type)); | |
1242 | if (p->type == CERT_AS_RANGE) { | |
1243 | io_simple_buffer(b, &p->range.min, sizeof(uint32_t)); | |
1244 | io_simple_buffer(b, &p->range.max, sizeof(uint32_t)); | |
1245 | } else if (p->type == CERT_AS_ID) | |
1246 | io_simple_buffer(b, &p->id, sizeof(uint32_t)); | |
1247 | } | |
1248 | ||
1249 | 1227 | /* |
1250 | 1228 | * Write certificate parsed content into buffer. |
1251 | 1229 | * See cert_read() for the other side of the pipe. |
1253 | 1231 | void |
1254 | 1232 | cert_buffer(struct ibuf *b, const struct cert *p) |
1255 | 1233 | { |
1256 | size_t i; | |
1257 | ||
1258 | io_simple_buffer(b, &p->valid, sizeof(int)); | |
1259 | io_simple_buffer(b, &p->expires, sizeof(time_t)); | |
1260 | io_simple_buffer(b, &p->purpose, sizeof(enum cert_purpose)); | |
1261 | io_simple_buffer(b, &p->ipsz, sizeof(size_t)); | |
1262 | for (i = 0; i < p->ipsz; i++) | |
1263 | cert_ip_buffer(b, &p->ips[i]); | |
1264 | ||
1265 | io_simple_buffer(b, &p->asz, sizeof(size_t)); | |
1266 | for (i = 0; i < p->asz; i++) | |
1267 | cert_as_buffer(b, &p->as[i]); | |
1234 | io_simple_buffer(b, &p->expires, sizeof(p->expires)); | |
1235 | io_simple_buffer(b, &p->purpose, sizeof(p->purpose)); | |
1236 | io_simple_buffer(b, &p->talid, sizeof(p->talid)); | |
1237 | io_simple_buffer(b, &p->ipsz, sizeof(p->ipsz)); | |
1238 | io_simple_buffer(b, &p->asz, sizeof(p->asz)); | |
1239 | ||
1240 | io_simple_buffer(b, p->ips, p->ipsz * sizeof(p->ips[0])); | |
1241 | io_simple_buffer(b, p->as, p->asz * sizeof(p->as[0])); | |
1242 | ||
1268 | 1243 | io_str_buffer(b, p->mft); |
1269 | 1244 | io_str_buffer(b, p->notify); |
1270 | 1245 | io_str_buffer(b, p->repo); |
1272 | 1247 | io_str_buffer(b, p->aia); |
1273 | 1248 | io_str_buffer(b, p->aki); |
1274 | 1249 | io_str_buffer(b, p->ski); |
1275 | io_str_buffer(b, p->tal); | |
1276 | 1250 | io_str_buffer(b, p->pubkey); |
1277 | } | |
1278 | ||
1279 | static void | |
1280 | cert_ip_read(struct ibuf *b, struct cert_ip *p) | |
1281 | { | |
1282 | io_read_buf(b, &p->afi, sizeof(enum afi)); | |
1283 | io_read_buf(b, &p->type, sizeof(enum cert_ip_type)); | |
1284 | ||
1285 | if (p->type != CERT_IP_INHERIT) { | |
1286 | io_read_buf(b, &p->min, sizeof(p->min)); | |
1287 | io_read_buf(b, &p->max, sizeof(p->max)); | |
1288 | } | |
1289 | ||
1290 | if (p->type == CERT_IP_RANGE) | |
1291 | ip_addr_range_read(b, &p->range); | |
1292 | else if (p->type == CERT_IP_ADDR) | |
1293 | ip_addr_read(b, &p->ip); | |
1294 | } | |
1295 | ||
1296 | static void | |
1297 | cert_as_read(struct ibuf *b, struct cert_as *p) | |
1298 | { | |
1299 | io_read_buf(b, &p->type, sizeof(enum cert_as_type)); | |
1300 | if (p->type == CERT_AS_RANGE) { | |
1301 | io_read_buf(b, &p->range.min, sizeof(uint32_t)); | |
1302 | io_read_buf(b, &p->range.max, sizeof(uint32_t)); | |
1303 | } else if (p->type == CERT_AS_ID) | |
1304 | io_read_buf(b, &p->id, sizeof(uint32_t)); | |
1305 | 1251 | } |
1306 | 1252 | |
1307 | 1253 | /* |
1313 | 1259 | cert_read(struct ibuf *b) |
1314 | 1260 | { |
1315 | 1261 | struct cert *p; |
1316 | size_t i; | |
1317 | 1262 | |
1318 | 1263 | if ((p = calloc(1, sizeof(struct cert))) == NULL) |
1319 | 1264 | err(1, NULL); |
1320 | 1265 | |
1321 | io_read_buf(b, &p->valid, sizeof(int)); | |
1322 | io_read_buf(b, &p->expires, sizeof(time_t)); | |
1323 | io_read_buf(b, &p->purpose, sizeof(enum cert_purpose)); | |
1324 | io_read_buf(b, &p->ipsz, sizeof(size_t)); | |
1266 | io_read_buf(b, &p->expires, sizeof(p->expires)); | |
1267 | io_read_buf(b, &p->purpose, sizeof(p->purpose)); | |
1268 | io_read_buf(b, &p->talid, sizeof(p->talid)); | |
1269 | io_read_buf(b, &p->ipsz, sizeof(p->ipsz)); | |
1270 | io_read_buf(b, &p->asz, sizeof(p->asz)); | |
1325 | 1271 | |
1326 | 1272 | p->ips = calloc(p->ipsz, sizeof(struct cert_ip)); |
1327 | 1273 | if (p->ips == NULL) |
1328 | 1274 | err(1, NULL); |
1329 | for (i = 0; i < p->ipsz; i++) | |
1330 | cert_ip_read(b, &p->ips[i]); | |
1331 | ||
1332 | io_read_buf(b, &p->asz, sizeof(size_t)); | |
1275 | io_read_buf(b, p->ips, p->ipsz * sizeof(p->ips[0])); | |
1276 | ||
1333 | 1277 | p->as = calloc(p->asz, sizeof(struct cert_as)); |
1334 | 1278 | if (p->as == NULL) |
1335 | 1279 | err(1, NULL); |
1336 | for (i = 0; i < p->asz; i++) | |
1337 | cert_as_read(b, &p->as[i]); | |
1280 | io_read_buf(b, p->as, p->asz * sizeof(p->as[0])); | |
1338 | 1281 | |
1339 | 1282 | io_read_str(b, &p->mft); |
1340 | 1283 | io_read_str(b, &p->notify); |
1343 | 1286 | io_read_str(b, &p->aia); |
1344 | 1287 | io_read_str(b, &p->aki); |
1345 | 1288 | io_read_str(b, &p->ski); |
1346 | io_read_str(b, &p->tal); | |
1347 | 1289 | io_read_str(b, &p->pubkey); |
1348 | 1290 | |
1349 | 1291 | assert(p->mft != NULL || p->purpose == CERT_PURPOSE_BGPSEC_ROUTER); |
1364 | 1306 | return RB_FIND(auth_tree, auths, &a); |
1365 | 1307 | } |
1366 | 1308 | |
1309 | int | |
1310 | auth_insert(struct auth_tree *auths, struct cert *cert, struct auth *parent) | |
1311 | { | |
1312 | struct auth *na; | |
1313 | ||
1314 | na = malloc(sizeof(*na)); | |
1315 | if (na == NULL) | |
1316 | err(1, NULL); | |
1317 | ||
1318 | na->parent = parent; | |
1319 | na->cert = cert; | |
1320 | ||
1321 | if (RB_INSERT(auth_tree, auths, na) != NULL) | |
1322 | err(1, "auth tree corrupted"); | |
1323 | ||
1324 | return 1; | |
1325 | } | |
1326 | ||
1367 | 1327 | static inline int |
1368 | 1328 | authcmp(struct auth *a, struct auth *b) |
1369 | 1329 | { |
1382 | 1342 | |
1383 | 1343 | b->asid = asid; |
1384 | 1344 | b->expires = cert->expires; |
1385 | if ((b->tal = strdup(cert->tal)) == NULL) | |
1386 | err(1, NULL); | |
1345 | b->talid = cert->talid; | |
1387 | 1346 | if ((b->ski = strdup(cert->ski)) == NULL) |
1388 | 1347 | err(1, NULL); |
1389 | 1348 | if ((b->pubkey = strdup(cert->pubkey)) == NULL) |
1396 | 1355 | if ((found = RB_INSERT(brk_tree, tree, b)) != NULL) { |
1397 | 1356 | if (found->expires < b->expires) { |
1398 | 1357 | found->expires = b->expires; |
1399 | free(found->tal); | |
1400 | found->tal = b->tal; | |
1401 | b->tal = NULL; | |
1358 | found->talid = b->talid; | |
1402 | 1359 | } |
1403 | 1360 | free(b->ski); |
1404 | 1361 | free(b->pubkey); |
1405 | free(b->tal); | |
1406 | 1362 | free(b); |
1407 | 1363 | } |
1408 | 1364 | } |
0 | /* $OpenBSD: encoding.c,v 1.8 2021/10/28 11:57:00 claudio Exp $ */ | |
0 | /* $OpenBSD: encoding.c,v 1.9 2021/10/31 16:00:14 claudio Exp $ */ | |
1 | 1 | /* |
2 | 2 | * Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org> |
3 | 3 | * |
16 | 16 | #include <sys/stat.h> |
17 | 17 | |
18 | 18 | #include <err.h> |
19 | #include <errno.h> | |
19 | 20 | #include <fcntl.h> |
20 | 21 | #include <limits.h> |
21 | 22 | #include <stdlib.h> |
36 | 37 | struct stat st; |
37 | 38 | ssize_t n; |
38 | 39 | size_t size; |
39 | int fd; | |
40 | int fd, saved_errno; | |
40 | 41 | |
41 | 42 | *len = 0; |
42 | 43 | |
44 | 45 | return NULL; |
45 | 46 | if (fstat(fd, &st) != 0) |
46 | 47 | goto err; |
47 | if (st.st_size < 0 || st.st_size > MAX_FILE_SIZE) | |
48 | if (st.st_size <= 0 || st.st_size > MAX_FILE_SIZE) { | |
49 | errno = EFBIG; | |
48 | 50 | goto err; |
51 | } | |
49 | 52 | size = (size_t)st.st_size; |
50 | 53 | if ((buf = malloc(size)) == NULL) |
51 | 54 | goto err; |
52 | 55 | n = read(fd, buf, size); |
53 | if (n < 0 || (size_t)n != size) | |
56 | if (n == -1) | |
54 | 57 | goto err; |
58 | if ((size_t)n != size) { | |
59 | errno = EIO; | |
60 | goto err; | |
61 | } | |
55 | 62 | close(fd); |
56 | 63 | *len = size; |
57 | 64 | return buf; |
58 | 65 | |
59 | 66 | err: |
67 | saved_errno = errno; | |
60 | 68 | close(fd); |
61 | 69 | free(buf); |
70 | errno = saved_errno; | |
62 | 71 | return NULL; |
63 | 72 | } |
64 | 73 |
0 | /* $OpenBSD: extern.h,v 1.86 2021/10/29 09:27:36 claudio Exp $ */ | |
0 | /* $OpenBSD: extern.h,v 1.95 2021/11/09 11:03:39 claudio Exp $ */ | |
1 | 1 | /* |
2 | 2 | * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> |
3 | 3 | * |
117 | 117 | size_t ipsz; /* length of "ips" */ |
118 | 118 | struct cert_as *as; /* list of AS numbers and ranges */ |
119 | 119 | size_t asz; /* length of "asz" */ |
120 | int talid; /* cert is covered by which TAL */ | |
120 | 121 | char *repo; /* CA repository (rsync:// uri) */ |
121 | 122 | char *mft; /* manifest (rsync:// uri) */ |
122 | 123 | char *notify; /* RRDP notify (https:// uri) */ |
124 | 125 | char *aia; /* AIA (or NULL, for trust anchor) */ |
125 | 126 | char *aki; /* AKI (or NULL, for trust anchor) */ |
126 | 127 | char *ski; /* SKI */ |
127 | char *tal; /* basename of TAL for this cert */ | |
128 | enum cert_purpose purpose; /* Certificate Purpose (BGPSec or CA) */ | |
128 | enum cert_purpose purpose; /* BGPSec or CA */ | |
129 | 129 | char *pubkey; /* Subject Public Key Info */ |
130 | int valid; /* validated resources */ | |
131 | 130 | X509 *x509; /* the cert */ |
132 | 131 | time_t expires; /* do not use after */ |
133 | 132 | }; |
145 | 144 | unsigned char *pkey; /* DER-encoded public key */ |
146 | 145 | size_t pkeysz; /* length of pkey */ |
147 | 146 | char *descr; /* basename of tal file */ |
147 | int id; /* ID of this TAL */ | |
148 | 148 | }; |
149 | 149 | |
150 | 150 | /* |
192 | 192 | uint32_t asid; /* asID of ROA (if 0, RFC 6483 sec 4) */ |
193 | 193 | struct roa_ip *ips; /* IP prefixes */ |
194 | 194 | size_t ipsz; /* number of IP prefixes */ |
195 | int talid; /* ROAs are covered by which TAL */ | |
195 | 196 | int valid; /* validated resources */ |
196 | 197 | char *aia; /* AIA */ |
197 | 198 | char *aki; /* AKI */ |
198 | 199 | char *ski; /* SKI */ |
199 | char *tal; /* basename of TAL for this cert */ | |
200 | 200 | time_t expires; /* do not use after */ |
201 | 201 | }; |
202 | 202 | |
216 | 216 | struct vrp { |
217 | 217 | RB_ENTRY(vrp) entry; |
218 | 218 | struct ip_addr addr; |
219 | int talid; /* covered by which TAL */ | |
219 | 220 | uint32_t asid; |
220 | char *tal; /* basename of TAL for this cert */ | |
221 | 221 | enum afi afi; |
222 | 222 | unsigned char maxlength; |
223 | 223 | time_t expires; /* transitive expiry moment */ |
234 | 234 | struct brk { |
235 | 235 | RB_ENTRY(brk) entry; |
236 | 236 | uint32_t asid; |
237 | char *tal; /* basename of TAL for this key */ | |
237 | int talid; /* covered by which TAL */ | |
238 | 238 | char *ski; /* Subject Key Identifier */ |
239 | 239 | char *pubkey; /* Subject Public Key Info */ |
240 | 240 | time_t expires; /* transitive expiry moment */ |
269 | 269 | RB_ENTRY(auth) entry; |
270 | 270 | struct cert *cert; /* owner information */ |
271 | 271 | struct auth *parent; /* pointer to parent or NULL for TA cert */ |
272 | char *tal; /* basename of TAL for this cert */ | |
273 | char *fn; /* FIXME: debugging */ | |
274 | 272 | }; |
275 | 273 | /* |
276 | 274 | * Tree of auth sorted by ski |
278 | 276 | RB_HEAD(auth_tree, auth); |
279 | 277 | RB_PROTOTYPE(auth_tree, auth, entry, authcmp); |
280 | 278 | |
281 | struct auth *auth_find(struct auth_tree *, const char *); | |
279 | struct auth *auth_find(struct auth_tree *, const char *); | |
280 | int auth_insert(struct auth_tree *, struct cert *, struct auth *); | |
282 | 281 | |
283 | 282 | /* |
284 | 283 | * Resource types specified by the RPKI profiles. |
341 | 340 | int has_data; /* whether data blob is specified */ |
342 | 341 | unsigned char *data; /* optional data blob */ |
343 | 342 | size_t datasz; /* length of optional data blob */ |
344 | char *descr; /* tal description */ | |
343 | int talid; /* tal identifier */ | |
345 | 344 | TAILQ_ENTRY(entity) entries; |
346 | 345 | }; |
347 | 346 | TAILQ_HEAD(entityq, entity); |
360 | 359 | size_t mfts_fail; /* failing syntactic parse */ |
361 | 360 | size_t mfts_stale; /* stale manifests */ |
362 | 361 | size_t certs; /* certificates */ |
363 | size_t certs_fail; /* failing syntactic parse */ | |
364 | size_t certs_invalid; /* invalid resources */ | |
362 | size_t certs_fail; /* invalid certificate */ | |
365 | 363 | size_t roas; /* route origin authorizations */ |
366 | 364 | size_t roas_fail; /* failing syntactic parse */ |
367 | 365 | size_t roas_invalid; /* invalid resources */ |
379 | 377 | size_t del_files; /* number of files removed in cleanup */ |
380 | 378 | size_t del_dirs; /* number of directories removed in cleanup */ |
381 | 379 | size_t brks; /* number of BGPsec Router Key (BRK) certificates */ |
382 | size_t brks_invalids; /* invalid BGPsec certs */ | |
383 | char *talnames; | |
384 | 380 | struct timeval elapsed_time; |
385 | 381 | struct timeval user_time; |
386 | 382 | struct timeval system_time; |
391 | 387 | |
392 | 388 | /* global variables */ |
393 | 389 | extern int verbose; |
390 | extern const char *tals[]; | |
391 | extern const char *taldescs[]; | |
392 | extern unsigned int talrepocnt[]; | |
393 | extern size_t talsz; | |
394 | 394 | |
395 | 395 | /* Routines for RPKI entities. */ |
396 | 396 | |
463 | 463 | enum afi, const char *, struct ip_addr *); |
464 | 464 | void ip_addr_print(const struct ip_addr *, enum afi, char *, |
465 | 465 | size_t); |
466 | void ip_addr_buffer(struct ibuf *, const struct ip_addr *); | |
467 | void ip_addr_range_buffer(struct ibuf *, | |
468 | const struct ip_addr_range *); | |
469 | void ip_addr_read(struct ibuf *, struct ip_addr *); | |
470 | void ip_addr_range_read(struct ibuf *, struct ip_addr_range *); | |
471 | 466 | int ip_addr_cmp(const struct ip_addr *, const struct ip_addr *); |
472 | 467 | int ip_addr_check_overlap(const struct cert_ip *, |
473 | 468 | const char *, const struct cert_ip *, size_t); |
506 | 501 | int rrdp_handle_file(size_t, enum publish_type, char *, |
507 | 502 | char *, size_t, char *, size_t); |
508 | 503 | char *repo_filename(const struct repo *, const char *); |
509 | struct repo *ta_lookup(struct tal *); | |
510 | struct repo *repo_lookup(const char *, const char *); | |
504 | struct repo *ta_lookup(int, struct tal *); | |
505 | struct repo *repo_lookup(int, const char *, const char *); | |
511 | 506 | int repo_queued(struct repo *, struct entity *); |
512 | 507 | void repo_cleanup(struct filepath_tree *); |
513 | 508 | void repo_free(void); |
522 | 517 | struct rrdp_session *); |
523 | 518 | void rrdp_http_done(size_t, enum http_result, const char *); |
524 | 519 | |
520 | int repo_next_timeout(int); | |
521 | void repo_check_timeout(void); | |
525 | 522 | |
526 | 523 | /* Logging (though really used for OpenSSL errors). */ |
527 | 524 | |
599 | 596 | |
600 | 597 | void logx(const char *fmt, ...) |
601 | 598 | __attribute__((format(printf, 1, 2))); |
599 | time_t getmonotime(void); | |
602 | 600 | |
603 | 601 | int mkpath(const char *); |
604 | 602 | |
605 | 603 | #ifndef RPKI_PATH_TAL_DIR |
606 | #define RPKI_PATH_TAL_DIR "/etc/rpki" | |
604 | #define RPKI_PATH_TAL_DIR "/etc/rpki" | |
607 | 605 | #endif |
608 | 606 | |
609 | 607 | #ifndef RPKI_PATH_OUT_DIR |
610 | #define RPKI_PATH_OUT_DIR "/var/db/rpki-client" | |
608 | #define RPKI_PATH_OUT_DIR "/var/db/rpki-client" | |
611 | 609 | #endif |
612 | 610 | |
613 | 611 | #ifndef RPKI_PATH_BASE_DIR |
614 | #define RPKI_PATH_BASE_DIR "/var/cache/rpki-client" | |
612 | #define RPKI_PATH_BASE_DIR "/var/cache/rpki-client" | |
615 | 613 | #endif |
616 | 614 | |
617 | 615 | #ifndef RPKI_CLIENT_USER |
618 | #define RPKI_CLIENT_USER "_rpki-client" | |
616 | #define RPKI_CLIENT_USER "_rpki-client" | |
619 | 617 | #endif |
620 | 618 | |
621 | 619 | #ifndef RPKI_RSYNC_CMD |
622 | #define RPKI_RSYNC_CMD "openrsync" | |
620 | #define RPKI_RSYNC_CMD "openrsync" | |
623 | 621 | #endif |
624 | 622 | |
625 | /* | |
626 | * Maximum number of ip ranges and AS ranges we will accept in | |
627 | * any single file | |
628 | */ | |
629 | #define MAX_IP_SIZE 200000 | |
630 | #define MAX_AS_SIZE 200000 | |
631 | ||
632 | /* | |
633 | * Maximum URI length we will accept | |
634 | */ | |
635 | #define MAX_URI_LENGTH 2048 | |
636 | ||
637 | /* | |
638 | * Maximum File Size we will accept | |
639 | */ | |
640 | #define MAX_FILE_SIZE 2000000 | |
641 | ||
642 | /* | |
643 | * Maximum number of FileAndHash entries per Manifest. | |
644 | */ | |
645 | #define MAX_MANIFEST_ENTRIES 100000 | |
623 | /* Maximum number of IP and AS ranges accepted in any single file */ | |
624 | #define MAX_IP_SIZE 200000 | |
625 | #define MAX_AS_SIZE 200000 | |
626 | ||
627 | /* Maximum acceptable URI length */ | |
628 | #define MAX_URI_LENGTH 2048 | |
629 | ||
630 | /* Maximum acceptable file size */ | |
631 | #define MAX_FILE_SIZE 2000000 | |
632 | ||
633 | /* Maximum number of FileAndHash entries per manifest. */ | |
634 | #define MAX_MANIFEST_ENTRIES 100000 | |
635 | ||
636 | /* Maximum depth of the RPKI tree. */ | |
637 | #define MAX_CERT_DEPTH 12 | |
638 | ||
639 | /* Maximum number of concurrent rsync processes. */ | |
640 | #define MAX_RSYNC_PROCESSES 16 | |
641 | ||
642 | /* Maximum allowd repositories per tal */ | |
643 | #define MAX_REPO_PER_TAL 1000 | |
644 | ||
645 | /* Timeout for repository synchronisation, in seconds */ | |
646 | #define MAX_REPO_TIMEOUT (15 * 60) | |
646 | 647 | |
647 | 648 | #endif /* ! EXTERN_H */ |
0 | /* $OpenBSD: http.c,v 1.46 2021/10/29 08:51:20 claudio Exp $ */ | |
0 | /* $OpenBSD: http.c,v 1.49 2021/11/09 11:00:43 claudio Exp $ */ | |
1 | 1 | /* |
2 | 2 | * Copyright (c) 2020 Nils Fisher <nils_fisher@hotmail.com> |
3 | 3 | * Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org> |
160 | 160 | #endif |
161 | 161 | |
162 | 162 | /* HTTP request API */ |
163 | static void http_req_new(size_t, char *, char *, int); | |
163 | static void http_req_new(size_t, char *, char *, int, int); | |
164 | 164 | static void http_req_free(struct http_request *); |
165 | 165 | static void http_req_done(size_t, enum http_result, const char *); |
166 | 166 | static void http_req_fail(size_t); |
193 | 193 | static enum res proxy_read(struct http_connection *); |
194 | 194 | static enum res proxy_write(struct http_connection *); |
195 | 195 | static enum res data_write(struct http_connection *); |
196 | ||
197 | static time_t | |
198 | getmonotime(void) | |
199 | { | |
200 | struct timespec ts; | |
201 | ||
202 | if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) | |
203 | err(1, "clock_gettime"); | |
204 | return (ts.tv_sec); | |
205 | } | |
206 | 196 | |
207 | 197 | /* |
208 | 198 | * Return a string that can be used in error message to identify the |
518 | 508 | * Create and queue a new request. |
519 | 509 | */ |
520 | 510 | static void |
521 | http_req_new(size_t id, char *uri, char *modified_since, int outfd) | |
511 | http_req_new(size_t id, char *uri, char *modified_since, int count, int outfd) | |
522 | 512 | { |
523 | 513 | struct http_request *req; |
524 | 514 | char *host, *port, *path; |
541 | 531 | req->path = path; |
542 | 532 | req->uri = uri; |
543 | 533 | req->modified_since = modified_since; |
534 | req->redirect_loop = count; | |
544 | 535 | |
545 | 536 | TAILQ_INSERT_TAIL(&queue, req, entry); |
546 | 537 | } |
1146 | 1137 | err(1, NULL); |
1147 | 1138 | |
1148 | 1139 | logx("redirect to %s", http_info(uri)); |
1149 | http_req_new(conn->req->id, uri, mod_since, outfd); | |
1140 | http_req_new(conn->req->id, uri, mod_since, conn->req->redirect_loop, | |
1141 | outfd); | |
1150 | 1142 | |
1151 | 1143 | /* clear request before moving connection to idle */ |
1152 | 1144 | http_req_free(conn->req); |
1680 | 1672 | |
1681 | 1673 | /* all data written, switch back to read */ |
1682 | 1674 | if (conn->bufpos == 0 || conn->iosz == 0) { |
1683 | if (conn->chunked) | |
1675 | if (conn->chunked && conn->iosz == 0) | |
1684 | 1676 | conn->state = STATE_RESPONSE_CHUNKED_TRAILER; |
1685 | 1677 | else |
1686 | 1678 | conn->state = STATE_RESPONSE_DATA; |
1880 | 1872 | io_read_str(b, &mod); |
1881 | 1873 | |
1882 | 1874 | /* queue up new requests */ |
1883 | http_req_new(id, uri, mod, b->fd); | |
1875 | http_req_new(id, uri, mod, 0, b->fd); | |
1884 | 1876 | ibuf_free(b); |
1885 | 1877 | } |
1886 | 1878 | } |
0 | /* $OpenBSD: ip.c,v 1.18 2021/10/23 16:06:04 claudio Exp $ */ | |
0 | /* $OpenBSD: ip.c,v 1.19 2021/11/05 10:50:41 claudio Exp $ */ | |
1 | 1 | /* |
2 | 2 | * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> |
3 | 3 | * |
281 | 281 | ip4_addr2str(addr, buf, bufsz); |
282 | 282 | else |
283 | 283 | ip6_addr2str(addr, buf, bufsz); |
284 | } | |
285 | ||
286 | /* | |
287 | * Serialise an ip_addr for sending over the wire. | |
288 | * Matched with ip_addr_read(). | |
289 | */ | |
290 | void | |
291 | ip_addr_buffer(struct ibuf *b, const struct ip_addr *p) | |
292 | { | |
293 | size_t sz = PREFIX_SIZE(p->prefixlen); | |
294 | ||
295 | assert(sz <= 16); | |
296 | io_simple_buffer(b, &p->prefixlen, sizeof(unsigned char)); | |
297 | io_simple_buffer(b, p->addr, sz); | |
298 | } | |
299 | ||
300 | /* | |
301 | * Serialise an ip_addr_range for sending over the wire. | |
302 | * Matched with ip_addr_range_read(). | |
303 | */ | |
304 | void | |
305 | ip_addr_range_buffer(struct ibuf *b, const struct ip_addr_range *p) | |
306 | { | |
307 | ip_addr_buffer(b, &p->min); | |
308 | ip_addr_buffer(b, &p->max); | |
309 | } | |
310 | ||
311 | /* | |
312 | * Read an ip_addr from the wire. | |
313 | * Matched with ip_addr_buffer(). | |
314 | */ | |
315 | void | |
316 | ip_addr_read(struct ibuf *b, struct ip_addr *p) | |
317 | { | |
318 | size_t sz; | |
319 | ||
320 | io_read_buf(b, &p->prefixlen, sizeof(unsigned char)); | |
321 | sz = PREFIX_SIZE(p->prefixlen); | |
322 | assert(sz <= 16); | |
323 | io_read_buf(b, p->addr, sz); | |
324 | } | |
325 | ||
326 | /* | |
327 | * Read an ip_addr_range from the wire. | |
328 | * Matched with ip_addr_range_buffer(). | |
329 | */ | |
330 | void | |
331 | ip_addr_range_read(struct ibuf *b, struct ip_addr_range *p) | |
332 | { | |
333 | ip_addr_read(b, &p->min); | |
334 | ip_addr_read(b, &p->max); | |
335 | 284 | } |
336 | 285 | |
337 | 286 | /* |
0 | /* $OpenBSD: main.c,v 1.157 2021/10/28 19:02:36 claudio Exp $ */ | |
0 | /* $OpenBSD: main.c,v 1.164 2021/11/09 11:03:39 claudio Exp $ */ | |
1 | 1 | /* |
2 | 2 | * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org> |
3 | 3 | * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> |
48 | 48 | */ |
49 | 49 | #define TALSZ_MAX 8 |
50 | 50 | |
51 | const char *tals[TALSZ_MAX]; | |
52 | const char *taldescs[TALSZ_MAX]; | |
53 | unsigned int talrepocnt[TALSZ_MAX]; | |
54 | size_t talsz; | |
55 | ||
51 | 56 | size_t entity_queue; |
52 | 57 | int timeout = 60*60; |
53 | 58 | volatile sig_atomic_t killme; |
81 | 86 | } |
82 | 87 | } |
83 | 88 | |
89 | time_t | |
90 | getmonotime(void) | |
91 | { | |
92 | struct timespec ts; | |
93 | ||
94 | if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) | |
95 | err(1, "clock_gettime"); | |
96 | return (ts.tv_sec); | |
97 | } | |
98 | ||
84 | 99 | void |
85 | 100 | entity_free(struct entity *ent) |
86 | 101 | { |
89 | 104 | |
90 | 105 | free(ent->data); |
91 | 106 | free(ent->file); |
92 | free(ent->descr); | |
93 | 107 | free(ent); |
94 | 108 | } |
95 | 109 | |
102 | 116 | entity_read_req(struct ibuf *b, struct entity *ent) |
103 | 117 | { |
104 | 118 | io_read_buf(b, &ent->type, sizeof(ent->type)); |
119 | io_read_buf(b, &ent->talid, sizeof(ent->talid)); | |
105 | 120 | io_read_str(b, &ent->file); |
106 | io_read_str(b, &ent->descr); | |
107 | 121 | io_read_buf(b, &ent->has_data, sizeof(ent->has_data)); |
108 | 122 | if (ent->has_data) |
109 | 123 | io_read_buf_alloc(b, (void **)&ent->data, &ent->datasz); |
126 | 140 | |
127 | 141 | b = io_new_buffer(); |
128 | 142 | io_simple_buffer(b, &ent->type, sizeof(ent->type)); |
143 | io_simple_buffer(b, &ent->talid, sizeof(ent->talid)); | |
129 | 144 | io_str_buffer(b, ent->file); |
130 | io_str_buffer(b, ent->descr); | |
131 | 145 | io_simple_buffer(b, &ent->has_data, sizeof(int)); |
132 | 146 | if (ent->has_data) |
133 | 147 | io_buf_buffer(b, ent->data, ent->datasz); |
168 | 182 | */ |
169 | 183 | static void |
170 | 184 | entityq_add(char *file, enum rtype type, struct repo *rp, |
171 | unsigned char *data, size_t datasz, char *descr) | |
185 | unsigned char *data, size_t datasz, int talid) | |
172 | 186 | { |
173 | 187 | struct entity *p; |
174 | 188 | |
176 | 190 | err(1, NULL); |
177 | 191 | |
178 | 192 | p->type = type; |
193 | p->talid = talid; | |
179 | 194 | p->file = file; |
180 | 195 | p->has_data = data != NULL; |
181 | 196 | if (p->has_data) { |
182 | 197 | p->data = data; |
183 | 198 | p->datasz = datasz; |
184 | 199 | } |
185 | if (descr != NULL) | |
186 | if ((p->descr = strdup(descr)) == NULL) | |
187 | err(1, NULL); | |
188 | 200 | |
189 | 201 | entity_queue++; |
190 | 202 | |
335 | 347 | * that the repository has already been loaded. |
336 | 348 | */ |
337 | 349 | |
338 | entityq_add(nfile, type, NULL, NULL, 0, NULL); | |
350 | entityq_add(nfile, type, NULL, NULL, 0, -1); | |
339 | 351 | } |
340 | 352 | |
341 | 353 | /* |
383 | 395 | * Add a local TAL file (RFC 7730) to the queue of files to fetch. |
384 | 396 | */ |
385 | 397 | static void |
386 | queue_add_tal(const char *file) | |
398 | queue_add_tal(const char *file, int id) | |
387 | 399 | { |
388 | 400 | unsigned char *buf; |
389 | 401 | char *nfile; |
392 | 404 | if ((nfile = strdup(file)) == NULL) |
393 | 405 | err(1, NULL); |
394 | 406 | buf = load_file(file, &len); |
395 | ||
396 | /* Record tal for later reporting */ | |
397 | if (stats.talnames == NULL) { | |
398 | if ((stats.talnames = strdup(file)) == NULL) | |
399 | err(1, NULL); | |
400 | } else { | |
401 | char *tmp; | |
402 | ||
403 | if (asprintf(&tmp, "%s %s", stats.talnames, file) == -1) | |
404 | err(1, NULL); | |
405 | free(stats.talnames); | |
406 | stats.talnames = tmp; | |
407 | if (buf == NULL) { | |
408 | warn("%s", file); | |
409 | return; | |
407 | 410 | } |
408 | 411 | |
409 | 412 | /* Not in a repository, so directly add to queue. */ |
410 | entityq_add(nfile, RTYPE_TAL, NULL, buf, len, buf); | |
413 | entityq_add(nfile, RTYPE_TAL, NULL, buf, len, id); | |
411 | 414 | } |
412 | 415 | |
413 | 416 | /* |
421 | 424 | |
422 | 425 | assert(tal->urisz); |
423 | 426 | |
427 | if ((taldescs[tal->id] = strdup(tal->descr)) == NULL) | |
428 | err(1, NULL); | |
429 | ||
424 | 430 | /* Look up the repository. */ |
425 | repo = ta_lookup(tal); | |
431 | repo = ta_lookup(tal->id, tal); | |
432 | if (repo == NULL) | |
433 | return; | |
426 | 434 | |
427 | 435 | /* steal the pkey from the tal structure */ |
428 | 436 | data = tal->pkey; |
429 | 437 | tal->pkey = NULL; |
430 | 438 | entityq_add(NULL, RTYPE_CER, repo, data, |
431 | tal->pkeysz, tal->descr); | |
439 | tal->pkeysz, tal->id); | |
432 | 440 | } |
433 | 441 | |
434 | 442 | /* |
440 | 448 | struct repo *repo; |
441 | 449 | char *nfile; |
442 | 450 | |
443 | repo = repo_lookup(cert->repo, rrdpon ? cert->notify : NULL); | |
444 | if (repo == NULL) { | |
445 | warnx("%s: repository lookup failed", cert->repo); | |
451 | repo = repo_lookup(cert->talid, cert->repo, | |
452 | rrdpon ? cert->notify : NULL); | |
453 | if (repo == NULL) | |
446 | 454 | return; |
447 | } | |
448 | 455 | |
449 | 456 | if ((nfile = strdup(cert->mft)) == NULL) |
450 | 457 | err(1, NULL); |
451 | entityq_add(nfile, RTYPE_MFT, repo, NULL, 0, NULL); | |
458 | entityq_add(nfile, RTYPE_MFT, repo, NULL, 0, -1); | |
452 | 459 | } |
453 | 460 | |
454 | 461 | /* |
492 | 499 | } |
493 | 500 | cert = cert_read(b); |
494 | 501 | if (cert->purpose == CERT_PURPOSE_CA) { |
495 | if (cert->valid) { | |
496 | /* | |
497 | * Process the revocation list from the | |
498 | * certificate *first*, since it might mark that | |
499 | * we're revoked and then we don't want to | |
500 | * process the MFT. | |
501 | */ | |
502 | queue_add_from_cert(cert); | |
503 | } else | |
504 | st->certs_invalid++; | |
502 | /* | |
503 | * Process the revocation list from the | |
504 | * certificate *first*, since it might mark that | |
505 | * we're revoked and then we don't want to | |
506 | * process the MFT. | |
507 | */ | |
508 | queue_add_from_cert(cert); | |
505 | 509 | } else if (cert->purpose == CERT_PURPOSE_BGPSEC_ROUTER) { |
506 | if (cert->valid) { | |
507 | cert_insert_brks(brktree, cert); | |
508 | st->brks++; | |
509 | } else | |
510 | st->brks_invalids++; | |
510 | cert_insert_brks(brktree, cert); | |
511 | st->brks++; | |
511 | 512 | } else |
512 | st->certs_invalid++; | |
513 | st->certs_fail++; | |
513 | 514 | cert_free(cert); |
514 | 515 | break; |
515 | 516 | case RTYPE_MFT: |
610 | 611 | * Don't exceded "max" filenames. |
611 | 612 | */ |
612 | 613 | static size_t |
613 | tal_load_default(const char *tals[], size_t max) | |
614 | tal_load_default(void) | |
614 | 615 | { |
615 | 616 | static const char *confdir = RPKI_PATH_TAL_DIR; |
616 | 617 | size_t s = 0; |
624 | 625 | while ((dp = readdir(dirp)) != NULL) { |
625 | 626 | if (fnmatch("*.tal", dp->d_name, FNM_PERIOD) == FNM_NOMATCH) |
626 | 627 | continue; |
627 | if (s >= max) | |
628 | if (s >= TALSZ_MAX) | |
628 | 629 | err(1, "too many tal files found in %s", |
629 | 630 | confdir); |
630 | 631 | if (asprintf(&path, "%s/%s", confdir, dp->d_name) == -1) |
673 | 674 | { |
674 | 675 | int rc, c, st, proc, rsync, http, rrdp, ok, hangup = 0; |
675 | 676 | int fl = SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK; |
676 | size_t i, id, talsz = 0; | |
677 | size_t i, id; | |
677 | 678 | pid_t pid, procpid, rsyncpid, httppid, rrdppid; |
678 | 679 | int fd[2]; |
679 | 680 | struct pollfd pfd[NPFD]; |
683 | 684 | char *rsync_prog = RPKI_RSYNC_CMD; |
684 | 685 | char *bind_addr = NULL; |
685 | 686 | const char *cachedir = NULL, *outputdir = NULL; |
686 | const char *tals[TALSZ_MAX], *errs, *name; | |
687 | const char *errs, *name; | |
687 | 688 | const char *file = NULL; |
688 | 689 | struct vrp_tree vrps = RB_INITIALIZER(&vrps); |
689 | 690 | struct brk_tree brks = RB_INITIALIZER(&brks); |
802 | 803 | | FORMAT_BIRD; |
803 | 804 | |
804 | 805 | if (talsz == 0) |
805 | talsz = tal_load_default(tals, TALSZ_MAX); | |
806 | talsz = tal_load_default(); | |
806 | 807 | if (talsz == 0) |
807 | 808 | err(1, "no TAL files found in %s", RPKI_PATH_TAL_DIR); |
808 | 809 | |
1002 | 1003 | */ |
1003 | 1004 | |
1004 | 1005 | for (i = 0; i < talsz; i++) |
1005 | queue_add_tal(tals[i]); | |
1006 | queue_add_tal(tals[i], i); | |
1006 | 1007 | |
1007 | 1008 | /* change working directory to the cache directory */ |
1008 | 1009 | if (fchdir(cachefd) == -1) |
1009 | 1010 | err(1, "fchdir"); |
1010 | 1011 | |
1011 | 1012 | while (entity_queue > 0 && !killme) { |
1013 | int polltim; | |
1014 | ||
1012 | 1015 | for (i = 0; i < NPFD; i++) { |
1013 | 1016 | pfd[i].events = POLLIN; |
1014 | 1017 | if (queues[i]->queued) |
1015 | 1018 | pfd[i].events |= POLLOUT; |
1016 | 1019 | } |
1017 | 1020 | |
1018 | if ((c = poll(pfd, NPFD, INFTIM)) == -1) { | |
1021 | polltim = repo_next_timeout(INFTIM); | |
1022 | ||
1023 | if ((c = poll(pfd, NPFD, polltim)) == -1) { | |
1019 | 1024 | if (errno == EINTR) |
1020 | 1025 | continue; |
1021 | 1026 | err(1, "poll"); |
1022 | 1027 | } |
1023 | 1028 | |
1024 | 1029 | for (i = 0; i < NPFD; i++) { |
1025 | if (pfd[i].revents & (POLLERR|POLLNVAL)) | |
1026 | errx(1, "poll[%zu]: bad fd", i); | |
1027 | if (pfd[i].revents & POLLHUP) { | |
1028 | warnx("poll[%zu]: hangup", i); | |
1030 | if (pfd[i].revents & (POLLERR|POLLNVAL)) { | |
1031 | warnx("poll[%zu]: bad fd", i); | |
1029 | 1032 | hangup = 1; |
1030 | 1033 | } |
1034 | if (pfd[i].revents & POLLHUP) | |
1035 | hangup = 1; | |
1031 | 1036 | if (pfd[i].revents & POLLOUT) { |
1032 | 1037 | switch (msgbuf_write(queues[i])) { |
1033 | 1038 | case 0: |
1034 | errx(1, "write[%zu]: " | |
1039 | warnx("write[%zu]: " | |
1035 | 1040 | "connection closed", i); |
1041 | hangup = 1; | |
1042 | break; | |
1036 | 1043 | case -1: |
1037 | err(1, "write[%zu]", i); | |
1044 | warn("write[%zu]", i); | |
1045 | hangup = 1; | |
1046 | break; | |
1038 | 1047 | } |
1039 | 1048 | } |
1040 | 1049 | } |
1041 | 1050 | if (hangup) |
1042 | 1051 | break; |
1052 | ||
1053 | repo_check_timeout(); | |
1043 | 1054 | |
1044 | 1055 | /* |
1045 | 1056 | * Check the rsync and http process. |
1149 | 1160 | |
1150 | 1161 | /* processing did not finish because of error */ |
1151 | 1162 | if (entity_queue != 0) |
1152 | return 1; | |
1163 | errx(1, "not all files processed, giving up"); | |
1153 | 1164 | |
1154 | 1165 | logx("all files parsed: generating output"); |
1155 | 1166 | |
1172 | 1183 | |
1173 | 1184 | if (outputfiles(&vrps, &brks, &stats)) |
1174 | 1185 | rc = 1; |
1175 | ||
1176 | 1186 | |
1177 | 1187 | logx("Processing time %lld seconds " |
1178 | 1188 | "(%lld seconds user, %lld seconds system)", |
1181 | 1191 | (long long)stats.system_time.tv_sec); |
1182 | 1192 | logx("Route Origin Authorizations: %zu (%zu failed parse, %zu invalid)", |
1183 | 1193 | stats.roas, stats.roas_fail, stats.roas_invalid); |
1184 | logx("BGPsec Router Certificates: %zu (%zu invalid)", | |
1185 | stats.brks, stats.brks_invalids); | |
1186 | logx("Certificates: %zu (%zu failed parse, %zu invalid)", | |
1187 | stats.certs, stats.certs_fail, stats.certs_invalid); | |
1188 | logx("Trust Anchor Locators: %zu", stats.tals); | |
1194 | logx("BGPsec Router Certificates: %zu", stats.brks); | |
1195 | logx("Certificates: %zu (%zu invalid)", | |
1196 | stats.certs, stats.certs_fail); | |
1197 | logx("Trust Anchor Locators: %zu (%zu invalid)", | |
1198 | stats.tals, talsz - stats.tals); | |
1189 | 1199 | logx("Manifests: %zu (%zu failed parse, %zu stale)", |
1190 | 1200 | stats.mfts, stats.mfts_fail, stats.mfts_stale); |
1191 | 1201 | logx("Certificate revocation lists: %zu", stats.crls); |
0 | /* $OpenBSD: output-csv.c,v 1.11 2021/10/11 16:50:03 job Exp $ */ | |
0 | /* $OpenBSD: output-csv.c,v 1.12 2021/11/04 11:32:55 claudio Exp $ */ | |
1 | 1 | /* |
2 | 2 | * Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org> |
3 | 3 | * |
33 | 33 | ip_addr_print(&v->addr, v->afi, buf, sizeof(buf)); |
34 | 34 | |
35 | 35 | if (fprintf(out, "AS%u,%s,%u,%s,%lld\n", v->asid, buf, |
36 | v->maxlength, v->tal, (long long)v->expires) < 0) | |
36 | v->maxlength, taldescs[v->talid], | |
37 | (long long)v->expires) < 0) | |
37 | 38 | return -1; |
38 | 39 | } |
39 | 40 | return 0; |
0 | /* $OpenBSD: output-json.c,v 1.20 2021/10/15 08:48:18 job Exp $ */ | |
0 | /* $OpenBSD: output-json.c,v 1.22 2021/11/04 11:32:55 claudio Exp $ */ | |
1 | 1 | /* |
2 | 2 | * Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org> |
3 | 3 | * |
27 | 27 | char hn[NI_MAXHOST], tbuf[26]; |
28 | 28 | struct tm *tp; |
29 | 29 | time_t t; |
30 | size_t i; | |
30 | 31 | |
31 | 32 | time(&t); |
32 | 33 | setenv("TZ", "UTC", 1); |
46 | 47 | "\t\t\"failedroas\": %zu,\n" |
47 | 48 | "\t\t\"invalidroas\": %zu,\n" |
48 | 49 | "\t\t\"bgpsec_pubkeys\": %zu,\n" |
49 | "\t\t\"invalidbgpsec_pubkeys\": %zu,\n" | |
50 | 50 | "\t\t\"certificates\": %zu,\n" |
51 | "\t\t\"failcertificates\": %zu,\n" | |
52 | 51 | "\t\t\"invalidcertificates\": %zu,\n" |
53 | 52 | "\t\t\"tals\": %zu,\n" |
54 | "\t\t\"talfiles\": \"%s\",\n" | |
53 | "\t\t\"invalidtals\": %zu,\n" | |
54 | "\t\t\"talfiles\": [\n", | |
55 | hn, tbuf, (long long)st->elapsed_time.tv_sec, | |
56 | (long long)st->user_time.tv_sec, (long long)st->system_time.tv_sec, | |
57 | st->roas, st->roas_fail, st->roas_invalid, | |
58 | st->brks, st->certs, st->certs_fail, | |
59 | st->tals, talsz - st->tals) < 0) | |
60 | return -1; | |
61 | ||
62 | for (i = 0; i < talsz; i++) { | |
63 | if (fprintf(out, | |
64 | "\t\t\t\"%s\"%s\n", | |
65 | tals[i], i == talsz - 1 ? "" : ",") < 0) | |
66 | return -1; | |
67 | } | |
68 | ||
69 | if (fprintf(out, | |
70 | "\t\t],\n" | |
55 | 71 | "\t\t\"manifests\": %zu,\n" |
56 | 72 | "\t\t\"failedmanifests\": %zu,\n" |
57 | 73 | "\t\t\"stalemanifests\": %zu,\n" |
63 | 79 | "\t\t\"cachedir_del_files\": %zu,\n" |
64 | 80 | "\t\t\"cachedir_del_dirs\": %zu\n" |
65 | 81 | "\t},\n\n", |
66 | hn, tbuf, (long long)st->elapsed_time.tv_sec, | |
67 | (long long)st->user_time.tv_sec, (long long)st->system_time.tv_sec, | |
68 | st->roas, st->roas_fail, st->roas_invalid, | |
69 | st->brks, st->brks_invalids, | |
70 | st->certs, st->certs_fail, st->certs_invalid, | |
71 | st->tals, st->talnames, | |
72 | 82 | st->mfts, st->mfts_fail, st->mfts_stale, |
73 | 83 | st->crls, |
74 | 84 | st->gbrs, |
105 | 115 | |
106 | 116 | if (fprintf(out, "\t\t{ \"asn\": %u, \"prefix\": \"%s\", " |
107 | 117 | "\"maxLength\": %u, \"ta\": \"%s\", \"expires\": %lld }", |
108 | v->asid, buf, v->maxlength, v->tal, (long long)v->expires) | |
118 | v->asid, buf, v->maxlength, taldescs[v->talid], | |
119 | (long long)v->expires) | |
109 | 120 | < 0) |
110 | 121 | return -1; |
111 | 122 | } |
123 | 134 | |
124 | 135 | if (fprintf(out, "\t\t{ \"asn\": %u, \"ski\": \"%s\", " |
125 | 136 | "\"pubkey\": \"%s\", \"ta\": \"%s\", \"expires\": %lld }", |
126 | b->asid, b->ski, b->pubkey, b->tal, | |
137 | b->asid, b->ski, b->pubkey, taldescs[b->talid], | |
127 | 138 | (long long)b->expires) < 0) |
128 | 139 | return -1; |
129 | 140 | } |
0 | /* $OpenBSD: output.c,v 1.22 2021/10/11 16:50:03 job Exp $ */ | |
0 | /* $OpenBSD: output.c,v 1.24 2021/11/04 11:32:55 claudio Exp $ */ | |
1 | 1 | /* |
2 | 2 | * Copyright (c) 2019 Theo de Raadt <deraadt@openbsd.org> |
3 | 3 | * |
200 | 200 | char hn[NI_MAXHOST], tbuf[80]; |
201 | 201 | struct tm *tp; |
202 | 202 | time_t t; |
203 | size_t i; | |
203 | 204 | |
204 | 205 | time(&t); |
205 | 206 | setenv("TZ", "UTC", 1); |
210 | 211 | |
211 | 212 | if (fprintf(out, |
212 | 213 | "# Generated on host %s at %s\n" |
213 | "# Processing time %lld seconds (%lld seconds user, %lld seconds system)\n" | |
214 | "# Processing time %lld seconds (%llds user, %llds system)\n" | |
214 | 215 | "# Route Origin Authorizations: %zu (%zu failed parse, %zu invalid)\n" |
215 | "# BGPsec Router Certificates: %zu (%zu invalid)\n" | |
216 | "# Certificates: %zu (%zu failed parse, %zu invalid)\n" | |
217 | "# Trust Anchor Locators: %zu (%s)\n" | |
216 | "# BGPsec Router Certificates: %zu\n" | |
217 | "# Certificates: %zu (%zu invalid)\n", | |
218 | hn, tbuf, (long long)st->elapsed_time.tv_sec, | |
219 | (long long)st->user_time.tv_sec, (long long)st->system_time.tv_sec, | |
220 | st->roas, st->roas_fail, st->roas_invalid, | |
221 | st->brks, st->certs, st->certs_fail) < 0) | |
222 | return -1; | |
223 | ||
224 | if (fprintf(out, | |
225 | "# Trust Anchor Locators: %zu (%zu invalid) [", st->tals, | |
226 | talsz - st->tals) < 0) | |
227 | return -1; | |
228 | for (i = 0; i < talsz; i++) | |
229 | if (fprintf(out, " %s", tals[i]) < 0) | |
230 | return -1; | |
231 | ||
232 | if (fprintf(out, | |
233 | " ]\n" | |
218 | 234 | "# Manifests: %zu (%zu failed parse, %zu stale)\n" |
219 | 235 | "# Certificate revocation lists: %zu\n" |
220 | 236 | "# Ghostbuster records: %zu\n" |
221 | 237 | "# Repositories: %zu\n" |
222 | 238 | "# VRP Entries: %zu (%zu unique)\n", |
223 | hn, tbuf, (long long)st->elapsed_time.tv_sec, | |
224 | (long long)st->user_time.tv_sec, (long long)st->system_time.tv_sec, | |
225 | st->roas, st->roas_fail, st->roas_invalid, | |
226 | st->brks, st->brks_invalids, | |
227 | st->certs, st->certs_fail, st->certs_invalid, | |
228 | st->tals, st->talnames, | |
229 | 239 | st->mfts, st->mfts_fail, st->mfts_stale, |
230 | 240 | st->crls, |
231 | 241 | st->gbrs, |
0 | /* $OpenBSD: parser.c,v 1.21 2021/10/28 09:02:19 beck Exp $ */ | |
0 | /* $OpenBSD: parser.c,v 1.28 2021/11/04 18:26:48 claudio Exp $ */ | |
1 | 1 | /* |
2 | 2 | * Copyright (c) 2019 Claudio Jeker <claudio@openbsd.org> |
3 | 3 | * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> |
40 | 40 | static struct crl *get_crl(const struct auth *); |
41 | 41 | static void build_crls(const struct crl *, STACK_OF(X509_CRL) **); |
42 | 42 | |
43 | /* Limit how deep the RPKI tree can be. */ | |
44 | #define MAX_CERT_DEPTH 12 | |
45 | ||
46 | 43 | static X509_STORE_CTX *ctx; |
47 | 44 | static struct auth_tree auths = RB_INITIALIZER(&auths); |
48 | 45 | static struct crl_tree crlt = RB_INITIALIZER(&crlt); |
67 | 64 | return NULL; |
68 | 65 | |
69 | 66 | a = valid_ski_aki(entp->file, &auths, roa->ski, roa->aki); |
70 | ||
71 | 67 | build_chain(a, &chain); |
72 | 68 | crl = get_crl(a); |
73 | 69 | build_crls(crl, &crls); |
98 | 94 | /* |
99 | 95 | * Check CRL to figure out the soonest transitive expiry moment |
100 | 96 | */ |
101 | if (roa->expires > crl->expires) | |
97 | if (crl != NULL && roa->expires > crl->expires) | |
102 | 98 | roa->expires = crl->expires; |
103 | 99 | |
104 | 100 | /* |
105 | 101 | * Scan the cert tree to figure out the soonest transitive |
106 | 102 | * expiry moment |
107 | 103 | */ |
108 | for (; a->parent != NULL; a = a->parent) { | |
104 | for (; a != NULL; a = a->parent) { | |
109 | 105 | if (roa->expires > a->cert->expires) |
110 | 106 | roa->expires = a->cert->expires; |
111 | 107 | } |
194 | 190 | struct cert *cert; |
195 | 191 | X509 *x509; |
196 | 192 | int c; |
197 | struct auth *a = NULL, *na; | |
193 | struct auth *a = NULL; | |
198 | 194 | STACK_OF(X509) *chain; |
199 | 195 | STACK_OF(X509_CRL) *crls; |
200 | 196 | |
235 | 231 | X509_STORE_CTX_cleanup(ctx); |
236 | 232 | sk_X509_free(chain); |
237 | 233 | sk_X509_CRL_free(crls); |
234 | X509_free(x509); | |
235 | ||
236 | cert->talid = a->cert->talid; | |
238 | 237 | |
239 | 238 | /* Validate the cert to get the parent */ |
240 | 239 | if (!valid_cert(entp->file, &auths, cert)) { |
241 | X509_free(x509); // needed? XXX | |
242 | return cert; | |
240 | cert_free(cert); | |
241 | return NULL; | |
243 | 242 | } |
244 | 243 | |
245 | 244 | /* |
246 | * Add validated certs to the RPKI auth tree. | |
245 | * Add validated CA certs to the RPKI auth tree. | |
247 | 246 | */ |
248 | ||
249 | cert->valid = 1; | |
250 | ||
251 | na = malloc(sizeof(*na)); | |
252 | if (na == NULL) | |
253 | err(1, NULL); | |
254 | ||
255 | cert->tal = strdup(a->tal); | |
256 | if (cert->tal == NULL) | |
257 | err(1, NULL); | |
258 | ||
259 | na->parent = a; | |
260 | na->cert = cert; | |
261 | na->tal = a->tal; | |
262 | na->fn = strdup(entp->file); | |
263 | if (na->fn == NULL) | |
264 | err(1, NULL); | |
265 | ||
266 | if (RB_INSERT(auth_tree, &auths, na) != NULL) | |
267 | err(1, "auth tree corrupted"); | |
247 | if (cert->purpose == CERT_PURPOSE_CA) { | |
248 | if (!auth_insert(&auths, cert, a)) { | |
249 | cert_free(cert); | |
250 | return NULL; | |
251 | } | |
252 | } | |
268 | 253 | |
269 | 254 | return cert; |
270 | 255 | } |
271 | ||
272 | 256 | |
273 | 257 | /* |
274 | 258 | * Root certificates come from TALs (has a pkey and is self-signed). |
288 | 272 | X509_NAME *name; |
289 | 273 | struct cert *cert; |
290 | 274 | X509 *x509; |
291 | struct auth *na; | |
292 | char *tal; | |
293 | 275 | |
294 | 276 | assert(entp->has_data); |
295 | 277 | |
334 | 316 | goto badcert; |
335 | 317 | } |
336 | 318 | |
319 | X509_free(x509); | |
320 | ||
321 | cert->talid = entp->talid; | |
322 | ||
337 | 323 | /* |
338 | 324 | * Add valid roots to the RPKI auth tree. |
339 | 325 | */ |
340 | ||
341 | cert->valid = 1; | |
342 | ||
343 | na = malloc(sizeof(*na)); | |
344 | if (na == NULL) | |
345 | err(1, NULL); | |
346 | ||
347 | if ((tal = strdup(entp->descr)) == NULL) | |
348 | err(1, NULL); | |
349 | ||
350 | na->parent = NULL; | |
351 | na->cert = cert; | |
352 | na->tal = tal; | |
353 | na->fn = strdup(entp->file); | |
354 | if (na->fn == NULL) | |
355 | err(1, NULL); | |
356 | ||
357 | if (RB_INSERT(auth_tree, &auths, na) != NULL) | |
358 | err(1, "auth tree corrupted"); | |
326 | if (!auth_insert(&auths, cert, NULL)) { | |
327 | cert_free(cert); | |
328 | return NULL; | |
329 | } | |
359 | 330 | |
360 | 331 | return cert; |
332 | ||
361 | 333 | badcert: |
362 | X509_free(x509); // needed? XXX | |
363 | return cert; | |
334 | X509_free(x509); | |
335 | cert_free(cert); | |
336 | return NULL; | |
364 | 337 | } |
365 | 338 | |
366 | 339 | /* |
546 | 519 | entp->datasz)) == NULL) |
547 | 520 | errx(1, "%s: could not parse tal file", |
548 | 521 | entp->file); |
522 | tal->id = entp->talid; | |
549 | 523 | tal_buffer(b, tal); |
550 | 524 | tal_free(tal); |
551 | 525 | break; |
0 | /* $OpenBSD: repo.c,v 1.9 2021/08/12 15:27:15 claudio Exp $ */ | |
0 | /* $OpenBSD: repo.c,v 1.11 2021/11/09 11:03:39 claudio Exp $ */ | |
1 | 1 | /* |
2 | 2 | * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org> |
3 | 3 | * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> |
26 | 26 | #include <fcntl.h> |
27 | 27 | #include <fts.h> |
28 | 28 | #include <limits.h> |
29 | #include <poll.h> | |
29 | 30 | #include <stdio.h> |
30 | 31 | #include <stdlib.h> |
31 | 32 | #include <string.h> |
87 | 88 | |
88 | 89 | struct repo { |
89 | 90 | SLIST_ENTRY(repo) entry; |
90 | char *repouri; /* CA repository base URI */ | |
91 | char *repouri; | |
92 | char *notifyuri; | |
91 | 93 | const struct rrdprepo *rrdp; |
92 | 94 | const struct rsyncrepo *rsync; |
93 | 95 | const struct tarepo *ta; |
94 | 96 | struct entityq queue; /* files waiting for repo */ |
97 | time_t alarm; /* sync timeout */ | |
98 | int talid; | |
95 | 99 | size_t id; /* identifier */ |
96 | 100 | }; |
97 | 101 | SLIST_HEAD(, repo) repos = SLIST_HEAD_INITIALIZER(repos); |
606 | 610 | * Allocate and insert a new repository. |
607 | 611 | */ |
608 | 612 | static struct repo * |
609 | repo_alloc(void) | |
613 | repo_alloc(int talid) | |
610 | 614 | { |
611 | 615 | struct repo *rp; |
612 | 616 | |
617 | if (++talrepocnt[talid] >= MAX_REPO_PER_TAL) { | |
618 | if (talrepocnt[talid] == MAX_REPO_PER_TAL) | |
619 | warnx("too many repositories under %s", tals[talid]); | |
620 | return NULL; | |
621 | } | |
622 | ||
613 | 623 | if ((rp = calloc(1, sizeof(*rp))) == NULL) |
614 | 624 | err(1, NULL); |
615 | 625 | |
616 | 626 | rp->id = ++repoid; |
627 | rp->talid = talid; | |
628 | rp->alarm = getmonotime() + MAX_REPO_TIMEOUT; | |
617 | 629 | TAILQ_INIT(&rp->queue); |
618 | 630 | SLIST_INSERT_HEAD(&repos, rp, entry); |
619 | 631 | |
930 | 942 | |
931 | 943 | tr = ta_find(id); |
932 | 944 | if (tr != NULL) { |
945 | /* repository changed state already, ignore request */ | |
946 | if (tr->state != REPO_LOADING) | |
947 | return; | |
933 | 948 | if (ok) { |
934 | 949 | logx("ta/%s: loaded from network", tr->descr); |
935 | 950 | stats.rsync_repos++; |
952 | 967 | if (rr == NULL) |
953 | 968 | errx(1, "unknown rsync repo %zu", id); |
954 | 969 | |
970 | /* repository changed state already, ignore request */ | |
971 | if (rr->state != REPO_LOADING) | |
972 | return; | |
955 | 973 | if (ok) { |
956 | 974 | logx("%s: loaded from network", rr->basedir); |
957 | 975 | stats.rsync_repos++; |
980 | 998 | rr = rrdp_find(id); |
981 | 999 | if (rr == NULL) |
982 | 1000 | errx(1, "unknown RRDP repo %zu", id); |
1001 | /* repository changed state already, ignore request */ | |
1002 | if (rr->state != REPO_LOADING) | |
1003 | return; | |
983 | 1004 | |
984 | 1005 | if (ok && rrdp_merge_repo(rr)) { |
985 | 1006 | logx("%s: loaded from network", rr->notifyuri); |
1031 | 1052 | return; |
1032 | 1053 | } |
1033 | 1054 | |
1055 | /* repository changed state already, ignore request */ | |
1056 | if (tr->state != REPO_LOADING) | |
1057 | return; | |
1058 | ||
1034 | 1059 | /* Move downloaded TA file into place, or unlink on failure. */ |
1035 | 1060 | if (res == HTTP_OK) { |
1036 | 1061 | char *file; |
1064 | 1089 | * Look up a trust anchor, queueing it for download if not found. |
1065 | 1090 | */ |
1066 | 1091 | struct repo * |
1067 | ta_lookup(struct tal *tal) | |
1092 | ta_lookup(int id, struct tal *tal) | |
1068 | 1093 | { |
1069 | 1094 | struct repo *rp; |
1070 | 1095 | |
1074 | 1099 | return rp; |
1075 | 1100 | } |
1076 | 1101 | |
1077 | rp = repo_alloc(); | |
1102 | rp = repo_alloc(id); | |
1103 | if (rp == NULL) | |
1104 | return NULL; | |
1105 | ||
1078 | 1106 | if ((rp->repouri = strdup(tal->descr)) == NULL) |
1079 | 1107 | err(1, NULL); |
1080 | 1108 | rp->ta = ta_get(tal); |
1086 | 1114 | * Look up a repository, queueing it for discovery if not found. |
1087 | 1115 | */ |
1088 | 1116 | struct repo * |
1089 | repo_lookup(const char *uri, const char *notify) | |
1090 | { | |
1091 | struct repo *rp; | |
1117 | repo_lookup(int id, const char *uri, const char *notify) | |
1118 | { | |
1119 | struct repo *rp; | |
1120 | char *repouri; | |
1121 | ||
1122 | if ((repouri = rsync_base_uri(uri)) == NULL) | |
1123 | errx(1, "bad caRepository URI: %s", uri); | |
1092 | 1124 | |
1093 | 1125 | /* Look up in repository table. */ |
1094 | 1126 | SLIST_FOREACH(rp, &repos, entry) { |
1095 | if (strcmp(rp->repouri, uri) != 0) | |
1127 | if (strcmp(rp->repouri, repouri) != 0) | |
1096 | 1128 | continue; |
1129 | if (rp->notifyuri != NULL) { | |
1130 | if (notify == NULL) | |
1131 | continue; | |
1132 | if (strcmp(rp->notifyuri, notify) != 0) | |
1133 | continue; | |
1134 | } else if (notify != NULL) | |
1135 | continue; | |
1136 | /* found matching repo */ | |
1137 | free(repouri); | |
1097 | 1138 | return rp; |
1098 | 1139 | } |
1099 | 1140 | |
1100 | rp = repo_alloc(); | |
1101 | if ((rp->repouri = strdup(uri)) == NULL) | |
1102 | err(1, NULL); | |
1141 | rp = repo_alloc(id); | |
1142 | if (rp == NULL) { | |
1143 | free(repouri); | |
1144 | return NULL; | |
1145 | } | |
1146 | ||
1147 | rp->repouri = repouri; | |
1148 | if (notify != NULL) | |
1149 | if ((rp->notifyuri = strdup(notify)) == NULL) | |
1150 | err(1, NULL); | |
1103 | 1151 | |
1104 | 1152 | /* try RRDP first if available */ |
1105 | 1153 | if (notify != NULL) |
1150 | 1198 | return 1; |
1151 | 1199 | } |
1152 | 1200 | return 0; |
1201 | } | |
1202 | ||
1203 | int | |
1204 | repo_next_timeout(int timeout) | |
1205 | { | |
1206 | struct repo *rp; | |
1207 | time_t now; | |
1208 | ||
1209 | now = getmonotime(); | |
1210 | /* Look up in repository table. (Lookup should actually fail here) */ | |
1211 | SLIST_FOREACH(rp, &repos, entry) { | |
1212 | if (repo_state(rp) == REPO_LOADING) { | |
1213 | int diff = rp->alarm - now; | |
1214 | diff *= 1000; | |
1215 | if (timeout == INFTIM || diff < timeout) | |
1216 | timeout = diff; | |
1217 | } | |
1218 | } | |
1219 | return timeout; | |
1220 | } | |
1221 | ||
1222 | static void | |
1223 | repo_fail(struct repo *rp) | |
1224 | { | |
1225 | /* reset the alarm since code may fallback to rsync */ | |
1226 | rp->alarm = getmonotime() + MAX_REPO_TIMEOUT; | |
1227 | ||
1228 | if (rp->ta) | |
1229 | http_finish(rp->ta->id, HTTP_FAILED, NULL); | |
1230 | else if (rp->rrdp) | |
1231 | rrdp_finish(rp->rrdp->id, 0); | |
1232 | else if (rp->rsync) | |
1233 | rsync_finish(rp->rsync->id, 0); | |
1234 | else | |
1235 | errx(1, "%s: bad repo", rp->repouri); | |
1236 | } | |
1237 | ||
1238 | void | |
1239 | repo_check_timeout(void) | |
1240 | { | |
1241 | struct repo *rp; | |
1242 | time_t now; | |
1243 | ||
1244 | now = getmonotime(); | |
1245 | /* Look up in repository table. (Lookup should actually fail here) */ | |
1246 | SLIST_FOREACH(rp, &repos, entry) { | |
1247 | if (repo_state(rp) == REPO_LOADING) { | |
1248 | if (rp->alarm <= now) { | |
1249 | warnx("%s: synchronisation timeout", | |
1250 | rp->repouri); | |
1251 | repo_fail(rp); | |
1252 | } | |
1253 | } | |
1254 | } | |
1153 | 1255 | } |
1154 | 1256 | |
1155 | 1257 | static char ** |
0 | /* $OpenBSD: roa.c,v 1.30 2021/10/28 09:02:19 beck Exp $ */ | |
0 | /* $OpenBSD: roa.c,v 1.32 2021/11/05 10:50:41 claudio Exp $ */ | |
1 | 1 | /* |
2 | 2 | * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> |
3 | 3 | * |
408 | 408 | free(p->aki); |
409 | 409 | free(p->ski); |
410 | 410 | free(p->ips); |
411 | free(p->tal); | |
412 | 411 | free(p); |
413 | 412 | } |
414 | 413 | |
419 | 418 | void |
420 | 419 | roa_buffer(struct ibuf *b, const struct roa *p) |
421 | 420 | { |
422 | size_t i; | |
423 | ||
424 | io_simple_buffer(b, &p->valid, sizeof(int)); | |
425 | io_simple_buffer(b, &p->asid, sizeof(uint32_t)); | |
426 | io_simple_buffer(b, &p->ipsz, sizeof(size_t)); | |
427 | io_simple_buffer(b, &p->expires, sizeof(time_t)); | |
428 | ||
429 | for (i = 0; i < p->ipsz; i++) { | |
430 | io_simple_buffer(b, &p->ips[i].afi, sizeof(enum afi)); | |
431 | io_simple_buffer(b, &p->ips[i].maxlength, sizeof(size_t)); | |
432 | io_simple_buffer(b, p->ips[i].min, sizeof(p->ips[i].min)); | |
433 | io_simple_buffer(b, p->ips[i].max, sizeof(p->ips[i].max)); | |
434 | ip_addr_buffer(b, &p->ips[i].addr); | |
435 | } | |
421 | io_simple_buffer(b, &p->valid, sizeof(p->valid)); | |
422 | io_simple_buffer(b, &p->asid, sizeof(p->asid)); | |
423 | io_simple_buffer(b, &p->talid, sizeof(p->talid)); | |
424 | io_simple_buffer(b, &p->ipsz, sizeof(p->ipsz)); | |
425 | io_simple_buffer(b, &p->expires, sizeof(p->expires)); | |
426 | ||
427 | io_simple_buffer(b, p->ips, p->ipsz * sizeof(p->ips[0])); | |
436 | 428 | |
437 | 429 | io_str_buffer(b, p->aia); |
438 | 430 | io_str_buffer(b, p->aki); |
439 | 431 | io_str_buffer(b, p->ski); |
440 | io_str_buffer(b, p->tal); | |
441 | 432 | } |
442 | 433 | |
443 | 434 | /* |
449 | 440 | roa_read(struct ibuf *b) |
450 | 441 | { |
451 | 442 | struct roa *p; |
452 | size_t i; | |
453 | 443 | |
454 | 444 | if ((p = calloc(1, sizeof(struct roa))) == NULL) |
455 | 445 | err(1, NULL); |
456 | 446 | |
457 | io_read_buf(b, &p->valid, sizeof(int)); | |
458 | io_read_buf(b, &p->asid, sizeof(uint32_t)); | |
459 | io_read_buf(b, &p->ipsz, sizeof(size_t)); | |
460 | io_read_buf(b, &p->expires, sizeof(time_t)); | |
447 | io_read_buf(b, &p->valid, sizeof(p->valid)); | |
448 | io_read_buf(b, &p->asid, sizeof(p->asid)); | |
449 | io_read_buf(b, &p->talid, sizeof(p->talid)); | |
450 | io_read_buf(b, &p->ipsz, sizeof(p->ipsz)); | |
451 | io_read_buf(b, &p->expires, sizeof(p->expires)); | |
461 | 452 | |
462 | 453 | if ((p->ips = calloc(p->ipsz, sizeof(struct roa_ip))) == NULL) |
463 | 454 | err(1, NULL); |
464 | ||
465 | for (i = 0; i < p->ipsz; i++) { | |
466 | io_read_buf(b, &p->ips[i].afi, sizeof(enum afi)); | |
467 | io_read_buf(b, &p->ips[i].maxlength, sizeof(size_t)); | |
468 | io_read_buf(b, &p->ips[i].min, sizeof(p->ips[i].min)); | |
469 | io_read_buf(b, &p->ips[i].max, sizeof(p->ips[i].max)); | |
470 | ip_addr_read(b, &p->ips[i].addr); | |
471 | } | |
455 | io_read_buf(b, p->ips, p->ipsz * sizeof(p->ips[0])); | |
472 | 456 | |
473 | 457 | io_read_str(b, &p->aia); |
474 | 458 | io_read_str(b, &p->aki); |
475 | 459 | io_read_str(b, &p->ski); |
476 | io_read_str(b, &p->tal); | |
477 | assert(p->aia && p->aki && p->ski && p->tal); | |
460 | assert(p->aia && p->aki && p->ski); | |
478 | 461 | |
479 | 462 | return p; |
480 | 463 | } |
498 | 481 | v->addr = roa->ips[i].addr; |
499 | 482 | v->maxlength = roa->ips[i].maxlength; |
500 | 483 | v->asid = roa->asid; |
501 | if ((v->tal = strdup(roa->tal)) == NULL) | |
502 | err(1, NULL); | |
484 | v->talid = roa->talid; | |
503 | 485 | v->expires = roa->expires; |
504 | 486 | |
505 | 487 | /* |
511 | 493 | /* already exists */ |
512 | 494 | if (found->expires < v->expires) { |
513 | 495 | /* update found with preferred data */ |
514 | found->expires = roa->expires; | |
515 | free(found->tal); | |
516 | found->tal = v->tal; | |
517 | v->tal = NULL; | |
496 | found->talid = v->talid; | |
497 | found->expires = v->expires; | |
518 | 498 | } |
519 | free(v->tal); | |
520 | 499 | free(v); |
521 | 500 | } else |
522 | 501 | (*uniqs)++; |
0 | /* $OpenBSD: rrdp_delta.c,v 1.4 2021/10/28 11:57:00 claudio Exp $ */ | |
0 | /* $OpenBSD: rrdp_delta.c,v 1.6 2021/11/09 11:01:04 claudio Exp $ */ | |
1 | 1 | /* |
2 | 2 | * Copyright (c) 2020 Nils Fisher <nils_fisher@hotmail.com> |
3 | 3 | * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org> |
86 | 86 | continue; |
87 | 87 | } |
88 | 88 | PARSE_FAIL(p, "parse failed - non conforming " |
89 | "attribute found in delta elem"); | |
89 | "attribute '%s' found in delta elem", attr[i]); | |
90 | 90 | } |
91 | 91 | if (!(has_xmlns && dxml->version && dxml->session_id && dxml->serial)) |
92 | 92 | PARSE_FAIL(p, "parse failed - incomplete delta attributes"); |
135 | 135 | continue; |
136 | 136 | } |
137 | 137 | PARSE_FAIL(p, "parse failed - non conforming " |
138 | "attribute found in publish/withdraw elem"); | |
138 | "attribute '%s' found in publish/withdraw elem", attr[i]); | |
139 | 139 | } |
140 | 140 | if (hasUri != 1) |
141 | 141 | PARSE_FAIL(p, |
224 | 224 | PARSE_FAIL(p, "parse failed - content too big"); |
225 | 225 | } |
226 | 226 | |
227 | static void | |
228 | delta_doctype_handler(void *data, const char *doctypeName, | |
229 | const char *sysid, const char *pubid, int subset) | |
230 | { | |
231 | struct delta_xml *dxml = data; | |
232 | XML_Parser p = dxml->parser; | |
233 | ||
234 | PARSE_FAIL(p, "parse failed - DOCTYPE not allowed"); | |
235 | } | |
236 | ||
227 | 237 | struct delta_xml * |
228 | 238 | new_delta_xml(XML_Parser p, struct rrdp_session *rs, struct rrdp *r) |
229 | 239 | { |
242 | 252 | delta_xml_elem_end); |
243 | 253 | XML_SetCharacterDataHandler(dxml->parser, delta_content_handler); |
244 | 254 | XML_SetUserData(dxml->parser, dxml); |
255 | XML_SetDoctypeDeclHandler(dxml->parser, delta_doctype_handler, NULL); | |
245 | 256 | |
246 | 257 | return dxml; |
247 | 258 | } |
0 | /* $OpenBSD: rrdp_notification.c,v 1.9 2021/10/29 09:27:36 claudio Exp $ */ | |
0 | /* $OpenBSD: rrdp_notification.c,v 1.11 2021/11/09 11:01:04 claudio Exp $ */ | |
1 | 1 | /* |
2 | 2 | * Copyright (c) 2020 Nils Fisher <nils_fisher@hotmail.com> |
3 | 3 | * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org> |
140 | 140 | continue; |
141 | 141 | } |
142 | 142 | PARSE_FAIL(p, "parse failed - non conforming " |
143 | "attribute found in notification elem"); | |
143 | "attribute '%s' found in notification elem", attr[i]); | |
144 | 144 | } |
145 | 145 | if (!(has_xmlns && nxml->version && nxml->session_id && nxml->serial)) |
146 | 146 | PARSE_FAIL(p, "parse failed - incomplete " |
184 | 184 | continue; |
185 | 185 | } |
186 | 186 | PARSE_FAIL(p, "parse failed - non conforming " |
187 | "attribute found in snapshot elem"); | |
187 | "attribute '%s' found in snapshot elem", attr[i]); | |
188 | 188 | } |
189 | 189 | if (hasUri != 1 || hasHash != 1) |
190 | 190 | PARSE_FAIL(p, "parse failed - incomplete snapshot attributes"); |
238 | 238 | continue; |
239 | 239 | } |
240 | 240 | PARSE_FAIL(p, "parse failed - non conforming " |
241 | "attribute found in snapshot elem"); | |
241 | "attribute '%s' found in snapshot elem", attr[i]); | |
242 | 242 | } |
243 | 243 | /* Only add to the list if we are relevant */ |
244 | 244 | if (hasUri != 1 || hasHash != 1 || delta_serial == 0) |
307 | 307 | PARSE_FAIL(p, "parse failed - unexpected elem exit found"); |
308 | 308 | } |
309 | 309 | |
310 | static void | |
311 | notification_doctype_handler(void *data, const char *doctypeName, | |
312 | const char *sysid, const char *pubid, int subset) | |
313 | { | |
314 | struct notification_xml *nxml = data; | |
315 | XML_Parser p = nxml->parser; | |
316 | ||
317 | PARSE_FAIL(p, "parse failed - DOCTYPE not allowed"); | |
318 | } | |
319 | ||
310 | 320 | struct notification_xml * |
311 | 321 | new_notification_xml(XML_Parser p, struct rrdp_session *repository, |
312 | 322 | struct rrdp_session *current, const char *notifyuri) |
324 | 334 | XML_SetElementHandler(nxml->parser, notification_xml_elem_start, |
325 | 335 | notification_xml_elem_end); |
326 | 336 | XML_SetUserData(nxml->parser, nxml); |
337 | XML_SetDoctypeDeclHandler(nxml->parser, notification_doctype_handler, | |
338 | NULL); | |
327 | 339 | |
328 | 340 | return nxml; |
329 | 341 | } |
0 | /* $OpenBSD: rrdp_snapshot.c,v 1.3 2021/10/28 11:57:00 claudio Exp $ */ | |
0 | /* $OpenBSD: rrdp_snapshot.c,v 1.5 2021/11/09 11:01:04 claudio Exp $ */ | |
1 | 1 | /* |
2 | 2 | * Copyright (c) 2020 Nils Fisher <nils_fisher@hotmail.com> |
3 | 3 | * Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org> |
79 | 79 | } |
80 | 80 | PARSE_FAIL(p, |
81 | 81 | "parse failed - non conforming " |
82 | "attribute found in snapshot elem"); | |
82 | "attribute '%s' found in snapshot elem", attr[i]); | |
83 | 83 | } |
84 | 84 | if (!(has_xmlns && sxml->version && sxml->session_id && sxml->serial)) |
85 | 85 | PARSE_FAIL(p, |
200 | 200 | PARSE_FAIL(p, "parse failed - content too big"); |
201 | 201 | } |
202 | 202 | |
203 | static void | |
204 | snapshot_doctype_handler(void *data, const char *doctypeName, | |
205 | const char *sysid, const char *pubid, int subset) | |
206 | { | |
207 | struct snapshot_xml *sxml = data; | |
208 | XML_Parser p = sxml->parser; | |
209 | ||
210 | PARSE_FAIL(p, "parse failed - DOCTYPE not allowed"); | |
211 | } | |
212 | ||
203 | 213 | struct snapshot_xml * |
204 | 214 | new_snapshot_xml(XML_Parser p, struct rrdp_session *rs, struct rrdp *r) |
205 | 215 | { |
218 | 228 | snapshot_xml_elem_end); |
219 | 229 | XML_SetCharacterDataHandler(sxml->parser, snapshot_content_handler); |
220 | 230 | XML_SetUserData(sxml->parser, sxml); |
231 | XML_SetDoctypeDeclHandler(sxml->parser, snapshot_doctype_handler, | |
232 | NULL); | |
221 | 233 | |
222 | 234 | return sxml; |
223 | 235 | } |
0 | /* $OpenBSD: rsync.c,v 1.29 2021/10/28 13:50:29 job Exp $ */ | |
0 | /* $OpenBSD: rsync.c,v 1.30 2021/11/03 14:59:37 claudio Exp $ */ | |
1 | 1 | /* |
2 | 2 | * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> |
3 | 3 | * |
118 | 118 | void |
119 | 119 | proc_rsync(char *prog, char *bind_addr, int fd) |
120 | 120 | { |
121 | size_t i, idsz = 0; | |
121 | size_t i, idsz = 0, nprocs = 0; | |
122 | 122 | int rc = 0; |
123 | 123 | struct pollfd pfd; |
124 | 124 | struct msgbuf msgq; |
185 | 185 | pid_t pid; |
186 | 186 | int st; |
187 | 187 | |
188 | pfd.events = POLLIN; | |
188 | pfd.events = 0; | |
189 | if (nprocs < MAX_RSYNC_PROCESSES) | |
190 | pfd.events |= POLLIN; | |
189 | 191 | if (msgq.queued) |
190 | 192 | pfd.events |= POLLOUT; |
191 | 193 | |
227 | 229 | ids[i].uri = NULL; |
228 | 230 | ids[i].pid = 0; |
229 | 231 | ids[i].id = 0; |
232 | nprocs--; | |
230 | 233 | } |
231 | 234 | if (pid == -1 && errno != ECHILD) |
232 | 235 | err(1, "waitpid"); |
313 | 316 | ids[i].id = id; |
314 | 317 | ids[i].pid = pid; |
315 | 318 | ids[i].uri = uri; |
319 | nprocs++; | |
316 | 320 | |
317 | 321 | /* Clean up temporary values. */ |
318 | 322 |
0 | /* $OpenBSD: tal.c,v 1.32 2021/10/26 16:12:54 claudio Exp $ */ | |
0 | /* $OpenBSD: tal.c,v 1.34 2021/11/04 11:32:55 claudio Exp $ */ | |
1 | 1 | /* |
2 | 2 | * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> |
3 | 3 | * |
57 | 57 | while ((nl = memchr(buf, '\n', len)) != NULL) { |
58 | 58 | line = buf; |
59 | 59 | |
60 | /* replace LF and optional CR with NUL */ | |
61 | *nl = '\0'; | |
62 | if (nl > line && nl[-1] == '\r') | |
63 | nl[-1] = '\0'; | |
64 | ||
65 | 60 | /* advance buffer to next line */ |
66 | 61 | len -= nl + 1 - buf; |
67 | 62 | buf = nl + 1; |
63 | ||
64 | /* replace LF and optional CR with NUL, point nl at first NUL */ | |
65 | *nl = '\0'; | |
66 | if (nl > line && nl[-1] == '\r') { | |
67 | nl[-1] = '\0'; | |
68 | nl--; | |
69 | } | |
68 | 70 | |
69 | 71 | if (optcomment) { |
70 | 72 | /* if this is a comment, just eat the line */ |
212 | 214 | { |
213 | 215 | size_t i; |
214 | 216 | |
217 | io_simple_buffer(b, &p->id, sizeof(p->id)); | |
215 | 218 | io_buf_buffer(b, p->pkey, p->pkeysz); |
216 | 219 | io_str_buffer(b, p->descr); |
217 | io_simple_buffer(b, &p->urisz, sizeof(size_t)); | |
220 | io_simple_buffer(b, &p->urisz, sizeof(p->urisz)); | |
218 | 221 | |
219 | 222 | for (i = 0; i < p->urisz; i++) |
220 | 223 | io_str_buffer(b, p->uri[i]); |
234 | 237 | if ((p = calloc(1, sizeof(struct tal))) == NULL) |
235 | 238 | err(1, NULL); |
236 | 239 | |
240 | io_read_buf(b, &p->id, sizeof(p->id)); | |
237 | 241 | io_read_buf_alloc(b, (void **)&p->pkey, &p->pkeysz); |
238 | 242 | io_read_str(b, &p->descr); |
239 | io_read_buf(b, &p->urisz, sizeof(size_t)); | |
243 | io_read_buf(b, &p->urisz, sizeof(p->urisz)); | |
240 | 244 | assert(p->pkeysz > 0); |
241 | 245 | assert(p->descr); |
242 | 246 | assert(p->urisz > 0); |
0 | /* $OpenBSD: validate.c,v 1.20 2021/10/29 09:27:36 claudio Exp $ */ | |
0 | /* $OpenBSD: validate.c,v 1.22 2021/11/04 11:32:55 claudio Exp $ */ | |
1 | 1 | /* |
2 | 2 | * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv> |
3 | 3 | * |
28 | 28 | #include <unistd.h> |
29 | 29 | |
30 | 30 | #include "extern.h" |
31 | ||
32 | static void | |
33 | tracewarn(const struct auth *a) | |
34 | { | |
35 | ||
36 | for (; a != NULL; a = a->parent) | |
37 | warnx(" ...inheriting from: %s", a->fn); | |
38 | } | |
39 | 31 | |
40 | 32 | /* |
41 | 33 | * Walk up the chain of certificates trying to match our AS number to |
175 | 167 | continue; |
176 | 168 | warnx("%s: RFC 6487: uncovered AS: " |
177 | 169 | "%u--%u", fn, min, max); |
178 | tracewarn(a); | |
179 | 170 | return 0; |
180 | 171 | } |
181 | 172 | |
203 | 194 | "(inherit)", fn); |
204 | 195 | break; |
205 | 196 | } |
206 | tracewarn(a); | |
207 | 197 | return 0; |
208 | 198 | } |
209 | 199 | |
226 | 216 | if (a == NULL) |
227 | 217 | return 0; |
228 | 218 | |
229 | if ((roa->tal = strdup(a->tal)) == NULL) | |
230 | err(1, NULL); | |
219 | roa->talid = a->cert->talid; | |
231 | 220 | |
232 | 221 | for (i = 0; i < roa->ipsz; i++) { |
233 | 222 | if (valid_ip(a, roa->ips[i].afi, roa->ips[i].min, |
237 | 226 | roa->ips[i].afi, buf, sizeof(buf)); |
238 | 227 | warnx("%s: RFC 6482: uncovered IP: " |
239 | 228 | "%s", fn, buf); |
240 | tracewarn(a); | |
241 | 229 | return 0; |
242 | 230 | } |
243 | 231 |