static gpgme_error_t* _p_gpg_passphrase_cb(void *hook, const char *uid_hint, const char *passphrase_info, int prev_was_bad, int fd) { if (passphrase) { gpgme_io_write(fd, passphrase, strlen(passphrase)); } else { GString *pass_term = g_string_new(""); char *password = ui_ask_pgp_passphrase(uid_hint, prev_was_bad); if (password) { g_string_append(pass_term, password); free(password); } g_string_append(pass_term, "\n"); if (passphrase_attempt) { free(passphrase_attempt); } passphrase_attempt = pass_term->str; g_string_free(pass_term, FALSE); gpgme_io_write(fd, passphrase_attempt, strlen(passphrase_attempt)); } return 0; }
/* The edit callback proper */ static gpg_error_t edit_fnc (void *opaque, gpgme_status_code_t status, const char *args, int fd) { struct edit_parms_s *parms = opaque; char *result = NULL; /* Whitelist all status code we know about. */ switch (status) { case GPGME_STATUS_ALREADY_SIGNED: case GPGME_STATUS_ERROR: case GPGME_STATUS_GET_BOOL: case GPGME_STATUS_GET_LINE: case GPGME_STATUS_KEY_CREATED: case GPGME_STATUS_NEED_PASSPHRASE_SYM: case GPGME_STATUS_SC_OP_FAILURE: break; default: /* We don't know and thus do not need this status code. */ return parms->err; } if (!parms->need_status_passphrase_sym && status == GPGME_STATUS_NEED_PASSPHRASE_SYM) { return parms->err; } else if (status == GPGME_STATUS_SC_OP_FAILURE) { if (args && !parms->err) { gpg_err_code_t ec; switch (strtoul (args, NULL, 10)) { case 1: ec = GPG_ERR_CANCELED; break; case 2: ec = GPG_ERR_BAD_PIN; break; default: ec = GPG_ERR_CARD; break; } if (ec) parms->err = gpg_error (ec); } return parms->err; } /* Call the save_error function. */ if (status == GPGME_STATUS_ERROR && args && parms->save_error) { int n = strcspn (args, " \t"); char *buf = g_strdup_printf ("%.*s: %s", n, args, gpg_strerror (strtoul (args+n, NULL, 10))); parms->save_error (parms->opaque, buf); } if (debug_edit_fsm) g_debug ("edit_fnc: state=%d input=%d (%s)", parms->state, status, args); /* Choose the next state based on the current one and the input */ parms->state = parms->transit (parms->state, status, args, parms->opaque, &parms->err); if (!parms->err) { gpg_error_t err; /* Choose the action based on the state */ err = parms->action (parms->state, parms->opaque, &result); if (debug_edit_fsm) g_debug ("edit_fnc: newstate=%d err=%s result=%s", parms->state, gpg_strerror (err), result); if (err) parms->err = err; /* Send the command, if any was provided */ if (result) { if (*result) gpgme_io_write (fd, result, strlen (result)); gpgme_io_write (fd, "\n", 1); } } else if (parms->err == gpg_error (GPG_ERR_EAGAIN)) { parms->err = 0; if (debug_edit_fsm) g_debug ("edit_fnc: newstate=%d again, default response", parms->state); /* Send an empty line as default response. */ gpgme_io_write (fd, "\n", 1); } else { if (debug_edit_fsm) g_debug ("edit_fnc: newstate=%d err=%s transit failed", parms->state, gpg_strerror (parms->err)); } return parms->err; }