diff options
author | 2019-04-25 16:50:36 +0000 | |
---|---|---|
committer | 2019-04-25 16:50:36 +0000 | |
commit | 6420a52df9e295f58c93015bcf521a31378f426b (patch) | |
tree | c59eb3664753eb37f42e862ce75d3a7135ae6081 | |
parent | Make openprom.4 platform independent. (diff) | |
download | wireguard-openbsd-6420a52df9e295f58c93015bcf521a31378f426b.tar.xz wireguard-openbsd-6420a52df9e295f58c93015bcf521a31378f426b.zip |
Split vnconfig out of mount_vnd, and begin work on a vnd-allocation
option which will ease distribution build.
not connected to the build yet.
-rw-r--r-- | sbin/vnconfig/Makefile | 11 | ||||
-rw-r--r-- | sbin/vnconfig/vnconfig.8 | 163 | ||||
-rw-r--r-- | sbin/vnconfig/vnconfig.c | 350 |
3 files changed, 524 insertions, 0 deletions
diff --git a/sbin/vnconfig/Makefile b/sbin/vnconfig/Makefile new file mode 100644 index 00000000000..15ef23c3041 --- /dev/null +++ b/sbin/vnconfig/Makefile @@ -0,0 +1,11 @@ +# $OpenBSD: Makefile,v 1.1 2019/04/25 16:50:36 deraadt Exp $ + +PROG= vnconfig +LDADD= -lutil +DPADD= ${LIBUTIL} + +CDIAGFLAGS+= -Wall + +MAN= vnconfig.8 + +.include <bsd.prog.mk> diff --git a/sbin/vnconfig/vnconfig.8 b/sbin/vnconfig/vnconfig.8 new file mode 100644 index 00000000000..4c6cc008964 --- /dev/null +++ b/sbin/vnconfig/vnconfig.8 @@ -0,0 +1,163 @@ +.\" $OpenBSD: vnconfig.8,v 1.1 2019/04/25 16:50:36 deraadt Exp $ +.\" +.\" Copyright (c) 1993 University of Utah. +.\" Copyright (c) 1980, 1989, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" This code is derived from software contributed to Berkeley by +.\" the Systems Programming Group of the University of Utah Computer +.\" Science Department. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)vnconfig.8 8.1 (Berkeley) 6/5/93 +.\" +.\" +.\" Copyright (c) 2007 Alexander von Gernler <grunk@openbsd.org> +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: April 25 2019 $ +.Dt VNCONFIG 8 +.Os +.Sh NAME +.Nm vnconfig +.Nd configure vnode disks +.Sh SYNOPSIS +.Nm vnconfig +.Bk -words +.Op Fl kluv +.Op Fl K Ar rounds +.Op Fl S Ar saltfile +.Op Fl t Ar disktype +.Ar vnd_dev +.Ar image +.Sh DESCRIPTION +The +.Nm vnconfig +command configures vnode pseudo disk devices. +It will associate (or disassociate) the special file +.Ar vnd_dev +with the regular file +.Ar image , +allowing the latter to be accessed as though it were a disk. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl K Ar rounds +Associate an encryption key with the device. +All data will be encrypted using the Blowfish cipher before it is +written to the disk. +The user is asked for both a passphrase and the name of a salt file. +The salt file can also be specified on the command line using the +.Fl S +option. +The passphrase and salt are combined according to PKCS #5 PBKDF2 for the +specified number of +rounds to generate the actual key used. +.Ar rounds +is a number between 1000 and +.Dv INT_MAX . +DO NOT LOSE THE SALT FILE. +.It Fl k +Associate an encryption key with the device. +All data will be encrypted using the Blowfish cipher before it is +written to the disk. +.It Fl l +List the vnd devices and indicate which ones are in use. +If a specific +.Ar vnd_dev +is given, then only that one will be described. +.It Fl S Ar saltfile +When +.Fl K +is used, specify the +.Pa saltfile . +.It Fl t Ar disktype +Specify a +.Ar disktype +entry from the +.Xr disktab 5 +database. +The +.Ar vnd_dev +will have the sector size, sectors per track, and tracks per cylinder values +of the specified +.Ar disktype . +The defaults are 512-byte sectors, 100 sectors per track and 1 track per +cylinder. +.It Fl u +Unconfigures a +.Ar vnd_dev . +.It Fl v +Print messages to stdout describing actions taken. +.El +.Sh FILES +.Bl -tag -width /etc/rvnd?? -compact +.It Pa /dev/{,r}vnd* +.El +.Sh EXAMPLES +Configure a CD-ROM or DVD image file as vnode disk vnd0 +and mount the ISO 9660 file system contained in it: +.Bd -literal -offset indent +# vnconfig vnd0 /tmp/diskimage +# mount -t cd9660 /dev/vnd0c /mnt +.Ed +.Pp +Configure an encrypted image file as vnode disk vnd0 and mount the FFS +file system contained in the +.Sq a +partition of the disklabel. +Same as above, but now configure the vnode using PKCS #5 PBKDF2 and +a salt file with 20000 rounds: +.Bd -literal -offset indent +# vnconfig -K 20000 vnd0 /tmp/cryptimg +Encryption key: +Salt file: /tmp/cryptsalt +# mount /dev/vnd0a /mnt +.Ed +.Pp +.Sh SEE ALSO +.Xr vnd 4 , +.Xr disktab 5 , +.Xr fstab 5 , +.Xr mount 8 , +.Xr swapon 8 , +.Xr umount 8 +.Sh HISTORY +The +.Nm +command first appeared in +.Ox 4.2 . diff --git a/sbin/vnconfig/vnconfig.c b/sbin/vnconfig/vnconfig.c new file mode 100644 index 00000000000..81c53414fd2 --- /dev/null +++ b/sbin/vnconfig/vnconfig.c @@ -0,0 +1,350 @@ +/* $OpenBSD: vnconfig.c,v 1.1 2019/04/25 16:50:36 deraadt Exp $ */ +/* + * Copyright (c) 1993 University of Utah. + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * the Systems Programming Group of the University of Utah Computer + * Science Department. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. +e */ + +#include <sys/param.h> /* DEV_BSIZE */ +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/disklabel.h> + +#include <dev/vndioctl.h> + +#include <blf.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <readpassphrase.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <limits.h> +#include <util.h> + +#define DEFAULT_VND "vnd0" + +#define VND_CONFIG 1 +#define VND_UNCONFIG 2 +#define VND_GETINFO 3 + +int verbose = 0; +int opt_A; + +__dead void usage(void); +int config(char **, int, struct disklabel *, char *, size_t); +int getinfo(const char *, int *availp); +char *get_pkcs_key(char *, char *); + +int +main(int argc, char **argv) +{ + int ch, rv, action, opt_k = 0, opt_K = 0, opt_l = 0, opt_u = 0; + char *key = NULL, *rounds = NULL, *saltopt = NULL; + size_t keylen = 0; + extern char *__progname; + struct disklabel *dp = NULL; + + action = VND_CONFIG; + + while ((ch = getopt(argc, argv, "AckK:lo:S:t:uv")) != -1) { + switch (ch) { + case 'c': + /* backwards compat */ + break; + case 'A': + opt_A = 1; + break; + case 'k': + opt_k = 1; + break; + case 'K': + opt_K = 1; + rounds = optarg; + break; + case 'l': + opt_l = 1; + break; + case 'S': + saltopt = optarg; + break; + case 't': + dp = getdiskbyname(optarg); + if (dp == NULL) + errx(1, "unknown disk type: %s", optarg); + break; + case 'u': + opt_u = 1; + break; + case 'v': + verbose = 1; + break; + default: + usage(); + /* NOTREACHED */ + } + } + argc -= optind; + argv += optind; + + if (opt_l + opt_u > 1) + errx(1, "-l and -u are mutually exclusive options"); + + if (opt_l) + action = VND_GETINFO; + else if (opt_u) + action = VND_UNCONFIG; + + if (saltopt && (!opt_K)) + errx(1, "-S only makes sense when used with -K"); + + if (action == VND_CONFIG) { + if (opt_A == 0 && argc != 2) + usage(); + if (opt_A == 1 && argc != 1) + usage(); + + if (opt_k || opt_K) + fprintf(stderr, "WARNING: Consider using softraid crypto.\n"); + if (opt_k) { + if (opt_K) + errx(1, "-k and -K are mutually exclusive"); + key = getpass("Encryption key: "); + if (key == NULL || (keylen = strlen(key)) == 0) + errx(1, "Need an encryption key"); + } else if (opt_K) { + key = get_pkcs_key(rounds, saltopt); + keylen = BLF_MAXUTILIZED; + } + rv = config(argv, action, dp, key, keylen); + } else if (action == VND_UNCONFIG && argc == 1) + rv = config(argv, action, NULL, NULL, 0); + else if (action == VND_GETINFO) + rv = getinfo(argc ? argv[0] : NULL, NULL); + else + usage(); + + exit(rv); +} + +char * +get_pkcs_key(char *arg, char *saltopt) +{ + char passphrase[128] = {'\0'}; + char saltbuf[128] = {'\0'}, saltfilebuf[PATH_MAX]; + char *key = NULL; + char *saltfile; + const char *errstr; + int rounds; + + rounds = strtonum(arg, 1000, INT_MAX, &errstr); + if (errstr) + err(1, "rounds: %s", errstr); + if (readpassphrase("Encryption key: ", passphrase, sizeof(passphrase), + RPP_REQUIRE_TTY) == NULL) + errx(1, "Unable to read passphrase"); + if (saltopt) + saltfile = saltopt; + else { + printf("Salt file: "); + fflush(stdout); + saltfile = fgets(saltfilebuf, sizeof(saltfilebuf), stdin); + if (saltfile) + saltfile[strcspn(saltfile, "\n")] = '\0'; + } + if (!saltfile || saltfile[0] == '\0') + warnx("Skipping salt file, insecure"); + else { + int fd; + + fd = open(saltfile, O_RDONLY); + if (fd == -1) { + int *s; + + fprintf(stderr, "Salt file not found, attempting to " + "create one\n"); + fd = open(saltfile, O_RDWR|O_CREAT|O_EXCL, 0600); + if (fd == -1) + err(1, "Unable to create salt file: '%s'", + saltfile); + for (s = (int *)saltbuf; + s < (int *)(saltbuf + sizeof(saltbuf)); s++) + *s = arc4random(); + if (write(fd, saltbuf, sizeof(saltbuf)) + != sizeof(saltbuf)) + err(1, "Unable to write salt file: '%s'", + saltfile); + fprintf(stderr, "Salt file created as '%s'\n", + saltfile); + } else { + if (read(fd, saltbuf, sizeof(saltbuf)) + != sizeof(saltbuf)) + err(1, "Unable to read salt file: '%s'", + saltfile); + } + close(fd); + } + if ((key = calloc(1, BLF_MAXUTILIZED)) == NULL) + err(1, NULL); + if (pkcs5_pbkdf2(passphrase, sizeof(passphrase), saltbuf, + sizeof (saltbuf), key, BLF_MAXUTILIZED, rounds)) + errx(1, "pkcs5_pbkdf2 failed"); + explicit_bzero(passphrase, sizeof(passphrase)); + + return (key); +} + +int +getinfo(const char *vname, int *availp) +{ + int vd, print_all = 0; + struct vnd_user vnu; + + if (vname == NULL) { + vname = DEFAULT_VND; + print_all = 1; + } + + vd = opendev((char *)vname, O_RDONLY, OPENDEV_PART, NULL); + if (vd < 0) + err(1, "open: %s", vname); + + vnu.vnu_unit = -1; + +query: + if (ioctl(vd, VNDIOCGET, &vnu) == -1) { + if (print_all && errno == ENXIO && vnu.vnu_unit > 0) + goto end; + err(1, "ioctl: %s", vname); + } + + if (availp) { + if (!vnu.vnu_ino) { + *availp = vnu.vnu_unit; + close(vd); + return (0); + } + vnu.vnu_unit++; + goto query; + } + + fprintf(stdout, "vnd%d: ", vnu.vnu_unit); + + if (!vnu.vnu_ino) + fprintf(stdout, "not in use\n"); + else + fprintf(stdout, "covering %s on %s, inode %llu\n", + vnu.vnu_file, devname(vnu.vnu_dev, S_IFBLK), + (unsigned long long)vnu.vnu_ino); + + if (print_all) { + vnu.vnu_unit++; + goto query; + } + +end: + close(vd); + if (availp) + return (-1); + return (0); +} + +int +config(char **argv, int action, struct disklabel *dp, char *key, size_t keylen) +{ + struct vnd_ioctl vndio; + char *rdev, *dev, *file; + int fd, rv = -1; + int unit; + + if (opt_A) { + if (getinfo(NULL, &unit) == -1) + err(1, "no devices available"); + printf("vnd%d\n", unit); + asprintf(&dev, "vnd%d", unit); + file = argv[0]; + } else { + dev = argv[0]; + file = argv[1]; + } + + if ((fd = opendev(dev, O_RDONLY, OPENDEV_PART, &rdev)) < 0) { + err(4, "%s", rdev); + goto out; + } + + vndio.vnd_file = file; + vndio.vnd_secsize = (dp && dp->d_secsize) ? dp->d_secsize : DEV_BSIZE; + vndio.vnd_nsectors = (dp && dp->d_nsectors) ? dp->d_nsectors : 100; + vndio.vnd_ntracks = (dp && dp->d_ntracks) ? dp->d_ntracks : 1; + vndio.vnd_key = (u_char *)key; + vndio.vnd_keylen = keylen; + + /* + * Clear (un-configure) the device + */ + if (action == VND_UNCONFIG) { + rv = ioctl(fd, VNDIOCCLR, &vndio); + if (rv) + warn("VNDIOCCLR"); + else if (verbose) + printf("%s: cleared\n", dev); + } + /* + * Configure the device + */ + if (action == VND_CONFIG) { + rv = ioctl(fd, VNDIOCSET, &vndio); + if (rv) + warn("VNDIOCSET"); + else if (verbose) + printf("%s: %llu bytes on %s\n", dev, vndio.vnd_size, + file); + } + + close(fd); + fflush(stdout); + out: + if (key) + explicit_bzero(key, keylen); + return (rv < 0); +} + +__dead void +usage(void) +{ + (void)fprintf(stderr, + "usage: vnconfig [-Ackluv] [-K rounds] [-S saltfile] " + "[-t disktype] vnd_dev image\n"); + exit(1); +} |