gpgme_assuan_result_t gpgme_op_assuan_result (gpgme_ctx_t ctx) { gpgme_error_t err; void *hook; op_data_t opd; TRACE_BEG (DEBUG_CTX, "gpgme_op_assuan_result", ctx); err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, -1, NULL); opd = hook; /* Check in case this function is used without having run a command before. */ if (err || !opd) { TRACE_SUC0 ("result=(null)"); return NULL; } /* All of this is a hack for the old style interface. The new style interface returns op errors directly. */ opd->result.err = _gpgme_engine_assuan_last_op_err (ctx->engine->engine); if (opd->result.err) { TRACE_LOG1 ("err = %s", gpg_strerror (0)); } else { TRACE_LOG2 ("err = %s <%s>", gpg_strerror (opd->result.err), gpg_strsource (opd->result.err)); } TRACE_SUC1 ("result=%p", &opd->result); return &opd->result; }
/* Create a new data buffer filled with SIZE bytes starting from BUFFER. If COPY is zero, copying is delayed until necessary, and the data is taken from the original location when needed. */ gpgme_error_t gpgme_data_new_from_mem (gpgme_data_t *r_dh, const char *buffer, size_t size, int copy) { gpgme_error_t err; TRACE_BEG4 (DEBUG_DATA, "gpgme_data_new_from_mem", r_dh, "buffer=%p, size=%u, copy=%i (%s)", buffer, size, copy, copy ? "yes" : "no"); err = _gpgme_data_new (r_dh, &mem_cbs); if (err) return TRACE_ERR (err); if (copy) { char *bufcpy = malloc (size); if (!bufcpy) { int saved_err = gpg_error_from_syserror (); _gpgme_data_release (*r_dh); return TRACE_ERR (saved_err); } memcpy (bufcpy, buffer, size); (*r_dh)->data.mem.buffer = bufcpy; } else (*r_dh)->data.mem.orig_buffer = buffer; (*r_dh)->data.mem.size = size; (*r_dh)->data.mem.length = size; return TRACE_SUC1 ("dh=%p", *r_dh); }
gpgme_error_t gpgme_data_new_from_fd (gpgme_data_t *r_dh, int fd) { gpgme_error_t err; TRACE_BEG1 (DEBUG_DATA, "gpgme_data_new_from_fd", r_dh, "fd=0x%x", fd); err = _gpgme_data_new (r_dh, &fd_cbs); if (err) return TRACE_ERR (err); (*r_dh)->data.fd = fd; return TRACE_SUC1 ("dh=%p", *r_dh); }
/* Create a new data buffer and return it in R_DH. */ gpgme_error_t gpgme_data_new (gpgme_data_t *r_dh) { gpgme_error_t err; TRACE_BEG (DEBUG_DATA, "gpgme_data_new", r_dh); err = _gpgme_data_new (r_dh, &mem_cbs); if (err) return TRACE_ERR (err); return TRACE_SUC1 ("dh=%p", *r_dh); }
gpgme_import_result_t gpgme_op_import_result (gpgme_ctx_t ctx) { void *hook; op_data_t opd; gpgme_error_t err; TRACE_BEG (DEBUG_CTX, "gpgme_op_import_result", ctx); err = _gpgme_op_data_lookup (ctx, OPDATA_IMPORT, &hook, -1, NULL); opd = hook; if (err || !opd) { TRACE_SUC0 ("result=(null)"); return NULL; } if (_gpgme_debug_trace ()) { gpgme_import_status_t impstat; int i; TRACE_LOG5 ("%i considered, %i no UID, %i imported, %i imported RSA, " "%i unchanged", opd->result.considered, opd->result.no_user_id, opd->result.imported, opd->result.imported_rsa, opd->result.unchanged); TRACE_LOG4 ("%i new UIDs, %i new sub keys, %i new signatures, " "%i new revocations", opd->result.new_user_ids, opd->result.new_sub_keys, opd->result.new_signatures, opd->result.new_revocations); TRACE_LOG3 ("%i secret keys, %i imported, %i unchanged", opd->result.secret_read, opd->result.secret_imported, opd->result.secret_unchanged); TRACE_LOG2 ("%i skipped new keys, %i not imported", opd->result.skipped_new_keys, opd->result.not_imported); impstat = opd->result.imports; i = 0; while (impstat) { TRACE_LOG4 ("import[%i] for %s = 0x%x (%s)", i, impstat->fpr, impstat->status, impstat->result); impstat = impstat->next; i++; } } TRACE_SUC1 ("result=%p", &opd->result); return &opd->result; }
gpgme_verify_result_t gpgme_op_verify_result (gpgme_ctx_t ctx) { void *hook; op_data_t opd; gpgme_error_t err; TRACE_BEG (DEBUG_CTX, "gpgme_op_verify_result", ctx); err = _gpgme_op_data_lookup (ctx, OPDATA_VERIFY, &hook, -1, NULL); opd = hook; if (err || !opd) { TRACE_SUC0 ("result=(null)"); return NULL; } if (_gpgme_debug_trace ()) { gpgme_signature_t sig = opd->result.signatures; int i = 0; while (sig) { TRACE_LOG4 ("sig[%i] = fpr %s, summary 0x%x, status %s", i, sig->fpr, sig->summary, gpg_strerror (sig->status)); TRACE_LOG6 ("sig[%i] = timestamps 0x%x/0x%x flags:%s%s%s", i, sig->timestamp, sig->exp_timestamp, sig->wrong_key_usage ? "wrong key usage" : "", sig->pka_trust == 1 ? "pka bad" : (sig->pka_trust == 2 ? "pka_okay" : "pka RFU"), sig->chain_model ? "chain model" : ""); TRACE_LOG5 ("sig[%i] = validity 0x%x (%s), algos %s/%s", i, sig->validity, gpg_strerror (sig->validity_reason), gpgme_pubkey_algo_name (sig->pubkey_algo), gpgme_hash_algo_name (sig->hash_algo)); if (sig->pka_address) { TRACE_LOG2 ("sig[%i] = PKA address %s", i, sig->pka_address); } if (sig->notations) { TRACE_LOG1 ("sig[%i] = has notations (not shown)", i); } sig = sig->next; i++; } } TRACE_SUC1 ("result=%p", &opd->result); return &opd->result; }
gpgme_error_t gpgme_data_new_from_cbs (gpgme_data_t *r_dh, gpgme_data_cbs_t cbs, void *handle) { gpgme_error_t err; TRACE_BEG1 (DEBUG_DATA, "gpgme_data_new_from_cbs", r_dh, "handle=%p", handle); err = _gpgme_data_new (r_dh, &user_cbs); if (err) return TRACE_ERR (err); (*r_dh)->data.user.cbs = cbs; (*r_dh)->data.user.handle = handle; return TRACE_SUC1 ("dh=%p", *r_dh); }
/* Write the printable version of FD to the buffer BUF of length BUFLEN. The printable version is the representation on the command line that the child process expects. */ int _gpgme_io_fd2str (char *buf, int buflen, int fd) { HANDLE hndl; TRACE_BEG1 (DEBUG_SYSIO, "_gpgme_io_fd2str", fd, "fd=%d", fd); if (giochannel_table[fd].fd != -1) hndl = (HANDLE) _get_osfhandle (giochannel_table[fd].fd); else hndl = (HANDLE) giochannel_table[fd].socket; TRACE_SUC1 ("syshd=%p", hndl); return snprintf (buf, buflen, "%d", (int) hndl); }
/* Destroy the data buffer DH and return a pointer to its content. The memory has be to released with gpgme_free() by the user. It's size is returned in R_LEN. */ char * gpgme_data_release_and_get_mem (gpgme_data_t dh, size_t *r_len) { char *str = NULL; TRACE_BEG1 (DEBUG_DATA, "gpgme_data_release_and_get_mem", dh, "r_len=%p", r_len); if (!dh || dh->cbs != &mem_cbs) { gpgme_data_release (dh); TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); return NULL; } str = dh->data.mem.buffer; if (!str && dh->data.mem.orig_buffer) { str = malloc (dh->data.mem.length); if (!str) { int saved_err = gpg_error_from_syserror (); gpgme_data_release (dh); TRACE_ERR (saved_err); return NULL; } memcpy (str, dh->data.mem.orig_buffer, dh->data.mem.length); } else /* Prevent mem_release from releasing the buffer memory. We must not fail from this point. */ dh->data.mem.buffer = NULL; if (r_len) *r_len = dh->data.mem.length; gpgme_data_release (dh); if (r_len) { TRACE_SUC2 ("buffer=%p, len=%u", str, *r_len); } else { TRACE_SUC1 ("buffer=%p", str); } return str; }
gpgme_decrypt_result_t gpgme_op_decrypt_result (gpgme_ctx_t ctx) { void *hook; op_data_t opd; gpgme_error_t err; TRACE_BEG (DEBUG_CTX, "gpgme_op_decrypt_result", ctx); err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook, -1, NULL); opd = hook; if (err || !opd) { TRACE_SUC0 ("result=(null)"); return NULL; } if (_gpgme_debug_trace ()) { gpgme_recipient_t rcp; if (opd->result.unsupported_algorithm) { TRACE_LOG1 ("result: unsupported_algorithm: %s", opd->result.unsupported_algorithm); } if (opd->result.wrong_key_usage) { TRACE_LOG ("result: wrong key usage"); } rcp = opd->result.recipients; while (rcp) { TRACE_LOG3 ("result: recipient: keyid=%s, pubkey_algo=%i, " "status=%s", rcp->keyid, rcp->pubkey_algo, gpg_strerror (rcp->status)); rcp = rcp->next; } if (opd->result.file_name) { TRACE_LOG1 ("result: original file name: %s", opd->result.file_name); } } TRACE_SUC1 ("result=%p", &opd->result); return &opd->result; }
int _gpgme_io_socket (int domain, int type, int proto) { int res; TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_socket", domain, "type=%i, protp=%i", type, proto); res = socket (domain, type, proto); if (res == INVALID_SOCKET) { errno = wsa2errno (WSAGetLastError ()); return TRACE_SYSRES (-1); } TRACE_SUC1 ("socket=0x%x", res); return res; }
/* Return the VALUE of FLAG in context CTX. */ int assuan_get_flag (assuan_context_t ctx, assuan_flag_t flag) { int res = 0; TRACE_BEG1 (ctx, ASSUAN_LOG_CTX, "assuan_get_flag", ctx, "flag=%i", flag); if (! ctx) return 0; switch (flag) { case ASSUAN_NO_WAITPID: res = ctx->flags.no_waitpid; break; case ASSUAN_CONFIDENTIAL: res = ctx->flags.confidential; break; case ASSUAN_NO_FIXSIGNALS: res = ctx->flags.no_fixsignals; break; case ASSUAN_CONVEY_COMMENTS: res = ctx->flags.convey_comments; break; case ASSUAN_NO_LOGGING: res = ctx->flags.no_logging; break; case ASSUAN_FORCE_CLOSE: res = ctx->flags.force_close; break; } return TRACE_SUC1 ("flag_value=%i", res); }
/* Create a new data buffer filled with LENGTH bytes starting from OFFSET within the file FNAME or stream STREAM (exactly one must be non-zero). */ gpgme_error_t gpgme_data_new_from_filepart (gpgme_data_t *r_dh, const char *fname, FILE *stream, off_t offset, size_t length) { gpgme_error_t err; char *buf = NULL; int res; TRACE_BEG4 (DEBUG_DATA, "gpgme_data_new_from_filepart", r_dh, "file_name=%s, stream=%p, offset=%lli, length=%u", fname, stream, offset, length); if (stream && fname) return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); if (fname) stream = fopen (fname, "rb"); if (!stream) return TRACE_ERR (gpg_error_from_errno (errno)); #ifdef HAVE_FSEEKO res = fseeko (stream, offset, SEEK_SET); #else /* FIXME: Check for overflow, or at least bail at compilation. */ res = fseek (stream, offset, SEEK_SET); #endif if (res) { int saved_errno = errno; if (fname) fclose (stream); return TRACE_ERR (gpg_error_from_errno (saved_errno)); } buf = malloc (length); if (!buf) { int saved_errno = errno; if (fname) fclose (stream); return TRACE_ERR (gpg_error_from_errno (saved_errno)); } while (fread (buf, length, 1, stream) < 1 && ferror (stream) && errno == EINTR); if (ferror (stream)) { int saved_errno = errno; if (buf) free (buf); if (fname) fclose (stream); return TRACE_ERR (gpg_error_from_errno (saved_errno)); } if (fname) fclose (stream); err = gpgme_data_new (r_dh); if (err) { if (buf) free (buf); return err; } (*r_dh)->data.mem.buffer = buf; (*r_dh)->data.mem.size = length; (*r_dh)->data.mem.length = length; return TRACE_SUC1 ("r_dh=%p", *r_dh); }
gpgme_verify_result_t gpgme_op_verify_result (gpgme_ctx_t ctx) { void *hook; op_data_t opd; gpgme_error_t err; gpgme_signature_t sig; TRACE_BEG (DEBUG_CTX, "gpgme_op_verify_result", ctx); err = _gpgme_op_data_lookup (ctx, OPDATA_VERIFY, &hook, -1, NULL); opd = hook; if (err || !opd) { TRACE_SUC0 ("result=(null)"); return NULL; } /* It is possible that we saw a new signature only followed by an ERROR line for that. In particular a missing X.509 key triggers this. In this case it is surprising that the summary field has not been updated. We fix it here by explicitly looking for this case. The real fix would be to have GPGME emit ERRSIG. */ for (sig = opd->result.signatures; sig; sig = sig->next) { if (!sig->summary) { switch (gpg_err_code (sig->status)) { case GPG_ERR_KEY_EXPIRED: sig->summary |= GPGME_SIGSUM_KEY_EXPIRED; break; case GPG_ERR_NO_PUBKEY: sig->summary |= GPGME_SIGSUM_KEY_MISSING; break; default: break; } } } /* Now for some tracing stuff. */ if (_gpgme_debug_trace ()) { int i; for (sig = opd->result.signatures, i = 0; sig; sig = sig->next, i++) { TRACE_LOG4 ("sig[%i] = fpr %s, summary 0x%x, status %s", i, sig->fpr, sig->summary, gpg_strerror (sig->status)); TRACE_LOG6 ("sig[%i] = timestamps 0x%x/0x%x flags:%s%s%s", i, sig->timestamp, sig->exp_timestamp, sig->wrong_key_usage ? "wrong key usage" : "", sig->pka_trust == 1 ? "pka bad" : (sig->pka_trust == 2 ? "pka_okay" : "pka RFU"), sig->chain_model ? "chain model" : ""); TRACE_LOG5 ("sig[%i] = validity 0x%x (%s), algos %s/%s", i, sig->validity, gpg_strerror (sig->validity_reason), gpgme_pubkey_algo_name (sig->pubkey_algo), gpgme_hash_algo_name (sig->hash_algo)); if (sig->pka_address) { TRACE_LOG2 ("sig[%i] = PKA address %s", i, sig->pka_address); } if (sig->notations) { TRACE_LOG1 ("sig[%i] = has notations (not shown)", i); } } } TRACE_SUC1 ("result=%p", &opd->result); return &opd->result; }
/* Create a new context as an environment for GPGME crypto operations. */ gpgme_error_t gpgme_new (gpgme_ctx_t *r_ctx) { gpgme_error_t err; gpgme_ctx_t ctx; TRACE_BEG (DEBUG_CTX, "gpgme_new", r_ctx); if (_gpgme_selftest) return TRACE_ERR (_gpgme_selftest); if (!r_ctx) return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); ctx = calloc (1, sizeof *ctx); if (!ctx) return TRACE_ERR (gpg_error_from_syserror ()); INIT_LOCK (ctx->lock); err = _gpgme_engine_info_copy (&ctx->engine_info); if (!err && !ctx->engine_info) err = gpg_error (GPG_ERR_NO_ENGINE); if (err) { free (ctx); return TRACE_ERR (err); } ctx->keylist_mode = GPGME_KEYLIST_MODE_LOCAL; ctx->include_certs = GPGME_INCLUDE_CERTS_DEFAULT; ctx->protocol = GPGME_PROTOCOL_OpenPGP; ctx->sub_protocol = GPGME_PROTOCOL_DEFAULT; _gpgme_fd_table_init (&ctx->fdt); LOCK (def_lc_lock); if (def_lc_ctype) { ctx->lc_ctype = strdup (def_lc_ctype); if (!ctx->lc_ctype) { int saved_err = gpg_error_from_syserror (); UNLOCK (def_lc_lock); _gpgme_engine_info_release (ctx->engine_info); free (ctx); return TRACE_ERR (saved_err); } } else def_lc_ctype = NULL; if (def_lc_messages) { ctx->lc_messages = strdup (def_lc_messages); if (!ctx->lc_messages) { int saved_err = gpg_error_from_syserror (); UNLOCK (def_lc_lock); if (ctx->lc_ctype) free (ctx->lc_ctype); _gpgme_engine_info_release (ctx->engine_info); free (ctx); return TRACE_ERR (saved_err); } } else def_lc_messages = NULL; UNLOCK (def_lc_lock); *r_ctx = ctx; return TRACE_SUC1 ("ctx=%p", ctx); }