Add support for GPG signature enforcement on booted
[petitboot] / ui / ncurses / nc-boot-editor.c
index 4012ec5a7658dfdc8f429e00130307ed7692ec44..7fa1a42f0eddfbc07794b9f003c4dbfd330dfac6 100644 (file)
@@ -63,6 +63,8 @@ struct boot_editor {
                struct nc_widget_textbox        *dtb_f;
                struct nc_widget_label          *args_l;
                struct nc_widget_textbox        *args_f;
+               struct nc_widget_label          *args_sig_file_l;
+               struct nc_widget_textbox        *args_sig_file_f;
                struct nc_widget_button         *ok_b;
                struct nc_widget_button         *help_b;
                struct nc_widget_button         *cancel_b;
@@ -73,6 +75,9 @@ struct boot_editor {
        char                    *initrd;
        char                    *dtb;
        char                    *args;
+       char                    *args_sig_file;
+
+       bool                    use_signature_files;
 };
 
 extern const struct help_text boot_editor_help_text;
@@ -198,6 +203,15 @@ static struct pb_boot_data *boot_editor_prepare_data(
        s = widget_textbox_get_value(boot_editor->widgets.args_f);
        bd->args = *s ? talloc_strdup(bd, s) : NULL;
 
+       if (boot_editor->use_signature_files) {
+               s = widget_textbox_get_value(
+                       boot_editor->widgets.args_sig_file_f);
+               bd->args_sig_file = conditional_prefix(bd, prefix, s);
+       }
+       else {
+               bd->args_sig_file = NULL;
+       }
+
        return bd;
 }
 
@@ -323,6 +337,12 @@ static void boot_editor_layout_widgets(struct boot_editor *boot_editor)
        y += layout_pair(boot_editor, y, boot_editor->widgets.args_l,
                                         boot_editor->widgets.args_f);
 
+       if (boot_editor->use_signature_files) {
+               y += layout_pair(boot_editor, y,
+                                       boot_editor->widgets.args_sig_file_l,
+                                       boot_editor->widgets.args_sig_file_f);
+       }
+
 
        y++;
        widget_move(widget_button_base(boot_editor->widgets.ok_b), y,
@@ -445,6 +465,11 @@ static void boot_editor_find_device(struct boot_editor *boot_editor,
        if (bd->dtb && !path_on_device(bd_info, bd->dtb))
                return;
 
+       if (boot_editor->use_signature_files)
+               if (bd->args_sig_file && !path_on_device(bd_info,
+                       bd->args_sig_file))
+                       return;
+
        /* ok, we match; preselect the device option, and remove the common
         * prefix */
        boot_editor->selected_device = bd_info->name;
@@ -454,6 +479,9 @@ static void boot_editor_find_device(struct boot_editor *boot_editor,
                boot_editor->initrd += len;
        if (boot_editor->dtb)
                boot_editor->dtb += len;
+       if (boot_editor->use_signature_files)
+               if (boot_editor->args_sig_file)
+                       boot_editor->args_sig_file += len;
 }
 
 static void boot_editor_setup_widgets(struct boot_editor *boot_editor,
@@ -501,6 +529,17 @@ static void boot_editor_setup_widgets(struct boot_editor *boot_editor,
        boot_editor->widgets.args_f = widget_new_textbox(set, 0, 0,
                                        field_size, boot_editor->args);
 
+       if (boot_editor->use_signature_files) {
+               boot_editor->widgets.args_sig_file_l = widget_new_label(set,
+                               0, 0, _("Argument signature file:"));
+               boot_editor->widgets.args_sig_file_f = widget_new_textbox(set,
+                               0, 0, field_size, boot_editor->args_sig_file);
+       }
+       else {
+               boot_editor->widgets.args_sig_file_l = NULL;
+               boot_editor->widgets.args_sig_file_f = NULL;
+       }
+
        boot_editor->widgets.ok_b = widget_new_button(set, 0, 0, 10,
                                        _("OK"), ok_click, boot_editor);
        boot_editor->widgets.help_b = widget_new_button(set, 0, 0, 10,
@@ -547,12 +586,22 @@ struct boot_editor *boot_editor_init(struct cui *cui,
                                struct pb_boot_data *bd))
 {
        struct boot_editor *boot_editor;
+       int ncols1, ncols2, ncols3;
 
        boot_editor = talloc_zero(cui, struct boot_editor);
 
        if (!boot_editor)
                return NULL;
 
+#if defined(HAVE_LIBGPGME)
+       if (access(LOCKDOWN_FILE, F_OK) == -1)
+               boot_editor->use_signature_files = false;
+       else
+               boot_editor->use_signature_files = true;
+#else
+       boot_editor->use_signature_files = false;
+#endif
+
        talloc_set_destructor(boot_editor, boot_editor_destructor);
        boot_editor->cui = cui;
        boot_editor->item = item;
@@ -561,11 +610,15 @@ struct boot_editor *boot_editor_init(struct cui *cui,
        boot_editor->need_redraw = false;
        boot_editor->need_update = false;
 
-       int ncols1 = strncols(_("Device tree:"));
-       int ncols2 = strncols(_("Boot arguments:"));
+       ncols1 = strncols(_("Device tree:"));
+       ncols2 = strncols(_("Boot arguments:"));
+       if (boot_editor->use_signature_files)
+               ncols3 = strncols(_("Argument signature file:"));
+       else
+               ncols3 = 0;
 
        boot_editor->label_x = 1;
-       boot_editor->field_x = 2 + max(ncols1, ncols2);
+       boot_editor->field_x = 2 + max(max(ncols1, ncols2), ncols3);
 
        nc_scr_init(&boot_editor->scr, pb_boot_editor_sig, 0,
                        cui, boot_editor_process_key,
@@ -584,10 +637,15 @@ struct boot_editor *boot_editor_init(struct cui *cui,
                boot_editor->initrd = bd->initrd;
                boot_editor->dtb = bd->dtb;
                boot_editor->args = bd->args;
+               if (boot_editor->use_signature_files)
+                       boot_editor->args_sig_file = bd->args_sig_file;
+               else
+                       boot_editor->args_sig_file = talloc_strdup(bd, "");
                boot_editor_find_device(boot_editor, bd, sysinfo);
        } else {
                boot_editor->image = boot_editor->initrd =
-                       boot_editor->dtb = boot_editor->args = "";
+                       boot_editor->dtb = boot_editor->args =
+                       boot_editor->args_sig_file = "";
        }
 
        boot_editor->pad = newpad(