Page MenuHome GnuPG

No OneTemporary

diff --git a/callbacks.h b/callbacks.h
index 71f6316b..4c7c7831 100644
--- a/callbacks.h
+++ b/callbacks.h
@@ -1,43 +1,44 @@
/*
callbacks.h - callback targets for internal use:
Copyright (C) 2003 Klarälvdalens Datakonsult AB
This file is part of GPGME++.
This is an internal header file, subject to change without
notice. DO NOT USE.
GPGME++ 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.
GPGME++ 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 GPGME++; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef __GPGMEPP_CALLBACKS_H__
#define __GPGMEPP_CALLBACKS_H__
#include <gpgme.h>
extern "C" {
void progress_callback( void * opaque, const char * what,
int type, int current, int total );
gpgme_error_t passphrase_callback( void * opaque, const char * uid_hint,
const char * desc, int prev_was_bad, int fd );
}
namespace GpgME {
extern gpgme_data_cbs data_provider_callbacks;
+ extern gpgme_edit_cb_t edit_interactor_callback;
}
#endif // __GPGME_CALLBACKS_H__
diff --git a/context.cpp b/context.cpp
index 19349b02..49e59ced 100644
--- a/context.cpp
+++ b/context.cpp
@@ -1,811 +1,811 @@
/*
context.cpp - wraps a gpgme key context
Copyright (C) 2003, 2007 Klarälvdalens Datakonsult AB
This file is part of GPGME++.
GPGME++ 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.
GPGME++ 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 GPGME++; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include <config-gpgme++.h>
#include <gpgme++/context.h>
#include <gpgme++/eventloopinteractor.h>
#include <gpgme++/trustitem.h>
#include <gpgme++/keylistresult.h>
#include <gpgme++/keygenerationresult.h>
#include <gpgme++/importresult.h>
#include <gpgme++/decryptionresult.h>
#include <gpgme++/verificationresult.h>
#include <gpgme++/signingresult.h>
#include <gpgme++/encryptionresult.h>
#include <gpgme++/engineinfo.h>
#include <gpgme++/editinteractor.h>
#include "callbacks.h"
#include "data_p.h"
#include "context_p.h"
#include "util.h"
#include <gpgme.h>
//#include <string>
//using std::string;
#ifndef NDEBUG
#include <iostream>
using std::cerr;
using std::endl;
#endif
#include <cassert>
namespace GpgME {
static inline gpgme_error_t makeError( gpg_err_code_t code ) {
return gpg_err_make( (gpg_err_source_t)22, code );
}
const char * Error::source() const {
return gpgme_strsource( (gpgme_error_t)mErr );
}
const char * Error::asString() const {
return gpgme_strerror( (gpgme_error_t)mErr );
}
int Error::code() const {
return gpgme_err_code( mErr );
}
int Error::sourceID() const {
return gpgme_err_source( mErr );
}
bool Error::isCanceled() const {
return code() == GPG_ERR_CANCELED;
}
Context::Context( gpgme_ctx_t ctx ) {
d = new Private( ctx );
}
Context::~Context() {
delete d; d = 0;
}
Context * Context::createForProtocol( Protocol proto ) {
gpgme_ctx_t ctx = 0;
if ( gpgme_new ( &ctx ) != 0 )
return 0;
switch ( proto ) {
case OpenPGP:
if ( gpgme_set_protocol( ctx, GPGME_PROTOCOL_OpenPGP ) != 0 ) {
gpgme_release( ctx );
return 0;
}
break;
case CMS:
if ( gpgme_set_protocol( ctx, GPGME_PROTOCOL_CMS ) != 0 ) {
gpgme_release( ctx );
return 0;
}
break;
default:
return 0;
}
return new Context( ctx );
}
//
//
// Context::Private
//
//
Context::Private::Private( gpgme_ctx_t c )
: ctx( c ),
iocbs( 0 ),
lastop( None ),
lasterr( GPG_ERR_NO_ERROR ),
lastEditInteractor(),
lastCardEditInteractor()
{
}
Context::Private::~Private() {
if ( ctx )
gpgme_release( ctx );
ctx = 0;
delete iocbs;
}
//
//
// Context attributes:
//
//
Protocol Context::protocol() const {
gpgme_protocol_t p = gpgme_get_protocol( d->ctx );
switch ( p ) {
case GPGME_PROTOCOL_OpenPGP: return OpenPGP;
case GPGME_PROTOCOL_CMS: return CMS;
default: return UnknownProtocol;
}
}
void Context::setArmor( bool useArmor ) {
gpgme_set_armor( d->ctx, int( useArmor ) );
}
bool Context::armor() const {
return gpgme_get_armor( d->ctx );
}
void Context::setTextMode( bool useTextMode ) {
gpgme_set_textmode( d->ctx, int( useTextMode ) );
}
bool Context::textMode() const {
return gpgme_get_textmode( d->ctx );
}
void Context::setIncludeCertificates( int which ) {
if ( which == DefaultCertificates ) {
#ifdef HAVE_GPGME_INCLUDE_CERTS_DEFAULT
which = GPGME_INCLUDE_CERTS_DEFAULT;
#else
which = 1;
#endif
}
gpgme_set_include_certs( d->ctx, which );
}
int Context::includeCertificates() const {
return gpgme_get_include_certs( d->ctx );
}
void Context::setKeyListMode( unsigned int mode ) {
gpgme_set_keylist_mode( d->ctx, add_to_gpgme_keylist_mode_t( 0, mode ) );
}
void Context::addKeyListMode( unsigned int mode ) {
const unsigned int cur = gpgme_get_keylist_mode( d->ctx );
gpgme_set_keylist_mode( d->ctx, add_to_gpgme_keylist_mode_t( cur, mode ) );
}
unsigned int Context::keyListMode() const {
return convert_from_gpgme_keylist_mode_t( gpgme_get_keylist_mode( d->ctx ) );
}
void Context::setProgressProvider( ProgressProvider * provider ) {
gpgme_set_progress_cb( d->ctx, provider ? &progress_callback : 0, provider );
}
ProgressProvider * Context::progressProvider() const {
void * pp = 0;
gpgme_progress_cb_t pcb = &progress_callback;
gpgme_get_progress_cb( d->ctx, &pcb, &pp );
return static_cast<ProgressProvider*>( pp );
}
void Context::setPassphraseProvider( PassphraseProvider * provider ) {
gpgme_set_passphrase_cb( d->ctx, provider ? &passphrase_callback : 0, provider );
}
PassphraseProvider * Context::passphraseProvider() const {
void * pp = 0;
gpgme_passphrase_cb_t pcb = &passphrase_callback;
gpgme_get_passphrase_cb( d->ctx, &pcb, &pp );
return static_cast<PassphraseProvider*>( pp );
}
void Context::setManagedByEventLoopInteractor( bool manage ) {
if ( !EventLoopInteractor::instance() ) {
#ifndef NDEBUG
cerr << "Context::setManagedByEventLoopInteractor(): "
"You must create an instance of EventLoopInteractor "
"before using anything that needs one." << endl;
#endif
return;
}
if ( manage )
EventLoopInteractor::instance()->manage( this );
else
EventLoopInteractor::instance()->unmanage( this );
}
bool Context::managedByEventLoopInteractor() const {
return d->iocbs != 0;
}
void Context::installIOCallbacks( gpgme_io_cbs * iocbs ) {
if ( !iocbs ) {
uninstallIOCallbacks();
return;
}
gpgme_set_io_cbs( d->ctx, iocbs );
delete d->iocbs; d->iocbs = iocbs;
}
void Context::uninstallIOCallbacks() {
static gpgme_io_cbs noiocbs = { 0, 0, 0, 0, 0 };
// io.add == 0 means disable io callbacks:
gpgme_set_io_cbs( d->ctx, &noiocbs );
delete d->iocbs; d->iocbs = 0;
}
Error Context::setLocale( int cat, const char * val ) {
return Error( d->lasterr = gpgme_set_locale( d->ctx, cat, val ) );
}
EngineInfo Context::engineInfo() const {
#ifdef HAVE_GPGME_CTX_GETSET_ENGINE_INFO
return EngineInfo( gpgme_ctx_get_engine_info( d->ctx ) );
#else
return EngineInfo();
#endif
}
Error Context::setEngineFileName( const char * filename ) {
#ifdef HAVE_GPGME_CTX_GETSET_ENGINE_INFO
const char * const home_dir = engineInfo().homeDirectory();
return Error( gpgme_ctx_set_engine_info( d->ctx, gpgme_get_protocol( d->ctx ), filename, home_dir ) );
#else
return Error( makeError( GPG_ERR_NOT_IMPLEMENTED ) );
#endif
}
Error Context::setEngineHomeDirectory( const char * home_dir ) {
#ifdef HAVE_GPGME_CTX_GETSET_ENGINE_INFO
const char * const filename = engineInfo().fileName();
return Error( gpgme_ctx_set_engine_info( d->ctx, gpgme_get_protocol( d->ctx ), filename, home_dir ) );
#else
return Error( makeError( GPG_ERR_NOT_IMPLEMENTED ) );
#endif
}
//
//
// Key Management
//
//
Error Context::startKeyListing( const char * pattern, bool secretOnly ) {
d->lastop = Private::KeyList;
return Error( d->lasterr = gpgme_op_keylist_start( d->ctx, pattern, int( secretOnly ) ) );
}
Error Context::startKeyListing( const char * patterns[], bool secretOnly ) {
d->lastop = Private::KeyList;
return Error( d->lasterr = gpgme_op_keylist_ext_start( d->ctx, patterns, int( secretOnly ), 0 ) );
}
Key Context::nextKey( GpgME::Error & e ) {
d->lastop = Private::KeyList;
gpgme_key_t key;
e = Error( d->lasterr = gpgme_op_keylist_next( d->ctx, &key ) );
return Key( key, false );
}
KeyListResult Context::endKeyListing() {
d->lasterr = gpgme_op_keylist_end( d->ctx );
return keyListResult();
}
KeyListResult Context::keyListResult() const {
return KeyListResult( d->ctx, Error(d->lasterr) );
}
Key Context::key( const char * fingerprint, GpgME::Error & e , bool secret /*, bool forceUpdate*/ ) {
d->lastop = Private::KeyList;
gpgme_key_t key;
e = Error( d->lasterr = gpgme_get_key( d->ctx, fingerprint, &key, int( secret )/*, int( forceUpdate )*/ ) );
return Key( key, false );
}
KeyGenerationResult Context::generateKey( const char * parameters, Data & pubKey ) {
d->lastop = Private::KeyGen;
Data::Private * const dp = pubKey.impl();
d->lasterr = gpgme_op_genkey( d->ctx, parameters, dp ? dp->data : 0, 0 );
return KeyGenerationResult( d->ctx, Error(d->lasterr) );
}
Error Context::startKeyGeneration( const char * parameters, Data & pubKey ) {
d->lastop = Private::KeyGen;
Data::Private * const dp = pubKey.impl();
return Error( d->lasterr = gpgme_op_genkey_start( d->ctx, parameters, dp ? dp->data : 0, 0 ) );
}
KeyGenerationResult Context::keyGenerationResult() const {
if ( d->lastop & Private::KeyGen )
return KeyGenerationResult( d->ctx, Error(d->lasterr) );
else
return KeyGenerationResult();
}
Error Context::exportPublicKeys( const char * pattern, Data & keyData ) {
d->lastop = Private::Export;
Data::Private * const dp = keyData.impl();
return Error( d->lasterr = gpgme_op_export( d->ctx, pattern, 0, dp ? dp->data : 0 ) );
}
Error Context::exportPublicKeys( const char * patterns[], Data & keyData ) {
d->lastop = Private::Export;
Data::Private * const dp = keyData.impl();
return Error( d->lasterr = gpgme_op_export_ext( d->ctx, patterns, 0, dp ? dp->data : 0 ) );
}
Error Context::startPublicKeyExport( const char * pattern, Data & keyData ) {
d->lastop = Private::Export;
Data::Private * const dp = keyData.impl();
return Error( d->lasterr = gpgme_op_export_start( d->ctx, pattern, 0, dp ? dp->data : 0 ) );
}
Error Context::startPublicKeyExport( const char * patterns[], Data & keyData ) {
d->lastop = Private::Export;
Data::Private * const dp = keyData.impl();
return Error( d->lasterr = gpgme_op_export_ext_start( d->ctx, patterns, 0, dp ? dp->data : 0 ) );
}
ImportResult Context::importKeys( const Data & data ) {
d->lastop = Private::Import;
const Data::Private * const dp = data.impl();
d->lasterr = gpgme_op_import( d->ctx, dp ? dp->data : 0 );
return ImportResult( d->ctx, Error(d->lasterr) );
}
Error Context::startKeyImport( const Data & data ) {
d->lastop = Private::Import;
const Data::Private * const dp = data.impl();
return Error( d->lasterr = gpgme_op_import_start( d->ctx, dp ? dp->data : 0 ) );
}
ImportResult Context::importResult() const {
if ( d->lastop & Private::Import )
return ImportResult( d->ctx, Error(d->lasterr) );
else
return ImportResult();
}
Error Context::deleteKey( const Key & key, bool allowSecretKeyDeletion ) {
d->lastop = Private::Delete;
return Error( d->lasterr = gpgme_op_delete( d->ctx, key.impl(), int( allowSecretKeyDeletion ) ) );
}
Error Context::startKeyDeletion( const Key & key, bool allowSecretKeyDeletion ) {
d->lastop = Private::Delete;
return Error( d->lasterr = gpgme_op_delete_start( d->ctx, key.impl(), int( allowSecretKeyDeletion ) ) );
}
Error Context::edit( const Key & key, std::auto_ptr<EditInteractor> func, Data & data ) {
d->lastop = Private::Edit;
d->lastEditInteractor = func;
Data::Private * const dp = data.impl();
return Error( d->lasterr = gpgme_op_edit( d->ctx, key.impl(),
- d->lastEditInteractor.get() ? d->lastCardEditInteractor->getCallback() : 0,
- d->lastEditInteractor.get() ? d->lastCardEditInteractor->getCallbackArgument() : 0,
+ d->lastEditInteractor.get() ? edit_interactor_callback : 0,
+ d->lastEditInteractor.get() ? d->lastEditInteractor->d : 0,
dp ? dp->data : 0 ) );
}
Error Context::startEditing( const Key & key, std::auto_ptr<EditInteractor> func, Data & data ) {
d->lastop = Private::Edit;
d->lastEditInteractor = func;
Data::Private * const dp = data.impl();
return Error( d->lasterr = gpgme_op_edit_start( d->ctx, key.impl(),
- d->lastEditInteractor.get() ? d->lastCardEditInteractor->getCallback() : 0,
- d->lastEditInteractor.get() ? d->lastCardEditInteractor->getCallbackArgument() : 0,
+ d->lastEditInteractor.get() ? edit_interactor_callback : 0,
+ d->lastEditInteractor.get() ? d->lastEditInteractor->d : 0,
dp ? dp->data : 0 ) );
}
EditInteractor * Context::lastEditInteractor() const {
return d->lastEditInteractor.get();
}
Error Context::cardEdit( const Key & key, std::auto_ptr<EditInteractor> func, Data & data ) {
d->lastop = Private::CardEdit;
d->lastCardEditInteractor = func;
Data::Private * const dp = data.impl();
return Error( d->lasterr = gpgme_op_card_edit( d->ctx, key.impl(),
- d->lastCardEditInteractor.get() ? d->lastCardEditInteractor->getCallback() : 0,
- d->lastCardEditInteractor.get() ? d->lastCardEditInteractor->getCallbackArgument() : 0,
+ d->lastCardEditInteractor.get() ? edit_interactor_callback : 0,
+ d->lastCardEditInteractor.get() ? d->lastCardEditInteractor->d : 0,
dp ? dp->data : 0 ) );
}
Error Context::startCardEditing( const Key & key, std::auto_ptr<EditInteractor> func, Data & data ) {
d->lastop = Private::CardEdit;
d->lastCardEditInteractor = func;
Data::Private * const dp = data.impl();
return Error( d->lasterr = gpgme_op_card_edit_start( d->ctx, key.impl(),
- d->lastCardEditInteractor.get() ? d->lastCardEditInteractor->getCallback() : 0,
- d->lastCardEditInteractor.get() ? d->lastCardEditInteractor->getCallbackArgument() : 0,
+ d->lastCardEditInteractor.get() ? edit_interactor_callback : 0,
+ d->lastCardEditInteractor.get() ? d->lastCardEditInteractor->d : 0,
dp ? dp->data : 0 ) );
}
EditInteractor * Context::lastCardEditInteractor() const {
return d->lastCardEditInteractor.get();
}
Error Context::startTrustItemListing( const char * pattern, int maxLevel ) {
d->lastop = Private::TrustList;
return Error( d->lasterr = gpgme_op_trustlist_start( d->ctx, pattern, maxLevel ) );
}
TrustItem Context::nextTrustItem( Error & e ) {
gpgme_trust_item_t ti = 0;
e = Error( d->lasterr = gpgme_op_trustlist_next( d->ctx, &ti ) );
return TrustItem( ti );
}
Error Context::endTrustItemListing() {
return Error( d->lasterr = gpgme_op_trustlist_end( d->ctx ) );
}
DecryptionResult Context::decrypt( const Data & cipherText, Data & plainText ) {
d->lastop = Private::Decrypt;
const Data::Private * const cdp = cipherText.impl();
Data::Private * const pdp = plainText.impl();
d->lasterr = gpgme_op_decrypt( d->ctx, cdp ? cdp->data : 0, pdp ? pdp->data : 0 );
return DecryptionResult( d->ctx, Error(d->lasterr) );
}
Error Context::startDecryption( const Data & cipherText, Data & plainText ) {
d->lastop = Private::Decrypt;
const Data::Private * const cdp = cipherText.impl();
Data::Private * const pdp = plainText.impl();
return Error( d->lasterr = gpgme_op_decrypt_start( d->ctx, cdp ? cdp->data : 0, pdp ? pdp->data : 0 ) );
}
DecryptionResult Context::decryptionResult() const {
if ( d->lastop & Private::Decrypt )
return DecryptionResult( d->ctx, Error(d->lasterr) );
else
return DecryptionResult();
}
VerificationResult Context::verifyDetachedSignature( const Data & signature, const Data & signedText ) {
d->lastop = Private::Verify;
const Data::Private * const sdp = signature.impl();
const Data::Private * const tdp = signedText.impl();
d->lasterr = gpgme_op_verify( d->ctx, sdp ? sdp->data : 0, tdp ? tdp->data : 0, 0 );
return VerificationResult( d->ctx, Error(d->lasterr) );
}
VerificationResult Context::verifyOpaqueSignature( const Data & signedData, Data & plainText ) {
d->lastop = Private::Verify;
const Data::Private * const sdp = signedData.impl();
Data::Private * const pdp = plainText.impl();
d->lasterr = gpgme_op_verify( d->ctx, sdp ? sdp->data : 0, 0, pdp ? pdp->data : 0 );
return VerificationResult( d->ctx, Error(d->lasterr) );
}
Error Context::startDetachedSignatureVerification( const Data & signature, const Data & signedText ) {
d->lastop = Private::Verify;
const Data::Private * const sdp = signature.impl();
const Data::Private * const tdp = signedText.impl();
return Error( d->lasterr = gpgme_op_verify_start( d->ctx, sdp ? sdp->data : 0, tdp ? tdp->data : 0, 0 ) );
}
Error Context::startOpaqueSignatureVerification( const Data & signedData, Data & plainText ) {
d->lastop = Private::Verify;
const Data::Private * const sdp = signedData.impl();
Data::Private * const pdp = plainText.impl();
return Error( d->lasterr = gpgme_op_verify_start( d->ctx, sdp ? sdp->data : 0, 0, pdp ? pdp->data : 0 ) );
}
VerificationResult Context::verificationResult() const {
if ( d->lastop & Private::Verify )
return VerificationResult( d->ctx, Error(d->lasterr) );
else
return VerificationResult();
}
std::pair<DecryptionResult,VerificationResult> Context::decryptAndVerify( const Data & cipherText, Data & plainText ) {
d->lastop = Private::DecryptAndVerify;
const Data::Private * const cdp = cipherText.impl();
Data::Private * const pdp = plainText.impl();
d->lasterr = gpgme_op_decrypt_verify( d->ctx, cdp ? cdp->data : 0, pdp ? pdp->data : 0 );
return std::make_pair( DecryptionResult( d->ctx, Error(d->lasterr) ),
VerificationResult( d->ctx, Error(d->lasterr) ) );
}
Error Context::startCombinedDecryptionAndVerification( const Data & cipherText, Data & plainText ) {
d->lastop = Private::DecryptAndVerify;
const Data::Private * const cdp = cipherText.impl();
Data::Private * const pdp = plainText.impl();
return Error( d->lasterr = gpgme_op_decrypt_verify_start( d->ctx, cdp ? cdp->data : 0, pdp ? pdp->data : 0 ) );
}
#ifdef HAVE_GPGME_OP_GETAUDITLOG
unsigned int to_auditlog_flags( unsigned int flags ) {
unsigned int result = 0;
if ( flags & Context::HtmlAuditLog )
result |= GPGME_AUDITLOG_HTML;
if ( flags & Context::AuditLogWithHelp )
result |= GPGME_AUDITLOG_WITH_HELP;
return result;
}
#endif // HAVE_GPGME_OP_GETAUDITLOG
Error Context::startGetAuditLog( Data & output, unsigned int flags ) {
d->lastop = Private::GetAuditLog;
#ifdef HAVE_GPGME_OP_GETAUDITLOG
Data::Private * const odp = output.impl();
return Error( d->lasterr = gpgme_op_getauditlog_start( d->ctx, odp ? odp->data : 0, to_auditlog_flags( flags ) ) );
#else
(void)output; (void)flags;
return Error( d->lasterr = makeError( GPG_ERR_NOT_IMPLEMENTED ) );
#endif
}
Error Context::getAuditLog( Data & output, unsigned int flags ) {
d->lastop = Private::GetAuditLog;
#ifdef HAVE_GPGME_OP_GETAUDITLOG
Data::Private * const odp = output.impl();
return Error( d->lasterr = gpgme_op_getauditlog( d->ctx, odp ? odp->data : 0, to_auditlog_flags( flags ) ) );
#else
(void)output; (void)flags;
return Error( d->lasterr = makeError( GPG_ERR_NOT_IMPLEMENTED ) );
#endif
}
void Context::clearSigningKeys() {
gpgme_signers_clear( d->ctx );
}
Error Context::addSigningKey( const Key & key ) {
return Error( d->lasterr = gpgme_signers_add( d->ctx, key.impl() ) );
}
Key Context::signingKey( unsigned int idx ) const {
gpgme_key_t key = gpgme_signers_enum( d->ctx, idx );
return Key( key, false );
}
std::vector<Key> Context::signingKeys() const {
std::vector<Key> result;
gpgme_key_t key;
for ( unsigned int i = 0 ; ( key = gpgme_signers_enum( d->ctx, i ) ) ; ++i )
result.push_back( Key( key, false ) );
return result;
}
void Context::clearSignatureNotations() {
#ifdef HAVE_GPGME_SIG_NOTATION_CLEARADDGET
gpgme_sig_notation_clear( d->ctx );
#endif
}
GpgME::Error Context::addSignatureNotation( const char * name, const char * value, unsigned int flags ) {
#ifdef HAVE_GPGME_SIG_NOTATION_CLEARADDGET
return Error( gpgme_sig_notation_add( d->ctx, name, value, add_to_gpgme_sig_notation_flags_t( 0, flags ) ) );
#else
(void)name; (void)value; (void)flags;
return Error( makeError( GPG_ERR_NOT_IMPLEMENTED ) );
#endif
}
GpgME::Error Context::addSignaturePolicyURL( const char * url, bool critical ) {
#ifdef HAVE_GPGME_SIG_NOTATION_CLEARADDGET
return Error( gpgme_sig_notation_add( d->ctx, 0, url, critical ? GPGME_SIG_NOTATION_CRITICAL : 0 ) );
#else
(void)url; (void)critical;
return Error( makeError( GPG_ERR_NOT_IMPLEMENTED ) );
#endif
}
const char * Context::signaturePolicyURL() const {
#ifdef HAVE_GPGME_SIG_NOTATION_CLEARADDGET
for ( gpgme_sig_notation_t n = gpgme_sig_notation_get( d->ctx ) ; n ; n = n->next )
if ( !n->name )
return n->value;
#endif
return 0;
}
Notation Context::signatureNotation( unsigned int idx ) const {
#ifdef HAVE_GPGME_SIG_NOTATION_CLEARADDGET
for ( gpgme_sig_notation_t n = gpgme_sig_notation_get( d->ctx ) ; n ; n = n->next )
if ( n->name )
if ( idx-- == 0 )
return Notation( n );
#endif
return Notation();
}
std::vector<Notation> Context::signatureNotations() const {
std::vector<Notation> result;
#ifdef HAVE_GPGME_SIG_NOTATION_CLEARADDGET
for ( gpgme_sig_notation_t n = gpgme_sig_notation_get( d->ctx ) ; n ; n = n->next )
if ( n->name )
result.push_back( Notation( n ) );
#endif
return result;
}
static gpgme_sig_mode_t sigmode2sigmode( SignatureMode mode ) {
switch ( mode ) {
default:
case NormalSignatureMode: return GPGME_SIG_MODE_NORMAL;
case Detached: return GPGME_SIG_MODE_DETACH;
case Clearsigned: return GPGME_SIG_MODE_CLEAR;
}
}
SigningResult Context::sign( const Data & plainText, Data & signature, SignatureMode mode ) {
d->lastop = Private::Sign;
const Data::Private * const pdp = plainText.impl();
Data::Private * const sdp = signature.impl();
d->lasterr = gpgme_op_sign( d->ctx, pdp ? pdp->data : 0, sdp ? sdp->data : 0, sigmode2sigmode( mode ) );
return SigningResult( d->ctx, Error(d->lasterr) );
}
Error Context::startSigning( const Data & plainText, Data & signature, SignatureMode mode ) {
d->lastop = Private::Sign;
const Data::Private * const pdp = plainText.impl();
Data::Private * const sdp = signature.impl();
return Error( d->lasterr = gpgme_op_sign_start( d->ctx, pdp ? pdp->data : 0, sdp ? sdp->data : 0, sigmode2sigmode( mode ) ) );
}
SigningResult Context::signingResult() const {
if ( d->lastop & Private::Sign )
return SigningResult( d->ctx, Error(d->lasterr) );
else
return SigningResult();
}
EncryptionResult Context::encrypt( const std::vector<Key> & recipients, const Data & plainText, Data & cipherText, EncryptionFlags flags ) {
d->lastop = Private::Encrypt;
const Data::Private * const pdp = plainText.impl();
Data::Private * const cdp = cipherText.impl();
gpgme_key_t * const keys = new gpgme_key_t[ recipients.size() + 1 ];
gpgme_key_t * keys_it = keys;
for ( std::vector<Key>::const_iterator it = recipients.begin() ; it != recipients.end() ; ++it )
if ( it->impl() )
*keys_it++ = it->impl();
*keys_it++ = 0;
d->lasterr = gpgme_op_encrypt( d->ctx, keys,
flags & AlwaysTrust ? GPGME_ENCRYPT_ALWAYS_TRUST : (gpgme_encrypt_flags_t)0,
pdp ? pdp->data : 0, cdp ? cdp->data : 0 );
delete[] keys;
return EncryptionResult( d->ctx, Error(d->lasterr) );
}
Error Context::encryptSymmetrically( const Data & plainText, Data & cipherText ) {
d->lastop = Private::Encrypt;
const Data::Private * const pdp = plainText.impl();
Data::Private * const cdp = cipherText.impl();
return Error( d->lasterr = gpgme_op_encrypt( d->ctx, 0, (gpgme_encrypt_flags_t)0,
pdp ? pdp->data : 0, cdp ? cdp->data : 0 ) );
}
Error Context::startEncryption( const std::vector<Key> & recipients, const Data & plainText, Data & cipherText, EncryptionFlags flags ) {
d->lastop = Private::Encrypt;
const Data::Private * const pdp = plainText.impl();
Data::Private * const cdp = cipherText.impl();
gpgme_key_t * const keys = new gpgme_key_t[ recipients.size() + 1 ];
gpgme_key_t * keys_it = keys;
for ( std::vector<Key>::const_iterator it = recipients.begin() ; it != recipients.end() ; ++it )
if ( it->impl() )
*keys_it++ = it->impl();
*keys_it++ = 0;
d->lasterr = gpgme_op_encrypt_start( d->ctx, keys,
flags & AlwaysTrust ? GPGME_ENCRYPT_ALWAYS_TRUST : (gpgme_encrypt_flags_t)0,
pdp ? pdp->data : 0, cdp ? cdp->data : 0 );
delete[] keys;
return Error( d->lasterr );
}
EncryptionResult Context::encryptionResult() const {
if ( d->lastop & Private::Encrypt )
return EncryptionResult( d->ctx, Error(d->lasterr) );
else
return EncryptionResult();
}
std::pair<SigningResult,EncryptionResult> Context::signAndEncrypt( const std::vector<Key> & recipients, const Data & plainText, Data & cipherText, EncryptionFlags flags ) {
d->lastop = Private::SignAndEncrypt;
const Data::Private * const pdp = plainText.impl();
Data::Private * const cdp = cipherText.impl();
gpgme_key_t * const keys = new gpgme_key_t[ recipients.size() + 1 ];
gpgme_key_t * keys_it = keys;
for ( std::vector<Key>::const_iterator it = recipients.begin() ; it != recipients.end() ; ++it )
if ( it->impl() )
*keys_it++ = it->impl();
*keys_it++ = 0;
d->lasterr = gpgme_op_encrypt_sign( d->ctx, keys,
flags & AlwaysTrust ? GPGME_ENCRYPT_ALWAYS_TRUST : (gpgme_encrypt_flags_t)0,
pdp ? pdp->data : 0, cdp ? cdp->data : 0 );
delete[] keys;
return std::make_pair( SigningResult( d->ctx, Error(d->lasterr) ),
EncryptionResult( d->ctx, Error(d->lasterr) ) );
}
Error Context::startCombinedSigningAndEncryption( const std::vector<Key> & recipients, const Data & plainText, Data & cipherText, EncryptionFlags flags ) {
d->lastop = Private::SignAndEncrypt;
const Data::Private * const pdp = plainText.impl();
Data::Private * const cdp = cipherText.impl();
gpgme_key_t * const keys = new gpgme_key_t[ recipients.size() + 1 ];
gpgme_key_t * keys_it = keys;
for ( std::vector<Key>::const_iterator it = recipients.begin() ; it != recipients.end() ; ++it )
if ( it->impl() )
*keys_it++ = it->impl();
*keys_it++ = 0;
d->lasterr = gpgme_op_encrypt_sign_start( d->ctx, keys,
flags & AlwaysTrust ? GPGME_ENCRYPT_ALWAYS_TRUST : (gpgme_encrypt_flags_t)0,
pdp ? pdp->data : 0, cdp ? cdp->data : 0 );
delete[] keys;
return Error( d->lasterr );
}
Error Context::cancelPendingOperation() {
return Error( gpgme_cancel( d->ctx ) );
}
bool Context::poll() {
gpgme_error_t e = GPG_ERR_NO_ERROR;
const bool finished = gpgme_wait( d->ctx, &e, 0 );
if ( finished )
d->lasterr = e;
return finished;
}
Error Context::wait() {
gpgme_error_t e = GPG_ERR_NO_ERROR;
gpgme_wait( d->ctx, &e, 1 );
return Error( d->lasterr = e );
}
Error Context::lastError() const {
return Error( d->lasterr );
}
} // namespace GpgME
GpgME::Error GpgME::setDefaultLocale( int cat, const char * val ) {
return Error( gpgme_set_locale( 0, cat, val ) );
}
GpgME::EngineInfo GpgME::engineInfo( GpgME::Protocol proto ) {
gpgme_engine_info_t ei = 0;
if ( gpgme_get_engine_info( &ei ) )
return EngineInfo();
const gpgme_protocol_t p = proto == CMS ? GPGME_PROTOCOL_CMS : GPGME_PROTOCOL_OpenPGP ;
for ( gpgme_engine_info_t i = ei ; i ; i = i->next )
if ( i->protocol == p )
return EngineInfo( i );
return EngineInfo();
}
GpgME::Error GpgME::checkEngine( GpgME::Protocol proto ) {
const gpgme_protocol_t p = proto == CMS ? GPGME_PROTOCOL_CMS : GPGME_PROTOCOL_OpenPGP ;
return Error( gpgme_engine_check_version( p ) );
}
diff --git a/editinteractor.cpp b/editinteractor.cpp
index 26de8b82..e346d2c0 100644
--- a/editinteractor.cpp
+++ b/editinteractor.cpp
@@ -1,152 +1,153 @@
/*
editinteractor.cpp - Interface for edit interactors
Copyright (C) 2007 Klarälvdalens Datakonsult AB
This file is part of GPGME++.
GPGME++ 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.
GPGME++ 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 GPGME++; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "editinteractor.h"
#include "callbacks.h"
#include "error.h"
#include <gpg-error.h>
#ifdef _WIN32
# include <io.h>
# define write _write
#else
# include <unistd.h>
#endif
#include <cstring>
using namespace GpgME;
+static int edit_interactor_callback_impl( void * opaque, gpgme_status_code_t status, const char * args, int fd );
+
class EditInteractor::Private {
friend class ::GpgME::EditInteractor;
EditInteractor * const q;
public:
explicit Private( EditInteractor * qq );
~Private();
- static gpgme_error_t edit_interactor_callback( void * opaque, gpgme_status_code_t status, const char * args, int fd ) {
+ friend int ::edit_interactor_callback_impl( void * opaque, gpgme_status_code_t status, const char * args, int fd ) {
Private * ei = (Private*)opaque;
try {
// advance to next state based on input:
const unsigned int oldState = ei->state;
ei->state = ei->q->nextState( status, args );
if ( ei->debug )
std::fprintf( ei->debug, "EditInteractor: %u -> nextState( %u, %s ) -> %u\n",
oldState, (unsigned int)status, args ? args : "<null>", ei->state );
if ( ei->state != oldState &&
// if there was an error from before, we stop here (### this looks weird, can this happen at all?)
gpg_err_code( ei->error.code() ) == GPG_ERR_NO_ERROR ) {
// successful state change -> call action
if ( const char * const result = ei->q->action() ) {
if ( ei->debug )
std::fprintf( ei->debug, "EditInteractor: action result \"%s\"\n", result );
// if there's a result, write it:
if ( *result )
write( fd, result, std::strlen( result ) );
write( fd, "\n", 1 );
} else {
if ( ei->debug )
std::fprintf( ei->debug, "EditInteractor: no action result\n" );
}
} else {
if ( ei->debug )
std::fprintf( ei->debug, "EditInteractor: no action executed\n" );
}
} catch ( const Error & err ) {
ei->error = err;
ei->state = EditInteractor::ErrorState;
}
if ( ei->debug )
std::fprintf( ei->debug, "EditInteractor: error now %u (%s)\n",
ei->error.encodedError(), gpg_strerror( ei->error.encodedError() ) );
return ei->error.encodedError();
}
private:
unsigned int state;
Error error;
std::FILE * debug;
};
+static gpgme_error_t edit_interactor_callback( void * opaque, gpgme_status_code_t status, const char * args, int fd )
+{
+ return edit_interactor_callback_impl( opaque, status, args, fd );
+}
+
+gpgme_edit_cb_t GpgME::edit_interactor_callback = ::edit_interactor_callback;
+
EditInteractor::Private::Private( EditInteractor * qq )
: q( qq ),
state( StartState ),
error()
{
}
EditInteractor::Private::~Private() {}
EditInteractor::EditInteractor()
: d( new Private( this ) )
{
}
EditInteractor::~EditInteractor() {
delete d; d = 0;
}
unsigned int EditInteractor::state() const {
return d->state;
}
Error EditInteractor::lastError() const {
return d->error;
}
bool EditInteractor::needsNoResponse( unsigned int status ) const {
switch ( status ) {
case GPGME_STATUS_EOF:
case GPGME_STATUS_GOT_IT:
case GPGME_STATUS_NEED_PASSPHRASE:
case GPGME_STATUS_NEED_PASSPHRASE_SYM:
case GPGME_STATUS_GOOD_PASSPHRASE:
case GPGME_STATUS_BAD_PASSPHRASE:
case GPGME_STATUS_USERID_HINT:
case GPGME_STATUS_SIGEXPIRED:
case GPGME_STATUS_KEYEXPIRED:
return true;
default:
return false;
}
}
void EditInteractor::setDebugChannel( std::FILE * debug ) {
d->debug = debug;
}
-
-gpgme_edit_cb_t EditInteractor::getCallback() {
- return Private::edit_interactor_callback;
-}
-
-void * EditInteractor::getCallbackArgument() {
- return d;
-}
diff --git a/editinteractor.h b/editinteractor.h
index f0c049b4..4924c32b 100644
--- a/editinteractor.h
+++ b/editinteractor.h
@@ -1,66 +1,64 @@
/*
editinteractor.h - Interface for edit interactors
Copyright (C) 2007 Klarälvdalens Datakonsult AB
This file is part of GPGME++.
GPGME++ 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.
GPGME++ 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 GPGME++; see the file COPYING.LIB. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef __GPGMEPP_EDITINTERACTOR_H__
#define __GPGMEPP_EDITINTERACTOR_H__
#include <gpgme++/gpgme++_export.h>
-#include <gpgme.h>
#include <cstdio>
namespace GpgME {
class Error;
+ class Context;
class GPGMEPP_EXPORT EditInteractor {
+ friend class ::GpgME::Context;
EditInteractor( const EditInteractor & );
EditInteractor & operator=( const EditInteractor & );
public:
EditInteractor();
virtual ~EditInteractor();
enum {
StartState = 0,
ErrorState = 0xFFFFFFFF
};
virtual const char * action() const = 0;
virtual unsigned int nextState( unsigned int statusCode, const char * args ) const = 0;
unsigned int state() const;
Error lastError() const;
bool needsNoResponse( unsigned int statusCode ) const;
void setDebugChannel( std::FILE * file );
- gpgme_edit_cb_t getCallback();
- void * getCallbackArgument();
-
private:
class Private;
Private * d;
};
} // namespace GpgME
#endif // __GPGMEPP_EDITINTERACTOR_H__

File Metadata

Mime Type
text/x-diff
Expires
Sun, Feb 23, 7:54 PM (5 h, 14 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
5e/72/2fc290d288957bde96b0ed4fb4a7

Event Timeline