/* Add KEY to list of signers in CTX. */ gpgme_error_t gpgme_signers_add (gpgme_ctx_t ctx, const gpgme_key_t key) { TRACE_BEG2 (DEBUG_CTX, "gpgme_signers_add", ctx, "key=%p (%s)", key, (key->subkeys && key->subkeys->fpr) ? key->subkeys->fpr : "invalid"); if (!ctx || !key) return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); if (ctx->signers_len == ctx->signers_size) { gpgme_key_t *newarr; int n = ctx->signers_size + 5; int j; newarr = realloc (ctx->signers, n * sizeof (*newarr)); if (!newarr) return TRACE_ERR (gpg_error_from_errno (errno)); for (j = ctx->signers_size; j < n; j++) newarr[j] = NULL; ctx->signers = newarr; ctx->signers_size = n; } gpgme_key_ref (key); ctx->signers[ctx->signers_len++] = key; return TRACE_SUC (); }
static void next_key_cb (GpaContext *context, gpgme_key_t key, GpaKeyTable *keytable) { keytable->tmp_list = g_list_prepend (keytable->tmp_list, key); gpgme_key_ref (key); if (keytable->next) { keytable->next (key, keytable->data); } }
static void select_btn_cb (GtkWidget *widget, gpointer data) { struct select_keys_s *sk = data; int row; gboolean use_key; gpgme_key_t key; cm_return_if_fail (sk); if (!sk->clist->selection) { debug_print ("** nothing selected"); return; } row = GPOINTER_TO_INT(sk->clist->selection->data); key = gtk_cmclist_get_row_data(sk->clist, row); if (key) { gpgme_user_id_t uid; for (uid = key->uids; uid; uid = uid->next) { gchar *raw_mail = NULL; if (!uid->email) continue; raw_mail = g_strdup(uid->email); extract_address(raw_mail); if (sk->pattern && !strcasecmp(sk->pattern, raw_mail)) { g_free(raw_mail); break; } g_free(raw_mail); } if (!uid) uid = key->uids; if ( uid->validity < GPGME_VALIDITY_FULL ) { use_key = use_untrusted(key, uid, sk->proto); if (!use_key) { debug_print ("** Key untrusted, will not encrypt"); return; } } sk->kset = g_realloc(sk->kset, sizeof(gpgme_key_t) * (sk->num_keys + 1)); gpgme_key_ref(key); sk->kset[sk->num_keys] = key; sk->num_keys++; sk->okay = 1; sk->result = KEY_SELECTION_OK; gtk_main_quit (); } }
/** * gpgmegtk_recipient_selection: * @recp_names: A list of email addresses * * Select a list of recipients from a given list of email addresses. * This may pop up a window to present the user a choice, it will also * check that the recipients key are all valid. * * Return value: NULL on error or a list of list of recipients. **/ gpgme_key_t * gpgmegtk_recipient_selection (GSList *recp_names, SelectionResult *result, gpgme_protocol_t proto) { struct select_keys_s sk; gpgme_key_t key = NULL; memset (&sk, 0, sizeof sk); open_dialog (&sk); do { sk.pattern = recp_names? recp_names->data:NULL; sk.proto = proto; gtk_cmclist_clear (sk.clist); key = fill_clist (&sk, sk.pattern, proto); update_progress (&sk, 0, sk.pattern ? sk.pattern : "NULL"); if (!key) { gtk_widget_show_all (sk.window); gtk_main (); } else { gtk_widget_hide (sk.window); sk.kset = g_realloc(sk.kset, sizeof(gpgme_key_t) * (sk.num_keys + 1)); gpgme_key_ref(key); sk.kset[sk.num_keys] = key; sk.num_keys++; sk.okay = 1; sk.result = KEY_SELECTION_OK; gpgme_release (sk.select_ctx); sk.select_ctx = NULL; debug_print("used %s\n", key->uids->email); } key = NULL; if (recp_names) recp_names = recp_names->next; } while (sk.okay && recp_names); close_dialog (&sk); if (!sk.okay) { g_free(sk.kset); sk.kset = NULL; } else { sk.kset = g_realloc(sk.kset, sizeof(gpgme_key_t) * (sk.num_keys + 1)); sk.kset[sk.num_keys] = NULL; } if (result) *result = sk.result; return sk.kset; }
/* Default key section. */ static void key_selected_cb (SettingsDlg *dialog) { GList *selected; selected = gpa_key_selector_get_selected_keys (dialog->default_key.list); gpgme_key_unref (dialog->default_key.key); dialog->default_key.key = selected? selected->data : NULL; if (dialog->default_key.key) gpgme_key_ref (dialog->default_key.key); g_list_free (selected); update_modified (dialog, 1); }
/* Return the SEQth signer's key in CTX with one reference. */ gpgme_key_t gpgme_signers_enum (const gpgme_ctx_t ctx, int seq) { unsigned int seqno; if (!ctx || seq < 0) return NULL; seqno = (unsigned int) seq; if (seqno >= ctx->signers_len) return NULL; gpgme_key_ref (ctx->signers[seqno]); return ctx->signers[seqno]; }
/** * keys: (GList) * * Creates a gpgme_key_t array out of the keylist. * */ static gpgme_key_t* keylist_to_keys (GList *keys) { gpgme_key_t *recips; int i; recips = g_new0 (gpgme_key_t, g_list_length (keys) + 1); for (i = 0; keys != NULL; keys = g_list_next (keys), i++) { g_return_val_if_fail (SEAHORSE_IS_GPGME_KEY (keys->data), recips); recips[i] = seahorse_gpgme_key_get_public (keys->data); gpgme_key_ref (recips[i]); } return recips; }
static void seahorse_gpgme_subkey_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { SeahorseGpgmeSubkey *self = SEAHORSE_GPGME_SUBKEY (object); switch (prop_id) { case PROP_PUBKEY: g_return_if_fail (!self->pv->pubkey); self->pv->pubkey = g_value_get_boxed (value); if (self->pv->pubkey) gpgme_key_ref (self->pv->pubkey); break; case PROP_SUBKEY: seahorse_gpgme_subkey_set_subkey (self, g_value_get_pointer (value)); break; } }
static void list_cache (GpaKeyTable *keytable) { GList *list = keytable->keys; for (; list; list = g_list_next (list)) { gpgme_key_t key = (gpgme_key_t) list->data; gpgme_key_ref (key); if (keytable->next) { keytable->next (key, keytable->data); } } if (keytable->end) { keytable->end (keytable->data); } }
static void gpa_backup_operation_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { GpaBackupOperation *op = GPA_BACKUP_OPERATION (object); gchar *fpr; gpgme_key_t key; switch (prop_id) { case PROP_KEY: key = (gpgme_key_t) g_value_get_pointer (value); if (key) { op->key = key; gpgme_key_ref (op->key); op->fpr = g_strdup (op->key->subkeys->fpr); op->key_id = g_strdup (gpa_gpgme_key_get_short_keyid (op->key)); } break; case PROP_FINGERPRINT: fpr = (gchar*) g_value_get_pointer (value); if (fpr) { op->key = NULL; op->fpr = g_strdup (fpr); op->key_id = g_strdup (fpr + strlen (fpr) - 8); } break; case PROP_PROTOCOL: op->protocol = g_value_get_int (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void seahorse_gpgme_uid_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { SeahorseGpgmeUid *self = SEAHORSE_GPGME_UID (object); gpgme_key_t pubkey; switch (prop_id) { case PROP_PUBKEY: pubkey = g_value_get_boxed (value); g_return_if_fail (pubkey); if (pubkey != self->pv->pubkey) { if (self->pv->pubkey) { /* Should always be set to the same actual key */ g_return_if_fail (compare_pubkeys (pubkey, self->pv->pubkey)); gpgme_key_unref (self->pv->pubkey); } self->pv->pubkey = g_value_get_boxed (value); if (self->pv->pubkey) gpgme_key_ref (self->pv->pubkey); /* This is expected to be set shortly along with pubkey */ self->pv->userid = NULL; } break; case PROP_ACTUAL_INDEX: seahorse_gpgme_uid_set_actual_index (self, g_value_get_uint (value)); break; case PROP_USERID: seahorse_gpgme_uid_set_userid (self, g_value_get_pointer (value)); break; } }
static gpgme_key_t get_key_from_name(gpgme_ctx_t ctx, const gchar * name, gboolean secret, gboolean accept_all, GtkWindow * parent, GError ** error) { GList *keys = NULL; gpgme_key_t key; gpgme_error_t err; gboolean found_bad; time_t now = time(NULL); /* let gpgme list keys */ if ((err = gpgme_op_keylist_start(ctx, name, secret)) != GPG_ERR_NO_ERROR) { gchar *msg = g_strdup_printf(_("could not list keys for \"%s\""), name); g_set_error_from_gpgme(error, err, msg); g_free(msg); return NULL; } found_bad = FALSE; while ((err = gpgme_op_keylist_next(ctx, &key)) == GPG_ERR_NO_ERROR) { /* check if this key and the relevant subkey are usable */ if (KEY_IS_OK(key)) { gpgme_subkey_t subkey = key->subkeys; while (subkey && ((secret && !subkey->can_sign) || (!secret && !subkey->can_encrypt))) subkey = subkey->next; if (subkey && KEY_IS_OK(subkey) && (subkey->expires == 0 || subkey->expires > now)) keys = g_list_append(keys, key); else found_bad = TRUE; } else found_bad = TRUE; } if (gpg_err_code(err) != GPG_ERR_EOF) { gchar *msg = g_strdup_printf(_("could not list keys for \"%s\""), name); g_set_error_from_gpgme(error, err, msg); g_free(msg); gpgme_op_keylist_end(ctx); g_list_foreach(keys, (GFunc) gpgme_key_unref, NULL); g_list_free(keys); return NULL; } gpgme_op_keylist_end(ctx); if (!keys) { if (error) { if (strchr(name, '@')) { if (found_bad) g_set_error(error, GPGME_ERROR_QUARK, GPG_ERR_KEY_SELECTION, _ ("%s: a key for %s is present, but it is expired, disabled, revoked or invalid"), "gmime-gpgme", name); else g_set_error(error, GPGME_ERROR_QUARK, GPG_ERR_KEY_SELECTION, _("%s: could not find a key for %s"), "gmime-gpgme", name); } else { if (found_bad) g_set_error(error, GPGME_ERROR_QUARK, GPG_ERR_KEY_SELECTION, _ ("%s: a key with id %s is present, but it is expired, disabled, revoked or invalid"), "gmime-gpgme", name); else g_set_error(error, GPGME_ERROR_QUARK, GPG_ERR_KEY_SELECTION, _("%s: could not find a key with id %s"), "gmime-gpgme", name); } } return NULL; } /* let the user select a key from the list if there is more than one */ if (g_list_length(keys) > 1) { if (select_key_cb) key = select_key_cb(name, secret, keys, gpgme_get_protocol(ctx), parent); else { if (error) g_set_error(error, GPGME_ERROR_QUARK, GPG_ERR_KEY_SELECTION, _("%s: multiple keys for %s"), "gmime-gpgme", name); key = NULL; } if (key) gpgme_key_ref(key); g_list_foreach(keys, (GFunc) gpgme_key_unref, NULL); } else key = (gpgme_key_t) keys->data; g_list_free(keys); /* OpenPGP: ask the user if a low-validity key should be trusted for * encryption */ // FIXME - shouldn't we do the same for S/MIME? if (key && !secret && !accept_all && gpgme_get_protocol(ctx) == GPGME_PROTOCOL_OpenPGP) { gpgme_user_id_t uid = key->uids; gchar *upcase_name = g_ascii_strup(name, -1); gboolean found = FALSE; while (!found && uid) { /* check the email field which may or may not be present */ if (uid->email && !g_ascii_strcasecmp(uid->email, name)) found = TRUE; else { /* no email or no match, check the uid */ gchar *upcase_uid = g_ascii_strup(uid->uid, -1); if (strstr(upcase_uid, upcase_name)) found = TRUE; else uid = uid->next; g_free(upcase_uid); } } g_free(upcase_name); /* ask the user if a low-validity key shall be used */ if (uid && uid->validity < GPGME_VALIDITY_FULL) { if (!accept_low_trust_cb || !accept_low_trust_cb(name, uid, parent)) { gpgme_key_unref(key); key = NULL; if (error) g_set_error(error, GPGME_ERROR_QUARK, GPG_ERR_KEY_SELECTION, _("%s: insufficient validity for uid %s"), "gmime-gpgme", name); } } } return key; }
/** * ref_return_key: * @key: the gpgme key * * Acquires an additional gpgme reference for the key * * Returns: the key */ static gpgme_key_t ref_return_key (gpgme_key_t key) { gpgme_key_ref (key); return key; }
/* Return an array of gpgme key objects derived from thye list of strings in RECPIENTS. */ static gpg_error_t prepare_recipient_keys (gpgme_key_t **r_keys, char **recipients, HWND hwnd) { gpg_error_t err; gpgme_key_t *keys = NULL; char **unknown = NULL; size_t n_keys, n_unknown, n_recp; int i; *r_keys = NULL; if (op_lookup_keys (recipients, &keys, &unknown)) { log_debug ("%s:%s: leave (lookup keys failed)\n", SRCNAME, __func__); return gpg_error (GPG_ERR_GENERAL); } n_recp = count_strings (recipients); n_keys = count_keys (keys); n_unknown = count_strings (unknown); log_debug ("%s:%s: found %d recipients, need %d, unknown=%d\n", SRCNAME, __func__, (int)n_keys, (int)n_recp, (int)n_unknown); if (n_keys != n_recp) { unsigned int opts; gpgme_key_t *keys2; log_debug ("%s:%s: calling recipient_dialog_box2", SRCNAME, __func__); opts = recipient_dialog_box2 (keys, unknown, &keys2); release_key_array (keys); keys = keys2; if ( (opts & OPT_FLAG_CANCEL) ) { err = gpg_error (GPG_ERR_CANCELED); goto leave; } } /* If a default key has been set, add it to the list of keys. Check that the key is actually available. */ if (opt.enable_default_key && opt.default_key && *opt.default_key) { gpgme_key_t defkey; defkey = op_get_one_key (opt.default_key); if (!defkey) { MessageBox (hwnd, _("The configured default encryption certificate is not " "available or does not unambigiously specify one. " "Please fix this in the option dialog.\n\n" "This message won't be be encrypted to this certificate!"), _("Encryption"), MB_ICONWARNING|MB_OK); } else { gpgme_key_t *tmpkeys; n_keys = count_keys (keys) + 1; tmpkeys = xcalloc (n_keys+1, sizeof *tmpkeys); for (i = 0; keys[i]; i++) { tmpkeys[i] = keys[i]; gpgme_key_ref (tmpkeys[i]); } tmpkeys[i++] = defkey; tmpkeys[i] = NULL; release_key_array (keys); keys = tmpkeys; } } if (keys) { for (i=0; keys[i]; i++) log_debug ("%s:%s: recp.%d 0x%s %s\n", SRCNAME, __func__, i, keyid_from_key (keys[i]), userid_from_key (keys[i])); } *r_keys = keys; keys = NULL; err = 0; leave: release_key_array (keys); return err; }