Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F34023990
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
9 KB
Subscribers
None
View Options
diff --git a/editinteractor.cpp b/editinteractor.cpp
index 3ecff719..2da11561 100644
--- a/editinteractor.cpp
+++ b/editinteractor.cpp
@@ -1,321 +1,325 @@
/*
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 <config-gpgme++.h>
#include "editinteractor.h"
#include "callbacks.h"
#include "error.h"
#include <gpg-error.h>
#ifdef _WIN32
# include <io.h>
#include <windows.h>
#else
# include <unistd.h>
#endif
#include <cerrno>
#include <cstring>
using namespace GpgME;
static const char * status_to_string( unsigned int status );
static Error status_to_error( unsigned int status );
class EditInteractor::Private {
friend class ::GpgME::EditInteractor;
friend class ::GpgME::CallbackHelper;
EditInteractor * const q;
public:
explicit Private( EditInteractor * qq );
~Private();
private:
unsigned int state;
Error error;
std::FILE * debug;
};
class GpgME::CallbackHelper {
private:
static int writeAll( int fd, const void * buf, size_t count ) {
size_t toWrite = count;
while ( toWrite > 0 ) {
#ifdef Q_OS_WIN
DWORD n;
if ( !WriteFile( (HANDLE)fd, buf, toWrite, &n, NULL ) )
return -1;
#else
const int n = write( fd, buf, toWrite );
#endif
if ( n < 0 )
return n;
toWrite -= n;
}
return count;
}
public:
static int edit_interactor_callback_impl( void * opaque, gpgme_status_code_t status, const char * args, int fd ) {
EditInteractor::Private * ei = (EditInteractor::Private*)opaque;
Error err = status_to_error( status );
if ( !err ) {
// advance to next state based on input:
const unsigned int oldState = ei->state;
ei->state = ei->q->nextState( status, args, err );
if ( ei->debug )
std::fprintf( ei->debug, "EditInteractor: %u -> nextState( %s, %s ) -> %u\n",
oldState, status_to_string(status), args ? args : "<null>", ei->state );
if ( err ) {
ei->state = oldState;
goto error;
}
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( err ) ) {
if ( err )
goto error;
if ( ei->debug )
std::fprintf( ei->debug, "EditInteractor: action result \"%s\"\n", result );
// if there's a result, write it:
if ( *result ) {
errno = 0;
if ( writeAll( fd, result, std::strlen( result ) ) != std::strlen( result ) ) {
err = Error( gpg_error_from_syserror() );
if ( ei->debug )
std::fprintf( ei->debug, "EditInteractor: Could not write to fd %d (%s)\n", fd, strerror( errno ) );
goto error;
}
}
errno = 0;
if ( writeAll( fd, "\n", 1 ) != 1 ) {
err = Error( gpg_error_from_syserror() );
if ( ei->debug )
std::fprintf( ei->debug, "EditInteractor: Could not write to fd %d (%s)\n", fd, strerror( errno ) );
goto error;
}
} else {
if ( err )
goto error;
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" );
}
}
error:
if ( 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();
}
};
static gpgme_error_t edit_interactor_callback( void * opaque, gpgme_status_code_t status, const char * args, int fd )
{
return CallbackHelper::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(),
debug(0)
{
}
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;
}
}
// static
Error status_to_error( unsigned int status ) {
switch ( status ) {
case GPGME_STATUS_MISSING_PASSPHRASE:
return Error( gpg_error( GPG_ERR_NO_PASSPHRASE ) );
case GPGME_STATUS_ALREADY_SIGNED:
return Error( gpg_error( GPG_ERR_ALREADY_SIGNED ) );
+ case GPGME_STATUS_KEYEXPIRED:
+ return Error( gpg_error( GPG_ERR_CERT_EXPIRED ) );
+ case GPGME_STATUS_SIGEXPIRED:
+ return Error( gpg_error( GPG_ERR_SIG_EXPIRED ) );
}
return Error();
}
void EditInteractor::setDebugChannel( std::FILE * debug ) {
d->debug = debug;
}
static const char * status_strings[] = {
"EOF",
/* mkstatus processing starts here */
"ENTER",
"LEAVE",
"ABORT",
"GOODSIG",
"BADSIG",
"ERRSIG",
"BADARMOR",
"RSA_OR_IDEA",
"KEYEXPIRED",
"KEYREVOKED",
"TRUST_UNDEFINED",
"TRUST_NEVER",
"TRUST_MARGINAL",
"TRUST_FULLY",
"TRUST_ULTIMATE",
"SHM_INFO",
"SHM_GET",
"SHM_GET_BOOL",
"SHM_GET_HIDDEN",
"NEED_PASSPHRASE",
"VALIDSIG",
"SIG_ID",
"ENC_TO",
"NODATA",
"BAD_PASSPHRASE",
"NO_PUBKEY",
"NO_SECKEY",
"NEED_PASSPHRASE_SYM",
"DECRYPTION_FAILED",
"DECRYPTION_OKAY",
"MISSING_PASSPHRASE",
"GOOD_PASSPHRASE",
"GOODMDC",
"BADMDC",
"ERRMDC",
"IMPORTED",
"IMPORT_OK",
"IMPORT_PROBLEM",
"IMPORT_RES",
"FILE_START",
"FILE_DONE",
"FILE_ERROR",
"BEGIN_DECRYPTION",
"END_DECRYPTION",
"BEGIN_ENCRYPTION",
"END_ENCRYPTION",
"DELETE_PROBLEM",
"GET_BOOL",
"GET_LINE",
"GET_HIDDEN",
"GOT_IT",
"PROGRESS",
"SIG_CREATED",
"SESSION_KEY",
"NOTATION_NAME",
"NOTATION_DATA",
"POLICY_URL",
"BEGIN_STREAM",
"END_STREAM",
"KEY_CREATED",
"USERID_HINT",
"UNEXPECTED",
"INV_RECP",
"NO_RECP",
"ALREADY_SIGNED",
"SIGEXPIRED",
"EXPSIG",
"EXPKEYSIG",
"TRUNCATED",
"ERROR",
"NEWSIG",
"REVKEYSIG",
"SIG_SUBPACKET",
"NEED_PASSPHRASE_PIN",
"SC_OP_FAILURE",
"SC_OP_SUCCESS",
"CARDCTRL",
"BACKUP_KEY_CREATED",
"PKA_TRUST_BAD",
"PKA_TRUST_GOOD",
"PLAINTEXT",
};
static const unsigned int num_status_strings = sizeof status_strings / sizeof *status_strings ;
const char * status_to_string( unsigned int idx ) {
if ( idx < num_status_strings )
return status_strings[idx];
else
return "(unknown)";
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Nov 29, 6:58 AM (1 d, 12 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
aa/a3/0f47be5c8a343ba709579e8e251b
Attached To
rGPGMEPP Gpgme plus plus
Event Timeline
Log In to Comment