gboolean rpmostree_compose_builtin_sign (int argc, char **argv, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; GOptionContext *context = g_option_context_new ("- Use rpm-sign to sign an OSTree commit"); gs_unref_object GFile *repopath = NULL; gs_unref_object OstreeRepo *repo = NULL; gs_unref_object GFile *tmp_commitdata_file = NULL; gs_unref_object GFileIOStream *tmp_sig_stream = NULL; gs_unref_object GFile *tmp_sig_file = NULL; gs_unref_object GFileIOStream *tmp_commitdata_stream = NULL; GOutputStream *tmp_commitdata_output = NULL; gs_unref_object GInputStream *commit_data = NULL; gs_free char *checksum = NULL; gs_unref_variant GVariant *commit_variant = NULL; gs_unref_bytes GBytes *commit_bytes = NULL; if (!rpmostree_option_context_parse (context, option_entries, &argc, &argv, error)) goto out; if (!(opt_repo_path && opt_key_id && opt_rev)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Missing required argument"); goto out; } repopath = g_file_new_for_path (opt_repo_path); repo = ostree_repo_new (repopath); if (!ostree_repo_open (repo, cancellable, error)) goto out; if (!ostree_repo_resolve_rev (repo, opt_rev, FALSE, &checksum, error)) goto out; if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, checksum, &commit_variant, error)) goto out; commit_bytes = g_variant_get_data_as_bytes (commit_variant); commit_data = (GInputStream*)g_memory_input_stream_new_from_bytes (commit_bytes); tmp_commitdata_file = g_file_new_tmp ("tmpsigXXXXXX", &tmp_commitdata_stream, error); if (!tmp_commitdata_file) goto out; tmp_commitdata_output = (GOutputStream*)g_io_stream_get_output_stream ((GIOStream*)tmp_commitdata_stream); if (g_output_stream_splice ((GOutputStream*)tmp_commitdata_output, commit_data, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, cancellable, error) < 0) goto out; tmp_sig_file = g_file_new_tmp ("tmpsigoutXXXXXX", &tmp_sig_stream, error); if (!tmp_sig_file) goto out; (void) g_io_stream_close ((GIOStream*)tmp_sig_stream, NULL, NULL); if (!gs_subprocess_simple_run_sync (NULL, GS_SUBPROCESS_STREAM_DISPOSITION_NULL, cancellable, error, "rpm-sign", "--key", opt_key_id, "--detachsign", gs_file_get_path_cached (tmp_commitdata_file), "--output", gs_file_get_path_cached (tmp_sig_file), NULL)) goto out; { char *sigcontent = NULL; gsize len; gs_unref_bytes GBytes *sigbytes = NULL; if (!g_file_load_contents (tmp_sig_file, cancellable, &sigcontent, &len, NULL, error)) goto out; sigbytes = g_bytes_new_take (sigcontent, len); if (!ostree_repo_append_gpg_signature (repo, checksum, sigbytes, cancellable, error)) goto out; } g_print ("Successfully signed OSTree commit=%s with key=%s\n", checksum, opt_key_id); ret = TRUE; out: if (tmp_commitdata_file) (void) gs_file_unlink (tmp_commitdata_file, NULL, NULL); if (tmp_sig_file) (void) gs_file_unlink (tmp_sig_file, NULL, NULL); return ret; }
int rpmostree_compose_builtin_sign (int argc, char **argv, GCancellable *cancellable, GError **error) { int exit_status = EXIT_FAILURE; GOptionContext *context = g_option_context_new ("- Use rpm-sign to sign an OSTree commit"); g_autoptr(GFile) repopath = NULL; glnx_unref_object OstreeRepo *repo = NULL; g_autoptr(GFile) tmp_commitdata_file = NULL; g_autoptr(GFileIOStream) tmp_sig_stream = NULL; g_autoptr(GFile) tmp_sig_file = NULL; g_autoptr(GFileIOStream) tmp_commitdata_stream = NULL; GOutputStream *tmp_commitdata_output = NULL; g_autoptr(GInputStream) commit_data = NULL; g_autofree char *checksum = NULL; g_autoptr(GVariant) commit_variant = NULL; g_autoptr(GBytes) commit_bytes = NULL; if (!rpmostree_option_context_parse (context, option_entries, &argc, &argv, RPM_OSTREE_BUILTIN_FLAG_LOCAL_CMD, cancellable, NULL, error)) goto out; if (!(opt_repo_path && opt_key_id && opt_rev)) { rpmostree_usage_error (context, "Missing required argument", error); goto out; } repopath = g_file_new_for_path (opt_repo_path); repo = ostree_repo_new (repopath); if (!ostree_repo_open (repo, cancellable, error)) goto out; if (!ostree_repo_resolve_rev (repo, opt_rev, FALSE, &checksum, error)) goto out; if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, checksum, &commit_variant, error)) goto out; commit_bytes = g_variant_get_data_as_bytes (commit_variant); commit_data = (GInputStream*)g_memory_input_stream_new_from_bytes (commit_bytes); tmp_commitdata_file = g_file_new_tmp ("tmpsigXXXXXX", &tmp_commitdata_stream, error); if (!tmp_commitdata_file) goto out; tmp_commitdata_output = (GOutputStream*)g_io_stream_get_output_stream ((GIOStream*)tmp_commitdata_stream); if (g_output_stream_splice ((GOutputStream*)tmp_commitdata_output, commit_data, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, cancellable, error) < 0) goto out; tmp_sig_file = g_file_new_tmp ("tmpsigoutXXXXXX", &tmp_sig_stream, error); if (!tmp_sig_file) goto out; (void) g_io_stream_close ((GIOStream*)tmp_sig_stream, NULL, NULL); { const char *child_argv[] = { "rpm-sign", "--key", opt_key_id, "--detachsign", gs_file_get_path_cached (tmp_commitdata_file), "--output", gs_file_get_path_cached (tmp_sig_file), NULL }; int estatus; if (!g_spawn_sync (NULL, (char**)child_argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, &estatus, error)) goto out; if (!g_spawn_check_exit_status (estatus, error)) goto out; } { char *sigcontent = NULL; gsize len; g_autoptr(GBytes) sigbytes = NULL; if (!g_file_load_contents (tmp_sig_file, cancellable, &sigcontent, &len, NULL, error)) goto out; sigbytes = g_bytes_new_take (sigcontent, len); if (!ostree_repo_append_gpg_signature (repo, checksum, sigbytes, cancellable, error)) goto out; } g_print ("Successfully signed OSTree commit=%s with key=%s\n", checksum, opt_key_id); exit_status = EXIT_SUCCESS; out: if (tmp_commitdata_file) (void) unlink (gs_file_get_path_cached (tmp_commitdata_file)); if (tmp_sig_file) (void) unlink (gs_file_get_path_cached (tmp_sig_file)); return exit_status; }