Add the concept of a verification method which allows cgdconfig(8)
to reprompt for the passphrase if the key does not meet certain criteria. The currently implemented methods are ``none'' and ``disklabel''. The first behaves in the original fashion, the second will scan for a disklabel on the cgd after configuration and if it does not find a disklabel then it will reprompt for the password and reconfigure the disk.
This commit is contained in:
parent
448f621758
commit
1242e52a64
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cgdconfig.c,v 1.2 2002/10/12 15:56:26 elric Exp $ */
|
||||
/* $NetBSD: cgdconfig.c,v 1.3 2002/10/12 21:02:18 elric Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
@ -41,7 +41,7 @@
|
||||
__COPYRIGHT(
|
||||
"@(#) Copyright (c) 2002\
|
||||
The NetBSD Foundation, Inc. All rights reserved.");
|
||||
__RCSID("$NetBSD: cgdconfig.c,v 1.2 2002/10/12 15:56:26 elric Exp $");
|
||||
__RCSID("$NetBSD: cgdconfig.c,v 1.3 2002/10/12 21:02:18 elric Exp $");
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
@ -55,6 +55,7 @@ __RCSID("$NetBSD: cgdconfig.c,v 1.2 2002/10/12 15:56:26 elric Exp $");
|
||||
#include <util.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <dev/cgdvar.h>
|
||||
@ -78,11 +79,12 @@ __RCSID("$NetBSD: cgdconfig.c,v 1.2 2002/10/12 15:56:26 elric Exp $");
|
||||
|
||||
int nflag = 0;
|
||||
|
||||
static int configure(int, char **, int);
|
||||
static int configure(int, char **, struct params *, int);
|
||||
static int configure_stdin(struct params *, int argc, char **);
|
||||
static int generate(struct params *, int, char **, const char *);
|
||||
static int unconfigure(int, char **, int);
|
||||
static int do_all(const char *, int, char **, int (*)(int, char **, int));
|
||||
static int unconfigure(int, char **, struct params *, int);
|
||||
static int do_all(const char *, int, char **,
|
||||
int (*)(int, char **, struct params *, int));
|
||||
|
||||
#define CONFIG_FLAGS_FROMALL 1 /* called from configure_all() */
|
||||
#define CONFIG_FLAGS_FROMMAIN 2 /* called from main() */
|
||||
@ -95,8 +97,10 @@ static int getkey(const char *, struct params *);
|
||||
static int getkeyfrompassphrase(const char *, struct params *);
|
||||
static int getkeyfromfile(FILE *, struct params *);
|
||||
static int opendisk_werror(const char *, char *, int);
|
||||
static int unconfigure_fd(int);
|
||||
static int verify(struct params *, int);
|
||||
|
||||
static void usage(void);
|
||||
static void usage(void);
|
||||
|
||||
/* Verbose Framework */
|
||||
int verbose = 0;
|
||||
@ -108,12 +112,12 @@ static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
fprintf(stderr, "usage: %s [-nv] cgd dev [paramsfile]\n",
|
||||
fprintf(stderr, "usage: %s [-nv] [-V vmeth] cgd dev [paramsfile]\n",
|
||||
getprogname());
|
||||
fprintf(stderr, " %s -C [-nv] [-f configfile]\n", getprogname());
|
||||
fprintf(stderr, " %s -U [-nv] [-f configfile]\n", getprogname());
|
||||
fprintf(stderr, " %s -g [-nv] [-i ivmeth] [-k kgmeth] "
|
||||
"[-o outfile] alg [keylen]\n", getprogname());
|
||||
"[-o outfile] [-V vmeth] alg [keylen]\n", getprogname());
|
||||
fprintf(stderr, " %s -s [-nv] [-i ivmeth] cgd dev alg "
|
||||
"[keylen]\n", getprogname());
|
||||
fprintf(stderr, " %s -u [-nv] cgd\n", getprogname());
|
||||
@ -134,7 +138,7 @@ main(int argc, char **argv)
|
||||
setprogname(*argv);
|
||||
params_init(&cf);
|
||||
|
||||
while ((ch = getopt(argc, argv, "CUb:f:gi:k:no:usv")) != -1)
|
||||
while ((ch = getopt(argc, argv, "CUV:b:f:gi:k:no:usv")) != -1)
|
||||
switch (ch) {
|
||||
case 'C':
|
||||
action = ACTION_CONFIGALL;
|
||||
@ -144,7 +148,11 @@ main(int argc, char **argv)
|
||||
action = ACTION_UNCONFIGALL;
|
||||
actions++;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
ret = params_setverify_method_str(&cf, optarg);
|
||||
if (ret)
|
||||
usage();
|
||||
break;
|
||||
case 'b':
|
||||
ret = params_setbsize(&cf, atoi(optarg));
|
||||
if (ret)
|
||||
@ -200,9 +208,9 @@ main(int argc, char **argv)
|
||||
|
||||
switch (action) {
|
||||
case ACTION_CONFIGURE:
|
||||
return configure(argc, argv, CONFIG_FLAGS_FROMMAIN);
|
||||
return configure(argc, argv, &cf, CONFIG_FLAGS_FROMMAIN);
|
||||
case ACTION_UNCONFIGURE:
|
||||
return unconfigure(argc, argv, CONFIG_FLAGS_FROMMAIN);
|
||||
return unconfigure(argc, argv, NULL, CONFIG_FLAGS_FROMMAIN);
|
||||
case ACTION_GENERATE:
|
||||
return generate(&cf, argc, argv, outfile);
|
||||
case ACTION_CONFIGALL:
|
||||
@ -264,6 +272,8 @@ getkeyfrompassphrase(const char *target, struct params *p)
|
||||
snprintf(buf, 1024, "%s's passphrase:", target);
|
||||
passp = getpass(buf);
|
||||
/* XXXrcd: data hiding ? we should be allocating the key here. */
|
||||
if (!p->key)
|
||||
free(p->key);
|
||||
ret = pkcs5_pbkdf2(&p->key, BITS2BYTES(p->keylen), passp,
|
||||
strlen(passp), p->keygen_salt, BITS2BYTES(p->keygen_saltlen),
|
||||
p->keygen_iterations);
|
||||
@ -272,10 +282,10 @@ getkeyfrompassphrase(const char *target, struct params *p)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
unconfigure(int argc, char **argv, int flags)
|
||||
unconfigure(int argc, char **argv, struct params *inparams, int flags)
|
||||
{
|
||||
struct cgd_ioctl ci;
|
||||
int fd;
|
||||
int ret;
|
||||
char buf[MAXPATHLEN] = "";
|
||||
@ -303,10 +313,21 @@ unconfigure(int argc, char **argv, int flags)
|
||||
if (nflag)
|
||||
return 0;
|
||||
|
||||
ret = unconfigure_fd(fd);
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
unconfigure_fd(int fd)
|
||||
{
|
||||
struct cgd_ioctl ci;
|
||||
int ret;
|
||||
|
||||
ret = ioctl(fd, CGDIOCCLR, &ci);
|
||||
if (ret == -1) {
|
||||
perror("ioctl");
|
||||
return errno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -314,7 +335,7 @@ unconfigure(int argc, char **argv, int flags)
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
configure(int argc, char **argv, int flags)
|
||||
configure(int argc, char **argv, struct params *inparams, int flags)
|
||||
{
|
||||
struct params params;
|
||||
int fd;
|
||||
@ -348,18 +369,53 @@ configure(int argc, char **argv, int flags)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
fd = opendisk_werror(argv[0], cgdname, sizeof(cgdname));
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
/*
|
||||
* over-ride the verify method with that specified on the
|
||||
* command line
|
||||
*/
|
||||
|
||||
ret = getkey(argv[1], ¶ms);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (inparams && inparams->verify_method != VERIFY_UNKNOWN)
|
||||
params.verify_method = inparams->verify_method;
|
||||
|
||||
ret = configure_params(fd, cgdname, argv[1], ¶ms);
|
||||
/*
|
||||
* loop over configuring the disk and checking to see if it
|
||||
* verifies properly. We open and close the disk device each
|
||||
* time, because if the user passes us the block device we
|
||||
* need to flush the buffer cache.
|
||||
*/
|
||||
|
||||
for (;;) {
|
||||
fd = opendisk_werror(argv[0], cgdname, sizeof(cgdname));
|
||||
if (fd == -1)
|
||||
return -1;
|
||||
|
||||
ret = getkey(argv[1], ¶ms);
|
||||
if (ret)
|
||||
goto bail_err;
|
||||
|
||||
ret = configure_params(fd, cgdname, argv[1], ¶ms);
|
||||
if (ret)
|
||||
goto bail_err;
|
||||
|
||||
ret = verify(¶ms, fd);
|
||||
if (ret == -1)
|
||||
goto bail_err;
|
||||
if (!ret)
|
||||
break;
|
||||
|
||||
fprintf(stderr, "verification failed, please reenter "
|
||||
"passphrase\n");
|
||||
|
||||
unconfigure_fd(fd);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
params_free(¶ms);
|
||||
return ret;
|
||||
close(fd);
|
||||
return 0;
|
||||
bail_err:
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -410,7 +466,7 @@ opendisk_werror(const char *cgd, char *buf, int buflen)
|
||||
return 0;
|
||||
}
|
||||
|
||||
fd = opendisk(cgd, O_RDWR, buf, buflen, 1);
|
||||
fd = opendisk(cgd, O_RDWR, buf, buflen, 0);
|
||||
if (fd == -1)
|
||||
fprintf(stderr, "can't open cgd \"%s\", \"%s\": %s\n",
|
||||
cgd, buf, strerror(errno));
|
||||
@ -452,6 +508,51 @@ configure_params(int fd, const char *cgd, const char *dev, struct params *p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* verify returns 0 for success, -1 for unrecoverable error, or 1 for retry.
|
||||
*/
|
||||
|
||||
#define SCANSIZE 8192
|
||||
|
||||
static int
|
||||
verify(struct params *p, int fd)
|
||||
{
|
||||
struct disklabel l;
|
||||
int ret;
|
||||
char buf[SCANSIZE];
|
||||
|
||||
switch (p->verify_method) {
|
||||
case VERIFY_NONE:
|
||||
return 0;
|
||||
case VERIFY_DISKLABEL:
|
||||
/*
|
||||
* for now this is the only method, so we just perform it
|
||||
* in this function.
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "verify: unimplemented verification method\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* we simply scan the first few blocks for a disklabel, ignoring
|
||||
* any MBR/filecore sorts of logic. MSDOS and RiscOS can't read
|
||||
* a cgd, anyway, so it is unlikely that there will be non-native
|
||||
* partition information.
|
||||
*/
|
||||
|
||||
ret = pread(fd, buf, 8192, 0);
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "verify: can't read disklabel area\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* now scan for the disklabel */
|
||||
|
||||
return disklabel_scan(&l, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
static int
|
||||
generate(struct params *p, int argc, char **argv, const char *outfile)
|
||||
{
|
||||
@ -505,7 +606,7 @@ generate(struct params *p, int argc, char **argv, const char *outfile)
|
||||
|
||||
static int
|
||||
do_all(const char *cfile, int argc, char **argv,
|
||||
int (*conf)(int, char **, int))
|
||||
int (*conf)(int, char **, struct params *, int))
|
||||
{
|
||||
FILE *f;
|
||||
size_t len;
|
||||
@ -542,7 +643,7 @@ do_all(const char *cfile, int argc, char **argv,
|
||||
continue;
|
||||
|
||||
my_argv = words(line, &my_argc);
|
||||
ret = conf(my_argc, my_argv, CONFIG_FLAGS_FROMALL);
|
||||
ret = conf(my_argc, my_argv, NULL, CONFIG_FLAGS_FROMALL);
|
||||
if (ret) {
|
||||
fprintf(stderr, "on \"%s\" line %lu\n", fn,
|
||||
(u_long)lineno);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: params.c,v 1.1 2002/10/04 18:37:20 elric Exp $ */
|
||||
/* $NetBSD: params.c,v 1.2 2002/10/12 21:02:18 elric Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
@ -90,6 +90,7 @@ params_init(struct params *p)
|
||||
p->keygen_salt = NULL;
|
||||
p->keygen_saltlen = -1;
|
||||
p->keygen_iterations = -1;
|
||||
p->verify_method = VERIFY_UNKNOWN;
|
||||
p->key_hash = NULL;
|
||||
p->key_hashlen = -1;
|
||||
p->xor_key = NULL;
|
||||
@ -113,6 +114,8 @@ params_filldefaults(struct params *p)
|
||||
|
||||
if (p->keygen_method == KEYGEN_UNKNOWN)
|
||||
p->keygen_method = KEYGEN_PKCS5_PBKDF2;
|
||||
if (p->verify_method == VERIFY_UNKNOWN)
|
||||
p->verify_method = VERIFY_NONE;
|
||||
if (!p->ivmeth)
|
||||
params_setivmeth(p, "encblkno");
|
||||
if (p->keylen == -1)
|
||||
@ -296,6 +299,37 @@ params_setkeygen_salt_b64(struct params *p, const char *in)
|
||||
return params_setb64(&p->keygen_salt, &p->keygen_saltlen, in);
|
||||
}
|
||||
|
||||
int
|
||||
params_setverify_method(struct params *p, int in)
|
||||
{
|
||||
|
||||
switch (in) {
|
||||
case VERIFY_NONE:
|
||||
case VERIFY_DISKLABEL:
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "params_setverify_method: unsupported "
|
||||
"verify_method (%d)\n", in);
|
||||
return -1;
|
||||
}
|
||||
p->verify_method = in;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
params_setverify_method_str(struct params *p, const char *in)
|
||||
{
|
||||
|
||||
if (!strcmp("none", in))
|
||||
return params_setverify_method(p, VERIFY_NONE);
|
||||
if (!strcmp("disklabel", in))
|
||||
return params_setverify_method(p, VERIFY_DISKLABEL);
|
||||
|
||||
fprintf(stderr, "params_setverify_method: unrecognized verify method "
|
||||
"\"%s\"\n", in);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
params_setxor_key(struct params *p, const char *in, int len)
|
||||
{
|
||||
@ -365,6 +399,8 @@ take_action(struct params *c, FILE *f, const char *key, char *val)
|
||||
fprintf(stderr, "xor_key improperly encoded\n");
|
||||
return -1;
|
||||
}
|
||||
} else if (!strcmp(key, "verify_method")) {
|
||||
return params_setverify_method_str(c, val);
|
||||
} else if (!strcmp(key, "key_hash")) {
|
||||
ret = params_setkey_hash_b64(c, val);
|
||||
if (ret < 0) {
|
||||
@ -502,6 +538,18 @@ params_fput(struct params *p, FILE *f)
|
||||
print_kvpair_str(f, "iv-method", p->ivmeth);
|
||||
print_kvpair_int(f, "keylength", p->keylen);
|
||||
print_kvpair_int(f, "blocksize", p->bsize);
|
||||
switch (p->verify_method) {
|
||||
case VERIFY_NONE:
|
||||
print_kvpair_str(f, "verify_method", "none");
|
||||
break;
|
||||
case VERIFY_DISKLABEL:
|
||||
print_kvpair_str(f, "verify_method", "disklabel");
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unsupported verify_method (%d)\n",
|
||||
p->verify_method);
|
||||
return -1;
|
||||
}
|
||||
switch (p->keygen_method) {
|
||||
case KEYGEN_RANDOMKEY:
|
||||
print_kvpair_str(f, "keygen_method", "randomkey");
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: params.h,v 1.1 2002/10/04 18:37:20 elric Exp $ */
|
||||
/* $NetBSD: params.h,v 1.2 2002/10/12 21:02:18 elric Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||
@ -46,16 +46,25 @@ struct params {
|
||||
u_int8_t *keygen_salt;
|
||||
int keygen_saltlen;
|
||||
int keygen_iterations;
|
||||
int verify_method;
|
||||
u_int8_t *key_hash;
|
||||
int key_hashlen;
|
||||
u_int8_t *xor_key;
|
||||
int xor_keylen;
|
||||
};
|
||||
|
||||
/* key generation methods */
|
||||
|
||||
#define KEYGEN_UNKNOWN 0x0
|
||||
#define KEYGEN_RANDOMKEY 0x1
|
||||
#define KEYGEN_PKCS5_PBKDF2 0x2
|
||||
|
||||
/* verification methods */
|
||||
|
||||
#define VERIFY_UNKNOWN 0x0
|
||||
#define VERIFY_NONE 0x1
|
||||
#define VERIFY_DISKLABEL 0x2
|
||||
|
||||
void params_init(struct params *);
|
||||
void params_free(struct params *);
|
||||
|
||||
@ -78,6 +87,8 @@ int params_setkeygen_method(struct params *, int);
|
||||
int params_setkeygen_method_str(struct params *, const char *);
|
||||
int params_setkeygen_salt(struct params *, const char *, int);
|
||||
int params_setkeygen_salt_b64(struct params *, const char *);
|
||||
int params_setverify_method(struct params *, int);
|
||||
int params_setverify_method_str(struct params *, const char *);
|
||||
int params_setxor_key(struct params *, const char *, int);
|
||||
int params_setxor_key_b64(struct params *, const char *);
|
||||
int params_setkey_hash(struct params *, const char *, int);
|
||||
|
Loading…
Reference in New Issue
Block a user