Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sbin/cgdconfig cgdconfig(8): Gracefully handle failed verifi...
details: https://anonhg.NetBSD.org/src/rev/e61bebe348f0
branches: trunk
changeset: 369742:e61bebe348f0
user: riastradh <riastradh%NetBSD.org@localhost>
date: Tue Aug 30 08:48:41 2022 +0000
description:
cgdconfig(8): Gracefully handle failed verification with shared keys.
The first time each key is verified, if verification fails, we chuck
the failed key and try again with passphrase re-entry.
But if a key has already been verified, and verification fails,
assume something is wrong with the disk and fail.
diffstat:
sbin/cgdconfig/cgdconfig.c | 58 ++++++++++++++++++++++++++++++++++++++-------
1 files changed, 48 insertions(+), 10 deletions(-)
diffs (166 lines):
diff -r 6919afffb2cb -r e61bebe348f0 sbin/cgdconfig/cgdconfig.c
--- a/sbin/cgdconfig/cgdconfig.c Tue Aug 30 08:48:24 2022 +0000
+++ b/sbin/cgdconfig/cgdconfig.c Tue Aug 30 08:48:41 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cgdconfig.c,v 1.58 2022/08/12 10:49:47 riastradh Exp $ */
+/* $NetBSD: cgdconfig.c,v 1.59 2022/08/30 08:48:41 riastradh Exp $ */
/*-
* Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
@@ -33,7 +33,7 @@
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 2002, 2003\
The NetBSD Foundation, Inc. All rights reserved.");
-__RCSID("$NetBSD: cgdconfig.c,v 1.58 2022/08/12 10:49:47 riastradh Exp $");
+__RCSID("$NetBSD: cgdconfig.c,v 1.59 2022/08/30 08:48:41 riastradh Exp $");
#endif
#ifdef HAVE_ARGON2
@@ -114,7 +114,9 @@
/*
* When configuring all cgds, save a cache of shared keys for key
- * derivation.
+ * derivation. If the _first_ verification with a shared key fails, we
+ * chuck it and start over; if _subsequent_ verifications fail, we
+ * assume the disk is wrong and give up on it immediately.
*/
struct sharedkey {
@@ -122,8 +124,11 @@
string_t *id;
bits_t *key;
LIST_ENTRY(sharedkey) list;
+ SLIST_ENTRY(sharedkey) used;
+ int verified;
};
LIST_HEAD(, sharedkey) sharedkeys;
+SLIST_HEAD(sharedkeyhits, sharedkey);
static int configure(int, char **, struct params *, int);
static int configure_stdin(struct params *, int argc, char **);
@@ -146,7 +151,8 @@
static int configure_params(int, const char *, const char *,
struct params *);
static void eliminate_cores(void);
-static bits_t *getkey(const char *, struct keygen *, size_t);
+static bits_t *getkey(const char *, struct keygen *, size_t,
+ struct sharedkeyhits *);
static bits_t *getkey_storedkey(const char *, struct keygen *, size_t);
static bits_t *getkey_randomkey(const char *, struct keygen *, size_t, int);
#ifdef HAVE_ARGON2
@@ -429,7 +435,8 @@
}
static bits_t *
-getkey(const char *dev, struct keygen *kg, size_t len0)
+getkey(const char *dev, struct keygen *kg, size_t len0,
+ struct sharedkeyhits *skh)
{
bits_t *ret = NULL;
bits_t *tmp;
@@ -502,9 +509,11 @@
sk->id = string_dup(kg->kg_sharedid);
sk->key = tmp;
LIST_INSERT_HEAD(&sharedkeys, sk, list);
+ sk->verified = 0;
}
derive: if (kg->kg_sharedid) {
+ assert(sk != NULL);
/*
* tmp holds the master key, owned by the
* struct sharedkey record; replace it by the
@@ -517,6 +526,8 @@
bits_free(ret);
return NULL;
}
+ if (skh)
+ SLIST_INSERT_HEAD(skh, sk, used);
}
if (ret)
ret = bits_xor_d(tmp, ret);
@@ -811,6 +822,12 @@
}
for (;;) {
+ struct sharedkeyhits skh;
+ struct sharedkey *sk, *sk1;
+ int all_verified;
+
+ SLIST_INIT(&skh);
+
fd = opendisk_werror(argv[0], cgdname, sizeof(cgdname));
if (fd == -1)
return -1;
@@ -818,7 +835,7 @@
if (p->key)
bits_free(p->key);
- p->key = getkey(argv[1], p->keygen, p->keylen);
+ p->key = getkey(argv[1], p->keygen, p->keylen, &skh);
if (!p->key)
goto bail_err;
@@ -831,12 +848,33 @@
(void)unconfigure_fd(fd);
goto bail_err;
}
- if (ret == 0) /* success */
+ if (ret == 0) { /* success */
+ SLIST_FOREACH(sk, &skh, used)
+ sk->verified = 1;
break;
+ }
(void)unconfigure_fd(fd);
(void)prog_close(fd);
+ /*
+ * If the shared keys were all verified already, assume
+ * something is wrong with the disk and give up. If
+ * not, flush the cache of the ones that have not been
+ * verified in case we can try again with passphrase
+ * re-entry.
+ */
+ all_verified = 1;
+ SLIST_FOREACH_SAFE(sk, &skh, used, sk1) {
+ all_verified &= sk->verified;
+ if (!sk->verified) {
+ LIST_REMOVE(sk, list);
+ free(sk);
+ }
+ }
+ if (all_verified)
+ loop = 0;
+
if (!loop) {
warnx("verification failed permanently");
goto bail_err;
@@ -1331,7 +1369,7 @@
return -1;
}
- oldp->key = getkey("old file", oldp->keygen, oldp->keylen);
+ oldp->key = getkey("old file", oldp->keygen, oldp->keylen, NULL);
/* we copy across the non-keygen info, here. */
@@ -1383,7 +1421,7 @@
return ret;
}
- p->key = getkey("new file", p->keygen, p->keylen);
+ p->key = getkey("new file", p->keygen, p->keylen, NULL);
kg = keygen_generate(KEYGEN_STOREDKEY);
kg->kg_key = bits_xor(p->key, oldp->key);
@@ -1569,7 +1607,7 @@
warnx("invalid parameters file \"%s\"", paramsfile);
return -1;
}
- p->key = getkey(dev, p->keygen, p->keylen);
+ p->key = getkey(dev, p->keygen, p->keylen, NULL);
raw = bits_getbuf(p->key);
nbits = bits_len(p->key);
assert(nbits <= INT_MAX - 7);
Home |
Main Index |
Thread Index |
Old Index