qgpgmesecretkeyexportjob.cpp
1 /*
2  qgpgmesecretexportjob.cpp
3 
4  This file is part of libkleopatra, the KDE keymanagement library
5  Copyright (c) 2004 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 "qgpgmesecretkeyexportjob.h"
38 
39 #include "gnupgprocessbase.h"
40 #include "qgpgmeprogresstokenmapper.h"
41 
42 #include <kdebug.h>
43 
44 #include <gpgmepp/context.h>
45 #include <gpgmepp/data.h>
46 
47 #include <qgpgme/eventloopinteractor.h>
48 
49 #include <tqstringlist.h>
50 
51 #include <gpg-error.h>
52 
53 #include <string.h>
54 #include <assert.h>
55 
56 Kleo::QGpgMESecretKeyExportJob::QGpgMESecretKeyExportJob( bool armour, const TQString& charset )
57  : ExportJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMESecretKeyExportJob" ),
58  mProcess( 0 ),
59  mError( 0 ),
60  mArmour( armour ),
61  mCharset( charset )
62 {
63 
64 }
65 
66 Kleo::QGpgMESecretKeyExportJob::~QGpgMESecretKeyExportJob() {
67 
68 }
69 
70 GpgME::Error Kleo::QGpgMESecretKeyExportJob::start( const TQStringList & patterns ) {
71  assert( mKeyData.isEmpty() );
72 
73  if ( patterns.size() != 1 || patterns.front().isEmpty() ) {
74  deleteLater();
75  return mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_INV_VALUE );
76  }
77 
78  // create and start gpgsm process:
79  mProcess = new GnuPGProcessBase( this, "gpgsm --export-secret-key-p12" );
80 
81  // FIXME: obtain the path to gpgsm from gpgme, so we use the same instance.
82  *mProcess << "gpgsm" << "--export-secret-key-p12";
83  if ( mArmour )
84  *mProcess << "--armor";
85  if ( !mCharset.isEmpty() )
86  *mProcess << "--p12-charset" << mCharset;
87  *mProcess << patterns.front().utf8();
88 
89  mProcess->setUsetStatusFD( true );
90 
91  connect( mProcess, TQ_SIGNAL(processExited(TDEProcess*)),
92  TQ_SLOT(slotProcessExited(TDEProcess*)) );
93  connect( mProcess, TQ_SIGNAL(receivedStdout(TDEProcess*,char*,int)),
94  TQ_SLOT(slotStdout(TDEProcess*,char*,int)) );
95  connect( mProcess, TQ_SIGNAL(receivedStderr(TDEProcess*,char*,int)),
96  TQ_SLOT(slotStderr(TDEProcess*,char*,int)) );
97  connect( mProcess, TQ_SIGNAL(status(Kleo::GnuPGProcessBase*,const TQString&,const TQStringList&)),
98  TQ_SLOT(slotStatus(Kleo::GnuPGProcessBase*,const TQString&,const TQStringList&)) );
99 
100  if ( !mProcess->start( TDEProcess::NotifyOnExit, TDEProcess::AllOutput ) ) {
101  mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_ENOENT ); // what else?
102  deleteLater();
103  return mError;
104  } else
105  return 0;
106 }
107 
108 void Kleo::QGpgMESecretKeyExportJob::slotCancel() {
109  if ( mProcess )
110  mProcess->kill();
111  mProcess = 0;
112  mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_CANCELED );
113 }
114 
115 void Kleo::QGpgMESecretKeyExportJob::slotStatus( GnuPGProcessBase * proc, const TQString & type, const TQStringList & args ) {
116  if ( proc != mProcess )
117  return;
118  TQStringList::const_iterator it = args.begin();
119  bool ok = false;
120 
121  if ( type == "ERROR" ) {
122 
123 
124  if ( args.size() < 2 ) {
125  kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() not recognising ERROR with < 2 args!" << endl;
126  return;
127  }
128  const int source = (*++it).toInt( &ok );
129  if ( !ok ) {
130  kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() expected number for first ERROR arg, got something else" << endl;
131  return;
132  }
133  ok = false;
134  const int code = (*++it).toInt( &ok );
135  if ( !ok ) {
136  kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() expected number for second ERROR arg, got something else" << endl;
137  return;
138  }
139  mError = gpg_err_make( (gpg_err_source_t)source, (gpg_err_code_t)code );
140 
141 
142  } else if ( type == "PROGRESS" ) {
143 
144 
145  if ( args.size() < 4 ) {
146  kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() not recognising PROGRESS with < 4 args!" << endl;
147  return;
148  }
149  const TQString what = *++it;
150  ++it; // don't use "type"...
151  const int cur = (*++it).toInt( &ok );
152  if ( !ok ) {
153  kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() expected number for \"cur\", got something else" << endl;
154  return;
155  }
156  ok = false;
157  const int total = (*++it).toInt( &ok );
158  if ( !ok ) {
159  kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() expected number for \"total\", got something else" << endl;
160  return;
161  }
162  emit progress( QGpgMEProgressTokenMapper::instance()->map( what, 0, cur, total ), cur, total );
163 
164 
165  }
166 }
167 
168 void Kleo::QGpgMESecretKeyExportJob::slotStdout( TDEProcess * proc, char * buf, int buflen ) {
169  if ( proc != mProcess )
170  return;
171  if ( buflen <= 0 )
172  return;
173  if ( !buf )
174  return;
175  const unsigned int oldlen = mKeyData.size();
176  mKeyData.resize( oldlen + buflen );
177  memcpy( mKeyData.data() + oldlen, buf, buflen );
178 }
179 
180 void Kleo::QGpgMESecretKeyExportJob::slotStderr( TDEProcess *, char *, int ) {
181  // implement? or not?
182 }
183 
184 void Kleo::QGpgMESecretKeyExportJob::slotProcessExited( TDEProcess * proc ) {
185  if ( proc != mProcess )
186  return;
187 
188  emit done();
189  if ( !mError &&
190  ( !mProcess->normalExit() || mProcess->exitStatus() != 0 ) )
191  mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_GENERAL );
192  emit result( mError, mKeyData );
193  deleteLater();
194 }
195 
196 #include "qgpgmesecretkeyexportjob.moc"
a base class for GPG and GPGSM processes.