~ubuntu-branches/ubuntu/lucid/cryptsetup/lucid

« back to all changes in this revision

Viewing changes to lib/setup.c

  • Committer: Bazaar Package Importer
  • Author(s): Jonas Meurer
  • Date: 2009-07-30 17:41:16 UTC
  • mfrom: (1.3.1 upstream) (0.2.2 sid)
  • mto: This revision was merged to the branch mainline in revision 65.
  • Revision ID: james.westby@ubuntu.com-20090730174116-24zvr0zhmgmgq2gk
Tags: 2:1.0.7-1
* new upstream release, highlights include (diff from ~rc1):
  - allow removal of last slot in luksRemoveKey and luksKillSlot
  - eject unsupported --offset and --skip options for luksFormat
* make passdev accept a timeout option, thanks to Evgeni Golov for the patch.
  (closes: #502598)
* finally add the cryptsource delay implementation from ubuntu, as it seems
  to workaround some issues where appearance of the root device takes longer
  than expected. (closes: #488271)
* execute udev_settle before $cryptremove if $cryptcreate fails at
  setup_mapping() in the initramfs cryptroot script. it seems like a short
  delay and/or udev_settly is needed in between of 'cryptsetup create' and
  'cryptsetup remove'. thanks to Gernot Schilling for the bugreport.
  (closes: #529527)
* talk about /dev/urandom instead of /dev/random in crypttab manpage.
  (closes: #537344)
* check for $IGNORE before check_key() in handle_crypttab_line_start()
* rewrite error code handling:
  - return 1 for errors in handle_crypttab_line_{start|stop}
  - handle_crypttab_line_... || true needed due to set -e in initscript
  - check for exit code of handle_crypttab_line_{start<stop} in
    cryptdisks_{start|stop}, exit with proper status code (closes: #524173)
* add a counter to the while loop in cryptdisks_{start|stop}, in order to
  detect if $dst was not found in crypttab. (closes: #524485)
* check for keyscript in the new location in initramfs/cryptopensc-hook.
* add README.opensc to docs, thanks to Benjamin Kiessling for writing it.
  (closes: #514538)
* add patches/03_rework_read.patch [rework write_blockwise() and
  read_blockwise()], but don't apply it yet as it's still experimental.
  applying it will increase the speed of luksOpen.

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
#define at_least_one(a) ({ __typeof__(a) __at_least_one=(a); (__at_least_one)?__at_least_one:1; })
28
28
 
29
29
static void logger(struct crypt_options *options, int class, char *format, ...) {
30
 
        va_list argp;
31
 
        char *target;
32
 
 
33
 
        va_start(argp, format);
34
 
        vasprintf(&target, format, argp);
35
 
        options->icb->log(class, target);
36
 
 
37
 
        va_end(argp);
38
 
        free(target);
 
30
        va_list argp;
 
31
        char *target = NULL;
 
32
 
 
33
        va_start(argp, format);
 
34
 
 
35
        if (vasprintf(&target, format, argp) > 0)
 
36
                options->icb->log(class, target);
 
37
 
 
38
        va_end(argp);
 
39
        free(target);
39
40
}
40
41
 
41
42
static void hexprintICB(struct crypt_options *options, int class, char *d, int n)
107
108
                memcpy(key,pass,options->key_size);
108
109
                return key;
109
110
        }
110
 
        
 
111
 
111
112
        /* key is coming from tty, fd or binary stdin */
112
113
        if (options->hash) {
113
114
                if (hash(NULL, options->hash,
299
300
                        return r;
300
301
        } else {
301
302
                if (r >= 0) {
302
 
                        set_error("Device already exists");
 
303
                        set_error("Device %s already exists.", options->name);
303
304
                        return -EEXIST;
304
305
                }
305
306
                if (r != -ENODEV)
335
336
                set_error("Key reading error");
336
337
                return -ENOENT;
337
338
        }
338
 
        
 
339
 
339
340
        processed_key = process_key(options,key,keyLen);
340
341
        safe_free(key);
341
 
        
 
342
 
342
343
        if (!processed_key) {
343
344
                const char *error=get_error();
344
345
                if(error) {
345
 
                        char *c_error_handling_sucks;
346
 
                        asprintf(&c_error_handling_sucks,"Key processing error: %s",error);
347
 
                        set_error(c_error_handling_sucks);
 
346
                        char *c_error_handling_sucks = NULL;
 
347
                        if (asprintf(&c_error_handling_sucks,"Key processing error: %s",error) > 0)
 
348
                                set_error(c_error_handling_sucks);
348
349
                        free(c_error_handling_sucks);
349
350
                } else
350
351
                        set_error("Key processing error");
351
352
                return -ENOENT;
352
353
        }
353
 
        
354
 
        r = backend->create(reload, options, processed_key);
355
 
        
 
354
 
 
355
        r = backend->create(reload, options, processed_key, NULL);
 
356
 
356
357
        safe_free(processed_key);
357
358
 
358
359
        return r;
404
405
        if (infos.readonly)
405
406
                options->flags |= CRYPT_FLAG_READONLY;
406
407
 
407
 
        r = backend->create(1, &tmp, key);
 
408
        r = backend->create(1, &tmp, key, NULL);
408
409
 
409
410
        safe_free(key);
410
411
 
430
431
static int __crypt_luks_format(int arg, struct setup_backend *backend, struct crypt_options *options)
431
432
{
432
433
        int r;
433
 
        
 
434
 
434
435
        struct luks_phdr header;
435
436
        struct luks_masterkey *mk=NULL;
436
437
        char *password=NULL; 
440
441
        int PBKDF2perSecond;
441
442
        int keyIndex;
442
443
 
443
 
        if (!LUKS_device_ready(options->device, O_RDWR | O_EXCL)) {
444
 
                set_error("Can not access device");
445
 
                r = -ENOTBLK; goto out;
446
 
        }
 
444
        if (!LUKS_device_ready(options->device, O_RDWR | O_EXCL))
 
445
                return -ENOTBLK;
447
446
 
448
447
        mk = LUKS_generate_masterkey(options->key_size);
449
448
        if(NULL == mk) return -ENOMEM; // FIXME This may be misleading, since we don't know what went wrong
509
508
{
510
509
        struct luks_masterkey *mk=NULL;
511
510
        struct luks_phdr hdr;
 
511
        char *prompt = NULL;
512
512
        char *password;
513
513
        unsigned int passwordLen;
514
514
        struct device_infos infos;
515
515
        struct crypt_options tmp = {
516
516
                .name = options->name,
517
517
        };
518
 
        char *dmCipherSpec;
 
518
        char *dmCipherSpec = NULL;
519
519
        int r, tries = options->tries;
520
520
        int excl = (options->flags & CRYPT_FLAG_NON_EXCLUSIVE_ACCESS) ? 0 : O_EXCL ;
521
521
 
522
522
        r = backend->status(0, &tmp, NULL);
523
523
        if (r >= 0) {
524
 
                set_error("Device already exists");
 
524
                set_error("Device %s already exists.", options->name);
525
525
                return -EEXIST;
526
526
        }
527
527
 
528
 
        if (!LUKS_device_ready(options->device, O_RDONLY | excl)) {
529
 
                set_error("Can not access device");
 
528
        if (!LUKS_device_ready(options->device, O_RDONLY | excl))
530
529
                return -ENOTBLK;
531
 
        }
532
530
 
533
531
        if (get_device_infos(options->device, &infos) < 0) {
534
532
                set_error("Can't get device information.\n");
538
536
        if (infos.readonly)
539
537
                options->flags |= CRYPT_FLAG_READONLY;
540
538
 
 
539
        if(asprintf(&prompt, "Enter LUKS passphrase for %s: ", options->device) < 0)
 
540
                return -ENOMEM;
 
541
 
541
542
start:
542
543
        mk=NULL;
543
544
 
544
 
        if(get_key("Enter LUKS passphrase: ",&password,&passwordLen, 0, options->key_file,  options->passphrase_fd, options->timeout, options->flags))
 
545
        if(get_key(prompt, &password, &passwordLen, 0, options->key_file, options->passphrase_fd, options->timeout, options->flags))
545
546
                tries--;
546
547
        else
547
548
                tries = 0;
558
559
 
559
560
        logger(options, CRYPT_LOG_NORMAL,"key slot %d unlocked.\n", r);
560
561
 
561
 
        
 
562
 
562
563
        options->offset = hdr.payloadOffset;
563
 
        asprintf(&dmCipherSpec, "%s-%s", hdr.cipherName, hdr.cipherMode);
564
 
        if(!dmCipherSpec) {
 
564
        if (asprintf(&dmCipherSpec, "%s-%s", hdr.cipherName, hdr.cipherMode) < 0) {
565
565
                r = -ENOMEM;
566
566
                goto out2;
567
567
        }
579
579
                r = -EINVAL; goto out2;
580
580
        }
581
581
        options->size -= options->offset;
582
 
        r = backend->create(0, options, mk->key);
 
582
        /* FIXME: code allows multiple crypt mapping, cannot use uuid then.
 
583
         * anyway, it is dangerous and can corrupt data. Remove it in next version! */
 
584
        r = backend->create(0, options, mk->key, excl ? hdr.uuid : NULL);
583
585
 
584
586
 out2:
585
587
        free(dmCipherSpec);
 
588
        dmCipherSpec = NULL;
586
589
 out1:
587
590
        safe_free(password);
588
591
 out:
590
593
        if (r == -EPERM && tries > 0)
591
594
                goto start;
592
595
 
 
596
        free(prompt);
 
597
 
593
598
        return r;
594
599
}
595
600
 
601
606
        unsigned int keyIndex;
602
607
        const char *device = options->device;
603
608
        int r;
604
 
        
605
 
        if (!LUKS_device_ready(options->device, O_RDWR)) {
606
 
                set_error("Can not access device");
607
 
                r = -ENOTBLK; goto out;
608
 
        }
 
609
 
 
610
        if (!LUKS_device_ready(options->device, O_RDWR))
 
611
                return -ENOTBLK;
609
612
 
610
613
        r = LUKS_read_phdr(device, &hdr);
611
614
        if(r < 0) return r;
636
639
                logger(options, CRYPT_LOG_NORMAL,"key slot %d unlocked.\n", r);
637
640
 
638
641
        safe_free(password);
639
 
        
 
642
 
640
643
        get_key("Enter new passphrase for key slot: ",
641
644
                &password,
642
645
                &passwordLen,
670
673
        const char *device = options->device;
671
674
        int keyIndex;
672
675
        int openedIndex;
673
 
        int r;
674
 
        if (!LUKS_device_ready(options->device, O_RDWR)) {
675
 
            set_error("Can not access device");
676
 
            r = -ENOTBLK; goto out;
677
 
        }
 
676
        int r, last_slot;
 
677
 
 
678
        if (!LUKS_device_ready(options->device, O_RDWR))
 
679
            return -ENOTBLK;
678
680
 
679
681
        if(supply_it) {
680
682
            get_key("Enter LUKS passphrase to be deleted: ",&password,&passwordLen, 0, options->new_key_file, options->passphrase_fd, options->timeout, options->flags);
692
694
            keyIndex = options->key_slot;
693
695
        }
694
696
 
695
 
        if(LUKS_is_last_keyslot(options->device, keyIndex) && 
696
 
           !(options->icb->yesDialog(_("This is the last keyslot. Device will become unusable after purging this key.")))) {
697
 
                r = -EINVAL;
698
 
                goto out;
699
 
        } 
 
697
        last_slot = LUKS_is_last_keyslot(options->device, keyIndex);
 
698
        if(last_slot && !(options->icb->yesDialog(_("This is the last keyslot. Device will become unusable after purging this key.")))) {
 
699
                r = -EINVAL; goto out;
 
700
        }
700
701
 
701
702
        if(options->flags & CRYPT_FLAG_VERIFY_ON_DELKEY) {
702
703
                options->flags &= ~CRYPT_FLAG_VERIFY_ON_DELKEY;
710
711
                        options->icb->log(CRYPT_LOG_ERROR,"Failed to access device.\n");
711
712
                        r = -EIO; goto out;
712
713
                }
713
 
                hdr.keyblock[keyIndex].active = LUKS_KEY_DISABLED;
 
714
 
 
715
                if(!last_slot)
 
716
                        hdr.keyblock[keyIndex].active = LUKS_KEY_DISABLED;
714
717
 
715
718
                openedIndex = LUKS_open_any_key_with_hdr(device, password, passwordLen, &hdr, &mk, backend);
716
719
                /* Clean up */
881
884
 
882
885
                        logger(options, CRYPT_LOG_NORMAL, "\tKey material offset:\t%d\n",hdr.keyblock[i].keyMaterialOffset);
883
886
                        logger(options, CRYPT_LOG_NORMAL, "\tAF stripes:            \t%d\n",hdr.keyblock[i].stripes);
884
 
                }               
 
887
                }
885
888
                else 
886
889
                        logger(options, CRYPT_LOG_NORMAL, "Key Slot %d: DISABLED\n",i);
887
890
        }