PERFORCE change 166896 for review
Gleb Kurtsou
gk at FreeBSD.org
Sat Aug 1 18:38:23 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=166896
Change 166896 by gk at gk_h1 on 2009/08/01 18:37:48
Implement changing directory key (pefs setkey)
Implement key chaining
Fix vop_link: forbid creation of link to unencrypted file, use same tweak and key for created link
Affected files ...
.. //depot/projects/soc2009/gk_pefs/sbin/pefs/Makefile#2 edit
.. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_ctl.c#2 edit
.. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_ctl.h#2 edit
.. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_key.c#2 edit
.. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_keychain.c#1 add
.. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_keychain.h#1 add
.. //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_mount.c#2 edit
.. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_crypto.c#5 edit
.. //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vnops.c#8 edit
Differences ...
==== //depot/projects/soc2009/gk_pefs/sbin/pefs/Makefile#2 (text+ko) ====
@@ -5,7 +5,7 @@
.PATH: ${MOUNT} ${SYS}/geom/eli ${SYS}/crypto/sha2
PROG= pefs
-SRCS= pefs_ctl.c pefs_mount.c pefs_key.c
+SRCS= pefs_ctl.c pefs_key.c pefs_keychain.c pefs_mount.c
SRCS+= getmntopts.c
SRCS+= g_eli_crypto.c pkcs5v2.c sha2.c
==== //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_ctl.c#2 (text+ko) ====
@@ -29,6 +29,8 @@
__FBSDID("$FreeBSD$");
#include <sys/types.h>
+#include <assert.h>
+#include <ctype.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
@@ -42,6 +44,7 @@
#include <fs/pefs/pefs.h>
#include "pefs_ctl.h"
+#include "pefs_keychain.h"
#define PATH_UMOUNT "/sbin/umount"
@@ -50,9 +53,14 @@
static int pefs_setkey(int argc, char *argv[]);
static int pefs_delkey(int argc, char *argv[]);
static int pefs_flushkeys(int argc, char *argv[]);
-static int pefs_status(int argc, char *argv[]);
+static int pefs_setchain(int argc, char *argv[]);
+static int pefs_delchain(int argc, char *argv[]);
+static int pefs_randomchain(int argc, char *argv[]);
+static int pefs_showkeys(int argc, char *argv[]);
+static int pefs_showchain(int argc, char *argv[]);
typedef int (*command_func_t)(int argc, char **argv);
+typedef int (*keyop_func_t)(struct pefs_keychain *kc, int fd);
struct command {
const char *name;
@@ -67,88 +75,237 @@
{ "setkey", pefs_setkey },
{ "delkey", pefs_delkey },
{ "flushkeys", pefs_flushkeys },
- { "status", pefs_status },
+ { "showkeys", pefs_showkeys },
+ { "status", pefs_showkeys },
+ { "randomchain", pefs_randomchain },
+ { "setchain", pefs_setchain },
+ { "delchain", pefs_delchain },
+ { "showchain", pefs_showchain },
{ NULL, NULL },
};
static int
-pefs_addkey(int argc, char *argv[])
+checkargs_fs(int argc, char **argv __unused)
+{
+ if (argc != 1) {
+ if (argc == 0)
+ warnx("missing filesystem argument");
+ else
+ warnx("too many arguments");
+ return (0);
+ }
+
+ return (1);
+}
+
+uintmax_t
+pefs_keyid_as_int(char *keyid)
+{
+ uintmax_t r;
+ int i;
+
+ assert(sizeof(uintmax_t) >= PEFS_KEYID_SIZE);
+ for (i = 0, r = 0; i < PEFS_KEYID_SIZE; i++) {
+ if (i)
+ r <<= 8;
+ r |= keyid[i] & 0xff;
+ }
+
+ return (r);
+}
+
+static inline void
+pefs_key_show(struct pefs_xkey *xk, int ind)
+{
+ printf("\t%-4d %016jx %s\n", ind, pefs_keyid_as_int(xk->pxk_keyid), pefs_alg_name(xk->pxk_alg));
+}
+
+static int
+pefs_keyop(keyop_func_t func, int argc, char *argv[])
{
struct pefs_xkey k;
- int error, fd;
+ struct pefs_keychain *kc;
+ struct pefs_keyparam kp;
+ int error, fd, i;
+ int chain = PEFS_KEYCHAIN_IGNORE_MISSING;
- error = pefs_get_key(&k, &argc, argv);
- if (error != 0)
- return (error);
+ pefs_keyparam_init(&kp);
+ while ((i = getopt(argc, argv, "pcCa:i:k:")) != -1)
+ switch(i) {
+ case 'a':
+ kp.kp_alg = optarg;
+ break;
+ case 'c':
+ chain = PEFS_KEYCHAIN_USE;
+ break;
+ case 'C':
+ chain = 0;
+ break;
+ case 'p':
+ kp.kp_nopassphrase = 1;
+ break;
+ case 'i':
+ kp.kp_iterations = atoi(optarg);
+ if (kp.kp_iterations <= 0) {
+ warnx("invalid iterations argument: %s", optarg);
+ pefs_usage();
+ }
+ break;
+ case 'k':
+ kp.kp_keyfile = optarg;
+ break;
+ default:
+ pefs_usage();
+ }
+ argc -= optind;
+ argv += optind;
- if (argc != 1) {
+ if (!checkargs_fs(argc, argv)) {
bzero(&k, sizeof(k));
- if (argc == 0)
- warnx("missing filesystem argument");
- else if (getopt(argc, argv, "") == -1)
- warnx("too many arguments");
pefs_usage();
}
+ error = pefs_key_get(&k, NULL, 0, &kp);
+ if (error != 0)
+ return (error);
+
+ kc = pefs_keychain_get(argv[0], chain, &k);
+ bzero(&k, sizeof(k));
+ if (kc == NULL) {
+ return (EX_DATAERR);
+ }
fd = open(argv[0], O_RDONLY);
if (fd == -1) {
- bzero(&k, sizeof(k));
err(EX_IOERR, "cannot open %s", argv[0]);
}
- if (ioctl(fd, PEFS_ADDKEY, &k) == -1) {
- bzero(&k, sizeof(k));
- err(EX_IOERR, "cannot add key");
+
+ error = func(kc, fd);
+
+ pefs_keychain_free(kc);
+
+ close(fd);
+
+ return (error);
+}
+
+static int
+pefs_addkey_op(struct pefs_keychain *kc, int fd)
+{
+ for (; kc; kc = kc->kc_next) {
+ if (ioctl(fd, PEFS_ADDKEY, &kc->kc_key) == -1) {
+ warn("cannot add key");
+ return (-1);
+ }
}
- bzero(&k, sizeof(k));
- close(fd);
return (0);
}
static int
-pefs_setkey(int argc __unused, char *argv[] __unused)
+pefs_delkey_op(struct pefs_keychain *kc, int fd)
{
- pefs_usage();
+ for (; kc; kc = kc->kc_next) {
+ if (ioctl(fd, PEFS_DELKEY, &kc->kc_key) == -1) {
+ warn("cannot delete key");
+ }
+ }
return (0);
}
static int
+pefs_addkey(int argc, char *argv[])
+{
+ return (pefs_keyop(pefs_addkey_op, argc, argv));
+}
+
+static int
pefs_delkey(int argc, char *argv[])
{
+ return (pefs_keyop(pefs_delkey_op, argc, argv));
+}
+
+static int
+pefs_setkey(int argc, char *argv[])
+{
struct pefs_xkey k;
- int error, fd;
+ struct pefs_keychain *kc;
+ struct pefs_keyparam kp;
+ int error, fd, i;
+ int addkey = 0;
+ int chain = PEFS_KEYCHAIN_IGNORE_MISSING;
+
+ pefs_keyparam_init(&kp);
+ while ((i = getopt(argc, argv, "xpcCa:i:k:")) != -1)
+ switch(i) {
+ case 'x':
+ addkey = 1;
+ break;
+ case 'a':
+ kp.kp_alg = optarg;
+ break;
+ case 'c':
+ chain = PEFS_KEYCHAIN_USE;
+ break;
+ case 'C':
+ chain = 0;
+ break;
+ case 'p':
+ kp.kp_nopassphrase = 1;
+ break;
+ case 'i':
+ kp.kp_iterations = atoi(optarg);
+ if (kp.kp_iterations <= 0) {
+ warnx("invalid iterations argument: %s", optarg);
+ pefs_usage();
+ }
+ break;
+ case 'k':
+ kp.kp_keyfile = optarg;
+ break;
+ default:
+ pefs_usage();
+ }
+ argc -= optind;
+ argv += optind;
- error = pefs_get_key(&k, &argc, argv);
- if (error != 0)
- return (error);
+ if (chain == PEFS_KEYCHAIN_USE && addkey)
+ errx(EX_USAGE, "invalid arguments: -x -c");
- bzero(k.pxk_key, PEFS_KEY_SIZE);
if (argc != 1) {
- bzero(&k, sizeof(k));
if (argc == 0)
- warnx("missing filesystem argument");
- else if (getopt(argc, argv, "") == -1)
+ warnx("missing directory argument");
+ else
warnx("too many arguments");
+ bzero(&k, sizeof(k));
pefs_usage();
}
+ error = pefs_key_get(&k, NULL, 0, &kp);
+ if (error != 0)
+ return (error);
+
+ kc = pefs_keychain_get(argv[0], chain, &k);
+ if (kc == NULL) {
+ return (EX_DATAERR);
+ }
+ pefs_keychain_free(kc);
+
+ bzero(k.pxk_key, PEFS_KEY_SIZE);
+
fd = open(argv[0], O_RDONLY);
if (fd == -1) {
- bzero(&k, sizeof(k));
err(EX_IOERR, "cannot open %s", argv[0]);
}
- if (ioctl(fd, PEFS_DELKEY, &k) == -1) {
- bzero(&k, sizeof(k));
- err(EX_IOERR, "cannot delete key");
+
+ if (ioctl(fd, PEFS_SETKEY, &k) == -1) {
+ warn("cannot set key");
+ error = EX_OSERR;
}
- bzero(&k, sizeof(k));
+
close(fd);
- return (0);
- pefs_usage();
-
- return (0);
+ return (error);
}
static int
@@ -156,11 +313,7 @@
{
int fd;
- if (argc != 1) {
- if (argc == 0)
- warnx("missing filesystem argument");
- else if (getopt(argc, argv, "") == -1)
- warnx("too many arguments");
+ if (!checkargs_fs(argc, argv)) {
pefs_usage();
}
@@ -177,17 +330,22 @@
}
static int
-pefs_status(int argc, char *argv[])
+pefs_showkeys(int argc, char *argv[])
{
struct pefs_xkey k;
- char buf[PEFS_KEYID_SIZE * 2 + 1];
- int fd, i;
+ int chain, fd, i;
+
+ chain = 1;
+ while ((i = getopt(argc, argv, "")) != -1)
+ switch(i) {
+ case '?':
+ default:
+ pefs_usage();
+ }
+ argc -= optind;
+ argv += optind;
- if (argc != 1) {
- if (argc == 0)
- warnx("missing filesystem argument");
- else if (getopt(argc, argv, "") == -1)
- warnx("too many arguments");
+ if (!checkargs_fs(argc, argv)) {
pefs_usage();
}
@@ -205,11 +363,7 @@
} else {
printf("Keys:\n");
while (1) {
- for (i = 0; i < PEFS_KEYID_SIZE; i++) {
- snprintf(buf + i * 2, sizeof(buf) - i * 2, "%02x",
- k.pxk_keyid[i] & 0xff);
- }
- printf("\t%-4d %16s %s\n", k.pxk_index, buf, pefs_alg_name(k.pxk_alg));
+ pefs_key_show(&k, k.pxk_index);
k.pxk_index++;
if (ioctl(fd, PEFS_GETKEY, &k) == -1)
break;
@@ -217,6 +371,9 @@
}
close(fd);
+ if (chain) {
+ }
+
return (0);
}
@@ -235,14 +392,13 @@
default:
pefs_usage();
}
- if (argc - optind == 0) {
- warnx("missing filesystem argument");
+ argc -= optind;
+ argv += optind;
+
+ if (!checkargs_fs(argc, argv)) {
pefs_usage();
}
- if (argc - optind > 1) {
- warnx("too many arguments");
- pefs_usage();
- }
+
nargv = malloc((argc + 2) * sizeof(*nargv));
for (i = 0; i < argc; i++)
nargv[i + 1] = argv[i];
@@ -251,19 +407,236 @@
if (execv(PATH_UMOUNT, nargv) == -1)
errx(EX_OSERR, "exec %s", PATH_UMOUNT);
+
+ return (0);
+}
+
+static int
+pefs_setchain(int argc, char *argv[])
+{
+ struct pefs_keychain *kc, *kci;
+ struct {
+ struct pefs_xkey k;
+ struct pefs_keyparam kp;
+ } p[2];
+ struct pefs_xkey *k1 = &p[0].k, *k2 = &p[1].k;
+ int error, i;
+
+ pefs_keyparam_init(&p[0].kp);
+ pefs_keyparam_init(&p[1].kp);
+ while ((i = getopt(argc, argv, "pPa:A:i:I:k:K:")) != -1)
+ switch(i) {
+ case 'a':
+ case 'A':
+ p[isupper(i) ? 1 : 0].kp.kp_alg = optarg;
+ break;
+ case 'p':
+ case 'P':
+ p[isupper(i) ? 1 : 0].kp.kp_nopassphrase = 1;
+ break;
+ case 'i':
+ case 'I':
+ if ((p[isupper(i) ? 1 : 0].kp.kp_iterations = atoi(optarg)) <= 0) {
+ warnx("invalid iterations argument: %s", optarg);
+ pefs_usage();
+ }
+ break;
+ case 'k':
+ case 'K':
+ p[isupper(i) ? 1 : 0].kp.kp_keyfile = optarg;
+ break;
+ default:
+ pefs_usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+
+ if (!checkargs_fs(argc, argv)) {
+ bzero(p, sizeof(p));
+ pefs_usage();
+ }
+
+ error = pefs_key_get(k1, "parent key passphrase", 1, &p[0].kp);
+ if (error != 0) {
+ bzero(p, sizeof(p));
+ return (error);
+ }
+ error = pefs_key_get(k2, "chained key passphrase", 1, &p[1].kp);
+ if (error != 0) {
+ bzero(p, sizeof(p));
+ return (error);
+ }
+
+ kc = pefs_keychain_get(argv[0], PEFS_KEYCHAIN_IGNORE_MISSING, k1);
+ for (kci = kc; kci; kci = kci->kc_next) {
+ if (memcmp(k2->pxk_keyid, kci->kc_key.pxk_keyid, PEFS_KEYID_SIZE) == 0) {
+ pefs_keychain_free(kc);
+ bzero(k1->pxk_key, PEFS_KEY_SIZE);
+ bzero(k2->pxk_key, PEFS_KEY_SIZE);
+ errx(EX_DATAERR, "key chain is already set: %016jx -> %016jx",
+ pefs_keyid_as_int(k1->pxk_keyid),
+ pefs_keyid_as_int(k2->pxk_keyid));
+ }
+ }
+ if (kc->kc_next != NULL) {
+ bzero(k1->pxk_key, PEFS_KEY_SIZE);
+ bzero(k2->pxk_key, PEFS_KEY_SIZE);
+ warnx("key chain for parent key is already set: %016jx -> %016jx",
+ pefs_keyid_as_int(kc->kc_key.pxk_keyid),
+ pefs_keyid_as_int(kc->kc_next->kc_key.pxk_keyid));
+ pefs_keychain_free(kc);
+ exit(EX_DATAERR);
+ }
+
+ error = pefs_keychain_set(argv[0], k1, k2);
+ if (error)
+ return (EX_DATAERR);
+
return (0);
}
+static int
+pefs_delchain(int argc, char *argv[])
+{
+ struct pefs_xkey k;
+ struct pefs_keyparam kp;
+ struct pefs_keychain *kc, *kci;
+ int error, i;
+ int force = 0;
+
+ pefs_keyparam_init(&kp);
+ while ((i = getopt(argc, argv, "fpa:i:k:")) != -1)
+ switch(i) {
+ case 'f':
+ force = 1;
+ break;
+ case 'a':
+ kp.kp_alg = optarg;
+ break;
+ case 'p':
+ kp.kp_nopassphrase = 1;
+ break;
+ case 'i':
+ kp.kp_iterations = atoi(optarg);
+ if (kp.kp_iterations <= 0) {
+ warnx("invalid iterations argument: %s", optarg);
+ pefs_usage();
+ }
+ break;
+ case 'k':
+ kp.kp_keyfile = optarg;
+ break;
+ default:
+ pefs_usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (!checkargs_fs(argc, argv)) {
+ pefs_usage();
+ }
+
+ error = pefs_key_get(&k, NULL, 0, &kp);
+ if (error != 0)
+ return (error);
+
+ kc = pefs_keychain_get(argv[0], PEFS_KEYCHAIN_USE, &k);
+ if (kc == NULL) {
+ bzero(&k, sizeof(k));
+ return (EX_DATAERR);
+ }
+
+ for (kci = kc; kci != NULL && kci->kc_next != NULL; kci = kci->kc_next) {
+ pefs_keychain_del(argv[0], &kci->kc_key);
+ if (!force)
+ break;
+ }
+ pefs_keychain_free(kc);
+
+ return (0);
+}
+
+static int
+pefs_showchain(int argc, char *argv[])
+{
+ struct pefs_xkey k;
+ struct pefs_keyparam kp;
+ struct pefs_keychain *kc, *kci;
+ int error, i;
+
+ pefs_keyparam_init(&kp);
+ while ((i = getopt(argc, argv, "pa:i:k:")) != -1)
+ switch(i) {
+ case 'a':
+ kp.kp_alg = optarg;
+ break;
+ case 'p':
+ kp.kp_nopassphrase = 1;
+ break;
+ case 'i':
+ kp.kp_iterations = atoi(optarg);
+ if (kp.kp_iterations <= 0) {
+ warnx("invalid iterations argument: %s", optarg);
+ pefs_usage();
+ }
+ break;
+ case 'k':
+ kp.kp_keyfile = optarg;
+ break;
+ default:
+ pefs_usage();
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (!checkargs_fs(argc, argv)) {
+ pefs_usage();
+ }
+
+ error = pefs_key_get(&k, NULL, 0, &kp);
+ if (error != 0)
+ return (error);
+
+ kc = pefs_keychain_get(argv[0], PEFS_KEYCHAIN_USE, &k);
+ if (kc == NULL) {
+ bzero(&k, sizeof(k));
+ return (EX_DATAERR);
+ }
+
+ printf("Key chain:\n");
+ bzero(&k, sizeof(k));
+ for (i = 1, kci = kc; kci != NULL; i++, kci = kci->kc_next) {
+ pefs_key_show(&kci->kc_key, i);
+ }
+ pefs_keychain_free(kc);
+
+ return (0);
+}
+
+static int
+pefs_randomchain(int argc __unused, char *argv[] __unused)
+{
+ return (0);
+}
+
+
void
pefs_usage(void)
{
fprintf(stderr, "usage: pefs mount [-o options] target filesystem\n"
" pefs unmount [-fv] filesystem\n"
- " pefs addkey [-p] [-a alg] [-i iterations] [-k keyfile] filesystem\n"
- " pefs setkey [-cp] [-a alg] [-i iterations] [-k keyfile] directory\n"
- " pefs delkey [-p] [-a alg] [-i iterations] [-k keyfile] filesystem\n"
+ " pefs addkey [-cCp] [-a alg] [-i iterations] [-k keyfile] filesystem\n"
+ " pefs setkey [-xcCp] [-a alg] [-i iterations] [-k keyfile] directory\n"
+ " pefs delkey [-cCp] [-a alg] [-i iterations] [-k keyfile] filesystem\n"
" pefs flushkeys filesystem\n"
- " pefs status filesystem\n");
+ " pefs setchain [-pP] [-a alg] [-i iterations] [-k keyfile]\n"
+ " [-A alg] [-I iterations] [-K keyfile] filesystem\n"
+ " pefs delchain [-pP] [-a alg] [-i iterations] [-k keyfile]\n"
+ " [-A alg] [-I iterations] [-K keyfile] filesystem\n"
+ " pefs showchain [-a alg] [-n min] [-N max] filesystem\n"
+ " pefs randomchain [-a alg] [-n min] [-N max] filesystem\n"
+ " pefs showkeys filesystem\n");
exit(EX_USAGE);
}
==== //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_ctl.h#2 (text+ko) ====
@@ -1,5 +1,6 @@
/*-
- * Copyright (c) 2009 Gleb Kurtsou. All rights reserved.
+ * Copyright (c) 2009 Gleb Kurtsou <gk at FreeBSD.org>
+ * All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,16 +25,33 @@
*
* $FreeBSD$
*/
-
#define PEFS_ALG_DEFAULT PEFS_ALG_SALSA20
#define PEFS_KDF_ITERATIONS 50000
struct pefs_xkey;
+struct pefs_keyparam {
+ int kp_nopassphrase;
+ int kp_iterations;
+ char *kp_keyfile;
+ char *kp_alg;
+};
+
+static inline void
+pefs_keyparam_init(struct pefs_keyparam *kp)
+{
+ kp->kp_nopassphrase = 0;
+ kp->kp_iterations = PEFS_KDF_ITERATIONS;
+ kp->kp_keyfile = NULL;
+ kp->kp_alg = NULL;
+}
+
void pefs_usage(void);
-int pefs_get_key(struct pefs_xkey *xk, int *pargc, char *argv[]);
+int pefs_key_get(struct pefs_xkey *xk, const char *prompt, int verify,
+ struct pefs_keyparam *kp);
int pefs_mount(int argc, char *argv[]);
int pefs_mount_prog(int argc, char *argv[]);
+uintmax_t pefs_keyid_as_int(char *keyid);
const char * pefs_alg_name(int alg_id);
==== //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_key.c#2 (text+ko) ====
@@ -44,6 +44,8 @@
#include "pefs_ctl.h"
+#define PEFS_KEY_PROMPT_DEFAULT "passphrase"
+
struct algorithm {
const char *name;
int id;
@@ -68,95 +70,76 @@
}
int
-pefs_get_key(struct pefs_xkey *xk, int *pargc, char *argv[])
+pefs_key_get(struct pefs_xkey *xk, const char *prompt, int verify, struct pefs_keyparam *kp)
{
struct hmac_ctx ctx;
struct algorithm *alg;
- char buf[BUFSIZ], *p;
- char *keyfile = NULL;
+ char promptbuf[64], buf[BUFSIZ], buf2[BUFSIZ], *p;
ssize_t done;
- int nopassphrase = 0;
- int iterations = PEFS_KDF_ITERATIONS;
- int i, fd, xargc = 0, orig_opterr;
+ int fd, i;
xk->pxk_index = -1;
xk->pxk_alg = PEFS_ALG_DEFAULT;
- orig_opterr = opterr;
- opterr = 0;
- while ((i = getopt(*pargc, argv, "pi:k:")) != -1)
- switch(i) {
- case 'a':
- for (alg = algs; alg->name != NULL; alg++) {
- if (strcmp(optarg, alg->name) == 0)
- xk->pxk_alg = alg->id;
- }
- errx(EX_USAGE, "invalid algorithm %s", optarg);
- break;
- case 'p':
- nopassphrase = 1;
- break;
- case 'i':
- iterations = atoi(optarg);
- if (iterations <= 0) {
- warnx("invalid iterations argument: %s", optarg);
- pefs_usage();
- }
- break;
- case 'k':
- keyfile = optarg;
- break;
- default:
- argv[xargc++] = argv[optind - 1];
+ if (kp->kp_alg != NULL) {
+ for (alg = algs; alg->name != NULL; alg++) {
+ if (strcmp(kp->kp_alg, alg->name) == 0)
+ xk->pxk_alg = alg->id;
}
- if (optind != *pargc) {
- if (strcmp(argv[optind - 1], "--") == 0)
- optind--;
- for (i = optind; i < *pargc; i++) {
- argv[xargc++] = argv[i];
- }
+ errx(EX_USAGE, "invalid algorithm %s", optarg);
}
- *pargc = xargc;
- opterr = orig_opterr;
- optind = 0;
- optreset = 1;
g_eli_crypto_hmac_init(&ctx, NULL, 0);
- if (keyfile != NULL && keyfile[0] == '\0')
- keyfile = NULL;
- if (keyfile == NULL && nopassphrase) {
+ if (kp->kp_keyfile != NULL && kp->kp_keyfile[0] == '\0')
+ kp->kp_keyfile = NULL;
+ if (kp->kp_keyfile == NULL && kp->kp_nopassphrase) {
warnx("no key components given");
pefs_usage();
}
- if (keyfile != NULL) {
- if (strcmp(keyfile, "-") == 0)
+ if (kp->kp_keyfile != NULL) {
+ if (strcmp(kp->kp_keyfile, "-") == 0)
fd = STDIN_FILENO;
else {
- fd = open(keyfile, O_RDONLY);
+ fd = open(kp->kp_keyfile, O_RDONLY);
if (fd == -1)
- err(EX_IOERR, "cannot open keyfile %s", keyfile);
+ err(EX_IOERR, "cannot open keyfile %s", kp->kp_keyfile);
}
while ((done = read(fd, buf, sizeof(buf))) > 0)
g_eli_crypto_hmac_update(&ctx, buf, done);
bzero(buf, sizeof(buf));
if (done == -1)
- err(EX_IOERR, "cannot read keyfile %s", keyfile);
+ err(EX_IOERR, "cannot read keyfile %s", kp->kp_keyfile);
if (fd != STDIN_FILENO)
close(fd);
}
- if (!nopassphrase) {
- p = readpassphrase("Enter passphrase:", buf, sizeof(buf),
- RPP_ECHO_OFF | RPP_REQUIRE_TTY);
- if (p == NULL) {
+ if (!kp->kp_nopassphrase) {
+ if (verify)
+ verify = 1;
+ if (prompt == NULL)
+ prompt = PEFS_KEY_PROMPT_DEFAULT;
+ for (i = 0; i <= verify; i++) {
+ snprintf(promptbuf, sizeof(promptbuf), "%s %s:",
+ !i ? "Enter" : "Reenter", prompt);
+ p = readpassphrase(promptbuf, !i ? buf : buf2, BUFSIZ,
+ RPP_ECHO_OFF | RPP_REQUIRE_TTY);
+ if (p == NULL) {
+ bzero(buf, sizeof(buf));
+ bzero(buf2, sizeof(buf2));
+ errx(EX_DATAERR, "unable to read passphrase");
+ }
+ }
+ if (verify && strcmp(buf, buf2) != 0) {
bzero(buf, sizeof(buf));
- errx(EX_DATAERR, "unable to read passphrase");
+ bzero(buf2, sizeof(buf2));
+ errx(EX_DATAERR, "passphrases didn't match");
}
- if (iterations == 0) {
+ bzero(buf2, sizeof(buf2));
+ if (kp->kp_iterations == 0) {
g_eli_crypto_hmac_update(&ctx, buf, strlen(buf));
} else {
- pkcs5v2_genkey(xk->pxk_key, PEFS_KEY_SIZE, buf, 0, buf, iterations);
+ pkcs5v2_genkey(xk->pxk_key, PEFS_KEY_SIZE, buf, 0, buf, kp->kp_iterations);
g_eli_crypto_hmac_update(&ctx, xk->pxk_key, PEFS_KEY_SIZE);
}
bzero(buf, sizeof(buf));
==== //depot/projects/soc2009/gk_pefs/sbin/pefs/pefs_mount.c#2 (text+ko) ====
@@ -30,28 +30,18 @@
* SUCH DAMAGE.
*/
-#ifndef lint
-static const char copyright[] =
-"@(#) Copyright (c) 1992, 1993, 1994\n\
- The Regents of the University of California. All rights reserved.\n";
-#endif /* not lint */
-
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)mount_null.c 8.6 (Berkeley) 4/26/95";
-#endif
/*
* Ancestors:
* FreeBSD: head/sbin/mount_nullfs/mount_nullfs.c 152670 2005-11-21 22:51:16Z rodrigc
*/
-static const char rcsid[] =
- "$FreeBSD$";
-#endif /* not lint */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/uio.h>
+#include <inttypes.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_crypto.c#5 (text+ko) ====
@@ -119,6 +119,7 @@
case PEFS_ALG_SALSA20:
break;
default:
+ printf("pefs: unknown algorithm %d\n", alg);
return (NULL);
}
==== //depot/projects/soc2009/gk_pefs/sys/fs/pefs/pefs_vnops.c#8 (text+ko) ====
@@ -43,6 +43,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
+#include <sys/fcntl.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
@@ -104,7 +105,7 @@
}
static int
-pefs_enccn_create(struct pefs_enccn *pec, struct pefs_key *pk, struct componentname *cnp)
+pefs_enccn_create(struct pefs_enccn *pec, struct pefs_key *pk, char *tweak, struct componentname *cnp)
{
int r;
@@ -115,7 +116,10 @@
pefs_enccn_init(pec, NULL, cnp->cn_nameptr, cnp->cn_namelen, cnp);
return (0);
}
- arc4rand(pec->pec_tkey.ptk_tweak, PEFS_TWEAK_SIZE, 0);
+ if (tweak == NULL)
+ arc4rand(pec->pec_tkey.ptk_tweak, PEFS_TWEAK_SIZE, 0);
+ else
+ memcpy(pec->pec_tkey.ptk_tweak, tweak, PEFS_TWEAK_SIZE);
pec->pec_tkey.ptk_key = pk;
PEFSDEBUG("%s: pk=%p\n", __func__, pk);
pec->pec_buf = uma_zalloc(namei_zone, M_WAITOK);
@@ -251,7 +255,7 @@
if (error == ENOENT) {
struct pefs_key *dpk = pefs_node_key(VP_TO_PN(dvp));
- error = pefs_enccn_create(pec, dpk, cnp);
+ error = pefs_enccn_create(pec, dpk, NULL, cnp);
pefs_key_release(dpk);
}
PEFSDEBUG("%s: returning = %d\n", __func__, error);
@@ -259,6 +263,22 @@
return (error);
}
+static inline int
+pefs_enccn_lookup_createcopy(struct pefs_enccn *pec, struct pefs_tkey *ptk, struct vnode *dvp, struct componentname *cnp)
+{
+ int error;
+
+ MPASS(ptk->ptk_key != NULL);
+ error = pefs_enccn_lookup(pec, dvp, cnp);
+ PEFSDEBUG("%s: lookup error = %d\n", __func__, error);
+ if (error == ENOENT) {
+ error = pefs_enccn_create(pec, ptk->ptk_key, ptk->ptk_tweak, cnp);
+ }
+ PEFSDEBUG("%s: returning = %d\n", __func__, error);
+
+ return (error);
+}
+
static int
pefs_enccn_get(struct pefs_enccn *pec, struct vnode *vp, struct vnode *dvp, struct componentname *cnp)
{
@@ -297,14 +317,20 @@
* Recycle vnodes using key pk.
* If pk is NULL recycle all vnodes with PN_HASKEY flag set.
*/
+#define PEFS_FLUSHKEY_ALL 1
+
static int
-pefs_flushkey(struct mount *mp, struct pefs_key *pk)
+pefs_flushkey(struct mount *mp, struct thread *td, int flags, struct pefs_key *pk)
{
struct vnode *vp, *mvp;
struct pefs_node *pn;
int error;
PEFSDEBUG("pefs_flushkey: pk=%p\n", pk);
+
+ vflush(mp, 0, 0, td);
+ if ((flags & PEFS_FLUSHKEY_ALL) == 0 && pk == NULL)
+ goto loop_end;
MNT_ILOCK(mp);
loop:
MNT_VNODE_FOREACH(vp, mp, mvp) {
@@ -313,7 +339,7 @@
VI_LOCK(vp);
pn = VP_TO_PN(vp);
if ((pn->pn_flags & PN_HASKEY) &&
- (pk == NULL || pn->pn_tkey.ptk_key == pk)) {
+ ((flags & PEFS_FLUSHKEY_ALL) || pn->pn_tkey.ptk_key == pk)) {
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list