summaryrefslogtreecommitdiff
path: root/gnu/packages/patches/gnupg-simple-query-ignore-status-messages.patch
blob: 153f71c38faa421db720d9b067d216f37b687cfb (plain)
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
Copied from upstream:
http://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=commitdiff;h=acac103ba5772ae738ce5409d17feab80596cde6

Fixes: https://debbugs.gnu.org/22558
Upstream bug: https://bugs.gnupg.org/gnupg/issue2229

From acac103ba5772ae738ce5409d17feab80596cde6 Mon Sep 17 00:00:00 2001
From: "Neal H. Walfield" <neal@g10code.com>
Date: Fri, 12 Feb 2016 22:12:21 +0100
Subject: [PATCH] common: Change simple_query to ignore status messages.

* common/simple-pwquery.c (simple_query): Ignore status messages.

--
Signed-off-by: Neal H. Walfield <neal@g10code.com>
GnuPG-bug-id: 2229
---
 common/simple-pwquery.c | 95 ++++++++++++++++++++++++++++++++++---------------
 1 file changed, 67 insertions(+), 28 deletions(-)

diff --git a/common/simple-pwquery.c b/common/simple-pwquery.c
index 90d04c0..b2d666c 100644
--- a/common/simple-pwquery.c
+++ b/common/simple-pwquery.c
@@ -618,6 +618,7 @@ simple_query (const char *query)
   int fd = -1;
   int nread;
   char response[500];
+  int have = 0;
   int rc;
 
   rc = agent_open (&fd);
@@ -628,40 +629,78 @@ simple_query (const char *query)
   if (rc)
     goto leave;
 
-  /* get response */
-  nread = readline (fd, response, 499);
-  if (nread < 0)
-    {
-      rc = -nread;
-      goto leave;
-    }
-  if (nread < 3)
+  while (1)
     {
-      rc = SPWQ_PROTOCOL_ERROR;
-      goto leave;
-    }
+      if (! have || ! strchr (response, '\n'))
+        /* get response */
+        {
+          nread = readline (fd, &response[have],
+                            sizeof (response) - 1 /* NUL */ - have);
+          if (nread < 0)
+            {
+              rc = -nread;
+              goto leave;
+            }
+          have += nread;
+          if (have < 3)
+            {
+              rc = SPWQ_PROTOCOL_ERROR;
+              goto leave;
+            }
+          response[have] = 0;
+        }
 
-  if (response[0] == 'O' && response[1] == 'K')
-    /* OK, do nothing.  */;
-  else if ((nread > 7 && !memcmp (response, "ERR 111", 7)
-            && (response[7] == ' ' || response[7] == '\n') )
-           || ((nread > 4 && !memcmp (response, "ERR ", 4)
-                && (strtoul (response+4, NULL, 0) & 0xffff) == 99)) )
-    {
-      /* 111 is the old Assuan code for canceled which might still
-         be in use by old installations. 99 is GPG_ERR_CANCELED as
-         used by modern gpg-agents; 0xffff is used to mask out the
-         error source.  */
+      if (response[0] == 'O' && response[1] == 'K')
+        /* OK, do nothing.  */;
+      else if ((nread > 7 && !memcmp (response, "ERR 111", 7)
+                && (response[7] == ' ' || response[7] == '\n') )
+               || ((nread > 4 && !memcmp (response, "ERR ", 4)
+                    && (strtoul (response+4, NULL, 0) & 0xffff) == 99)) )
+        {
+          /* 111 is the old Assuan code for canceled which might still
+             be in use by old installations. 99 is GPG_ERR_CANCELED as
+             used by modern gpg-agents; 0xffff is used to mask out the
+             error source.  */
 #ifdef SPWQ_USE_LOGGING
-      log_info (_("canceled by user\n") );
+          log_info (_("canceled by user\n") );
 #endif
-    }
-  else
-    {
+        }
+      else if (response[0] == 'S' && response[1] == ' ')
+        {
+          char *nextline;
+          int consumed;
+
+          nextline = strchr (response, '\n');
+          if (! nextline)
+            /* Point to the NUL.  */
+            nextline = &response[have];
+          else
+            /* Move past the \n.  */
+            nextline ++;
+
+          consumed = (size_t) nextline - (size_t) response;
+
+          /* Skip any additional newlines.  */
+          while (consumed < have && response[consumed] == '\n')
+            consumed ++;
+
+          have -= consumed;
+
+          if (have)
+            memmove (response, &response[consumed], have + 1);
+
+          continue;
+        }
+      else
+        {
 #ifdef SPWQ_USE_LOGGING
-      log_error (_("problem with the agent\n"));
+          log_error (_("problem with the agent (unexpected response \"%s\"\n"),
+                     response);
 #endif
-      rc = SPWQ_ERR_RESPONSE;
+          rc = SPWQ_ERR_RESPONSE;
+        }
+
+      break;
     }
 
  leave:
-- 
2.6.3