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/>.
33 #include "../common/util.h"
34 #include "../common/asshelp.h"
35 #include "../common/sysutils.h"
36 #include "../common/membuf.h"
37 #include "../common/ttyio.h"
38 #ifdef HAVE_W32_SYSTEM
39 # include "../common/exechelp.h"
41 #include "../common/init.h"
44 #define CONTROL_D ('D' - 'A' + 1)
45 #define octdigitp(p) (*(p) >= '0' && *(p) <= '7')
47 /* Constants to identify the commands and options. */
48 enum cmd_and_opt_values
73 /* The list of commands and options. */
74 static ARGPARSE_OPTS opts[] = {
75 ARGPARSE_group (301, N_("@\nOptions:\n ")),
77 ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
78 ARGPARSE_s_n (oQuiet, "quiet", N_("quiet")),
79 ARGPARSE_s_n (oHex, "hex", N_("print data out hex encoded")),
80 ARGPARSE_s_n (oDecode,"decode", N_("decode received data lines")),
81 ARGPARSE_s_n (oDirmngr,"dirmngr", N_("connect to the dirmngr")),
82 ARGPARSE_s_n (oUIServer, "uiserver", "@"),
83 ARGPARSE_s_s (oRawSocket, "raw-socket",
84 N_("|NAME|connect to Assuan socket NAME")),
85 ARGPARSE_s_s (oTcpSocket, "tcp-socket",
86 N_("|ADDR|connect to Assuan server at ADDR")),
87 ARGPARSE_s_n (oExec, "exec",
88 N_("run the Assuan server given on the command line")),
89 ARGPARSE_s_n (oNoExtConnect, "no-ext-connect",
90 N_("do not use extended connect mode")),
91 ARGPARSE_s_s (oRun, "run",
92 N_("|FILE|run commands from FILE on startup")),
93 ARGPARSE_s_n (oSubst, "subst", N_("run /subst on startup")),
95 ARGPARSE_s_n (oNoAutostart, "no-autostart", "@"),
96 ARGPARSE_s_n (oNoVerbose, "no-verbose", "@"),
97 ARGPARSE_s_s (oHomedir, "homedir", "@" ),
98 ARGPARSE_s_s (oAgentProgram, "agent-program", "@"),
99 ARGPARSE_s_s (oDirmngrProgram, "dirmngr-program", "@"),
105 /* We keep all global options in the structure OPT. */
108 int verbose; /* Verbosity level. */
109 int quiet; /* Be extra quiet. */
110 int autostart; /* Start the server if not running. */
111 const char *homedir; /* Configuration directory name */
112 const char *agent_program; /* Value of --agent-program. */
113 const char *dirmngr_program; /* Value of --dirmngr-program. */
114 int hex; /* Print data lines in hex format. */
115 int decode; /* Decode received data lines. */
116 int use_dirmngr; /* Use the dirmngr and not gpg-agent. */
117 int use_uiserver; /* Use the standard UI server. */
118 const char *raw_socket; /* Name of socket to connect in raw mode. */
119 const char *tcp_socket; /* Name of server to connect in tcp mode. */
120 int exec; /* Run the pgm given on the command line. */
121 unsigned int connect_flags; /* Flags used for connecting. */
122 int enable_varsubst; /* Set if variable substitution is enabled. */
123 int trim_leading_spaces;
128 /* Definitions for /definq commands and a global linked list with all
132 struct definq_s *next;
133 char *name; /* Name of inquiry or NULL for any name. */
134 int is_var; /* True if FILE is a variable name. */
135 int is_prog; /* True if FILE is a program to run. */
136 char file[1]; /* Name of file or program. */
138 typedef struct definq_s *definq_t;
140 static definq_t definq_list;
141 static definq_t *definq_list_tail = &definq_list;
144 /* Variable definitions and glovbal table. */
147 struct variable_s *next;
148 char *value; /* Malloced value - always a string. */
149 char name[1]; /* Name of the variable. */
151 typedef struct variable_s *variable_t;
153 static variable_t variable_table;
156 /* To implement loops we store entire lines in a linked list. */
159 struct loopline_s *next;
162 typedef struct loopline_s *loopline_t;
165 /* This is used to store the pid of the server. */
166 static pid_t server_pid = (pid_t)(-1);
168 /* The current datasink file or NULL. */
169 static FILE *current_datasink;
171 /* A list of open file descriptors. */
175 #ifdef HAVE_W32_SYSTEM
178 } open_fd_table[256];
181 /*-- local prototypes --*/
182 static char *substitute_line_copy (const char *buffer);
183 static int read_and_print_response (assuan_context_t ctx, int withhash,
185 static assuan_context_t start_agent (void);
190 /* Print usage information and and provide strings for help. */
192 my_strusage( int level )
198 case 11: p = "@GPG@-connect-agent (@GNUPG@)";
200 case 13: p = VERSION; break;
201 case 17: p = PRINTABLE_OS_NAME; break;
202 case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
205 case 40: p = _("Usage: @GPG@-connect-agent [options] (-h for help)");
208 p = _("Syntax: @GPG@-connect-agent [options]\n"
209 "Connect to a running agent and send commands\n");
211 case 31: p = "\nHome: "; break;
212 case 32: p = gnupg_homedir (); break;
213 case 33: p = "\n"; break;
215 default: p = NULL; break;
221 /* Unescape STRING and returned the malloced result. The surrounding
222 quotes must already be removed from STRING. */
224 unescape_string (const char *string)
226 const unsigned char *s;
233 for (s = (const unsigned char*)string, esc=0; *s; s++)
247 case '\\': n++; break;
249 if (s[1] && s[2] && hexdigitp (s+1) && hexdigitp (s+2))
255 && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
267 buffer = xmalloc (n+1);
268 d = (unsigned char*)buffer;
269 for (s = (const unsigned char*)string, esc=0; *s; s++)
275 case 'b': *d++ = '\b'; break;
276 case 't': *d++ = '\t'; break;
277 case 'v': *d++ = '\v'; break;
278 case 'n': *d++ = '\n'; break;
279 case 'f': *d++ = '\f'; break;
280 case 'r': *d++ = '\r'; break;
281 case '"': *d++ = '\"'; break;
282 case '\'': *d++ = '\''; break;
283 case '\\': *d++ = '\\'; break;
285 if (s[1] && s[2] && hexdigitp (s+1) && hexdigitp (s+2))
295 && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
297 *d++ = (atoi_1 (s)*64) + (atoi_1 (s+1)*8) + atoi_1 (s+2);
314 /* Do the percent unescaping and return a newly malloced string.
315 If WITH_PLUS is set '+' characters will be changed to space. */
317 unpercent_string (const char *string, int with_plus)
319 const unsigned char *s;
320 unsigned char *buffer, *p;
324 for (s=(const unsigned char *)string; *s; s++)
326 if (*s == '%' && s[1] && s[2])
332 else if (with_plus && *s == '+')
338 buffer = xmalloc (n+1);
340 for (s=(const unsigned char *)string; *s; s++)
342 if (*s == '%' && s[1] && s[2])
348 else if (with_plus && *s == '+')
354 return (char*)buffer;
362 set_var (const char *name, const char *value)
366 for (var = variable_table; var; var = var->next)
367 if (!strcmp (var->name, name))
371 var = xmalloc (sizeof *var + strlen (name));
373 strcpy (var->name, name);
374 var->next = variable_table;
375 variable_table = var;
378 var->value = value? xstrdup (value) : NULL;
384 set_int_var (const char *name, int value)
388 snprintf (numbuf, sizeof numbuf, "%d", value);
389 set_var (name, numbuf);
393 /* Return the value of a variable. That value is valid until a
394 variable of the name is changed. Return NULL if not found. Note
395 that envvars are copied to our variable list at the first access
396 and not at oprogram start. */
398 get_var (const char *name)
405 for (var = variable_table; var; var = var->next)
406 if (!strcmp (var->name, name))
408 if (!var && (s = getenv (name)))
409 return set_var (name, s);
410 if (!var || !var->value)
416 /* Perform some simple arithmetic operations. Caller must release
417 the return value. On error the return value is NULL. */
419 arithmetic_op (int operator, const char *operands)
424 while ( spacep (operands) )
428 result = strtol (operands, NULL, 0);
429 while (*operands && !spacep (operands) )
436 while ( spacep (operands) )
440 value = strtol (operands, NULL, 0);
441 while (*operands && !spacep (operands) )
445 case '+': result += value; break;
446 case '-': result -= value; break;
447 case '*': result *= value; break;
458 case '!': result = !value; break;
459 case '|': result = result || value; break;
460 case '&': result = result && value; break;
462 log_error ("unknown arithmetic operator '%c'\n", operator);
466 snprintf (numbuf, sizeof numbuf, "%ld", result);
467 return xstrdup (numbuf);
472 /* Extended version of get_var. This returns a malloced string and
473 understand the function syntax: "func args".
475 Defined functions are
477 get - Return a value described by the next argument:
478 cwd - The current working directory.
479 homedir - The gnupg homedir.
480 sysconfdir - GnuPG's system configuration directory.
481 bindir - GnuPG's binary directory.
482 libdir - GnuPG's library directory.
483 libexecdir - GnuPG's library directory for executable files.
484 datadir - GnuPG's data directory.
485 serverpid - The PID of the current server.
488 Remove C-style escapes from string. Note that "\0" and
489 "\x00" terminate the string implictly. Use "\x7d" to
490 represent the closing brace. The args start right after
491 the first space after the function name.
495 Remove percent style ecaping from string. Note that "%00
496 terminates the string implicitly. Use "%7d" to represetn
497 the closing brace. The args start right after the first
498 space after the function name. "unpercent+" also maps '+'
503 Escape the args using the percent style. Tabs, formfeeds,
504 linefeeds, carriage return, and the plus sign are also
505 escaped. "percent+" also maps spaces to plus characters.
508 Assuming ARG is an integer, return the gpg-error code.
511 Assuming ARG is an integer, return the gpg-error source.
514 Assuming ARG is an integer return a formatted fpf error string.
517 Example: get_var_ext ("get sysconfdir") -> "/etc/gnupg"
521 get_var_ext (const char *name)
523 static int recursion_count;
527 char *free_me = NULL;
530 if (recursion_count > 50)
532 log_error ("variables nested too deeply\n");
537 free_me = opt.enable_varsubst? substitute_line_copy (name) : NULL;
540 for (s=name; *s && !spacep (s); s++)
545 result = s? xstrdup (s): NULL;
547 else if ( (s - name) == 3 && !strncmp (name, "get", 3))
551 if (!strcmp (s, "cwd"))
553 result = gnupg_getcwd ();
555 log_error ("getcwd failed: %s\n", strerror (errno));
557 else if (!strcmp (s, "homedir"))
558 result = xstrdup (gnupg_homedir ());
559 else if (!strcmp (s, "sysconfdir"))
560 result = xstrdup (gnupg_sysconfdir ());
561 else if (!strcmp (s, "bindir"))
562 result = xstrdup (gnupg_bindir ());
563 else if (!strcmp (s, "libdir"))
564 result = xstrdup (gnupg_libdir ());
565 else if (!strcmp (s, "libexecdir"))
566 result = xstrdup (gnupg_libexecdir ());
567 else if (!strcmp (s, "datadir"))
568 result = xstrdup (gnupg_datadir ());
569 else if (!strcmp (s, "serverpid"))
570 result = xasprintf ("%d", (int)server_pid);
573 log_error ("invalid argument '%s' for variable function 'get'\n", s);
574 log_info ("valid are: cwd, "
575 "{home,bin,lib,libexec,data}dir, serverpid\n");
579 else if ( (s - name) == 8 && !strncmp (name, "unescape", 8))
582 result = unescape_string (s);
584 else if ( (s - name) == 9 && !strncmp (name, "unpercent", 9))
587 result = unpercent_string (s, 0);
589 else if ( (s - name) == 10 && !strncmp (name, "unpercent+", 10))
592 result = unpercent_string (s, 1);
594 else if ( (s - name) == 7 && !strncmp (name, "percent", 7))
597 result = percent_escape (s, "+\t\r\n\f\v");
599 else if ( (s - name) == 8 && !strncmp (name, "percent+", 8))
602 result = percent_escape (s, "+\t\r\n\f\v");
603 for (p=result; *p; p++)
607 else if ( (s - name) == 7 && !strncmp (name, "errcode", 7))
610 intvalue = (int)strtol (s, NULL, 0);
611 result = xasprintf ("%d", gpg_err_code (intvalue));
613 else if ( (s - name) == 9 && !strncmp (name, "errsource", 9))
616 intvalue = (int)strtol (s, NULL, 0);
617 result = xasprintf ("%d", gpg_err_source (intvalue));
619 else if ( (s - name) == 9 && !strncmp (name, "errstring", 9))
622 intvalue = (int)strtol (s, NULL, 0);
623 result = xasprintf ("%s <%s>",
624 gpg_strerror (intvalue), gpg_strsource (intvalue));
626 else if ( (s - name) == 1 && strchr ("+-*/%!|&", *name))
628 result = arithmetic_op (*name, s+1);
632 log_error ("unknown variable function '%.*s'\n", (int)(s-name), name);
642 /* Substitute variables in LINE and return a new allocated buffer if
643 required. The function might modify LINE if the expanded version
646 substitute_line (char *buffer)
657 p = strchr (line, '$');
659 return result; /* No more variables. */
661 if (p[1] == '$') /* Escaped dollar sign. */
663 memmove (p, p+1, strlen (p+1)+1);
671 for (pend=p+2; *pend; pend++)
675 else if (*pend == '}')
682 return result; /* Unclosed - don't substitute. */
686 for (pend=p+1; *pend && !spacep (pend) && *pend != '$' ; pend++)
689 if (p[1] == '{' && *pend == '}')
693 freeme = get_var_ext (p+2);
701 value = get_var (p+1);
705 value = get_var (p+1);
708 valuelen = strlen (value);
709 if (valuelen <= pend - p)
711 memcpy (p, value, valuelen);
715 memmove (p, p+n, strlen (p+n)+1);
720 char *src = result? result : buffer;
723 dst = xmalloc (strlen (src) + valuelen + 1);
725 memcpy (dst, src, n);
726 memcpy (dst + n, value, valuelen);
728 strcpy (dst + n, pend);
739 /* Same as substitute_line but do not modify BUFFER. */
741 substitute_line_copy (const char *buffer)
745 p = xstrdup (buffer?buffer:"");
746 result = substitute_line (p);
756 assign_variable (char *line, int syslet)
758 char *name, *p, *tmp, *free_me, *buffer;
762 for (p=name; *p && !spacep (p); p++)
770 set_var (name, NULL); /* Remove variable. */
773 free_me = opt.enable_varsubst? substitute_line_copy (p) : NULL;
776 buffer = xmalloc (4 + strlen (p) + 1);
777 strcpy (stpcpy (buffer, "get "), p);
778 tmp = get_var_ext (buffer);
786 tmp = opt.enable_varsubst? substitute_line_copy (p) : NULL;
799 show_variables (void)
803 for (var = variable_table; var; var = var->next)
805 printf ("%-20s %s\n", var->name, var->value);
809 /* Store an inquire response pattern. Note, that this function may
810 change the content of LINE. We assume that leading white spaces
811 are already removed. */
813 add_definq (char *line, int is_var, int is_prog)
820 for (p=name; *p && !spacep (p); p++)
827 d = xmalloc (sizeof *d + strlen (p) );
830 d->is_prog = is_prog;
831 if ( !strcmp (name, "*"))
834 d->name = xstrdup (name);
837 *definq_list_tail = d;
838 definq_list_tail = &d->next;
842 /* Show all inquiry defintions. */
848 for (d=definq_list; d; d = d->next)
850 printf ("%-20s %c %s\n",
851 d->name, d->is_var? 'v' : d->is_prog? 'p':'f', d->file);
852 for (d=definq_list; d; d = d->next)
854 printf ("%-20s %c %s\n", "*",
855 d->is_var? 'v': d->is_prog? 'p':'f', d->file);
859 /* Clear all inquiry definitions. */
865 definq_t tmp = definq_list->next;
866 xfree (definq_list->name);
870 definq_list_tail = &definq_list;
875 do_sendfd (assuan_context_t ctx, char *line)
878 char *name, *mode, *p;
883 for (p=name; *p && !spacep (p); p++)
896 for (p=mode; *p && !spacep (p); p++)
903 fp = fopen (name, mode);
906 log_error ("can't open '%s' in \"%s\" mode: %s\n",
907 name, mode, strerror (errno));
913 log_error ("file '%s' opened in \"%s\" mode, fd=%d\n",
916 rc = assuan_sendfd (ctx, INT2FD (fd) );
918 log_error ("sending descriptor %d failed: %s\n", fd, gpg_strerror (rc));
924 do_recvfd (assuan_context_t ctx, char *line)
928 log_info ("This command has not yet been implemented\n");
936 char *varname, *name, *mode, *p;
939 #ifdef HAVE_W32_SYSTEM
940 if (server_pid == (pid_t)(-1))
942 log_error ("the pid of the server is unknown\n");
943 log_info ("use command \"/serverpid\" first\n");
948 /* Get variable name. */
950 for (p=varname; *p && !spacep (p); p++)
959 for (p=name; *p && !spacep (p); p++)
972 for (p=mode; *p && !spacep (p); p++)
979 fp = fopen (name, mode);
982 log_error ("can't open '%s' in \"%s\" mode: %s\n",
983 name, mode, strerror (errno));
987 if (fd >= 0 && fd < DIM (open_fd_table))
989 open_fd_table[fd].inuse = 1;
990 #ifdef HAVE_W32CE_SYSTEM
991 # warning fixme: implement our pipe emulation.
993 #if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
995 HANDLE prochandle, handle, newhandle;
997 handle = (void*)_get_osfhandle (fd);
999 prochandle = OpenProcess (PROCESS_DUP_HANDLE, FALSE, server_pid);
1002 log_error ("failed to open the server process\n");
1007 if (!DuplicateHandle (GetCurrentProcess(), handle,
1008 prochandle, &newhandle, 0,
1009 TRUE, DUPLICATE_SAME_ACCESS ))
1011 log_error ("failed to duplicate the handle\n");
1013 CloseHandle (prochandle);
1016 CloseHandle (prochandle);
1017 open_fd_table[fd].handle = newhandle;
1020 log_info ("file '%s' opened in \"%s\" mode, fd=%d (libc=%d)\n",
1021 name, mode, (int)open_fd_table[fd].handle, fd);
1022 set_int_var (varname, (int)open_fd_table[fd].handle);
1025 log_info ("file '%s' opened in \"%s\" mode, fd=%d\n",
1027 set_int_var (varname, fd);
1032 log_error ("can't put fd %d into table\n", fd);
1039 do_close (char *line)
1041 int fd = atoi (line);
1043 #ifdef HAVE_W32_SYSTEM
1046 for (i=0; i < DIM (open_fd_table); i++)
1047 if ( open_fd_table[i].inuse && open_fd_table[i].handle == (void*)fd)
1049 if (i < DIM (open_fd_table))
1053 log_error ("given fd (system handle) has not been opened\n");
1058 if (fd < 0 || fd >= DIM (open_fd_table))
1060 log_error ("invalid fd\n");
1064 if (!open_fd_table[fd].inuse)
1066 log_error ("given fd has not been opened\n");
1069 #ifdef HAVE_W32_SYSTEM
1070 CloseHandle (open_fd_table[fd].handle); /* Close duped handle. */
1073 open_fd_table[fd].inuse = 0;
1082 for (i=0; i < DIM (open_fd_table); i++)
1083 if (open_fd_table[i].inuse)
1085 #ifdef HAVE_W32_SYSTEM
1086 printf ("%-15d (libc=%d)\n", (int)open_fd_table[i].handle, i);
1088 printf ("%-15d\n", i);
1096 getinfo_pid_cb (void *opaque, const void *buffer, size_t length)
1098 membuf_t *mb = opaque;
1099 put_membuf (mb, buffer, length);
1103 /* Get the pid of the server and store it locally. */
1105 do_serverpid (assuan_context_t ctx)
1111 init_membuf (&mb, 100);
1112 rc = assuan_transact (ctx, "GETINFO pid", getinfo_pid_cb, &mb,
1113 NULL, NULL, NULL, NULL);
1114 put_membuf (&mb, "", 1);
1115 buffer = get_membuf (&mb, NULL);
1117 log_error ("command \"%s\" failed: %s\n",
1118 "GETINFO pid", gpg_strerror (rc));
1121 server_pid = (pid_t)strtoul (buffer, NULL, 10);
1123 log_info ("server's PID is %lu\n", (unsigned long)server_pid);
1129 /* Return true if the command is either "HELP" or "SCD HELP". */
1131 help_cmd_p (const char *line)
1133 if (!ascii_strncasecmp (line, "SCD", 3)
1134 && (spacep (line+3) || !line[3]))
1136 for (line += 3; spacep (line); line++)
1140 return (!ascii_strncasecmp (line, "HELP", 4)
1141 && (spacep (line+4) || !line[4]));
1145 /* gpg-connect-agent's entry point. */
1147 main (int argc, char **argv)
1149 ARGPARSE_ARGS pargs;
1150 int no_more_options = 0;
1151 assuan_context_t ctx;
1157 const char *opt_run = NULL;
1158 FILE *script_fp = NULL;
1159 int use_tty, keep_line;
1165 unsigned int nestlevel;
1170 char **cmdline_commands = NULL;
1172 early_system_init ();
1173 gnupg_rl_initialize ();
1174 set_strusage (my_strusage);
1175 log_set_prefix ("gpg-connect-agent", GPGRT_LOG_WITH_PREFIX);
1177 /* Make sure that our subsystems are ready. */
1179 init_common_subsystems (&argc, &argv);
1181 assuan_set_gpg_err_source (0);
1185 opt.connect_flags = 1;
1187 /* Parse the command line. */
1190 pargs.flags = 1; /* Do not remove the args. */
1191 while (!no_more_options && optfile_parse (NULL, NULL, NULL, &pargs, opts))
1193 switch (pargs.r_opt)
1195 case oQuiet: opt.quiet = 1; break;
1196 case oVerbose: opt.verbose++; break;
1197 case oNoVerbose: opt.verbose = 0; break;
1198 case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
1199 case oAgentProgram: opt.agent_program = pargs.r.ret_str; break;
1200 case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str; break;
1201 case oNoAutostart: opt.autostart = 0; break;
1202 case oHex: opt.hex = 1; break;
1203 case oDecode: opt.decode = 1; break;
1204 case oDirmngr: opt.use_dirmngr = 1; break;
1205 case oUIServer: opt.use_uiserver = 1; break;
1206 case oRawSocket: opt.raw_socket = pargs.r.ret_str; break;
1207 case oTcpSocket: opt.tcp_socket = pargs.r.ret_str; break;
1208 case oExec: opt.exec = 1; break;
1209 case oNoExtConnect: opt.connect_flags &= ~(1); break;
1210 case oRun: opt_run = pargs.r.ret_str; break;
1212 opt.enable_varsubst = 1;
1213 opt.trim_leading_spaces = 1;
1216 default: pargs.err = 2; break;
1220 if (log_get_errorcount (0))
1223 /* --uiserver is a shortcut for a specific raw socket. This comes
1224 in particular handy on Windows. */
1225 if (opt.use_uiserver)
1227 opt.raw_socket = make_absfilename (gnupg_homedir (), "S.uiserver", NULL);
1230 /* Print a warning if an argument looks like an option. */
1231 if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
1235 for (i=0; i < argc; i++)
1236 if (argv[i][0] == '-' && argv[i][1] == '-')
1237 log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
1241 use_tty = (gnupg_isatty (fileno (stdin)) && gnupg_isatty (fileno (stdout)));
1247 log_error (_("option \"%s\" requires a program "
1248 "and optional arguments\n"), "--exec" );
1253 cmdline_commands = argv;
1255 if (opt.exec && opt.raw_socket)
1257 opt.raw_socket = NULL;
1258 log_info (_("option \"%s\" ignored due to \"%s\"\n"),
1259 "--raw-socket", "--exec");
1261 if (opt.exec && opt.tcp_socket)
1263 opt.tcp_socket = NULL;
1264 log_info (_("option \"%s\" ignored due to \"%s\"\n"),
1265 "--tcp-socket", "--exec");
1267 if (opt.tcp_socket && opt.raw_socket)
1269 opt.tcp_socket = NULL;
1270 log_info (_("option \"%s\" ignored due to \"%s\"\n"),
1271 "--tcp-socket", "--raw-socket");
1274 if (opt_run && !(script_fp = fopen (opt_run, "r")))
1276 log_error ("cannot open run file '%s': %s\n",
1277 opt_run, strerror (errno));
1284 assuan_fd_t no_close[3];
1286 no_close[0] = assuan_fd_from_posix_fd (es_fileno (es_stderr));
1287 no_close[1] = assuan_fd_from_posix_fd (log_get_fd ());
1288 no_close[2] = ASSUAN_INVALID_FD;
1290 rc = assuan_new (&ctx);
1293 log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
1297 rc = assuan_pipe_connect
1298 (ctx, *argv, (const char **)argv, no_close, NULL, NULL,
1299 (opt.connect_flags & 1) ? ASSUAN_PIPE_CONNECT_FDPASSING : 0);
1302 log_error ("assuan_pipe_connect_ext failed: %s\n",
1308 log_info ("server '%s' started\n", *argv);
1311 else if (opt.raw_socket)
1313 rc = assuan_new (&ctx);
1316 log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
1320 rc = assuan_socket_connect
1321 (ctx, opt.raw_socket, 0,
1322 (opt.connect_flags & 1) ? ASSUAN_SOCKET_CONNECT_FDPASSING : 0);
1325 log_error ("can't connect to socket '%s': %s\n",
1326 opt.raw_socket, gpg_strerror (rc));
1331 log_info ("connection to socket '%s' established\n", opt.raw_socket);
1333 else if (opt.tcp_socket)
1337 url = xstrconcat ("assuan://", opt.tcp_socket, NULL);
1339 rc = assuan_new (&ctx);
1342 log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
1346 rc = assuan_socket_connect (ctx, opt.tcp_socket, 0, 0);
1349 log_error ("can't connect to server '%s': %s\n",
1350 opt.tcp_socket, gpg_strerror (rc));
1355 log_info ("connection to socket '%s' established\n", url);
1360 ctx = start_agent ();
1362 /* See whether there is a line pending from the server (in case
1363 assuan did not run the initial handshaking). */
1364 if (assuan_pending_line (ctx))
1366 rc = read_and_print_response (ctx, 0, &cmderr);
1368 log_info (_("receiving line failed: %s\n"), gpg_strerror (rc) );
1372 for (loopidx=0; loopidx < DIM (loopstack); loopidx++)
1373 loopstack[loopidx].collecting = 0;
1381 size_t maxlength = 2048;
1383 assert (loopidx < (int)DIM (loopstack));
1384 if (loopidx >= 0 && loopstack[loopidx].current)
1388 line = xstrdup (loopstack[loopidx].current->line);
1390 /* Never go beyond of the final /end. */
1391 if (loopstack[loopidx].current->next)
1392 loopstack[loopidx].current = loopstack[loopidx].current->next;
1393 else if (!strncmp (line, "/end", 4) && (!line[4]||spacep(line+4)))
1396 log_fatal ("/end command vanished\n");
1398 else if (cmdline_commands && *cmdline_commands && !script_fp)
1402 line = xstrdup (*cmdline_commands);
1408 else if (use_tty && !script_fp)
1412 line = tty_get ("> ");
1414 if (n==1 && *line == CONTROL_D)
1428 n = read_line (script_fp? script_fp:stdin,
1429 &line, &linesize, &maxlength);
1433 log_error (_("error reading input: %s\n"), strerror (errno));
1438 log_error ("stopping script execution\n");
1451 log_info ("end of script\n");
1458 log_error (_("line too long - skipped\n"));
1461 if (memchr (line, 0, n))
1462 log_info (_("line shortened due to embedded Nul character\n"));
1463 if (line[n-1] == '\n')
1466 if (opt.trim_leading_spaces)
1468 const char *s = line;
1481 if (loopidx+1 >= 0 && loopstack[loopidx+1].collecting)
1485 ll = xmalloc (sizeof *ll + strlen (line));
1487 strcpy (ll->line, line);
1488 *loopstack[loopidx+1].tail = ll;
1489 loopstack[loopidx+1].tail = &ll->next;
1491 if (!strncmp (line, "/end", 4) && (!line[4]||spacep(line+4)))
1492 loopstack[loopidx+1].nestlevel--;
1493 else if (!strncmp (line, "/while", 6) && (!line[6]||spacep(line+6)))
1494 loopstack[loopidx+1].nestlevel++;
1496 if (loopstack[loopidx+1].nestlevel)
1498 /* We reached the corresponding /end. */
1499 loopstack[loopidx+1].collecting = 0;
1505 /* Handle control commands. */
1508 for (p=cmd; *p && !spacep (p); p++)
1514 if (!strcmp (cmd, "let"))
1516 assign_variable (p, 0);
1518 else if (!strcmp (cmd, "slet"))
1520 /* Deprecated - never used in a released version. */
1521 assign_variable (p, 1);
1523 else if (!strcmp (cmd, "showvar"))
1527 else if (!strcmp (cmd, "definq"))
1529 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1532 add_definq (tmpline, 1, 0);
1536 add_definq (p, 1, 0);
1538 else if (!strcmp (cmd, "definqfile"))
1540 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1543 add_definq (tmpline, 0, 0);
1547 add_definq (p, 0, 0);
1549 else if (!strcmp (cmd, "definqprog"))
1551 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1554 add_definq (tmpline, 0, 1);
1558 add_definq (p, 0, 1);
1560 else if (!strcmp (cmd, "datafile"))
1564 if (current_datasink)
1566 if (current_datasink != stdout)
1567 fclose (current_datasink);
1568 current_datasink = NULL;
1570 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1571 fname = tmpline? tmpline : p;
1572 if (fname && !strcmp (fname, "-"))
1573 current_datasink = stdout;
1574 else if (fname && *fname)
1576 current_datasink = fopen (fname, "wb");
1577 if (!current_datasink)
1578 log_error ("can't open '%s': %s\n",
1579 fname, strerror (errno));
1583 else if (!strcmp (cmd, "showdef"))
1587 else if (!strcmp (cmd, "cleardef"))
1591 else if (!strcmp (cmd, "echo"))
1593 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1602 else if (!strcmp (cmd, "sendfd"))
1604 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1607 do_sendfd (ctx, tmpline);
1614 else if (!strcmp (cmd, "recvfd"))
1616 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1619 do_recvfd (ctx, tmpline);
1626 else if (!strcmp (cmd, "open"))
1628 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1637 else if (!strcmp (cmd, "close"))
1639 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1648 else if (!strcmp (cmd, "showopen"))
1652 else if (!strcmp (cmd, "serverpid"))
1656 else if (!strcmp (cmd, "hex"))
1658 else if (!strcmp (cmd, "nohex"))
1660 else if (!strcmp (cmd, "decode"))
1662 else if (!strcmp (cmd, "nodecode"))
1664 else if (!strcmp (cmd, "subst"))
1666 opt.enable_varsubst = 1;
1667 opt.trim_leading_spaces = 1;
1669 else if (!strcmp (cmd, "nosubst"))
1670 opt.enable_varsubst = 0;
1671 else if (!strcmp (cmd, "run"))
1675 for (p2=p; *p2 && !spacep (p2); p2++)
1683 log_error ("syntax error in run command\n");
1692 log_error ("cannot nest run commands - stop\n");
1696 else if (!(script_fp = fopen (p, "r")))
1698 log_error ("cannot open run file '%s': %s\n",
1699 p, strerror (errno));
1701 else if (opt.verbose)
1702 log_info ("running commands from '%s'\n", p);
1704 else if (!strcmp (cmd, "while"))
1706 if (loopidx+2 >= (int)DIM(loopstack))
1708 log_error ("blocks are nested too deep\n");
1709 /* We should better die or break all loop in this
1710 case as recovering from this error won't be
1715 loopstack[loopidx+1].head = NULL;
1716 loopstack[loopidx+1].tail = &loopstack[loopidx+1].head;
1717 loopstack[loopidx+1].current = NULL;
1718 loopstack[loopidx+1].nestlevel = 1;
1719 loopstack[loopidx+1].oneshot = 0;
1720 loopstack[loopidx+1].condition = xstrdup (p);
1721 loopstack[loopidx+1].collecting = 1;
1724 else if (!strcmp (cmd, "if"))
1726 if (loopidx+2 >= (int)DIM(loopstack))
1728 log_error ("blocks are nested too deep\n");
1732 /* Note that we need to evaluate the condition right
1733 away and not just at the end of the block as we
1735 loopstack[loopidx+1].head = NULL;
1736 loopstack[loopidx+1].tail = &loopstack[loopidx+1].head;
1737 loopstack[loopidx+1].current = NULL;
1738 loopstack[loopidx+1].nestlevel = 1;
1739 loopstack[loopidx+1].oneshot = 1;
1740 loopstack[loopidx+1].condition = substitute_line_copy (p);
1741 loopstack[loopidx+1].collecting = 1;
1744 else if (!strcmp (cmd, "end"))
1747 log_error ("stray /end command encountered - ignored\n");
1754 /* Evaluate the condition. */
1755 tmpcond = xstrdup (loopstack[loopidx].condition);
1756 if (loopstack[loopidx].oneshot)
1758 xfree (loopstack[loopidx].condition);
1759 loopstack[loopidx].condition = xstrdup ("0");
1761 tmpline = substitute_line (tmpcond);
1762 value = tmpline? tmpline : tmpcond;
1763 /* "true" or "yes" are commonly used to mean TRUE;
1764 all other strings will evaluate to FALSE due to
1766 if (!ascii_strcasecmp (value, "true")
1767 || !ascii_strcasecmp (value, "yes"))
1770 condition = strtol (value, NULL, 0);
1777 loopstack[loopidx].current = loopstack[loopidx].head;
1782 while (loopstack[loopidx].head)
1784 loopline_t tmp = loopstack[loopidx].head->next;
1785 xfree (loopstack[loopidx].head);
1786 loopstack[loopidx].head = tmp;
1788 loopstack[loopidx].tail = NULL;
1789 loopstack[loopidx].current = NULL;
1790 loopstack[loopidx].nestlevel = 0;
1791 loopstack[loopidx].collecting = 0;
1792 loopstack[loopidx].oneshot = 0;
1793 xfree (loopstack[loopidx].condition);
1794 loopstack[loopidx].condition = NULL;
1799 else if (!strcmp (cmd, "bye"))
1803 else if (!strcmp (cmd, "sleep"))
1807 else if (!strcmp (cmd, "help"))
1810 "Available commands:\n"
1811 "/echo ARGS Echo ARGS.\n"
1812 "/let NAME VALUE Set variable NAME to VALUE.\n"
1813 "/showvar Show all variables.\n"
1814 "/definq NAME VAR Use content of VAR for inquiries with NAME.\n"
1815 "/definqfile NAME FILE Use content of FILE for inquiries with NAME.\n"
1816 "/definqprog NAME PGM Run PGM for inquiries with NAME.\n"
1817 "/datafile [NAME] Write all D line content to file NAME.\n"
1818 "/showdef Print all definitions.\n"
1819 "/cleardef Delete all definitions.\n"
1820 "/sendfd FILE MODE Open FILE and pass descriptor to server.\n"
1821 "/recvfd Receive FD from server and print.\n"
1822 "/open VAR FILE MODE Open FILE and assign the file descriptor to VAR.\n"
1823 "/close FD Close file with descriptor FD.\n"
1824 "/showopen Show descriptors of all open files.\n"
1825 "/serverpid Retrieve the pid of the server.\n"
1826 "/[no]hex Enable hex dumping of received data lines.\n"
1827 "/[no]decode Enable decoding of received data lines.\n"
1828 "/[no]subst Enable variable substitution.\n"
1829 "/run FILE Run commands from FILE.\n"
1830 "/if VAR Begin conditional block controlled by VAR.\n"
1831 "/while VAR Begin loop controlled by VAR.\n"
1832 "/end End loop or condition\n"
1833 "/bye Terminate gpg-connect-agent.\n"
1834 "/help Print this help.");
1837 log_error (_("unknown command '%s'\n"), cmd );
1842 if (opt.verbose && script_fp)
1845 tmpline = opt.enable_varsubst? substitute_line (line) : NULL;
1848 rc = assuan_write_line (ctx, tmpline);
1852 rc = assuan_write_line (ctx, line);
1855 log_info (_("sending line failed: %s\n"), gpg_strerror (rc) );
1858 if (*line == '#' || !*line)
1859 continue; /* Don't expect a response for a comment line. */
1861 rc = read_and_print_response (ctx, help_cmd_p (line), &cmderr);
1863 log_info (_("receiving line failed: %s\n"), gpg_strerror (rc) );
1864 if ((rc || cmderr) && script_fp)
1866 log_error ("stopping script execution\n");
1872 /* FIXME: If the last command was BYE or the server died for
1873 some other reason, we won't notice until we get the next
1874 input command. Probing the connection with a non-blocking
1875 read could help to notice termination or other problems
1880 log_info ("closing connection to agent\n");
1882 /* XXX: We would like to release the context here, but libassuan
1883 nicely says good bye to the server, which results in a SIGPIPE if
1884 the server died. Unfortunately, libassuan does not ignore
1885 SIGPIPE when used with UNIX sockets, hence we simply leak the
1888 assuan_release (ctx);
1890 gpgrt_annotate_leaked_object (ctx);
1896 /* Handle an Inquire from the server. Return False if it could not be
1897 handled; in this case the caller shll complete the operation. LINE
1898 is the complete line as received from the server. This function
1899 may change the content of LINE. */
1901 handle_inquire (assuan_context_t ctx, char *line)
1909 /* Skip the command and trailing spaces. */
1910 for (; *line && !spacep (line); line++)
1912 while (spacep (line))
1916 for (; *line && !spacep (line); line++)
1921 /* Now match it against our list. The second loop is there to
1922 detect the match-all entry. */
1923 for (d=definq_list; d; d = d->next)
1924 if (d->name && !strcmp (d->name, name))
1927 for (d=definq_list; d; d = d->next)
1933 log_info ("no handler for inquiry '%s' found\n", name);
1939 char *tmpvalue = get_var_ext (d->file);
1941 rc = assuan_send_data (ctx, tmpvalue, strlen (tmpvalue));
1943 rc = assuan_send_data (ctx, "", 0);
1946 log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
1952 #ifdef HAVE_W32CE_SYSTEM
1955 fp = popen (d->file, "r");
1958 log_error ("error executing '%s': %s\n",
1959 d->file, strerror (errno));
1960 else if (opt.verbose)
1961 log_error ("handling inquiry '%s' by running '%s'\n",
1966 fp = fopen (d->file, "rb");
1968 log_error ("error opening '%s': %s\n", d->file, strerror (errno));
1969 else if (opt.verbose)
1970 log_error ("handling inquiry '%s' by returning content of '%s'\n",
1976 while ( (n = fread (buffer, 1, sizeof buffer, fp)) )
1978 rc = assuan_send_data (ctx, buffer, n);
1981 log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
1986 log_error ("error reading from '%s': %s\n", d->file, strerror (errno));
1989 rc = assuan_send_data (ctx, NULL, 0);
1991 log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
1995 else if (d->is_prog)
1997 #ifndef HAVE_W32CE_SYSTEM
1999 log_error ("error running '%s': %s\n", d->file, strerror (errno));
2008 /* Read all response lines from server and print them. Returns 0 on
2009 success or an assuan error code. If WITHHASH istrue, comment lines
2010 are printed. Sets R_GOTERR to true if the command did not returned
2013 read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr)
2026 rc = assuan_read_line (ctx, &line, &linelen);
2030 if ((withhash || opt.verbose > 1) && *line == '#')
2032 fwrite (line, linelen, 1, stdout);
2036 while (*line == '#' || !linelen);
2039 && line[0] == 'D' && line[1] == ' ')
2041 if (current_datasink)
2043 const unsigned char *s;
2046 for (j=2, s=(unsigned char*)line+2; j < linelen; j++, s++ )
2048 if (*s == '%' && j+2 < linelen)
2056 putc (c, current_datasink);
2061 for (i=2; i < linelen; )
2065 printf ("D[%04X] ", i-2);
2066 for (j=0; j < 16 ; j++, i++)
2071 printf (" %02X", ((unsigned char*)line)[i]);
2073 fputs (" ", stdout);
2075 fputs (" ", stdout);
2077 for (j=0; j < 16; j++, i++)
2079 unsigned int c = ((unsigned char*)line)[i];
2082 else if (isascii (c) && isprint (c) && !iscntrl (c))
2090 else if (opt.decode)
2092 const unsigned char *s;
2096 for (j=2, s=(unsigned char*)line+2; j < linelen; j++, s++ )
2100 fputs ("D ", stdout);
2103 if (*s == '%' && j+2 < linelen)
2115 need_lf = (c != '\n');
2119 fwrite (line, linelen, 1, stdout);
2127 if (!current_datasink || current_datasink != stdout)
2134 && (line[1] == '\0' || line[1] == ' '))
2136 if (!current_datasink || current_datasink != stdout)
2138 fwrite (line, linelen, 1, stdout);
2142 else if (linelen >= 2
2143 && line[0] == 'O' && line[1] == 'K'
2144 && (line[2] == '\0' || line[2] == ' '))
2146 if (!current_datasink || current_datasink != stdout)
2148 fwrite (line, linelen, 1, stdout);
2151 set_int_var ("?", 0);
2154 else if (linelen >= 3
2155 && line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
2156 && (line[3] == '\0' || line[3] == ' '))
2160 errval = strtol (line+3, NULL, 10);
2163 set_int_var ("?", errval);
2164 if (!current_datasink || current_datasink != stdout)
2166 fwrite (line, linelen, 1, stdout);
2172 else if (linelen >= 7
2173 && line[0] == 'I' && line[1] == 'N' && line[2] == 'Q'
2174 && line[3] == 'U' && line[4] == 'I' && line[5] == 'R'
2176 && (line[7] == '\0' || line[7] == ' '))
2178 if (!current_datasink || current_datasink != stdout)
2180 fwrite (line, linelen, 1, stdout);
2183 if (!handle_inquire (ctx, line))
2184 assuan_write_line (ctx, "CANCEL");
2186 else if (linelen >= 3
2187 && line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
2188 && (line[3] == '\0' || line[3] == ' '))
2190 if (!current_datasink || current_datasink != stdout)
2192 fwrite (line, linelen, 1, stdout);
2195 /* Received from server, thus more responses are expected. */
2198 return gpg_error (GPG_ERR_ASS_INV_RESPONSE);
2206 /* Connect to the agent and send the standard options. */
2207 static assuan_context_t
2211 assuan_context_t ctx;
2212 session_env_t session_env;
2214 session_env = session_env_new ();
2216 log_fatal ("error allocating session environment block: %s\n",
2218 if (opt.use_dirmngr)
2219 err = start_new_dirmngr (&ctx,
2220 GPG_ERR_SOURCE_DEFAULT,
2221 opt.dirmngr_program,
2226 err = start_new_gpg_agent (&ctx,
2227 GPG_ERR_SOURCE_DEFAULT,
2235 session_env_release (session_env);
2239 && (gpg_err_code (err)
2240 == opt.use_dirmngr? GPG_ERR_NO_DIRMNGR : GPG_ERR_NO_AGENT))
2242 /* In the no-autostart case we don't make gpg-connect-agent
2243 fail on a missing server. */
2244 log_info (opt.use_dirmngr?
2245 _("no dirmngr running in this session\n"):
2246 _("no gpg-agent running in this session\n"));
2251 log_error (_("error sending standard options: %s\n"),
2252 gpg_strerror (err));