X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=cmd_key.c;h=6052cb0061762b8ed8d6a1f4c56dfc8c7e54ee41;hb=76a549d82d1383c02e4aa6f7d9eda2df9f2196b3;hp=879163f151d2c1ab542702e14632afce584f21bd;hpb=997bb216aa37010826067d0cfa33b4fde5aaa225;p=bcachefs-tools-debian diff --git a/cmd_key.c b/cmd_key.c index 879163f..6052cb0 100644 --- a/cmd_key.c +++ b/cmd_key.c @@ -7,23 +7,61 @@ #include "crypto.h" #include "libbcachefs.h" +static void unlock_usage(void) +{ + puts("bcachefs unlock - unlock an encrypted filesystem so it can be mounted\n" + "Usage: bcachefs unlock [OPTION] device\n" + "\n" + "Options:\n" + " -c Check if a device is encrypted\n" + " -h Display this help and exit\n" + "Report bugs to "); +} + int cmd_unlock(int argc, char *argv[]) { + bool check = false; + int opt; + + while ((opt = getopt(argc, argv, "ch")) != -1) + switch (opt) { + case 'c': + check = true; + break; + case 'h': + unlock_usage(); + exit(EXIT_SUCCESS); + } + args_shift(optind); + + char *dev = arg_pop(); + if (!dev) + die("Please supply a device"); + + if (argc) + die("Too many arguments"); + + struct bch_opts opts = bch2_opts_empty(); + + opt_set(opts, noexcl, true); + opt_set(opts, nochanges, true); + struct bch_sb_handle sb; - const char *err; - char *passphrase; + int ret = bch2_read_super(dev, &opts, &sb); + if (ret) + die("Error opening %s: %s", dev, strerror(-ret)); - if (argc != 2) - die("Please supply a single device"); + if (!bch2_sb_is_encrypted(sb.sb)) + die("%s is not encrypted", dev); - err = bch2_read_super(argv[1], bch2_opts_empty(), &sb); - if (err) - die("Error opening %s: %s", argv[1], err); + if (check) + exit(EXIT_SUCCESS); - passphrase = read_passphrase("Enter passphrase: "); + char *passphrase = read_passphrase("Enter passphrase: "); bch2_add_key(sb.sb, passphrase); + bch2_free_super(&sb); memzero_explicit(passphrase, strlen(passphrase)); free(passphrase); return 0; @@ -32,18 +70,23 @@ int cmd_unlock(int argc, char *argv[]) int cmd_set_passphrase(int argc, char *argv[]) { struct bch_opts opts = bch2_opts_empty(); - struct bch_fs *c = NULL; - const char *err; + struct bch_fs *c; if (argc < 2) die("Please supply one or more devices"); opt_set(opts, nostart, true); - err = bch2_fs_open(argv + 1, argc - 1, opts, &c); - if (err) - die("Error opening %s: %s", argv[1], err); - struct bch_sb_field_crypt *crypt = bch2_sb_get_crypt(c->disk_sb); + /* + * we use bch2_fs_open() here, instead of just reading the superblock, + * to make sure we're opening and updating every component device: + */ + + c = bch2_fs_open(argv + 1, argc - 1, opts); + if (IS_ERR(c)) + die("Error opening %s: %s", argv[1], strerror(-PTR_ERR(c))); + + struct bch_sb_field_crypt *crypt = bch2_sb_get_crypt(c->disk_sb.sb); if (!crypt) die("Filesystem does not have encryption enabled"); @@ -57,7 +100,7 @@ int cmd_set_passphrase(int argc, char *argv[]) char *new_passphrase = read_passphrase_twice("Enter new passphrase: "); struct bch_key passphrase_key = derive_passphrase(crypt, new_passphrase); - if (bch2_chacha_encrypt_key(&passphrase_key, __bch2_sb_key_nonce(c->disk_sb), + if (bch2_chacha_encrypt_key(&passphrase_key, __bch2_sb_key_nonce(c->disk_sb.sb), &new_key, sizeof(new_key))) die("error encrypting key"); crypt->key = new_key; @@ -70,18 +113,17 @@ int cmd_set_passphrase(int argc, char *argv[]) int cmd_remove_passphrase(int argc, char *argv[]) { struct bch_opts opts = bch2_opts_empty(); - struct bch_fs *c = NULL; - const char *err; + struct bch_fs *c; if (argc < 2) die("Please supply one or more devices"); opt_set(opts, nostart, true); - err = bch2_fs_open(argv + 1, argc - 1, opts, &c); - if (err) - die("Error opening %s: %s", argv[1], err); + c = bch2_fs_open(argv + 1, argc - 1, opts); + if (IS_ERR(c)) + die("Error opening %s: %s", argv[1], strerror(-PTR_ERR(c))); - struct bch_sb_field_crypt *crypt = bch2_sb_get_crypt(c->disk_sb); + struct bch_sb_field_crypt *crypt = bch2_sb_get_crypt(c->disk_sb.sb); if (!crypt) die("Filesystem does not have encryption enabled");