Hello community,

here is the log from the commit of package mksusecd for openSUSE:Factory 
checked in at 2018-01-20 11:27:47
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/mksusecd (Old)
 and      /work/SRC/openSUSE:Factory/.mksusecd.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "mksusecd"

Sat Jan 20 11:27:47 2018 rev:42 rq:567602 version:1.56

Changes:
--------
--- /work/SRC/openSUSE:Factory/mksusecd/mksusecd.changes        2017-12-06 
09:00:01.757822142 +0100
+++ /work/SRC/openSUSE:Factory/.mksusecd.new/mksusecd.changes   2018-01-20 
11:27:49.537249097 +0100
@@ -1,0 +2,8 @@
+Fri Jan 19 09:26:47 UTC 2018 - [email protected]
+
+- merge gh#openSUSE/mksusecd#29
+- allow building of encrypted installation media
+- fix handling of repo-md repositories with encrypted media
+- 1.56
+
+--------------------------------------------------------------------

Old:
----
  mksusecd-1.55.tar.xz

New:
----
  mksusecd-1.56.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ mksusecd.spec ++++++
--- /var/tmp/diff_new_pack.vJGxMH/_old  2018-01-20 11:27:49.989227960 +0100
+++ /var/tmp/diff_new_pack.vJGxMH/_new  2018-01-20 11:27:49.993227773 +0100
@@ -18,7 +18,7 @@
 
 
 Name:           mksusecd
-Version:        1.55
+Version:        1.56
 Release:        0
 Summary:        Create SUSE Linux installation ISOs
 License:        GPL-3.0+

++++++ mksusecd-1.55.tar.xz -> mksusecd-1.56.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mksusecd-1.55/VERSION new/mksusecd-1.56/VERSION
--- old/mksusecd-1.55/VERSION   2017-12-05 10:50:35.000000000 +0100
+++ new/mksusecd-1.56/VERSION   2018-01-19 10:26:47.000000000 +0100
@@ -1 +1 @@
-1.55
+1.56
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mksusecd-1.55/changelog new/mksusecd-1.56/changelog
--- old/mksusecd-1.55/changelog 2017-12-05 10:50:35.000000000 +0100
+++ new/mksusecd-1.56/changelog 2018-01-19 10:26:47.000000000 +0100
@@ -1,3 +1,7 @@
+2018-01-18:    1.56
+       - fix handling of repo-md repositories with encrypted media
+       - allow building of encrypted installation media
+
 2017-12-01:    1.55
        - support new CHECKSUMS file
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mksusecd-1.55/mksusecd new/mksusecd-1.56/mksusecd
--- old/mksusecd-1.55/mksusecd  2017-12-05 10:50:35.000000000 +0100
+++ new/mksusecd-1.56/mksusecd  2018-01-19 10:26:47.000000000 +0100
@@ -205,6 +205,8 @@
 sub wipe_iso;
 sub analyze_products;
 sub check_product;
+sub crypto_cleanup;
+sub run_crypto_disk;
 
 my %config;
 my $sudo;
@@ -253,6 +255,11 @@
 my $opt_merge_repos = 1;
 my $opt_list_repos;
 my $opt_include_repos;
+my $opt_crypto;
+my $opt_crypto_fs = 'ext4';
+my $opt_crypto_password;
+my $opt_crypto_title;
+my $opt_crypto_top_dir;
 
 
 GetOptions(
@@ -276,6 +283,11 @@
   'no-hybrid'        => sub { $opt_hybrid = 0 },
   'hybrid-fs=s'      => sub { $opt_hybrid = 1; $opt_hybrid_fs = $_[1] },
   'fat'              => sub { $opt_hybrid = 1; $opt_hybrid_fs = 'fat'; 
$opt_efi = 0; $opt_no_iso = 1 },
+  'crypto'           => sub { $opt_crypto = 1; $opt_hybrid = 0; },
+  'password=s'       => \$opt_crypto_password,
+  'title=s'          => \$opt_crypto_title,
+  'top-dir=s'        => \$opt_crypto_top_dir,
+  'filesystem=s'     => \$opt_crypto_fs,
   'no-iso'           => \$opt_no_iso,
   'size=s'           => \$opt_size,
   'protective-mbr'   => sub { $opt_no_prot_mbr = 0 },
@@ -325,6 +337,8 @@
 usage 1 if $opt_hybrid_fs !~ '^(|iso|fat)$';
 usage 1 if defined($opt_digest) && $opt_digest !~ 
'^(md5|sha1|sha224|sha256|sha384|sha512)$';
 
+die "no password\n" if $opt_crypto && $opt_crypto_password eq "";
+
 $ENV{PATH} = "$LIBEXECDIR/mksusecd:/usr/bin:/bin:/usr/sbin:/sbin";
 
 if($opt_rebuild_initrd && $>) {
@@ -391,6 +405,7 @@
 my $linuxrc_options;
 my $has_content;
 my $product_db;
+my $repomd_instsys_location;
 
 my $progress_start = 0;
 my $progress_end = 100;
@@ -412,7 +427,7 @@
 #  }
 
   # we might need two mkisofs runs...
-  $two_runs = $opt_hybrid && $opt_hybrid_fs;
+  $two_runs = ($opt_hybrid && $opt_hybrid_fs) || $opt_crypto;
 
   $iso_file = $opt_dst;
 
@@ -466,7 +481,13 @@
       my $x = get_kernel_initrd;
       die "oops: no initrd?\n" unless $x;
       if($x->{initrd} =~ m#(boot/[^/]+)/#) {
-        $opt_instsys = "disk:/$1/root";
+        $repomd_instsys_location = "$1/root";
+        # Note
+        #   When encryption is in use we must not set the instsys location
+        #   here. This would cause linuxrc to miss the instsys as the URL
+        #   below does never point inside an encrypted volume.
+        #   Instead, run_crypto_disk() handles this when writing 90_crypto.
+        $opt_instsys = "disk:/$repomd_instsys_location" unless $opt_crypto;
       }
     }
 
@@ -532,6 +553,13 @@
   run_mkisofs;
 
   if($two_runs) {
+    if($opt_crypto) {
+      $progress_start = 50;
+      $progress_end = 100;
+      run_crypto_disk;
+      exit
+    }
+
     rerun_mkisofs;
   }
 
@@ -623,12 +651,22 @@
                                 used to write a DVD. You can adjust the file 
system size
                                 with the --size option.
                                 Technically an alias for '--hybrid-fs=fat 
--no-efi --no-iso'.
-      --size SIZE_SPEC          When using a FAT file system, you can set the 
intended size of
-                                the disk image.
+      --size SIZE_SPEC          When using a FAT file system or the --crypto 
option you can
+                                set the intended size of the disk image.
                                 SIZE_SPEC can be a number, optionally followed 
by a unit ('b',
                                 'k', 'm', 'g', 't') indicating blocks, kiB, 
MiB, GiB, or TiB.
                                 But SIZE_SPEC can also be a device name like 
'/dev/sda', in
                                 which casee the size of the device is used.
+      --crypto                  If set, an encrypted disk image is created.
+                                See Crypto notes below for details.
+      --password PASSWORD       Use PASSWORD for encrypting the disk image.
+      --title TITLE             The password query screen uses TITLE as title 
(default: openSUSE).
+      --top-dir DIR             The installation files are placed into subdir 
DIR in the created
+                                image. This helps keeping the directory 
structure nice and clean
+                                in case you are using the image also for other 
things. The boot
+                                config is adjusted accordingly.
+      --filesystem FS           Use FILESYSTEM for the encrypted image 
(default: ext4). Don't be
+                                too creative here - the filesystem must be 
supported by grub2.
       --zipl                    Make zIPL bootable (default on s390x).
       --no-zipl                 Don't make zIPL bootable (default except on 
s390x).
       --initrd DIR|RPM|DUD      Add directory DIR or package RPM or driver 
update DUD
@@ -720,40 +758,40 @@
 
 Signing notes:
 
-    On all media there is a file '/content' holding SHA256 sums of all files
-    relevant during installation. The file is signed and is used to ensure
-    the integrity of the installation environment.
-
-    If you modify any file mentioned there (e.g. replacing it or implicitly
-    as a result of the --initrd or --boot options) '/content' is updated and
-    must be re-signed. Otherwise the installer will complain when it starts
-    up. For this, mksusecd will re-sign the file and add the public part of
-    the signing key to the initrd.
+  On all media there is a file '/content' holding SHA256 sums of all files
+  relevant during installation. The file is signed and is used to ensure
+  the integrity of the installation environment.
+
+  If you modify any file mentioned there (e.g. replacing it or implicitly
+  as a result of the --initrd or --boot options) '/content' is updated and
+  must be re-signed. Otherwise the installer will complain when it starts
+  up. For this, mksusecd will re-sign the file and add the public part of
+  the signing key to the initrd.
 
-    You can specify the key to use with the 'sign-key' option. The option
-    must point to a private key file.
+  You can specify the key to use with the 'sign-key' option. The option
+  must point to a private key file.
 
-    If there's no 'sign-key' option, a transient key is created. The public
-    part is added to the initrd and the key is deleted.
+  If there's no 'sign-key' option, a transient key is created. The public
+  part is added to the initrd and the key is deleted.
 
 Add-on notes:
 
-    The add-on created here is just a repository, not a full add-on product.
-    If you need the latter, you will have to create that on your own and add
-    it to the iso.
-
-    Although it auto-generates a name for the repository, it's not a very
-    creative one and it's probably a good idea to choose one explicitly
-    using the --addon-name option.
-
-    The default installation repositories have priority 99. Any smaller
-    number for the add-on repository will prefer the add-on packages even
-    though the package version number is smaller than in the standard
-    repository.
-
-    The default priority of 60 is chosen to be between the priority of the
-    default installation repositories (99) and the repositories created by
-    driver updates (50).
+  The add-on created here is just a repository, not a full add-on product.
+  If you need the latter, you will have to create that on your own and add
+  it to the iso.
+
+  Although it auto-generates a name for the repository, it's not a very
+  creative one and it's probably a good idea to choose one explicitly
+  using the --addon-name option.
+
+  The default installation repositories have priority 99. Any smaller
+  number for the add-on repository will prefer the add-on packages even
+  though the package version number is smaller than in the standard
+  repository.
+
+  The default priority of 60 is chosen to be between the priority of the
+  default installation repositories (99) and the repositories created by
+  driver updates (50).
 
 Repository notes:
 
@@ -797,6 +835,46 @@
   Check the available modules with --list-repos and then pick the modules
   you need with --include-repos.
 
+Crypto notes:
+
+  The --crypto option allows you to create an encrypted installation disk.
+  Note that this image is explicitly *not* bootable as cd/dvd (no hybrid
+  image). It is both legacy BIOS and UEFI bootable, though.
+
+  Everything except the plain grub2 binaries is encrypted on a LUKS
+  partition. Including the installer specific boot config. So if you for
+  example put some password into the default boot options via --boot this
+  is also stored in the encrypted part.
+
+  At the moment only x86_64 is supported. And you have to run mksusecd on a
+  machine that has grub2-i386-pc installed (to get the legacy BIOS setup).
+
+  Unlike the usual setup, grub2 is used for both legacy BIOS and UEFI
+  booting. So the boot screen really looks identical in both cases.
+
+  The default image size is chosen to leave only minimal free space. To
+  adjust the image size to your needs, use the --size option.
+
+  ***  Important  ***
+
+    For this to work, the 'cryptsetup' tools must be available in the
+    installer's initrd. This is not the case for older media (prior to
+    recent Tumbleweed and SLE/Leap 15).
+
+    If you work with these old media you must also add the following two
+    packages to the initrd explicitly:
+
+      - cryptsetup
+      - libpwquality1
+
+    You can find the required versions on the install medium in either the
+    /suse/x86_64 or /x86_64 directory. Copy them to some temporary location
+    and add
+
+      --initrd cryptsetup.rpm --initrd libpwquality1.rpm
+
+    to your mksusecd command line.
+
 Configuration file:
 
   \$HOME/.mksusecdrc
@@ -4337,3 +4415,447 @@
   return 1;
 }
 
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# crypto_cleanup(image_file, crypt_vol, crypt_loop, crypt_mount, esp_loop, 
esp_mount, iso_mount)
+#
+# Cleanup things in case we have to leave run_crypto_disk() early.
+#
+sub crypto_cleanup
+{
+  my ($image_file, $crypt_vol, $crypt_loop, $crypt_mount, $esp_loop, 
$esp_mount, $iso_mount) = @_;
+
+  # unmount things that might have been mounted
+  susystem "umount $crypt_mount" if -d $crypt_mount;
+  susystem "umount $esp_mount" if -d $esp_mount;
+  susystem "umount $iso_mount" if -d $iso_mount;
+
+  # close the luks volume
+  susystem "cryptsetup close $crypt_vol" if -b "/dev/mapper/$crypt_vol";
+
+  # detach loop devices
+  susystem "losetup -d $esp_loop" if -b $esp_loop;
+  susystem "losetup -d $crypt_loop" if -b $crypt_loop;
+
+  # remove the temporary image
+  unlink $image_file;
+}
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# run_crypto_disk()
+#
+# Create an LUKS-encrypted install disk.
+#
+# Notes:
+#   - this is not a hybrid image - you cannot use it as dvd image
+#   - so far only for x86_64
+#   - the image is UEFI and legacy BIOS bootable
+#   - there are two partitions: an (unencrypted) EFI system partition and
+#     the encrypted install partition
+#   - everything except the grub binary is encrypted - including the boot
+#     config files used for installation
+#   - a lot of things have to be done with root permissions, even though
+#     we are working only on image files :-(
+#
+# This function uses the iso produced in the first pass as basis.
+#
+sub run_crypto_disk
+{
+  die "\nsorry, package grub2-i386-pc must be installed\n" unless -f 
"/usr/lib/grub2/i386-pc/boot.img";
+
+  die "\nfilesystem '$opt_crypto_fs' not supported\n" unless -x 
"/usr/sbin/mkfs.$opt_crypto_fs";
+
+  # if set, it must have a "/" at the end (e.g. "foo/")
+  my $top_dir = $opt_crypto_top_dir;
+  die "\n$top_dir: top-dir value not allowed\n" if $top_dir =~ m#/# || 
$top_dir eq '.' || $top_dir eq '..';
+  $top_dir .= "/" if $top_dir ne "";
+
+  # EFI system partition start in MiB
+  my $esp_start_mb = 1;
+
+  # EFI system partition size in MiB
+  my $esp_size_mb = 7;
+
+  # install partition start in MiB
+  my $crypt_start_mb = $esp_start_mb + $esp_size_mb;
+
+  # we need a temporary device mapper target - just use our tmp dir name
+  my $crypt_vol;
+  $crypt_vol = $1 if $tmp_new =~ m#/tmp/([^/]+)#;
+  die "\noops: can't generate device mapper name\n" if $crypt_vol eq "";
+
+  # get the image size
+  if(!$image_size) {
+    my $size = (-s $iso_file) >> 20;
+    # increase size slightly to ensure we have enough space
+    $size = $size * 1.2;
+    $size += $esp_size_mb + $esp_start_mb + 8;
+    $image_size = int($size) << 11;
+  }
+
+  my $image_file = "${iso_file}.tmp.$crypt_vol";
+
+  my ($crypt_loop, $crypt_mount, $esp_loop, $esp_mount, $iso_mount, $fh);
+
+  # store the password to be used by cryptsetup later
+  my $crypt_pw = $tmp->file('pw');
+  open $fh, ">$crypt_pw" or die "\npassword file: $!\n";
+  print $fh $opt_crypto_password;
+  close $fh;
+
+  # register cleanup function in case we error out
+  END { crypto_cleanup $image_file, $crypt_vol, $crypt_loop, $crypt_mount, 
$esp_loop, $esp_mount, $iso_mount }
+
+  # create the empty image
+  open $fh, ">", $image_file;
+  close $fh;
+  truncate $image_file, $image_size << 9;
+
+  # partition it
+  system "parted -s '$image_file' mklabel msdos";
+  system "parted -s '$image_file' mkpart p ${esp_start_mb}MiB 
${crypt_start_mb}MiB";
+  system "parted -s '$image_file' mkpart p ${crypt_start_mb}MiB 100%";
+  system "parted -s '$image_file' set 1 boot on";
+  system "sfdisk --change-id '$image_file' 1 0xef 2>/dev/null";
+
+  # make an efi system partition (fat)
+  fat_mkfs $tmp_fat, $esp_size_mb << 11, $esp_start_mb << 11, 1, "EFI_PART";
+
+  # ... and copy it into the efi system partition
+  system "dd if='$tmp_fat' of='$image_file' bs=1b seek=" . ($esp_start_mb << 
11) . " conv=notrunc status=none ; sync";
+
+  # get loop device for install partition
+  $crypt_loop = `${sudo}losetup --show -f -o ${\($crypt_start_mb << 20)} 
'$image_file'`;
+  chomp $crypt_loop;
+
+  die "\noops: no loop device\n" unless -b $crypt_loop;
+
+  show_progress 10;
+
+  # create luks container
+  susystem "cryptsetup --batch-mode --force-password --key-file=$crypt_pw 
luksFormat $crypt_loop";
+  susystem "cryptsetup --key-file=$crypt_pw open $crypt_loop $crypt_vol";
+
+  # add filesystem
+  susystem "mkfs.$opt_crypto_fs -q /dev/mapper/$crypt_vol";
+
+  # get filesystem uuid
+  my $fs_uuid=`${sudo}blkid -o value -s UUID /dev/mapper/$crypt_vol`;
+  chomp $fs_uuid;
+
+  # ... and luks partition uuid
+  my $luks_uuid=`${sudo}blkid -o value -s UUID $crypt_loop`;
+  chomp $luks_uuid;
+
+  # grub prefers the uuid without dashes ('-')
+  my $grub_uuid = $luks_uuid;
+  $grub_uuid =~ tr/-//d;
+
+  die "\noops: cryptsetup failed\n" if $fs_uuid eq "" || $luks_uuid eq "";
+
+  show_progress 30;
+
+  # get loop device for efi system partition
+  $esp_loop = `${sudo}losetup --show -f -o ${\($esp_start_mb << 20)} 
--sizelimit ${\($esp_size_mb << 20)} '$image_file'`;
+  chomp $esp_loop;
+
+  die "\noops: no loop device\n" unless -b $esp_loop;
+
+  # create temporary mount points
+  $esp_mount = $tmp->dir('esp');
+  $crypt_mount = $tmp->dir('crypt');
+  $iso_mount = $tmp->dir('iso');
+
+  # mount install partition, efi partition, and the prepared iso image
+  die "\ncrypto mount failed\n" if susystem "mount /dev/mapper/$crypt_vol 
$crypt_mount";
+  die "\nesp mount failed\n" if susystem "mount -oumask=0 $esp_loop 
$esp_mount";
+  die "\niso mount failed\n" if susystem "mount -oloop,ro '$iso_file' 
$iso_mount";
+
+  # some checks
+  die "\nsorry, only x86_64 media supported atm\n" unless -d 
"$iso_mount/boot/x86_64/grub2-efi";
+  die "\nsorry, efi boot is required\n" unless -d "$iso_mount/EFI/BOOT";
+
+  # now our partitions are prepared and mounted
+
+  show_progress 50;
+
+  my $tmp_dir = $tmp->dir();
+
+  my $title = $opt_crypto_title || "openSUSE";
+
+  # ---  1. grub2 legacy setup  ---
+
+  (my $grub_mods = <<"  = = = = = = = =") =~ s/\s+/ /g;
+    gfxmenu gfxterm
+    video videoinfo vga vbe
+    biosdisk linux
+    ext2 btrfs xfs jfs reiserfs iso9660 tar memdisk probe
+    cryptodisk luks gcry_rijndael gcry_sha1 gcry_sha256
+    all_video boot cat chain configfile echo
+    font gzio halt
+    jpeg minicmd normal part_apple part_msdos part_gpt
+    password_pbkdf2 png reboot search search_fs_uuid
+    search_fs_file search_label sleep test video fat loadenv
+  = = = = = = = =
+
+  # copy grub boot block to the required place for grub2-mkimage
+  File::Path::make_path "$esp_mount/BOOT/grub2/i386-pc";
+  system "cp /usr/lib/grub2/i386-pc/boot.img $esp_mount/boot/grub2/i386-pc";
+
+  my $title_centered = $title;
+  if(length $title <= 78) {
+    $title_centered = (" " x ((80 - length $title) / 2)) . $title;
+  }
+
+  # This is the initial grub config - just ask for password and mount
+  # the luks volume.
+  # The real grub config with the install menu is inside the luks volume.
+  (my $load_cfg = <<"  = = = = = = = =") =~ s/^ +//mg;
+    locale_dir=\$prefix/locale
+    lang=en_US
+    clear
+    echo
+    echo "$title_centered"
+    echo
+    echo "                                   -- BIOS --"
+    echo
+    cryptomount -u $grub_uuid
+    root=crypto0
+    set prefix=(\$root)/${top_dir}boot/x86_64/grub2-efi
+  = = = = = = = =
+
+  (my $grub_po = <<"  = = = = = = = =") =~ s/^ +//mg;
+    msgid "GNU GRUB  version %s"
+    msgstr "$title"
+
+    msgid "Attempting to decrypt master key..."
+    msgstr " "
+
+    msgid "Enter passphrase for %s%s%s (%s): "
+    msgstr "Enter passphrase: "
+  = = = = = = = =
+
+  open $fh, ">$tmp_dir/load.cfg";
+  print $fh $load_cfg;
+  close $fh;
+
+  # The default grub password dialog looks dead ugly; (ab)use
+  # localization to make it look nice.
+  # The en.mo file is placed into a memdisk which is then embedded into the
+  # grub image.
+  File::Path::make_path "$tmp_dir/memdisk/locale";
+  open $fh, "| msgfmt -o $tmp_dir/memdisk/locale/en.mo -";
+  print $fh $grub_po;
+  close $fh;
+  system "cd $tmp_dir/memdisk ; tar -cf ../memdisk.tar *";
+
+  system "grub2-mkimage -O i386-pc -m $tmp_dir/memdisk.tar -p '(memdisk)'" .
+    " -c $tmp_dir/load.cfg -o $esp_mount/boot/grub2/i386-pc/core.img 
$grub_mods";
+
+  # grub2-bios-setup behaves a bit weird; I've seen no way to stop it from
+  # trying to figure out things on its own. So it needs root permissions
+  # to trace things through the loop device.
+  susystem "grub2-bios-setup -s -d $esp_mount/boot/grub2/i386-pc 
'$image_file'";
+
+  # the grub stuff is no longer needed, clear the efi partition
+  system "rm -r $esp_mount/boot";
+
+  # ---  grub2 legacy setup done  ---
+
+  # ---  2. grub2 efi setup  ---
+
+  # copy the efi config from the prepared iso and add our en.mo file
+  system "cp -r $iso_mount/EFI $esp_mount/";
+  system "cp $tmp_dir/memdisk/locale/en.mo $esp_mount/EFI/BOOT/locale";
+
+  # adjust the startup message to indicate we've booted via efi
+  $load_cfg =~ s/BIOS/UEFI/g;
+
+  # we have to explicitly load the final grub config (in the legacy case it
+  # is done automatically)
+  $load_cfg .= "configfile \$prefix/efi.cfg\n";
+
+  # write initial grub config
+  open $fh, ">$esp_mount/EFI/BOOT/grub.cfg";
+  print $fh $load_cfg;
+  close $fh;
+
+  # ---  grub2 efi setup done  ---
+
+  show_progress 60;
+
+  # ---  3. install partition setup  ---
+
+  # 3.1. copy everything
+
+  # maybe put everything into a separate directory
+  susystem "mkdir $crypt_mount/$top_dir" if $top_dir;
+
+  # copy everything except the efi config - it's already on the efi system
+  # partition
+  system "${sudo}tar -C $iso_mount --exclude EFI -cf - . | ${sudo}tar -C 
$crypt_mount/$top_dir -xpf -";
+
+  show_progress 90;
+
+  # move locale settings to the correct place
+  susystem "cp -r $iso_mount/EFI/BOOT/locale 
$crypt_mount/${top_dir}boot/x86_64/grub2-efi";
+
+  # sanitize permissions (everything is ro on an iso9660 fs)
+  susystem "chmod -R u+w $crypt_mount";
+
+  # the el-torito efi image is not needed
+  susystem "rm -f $crypt_mount/${top_dir}boot/x86_64/efi";
+
+  # 3.2. adjust grub install config
+
+  # There's only a grub config for efi on our media. We derive the legacy
+  # config from it - it needs just a few modifications.
+
+  # get it
+  my $grub_cfg = `cat $iso_mount/EFI/BOOT/grub.cfg`;
+  die "\nno grub config found\n" if $grub_cfg eq "";
+
+  # strip things we don't want (it's been setup in the initial grub config)
+  $grub_cfg =~ s/^search .*\n//m;
+  $grub_cfg =~ s/^prefix=.*\n//m;
+  $grub_cfg =~ s/^insmod efi_.*\n//mg;
+
+   # adjust paths
+  if($top_dir ne "") {
+    $grub_cfg =~ s#/boot/#/${top_dir}boot/#g
+  }
+
+  # write grub efi config
+
+  # Due to permission issues (the install partition is only root-writable)
+  # write it to a tmp file and copy later.
+  open $fh, ">$tmp_dir/grub.cfg";
+  print $fh $grub_cfg;
+  close $fh;
+
+  # it's the efi config
+  susystem "cp $tmp_dir/grub.cfg 
$crypt_mount/${top_dir}boot/x86_64/grub2-efi/efi.cfg";
+
+  # convert efi config to legacy config
+
+  # Basically replace linuxefi/initrdefi with linux/initrd and replace the
+  # 'local boot' entry.
+  $grub_cfg =~ s/\b(linux|initrd)efi\b/$1/g;
+
+  (my $local_boot = <<"  = = = = = = = =") =~ s/^ {4}//mg;
+    menuentry "Boot from Hard Disk" --class opensuse --class gnu-linux --class 
gnu --class os {
+      set root=hd1
+      chainloader (hd1)+1
+    }
+  = = = = = = = =
+
+  $grub_cfg =~ s/^menuentry "Boot from Hard Disk".*?^\}\n/$local_boot/sm;
+
+  # write grub legacy config
+
+  # Due to permission issues (the install partition is only root-writable)
+  # write it to a tmp file and copy later.
+  open $fh, ">$tmp_dir/grub.cfg";
+  print $fh $grub_cfg;
+  close $fh;
+
+  susystem "cp $tmp_dir/grub.cfg 
$crypt_mount/${top_dir}boot/x86_64/grub2-efi/grub.cfg";
+
+  # adjust initrd
+
+  # Now inject code to decrypt and mount the install partition. Also, point
+  # the install source to the luks volume.
+
+  # find the initrd
+  my $initrd_file = "$crypt_mount/${top_dir}boot/x86_64/loader/initrd";
+  $initrd_file = "$crypt_mount/${top_dir}boot/x86_64/initrd" unless -f 
$initrd_file;
+  die "\nsorry, no initrd found\n" unless -f $initrd_file;
+
+  File::Path::make_path "$tmp_dir/initrd/etc/linuxrc.d";
+
+  # Store the password in the initrd so the user doesn't have to enter it 
twice.
+  # (Note the initrd is on the encrypted volume.)
+  # To avoid accidentally leaking the password when the user hands out the
+  # initrd to someone else, encrypt the password file with the luks and
+  # filesystem uuid as key. The uuid info is separate from the initrd. So even
+  # if you copy the whole install souces from the unlocked luks volume, it
+  # doesn't leak your password.
+  open $fh, "| gpg --passphrase '$luks_uuid $fs_uuid' -c --batch --cipher-algo 
aes256 -o $tmp_dir/initrd/.password 2>/dev/null";
+  print $fh "$opt_crypto_password";
+  close $fh;
+
+  die "\noops: password setup failed\n" unless -s "$tmp_dir/initrd/.password";
+
+  # strip the final slash
+  my $t = ${top_dir};
+  $t =~ s#/$##;
+
+  # Inject a linuxrc config entry to unlock the luks volume and point the
+  # install source to the volume.
+  # Note: we cannot unlock the volume directly here but have to append the
+  # call to the 'early_setup' script as the config files are parsed _before_
+  # udev sets up the devices.
+  # The install option can still be overriden by anything passed via kernel
+  # command line.
+  (my $linuxrc_setup = <<"  = = = = = = = =") =~ s/^ +//mg;
+    exec=echo /scripts/crypt_setup >>/scripts/early_setup
+    install=hd:/$t?device=/dev/mapper/install.luks
+  = = = = = = = =
+
+  # for repo-md, instsys location should be set explicitly
+  if($repomd_instsys_location) {
+    my $dir = "/$t/$repomd_instsys_location";
+    # be careful to have only single slashes
+    $dir =~ s#//#/#g;
+    $linuxrc_setup .= "instsys=hd:$dir?device=/dev/mapper/install.luks\n";
+  }
+
+  open $fh, ">$tmp_dir/initrd/etc/linuxrc.d/90_crypto";
+  print $fh $linuxrc_setup;
+  close $fh;
+
+  # Store a small part of the id in the script to help identify the right
+  # volume.
+  # It's strictly not necessary but this way we don't waste too much efford
+  # on systems with lots of volumes.
+  my $short_uuid = substr $luks_uuid, 0, 4;
+
+  # Here's the script. It iterates over all volumes, tries to decrypt the
+  # password with the uuids it sees, and on success sets up the luks volume
+  # and deletes the password files and itself.
+  (my $crypt_setup = <<"  = = = = = = = =") =~ s/^ {4}//mg;
+    #! /bin/bash
+    cd /dev/disk/by-uuid
+    for uuid in $short_uuid* ; do
+      gpg --passphrase \"\$uuid $fs_uuid\" -d --batch --cipher-algo aes256 -o 
/.password. /.password 2>/dev/null
+      if [ -f /.password. ] ; then
+        cryptsetup --key-file=/.password. open /dev/disk/by-uuid/\$uuid 
install.luks
+        break
+      fi
+    done
+    rm -f /.password* /scripts/crypt_setup
+  = = = = = = = =
+
+  # add the script to our initrd tree
+  mkdir "$tmp_dir/initrd/scripts";
+  open $fh, ">$tmp_dir/initrd/scripts/crypt_setup";
+  print $fh $crypt_setup;
+  close $fh;
+  chmod 0755, "$tmp_dir/initrd/scripts/crypt_setup";
+
+  # pack, compress, and append our initrd stuff to the initrd
+  system "( cd $tmp_dir/initrd ; find . | cpio --quiet -o -H newc --owner 0:0 
| xz --check=crc32 -c ) > $tmp_dir/initrd.xz";
+  susystem "sh -c 'cat $tmp_dir/initrd.xz >> $initrd_file'";
+
+  # ---  install partition setup done  ---
+
+  # That's it, we're done.
+
+  show_progress 100;
+
+  # rename our temporary image to the final name
+  rename $image_file, $iso_file;
+
+  print "\n";
+}


Reply via email to