-/* $OpenBSD: extern.h,v 1.142 2022/06/10 10:36:43 tb Exp $ */
+/* $OpenBSD: extern.h,v 1.143 2022/06/27 10:18:27 job Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
*
#include <openssl/x509.h>
#include <openssl/x509v3.h>
+/*
+ * Distrusted hosts (loaded from skipfile).
+ */
+struct skiplistentry {
+ LIST_ENTRY(skiplistentry) entry;
+ char *value; /* FQDN */
+};
+LIST_HEAD(skiplist, skiplistentry);
+
/*
* Enumeration for ASN.1 explicit tags in RSC eContent
*/
size_t extra_files; /* number of superfluous files */
size_t del_dirs; /* number of directories removed in cleanup */
size_t brks; /* number of BGPsec Router Key (BRK) certificates */
+ size_t skiplistentries; /* number of skiplist entries */
struct timeval elapsed_time;
struct timeval user_time;
struct timeval system_time;
#define RPKI_PATH_OUT_DIR "/var/db/rpki-client"
#define RPKI_PATH_BASE_DIR "/var/cache/rpki-client"
+#define DEFAULT_SKIPLIST_FILE "/etc/rpki/skiplist"
+
/* Maximum number of TAL files we'll load. */
#define TALSZ_MAX 8
-/* $OpenBSD: main.c,v 1.207 2022/06/25 20:25:43 tb Exp $ */
+/* $OpenBSD: main.c,v 1.208 2022/06/27 10:18:27 job Exp $ */
/*
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
#include <sys/wait.h>
#include <assert.h>
+#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <dirent.h>
int rrdpon = 1;
int repo_timeout;
+struct skiplist skiplist = LIST_HEAD_INITIALIZER(skiplist);
+
struct stats stats;
/*
static void
queue_add_from_cert(const struct cert *cert)
{
- struct repo *repo;
- char *nfile, *npath;
- const char *uri, *repouri, *file;
- size_t repourisz;
+ struct repo *repo;
+ struct skiplistentry *sle;
+ char *nfile, *npath, *host;
+ const char *uri, *repouri, *file;
+ size_t repourisz;
+
+ LIST_FOREACH(sle, &skiplist, entry) {
+ if (strncmp(cert->repo, "rsync://", 8) != 0)
+ errx(1, "unexpected protocol");
+ host = cert->repo + 8;
+
+ if (strncasecmp(host, sle->value, strcspn(host, "/")) == 0) {
+ warnx("skipping %s (listed in skiplist)", cert->repo);
+ return;
+ }
+ }
repo = repo_lookup(cert->talid, cert->repo,
rrdpon ? cert->notify : NULL);
return s;
}
+/*
+ * Load the list of FQDNs from the skiplist which are to be distrusted.
+ * Return 0 on success.
+ */
+static void
+load_skiplist(const char *slf)
+{
+ struct skiplistentry *sle;
+ FILE *fp;
+ char *line = NULL;
+ size_t linesize = 0, s;
+ ssize_t linelen;
+
+ if ((fp = fopen(slf, "r")) == NULL) {
+ if (strcmp(slf, DEFAULT_SKIPLIST_FILE) != 0)
+ errx(1, "failed to open skiplist %s", slf);
+ return;
+ }
+
+ while ((linelen = getline(&line, &linesize, fp)) != -1) {
+ /* just eat comment lines or empty lines*/
+ if (line[0] == '#' || line[0] == '\n')
+ continue;
+
+ if (line[0] == ' ' || line[0] == '\t')
+ errx(1, "invalid entry in skiplist: %s", line);
+
+ /*
+ * Ignore anything after comment sign, whitespaces,
+ * also chop off LF or CR.
+ */
+ line[strcspn(line, " #\r\n\t")] = 0;
+
+ for (s = 0; s < strlen(line); s++)
+ if (!isalnum((unsigned char)line[s]) &&
+ !ispunct((unsigned char)line[s]))
+ errx(1, "invalid entry in skiplist: %s", line);
+
+ if ((sle = malloc(sizeof(struct skiplistentry))) == NULL)
+ err(1, NULL);
+ if ((sle->value = strdup(line)) == NULL)
+ err(1, NULL);
+
+ LIST_INSERT_HEAD(&skiplist, sle, entry);
+ stats.skiplistentries++;
+ }
+
+ fclose(fp);
+ free(line);
+}
+
static void
check_fs_size(int fd, const char *cachedir)
{
char *bind_addr = NULL;
const char *cachedir = NULL, *outputdir = NULL;
const char *errs, *name;
+ const char *skiplistfile = NULL;
struct vrp_tree vrps = RB_INITIALIZER(&vrps);
struct brk_tree brks = RB_INITIALIZER(&brks);
struct rusage ru;
cachedir = RPKI_PATH_BASE_DIR;
outputdir = RPKI_PATH_OUT_DIR;
repo_timeout = timeout / 4;
+ skiplistfile = DEFAULT_SKIPLIST_FILE;
if (pledge("stdio rpath wpath cpath inet fattr dns sendfd recvfd "
"proc exec unveil", NULL) == -1)
err(1, "pledge");
- while ((c = getopt(argc, argv, "b:Bcd:e:fjnorRs:t:T:vV")) != -1)
+ while ((c = getopt(argc, argv, "b:Bcd:e:fjnorRs:S:t:T:vV")) != -1)
switch (c) {
case 'b':
bind_addr = optarg;
else
repo_timeout = timeout / 4;
break;
+ case 'S':
+ skiplistfile = optarg;
+ break;
case 't':
if (talsz >= TALSZ_MAX)
err(1, "too many tal files specified");
pfd[3].fd = rrdp;
queues[3] = &rrdpq;
+ load_skiplist(skiplistfile);
+
/*
* Prime the process with our TAL files.
* These will (hopefully) contain links to manifests and we
(long long)stats.elapsed_time.tv_sec,
(long long)stats.user_time.tv_sec,
(long long)stats.system_time.tv_sec);
+ printf("Skiplist entries: %zu\n", stats.skiplistentries);
printf("Route Origin Authorizations: %zu (%zu failed parse, %zu invalid)\n",
stats.roas, stats.roas_fail, stats.roas_invalid);
printf("BGPsec Router Certificates: %zu\n", stats.brks);
fprintf(stderr,
"usage: rpki-client [-BcjnoRrVv] [-b sourceaddr] [-d cachedir]"
" [-e rsync_prog]\n"
- " [-s timeout] [-T table] [-t tal]"
+ " [-S skiplist] [-s timeout] [-T table] [-t tal]"
" [outputdir]\n"
" rpki-client [-Vv] [-d cachedir] [-t tal] -f file ...\n");
return 1;
-.\" $OpenBSD: rpki-client.8,v 1.65 2022/05/31 18:42:26 tb Exp $
+.\" $OpenBSD: rpki-client.8,v 1.66 2022/06/27 10:18:27 job Exp $
.\"
.\" Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
.\"
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: May 31 2022 $
+.Dd $Mdocdate: June 27 2022 $
.Dt RPKI-CLIENT 8
.Os
.Sh NAME
.Op Fl b Ar sourceaddr
.Op Fl d Ar cachedir
.Op Fl e Ar rsync_prog
+.Op Fl S Ar skiplist
.Op Fl s Ar timeout
.Op Fl T Ar table
.Op Fl t Ar tal
This is the default.
Mutually exclusive with
.Fl n .
+.It Fl S Ar skiplist
+Do not connect to any hosts listed in the
+.Ar skiplist
+file.
+Entries in the
+.Ar skiplist
+are newline separated
+.Em Fully Qualified Domain Names Pq FQDNs .
+A
+.Ql #
+indicates the beginning of a comment; characters up to the end of the line are
+not interpreted.
+The skip filter is enforced during processing of the
+.Em Subject Information Access Pq SIA
+extension in CA certificates, thus applies to both RSYNC and RRDP connections.
+By default load entries from
+.Pa /etc/rpki/skiplist .
.It Fl s Ar timeout
Terminate after
.Ar timeout
default TAL files used unless
.Fl t Ar tal
is specified.
+.It Pa /etc/rpki/skiplist
+default skiplist file, unless
+.Fl S Ar skiplist
+is specified.
.It Pa /var/cache/rpki-client
cached repository data.
.It Pa /var/db/rpki-client/openbgpd