From 562c8c525f7b9bf005c56e589623817a19e23438 Mon Sep 17 00:00:00 2001 From: Pascal Rigaux Date: Thu, 18 Sep 2008 17:00:11 +0000 Subject: - diskdrake: o handle partitions encrypted with cryptsetup --- perl-install/NEWS | 1 + perl-install/diskdrake/hd_gtk.pm | 13 +++++-- perl-install/diskdrake/interactive.pm | 66 ++++++++++++++++++++++++++++++++++- perl-install/fs.pm | 3 +- perl-install/fs/get.pm | 6 ++-- perl-install/fs/type.pm | 8 +++-- perl-install/fsedit.pm | 18 ++++++++++ perl-install/install/NEWS | 1 + perl-install/install/share/list.xml | 1 + perl-install/partition_table.pm | 3 +- 10 files changed, 110 insertions(+), 10 deletions(-) (limited to 'perl-install') diff --git a/perl-install/NEWS b/perl-install/NEWS index 497b42cde..7d6d2e286 100644 --- a/perl-install/NEWS +++ b/perl-install/NEWS @@ -1,6 +1,7 @@ - handle new driver: o ethernet: jme - diskdrake: + o handle partitions encrypted with cryptsetup o fix file system type drop down list showing most types as "..." in "Change partition type" dialog in expert mode due to ellipsizing - harddrake2: diff --git a/perl-install/diskdrake/hd_gtk.pm b/perl-install/diskdrake/hd_gtk.pm index e89613bcf..a5828783e 100644 --- a/perl-install/diskdrake/hd_gtk.pm +++ b/perl-install/diskdrake/hd_gtk.pm @@ -29,7 +29,7 @@ struct { string name # which is displayed in tab of the notebook bool no_auto # wether the kind can disappear after creation string type # one of { 'hd', 'raid', 'lvm', 'loopback', 'removable', 'nfs', 'smb' } - hd | hd_lvm | part_raid[] | part_loopback[] | raw_hd[] val + hd | hd_lvm | part_raid[] | part_dmcrypt[] | part_loopback[] | raw_hd[] val # widget main_box @@ -250,9 +250,10 @@ sub current_kind_changed { my $v = $kind->{val}; my @parts = $kind->{type} eq 'raid' ? grep { $_ } @$v : + $kind->{type} eq 'dmcrypt' ? @$v : $kind->{type} eq 'loopback' ? @$v : fs::get::hds_fstab_and_holes($v); my $totalsectors = - $kind->{type} =~ /raid|loopback/ ? sum(map { $_->{size} } @parts) : $v->{totalsectors}; + $kind->{type} =~ /raid|dmcrypt|loopback/ ? sum(map { $_->{size} } @parts) : $v->{totalsectors}; create_buttons4partitions($kind, $totalsectors, @parts); } @@ -279,6 +280,7 @@ sub create_automatic_notebooks { $may_add->(hd2kind($_)) foreach @{$all_hds->{hds}}; $may_add->(lvm2kind($_)) foreach @{$all_hds->{lvms}}; $may_add->(raid2kind()) if @{$all_hds->{raids}}; + $may_add->(dmcrypt2kind()) if @{$all_hds->{dmcrypts}}; $may_add->(loopback2kind()) if @{$all_hds->{loopbacks}}; @notebook = grep_index { @@ -431,6 +433,13 @@ sub raid2kind() { { type => 'raid', name => 'raid', val => $all_hds->{raids} }; } +################################################################################ +# loopbacks: helpers +################################################################################ +sub dmcrypt2kind() { + { type => 'dmcrypt', name => 'dmcrypt', val => $all_hds->{dmcrypts} }; +} + ################################################################################ # loopbacks: helpers ################################################################################ diff --git a/perl-install/diskdrake/interactive.pm b/perl-install/diskdrake/interactive.pm index ff42f67fd..9c2c6750c 100644 --- a/perl-install/diskdrake/interactive.pm +++ b/perl-install/diskdrake/interactive.pm @@ -64,6 +64,10 @@ struct part { string lvm # partition used as a PV for the VG with {lvm} as VG_name #-# loopback loopback[] # loopback living on this partition + string dmcrypt_key + string dm_name + bool dm_active + # internal string real_device # '/dev/loop0', '/dev/loop1' ... (used for encrypted loopback) @@ -89,6 +93,12 @@ struct part_raid inherits part { # invalid: active, start, rootDevice, device_windobe?, CHS } +struct part_dmcrypt inherits part { + string dmcrypt_name + + # rootDevice is special here: it is the device hosting the dm +} + struct part_loopback inherits part { string loopback_file # absolute file name which is relative to the partition part loopback_device # where the loopback file live @@ -168,6 +178,7 @@ struct all_hds { hd hds[] hd_lvm lvms[] part_raid raids[] + part_dmcrypt dmcrypts[] part_loopback loopbacks[] raw_hd raw_hds[] raw_hd nfss[] @@ -328,6 +339,7 @@ sub Clear_all { foreach (@parts) { RemoveFromLVM($in, $hd, $_, $all_hds) if isPartOfLVM($_); RemoveFromRAID($in, $hd, $_, $all_hds) if isPartOfRAID($_); + RemoveFromDm($in, $hd, $_, $all_hds) if $_->{dm_active}; } if (isLVM($hd)) { lvm::lv_delete($hd, $_) foreach @parts; @@ -387,14 +399,16 @@ sub part_possible_actions { N_("Options") => '!isSwap($part) && !isNonMountable && $::expert', N_("Label") => '!isNonMountable && $::expert', N_("Resize") => '!isBusy && !readonly && !isSpecial || isLVM($hd) && LVM_resizable', - N_("Format") => '!isBusy && !readonly && ($::expert || $::isStandalone)', + N_("Format") => '!isBusy && (!readonly && ($::expert || $::isStandalone) || fs::type::isRawLUKS($part))', N_("Mount") => '!isBusy && (hasMntpoint || isSwap) && maybeFormatted && ($::expert || $::isStandalone)', N_("Add to RAID") => '!isBusy && isRawRAID && (!isSpecial || isRAID)', N_("Add to LVM") => '!isBusy && isRawLVM', + N_("Use") => '!isBusy && fs::type::isRawLUKS($part) && !$part->{notFormatted}', N_("Unmount") => '!$part->{real_mntpoint} && isMounted', N_("Delete") => '!isBusy && !readonly', N_("Remove from RAID") => 'isPartOfRAID', N_("Remove from LVM") => 'isPartOfLVM', + N_("Remove from dm") => '$part->{dm_active}', N_("Modify RAID") => 'canModifyRAID', N_("Use for loopback") => '!$part->{real_mntpoint} && isMountableRW && !isSpecial && hasMntpoint && maybeFormatted && $::expert', ); @@ -798,6 +812,30 @@ sub Mount { $w->set($msg); }); } + +sub dmcrypt_open { + my ($in, $_hd, $part, $all_hds) = @_; + $part->{dm_name} ||= do { + my $s = $part->{device}; + $s =~ s/[^\w]/_/g; + "crypt_$s"; + }; + + if (!$part->{dmcrypt_key}) { + $in->ask_from_({ + title => N("Filesystem encryption key"), + messages => N("Enter your filesystem encryption key"), + }, [ { label => N("Encryption key"), val => \$part->{dmcrypt_key}, + hidden => 1, focus => sub { 1 } } ]) or return; + } + + eval { fs::dmcrypt::open_part($all_hds->{dmcrypts}, $part) }; + if ($@) { + delete $part->{dmcrypt_key}; + die(($? >> 8) == 255 ? N("Invalid key") : $@); + } +} + sub Add2RAID { my ($in, $_hd, $part, $all_hds) = @_; my $raids = $all_hds->{raids}; @@ -843,6 +881,10 @@ sub RemoveFromRAID { my ($_in, $_hd, $part, $all_hds) = @_; raid::removeDisk($all_hds->{raids}, $part); } +sub RemoveFromDm { + my ($_in, $_hd, $part, $all_hds) = @_; + fs::dmcrypt::close_part($all_hds->{dmcrypts}, $part); +} sub RemoveFromLVM { my ($in, $_hd, $part, $all_hds) = @_; isPartOfLVM($part) or die; @@ -979,6 +1021,8 @@ sub Options { *{'Modify RAID'} = \&ModifyRAID; *{'Add to RAID'} = \&Add2RAID; *{'Remove from RAID'} = \&RemoveFromRAID; + *{'Use'} = \&dmcrypt_open; + *{'Remove from dm'} = \&RemoveFromDm; *{'Add to LVM'} = \&Add2LVM; *{'Remove from LVM'} = \&RemoveFromLVM; *{'Use for loopback'} = \&Loopback; @@ -1096,10 +1140,21 @@ sub ensure_we_have_encrypt_key_if_needed { if ($part->{options} =~ /encrypted/ && !$part->{encrypt_key}) { my ($options, $_unknown) = fs::mount_options::unpack($part); $part->{encrypt_key} = choose_encrypt_key($in, $options, 'skip_encrypt_algo') or return; + } elsif (fs::type::isRawLUKS($part)) { + $part->{dmcrypt_key} ||= choose_encrypt_key($in, {}, 'skip_encrypt_algo') or return; } 1; } +sub dmcrypt_format { + my ($in, $hd, $part, $all_hds) = @_; + my $_wait = $in->wait_message(N("Please wait"), N("Formatting partition %s", $part->{device})); + require fs::dmcrypt; + fs::dmcrypt::format_part($part); + # we open it now: + &dmcrypt_open; +} + sub format_ { my ($in, $hd, $part, $all_hds) = @_; @@ -1107,6 +1162,10 @@ sub format_ { write_partitions($in, $_) or return foreach isRAID($part) ? @{$all_hds->{hds}} : $hd; ask_alldatawillbelost($in, $part, N_("After formatting partition %s, all data on this partition will be lost")) or return; + + if (fs::type::isRawLUKS($part)) { + return &dmcrypt_format; + } if ($::isStandalone) { fs::format::check_package_is_installed($in->do_pkgs, $part->{fs_type}) or return; } @@ -1218,6 +1277,11 @@ sub format_part_info { $info .= N("Not formatted\n") if !$part->{isFormatted} && $part->{notFormatted}; $info .= N("Mounted\n") if $part->{isMounted}; $info .= N("RAID %s\n", $part->{raid}) if isPartOfRAID($part); + if (fs::type::isRawLUKS($part)) { + $info .= N("Encrypted") . ($part->{dm_active} && $part->{dm_name} ? N(" (mapped on %s)", $part->{dm_name}) : + $part->{dm_name} ? N(" (to map on %s)", $part->{dm_name}) : + N(" (inactive)")) . "\n"; + } if (isPartOfLVM($part)) { $info .= sprintf "LVM %s\n", $part->{lvm}; $info .= sprintf "Used physical extents %d / %d\n", lvm::pv_physical_extents($part); diff --git a/perl-install/fs.pm b/perl-install/fs.pm index a5b24edab..0025583c9 100644 --- a/perl-install/fs.pm +++ b/perl-install/fs.pm @@ -228,7 +228,7 @@ sub prepare_write_fstab { my ($freq, $passno) = exists $_->{freq} ? ($_->{freq}, $_->{passno}) : - isTrueLocalFS($_) && $_->{options} !~ /encryption=/ && (!$_->{is_removable} || member($_->{mntpoint}, fs::type::directories_needed_to_boot())) ? + isTrueLocalFS($_) && !$_->{dmcrypt_name} && $_->{options} !~ /encryption=/ && (!$_->{is_removable} || member($_->{mntpoint}, fs::type::directories_needed_to_boot())) ? (1, $_->{mntpoint} eq '/' ? 1 : fs::type::carry_root_loopback($_) ? 0 : 2) : (0, 0); @@ -293,6 +293,7 @@ sub write_fstab { my ($s, $smb_credentials) = prepare_write_fstab($fstab, $o_prefix, ''); output("$o_prefix/etc/fstab", $s); fs::remote::smb::save_credentials($_) foreach @$smb_credentials; + fs::dmcrypt::save_crypttab($all_hds) if @{$all_hds->{dmcrypts}}; } sub set_removable_mntpoints { diff --git a/perl-install/fs/get.pm b/perl-install/fs/get.pm index aa23d1c61..d98ccb2c7 100644 --- a/perl-install/fs/get.pm +++ b/perl-install/fs/get.pm @@ -12,12 +12,12 @@ use common; use log; sub empty_all_hds() { - { hds => [], lvms => [], raids => [], loopbacks => [], raw_hds => [], nfss => [], smbs => [], davs => [], special => [] }; + { hds => [], lvms => [], raids => [], dmcrypts => [], loopbacks => [], raw_hds => [], nfss => [], smbs => [], davs => [], special => [] }; } sub fstab { my ($all_hds) = @_; my @parts = map { partition_table::get_normal_parts($_) } hds($all_hds); - @parts, @{$all_hds->{raids}}, @{$all_hds->{loopbacks}}; + @parts, @{$all_hds->{raids}}, @{$all_hds->{dmcrypts}}, @{$all_hds->{loopbacks}}; } sub really_all_fstab { my ($all_hds) = @_; @@ -28,7 +28,7 @@ sub really_all_fstab { sub fstab_and_holes { my ($all_hds, $b_non_readonly) = @_; my @hds = grep { !($b_non_readonly && $_->{readonly}) } hds($all_hds); - hds_fstab_and_holes(@hds), @{$all_hds->{raids}}, @{$all_hds->{loopbacks}}; + hds_fstab_and_holes(@hds), @{$all_hds->{raids}}, @{$all_hds->{dmcrypts}}, @{$all_hds->{loopbacks}}; } sub holes { diff --git a/perl-install/fs/type.pm b/perl-install/fs/type.pm index ab7689d30..102a60830 100644 --- a/perl-install/fs/type.pm +++ b/perl-install/fs/type.pm @@ -39,6 +39,7 @@ if_(arch() =~ /ppc/, 0x402 => 'hfs', 'Apple HFS Partition', 0x41 => '', 'PPC PReP Boot', ), + 0x83 => '', 'Encrypted', ], non_fs_type => [ @@ -291,6 +292,8 @@ sub type_subpart_from_magic { }->{$ids->{ID_FS_TYPE}}; $p = type_name2subpart($name) if $name; + } elsif ($ids->{ID_FS_USAGE} eq 'crypto') { + $p = type_name2subpart('Encrypted'); } elsif (my $fs_type = $ids->{ID_FS_TYPE}) { $fs_type = 'ntfs-3g' if $fs_type eq 'ntfs'; $p = fs_type2subpart($fs_type) or log::l("unknown filesystem $fs_type returned by vol_id"); @@ -312,6 +315,7 @@ sub isWholedisk { arch() =~ /^sparc/ && $_[0]{pt_type} == 5 } sub isExtended { arch() !~ /^sparc/ && ($_[0]{pt_type} == 5 || $_[0]{pt_type} == 0xf || $_[0]{pt_type} == 0x85) } sub isRawLVM { $_[0]{pt_type} == 0x8e || $_[0]{type_name} eq 'Linux Logical Volume Manager' } sub isRawRAID { $_[0]{pt_type} == 0xfd || $_[0]{type_name} eq 'Linux RAID' } +sub isRawLUKS { $_[0]{type_name} eq 'Encrypted' } sub isSwap { $_[0]{fs_type} eq 'swap' } sub isDos { arch() !~ /^sparc/ && ${{ 1 => 1, 4 => 1, 6 => 1 }}{$_[0]{pt_type}} } sub isFat_or_NTFS { member($_[0]{fs_type}, 'vfat', 'ntfs', 'ntfs-3g') } @@ -325,7 +329,7 @@ sub isOtherAvailableFS { isEfi($_[0]) || isFat_or_NTFS($_[0]) || member($_[0]{fs sub isMountableRW { (isTrueFS($_[0]) || isOtherAvailableFS($_[0])) && $_[0]{fs_type} ne 'ntfs' } sub cannotBeMountable { my ($part) = @_; - isRawRAID($part) || isRawLVM($part); + isRawRAID($part) || isRawLUKS($part) || isRawLVM($part); } sub isNonMountable { my ($part) = @_; @@ -340,7 +344,7 @@ sub isUBD { $_[0]{device} =~ /^ubd/ } #- should be always true during an $::uml_ sub isLVM { $_[0]{VG_name} || $_[0]{lv_name} } sub isLoopback { defined $_[0]{loopback_file} } sub isMounted { $_[0]{isMounted} } -sub isBusy { isMounted($_[0]) || isPartOfRAID($_[0]) || isPartOfLVM($_[0]) || isPartOfLoopback($_[0]) } +sub isBusy { isMounted($_[0]) || isPartOfRAID($_[0]) || isPartOfLVM($_[0]) || $_[0]{dm_active} || isPartOfLoopback($_[0]) } sub isSpecial { isRAID($_[0]) || isLVM($_[0]) || isLoopback($_[0]) || isUBD($_[0]) } #- not for partitions, but for hds: diff --git a/perl-install/fsedit.pm b/perl-install/fsedit.pm index 81564bb1b..d0d9b6a2e 100644 --- a/perl-install/fsedit.pm +++ b/perl-install/fsedit.pm @@ -72,6 +72,21 @@ sub raids { raid::get_existing(@l); } +sub dmcrypts { + my ($all_hds) = @_; + + my @parts = fs::get::fstab($all_hds); + + my @l = grep { fs::type::isRawLUKS($_) } @parts or return; + + log::l("using dm-crypt from " . join(' ', map { $_->{device} } @l)); + + require fs::dmcrypt; + fs::dmcrypt::read_crypttab($all_hds); + + fs::dmcrypt::get_existing(@l); +} + sub lvms { my ($all_hds) = @_; my @pvs = grep { isRawLVM($_) } fs::get::fstab($all_hds) or return; @@ -267,6 +282,9 @@ Do you agree to lose all the partitions? fs::get_major_minor([ fs::get::fstab($all_hds) ]); + # must be done after getting major/minor + $all_hds->{dmcrypts} = [ dmcrypts($all_hds) ]; + $_->{faked_device} = 0 foreach fs::get::fstab($all_hds); $all_hds; diff --git a/perl-install/install/NEWS b/perl-install/install/NEWS index aa4aaadc6..6ec7c32dd 100644 --- a/perl-install/install/NEWS +++ b/perl-install/install/NEWS @@ -1,6 +1,7 @@ - handle new driver: o ethernet: jme - partitionning step + o handle partitions encrypted with cryptsetup o fix file system type drop down list showing most types as "..." in "Change partition type" dialog in expert mode due to ellipsizing - list btusb instead of hci_usb in bus/bluetooth (renamed in 2.6.27) diff --git a/perl-install/install/share/list.xml b/perl-install/install/share/list.xml index f5bfc3220..4f5b82540 100644 --- a/perl-install/install/share/list.xml +++ b/perl-install/install/share/list.xml @@ -36,6 +36,7 @@ mkfs.jfs fsck.jfs quotacheck + cryptsetup dmsetup setfont kbd_mode Xorg xset diff --git a/perl-install/partition_table.pm b/perl-install/partition_table.pm index d26a14e31..1ff4936db 100644 --- a/perl-install/partition_table.pm +++ b/perl-install/partition_table.pm @@ -260,7 +260,7 @@ sub read_primary { #- but other sectors (typically for extended partition ones) have to match this type! my @parttype = ( if_(arch() =~ /^ia64/, 'gpt'), - arch() =~ /^sparc/ ? ('sun', 'bsd') : ('lvm', 'dos', 'bsd', 'sun', 'mac'), + arch() =~ /^sparc/ ? ('sun', 'bsd') : ('lvm', 'dmcrypt', 'dos', 'bsd', 'sun', 'mac'), ); foreach ('empty', @parttype, 'unknown') { /unknown/ and die "unknown partition table format on disk " . $hd->{file}; @@ -268,6 +268,7 @@ sub read_primary { # perl_checker: require partition_table::bsd # perl_checker: require partition_table::dos # perl_checker: require partition_table::empty + # perl_checker: require partition_table::dmcrypt # perl_checker: require partition_table::lvm # perl_checker: require partition_table::gpt # perl_checker: require partition_table::mac -- cgit v1.2.1