chiasmusjob.cpp
1 /*
2  chiasmusjob.cpp
3 
4  This file is part of libkleopatra, the KDE keymanagement library
5  Copyright (c) 2005 Klarälvdalens Datakonsult AB
6 
7  Libkleopatra is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of the
10  License, or (at your option) any later version.
11 
12  Libkleopatra is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 
21  In addition, as a special exception, the copyright holders give
22  permission to link the code of this program with any edition of
23  the TQt library by Trolltech AS, Norway (or with modified versions
24  of TQt that use the same license as TQt), and distribute linked
25  combinations including the two. You must obey the GNU General
26  Public License in all respects for all of the code used other than
27  TQt. If you modify this file, you may extend this exception to
28  your version of the file, but you are not obligated to do so. If
29  you do not wish to do so, delete this exception statement from
30  your version.
31 */
32 
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36 
37 #include "chiasmusjob.h"
38 #include "chiasmusbackend.h"
39 #include "symcryptrunprocessbase.h"
40 
41 #include "kleo/cryptoconfig.h"
42 #include "ui/passphrasedialog.h"
43 
44 #include <gpg-error.h>
45 
46 #include <kshell.h>
47 #include <tdelocale.h>
48 #include <kdebug.h>
49 #include <tdemessagebox.h>
50 
51 #include <tqtimer.h>
52 #include <tqfileinfo.h>
53 #include <tqvariant.h>
54 
55 #include <memory>
56 
57 #include <cassert>
58 
59 Kleo::ChiasmusJob::ChiasmusJob( Mode mode )
60  : Kleo::SpecialJob( 0, 0 ),
61  mSymCryptRun( 0 ),
62  mError( 0 ),
63  mCanceled( false ),
64  mTimeout( false ),
65  mMode( mode )
66 {
67 
68 }
69 
70 Kleo::ChiasmusJob::~ChiasmusJob() {}
71 
72 GpgME::Error Kleo::ChiasmusJob::setup() {
73  if ( !checkPreconditions() )
74  return mError = gpg_error( GPG_ERR_INV_VALUE );
75 
76  const Kleo::CryptoConfigEntry * class_
77  = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "symcryptrun-class" );
78  const Kleo::CryptoConfigEntry * chiasmus
79  = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "path" );
80  const Kleo::CryptoConfigEntry * timeoutEntry
81  = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "timeout" );
82  if ( !class_ || !chiasmus || !timeoutEntry )
83  return mError = gpg_error( GPG_ERR_INTERNAL );
84 
85  mSymCryptRun = new SymCryptRunProcessBase( class_->stringValue(),
86  KShell::tildeExpand( chiasmus->urlValue().path() ),
87  mKey, mOptions,
88  mMode == Encrypt
89  ? SymCryptRunProcessBase::Encrypt
90  : SymCryptRunProcessBase::Decrypt,
91  this, "symcryptrun" );
92  TQTimer::singleShot( timeoutEntry->uintValue() * 1000, this,
93  TQ_SLOT( slotTimeout() ) );
94  return 0;
95 }
96 
97 namespace {
98  struct LaterDeleter {
99  TQObject * _this;
100  LaterDeleter( TQObject * o ) : _this( o ) {}
101  ~LaterDeleter() { if ( _this ) _this->deleteLater(); }
102  void disable() { _this = 0; }
103  };
104 }
105 
106 GpgME::Error Kleo::ChiasmusJob::start() {
107 
108  LaterDeleter d( this );
109 
110  if ( const GpgME::Error err = setup() )
111  return mError = err;
112 
113  connect( mSymCryptRun, TQ_SIGNAL(processExited(TDEProcess*)),
114  this, TQ_SLOT(slotProcessExited(TDEProcess*)) );
115 
116  if ( !mSymCryptRun->launch( mInput ) )
117  return mError = gpg_error( GPG_ERR_ENOENT ); // what else?
118 
119  d.disable();
120  return mError = 0;
121 }
122 
123 GpgME::Error Kleo::ChiasmusJob::slotProcessExited( TDEProcess * proc ) {
124  if ( proc != mSymCryptRun )
125  mError = gpg_error( GPG_ERR_INTERNAL );
126  else if ( mCanceled )
127  mError = gpg_error( GPG_ERR_CANCELED );
128  else if ( mTimeout )
129  mError = gpg_error( GPG_ERR_TIMEOUT );
130  else if ( !proc->normalExit() )
131  mError = gpg_error( GPG_ERR_GENERAL );
132  else
133  switch ( proc->exitStatus() ) {
134  case 0: // success
135  mOutput = mSymCryptRun->output();
136  mError = 0;
137  break;
138  default:
139  case 1: // Some error occured
140  mStderr = mSymCryptRun->stdErr();
141  mError = gpg_error( GPG_ERR_GENERAL );
142  break;
143  case 2: // No valid passphrase was provided
144  mError = gpg_error( GPG_ERR_INV_PASSPHRASE );
145  break;
146  case 3: // Canceled
147  mError = gpg_error( GPG_ERR_CANCELED );
148  break;
149  }
150 
151  const Kleo::CryptoConfigEntry * showOutput
152  = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "show-output" );
153  if ( showOutput && showOutput->boolValue() ) {
154  showChiasmusOutput();
155  }
156 
157  emit done();
158  emit SpecialJob::result( mError, TQVariant( mOutput ) );
159  return mError;
160 }
161 
162 void Kleo::ChiasmusJob::showChiasmusOutput() {
163  kdDebug() << k_funcinfo << endl;
164  if ( mStderr.isEmpty() )
165  return;
166  KMessageBox::information( 0 /*how to get a parent widget?*/,
167  mStderr,
168  i18n( "Output from chiasmus" ) );
169 }
170 
171 GpgME::Error Kleo::ChiasmusJob::exec() {
172  if ( const GpgME::Error err = setup() )
173  return mError = err;
174 
175  if ( !mSymCryptRun->launch( mInput, TDEProcess::Block ) ) {
176  delete mSymCryptRun; mSymCryptRun = 0;
177  return mError = gpg_error( GPG_ERR_ENOENT ); // what else?
178  }
179 
180  const GpgME::Error err = slotProcessExited( mSymCryptRun );
181  delete mSymCryptRun; mSymCryptRun = 0;
182  return err;
183 }
184 
185 bool Kleo::ChiasmusJob::checkPreconditions() const {
186  return !mKey.isEmpty();
187 }
188 
189 void Kleo::ChiasmusJob::slotCancel() {
190  if ( mSymCryptRun )
191  mSymCryptRun->kill();
192  mCanceled = true;
193 }
194 
195 void Kleo::ChiasmusJob::slotTimeout() {
196  if ( !mSymCryptRun )
197  return;
198  mSymCryptRun->kill();
199  mTimeout = true;
200 }
201 
202 
203 void Kleo::ChiasmusJob::showErrorDialog( TQWidget * parent, const TQString & caption ) const {
204  if ( !mError )
205  return;
206  if ( mError.isCanceled() )
207  return;
208  const TQString msg = ( mMode == Encrypt
209  ? i18n( "Encryption failed: %1" )
210  : i18n( "Decryption failed: %1" ) )
211  .arg( TQString::fromLocal8Bit( mError.asString() ) );
212  if ( !mStderr.isEmpty() ) {
213  const TQString details = i18n( "The following was received on stderr:\n%1" ).arg( mStderr );
214  KMessageBox::detailedError( parent, msg, details, caption );
215  } else {
216  KMessageBox::error( parent, msg, caption );
217  }
218 }
219 
220 #include "chiasmusjob.moc"
GpgME::Error exec()
void showErrorDialog(TQWidget *, const TQString &) const
GpgME::Error start()
Description of a single option.
Definition: cryptoconfig.h:49
virtual TQString stringValue() const =0
Return value as a string (available for all argtypes) The returned string can be empty (explicitely s...
virtual unsigned int uintValue() const =0
Return value as an unsigned int.
virtual bool boolValue() const =0
Return value as a bool (only allowed for ArgType_None)
virtual KURL urlValue() const =0
Return value as a URL (only meaningful for Path and URL argtypes)