libkpgp

kpgpbase.cpp

00001 /*
00002     kpgpbase.cpp
00003 
00004     Copyright (C) 2001,2002 the KPGP authors
00005     See file AUTHORS.kpgp for details
00006 
00007     This file is part of KPGP, the KDE PGP/GnuPG support library.
00008 
00009     KPGP is free software; you can redistribute it and/or modify
00010     it under the terms of the GNU General Public License as published by
00011     the Free Software Foundation; either version 2 of the License, or
00012     (at your option) any later version.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program; if not, write to the Free Software Foundation,
00016     Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
00017  */
00018 
00019 #include <kdebug.h>
00020 
00021 #include <config.h>
00022 
00023 #include "kpgpbase.h"
00024 #include "kpgp.h"
00025 #include "kpgpblock.h"
00026 
00027 #include <stdlib.h> /* setenv, unsetenv */
00028 #include <unistd.h> /* pipe, close, fork, dup2, execl, _exit, write, read */
00029 #include <sys/poll.h>  /* poll, etc. */
00030 #include <sys/types.h> /* pid_t */
00031 #include <sys/wait.h> /* waitpid */
00032 #include <errno.h>
00033 
00034 #include <tqapplication.h>
00035 
00036 
00037 namespace Kpgp {
00038 
00039 Base::Base()
00040   : input(), output(), error(), errMsg(), status(OK)
00041 {
00042 }
00043 
00044 
00045 Base::~Base()
00046 {
00047 }
00048 
00049 
00050 void
00051 Base::clear()
00052 {
00053   input = TQCString();
00054   output = TQCString();
00055   error = TQCString();
00056   errMsg = TQString();
00057   status = OK;
00058 }
00059 
00060 
00061 int
00062 Base::run( const char *cmd, const char *passphrase, bool onlyReadFromPGP )
00063 {
00064   /* the pipe ppass is used for to pass the password to
00065    * pgp. passing the password together with the normal input through
00066    * stdin doesn't seem to work as expected (at least for pgp5.0)
00067    */
00068   char str[1025] = "\0";
00069   int pin[2], pout[2], perr[2], ppass[2];
00070   int len, len2;
00071   FILE *pass;
00072   pid_t child_pid;
00073   int childExiStatus;
00074   struct pollfd pollin, pollout, pollerr;
00075   int pollstatus;
00076 
00077   if(passphrase)
00078   {
00079     if (pipe(ppass) < 0) {
00080       // An error occurred
00081       // FIXME
00082       printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
00083     }
00084 
00085     pass = fdopen(ppass[1], "w");
00086     fwrite(passphrase, sizeof(char), strlen(passphrase), pass);
00087     fwrite("\n", sizeof(char), 1, pass);
00088     fclose(pass);
00089     close(ppass[1]);
00090 
00091     // tell pgp which fd to use for the passphrase
00092     TQCString tmp;
00093     tmp.sprintf("%d",ppass[0]);
00094     ::setenv("PGPPASSFD",tmp.data(),1);
00095 
00096     //Uncomment these lines for testing only! Doing so will decrease security!
00097     //kdDebug(5100) << "pgp PGPPASSFD = " << tmp << endl;
00098     //kdDebug(5100) << "pgp pass = " << passphrase << endl;
00099   }
00100   else
00101     ::unsetenv("PGPPASSFD");
00102 
00103   //Uncomment these lines for testing only! Doing so will decrease security!
00104   kdDebug(5100) << "pgp cmd = " << cmd << endl;
00105   //kdDebug(5100) << "pgp input = " << TQString(input)
00106   //          << "input length = " << input.length() << endl;
00107 
00108   error = "";
00109   output = "";
00110 
00111   if (pipe(pin) < 0) {
00112     // An error occurred
00113     // FIXME
00114     printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
00115   }
00116   if (pipe(pout) < 0) {
00117     // An error occurred
00118     // FIXME
00119     printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
00120   }
00121   if (pipe(perr) < 0) {
00122     // An error occurred
00123     // FIXME
00124     printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
00125   }
00126 
00127   TQApplication::flushX();
00128   if(!(child_pid = fork()))
00129   {
00130     /*We're the child.*/
00131     close(pin[1]);
00132     dup2(pin[0], 0);
00133     close(pin[0]);
00134 
00135     close(pout[0]);
00136     dup2(pout[1], 1);
00137     close(pout[1]);
00138 
00139     close(perr[0]);
00140     dup2(perr[1], 2);
00141     close(perr[1]);
00142 
00143     execl("/bin/sh", "sh", "-c", cmd,  (void *)0);
00144     _exit(127);
00145   }
00146 
00147   /*Only get here if we're the parent.*/
00148   close(pin[0]);
00149   close(pout[1]);
00150   close(perr[1]);
00151 
00152   // poll for "There is data to read."
00153   pollout.fd = pout[0];
00154   pollout.events = POLLIN;
00155   pollout.revents = 0; // init with 0, just in case
00156   pollerr.fd = perr[0];
00157   pollerr.events = POLLIN;
00158   pollerr.revents = 0; // init with 0, just in case
00159 
00160   // poll for "Writing now will not block."
00161   pollin.fd = pin[1];
00162   pollin.events = POLLOUT;
00163   pollin.revents = 0; // init with 0, just in case
00164 
00165   if (!onlyReadFromPGP) {
00166     if (!input.isEmpty()) {
00167       // write to pin[1] one line after the other to prevent dead lock
00168       uint input_length = input.length();
00169       for (unsigned int i=0; i<input_length; i+=len2) {
00170         len2 = 0;
00171 
00172         // check if writing now to pin[1] will not block (5 ms timeout)
00173         //kdDebug(5100) << "Polling pin[1]..." << endl;
00174         pollstatus = poll(&pollin, 1, 5);
00175         if (pollstatus == 1) {
00176           //kdDebug(5100) << "Status for polling pin[1]: " << pollin.revents << endl;
00177           if (pollin.revents & POLLERR) {
00178             kdDebug(5100) << "PGP seems to have hung up" << endl;
00179             break;
00180           }
00181           else if (pollin.revents & POLLOUT) {
00182             // search end of next line
00183             if ((len2 = input.find('\n', i)) == -1)
00184               len2 = input_length - i;
00185             else
00186               len2 = len2 - i + 1;
00187 
00188             //kdDebug(5100) << "Trying to write " << len2 << " bytes to pin[1] ..." << endl;
00189             len2 = write(pin[1], input.data() + i, len2);
00190             //kdDebug(5100) << "Wrote " << len2 << " bytes to pin[1] ..." << endl;
00191           }
00192         }
00193         else if (!pollstatus) {
00194           //kdDebug(5100) << "Timeout while polling pin[1]: "
00195           //              << pollin.revents << endl;
00196         }
00197         else if (pollstatus == -1) {
00198           kdDebug(5100) << "Error while polling pin[1]: "
00199                         << pollin.revents << endl;
00200         }
00201 
00202         if (pout[0] >= 0) {
00203           do {
00204             // check if there is data to read from pout[0]
00205             //kdDebug(5100) << "Polling pout[0]..." << endl;
00206             pollstatus = poll(&pollout, 1, 0);
00207             if (pollstatus == 1) {
00208               //kdDebug(5100) << "Status for polling pout[0]: " << pollout.revents << endl;
00209               if (pollout.revents & POLLIN) {
00210                 //kdDebug(5100) << "Trying to read " << 1024 << " bytes from pout[0]" << endl;
00211                 if ((len = read(pout[0],str,1024))>0) {
00212                   //kdDebug(5100) << "Read " << len << " bytes from pout[0]" << endl;
00213                   str[len] ='\0';
00214                   output += str;
00215                 }
00216                 else
00217                   break;
00218               }
00219             }
00220             else if (pollstatus == -1) {
00221               kdDebug(5100) << "Error while polling pout[0]: "
00222                             << pollout.revents << endl;
00223             }
00224           } while ((pollstatus == 1) && (pollout.revents & POLLIN));
00225         }
00226 
00227         if (perr[0] >= 0) {
00228           do {
00229             // check if there is data to read from perr[0]
00230             //kdDebug(5100) << "Polling perr[0]..." << endl;
00231             pollstatus = poll(&pollerr, 1, 0);
00232             if (pollstatus == 1) {
00233               //kdDebug(5100) << "Status for polling perr[0]: " << pollerr.revents << endl;
00234               if (pollerr.revents & POLLIN) {
00235                 //kdDebug(5100) << "Trying to read " << 1024 << " bytes from perr[0]" << endl;
00236                 if ((len = read(perr[0],str,1024))>0) {
00237                   //kdDebug(5100) << "Read " << len << " bytes from perr[0]" << endl;
00238                   str[len] ='\0';
00239                   error += str;
00240                 }
00241                 else
00242                   break;
00243               }
00244             }
00245             else if (pollstatus == -1) {
00246               kdDebug(5100) << "Error while polling perr[0]: "
00247                             << pollerr.revents << endl;
00248             }
00249           } while ((pollstatus == 1) && (pollerr.revents & POLLIN));
00250         }
00251 
00252         // abort writing to PGP if PGP hung up
00253         if ((pollstatus == 1) &&
00254             ((pollout.revents & POLLHUP) || (pollerr.revents & POLLHUP))) {
00255           kdDebug(5100) << "PGP hung up" << endl;
00256           break;
00257         }
00258       }
00259     }
00260     else { // if input.isEmpty()
00261       if (write(pin[1], "\n", 1) < 0) {
00262         // An error occurred
00263         // FIXME
00264         printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
00265       }
00266     }
00267     //kdDebug(5100) << "All input was written to pin[1]" << endl;
00268   }
00269   close(pin[1]);
00270 
00271   pid_t waitpidRetVal;
00272 
00273   do {
00274     //kdDebug(5100) << "Checking if PGP is still running..." << endl;
00275     childExiStatus = 0;
00276     waitpidRetVal = waitpid(child_pid, &childExiStatus, WNOHANG);
00277     //kdDebug(5100) << "waitpid returned " << waitpidRetVal << endl;
00278     if (pout[0] >= 0) {
00279       do {
00280         // check if there is data to read from pout[0]
00281         //kdDebug(5100) << "Polling pout[0]..." << endl;
00282         pollstatus = poll(&pollout, 1, 0);
00283         if (pollstatus == 1) {
00284           //kdDebug(5100) << "Status for polling pout[0]: " << pollout.revents << endl;
00285           if (pollout.revents & POLLIN) {
00286             //kdDebug(5100) << "Trying to read " << 1024 << " bytes from pout[0]" << endl;
00287             if ((len = read(pout[0],str,1024))>0) {
00288               //kdDebug(5100) << "Read " << len << " bytes from pout[0]" << endl;
00289               str[len] ='\0';
00290               output += str;
00291             } else {
00292               /*
00293                * Apparently, on NetBSD when the child dies, the pipe begins
00294                * receiving empty data packets *before* waitpid() has signaled
00295                * that the child has died.  Also, notice that this happens
00296                * without any error bit being set in pollfd.revents (is this a
00297                * NetBSD bug??? ).  Notice that these anomalous packets exist
00298                * according to poll(), but have length 0 according to read().
00299                * Thus, kde can remain stuck inside this loop.
00300                *
00301                * A solution to this problem is to get out of the inner loop
00302                * when read() returns <=0.  In this way, kde has another chance
00303                * to call waitpid() to check if the child has died -- and this
00304                * time the call should succeed.
00305                *
00306                * Setting POLLHUP in pollfd.revents is not necessary, but I just
00307                * like the idea of signaling that something strange has
00308                * happened.
00309                */
00310               pollout.revents |= POLLHUP;
00311               break;
00312             }
00313           }
00314         }
00315         else if (pollstatus == -1) {
00316           kdDebug(5100) << "Error while polling pout[0]: "
00317                         << pollout.revents << endl;
00318         }
00319       } while ((pollstatus == 1) && (pollout.revents & POLLIN));
00320     }
00321 
00322     if (perr[0] >= 0) {
00323       do {
00324         // check if there is data to read from perr[0]
00325         //kdDebug(5100) << "Polling perr[0]..." << endl;
00326         pollstatus = poll(&pollerr, 1, 0);
00327         if (pollstatus == 1) {
00328           //kdDebug(5100) << "Status for polling perr[0]: " << pollerr.revents << endl;
00329           if (pollerr.revents & POLLIN) {
00330             //kdDebug(5100) << "Trying to read " << 1024 << " bytes from perr[0]" << endl;
00331             if ((len = read(perr[0],str,1024))>0) {
00332               //kdDebug(5100) << "Read " << len << " bytes from perr[0]" << endl;
00333               str[len] ='\0';
00334               error += str;
00335             } else {
00336               /*
00337                * Apparently, on NetBSD when the child dies, the pipe begins
00338                * receiving empty data packets *before* waitpid() has signaled
00339                * that the child has died.  Also, notice that this happens
00340                * without any error bit being set in pollfd.revents (is this a
00341                * NetBSD bug??? ).  Notice that these anomalous packets exist
00342                * according to poll(), but have length 0 according to read().
00343                * Thus, kde can remain stuck inside this loop.
00344                *
00345                * A solution to this problem is to get out of the inner loop
00346                * when read() returns <=0.  In this way, kde has another chance
00347                * to call waitpid() to check if the child has died -- and this
00348                * time the call should succeed.
00349                *
00350                * Setting POLLHUP in pollfd.revents is not necessary, but I just
00351                * like the idea of signaling that something strange has
00352                * happened.
00353                */
00354               pollerr.revents |= POLLHUP;
00355               break;
00356             }
00357           }
00358         }
00359         else if (pollstatus == -1) {
00360           kdDebug(5100) << "Error while polling perr[0]: "
00361                         << pollerr.revents << endl;
00362         }
00363       } while ((pollstatus == 1) && (pollerr.revents & POLLIN));
00364     }
00365   } while (waitpidRetVal == 0);
00366 
00367   close(pout[0]);
00368   close(perr[0]);
00369 
00370   unsetenv("PGPPASSFD");
00371   if(passphrase)
00372     close(ppass[0]);
00373 
00374   // Did the child exit normally?
00375   if (WIFEXITED(childExiStatus) != 0) {
00376     // Get the return code of the child
00377     childExiStatus = WEXITSTATUS(childExiStatus);
00378     kdDebug(5100) << "PGP exited with exit status " << childExiStatus
00379                   << endl;
00380   }
00381   else {
00382     childExiStatus = -1;
00383     kdDebug(5100) << "PGP exited abnormally!" << endl;
00384   }
00385 
00386   //Uncomment these lines for testing only! Doing so will decrease security!
00387   //kdDebug(5100) << "pgp output = " << TQString(output) << endl;
00388   //kdDebug(5100) << "pgp error = " << error << endl;
00389 
00390   /* Make the information visible, so that a user can
00391    * get to know what's going on during the pgp calls.
00392    */
00393   kdDebug(5100) << error << endl;
00394 
00395   return childExiStatus;
00396 }
00397 
00398 
00399 int
00400 Base::runGpg( const char *cmd, const char *passphrase, bool onlyReadFromGnuPG )
00401 {
00402   /* the pipe ppass is used for to pass the password to
00403    * pgp. passing the password together with the normal input through
00404    * stdin doesn't seem to work as expected (at least for pgp5.0)
00405    */
00406   char str[1025] = "\0";
00407   int pin[2], pout[2], perr[2], ppass[2];
00408   int len, len2;
00409   FILE *pass;
00410   pid_t child_pid;
00411   int childExiStatus;
00412   char gpgcmd[1024] = "\0";
00413   struct pollfd poller[3];
00414   int num_pollers = 0;
00415   const int STD_OUT = 0;
00416   const int STD_ERR = 1;
00417   const int STD_IN = 2;
00418   int pollstatus;
00419 
00420   if(passphrase)
00421   {
00422     if (pipe(ppass) < 0) {
00423       // An error occurred
00424       // FIXME
00425       printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
00426     }
00427 
00428     pass = fdopen(ppass[1], "w");
00429     fwrite(passphrase, sizeof(char), strlen(passphrase), pass);
00430     fwrite("\n", sizeof(char), 1, pass);
00431     fclose(pass);
00432     close(ppass[1]);
00433 
00434     //Uncomment these lines for testing only! Doing so will decrease security!
00435     //kdDebug(5100) << "pass = " << passphrase << endl;
00436   }
00437 
00438   //Uncomment these lines for testing only! Doing so will decrease security!
00439   //kdDebug(5100) << "pgp cmd = " << cmd << endl;
00440   //kdDebug(5100) << "pgp input = " << TQString(input)
00441   //          << "input length = " << input.length() << endl;
00442 
00443   error = "";
00444   output = "";
00445 
00446   if (pipe(pin) < 0) {
00447     // An error occurred
00448     // FIXME
00449     printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
00450   }
00451   if (pipe(pout) < 0) {
00452     // An error occurred
00453     // FIXME
00454     printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
00455   }
00456   if (pipe(perr) < 0) {
00457     // An error occurred
00458     // FIXME
00459     printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
00460   }
00461 
00462   if( passphrase ) {
00463     if( mVersion >= "1.0.7" ) {
00464       // GnuPG >= 1.0.7 supports the gpg-agent, so we look for it.
00465       if( 0 == getenv("GPG_AGENT_INFO") ) {
00466         // gpg-agent not found, so we tell gpg not to use the agent
00467         snprintf( gpgcmd, 1023,
00468                   "LANGUAGE=C gpg --no-use-agent --passphrase-fd %d %s",
00469                   ppass[0], cmd );
00470       }
00471       else {
00472         // gpg-agent seems to be running, so we tell gpg to use the agent
00473         snprintf( gpgcmd, 1023,
00474                   "LANGUAGE=C gpg --use-agent %s",
00475                   cmd );
00476       }
00477     }
00478     else {
00479       // GnuPG < 1.0.7 doesn't know anything about the gpg-agent
00480       snprintf( gpgcmd, 1023,
00481                 "LANGUAGE=C gpg --passphrase-fd %d %s",
00482                 ppass[0], cmd );
00483     }
00484   }
00485   else {
00486     snprintf(gpgcmd, 1023, "LANGUAGE=C gpg %s",cmd);
00487   }
00488 
00489   TQApplication::flushX();
00490   if(!(child_pid = fork()))
00491   {
00492     /*We're the child.*/
00493     close(pin[1]);
00494     dup2(pin[0], 0);
00495     close(pin[0]);
00496 
00497     close(pout[0]);
00498     dup2(pout[1], 1);
00499     close(pout[1]);
00500 
00501     close(perr[0]);
00502     dup2(perr[1], 2);
00503     close(perr[1]);
00504 
00505     //#warning FIXME: there has to be a better way to do this
00506      /* this is nasty nasty nasty (but it works) */
00507     if( passphrase ) {
00508       if( mVersion >= "1.0.7" ) {
00509         // GnuPG >= 1.0.7 supports the gpg-agent, so we look for it.
00510         if( 0 == getenv("GPG_AGENT_INFO") ) {
00511           // gpg-agent not found, so we tell gpg not to use the agent
00512           snprintf( gpgcmd, 1023,
00513                     "LANGUAGE=C gpg --no-use-agent --passphrase-fd %d %s",
00514                     ppass[0], cmd );
00515         }
00516         else {
00517           // gpg-agent seems to be running, so we tell gpg to use the agent
00518           snprintf( gpgcmd, 1023,
00519                     "LANGUAGE=C gpg --use-agent %s",
00520                     cmd );
00521         }
00522       }
00523       else {
00524         // GnuPG < 1.0.7 doesn't know anything about the gpg-agent
00525         snprintf( gpgcmd, 1023,
00526                   "LANGUAGE=C gpg --passphrase-fd %d %s",
00527                   ppass[0], cmd );
00528       }
00529     }
00530     else {
00531       snprintf(gpgcmd, 1023, "LANGUAGE=C gpg %s",cmd);
00532     }
00533 
00534     kdDebug(5100) << "pgp cmd = " << gpgcmd << endl;
00535 
00536     execl("/bin/sh", "sh", "-c", gpgcmd,  (void *)0);
00537     _exit(127);
00538   }
00539 
00540   // Only get here if we're the parent.
00541 
00542   close(pin[0]);
00543   close(pout[1]);
00544   close(perr[1]);
00545 
00546   // poll for "There is data to read."
00547   poller[STD_OUT].fd = pout[0];
00548   poller[STD_OUT].events = POLLIN;
00549   poller[STD_ERR].fd = perr[0];
00550   poller[STD_ERR].events = POLLIN;
00551   num_pollers = 2;
00552 
00553   if (!onlyReadFromGnuPG) {
00554     // poll for "Writing now will not block."
00555     poller[STD_IN].fd = pin[1];
00556     poller[STD_IN].events = POLLOUT;
00557     num_pollers = 3;
00558   } else {
00559     close (pin[1]);
00560     pin[1] = -1;
00561   }
00562 
00563   pid_t waitpidRetVal;
00564   unsigned int input_pos = 0;
00565   uint input_length = input.length();
00566 
00567   do {
00568     //kdDebug(5100) << "Checking if GnuPG is still running..." << endl;
00569     childExiStatus = 0;
00570     waitpidRetVal = waitpid(child_pid, &childExiStatus, WNOHANG);
00571     //kdDebug(5100) << "waitpid returned " << waitpidRetVal << endl;
00572     do {
00573       // poll the pipes
00574       pollstatus = poll(poller, num_pollers, 10);
00575       if( 0 < pollstatus ) {
00576         // Check stdout.
00577         if (poller[STD_OUT].revents & POLLIN) {
00578           //kdDebug(5100) << "Trying to read " << 1024 << " bytes from pout[0]" << endl;
00579           if ((len = read(pout[0],str,1024))>0) {
00580             //kdDebug(5100) << "Read " << len << " bytes from pout[0]" << endl;
00581             str[len] ='\0';
00582             output += str;
00583           }
00584           else {
00585             // FreeBSD/NetBSD workaround
00586             //
00587             // Apparently, on Free/NetBSD when the child dies, the pipe begins
00588             // receiving empty data packets *before* waitpid() has signaled
00589             // that the child has died.  Also, notice that this happens
00590             // without any error bit being set in pollfd.revents (is this a
00591             // Free/NetBSD bug??? ).  Notice that these anomalous packets exist
00592             // according to poll(), but have length 0 according to read().
00593             // Thus, we can remain stuck inside this loop.
00594             //
00595             // A solution to this problem is to get out of the inner loop
00596             // when read() returns <=0.  In this way, we have another chance
00597             // to call waitpid() to check if the child has died -- and this
00598             // time the call should succeed.
00599             //
00600             // Set POLLHUP in pollfd.revents to signal that something strange
00601             // has happened and disable polling of stdout.
00602             poller[STD_OUT].revents |= POLLHUP;
00603             poller[STD_OUT].events = 0;
00604           }
00605         } else if (poller[STD_OUT].revents & POLLHUP) {
00606           // disable polling of stdout
00607           poller[STD_OUT].events = 0;
00608         }
00609 
00610         // Check stderr.
00611         if (poller[STD_ERR].revents & POLLIN) {
00612           //kdDebug(5100) << "Trying to read " << 1024 << " bytes from perr[0]" << endl;
00613           if ((len = read(poller[STD_ERR].fd,str,1024))>0) {
00614             //kdDebug(5100) << "Read " << len << " bytes from perr[0]" << endl;
00615             str[len] ='\0';
00616             error += str;
00617           }
00618           else {
00619             // FreeBSD/NetBSD workaround (for details see above)
00620             poller[STD_ERR].revents |= POLLHUP;
00621             poller[STD_ERR].events = 0;
00622           }
00623         } else if (poller[STD_ERR].revents & POLLHUP) {
00624           // disable polling of stderr
00625           poller[STD_ERR].events = 0;
00626         }
00627 
00628         if (num_pollers > 2) {
00629           if (poller[STD_IN].revents & ( POLLERR | POLLHUP ) ) {
00630             kdDebug(5100) << "GnuPG seems to have hung up" << endl;
00631             close (pin[1]);
00632             pin[1] = -1;
00633             --num_pollers;
00634           }
00635           else if (poller[STD_IN].revents & POLLOUT) {
00636             if (!input.isEmpty()) {
00637               // search end of next line
00638               if ((len2 = input.find('\n', input_pos)) == -1)
00639                 len2 = input_length - input_pos;
00640               else
00641                 len2 = len2 - input_pos + 1;
00642 
00643               //kdDebug(5100) << "Trying to write " << len2 << " bytes to pin[1] ..." << endl;
00644               len2 = write(pin[1], input.data() + input_pos, len2 );
00645               //kdDebug(5100) << "Wrote " << len2 << " bytes to pin[1] ..." << endl;
00646               input_pos += len2;
00647 
00648               // We are done.
00649               if (input_pos >= input_length) {
00650                 //kdDebug(5100) << "All input was written to pin[1]" << endl;
00651                 close (pin[1]);
00652                 pin[1] = -1;
00653                 --num_pollers;
00654               }
00655             }
00656             else { // if input.isEmpty()
00657               if (write(pin[1], "\n", 1) < 0) {
00658                 // An error occurred
00659                 // FIXME
00660                 printf("Something went wrong in libkpgp/kpgpbase.cpp\n");
00661               }
00662               //kdDebug(5100) << "All input was written to pin[1]" << endl;
00663               close (pin[1]);
00664               pin[1] = -1;
00665               --num_pollers;
00666             }
00667           }
00668         }
00669       }
00670     } while ( (pollstatus > 0) && ( (num_pollers > 2)
00671                                     || (poller[STD_OUT].events != 0)
00672                                     || (poller[STD_ERR].events != 0) ) );
00673 
00674     if (pollstatus == -1) {
00675       kdDebug(5100) << "GnuPG poll failed, errno: " << errno << endl;
00676     }
00677 
00678   } while(waitpidRetVal == 0);
00679 
00680   if( 0 <= pin[1] )
00681     close (pin[1]);
00682   close(pout[0]);
00683   close(perr[0]);
00684 
00685   if(passphrase)
00686     close(ppass[0]);
00687 
00688   // Did the child exit normally?
00689   if (WIFEXITED(childExiStatus) != 0) {
00690     // Get the return code of the child
00691     childExiStatus = WEXITSTATUS(childExiStatus);
00692     kdDebug(5100) << "GnuPG exited with exit status " << childExiStatus
00693                   << endl;
00694   }
00695   else {
00696     childExiStatus = -1;
00697     kdDebug(5100) << "GnuPG exited abnormally!" << endl;
00698   }
00699 
00700   //Uncomment these lines for testing only! Doing so will decrease security!
00701   //kdDebug(5100) << "gpg stdout:\n" << TQString(output) << endl;
00702 
00703   // Make the information visible, so that a user can
00704   // get to know what's going on during the gpg calls.
00705   kdDebug(5100) << "gpg stderr:\n" << error << endl;
00706 
00707   return childExiStatus;
00708 }
00709 
00710 
00711 TQCString
00712 Base::addUserId()
00713 {
00714   TQCString cmd;
00715   TQCString pgpUser = Module::getKpgp()->user();
00716 
00717   if(!pgpUser.isEmpty())
00718   {
00719     cmd += " -u 0x";
00720     cmd += pgpUser;
00721     return cmd;
00722   }
00723   return TQCString();
00724 }
00725 
00726 
00727 } // namespace Kpgp