"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/veritysetup.c" between
cryptsetup-2.3.6.tar.xz and cryptsetup-2.4.0.tar.xz

About: cryptsetup is a utility used to conveniently setup disk encryption based on the dm-crypt kernel module. These include plain dm-crypt volumes, LUKS volumes, loop-AES and TrueCrypt compatible format.

veritysetup.c  (cryptsetup-2.3.6.tar.xz):veritysetup.c  (cryptsetup-2.4.0.tar.xz)
skipping to change at line 23 skipping to change at line 23
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include "cryptsetup.h" #include "cryptsetup.h"
#include "veritysetup_args.h"
#define PACKAGE_VERITY "veritysetup" #define PACKAGE_VERITY "veritysetup"
static char *opt_fec_device = NULL;
static char *opt_hash_algorithm = NULL;
static char *opt_salt = NULL;
static char *opt_uuid = NULL;
static char *opt_root_hash_signature = NULL;
static int opt_use_superblock = 1;
static int opt_fec_roots = DEFAULT_VERITY_FEC_ROOTS;
static int opt_hash_type = 1;
static int opt_data_block_size = DEFAULT_VERITY_DATA_BLOCK;
static int opt_hash_block_size = DEFAULT_VERITY_HASH_BLOCK;
static uint64_t data_blocks = 0;
static uint64_t hash_offset = 0;
static uint64_t fec_offset = 0;
static int opt_restart_on_corruption = 0;
static int opt_panic_on_corruption = 0;
static int opt_ignore_corruption = 0;
static int opt_ignore_zero_blocks = 0;
static int opt_check_at_most_once = 0;
static const char **action_argv; static const char **action_argv;
static int action_argc; static int action_argc;
static struct tools_log_params log_parms;
void tools_cleanup(void) void tools_cleanup(void)
{ {
FREE_AND_NULL(opt_fec_device); tools_args_free(tool_core_args, ARRAY_SIZE(tool_core_args));
FREE_AND_NULL(opt_hash_algorithm);
FREE_AND_NULL(opt_salt);
FREE_AND_NULL(opt_uuid);
FREE_AND_NULL(opt_root_hash_signature);
} }
static int _prepare_format(struct crypt_params_verity *params, static int _prepare_format(struct crypt_params_verity *params,
const char *data_device, const char *data_device,
uint32_t flags) uint32_t flags)
{ {
char *salt = NULL; char *salt = NULL;
int len; int len;
params->hash_name = opt_hash_algorithm ?: DEFAULT_VERITY_HASH; params->hash_name = ARG_STR(OPT_HASH_ID);
params->data_device = data_device; params->data_device = data_device;
params->fec_device = opt_fec_device; params->fec_device = ARG_STR(OPT_FEC_DEVICE_ID);
params->fec_roots = opt_fec_roots; params->fec_roots = ARG_UINT32(OPT_FEC_ROOTS_ID);
if (opt_salt && !strcmp(opt_salt, "-")) { if (ARG_STR(OPT_SALT_ID) && !strcmp(ARG_STR(OPT_SALT_ID), "-")) {
params->salt_size = 0; params->salt_size = 0;
params->salt = NULL; params->salt = NULL;
} else if (opt_salt) { } else if (ARG_SET(OPT_SALT_ID)) {
len = crypt_hex_to_bytes(opt_salt, &salt, 0); len = crypt_hex_to_bytes(ARG_STR(OPT_SALT_ID), &salt, 0);
if (len < 0) { if (len < 0) {
log_err(_("Invalid salt string specified.")); log_err(_("Invalid salt string specified."));
return -EINVAL; return -EINVAL;
} }
params->salt_size = len; params->salt_size = len;
params->salt = salt; params->salt = salt;
} else { } else {
params->salt_size = DEFAULT_VERITY_SALT_SIZE; params->salt_size = DEFAULT_VERITY_SALT_SIZE;
params->salt = NULL; params->salt = NULL;
} }
params->data_block_size = opt_data_block_size; params->data_block_size = ARG_UINT32(OPT_DATA_BLOCK_SIZE_ID);
params->hash_block_size = opt_hash_block_size; params->hash_block_size = ARG_UINT32(OPT_HASH_BLOCK_SIZE_ID);
params->data_size = data_blocks; params->data_size = ARG_UINT64(OPT_DATA_BLOCKS_ID);
params->hash_area_offset = hash_offset; params->hash_area_offset = ARG_UINT64(OPT_HASH_OFFSET_ID);
params->fec_area_offset = fec_offset; params->fec_area_offset = ARG_UINT64(OPT_FEC_OFFSET_ID);
params->hash_type = opt_hash_type; params->hash_type = ARG_UINT32(OPT_FORMAT_ID);
params->flags = flags; params->flags = flags;
return 0; return 0;
} }
static int action_format(int arg) static int action_format(void)
{ {
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
struct crypt_params_verity params = {}; struct crypt_params_verity params = {};
uint32_t flags = CRYPT_VERITY_CREATE_HASH; uint32_t flags = CRYPT_VERITY_CREATE_HASH;
int r; char *root_hash_bytes = NULL;
size_t root_hash_size;
int root_hash_fd = -1, i, r;
/* Try to create hash image if doesn't exist */ /* Try to create hash image if doesn't exist */
r = open(action_argv[1], O_WRONLY | O_EXCL | O_CREAT, S_IRUSR | S_IWUSR); r = open(action_argv[1], O_WRONLY | O_EXCL | O_CREAT, S_IRUSR | S_IWUSR);
if (r < 0 && errno != EEXIST) { if (r < 0 && errno != EEXIST) {
log_err(_("Cannot create hash image %s for writing."), action_arg v[1]); log_err(_("Cannot create hash image %s for writing."), action_arg v[1]);
return -EINVAL; return -EINVAL;
} else if (r >= 0) { } else if (r >= 0) {
log_dbg("Created hash image %s.", action_argv[1]); log_dbg("Created hash image %s.", action_argv[1]);
close(r); close(r);
} }
/* Try to create FEC image if doesn't exist */ /* Try to create FEC image if doesn't exist */
if (opt_fec_device) { if (ARG_SET(OPT_FEC_DEVICE_ID)) {
r = open(opt_fec_device, O_WRONLY | O_EXCL | O_CREAT, S_IRUSR | S r = open(ARG_STR(OPT_FEC_DEVICE_ID), O_WRONLY | O_EXCL | O_CREAT,
_IWUSR); S_IRUSR | S_IWUSR);
if (r < 0 && errno != EEXIST) { if (r < 0 && errno != EEXIST) {
log_err(_("Cannot create FEC image %s for writing."), opt _fec_device); log_err(_("Cannot create FEC image %s for writing."), ARG _STR(OPT_FEC_DEVICE_ID));
return -EINVAL; return -EINVAL;
} else if (r >= 0) { } else if (r >= 0) {
log_dbg("Created FEC image %s.", opt_fec_device); log_dbg("Created FEC image %s.", ARG_STR(OPT_FEC_DEVICE_I D));
close(r); close(r);
} }
} }
if ((r = crypt_init(&cd, action_argv[1]))) if ((r = crypt_init(&cd, action_argv[1])))
goto out; goto out;
if (!opt_use_superblock) if (ARG_SET(OPT_NO_SUPERBLOCK_ID))
flags |= CRYPT_VERITY_NO_HEADER; flags |= CRYPT_VERITY_NO_HEADER;
r = _prepare_format(&params, action_argv[0], flags); r = _prepare_format(&params, action_argv[0], flags);
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_format(cd, CRYPT_VERITY, NULL, NULL, opt_uuid, NULL, 0, &params r = crypt_format(cd, CRYPT_VERITY, NULL, NULL, ARG_STR(OPT_UUID_ID), NULL
); , 0, &params);
if (!r) if (r < 0)
crypt_dump(cd); goto out;
crypt_dump(cd);
/* Create or overwrite the root hash file */
if (ARG_SET(OPT_ROOT_HASH_FILE_ID)) {
root_hash_size = crypt_get_volume_key_size(cd);
root_hash_bytes = malloc(root_hash_size);
if (!root_hash_bytes) {
r = -ENOMEM;
goto out;
}
r = crypt_volume_key_get(cd, CRYPT_ANY_SLOT, root_hash_bytes, &ro
ot_hash_size, NULL, 0);
if (r < 0)
goto out;
root_hash_fd = open(ARG_STR(OPT_ROOT_HASH_FILE_ID), O_WRONLY | O_
TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
if (root_hash_fd == -1) {
log_err(_("Cannot create root hash file %s for writing.")
, ARG_STR(OPT_ROOT_HASH_FILE_ID));
r = -EINVAL;
goto out;
}
for (i = 0; i < (int)root_hash_size; i++)
if (dprintf(root_hash_fd, "%02hhx", root_hash_bytes[i]) !
= 2) {
log_err(_("Cannot write to root hash file %s."),
ARG_STR(OPT_ROOT_HASH_FILE_ID));
r = -EIO;
goto out;
}
log_dbg("Created root hash file %s.", ARG_STR(OPT_ROOT_HASH_FILE_
ID));
}
out: out:
crypt_free(cd); crypt_free(cd);
free(CONST_CAST(char*)params.salt); free(CONST_CAST(char*)params.salt);
free(root_hash_bytes);
if (root_hash_fd != -1)
close(root_hash_fd);
return r; return r;
} }
static int _activate(const char *dm_device, static int _activate(const char *dm_device,
const char *data_device, const char *data_device,
const char *hash_device, const char *hash_device,
const char *root_hash, const char *root_hash,
uint32_t flags) uint32_t flags)
{ {
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
struct crypt_params_verity params = {}; struct crypt_params_verity params = {};
uint32_t activate_flags = CRYPT_ACTIVATE_READONLY; uint32_t activate_flags = CRYPT_ACTIVATE_READONLY;
char *root_hash_bytes = NULL; char *root_hash_bytes = NULL, *root_hash_from_file = NULL;
ssize_t hash_size; ssize_t hash_size, hash_size_hex;
struct stat st; struct stat st;
char *signature = NULL; char *signature = NULL;
int signature_size = 0, r; int signature_size = 0, root_hash_fd = -1, r;
if ((r = crypt_init_data_device(&cd, hash_device, data_device))) if ((r = crypt_init_data_device(&cd, hash_device, data_device)))
goto out; goto out;
if (opt_ignore_corruption) if (ARG_SET(OPT_IGNORE_CORRUPTION_ID))
activate_flags |= CRYPT_ACTIVATE_IGNORE_CORRUPTION; activate_flags |= CRYPT_ACTIVATE_IGNORE_CORRUPTION;
if (opt_restart_on_corruption) if (ARG_SET(OPT_RESTART_ON_CORRUPTION_ID))
activate_flags |= CRYPT_ACTIVATE_RESTART_ON_CORRUPTION; activate_flags |= CRYPT_ACTIVATE_RESTART_ON_CORRUPTION;
if (opt_panic_on_corruption) if (ARG_SET(OPT_PANIC_ON_CORRUPTION_ID))
activate_flags |= CRYPT_ACTIVATE_PANIC_ON_CORRUPTION; activate_flags |= CRYPT_ACTIVATE_PANIC_ON_CORRUPTION;
if (opt_ignore_zero_blocks) if (ARG_SET(OPT_IGNORE_ZERO_BLOCKS_ID))
activate_flags |= CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS; activate_flags |= CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS;
if (opt_check_at_most_once) if (ARG_SET(OPT_CHECK_AT_MOST_ONCE_ID))
activate_flags |= CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE; activate_flags |= CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE;
if (opt_use_superblock) { if (!ARG_SET(OPT_NO_SUPERBLOCK_ID)) {
params.flags = flags; params.flags = flags;
params.hash_area_offset = hash_offset; params.hash_area_offset = ARG_UINT64(OPT_HASH_OFFSET_ID);
params.fec_area_offset = fec_offset; params.fec_area_offset = ARG_UINT64(OPT_FEC_OFFSET_ID);
params.fec_device = opt_fec_device; params.fec_device = ARG_STR(OPT_FEC_DEVICE_ID);
params.fec_roots = opt_fec_roots; params.fec_roots = ARG_UINT32(OPT_FEC_ROOTS_ID);
r = crypt_load(cd, CRYPT_VERITY, &params); r = crypt_load(cd, CRYPT_VERITY, &params);
} else { } else {
r = _prepare_format(&params, data_device, flags | CRYPT_VERITY_NO _HEADER); r = _prepare_format(&params, data_device, flags | CRYPT_VERITY_NO _HEADER);
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_format(cd, CRYPT_VERITY, NULL, NULL, NULL, NULL, 0, &pa rams); r = crypt_format(cd, CRYPT_VERITY, NULL, NULL, NULL, NULL, 0, &pa rams);
} }
if (r < 0) if (r < 0)
goto out; goto out;
hash_size = crypt_get_volume_key_size(cd); hash_size = crypt_get_volume_key_size(cd);
hash_size_hex = 2 * hash_size;
if (!root_hash) {
root_hash_fd = open(ARG_STR(OPT_ROOT_HASH_FILE_ID), O_RDONLY);
if (root_hash_fd == -1) {
log_err(_("Cannot read root hash file %s."), ARG_STR(OPT_
ROOT_HASH_FILE_ID));
goto out;
}
if (fstat(root_hash_fd, &st) || !S_ISREG(st.st_mode) || st.st_siz
e < hash_size_hex) {
log_err(_("Invalid root hash file %s."), ARG_STR(OPT_ROOT
_HASH_FILE_ID));
r = -EINVAL;
goto out;
}
root_hash_from_file = malloc(hash_size_hex + 1);
if (!root_hash_from_file) {
r = -ENOMEM;
goto out;
}
if (read_buffer(root_hash_fd, root_hash_from_file, hash_size_hex)
!= hash_size_hex) {
log_err(_("Cannot read root hash file %s."), root_hash_fr
om_file);
goto out;
}
root_hash_from_file[hash_size_hex] = '\0';
root_hash = root_hash_from_file;
}
if (crypt_hex_to_bytes(root_hash, &root_hash_bytes, 0) != hash_size) { if (crypt_hex_to_bytes(root_hash, &root_hash_bytes, 0) != hash_size) {
log_err(_("Invalid root hash string specified.")); log_err(_("Invalid root hash string specified."));
r = -EINVAL; r = -EINVAL;
goto out; goto out;
} }
if (opt_root_hash_signature) { if (ARG_SET(OPT_ROOT_HASH_SIGNATURE_ID)) {
// FIXME: check max file size // FIXME: check max file size
if (stat(opt_root_hash_signature, &st) || !S_ISREG(st.st_mode) || if (stat(ARG_STR(OPT_ROOT_HASH_SIGNATURE_ID), &st) || !S_ISREG(st
!st.st_size) { .st_mode) || !st.st_size) {
log_err(_("Invalid signature file %s."), opt_root_hash_si log_err(_("Invalid signature file %s."), ARG_STR(OPT_ROOT
gnature); _HASH_SIGNATURE_ID));
r = -EINVAL; r = -EINVAL;
goto out; goto out;
} }
signature_size = st.st_size; signature_size = st.st_size;
r = tools_read_mk(opt_root_hash_signature, &signature, signature_ size); r = tools_read_mk(ARG_STR(OPT_ROOT_HASH_SIGNATURE_ID), &signature , signature_size);
if (r < 0) { if (r < 0) {
log_err(_("Cannot read signature file %s."), opt_root_has h_signature); log_err(_("Cannot read signature file %s."), ARG_STR(OPT_ ROOT_HASH_SIGNATURE_ID));
goto out; goto out;
} }
} }
r = crypt_activate_by_signed_key(cd, dm_device, r = crypt_activate_by_signed_key(cd, dm_device,
root_hash_bytes, root_hash_bytes,
hash_size, hash_size,
signature, signature_size, signature, signature_size,
activate_flags); activate_flags);
out: out:
crypt_safe_free(signature); crypt_safe_free(signature);
crypt_free(cd); crypt_free(cd);
free(root_hash_from_file);
free(root_hash_bytes); free(root_hash_bytes);
free(CONST_CAST(char*)params.salt); free(CONST_CAST(char*)params.salt);
if (root_hash_fd != -1)
close(root_hash_fd);
return r; return r;
} }
static int action_open(int arg) static int action_open(void)
{ {
if (action_argc < 4 && !ARG_SET(OPT_ROOT_HASH_FILE_ID)) {
log_err(_("Command requires <root_hash> or --root-hash-file optio
n as argument."));
return -EINVAL;
}
return _activate(action_argv[1], return _activate(action_argv[1],
action_argv[0], action_argv[0],
action_argv[2], action_argv[2],
action_argv[3], ARG_SET(OPT_ROOT_HASH_FILE_ID) ? NULL : action_argv[3],
opt_root_hash_signature ? CRYPT_VERITY_ROOT_HASH_SIGNATU ARG_SET(OPT_ROOT_HASH_SIGNATURE_ID) ? CRYPT_VERITY_ROOT_
RE : 0); HASH_SIGNATURE : 0);
} }
static int action_verify(int arg) static int action_verify(void)
{ {
if (action_argc < 3 && !ARG_SET(OPT_ROOT_HASH_FILE_ID)) {
log_err(_("Command requires <root_hash> or --root-hash-file optio
n as argument."));
return -EINVAL;
}
return _activate(NULL, return _activate(NULL,
action_argv[0], action_argv[0],
action_argv[1], action_argv[1],
action_argv[2], ARG_SET(OPT_ROOT_HASH_FILE_ID) ? NULL : action_argv[2],
CRYPT_VERITY_CHECK_HASH); CRYPT_VERITY_CHECK_HASH);
} }
static int action_close(int arg) static int action_close(void)
{ {
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
crypt_status_info ci;
uint32_t flags = 0;
int r; int r;
if (ARG_SET(OPT_DEFERRED_ID))
flags |= CRYPT_DEACTIVATE_DEFERRED;
if (ARG_SET(OPT_CANCEL_DEFERRED_ID))
flags |= CRYPT_DEACTIVATE_DEFERRED_CANCEL;
r = crypt_init_by_name(&cd, action_argv[0]); r = crypt_init_by_name(&cd, action_argv[0]);
if (r == 0) if (r == 0)
r = crypt_deactivate(cd, action_argv[0]); r = crypt_deactivate_by_name(cd, action_argv[0], flags);
if (!r && ARG_SET(OPT_DEFERRED_ID)) {
ci = crypt_status(cd, action_argv[0]);
if (ci == CRYPT_ACTIVE || ci == CRYPT_BUSY)
log_std(_("Device %s is still active and scheduled for de
ferred removal.\n"),
action_argv[0]);
}
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int action_status(int arg) static int action_status(void)
{ {
crypt_status_info ci; crypt_status_info ci;
struct crypt_active_device cad; struct crypt_active_device cad;
struct crypt_params_verity vp = {}; struct crypt_params_verity vp = {};
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
struct stat st; struct stat st;
char *backing_file, *root_hash; char *backing_file, *root_hash;
size_t root_hash_size; size_t root_hash_size;
unsigned i, path = 0; unsigned i, path = 0;
int r = 0; int r = 0;
skipping to change at line 341 skipping to change at line 413
log_std(" hash device: %s\n", vp.hash_device); log_std(" hash device: %s\n", vp.hash_device);
if ((backing_file = crypt_loop_backing_file(vp.hash_device))) { if ((backing_file = crypt_loop_backing_file(vp.hash_device))) {
log_std(" hash loop: %s\n", backing_file); log_std(" hash loop: %s\n", backing_file);
free(backing_file); free(backing_file);
} }
log_std(" hash offset: %" PRIu64 " sectors\n", log_std(" hash offset: %" PRIu64 " sectors\n",
vp.hash_area_offset * vp.hash_block_size / 512); vp.hash_area_offset * vp.hash_block_size / 512);
if (vp.fec_device) { if (vp.fec_device) {
log_std(" FEC device: %s\n", vp.fec_device); log_std(" FEC device: %s\n", vp.fec_device);
if ((backing_file = crypt_loop_backing_file(opt_fec_devic e))) { if ((backing_file = crypt_loop_backing_file(ARG_STR(OPT_F EC_DEVICE_ID)))) {
log_std(" FEC loop: %s\n", backing_file); log_std(" FEC loop: %s\n", backing_file);
free(backing_file); free(backing_file);
} }
log_std(" FEC offset: %" PRIu64 " sectors\n", log_std(" FEC offset: %" PRIu64 " sectors\n",
vp.fec_area_offset * vp.hash_block_size / 512); vp.fec_area_offset * vp.hash_block_size / 512);
log_std(" FEC roots: %u\n", vp.fec_roots); log_std(" FEC roots: %u\n", vp.fec_roots);
} }
root_hash_size = crypt_get_volume_key_size(cd); root_hash_size = crypt_get_volume_key_size(cd);
if (root_hash_size > 0 && (root_hash = malloc(root_hash_size))) { if (root_hash_size > 0 && (root_hash = malloc(root_hash_size))) {
skipping to change at line 381 skipping to change at line 453
(cad.flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS) ? "ignore_zero_blocks " : "", (cad.flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS) ? "ignore_zero_blocks " : "",
(cad.flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? "check_at_most_once" : ""); (cad.flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? "check_at_most_once" : "");
} }
out: out:
crypt_free(cd); crypt_free(cd);
if (r == -ENOTSUP) if (r == -ENOTSUP)
r = 0; r = 0;
return r; return r;
} }
static int action_dump(int arg) static int action_dump(void)
{ {
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
struct crypt_params_verity params = {}; struct crypt_params_verity params = {};
int r; int r;
if ((r = crypt_init(&cd, action_argv[0]))) if ((r = crypt_init(&cd, action_argv[0])))
return r; return r;
params.hash_area_offset = hash_offset; params.hash_area_offset = ARG_UINT64(OPT_HASH_OFFSET_ID);
params.fec_area_offset = fec_offset; params.fec_area_offset = ARG_UINT64(OPT_FEC_OFFSET_ID);
r = crypt_load(cd, CRYPT_VERITY, &params); r = crypt_load(cd, CRYPT_VERITY, &params);
if (!r) if (!r)
crypt_dump(cd); crypt_dump(cd);
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static struct action_type { static struct action_type {
const char *type; const char *type;
int (*handler)(int); int (*handler)(void);
int required_action_argc; int required_action_argc;
const char *arg_desc; const char *arg_desc;
const char *desc; const char *desc;
} action_types[] = { } action_types[] = {
{ "format", action_format, 2, N_("<data_device> <hash_device>"),N_("f ormat device") }, { "format", action_format, 2, N_("<data_device> <hash_device>"),N_("f ormat device") },
{ "verify", action_verify, 3, N_("<data_device> <hash_device> <root_h { "verify", action_verify, 2, N_("<data_device> <hash_device> [<root_
ash>"),N_("verify device") }, hash>]"),N_("verify device") },
{ "open", action_open, 4, N_("<data_device> <name> <hash_device> { "open", action_open, 3, N_("<data_device> <name> <hash_device>
<root_hash>"),N_("open device as <name>") }, [<root_hash>]"),N_("open device as <name>") },
{ "close", action_close, 1, N_("<name>"),N_("close device (remove m apping)") }, { "close", action_close, 1, N_("<name>"),N_("close device (remove m apping)") },
{ "status", action_status, 1, N_("<name>"),N_("show active device sta tus") }, { "status", action_status, 1, N_("<name>"),N_("show active device sta tus") },
{ "dump", action_dump, 1, N_("<hash_device>"),N_("show on-disk in formation") }, { "dump", action_dump, 1, N_("<hash_device>"),N_("show on-disk in formation") },
{ NULL, NULL, 0, NULL, NULL } { NULL, NULL, 0, NULL, NULL }
}; };
static void help(poptContext popt_context, static void help(poptContext popt_context,
enum poptCallbackReason reason __attribute__((unused)), enum poptCallbackReason reason __attribute__((unused)),
struct poptOption *key, struct poptOption *key,
const char *arg __attribute__((unused)), const char *arg __attribute__((unused)),
skipping to change at line 461 skipping to change at line 533
} else } else
usage(popt_context, EXIT_SUCCESS, NULL, NULL); usage(popt_context, EXIT_SUCCESS, NULL, NULL);
} }
static int run_action(struct action_type *action) static int run_action(struct action_type *action)
{ {
int r; int r;
log_dbg("Running command %s.", action->type); log_dbg("Running command %s.", action->type);
r = action->handler(0); r = action->handler();
show_status(r); show_status(r);
return translate_errno(r); return translate_errno(r);
} }
static void basic_options_cb(poptContext popt_context,
enum poptCallbackReason reason __attribute__((unused)),
struct poptOption *key,
const char *arg,
void *data __attribute__((unused)))
{
tools_parse_arg_value(popt_context, tool_core_args[key->val].type, tool_c
ore_args + key->val, arg, key->val, NULL);
switch (key->val) {
case OPT_DEBUG_ID:
log_parms.debug = true;
/* fall through */
case OPT_VERBOSE_ID:
log_parms.verbose = true;
}
}
int main(int argc, const char **argv) int main(int argc, const char **argv)
{ {
static const char *null_action_argv[] = {NULL}; static const char *null_action_argv[] = {NULL};
static struct poptOption popt_help_options[] = { static struct poptOption popt_help_options[] = {
{ NULL, '\0', POPT_ARG_CALLBACK, help, 0, NULL, NULL }, { NULL, '\0', POPT_ARG_CALLBACK, help, 0, NULL, NULL },
{ "help", '?', POPT_ARG_NONE, NULL, 0, N_("Show this help m essage"), NULL }, { "help", '?', POPT_ARG_NONE, NULL, 0, N_("Show this help m essage"), NULL },
{ "usage", '\0', POPT_ARG_NONE, NULL, 0, N_("Display brief us age"), NULL }, { "usage", '\0', POPT_ARG_NONE, NULL, 0, N_("Display brief us age"), NULL },
{ "version",'V', POPT_ARG_NONE, NULL, 0, N_("Print package ve rsion"), NULL }, { "version",'V', POPT_ARG_NONE, NULL, 0, N_("Print package ve rsion"), NULL },
POPT_TABLEEND POPT_TABLEEND
}; };
static struct poptOption popt_basic_options[] = {
{ NULL, '\0', POPT_ARG_CALLBACK, basic_options_cb, 0, NULL, NU
LL },
#define ARG(A, B, C, D, E, F, G, H) { A, B, C, NULL, A ## _ID, D, E },
#include "veritysetup_arg_list.h"
#undef arg
POPT_TABLEEND
};
static struct poptOption popt_options[] = { static struct poptOption popt_options[] = {
{ NULL, '\0', POPT_ARG_INCLUDE_TABLE, popt_help_opti ons, 0, N_("Help options:"), NULL }, { NULL, '\0', POPT_ARG_INCLUDE_TABLE, popt_help_opti ons, 0, N_("Help options:"), NULL },
{ "verbose", 'v', POPT_ARG_NONE, &opt_verbose, 0, N { NULL, '\0', POPT_ARG_INCLUDE_TABLE, popt_basic_opt
_("Shows more detailed error messages"), NULL }, ions, 0, NULL, NULL },
{ "debug", '\0', POPT_ARG_NONE, &opt_debug, 0, N
_("Show debug messages"), NULL },
{ "no-superblock", 0, POPT_ARG_VAL, &opt_use_superblock,
0, N_("Do not use verity superblock"), NULL },
{ "format", 0, POPT_ARG_INT, &opt_hash_type,
0, N_("Format type (1 - normal, 0 - original Chrome OS)"), N_("number") },
{ "data-block-size", 0, POPT_ARG_INT, &opt_data_block_size,
0, N_("Block size on the data device"), N_("bytes") },
{ "hash-block-size", 0, POPT_ARG_INT, &opt_hash_block_size,
0, N_("Block size on the hash device"), N_("bytes") },
{ "fec-roots", 0, POPT_ARG_INT, &opt_fec_roots,
0, N_("FEC parity bytes"), N_("bytes") },
{ "data-blocks", 0, POPT_ARG_STRING, NULL, 1, N_("Th
e number of blocks in the data file"), N_("blocks") },
{ "fec-device", 0, POPT_ARG_STRING, &opt_fec_device,
0, N_("Path to device with error correction data"), N_("path") },
{ "hash-offset", 0, POPT_ARG_STRING, NULL, 2, N_("St
arting offset on the hash device"), N_("bytes") },
{ "fec-offset", 0, POPT_ARG_STRING, NULL, 3, N_("St
arting offset on the FEC device"), N_("bytes") },
{ "hash", 'h', POPT_ARG_STRING, &opt_hash_algorithm,
0, N_("Hash algorithm"), N_("string") },
{ "salt", 's', POPT_ARG_STRING, &opt_salt, 0, N_("
Salt"), N_("hex string") },
{ "uuid", '\0', POPT_ARG_STRING, &opt_uuid, 0, N
_("UUID for device to use"), NULL },
{ "root-hash-signature",'\0', POPT_ARG_STRING, &opt_root_hash_sig
nature, 0, N_("Path to root hash signature file"), NULL },
{ "restart-on-corruption", 0,POPT_ARG_NONE,&opt_restart_on_corrup
tion, 0, N_("Restart kernel if corruption is detected"), NULL },
{ "panic-on-corruption", 0,POPT_ARG_NONE, &opt_panic_on_corruptio
n, 0, N_("Panic kernel if corruption is detected"), NULL },
{ "ignore-corruption", 0, POPT_ARG_NONE, &opt_ignore_corruption,
0, N_("Ignore corruption, log it only"), NULL },
{ "ignore-zero-blocks", 0, POPT_ARG_NONE, &opt_ignore_zero_blocks
, 0, N_("Do not verify zeroed blocks"), NULL },
{ "check-at-most-once", 0, POPT_ARG_NONE, &opt_check_at_most_once
, 0, N_("Verify data block only the first time it is read"), NULL },
POPT_TABLEEND POPT_TABLEEND
}; };
poptContext popt_context; poptContext popt_context;
struct action_type *action; struct action_type *action;
const char *aname; const char *aname;
int r; int r;
crypt_set_log_callback(NULL, tool_log, NULL); crypt_set_log_callback(NULL, tool_log, &log_parms);
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR); bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE); textdomain(PACKAGE);
popt_context = poptGetContext("verity", argc, argv, popt_options, 0); popt_context = poptGetContext("verity", argc, argv, popt_options, 0);
poptSetOtherOptionHelp(popt_context, poptSetOtherOptionHelp(popt_context,
_("[OPTION...] <action> <action-specific>")); _("[OPTION...] <action> <action-specific>"));
while((r = poptGetNextOpt(popt_context)) > 0) { while((r = poptGetNextOpt(popt_context)) > 0) {}
unsigned long long ull_value;
char *endp, *str = poptGetOptArg(popt_context);
errno = 0;
ull_value = strtoull(str, &endp, 10);
if (*endp || !*str || !isdigit(*str) ||
(errno == ERANGE && ull_value == ULLONG_MAX) ||
(errno != 0 && ull_value == 0))
r = POPT_ERROR_BADNUMBER;
free(str);
switch(r) {
case 1:
data_blocks = ull_value;
break;
case 2:
hash_offset = ull_value;
break;
case 3:
fec_offset = ull_value;
break;
}
if (r < 0)
break;
}
if (r < -1) if (r < -1)
usage(popt_context, EXIT_FAILURE, poptStrerror(r), usage(popt_context, EXIT_FAILURE, poptStrerror(r),
poptBadOption(popt_context, POPT_BADOPTION_NOALIAS)); poptBadOption(popt_context, POPT_BADOPTION_NOALIAS));
if (!(aname = poptGetArg(popt_context))) if (!(aname = poptGetArg(popt_context)))
usage(popt_context, EXIT_FAILURE, _("Argument <action> missing.") , usage(popt_context, EXIT_FAILURE, _("Argument <action> missing.") ,
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
action_argc = 0; action_argc = 0;
skipping to change at line 592 skipping to change at line 642
usage(popt_context, EXIT_FAILURE, _("Unknown action."), usage(popt_context, EXIT_FAILURE, _("Unknown action."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (action_argc < action->required_action_argc) { if (action_argc < action->required_action_argc) {
char buf[128]; char buf[128];
snprintf(buf, 128,_("%s: requires %s as arguments"), action->type , action->arg_desc); snprintf(buf, 128,_("%s: requires %s as arguments"), action->type , action->arg_desc);
usage(popt_context, EXIT_FAILURE, buf, usage(popt_context, EXIT_FAILURE, buf,
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
} }
if (opt_data_block_size < 0 || opt_hash_block_size < 0 || opt_hash_type < tools_check_args(action->type, tool_core_args, ARRAY_SIZE(tool_core_args)
0) { , popt_context);
usage(popt_context, EXIT_FAILURE,
_("Negative number for option not permitted."),
poptGetInvocationName(popt_context));
}
if ((opt_ignore_corruption || opt_restart_on_corruption || opt_ignore_zer
o_blocks) && strcmp(aname, "open"))
usage(popt_context, EXIT_FAILURE,
_("Option --ignore-corruption, --restart-on-corruption or --ignor
e-zero-blocks is allowed only for open operation."),
poptGetInvocationName(popt_context));
if (opt_root_hash_signature && strcmp(aname, "open"))
usage(popt_context, EXIT_FAILURE,
_("Option --root-hash-signature can be used only for open operati
on."),
poptGetInvocationName(popt_context));
if (opt_ignore_corruption && opt_restart_on_corruption) if (ARG_SET(OPT_IGNORE_CORRUPTION_ID) && ARG_SET(OPT_RESTART_ON_CORRUPTIO N_ID))
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Option --ignore-corruption and --restart-on-corruption cannot be used together."), _("Option --ignore-corruption and --restart-on-corruption cannot be used together."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_panic_on_corruption && opt_restart_on_corruption) if (ARG_SET(OPT_PANIC_ON_CORRUPTION_ID) && ARG_SET(OPT_RESTART_ON_CORRUPT ION_ID))
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Option --panic-on-corruption and --restart-on-corruption canno t be used together."), _("Option --panic-on-corruption and --restart-on-corruption canno t be used together."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_debug) { if (ARG_SET(OPT_CANCEL_DEFERRED_ID) && ARG_SET(OPT_DEFERRED_ID))
opt_verbose = 1; usage(popt_context, EXIT_FAILURE,
crypt_set_debug_level(-1); _("Options --cancel-deferred and --deferred cannot be used
at the same time."),
poptGetInvocationName(popt_context));
if (ARG_SET(OPT_DEBUG_ID)) {
crypt_set_debug_level(CRYPT_DEBUG_ALL);
dbg_version_and_cmd(argc, argv); dbg_version_and_cmd(argc, argv);
} }
r = run_action(action); r = run_action(action);
tools_cleanup(); tools_cleanup();
poptFreeContext(popt_context); poptFreeContext(popt_context);
return r; return r;
} }
 End of changes. 59 change blocks. 
181 lines changed or deleted 216 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)