installer: Add support for creating encrypted partitions.
authorSascha Wildner <saw@online.de>
Sat, 6 Nov 2010 01:37:38 +0000 (02:37 +0100)
committerSascha Wildner <saw@online.de>
Sat, 6 Nov 2010 01:38:16 +0000 (02:38 +0100)
With the exception of /boot for the HAMMER install and / for the UFS
install, allow the configuration of encryption of partitions via
checkboxes in the partition creation stage.

nrelease/root/boot/loader.conf
share/installer/cmdnames.conf
usr.sbin/installer/dfuibe_installer/fn.h
usr.sbin/installer/dfuibe_installer/fn_configure.c
usr.sbin/installer/dfuibe_installer/fn_install.c
usr.sbin/installer/dfuibe_installer/fn_subpart_hammer.c
usr.sbin/installer/dfuibe_installer/fn_subpart_ufs.c
usr.sbin/installer/libinstaller/diskutil.c
usr.sbin/installer/libinstaller/diskutil.h

index 918ad3e..cee3f31 100644 (file)
@@ -5,3 +5,4 @@
 #
 kernel_options="-C"
 kern.emergency_intr_enable=1
+dm_load="YES"
index 7e8726e..2996556 100644 (file)
@@ -24,12 +24,14 @@ RM=bin/rm
 SH=bin/sh
 TEST=bin/test
 
+CRYPTSETUP=sbin/cryptsetup
 DHCLIENT=sbin/dhclient
 DISKLABEL64=sbin/disklabel64
 DUMPON=sbin/dumpon
 FDISK=sbin/fdisk
 HAMMER=sbin/hammer
 IFCONFIG=sbin/ifconfig
+MKINITRD=sbin/mkinitrd
 MOUNT=sbin/mount
 MOUNTD=sbin/mountd
 MOUNT_HAMMER=sbin/mount_hammer
index 0265a32..cdf5dde 100644 (file)
@@ -50,6 +50,7 @@
 
 void            fn_select_disk(struct i_fn_args *);
 void            fn_select_slice(struct i_fn_args *);
+void            fn_get_passphrase(struct i_fn_args *);
 
 /* Configure an Installed System (only) */
 
index 7fdd521..3478be5 100644 (file)
  * $Id: fn_configure.c,v 1.82 2005/03/25 05:24:00 cpressey Exp $
  */
 
+#include <sys/stat.h>
 #include <sys/types.h>
 
 #include <ctype.h>
 #include <dirent.h>
+#include <fcntl.h>
 #include <libgen.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
+#include <unistd.h>
 
 #ifdef ENABLE_NLS
 #include <libintl.h>
@@ -336,10 +339,97 @@ fn_root_passwd(struct i_fn_args *a)
        dfui_form_free(f);
 }
 
+void
+fn_get_passphrase(struct i_fn_args *a)
+{
+       struct dfui_dataset *ds, *new_ds;
+       struct dfui_form *f;
+       struct dfui_response *r;
+       const char *passphrase_1, *passphrase_2;
+       int fd;
+       int done = 0;
+
+       f = dfui_form_create(
+           "crypt_passphrase",
+           _("Set Passphrase For Encryption"),
+           _("Please specify the passphrase to be used for the encrypted "
+           "filesystems.\n\n"
+           "Please note that in the LiveCD environment the keymap is set to "
+           "\"US ISO\". "
+           "If you prefer a different keymap for entering the passphrase "
+           "here, you will need to set it manually using kbdcontrol(1)."),
+           "",
+
+           "f", "passphrase_1", _("Passphrase"),
+           _("Enter the passphrase you would like to use for encryption"), "",
+           "p", "obscured", "true",
+           "f", "passphrase_2", _("Passphrase again"),
+           _("Enter the passphrase again to confirm"), "",
+           "p", "obscured", "true",
+
+           "a", "ok", _("Accept and Set Passphrase"), "", "",
+           "p", "accelerator", "ESC",
+
+           NULL
+       );
+
+       ds = dfui_dataset_new();
+       dfui_dataset_celldata_add(ds, "passphrase_1", "");
+       dfui_dataset_celldata_add(ds, "passphrase_2", "");
+       dfui_form_dataset_add(f, ds);
+
+       while (!done) {
+               if (!dfui_be_present(a->c, f, &r))
+                       abort_backend();
+
+               if (strcmp(dfui_response_get_action_id(r), "ok") == 0) {
+                       new_ds = dfui_dataset_dup(dfui_response_dataset_get_first(r));
+                       dfui_form_datasets_free(f);
+                       dfui_form_dataset_add(f, new_ds);
+
+                       /*
+                        * Fetch form field values.
+                        */
+
+                       passphrase_1 = dfui_dataset_get_value(new_ds, "passphrase_1");
+                       passphrase_2 = dfui_dataset_get_value(new_ds, "passphrase_2");
+
+                       if (strlen(passphrase_1) == 0 && strlen(passphrase_2) == 0) {
+                               done = 0;
+                       } else if (strcmp(passphrase_1, passphrase_2) == 0) {
+                               /*
+                                * Passphrases match, write it out.
+                                */
+                               fd = open("/tmp/t1", O_RDWR | O_CREAT | O_TRUNC,
+                                   S_IRUSR);
+                               if (fd != -1) {
+                                       write(fd, passphrase_1, strlen(passphrase_1));
+                                       close(fd);
+                                       done = 1;
+                               } else {
+                                       inform(a->c, _("write() error"));
+                                       done = 0;
+                               }
+                       } else {
+                               /*
+                                * Passphrases don't match, tell the user,
+                                * let them try again.
+                                */
+                               inform(a->c, _("The passphrases do not match."));
+                               done = 0;
+                       }
+               }
+
+               dfui_response_free(r);
+       }
+
+       dfui_form_free(f);
+}
+
 void
 fn_install_packages(struct i_fn_args *a)
 {
-       FILE *pipe;
+       FILE *pfp;
        struct commands *cmds;
        struct dfui_celldata *cd;
        struct dfui_dataset *ds;
@@ -372,8 +462,8 @@ fn_install_packages(struct i_fn_args *a)
 
        ds = dfui_dataset_new();
        snprintf(command, 256, "ls %svar/db/pkg", a->os_root);
-       if ((pipe = popen(command, "r")) != NULL) {
-               while (fgets(pkg_name, 255, pipe) != NULL) {
+       if ((pfp = popen(command, "r")) != NULL) {
+               while (fgets(pkg_name, 255, pfp) != NULL) {
                        while (strlen(pkg_name) > 0 &&
                               isspace(pkg_name[strlen(pkg_name) - 1])) {
                                pkg_name[strlen(pkg_name) - 1] = '\0';
@@ -384,7 +474,7 @@ fn_install_packages(struct i_fn_args *a)
                        dfui_dataset_celldata_add(ds,
                            pkg_name, "Y");
                }
-               pclose(pipe);
+               pclose(pfp);
        }
        dfui_form_dataset_add(f, ds);
 
@@ -430,7 +520,7 @@ fn_install_packages(struct i_fn_args *a)
 void
 fn_remove_packages(struct i_fn_args *a)
 {
-       FILE *pipe;
+       FILE *pfp;
        struct commands *cmds;
        struct dfui_celldata *cd;
        struct dfui_dataset *ds;
@@ -455,8 +545,8 @@ fn_remove_packages(struct i_fn_args *a)
 
        ds = dfui_dataset_new();
        snprintf(command, 256, "ls %smnt/var/db/pkg", a->os_root);
-       if ((pipe = popen(command, "r")) != NULL) {
-               while (fgets(pkg_name, 255, pipe)) {
+       if ((pfp = popen(command, "r")) != NULL) {
+               while (fgets(pkg_name, 255, pfp)) {
                        pkg_name[strlen(pkg_name) - 1] = '\0';
                        fi = dfui_form_field_add(f, pkg_name,
                            dfui_info_new(pkg_name, "", ""));
@@ -464,7 +554,7 @@ fn_remove_packages(struct i_fn_args *a)
                        dfui_dataset_celldata_add(ds,
                            pkg_name, "N");
                }
-               pclose(pipe);
+               pclose(pfp);
        }
        dfui_form_dataset_add(f, ds);
 
@@ -871,7 +961,7 @@ fn_assign_hostname_domain(struct i_fn_args *a)
                config_var_set(rc_conf, "hostname", fqdn);
                config_var_set(resolv_conf, "search", domain);
                config_vars_write(resolv_conf, CONFIG_TYPE_RESOLV,
-                   "%s%setc/resolv.conf", "/", a->cfg_root);
+                   "%s%setc/resolv.conf", a->os_root, a->cfg_root);
 
                config_vars_free(resolv_conf);
 
@@ -1118,7 +1208,8 @@ fn_select_services(struct i_fn_args *a)
        struct dfui_form *f;
        struct dfui_response *r;
 
-       if (!config_vars_read(a, rc_conf, CONFIG_TYPE_SH, "%setc/rc.conf", a->cfg_root)) {
+       if (!config_vars_read(a, rc_conf, CONFIG_TYPE_SH, "%s%setc/rc.conf",
+               a->os_root, a->cfg_root)) {
                inform(a->c, _("Couldn't read %s%setc/rc.conf."),
                    a->os_root, a->cfg_root);
                a->result = 0;
@@ -1223,10 +1314,10 @@ convert_tmpfs_options(char *line)
 int
 mount_target_system(struct i_fn_args *a)
 {
-       FILE *fstab;
+       FILE *crypttab, *fstab;
        struct commands *cmds;
        struct subpartition *a_subpart;
-       char device[256], mtpt[256], fstype[256], options[256];
+       char name[256], device[256], mtpt[256], fstype[256], options[256];
        char *filename, line[256];
        const char *try_mtpt[5]  = {"/var", "/tmp", "/usr", "/home", NULL};
        char *word, *cvtoptions;
@@ -1255,8 +1346,8 @@ mount_target_system(struct i_fn_args *a)
         * assume exists
         */
 
-       a_subpart = subpartition_new(storage_get_selected_slice(a->s),
-           "/dummy", 0, 0, 0, 0, 0);
+       a_subpart = subpartition_new_ufs(storage_get_selected_slice(a->s),
+           "/dummy", 0, 0, 0, 0, 0, 0);
 
        /*
         * Mount the target's / and read its /etc/fstab.
@@ -1267,6 +1358,12 @@ mount_target_system(struct i_fn_args *a)
                    a->os_root,
                    subpartition_get_device_name(a_subpart),
                    a->os_root, a->cfg_root);
+               command_add(cmds,
+                   "%s%s -f %st2;"
+                   "%s%s \"^[^#]\" %s%s/etc/crypttab >%st2",
+                   a->os_root, cmd_name(a, "RM"), a->tmp,
+                   a->os_root, cmd_name(a, "GREP"),
+                   a->os_root, a->cfg_root, a->tmp);
        } else {
                command_add(cmds, "%s%s %sdev/%s %sboot",
                    a->os_root, cmd_name(a, "MOUNT"),
@@ -1274,31 +1371,110 @@ mount_target_system(struct i_fn_args *a)
                    subpartition_get_device_name(a_subpart),
                    a->os_root);
                command_add(cmds,
-                   "%s%s %sdev/`%s%s \"^vfs\\.root\\.mountfrom\" %sboot/loader.conf |"
-                   "%s%s -Fhammer: '{print $2;}' |"
-                   "%s%s 's/\"//'` %s%s",
-                   a->os_root, cmd_name(a, "MOUNT_HAMMER"),
-                   a->os_root,
+                   "%s%s -f %st2;"
+                   "%s%s \"^vfs\\.root\\.realroot=\" %sboot/loader.conf >%st2",
+                   a->os_root, cmd_name(a, "RM"), a->tmp,
                    a->os_root, cmd_name(a, "GREP"),
-                   a->os_root,
-                   a->os_root, cmd_name(a, "AWK"),
-                   a->os_root, cmd_name(a, "SED"),
-                   a->os_root, a->cfg_root);
-               command_add(cmds, "%s%s %sboot",
-                   a->os_root, cmd_name(a, "UMOUNT"),
-                   a->os_root);
+                   a->os_root, a->tmp);
+       }
+       if (!commands_execute(a, cmds)) {
+               commands_free(cmds);
+               return(0);
+       }
+       commands_free(cmds);
+       cmds = commands_new();
+
+       if (use_hammer) {
+               struct stat sb = { .st_size = 0 };
+               stat("/tmp/t2", &sb);
+               if (sb.st_size > 0) {
+                       command_add(cmds, "%s%s %sboot",
+                           a->os_root, cmd_name(a, "UMOUNT"),
+                           a->os_root);
+                       fn_get_passphrase(a);
+                       command_add(cmds,
+                           "%s%s -d /tmp/t1 luksOpen %sdev/`%s%s \"^vfs\\.root\\.realroot=\" %st2 |"
+                           "%s%s -Fhammer: '{print $2;}' |"
+                           "%s%s -F: '{print $1;}'` root",
+                           a->os_root, cmd_name(a, "CRYPTSETUP"),
+                           a->os_root,
+                           a->os_root, cmd_name(a, "GREP"),
+                           a->tmp,
+                           a->os_root, cmd_name(a, "AWK"),
+                           a->os_root, cmd_name(a, "AWK"));
+                       command_add(cmds,
+                           "%s%s %sdev/mapper/root %s%s",
+                           a->os_root, cmd_name(a, "MOUNT_HAMMER"),
+                           a->os_root,
+                           a->os_root, a->cfg_root);
+               } else {
+                       command_add(cmds,
+                           "%s%s %sdev/`%s%s \"^vfs\\.root\\.mountfrom\" %sboot/loader.conf |"
+                           "%s%s -Fhammer: '{print $2;}' |"
+                           "%s%s 's/\"//'` %s%s",
+                           a->os_root, cmd_name(a, "MOUNT_HAMMER"),
+                           a->os_root,
+                           a->os_root, cmd_name(a, "GREP"),
+                           a->os_root,
+                           a->os_root, cmd_name(a, "AWK"),
+                           a->os_root, cmd_name(a, "SED"),
+                           a->os_root, a->cfg_root);
+                       command_add(cmds, "%s%s %sboot",
+                           a->os_root, cmd_name(a, "UMOUNT"),
+                           a->os_root);
+               }
        }
        if (!commands_execute(a, cmds)) {
                commands_free(cmds);
                return(0);
        }
        commands_free(cmds);
+       cmds = commands_new();
 
        /*
         * Get rid of the dummy subpartition.
         */
        subpartitions_free(storage_get_selected_slice(a->s));
 
+       /*
+        * See if an /etc/crypttab exists.
+        */
+       asprintf(&filename, "%s%s/etc/crypttab", a->os_root, a->cfg_root);
+       crypttab = fopen(filename, "r");
+       free(filename);
+       if (crypttab != NULL) {
+               if (!use_hammer)
+                       fn_get_passphrase(a);
+               while (fgets(line, 256, crypttab) != NULL) {
+                       /*
+                        * Parse the crypttab line.
+                        */
+                       if (first_non_space_char_is(line, '#'))
+                               continue;
+                       if ((word = strtok(line, " \t")) == NULL)
+                               continue;
+                       strlcpy(name, word, 256);
+                       if (strcmp(name, "swap") == 0)
+                               continue;
+                       if ((word = strtok(NULL, " \t")) == NULL)
+                               continue;
+                       strlcpy(device, word, 256);
+
+                       command_add(cmds,
+                           "%s%s -d /tmp/t1 luksOpen %s %s",
+                           a->os_root, cmd_name(a, "CRYPTSETUP"),
+                           device, name);
+
+                       continue;
+               }
+               fclose(crypttab);
+       }
+       if (!commands_execute(a, cmds)) {
+               commands_free(cmds);
+               return(0);
+       }
+       commands_free(cmds);
+
        asprintf(&filename, "%s%s/etc/fstab", a->os_root, a->cfg_root);
        fstab = fopen(filename, "r");
        free(filename);
@@ -1380,8 +1556,8 @@ mount_target_system(struct i_fn_args *a)
                                                    "%s%s -o %s %s%s%s %s%s%s",
                                                    a->os_root, cmd_name(a, "MOUNT_NULL"),
                                                    options,
-                                                   a->os_root, a->cfg_root, device, a->os_root,
-                                                   a->cfg_root, mtpt);
+                                                   a->os_root, a->cfg_root, device,
+                                                   a->os_root, a->cfg_root, mtpt);
                                        }
                                }
                        }
index 34db13a..f18d69d 100644 (file)
@@ -125,7 +125,7 @@ fn_install_os(struct i_fn_args *a)
        struct subpartition *sp;
        struct commands *cmds;
        struct command *cmd;
-       int i, seen_it, prefix, j;
+       int i, seen_it, prefix, j, needcrypt;
        FILE *sources_conf;
        char line[256];
        char cp_src[64][256];
@@ -164,7 +164,8 @@ fn_install_os(struct i_fn_args *a)
                            a->os_root,
                            cmd_name(a, "SWAPON"),
                            a->os_root,
-                           subpartition_get_device_name(sp));
+                           subpartition_is_encrypted(sp) ?
+                           "mapper/swap" : subpartition_get_device_name(sp));
                }
        }
 
@@ -173,6 +174,16 @@ fn_install_os(struct i_fn_args *a)
         */
        unmount_all_under(a, cmds, "%smnt", a->os_root);
 
+       /* Check if crypto support is needed */
+       needcrypt = 0;
+       for (sp = slice_subpartition_first(storage_get_selected_slice(a->s));
+            sp != NULL; sp = subpartition_next(sp)) {
+               if (subpartition_is_encrypted(sp)) {
+                       needcrypt = 1;
+                       break;
+               }
+       }
+
        for (sp = slice_subpartition_first(storage_get_selected_slice(a->s));
             sp != NULL; sp = subpartition_next(sp)) {
                if (strcmp(subpartition_get_mountpoint(sp), "/") == 0) {
@@ -180,7 +191,8 @@ fn_install_os(struct i_fn_args *a)
                                command_add(cmds, "%s%s %sdev/%s %smnt%s",
                                    a->os_root, cmd_name(a, "MOUNT_HAMMER"),
                                    a->os_root,
-                                   subpartition_get_device_name(sp),
+                                   subpartition_is_encrypted(sp) ?
+                                   "mapper/root" : subpartition_get_device_name(sp),
                                    a->os_root,
                                    subpartition_get_mountpoint(sp));
                        } else {
@@ -209,10 +221,12 @@ fn_install_os(struct i_fn_args *a)
                        command_add(cmds, "%s%s -v %sdev/%s",
                            a->os_root, cmd_name(a, "DUMPON"),
                            a->os_root,
-                           subpartition_get_device_name(sp));
+                           subpartition_is_encrypted(sp) ?
+                           "mapper/swap" : subpartition_get_device_name(sp));
 
                        asprintf(&string, "/dev/%s",
-                           subpartition_get_device_name(sp));
+                           subpartition_is_encrypted(sp) ?
+                           "mapper/swap" : subpartition_get_device_name(sp));
                        config_var_set(rc_conf, "dumpdev", string);
                        free(string);
                        continue;
@@ -228,12 +242,21 @@ fn_install_os(struct i_fn_args *a)
                                /* Don't mount it if it's TMPFS-backed. */
                                if (subpartition_is_tmpfsbacked(sp))
                                        continue;
-                               command_add(cmds, "%s%s %sdev/%s %smnt%s",
-                                   a->os_root, cmd_name(a, "MOUNT"),
-                                   a->os_root,
-                                   subpartition_get_device_name(sp),
-                                   a->os_root,
-                                   subpartition_get_mountpoint(sp));
+                               if (subpartition_is_encrypted(sp)) {
+                                       command_add(cmds, "%s%s %sdev/mapper/%s %smnt%s",
+                                           a->os_root, cmd_name(a, "MOUNT"),
+                                           a->os_root,
+                                           subpartition_get_mountpoint(sp) + 1,
+                                           a->os_root,
+                                           subpartition_get_mountpoint(sp));
+                               } else {
+                                       command_add(cmds, "%s%s %sdev/%s %smnt%s",
+                                           a->os_root, cmd_name(a, "MOUNT"),
+                                           a->os_root,
+                                           subpartition_get_device_name(sp),
+                                           a->os_root,
+                                           subpartition_get_mountpoint(sp));
+                               }
                        }
                } else if (strcmp(subpartition_get_mountpoint(sp), "/boot") == 0) {
                        command_add(cmds, "%s%s -p %smnt%s",
@@ -432,6 +455,12 @@ fn_install_os(struct i_fn_args *a)
            a->os_root, cmd_name(a, "RM"), a->os_root);
        command_add(cmds, "%s%s -f %smnt/tmp/install.log",
            a->os_root, cmd_name(a, "RM"), a->os_root);
+       command_add(cmds, "%s%s -f %smnt/tmp/t[12]",
+           a->os_root, cmd_name(a, "RM"), a->os_root);
+       command_add(cmds, "%s%s -f %smnt/tmp/test_in",
+           a->os_root, cmd_name(a, "RM"), a->os_root);
+       command_add(cmds, "%s%s -f %smnt/tmp/test_out",
+           a->os_root, cmd_name(a, "RM"), a->os_root);
 
        /*
         * Copy pristine versions over any files we might have installed.
@@ -509,6 +538,11 @@ fn_install_os(struct i_fn_args *a)
             sp != NULL; sp = subpartition_next(sp)) {
                if (strcmp(subpartition_get_mountpoint(sp), "swap") == 0) {
                        command_add(cmds, "%s%s '/dev/%s\t\tnone\t\tswap\tsw\t\t0\t0' >>%smnt/etc/fstab",
+                           a->os_root, cmd_name(a, "ECHO"),
+                           subpartition_is_encrypted(sp) ?
+                           "mapper/swap" : subpartition_get_device_name(sp),
+                           a->os_root);
+                       command_add(cmds, "%s%s 'swap\t/dev/%s\tnone\tnone' >>%smnt/etc/crypttab",
                            a->os_root, cmd_name(a, "ECHO"),
                            subpartition_get_device_name(sp),
                            a->os_root);
@@ -523,10 +557,21 @@ fn_install_os(struct i_fn_args *a)
                                    a->os_root, cmd_name(a, "ECHO"), a->os_root);
                        } else if (subpartition_is_tmpfsbacked(sp)) {
                                command_add(cmds, "%s%s 'tmpfs\t\t\t%s\t\ttmpfs\trw,-s%luM\t1\t1' >>%smnt/etc/fstab",
-                                       a->os_root, cmd_name(a, "ECHO"),
-                                       subpartition_get_mountpoint(sp),
-                                       subpartition_get_capacity(sp),
-                                       a->os_root);
+                                   a->os_root, cmd_name(a, "ECHO"),
+                                   subpartition_get_mountpoint(sp),
+                                   subpartition_get_capacity(sp),
+                                   a->os_root);
+                       } else if (subpartition_is_encrypted(sp)) {
+                               command_add(cmds, "%s%s '%s\t/dev/%s\tnone\tnone' >>%smnt/etc/crypttab",
+                                   a->os_root, cmd_name(a, "ECHO"),
+                                   subpartition_get_mountpoint(sp) + 1,
+                                   subpartition_get_device_name(sp),
+                                   a->os_root);
+                               command_add(cmds, "%s%s '/dev/mapper/%s\t\t%s\t\tufs\trw\t\t2\t2' >>%smnt/etc/fstab",
+                                   a->os_root, cmd_name(a, "ECHO"),
+                                   subpartition_get_mountpoint(sp) + 1,
+                                   subpartition_get_mountpoint(sp),
+                                   a->os_root);
                        } else {
                                command_add(cmds, "%s%s '/dev/%s\t\t%s\t\tufs\trw\t\t2\t2' >>%smnt/etc/fstab",
                                    a->os_root, cmd_name(a, "ECHO"),
@@ -541,12 +586,25 @@ fn_install_os(struct i_fn_args *a)
                                    subpartition_get_device_name(sp),
                                    subpartition_get_mountpoint(sp),
                                    a->os_root);
-                               command_add(cmds, "%s%s 'vfs.root.mountfrom=\"hammer:%s\"' >>%smnt/boot/loader.conf",
-                                   a->os_root, cmd_name(a, "ECHO"),
-                                   subpartition_get_device_name(sp),
-                                   a->os_root);
                                command_add(cmds, "%s%s 'kern.emergency_intr_enable=1' >>%smnt/boot/loader.conf",
                                    a->os_root, cmd_name(a, "ECHO"), a->os_root);
+                               if (subpartition_is_encrypted(sp)) {
+                                       command_add(cmds,
+                                           "%s%s 'vfs.root.mountfrom=\"ufs:md0s0\"' >>%smnt/boot/loader.conf",
+                                           a->os_root, cmd_name(a, "ECHO"),
+                                           a->os_root);
+                                       command_add(cmds,
+                                           "%s%s 'vfs.root.realroot=\"crypt:hammer:%s:root\"' >>%smnt/boot/loader.conf",
+                                           a->os_root, cmd_name(a, "ECHO"),
+                                           subpartition_get_device_name(sp),
+                                           a->os_root);
+                               } else {
+                                       command_add(cmds,
+                                           "%s%s 'vfs.root.mountfrom=\"hammer:%s\"' >>%smnt/boot/loader.conf",
+                                           a->os_root, cmd_name(a, "ECHO"),
+                                           subpartition_get_device_name(sp),
+                                           a->os_root);
+                               }
                        } else if (strcmp(subpartition_get_mountpoint(sp), "/boot") == 0) {
                                command_add(cmds, "%s%s '/dev/%s\t\t%s\t\tufs\trw\t\t1\t1' >>%smnt/etc/fstab",
                                    a->os_root, cmd_name(a, "ECHO"),
@@ -621,6 +679,29 @@ fn_install_os(struct i_fn_args *a)
            a->os_root, cmd_name(a, "RM"),
            a->os_root);
 
+       /* Do some preparation if encrypted partitions were configured */
+       if (needcrypt) {
+               command_add(cmds,
+                   "%s%s 'dm_load=\"yes\"' >>%smnt/boot/loader.conf",
+                   a->os_root, cmd_name(a, "ECHO"),
+                   a->os_root);
+               if (use_hammer) {
+                       command_add(cmds, "%s%s -b %smnt/boot -t %smnt/tmp",
+                           a->os_root, cmd_name(a, "MKINITRD"),
+                           a->os_root, a->os_root);
+                       command_add(cmds, "%s%s -rf %smnt/tmp/initrd",
+                           a->os_root, cmd_name(a, "RM"), a->os_root);
+                       command_add(cmds,
+                           "%s%s 'initrd.img_load=\"YES\"' >>%smnt/boot/loader.conf",
+                           a->os_root, cmd_name(a, "ECHO"),
+                           a->os_root);
+                       command_add(cmds,
+                           "%s%s 'initrd.img_type=\"md_image\"' >>%smnt/boot/loader.conf",
+                           a->os_root, cmd_name(a, "ECHO"),
+                           a->os_root);
+               }
+       }
+
        /* Customize stuff here */
        if(is_file("%susr/local/bin/after_installation_routines.sh", a->os_root)) {
                command_add(cmds, "%susr/local/bin/after_installation_routines.sh",
index c9a61cd..ab15576 100644 (file)
@@ -72,6 +72,7 @@ static int    check_subpartition_selections(struct dfui_response *, struct i_fn_arg
 static void    save_subpartition_selections(struct dfui_response *, struct i_fn_args *);
 static void    populate_create_subpartitions_form(struct dfui_form *, struct i_fn_args *);
 static int     warn_subpartition_selections(struct i_fn_args *);
+static int     warn_encrypted_boot(struct i_fn_args *);
 static struct dfui_form *make_create_subpartitions_form(struct i_fn_args *);
 static int     show_create_subpartitions_form(struct dfui_form *, struct i_fn_args *);
 
@@ -191,13 +192,38 @@ create_subpartitions(struct i_fn_args *a)
            a->os_root, cmd_name(a, "DISKLABEL64"),
            slice_get_device_name(storage_get_selected_slice(a->s)));
 
+       /*
+        * If encryption was specified, load dm(4).
+        */
+       for (sp = slice_subpartition_first(storage_get_selected_slice(a->s));
+            sp != NULL; sp = subpartition_next(sp)) {
+               if (subpartition_is_encrypted(sp)) {
+                       fn_get_passphrase(a);
+                       break;
+               }
+       }
+
        /*
         * Create filesystems on the newly-created subpartitions.
         */
        for (sp = slice_subpartition_first(storage_get_selected_slice(a->s));
             sp != NULL; sp = subpartition_next(sp)) {
-               if (subpartition_is_swap(sp) || subpartition_is_tmpfsbacked(sp))
+               if (subpartition_is_swap(sp) || subpartition_is_tmpfsbacked(sp)) {
+                       if (subpartition_is_swap(sp) &&
+                           subpartition_is_encrypted(sp)) {
+                               command_add(cmds,
+                                   "%s%s -d /tmp/t1 luksFormat %sdev/%s",
+                                   a->os_root, cmd_name(a, "CRYPTSETUP"),
+                                   a->os_root,
+                                   subpartition_get_device_name(sp));
+                               command_add(cmds,
+                                   "%s%s -d /tmp/t1 luksOpen %sdev/%s swap",
+                                   a->os_root, cmd_name(a, "CRYPTSETUP"),
+                                   a->os_root,
+                                   subpartition_get_device_name(sp));
+                       }
                        continue;
+               }
 
                if (strcmp(subpartition_get_mountpoint(sp), "/boot") == 0) {
                        command_add(cmds, "%s%s %sdev/%s",
@@ -205,10 +231,23 @@ create_subpartitions(struct i_fn_args *a)
                            a->os_root,
                            subpartition_get_device_name(sp));
                } else {
+                       if (subpartition_is_encrypted(sp)) {
+                               command_add(cmds,
+                                   "%s%s -d /tmp/t1 luksFormat %sdev/%s",
+                                   a->os_root, cmd_name(a, "CRYPTSETUP"),
+                                   a->os_root,
+                                   subpartition_get_device_name(sp));
+                               command_add(cmds,
+                                   "%s%s -d /tmp/t1 luksOpen %sdev/%s root",
+                                   a->os_root, cmd_name(a, "CRYPTSETUP"),
+                                   a->os_root,
+                                   subpartition_get_device_name(sp));
+                       }
                        command_add(cmds, "%s%s -f -L ROOT %sdev/%s",
                            a->os_root, cmd_name(a, "NEWFS_HAMMER"),
                            a->os_root,
-                           subpartition_get_device_name(sp));
+                           subpartition_is_encrypted(sp) ?
+                           "mapper/root" : subpartition_get_device_name(sp));
                }
        }
 
@@ -445,7 +484,8 @@ save_subpartition_selections(struct dfui_response *r, struct i_fn_args *a)
 
                if (string_to_capacity(capstring, &capacity)) {
                        subpartition_new_hammer(storage_get_selected_slice(a->s),
-                            mountpoint, capacity);
+                           mountpoint, capacity,
+                           strcasecmp(dfui_dataset_get_value(ds, "encrypted"), "Y") == 0);
                }
        }
 }
@@ -470,6 +510,8 @@ populate_create_subpartitions_form(struct dfui_form *f, struct i_fn_args *a)
                            subpartition_get_mountpoint(sp));
                        dfui_dataset_celldata_add(ds, "capacity",
                            capacity_to_string(subpartition_get_capacity(sp)));
+                       dfui_dataset_celldata_add(ds, "encrypted",
+                           subpartition_is_encrypted(sp) ? "Y" : "N");
                        dfui_form_dataset_add(f, ds);
                }
        } else {
@@ -486,6 +528,7 @@ populate_create_subpartitions_form(struct dfui_form *f, struct i_fn_args *a)
                            def_mountpt[i]);
                        dfui_dataset_celldata_add(ds, "capacity",
                            capacity_to_string(capacity));
+                       dfui_dataset_celldata_add(ds, "encrypted", "N");
                        dfui_form_dataset_add(f, ds);
                }
        }
@@ -515,6 +558,36 @@ warn_subpartition_selections(struct i_fn_args *a)
        return(!valid);
 }
 
+static int
+warn_encrypted_boot(struct i_fn_args *a)
+{
+       int valid = 1;
+
+       struct subpartition *sp;
+
+       sp = subpartition_find(storage_get_selected_slice(a->s), "/boot");
+       if (sp == NULL)
+               return(!valid);
+
+       if (subpartition_is_encrypted(sp)) {
+               switch (dfui_be_present_dialog(a->c, _("/boot cannot be encrypted"),
+                   _("Leave /boot unencrypted|Return to Create Subpartitions"),
+                   _("You have selected encryption for the /boot partition which "
+                   "is not supported."))) {
+               case 1:
+                       valid = 1;
+                       break;
+               case 2:
+                       valid = 0;
+                       break;
+               default:
+                       abort_backend();
+               }
+       }
+
+       return(!valid);
+}
+
 static struct dfui_form *
 make_create_subpartitions_form(struct i_fn_args *a)
 {
@@ -550,6 +623,9 @@ make_create_subpartitions_form(struct i_fn_args *a)
            "f", "mountpoint", _("Mountpoint"), "", "",
            "f", "capacity", _("Capacity"), "", "",
 
+           "f", "encrypted", _("Encrypted"), "", "",
+           "p", "control", "checkbox",
+
            "a", "ok", _("Accept and Create"), "", "",
            "a", "cancel",
            (disk_get_formatted(storage_get_selected_disk(a->s)) ?
@@ -624,7 +700,8 @@ show_create_subpartitions_form(struct dfui_form *f, struct i_fn_args *a)
                } else {
                        if (check_subpartition_selections(r, a)) {
                                save_subpartition_selections(r, a);
-                               if (!warn_subpartition_selections(a)) {
+                               if (!warn_subpartition_selections(a) &&
+                                   !warn_encrypted_boot(a)) {
                                        if (!create_subpartitions(a)) {
                                                inform(a->c, _("The subpartitions you chose were "
                                                        "not correctly created, and the "
index ea1ca4a..d5407c3 100644 (file)
@@ -73,6 +73,7 @@ static int    check_subpartition_selections(struct dfui_response *, struct i_fn_arg
 static void    save_subpartition_selections(struct dfui_response *, struct i_fn_args *);
 static void    populate_create_subpartitions_form(struct dfui_form *, struct i_fn_args *);
 static int     warn_subpartition_selections(struct i_fn_args *);
+static int     warn_encrypted_root(struct i_fn_args *);
 static struct dfui_form *make_create_subpartitions_form(struct i_fn_args *);
 static int     show_create_subpartitions_form(struct dfui_form *, struct i_fn_args *);
 
@@ -187,21 +188,68 @@ create_subpartitions(struct i_fn_args *a)
            a->os_root, cmd_name(a, "DISKLABEL64"),
            slice_get_device_name(storage_get_selected_slice(a->s)));
 
+       /*
+        * If encryption was specified, load dm(4).
+        */
+       for (sp = slice_subpartition_first(storage_get_selected_slice(a->s));
+            sp != NULL; sp = subpartition_next(sp)) {
+               if (subpartition_is_encrypted(sp)) {
+                       fn_get_passphrase(a);
+                       break;
+               }
+       }
+
        /*
         * Create filesystems on the newly-created subpartitions.
         */
        for (sp = slice_subpartition_first(storage_get_selected_slice(a->s));
             sp != NULL; sp = subpartition_next(sp)) {
-               if (subpartition_is_swap(sp) || subpartition_is_tmpfsbacked(sp))
+               if (subpartition_is_swap(sp) || subpartition_is_tmpfsbacked(sp)) {
+                       if (subpartition_is_swap(sp) &&
+                           subpartition_is_encrypted(sp)) {
+                               command_add(cmds,
+                                   "%s%s -d /tmp/t1 luksFormat %sdev/%s",
+                                   a->os_root, cmd_name(a, "CRYPTSETUP"),
+                                   a->os_root,
+                                   subpartition_get_device_name(sp));
+                               command_add(cmds,
+                                   "%s%s -d /tmp/t1 luksOpen %sdev/%s swap",
+                                   a->os_root, cmd_name(a, "CRYPTSETUP"),
+                                   a->os_root,
+                                   subpartition_get_device_name(sp));
+                       }
                        continue;
+               }
 
-               command_add(cmds, "%s%s%s -b %ld -f %ld %sdev/%s",
-                   a->os_root, cmd_name(a, "NEWFS"),
-                   subpartition_is_softupdated(sp) ? " -U" : "",
-                   subpartition_get_bsize(sp),
-                   subpartition_get_fsize(sp),
-                   a->os_root,
-                   subpartition_get_device_name(sp));
+               if (subpartition_is_encrypted(sp) &&
+                   strcmp(subpartition_get_mountpoint(sp), "/") != 0) {
+                       command_add(cmds,
+                           "%s%s -d /tmp/t1 luksFormat %sdev/%s",
+                           a->os_root, cmd_name(a, "CRYPTSETUP"),
+                           a->os_root,
+                           subpartition_get_device_name(sp));
+                       command_add(cmds,
+                           "%s%s -d /tmp/t1 luksOpen %sdev/%s %s",
+                           a->os_root, cmd_name(a, "CRYPTSETUP"),
+                           a->os_root,
+                           subpartition_get_device_name(sp),
+                           subpartition_get_mountpoint(sp) + 1);
+                       command_add(cmds, "%s%s%s -b %ld -f %ld %sdev/mapper/%s",
+                           a->os_root, cmd_name(a, "NEWFS"),
+                           subpartition_is_softupdated(sp) ? " -U" : "",
+                           subpartition_get_bsize(sp),
+                           subpartition_get_fsize(sp),
+                           a->os_root,
+                           subpartition_get_mountpoint(sp) + 1);
+               } else {
+                       command_add(cmds, "%s%s%s -b %ld -f %ld %sdev/%s",
+                           a->os_root, cmd_name(a, "NEWFS"),
+                           subpartition_is_softupdated(sp) ? " -U" : "",
+                           subpartition_get_bsize(sp),
+                           subpartition_get_fsize(sp),
+                           a->os_root,
+                           subpartition_get_device_name(sp));
+               }
        }
 
        result = commands_execute(a, cmds);
@@ -462,7 +510,9 @@ save_subpartition_selections(struct dfui_response *r, struct i_fn_args *a)
                }
 
                if (string_to_capacity(capstring, &capacity)) {
-                       subpartition_new(storage_get_selected_slice(a->s), mountpoint, capacity,
+                       subpartition_new_ufs(storage_get_selected_slice(a->s),
+                           mountpoint, capacity,
+                           strcasecmp(dfui_dataset_get_value(ds, "encrypted"), "Y") == 0,
                            softupdates, fsize, bsize, tmpfsbacked);
                }
        }
@@ -489,6 +539,8 @@ populate_create_subpartitions_form(struct dfui_form *f, struct i_fn_args *a)
                            subpartition_get_mountpoint(sp));
                        dfui_dataset_celldata_add(ds, "capacity",
                            capacity_to_string(subpartition_get_capacity(sp)));
+                       dfui_dataset_celldata_add(ds, "encrypted",
+                           subpartition_is_encrypted(sp) ? "Y" : "N");
                        if (expert) {
                                dfui_dataset_celldata_add(ds, "softupdates",
                                    subpartition_is_softupdated(sp) ? "Y" : "N");
@@ -517,6 +569,7 @@ populate_create_subpartitions_form(struct dfui_form *f, struct i_fn_args *a)
                            def_mountpt[mtpt]);
                        dfui_dataset_celldata_add(ds, "capacity",
                            capacity_to_string(capacity));
+                       dfui_dataset_celldata_add(ds, "encrypted", "N");
                        if (expert) {
                                dfui_dataset_celldata_add(ds, "softupdates",
                                    strcmp(def_mountpt[mtpt], "/") != 0 ? "Y" : "N");
@@ -585,6 +638,35 @@ warn_subpartition_selections(struct i_fn_args *a)
        return(!valid);
 }
 
+static int
+warn_encrypted_root(struct i_fn_args *a)
+{
+       int valid = 1;
+       struct subpartition *sp;
+
+       sp = subpartition_find(storage_get_selected_slice(a->s), "/");
+       if (sp == NULL)
+               return(!valid);
+
+       if (subpartition_is_encrypted(sp)) {
+               switch (dfui_be_present_dialog(a->c, _("root cannot be encrypted"),
+                   _("Leave root unencrypted|Return to Create Subpartitions"),
+                   _("You have selected encryption for the root partition which "
+                   "is not supported."))) {
+               case 1:
+                       valid = 1;
+                       break;
+               case 2:
+                       valid = 0;
+                       break;
+               default:
+                       abort_backend();
+               }
+       }
+
+       return(!valid);
+}
+
 static struct dfui_form *
 make_create_subpartitions_form(struct i_fn_args *a)
 {
@@ -620,6 +702,9 @@ make_create_subpartitions_form(struct i_fn_args *a)
            "f", "mountpoint", _("Mountpoint"), "", "",
            "f", "capacity", _("Capacity"), "", "",
 
+           "f", "encrypted", _("Encrypted"), "", "",
+           "p", "control", "checkbox",
+
            "a", "ok", _("Accept and Create"), "", "",
            "a", "cancel",
            (disk_get_formatted(storage_get_selected_disk(a->s)) ?
@@ -690,7 +775,8 @@ show_create_subpartitions_form(struct dfui_form *f, struct i_fn_args *a)
                } else {
                        if (check_subpartition_selections(r, a)) {
                                save_subpartition_selections(r, a);
-                               if (!warn_subpartition_selections(a)) {
+                               if (!warn_subpartition_selections(a) &&
+                                   !warn_encrypted_root(a)) {
                                        if (!create_subpartitions(a)) {
                                                inform(a->c, _("The subpartitions you chose were "
                                                        "not correctly created, and the "
index 93db553..74a8eb5 100644 (file)
@@ -505,7 +505,8 @@ slices_free(struct slice *head)
 }
 
 struct subpartition *
-subpartition_new_hammer(struct slice *s, const char *mountpoint, long capacity)
+subpartition_new_hammer(struct slice *s, const char *mountpoint, long capacity,
+    int encrypted)
 {
        struct subpartition *sp;
 
@@ -524,6 +525,7 @@ subpartition_new_hammer(struct slice *s, const char *mountpoint, long capacity)
 
        sp->mountpoint = aura_strdup(mountpoint);
        sp->capacity = capacity;
+       sp->encrypted = encrypted;
        sp->type = FS_HAMMER;
 
        /*
@@ -566,8 +568,8 @@ subpartition_new_hammer(struct slice *s, const char *mountpoint, long capacity)
  * "choose a reasonable default."
  */
 struct subpartition *
-subpartition_new(struct slice *s, const char *mountpoint, long capacity,
-                int softupdates, long fsize, long bsize, int tmpfsbacked)
+subpartition_new_ufs(struct slice *s, const char *mountpoint, long capacity,
+    int encrypted, int softupdates, long fsize, long bsize, int tmpfsbacked)
 {
        struct subpartition *sp, *sptmp;
        int letter='d';
@@ -578,6 +580,7 @@ subpartition_new(struct slice *s, const char *mountpoint, long capacity,
 
        sp->mountpoint = aura_strdup(mountpoint);
        sp->capacity = capacity;
+       sp->encrypted = encrypted;
        sp->type = FS_UFS;
 
        if (fsize == -1) {
@@ -789,6 +792,12 @@ subpartition_get_capacity(const struct subpartition *sp)
        return(sp->capacity);
 }
 
+int
+subpartition_is_encrypted(const struct subpartition *sp)
+{
+       return(sp->encrypted);
+}
+
 int
 subpartition_is_swap(const struct subpartition *sp)
 {
index b88ead5..67f6109 100644 (file)
@@ -101,6 +101,7 @@ struct subpartition {
        char letter;                    /* 'a' = root partition */
        char *mountpoint;               /* includes leading slash */
        long capacity;                  /* in megabytes, -1 = "rest of disk" */
+       int encrypted;
        int softupdates;
        long fsize;                     /* fragment size */
        long bsize;                     /* block size */
@@ -157,9 +158,10 @@ int                         slice_get_flags(const struct slice *);
 void                    slices_free(struct slice *);
 struct subpartition    *slice_subpartition_first(const struct slice *);
 
-struct subpartition    *subpartition_new(struct slice *, const char *, long,
-                                         int, long, long, int);
-struct subpartition    *subpartition_new_hammer(struct slice *, const char *, long);
+struct subpartition    *subpartition_new_hammer(struct slice *, const char *,
+                                                long, int);
+struct subpartition    *subpartition_new_ufs(struct slice *, const char *,
+                                             long, int, int, long, long, int);
 int                     subpartition_count(const struct slice *);
 struct subpartition    *subpartition_find(const struct slice *, const char *, ...)
                             __printflike(2, 3);
@@ -175,6 +177,7 @@ char                         subpartition_get_letter(const struct subpartition *);
 unsigned long           subpartition_get_fsize(const struct subpartition *);
 unsigned long           subpartition_get_bsize(const struct subpartition *);
 long                    subpartition_get_capacity(const struct subpartition *);
+int                     subpartition_is_encrypted(const struct subpartition *);
 int                     subpartition_is_swap(const struct subpartition *);
 int                     subpartition_is_softupdated(const struct subpartition *);
 int                     subpartition_is_tmpfsbacked(const struct subpartition *);