libkpgp

kpgpbase.cpp
1 /*
2  kpgpbase.cpp
3 
4  Copyright (C) 2001,2002 the KPGP authors
5  See file AUTHORS.kpgp for details
6 
7  This file is part of KPGP, the KDE PGP/GnuPG support library.
8 
9  KPGP is free software; you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 2 of the License, or
12  (at your option) any later version.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software Foundation,
16  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18 
19 #include <kdebug.h>
20 
21 #include <config.h>
22 
23 #include "kpgpbase.h"
24 #include "kpgp.h"
25 #include "kpgpblock.h"
26 
27 #include <stdlib.h> /* setenv, unsetenv */
28 #include <unistd.h> /* pipe, close, fork, dup2, execl, _exit, write, read */
29 #include <sys/poll.h> /* poll, etc. */
30 #include <sys/types.h> /* pid_t */
31 #include <sys/wait.h> /* waitpid */
32 #include <errno.h>
33 
34 #include <tqapplication.h>
35 
36 
37 namespace Kpgp {
38 
39 Base::Base()
40  : input(), output(), error(), errMsg(), status(OK)
41 {
42 }
43 
44 
45 Base::~Base()
46 {
47 }
48 
49 
50 void
51 Base::clear()
52 {
53  input = TQCString();
54  output = TQCString();
55  error = TQCString();
56  errMsg = TQString();
57  status = OK;
58 }
59 
60 
61 int
62 Base::run( const char *cmd, const char *passphrase, bool onlyReadFromPGP )
63 {
64  /* the pipe ppass is used for to pass the password to
65  * pgp. passing the password together with the normal input through
66  * stdin doesn't seem to work as expected (at least for pgp5.0)
67  */
68  char str[1025] = "\0";
69  int pin[2], pout[2], perr[2], ppass[2];
70  int len, len2;
71  FILE *pass;
72  pid_t child_pid;
73  int childExiStatus;
74  struct pollfd pollin, pollout, pollerr;
75  int pollstatus;
76 
77  if(passphrase)
78  {
79  if (pipe(ppass) < 0) {
80  // An error occurred
81  // FIXME
82  printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
83  }
84 
85  pass = fdopen(ppass[1], "w");
86  fwrite(passphrase, sizeof(char), strlen(passphrase), pass);
87  fwrite("\n", sizeof(char), 1, pass);
88  fclose(pass);
89  close(ppass[1]);
90 
91  // tell pgp which fd to use for the passphrase
92  TQCString tmp;
93  tmp.sprintf("%d",ppass[0]);
94  ::setenv("PGPPASSFD",tmp.data(),1);
95 
96  //Uncomment these lines for testing only! Doing so will decrease security!
97  //kdDebug(5100) << "pgp PGPPASSFD = " << tmp << endl;
98  //kdDebug(5100) << "pgp pass = " << passphrase << endl;
99  }
100  else
101  ::unsetenv("PGPPASSFD");
102 
103  //Uncomment these lines for testing only! Doing so will decrease security!
104  kdDebug(5100) << "pgp cmd = " << cmd << endl;
105  //kdDebug(5100) << "pgp input = " << TQString(input)
106  // << "input length = " << input.length() << endl;
107 
108  error = "";
109  output = "";
110 
111  if (pipe(pin) < 0) {
112  // An error occurred
113  // FIXME
114  printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
115  }
116  if (pipe(pout) < 0) {
117  // An error occurred
118  // FIXME
119  printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
120  }
121  if (pipe(perr) < 0) {
122  // An error occurred
123  // FIXME
124  printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
125  }
126 
127  TQApplication::flushX();
128  if(!(child_pid = fork()))
129  {
130  /*We're the child.*/
131  close(pin[1]);
132  dup2(pin[0], 0);
133  close(pin[0]);
134 
135  close(pout[0]);
136  dup2(pout[1], 1);
137  close(pout[1]);
138 
139  close(perr[0]);
140  dup2(perr[1], 2);
141  close(perr[1]);
142 
143  execl("/bin/sh", "sh", "-c", cmd, (void *)0);
144  _exit(127);
145  }
146 
147  /*Only get here if we're the parent.*/
148  close(pin[0]);
149  close(pout[1]);
150  close(perr[1]);
151 
152  // poll for "There is data to read."
153  pollout.fd = pout[0];
154  pollout.events = POLLIN;
155  pollout.revents = 0; // init with 0, just in case
156  pollerr.fd = perr[0];
157  pollerr.events = POLLIN;
158  pollerr.revents = 0; // init with 0, just in case
159 
160  // poll for "Writing now will not block."
161  pollin.fd = pin[1];
162  pollin.events = POLLOUT;
163  pollin.revents = 0; // init with 0, just in case
164 
165  if (!onlyReadFromPGP) {
166  if (!input.isEmpty()) {
167  // write to pin[1] one line after the other to prevent dead lock
168  uint input_length = input.length();
169  for (unsigned int i=0; i<input_length; i+=len2) {
170  len2 = 0;
171 
172  // check if writing now to pin[1] will not block (5 ms timeout)
173  //kdDebug(5100) << "Polling pin[1]..." << endl;
174  pollstatus = poll(&pollin, 1, 5);
175  if (pollstatus == 1) {
176  //kdDebug(5100) << "Status for polling pin[1]: " << pollin.revents << endl;
177  if (pollin.revents & POLLERR) {
178  kdDebug(5100) << "PGP seems to have hung up" << endl;
179  break;
180  }
181  else if (pollin.revents & POLLOUT) {
182  // search end of next line
183  if ((len2 = input.find('\n', i)) == -1)
184  len2 = input_length - i;
185  else
186  len2 = len2 - i + 1;
187 
188  //kdDebug(5100) << "Trying to write " << len2 << " bytes to pin[1] ..." << endl;
189  len2 = write(pin[1], input.data() + i, len2);
190  //kdDebug(5100) << "Wrote " << len2 << " bytes to pin[1] ..." << endl;
191  }
192  }
193  else if (!pollstatus) {
194  //kdDebug(5100) << "Timeout while polling pin[1]: "
195  // << pollin.revents << endl;
196  }
197  else if (pollstatus == -1) {
198  kdDebug(5100) << "Error while polling pin[1]: "
199  << pollin.revents << endl;
200  }
201 
202  if (pout[0] >= 0) {
203  do {
204  // check if there is data to read from pout[0]
205  //kdDebug(5100) << "Polling pout[0]..." << endl;
206  pollstatus = poll(&pollout, 1, 0);
207  if (pollstatus == 1) {
208  //kdDebug(5100) << "Status for polling pout[0]: " << pollout.revents << endl;
209  if (pollout.revents & POLLIN) {
210  //kdDebug(5100) << "Trying to read " << 1024 << " bytes from pout[0]" << endl;
211  if ((len = read(pout[0],str,1024))>0) {
212  //kdDebug(5100) << "Read " << len << " bytes from pout[0]" << endl;
213  str[len] ='\0';
214  output += str;
215  }
216  else
217  break;
218  }
219  }
220  else if (pollstatus == -1) {
221  kdDebug(5100) << "Error while polling pout[0]: "
222  << pollout.revents << endl;
223  }
224  } while ((pollstatus == 1) && (pollout.revents & POLLIN));
225  }
226 
227  if (perr[0] >= 0) {
228  do {
229  // check if there is data to read from perr[0]
230  //kdDebug(5100) << "Polling perr[0]..." << endl;
231  pollstatus = poll(&pollerr, 1, 0);
232  if (pollstatus == 1) {
233  //kdDebug(5100) << "Status for polling perr[0]: " << pollerr.revents << endl;
234  if (pollerr.revents & POLLIN) {
235  //kdDebug(5100) << "Trying to read " << 1024 << " bytes from perr[0]" << endl;
236  if ((len = read(perr[0],str,1024))>0) {
237  //kdDebug(5100) << "Read " << len << " bytes from perr[0]" << endl;
238  str[len] ='\0';
239  error += str;
240  }
241  else
242  break;
243  }
244  }
245  else if (pollstatus == -1) {
246  kdDebug(5100) << "Error while polling perr[0]: "
247  << pollerr.revents << endl;
248  }
249  } while ((pollstatus == 1) && (pollerr.revents & POLLIN));
250  }
251 
252  // abort writing to PGP if PGP hung up
253  if ((pollstatus == 1) &&
254  ((pollout.revents & POLLHUP) || (pollerr.revents & POLLHUP))) {
255  kdDebug(5100) << "PGP hung up" << endl;
256  break;
257  }
258  }
259  }
260  else { // if input.isEmpty()
261  if (write(pin[1], "\n", 1) < 0) {
262  // An error occurred
263  // FIXME
264  printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
265  }
266  }
267  //kdDebug(5100) << "All input was written to pin[1]" << endl;
268  }
269  close(pin[1]);
270 
271  pid_t waitpidRetVal;
272 
273  do {
274  //kdDebug(5100) << "Checking if PGP is still running..." << endl;
275  childExiStatus = 0;
276  waitpidRetVal = waitpid(child_pid, &childExiStatus, WNOHANG);
277  //kdDebug(5100) << "waitpid returned " << waitpidRetVal << endl;
278  if (pout[0] >= 0) {
279  do {
280  // check if there is data to read from pout[0]
281  //kdDebug(5100) << "Polling pout[0]..." << endl;
282  pollstatus = poll(&pollout, 1, 0);
283  if (pollstatus == 1) {
284  //kdDebug(5100) << "Status for polling pout[0]: " << pollout.revents << endl;
285  if (pollout.revents & POLLIN) {
286  //kdDebug(5100) << "Trying to read " << 1024 << " bytes from pout[0]" << endl;
287  if ((len = read(pout[0],str,1024))>0) {
288  //kdDebug(5100) << "Read " << len << " bytes from pout[0]" << endl;
289  str[len] ='\0';
290  output += str;
291  } else {
292  /*
293  * Apparently, on NetBSD when the child dies, the pipe begins
294  * receiving empty data packets *before* waitpid() has signaled
295  * that the child has died. Also, notice that this happens
296  * without any error bit being set in pollfd.revents (is this a
297  * NetBSD bug??? ). Notice that these anomalous packets exist
298  * according to poll(), but have length 0 according to read().
299  * Thus, kde can remain stuck inside this loop.
300  *
301  * A solution to this problem is to get out of the inner loop
302  * when read() returns <=0. In this way, kde has another chance
303  * to call waitpid() to check if the child has died -- and this
304  * time the call should succeed.
305  *
306  * Setting POLLHUP in pollfd.revents is not necessary, but I just
307  * like the idea of signaling that something strange has
308  * happened.
309  */
310  pollout.revents |= POLLHUP;
311  break;
312  }
313  }
314  }
315  else if (pollstatus == -1) {
316  kdDebug(5100) << "Error while polling pout[0]: "
317  << pollout.revents << endl;
318  }
319  } while ((pollstatus == 1) && (pollout.revents & POLLIN));
320  }
321 
322  if (perr[0] >= 0) {
323  do {
324  // check if there is data to read from perr[0]
325  //kdDebug(5100) << "Polling perr[0]..." << endl;
326  pollstatus = poll(&pollerr, 1, 0);
327  if (pollstatus == 1) {
328  //kdDebug(5100) << "Status for polling perr[0]: " << pollerr.revents << endl;
329  if (pollerr.revents & POLLIN) {
330  //kdDebug(5100) << "Trying to read " << 1024 << " bytes from perr[0]" << endl;
331  if ((len = read(perr[0],str,1024))>0) {
332  //kdDebug(5100) << "Read " << len << " bytes from perr[0]" << endl;
333  str[len] ='\0';
334  error += str;
335  } else {
336  /*
337  * Apparently, on NetBSD when the child dies, the pipe begins
338  * receiving empty data packets *before* waitpid() has signaled
339  * that the child has died. Also, notice that this happens
340  * without any error bit being set in pollfd.revents (is this a
341  * NetBSD bug??? ). Notice that these anomalous packets exist
342  * according to poll(), but have length 0 according to read().
343  * Thus, kde can remain stuck inside this loop.
344  *
345  * A solution to this problem is to get out of the inner loop
346  * when read() returns <=0. In this way, kde has another chance
347  * to call waitpid() to check if the child has died -- and this
348  * time the call should succeed.
349  *
350  * Setting POLLHUP in pollfd.revents is not necessary, but I just
351  * like the idea of signaling that something strange has
352  * happened.
353  */
354  pollerr.revents |= POLLHUP;
355  break;
356  }
357  }
358  }
359  else if (pollstatus == -1) {
360  kdDebug(5100) << "Error while polling perr[0]: "
361  << pollerr.revents << endl;
362  }
363  } while ((pollstatus == 1) && (pollerr.revents & POLLIN));
364  }
365  } while (waitpidRetVal == 0);
366 
367  close(pout[0]);
368  close(perr[0]);
369 
370  unsetenv("PGPPASSFD");
371  if(passphrase)
372  close(ppass[0]);
373 
374  // Did the child exit normally?
375  if (WIFEXITED(childExiStatus) != 0) {
376  // Get the return code of the child
377  childExiStatus = WEXITSTATUS(childExiStatus);
378  kdDebug(5100) << "PGP exited with exit status " << childExiStatus
379  << endl;
380  }
381  else {
382  childExiStatus = -1;
383  kdDebug(5100) << "PGP exited abnormally!" << endl;
384  }
385 
386  //Uncomment these lines for testing only! Doing so will decrease security!
387  //kdDebug(5100) << "pgp output = " << TQString(output) << endl;
388  //kdDebug(5100) << "pgp error = " << error << endl;
389 
390  /* Make the information visible, so that a user can
391  * get to know what's going on during the pgp calls.
392  */
393  kdDebug(5100) << error << endl;
394 
395  return childExiStatus;
396 }
397 
398 
399 int
400 Base::runGpg( const char *cmd, const char *passphrase, bool onlyReadFromGnuPG )
401 {
402  /* the pipe ppass is used for to pass the password to
403  * pgp. passing the password together with the normal input through
404  * stdin doesn't seem to work as expected (at least for pgp5.0)
405  */
406  char str[1025] = "\0";
407  int pin[2], pout[2], perr[2], ppass[2];
408  int len, len2;
409  FILE *pass;
410  pid_t child_pid;
411  int childExiStatus;
412  char gpgcmd[1024] = "\0";
413  struct pollfd poller[3];
414  int num_pollers = 0;
415  const int STD_OUT = 0;
416  const int STD_ERR = 1;
417  const int STD_IN = 2;
418  int pollstatus;
419 
420  if(passphrase)
421  {
422  if (pipe(ppass) < 0) {
423  // An error occurred
424  // FIXME
425  printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
426  }
427 
428  pass = fdopen(ppass[1], "w");
429  fwrite(passphrase, sizeof(char), strlen(passphrase), pass);
430  fwrite("\n", sizeof(char), 1, pass);
431  fclose(pass);
432  close(ppass[1]);
433 
434  //Uncomment these lines for testing only! Doing so will decrease security!
435  //kdDebug(5100) << "pass = " << passphrase << endl;
436  }
437 
438  //Uncomment these lines for testing only! Doing so will decrease security!
439  //kdDebug(5100) << "pgp cmd = " << cmd << endl;
440  //kdDebug(5100) << "pgp input = " << TQString(input)
441  // << "input length = " << input.length() << endl;
442 
443  error = "";
444  output = "";
445 
446  if (pipe(pin) < 0) {
447  // An error occurred
448  // FIXME
449  printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
450  }
451  if (pipe(pout) < 0) {
452  // An error occurred
453  // FIXME
454  printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
455  }
456  if (pipe(perr) < 0) {
457  // An error occurred
458  // FIXME
459  printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
460  }
461 
462  if( passphrase ) {
463  if( mVersion >= "1.0.7" ) {
464  // GnuPG >= 1.0.7 supports the gpg-agent, so we look for it.
465  if( 0 == getenv("GPG_AGENT_INFO") ) {
466  // gpg-agent not found, so we tell gpg not to use the agent
467  snprintf( gpgcmd, 1023,
468  "LANGUAGE=C gpg --no-use-agent --passphrase-fd %d %s",
469  ppass[0], cmd );
470  }
471  else {
472  // gpg-agent seems to be running, so we tell gpg to use the agent
473  snprintf( gpgcmd, 1023,
474  "LANGUAGE=C gpg --use-agent %s",
475  cmd );
476  }
477  }
478  else {
479  // GnuPG < 1.0.7 doesn't know anything about the gpg-agent
480  snprintf( gpgcmd, 1023,
481  "LANGUAGE=C gpg --passphrase-fd %d %s",
482  ppass[0], cmd );
483  }
484  }
485  else {
486  snprintf(gpgcmd, 1023, "LANGUAGE=C gpg %s",cmd);
487  }
488 
489  TQApplication::flushX();
490  if(!(child_pid = fork()))
491  {
492  /*We're the child.*/
493  close(pin[1]);
494  dup2(pin[0], 0);
495  close(pin[0]);
496 
497  close(pout[0]);
498  dup2(pout[1], 1);
499  close(pout[1]);
500 
501  close(perr[0]);
502  dup2(perr[1], 2);
503  close(perr[1]);
504 
505  //#warning FIXME: there has to be a better way to do this
506  /* this is nasty nasty nasty (but it works) */
507  if( passphrase ) {
508  if( mVersion >= "1.0.7" ) {
509  // GnuPG >= 1.0.7 supports the gpg-agent, so we look for it.
510  if( 0 == getenv("GPG_AGENT_INFO") ) {
511  // gpg-agent not found, so we tell gpg not to use the agent
512  snprintf( gpgcmd, 1023,
513  "LANGUAGE=C gpg --no-use-agent --passphrase-fd %d %s",
514  ppass[0], cmd );
515  }
516  else {
517  // gpg-agent seems to be running, so we tell gpg to use the agent
518  snprintf( gpgcmd, 1023,
519  "LANGUAGE=C gpg --use-agent %s",
520  cmd );
521  }
522  }
523  else {
524  // GnuPG < 1.0.7 doesn't know anything about the gpg-agent
525  snprintf( gpgcmd, 1023,
526  "LANGUAGE=C gpg --passphrase-fd %d %s",
527  ppass[0], cmd );
528  }
529  }
530  else {
531  snprintf(gpgcmd, 1023, "LANGUAGE=C gpg %s",cmd);
532  }
533 
534  kdDebug(5100) << "pgp cmd = " << gpgcmd << endl;
535 
536  execl("/bin/sh", "sh", "-c", gpgcmd, (void *)0);
537  _exit(127);
538  }
539 
540  // Only get here if we're the parent.
541 
542  close(pin[0]);
543  close(pout[1]);
544  close(perr[1]);
545 
546  // poll for "There is data to read."
547  poller[STD_OUT].fd = pout[0];
548  poller[STD_OUT].events = POLLIN;
549  poller[STD_ERR].fd = perr[0];
550  poller[STD_ERR].events = POLLIN;
551  num_pollers = 2;
552 
553  if (!onlyReadFromGnuPG) {
554  // poll for "Writing now will not block."
555  poller[STD_IN].fd = pin[1];
556  poller[STD_IN].events = POLLOUT;
557  num_pollers = 3;
558  } else {
559  close (pin[1]);
560  pin[1] = -1;
561  }
562 
563  pid_t waitpidRetVal;
564  unsigned int input_pos = 0;
565  uint input_length = input.length();
566 
567  do {
568  //kdDebug(5100) << "Checking if GnuPG is still running..." << endl;
569  childExiStatus = 0;
570  waitpidRetVal = waitpid(child_pid, &childExiStatus, WNOHANG);
571  //kdDebug(5100) << "waitpid returned " << waitpidRetVal << endl;
572  do {
573  // poll the pipes
574  pollstatus = poll(poller, num_pollers, 10);
575  if( 0 < pollstatus ) {
576  // Check stdout.
577  if (poller[STD_OUT].revents & POLLIN) {
578  //kdDebug(5100) << "Trying to read " << 1024 << " bytes from pout[0]" << endl;
579  if ((len = read(pout[0],str,1024))>0) {
580  //kdDebug(5100) << "Read " << len << " bytes from pout[0]" << endl;
581  str[len] ='\0';
582  output += str;
583  }
584  else {
585  // FreeBSD/NetBSD workaround
586  //
587  // Apparently, on Free/NetBSD when the child dies, the pipe begins
588  // receiving empty data packets *before* waitpid() has signaled
589  // that the child has died. Also, notice that this happens
590  // without any error bit being set in pollfd.revents (is this a
591  // Free/NetBSD bug??? ). Notice that these anomalous packets exist
592  // according to poll(), but have length 0 according to read().
593  // Thus, we can remain stuck inside this loop.
594  //
595  // A solution to this problem is to get out of the inner loop
596  // when read() returns <=0. In this way, we have another chance
597  // to call waitpid() to check if the child has died -- and this
598  // time the call should succeed.
599  //
600  // Set POLLHUP in pollfd.revents to signal that something strange
601  // has happened and disable polling of stdout.
602  poller[STD_OUT].revents |= POLLHUP;
603  poller[STD_OUT].events = 0;
604  }
605  } else if (poller[STD_OUT].revents & POLLHUP) {
606  // disable polling of stdout
607  poller[STD_OUT].events = 0;
608  }
609 
610  // Check stderr.
611  if (poller[STD_ERR].revents & POLLIN) {
612  //kdDebug(5100) << "Trying to read " << 1024 << " bytes from perr[0]" << endl;
613  if ((len = read(poller[STD_ERR].fd,str,1024))>0) {
614  //kdDebug(5100) << "Read " << len << " bytes from perr[0]" << endl;
615  str[len] ='\0';
616  error += str;
617  }
618  else {
619  // FreeBSD/NetBSD workaround (for details see above)
620  poller[STD_ERR].revents |= POLLHUP;
621  poller[STD_ERR].events = 0;
622  }
623  } else if (poller[STD_ERR].revents & POLLHUP) {
624  // disable polling of stderr
625  poller[STD_ERR].events = 0;
626  }
627 
628  if (num_pollers > 2) {
629  if (poller[STD_IN].revents & ( POLLERR | POLLHUP ) ) {
630  kdDebug(5100) << "GnuPG seems to have hung up" << endl;
631  close (pin[1]);
632  pin[1] = -1;
633  --num_pollers;
634  }
635  else if (poller[STD_IN].revents & POLLOUT) {
636  if (!input.isEmpty()) {
637  // search end of next line
638  if ((len2 = input.find('\n', input_pos)) == -1)
639  len2 = input_length - input_pos;
640  else
641  len2 = len2 - input_pos + 1;
642 
643  //kdDebug(5100) << "Trying to write " << len2 << " bytes to pin[1] ..." << endl;
644  len2 = write(pin[1], input.data() + input_pos, len2 );
645  //kdDebug(5100) << "Wrote " << len2 << " bytes to pin[1] ..." << endl;
646  input_pos += len2;
647 
648  // We are done.
649  if (input_pos >= input_length) {
650  //kdDebug(5100) << "All input was written to pin[1]" << endl;
651  close (pin[1]);
652  pin[1] = -1;
653  --num_pollers;
654  }
655  }
656  else { // if input.isEmpty()
657  if (write(pin[1], "\n", 1) < 0) {
658  // An error occurred
659  // FIXME
660  printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
661  }
662  //kdDebug(5100) << "All input was written to pin[1]" << endl;
663  close (pin[1]);
664  pin[1] = -1;
665  --num_pollers;
666  }
667  }
668  }
669  }
670  } while ( (pollstatus > 0) && ( (num_pollers > 2)
671  || (poller[STD_OUT].events != 0)
672  || (poller[STD_ERR].events != 0) ) );
673 
674  if (pollstatus == -1) {
675  kdDebug(5100) << "GnuPG poll failed, errno: " << errno << endl;
676  }
677 
678  } while(waitpidRetVal == 0);
679 
680  if( 0 <= pin[1] )
681  close (pin[1]);
682  close(pout[0]);
683  close(perr[0]);
684 
685  if(passphrase)
686  close(ppass[0]);
687 
688  // Did the child exit normally?
689  if (WIFEXITED(childExiStatus) != 0) {
690  // Get the return code of the child
691  childExiStatus = WEXITSTATUS(childExiStatus);
692  kdDebug(5100) << "GnuPG exited with exit status " << childExiStatus
693  << endl;
694  }
695  else {
696  childExiStatus = -1;
697  kdDebug(5100) << "GnuPG exited abnormally!" << endl;
698  }
699 
700  //Uncomment these lines for testing only! Doing so will decrease security!
701  //kdDebug(5100) << "gpg stdout:\n" << TQString(output) << endl;
702 
703  // Make the information visible, so that a user can
704  // get to know what's going on during the gpg calls.
705  kdDebug(5100) << "gpg stderr:\n" << error << endl;
706 
707  return childExiStatus;
708 }
709 
710 
711 TQCString
712 Base::addUserId()
713 {
714  TQCString cmd;
715  TQCString pgpUser = Module::getKpgp()->user();
716 
717  if(!pgpUser.isEmpty())
718  {
719  cmd += " -u 0x";
720  cmd += pgpUser;
721  return cmd;
722  }
723  return TQCString();
724 }
725 
726 
727 } // namespace Kpgp
Definition: kpgp.cpp:48