certmanager/lib

chiasmusjob.cpp

00001 /*
00002     chiasmusjob.cpp
00003 
00004     This file is part of libkleopatra, the KDE keymanagement library
00005     Copyright (c) 2005 Klarälvdalens Datakonsult AB
00006 
00007     Libkleopatra is free software; you can redistribute it and/or
00008     modify it under the terms of the GNU General Public License as
00009     published by the Free Software Foundation; either version 2 of the
00010     License, or (at your option) any later version.
00011 
00012     Libkleopatra is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program; if not, write to the Free Software
00019     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021     In addition, as a special exception, the copyright holders give
00022     permission to link the code of this program with any edition of
00023     the Qt library by Trolltech AS, Norway (or with modified versions
00024     of Qt that use the same license as Qt), and distribute linked
00025     combinations including the two.  You must obey the GNU General
00026     Public License in all respects for all of the code used other than
00027     Qt.  If you modify this file, you may extend this exception to
00028     your version of the file, but you are not obligated to do so.  If
00029     you do not wish to do so, delete this exception statement from
00030     your version.
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 ); // what else?
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: // success
00135       mOutput = mSymCryptRun->output();
00136       mError = 0;
00137       break;
00138     default:
00139     case 1: // Some error occured
00140       mStderr = mSymCryptRun->stdErr();
00141       mError = gpg_error( GPG_ERR_GENERAL );
00142       break;
00143     case 2: // No valid passphrase was provided
00144       mError = gpg_error( GPG_ERR_INV_PASSPHRASE );
00145       break;
00146     case 3: // Canceled
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 /*how to get a parent widget?*/,
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 ); // what else?
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"
KDE Home | KDE Accessibility Home | Description of Access Keys