Changeset View
Changeset View
Standalone View
Standalone View
sys/geom/eli/g_eli_ctl.c
Show First 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | |||||
static void | static void | ||||
g_eli_ctl_attach(struct gctl_req *req, struct g_class *mp) | g_eli_ctl_attach(struct gctl_req *req, struct g_class *mp) | ||||
{ | { | ||||
struct g_eli_metadata md; | struct g_eli_metadata md; | ||||
struct g_provider *pp; | struct g_provider *pp; | ||||
const char *name; | const char *name; | ||||
u_char *key, mkey[G_ELI_DATAIVKEYLEN]; | u_char *key, mkey[G_ELI_DATAIVKEYLEN]; | ||||
char param[16], argname[16]; | |||||
int *nargs, *detach, *readonly; | int *nargs, *detach, *readonly; | ||||
int keysize, error; | int i, keysize, error; | ||||
u_int nkey; | u_int nkey; | ||||
g_topology_assert(); | g_topology_assert(); | ||||
nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); | nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); | ||||
if (nargs == NULL) { | if (nargs == NULL) { | ||||
gctl_error(req, "No '%s' argument.", "nargs"); | gctl_error(req, "No '%s' argument.", "nargs"); | ||||
return; | return; | ||||
} | } | ||||
if (*nargs != 1) { | if (*nargs == 0) { | ||||
gctl_error(req, "Invalid number of arguments."); | gctl_error(req, "Too few arguments."); | ||||
return; | return; | ||||
} | } | ||||
detach = gctl_get_paraml(req, "detach", sizeof(*detach)); | detach = gctl_get_paraml(req, "detach", sizeof(*detach)); | ||||
if (detach == NULL) { | if (detach == NULL) { | ||||
gctl_error(req, "No '%s' argument.", "detach"); | gctl_error(req, "No '%s' argument.", "detach"); | ||||
return; | return; | ||||
} | } | ||||
readonly = gctl_get_paraml(req, "readonly", sizeof(*readonly)); | readonly = gctl_get_paraml(req, "readonly", sizeof(*readonly)); | ||||
if (readonly == NULL) { | if (readonly == NULL) { | ||||
gctl_error(req, "No '%s' argument.", "readonly"); | gctl_error(req, "No '%s' argument.", "readonly"); | ||||
return; | return; | ||||
} | } | ||||
if (*detach && *readonly) { | if (*detach && *readonly) { | ||||
gctl_error(req, "Options -d and -r are mutually exclusive."); | gctl_error(req, "Options -d and -r are mutually exclusive."); | ||||
return; | return; | ||||
} | } | ||||
name = gctl_get_asciiparam(req, "arg0"); | /* Attach each provider in the request */ | ||||
for (i = 0; i < *nargs; i++) { | |||||
snprintf(argname, sizeof(argname), "arg%d", i); | |||||
name = gctl_get_asciiparam(req, argname); | |||||
if (name == NULL) { | if (name == NULL) { | ||||
gctl_error(req, "No 'arg%u' argument.", 0); | gctl_error(req, "No '%s' argument.", argname); | ||||
return; | continue; | ||||
} | } | ||||
if (strncmp(name, "/dev/", strlen("/dev/")) == 0) | if (strncmp(name, "/dev/", strlen("/dev/")) == 0) | ||||
name += strlen("/dev/"); | name += strlen("/dev/"); | ||||
pp = g_provider_by_name(name); | pp = g_provider_by_name(name); | ||||
if (pp == NULL) { | if (pp == NULL) { | ||||
gctl_error(req, "Provider %s is invalid.", name); | gctl_error(req, "Provider %s is invalid.", name); | ||||
return; | continue; | ||||
} | } | ||||
error = g_eli_read_metadata(mp, pp, &md); | error = g_eli_read_metadata(mp, pp, &md); | ||||
if (error != 0) { | if (error != 0) { | ||||
gctl_error(req, "Cannot read metadata from %s (error=%d).", | gctl_error(req, "Cannot read metadata from %s (error=%d).", | ||||
name, error); | name, error); | ||||
return; | continue; | ||||
} | } | ||||
if (md.md_keys == 0x00) { | if (md.md_keys == 0x00) { | ||||
explicit_bzero(&md, sizeof(md)); | explicit_bzero(&md, sizeof(md)); | ||||
gctl_error(req, "No valid keys on %s.", pp->name); | gctl_error(req, "No valid keys on %s.", pp->name); | ||||
return; | continue; | ||||
} | } | ||||
key = gctl_get_param(req, "key", &keysize); | /* Get the derived key for this provider from the request */ | ||||
snprintf(param, sizeof(param), "key%d", i); | |||||
key = gctl_get_param(req, param, &keysize); | |||||
if (key == NULL || keysize != G_ELI_USERKEYLEN) { | if (key == NULL || keysize != G_ELI_USERKEYLEN) { | ||||
explicit_bzero(&md, sizeof(md)); | explicit_bzero(&md, sizeof(md)); | ||||
gctl_error(req, "No '%s' argument.", "key"); | gctl_error(req, "No '%s' argument.", param); | ||||
return; | continue; | ||||
} | } | ||||
/* Decrypt the master key for this provider */ | |||||
error = g_eli_mkey_decrypt(&md, key, mkey, &nkey); | error = g_eli_mkey_decrypt(&md, key, mkey, &nkey); | ||||
explicit_bzero(key, keysize); | explicit_bzero(key, keysize); | ||||
if (error == -1) { | if (error == -1) { | ||||
explicit_bzero(&md, sizeof(md)); | explicit_bzero(&md, sizeof(md)); | ||||
gctl_error(req, "Wrong key for %s.", pp->name); | gctl_error(req, "Wrong key for %s.", pp->name); | ||||
return; | continue; | ||||
} else if (error > 0) { | } else if (error > 0) { | ||||
explicit_bzero(&md, sizeof(md)); | explicit_bzero(&md, sizeof(md)); | ||||
gctl_error(req, "Cannot decrypt Master Key for %s (error=%d).", | gctl_error(req, "Cannot decrypt Master Key for %s (error=%d).", | ||||
pp->name, error); | pp->name, error); | ||||
return; | continue; | ||||
} | } | ||||
G_ELI_DEBUG(1, "Using Master Key %u for %s.", nkey, pp->name); | G_ELI_DEBUG(1, "Using Master Key %u for %s.", nkey, pp->name); | ||||
/* Create the new GEOM provider using the master key */ | |||||
if (*detach) | if (*detach) | ||||
md.md_flags |= G_ELI_FLAG_WO_DETACH; | md.md_flags |= G_ELI_FLAG_WO_DETACH; | ||||
if (*readonly) | if (*readonly) | ||||
md.md_flags |= G_ELI_FLAG_RO; | md.md_flags |= G_ELI_FLAG_RO; | ||||
g_eli_create(req, mp, pp, &md, mkey, nkey); | g_eli_create(req, mp, pp, &md, mkey, nkey); | ||||
explicit_bzero(mkey, sizeof(mkey)); | explicit_bzero(mkey, sizeof(mkey)); | ||||
explicit_bzero(&md, sizeof(md)); | explicit_bzero(&md, sizeof(md)); | ||||
} | |||||
} | } | ||||
static struct g_eli_softc * | static struct g_eli_softc * | ||||
g_eli_find_device(struct g_class *mp, const char *prov) | g_eli_find_device(struct g_class *mp, const char *prov) | ||||
{ | { | ||||
struct g_eli_softc *sc; | struct g_eli_softc *sc; | ||||
struct g_geom *gp; | struct g_geom *gp; | ||||
struct g_provider *pp; | struct g_provider *pp; | ||||
▲ Show 20 Lines • Show All 1,011 Lines • Show Last 20 Lines |