1 /* gpg-connect-agent.c - Tool to connect to the agent.
2 * Copyright (C) 2005, 2007, 2008 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
32 #include "../common/util.h"
33 #include "../common/asshelp.h"
34 #include "../common/sysutils.h"
35 #include "../common/membuf.h"
36 #include "../common/ttyio.h"
37 #ifdef HAVE_W32_SYSTEM
38 # include "../common/exechelp.h"
42 #define CONTROL_D ('D' - 'A' + 1)
43 #define octdigitp(p) (*(p) >= '0' && *(p) <= '7')
45 /* Constants to identify the commands and options. */
46 enum cmd_and_opt_values
65 /* The list of commands and options. */
66 static ARGPARSE_OPTS opts[] = {
67 ARGPARSE_group (301, N_("@\nOptions:\n ")),
69 ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
70 ARGPARSE_s_n (oQuiet, "quiet", N_("quiet")),
71 ARGPARSE_s_n (oHex, "hex", N_("print data out hex encoded")),
72 ARGPARSE_s_n (oDecode,"decode", N_("decode received data lines")),
73 ARGPARSE_s_s (oRawSocket, "raw-socket",
74 N_("|NAME|connect to Assuan socket NAME")),
75 ARGPARSE_s_n (oExec, "exec",
76 N_("run the Assuan server given on the command line")),
77 ARGPARSE_s_n (oNoExtConnect, "no-ext-connect",
78 N_("do not use extended connect mode")),
79 ARGPARSE_s_s (oRun, "run",
80 N_("|FILE|run commands from FILE on startup")),
81 ARGPARSE_s_n (oSubst, "subst", N_("run /subst on startup")),
83 ARGPARSE_s_n (oNoVerbose, "no-verbose", "@"),
84 ARGPARSE_s_s (oHomedir, "homedir", "@" ),
90 /* We keep all global options in the structure OPT. */
93 int verbose; /* Verbosity level. */
94 int quiet; /* Be extra quiet. */
95 const char *homedir; /* Configuration directory name */
96 int hex; /* Print data lines in hex format. */
97 int decode; /* Decode received data lines. */
98 const char *raw_socket; /* Name of socket to connect in raw mode. */
99 int exec; /* Run the pgm given on the command line. */
100 unsigned int connect_flags; /* Flags used for connecting. */
101 int enable_varsubst; /* Set if variable substitution is enabled. */
102 int trim_leading_spaces;
107 /* Definitions for /definq commands and a global linked list with all
111 struct definq_s *next;
112 char *name; /* Name of inquiry or NULL for any name. */
113 int is_var; /* True if FILE is a variable name. */
114 int is_prog; /* True if FILE is a program to run. */
115 char file[1]; /* Name of file or program. */
117 typedef struct definq_s *definq_t;
119 static definq_t definq_list;
120 static definq_t *definq_list_tail = &definq_list;
123 /* Variable definitions and glovbal table. */
126 struct variable_s *next;
127 char *value; /* Malloced value - always a string. */
128 char name[1]; /* Name of the variable. */
130 typedef struct variable_s *variable_t;
132 static variable_t variable_table;
135 /* To implement loops we store entire lines in a linked list. */
138 struct loopline_s *next;
141 typedef struct loopline_s *loopline_t;
144 /* This is used to store the pid of the server. */
145 static pid_t server_pid = (pid_t)(-1);
147 /* The current datasink file or NULL. */
148 static FILE *current_datasink;
150 /* A list of open file descriptors. */
154 #ifdef HAVE_W32_SYSTEM
157 } open_fd_table[256];
160 /*-- local prototypes --*/
161 static char *substitute_line_copy (const char *buffer);
162 static int read_and_print_response (assuan_context_t ctx, int withhash,
164 static assuan_context_t start_agent (void);
169 /* Print usage information and and provide strings for help. */
171 my_strusage( int level )
177 case 11: p = "gpg-connect-agent (GnuPG)";
179 case 13: p = VERSION; break;
180 case 17: p = PRINTABLE_OS_NAME; break;
181 case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
184 case 40: p = _("Usage: gpg-connect-agent [options] (-h for help)");
187 p = _("Syntax: gpg-connect-agent [options]\n"
188 "Connect to a running agent and send commands\n");
190 case 31: p = "\nHome: "; break;
191 case 32: p = opt.homedir; break;
192 case 33: p = "\n"; break;
194 default: p = NULL; break;
208 buffer = xmalloc (size+1);
209 if (getcwd (buffer, size) == buffer)
219 /* Unescape STRING and returned the malloced result. The surrounding
220 quotes must already be removed from STRING. */
222 unescape_string (const char *string)
224 const unsigned char *s;
231 for (s = (const unsigned char*)string, esc=0; *s; s++)
245 case '\\': n++; break;
247 if (s[1] && s[2] && hexdigitp (s+1) && hexdigitp (s+2))
253 && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
265 buffer = xmalloc (n+1);
266 d = (unsigned char*)buffer;
267 for (s = (const unsigned char*)string, esc=0; *s; s++)
273 case 'b': *d++ = '\b'; break;
274 case 't': *d++ = '\t'; break;
275 case 'v': *d++ = '\v'; break;
276 case 'n': *d++ = '\n'; break;
277 case 'f': *d++ = '\f'; break;
278 case 'r': *d++ = '\r'; break;
279 case '"': *d++ = '\"'; break;
280 case '\'': *d++ = '\''; break;
281 case '\\': *d++ = '\\'; break;
283 if (s[1] && s[2] && hexdigitp (s+1) && hexdigitp (s+2))
293 && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
295 *d++ = (atoi_1 (s)*64) + (atoi_1 (s+1)*8) + atoi_1 (s+2);
312 /* Do the percent unescaping and return a newly malloced string.
313 If WITH_PLUS is set '+' characters will be changed to space. */
315 unpercent_string (const char *string, int with_plus)
317 const unsigned char *s;
318 unsigned char *buffer, *p;
322 for (s=(const unsigned char *)string; *s; s++)
324 if (*s == '%' && s[1] && s[2])
330 else if (with_plus && *s == '+')
336 buffer = xmalloc (n+1);
338 for (s=(const unsigned char *)string; *s; s++)
340 if (*s == '%' && s[1] && s[2])
346 else if (with_plus && *s == '+')
352 return (char*)buffer;
360 set_var (const char *name, const char *value)
364 for (var = variable_table; var; var = var->next)
365 if (!strcmp (var->name, name))
369 var = xmalloc (sizeof *var + strlen (name));
371 strcpy (var->name, name);
372 var->next = variable_table;
373 variable_table = var;
376 var->value = value? xstrdup (value) : NULL;
382 set_int_var (const char *name, int value)
386 snprintf (numbuf, sizeof numbuf, "%d", value);
387 set_var (name, numbuf);
391 /* Return the value of a variable. That value is valid until a
392 variable of the name is changed. Return NULL if not found. Note
393 that envvars are copied to our variable list at the first access
394 and not at oprogram start. */
396 get_var (const char *name)
403 for (var = variable_table; var; var = var->next)
404 if (!strcmp (var->name, name))
406 if (!var && (s = getenv (name)))
407 return set_var (name, s);
408 if (!var || !var->value)
414 /* Perform some simple arithmentic operations. Caller must release
415 the return value. On error the return value is NULL. */
417 arithmetic_op (int operator, const char *operands)
422 while ( spacep (operands) )
426 result = strtol (operands, NULL, 0);
427 while (*operands && !spacep (operands) )
434 while ( spacep (operands) )
438 value = strtol (operands, NULL, 0);
439 while (*operands && !spacep (operands) )
443 case '+': result += value; break;
444 case '-': result -= value; break;
445 case '*': result *= value; break;
456 case '!': result = !value; break;
457 case '|': result = result || value; break;
458 case '&': result = result && value; break;
460 log_error ("unknown arithmetic operator `%c'\n", operator);
464 snprintf (numbuf, sizeof numbuf, "%ld", result);
465 return xstrdup (numbuf);
470 /* Extended version of get_var. This returns a malloced string and
471 understand the function syntax: "func args".
473 Defined functions are
475 get - Return a value described by the next argument:
476 cwd - The current working directory.
477 homedir - The gnupg homedir.
478 sysconfdir - GnuPG's system configuration directory.
479 bindir - GnuPG's binary directory.
480 libdir - GnuPG's library directory.
481 libexecdir - GnuPG's library directory for executable files.
482 datadir - GnuPG's data directory.
483 serverpid - The PID of the current server.
486 Remove C-style escapes from string. Note that "\0" and
487 "\x00" terminate the string implictly. Use "\x7d" to
488 represent the closing brace. The args start right after
489 the first space after the function name.
493 Remove percent style ecaping from string. Note that "%00
494 terminates the string implicitly. Use "%7d" to represetn
495 the closing brace. The args start right after the first
496 space after the function name. "unpercent+" also maps '+'
501 Escape the args using the percent style. Tabs, formfeeds,
502 linefeeds and carriage returns are also escaped.
503 "percent+" also maps spaces to plus characters.
506 Assuming ARG is an integer, return the gpg-error code.
509 Assuming ARG is an integer, return the gpg-error source.
512 Assuming ARG is an integer return a formatted fpf error string.
515 Example: get_var_ext ("get sysconfdir") -> "/etc/gnupg"
519 get_var_ext (const char *name)
521 static int recursion_count;
525 char *free_me = NULL;
528 if (recursion_count > 50)
530 log_error ("variables nested too deeply\n");
535 free_me = opt.enable_varsubst? substitute_line_copy (name) : NULL;
538 for (s=name; *s && !spacep (s); s++)
543 result = s? xstrdup (s): NULL;
545 else if ( (s - name) == 3 && !strncmp (name, "get", 3))
549 if (!strcmp (s, "cwd"))
551 result = gnu_getcwd ();
553 log_error ("getcwd failed: %s\n", strerror (errno));
555 else if (!strcmp (s, "homedir"))
556 result = make_filename (opt.homedir, NULL);
557 else if (!strcmp (s, "sysconfdir"))
558 result = xstrdup (gnupg_sysconfdir ());
559 else if (!strcmp (s, "bindir"))
560 result = xstrdup (gnupg_bindir ());
561 else if (!strcmp (s, "libdir"))
562 result = xstrdup (gnupg_libdir ());
563 else if (!strcmp (s, "libexecdir"))
564 result = xstrdup (gnupg_libexecdir ());
565 else if (!strcmp (s, "datadir"))
566 result = xstrdup (gnupg_datadir ());
567 else if (!strcmp (s, "serverpid"))
568 result = xasprintf ("%d", (int)server_pid);
571 log_error ("invalid argument `%s' for variable function `get'\n", s);
572 log_info ("valid are: cwd, "
573 "{home,bin,lib,libexec,data}dir, serverpid\n");
577 else if ( (s - name) == 8 && !strncmp (name, "unescape", 8))
580 result = unescape_string (s);
582 else if ( (s - name) == 9 && !strncmp (name, "unpercent", 9))
585 result = unpercent_string (s, 0);
587 else if ( (s - name) == 10 && !strncmp (name, "unpercent+", 10))
590 result = unpercent_string (s, 1);
592 else if ( (s - name) == 7 && !strncmp (name, "percent", 7))
595 result = percent_escape (s, "\t\r\n\f\v");
597 else if ( (s - name) == 8 && !strncmp (name, "percent+", 8))
600 result = percent_escape (s, "\t\r\n\f\v");
601 for (p=result; *p; p++)
605 else if ( (s - name) == 7 && !strncmp (name, "errcode", 7))
608 intvalue = (int)strtol (s, NULL, 0);
609 result = xasprintf ("%d", gpg_err_code (intvalue));
611 else if ( (s - name) == 9 && !strncmp (name, "errsource", 9))
614 intvalue = (int)strtol (s, NULL, 0);
615 result = xasprintf ("%d", gpg_err_source (intvalue));
617 else if ( (s - name) == 9 && !strncmp (name, "errstring", 9))
620 intvalue = (int)strtol (s, NULL, 0);
621 result = xasprintf ("%s <%s>",
622 gpg_strerror (intvalue), gpg_strsource (intvalue));
624 else if ( (s - name) == 1 && strchr ("+-*/%!|&", *name))
626 result = arithmetic_op (*name, s+1);
630 log_error ("unknown variable function `%.*s'\n", (int)(s-name), name);
640 /* Substitute variables in LINE and return a new allocated buffer if
641 required. The function might modify LINE if the expanded version
644 substitute_line (char *buffer)
655 p = strchr (line, '$');
657 return result; /* No more variables. */
659 if (p[1] == '$') /* Escaped dollar sign. */
661 memmove (p, p+1, strlen (p+1)+1);
669 for (pend=p+2; *pend; pend++)
673 else if (*pend == '}')
680 return result; /* Unclosed - don't substitute. */
684 for (pend=p+1; *pend && !spacep (pend) && *pend != '$' ; pend++)
687 if (p[1] == '{' && *pend == '}')
691 freeme = get_var_ext (p+2);
699 value = get_var (p+1);
703 value = get_var (p+1);
706 valuelen = strlen (value);
707 if (valuelen <= pend - p)
709 memcpy (p, value, valuelen);
713 memmove (p, p+n, strlen (p+n)+1);
718 char *src = result? result : buffer;
721 dst = xmalloc (strlen (src) + valuelen + 1);
723 memcpy (dst, src, n);
724 memcpy (dst + n, value, valuelen);
726 strcpy (dst + n, pend);
737 /* Same as substitute_line but do not modify BUFFER. */
739 substitute_line_copy (const char *buffer)
743 p = xstrdup (buffer?buffer:"");
744 result = substitute_line (p);
754 assign_variable (char *line, int syslet)
756 char *name, *p, *tmp, *free_me, *buffer;
760 for (p=name; *p && !spacep (p); p++)
768 set_var (name, NULL); /* Remove variable. */
771 free_me = opt.enable_varsubst? substitute_line_copy (p) : NULL;
774 buffer = xmalloc (4 + strlen (p) + 1);
775 strcpy (stpcpy (buffer, "get "), p);
776 tmp = get_var_ext (buffer);
784 tmp = opt.enable_varsubst? substitute_line_copy (p) : NULL;
797 show_variables (void)
801 for (var = variable_table; var; var = var->next)
803 printf ("%-20s %s\n", var->name, var->value);
807 /* Store an inquire response pattern. Note, that this function may
808 change the content of LINE. We assume that leading white spaces
809 are already removed. */
811 add_definq (char *line, int is_var, int is_prog)
818 for (p=name; *p && !spacep (p); p++)
825 d = xmalloc (sizeof *d + strlen (p) );
828 d->is_prog = is_prog;
829 if ( !strcmp (name, "*"))
832 d->name = xstrdup (name);
835 *definq_list_tail = d;
836 definq_list_tail = &d->next;
840 /* Show all inquiry defintions. */
846 for (d=definq_list; d; d = d->next)
848 printf ("%-20s %c %s\n",
849 d->name, d->is_var? 'v' : d->is_prog? 'p':'f', d->file);
850 for (d=definq_list; d; d = d->next)
852 printf ("%-20s %c %s\n", "*",
853 d->is_var? 'v': d->is_prog? 'p':'f', d->file);
857 /* Clear all inquiry definitions. */
863 definq_t tmp = definq_list->next;
864 xfree (definq_list->name);
868 definq_list_tail = &definq_list;
873 do_sendfd (assuan_context_t ctx, char *line)
876 char *name, *mode, *p;
881 for (p=name; *p && !spacep (p); p++)
894 for (p=mode; *p && !spacep (p); p++)
901 fp = fopen (name, mode);
904 log_error ("can't open `%s' in \"%s\" mode: %s\n",
905 name, mode, strerror (errno));
911 log_error ("file `%s' opened in \"%s\" mode, fd=%d\n",
914 rc = assuan_sendfd (ctx, INT2FD (fd) );
916 log_error ("sending descriptor %d failed: %s\n", fd, gpg_strerror (rc));
922 do_recvfd (assuan_context_t ctx, char *line)
926 log_info ("This command has not yet been implemented\n");
934 char *varname, *name, *mode, *p;
937 #ifdef HAVE_W32_SYSTEM
938 if (server_pid == (pid_t)(-1))
940 log_error ("the pid of the server is unknown\n");
941 log_info ("use command \"/serverpid\" first\n");
946 /* Get variable name. */
948 for (p=varname; *p && !spacep (p); p++)
957 for (p=name; *p && !spacep (p); p++)
970 for (p=mode; *p && !spacep (p); p++)
977 fp = fopen (name, mode);
980 log_error ("can't open `%s' in \"%s\" mode: %s\n",
981 name, mode, strerror (errno));
985 if (fd >= 0 && fd < DIM (open_fd_table))
987 open_fd_table[fd].inuse = 1;
988 #ifdef HAVE_W32_SYSTEM
990 HANDLE prochandle, handle, newhandle;
992 handle = (void*)_get_osfhandle (fd);
994 prochandle = OpenProcess (PROCESS_DUP_HANDLE, FALSE, server_pid);
997 log_error ("failed to open the server process\n");
1002 if (!DuplicateHandle (GetCurrentProcess(), handle,
1003 prochandle, &newhandle, 0,
1004 TRUE, DUPLICATE_SAME_ACCESS ))
1006 log_error ("failed to duplicate the handle\n");
1008 CloseHandle (prochandle);
1011 CloseHandle (prochandle);
1012 open_fd_table[fd].handle = newhandle;
1015 log_info ("file `%s' opened in \"%s\" mode, fd=%d (libc=%d)\n",
1016 name, mode, (int)open_fd_table[fd].handle, fd);
1017 set_int_var (varname, (int)open_fd_table[fd].handle);
1020 log_info ("file `%s' opened in \"%s\" mode, fd=%d\n",
1022 set_int_var (varname, fd);
1027 log_error ("can't put fd %d into table\n", fd);
1034 do_close (char *line)
1036 int fd = atoi (line);
1038 #ifdef HAVE_W32_SYSTEM
1041 for (i=0; i < DIM (open_fd_table); i++)
1042 if ( open_fd_table[i].inuse && open_fd_table[i].handle == (void*)fd)
1044 if (i < DIM (open_fd_table))
1048 log_error ("given fd (system handle) has not been opened\n");
1053 if (fd < 0 || fd >= DIM (open_fd_table))
1055 log_error ("invalid fd\n");
1059 if (!open_fd_table[fd].inuse)
1061 log_error ("given fd has not been opened\n");
1064 #ifdef HAVE_W32_SYSTEM
1065 CloseHandle (open_fd_table[fd].handle); /* Close duped handle. */
1068 open_fd_table[fd].inuse = 0;
1077 for (i=0; i < DIM (open_fd_table); i++)
1078 if (open_fd_table[i].inuse)
1080 #ifdef HAVE_W32_SYSTEM
1081 printf ("%-15d (libc=%d)\n", (int)open_fd_table[i].handle, i);
1083 printf ("%-15d\n", i);
1091 getinfo_pid_cb (void *opaque, const void *buffer, size_t length)
1093 membuf_t *mb = opaque;
1094 put_membuf (mb, buffer, length);
1098 /* Get the pid of the server and store it locally. */
1100 do_serverpid (assuan_context_t ctx)
1106 init_membuf (&mb, 100);
1107 rc = assuan_transact (ctx, "GETINFO pid", getinfo_pid_cb, &mb,
1108 NULL, NULL, NULL, NULL);
1109 put_membuf (&mb, "", 1);
1110 buffer = get_membuf (&mb, NULL);
1112 log_error ("command \"%s\" failed: %s\n",
1113 "GETINFO pid", gpg_strerror (rc));
1116 server_pid = (pid_t)strtoul (buffer, NULL, 10);
1118 log_info ("server's PID is %lu\n", (unsigned long)server_pid);
1124 /* gpg-connect-agent's entry point. */
1126 main (int argc, char **argv)
1128 ARGPARSE_ARGS pargs;
1129 int no_more_options = 0;
1130 assuan_context_t ctx;
1136 const char *opt_run = NULL;
1137 FILE *script_fp = NULL;
1138 int use_tty, keep_line;
1144 unsigned int nestlevel;
1149 char **cmdline_commands = NULL;
1151 gnupg_rl_initialize ();
1152 set_strusage (my_strusage);
1153 log_set_prefix ("gpg-connect-agent", 1);
1155 /* Make sure that our subsystems are ready. */
1157 init_common_subsystems ();
1159 assuan_set_gpg_err_source (0);
1162 opt.homedir = default_homedir ();
1163 opt.connect_flags = 1;
1165 /* Parse the command line. */
1168 pargs.flags = 1; /* Do not remove the args. */
1169 while (!no_more_options && optfile_parse (NULL, NULL, NULL, &pargs, opts))
1171 switch (pargs.r_opt)
1173 case oQuiet: opt.quiet = 1; break;
1174 case oVerbose: opt.verbose++; break;
1175 case oNoVerbose: opt.verbose = 0; break;
1176 case oHomedir: opt.homedir = pargs.r.ret_str; break;
1177 case oHex: opt.hex = 1; break;
1178 case oDecode: opt.decode = 1; break;
1179 case oRawSocket: opt.raw_socket = pargs.r.ret_str; break;
1180 case oExec: opt.exec = 1; break;
1181 case oNoExtConnect: opt.connect_flags &= ~(1); break;
1182 case oRun: opt_run = pargs.r.ret_str; break;
1184 opt.enable_varsubst = 1;
1185 opt.trim_leading_spaces = 1;
1188 default: pargs.err = 2; break;
1192 if (log_get_errorcount (0))
1195 use_tty = (isatty ( fileno (stdin)) && isatty (fileno (stdout)));
1201 log_error (_("option \"%s\" requires a program "
1202 "and optional arguments\n"), "--exec" );
1207 cmdline_commands = argv;
1209 if (opt.exec && opt.raw_socket)
1210 log_info (_("option \"%s\" ignored due to \"%s\"\n"),
1211 "--raw-socket", "--exec");
1213 if (opt_run && !(script_fp = fopen (opt_run, "r")))
1215 log_error ("cannot open run file `%s': %s\n",
1216 opt_run, strerror (errno));
1225 no_close[0] = fileno (stderr);
1226 no_close[1] = log_get_fd ();
1229 rc = assuan_new (&ctx);
1232 log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
1236 rc = assuan_pipe_connect
1237 (ctx, *argv, (const char **)argv, no_close, NULL, NULL,
1238 (opt.connect_flags & 1) ? ASSUAN_PIPE_CONNECT_FDPASSING : 0);
1241 log_error ("assuan_pipe_connect_ext failed: %s\n",
1247 log_info ("server `%s' started\n", *argv);
1250 else if (opt.raw_socket)
1252 rc = assuan_new (&ctx);
1255 log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
1259 rc = assuan_socket_connect
1260 (ctx, opt.raw_socket, 0,
1261 (opt.connect_flags & 1) ? ASSUAN_SOCKET_CONNECT_FDPASSING : 0);
1264 log_error ("can't connect to socket `%s': %s\n",
1265 opt.raw_socket, gpg_strerror (rc));
1270 log_info ("connection to socket `%s' established\n", opt.raw_socket);
1273 ctx = start_agent ();
1275 /* See whether there is a line pending from the server (in case
1276 assuan did not run the initial handshaking). */
1277 if (assuan_pending_line (ctx))
1279 rc = read_and_print_response (ctx, 0, &cmderr);
1281 log_info (_("receiving line failed: %s\n"), gpg_strerror (rc) );
1285 for (loopidx=0; loopidx < DIM (loopstack); loopidx++)
1286 loopstack[loopidx].collecting = 0;
1294 size_t maxlength = 2048;
1296 assert (loopidx < (int)DIM (loopstack));
1297 if (loopidx >= 0 && loopstack[loopidx].current)
1301 line = xstrdup (loopstack[loopidx].current->line);
1303 /* Never go beyond of the final /end. */
1304 if (loopstack[loopidx].current->next)
1305 loopstack[loopidx].current = loopstack[loopidx].current->next;
1306 else if (!strncmp (line, "/end", 4) && (!line[4]||spacep(line+4)))
1309 log_fatal ("/end command vanished\n");
1311 else if (cmdline_commands && *cmdline_commands && !script_fp)
1315 line = xstrdup (*cmdline_commands);
1321 else if (use_tty && !script_fp)
1325 line = tty_get ("> ");
1327 if (n==1 && *line == CONTROL_D)
1341 n = read_line (script_fp? script_fp:stdin,
1342 &line, &linesize, &maxlength);
1346 log_error (_("error reading input: %s\n"), strerror (errno));
1351 log_error ("stopping script execution\n");
1364 log_info ("end of script\n");
1371 log_error (_("line too long - skipped\n"));
1374 if (memchr (line, 0, n))
1375 log_info (_("line shortened due to embedded Nul character\n"));
1376 if (line[n-1] == '\n')
1379 if (opt.trim_leading_spaces)
1381 const char *s = line;
1394 if (loopidx+1 >= 0 && loopstack[loopidx+1].collecting)
1398 ll = xmalloc (sizeof *ll + strlen (line));
1400 strcpy (ll->line, line);
1401 *loopstack[loopidx+1].tail = ll;
1402 loopstack[loopidx+1].tail = &ll->next;
1404 if (!strncmp (line, "/end", 4) && (!line[4]||spacep(line+4)))
1405 loopstack[loopidx+1].nestlevel--;
1406 else if (!strncmp (line, "/while", 6) && (!line[6]||spacep(line+6)))
1407 loopstack[loopidx+1].nestlevel++;
1409 if (loopstack[loopidx+1].nestlevel)
1411 /* We reached the corresponding /end. */
1412 loopstack[loopidx+1].collecting = 0;
1418 /* Handle control commands. */
1421 for (p=cmd; *p && !spacep (p); p++)
1427 if (!strcmp (cmd, "let"))
1429 assign_variable (p, 0);
1431 else if (!strcmp (cmd, "slet"))
1433 /* Deprecated - never used in a released version. */
1434 assign_variable (p, 1);
1436 else if (!strcmp (cmd, "showvar"))
1440 else if (!strcmp (cmd, "definq"))
1442 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1445 add_definq (tmpline, 1, 0);
1449 add_definq (p, 1, 0);
1451 else if (!strcmp (cmd, "definqfile"))
1453 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1456 add_definq (tmpline, 0, 0);
1460 add_definq (p, 0, 0);
1462 else if (!strcmp (cmd, "definqprog"))
1464 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1467 add_definq (tmpline, 0, 1);
1471 add_definq (p, 0, 1);
1473 else if (!strcmp (cmd, "datafile"))
1477 if (current_datasink)
1479 if (current_datasink != stdout)
1480 fclose (current_datasink);
1481 current_datasink = NULL;
1483 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1484 fname = tmpline? tmpline : p;
1485 if (fname && !strcmp (fname, "-"))
1486 current_datasink = stdout;
1487 else if (fname && *fname)
1489 current_datasink = fopen (fname, "wb");
1490 if (!current_datasink)
1491 log_error ("can't open `%s': %s\n",
1492 fname, strerror (errno));
1496 else if (!strcmp (cmd, "showdef"))
1500 else if (!strcmp (cmd, "cleardef"))
1504 else if (!strcmp (cmd, "echo"))
1506 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1515 else if (!strcmp (cmd, "sendfd"))
1517 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1520 do_sendfd (ctx, tmpline);
1527 else if (!strcmp (cmd, "recvfd"))
1529 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1532 do_recvfd (ctx, tmpline);
1539 else if (!strcmp (cmd, "open"))
1541 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1550 else if (!strcmp (cmd, "close"))
1552 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1561 else if (!strcmp (cmd, "showopen"))
1565 else if (!strcmp (cmd, "serverpid"))
1569 else if (!strcmp (cmd, "hex"))
1571 else if (!strcmp (cmd, "nohex"))
1573 else if (!strcmp (cmd, "decode"))
1575 else if (!strcmp (cmd, "nodecode"))
1577 else if (!strcmp (cmd, "subst"))
1579 opt.enable_varsubst = 1;
1580 opt.trim_leading_spaces = 1;
1582 else if (!strcmp (cmd, "nosubst"))
1583 opt.enable_varsubst = 0;
1584 else if (!strcmp (cmd, "run"))
1588 for (p2=p; *p2 && !spacep (p2); p2++)
1596 log_error ("syntax error in run command\n");
1605 log_error ("cannot nest run commands - stop\n");
1609 else if (!(script_fp = fopen (p, "r")))
1611 log_error ("cannot open run file `%s': %s\n",
1612 p, strerror (errno));
1614 else if (opt.verbose)
1615 log_info ("running commands from `%s'\n", p);
1617 else if (!strcmp (cmd, "while"))
1619 if (loopidx+2 >= (int)DIM(loopstack))
1621 log_error ("blocks are nested too deep\n");
1622 /* We should better die or break all loop in this
1623 case as recovering from this error won't be
1628 loopstack[loopidx+1].head = NULL;
1629 loopstack[loopidx+1].tail = &loopstack[loopidx+1].head;
1630 loopstack[loopidx+1].current = NULL;
1631 loopstack[loopidx+1].nestlevel = 1;
1632 loopstack[loopidx+1].oneshot = 0;
1633 loopstack[loopidx+1].condition = xstrdup (p);
1634 loopstack[loopidx+1].collecting = 1;
1637 else if (!strcmp (cmd, "if"))
1639 if (loopidx+2 >= (int)DIM(loopstack))
1641 log_error ("blocks are nested too deep\n");
1645 /* Note that we need to evaluate the condition right
1646 away and not just at the end of the block as we
1648 loopstack[loopidx+1].head = NULL;
1649 loopstack[loopidx+1].tail = &loopstack[loopidx+1].head;
1650 loopstack[loopidx+1].current = NULL;
1651 loopstack[loopidx+1].nestlevel = 1;
1652 loopstack[loopidx+1].oneshot = 1;
1653 loopstack[loopidx+1].condition = substitute_line_copy (p);
1654 loopstack[loopidx+1].collecting = 1;
1657 else if (!strcmp (cmd, "end"))
1660 log_error ("stray /end command encountered - ignored\n");
1667 /* Evaluate the condition. */
1668 tmpcond = xstrdup (loopstack[loopidx].condition);
1669 if (loopstack[loopidx].oneshot)
1671 xfree (loopstack[loopidx].condition);
1672 loopstack[loopidx].condition = xstrdup ("0");
1674 tmpline = substitute_line (tmpcond);
1675 value = tmpline? tmpline : tmpcond;
1676 condition = strtol (value, NULL, 0);
1683 loopstack[loopidx].current = loopstack[loopidx].head;
1688 while (loopstack[loopidx].head)
1690 loopline_t tmp = loopstack[loopidx].head->next;
1691 xfree (loopstack[loopidx].head);
1692 loopstack[loopidx].head = tmp;
1694 loopstack[loopidx].tail = NULL;
1695 loopstack[loopidx].current = NULL;
1696 loopstack[loopidx].nestlevel = 0;
1697 loopstack[loopidx].collecting = 0;
1698 loopstack[loopidx].oneshot = 0;
1699 xfree (loopstack[loopidx].condition);
1700 loopstack[loopidx].condition = NULL;
1705 else if (!strcmp (cmd, "bye"))
1709 else if (!strcmp (cmd, "sleep"))
1713 else if (!strcmp (cmd, "help"))
1716 "Available commands:\n"
1717 "/echo ARGS Echo ARGS.\n"
1718 "/let NAME VALUE Set variable NAME to VALUE.\n"
1719 "/showvar Show all variables.\n"
1720 "/definq NAME VAR Use content of VAR for inquiries with NAME.\n"
1721 "/definqfile NAME FILE Use content of FILE for inquiries with NAME.\n"
1722 "/definqprog NAME PGM Run PGM for inquiries with NAME.\n"
1723 "/datafile [NAME] Write all D line content to file NAME.\n"
1724 "/showdef Print all definitions.\n"
1725 "/cleardef Delete all definitions.\n"
1726 "/sendfd FILE MODE Open FILE and pass descriptor to server.\n"
1727 "/recvfd Receive FD from server and print.\n"
1728 "/open VAR FILE MODE Open FILE and assign the file descriptor to VAR.\n"
1729 "/close FD Close file with descriptor FD.\n"
1730 "/showopen Show descriptors of all open files.\n"
1731 "/serverpid Retrieve the pid of the server.\n"
1732 "/[no]hex Enable hex dumping of received data lines.\n"
1733 "/[no]decode Enable decoding of received data lines.\n"
1734 "/[no]subst Enable variable substitution.\n"
1735 "/run FILE Run commands from FILE.\n"
1736 "/if VAR Begin conditional block controlled by VAR.\n"
1737 "/while VAR Begin loop controlled by VAR.\n"
1738 "/end End loop or condition\n"
1739 "/bye Terminate gpg-connect-agent.\n"
1740 "/help Print this help.");
1743 log_error (_("unknown command `%s'\n"), cmd );
1748 if (opt.verbose && script_fp)
1751 tmpline = opt.enable_varsubst? substitute_line (line) : NULL;
1754 rc = assuan_write_line (ctx, tmpline);
1758 rc = assuan_write_line (ctx, line);
1761 log_info (_("sending line failed: %s\n"), gpg_strerror (rc) );
1764 if (*line == '#' || !*line)
1765 continue; /* Don't expect a response for a comment line. */
1767 rc = read_and_print_response (ctx, (!ascii_strncasecmp (line, "HELP", 4)
1768 && (spacep (line+4) || !line[4])),
1771 log_info (_("receiving line failed: %s\n"), gpg_strerror (rc) );
1772 if ((rc || cmderr) && script_fp)
1774 log_error ("stopping script execution\n");
1780 /* FIXME: If the last command was BYE or the server died for
1781 some other reason, we won't notice until we get the next
1782 input command. Probing the connection with a non-blocking
1783 read could help to notice termination or other problems
1788 log_info ("closing connection to agent\n");
1794 /* Handle an Inquire from the server. Return False if it could not be
1795 handled; in this case the caller shll complete the operation. LINE
1796 is the complete line as received from the server. This function
1797 may change the content of LINE. */
1799 handle_inquire (assuan_context_t ctx, char *line)
1807 /* Skip the command and trailing spaces. */
1808 for (; *line && !spacep (line); line++)
1810 while (spacep (line))
1814 for (; *line && !spacep (line); line++)
1819 /* Now match it against our list. The second loop is there to
1820 detect the match-all entry. */
1821 for (d=definq_list; d; d = d->next)
1822 if (d->name && !strcmp (d->name, name))
1825 for (d=definq_list; d; d = d->next)
1831 log_info ("no handler for inquiry `%s' found\n", name);
1837 char *tmpvalue = get_var_ext (d->file);
1838 rc = assuan_send_data (ctx, tmpvalue, strlen (tmpvalue));
1841 log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
1847 fp = popen (d->file, "r");
1849 log_error ("error executing `%s': %s\n",
1850 d->file, strerror (errno));
1851 else if (opt.verbose)
1852 log_error ("handling inquiry `%s' by running `%s'\n",
1857 fp = fopen (d->file, "rb");
1859 log_error ("error opening `%s': %s\n", d->file, strerror (errno));
1860 else if (opt.verbose)
1861 log_error ("handling inquiry `%s' by returning content of `%s'\n",
1867 while ( (n = fread (buffer, 1, sizeof buffer, fp)) )
1869 rc = assuan_send_data (ctx, buffer, n);
1872 log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
1877 log_error ("error reading from `%s': %s\n", d->file, strerror (errno));
1880 rc = assuan_send_data (ctx, NULL, 0);
1882 log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
1886 else if (d->is_prog)
1889 log_error ("error running `%s': %s\n", d->file, strerror (errno));
1897 /* Read all response lines from server and print them. Returns 0 on
1898 success or an assuan error code. If WITHHASH istrue, comment lines
1899 are printed. Sets R_GOTERR to true if the command did not returned
1902 read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr)
1915 rc = assuan_read_line (ctx, &line, &linelen);
1919 if ((withhash || opt.verbose > 1) && *line == '#')
1921 fwrite (line, linelen, 1, stdout);
1925 while (*line == '#' || !linelen);
1928 && line[0] == 'D' && line[1] == ' ')
1930 if (current_datasink)
1932 const unsigned char *s;
1935 for (j=2, s=(unsigned char*)line+2; j < linelen; j++, s++ )
1937 if (*s == '%' && j+2 < linelen)
1945 putc (c, current_datasink);
1950 for (i=2; i < linelen; )
1954 printf ("D[%04X] ", i-2);
1955 for (j=0; j < 16 ; j++, i++)
1960 printf (" %02X", ((unsigned char*)line)[i]);
1962 fputs (" ", stdout);
1964 fputs (" ", stdout);
1966 for (j=0; j < 16; j++, i++)
1968 unsigned int c = ((unsigned char*)line)[i];
1971 else if (isascii (c) && isprint (c) && !iscntrl (c))
1979 else if (opt.decode)
1981 const unsigned char *s;
1985 for (j=2, s=(unsigned char*)line+2; j < linelen; j++, s++ )
1989 fputs ("D ", stdout);
1992 if (*s == '%' && j+2 < linelen)
2004 need_lf = (c != '\n');
2008 fwrite (line, linelen, 1, stdout);
2016 if (!current_datasink || current_datasink != stdout)
2023 && (line[1] == '\0' || line[1] == ' '))
2025 if (!current_datasink || current_datasink != stdout)
2027 fwrite (line, linelen, 1, stdout);
2031 else if (linelen >= 2
2032 && line[0] == 'O' && line[1] == 'K'
2033 && (line[2] == '\0' || line[2] == ' '))
2035 if (!current_datasink || current_datasink != stdout)
2037 fwrite (line, linelen, 1, stdout);
2040 set_int_var ("?", 0);
2043 else if (linelen >= 3
2044 && line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
2045 && (line[3] == '\0' || line[3] == ' '))
2049 errval = strtol (line+3, NULL, 10);
2052 set_int_var ("?", errval);
2053 if (!current_datasink || current_datasink != stdout)
2055 fwrite (line, linelen, 1, stdout);
2061 else if (linelen >= 7
2062 && line[0] == 'I' && line[1] == 'N' && line[2] == 'Q'
2063 && line[3] == 'U' && line[4] == 'I' && line[5] == 'R'
2065 && (line[7] == '\0' || line[7] == ' '))
2067 if (!current_datasink || current_datasink != stdout)
2069 fwrite (line, linelen, 1, stdout);
2072 if (!handle_inquire (ctx, line))
2073 assuan_write_line (ctx, "CANCEL");
2075 else if (linelen >= 3
2076 && line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
2077 && (line[3] == '\0' || line[3] == ' '))
2079 if (!current_datasink || current_datasink != stdout)
2081 fwrite (line, linelen, 1, stdout);
2084 /* Received from server, thus more responses are expected. */
2087 return gpg_error (GPG_ERR_ASS_INV_RESPONSE);
2095 /* Connect to the agent and send the standard options. */
2096 static assuan_context_t
2101 assuan_context_t ctx;
2102 session_env_t session_env;
2104 infostr = getenv ("GPG_AGENT_INFO");
2105 if (!infostr || !*infostr)
2109 rc = assuan_new (&ctx);
2112 log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
2116 /* Check whether we can connect at the standard socket. */
2117 sockname = make_filename (opt.homedir, "S.gpg-agent", NULL);
2118 rc = assuan_socket_connect (ctx, sockname, 0, 0);
2120 #ifdef HAVE_W32_SYSTEM
2121 /* If we failed to connect under Windows, we fire up the agent. */
2122 if (gpg_err_code (rc) == GPG_ERR_ASS_CONNECT_FAILED)
2124 const char *agent_program;
2125 const char *argv[3];
2129 log_info (_("no running gpg-agent - starting one\n"));
2130 agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT);
2132 argv[0] = "--daemon";
2133 argv[1] = "--use-standard-socket";
2136 rc = gnupg_spawn_process_detached (agent_program, argv, NULL);
2138 log_debug ("failed to start agent `%s': %s\n",
2139 agent_program, gpg_strerror (rc));
2142 /* Give the agent some time to prepare itself. */
2144 /* Now try again to connect the agent. */
2145 rc = assuan_new (&ctx);
2148 log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
2152 rc = assuan_socket_connect (ctx, sockname, 0, 0);
2157 #endif /*HAVE_W32_SYSTEM*/
2165 infostr = xstrdup (infostr);
2166 if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr)
2168 log_error (_("malformed GPG_AGENT_INFO environment variable\n"));
2174 while (*p && *p != PATHSEP_C)
2176 prot = *p? atoi (p+1) : 0;
2179 log_error (_("gpg-agent protocol version %d is not supported\n"),
2185 rc = assuan_new (&ctx);
2188 log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
2192 rc = assuan_socket_connect (ctx, infostr, pid, 0);
2198 log_error ("can't connect to the agent: %s\n", gpg_strerror (rc));
2203 log_info ("connection to agent established\n");
2205 rc = assuan_transact (ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL);
2208 log_error (_("error sending %s command: %s\n"), "RESET",
2213 session_env = session_env_new ();
2215 log_fatal ("error allocating session environment block: %s\n",
2218 rc = send_pinentry_environment (ctx, GPG_ERR_SOURCE_DEFAULT,
2219 NULL, NULL, session_env);
2220 session_env_release (session_env);
2223 log_error (_("error sending standard options: %s\n"), gpg_strerror (rc));