~ubuntu-branches/debian/sid/cryptsetup/sid

« back to all changes in this revision

Viewing changes to .pc/03_create_fix_keyfile.patch/src/cryptsetup.c

  • Committer: Package Import Robot
  • Author(s): Jonas Meurer
  • Date: 2012-02-05 03:17:59 UTC
  • mfrom: (0.2.9)
  • Revision ID: package-import@ubuntu.com-20120205031759-kua3bplwunj0q2zl
Tags: 2:1.4.1-1
* new upstream release (1.4.0 + 1.4.1) (closes: #647851)
  - fixes typo in german translation. (closes: #645528)
  - remove patches, all incorporated upstream.
  - soname bump, rename library package to libcryptsetup4
* check for busybox in initramfs cryptroot hook, and install the sed binary
  in case it's either not installed or not activated. (closes: #591853)
* add checks for 'type $KEYSCRIPT' to initscripts cryptdisks.functions, and
  to cryptroot initramfs script/hook. this adds support for keyscripts inside
  $PATH. thanks to Ian Jackson for the suggestion. (closes: #597583)
* use argument '--sysinit' for vgchange in cryptroot initramfs script. Thanks
  to Christoph Anton Mitterer for the suggestion.
* add option for discard/trim features to crypttab and initramfs scripts.
  Thanks to intrigeri and Peter Colberg for patches. (closes: #648868)
* print $target on error in initramfs hook. Thanks to Daniel Hahler for the
  bugreport. (closes: #648192)
* add a warning about using decrypt_derived keyscript for devices with
  persistent data. Thanks to Arno Wagner for pointing this out.
* remove quotes from resume device candidates at get_resume_devs() in
  initramfs hook script. Thanks to Johannes Rohr. (closes: #634017)
* support custom $TABFILE, thanks to Douglas Huff. (closes: #638317)
* fix get_lvm_deps() in initramfs cryptroot hook to add all physical volumes
  of lvm volume group that contains the rootfs logical volume, even if the
  rootfs is lv is not spread over all physical volumes. Thanks to Christian
  Pernegger for bugreport and patch. (closes: #634109)
* debian/initramfs/cryptroot-script: Move check for maximum number of tries
  behind the while loop, to make the warning appear in case that maximum
  number of tries is reached. Thanks to Chistian Lamparter for bugreport and
  patch. (closes: #646083)
* incorporate changes to package descriptions and debconf templates that
  suggested by debian-l10n-english people. Special thanks go to Justin B Rye.
* acknowledge NMU, thanks a lot to Christian Perrier for his great work on
  the i18n front. (closes: #633105, #641719, #641839, #641947, #642470,
  #640056, #642540, #643633, #643962, #644853)
* add and update debconf translations:
  - italian, thanks to Milo Casagrande, Francesca Ciceri. (closes: #656933)
  - german, thanks to Erik Pfannenstein. (closes: #642147)
  - spanish, thanks to Camaleón. (closes: #658360)
  - russian, thanks to Yuri Kuzlov (closes: #654676)
* set architecture to linux-any, depends on linux kernel anyway. Thanks to
  Christoph Egger. (closes: #638257)
* small updates to the copyright file.
* add targets build-indep and build-arch to debian/rules, thanks to lintian.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * cryptsetup - setup cryptographic volumes for dm-crypt
3
 
 *
4
 
 * Copyright (C) 2004, Christophe Saout <christophe@saout.de>
5
 
 * Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
6
 
 * Copyright (C) 2009-2011, Red Hat, Inc. All rights reserved.
7
 
 *
8
 
 * This program is free software; you can redistribute it and/or
9
 
 * modify it under the terms of the GNU General Public License
10
 
 * version 2 as published by the Free Software Foundation.
11
 
 *
12
 
 * This program is distributed in the hope that it will be useful,
13
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
 * GNU General Public License for more details.
16
 
 *
17
 
 * You should have received a copy of the GNU General Public License
18
 
 * along with this program; if not, write to the Free Software
19
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 
 */
21
 
 
22
 
#include <string.h>
23
 
#include <stdio.h>
24
 
#include <stdlib.h>
25
 
#include <stdint.h>
26
 
#include <stdarg.h>
27
 
#include <inttypes.h>
28
 
#include <errno.h>
29
 
#include <unistd.h>
30
 
#include <fcntl.h>
31
 
#include <assert.h>
32
 
#include <libcryptsetup.h>
33
 
#include <popt.h>
34
 
 
35
 
#include "cryptsetup.h"
36
 
 
37
 
static int opt_verbose = 0;
38
 
static int opt_debug = 0;
39
 
static char *opt_cipher = NULL;
40
 
static char *opt_hash = NULL;
41
 
static int opt_verify_passphrase = 0;
42
 
static char *opt_key_file = NULL;
43
 
static char *opt_master_key_file = NULL;
44
 
static char *opt_header_backup_file = NULL;
45
 
static char *opt_uuid = NULL;
46
 
static int opt_key_size = 0;
47
 
static long opt_keyfile_size = 0;
48
 
static long opt_new_keyfile_size = 0;
49
 
static int opt_key_slot = CRYPT_ANY_SLOT;
50
 
static uint64_t opt_size = 0;
51
 
static uint64_t opt_offset = 0;
52
 
static uint64_t opt_skip = 0;
53
 
static int opt_skip_valid = 0;
54
 
static int opt_readonly = 0;
55
 
static int opt_iteration_time = 1000;
56
 
static int opt_batch_mode = 0;
57
 
static int opt_version_mode = 0;
58
 
static int opt_timeout = 0;
59
 
static int opt_tries = 3;
60
 
static int opt_align_payload = 0;
61
 
static int opt_random = 0;
62
 
static int opt_urandom = 0;
63
 
static int opt_dump_master_key = 0;
64
 
 
65
 
static const char **action_argv;
66
 
static int action_argc;
67
 
 
68
 
static int action_create(int arg);
69
 
static int action_remove(int arg);
70
 
static int action_resize(int arg);
71
 
static int action_status(int arg);
72
 
static int action_luksFormat(int arg);
73
 
static int action_luksOpen(int arg);
74
 
static int action_luksAddKey(int arg);
75
 
static int action_luksKillSlot(int arg);
76
 
static int action_luksRemoveKey(int arg);
77
 
static int action_luksChangeKey(int arg);
78
 
static int action_isLuks(int arg);
79
 
static int action_luksUUID(int arg);
80
 
static int action_luksDump(int arg);
81
 
static int action_luksSuspend(int arg);
82
 
static int action_luksResume(int arg);
83
 
static int action_luksBackup(int arg);
84
 
static int action_luksRestore(int arg);
85
 
static int action_loopaesOpen(int arg);
86
 
 
87
 
static struct action_type {
88
 
        const char *type;
89
 
        int (*handler)(int);
90
 
        int arg;
91
 
        int required_action_argc;
92
 
        int required_memlock;
93
 
        const char *arg_desc;
94
 
        const char *desc;
95
 
} action_types[] = {
96
 
        { "create",     action_create,          0, 2, 1, N_("<name> <device>"),N_("create device") },
97
 
        { "remove",     action_remove,          0, 1, 1, N_("<name>"), N_("remove device") },
98
 
        { "resize",     action_resize,          0, 1, 1, N_("<name>"), N_("resize active device") },
99
 
        { "status",     action_status,          0, 1, 0, N_("<name>"), N_("show device status") },
100
 
        { "luksFormat", action_luksFormat,      0, 1, 1, N_("<device> [<new key file>]"), N_("formats a LUKS device") },
101
 
        { "luksOpen",   action_luksOpen,        0, 2, 1, N_("<device> <name> "), N_("open LUKS device as mapping <name>") },
102
 
        { "luksAddKey", action_luksAddKey,      0, 1, 1, N_("<device> [<new key file>]"), N_("add key to LUKS device") },
103
 
        { "luksRemoveKey",action_luksRemoveKey, 0, 1, 1, N_("<device> [<key file>]"), N_("removes supplied key or key file from LUKS device") },
104
 
        { "luksChangeKey",action_luksChangeKey, 0, 1, 1, N_("<device> [<key file>]"), N_("changes supplied key or key file of LUKS device") },
105
 
        { "luksKillSlot",  action_luksKillSlot, 0, 2, 1, N_("<device> <key slot>"), N_("wipes key with number <key slot> from LUKS device") },
106
 
        { "luksUUID",   action_luksUUID,        0, 1, 0, N_("<device>"), N_("print UUID of LUKS device") },
107
 
        { "isLuks",     action_isLuks,          0, 1, 0, N_("<device>"), N_("tests <device> for LUKS partition header") },
108
 
        { "luksClose",  action_remove,          0, 1, 1, N_("<name>"), N_("remove LUKS mapping") },
109
 
        { "luksDump",   action_luksDump,        0, 1, 1, N_("<device>"), N_("dump LUKS partition information") },
110
 
        { "luksSuspend",action_luksSuspend,     0, 1, 1, N_("<device>"), N_("Suspend LUKS device and wipe key (all IOs are frozen).") },
111
 
        { "luksResume", action_luksResume,      0, 1, 1, N_("<device>"), N_("Resume suspended LUKS device.") },
112
 
        { "luksHeaderBackup",action_luksBackup, 0, 1, 1, N_("<device>"), N_("Backup LUKS device header and keyslots") },
113
 
        { "luksHeaderRestore",action_luksRestore,0,1, 1, N_("<device>"), N_("Restore LUKS device header and keyslots") },
114
 
        { "loopaesOpen",action_loopaesOpen,     0, 2, 1, N_("<device> <name> "), N_("open loop-AES device as mapping <name>") },
115
 
        { "loopaesClose",action_remove,         0, 1, 1, N_("<name>"), N_("remove loop-AES mapping") },
116
 
        { NULL, NULL, 0, 0, 0, NULL, NULL }
117
 
};
118
 
 
119
 
static void clogger(struct crypt_device *cd, int level, const char *file,
120
 
                   int line, const char *format, ...)
121
 
{
122
 
        va_list argp;
123
 
        char *target = NULL;
124
 
 
125
 
        va_start(argp, format);
126
 
 
127
 
        if (vasprintf(&target, format, argp) > 0) {
128
 
                if (level >= 0) {
129
 
                        crypt_log(cd, level, target);
130
 
#ifdef CRYPT_DEBUG
131
 
                } else if (opt_debug)
132
 
                        printf("# %s:%d %s\n", file ?: "?", line, target);
133
 
#else
134
 
                } else if (opt_debug)
135
 
                        printf("# %s\n", target);
136
 
#endif
137
 
        }
138
 
 
139
 
        va_end(argp);
140
 
        free(target);
141
 
}
142
 
 
143
 
static int _yesDialog(const char *msg, void *usrptr)
144
 
{
145
 
        char *answer = NULL;
146
 
        size_t size = 0;
147
 
        int r = 1;
148
 
 
149
 
        if(isatty(0) && !opt_batch_mode) {
150
 
                log_std("\nWARNING!\n========\n");
151
 
                log_std("%s\n\nAre you sure? (Type uppercase yes): ", msg);
152
 
                if(getline(&answer, &size, stdin) == -1) {
153
 
                        perror("getline");
154
 
                        free(answer);
155
 
                        return 0;
156
 
                }
157
 
                if(strcmp(answer, "YES\n"))
158
 
                        r = 0;
159
 
                free(answer);
160
 
        }
161
 
 
162
 
        return r;
163
 
}
164
 
 
165
 
static void _log(int level, const char *msg, void *usrptr)
166
 
{
167
 
        switch(level) {
168
 
 
169
 
        case CRYPT_LOG_NORMAL:
170
 
                fputs(msg, stdout);
171
 
                break;
172
 
        case CRYPT_LOG_VERBOSE:
173
 
                if (opt_verbose)
174
 
                        fputs(msg, stdout);
175
 
                break;
176
 
        case CRYPT_LOG_ERROR:
177
 
                fputs(msg, stderr);
178
 
                break;
179
 
        case CRYPT_LOG_DEBUG:
180
 
                if (opt_debug)
181
 
                        printf("# %s\n", msg);
182
 
                break;
183
 
        default:
184
 
                fprintf(stderr, "Internal error on logging class for msg: %s", msg);
185
 
                break;
186
 
        }
187
 
}
188
 
 
189
 
static void show_status(int errcode)
190
 
{
191
 
        char error[256], *error_;
192
 
 
193
 
        if(!opt_verbose)
194
 
                return;
195
 
 
196
 
        if(!errcode) {
197
 
                log_std(_("Command successful.\n"));
198
 
                return;
199
 
        }
200
 
 
201
 
        crypt_get_error(error, sizeof(error));
202
 
 
203
 
        if (!error[0]) {
204
 
                error_ = strerror_r(-errcode, error, sizeof(error));
205
 
                if (error_ != error) {
206
 
                        strncpy(error, error_, sizeof(error));
207
 
                        error[sizeof(error) - 1] = '\0';
208
 
                }
209
 
        }
210
 
 
211
 
        log_err(_("Command failed with code %i"), -errcode);
212
 
        if (*error)
213
 
                log_err(": %s\n", error);
214
 
        else
215
 
                log_err(".\n");
216
 
}
217
 
 
218
 
static int action_create(int arg)
219
 
{
220
 
        struct crypt_device *cd = NULL;
221
 
        char cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
222
 
        struct crypt_params_plain params = {
223
 
                .hash = opt_hash ?: DEFAULT_PLAIN_HASH,
224
 
                .skip = opt_skip,
225
 
                .offset = opt_offset,
226
 
        };
227
 
        char *password = NULL;
228
 
        size_t passwordLen;
229
 
        size_t key_size = (opt_key_size ?: DEFAULT_PLAIN_KEYBITS) / 8;
230
 
        int r;
231
 
 
232
 
        if (params.hash && !strcmp(params.hash, "plain"))
233
 
                params.hash = NULL;
234
 
 
235
 
        /* FIXME: temporary hack */
236
 
        if (opt_key_file && strcmp(opt_key_file, "-"))
237
 
                params.hash = NULL;
238
 
 
239
 
        if (opt_keyfile_size && opt_key_file)
240
 
                log_std(("Ignoring keyfile size option, keyfile read size "
241
 
                         "is always the same as encryption key size.\n"));
242
 
 
243
 
        r = crypt_parse_name_and_mode(opt_cipher ?: DEFAULT_CIPHER(PLAIN),
244
 
                                      cipher, NULL, cipher_mode);
245
 
        if (r < 0) {
246
 
                log_err("No known cipher specification pattern detected.\n");
247
 
                goto out;
248
 
        }
249
 
 
250
 
        if ((r = crypt_init(&cd, action_argv[1])))
251
 
                goto out;
252
 
 
253
 
        crypt_set_timeout(cd, opt_timeout);
254
 
        crypt_set_password_retry(cd, opt_tries);
255
 
 
256
 
        r = crypt_format(cd, CRYPT_PLAIN,
257
 
                         cipher, cipher_mode,
258
 
                         NULL, NULL,
259
 
                         key_size,
260
 
                         &params);
261
 
        if (r < 0)
262
 
                goto out;
263
 
 
264
 
        if (opt_key_file)
265
 
                r = crypt_activate_by_keyfile(cd, action_argv[0],
266
 
                        CRYPT_ANY_SLOT, opt_key_file, key_size,
267
 
                        opt_readonly ?  CRYPT_ACTIVATE_READONLY : 0);
268
 
        else {
269
 
                r = crypt_get_key(_("Enter passphrase: "),
270
 
                                  &password, &passwordLen, opt_keyfile_size,
271
 
                                  NULL, opt_timeout,
272
 
                                  opt_batch_mode ? 0 : opt_verify_passphrase,
273
 
                                  cd);
274
 
                if (r < 0)
275
 
                        goto out;
276
 
 
277
 
                r = crypt_activate_by_passphrase(cd, action_argv[0],
278
 
                        CRYPT_ANY_SLOT, password, passwordLen,
279
 
                        opt_readonly ?  CRYPT_ACTIVATE_READONLY : 0);
280
 
        }
281
 
 
282
 
        /* FIXME: workaround, new api missing format parameter for size.
283
 
         * Properly fix it after bumping library version,
284
 
         * add start_offset and size into "PLAIN" format specifiers.
285
 
         */
286
 
        if (r >= 0 && opt_size)
287
 
                r = crypt_resize(cd, action_argv[0], opt_size);
288
 
 
289
 
out:
290
 
        crypt_free(cd);
291
 
        crypt_safe_free(password);
292
 
 
293
 
        return r;
294
 
}
295
 
 
296
 
static int action_loopaesOpen(int arg)
297
 
{
298
 
        struct crypt_device *cd = NULL;
299
 
        struct crypt_params_loopaes params = {
300
 
                .hash = opt_hash ?: NULL,
301
 
                .offset = opt_offset,
302
 
                .skip = opt_skip_valid ? opt_skip : opt_offset,
303
 
        };
304
 
        unsigned int key_size = (opt_key_size ?: DEFAULT_LOOPAES_KEYBITS) / 8;
305
 
        int r;
306
 
 
307
 
        if (!opt_key_file) {
308
 
                log_err(_("Option --key-file is required.\n"));
309
 
                return -EINVAL;
310
 
        }
311
 
 
312
 
        if ((r = crypt_init(&cd, action_argv[0])))
313
 
                goto out;
314
 
 
315
 
        r = crypt_format(cd, CRYPT_LOOPAES, opt_cipher ?: DEFAULT_LOOPAES_CIPHER,
316
 
                         NULL, NULL, NULL, key_size, &params);
317
 
        if (r < 0)
318
 
                goto out;
319
 
 
320
 
        r = crypt_activate_by_keyfile(cd, action_argv[1],
321
 
                CRYPT_ANY_SLOT, opt_key_file, opt_keyfile_size,
322
 
                opt_readonly ?  CRYPT_ACTIVATE_READONLY : 0);
323
 
out:
324
 
        crypt_free(cd);
325
 
 
326
 
        return r;
327
 
}
328
 
 
329
 
static int action_remove(int arg)
330
 
{
331
 
        struct crypt_device *cd = NULL;
332
 
        int r;
333
 
 
334
 
        r = crypt_init_by_name(&cd, action_argv[0]);
335
 
        if (r == 0)
336
 
                r = crypt_deactivate(cd, action_argv[0]);
337
 
 
338
 
        crypt_free(cd);
339
 
        return r;
340
 
}
341
 
 
342
 
static int action_resize(int arg)
343
 
{
344
 
        struct crypt_device *cd = NULL;
345
 
        int r;
346
 
 
347
 
        r = crypt_init_by_name(&cd, action_argv[0]);
348
 
        if (r == 0)
349
 
                r = crypt_resize(cd, action_argv[0], opt_size);
350
 
 
351
 
        crypt_free(cd);
352
 
        return r;
353
 
}
354
 
 
355
 
static int action_status(int arg)
356
 
{
357
 
        crypt_status_info ci;
358
 
        struct crypt_active_device cad;
359
 
        struct crypt_device *cd = NULL;
360
 
        char *backing_file;
361
 
        const char *device;
362
 
        int r = 0;
363
 
 
364
 
        ci = crypt_status(NULL, action_argv[0]);
365
 
        switch (ci) {
366
 
        case CRYPT_INVALID:
367
 
                r = -ENODEV;
368
 
                break;
369
 
        case CRYPT_INACTIVE:
370
 
                log_std("%s/%s is inactive.\n", crypt_get_dir(), action_argv[0]);
371
 
                break;
372
 
        case CRYPT_ACTIVE:
373
 
        case CRYPT_BUSY:
374
 
                log_std("%s/%s is active%s.\n", crypt_get_dir(), action_argv[0],
375
 
                        ci == CRYPT_BUSY ? " and is in use" : "");
376
 
                r = crypt_init_by_name(&cd, action_argv[0]);
377
 
                if (r < 0 || !crypt_get_type(cd))
378
 
                        goto out;
379
 
 
380
 
                log_std("  type:    %s\n", crypt_get_type(cd));
381
 
 
382
 
                r = crypt_get_active_device(cd, action_argv[0], &cad);
383
 
                if (r < 0)
384
 
                        goto out;
385
 
 
386
 
                log_std("  cipher:  %s-%s\n", crypt_get_cipher(cd), crypt_get_cipher_mode(cd));
387
 
                log_std("  keysize: %d bits\n", crypt_get_volume_key_size(cd) * 8);
388
 
                device = crypt_get_device_name(cd);
389
 
                log_std("  device:  %s\n", device);
390
 
                if (crypt_loop_device(device)) {
391
 
                        backing_file = crypt_loop_backing_file(device);
392
 
                        log_std("  loop:    %s\n", backing_file);
393
 
                        free(backing_file);
394
 
                }
395
 
                log_std("  offset:  %" PRIu64 " sectors\n", cad.offset);
396
 
                log_std("  size:    %" PRIu64 " sectors\n", cad.size);
397
 
                if (cad.iv_offset)
398
 
                        log_std("  skipped: %" PRIu64 " sectors\n", cad.iv_offset);
399
 
                log_std("  mode:    %s\n", cad.flags & CRYPT_ACTIVATE_READONLY ?
400
 
                                           "readonly" : "read/write");
401
 
        }
402
 
out:
403
 
        crypt_free(cd);
404
 
        return r;
405
 
}
406
 
 
407
 
static int _read_mk(const char *file, char **key, int keysize)
408
 
{
409
 
        int fd;
410
 
 
411
 
        *key = crypt_safe_alloc(keysize);
412
 
        if (!*key)
413
 
                return -ENOMEM;
414
 
 
415
 
        fd = open(file, O_RDONLY);
416
 
        if (fd == -1) {
417
 
                log_err("Cannot read keyfile %s.\n", file);
418
 
                goto fail;
419
 
        }
420
 
        if ((read(fd, *key, keysize) != keysize)) {
421
 
                log_err("Cannot read %d bytes from keyfile %s.\n", keysize, file);
422
 
                close(fd);
423
 
                goto fail;
424
 
        }
425
 
        close(fd);
426
 
        return 0;
427
 
fail:
428
 
        crypt_safe_free(*key);
429
 
        *key = NULL;
430
 
        return -EINVAL;
431
 
}
432
 
 
433
 
static int action_luksFormat(int arg)
434
 
{
435
 
        int r = -EINVAL, keysize;
436
 
        char *msg = NULL, *key = NULL, cipher [MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
437
 
        char *password = NULL;
438
 
        size_t passwordLen;
439
 
        struct crypt_device *cd = NULL;
440
 
        struct crypt_params_luks1 params = {
441
 
                .hash = opt_hash ?: DEFAULT_LUKS1_HASH,
442
 
                .data_alignment = opt_align_payload,
443
 
        };
444
 
 
445
 
        if(asprintf(&msg, _("This will overwrite data on %s irrevocably."), action_argv[0]) == -1) {
446
 
                log_err(_("memory allocation error in action_luksFormat"));
447
 
                r = -ENOMEM;
448
 
                goto out;
449
 
        }
450
 
        r = _yesDialog(msg, NULL) ? 0 : -EINVAL;
451
 
        free(msg);
452
 
        if (r < 0)
453
 
                goto out;
454
 
 
455
 
        r = crypt_parse_name_and_mode(opt_cipher ?: DEFAULT_CIPHER(LUKS1),
456
 
                                      cipher, NULL, cipher_mode);
457
 
        if (r < 0) {
458
 
                log_err("No known cipher specification pattern detected.\n");
459
 
                goto out;
460
 
        }
461
 
 
462
 
        if ((r = crypt_init(&cd, action_argv[0])))
463
 
                goto out;
464
 
 
465
 
        keysize = (opt_key_size ?: DEFAULT_LUKS1_KEYBITS) / 8;
466
 
 
467
 
        crypt_set_password_verify(cd, 1);
468
 
        crypt_set_timeout(cd, opt_timeout);
469
 
        if (opt_iteration_time)
470
 
                crypt_set_iterarion_time(cd, opt_iteration_time);
471
 
 
472
 
        if (opt_random)
473
 
                crypt_set_rng_type(cd, CRYPT_RNG_RANDOM);
474
 
        else if (opt_urandom)
475
 
                crypt_set_rng_type(cd, CRYPT_RNG_URANDOM);
476
 
 
477
 
        r = crypt_get_key(_("Enter LUKS passphrase: "), &password, &passwordLen,
478
 
                          opt_keyfile_size, opt_key_file, opt_timeout,
479
 
                          opt_batch_mode ? 0 : 1 /* always verify */, cd);
480
 
        if (r < 0)
481
 
                goto out;
482
 
 
483
 
        if (opt_master_key_file) {
484
 
                r = _read_mk(opt_master_key_file, &key, keysize);
485
 
                if (r < 0)
486
 
                        goto out;
487
 
        }
488
 
 
489
 
        r = crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode,
490
 
                         opt_uuid, key, keysize, &params);
491
 
        if (r < 0)
492
 
                goto out;
493
 
 
494
 
        r = crypt_keyslot_add_by_volume_key(cd, opt_key_slot,
495
 
                                            key, keysize,
496
 
                                            password, passwordLen);
497
 
out:
498
 
        crypt_free(cd);
499
 
        crypt_safe_free(key);
500
 
        crypt_safe_free(password);
501
 
 
502
 
        return r;
503
 
}
504
 
 
505
 
static int action_luksOpen(int arg)
506
 
{
507
 
        struct crypt_device *cd = NULL;
508
 
        uint32_t flags = 0;
509
 
        int r;
510
 
 
511
 
        if ((r = crypt_init(&cd, action_argv[0])))
512
 
                goto out;
513
 
 
514
 
        if ((r = crypt_load(cd, CRYPT_LUKS1, NULL)))
515
 
                goto out;
516
 
 
517
 
        crypt_set_timeout(cd, opt_timeout);
518
 
        crypt_set_password_retry(cd, opt_tries);
519
 
 
520
 
        if (opt_iteration_time)
521
 
                crypt_set_iterarion_time(cd, opt_iteration_time);
522
 
        if (opt_readonly)
523
 
                flags |= CRYPT_ACTIVATE_READONLY;
524
 
 
525
 
        if (opt_key_file) {
526
 
                crypt_set_password_retry(cd, 1);
527
 
                r = crypt_activate_by_keyfile(cd, action_argv[1],
528
 
                        CRYPT_ANY_SLOT, opt_key_file, opt_keyfile_size,
529
 
                        flags);
530
 
        } else
531
 
                r = crypt_activate_by_passphrase(cd, action_argv[1],
532
 
                        CRYPT_ANY_SLOT, NULL, 0, flags);
533
 
out:
534
 
        crypt_free(cd);
535
 
        return r;
536
 
}
537
 
 
538
 
static int verify_keyslot(struct crypt_device *cd, int key_slot,
539
 
                          char *msg_last, char *msg_pass,
540
 
                          const char *key_file, int keyfile_size)
541
 
{
542
 
        crypt_keyslot_info ki;
543
 
        char *password = NULL;
544
 
        size_t passwordLen;
545
 
        int i, r;
546
 
 
547
 
        ki = crypt_keyslot_status(cd, key_slot);
548
 
        if (ki == CRYPT_SLOT_ACTIVE_LAST && msg_last && !_yesDialog(msg_last, NULL))
549
 
                return -EPERM;
550
 
 
551
 
        r = crypt_get_key(msg_pass, &password, &passwordLen,
552
 
                          keyfile_size, key_file, opt_timeout,
553
 
                          opt_batch_mode ? 0 : opt_verify_passphrase, cd);
554
 
        if(r < 0)
555
 
                goto out;
556
 
 
557
 
        if (ki == CRYPT_SLOT_ACTIVE_LAST) {
558
 
                /* check the last keyslot */
559
 
                r = crypt_activate_by_passphrase(cd, NULL, key_slot,
560
 
                                                 password, passwordLen, 0);
561
 
        } else {
562
 
                /* try all other keyslots */
563
 
                for (i = 0; i < crypt_keyslot_max(CRYPT_LUKS1); i++) {
564
 
                        if (i == key_slot)
565
 
                                continue;
566
 
                        ki = crypt_keyslot_status(cd, key_slot);
567
 
                        if (ki == CRYPT_SLOT_ACTIVE)
568
 
                        r = crypt_activate_by_passphrase(cd, NULL, i,
569
 
                                                         password, passwordLen, 0);
570
 
                        if (r == i)
571
 
                                break;
572
 
                }
573
 
        }
574
 
 
575
 
        if (r < 0)
576
 
                log_err(_("No key available with this passphrase.\n"));
577
 
out:
578
 
        crypt_safe_free(password);
579
 
        return r;
580
 
}
581
 
 
582
 
static int action_luksKillSlot(int arg)
583
 
{
584
 
        struct crypt_device *cd = NULL;
585
 
        int r;
586
 
 
587
 
        if ((r = crypt_init(&cd, action_argv[0])))
588
 
                goto out;
589
 
 
590
 
        crypt_set_confirm_callback(cd, _yesDialog, NULL);
591
 
        crypt_set_timeout(cd, opt_timeout);
592
 
 
593
 
        if ((r = crypt_load(cd, CRYPT_LUKS1, NULL)))
594
 
                goto out;
595
 
 
596
 
        switch (crypt_keyslot_status(cd, opt_key_slot)) {
597
 
        case CRYPT_SLOT_ACTIVE_LAST:
598
 
        case CRYPT_SLOT_ACTIVE:
599
 
                log_verbose(_("Key slot %d selected for deletion.\n"), opt_key_slot);
600
 
                break;
601
 
        case CRYPT_SLOT_INACTIVE:
602
 
                log_err(_("Key %d not active. Can't wipe.\n"), opt_key_slot);
603
 
        case CRYPT_SLOT_INVALID:
604
 
                goto out;
605
 
        }
606
 
 
607
 
        if (!opt_batch_mode) {
608
 
                r = verify_keyslot(cd, opt_key_slot,
609
 
                        _("This is the last keyslot. Device will become unusable after purging this key."),
610
 
                        _("Enter any remaining LUKS passphrase: "),
611
 
                        opt_key_file, opt_keyfile_size);
612
 
                if (r < 0)
613
 
                        goto out;
614
 
        }
615
 
 
616
 
        r = crypt_keyslot_destroy(cd, opt_key_slot);
617
 
out:
618
 
        crypt_free(cd);
619
 
        return r;
620
 
}
621
 
 
622
 
static int action_luksRemoveKey(int arg)
623
 
{
624
 
        struct crypt_device *cd = NULL;
625
 
        char *password = NULL;
626
 
        size_t passwordLen;
627
 
        int r;
628
 
 
629
 
        if ((r = crypt_init(&cd, action_argv[0])))
630
 
                goto out;
631
 
 
632
 
        crypt_set_confirm_callback(cd, _yesDialog, NULL);
633
 
        crypt_set_timeout(cd, opt_timeout);
634
 
 
635
 
        if ((r = crypt_load(cd, CRYPT_LUKS1, NULL)))
636
 
                goto out;
637
 
 
638
 
        r = crypt_get_key(_("Enter LUKS passphrase to be deleted: "),
639
 
                      &password, &passwordLen,
640
 
                      opt_keyfile_size, opt_key_file,
641
 
                      opt_timeout,
642
 
                      opt_batch_mode ? 0 : opt_verify_passphrase,
643
 
                      cd);
644
 
        if(r < 0)
645
 
                goto out;
646
 
 
647
 
        r = crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT,
648
 
                                         password, passwordLen, 0);
649
 
        if (r < 0)
650
 
                goto out;
651
 
 
652
 
        opt_key_slot = r;
653
 
        log_verbose(_("Key slot %d selected for deletion.\n"), opt_key_slot);
654
 
 
655
 
        if (crypt_keyslot_status(cd, opt_key_slot) == CRYPT_SLOT_ACTIVE_LAST &&
656
 
            !_yesDialog(_("This is the last keyslot. "
657
 
                          "Device will become unusable after purging this key."),
658
 
                        NULL)) {
659
 
                r = -EPERM;
660
 
                goto out;
661
 
        }
662
 
 
663
 
        r = crypt_keyslot_destroy(cd, opt_key_slot);
664
 
out:
665
 
        crypt_safe_free(password);
666
 
        crypt_free(cd);
667
 
        return r;
668
 
}
669
 
 
670
 
static int action_luksAddKey(int arg)
671
 
{
672
 
        int r = -EINVAL, keysize = 0;
673
 
        char *key = NULL;
674
 
        const char *opt_new_key_file = (action_argc > 1 ? action_argv[1] : NULL);
675
 
        struct crypt_device *cd = NULL;
676
 
 
677
 
        if ((r = crypt_init(&cd, action_argv[0])))
678
 
                goto out;
679
 
 
680
 
        crypt_set_confirm_callback(cd, _yesDialog, NULL);
681
 
 
682
 
        if ((r = crypt_load(cd, CRYPT_LUKS1, NULL)))
683
 
                goto out;
684
 
 
685
 
        keysize = crypt_get_volume_key_size(cd);
686
 
        crypt_set_password_verify(cd, opt_verify_passphrase ? 1 : 0);
687
 
        crypt_set_timeout(cd, opt_timeout);
688
 
        if (opt_iteration_time)
689
 
                crypt_set_iterarion_time(cd, opt_iteration_time);
690
 
 
691
 
        if (opt_master_key_file) {
692
 
                r = _read_mk(opt_master_key_file, &key, keysize);
693
 
                if (r < 0)
694
 
                        goto out;
695
 
                //FIXME: process keyfile arg
696
 
                r = crypt_keyslot_add_by_volume_key(cd, opt_key_slot,
697
 
                                                    key, keysize, NULL, 0);
698
 
        } else if (opt_key_file || opt_new_key_file) {
699
 
                r = crypt_keyslot_add_by_keyfile(cd, opt_key_slot,
700
 
                                                 opt_key_file, opt_keyfile_size,
701
 
                                                 opt_new_key_file, opt_new_keyfile_size);
702
 
        } else {
703
 
                r = crypt_keyslot_add_by_passphrase(cd, opt_key_slot,
704
 
                                                    NULL, 0, NULL, 0);
705
 
        }
706
 
out:
707
 
        crypt_free(cd);
708
 
        crypt_safe_free(key);
709
 
        return r;
710
 
}
711
 
 
712
 
static int _slots_full(struct crypt_device *cd)
713
 
{
714
 
        int i;
715
 
 
716
 
        for (i = 0; i < crypt_keyslot_max(crypt_get_type(cd)); i++)
717
 
                if (crypt_keyslot_status(cd, i) == CRYPT_SLOT_INACTIVE)
718
 
                        return 0;
719
 
        return 1;
720
 
}
721
 
 
722
 
static int action_luksChangeKey(int arg)
723
 
{
724
 
        const char *opt_new_key_file = (action_argc > 1 ? action_argv[1] : NULL);
725
 
        struct crypt_device *cd = NULL;
726
 
        char *vk = NULL, *password = NULL;
727
 
        size_t passwordLen = 0;
728
 
        size_t vk_size;
729
 
        int new_key_slot, old_key_slot, r;
730
 
 
731
 
        if ((r = crypt_init(&cd, action_argv[0])))
732
 
                goto out;
733
 
 
734
 
        if ((r = crypt_load(cd, CRYPT_LUKS1, NULL)))
735
 
                goto out;
736
 
 
737
 
        if (opt_iteration_time)
738
 
                crypt_set_iterarion_time(cd, opt_iteration_time);
739
 
 
740
 
        r = crypt_get_key(_("Enter LUKS passphrase to be changed: "),
741
 
                      &password, &passwordLen,
742
 
                      opt_keyfile_size, opt_key_file, opt_timeout,
743
 
                      opt_batch_mode ? 0 : opt_verify_passphrase, cd);
744
 
        if (r < 0)
745
 
                goto out;
746
 
 
747
 
        vk_size = crypt_get_volume_key_size(cd);
748
 
        vk = crypt_safe_alloc(vk_size);
749
 
        if (!vk) {
750
 
                r = -ENOMEM;
751
 
                goto out;
752
 
        }
753
 
 
754
 
        r = crypt_volume_key_get(cd, opt_key_slot, vk, &vk_size,
755
 
                                 password, passwordLen);
756
 
        if (r < 0) {
757
 
                if (opt_key_slot != CRYPT_ANY_SLOT)
758
 
                        log_err(_("No key available with this passphrase.\n"));
759
 
                goto out;
760
 
        }
761
 
 
762
 
        if (opt_key_slot != CRYPT_ANY_SLOT || _slots_full(cd)) {
763
 
                log_dbg("Key slot %d is going to be overwritten (%s).",
764
 
                        r, opt_key_slot != CRYPT_ANY_SLOT ?
765
 
                        "explicit key slot specified" : "no free key slot");
766
 
                old_key_slot = r;
767
 
                new_key_slot = r;
768
 
        } else {
769
 
                log_dbg("Allocating new key slot.");
770
 
                old_key_slot = r;
771
 
                new_key_slot = CRYPT_ANY_SLOT;
772
 
        }
773
 
 
774
 
        crypt_safe_free(password);
775
 
        password = NULL;
776
 
        passwordLen = 0;
777
 
        r = crypt_get_key(_("Enter new LUKS passphrase: "),
778
 
                          &password, &passwordLen,
779
 
                          opt_new_keyfile_size, opt_new_key_file,
780
 
                          opt_timeout, opt_batch_mode ? 0 : 1, cd);
781
 
        if (r < 0)
782
 
                goto out;
783
 
 
784
 
        if (new_key_slot == old_key_slot) {
785
 
                (void)crypt_keyslot_destroy(cd, old_key_slot);
786
 
                r = crypt_keyslot_add_by_volume_key(cd, new_key_slot,
787
 
                                                    vk, vk_size,
788
 
                                                    password, passwordLen);
789
 
                if (r >= 0)
790
 
                        log_verbose(_("Key slot %d changed.\n"), r);
791
 
        } else {
792
 
                r = crypt_keyslot_add_by_volume_key(cd, CRYPT_ANY_SLOT,
793
 
                                                    vk, vk_size,
794
 
                                                    password, passwordLen);
795
 
                if (r >= 0) {
796
 
                        log_verbose(_("Replaced with key slot %d.\n"), r);
797
 
                        r = crypt_keyslot_destroy(cd, old_key_slot);
798
 
                }
799
 
        }
800
 
        if (r < 0)
801
 
                log_err(_("Failed to swap new key slot.\n"));
802
 
out:
803
 
        crypt_safe_free(vk);
804
 
        crypt_safe_free(password);
805
 
        crypt_free(cd);
806
 
        return r;
807
 
}
808
 
 
809
 
static int action_isLuks(int arg)
810
 
{
811
 
        struct crypt_device *cd = NULL;
812
 
        int r;
813
 
 
814
 
        if ((r = crypt_init(&cd, action_argv[0])))
815
 
                goto out;
816
 
 
817
 
        r = crypt_load(cd, CRYPT_LUKS1, NULL);
818
 
out:
819
 
        crypt_free(cd);
820
 
        return r;
821
 
}
822
 
 
823
 
static int action_luksUUID(int arg)
824
 
{
825
 
        struct crypt_device *cd = NULL;
826
 
        const char *existing_uuid = NULL;
827
 
        int r;
828
 
 
829
 
        if ((r = crypt_init(&cd, action_argv[0])))
830
 
                goto out;
831
 
 
832
 
        crypt_set_confirm_callback(cd, _yesDialog, NULL);
833
 
 
834
 
        if ((r = crypt_load(cd, CRYPT_LUKS1, NULL)))
835
 
                goto out;
836
 
 
837
 
        if (opt_uuid)
838
 
                r = crypt_set_uuid(cd, opt_uuid);
839
 
        else {
840
 
                existing_uuid = crypt_get_uuid(cd);
841
 
                log_std("%s\n", existing_uuid ?: "");
842
 
                r = existing_uuid ? 0 : 1;
843
 
        }
844
 
out:
845
 
        crypt_free(cd);
846
 
        return r;
847
 
}
848
 
 
849
 
static int luksDump_with_volume_key(struct crypt_device *cd)
850
 
{
851
 
        char *vk = NULL, *password = NULL;
852
 
        size_t passwordLen = 0;
853
 
        size_t vk_size;
854
 
        int i, r;
855
 
 
856
 
        crypt_set_confirm_callback(cd, _yesDialog, NULL);
857
 
        if (!_yesDialog(
858
 
            _("LUKS header dump with volume key is sensitive information\n"
859
 
              "which allows access to encrypted partition without passphrase.\n"
860
 
              "This dump should be always stored encrypted on safe place."),
861
 
              NULL))
862
 
                return -EPERM;
863
 
 
864
 
        vk_size = crypt_get_volume_key_size(cd);
865
 
        vk = crypt_safe_alloc(vk_size);
866
 
        if (!vk)
867
 
                return -ENOMEM;
868
 
 
869
 
        r = crypt_get_key(_("Enter LUKS passphrase: "), &password, &passwordLen,
870
 
                          opt_keyfile_size, opt_key_file, opt_timeout, 0, cd);
871
 
        if (r < 0)
872
 
                goto out;
873
 
 
874
 
        r = crypt_volume_key_get(cd, CRYPT_ANY_SLOT, vk, &vk_size,
875
 
                                 password, passwordLen);
876
 
        if (r < 0)
877
 
                goto out;
878
 
 
879
 
        log_std("LUKS header information for %s\n", crypt_get_device_name(cd));
880
 
        log_std("Cipher name:   \t%s\n", crypt_get_cipher(cd));
881
 
        log_std("Cipher mode:   \t%s\n", crypt_get_cipher_mode(cd));
882
 
        log_std("Payload offset:\t%d\n", crypt_get_data_offset(cd));
883
 
        log_std("UUID:          \t%s\n", crypt_get_uuid(cd));
884
 
        log_std("MK bits:       \t%d\n", vk_size * 8);
885
 
        log_std("MK dump:\t");
886
 
 
887
 
        for(i = 0; i < vk_size; i++) {
888
 
                if (i && !(i % 16))
889
 
                        log_std("\n\t\t");
890
 
                log_std("%02hhx ", (char)vk[i]);
891
 
        }
892
 
        log_std("\n");
893
 
 
894
 
out:
895
 
        crypt_safe_free(password);
896
 
        crypt_safe_free(vk);
897
 
        return r;
898
 
}
899
 
 
900
 
static int action_luksDump(int arg)
901
 
{
902
 
        struct crypt_device *cd = NULL;
903
 
        int r;
904
 
 
905
 
        if ((r = crypt_init(&cd, action_argv[0])))
906
 
                goto out;
907
 
 
908
 
        if ((r = crypt_load(cd, CRYPT_LUKS1, NULL)))
909
 
                goto out;
910
 
 
911
 
        if (opt_dump_master_key)
912
 
                r = luksDump_with_volume_key(cd);
913
 
        else
914
 
                r = crypt_dump(cd);
915
 
out:
916
 
        crypt_free(cd);
917
 
        return r;
918
 
}
919
 
 
920
 
static int action_luksSuspend(int arg)
921
 
{
922
 
        struct crypt_device *cd = NULL;
923
 
        int r;
924
 
 
925
 
        r = crypt_init_by_name(&cd, action_argv[0]);
926
 
        if (!r)
927
 
                r = crypt_suspend(cd, action_argv[0]);
928
 
 
929
 
        crypt_free(cd);
930
 
        return r;
931
 
}
932
 
 
933
 
static int action_luksResume(int arg)
934
 
{
935
 
        struct crypt_device *cd = NULL;
936
 
        int r;
937
 
 
938
 
        if ((r = crypt_init_by_name(&cd, action_argv[0])))
939
 
                goto out;
940
 
 
941
 
        if ((r = crypt_load(cd, CRYPT_LUKS1, NULL)))
942
 
                goto out;
943
 
 
944
 
        if (opt_key_file)
945
 
                r = crypt_resume_by_keyfile(cd, action_argv[0], CRYPT_ANY_SLOT,
946
 
                                            opt_key_file, opt_keyfile_size);
947
 
        else
948
 
                r = crypt_resume_by_passphrase(cd, action_argv[0], CRYPT_ANY_SLOT,
949
 
                                               NULL, 0);
950
 
out:
951
 
        crypt_free(cd);
952
 
        return r;
953
 
}
954
 
 
955
 
static int action_luksBackup(int arg)
956
 
{
957
 
        struct crypt_device *cd = NULL;
958
 
        int r;
959
 
 
960
 
        if (!opt_header_backup_file) {
961
 
                log_err(_("Option --header-backup-file is required.\n"));
962
 
                return -EINVAL;
963
 
        }
964
 
 
965
 
        if ((r = crypt_init(&cd, action_argv[0])))
966
 
                goto out;
967
 
 
968
 
        crypt_set_confirm_callback(cd, _yesDialog, NULL);
969
 
 
970
 
        r = crypt_header_backup(cd, CRYPT_LUKS1, opt_header_backup_file);
971
 
out:
972
 
        crypt_free(cd);
973
 
        return r;
974
 
}
975
 
 
976
 
static int action_luksRestore(int arg)
977
 
{
978
 
        struct crypt_device *cd = NULL;
979
 
        int r = 0;
980
 
 
981
 
        if (!opt_header_backup_file) {
982
 
                log_err(_("Option --header-backup-file is required.\n"));
983
 
                return -EINVAL;
984
 
        }
985
 
 
986
 
        if ((r = crypt_init(&cd, action_argv[0])))
987
 
                goto out;
988
 
 
989
 
        crypt_set_confirm_callback(cd, _yesDialog, NULL);
990
 
        r = crypt_header_restore(cd, CRYPT_LUKS1, opt_header_backup_file);
991
 
out:
992
 
        crypt_free(cd);
993
 
        return r;
994
 
}
995
 
 
996
 
static __attribute__ ((noreturn)) void usage(poptContext popt_context,
997
 
                                             int exitcode, const char *error,
998
 
                                             const char *more)
999
 
{
1000
 
        poptPrintUsage(popt_context, stderr, 0);
1001
 
        if (error)
1002
 
                log_err("%s: %s\n", more, error);
1003
 
        exit(exitcode);
1004
 
}
1005
 
 
1006
 
static void help(poptContext popt_context, enum poptCallbackReason reason,
1007
 
                 struct poptOption *key, const char * arg, void *data)
1008
 
{
1009
 
        if (key->shortName == '?') {
1010
 
                struct action_type *action;
1011
 
 
1012
 
                log_std("%s\n",PACKAGE_STRING);
1013
 
 
1014
 
                poptPrintHelp(popt_context, stdout, 0);
1015
 
 
1016
 
                log_std(_("\n"
1017
 
                         "<action> is one of:\n"));
1018
 
 
1019
 
                for(action = action_types; action->type; action++)
1020
 
                        log_std("\t%s %s - %s\n", action->type, _(action->arg_desc), _(action->desc));
1021
 
 
1022
 
                log_std(_("\n"
1023
 
                         "<name> is the device to create under %s\n"
1024
 
                         "<device> is the encrypted device\n"
1025
 
                         "<key slot> is the LUKS key slot number to modify\n"
1026
 
                         "<key file> optional key file for the new key for luksAddKey action\n"),
1027
 
                        crypt_get_dir());
1028
 
 
1029
 
                log_std(_("\nDefault compiled-in keyfile parameters:\n"
1030
 
                         "\tMaximum keyfile size: %dkB, "
1031
 
                         "Maximum interactive passphrase length %d (characters)\n"),
1032
 
                         DEFAULT_KEYFILE_SIZE_MAXKB, DEFAULT_PASSPHRASE_SIZE_MAX);
1033
 
 
1034
 
                log_std(_("\nDefault compiled-in device cipher parameters:\n"
1035
 
                         "\tloop-AES: %s, Key %d bits\n"
1036
 
                         "\tplain: %s, Key: %d bits, Password hashing: %s\n"
1037
 
                         "\tLUKS1: %s, Key: %d bits, LUKS header hashing: %s, RNG: %s\n"),
1038
 
                         DEFAULT_LOOPAES_CIPHER, DEFAULT_LOOPAES_KEYBITS,
1039
 
                         DEFAULT_CIPHER(PLAIN), DEFAULT_PLAIN_KEYBITS, DEFAULT_PLAIN_HASH,
1040
 
                         DEFAULT_CIPHER(LUKS1), DEFAULT_LUKS1_KEYBITS, DEFAULT_LUKS1_HASH,
1041
 
                         DEFAULT_RNG);
1042
 
                exit(EXIT_SUCCESS);
1043
 
        } else
1044
 
                usage(popt_context, EXIT_SUCCESS, NULL, NULL);
1045
 
}
1046
 
 
1047
 
static void _dbg_version_and_cmd(int argc, char **argv)
1048
 
{
1049
 
        int i;
1050
 
 
1051
 
        log_std("# %s %s processing \"", PACKAGE_NAME, PACKAGE_VERSION);
1052
 
        for (i = 0; i < argc; i++) {
1053
 
                if (i)
1054
 
                        log_std(" ");
1055
 
                log_std(argv[i]);
1056
 
        }
1057
 
        log_std("\"\n");
1058
 
}
1059
 
 
1060
 
static int run_action(struct action_type *action)
1061
 
{
1062
 
        int r;
1063
 
 
1064
 
        log_dbg("Running command %s.", action->type);
1065
 
 
1066
 
        if (action->required_memlock)
1067
 
                crypt_memory_lock(NULL, 1);
1068
 
 
1069
 
        r = action->handler(action->arg);
1070
 
 
1071
 
        if (action->required_memlock)
1072
 
                crypt_memory_lock(NULL, 0);
1073
 
 
1074
 
        /* Some functions returns keyslot # */
1075
 
        if (r > 0)
1076
 
                r = 0;
1077
 
 
1078
 
        show_status(r);
1079
 
 
1080
 
        /* Translate exit code to simple codes */
1081
 
        switch (r) {
1082
 
        case 0:         r = EXIT_SUCCESS; break;
1083
 
        case -EEXIST:
1084
 
        case -EBUSY:    r = 5; break;
1085
 
        case -ENOTBLK:
1086
 
        case -ENODEV:   r = 4; break;
1087
 
        case -ENOMEM:   r = 3; break;
1088
 
        case -EPERM:    r = 2; break;
1089
 
        case -EINVAL:
1090
 
        case -ENOENT:
1091
 
        case -ENOSYS:
1092
 
        default:        r = EXIT_FAILURE;
1093
 
        }
1094
 
        return r;
1095
 
}
1096
 
 
1097
 
int main(int argc, char **argv)
1098
 
{
1099
 
        static char *popt_tmp;
1100
 
        static struct poptOption popt_help_options[] = {
1101
 
                { NULL,    '\0', POPT_ARG_CALLBACK, help, 0, NULL,                         NULL },
1102
 
                { "help",  '?',  POPT_ARG_NONE,     NULL, 0, N_("Show this help message"), NULL },
1103
 
                { "usage", '\0', POPT_ARG_NONE,     NULL, 0, N_("Display brief usage"),    NULL },
1104
 
                POPT_TABLEEND
1105
 
        };
1106
 
        static struct poptOption popt_options[] = {
1107
 
                { NULL,                '\0', POPT_ARG_INCLUDE_TABLE, popt_help_options, 0, N_("Help options:"), NULL },
1108
 
                { "version",           '\0', POPT_ARG_NONE, &opt_version_mode,          0, N_("Print package version"), NULL },
1109
 
                { "verbose",           'v',  POPT_ARG_NONE, &opt_verbose,               0, N_("Shows more detailed error messages"), NULL },
1110
 
                { "debug",             '\0', POPT_ARG_NONE, &opt_debug,                 0, N_("Show debug messages"), NULL },
1111
 
                { "cipher",            'c',  POPT_ARG_STRING, &opt_cipher,              0, N_("The cipher used to encrypt the disk (see /proc/crypto)"), NULL },
1112
 
                { "hash",              'h',  POPT_ARG_STRING, &opt_hash,                0, N_("The hash used to create the encryption key from the passphrase"), NULL },
1113
 
                { "verify-passphrase", 'y',  POPT_ARG_NONE, &opt_verify_passphrase,     0, N_("Verifies the passphrase by asking for it twice"), NULL },
1114
 
                { "key-file",          'd',  POPT_ARG_STRING, &opt_key_file,            0, N_("Read the key from a file."), NULL },
1115
 
                { "master-key-file",  '\0',  POPT_ARG_STRING, &opt_master_key_file,     0, N_("Read the volume (master) key from file."), NULL },
1116
 
                { "dump-master-key",  '\0',  POPT_ARG_NONE, &opt_dump_master_key,       0, N_("Dump volume (master) key instead of keyslots info."), NULL },
1117
 
                { "key-size",          's',  POPT_ARG_INT, &opt_key_size,               0, N_("The size of the encryption key"), N_("BITS") },
1118
 
                { "keyfile-size",      'l',  POPT_ARG_LONG, &opt_keyfile_size,          0, N_("Limits the read from keyfile"), N_("bytes") },
1119
 
                { "new-keyfile-size", '\0',  POPT_ARG_LONG, &opt_new_keyfile_size,      0, N_("Limits the read from newly added keyfile"), N_("bytes") },
1120
 
                { "key-slot",          'S',  POPT_ARG_INT, &opt_key_slot,               0, N_("Slot number for new key (default is first free)"), NULL },
1121
 
                { "size",              'b',  POPT_ARG_STRING, &popt_tmp,                1, N_("The size of the device"), N_("SECTORS") },
1122
 
                { "offset",            'o',  POPT_ARG_STRING, &popt_tmp,                2, N_("The start offset in the backend device"), N_("SECTORS") },
1123
 
                { "skip",              'p',  POPT_ARG_STRING, &popt_tmp,                3, N_("How many sectors of the encrypted data to skip at the beginning"), N_("SECTORS") },
1124
 
                { "readonly",          'r',  POPT_ARG_NONE, &opt_readonly,              0, N_("Create a readonly mapping"), NULL },
1125
 
                { "iter-time",         'i',  POPT_ARG_INT, &opt_iteration_time,         0, N_("PBKDF2 iteration time for LUKS (in ms)"), N_("msecs") },
1126
 
                { "batch-mode",        'q',  POPT_ARG_NONE, &opt_batch_mode,            0, N_("Do not ask for confirmation"), NULL },
1127
 
                { "timeout",           't',  POPT_ARG_INT, &opt_timeout,                0, N_("Timeout for interactive passphrase prompt (in seconds)"), N_("secs") },
1128
 
                { "tries",             'T',  POPT_ARG_INT, &opt_tries,                  0, N_("How often the input of the passphrase can be retried"), NULL },
1129
 
                { "align-payload",     '\0', POPT_ARG_INT, &opt_align_payload,          0, N_("Align payload at <n> sector boundaries - for luksFormat"), N_("SECTORS") },
1130
 
                { "header-backup-file",'\0', POPT_ARG_STRING, &opt_header_backup_file,  0, N_("File with LUKS header and keyslots backup."), NULL },
1131
 
                { "use-random",        '\0', POPT_ARG_NONE, &opt_random,                0, N_("Use /dev/random for generating volume key."), NULL },
1132
 
                { "use-urandom",       '\0', POPT_ARG_NONE, &opt_urandom,               0, N_("Use /dev/urandom for generating volume key."), NULL },
1133
 
                { "uuid",              '\0',  POPT_ARG_STRING, &opt_uuid,               0, N_("UUID for device to use."), NULL },
1134
 
                POPT_TABLEEND
1135
 
        };
1136
 
        poptContext popt_context;
1137
 
        struct action_type *action;
1138
 
        char *aname;
1139
 
        int r;
1140
 
        const char *null_action_argv[] = {NULL};
1141
 
 
1142
 
        crypt_set_log_callback(NULL, _log, NULL);
1143
 
 
1144
 
        setlocale(LC_ALL, "");
1145
 
        bindtextdomain(PACKAGE, LOCALEDIR);
1146
 
        textdomain(PACKAGE);
1147
 
 
1148
 
        popt_context = poptGetContext(PACKAGE, argc, (const char **)argv,
1149
 
                                      popt_options, 0);
1150
 
        poptSetOtherOptionHelp(popt_context,
1151
 
                               N_("[OPTION...] <action> <action-specific>]"));
1152
 
 
1153
 
        while((r = poptGetNextOpt(popt_context)) > 0) {
1154
 
                unsigned long long ull_value;
1155
 
                char *endp;
1156
 
 
1157
 
                ull_value = strtoull(popt_tmp, &endp, 0);
1158
 
                if (*endp || !*popt_tmp)
1159
 
                        r = POPT_ERROR_BADNUMBER;
1160
 
 
1161
 
                switch(r) {
1162
 
                        case 1:
1163
 
                                opt_size = ull_value;
1164
 
                                break;
1165
 
                        case 2:
1166
 
                                opt_offset = ull_value;
1167
 
                                break;
1168
 
                        case 3:
1169
 
                                opt_skip = ull_value;
1170
 
                                opt_skip_valid = 1;
1171
 
                                break;
1172
 
                }
1173
 
 
1174
 
                if (r < 0)
1175
 
                        break;
1176
 
        }
1177
 
 
1178
 
        if (r < -1)
1179
 
                usage(popt_context, EXIT_FAILURE, poptStrerror(r),
1180
 
                      poptBadOption(popt_context, POPT_BADOPTION_NOALIAS));
1181
 
        if (opt_version_mode) {
1182
 
                log_std("%s %s\n", PACKAGE_NAME, PACKAGE_VERSION);
1183
 
                exit(EXIT_SUCCESS);
1184
 
        }
1185
 
 
1186
 
        if (!(aname = (char *)poptGetArg(popt_context)))
1187
 
                usage(popt_context, EXIT_FAILURE, _("Argument <action> missing."),
1188
 
                      poptGetInvocationName(popt_context));
1189
 
        for(action = action_types; action->type; action++)
1190
 
                if (strcmp(action->type, aname) == 0)
1191
 
                        break;
1192
 
        if (!action->type)
1193
 
                usage(popt_context, EXIT_FAILURE, _("Unknown action."),
1194
 
                      poptGetInvocationName(popt_context));
1195
 
 
1196
 
        action_argc = 0;
1197
 
        action_argv = poptGetArgs(popt_context);
1198
 
        /* Make return values of poptGetArgs more consistent in case of remaining argc = 0 */
1199
 
        if(!action_argv)
1200
 
                action_argv = null_action_argv;
1201
 
 
1202
 
        /* Count args, somewhat unnice, change? */
1203
 
        while(action_argv[action_argc] != NULL)
1204
 
                action_argc++;
1205
 
 
1206
 
        if(action_argc < action->required_action_argc) {
1207
 
                char buf[128];
1208
 
                snprintf(buf, 128,_("%s: requires %s as arguments"), action->type, action->arg_desc);
1209
 
                usage(popt_context, EXIT_FAILURE, buf,
1210
 
                      poptGetInvocationName(popt_context));
1211
 
        }
1212
 
 
1213
 
        /* FIXME: rewrite this from scratch */
1214
 
 
1215
 
        if (opt_key_size &&
1216
 
           strcmp(aname, "luksFormat") &&
1217
 
           strcmp(aname, "create") &&
1218
 
           strcmp(aname, "loopaesOpen")) {
1219
 
                usage(popt_context, EXIT_FAILURE,
1220
 
                      _("Option --key-size is allowed only for luksFormat, create and loopaesOpen.\n"
1221
 
                        "To limit read from keyfile use --keyfile-size=(bytes)."),
1222
 
                      poptGetInvocationName(popt_context));
1223
 
        }
1224
 
 
1225
 
        if (opt_key_size % 8)
1226
 
                usage(popt_context, EXIT_FAILURE,
1227
 
                      _("Key size must be a multiple of 8 bits"),
1228
 
                      poptGetInvocationName(popt_context));
1229
 
 
1230
 
        if (!strcmp(aname, "luksKillSlot") && action_argc > 1)
1231
 
                opt_key_slot = atoi(action_argv[1]);
1232
 
        if (opt_key_slot != CRYPT_ANY_SLOT &&
1233
 
            (opt_key_slot < 0 || opt_key_slot > crypt_keyslot_max(CRYPT_LUKS1)))
1234
 
                usage(popt_context, EXIT_FAILURE, _("Key slot is invalid."),
1235
 
                      poptGetInvocationName(popt_context));
1236
 
 
1237
 
        if ((!strcmp(aname, "luksRemoveKey") ||
1238
 
             !strcmp(aname, "luksFormat")) &&
1239
 
             action_argc > 1) {
1240
 
                if (opt_key_file)
1241
 
                        log_err(_("Option --key-file takes precedence over specified key file argument.\n"));
1242
 
                else
1243
 
                        opt_key_file = (char*)action_argv[1];
1244
 
        }
1245
 
 
1246
 
        if (opt_keyfile_size < 0 || opt_new_keyfile_size < 0 || opt_key_size < 0) {
1247
 
                usage(popt_context, EXIT_FAILURE,
1248
 
                      _("Negative number for option not permitted."),
1249
 
                      poptGetInvocationName(popt_context));
1250
 
        }
1251
 
 
1252
 
        if (opt_random && opt_urandom)
1253
 
                usage(popt_context, EXIT_FAILURE, _("Only one of --use-[u]random options is allowed."),
1254
 
                      poptGetInvocationName(popt_context));
1255
 
        if ((opt_random || opt_urandom) && strcmp(aname, "luksFormat"))
1256
 
                usage(popt_context, EXIT_FAILURE, _("Option --use-[u]random is allowed only for luksFormat."),
1257
 
                      poptGetInvocationName(popt_context));
1258
 
 
1259
 
        if (opt_uuid && strcmp(aname, "luksFormat") && strcmp(aname, "luksUUID"))
1260
 
                usage(popt_context, EXIT_FAILURE, _("Option --uuid is allowed only for luksFormat and luksUUID."),
1261
 
                      poptGetInvocationName(popt_context));
1262
 
 
1263
 
        if (opt_skip && strcmp(aname, "create") && strcmp(aname, "loopaesOpen"))
1264
 
                usage(popt_context, EXIT_FAILURE,
1265
 
                _("Option --skip is supported only for create and loopaesOpen commands.\n"),
1266
 
                poptGetInvocationName(popt_context));
1267
 
 
1268
 
        if (opt_offset && strcmp(aname, "create") && strcmp(aname, "loopaesOpen"))
1269
 
                usage(popt_context, EXIT_FAILURE,
1270
 
                _("Option --offset is supported only for create and loopaesOpen commands.\n"),
1271
 
                poptGetInvocationName(popt_context));
1272
 
 
1273
 
        if (opt_debug) {
1274
 
                opt_verbose = 1;
1275
 
                crypt_set_debug_level(-1);
1276
 
                _dbg_version_and_cmd(argc, argv);
1277
 
        }
1278
 
 
1279
 
        return run_action(action);
1280
 
}