Fix bug 894.
[gnupg.git] / g10 / call-agent.c
1 /* call-agent.c - Divert GPG operations to the agent.
2  * Copyright (C) 2001, 2002, 2003, 2006, 2007, 
3  *               2008 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <unistd.h> 
27 #include <time.h>
28 #include <assert.h>
29 #ifdef HAVE_LOCALE_H
30 #include <locale.h>
31 #endif
32 #include <assuan.h>
33
34 #include "gpg.h"
35 #include "util.h"
36 #include "membuf.h"
37 #include "options.h"
38 #include "i18n.h"
39 #include "asshelp.h"
40 #include "sysutils.h"
41 #include "call-agent.h"
42
43 #ifndef DBG_ASSUAN
44 # define DBG_ASSUAN 1
45 #endif
46
47 static assuan_context_t agent_ctx = NULL;
48
49 struct cipher_parm_s 
50 {
51   assuan_context_t ctx;
52   const char *ciphertext;
53   size_t ciphertextlen;
54 };
55
56 struct writekey_parm_s
57 {
58   assuan_context_t ctx;
59   const unsigned char *keydata;
60   size_t keydatalen;
61 };
62
63 struct genkey_parm_s 
64 {
65   assuan_context_t ctx;
66   const char *sexp;
67   size_t sexplen;
68 };
69
70
71 \f
72 /* Try to connect to the agent via socket or fork it off and work by
73    pipes.  Handle the server's initial greeting */
74 static int
75 start_agent (void)
76 {
77   int rc;
78
79   if (agent_ctx)
80     return 0; /* Fixme: We need a context for each thread or serialize
81                  the access to the agent. */
82
83   rc = start_new_gpg_agent (&agent_ctx,
84                             GPG_ERR_SOURCE_DEFAULT,
85                             opt.homedir,
86                             opt.agent_program,
87                             opt.display, opt.ttyname, opt.ttytype,
88                             opt.lc_ctype, opt.lc_messages,
89                             opt.xauthority, opt.pinentry_user_data,
90                             opt.verbose, DBG_ASSUAN,
91                             NULL, NULL);
92   if (!rc)
93     {
94       /* Tell the agent that we support Pinentry notifications.  No
95          error checking so that it will work also with older
96          agents.  */
97       assuan_transact (agent_ctx, "OPTION allow-pinentry-notify",
98                        NULL, NULL, NULL, NULL, NULL, NULL);
99     }
100
101   return rc;
102 }
103
104
105 /* Return a new malloced string by unescaping the string S.  Escaping
106    is percent escaping and '+'/space mapping.  A binary nul will
107    silently be replaced by a 0xFF.  Function returns NULL to indicate
108    an out of memory status. */
109 static char *
110 unescape_status_string (const unsigned char *s)
111 {
112   char *buffer, *d;
113
114   buffer = d = xtrymalloc (strlen (s)+1);
115   if (!buffer)
116     return NULL;
117   while (*s)
118     {
119       if (*s == '%' && s[1] && s[2])
120         { 
121           s++;
122           *d = xtoi_2 (s);
123           if (!*d)
124             *d = '\xff';
125           d++;
126           s += 2;
127         }
128       else if (*s == '+')
129         {
130           *d++ = ' ';
131           s++;
132         }
133       else
134         *d++ = *s++;
135     }
136   *d = 0; 
137   return buffer;
138 }
139
140 /* Copy the text ATEXT into the buffer P and do plus '+' and percent
141    escaping.  Note that the provided buffer needs to be 3 times the
142    size of ATEXT plus 1.  Returns a pointer to the leading Nul in P. */
143 static char *
144 percent_plus_escape (char *p, const char *atext)
145 {
146   const unsigned char *s;
147
148   for (s=atext; *s; s++)
149     {
150       if (*s < ' ' || *s == '+')
151         {
152           sprintf (p, "%%%02X", *s);
153           p += 3;
154         }
155       else if (*s == ' ')
156         *p++ = '+';
157       else
158         *p++ = *s;
159     }
160   *p = 0;
161   return p;
162 }
163
164 /* Take a 20 byte hexencoded string and put it into the the provided
165    20 byte buffer FPR in binary format. */
166 static int
167 unhexify_fpr (const char *hexstr, unsigned char *fpr)
168 {
169   const char *s;
170   int n;
171
172   for (s=hexstr, n=0; hexdigitp (s); s++, n++)
173     ;
174   if (*s || (n != 40))
175     return 0; /* no fingerprint (invalid or wrong length). */
176   n /= 2;
177   for (s=hexstr, n=0; *s; s += 2, n++)
178     fpr[n] = xtoi_2 (s);
179   return 1; /* okay */
180 }
181
182 /* Take the serial number from LINE and return it verbatim in a newly
183    allocated string.  We make sure that only hex characters are
184    returned. */
185 static char *
186 store_serialno (const char *line)
187 {
188   const char *s;
189   char *p;
190
191   for (s=line; hexdigitp (s); s++)
192     ;
193   p = xtrymalloc (s + 1 - line);
194   if (p)
195     {
196       memcpy (p, line, s-line);
197       p[s-line] = 0;
198     }
199   return p;
200 }
201
202
203 \f
204 /* This is the default inquiry callback.  It mainly handles the
205    Pinentry notifications.  */
206 static int
207 default_inq_cb (void *opaque, const char *line)
208 {
209   (void)opaque;
210
211   if (!strncmp (line, "PINENTRY_LAUNCHED", 17) && (line[17]==' '||!line[17]))
212     {
213       /* There is no working server mode yet thus we use
214          AllowSetForegroundWindow window right here.  We might want to
215          do this anyway in case gpg is called on the console. */
216       gnupg_allow_set_foregound_window ((pid_t)strtoul (line+17, NULL, 10));
217       /* We do not pass errors to avoid breaking other code.  */
218     }
219   else
220     log_debug ("ignoring gpg-agent inquiry `%s'\n", line);
221
222   return 0;
223 }
224
225
226
227 /* Release the card info structure INFO. */
228 void
229 agent_release_card_info (struct agent_card_info_s *info)
230 {
231   if (!info)
232     return;
233
234   xfree (info->serialno); info->serialno = NULL;
235   xfree (info->disp_name); info->disp_name = NULL;
236   xfree (info->disp_lang); info->disp_lang = NULL;
237   xfree (info->pubkey_url); info->pubkey_url = NULL;
238   xfree (info->login_data); info->login_data = NULL;
239   info->cafpr1valid = info->cafpr2valid = info->cafpr3valid = 0;
240   info->fpr1valid = info->fpr2valid = info->fpr3valid = 0;
241 }
242
243 static int
244 learn_status_cb (void *opaque, const char *line)
245 {
246   struct agent_card_info_s *parm = opaque;
247   const char *keyword = line;
248   int keywordlen;
249   int i;
250
251   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
252     ;
253   while (spacep (line))
254     line++;
255
256   if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
257     {
258       xfree (parm->serialno);
259       parm->serialno = store_serialno (line);
260     }
261   else if (keywordlen == 9 && !memcmp (keyword, "DISP-NAME", keywordlen))
262     {
263       xfree (parm->disp_name);
264       parm->disp_name = unescape_status_string (line);
265     }
266   else if (keywordlen == 9 && !memcmp (keyword, "DISP-LANG", keywordlen))
267     {
268       xfree (parm->disp_lang);
269       parm->disp_lang = unescape_status_string (line);
270     }
271   else if (keywordlen == 8 && !memcmp (keyword, "DISP-SEX", keywordlen))
272     {
273       parm->disp_sex = *line == '1'? 1 : *line == '2' ? 2: 0;
274     }
275   else if (keywordlen == 10 && !memcmp (keyword, "PUBKEY-URL", keywordlen))
276     {
277       xfree (parm->pubkey_url);
278       parm->pubkey_url = unescape_status_string (line);
279     }
280   else if (keywordlen == 10 && !memcmp (keyword, "LOGIN-DATA", keywordlen))
281     {
282       xfree (parm->login_data);
283       parm->login_data = unescape_status_string (line);
284     }
285   else if (keywordlen == 11 && !memcmp (keyword, "SIG-COUNTER", keywordlen))
286     {
287       parm->sig_counter = strtoul (line, NULL, 0);
288     }
289   else if (keywordlen == 10 && !memcmp (keyword, "CHV-STATUS", keywordlen))
290     {
291       char *p, *buf;
292
293       buf = p = unescape_status_string (line);
294       if (buf)
295         {
296           while (spacep (p))
297             p++;
298           parm->chv1_cached = atoi (p);
299           while (*p && !spacep (p))
300             p++;
301           while (spacep (p))
302             p++;
303           for (i=0; *p && i < 3; i++)
304             {
305               parm->chvmaxlen[i] = atoi (p);
306               while (*p && !spacep (p))
307                 p++;
308               while (spacep (p))
309                 p++;
310             }
311           for (i=0; *p && i < 3; i++)
312             {
313               parm->chvretry[i] = atoi (p);
314               while (*p && !spacep (p))
315                 p++;
316               while (spacep (p))
317                 p++;
318             }
319           xfree (buf);
320         }
321     }
322   else if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
323     {
324       int no = atoi (line);
325       while (*line && !spacep (line))
326         line++;
327       while (spacep (line))
328         line++;
329       if (no == 1)
330         parm->fpr1valid = unhexify_fpr (line, parm->fpr1);
331       else if (no == 2)
332         parm->fpr2valid = unhexify_fpr (line, parm->fpr2);
333       else if (no == 3)
334         parm->fpr3valid = unhexify_fpr (line, parm->fpr3);
335     }
336   else if (keywordlen == 6 && !memcmp (keyword, "CA-FPR", keywordlen))
337     {
338       int no = atoi (line);
339       while (*line && !spacep (line))
340         line++;
341       while (spacep (line))
342         line++;
343       if (no == 1)
344         parm->cafpr1valid = unhexify_fpr (line, parm->cafpr1);
345       else if (no == 2)
346         parm->cafpr2valid = unhexify_fpr (line, parm->cafpr2);
347       else if (no == 3)
348         parm->cafpr3valid = unhexify_fpr (line, parm->cafpr3);
349     }
350   
351   return 0;
352 }
353
354 /* Call the agent to learn about a smartcard */
355 int
356 agent_learn (struct agent_card_info_s *info)
357 {
358   int rc;
359
360   rc = start_agent ();
361   if (rc)
362     return rc;
363
364   memset (info, 0, sizeof *info);
365   rc = assuan_transact (agent_ctx, "LEARN --send",
366                         NULL, NULL, default_inq_cb, NULL,
367                         learn_status_cb, info);
368   
369   return rc;
370 }
371
372 /* Call the agent to retrieve a data object.  This function returns
373    the data in the same structure as used by the learn command.  It is
374    allowed to update such a structure using this commmand. */
375 int
376 agent_scd_getattr (const char *name, struct agent_card_info_s *info)
377 {
378   int rc;
379   char line[ASSUAN_LINELENGTH];
380
381   if (!*name)
382     return gpg_error (GPG_ERR_INV_VALUE);
383
384   /* We assume that NAME does not need escaping. */
385   if (12 + strlen (name) > DIM(line)-1)
386     return gpg_error (GPG_ERR_TOO_LARGE);
387   stpcpy (stpcpy (line, "SCD GETATTR "), name); 
388
389   rc = start_agent ();
390   if (rc)
391     return rc;
392
393   rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, NULL,
394                         learn_status_cb, info);
395   
396   return rc;
397 }
398
399 \f
400 /* Send an setattr command to the SCdaemon.  SERIALNO is not actually
401    used here but required by gpg 1.4's implementation of this code in
402    cardglue.c. */
403 int
404 agent_scd_setattr (const char *name,
405                    const unsigned char *value, size_t valuelen,
406                    const char *serialno)
407 {
408   int rc;
409   char line[ASSUAN_LINELENGTH];
410   char *p;
411
412   if (!*name || !valuelen)
413     return gpg_error (GPG_ERR_INV_VALUE);
414
415   /* We assume that NAME does not need escaping. */
416   if (12 + strlen (name) > DIM(line)-1)
417     return gpg_error (GPG_ERR_TOO_LARGE);
418       
419   p = stpcpy (stpcpy (line, "SCD SETATTR "), name); 
420   *p++ = ' ';
421   for (; valuelen; value++, valuelen--)
422     {
423       if (p >= line + DIM(line)-5 )
424         return gpg_error (GPG_ERR_TOO_LARGE);
425       if (*value < ' ' || *value == '+' || *value == '%')
426         {
427           sprintf (p, "%%%02X", *value);
428           p += 3;
429         }
430       else if (*value == ' ')
431         *p++ = '+';
432       else
433         *p++ = *value;
434     }
435   *p = 0;
436
437   rc = start_agent ();
438   if (rc)
439     return rc;
440
441   rc = assuan_transact (agent_ctx, line, NULL, NULL, 
442                         default_inq_cb, NULL, NULL, NULL);
443   return rc;
444 }
445
446
447 \f
448 /* Handle a KEYDATA inquiry.  Note, we only send the data,
449    assuan_transact takes care of flushing and writing the end */
450 static int
451 inq_writekey_parms (void *opaque, const char *line)
452 {
453   int rc;
454   struct writekey_parm_s *parm = opaque; 
455
456   if (!strncmp (line, "KEYDATA", 7) && (line[7]==' '||!line[7]))
457     {
458       rc = assuan_send_data (parm->ctx, parm->keydata, parm->keydatalen);
459     }
460   else
461     rc = default_inq_cb (opaque, line);
462
463   return rc;
464 }
465
466
467 /* Send a WRITEKEY command to the SCdaemon. */
468 int 
469 agent_scd_writekey (int keyno, const char *serialno,
470                     const unsigned char *keydata, size_t keydatalen)
471 {
472   int rc;
473   char line[ASSUAN_LINELENGTH];
474   struct writekey_parm_s parms;
475
476   rc = start_agent ();
477   if (rc)
478     return rc;
479
480   memset (&parms, 0, sizeof parms);
481
482   snprintf (line, DIM(line)-1, "SCD WRITEKEY --force OPENPGP.%d", keyno);
483   line[DIM(line)-1] = 0;
484   parms.ctx = agent_ctx;
485   parms.keydata = keydata;
486   parms.keydatalen = keydatalen;
487   
488   rc = assuan_transact (agent_ctx, line, NULL, NULL,
489                         inq_writekey_parms, &parms, NULL, NULL);
490
491   return rc;
492 }
493
494
495
496 \f
497 /* Status callback for the SCD GENKEY command. */
498 static int
499 scd_genkey_cb (void *opaque, const char *line)
500 {
501   struct agent_card_genkey_s *parm = opaque;
502   const char *keyword = line;
503   int keywordlen;
504   gpg_error_t rc;
505
506   log_debug ("got status line `%s'\n", line);
507   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
508     ;
509   while (spacep (line))
510     line++;
511
512   if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
513     {
514       parm->fprvalid = unhexify_fpr (line, parm->fpr);
515     }
516   if (keywordlen == 8 && !memcmp (keyword, "KEY-DATA", keywordlen))
517     {
518       gcry_mpi_t a;
519       const char *name = line;
520
521       while (*line && !spacep (line))
522         line++;
523       while (spacep (line))
524         line++;
525
526       rc = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, line, 0, NULL);
527       if (rc)
528         log_error ("error parsing received key data: %s\n", gpg_strerror (rc));
529       else if (*name == 'n' && spacep (name+1))
530         parm->n = a;
531       else if (*name == 'e' && spacep (name+1))
532         parm->e = a;
533       else
534         {
535           log_info ("unknown parameter name in received key data\n");
536           gcry_mpi_release (a);
537         }
538     }
539   else if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen))
540     {
541       parm->created_at = (u32)strtoul (line, NULL, 10);
542     }
543
544   return 0;
545 }
546
547 /* Send a GENKEY command to the SCdaemon.  SERIALNO is not used in
548    this implementation.  If CREATEDATE has been given, it will be
549    passed to SCDAEMON so that the key can be created with this
550    timestamp; note the user needs to use the returned timestamp as old
551    versions of scddaemon don't support this option.  */
552 int
553 agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
554                   const char *serialno, u32 createtime)
555 {
556   int rc;
557   char line[ASSUAN_LINELENGTH];
558   gnupg_isotime_t tbuf;
559
560   rc = start_agent ();
561   if (rc)
562     return rc;
563
564   if (createtime)
565     epoch2isotime (tbuf, createtime);
566   else
567     *tbuf = 0;
568
569   memset (info, 0, sizeof *info);
570   snprintf (line, DIM(line)-1, "SCD GENKEY %s%s %s %d",
571             *tbuf? "--timestamp=":"", tbuf,
572             force? "--force":"", 
573             keyno);
574   line[DIM(line)-1] = 0;
575
576   memset (info, 0, sizeof *info);
577   rc = assuan_transact (agent_ctx, line,
578                         NULL, NULL, default_inq_cb, NULL,
579                         scd_genkey_cb, info);
580   
581   return rc;
582 }
583
584 \f
585 static int
586 membuf_data_cb (void *opaque, const void *buffer, size_t length)
587 {
588   membuf_t *data = opaque;
589
590   if (buffer)
591     put_membuf (data, buffer, length);
592   return 0;
593 }
594   
595 /* Send a sign command to the scdaemon via gpg-agent's pass thru
596    mechanism. */
597 int
598 agent_scd_pksign (const char *serialno, int hashalgo,
599                   const unsigned char *indata, size_t indatalen,
600                   unsigned char **r_buf, size_t *r_buflen)
601 {
602   int rc, i;
603   char *p, line[ASSUAN_LINELENGTH];
604   membuf_t data;
605   size_t len;
606
607   /* Note, hashalgo is not yet used but hardwired to SHA1 in SCdaemon. */
608
609   *r_buf = NULL;
610   *r_buflen = 0;
611
612   rc = start_agent ();
613   if (rc)
614     return rc;
615
616   if (indatalen*2 + 50 > DIM(line))
617     return gpg_error (GPG_ERR_GENERAL);
618
619   sprintf (line, "SCD SETDATA ");
620   p = line + strlen (line);
621   for (i=0; i < indatalen ; i++, p += 2 )
622     sprintf (p, "%02X", indata[i]);
623   rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
624   if (rc)
625     return rc;
626
627   init_membuf (&data, 1024);
628 #if 0
629   if (!hashalgo) /* Temporary test hack. */
630     snprintf (line, DIM(line)-1, "SCD PKAUTH %s", serialno);
631   else
632 #endif
633     snprintf (line, DIM(line)-1, "SCD PKSIGN %s%s",
634               hashalgo == GCRY_MD_RMD160? "--hash=rmd160 " : "",
635               serialno);
636   line[DIM(line)-1] = 0;
637   rc = assuan_transact (agent_ctx, line, membuf_data_cb, &data,
638                         default_inq_cb, NULL, NULL, NULL);
639   if (rc)
640     {
641       xfree (get_membuf (&data, &len));
642       return rc;
643     }
644   *r_buf = get_membuf (&data, r_buflen);
645
646   return 0;
647 }
648
649
650 /* Decrypt INDATA of length INDATALEN using the card identified by
651    SERIALNO.  Return the plaintext in a nwly allocated buffer stored
652    at the address of R_BUF. 
653
654    Note, we currently support only RSA or more exactly algorithms
655    taking one input data element. */
656 int
657 agent_scd_pkdecrypt (const char *serialno,
658                      const unsigned char *indata, size_t indatalen,
659                      unsigned char **r_buf, size_t *r_buflen)
660 {
661   int rc, i;
662   char *p, line[ASSUAN_LINELENGTH];
663   membuf_t data;
664   size_t len;
665
666   *r_buf = NULL;
667   rc = start_agent ();
668   if (rc)
669     return rc;
670
671   /* FIXME: use secure memory where appropriate */
672   if (indatalen*2 + 50 > DIM(line))
673     return gpg_error (GPG_ERR_GENERAL);
674
675   sprintf (line, "SCD SETDATA ");
676   p = line + strlen (line);
677   for (i=0; i < indatalen ; i++, p += 2 )
678     sprintf (p, "%02X", indata[i]);
679   rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
680   if (rc)
681     return rc;
682
683   init_membuf (&data, 1024);
684   snprintf (line, DIM(line)-1, "SCD PKDECRYPT %s", serialno);
685   line[DIM(line)-1] = 0;
686   rc = assuan_transact (agent_ctx, line,
687                         membuf_data_cb, &data,
688                         default_inq_cb, NULL, NULL, NULL);
689   if (rc)
690     {
691       xfree (get_membuf (&data, &len));
692       return rc;
693     }
694   *r_buf = get_membuf (&data, r_buflen);
695   if (!*r_buf)
696     return gpg_error (GPG_ERR_ENOMEM);
697
698   return 0;
699 }
700
701
702 /* Change the PIN of an OpenPGP card or reset the retry counter.
703    CHVNO 1: Change the PIN
704          2: Same as 1
705          3: Change the admin PIN
706        101: Set a new PIN and reset the retry counter
707        102: Same as 101
708    SERIALNO is not used.
709  */
710 int
711 agent_scd_change_pin (int chvno, const char *serialno)
712 {
713   int rc;
714   char line[ASSUAN_LINELENGTH];
715   const char *reset = "";
716
717   if (chvno >= 100)
718     reset = "--reset";
719   chvno %= 100;
720
721   rc = start_agent ();
722   if (rc)
723     return rc;
724
725   snprintf (line, DIM(line)-1, "SCD PASSWD %s %d", reset, chvno);
726   line[DIM(line)-1] = 0;
727   rc = assuan_transact (agent_ctx, line, NULL, NULL,
728                         default_inq_cb, NULL, NULL, NULL);
729   return rc;
730 }
731
732
733 /* Perform a CHECKPIN operation.  SERIALNO should be the serial
734    number of the card - optionally followed by the fingerprint;
735    however the fingerprint is ignored here. */
736 int
737 agent_scd_checkpin  (const char *serialno)
738 {
739   int rc;
740   char line[ASSUAN_LINELENGTH];
741
742   rc = start_agent ();
743   if (rc)
744     return rc;
745
746   snprintf (line, DIM(line)-1, "SCD CHECKPIN %s", serialno);
747   line[DIM(line)-1] = 0;
748   return assuan_transact (agent_ctx, line,
749                           NULL, NULL,
750                           default_inq_cb, NULL, NULL, NULL);
751 }
752
753
754 /* Dummy function, only used by the gpg 1.4 implementation. */
755 void
756 agent_clear_pin_cache (const char *sn)
757 {
758
759 }
760
761
762
763 \f
764 /* Note: All strings shall be UTF-8. On success the caller needs to
765    free the string stored at R_PASSPHRASE. On error NULL will be
766    stored at R_PASSPHRASE and an appropriate fpf error code
767    returned. */
768 gpg_error_t
769 agent_get_passphrase (const char *cache_id,
770                       const char *err_msg,
771                       const char *prompt,
772                       const char *desc_msg,
773                       char **r_passphrase)
774 {
775   int rc;
776   char *line, *p;
777   char cmd[] = "GET_PASSPHRASE --data -- ";
778   membuf_t data;
779
780   *r_passphrase = NULL;
781
782   rc = start_agent ();
783   if (rc)
784     return rc;
785
786   /* We allocate 3 times the needed space for the texts so that
787      there is enough space for escaping. */
788   line = xtrymalloc ( strlen (cmd) + 1
789                       + (cache_id? 3*strlen (cache_id): 1) + 1
790                       + (err_msg?  3*strlen (err_msg): 1) + 1
791                       + (prompt?   3*strlen (prompt): 1) + 1
792                       + (desc_msg? 3*strlen (desc_msg): 1) + 1
793                       + 1);
794   if (!line)
795     return gpg_error_from_syserror ();
796
797   p = stpcpy (line, cmd);
798   if (cache_id && *cache_id)
799     p = percent_plus_escape (p, cache_id);
800   else
801     *p++ = 'X';
802   *p++ = ' ';
803
804   if (err_msg && *err_msg)
805     p = percent_plus_escape (p, err_msg);
806   else
807     *p++ = 'X';
808   *p++ = ' ';
809
810   if (prompt && *prompt)
811     p = percent_plus_escape (p, prompt);
812   else
813     *p++ = 'X'; 
814   *p++ = ' ';
815
816   if (desc_msg && *desc_msg)
817     p = percent_plus_escape (p, desc_msg);
818   else
819     *p++ = 'X';
820   *p = 0;
821
822   init_membuf_secure (&data, 64);
823   rc = assuan_transact (agent_ctx, line, 
824                         membuf_data_cb, &data,
825                         default_inq_cb, NULL, NULL, NULL);
826
827   if (rc)
828     xfree (get_membuf (&data, NULL));
829   else 
830     {
831       put_membuf (&data, "", 1);
832       *r_passphrase = get_membuf (&data, NULL);
833       if (!*r_passphrase)
834         rc = gpg_error_from_syserror ();
835     }
836   xfree (line);
837   return rc;
838 }
839
840
841 gpg_error_t
842 agent_clear_passphrase (const char *cache_id)
843 {
844   int rc;
845   char line[ASSUAN_LINELENGTH];
846
847   if (!cache_id || !*cache_id)
848     return 0;
849
850   rc = start_agent ();
851   if (rc)
852     return rc;
853
854   snprintf (line, DIM(line)-1, "CLEAR_PASSPHRASE %s", cache_id);
855   line[DIM(line)-1] = 0;
856   return assuan_transact (agent_ctx, line, NULL, NULL,
857                           default_inq_cb, NULL, NULL, NULL);
858 }