1 /* gpg-connect-agent.c - Tool to connect to the agent.
2 * Copyright (C) 2005, 2007, 2008, 2010 Free Software Foundation, Inc.
3 * Copyright (C) 2014 Werner Koch
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 <https://www.gnu.org/licenses/>.
19 * SPDX-License-Identifier: GPL-3.0-or-later
32 #define INCLUDED_BY_MAIN_MODULE 1
33 #include "../common/i18n.h"
34 #include "../common/util.h"
35 #include "../common/asshelp.h"
36 #include "../common/sysutils.h"
37 #include "../common/membuf.h"
38 #include "../common/ttyio.h"
39 #ifdef HAVE_W32_SYSTEM
40 # include "../common/exechelp.h"
42 #include "../common/init.h"
43 #include "../common/comopt.h"
46 #define CONTROL_D ('D' - 'A' + 1)
47 #define octdigitp(p) (*(p) >= '0' && *(p) <= '7')
49 #define HISTORYNAME ".gpg-connect_history"
52 /* Constants to identify the commands and options. */
53 enum cmd_and_opt_values
84 /* The list of commands and options. */
85 static gpgrt_opt_t opts[] = {
86 ARGPARSE_group (301, N_("@\nOptions:\n ")),
88 ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
89 ARGPARSE_s_n (oQuiet, "quiet", N_("quiet")),
90 ARGPARSE_s_n (oHex, "hex", N_("print data out hex encoded")),
91 ARGPARSE_s_n (oDecode,"decode", N_("decode received data lines")),
92 ARGPARSE_s_n (oDirmngr,"dirmngr", N_("connect to the dirmngr")),
93 ARGPARSE_s_n (oKeyboxd,"keyboxd", N_("connect to the keyboxd")),
94 ARGPARSE_s_n (oUIServer, "uiserver", "@"),
95 ARGPARSE_s_s (oRawSocket, "raw-socket",
96 N_("|NAME|connect to Assuan socket NAME")),
97 ARGPARSE_s_s (oTcpSocket, "tcp-socket",
98 N_("|ADDR|connect to Assuan server at ADDR")),
99 ARGPARSE_s_n (oExec, "exec",
100 N_("run the Assuan server given on the command line")),
101 ARGPARSE_s_n (oNoExtConnect, "no-ext-connect",
102 N_("do not use extended connect mode")),
103 ARGPARSE_s_s (oRun, "run",
104 N_("|FILE|run commands from FILE on startup")),
105 ARGPARSE_s_n (oSubst, "subst", N_("run /subst on startup")),
107 ARGPARSE_s_n (oNoAutostart, "no-autostart", "@"),
108 ARGPARSE_s_n (oNoVerbose, "no-verbose", "@"),
109 ARGPARSE_s_n (oNoHistory,"no-history",
110 "do not use the command history file"),
111 ARGPARSE_s_s (oHomedir, "homedir", "@" ),
112 ARGPARSE_s_s (oAgentProgram, "agent-program", "@"),
113 ARGPARSE_s_s (oDirmngrProgram, "dirmngr-program", "@"),
114 ARGPARSE_s_s (oKeyboxdProgram, "keyboxd-program", "@"),
115 ARGPARSE_s_s (oChUid, "chuid", "@"),
116 ARGPARSE_s_n (oUnBuffered, "unbuffered", "@"),
122 /* We keep all global options in the structure OPT. */
125 int verbose; /* Verbosity level. */
126 int quiet; /* Be extra quiet. */
127 int autostart; /* Start the server if not running. */
128 const char *homedir; /* Configuration directory name */
129 const char *agent_program; /* Value of --agent-program. */
130 const char *dirmngr_program; /* Value of --dirmngr-program. */
131 const char *keyboxd_program; /* Value of --keyboxd-program. */
132 int hex; /* Print data lines in hex format. */
133 int decode; /* Decode received data lines. */
134 int use_dirmngr; /* Use the dirmngr and not gpg-agent. */
135 int use_keyboxd; /* Use the keyboxd and not gpg-agent. */
136 int use_uiserver; /* Use the standard UI server. */
137 const char *raw_socket; /* Name of socket to connect in raw mode. */
138 const char *tcp_socket; /* Name of server to connect in tcp mode. */
139 int exec; /* Run the pgm given on the command line. */
140 unsigned int connect_flags; /* Flags used for connecting. */
141 int enable_varsubst; /* Set if variable substitution is enabled. */
142 int trim_leading_spaces;
144 int unbuffered; /* Set if unbuffered mode for stdin/out is preferred. */
149 /* Definitions for /definq commands and a global linked list with all
153 struct definq_s *next;
154 char *name; /* Name of inquiry or NULL for any name. */
155 int is_var; /* True if FILE is a variable name. */
156 int is_prog; /* True if FILE is a program to run. */
157 char file[1]; /* Name of file or program. */
159 typedef struct definq_s *definq_t;
161 static definq_t definq_list;
162 static definq_t *definq_list_tail = &definq_list;
165 /* Variable definitions and glovbal table. */
168 struct variable_s *next;
169 char *value; /* Malloced value - always a string. */
170 char name[1]; /* Name of the variable. */
172 typedef struct variable_s *variable_t;
174 static variable_t variable_table;
177 /* To implement loops we store entire lines in a linked list. */
180 struct loopline_s *next;
183 typedef struct loopline_s *loopline_t;
186 /* This is used to store the pid of the server. */
187 static pid_t server_pid = (pid_t)(-1);
189 /* The current datasink file or NULL. */
190 static estream_t current_datasink;
192 /* A list of open file descriptors. */
196 #ifdef HAVE_W32_SYSTEM
199 } open_fd_table[256];
202 /*-- local prototypes --*/
203 static char *substitute_line_copy (const char *buffer);
204 static int read_and_print_response (assuan_context_t ctx, int withhash,
206 static assuan_context_t start_agent (void);
211 /* Print usage information and provide strings for help. */
213 my_strusage( int level )
219 case 9: p = "GPL-3.0-or-later"; break;
220 case 11: p = "@GPG@-connect-agent (@GNUPG@)";
222 case 13: p = VERSION; break;
223 case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
224 case 17: p = PRINTABLE_OS_NAME; break;
225 case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
228 case 40: p = _("Usage: @GPG@-connect-agent [options] (-h for help)");
231 p = _("Syntax: @GPG@-connect-agent [options]\n"
232 "Connect to a running agent and send commands\n");
234 case 31: p = "\nHome: "; break;
235 case 32: p = gnupg_homedir (); break;
236 case 33: p = "\n"; break;
238 default: p = NULL; break;
244 /* Unescape STRING and returned the malloced result. The surrounding
245 quotes must already be removed from STRING. */
247 unescape_string (const char *string)
249 const unsigned char *s;
256 for (s = (const unsigned char*)string, esc=0; *s; s++)
270 case '\\': n++; break;
272 if (s[1] && s[2] && hexdigitp (s+1) && hexdigitp (s+2))
278 && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
290 buffer = xmalloc (n+1);
291 d = (unsigned char*)buffer;
292 for (s = (const unsigned char*)string, esc=0; *s; s++)
298 case 'b': *d++ = '\b'; break;
299 case 't': *d++ = '\t'; break;
300 case 'v': *d++ = '\v'; break;
301 case 'n': *d++ = '\n'; break;
302 case 'f': *d++ = '\f'; break;
303 case 'r': *d++ = '\r'; break;
304 case '"': *d++ = '\"'; break;
305 case '\'': *d++ = '\''; break;
306 case '\\': *d++ = '\\'; break;
308 if (s[1] && s[2] && hexdigitp (s+1) && hexdigitp (s+2))
318 && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
320 *d++ = (atoi_1 (s)*64) + (atoi_1 (s+1)*8) + atoi_1 (s+2);
337 /* Do the percent unescaping and return a newly malloced string.
338 If WITH_PLUS is set '+' characters will be changed to space. */
340 unpercent_string (const char *string, int with_plus)
342 const unsigned char *s;
343 unsigned char *buffer, *p;
347 for (s=(const unsigned char *)string; *s; s++)
349 if (*s == '%' && s[1] && s[2])
355 else if (with_plus && *s == '+')
361 buffer = xmalloc (n+1);
363 for (s=(const unsigned char *)string; *s; s++)
365 if (*s == '%' && s[1] && s[2])
371 else if (with_plus && *s == '+')
377 return (char*)buffer;
385 set_var (const char *name, const char *value)
389 for (var = variable_table; var; var = var->next)
390 if (!strcmp (var->name, name))
394 var = xmalloc (sizeof *var + strlen (name));
396 strcpy (var->name, name);
397 var->next = variable_table;
398 variable_table = var;
401 var->value = value? xstrdup (value) : NULL;
407 set_int_var (const char *name, int value)
411 snprintf (numbuf, sizeof numbuf, "%d", value);
412 set_var (name, numbuf);
416 /* Return the value of a variable. That value is valid until a
417 variable of the name is changed. Return NULL if not found. Note
418 that envvars are copied to our variable list at the first access
419 and not at oprogram start. */
421 get_var (const char *name)
428 for (var = variable_table; var; var = var->next)
429 if (!strcmp (var->name, name))
431 if (!var && (s = getenv (name)))
432 return set_var (name, s);
433 if (!var || !var->value)
439 /* Perform some simple arithmetic operations. Caller must release
440 the return value. On error the return value is NULL. */
442 arithmetic_op (int operator, const char *operands)
447 while ( spacep (operands) )
451 result = strtol (operands, NULL, 0);
452 while (*operands && !spacep (operands) )
459 while ( spacep (operands) )
463 value = strtol (operands, NULL, 0);
464 while (*operands && !spacep (operands) )
468 case '+': result += value; break;
469 case '-': result -= value; break;
470 case '*': result *= value; break;
481 case '!': result = !value; break;
482 case '|': result = result || value; break;
483 case '&': result = result && value; break;
485 log_error ("unknown arithmetic operator '%c'\n", operator);
489 snprintf (numbuf, sizeof numbuf, "%ld", result);
490 return xstrdup (numbuf);
495 /* Extended version of get_var. This returns a malloced string and
496 understand the function syntax: "func args".
498 Defined functions are
500 get - Return a value described by the next argument:
501 cwd - The current working directory.
502 homedir - The gnupg homedir.
503 sysconfdir - GnuPG's system configuration directory.
504 bindir - GnuPG's binary directory.
505 libdir - GnuPG's library directory.
506 libexecdir - GnuPG's library directory for executable files.
507 datadir - GnuPG's data directory.
508 serverpid - The PID of the current server.
511 Remove C-style escapes from string. Note that "\0" and
512 "\x00" terminate the string implicitly. Use "\x7d" to
513 represent the closing brace. The args start right after
514 the first space after the function name.
518 Remove percent style ecaping from string. Note that "%00
519 terminates the string implicitly. Use "%7d" to represetn
520 the closing brace. The args start right after the first
521 space after the function name. "unpercent+" also maps '+'
526 Escape the args using the percent style. Tabs, formfeeds,
527 linefeeds, carriage return, and the plus sign are also
528 escaped. "percent+" also maps spaces to plus characters.
531 Assuming ARG is an integer, return the gpg-error code.
534 Assuming ARG is an integer, return the gpg-error source.
537 Assuming ARG is an integer return a formatted fpf error string.
540 Example: get_var_ext ("get sysconfdir") -> "/etc/gnupg"
544 get_var_ext (const char *name)
546 static int recursion_count;
550 char *free_me = NULL;
553 if (recursion_count > 50)
555 log_error ("variables nested too deeply\n");
560 free_me = opt.enable_varsubst? substitute_line_copy (name) : NULL;
563 for (s=name; *s && !spacep (s); s++)
568 result = s? xstrdup (s): NULL;
570 else if ( (s - name) == 3 && !strncmp (name, "get", 3))
574 if (!strcmp (s, "cwd"))
576 result = gnupg_getcwd ();
578 log_error ("getcwd failed: %s\n", strerror (errno));
580 else if (!strcmp (s, "homedir"))
581 result = xstrdup (gnupg_homedir ());
582 else if (!strcmp (s, "sysconfdir"))
583 result = xstrdup (gnupg_sysconfdir ());
584 else if (!strcmp (s, "bindir"))
585 result = xstrdup (gnupg_bindir ());
586 else if (!strcmp (s, "libdir"))
587 result = xstrdup (gnupg_libdir ());
588 else if (!strcmp (s, "libexecdir"))
589 result = xstrdup (gnupg_libexecdir ());
590 else if (!strcmp (s, "datadir"))
591 result = xstrdup (gnupg_datadir ());
592 else if (!strcmp (s, "serverpid"))
593 result = xasprintf ("%d", (int)server_pid);
596 log_error ("invalid argument '%s' for variable function 'get'\n", s);
597 log_info ("valid are: cwd, "
598 "{home,bin,lib,libexec,data}dir, serverpid\n");
602 else if ( (s - name) == 8 && !strncmp (name, "unescape", 8))
605 result = unescape_string (s);
607 else if ( (s - name) == 9 && !strncmp (name, "unpercent", 9))
610 result = unpercent_string (s, 0);
612 else if ( (s - name) == 10 && !strncmp (name, "unpercent+", 10))
615 result = unpercent_string (s, 1);
617 else if ( (s - name) == 7 && !strncmp (name, "percent", 7))
620 result = percent_escape (s, "+\t\r\n\f\v");
622 else if ( (s - name) == 8 && !strncmp (name, "percent+", 8))
625 result = percent_escape (s, "+\t\r\n\f\v");
626 for (p=result; *p; p++)
630 else if ( (s - name) == 7 && !strncmp (name, "errcode", 7))
633 intvalue = (int)strtol (s, NULL, 0);
634 result = xasprintf ("%d", gpg_err_code (intvalue));
636 else if ( (s - name) == 9 && !strncmp (name, "errsource", 9))
639 intvalue = (int)strtol (s, NULL, 0);
640 result = xasprintf ("%d", gpg_err_source (intvalue));
642 else if ( (s - name) == 9 && !strncmp (name, "errstring", 9))
645 intvalue = (int)strtol (s, NULL, 0);
646 result = xasprintf ("%s <%s>",
647 gpg_strerror (intvalue), gpg_strsource (intvalue));
649 else if ( (s - name) == 1 && strchr ("+-*/%!|&", *name))
651 result = arithmetic_op (*name, s+1);
655 log_error ("unknown variable function '%.*s'\n", (int)(s-name), name);
665 /* Substitute variables in LINE and return a new allocated buffer if
666 required. The function might modify LINE if the expanded version
669 substitute_line (char *buffer)
680 p = strchr (line, '$');
682 return result; /* No more variables. */
684 if (p[1] == '$') /* Escaped dollar sign. */
686 memmove (p, p+1, strlen (p+1)+1);
694 for (pend=p+2; *pend; pend++)
698 else if (*pend == '}')
705 return result; /* Unclosed - don't substitute. */
709 for (pend=p+1; *pend && !spacep (pend) && *pend != '$' ; pend++)
712 if (p[1] == '{' && *pend == '}')
716 freeme = get_var_ext (p+2);
724 value = get_var (p+1);
728 value = get_var (p+1);
731 valuelen = strlen (value);
732 if (valuelen <= pend - p)
734 memcpy (p, value, valuelen);
738 memmove (p, p+n, strlen (p+n)+1);
743 char *src = result? result : buffer;
746 dst = xmalloc (strlen (src) + valuelen + 1);
748 memcpy (dst, src, n);
749 memcpy (dst + n, value, valuelen);
751 strcpy (dst + n, pend);
762 /* Same as substitute_line but do not modify BUFFER. */
764 substitute_line_copy (const char *buffer)
768 p = xstrdup (buffer?buffer:"");
769 result = substitute_line (p);
779 assign_variable (char *line, int syslet)
781 char *name, *p, *tmp, *free_me, *buffer;
785 for (p=name; *p && !spacep (p); p++)
793 set_var (name, NULL); /* Remove variable. */
796 free_me = opt.enable_varsubst? substitute_line_copy (p) : NULL;
799 buffer = xmalloc (4 + strlen (p) + 1);
800 strcpy (stpcpy (buffer, "get "), p);
801 tmp = get_var_ext (buffer);
809 tmp = opt.enable_varsubst? substitute_line_copy (p) : NULL;
822 show_variables (void)
826 for (var = variable_table; var; var = var->next)
828 printf ("%-20s %s\n", var->name, var->value);
832 /* Store an inquire response pattern. Note, that this function may
833 change the content of LINE. We assume that leading white spaces
834 are already removed. */
836 add_definq (char *line, int is_var, int is_prog)
843 for (p=name; *p && !spacep (p); p++)
850 d = xmalloc (sizeof *d + strlen (p) );
853 d->is_prog = is_prog;
854 if ( !strcmp (name, "*"))
857 d->name = xstrdup (name);
860 *definq_list_tail = d;
861 definq_list_tail = &d->next;
865 /* Show all inquiry definitions. */
871 for (d=definq_list; d; d = d->next)
873 printf ("%-20s %c %s\n",
874 d->name, d->is_var? 'v' : d->is_prog? 'p':'f', d->file);
875 for (d=definq_list; d; d = d->next)
877 printf ("%-20s %c %s\n", "*",
878 d->is_var? 'v': d->is_prog? 'p':'f', d->file);
882 /* Clear all inquiry definitions. */
888 definq_t tmp = definq_list->next;
889 xfree (definq_list->name);
893 definq_list_tail = &definq_list;
898 do_sendfd (assuan_context_t ctx, char *line)
901 char *name, *mode, *p;
906 for (p=name; *p && !spacep (p); p++)
919 for (p=mode; *p && !spacep (p); p++)
926 fp = es_fopen (name, mode);
929 log_error ("can't open '%s' in \"%s\" mode: %s\n",
930 name, mode, strerror (errno));
936 log_error ("file '%s' opened in \"%s\" mode, fd=%d\n",
939 rc = assuan_sendfd (ctx, INT2FD (fd) );
941 log_error ("sending descriptor %d failed: %s\n", fd, gpg_strerror (rc));
947 do_recvfd (assuan_context_t ctx, char *line)
951 log_info ("This command has not yet been implemented\n");
959 char *varname, *name, *mode, *p;
962 #ifdef HAVE_W32_SYSTEM
963 if (server_pid == (pid_t)(-1))
965 log_error ("the pid of the server is unknown\n");
966 log_info ("use command \"/serverpid\" first\n");
971 /* Get variable name. */
973 for (p=varname; *p && !spacep (p); p++)
982 for (p=name; *p && !spacep (p); p++)
995 for (p=mode; *p && !spacep (p); p++)
1001 /* Open and send. */
1002 fp = es_fopen (name, mode);
1005 log_error ("can't open '%s' in \"%s\" mode: %s\n",
1006 name, mode, strerror (errno));
1009 fd = dup (es_fileno (fp));
1010 if (fd >= 0 && fd < DIM (open_fd_table))
1012 open_fd_table[fd].inuse = 1;
1013 #if defined(HAVE_W32_SYSTEM)
1015 HANDLE prochandle, handle, newhandle;
1017 handle = (void*)_get_osfhandle (fd);
1019 prochandle = OpenProcess (PROCESS_DUP_HANDLE, FALSE, server_pid);
1022 log_error ("failed to open the server process\n");
1027 if (!DuplicateHandle (GetCurrentProcess(), handle,
1028 prochandle, &newhandle, 0,
1029 TRUE, DUPLICATE_SAME_ACCESS ))
1031 log_error ("failed to duplicate the handle\n");
1033 CloseHandle (prochandle);
1036 CloseHandle (prochandle);
1037 open_fd_table[fd].handle = newhandle;
1040 log_info ("file '%s' opened in \"%s\" mode, fd=%d (libc=%d)\n",
1041 name, mode, (int)open_fd_table[fd].handle, fd);
1042 set_int_var (varname, (int)open_fd_table[fd].handle);
1045 log_info ("file '%s' opened in \"%s\" mode, fd=%d\n",
1047 set_int_var (varname, fd);
1052 log_error ("can't put fd %d into table\n", fd);
1054 close (fd); /* Table was full. */
1061 do_close (char *line)
1063 int fd = atoi (line);
1065 #ifdef HAVE_W32_SYSTEM
1068 for (i=0; i < DIM (open_fd_table); i++)
1069 if ( open_fd_table[i].inuse && open_fd_table[i].handle == (void*)fd)
1071 if (i < DIM (open_fd_table))
1075 log_error ("given fd (system handle) has not been opened\n");
1080 if (fd < 0 || fd >= DIM (open_fd_table))
1082 log_error ("invalid fd\n");
1086 if (!open_fd_table[fd].inuse)
1088 log_error ("given fd has not been opened\n");
1091 #ifdef HAVE_W32_SYSTEM
1092 CloseHandle (open_fd_table[fd].handle); /* Close duped handle. */
1095 open_fd_table[fd].inuse = 0;
1104 for (i=0; i < DIM (open_fd_table); i++)
1105 if (open_fd_table[i].inuse)
1107 #ifdef HAVE_W32_SYSTEM
1108 printf ("%-15d (libc=%d)\n", (int)open_fd_table[i].handle, i);
1110 printf ("%-15d\n", i);
1118 getinfo_pid_cb (void *opaque, const void *buffer, size_t length)
1120 membuf_t *mb = opaque;
1121 put_membuf (mb, buffer, length);
1125 /* Get the pid of the server and store it locally. */
1127 do_serverpid (assuan_context_t ctx)
1133 init_membuf (&mb, 100);
1134 rc = assuan_transact (ctx, "GETINFO pid", getinfo_pid_cb, &mb,
1135 NULL, NULL, NULL, NULL);
1136 put_membuf (&mb, "", 1);
1137 buffer = get_membuf (&mb, NULL);
1139 log_error ("command \"%s\" failed: %s\n",
1140 "GETINFO pid", gpg_strerror (rc));
1143 server_pid = (pid_t)strtoul (buffer, NULL, 10);
1145 log_info ("server's PID is %lu\n", (unsigned long)server_pid);
1151 /* Return true if the command is either "HELP" or "SCD HELP". */
1153 help_cmd_p (const char *line)
1155 if (!ascii_strncasecmp (line, "SCD", 3)
1156 && (spacep (line+3) || !line[3]))
1158 for (line += 3; spacep (line); line++)
1162 return (!ascii_strncasecmp (line, "HELP", 4)
1163 && (spacep (line+4) || !line[4]));
1167 /* gpg-connect-agent's entry point. */
1169 main (int argc, char **argv)
1171 gpgrt_argparse_t pargs;
1172 int no_more_options = 0;
1173 assuan_context_t ctx;
1179 const char *opt_run = NULL;
1180 gpgrt_stream_t script_fp = NULL;
1181 int use_tty, keep_line;
1187 unsigned int nestlevel;
1192 char **cmdline_commands = NULL;
1193 char *historyname = NULL;
1195 static const char *changeuser;
1198 early_system_init ();
1199 gnupg_rl_initialize ();
1200 gpgrt_set_strusage (my_strusage);
1201 log_set_prefix ("gpg-connect-agent",
1202 GPGRT_LOG_WITH_PREFIX|GPGRT_LOG_NO_REGISTRY);
1204 /* Make sure that our subsystems are ready. */
1206 init_common_subsystems (&argc, &argv);
1208 assuan_set_gpg_err_source (0);
1210 gnupg_init_signals (0, NULL);
1213 opt.connect_flags = 1;
1215 /* Parse the command line. */
1218 pargs.flags = ARGPARSE_FLAG_KEEP;
1219 while (!no_more_options && gpgrt_argparse (NULL, &pargs, opts))
1221 switch (pargs.r_opt)
1223 case oQuiet: opt.quiet = 1; break;
1224 case oVerbose: opt.verbose++; break;
1225 case oNoVerbose: opt.verbose = 0; break;
1226 case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
1227 case oAgentProgram: opt.agent_program = pargs.r.ret_str; break;
1228 case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str; break;
1229 case oKeyboxdProgram: opt.keyboxd_program = pargs.r.ret_str; break;
1230 case oNoAutostart: opt.autostart = 0; break;
1231 case oNoHistory: opt.no_history = 1; break;
1232 case oHex: opt.hex = 1; break;
1233 case oDecode: opt.decode = 1; break;
1234 case oDirmngr: opt.use_dirmngr = 1; break;
1235 case oKeyboxd: opt.use_keyboxd = 1; break;
1236 case oUIServer: opt.use_uiserver = 1; break;
1237 case oRawSocket: opt.raw_socket = pargs.r.ret_str; break;
1238 case oTcpSocket: opt.tcp_socket = pargs.r.ret_str; break;
1239 case oExec: opt.exec = 1; break;
1240 case oNoExtConnect: opt.connect_flags &= ~(1); break;
1241 case oRun: opt_run = pargs.r.ret_str; break;
1243 opt.enable_varsubst = 1;
1244 opt.trim_leading_spaces = 1;
1246 case oChUid: changeuser = pargs.r.ret_str; break;
1247 case oUnBuffered: opt.unbuffered = 1; break;
1249 default: pargs.err = 2; break;
1252 gpgrt_argparse (NULL, &pargs, NULL); /* Release internal state. */
1254 if (changeuser && gnupg_chuid (changeuser, 0))
1255 log_inc_errorcount (); /* Force later termination. */
1257 if (log_get_errorcount (0))
1260 /* Process common component options. Note that we set the config
1261 * dir only here so that --homedir will have an effect. */
1262 gpgrt_set_confdir (GPGRT_CONFDIR_SYS, gnupg_sysconfdir ());
1263 gpgrt_set_confdir (GPGRT_CONFDIR_USER, gnupg_homedir ());
1264 if (parse_comopt (GNUPG_MODULE_NAME_CONNECT_AGENT, opt.verbose > 1))
1267 if (comopt.no_autostart)
1270 /* --uiserver is a shortcut for a specific raw socket. This comes
1271 in particular handy on Windows. */
1272 if (opt.use_uiserver)
1274 opt.raw_socket = make_absfilename (gnupg_homedir (), "S.uiserver", NULL);
1277 /* Print a warning if an argument looks like an option. */
1278 if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
1282 for (i=0; i < argc; i++)
1283 if (argv[i][0] == '-' && argv[i][1] == '-')
1284 log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
1288 use_tty = (gnupg_isatty (fileno (stdin)) && gnupg_isatty (fileno (stdout)));
1294 log_error (_("option \"%s\" requires a program "
1295 "and optional arguments\n"), "--exec" );
1300 cmdline_commands = argv;
1302 if (opt.exec && opt.raw_socket)
1304 opt.raw_socket = NULL;
1305 log_info (_("option \"%s\" ignored due to \"%s\"\n"),
1306 "--raw-socket", "--exec");
1308 if (opt.exec && opt.tcp_socket)
1310 opt.tcp_socket = NULL;
1311 log_info (_("option \"%s\" ignored due to \"%s\"\n"),
1312 "--tcp-socket", "--exec");
1314 if (opt.tcp_socket && opt.raw_socket)
1316 opt.tcp_socket = NULL;
1317 log_info (_("option \"%s\" ignored due to \"%s\"\n"),
1318 "--tcp-socket", "--raw-socket");
1321 if (opt_run && !(script_fp = gpgrt_fopen (opt_run, "r")))
1323 log_error ("cannot open run file '%s': %s\n",
1324 opt_run, strerror (errno));
1331 assuan_fd_t no_close[3];
1333 no_close[0] = assuan_fd_from_posix_fd (es_fileno (es_stderr));
1334 no_close[1] = ASSUAN_INVALID_FD;
1336 rc = assuan_new (&ctx);
1339 log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
1343 rc = assuan_pipe_connect
1344 (ctx, *argv, (const char **)argv, no_close, NULL, NULL,
1345 (opt.connect_flags & 1) ? ASSUAN_PIPE_CONNECT_FDPASSING : 0);
1348 log_error ("assuan_pipe_connect_ext failed: %s\n",
1354 log_info ("server '%s' started\n", *argv);
1357 else if (opt.raw_socket)
1359 rc = assuan_new (&ctx);
1362 log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
1366 rc = assuan_socket_connect
1367 (ctx, opt.raw_socket, 0,
1368 (opt.connect_flags & 1) ? ASSUAN_SOCKET_CONNECT_FDPASSING : 0);
1371 log_error ("can't connect to socket '%s': %s\n",
1372 opt.raw_socket, gpg_strerror (rc));
1377 log_info ("connection to socket '%s' established\n", opt.raw_socket);
1379 else if (opt.tcp_socket)
1383 url = xstrconcat ("assuan://", opt.tcp_socket, NULL);
1385 rc = assuan_new (&ctx);
1388 log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
1392 rc = assuan_socket_connect (ctx, opt.tcp_socket, 0, 0);
1395 log_error ("can't connect to server '%s': %s\n",
1396 opt.tcp_socket, gpg_strerror (rc));
1401 log_info ("connection to socket '%s' established\n", url);
1406 ctx = start_agent ();
1408 /* See whether there is a line pending from the server (in case
1409 assuan did not run the initial handshaking). */
1410 if (assuan_pending_line (ctx))
1412 rc = read_and_print_response (ctx, 0, &cmderr);
1414 log_info (_("receiving line failed: %s\n"), gpg_strerror (rc) );
1417 if (!script_fp && opt.unbuffered)
1419 gpgrt_setvbuf (gpgrt_stdin, NULL, _IONBF, 0);
1420 setvbuf (stdout, NULL, _IONBF, 0);
1423 for (loopidx=0; loopidx < DIM (loopstack); loopidx++)
1424 loopstack[loopidx].collecting = 0;
1432 size_t maxlength = 2048;
1434 assert (loopidx < (int)DIM (loopstack));
1435 if (loopidx >= 0 && loopstack[loopidx].current)
1439 line = xstrdup (loopstack[loopidx].current->line);
1441 /* Never go beyond of the final /end. */
1442 if (loopstack[loopidx].current->next)
1443 loopstack[loopidx].current = loopstack[loopidx].current->next;
1444 else if (!strncmp (line, "/end", 4) && (!line[4]||spacep(line+4)))
1447 log_fatal ("/end command vanished\n");
1449 else if (cmdline_commands && *cmdline_commands && !script_fp)
1453 line = xstrdup (*cmdline_commands);
1459 else if (use_tty && !script_fp)
1463 if (!historyname && !opt.no_history)
1465 historyname = make_filename (gnupg_homedir (), HISTORYNAME, NULL);
1466 if (tty_read_history (historyname, 500))
1467 log_info ("error reading '%s': %s\n",
1469 gpg_strerror (gpg_error_from_syserror ()));
1472 line = tty_get ("> ");
1474 if (n==1 && *line == CONTROL_D)
1488 n = gpgrt_read_line (script_fp ? script_fp : gpgrt_stdin,
1489 &line, &linesize, &maxlength);
1493 log_error (_("error reading input: %s\n"), strerror (errno));
1496 gpgrt_fclose (script_fp);
1498 log_error ("stopping script execution\n");
1508 gpgrt_fclose (script_fp);
1511 log_info ("end of script\n");
1518 log_error (_("line too long - skipped\n"));
1521 if (memchr (line, 0, n))
1522 log_info (_("line shortened due to embedded Nul character\n"));
1523 if (line[n-1] == '\n')
1526 if (opt.trim_leading_spaces)
1528 const char *s = line;
1541 if (loopidx+1 >= 0 && loopstack[loopidx+1].collecting)
1545 ll = xmalloc (sizeof *ll + strlen (line));
1547 strcpy (ll->line, line);
1548 *loopstack[loopidx+1].tail = ll;
1549 loopstack[loopidx+1].tail = &ll->next;
1551 if (!strncmp (line, "/end", 4) && (!line[4]||spacep(line+4)))
1552 loopstack[loopidx+1].nestlevel--;
1553 else if (!strncmp (line, "/while", 6) && (!line[6]||spacep(line+6)))
1554 loopstack[loopidx+1].nestlevel++;
1556 if (loopstack[loopidx+1].nestlevel)
1558 /* We reached the corresponding /end. */
1559 loopstack[loopidx+1].collecting = 0;
1565 /* Handle control commands. */
1568 for (p=cmd; *p && !spacep (p); p++)
1574 if (!strcmp (cmd, "let"))
1576 assign_variable (p, 0);
1578 else if (!strcmp (cmd, "slet"))
1580 /* Deprecated - never used in a released version. */
1581 assign_variable (p, 1);
1583 else if (!strcmp (cmd, "showvar"))
1587 else if (!strcmp (cmd, "definq"))
1589 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1592 add_definq (tmpline, 1, 0);
1596 add_definq (p, 1, 0);
1598 else if (!strcmp (cmd, "definqfile"))
1600 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1603 add_definq (tmpline, 0, 0);
1607 add_definq (p, 0, 0);
1609 else if (!strcmp (cmd, "definqprog"))
1611 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1614 add_definq (tmpline, 0, 1);
1618 add_definq (p, 0, 1);
1620 else if (!strcmp (cmd, "datafile"))
1624 if (current_datasink)
1626 if (current_datasink != es_stdout)
1627 es_fclose (current_datasink);
1628 current_datasink = NULL;
1630 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1631 fname = tmpline? tmpline : p;
1632 if (fname && !strcmp (fname, "-"))
1633 current_datasink = es_stdout;
1634 else if (fname && *fname)
1636 current_datasink = es_fopen (fname, "wb");
1637 if (!current_datasink)
1638 log_error ("can't open '%s': %s\n",
1639 fname, strerror (errno));
1643 else if (!strcmp (cmd, "showdef"))
1647 else if (!strcmp (cmd, "cleardef"))
1651 else if (!strcmp (cmd, "echo"))
1653 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1662 else if (!strcmp (cmd, "sendfd"))
1664 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1667 do_sendfd (ctx, tmpline);
1674 else if (!strcmp (cmd, "recvfd"))
1676 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1679 do_recvfd (ctx, tmpline);
1686 else if (!strcmp (cmd, "open"))
1688 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1697 else if (!strcmp (cmd, "close"))
1699 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1708 else if (!strcmp (cmd, "showopen"))
1712 else if (!strcmp (cmd, "serverpid"))
1716 else if (!strcmp (cmd, "hex"))
1718 else if (!strcmp (cmd, "nohex"))
1720 else if (!strcmp (cmd, "decode"))
1722 else if (!strcmp (cmd, "nodecode"))
1724 else if (!strcmp (cmd, "subst"))
1726 opt.enable_varsubst = 1;
1727 opt.trim_leading_spaces = 1;
1729 else if (!strcmp (cmd, "nosubst"))
1730 opt.enable_varsubst = 0;
1731 else if (!strcmp (cmd, "run"))
1735 for (p2=p; *p2 && !spacep (p2); p2++)
1743 log_error ("syntax error in run command\n");
1746 gpgrt_fclose (script_fp);
1752 log_error ("cannot nest run commands - stop\n");
1753 gpgrt_fclose (script_fp);
1756 else if (!(script_fp = gpgrt_fopen (p, "r")))
1758 log_error ("cannot open run file '%s': %s\n",
1759 p, strerror (errno));
1761 else if (opt.verbose)
1762 log_info ("running commands from '%s'\n", p);
1764 else if (!strcmp (cmd, "while"))
1766 if (loopidx+2 >= (int)DIM(loopstack))
1768 log_error ("blocks are nested too deep\n");
1769 /* We should better die or break all loop in this
1770 case as recovering from this error won't be
1775 loopstack[loopidx+1].head = NULL;
1776 loopstack[loopidx+1].tail = &loopstack[loopidx+1].head;
1777 loopstack[loopidx+1].current = NULL;
1778 loopstack[loopidx+1].nestlevel = 1;
1779 loopstack[loopidx+1].oneshot = 0;
1780 loopstack[loopidx+1].condition = xstrdup (p);
1781 loopstack[loopidx+1].collecting = 1;
1784 else if (!strcmp (cmd, "if"))
1786 if (loopidx+2 >= (int)DIM(loopstack))
1788 log_error ("blocks are nested too deep\n");
1792 /* Note that we need to evaluate the condition right
1793 away and not just at the end of the block as we
1795 loopstack[loopidx+1].head = NULL;
1796 loopstack[loopidx+1].tail = &loopstack[loopidx+1].head;
1797 loopstack[loopidx+1].current = NULL;
1798 loopstack[loopidx+1].nestlevel = 1;
1799 loopstack[loopidx+1].oneshot = 1;
1800 loopstack[loopidx+1].condition = substitute_line_copy (p);
1801 loopstack[loopidx+1].collecting = 1;
1804 else if (!strcmp (cmd, "end"))
1807 log_error ("stray /end command encountered - ignored\n");
1814 /* Evaluate the condition. */
1815 tmpcond = xstrdup (loopstack[loopidx].condition);
1816 if (loopstack[loopidx].oneshot)
1818 xfree (loopstack[loopidx].condition);
1819 loopstack[loopidx].condition = xstrdup ("0");
1821 tmpline = substitute_line (tmpcond);
1822 value = tmpline? tmpline : tmpcond;
1823 /* "true" or "yes" are commonly used to mean TRUE;
1824 all other strings will evaluate to FALSE due to
1826 if (!ascii_strcasecmp (value, "true")
1827 || !ascii_strcasecmp (value, "yes"))
1830 condition = strtol (value, NULL, 0);
1837 loopstack[loopidx].current = loopstack[loopidx].head;
1842 while (loopstack[loopidx].head)
1844 loopline_t tmp = loopstack[loopidx].head->next;
1845 xfree (loopstack[loopidx].head);
1846 loopstack[loopidx].head = tmp;
1848 loopstack[loopidx].tail = NULL;
1849 loopstack[loopidx].current = NULL;
1850 loopstack[loopidx].nestlevel = 0;
1851 loopstack[loopidx].collecting = 0;
1852 loopstack[loopidx].oneshot = 0;
1853 xfree (loopstack[loopidx].condition);
1854 loopstack[loopidx].condition = NULL;
1859 else if (!strcmp (cmd, "bye") || !strcmp (cmd, "quit"))
1863 else if (!strcmp (cmd, "sleep"))
1867 else if (!strcmp (cmd, "history"))
1869 if (!strcmp (p, "--clear"))
1871 tty_read_history (NULL, 0);
1874 log_error ("Only \"/history --clear\" is supported\n");
1876 else if (!strcmp (cmd, "help"))
1879 "Available commands:\n"
1880 "/echo ARGS Echo ARGS.\n"
1881 "/let NAME VALUE Set variable NAME to VALUE.\n"
1882 "/showvar Show all variables.\n"
1883 "/definq NAME VAR Use content of VAR for inquiries with NAME.\n"
1884 "/definqfile NAME FILE Use content of FILE for inquiries with NAME.\n"
1885 "/definqprog NAME PGM Run PGM for inquiries with NAME.\n"
1886 "/datafile [NAME] Write all D line content to file NAME.\n"
1887 "/showdef Print all definitions.\n"
1888 "/cleardef Delete all definitions.\n"
1889 "/sendfd FILE MODE Open FILE and pass descriptor to server.\n"
1890 "/recvfd Receive FD from server and print.\n"
1891 "/open VAR FILE MODE Open FILE and assign the file descriptor to VAR.\n"
1892 "/close FD Close file with descriptor FD.\n"
1893 "/showopen Show descriptors of all open files.\n"
1894 "/serverpid Retrieve the pid of the server.\n"
1895 "/[no]hex Enable hex dumping of received data lines.\n"
1896 "/[no]decode Enable decoding of received data lines.\n"
1897 "/[no]subst Enable variable substitution.\n"
1898 "/run FILE Run commands from FILE.\n"
1899 "/if VAR Begin conditional block controlled by VAR.\n"
1900 "/while VAR Begin loop controlled by VAR.\n"
1901 "/end End loop or condition\n"
1902 "/history Manage the history\n"
1903 "/bye Terminate gpg-connect-agent.\n"
1904 "/help Print this help.");
1907 log_error (_("unknown command '%s'\n"), cmd );
1912 if (opt.verbose && script_fp)
1915 tmpline = opt.enable_varsubst? substitute_line (line) : NULL;
1918 rc = assuan_write_line (ctx, tmpline);
1922 rc = assuan_write_line (ctx, line);
1925 log_info (_("sending line failed: %s\n"), gpg_strerror (rc) );
1928 if (*line == '#' || !*line)
1929 continue; /* Don't expect a response for a comment line. */
1931 rc = read_and_print_response (ctx, help_cmd_p (line), &cmderr);
1933 log_info (_("receiving line failed: %s\n"), gpg_strerror (rc) );
1934 if ((rc || cmderr) && script_fp)
1936 log_error ("stopping script execution\n");
1937 gpgrt_fclose (script_fp);
1942 /* FIXME: If the last command was BYE or the server died for
1943 some other reason, we won't notice until we get the next
1944 input command. Probing the connection with a non-blocking
1945 read could help to notice termination or other problems
1950 log_info ("closing connection to %s\n",
1951 opt.use_dirmngr? "dirmngr" :
1952 opt.use_keyboxd? "keyboxd" :
1956 if (historyname && tty_write_history (historyname))
1957 log_info ("error writing '%s': %s\n",
1958 historyname, gpg_strerror (gpg_error_from_syserror ()));
1961 /* XXX: We would like to release the context here, but libassuan
1962 nicely says good bye to the server, which results in a SIGPIPE if
1963 the server died. Unfortunately, libassuan does not ignore
1964 SIGPIPE when used with UNIX sockets, hence we simply leak the
1967 assuan_release (ctx);
1969 gpgrt_annotate_leaked_object (ctx);
1970 xfree (historyname);
1976 /* Handle an Inquire from the server. Return False if it could not be
1977 handled; in this case the caller shll complete the operation. LINE
1978 is the complete line as received from the server. This function
1979 may change the content of LINE. */
1981 handle_inquire (assuan_context_t ctx, char *line)
1985 /* FIXME: Due to the use of popen we can't easily switch to estream. */
1991 /* Skip the command and trailing spaces. */
1992 for (; *line && !spacep (line); line++)
1994 while (spacep (line))
1998 for (; *line && !spacep (line); line++)
2003 /* Now match it against our list. The second loop is there to
2004 detect the match-all entry. */
2005 for (d=definq_list; d; d = d->next)
2006 if (d->name && !strcmp (d->name, name))
2009 for (d=definq_list; d; d = d->next)
2015 log_info ("no handler for inquiry '%s' found\n", name);
2021 char *tmpvalue = get_var_ext (d->file);
2023 rc = assuan_send_data (ctx, tmpvalue, strlen (tmpvalue));
2025 rc = assuan_send_data (ctx, "", 0);
2028 log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
2034 fp = popen (d->file, "r");
2036 log_error ("error executing '%s': %s\n",
2037 d->file, strerror (errno));
2038 else if (opt.verbose)
2039 log_error ("handling inquiry '%s' by running '%s'\n",
2044 fp = fopen (d->file, "rb");
2046 log_error ("error opening '%s': %s\n", d->file, strerror (errno));
2047 else if (opt.verbose)
2048 log_error ("handling inquiry '%s' by returning content of '%s'\n",
2054 while ( (n = fread (buffer, 1, sizeof buffer, fp)) )
2056 rc = assuan_send_data (ctx, buffer, n);
2059 log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
2064 log_error ("error reading from '%s': %s\n", d->file, strerror (errno));
2069 else if (d->is_prog)
2077 rc = assuan_send_data (ctx, NULL, cancelled);
2079 log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
2085 /* Read all response lines from server and print them. Returns 0 on
2086 success or an assuan error code. If WITHHASH istrue, comment lines
2087 are printed. Sets R_GOTERR to true if the command did not returned
2090 read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr)
2103 rc = assuan_read_line (ctx, &line, &linelen);
2107 if ((withhash || opt.verbose > 1) && *line == '#')
2109 fwrite (line, linelen, 1, stdout);
2113 while (*line == '#' || !linelen);
2116 && line[0] == 'D' && line[1] == ' ')
2118 if (current_datasink)
2120 const unsigned char *s;
2123 for (j=2, s=(unsigned char*)line+2; j < linelen; j++, s++ )
2125 if (*s == '%' && j+2 < linelen)
2133 es_putc (c, current_datasink);
2138 for (i=2; i < linelen; )
2142 printf ("D[%04X] ", i-2);
2143 for (j=0; j < 16 ; j++, i++)
2148 printf (" %02X", ((unsigned char*)line)[i]);
2150 fputs (" ", stdout);
2152 fputs (" ", stdout);
2154 for (j=0; j < 16; j++, i++)
2156 unsigned int c = ((unsigned char*)line)[i];
2159 else if (isascii (c) && isprint (c) && !iscntrl (c))
2167 else if (opt.decode)
2169 const unsigned char *s;
2173 for (j=2, s=(unsigned char*)line+2; j < linelen; j++, s++ )
2177 fputs ("D ", stdout);
2180 if (*s == '%' && j+2 < linelen)
2192 need_lf = (c != '\n');
2196 fwrite (line, linelen, 1, stdout);
2204 if (!current_datasink || current_datasink != es_stdout)
2211 && (line[1] == '\0' || line[1] == ' '))
2213 if (!current_datasink || current_datasink != es_stdout)
2215 fwrite (line, linelen, 1, stdout);
2219 else if (linelen >= 2
2220 && line[0] == 'O' && line[1] == 'K'
2221 && (line[2] == '\0' || line[2] == ' '))
2223 if (!current_datasink || current_datasink != es_stdout)
2225 fwrite (line, linelen, 1, stdout);
2228 set_int_var ("?", 0);
2231 else if (linelen >= 3
2232 && line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
2233 && (line[3] == '\0' || line[3] == ' '))
2237 errval = strtol (line+3, NULL, 10);
2240 set_int_var ("?", errval);
2241 if (!current_datasink || current_datasink != es_stdout)
2243 fwrite (line, linelen, 1, stdout);
2249 else if (linelen >= 7
2250 && line[0] == 'I' && line[1] == 'N' && line[2] == 'Q'
2251 && line[3] == 'U' && line[4] == 'I' && line[5] == 'R'
2253 && (line[7] == '\0' || line[7] == ' '))
2255 if (!current_datasink || current_datasink != es_stdout)
2257 fwrite (line, linelen, 1, stdout);
2260 if (!handle_inquire (ctx, line))
2261 assuan_write_line (ctx, "CANCEL");
2263 else if (linelen >= 3
2264 && line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
2265 && (line[3] == '\0' || line[3] == ' '))
2267 if (!current_datasink || current_datasink != es_stdout)
2269 fwrite (line, linelen, 1, stdout);
2272 /* Received from server, thus more responses are expected. */
2275 return gpg_error (GPG_ERR_ASS_INV_RESPONSE);
2283 /* Connect to the agent and send the standard options. */
2284 static assuan_context_t
2288 assuan_context_t ctx;
2289 session_env_t session_env;
2291 session_env = session_env_new ();
2293 log_fatal ("error allocating session environment block: %s\n",
2295 if (opt.use_dirmngr)
2296 err = start_new_dirmngr (&ctx,
2297 GPG_ERR_SOURCE_DEFAULT,
2298 opt.dirmngr_program,
2302 else if (opt.use_keyboxd)
2303 err = start_new_keyboxd (&ctx,
2304 GPG_ERR_SOURCE_DEFAULT,
2305 opt.keyboxd_program,
2310 err = start_new_gpg_agent (&ctx,
2311 GPG_ERR_SOURCE_DEFAULT,
2319 session_env_release (session_env);
2323 && (gpg_err_code (err)
2324 == (opt.use_dirmngr? GPG_ERR_NO_DIRMNGR :
2325 opt.use_keyboxd? GPG_ERR_NO_KEYBOXD : GPG_ERR_NO_AGENT)))
2327 /* In the no-autostart case we don't make gpg-connect-agent
2328 fail on a missing server. */
2329 log_info (opt.use_dirmngr?
2330 _("no dirmngr running in this session\n"):
2332 _("no keybox daemon running in this session\n"):
2333 _("no gpg-agent running in this session\n"));
2338 log_error (_("error sending standard options: %s\n"),
2339 gpg_strerror (err));