/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* gkr-tool-import.c: Command line key/certificate import Copyright (C) 2008 Stefan Walter The Gnome Keyring Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The Gnome Keyring Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the Gnome Library; see the file COPYING.LIB. If not, . Author: Stef Walter */ #include "config.h" #include "gkr-tool.h" #include #include #include "egg/egg-hex.h" static gchar **import_files = NULL; static GOptionEntry import_entries[] = { GKR_TOOL_BASIC_OPTIONS { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &import_files, "Filename", NULL }, { NULL } }; static void imported_fingerprint (const gchar *fingerprint, const gchar *destination) { g_print ("%s: imported openpgp\n", destination); g_print ("\tfingerprint: %s\n", fingerprint); } static void imported_object (GckObject *object, const gchar *destination) { gulong attr_types[3]; GckAttributes *attrs; const GckAttribute *id; CK_OBJECT_CLASS klass; const gchar *message; GError *err = NULL; gchar *label, *hex; attr_types[0] = CKA_LABEL; attr_types[1] = CKA_CLASS; attr_types[2] = CKA_ID; attrs = gck_object_get_full (object, attr_types, G_N_ELEMENTS (attr_types), NULL, &err); if (attrs == NULL) { gkr_tool_handle_error (&err, "couldn't get imported object info"); return; } if (!gck_attributes_find_string (attrs, CKA_LABEL, &label)) label = g_strdup ("unknown"); if (!gck_attributes_find_ulong (attrs, CKA_CLASS, &klass)) klass = CKO_DATA; id = gck_attributes_find (attrs, CKA_ID); switch (klass) { case CKO_CERTIFICATE: message = "%s: imported certificate: %s\n"; break; case CKO_DATA: message = "%s: imported data: %s\n"; break; case CKO_PRIVATE_KEY: message = "%s: imported private key: %s\n"; break; case CKO_PUBLIC_KEY: message = "%s: imported public key: %s\n"; break; case CKO_SECRET_KEY: message = "%s: imported secret key: %s\n"; break; default: message = "%s: imported object: %s\n"; break; }; g_print (message, destination, label); if (id) { hex = egg_hex_encode (id->value, id->length); g_print ("\tidentifier: %s\n", hex); g_free (hex); } gck_attributes_unref (attrs); g_free (label); } static void imported_display (GcrImporter *importer) { GParamSpec *spec; gchar *label = NULL; spec = g_object_class_find_property (G_OBJECT_GET_CLASS (importer), "imported"); if (spec == NULL) return; g_object_get (importer, "label", &label, NULL); if (spec->value_type == GCK_TYPE_LIST) { GList *list, *l; g_object_get (importer, "imported", &list, NULL); for (l = list; l != NULL; l = g_list_next (l)) imported_object (l->data, label); gck_list_unref_free (list); } else if (spec->value_type == G_TYPE_STRV) { gchar **fingerprints; guint i; g_object_get (importer, "imported", &fingerprints, NULL); for (i = 0; fingerprints && fingerprints[i] != NULL; i++) imported_fingerprint (fingerprints[i], label); g_strfreev (fingerprints); } } typedef struct { GList *importers; gboolean num_parsed; } ImportClosure; static void on_parser_parsed (GcrParser *parser, gpointer user_data) { ImportClosure *closure = user_data; GcrParsed *parsed; GList *filtered; parsed = gcr_parser_get_parsed (parser); if (closure->num_parsed == 0) { closure->importers = gcr_importer_create_for_parsed (parsed); } else { filtered = gcr_importer_queue_and_filter_for_parsed (closure->importers, parsed); gck_list_unref_free (closure->importers); closure->importers = filtered; } closure->num_parsed++; } int gkr_tool_import (int argc, char *argv[]) { GcrParser *parser; GError *error = NULL; GInputStream *input; ImportClosure *closure; GFile *file; gchar **imp; int ret = 0; GList *l; ret = gkr_tool_parse_options (&argc, &argv, import_entries); if (ret != 0) return ret; if(!import_files || !*import_files) { gkr_tool_handle_error (NULL, "specify files to import"); return 2; } if (!gcr_pkcs11_initialize (NULL, &error)) { gkr_tool_handle_error (&error, "couldn't initialize pkcs11 modules"); return 1; } parser = gcr_parser_new (); closure = g_new0 (ImportClosure, 1); g_signal_connect (parser, "parsed", G_CALLBACK (on_parser_parsed), closure); for (imp = import_files; *imp; ++imp) { file = g_file_new_for_commandline_arg (*imp); input = G_INPUT_STREAM (g_file_read (file, NULL, &error)); g_object_unref (file); if (input == NULL) { gkr_tool_handle_error (&error, "couldn't read file: %s", *imp); ret = 1; } else { if (!gcr_parser_parse_stream (parser, input, NULL, &error)) { if (error->code != GCR_ERROR_CANCELLED) gkr_tool_handle_error (&error, "couldn't parse: %s", *imp); ret = 1; } g_object_unref (input); } } if (closure->importers == NULL) { gkr_tool_handle_error (NULL, "couldn't find any place to import files"); ret = 1; } for (l = closure->importers; l != NULL; l = g_list_next (l)) { if (gcr_importer_import (l->data, NULL, &error)) { if (!gkr_tool_mode_quiet) imported_display (l->data); } else { if (error->code != GCR_ERROR_CANCELLED) gkr_tool_handle_error (&error, "couldn't import"); ret = 1; } } gck_list_unref_free (closure->importers); g_free (closure); g_object_unref (parser); return ret; }