certmanager/lib
chiasmusjob.cpp00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifdef HAVE_CONFIG_H
00034 #include <config.h>
00035 #endif
00036
00037 #include "chiasmusjob.h"
00038 #include "chiasmusbackend.h"
00039 #include "symcryptrunprocessbase.h"
00040
00041 #include "kleo/cryptoconfig.h"
00042 #include "ui/passphrasedialog.h"
00043
00044 #include <gpg-error.h>
00045
00046 #include <kshell.h>
00047 #include <klocale.h>
00048 #include <kdebug.h>
00049 #include <kmessagebox.h>
00050
00051 #include <qtimer.h>
00052 #include <qfileinfo.h>
00053 #include <qvariant.h>
00054
00055 #include <memory>
00056
00057 #include <cassert>
00058
00059 Kleo::ChiasmusJob::ChiasmusJob( Mode mode )
00060 : Kleo::SpecialJob( 0, 0 ),
00061 mSymCryptRun( 0 ),
00062 mError( 0 ),
00063 mCanceled( false ),
00064 mTimeout( false ),
00065 mMode( mode )
00066 {
00067
00068 }
00069
00070 Kleo::ChiasmusJob::~ChiasmusJob() {}
00071
00072 GpgME::Error Kleo::ChiasmusJob::setup() {
00073 if ( !checkPreconditions() )
00074 return mError = gpg_error( GPG_ERR_INV_VALUE );
00075
00076 const Kleo::CryptoConfigEntry * class_
00077 = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "symcryptrun-class" );
00078 const Kleo::CryptoConfigEntry * chiasmus
00079 = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "path" );
00080 const Kleo::CryptoConfigEntry * timeoutEntry
00081 = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "timeout" );
00082 if ( !class_ || !chiasmus || !timeoutEntry )
00083 return mError = gpg_error( GPG_ERR_INTERNAL );
00084
00085 mSymCryptRun = new SymCryptRunProcessBase( class_->stringValue(),
00086 KShell::tildeExpand( chiasmus->urlValue().path() ),
00087 mKey, mOptions,
00088 mMode == Encrypt
00089 ? SymCryptRunProcessBase::Encrypt
00090 : SymCryptRunProcessBase::Decrypt,
00091 this, "symcryptrun" );
00092 QTimer::singleShot( timeoutEntry->uintValue() * 1000, this,
00093 SLOT( slotTimeout() ) );
00094 return 0;
00095 }
00096
00097 namespace {
00098 struct LaterDeleter {
00099 QObject * _this;
00100 LaterDeleter( QObject * o ) : _this( o ) {}
00101 ~LaterDeleter() { if ( _this ) _this->deleteLater(); }
00102 void disable() { _this = 0; }
00103 };
00104 }
00105
00106 GpgME::Error Kleo::ChiasmusJob::start() {
00107
00108 LaterDeleter d( this );
00109
00110 if ( const GpgME::Error err = setup() )
00111 return mError = err;
00112
00113 connect( mSymCryptRun, SIGNAL(processExited(KProcess*)),
00114 this, SLOT(slotProcessExited(KProcess*)) );
00115
00116 if ( !mSymCryptRun->launch( mInput ) )
00117 return mError = gpg_error( GPG_ERR_ENOENT );
00118
00119 d.disable();
00120 return mError = 0;
00121 }
00122
00123 GpgME::Error Kleo::ChiasmusJob::slotProcessExited( KProcess * proc ) {
00124 if ( proc != mSymCryptRun )
00125 mError = gpg_error( GPG_ERR_INTERNAL );
00126 else if ( mCanceled )
00127 mError = gpg_error( GPG_ERR_CANCELED );
00128 else if ( mTimeout )
00129 mError = gpg_error( GPG_ERR_TIMEOUT );
00130 else if ( !proc->normalExit() )
00131 mError = gpg_error( GPG_ERR_GENERAL );
00132 else
00133 switch ( proc->exitStatus() ) {
00134 case 0:
00135 mOutput = mSymCryptRun->output();
00136 mError = 0;
00137 break;
00138 default:
00139 case 1:
00140 mStderr = mSymCryptRun->stdErr();
00141 mError = gpg_error( GPG_ERR_GENERAL );
00142 break;
00143 case 2:
00144 mError = gpg_error( GPG_ERR_INV_PASSPHRASE );
00145 break;
00146 case 3:
00147 mError = gpg_error( GPG_ERR_CANCELED );
00148 break;
00149 }
00150
00151 const Kleo::CryptoConfigEntry * showOutput
00152 = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "show-output" );
00153 if ( showOutput && showOutput->boolValue() ) {
00154 showChiasmusOutput();
00155 }
00156
00157 emit done();
00158 emit SpecialJob::result( mError, QVariant( mOutput ) );
00159 return mError;
00160 }
00161
00162 void Kleo::ChiasmusJob::showChiasmusOutput() {
00163 kdDebug() << k_funcinfo << endl;
00164 if ( mStderr.isEmpty() )
00165 return;
00166 KMessageBox::information( 0 ,
00167 mStderr,
00168 i18n( "Output from chiasmus" ) );
00169 }
00170
00171 GpgME::Error Kleo::ChiasmusJob::exec() {
00172 if ( const GpgME::Error err = setup() )
00173 return mError = err;
00174
00175 if ( !mSymCryptRun->launch( mInput, KProcess::Block ) ) {
00176 delete mSymCryptRun; mSymCryptRun = 0;
00177 return mError = gpg_error( GPG_ERR_ENOENT );
00178 }
00179
00180 const GpgME::Error err = slotProcessExited( mSymCryptRun );
00181 delete mSymCryptRun; mSymCryptRun = 0;
00182 return err;
00183 }
00184
00185 bool Kleo::ChiasmusJob::checkPreconditions() const {
00186 return !mKey.isEmpty();
00187 }
00188
00189 void Kleo::ChiasmusJob::slotCancel() {
00190 if ( mSymCryptRun )
00191 mSymCryptRun->kill();
00192 mCanceled = true;
00193 }
00194
00195 void Kleo::ChiasmusJob::slotTimeout() {
00196 if ( !mSymCryptRun )
00197 return;
00198 mSymCryptRun->kill();
00199 mTimeout = true;
00200 }
00201
00202
00203 void Kleo::ChiasmusJob::showErrorDialog( QWidget * parent, const QString & caption ) const {
00204 if ( !mError )
00205 return;
00206 if ( mError.isCanceled() )
00207 return;
00208 const QString msg = ( mMode == Encrypt
00209 ? i18n( "Encryption failed: %1" )
00210 : i18n( "Decryption failed: %1" ) )
00211 .arg( QString::fromLocal8Bit( mError.asString() ) );
00212 if ( !mStderr.isEmpty() ) {
00213 const QString details = i18n( "The following was received on stderr:\n%1" ).arg( mStderr );
00214 KMessageBox::detailedError( parent, msg, details, caption );
00215 } else {
00216 KMessageBox::error( parent, msg, caption );
00217 }
00218 }
00219
00220 #include "chiasmusjob.moc"
|