#include <string.h>
#include <errno.h>
+#include <sys/mman.h>
#include <libcryptsetup.h>
static const char *opt_type = NULL; /* LUKS1 or PLAIN */
static char *opt_cipher = NULL;
-static char *opt_cipher_mode = NULL;
static unsigned opt_key_size = 0;
static char *opt_hash = NULL;
static unsigned opt_tries = 0;
static bool opt_verify = false;
static usec_t opt_timeout = 0;
+/* Options Debian's crypttab knows we don't:
+
+ offset=
+ skip=
+ precheck=
+ check=
+ checkargs=
+ noearly=
+ loud=
+ keyscript=
+*/
+
static int parse_one_option(const char *option) {
assert(option);
free(opt_hash);
opt_hash = t;
- } else if (startswith(option, "mode=")) {
- char *t;
-
- if (!(t = strdup(option+5)))
- return -ENOMEM;
-
- free(opt_cipher_mode);
- opt_cipher_mode = t;
-
} else if (startswith(option, "tries=")) {
if (safe_atou(option+6, &opt_tries) < 0) {
int main(int argc, char *argv[]) {
int r = EXIT_FAILURE;
struct crypt_device *cd = NULL;
- char *password = NULL;
+ char *password = NULL, *truncated_cipher = NULL;
const char *cipher = NULL, *cipher_mode = NULL, *hash = NULL;
- crypt_status_info status;
if (argc < 3) {
log_error("This program requires at least two arguments.");
unsigned try;
const char *key_file = NULL;
usec_t until;
+ crypt_status_info status;
if (argc < 4) {
log_error("attach requires at least two arguments.");
goto finish;
}
- if (argc >= 5 && argv[4][0] && !streq(argv[4], "-")) {
+ if (argc >= 5 &&
+ argv[4][0] &&
+ !streq(argv[4], "-") &&
+ !streq(argv[4], "none")) {
if (!path_is_absolute(argv[4]))
log_error("Password file path %s is not absolute. Ignoring.", argv[4]);
if (argc >= 6 && argv[5][0] && !streq(argv[5], "-"))
parse_options(argv[5]);
+ /* A delicious drop of snake oil */
+ mlockall(MCL_FUTURE);
+
if ((k = crypt_init(&cd, argv[3]))) {
log_error("crypt_init() failed: %s", strerror(-k));
goto finish;
opt_tries = opt_tries > 0 ? opt_tries : 3;
opt_key_size = (opt_key_size > 0 ? opt_key_size : 256);
- cipher = opt_cipher ? opt_cipher : "aes";
- cipher_mode = opt_cipher_mode ? opt_cipher_mode : "cbc-essiv:sha256";
hash = opt_hash ? opt_hash : "ripemd160";
+ if (opt_cipher) {
+ size_t l;
+
+ l = strcspn(opt_cipher, "-");
+
+ if (!(truncated_cipher = strndup(opt_cipher, l))) {
+ log_error("Out of memory");
+ goto finish;
+ }
+
+ cipher = truncated_cipher;
+ cipher_mode = opt_cipher[l] ? opt_cipher+l+1 : "plain";
+ } else {
+ cipher = "aes";
+ cipher_mode = "cbc-essiv:sha256";
+ }
+
for (try = 0; try < opt_tries; try++) {
bool pass_volume_key = false;
password = NULL;
if (!key_file) {
+ char *text;
+
+ if (asprintf(&text, "Please enter passphrase for disk %s!", argv[2]) < 0) {
+ log_error("Out of memory");
+ goto finish;
+ }
- if ((k = ask_password_auto("Please enter passphrase for disk:", "drive-harddisk", until, &password)) < 0) {
+ k = ask_password_auto(text, "drive-harddisk", until, &password);
+ free(text);
+
+ if (k < 0) {
log_error("Failed to query password: %s", strerror(-k));
goto finish;
}
if (opt_verify) {
char *password2 = NULL;
- if ((k = ask_password_auto("Please enter passphrase for disk (verification):", "drive-harddisk", until, &password2)) < 0) {
+ if (asprintf(&text, "Please enter passphrase for disk %s! (verification)", argv[2]) < 0) {
+ log_error("Out of memory");
+ goto finish;
+ }
+
+ k = ask_password_auto(text, "drive-harddisk", until, &password2);
+ free(text);
+
+ if (k < 0) {
log_error("Failed to query verification password: %s", strerror(-k));
goto finish;
}
crypt_free(cd);
free(opt_cipher);
- free(opt_cipher_mode);
free(opt_hash);
+ free(truncated_cipher);
+
free(password);
return r;