Hide length of geli passphrase during boot.
Introduce additional flag to the geli which allows to restore previous behavior. Reviewed by: AllanJude@, cem@ (previous version) MFC: 1 month Relnotes: yes Differential Revision: https://reviews.freebsd.org/D11751
This commit is contained in:
parent
b92e8635f9
commit
3453dc72ad
4
UPDATING
4
UPDATING
@ -51,6 +51,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW:
|
||||
|
||||
****************************** SPECIAL WARNING: ******************************
|
||||
|
||||
20170826:
|
||||
During boot the geli passphrase will be hidden. To restore previous
|
||||
behavior see geli(8) configuration options.
|
||||
|
||||
20170825:
|
||||
Move PMTUD blackhole counters to TCPSTATS and remove them from bare
|
||||
sysctl values. Minor nit, but requires a rebuild of both world/kernel
|
||||
|
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd August 3, 2016
|
||||
.Dd August 26, 2017
|
||||
.Dt GELI 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -51,7 +51,7 @@ utility:
|
||||
.Pp
|
||||
.Nm
|
||||
.Cm init
|
||||
.Op Fl bgPTv
|
||||
.Op Fl bdgPTv
|
||||
.Op Fl a Ar aalgo
|
||||
.Op Fl B Ar backupfile
|
||||
.Op Fl e Ar ealgo
|
||||
@ -88,7 +88,7 @@ utility:
|
||||
.Ar prov
|
||||
.Nm
|
||||
.Cm configure
|
||||
.Op Fl bBgGtT
|
||||
.Op Fl bBdDgGtT
|
||||
.Ar prov ...
|
||||
.Nm
|
||||
.Cm setkey
|
||||
@ -279,6 +279,9 @@ To inhibit backups, you can use
|
||||
.Pa none
|
||||
as the
|
||||
.Ar backupfile .
|
||||
.It Fl d
|
||||
While booting from this encrypted root filesystem enable visibility of
|
||||
passphrase length.
|
||||
.It Fl e Ar ealgo
|
||||
Encryption algorithm to use.
|
||||
Currently supported algorithms are:
|
||||
@ -490,6 +493,12 @@ For more information, see the description of the
|
||||
subcommand.
|
||||
.It Fl B
|
||||
Remove the BOOT flag from the given providers.
|
||||
.It Fl d
|
||||
While booting from this encrypted root filesystem enable visibility of
|
||||
passphrase length.
|
||||
.It Fl D
|
||||
While booting from this encrypted root filesystem disable visibility of
|
||||
passphrase length.
|
||||
.It Fl g
|
||||
Enable booting from this encrypted root filesystem.
|
||||
The boot loader prompts for the passphrase and loads
|
||||
|
@ -82,7 +82,7 @@ static int eli_backup_create(struct gctl_req *req, const char *prov,
|
||||
/*
|
||||
* Available commands:
|
||||
*
|
||||
* init [-bgPTv] [-a aalgo] [-B backupfile] [-e ealgo] [-i iterations] [-l keylen] [-J newpassfile] [-K newkeyfile] [-s sectorsize] [-V version] prov
|
||||
* init [-bdgPTv] [-a aalgo] [-B backupfile] [-e ealgo] [-i iterations] [-l keylen] [-J newpassfile] [-K newkeyfile] [-s sectorsize] [-V version] prov
|
||||
* label - alias for 'init'
|
||||
* attach [-dprv] [-j passfile] [-k keyfile] prov
|
||||
* detach [-fl] prov ...
|
||||
@ -107,6 +107,7 @@ struct g_command class_commands[] = {
|
||||
{ 'a', "aalgo", "", G_TYPE_STRING },
|
||||
{ 'b', "boot", NULL, G_TYPE_BOOL },
|
||||
{ 'B', "backupfile", "", G_TYPE_STRING },
|
||||
{ 'd', "displaypass", NULL, G_TYPE_BOOL },
|
||||
{ 'e', "ealgo", "", G_TYPE_STRING },
|
||||
{ 'g', "geliboot", NULL, G_TYPE_BOOL },
|
||||
{ 'i', "iterations", "-1", G_TYPE_NUMBER },
|
||||
@ -119,13 +120,14 @@ struct g_command class_commands[] = {
|
||||
{ 'V', "mdversion", "-1", G_TYPE_NUMBER },
|
||||
G_OPT_SENTINEL
|
||||
},
|
||||
"[-bgPTv] [-a aalgo] [-B backupfile] [-e ealgo] [-i iterations] [-l keylen] [-J newpassfile] [-K newkeyfile] [-s sectorsize] [-V version] prov"
|
||||
"[-bdgPTv] [-a aalgo] [-B backupfile] [-e ealgo] [-i iterations] [-l keylen] [-J newpassfile] [-K newkeyfile] [-s sectorsize] [-V version] prov"
|
||||
},
|
||||
{ "label", G_FLAG_VERBOSE, eli_main,
|
||||
{
|
||||
{ 'a', "aalgo", "", G_TYPE_STRING },
|
||||
{ 'b', "boot", NULL, G_TYPE_BOOL },
|
||||
{ 'B', "backupfile", "", G_TYPE_STRING },
|
||||
{ 'd', "displaypass", NULL, G_TYPE_BOOL },
|
||||
{ 'e', "ealgo", "", G_TYPE_STRING },
|
||||
{ 'g', "geliboot", NULL, G_TYPE_BOOL },
|
||||
{ 'i', "iterations", "-1", G_TYPE_NUMBER },
|
||||
@ -182,13 +184,15 @@ struct g_command class_commands[] = {
|
||||
{
|
||||
{ 'b', "boot", NULL, G_TYPE_BOOL },
|
||||
{ 'B', "noboot", NULL, G_TYPE_BOOL },
|
||||
{ 'd', "displaypass", NULL, G_TYPE_BOOL },
|
||||
{ 'D', "nodisplaypass", NULL, G_TYPE_BOOL },
|
||||
{ 'g', "geliboot", NULL, G_TYPE_BOOL },
|
||||
{ 'G', "nogeliboot", NULL, G_TYPE_BOOL },
|
||||
{ 't', "trim", NULL, G_TYPE_BOOL },
|
||||
{ 'T', "notrim", NULL, G_TYPE_BOOL },
|
||||
G_OPT_SENTINEL
|
||||
},
|
||||
"[-bBgGtT] prov ..."
|
||||
"[-bBdDgGtT] prov ..."
|
||||
},
|
||||
{ "setkey", G_FLAG_VERBOSE, eli_main,
|
||||
{
|
||||
@ -708,6 +712,8 @@ eli_init(struct gctl_req *req)
|
||||
md.md_flags |= G_ELI_FLAG_BOOT;
|
||||
if (gctl_get_int(req, "geliboot"))
|
||||
md.md_flags |= G_ELI_FLAG_GELIBOOT;
|
||||
if (gctl_get_int(req, "displaypass"))
|
||||
md.md_flags |= G_ELI_FLAG_GELIDISPLAYPASS;
|
||||
if (gctl_get_int(req, "notrim"))
|
||||
md.md_flags |= G_ELI_FLAG_NODELETE;
|
||||
md.md_ealgo = CRYPTO_ALGORITHM_MIN - 1;
|
||||
@ -912,7 +918,7 @@ eli_attach(struct gctl_req *req)
|
||||
|
||||
static void
|
||||
eli_configure_detached(struct gctl_req *req, const char *prov, int boot,
|
||||
int geliboot, int trim)
|
||||
int geliboot, int displaypass, int trim)
|
||||
{
|
||||
struct g_eli_metadata md;
|
||||
bool changed = 0;
|
||||
@ -948,6 +954,21 @@ eli_configure_detached(struct gctl_req *req, const char *prov, int boot,
|
||||
changed = 1;
|
||||
}
|
||||
|
||||
if (displaypass == 1 && (md.md_flags & G_ELI_FLAG_GELIDISPLAYPASS)) {
|
||||
if (verbose)
|
||||
printf("GELIDISPLAYPASS flag already configured for %s.\n", prov);
|
||||
} else if (displaypass == 0 &&
|
||||
!(md.md_flags & G_ELI_FLAG_GELIDISPLAYPASS)) {
|
||||
if (verbose)
|
||||
printf("GELIDISPLAYPASS flag not configured for %s.\n", prov);
|
||||
} else if (displaypass >= 0) {
|
||||
if (displaypass)
|
||||
md.md_flags |= G_ELI_FLAG_GELIDISPLAYPASS;
|
||||
else
|
||||
md.md_flags &= ~G_ELI_FLAG_GELIDISPLAYPASS;
|
||||
changed = 1;
|
||||
}
|
||||
|
||||
if (trim == 0 && (md.md_flags & G_ELI_FLAG_NODELETE)) {
|
||||
if (verbose)
|
||||
printf("TRIM disable flag already configured for %s.\n", prov);
|
||||
@ -971,8 +992,9 @@ static void
|
||||
eli_configure(struct gctl_req *req)
|
||||
{
|
||||
const char *prov;
|
||||
bool boot, noboot, geliboot, nogeliboot, trim, notrim;
|
||||
int doboot, dogeliboot, dotrim;
|
||||
bool boot, noboot, geliboot, nogeliboot, displaypass, nodisplaypass;
|
||||
bool trim, notrim;
|
||||
int doboot, dogeliboot, dodisplaypass, dotrim;
|
||||
int i, nargs;
|
||||
|
||||
nargs = gctl_get_int(req, "nargs");
|
||||
@ -985,6 +1007,8 @@ eli_configure(struct gctl_req *req)
|
||||
noboot = gctl_get_int(req, "noboot");
|
||||
geliboot = gctl_get_int(req, "geliboot");
|
||||
nogeliboot = gctl_get_int(req, "nogeliboot");
|
||||
displaypass = gctl_get_int(req, "displaypass");
|
||||
nodisplaypass = gctl_get_int(req, "nodisplaypass");
|
||||
trim = gctl_get_int(req, "trim");
|
||||
notrim = gctl_get_int(req, "notrim");
|
||||
|
||||
@ -1008,6 +1032,16 @@ eli_configure(struct gctl_req *req)
|
||||
else if (nogeliboot)
|
||||
dogeliboot = 0;
|
||||
|
||||
dodisplaypass = -1;
|
||||
if (displaypass && nodisplaypass) {
|
||||
gctl_error(req, "Options -d and -D are mutually exclusive.");
|
||||
return;
|
||||
}
|
||||
if (displaypass)
|
||||
dodisplaypass = 1;
|
||||
else if (nodisplaypass)
|
||||
dodisplaypass = 0;
|
||||
|
||||
dotrim = -1;
|
||||
if (trim && notrim) {
|
||||
gctl_error(req, "Options -t and -T are mutually exclusive.");
|
||||
@ -1018,7 +1052,8 @@ eli_configure(struct gctl_req *req)
|
||||
else if (notrim)
|
||||
dotrim = 0;
|
||||
|
||||
if (doboot == -1 && dogeliboot == -1 && dotrim == -1) {
|
||||
if (doboot == -1 && dogeliboot == -1 && dodisplaypass == -1 &&
|
||||
dotrim == -1) {
|
||||
gctl_error(req, "No option given.");
|
||||
return;
|
||||
}
|
||||
@ -1028,8 +1063,10 @@ eli_configure(struct gctl_req *req)
|
||||
/* Now the rest. */
|
||||
for (i = 0; i < nargs; i++) {
|
||||
prov = gctl_get_ascii(req, "arg%d", i);
|
||||
if (!eli_is_attached(prov))
|
||||
eli_configure_detached(req, prov, doboot, dogeliboot, dotrim);
|
||||
if (!eli_is_attached(prov)) {
|
||||
eli_configure_detached(req, prov, doboot, dogeliboot,
|
||||
dodisplaypass, dotrim);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,8 +220,9 @@ geli_taste(int read_func(void *vdev, void *priv, off_t off, void *buf,
|
||||
/*
|
||||
* Attempt to decrypt the device
|
||||
*/
|
||||
int
|
||||
geli_attach(struct dsk *dskp, const char *passphrase, const u_char *mkeyp)
|
||||
static int
|
||||
geli_attach(struct geli_entry *ge, struct dsk *dskp, const char *passphrase,
|
||||
const u_char *mkeyp)
|
||||
{
|
||||
u_char key[G_ELI_USERKEYLEN], mkey[G_ELI_DATAIVKEYLEN], *mkp;
|
||||
u_int keynum;
|
||||
@ -233,92 +234,83 @@ geli_attach(struct dsk *dskp, const char *passphrase, const u_char *mkeyp)
|
||||
explicit_bzero(mkeyp, G_ELI_DATAIVKEYLEN);
|
||||
}
|
||||
|
||||
SLIST_FOREACH_SAFE(geli_e, &geli_head, entries, geli_e_tmp) {
|
||||
if (geli_same_device(geli_e, dskp) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mkeyp != NULL || geli_findkey(geli_e, dskp, mkey) == 0) {
|
||||
goto found_key;
|
||||
}
|
||||
|
||||
g_eli_crypto_hmac_init(&ctx, NULL, 0);
|
||||
/*
|
||||
* Prepare Derived-Key from the user passphrase.
|
||||
*/
|
||||
if (geli_e->md.md_iterations < 0) {
|
||||
/* XXX TODO: Support loading key files. */
|
||||
return (1);
|
||||
} else if (geli_e->md.md_iterations == 0) {
|
||||
g_eli_crypto_hmac_update(&ctx, geli_e->md.md_salt,
|
||||
sizeof(geli_e->md.md_salt));
|
||||
g_eli_crypto_hmac_update(&ctx, passphrase,
|
||||
strlen(passphrase));
|
||||
} else if (geli_e->md.md_iterations > 0) {
|
||||
printf("Calculating GELI Decryption Key disk%dp%d @ %d"
|
||||
" iterations...\n", dskp->unit,
|
||||
(dskp->slice > 0 ? dskp->slice : dskp->part),
|
||||
geli_e->md.md_iterations);
|
||||
u_char dkey[G_ELI_USERKEYLEN];
|
||||
|
||||
pkcs5v2_genkey(dkey, sizeof(dkey), geli_e->md.md_salt,
|
||||
sizeof(geli_e->md.md_salt), passphrase,
|
||||
geli_e->md.md_iterations);
|
||||
g_eli_crypto_hmac_update(&ctx, dkey, sizeof(dkey));
|
||||
explicit_bzero(dkey, sizeof(dkey));
|
||||
}
|
||||
|
||||
g_eli_crypto_hmac_final(&ctx, key, 0);
|
||||
|
||||
error = g_eli_mkey_decrypt(&geli_e->md, key, mkey, &keynum);
|
||||
if (error == -1) {
|
||||
explicit_bzero(mkey, sizeof(mkey));
|
||||
explicit_bzero(key, sizeof(key));
|
||||
printf("Bad GELI key: bad password?\n");
|
||||
return (error);
|
||||
} else if (error != 0) {
|
||||
explicit_bzero(mkey, sizeof(mkey));
|
||||
explicit_bzero(key, sizeof(key));
|
||||
printf("Failed to decrypt GELI master key: %d\n", error);
|
||||
return (error);
|
||||
} else {
|
||||
/* Add key to keychain */
|
||||
save_key(key);
|
||||
explicit_bzero(&key, sizeof(key));
|
||||
}
|
||||
|
||||
found_key:
|
||||
/* Store the keys */
|
||||
bcopy(mkey, geli_e->sc.sc_mkey, sizeof(geli_e->sc.sc_mkey));
|
||||
bcopy(mkey, geli_e->sc.sc_ivkey, sizeof(geli_e->sc.sc_ivkey));
|
||||
mkp = mkey + sizeof(geli_e->sc.sc_ivkey);
|
||||
if ((geli_e->sc.sc_flags & G_ELI_FLAG_AUTH) == 0) {
|
||||
bcopy(mkp, geli_e->sc.sc_ekey, G_ELI_DATAKEYLEN);
|
||||
} else {
|
||||
/*
|
||||
* The encryption key is: ekey = HMAC_SHA512(Data-Key, 0x10)
|
||||
*/
|
||||
g_eli_crypto_hmac(mkp, G_ELI_MAXKEYLEN, "\x10", 1,
|
||||
geli_e->sc.sc_ekey, 0);
|
||||
}
|
||||
explicit_bzero(mkey, sizeof(mkey));
|
||||
|
||||
/* Initialize the per-sector IV. */
|
||||
switch (geli_e->sc.sc_ealgo) {
|
||||
case CRYPTO_AES_XTS:
|
||||
break;
|
||||
default:
|
||||
SHA256_Init(&geli_e->sc.sc_ivctx);
|
||||
SHA256_Update(&geli_e->sc.sc_ivctx, geli_e->sc.sc_ivkey,
|
||||
sizeof(geli_e->sc.sc_ivkey));
|
||||
break;
|
||||
}
|
||||
|
||||
return (0);
|
||||
if (mkeyp != NULL || geli_findkey(ge, dskp, mkey) == 0) {
|
||||
goto found_key;
|
||||
}
|
||||
|
||||
/* Disk not found. */
|
||||
return (2);
|
||||
g_eli_crypto_hmac_init(&ctx, NULL, 0);
|
||||
/*
|
||||
* Prepare Derived-Key from the user passphrase.
|
||||
*/
|
||||
if (geli_e->md.md_iterations < 0) {
|
||||
/* XXX TODO: Support loading key files. */
|
||||
return (1);
|
||||
} else if (geli_e->md.md_iterations == 0) {
|
||||
g_eli_crypto_hmac_update(&ctx, geli_e->md.md_salt,
|
||||
sizeof(geli_e->md.md_salt));
|
||||
g_eli_crypto_hmac_update(&ctx, passphrase,
|
||||
strlen(passphrase));
|
||||
} else if (geli_e->md.md_iterations > 0) {
|
||||
printf("Calculating GELI Decryption Key disk%dp%d @ %d"
|
||||
" iterations...\n", dskp->unit,
|
||||
(dskp->slice > 0 ? dskp->slice : dskp->part),
|
||||
geli_e->md.md_iterations);
|
||||
u_char dkey[G_ELI_USERKEYLEN];
|
||||
|
||||
pkcs5v2_genkey(dkey, sizeof(dkey), geli_e->md.md_salt,
|
||||
sizeof(geli_e->md.md_salt), passphrase,
|
||||
geli_e->md.md_iterations);
|
||||
g_eli_crypto_hmac_update(&ctx, dkey, sizeof(dkey));
|
||||
explicit_bzero(dkey, sizeof(dkey));
|
||||
}
|
||||
|
||||
g_eli_crypto_hmac_final(&ctx, key, 0);
|
||||
|
||||
error = g_eli_mkey_decrypt(&geli_e->md, key, mkey, &keynum);
|
||||
if (error == -1) {
|
||||
explicit_bzero(mkey, sizeof(mkey));
|
||||
explicit_bzero(key, sizeof(key));
|
||||
printf("Bad GELI key: bad password?\n");
|
||||
return (error);
|
||||
} else if (error != 0) {
|
||||
explicit_bzero(mkey, sizeof(mkey));
|
||||
explicit_bzero(key, sizeof(key));
|
||||
printf("Failed to decrypt GELI master key: %d\n", error);
|
||||
return (error);
|
||||
} else {
|
||||
/* Add key to keychain */
|
||||
save_key(key);
|
||||
explicit_bzero(&key, sizeof(key));
|
||||
}
|
||||
|
||||
found_key:
|
||||
/* Store the keys */
|
||||
bcopy(mkey, geli_e->sc.sc_mkey, sizeof(geli_e->sc.sc_mkey));
|
||||
bcopy(mkey, geli_e->sc.sc_ivkey, sizeof(geli_e->sc.sc_ivkey));
|
||||
mkp = mkey + sizeof(geli_e->sc.sc_ivkey);
|
||||
if ((geli_e->sc.sc_flags & G_ELI_FLAG_AUTH) == 0) {
|
||||
bcopy(mkp, geli_e->sc.sc_ekey, G_ELI_DATAKEYLEN);
|
||||
} else {
|
||||
/*
|
||||
* The encryption key is: ekey = HMAC_SHA512(Data-Key, 0x10)
|
||||
*/
|
||||
g_eli_crypto_hmac(mkp, G_ELI_MAXKEYLEN, "\x10", 1,
|
||||
geli_e->sc.sc_ekey, 0);
|
||||
}
|
||||
explicit_bzero(mkey, sizeof(mkey));
|
||||
|
||||
/* Initialize the per-sector IV. */
|
||||
switch (geli_e->sc.sc_ealgo) {
|
||||
case CRYPTO_AES_XTS:
|
||||
break;
|
||||
default:
|
||||
SHA256_Init(&geli_e->sc.sc_ivctx);
|
||||
SHA256_Update(&geli_e->sc.sc_ivctx, geli_e->sc.sc_ivkey,
|
||||
sizeof(geli_e->sc.sc_ivkey));
|
||||
break;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
@ -402,7 +394,7 @@ geli_havekey(struct dsk *dskp)
|
||||
}
|
||||
|
||||
if (geli_findkey(geli_e, dskp, mkey) == 0) {
|
||||
if (geli_attach(dskp, NULL, mkey) == 0) {
|
||||
if (geli_attach(geli_e, dskp, NULL, mkey) == 0) {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
@ -417,20 +409,28 @@ geli_passphrase(char *pw, int disk, int parttype, int part, struct dsk *dskp)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* TODO: Implement GELI keyfile(s) support */
|
||||
for (i = 0; i < 3; i++) {
|
||||
/* Try cached passphrase */
|
||||
if (i == 0 && pw[0] != '\0') {
|
||||
if (geli_attach(dskp, pw, NULL) == 0) {
|
||||
SLIST_FOREACH_SAFE(geli_e, &geli_head, entries, geli_e_tmp) {
|
||||
if (geli_same_device(geli_e, dskp) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* TODO: Implement GELI keyfile(s) support */
|
||||
for (i = 0; i < 3; i++) {
|
||||
/* Try cached passphrase */
|
||||
if (i == 0 && pw[0] != '\0') {
|
||||
if (geli_attach(geli_e, dskp, pw, NULL) == 0) {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
printf("GELI Passphrase for disk%d%c%d: ", disk,
|
||||
parttype, part);
|
||||
pwgets(pw, GELI_PW_MAXLEN,
|
||||
(geli_e->md.md_flags & G_ELI_FLAG_GELIDISPLAYPASS) == 0);
|
||||
printf("\n");
|
||||
if (geli_attach(geli_e, dskp, pw, NULL) == 0) {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
printf("GELI Passphrase for disk%d%c%d: ", disk, parttype, part);
|
||||
pwgets(pw, GELI_PW_MAXLEN);
|
||||
printf("\n");
|
||||
if (geli_attach(dskp, pw, NULL) == 0) {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
return (1);
|
||||
|
@ -46,12 +46,11 @@
|
||||
#define GELI_MAX_KEYS 64
|
||||
#define GELI_PW_MAXLEN 256
|
||||
|
||||
extern void pwgets(char *buf, int n);
|
||||
extern void pwgets(char *buf, int n, int hide);
|
||||
|
||||
void geli_init(void);
|
||||
int geli_taste(int read_func(void *vdev, void *priv, off_t off,
|
||||
void *buf, size_t bytes), struct dsk *dsk, daddr_t lastsector);
|
||||
int geli_attach(struct dsk *dskp, const char *passphrase, const u_char *mkeyp);
|
||||
int is_geli(struct dsk *dsk);
|
||||
int geli_read(struct dsk *dsk, off_t offset, u_char *buf, size_t bytes);
|
||||
int geli_decrypt(u_int algo, u_char *data, size_t datasize,
|
||||
|
@ -39,7 +39,7 @@ __FBSDID("$FreeBSD$");
|
||||
/* gets() with constrained input length, for passwords */
|
||||
|
||||
void
|
||||
pwgets(char *buf, int n)
|
||||
pwgets(char *buf, int n, int hide)
|
||||
{
|
||||
int c;
|
||||
char *lp;
|
||||
@ -55,9 +55,11 @@ pwgets(char *buf, int n)
|
||||
case '\177':
|
||||
if (lp > buf) {
|
||||
lp--;
|
||||
putchar('\b');
|
||||
putchar(' ');
|
||||
putchar('\b');
|
||||
if (hide == 0) {
|
||||
putchar('\b');
|
||||
putchar(' ');
|
||||
putchar('\b');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'u'&037:
|
||||
@ -68,7 +70,9 @@ pwgets(char *buf, int n)
|
||||
default:
|
||||
if ((n < 1) || ((lp - buf) < n - 1)) {
|
||||
*lp++ = c;
|
||||
putchar('*');
|
||||
if (hide == 0) {
|
||||
putchar('*');
|
||||
}
|
||||
}
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
|
@ -1023,7 +1023,7 @@ g_eli_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
|
||||
struct hmac_ctx ctx;
|
||||
char passphrase[256];
|
||||
u_char key[G_ELI_USERKEYLEN], mkey[G_ELI_DATAIVKEYLEN];
|
||||
u_int i, nkey, nkeyfiles, tries;
|
||||
u_int i, nkey, nkeyfiles, tries, showpass;
|
||||
int error;
|
||||
struct keybuf *keybuf;
|
||||
|
||||
@ -1112,8 +1112,11 @@ g_eli_taste(struct g_class *mp, struct g_provider *pp, int flags __unused)
|
||||
sizeof(passphrase));
|
||||
} else {
|
||||
printf("Enter passphrase for %s: ", pp->name);
|
||||
showpass = g_eli_visible_passphrase;
|
||||
if ((md.md_flags & G_ELI_FLAG_GELIDISPLAYPASS) != 0)
|
||||
showpass = GETS_ECHOPASS;
|
||||
cngets(passphrase, sizeof(passphrase),
|
||||
g_eli_visible_passphrase);
|
||||
showpass);
|
||||
memcpy(cached_passphrase, passphrase,
|
||||
sizeof(passphrase));
|
||||
}
|
||||
@ -1232,6 +1235,7 @@ g_eli_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp,
|
||||
ADD_FLAG(G_ELI_FLAG_RO, "READ-ONLY");
|
||||
ADD_FLAG(G_ELI_FLAG_NODELETE, "NODELETE");
|
||||
ADD_FLAG(G_ELI_FLAG_GELIBOOT, "GELIBOOT");
|
||||
ADD_FLAG(G_ELI_FLAG_GELIDISPLAYPASS, "GELIDISPLAYPASS");
|
||||
#undef ADD_FLAG
|
||||
}
|
||||
sbuf_printf(sb, "</Flags>\n");
|
||||
|
@ -100,6 +100,8 @@
|
||||
#define G_ELI_FLAG_NODELETE 0x00000040
|
||||
/* This GELI supports GELIBoot */
|
||||
#define G_ELI_FLAG_GELIBOOT 0x00000080
|
||||
/* Hide passphrase length in GELIboot. */
|
||||
#define G_ELI_FLAG_GELIDISPLAYPASS 0x00000100
|
||||
/* RUNTIME FLAGS. */
|
||||
/* Provider was open for writing. */
|
||||
#define G_ELI_FLAG_WOPEN 0x00010000
|
||||
|
@ -377,6 +377,7 @@ g_eli_ctl_configure(struct gctl_req *req, struct g_class *mp)
|
||||
const char *prov;
|
||||
u_char *sector;
|
||||
int *nargs, *boot, *noboot, *trim, *notrim, *geliboot, *nogeliboot;
|
||||
int *displaypass, *nodisplaypass;
|
||||
int zero, error, changed;
|
||||
u_int i;
|
||||
|
||||
@ -434,6 +435,19 @@ g_eli_ctl_configure(struct gctl_req *req, struct g_class *mp)
|
||||
if (*geliboot || *nogeliboot)
|
||||
changed = 1;
|
||||
|
||||
displaypass = gctl_get_paraml(req, "displaypass", sizeof(*displaypass));
|
||||
if (displaypass == NULL)
|
||||
displaypass = &zero;
|
||||
nodisplaypass = gctl_get_paraml(req, "nodisplaypass", sizeof(*nodisplaypass));
|
||||
if (nodisplaypass == NULL)
|
||||
nodisplaypass = &zero;
|
||||
if (*displaypass && *nodisplaypass) {
|
||||
gctl_error(req, "Options -d and -D are mutually exclusive.");
|
||||
return;
|
||||
}
|
||||
if (*displaypass || *nodisplaypass)
|
||||
changed = 1;
|
||||
|
||||
if (!changed) {
|
||||
gctl_error(req, "No option given.");
|
||||
return;
|
||||
@ -492,6 +506,17 @@ g_eli_ctl_configure(struct gctl_req *req, struct g_class *mp)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*displaypass && (sc->sc_flags & G_ELI_FLAG_GELIDISPLAYPASS)) {
|
||||
G_ELI_DEBUG(1, "GELIDISPLAYPASS flag already configured for %s.",
|
||||
prov);
|
||||
continue;
|
||||
} else if (*nodisplaypass &&
|
||||
!(sc->sc_flags & G_ELI_FLAG_GELIDISPLAYPASS)) {
|
||||
G_ELI_DEBUG(1, "GELIDISPLAYPASS flag not configured for %s.",
|
||||
prov);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(sc->sc_flags & G_ELI_FLAG_ONETIME)) {
|
||||
/*
|
||||
* ONETIME providers don't write metadata to
|
||||
@ -535,6 +560,14 @@ g_eli_ctl_configure(struct gctl_req *req, struct g_class *mp)
|
||||
sc->sc_flags &= ~G_ELI_FLAG_GELIBOOT;
|
||||
}
|
||||
|
||||
if (*displaypass) {
|
||||
md.md_flags |= G_ELI_FLAG_GELIDISPLAYPASS;
|
||||
sc->sc_flags |= G_ELI_FLAG_GELIDISPLAYPASS;
|
||||
} else if (*nodisplaypass) {
|
||||
md.md_flags &= ~G_ELI_FLAG_GELIDISPLAYPASS;
|
||||
sc->sc_flags &= ~G_ELI_FLAG_GELIDISPLAYPASS;
|
||||
}
|
||||
|
||||
if (sc->sc_flags & G_ELI_FLAG_ONETIME) {
|
||||
/* There's no metadata on disk so we are done here. */
|
||||
continue;
|
||||
|
Loading…
Reference in New Issue
Block a user