Package: irssi-plugin-xmpp / 0.54-3

singpolyma-0101-Repair-broken-passphrase-retry.patch Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
From 0411946bef40d584ae77ed5a84b8ef1dbb152cec Mon Sep 17 00:00:00 2001
From: Jan Losinski <losinski@wh2.tu-dresden.de>
Date: Tue, 24 Feb 2015 22:19:53 +0100
Subject: [PATCH 01/10] 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 <losinski@wh2.tu-dresden.de>
---
 src/core/popenRWE.c |  4 +++-
 src/core/tools.c    | 21 +++++++++++++++++----
 2 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/src/core/popenRWE.c b/src/core/popenRWE.c
index e5a72be..f9a4ab5 100644
--- a/src/core/popenRWE.c
+++ b/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/src/core/tools.c b/src/core/tools.c
index e25e3d4..a98a72e 100644
--- a/src/core/tools.c
+++ b/src/core/tools.c
@@ -21,6 +21,7 @@
 #include <stdio.h>
 
 #include <string.h>
+#include <sys/wait.h>
 
 #include "module.h"
 #include "recode.h"
@@ -34,8 +35,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;
@@ -124,10 +125,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);
@@ -141,6 +147,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)
-- 
2.1.4