4 Copyright (C) 2001,2002 the KPGP authors
5 See file AUTHORS.kpgp for details
7 This file is part of KPGP, the KDE PGP/GnuPG support library.
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.
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
19 #include <config-libkpgp.h> /* HAVE_SYS_POLL_H */
23 #include "kpgpblock.h"
26 #include <kdefakes.h> /* setenv, unsetenv */
28 #include <QApplication>
31 #include <stdlib.h> /* setenv, unsetenv */
32 #include <unistd.h> /* pipe, close, fork, dup2, execl, _exit, write, read */
35 #ifdef HAVE_SYS_POLL_H
36 #include <sys/poll.h> /* poll, etc. */
39 #include <sys/types.h> /* pid_t */
40 #include <sys/wait.h> /* waitpid */
45 : input(), output(), error(), errMsg(), status(OK
)
59 output
= QByteArray();
67 Base::run( const char *cmd
, const char *passphrase
, bool onlyReadFromPGP
)
69 #ifdef HAVE_SYS_POLL_H
70 /* the pipe ppass is used for to pass the password to
71 * pgp. passing the password together with the normal input through
72 * stdin doesn't seem to work as expected (at least for pgp5.0)
74 char str
[1025] = "\0";
75 int pin
[2], pout
[2], perr
[2], ppass
[2];
80 struct pollfd pollin
, pollout
, pollerr
;
87 pass
= fdopen(ppass
[1], "w");
88 fwrite(passphrase
, sizeof(char), strlen(passphrase
), pass
);
89 fwrite("\n", sizeof(char), 1, pass
);
93 // tell pgp which fd to use for the passphrase
95 tmp
.sprintf("%d",ppass
[0]);
96 ::setenv("PGPPASSFD",tmp
.toUtf8()/*.data()*/,1);
98 //Uncomment these lines for testing only! Doing so will decrease security!
99 //kDebug( 5326 ) <<"pgp PGPPASSFD =" << tmp;
100 //kDebug( 5326 ) <<"pgp pass =" << passphrase;
103 ::unsetenv("PGPPASSFD");
105 //Uncomment these lines for testing only! Doing so will decrease security!
106 kDebug( 5326 ) <<"pgp cmd =" << cmd
;
107 //kDebug( 5326 ) <<"pgp input =" << QString(input)
108 // << "input length =" << input.length();
117 QApplication::flush();
118 if(!(child_pid
= fork()))
133 execl("/bin/sh", "sh", "-c", cmd
, (void *)0);
137 /*Only get here if we're the parent.*/
142 // poll for "There is data to read."
143 pollout
.fd
= pout
[0];
144 pollout
.events
= POLLIN
;
145 pollout
.revents
= 0; // init with 0, just in case
146 pollerr
.fd
= perr
[0];
147 pollerr
.events
= POLLIN
;
148 pollerr
.revents
= 0; // init with 0, just in case
150 // poll for "Writing now will not block."
152 pollin
.events
= POLLOUT
;
153 pollin
.revents
= 0; // init with 0, just in case
155 if (!onlyReadFromPGP
) {
156 if (!input
.isEmpty()) {
157 // write to pin[1] one line after the other to prevent dead lock
158 int input_length
= input
.length();
159 for (int i
=0; i
<input_length
; i
+=len2
) {
162 // check if writing now to pin[1] will not block (5 ms timeout)
163 //kDebug( 5326 ) <<"Polling pin[1]...";
164 pollstatus
= poll(&pollin
, 1, 5);
165 if (pollstatus
== 1) {
166 //kDebug( 5326 ) <<"Status for polling pin[1]:" << pollin.revents;
167 if (pollin
.revents
& POLLERR
) {
168 kDebug( 5326 ) <<"PGP seems to have hung up";
171 else if (pollin
.revents
& POLLOUT
) {
172 // search end of next line
173 if ((len2
= input
.indexOf('\n', i
)) == -1)
174 len2
= input_length
- i
;
178 //kDebug( 5326 ) <<"Trying to write" << len2 <<" bytes to pin[1] ...";
179 len2
= write(pin
[1], input
.data() + i
, len2
);
180 //kDebug( 5326 ) <<"Wrote" << len2 <<" bytes to pin[1] ...";
183 else if (!pollstatus
) {
184 //kDebug( 5326 ) <<"Timeout while polling pin[1]:"
185 // << pollin.revents;
187 else if (pollstatus
== -1) {
188 kDebug( 5326 ) <<"Error while polling pin[1]:"
194 // check if there is data to read from pout[0]
195 //kDebug( 5326 ) <<"Polling pout[0]...";
196 pollstatus
= poll(&pollout
, 1, 0);
197 if (pollstatus
== 1) {
198 //kDebug( 5326 ) <<"Status for polling pout[0]:" << pollout.revents;
199 if (pollout
.revents
& POLLIN
) {
200 //kDebug( 5326 ) <<"Trying to read" << 1024 <<" bytes from pout[0]";
201 if ((len
= read(pout
[0],str
,1024))>0) {
202 //kDebug( 5326 ) <<"Read" << len <<" bytes from pout[0]";
210 else if (pollstatus
== -1) {
211 kDebug( 5326 ) <<"Error while polling pout[0]:"
214 } while ((pollstatus
== 1) && (pollout
.revents
& POLLIN
));
219 // check if there is data to read from perr[0]
220 //kDebug( 5326 ) <<"Polling perr[0]...";
221 pollstatus
= poll(&pollerr
, 1, 0);
222 if (pollstatus
== 1) {
223 //kDebug( 5326 ) <<"Status for polling perr[0]:" << pollerr.revents;
224 if (pollerr
.revents
& POLLIN
) {
225 //kDebug( 5326 ) <<"Trying to read" << 1024 <<" bytes from perr[0]";
226 if ((len
= read(perr
[0],str
,1024))>0) {
227 //kDebug( 5326 ) <<"Read" << len <<" bytes from perr[0]";
235 else if (pollstatus
== -1) {
236 kDebug( 5326 ) <<"Error while polling perr[0]:"
239 } while ((pollstatus
== 1) && (pollerr
.revents
& POLLIN
));
242 // abort writing to PGP if PGP hung up
243 if ((pollstatus
== 1) &&
244 ((pollout
.revents
& POLLHUP
) || (pollerr
.revents
& POLLHUP
))) {
245 kDebug( 5326 ) <<"PGP hung up";
250 else // if input.isEmpty()
251 write(pin
[1], "\n", 1);
252 //kDebug( 5326 ) <<"All input was written to pin[1]";
259 //kDebug( 5326 ) <<"Checking if PGP is still running...";
261 waitpidRetVal
= waitpid(child_pid
, &childExitStatus
, WNOHANG
);
262 //kDebug( 5326 ) <<"waitpid returned" << waitpidRetVal;
265 // check if there is data to read from pout[0]
266 //kDebug( 5326 ) <<"Polling pout[0]...";
267 pollstatus
= poll(&pollout
, 1, 0);
268 if (pollstatus
== 1) {
269 //kDebug( 5326 ) <<"Status for polling pout[0]:" << pollout.revents;
270 if (pollout
.revents
& POLLIN
) {
271 //kDebug( 5326 ) <<"Trying to read" << 1024 <<" bytes from pout[0]";
272 if ((len
= read(pout
[0],str
,1024))>0) {
273 //kDebug( 5326 ) <<"Read" << len <<" bytes from pout[0]";
278 * Apparently, on NetBSD when the child dies, the pipe begins
279 * receiving empty data packets *before* waitpid() has signaled
280 * that the child has died. Also, notice that this happens
281 * without any error bit being set in pollfd.revents (is this a
282 * NetBSD bug??? ). Notice that these anomalous packets exist
283 * according to poll(), but have length 0 according to read().
284 * Thus, kde can remain stuck inside this loop.
286 * A solution to this problem is to get out of the inner loop
287 * when read() returns <=0. In this way, kde has another chance
288 * to call waitpid() to check if the child has died -- and this
289 * time the call should succeed.
291 * Setting POLLHUP in pollfd.revents is not necessary, but I just
292 * like the idea of signaling that something strange has
295 pollout
.revents
|= POLLHUP
;
300 else if (pollstatus
== -1) {
301 kDebug( 5326 ) <<"Error while polling pout[0]:"
304 } while ((pollstatus
== 1) && (pollout
.revents
& POLLIN
));
309 // check if there is data to read from perr[0]
310 //kDebug( 5326 ) <<"Polling perr[0]...";
311 pollstatus
= poll(&pollerr
, 1, 0);
312 if (pollstatus
== 1) {
313 //kDebug( 5326 ) <<"Status for polling perr[0]:" << pollerr.revents;
314 if (pollerr
.revents
& POLLIN
) {
315 //kDebug( 5326 ) <<"Trying to read" << 1024 <<" bytes from perr[0]";
316 if ((len
= read(perr
[0],str
,1024))>0) {
317 //kDebug( 5326 ) <<"Read" << len <<" bytes from perr[0]";
322 * Apparently, on NetBSD when the child dies, the pipe begins
323 * receiving empty data packets *before* waitpid() has signaled
324 * that the child has died. Also, notice that this happens
325 * without any error bit being set in pollfd.revents (is this a
326 * NetBSD bug??? ). Notice that these anomalous packets exist
327 * according to poll(), but have length 0 according to read().
328 * Thus, kde can remain stuck inside this loop.
330 * A solution to this problem is to get out of the inner loop
331 * when read() returns <=0. In this way, kde has another chance
332 * to call waitpid() to check if the child has died -- and this
333 * time the call should succeed.
335 * Setting POLLHUP in pollfd.revents is not necessary, but I just
336 * like the idea of signaling that something strange has
339 pollerr
.revents
|= POLLHUP
;
344 else if (pollstatus
== -1) {
345 kDebug( 5326 ) <<"Error while polling perr[0]:"
348 } while ((pollstatus
== 1) && (pollerr
.revents
& POLLIN
));
350 } while (waitpidRetVal
== 0);
355 unsetenv("PGPPASSFD");
359 // Did the child exit normally?
360 if (WIFEXITED(childExitStatus
) != 0) {
361 // Get the return code of the child
362 childExitStatus
= WEXITSTATUS(childExitStatus
);
363 kDebug( 5326 ) <<"PGP exited with exit status" << childExitStatus
;
366 childExitStatus
= -1;
367 kDebug( 5326 ) <<"PGP exited abnormally!";
370 //Uncomment these lines for testing only! Doing so will decrease security!
371 //kDebug( 5326 ) <<"pgp output =" << QString(output);
372 //kDebug( 5326 ) <<"pgp error =" << error;
374 /* Make the information visible, so that a user can
375 * get to know what's going on during the pgp calls.
377 kDebug( 5326 ) << error
;
379 return childExitStatus
;
380 #else // HAVE_SYS_POLL_H
382 #warning WIN32 libkpgp: PGP support not ported to win32!
390 Base::runGpg( const char *cmd
, const char *passphrase
, bool onlyReadFromGnuPG
)
392 #ifdef HAVE_SYS_POLL_H
393 /* the pipe ppass is used for to pass the password to
394 * pgp. passing the password together with the normal input through
395 * stdin doesn't seem to work as expected (at least for pgp5.0)
397 char str
[1025] = "\0";
398 int pin
[2], pout
[2], perr
[2], ppass
[2];
403 char gpgcmd
[1024] = "\0";
404 struct pollfd poller
[3];
406 const int STD_OUT
= 0;
407 const int STD_ERR
= 1;
408 const int STD_IN
= 2;
415 pass
= fdopen(ppass
[1], "w");
416 fwrite(passphrase
, sizeof(char), strlen(passphrase
), pass
);
417 fwrite("\n", sizeof(char), 1, pass
);
421 //Uncomment these lines for testing only! Doing so will decrease security!
422 //kDebug( 5326 ) <<"pass =" << passphrase;
425 //Uncomment these lines for testing only! Doing so will decrease security!
426 //kDebug( 5326 ) <<"pgp cmd =" << cmd;
427 //kDebug( 5326 ) <<"pgp input =" << QString(input)
428 // << "input length =" << input.length();
438 if( mVersion
>= "1.0.7" ) {
439 // GnuPG >= 1.0.7 supports the gpg-agent, so we look for it.
440 if( 0 == getenv("GPG_AGENT_INFO") ) {
441 // gpg-agent not found, so we tell gpg not to use the agent
442 snprintf( gpgcmd
, 1023,
443 "LANGUAGE=C gpg --no-use-agent --passphrase-fd %d %s",
447 // gpg-agent seems to be running, so we tell gpg to use the agent
448 snprintf( gpgcmd
, 1023,
449 "LANGUAGE=C gpg --use-agent %s",
454 // GnuPG < 1.0.7 doesn't know anything about the gpg-agent
455 snprintf( gpgcmd
, 1023,
456 "LANGUAGE=C gpg --passphrase-fd %d %s",
461 snprintf(gpgcmd
, 1023, "LANGUAGE=C gpg %s",cmd
);
464 QApplication::flush();
465 if(!(child_pid
= fork()))
480 //#warning FIXME: there has to be a better way to do this
481 /* this is nasty nasty nasty (but it works) */
483 if( mVersion
>= "1.0.7" ) {
484 // GnuPG >= 1.0.7 supports the gpg-agent, so we look for it.
485 if( 0 == getenv("GPG_AGENT_INFO") ) {
486 // gpg-agent not found, so we tell gpg not to use the agent
487 snprintf( gpgcmd
, 1023,
488 "LANGUAGE=C gpg --no-use-agent --passphrase-fd %d %s",
492 // gpg-agent seems to be running, so we tell gpg to use the agent
493 snprintf( gpgcmd
, 1023,
494 "LANGUAGE=C gpg --use-agent %s",
499 // GnuPG < 1.0.7 doesn't know anything about the gpg-agent
500 snprintf( gpgcmd
, 1023,
501 "LANGUAGE=C gpg --passphrase-fd %d %s",
506 snprintf(gpgcmd
, 1023, "LANGUAGE=C gpg %s",cmd
);
509 kDebug( 5326 ) <<"pgp cmd =" << gpgcmd
;
511 execl("/bin/sh", "sh", "-c", gpgcmd
, (void *)0);
515 // Only get here if we're the parent.
521 // poll for "There is data to read."
522 poller
[STD_OUT
].fd
= pout
[0];
523 poller
[STD_OUT
].events
= POLLIN
;
524 poller
[STD_ERR
].fd
= perr
[0];
525 poller
[STD_ERR
].events
= POLLIN
;
528 if (!onlyReadFromGnuPG
) {
529 // poll for "Writing now will not block."
530 poller
[STD_IN
].fd
= pin
[1];
531 poller
[STD_IN
].events
= POLLOUT
;
540 int input_length
= input
.length();
543 //kDebug( 5326 ) <<"Checking if GnuPG is still running...";
545 waitpidRetVal
= waitpid(child_pid
, &childExitStatus
, WNOHANG
);
546 //kDebug( 5326 ) <<"waitpid returned" << waitpidRetVal;
549 pollstatus
= poll(poller
, num_pollers
, 10);
550 if( 0 < pollstatus
) {
552 if (poller
[STD_OUT
].revents
& POLLIN
) {
553 //kDebug( 5326 ) <<"Trying to read" << 1024 <<" bytes from pout[0]";
554 if ((len
= read(pout
[0],str
,1024))>0) {
555 //kDebug( 5326 ) <<"Read" << len <<" bytes from pout[0]";
560 // FreeBSD/NetBSD workaround
562 // Apparently, on Free/NetBSD when the child dies, the pipe begins
563 // receiving empty data packets *before* waitpid() has signaled
564 // that the child has died. Also, notice that this happens
565 // without any error bit being set in pollfd.revents (is this a
566 // Free/NetBSD bug??? ). Notice that these anomalous packets exist
567 // according to poll(), but have length 0 according to read().
568 // Thus, we can remain stuck inside this loop.
570 // A solution to this problem is to get out of the inner loop
571 // when read() returns <=0. In this way, we have another chance
572 // to call waitpid() to check if the child has died -- and this
573 // time the call should succeed.
575 // Set POLLHUP in pollfd.revents to signal that something strange
576 // has happened and disable polling of stdout.
577 poller
[STD_OUT
].revents
|= POLLHUP
;
578 poller
[STD_OUT
].events
= 0;
580 } else if (poller
[STD_OUT
].revents
& POLLHUP
) {
581 // disable polling of stdout
582 poller
[STD_OUT
].events
= 0;
586 if (poller
[STD_ERR
].revents
& POLLIN
) {
587 //kDebug( 5326 ) <<"Trying to read" << 1024 <<" bytes from perr[0]";
588 if ((len
= read(poller
[STD_ERR
].fd
,str
,1024))>0) {
589 //kDebug( 5326 ) <<"Read" << len <<" bytes from perr[0]";
594 // FreeBSD/NetBSD workaround (for details see above)
595 poller
[STD_ERR
].revents
|= POLLHUP
;
596 poller
[STD_ERR
].events
= 0;
598 } else if (poller
[STD_ERR
].revents
& POLLHUP
) {
599 // disable polling of stderr
600 poller
[STD_ERR
].events
= 0;
603 if (num_pollers
> 2) {
604 if (poller
[STD_IN
].revents
& ( POLLERR
| POLLHUP
) ) {
605 kDebug( 5326 ) <<"GnuPG seems to have hung up";
610 else if (poller
[STD_IN
].revents
& POLLOUT
) {
611 if (!input
.isEmpty()) {
612 // search end of next line
613 if ((len2
= input
.indexOf('\n', input_pos
)) == -1)
614 len2
= input_length
- input_pos
;
616 len2
= len2
- input_pos
+ 1;
618 //kDebug( 5326 ) <<"Trying to write" << len2 <<" bytes to pin[1] ...";
619 len2
= write(pin
[1], input
.data() + input_pos
, len2
);
620 //kDebug( 5326 ) <<"Wrote" << len2 <<" bytes to pin[1] ...";
624 if (input_pos
>= input_length
) {
625 //kDebug( 5326 ) <<"All input was written to pin[1]";
631 else { // if input.isEmpty()
632 write(pin
[1], "\n", 1);
633 //kDebug( 5326 ) <<"All input was written to pin[1]";
641 } while ( (pollstatus
> 0) && ( (num_pollers
> 2)
642 || (poller
[STD_OUT
].events
!= 0)
643 || (poller
[STD_ERR
].events
!= 0) ) );
645 if (pollstatus
== -1) {
646 kDebug( 5326 ) <<"GnuPG poll failed, errno:" << errno
;
649 } while(waitpidRetVal
== 0);
659 // Did the child exit normally?
660 if (WIFEXITED(childExitStatus
) != 0) {
661 // Get the return code of the child
662 childExitStatus
= WEXITSTATUS(childExitStatus
);
663 kDebug( 5326 ) <<"GnuPG exited with exit status" << childExitStatus
;
666 childExitStatus
= -1;
667 kDebug( 5326 ) <<"GnuPG exited abnormally!";
670 //Uncomment these lines for testing only! Doing so will decrease security!
671 //kDebug( 5326 ) <<"gpg stdout:" << QString(output);
673 // Make the information visible, so that a user can
674 // get to know what's going on during the gpg calls.
675 kDebug( 5326 ) <<"gpg stderr:" << error
;
677 return childExitStatus
;
678 #else // HAVE_SYS_POLL_H
680 #warning WIN32 libkpgp: GnuPG support not ported to WIN32!
691 QByteArray pgpUser
= Module::getKpgp()->user();
693 if(!pgpUser
.isEmpty())