1 /* call-agent.c - Divert GPG operations to the agent.
2 * Copyright (C) 2001, 2002, 2003, 2006, 2007,
3 * 2008 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
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.
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.
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/>.
41 #include "call-agent.h"
48 static assuan_context_t agent_ctx
= NULL
;
49 static int did_early_card_test
;
54 const char *ciphertext
;
58 struct writecert_parm_s
61 const unsigned char *certdata
;
65 struct writekey_parm_s
68 const unsigned char *keydata
;
80 static int learn_status_cb (void *opaque
, const char *line
);
84 /* If RC is not 0, write an appropriate status message. */
86 status_sc_op_failure (int rc
)
88 switch (gpg_err_code (rc
))
92 case GPG_ERR_CANCELED
:
93 write_status_text (STATUS_SC_OP_FAILURE
, "1");
96 write_status_text (STATUS_SC_OP_FAILURE
, "2");
99 write_status (STATUS_SC_OP_FAILURE
);
107 /* Try to connect to the agent via socket or fork it off and work by
108 pipes. Handle the server's initial greeting */
110 start_agent (int for_card
)
114 /* Fixme: We need a context for each thread or serialize the access
120 rc
= start_new_gpg_agent (&agent_ctx
,
121 GPG_ERR_SOURCE_DEFAULT
,
124 opt
.lc_ctype
, opt
.lc_messages
,
126 opt
.verbose
, DBG_ASSUAN
,
130 /* Tell the agent that we support Pinentry notifications.
131 No error checking so that it will work also with older
133 assuan_transact (agent_ctx
, "OPTION allow-pinentry-notify",
134 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
138 if (!rc
&& for_card
&& !did_early_card_test
)
140 /* Request the serial number of the card for an early test. */
141 struct agent_card_info_s info
;
143 memset (&info
, 0, sizeof info
);
144 rc
= assuan_transact (agent_ctx
, "SCD SERIALNO openpgp",
145 NULL
, NULL
, NULL
, NULL
,
146 learn_status_cb
, &info
);
149 switch (gpg_err_code (rc
))
151 case GPG_ERR_NOT_SUPPORTED
:
152 case GPG_ERR_NO_SCDAEMON
:
153 write_status_text (STATUS_CARDCTRL
, "6");
156 write_status_text (STATUS_CARDCTRL
, "4");
157 log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc
));
162 if (!rc
&& is_status_enabled () && info
.serialno
)
166 buf
= xasprintf ("3 %s", info
.serialno
);
167 write_status_text (STATUS_CARDCTRL
, buf
);
171 agent_release_card_info (&info
);
174 did_early_card_test
= 1;
182 /* Return a new malloced string by unescaping the string S. Escaping
183 is percent escaping and '+'/space mapping. A binary nul will
184 silently be replaced by a 0xFF. Function returns NULL to indicate
185 an out of memory status. */
187 unescape_status_string (const unsigned char *s
)
189 return percent_plus_unescape (s
, 0xff);
193 /* Take a 20 byte hexencoded string and put it into the the provided
194 20 byte buffer FPR in binary format. */
196 unhexify_fpr (const char *hexstr
, unsigned char *fpr
)
201 for (s
=hexstr
, n
=0; hexdigitp (s
); s
++, n
++)
204 return 0; /* no fingerprint (invalid or wrong length). */
205 for (s
=hexstr
, n
=0; *s
; s
+= 2, n
++)
210 /* Take the serial number from LINE and return it verbatim in a newly
211 allocated string. We make sure that only hex characters are
214 store_serialno (const char *line
)
219 for (s
=line
; hexdigitp (s
); s
++)
221 p
= xtrymalloc (s
+ 1 - line
);
224 memcpy (p
, line
, s
-line
);
232 /* This is a dummy data line callback. */
234 dummy_data_cb (void *opaque
, const void *buffer
, size_t length
)
243 /* This is the default inquiry callback. It mainly handles the
244 Pinentry notifications. */
246 default_inq_cb (void *opaque
, const char *line
)
250 if (!strncmp (line
, "PINENTRY_LAUNCHED", 17) && (line
[17]==' '||!line
[17]))
252 /* There is no working server mode yet thus we use
253 AllowSetForegroundWindow window right here. We might want to
254 do this anyway in case gpg is called on the console. */
255 gnupg_allow_set_foregound_window ((pid_t
)strtoul (line
+17, NULL
, 10));
256 /* We do not pass errors to avoid breaking other code. */
259 log_debug ("ignoring gpg-agent inquiry `%s'\n", line
);
266 /* Release the card info structure INFO. */
268 agent_release_card_info (struct agent_card_info_s
*info
)
273 xfree (info
->serialno
); info
->serialno
= NULL
;
274 xfree (info
->apptype
); info
->apptype
= NULL
;
275 xfree (info
->disp_name
); info
->disp_name
= NULL
;
276 xfree (info
->disp_lang
); info
->disp_lang
= NULL
;
277 xfree (info
->pubkey_url
); info
->pubkey_url
= NULL
;
278 xfree (info
->login_data
); info
->login_data
= NULL
;
279 info
->cafpr1valid
= info
->cafpr2valid
= info
->cafpr3valid
= 0;
280 info
->fpr1valid
= info
->fpr2valid
= info
->fpr3valid
= 0;
284 learn_status_cb (void *opaque
, const char *line
)
286 struct agent_card_info_s
*parm
= opaque
;
287 const char *keyword
= line
;
291 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
293 while (spacep (line
))
296 if (keywordlen
== 8 && !memcmp (keyword
, "SERIALNO", keywordlen
))
298 xfree (parm
->serialno
);
299 parm
->serialno
= store_serialno (line
);
300 parm
->is_v2
= (strlen (parm
->serialno
) >= 16
301 && xtoi_2 (parm
->serialno
+12) >= 2 );
303 else if (keywordlen
== 7 && !memcmp (keyword
, "APPTYPE", keywordlen
))
305 xfree (parm
->apptype
);
306 parm
->apptype
= unescape_status_string (line
);
308 else if (keywordlen
== 9 && !memcmp (keyword
, "DISP-NAME", keywordlen
))
310 xfree (parm
->disp_name
);
311 parm
->disp_name
= unescape_status_string (line
);
313 else if (keywordlen
== 9 && !memcmp (keyword
, "DISP-LANG", keywordlen
))
315 xfree (parm
->disp_lang
);
316 parm
->disp_lang
= unescape_status_string (line
);
318 else if (keywordlen
== 8 && !memcmp (keyword
, "DISP-SEX", keywordlen
))
320 parm
->disp_sex
= *line
== '1'? 1 : *line
== '2' ? 2: 0;
322 else if (keywordlen
== 10 && !memcmp (keyword
, "PUBKEY-URL", keywordlen
))
324 xfree (parm
->pubkey_url
);
325 parm
->pubkey_url
= unescape_status_string (line
);
327 else if (keywordlen
== 10 && !memcmp (keyword
, "LOGIN-DATA", keywordlen
))
329 xfree (parm
->login_data
);
330 parm
->login_data
= unescape_status_string (line
);
332 else if (keywordlen
== 11 && !memcmp (keyword
, "SIG-COUNTER", keywordlen
))
334 parm
->sig_counter
= strtoul (line
, NULL
, 0);
336 else if (keywordlen
== 10 && !memcmp (keyword
, "CHV-STATUS", keywordlen
))
340 buf
= p
= unescape_status_string (line
);
345 parm
->chv1_cached
= atoi (p
);
346 while (*p
&& !spacep (p
))
350 for (i
=0; *p
&& i
< 3; i
++)
352 parm
->chvmaxlen
[i
] = atoi (p
);
353 while (*p
&& !spacep (p
))
358 for (i
=0; *p
&& i
< 3; i
++)
360 parm
->chvretry
[i
] = atoi (p
);
361 while (*p
&& !spacep (p
))
369 else if (keywordlen
== 7 && !memcmp (keyword
, "KEY-FPR", keywordlen
))
371 int no
= atoi (line
);
372 while (*line
&& !spacep (line
))
374 while (spacep (line
))
377 parm
->fpr1valid
= unhexify_fpr (line
, parm
->fpr1
);
379 parm
->fpr2valid
= unhexify_fpr (line
, parm
->fpr2
);
381 parm
->fpr3valid
= unhexify_fpr (line
, parm
->fpr3
);
383 else if (keywordlen
== 6 && !memcmp (keyword
, "CA-FPR", keywordlen
))
385 int no
= atoi (line
);
386 while (*line
&& !spacep (line
))
388 while (spacep (line
))
391 parm
->cafpr1valid
= unhexify_fpr (line
, parm
->cafpr1
);
393 parm
->cafpr2valid
= unhexify_fpr (line
, parm
->cafpr2
);
395 parm
->cafpr3valid
= unhexify_fpr (line
, parm
->cafpr3
);
397 else if (keywordlen
== 8 && !memcmp (keyword
, "KEY-ATTR", keywordlen
))
399 int keyno
, algo
, nbits
;
401 sscanf (line
, "%d %d %d", &keyno
, &algo
, &nbits
);
403 if (keyno
>= 0 && keyno
< DIM (parm
->key_attr
))
405 parm
->key_attr
[keyno
].algo
= algo
;
406 parm
->key_attr
[keyno
].nbits
= nbits
;
413 /* Call the agent to learn about a smartcard */
415 agent_learn (struct agent_card_info_s
*info
)
419 rc
= start_agent (1);
423 memset (info
, 0, sizeof *info
);
424 rc
= assuan_transact (agent_ctx
, "SCD LEARN --force",
425 dummy_data_cb
, NULL
, default_inq_cb
, NULL
,
426 learn_status_cb
, info
);
427 /* Also try to get the key attributes. */
429 agent_scd_getattr ("KEY-ATTR", info
);
434 /* Call the agent to retrieve a data object. This function returns
435 the data in the same structure as used by the learn command. It is
436 allowed to update such a structure using this commmand. */
438 agent_scd_getattr (const char *name
, struct agent_card_info_s
*info
)
441 char line
[ASSUAN_LINELENGTH
];
444 return gpg_error (GPG_ERR_INV_VALUE
);
446 /* We assume that NAME does not need escaping. */
447 if (12 + strlen (name
) > DIM(line
)-1)
448 return gpg_error (GPG_ERR_TOO_LARGE
);
449 stpcpy (stpcpy (line
, "SCD GETATTR "), name
);
451 rc
= start_agent (1);
455 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, default_inq_cb
, NULL
,
456 learn_status_cb
, info
);
462 /* Send an setattr command to the SCdaemon. SERIALNO is not actually
463 used here but required by gpg 1.4's implementation of this code in
466 agent_scd_setattr (const char *name
,
467 const unsigned char *value
, size_t valuelen
,
468 const char *serialno
)
471 char line
[ASSUAN_LINELENGTH
];
476 if (!*name
|| !valuelen
)
477 return gpg_error (GPG_ERR_INV_VALUE
);
479 /* We assume that NAME does not need escaping. */
480 if (12 + strlen (name
) > DIM(line
)-1)
481 return gpg_error (GPG_ERR_TOO_LARGE
);
483 p
= stpcpy (stpcpy (line
, "SCD SETATTR "), name
);
485 for (; valuelen
; value
++, valuelen
--)
487 if (p
>= line
+ DIM(line
)-5 )
488 return gpg_error (GPG_ERR_TOO_LARGE
);
489 if (*value
< ' ' || *value
== '+' || *value
== '%')
491 sprintf (p
, "%%%02X", *value
);
494 else if (*value
== ' ')
501 rc
= start_agent (1);
504 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
505 default_inq_cb
, NULL
, NULL
, NULL
);
508 status_sc_op_failure (rc
);
514 /* Handle a CERTDATA inquiry. Note, we only send the data,
515 assuan_transact takes care of flushing and writing the END
518 inq_writecert_parms (void *opaque
, const char *line
)
521 struct writecert_parm_s
*parm
= opaque
;
523 if (!strncmp (line
, "CERTDATA", 8) && (line
[8]==' '||!line
[8]))
525 rc
= assuan_send_data (parm
->ctx
, parm
->certdata
, parm
->certdatalen
);
528 rc
= default_inq_cb (opaque
, line
);
534 /* Send a WRITECERT command to the SCdaemon. */
536 agent_scd_writecert (const char *certidstr
,
537 const unsigned char *certdata
, size_t certdatalen
)
540 char line
[ASSUAN_LINELENGTH
];
541 struct writecert_parm_s parms
;
543 rc
= start_agent (1);
547 memset (&parms
, 0, sizeof parms
);
549 snprintf (line
, DIM(line
)-1, "SCD WRITECERT %s", certidstr
);
550 line
[DIM(line
)-1] = 0;
551 parms
.ctx
= agent_ctx
;
552 parms
.certdata
= certdata
;
553 parms
.certdatalen
= certdatalen
;
555 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
556 inq_writecert_parms
, &parms
, NULL
, NULL
);
563 /* Handle a KEYDATA inquiry. Note, we only send the data,
564 assuan_transact takes care of flushing and writing the end */
566 inq_writekey_parms (void *opaque
, const char *line
)
569 struct writekey_parm_s
*parm
= opaque
;
571 if (!strncmp (line
, "KEYDATA", 7) && (line
[7]==' '||!line
[7]))
573 rc
= assuan_send_data (parm
->ctx
, parm
->keydata
, parm
->keydatalen
);
576 rc
= default_inq_cb (opaque
, line
);
582 /* Send a WRITEKEY command to the SCdaemon. */
584 agent_scd_writekey (int keyno
, const char *serialno
,
585 const unsigned char *keydata
, size_t keydatalen
)
588 char line
[ASSUAN_LINELENGTH
];
589 struct writekey_parm_s parms
;
593 rc
= start_agent (1);
597 memset (&parms
, 0, sizeof parms
);
599 snprintf (line
, DIM(line
)-1, "SCD WRITEKEY --force OPENPGP.%d", keyno
);
600 line
[DIM(line
)-1] = 0;
601 parms
.ctx
= agent_ctx
;
602 parms
.keydata
= keydata
;
603 parms
.keydatalen
= keydatalen
;
605 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
606 inq_writekey_parms
, &parms
, NULL
, NULL
);
608 status_sc_op_failure (rc
);
614 /* Status callback for the SCD GENKEY command. */
616 scd_genkey_cb (void *opaque
, const char *line
)
618 struct agent_card_genkey_s
*parm
= opaque
;
619 const char *keyword
= line
;
623 for (keywordlen
=0; *line
&& !spacep (line
); line
++, keywordlen
++)
625 while (spacep (line
))
628 if (keywordlen
== 7 && !memcmp (keyword
, "KEY-FPR", keywordlen
))
630 parm
->fprvalid
= unhexify_fpr (line
, parm
->fpr
);
632 if (keywordlen
== 8 && !memcmp (keyword
, "KEY-DATA", keywordlen
))
635 const char *name
= line
;
637 while (*line
&& !spacep (line
))
639 while (spacep (line
))
642 rc
= gcry_mpi_scan (&a
, GCRYMPI_FMT_HEX
, line
, 0, NULL
);
644 log_error ("error parsing received key data: %s\n", gpg_strerror (rc
));
645 else if (*name
== 'n' && spacep (name
+1))
647 else if (*name
== 'e' && spacep (name
+1))
651 log_info ("unknown parameter name in received key data\n");
652 gcry_mpi_release (a
);
655 else if (keywordlen
== 14 && !memcmp (keyword
,"KEY-CREATED-AT", keywordlen
))
657 parm
->created_at
= (u32
)strtoul (line
, NULL
, 10);
663 /* Send a GENKEY command to the SCdaemon. SERIALNO is not used in
664 this implementation. If CREATEDATE has been given, it will be
665 passed to SCDAEMON so that the key can be created with this
666 timestamp; note the user needs to use the returned timestamp as old
667 versions of scddaemon don't support this option. */
669 agent_scd_genkey (struct agent_card_genkey_s
*info
, int keyno
, int force
,
670 const char *serialno
, u32 createtime
)
673 char line
[ASSUAN_LINELENGTH
];
674 gnupg_isotime_t tbuf
;
678 rc
= start_agent (1);
683 epoch2isotime (tbuf
, createtime
);
687 memset (info
, 0, sizeof *info
);
688 snprintf (line
, DIM(line
)-1, "SCD GENKEY %s%s %s %d",
689 *tbuf
? "--timestamp=":"", tbuf
,
692 line
[DIM(line
)-1] = 0;
694 memset (info
, 0, sizeof *info
);
695 rc
= assuan_transact (agent_ctx
, line
,
696 NULL
, NULL
, default_inq_cb
, NULL
,
697 scd_genkey_cb
, info
);
699 status_sc_op_failure (rc
);
705 membuf_data_cb (void *opaque
, const void *buffer
, size_t length
)
707 membuf_t
*data
= opaque
;
710 put_membuf (data
, buffer
, length
);
714 /* Send a sign command to the scdaemon via gpg-agent's pass thru
717 agent_scd_pksign (const char *serialno
, int hashalgo
,
718 const unsigned char *indata
, size_t indatalen
,
719 unsigned char **r_buf
, size_t *r_buflen
)
722 char *p
, line
[ASSUAN_LINELENGTH
];
726 /* Note, hashalgo is not yet used but hardwired to SHA1 in SCdaemon. */
731 rc
= start_agent (1);
735 if (indatalen
*2 + 50 > DIM(line
))
736 return gpg_error (GPG_ERR_GENERAL
);
738 /* Send the serialno command to initialize the connection. We don't
739 care about the data returned. If the card has already been
740 initialized, this is a very fast command. We request the openpgp
741 card because that is what we expect. */
742 rc
= assuan_transact (agent_ctx
, "SCD SERIALNO openpgp",
743 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
747 sprintf (line
, "SCD SETDATA ");
748 p
= line
+ strlen (line
);
749 for (i
=0; i
< indatalen
; i
++, p
+= 2 )
750 sprintf (p
, "%02X", indata
[i
]);
751 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
755 init_membuf (&data
, 1024);
757 if (!hashalgo
) /* Temporary test hack. */
758 snprintf (line
, DIM(line
)-1, "SCD PKAUTH %s", serialno
);
761 snprintf (line
, DIM(line
)-1, "SCD PKSIGN %s%s",
762 hashalgo
== GCRY_MD_RMD160
? "--hash=rmd160 " : "",
764 line
[DIM(line
)-1] = 0;
765 rc
= assuan_transact (agent_ctx
, line
, membuf_data_cb
, &data
,
766 default_inq_cb
, NULL
, NULL
, NULL
);
769 xfree (get_membuf (&data
, &len
));
772 *r_buf
= get_membuf (&data
, r_buflen
);
774 status_sc_op_failure (rc
);
779 /* Decrypt INDATA of length INDATALEN using the card identified by
780 SERIALNO. Return the plaintext in a nwly allocated buffer stored
781 at the address of R_BUF.
783 Note, we currently support only RSA or more exactly algorithms
784 taking one input data element. */
786 agent_scd_pkdecrypt (const char *serialno
,
787 const unsigned char *indata
, size_t indatalen
,
788 unsigned char **r_buf
, size_t *r_buflen
)
791 char *p
, line
[ASSUAN_LINELENGTH
];
796 rc
= start_agent (1);
800 /* FIXME: use secure memory where appropriate */
801 if (indatalen
*2 + 50 > DIM(line
))
802 return gpg_error (GPG_ERR_GENERAL
);
804 /* Send the serialno command to initialize the connection. We don't
805 care about the data returned. If the card has already been
806 initialized, this is a very fast command. We request the openpgp
807 card because that is what we expect. */
808 rc
= assuan_transact (agent_ctx
, "SCD SERIALNO openpgp",
809 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
813 sprintf (line
, "SCD SETDATA ");
814 p
= line
+ strlen (line
);
815 for (i
=0; i
< indatalen
; i
++, p
+= 2 )
816 sprintf (p
, "%02X", indata
[i
]);
817 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
821 init_membuf (&data
, 1024);
822 snprintf (line
, DIM(line
)-1, "SCD PKDECRYPT %s", serialno
);
823 line
[DIM(line
)-1] = 0;
824 rc
= assuan_transact (agent_ctx
, line
,
825 membuf_data_cb
, &data
,
826 default_inq_cb
, NULL
, NULL
, NULL
);
829 xfree (get_membuf (&data
, &len
));
833 *r_buf
= get_membuf (&data
, r_buflen
);
835 rc
= gpg_error (GPG_ERR_ENOMEM
);
838 status_sc_op_failure (rc
);
844 /* Send a READCERT command to the SCdaemon. */
846 agent_scd_readcert (const char *certidstr
,
847 void **r_buf
, size_t *r_buflen
)
850 char line
[ASSUAN_LINELENGTH
];
855 rc
= start_agent (1);
859 init_membuf (&data
, 2048);
861 snprintf (line
, DIM(line
)-1, "SCD READCERT %s", certidstr
);
862 line
[DIM(line
)-1] = 0;
863 rc
= assuan_transact (agent_ctx
, line
,
864 membuf_data_cb
, &data
,
865 default_inq_cb
, NULL
, NULL
, NULL
);
868 xfree (get_membuf (&data
, &len
));
871 *r_buf
= get_membuf (&data
, r_buflen
);
873 return gpg_error (GPG_ERR_ENOMEM
);
880 /* Change the PIN of an OpenPGP card or reset the retry counter.
881 CHVNO 1: Change the PIN
882 2: For v1 cards: Same as 1.
883 For v2 cards: Reset the PIN using the Reset Code.
884 3: Change the admin PIN
885 101: Set a new PIN and reset the retry counter
886 102: For v1 cars: Same as 101.
887 For v2 cards: Set a new Reset Code.
888 SERIALNO is not used.
891 agent_scd_change_pin (int chvno
, const char *serialno
)
894 char line
[ASSUAN_LINELENGTH
];
895 const char *reset
= "";
903 rc
= start_agent (1);
907 snprintf (line
, DIM(line
)-1, "SCD PASSWD %s %d", reset
, chvno
);
908 line
[DIM(line
)-1] = 0;
909 rc
= assuan_transact (agent_ctx
, line
, NULL
, NULL
,
910 default_inq_cb
, NULL
, NULL
, NULL
);
911 status_sc_op_failure (rc
);
916 /* Perform a CHECKPIN operation. SERIALNO should be the serial
917 number of the card - optionally followed by the fingerprint;
918 however the fingerprint is ignored here. */
920 agent_scd_checkpin (const char *serialno
)
923 char line
[ASSUAN_LINELENGTH
];
925 rc
= start_agent (1);
929 snprintf (line
, DIM(line
)-1, "SCD CHECKPIN %s", serialno
);
930 line
[DIM(line
)-1] = 0;
931 rc
= assuan_transact (agent_ctx
, line
,
933 default_inq_cb
, NULL
, NULL
, NULL
);
934 status_sc_op_failure (rc
);
939 /* Dummy function, only used by the gpg 1.4 implementation. */
941 agent_clear_pin_cache (const char *sn
)
949 /* Note: All strings shall be UTF-8. On success the caller needs to
950 free the string stored at R_PASSPHRASE. On error NULL will be
951 stored at R_PASSPHRASE and an appropriate fpf error code
954 agent_get_passphrase (const char *cache_id
,
957 const char *desc_msg
,
963 char line
[ASSUAN_LINELENGTH
];
970 *r_passphrase
= NULL
;
972 rc
= start_agent (0);
976 /* Check that the gpg-agent understands the repeat option. */
977 if (assuan_transact (agent_ctx
,
978 "GETINFO cmd_has_option GET_PASSPHRASE repeat",
979 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
))
980 return gpg_error (GPG_ERR_NOT_SUPPORTED
);
982 if (cache_id
&& *cache_id
)
983 if (!(arg1
= percent_plus_escape (cache_id
)))
985 if (err_msg
&& *err_msg
)
986 if (!(arg2
= percent_plus_escape (err_msg
)))
988 if (prompt
&& *prompt
)
989 if (!(arg3
= percent_plus_escape (prompt
)))
991 if (desc_msg
&& *desc_msg
)
992 if (!(arg4
= percent_plus_escape (desc_msg
)))
995 snprintf (line
, DIM(line
)-1,
996 "GET_PASSPHRASE --data --repeat=%d%s -- %s %s %s %s",
998 check
? " --check --qualitybar":"",
1003 line
[DIM(line
)-1] = 0;
1009 init_membuf_secure (&data
, 64);
1010 rc
= assuan_transact (agent_ctx
, line
,
1011 membuf_data_cb
, &data
,
1012 default_inq_cb
, NULL
, NULL
, NULL
);
1015 xfree (get_membuf (&data
, NULL
));
1018 put_membuf (&data
, "", 1);
1019 *r_passphrase
= get_membuf (&data
, NULL
);
1021 rc
= gpg_error_from_syserror ();
1025 rc
= gpg_error_from_syserror ();
1035 agent_clear_passphrase (const char *cache_id
)
1038 char line
[ASSUAN_LINELENGTH
];
1040 if (!cache_id
|| !*cache_id
)
1043 rc
= start_agent (0);
1047 snprintf (line
, DIM(line
)-1, "CLEAR_PASSPHRASE %s", cache_id
);
1048 line
[DIM(line
)-1] = 0;
1049 return assuan_transact (agent_ctx
, line
, NULL
, NULL
,
1050 default_inq_cb
, NULL
, NULL
, NULL
);