/* Parse an error status line and if SET_STATUS is true update the result status as appropriate. With SET_STATUS being false, only check for an error. */ static gpgme_error_t parse_error(gpgme_signature_t sig, char *args, int set_status) { gpgme_error_t err; char *where = strchr(args, ' '); char *which; if(where) { *where = '\0'; which = where + 1; where = strchr(which, ' '); if(where) *where = '\0'; where = args; } else return gpg_error(GPG_ERR_INV_ENGINE); err = _gpgme_map_gnupg_error(which); if(!strcmp(where, "proc_pkt.plaintext") && gpg_err_code(err) == GPG_ERR_BAD_DATA) { /* This indicates a double plaintext. The only solid way to handle this is by failing the oepration. */ return gpg_error(GPG_ERR_BAD_DATA); } else if(!set_status) ; else if(!strcmp(where, "verify.findkey")) sig->status = err; else if(!strcmp(where, "verify.keyusage") && gpg_err_code(err) == GPG_ERR_WRONG_KEY_USAGE) sig->wrong_key_usage = 1; return 0; }
static gpgme_error_t parse_trust(gpgme_signature_t sig, gpgme_status_code_t code, char *args) { char *end = strchr(args, ' '); if(end) *end = '\0'; switch(code) { case GPGME_STATUS_TRUST_UNDEFINED: default: sig->validity = GPGME_VALIDITY_UNKNOWN; break; case GPGME_STATUS_TRUST_NEVER: sig->validity = GPGME_VALIDITY_NEVER; break; case GPGME_STATUS_TRUST_MARGINAL: sig->validity = GPGME_VALIDITY_MARGINAL; break; case GPGME_STATUS_TRUST_FULLY: case GPGME_STATUS_TRUST_ULTIMATE: sig->validity = GPGME_VALIDITY_FULL; break; } if(*args) sig->validity_reason = _gpgme_map_gnupg_error(args); else sig->validity_reason = 0; return 0; }
gpgme_error_t _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code, char *args) { gpgme_ctx_t ctx = (gpgme_ctx_t) priv; gpgme_error_t err; void *hook; op_data_t opd; err = _gpgme_passphrase_status_handler (priv, code, args); if (err) return err; err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook, -1, NULL); opd = hook; if (err) return err; switch (code) { case GPGME_STATUS_EOF: /* FIXME: These error values should probably be attributed to the underlying crypto engine (as error source). */ if (opd->failed) return gpg_error (GPG_ERR_DECRYPT_FAILED); else if (!opd->okay) return gpg_error (GPG_ERR_NO_DATA); break; case GPGME_STATUS_DECRYPTION_OKAY: opd->okay = 1; break; case GPGME_STATUS_DECRYPTION_FAILED: opd->failed = 1; break; case GPGME_STATUS_ERROR: /* Note that this is an informational status code which should not lead to an error return unless it is something not related to the backend. */ { const char d_alg[] = "decrypt.algorithm"; const char u_alg[] = "Unsupported_Algorithm"; const char k_alg[] = "decrypt.keyusage"; if (!strncmp (args, d_alg, sizeof (d_alg) - 1)) { args += sizeof (d_alg) - 1; while (*args == ' ') args++; if (!strncmp (args, u_alg, sizeof (u_alg) - 1)) { char *end; args += sizeof (u_alg) - 1; while (*args == ' ') args++; end = strchr (args, ' '); if (end) *end = '\0'; if (!(*args == '?' && *(args + 1) == '\0')) { opd->result.unsupported_algorithm = strdup (args); if (!opd->result.unsupported_algorithm) return gpg_error_from_errno (errno); } } } else if (!strncmp (args, k_alg, sizeof (k_alg) - 1)) { args += sizeof (k_alg) - 1; while (*args == ' ') args++; err = _gpgme_map_gnupg_error (args); if (gpg_err_code (err) == GPG_ERR_WRONG_KEY_USAGE) opd->result.wrong_key_usage = 1; } } break; case GPGME_STATUS_ENC_TO: err = parse_enc_to (args, opd->last_recipient_p); if (err) return err; opd->last_recipient_p = &(*opd->last_recipient_p)->next; break; case GPGME_STATUS_NO_SECKEY: { gpgme_recipient_t rec = opd->result.recipients; while (rec) { if (!strcmp (rec->keyid, args)) { rec->status = gpg_error (GPG_ERR_NO_SECKEY); break; } rec = rec->next; } /* FIXME: Is this ok? */ if (!rec) return gpg_error (GPG_ERR_INV_ENGINE); } break; case GPGME_STATUS_PLAINTEXT: err = _gpgme_parse_plaintext (args, &opd->result.file_name); if (err) return err; default: break; } return 0; }