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