Package: irssi-plugin-xmpp
Version: 0.52+git20140102-2
Severity: important
Tags: patch

Dear Maintainer,

the irssi-xmpp-plugin in debian is patched with patches from [1] that
brings pgp features to the plugin. It uses the pgp command in a creative
way. If the raw exit status from waitpid of the pgp command is 512 it
think that the passphrase was wrong and does the pgp call recursively
again.

On my system this condition is triggered when pgp failed to find a key
for a signature it should verify. This led to a endless recursion
that finally kills irssi because it reaches the max stack size. It also
causes /tmp to get filled up with tmpfiles.

I have a patch at [2] that fixes some of the issues. It uses the waidpid
macros to process the status value and uses the gpg exit values from
[3]. This seems to work. 

The general quality of the code is not as optimal for some security
feature. I recommend to remove this patches or migrate the code to use
GpgME.


[1] https://github.com/singpolyma/irssi-xmpp
[2] 
https://github.com/janLo/irssi-xmpp-1/commit/52e16dcf749de632c21508fd33f14e84d5358170
[3] 
http://www.gnu-darwin.org/www001/src/ports/security/libgpg-error/work/libgpg-error-1.5/src/err-codes.h.in


-- System Information:
Debian Release: 8.0
  APT prefers testing
  APT policy: (500, 'testing'), (150, 'unstable'), (145, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.16.0-4-amd64 (SMP w/6 CPU cores)
Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)

Versions of packages irssi-plugin-xmpp depends on:
ii  irssi            0.8.17-1
ii  libc6            2.19-13
ii  libglib2.0-0     2.42.1-1
ii  libloudmouth1-0  1.4.3-12

irssi-plugin-xmpp recommends no packages.

irssi-plugin-xmpp suggests no packages.

-- no debconf information
commit 52e16dcf749de632c21508fd33f14e84d5358170
Author: Jan Losinski <[email protected]>
Date:   Tue Feb 24 22:19:53 2015 +0100

    Repair broken passphrase retry
    
    The exit code handling of the gpg process to detect wrong passphrases
    was a bit adventurous. It checked for the raw status value from waitpid
    instead of the WEXITSTATUS() macro.
    The code that handles the waitpid also does not check for any errors.
    This is now fixed by evaluating the waitpid return value and the use of
    the WEXITSTATUS() macro.
    
    Signed-off-by: Jan Losinski <[email protected]>

diff --git a/irssi-xmpp/src/core/popenRWE.c b/irssi-xmpp/src/core/popenRWE.c
index e5a72be..f9a4ab5 100644
--- a/irssi-xmpp/src/core/popenRWE.c
+++ b/irssi-xmpp/src/core/popenRWE.c
@@ -88,6 +88,8 @@ int pcloseRWE(int pid, int *rwepipe) {
 	close(rwepipe[0]);
 	close(rwepipe[1]);
 	close(rwepipe[2]);
-	rc = waitpid(pid, &status, 0);
+	do {
+		rc = waitpid(pid, &status, 0);
+	} while (rc != 0 && ! WIFEXITED(status));
 	return status;
 }
diff --git a/irssi-xmpp/src/core/tools.c b/irssi-xmpp/src/core/tools.c
index 5a3e959..6179514 100644
--- a/irssi-xmpp/src/core/tools.c
+++ b/irssi-xmpp/src/core/tools.c
@@ -23,6 +23,7 @@
 #include <stdio.h>
 
 #include <string.h>
+#include <sys/wait.h>
 
 #include "module.h"
 #include "recode.h"
@@ -36,8 +37,8 @@
 
 static const char *utf8_charset = "UTF-8";
 
-char *call_gpg(char *switches, char *input, char *input2, \
-               int get_stderr, int snip_data) {
+char *call_gpg_round(char *switches, char *input, char *input2, \
+               int get_stderr, int snip_data, unsigned round) {
 	int pipefd[2], rwepipe[3], childpid, tmp2_fd = 0, in_data = !snip_data;
 	FILE* cstream;
 	char *cmd, *tmp2_path = NULL, *output = NULL;
@@ -126,10 +127,15 @@ char *call_gpg(char *switches, char *input, char *input2, \
 		strcat(output, buf2);
 	}
 
-	if(pcloseRWE(childpid, rwepipe) == 512) { /* TODO: more check exit code */
+	// http://www.gnu-darwin.org/www001/src/ports/security/libgpg-error/work/libgpg-error-1.5/src/err-codes.h.in
+	// 11	GPG_ERR_BAD_PASSPHRASE		Bad passphrase
+	// 31	GPG_ERR_INV_PASSPHRASE		Invalid passphrase
+	int exit_status = WEXITSTATUS(pcloseRWE(childpid, rwepipe));
+	if(round > 0 && (exit_status == 11 || exit_status == 31)) {
 		g_free(pgp_passwd);
 		pgp_passwd = NULL;
-		output = call_gpg(switches, input, input2, get_stderr, snip_data);
+		output = call_gpg_round(switches, input, input2, get_stderr,
+					snip_data, round--);
 	}
 
 	if(tmp2_fd)   close(tmp2_fd);
@@ -143,6 +149,13 @@ pgp_error:
 }
 
 
+char *call_gpg(char *switches, char *input, char *input2, \
+               int get_stderr, int snip_data, unsigned round) {
+	return call_gpg_round(switches, input, input2, get_stderr,
+			      snip_data, 3);
+}
+
+
 
 static gboolean
 xmpp_get_local_charset(G_CONST_RETURN char **charset)

Reply via email to