Initialize opt.session_env.
[gnupg.git] / tools / gpg-connect-agent.c
bloba2fb1d136bbec8c88b9612e31cc807fc9ad530ee
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/>.
20 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <ctype.h>
27 #include <assuan.h>
28 #include <unistd.h>
29 #include <assert.h>
31 #include "i18n.h"
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"
39 #endif
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
48 aNull = 0,
49 oQuiet = 'q',
50 oVerbose = 'v',
51 oRawSocket = 'S',
52 oExec = 'E',
53 oRun = 'r',
54 oSubst = 's',
56 oNoVerbose = 500,
57 oHomedir,
58 oHex,
59 oDecode,
60 oNoExtConnect
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", "@" ),
86 ARGPARSE_end ()
90 /* We keep all global options in the structure OPT. */
91 struct
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;
103 } opt;
107 /* Definitions for /definq commands and a global linked list with all
108 the definitions. */
109 struct definq_s
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. */
124 struct variable_s
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. */
136 struct loopline_s
138 struct loopline_s *next;
139 char line[1];
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. */
151 static struct
153 int inuse;
154 #ifdef HAVE_W32_SYSTEM
155 HANDLE handle;
156 #endif
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,
163 int *r_goterr);
164 static assuan_context_t start_agent (void);
169 /* Print usage information and and provide strings for help. */
170 static const char *
171 my_strusage( int level )
173 const char *p;
175 switch (level)
177 case 11: p = "gpg-connect-agent (GnuPG)";
178 break;
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;
183 case 1:
184 case 40: p = _("Usage: gpg-connect-agent [options] (-h for help)");
185 break;
186 case 41:
187 p = _("Syntax: gpg-connect-agent [options]\n"
188 "Connect to a running agent and send commands\n");
189 break;
190 case 31: p = "\nHome: "; break;
191 case 32: p = opt.homedir; break;
192 case 33: p = "\n"; break;
194 default: p = NULL; break;
196 return p;
200 static char *
201 gnu_getcwd (void)
203 char *buffer;
204 size_t size = 100;
206 for (;;)
208 buffer = xmalloc (size+1);
209 if (getcwd (buffer, size) == buffer)
210 return buffer;
211 xfree (buffer);
212 if (errno != ERANGE)
213 return NULL;
214 size *= 2;
219 /* Unescape STRING and returned the malloced result. The surrounding
220 quotes must already be removed from STRING. */
221 static char *
222 unescape_string (const char *string)
224 const unsigned char *s;
225 int esc;
226 size_t n;
227 char *buffer;
228 unsigned char *d;
230 n = 0;
231 for (s = (const unsigned char*)string, esc=0; *s; s++)
233 if (esc)
235 switch (*s)
237 case 'b':
238 case 't':
239 case 'v':
240 case 'n':
241 case 'f':
242 case 'r':
243 case '"':
244 case '\'':
245 case '\\': n++; break;
246 case 'x':
247 if (s[1] && s[2] && hexdigitp (s+1) && hexdigitp (s+2))
248 n++;
249 break;
251 default:
252 if (s[1] && s[2]
253 && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
254 n++;
255 break;
257 esc = 0;
259 else if (*s == '\\')
260 esc = 1;
261 else
262 n++;
265 buffer = xmalloc (n+1);
266 d = (unsigned char*)buffer;
267 for (s = (const unsigned char*)string, esc=0; *s; s++)
269 if (esc)
271 switch (*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;
282 case 'x':
283 if (s[1] && s[2] && hexdigitp (s+1) && hexdigitp (s+2))
285 s++;
286 *d++ = xtoi_2 (s);
287 s++;
289 break;
291 default:
292 if (s[1] && 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);
296 s += 2;
298 break;
300 esc = 0;
302 else if (*s == '\\')
303 esc = 1;
304 else
305 *d++ = *s;
307 *d = 0;
308 return buffer;
312 /* Do the percent unescaping and return a newly malloced string.
313 If WITH_PLUS is set '+' characters will be changed to space. */
314 static char *
315 unpercent_string (const char *string, int with_plus)
317 const unsigned char *s;
318 unsigned char *buffer, *p;
319 size_t n;
321 n = 0;
322 for (s=(const unsigned char *)string; *s; s++)
324 if (*s == '%' && s[1] && s[2])
326 s++;
327 n++;
328 s++;
330 else if (with_plus && *s == '+')
331 n++;
332 else
333 n++;
336 buffer = xmalloc (n+1);
337 p = buffer;
338 for (s=(const unsigned char *)string; *s; s++)
340 if (*s == '%' && s[1] && s[2])
342 s++;
343 *p++ = xtoi_2 (s);
344 s++;
346 else if (with_plus && *s == '+')
347 *p++ = ' ';
348 else
349 *p++ = *s;
351 *p = 0;
352 return (char*)buffer;
359 static const char *
360 set_var (const char *name, const char *value)
362 variable_t var;
364 for (var = variable_table; var; var = var->next)
365 if (!strcmp (var->name, name))
366 break;
367 if (!var)
369 var = xmalloc (sizeof *var + strlen (name));
370 var->value = NULL;
371 strcpy (var->name, name);
372 var->next = variable_table;
373 variable_table = var;
375 xfree (var->value);
376 var->value = value? xstrdup (value) : NULL;
377 return var->value;
381 static void
382 set_int_var (const char *name, int value)
384 char numbuf[35];
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. */
395 static const char *
396 get_var (const char *name)
398 variable_t var;
399 const char *s;
401 if (!*name)
402 return "";
403 for (var = variable_table; var; var = var->next)
404 if (!strcmp (var->name, name))
405 break;
406 if (!var && (s = getenv (name)))
407 return set_var (name, s);
408 if (!var || !var->value)
409 return NULL;
410 return var->value;
414 /* Perform some simple arithmentic operations. Caller must release
415 the return value. On error the return value is NULL. */
416 static char *
417 arithmetic_op (int operator, const char *operands)
419 long result, value;
420 char numbuf[35];
422 while ( spacep (operands) )
423 operands++;
424 if (!*operands)
425 return NULL;
426 result = strtol (operands, NULL, 0);
427 while (*operands && !spacep (operands) )
428 operands++;
429 if (operator == '!')
430 result = !result;
432 while (*operands)
434 while ( spacep (operands) )
435 operands++;
436 if (!*operands)
437 break;
438 value = strtol (operands, NULL, 0);
439 while (*operands && !spacep (operands) )
440 operands++;
441 switch (operator)
443 case '+': result += value; break;
444 case '-': result -= value; break;
445 case '*': result *= value; break;
446 case '/':
447 if (!value)
448 return NULL;
449 result /= value;
450 break;
451 case '%':
452 if (!value)
453 return NULL;
454 result %= value;
455 break;
456 case '!': result = !value; break;
457 case '|': result = result || value; break;
458 case '&': result = result && value; break;
459 default:
460 log_error ("unknown arithmetic operator `%c'\n", operator);
461 return NULL;
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.
485 unescape ARGS
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.
491 unpercent ARGS
492 unpercent+ ARGS
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 '+'
497 to space.
499 percent ARGS
500 percent+ ARGS
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.
505 errcode ARG
506 Assuming ARG is an integer, return the gpg-error code.
508 errsource ARG
509 Assuming ARG is an integer, return the gpg-error source.
511 errstring ARG
512 Assuming ARG is an integer return a formatted fpf error string.
515 Example: get_var_ext ("get sysconfdir") -> "/etc/gnupg"
518 static char *
519 get_var_ext (const char *name)
521 static int recursion_count;
522 const char *s;
523 char *result;
524 char *p;
525 char *free_me = NULL;
526 int intvalue;
528 if (recursion_count > 50)
530 log_error ("variables nested too deeply\n");
531 return NULL;
534 recursion_count++;
535 free_me = opt.enable_varsubst? substitute_line_copy (name) : NULL;
536 if (free_me)
537 name = free_me;
538 for (s=name; *s && !spacep (s); s++)
540 if (!*s)
542 s = get_var (name);
543 result = s? xstrdup (s): NULL;
545 else if ( (s - name) == 3 && !strncmp (name, "get", 3))
547 while ( spacep (s) )
548 s++;
549 if (!strcmp (s, "cwd"))
551 result = gnu_getcwd ();
552 if (!result)
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);
569 else
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");
574 result = NULL;
577 else if ( (s - name) == 8 && !strncmp (name, "unescape", 8))
579 s++;
580 result = unescape_string (s);
582 else if ( (s - name) == 9 && !strncmp (name, "unpercent", 9))
584 s++;
585 result = unpercent_string (s, 0);
587 else if ( (s - name) == 10 && !strncmp (name, "unpercent+", 10))
589 s++;
590 result = unpercent_string (s, 1);
592 else if ( (s - name) == 7 && !strncmp (name, "percent", 7))
594 s++;
595 result = percent_escape (s, "\t\r\n\f\v");
597 else if ( (s - name) == 8 && !strncmp (name, "percent+", 8))
599 s++;
600 result = percent_escape (s, "\t\r\n\f\v");
601 for (p=result; *p; p++)
602 if (*p == ' ')
603 *p = '+';
605 else if ( (s - name) == 7 && !strncmp (name, "errcode", 7))
607 s++;
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))
613 s++;
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))
619 s++;
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);
628 else
630 log_error ("unknown variable function `%.*s'\n", (int)(s-name), name);
631 result = NULL;
634 xfree (free_me);
635 recursion_count--;
636 return result;
640 /* Substitute variables in LINE and return a new allocated buffer if
641 required. The function might modify LINE if the expanded version
642 fits into it. */
643 static char *
644 substitute_line (char *buffer)
646 char *line = buffer;
647 char *p, *pend;
648 const char *value;
649 size_t valuelen, n;
650 char *result = NULL;
651 char *freeme = NULL;
653 while (*line)
655 p = strchr (line, '$');
656 if (!p)
657 return result; /* No more variables. */
659 if (p[1] == '$') /* Escaped dollar sign. */
661 memmove (p, p+1, strlen (p+1)+1);
662 line = p + 1;
663 continue;
665 if (p[1] == '{')
667 int count = 0;
669 for (pend=p+2; *pend; pend++)
671 if (*pend == '{')
672 count++;
673 else if (*pend == '}')
675 if (--count < 0)
676 break;
679 if (!*pend)
680 return result; /* Unclosed - don't substitute. */
682 else
684 for (pend=p+1; *pend && !spacep (pend) && *pend != '$' ; pend++)
687 if (p[1] == '{' && *pend == '}')
689 int save = *pend;
690 *pend = 0;
691 freeme = get_var_ext (p+2);
692 value = freeme;
693 *pend++ = save;
695 else if (*pend)
697 int save = *pend;
698 *pend = 0;
699 value = get_var (p+1);
700 *pend = save;
702 else
703 value = get_var (p+1);
704 if (!value)
705 value = "";
706 valuelen = strlen (value);
707 if (valuelen <= pend - p)
709 memcpy (p, value, valuelen);
710 p += valuelen;
711 n = pend - p;
712 if (n)
713 memmove (p, p+n, strlen (p+n)+1);
714 line = p;
716 else
718 char *src = result? result : buffer;
719 char *dst;
721 dst = xmalloc (strlen (src) + valuelen + 1);
722 n = p - src;
723 memcpy (dst, src, n);
724 memcpy (dst + n, value, valuelen);
725 n += valuelen;
726 strcpy (dst + n, pend);
727 line = dst + n;
728 xfree (result);
729 result = dst;
731 xfree (freeme);
732 freeme = NULL;
734 return result;
737 /* Same as substitute_line but do not modify BUFFER. */
738 static char *
739 substitute_line_copy (const char *buffer)
741 char *result, *p;
743 p = xstrdup (buffer?buffer:"");
744 result = substitute_line (p);
745 if (!result)
746 result = p;
747 else
748 xfree (p);
749 return result;
753 static void
754 assign_variable (char *line, int syslet)
756 char *name, *p, *tmp, *free_me, *buffer;
758 /* Get the name. */
759 name = line;
760 for (p=name; *p && !spacep (p); p++)
762 if (*p)
763 *p++ = 0;
764 while (spacep (p))
765 p++;
767 if (!*p)
768 set_var (name, NULL); /* Remove variable. */
769 else if (syslet)
771 free_me = opt.enable_varsubst? substitute_line_copy (p) : NULL;
772 if (free_me)
773 p = free_me;
774 buffer = xmalloc (4 + strlen (p) + 1);
775 strcpy (stpcpy (buffer, "get "), p);
776 tmp = get_var_ext (buffer);
777 xfree (buffer);
778 set_var (name, tmp);
779 xfree (tmp);
780 xfree (free_me);
782 else
784 tmp = opt.enable_varsubst? substitute_line_copy (p) : NULL;
785 if (tmp)
787 set_var (name, tmp);
788 xfree (tmp);
790 else
791 set_var (name, p);
796 static void
797 show_variables (void)
799 variable_t var;
801 for (var = variable_table; var; var = var->next)
802 if (var->value)
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. */
810 static void
811 add_definq (char *line, int is_var, int is_prog)
813 definq_t d;
814 char *name, *p;
816 /* Get name. */
817 name = line;
818 for (p=name; *p && !spacep (p); p++)
820 if (*p)
821 *p++ = 0;
822 while (spacep (p))
823 p++;
825 d = xmalloc (sizeof *d + strlen (p) );
826 strcpy (d->file, p);
827 d->is_var = is_var;
828 d->is_prog = is_prog;
829 if ( !strcmp (name, "*"))
830 d->name = NULL;
831 else
832 d->name = xstrdup (name);
834 d->next = NULL;
835 *definq_list_tail = d;
836 definq_list_tail = &d->next;
840 /* Show all inquiry defintions. */
841 static void
842 show_definq (void)
844 definq_t d;
846 for (d=definq_list; d; d = d->next)
847 if (d->name)
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)
851 if (!d->name)
852 printf ("%-20s %c %s\n", "*",
853 d->is_var? 'v': d->is_prog? 'p':'f', d->file);
857 /* Clear all inquiry definitions. */
858 static void
859 clear_definq (void)
861 while (definq_list)
863 definq_t tmp = definq_list->next;
864 xfree (definq_list->name);
865 xfree (definq_list);
866 definq_list = tmp;
868 definq_list_tail = &definq_list;
872 static void
873 do_sendfd (assuan_context_t ctx, char *line)
875 FILE *fp;
876 char *name, *mode, *p;
877 int rc, fd;
879 /* Get file name. */
880 name = line;
881 for (p=name; *p && !spacep (p); p++)
883 if (*p)
884 *p++ = 0;
885 while (spacep (p))
886 p++;
888 /* Get mode. */
889 mode = p;
890 if (!*mode)
891 mode = "r";
892 else
894 for (p=mode; *p && !spacep (p); p++)
896 if (*p)
897 *p++ = 0;
900 /* Open and send. */
901 fp = fopen (name, mode);
902 if (!fp)
904 log_error ("can't open `%s' in \"%s\" mode: %s\n",
905 name, mode, strerror (errno));
906 return;
908 fd = fileno (fp);
910 if (opt.verbose)
911 log_error ("file `%s' opened in \"%s\" mode, fd=%d\n",
912 name, mode, fd);
914 rc = assuan_sendfd (ctx, INT2FD (fd) );
915 if (rc)
916 log_error ("sending descriptor %d failed: %s\n", fd, gpg_strerror (rc));
917 fclose (fp);
921 static void
922 do_recvfd (assuan_context_t ctx, char *line)
924 (void)ctx;
925 (void)line;
926 log_info ("This command has not yet been implemented\n");
930 static void
931 do_open (char *line)
933 FILE *fp;
934 char *varname, *name, *mode, *p;
935 int fd;
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");
942 return;
944 #endif
946 /* Get variable name. */
947 varname = line;
948 for (p=varname; *p && !spacep (p); p++)
950 if (*p)
951 *p++ = 0;
952 while (spacep (p))
953 p++;
955 /* Get file name. */
956 name = p;
957 for (p=name; *p && !spacep (p); p++)
959 if (*p)
960 *p++ = 0;
961 while (spacep (p))
962 p++;
964 /* Get mode. */
965 mode = p;
966 if (!*mode)
967 mode = "r";
968 else
970 for (p=mode; *p && !spacep (p); p++)
972 if (*p)
973 *p++ = 0;
976 /* Open and send. */
977 fp = fopen (name, mode);
978 if (!fp)
980 log_error ("can't open `%s' in \"%s\" mode: %s\n",
981 name, mode, strerror (errno));
982 return;
984 fd = fileno (fp);
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);
995 if (!prochandle)
997 log_error ("failed to open the server process\n");
998 close (fd);
999 return;
1002 if (!DuplicateHandle (GetCurrentProcess(), handle,
1003 prochandle, &newhandle, 0,
1004 TRUE, DUPLICATE_SAME_ACCESS ))
1006 log_error ("failed to duplicate the handle\n");
1007 close (fd);
1008 CloseHandle (prochandle);
1009 return;
1011 CloseHandle (prochandle);
1012 open_fd_table[fd].handle = newhandle;
1014 if (opt.verbose)
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);
1018 #else
1019 if (opt.verbose)
1020 log_info ("file `%s' opened in \"%s\" mode, fd=%d\n",
1021 name, mode, fd);
1022 set_int_var (varname, fd);
1023 #endif
1025 else
1027 log_error ("can't put fd %d into table\n", fd);
1028 close (fd);
1033 static void
1034 do_close (char *line)
1036 int fd = atoi (line);
1038 #ifdef HAVE_W32_SYSTEM
1039 int i;
1041 for (i=0; i < DIM (open_fd_table); i++)
1042 if ( open_fd_table[i].inuse && open_fd_table[i].handle == (void*)fd)
1043 break;
1044 if (i < DIM (open_fd_table))
1045 fd = i;
1046 else
1048 log_error ("given fd (system handle) has not been opened\n");
1049 return;
1051 #endif
1053 if (fd < 0 || fd >= DIM (open_fd_table))
1055 log_error ("invalid fd\n");
1056 return;
1059 if (!open_fd_table[fd].inuse)
1061 log_error ("given fd has not been opened\n");
1062 return;
1064 #ifdef HAVE_W32_SYSTEM
1065 CloseHandle (open_fd_table[fd].handle); /* Close duped handle. */
1066 #endif
1067 close (fd);
1068 open_fd_table[fd].inuse = 0;
1072 static void
1073 do_showopen (void)
1075 int i;
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);
1082 #else
1083 printf ("%-15d\n", i);
1084 #endif
1090 static gpg_error_t
1091 getinfo_pid_cb (void *opaque, const void *buffer, size_t length)
1093 membuf_t *mb = opaque;
1094 put_membuf (mb, buffer, length);
1095 return 0;
1098 /* Get the pid of the server and store it locally. */
1099 static void
1100 do_serverpid (assuan_context_t ctx)
1102 int rc;
1103 membuf_t mb;
1104 char *buffer;
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);
1111 if (rc || !buffer)
1112 log_error ("command \"%s\" failed: %s\n",
1113 "GETINFO pid", gpg_strerror (rc));
1114 else
1116 server_pid = (pid_t)strtoul (buffer, NULL, 10);
1117 if (opt.verbose)
1118 log_info ("server's PID is %lu\n", (unsigned long)server_pid);
1120 xfree (buffer);
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;
1131 char *line, *p;
1132 char *tmpline;
1133 size_t linesize;
1134 int rc;
1135 int cmderr;
1136 const char *opt_run = NULL;
1137 FILE *script_fp = NULL;
1138 int use_tty, keep_line;
1139 struct {
1140 int collecting;
1141 loopline_t head;
1142 loopline_t *tail;
1143 loopline_t current;
1144 unsigned int nestlevel;
1145 int oneshot;
1146 char *condition;
1147 } loopstack[20];
1148 int loopidx;
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. */
1156 i18n_init();
1157 init_common_subsystems ();
1159 assuan_set_gpg_err_source (0);
1162 opt.homedir = default_homedir ();
1163 opt.connect_flags = 1; /* Use extended connect mode. */
1165 /* Parse the command line. */
1166 pargs.argc = &argc;
1167 pargs.argv = &argv;
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;
1183 case oSubst:
1184 opt.enable_varsubst = 1;
1185 opt.trim_leading_spaces = 1;
1186 break;
1188 default: pargs.err = 2; break;
1192 if (log_get_errorcount (0))
1193 exit (2);
1195 use_tty = (isatty ( fileno (stdin)) && isatty (fileno (stdout)));
1197 if (opt.exec)
1199 if (!argc)
1201 log_error (_("option \"%s\" requires a program "
1202 "and optional arguments\n"), "--exec" );
1203 exit (1);
1206 else if (argc)
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));
1217 exit (1);
1221 if (opt.exec)
1223 int no_close[3];
1225 no_close[0] = fileno (stderr);
1226 no_close[1] = log_get_fd ();
1227 no_close[2] = -1;
1229 rc = assuan_new (&ctx);
1230 if (rc)
1232 log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
1233 exit (1);
1236 rc = assuan_pipe_connect_ext (ctx, *argv, (const char **)argv,
1237 no_close, NULL, NULL,
1238 opt.connect_flags);
1239 if (rc)
1241 log_error ("assuan_pipe_connect_ext failed: %s\n",
1242 gpg_strerror (rc));
1243 exit (1);
1246 if (opt.verbose)
1247 log_info ("server `%s' started\n", *argv);
1250 else if (opt.raw_socket)
1252 rc = assuan_new (&ctx);
1253 if (rc)
1255 log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
1256 exit (1);
1259 rc = assuan_socket_connect_ext (ctx, opt.raw_socket, 0,
1260 opt.connect_flags);
1261 if (rc)
1263 log_error ("can't connect to socket `%s': %s\n",
1264 opt.raw_socket, gpg_strerror (rc));
1265 exit (1);
1268 if (opt.verbose)
1269 log_info ("connection to socket `%s' established\n", opt.raw_socket);
1271 else
1272 ctx = start_agent ();
1274 /* See whether there is a line pending from the server (in case
1275 assuan did not run the initial handshaking). */
1276 if (assuan_pending_line (ctx))
1278 rc = read_and_print_response (ctx, 0, &cmderr);
1279 if (rc)
1280 log_info (_("receiving line failed: %s\n"), gpg_strerror (rc) );
1284 for (loopidx=0; loopidx < DIM (loopstack); loopidx++)
1285 loopstack[loopidx].collecting = 0;
1286 loopidx = -1;
1287 line = NULL;
1288 linesize = 0;
1289 keep_line = 1;
1290 for (;;)
1292 int n;
1293 size_t maxlength = 2048;
1295 assert (loopidx < (int)DIM (loopstack));
1296 if (loopidx >= 0 && loopstack[loopidx].current)
1298 keep_line = 0;
1299 xfree (line);
1300 line = xstrdup (loopstack[loopidx].current->line);
1301 n = strlen (line);
1302 /* Never go beyond of the final /end. */
1303 if (loopstack[loopidx].current->next)
1304 loopstack[loopidx].current = loopstack[loopidx].current->next;
1305 else if (!strncmp (line, "/end", 4) && (!line[4]||spacep(line+4)))
1307 else
1308 log_fatal ("/end command vanished\n");
1310 else if (cmdline_commands && *cmdline_commands && !script_fp)
1312 keep_line = 0;
1313 xfree (line);
1314 line = xstrdup (*cmdline_commands);
1315 cmdline_commands++;
1316 n = strlen (line);
1317 if (n >= maxlength)
1318 maxlength = 0;
1320 else if (use_tty && !script_fp)
1322 keep_line = 0;
1323 xfree (line);
1324 line = tty_get ("> ");
1325 n = strlen (line);
1326 if (n==1 && *line == CONTROL_D)
1327 n = 0;
1328 if (n >= maxlength)
1329 maxlength = 0;
1331 else
1333 if (!keep_line)
1335 xfree (line);
1336 line = NULL;
1337 linesize = 0;
1338 keep_line = 1;
1340 n = read_line (script_fp? script_fp:stdin,
1341 &line, &linesize, &maxlength);
1343 if (n < 0)
1345 log_error (_("error reading input: %s\n"), strerror (errno));
1346 if (script_fp)
1348 fclose (script_fp);
1349 script_fp = NULL;
1350 log_error ("stopping script execution\n");
1351 continue;
1353 exit (1);
1355 if (!n)
1357 /* EOF */
1358 if (script_fp)
1360 fclose (script_fp);
1361 script_fp = NULL;
1362 if (opt.verbose)
1363 log_info ("end of script\n");
1364 continue;
1366 break;
1368 if (!maxlength)
1370 log_error (_("line too long - skipped\n"));
1371 continue;
1373 if (memchr (line, 0, n))
1374 log_info (_("line shortened due to embedded Nul character\n"));
1375 if (line[n-1] == '\n')
1376 line[n-1] = 0;
1378 if (opt.trim_leading_spaces)
1380 const char *s = line;
1382 while (spacep (s))
1383 s++;
1384 if (s != line)
1386 for (p=line; *s;)
1387 *p++ = *s++;
1388 *p = 0;
1389 n = p - line;
1393 if (loopidx+1 >= 0 && loopstack[loopidx+1].collecting)
1395 loopline_t ll;
1397 ll = xmalloc (sizeof *ll + strlen (line));
1398 ll->next = NULL;
1399 strcpy (ll->line, line);
1400 *loopstack[loopidx+1].tail = ll;
1401 loopstack[loopidx+1].tail = &ll->next;
1403 if (!strncmp (line, "/end", 4) && (!line[4]||spacep(line+4)))
1404 loopstack[loopidx+1].nestlevel--;
1405 else if (!strncmp (line, "/while", 6) && (!line[6]||spacep(line+6)))
1406 loopstack[loopidx+1].nestlevel++;
1408 if (loopstack[loopidx+1].nestlevel)
1409 continue;
1410 /* We reached the corresponding /end. */
1411 loopstack[loopidx+1].collecting = 0;
1412 loopidx++;
1415 if (*line == '/')
1417 /* Handle control commands. */
1418 char *cmd = line+1;
1420 for (p=cmd; *p && !spacep (p); p++)
1422 if (*p)
1423 *p++ = 0;
1424 while (spacep (p))
1425 p++;
1426 if (!strcmp (cmd, "let"))
1428 assign_variable (p, 0);
1430 else if (!strcmp (cmd, "slet"))
1432 /* Deprecated - never used in a released version. */
1433 assign_variable (p, 1);
1435 else if (!strcmp (cmd, "showvar"))
1437 show_variables ();
1439 else if (!strcmp (cmd, "definq"))
1441 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1442 if (tmpline)
1444 add_definq (tmpline, 1, 0);
1445 xfree (tmpline);
1447 else
1448 add_definq (p, 1, 0);
1450 else if (!strcmp (cmd, "definqfile"))
1452 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1453 if (tmpline)
1455 add_definq (tmpline, 0, 0);
1456 xfree (tmpline);
1458 else
1459 add_definq (p, 0, 0);
1461 else if (!strcmp (cmd, "definqprog"))
1463 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1464 if (tmpline)
1466 add_definq (tmpline, 0, 1);
1467 xfree (tmpline);
1469 else
1470 add_definq (p, 0, 1);
1472 else if (!strcmp (cmd, "datafile"))
1474 const char *fname;
1476 if (current_datasink)
1478 if (current_datasink != stdout)
1479 fclose (current_datasink);
1480 current_datasink = NULL;
1482 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1483 fname = tmpline? tmpline : p;
1484 if (fname && !strcmp (fname, "-"))
1485 current_datasink = stdout;
1486 else if (fname && *fname)
1488 current_datasink = fopen (fname, "wb");
1489 if (!current_datasink)
1490 log_error ("can't open `%s': %s\n",
1491 fname, strerror (errno));
1493 xfree (tmpline);
1495 else if (!strcmp (cmd, "showdef"))
1497 show_definq ();
1499 else if (!strcmp (cmd, "cleardef"))
1501 clear_definq ();
1503 else if (!strcmp (cmd, "echo"))
1505 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1506 if (tmpline)
1508 puts (tmpline);
1509 xfree (tmpline);
1511 else
1512 puts (p);
1514 else if (!strcmp (cmd, "sendfd"))
1516 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1517 if (tmpline)
1519 do_sendfd (ctx, tmpline);
1520 xfree (tmpline);
1522 else
1523 do_sendfd (ctx, p);
1524 continue;
1526 else if (!strcmp (cmd, "recvfd"))
1528 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1529 if (tmpline)
1531 do_recvfd (ctx, tmpline);
1532 xfree (tmpline);
1534 else
1535 do_recvfd (ctx, p);
1536 continue;
1538 else if (!strcmp (cmd, "open"))
1540 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1541 if (tmpline)
1543 do_open (tmpline);
1544 xfree (tmpline);
1546 else
1547 do_open (p);
1549 else if (!strcmp (cmd, "close"))
1551 tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1552 if (tmpline)
1554 do_close (tmpline);
1555 xfree (tmpline);
1557 else
1558 do_close (p);
1560 else if (!strcmp (cmd, "showopen"))
1562 do_showopen ();
1564 else if (!strcmp (cmd, "serverpid"))
1566 do_serverpid (ctx);
1568 else if (!strcmp (cmd, "hex"))
1569 opt.hex = 1;
1570 else if (!strcmp (cmd, "nohex"))
1571 opt.hex = 0;
1572 else if (!strcmp (cmd, "decode"))
1573 opt.decode = 1;
1574 else if (!strcmp (cmd, "nodecode"))
1575 opt.decode = 0;
1576 else if (!strcmp (cmd, "subst"))
1578 opt.enable_varsubst = 1;
1579 opt.trim_leading_spaces = 1;
1581 else if (!strcmp (cmd, "nosubst"))
1582 opt.enable_varsubst = 0;
1583 else if (!strcmp (cmd, "run"))
1585 char *p2;
1587 for (p2=p; *p2 && !spacep (p2); p2++)
1589 if (*p2)
1590 *p2++ = 0;
1591 while (spacep (p2))
1592 p++;
1593 if (*p2)
1595 log_error ("syntax error in run command\n");
1596 if (script_fp)
1598 fclose (script_fp);
1599 script_fp = NULL;
1602 else if (script_fp)
1604 log_error ("cannot nest run commands - stop\n");
1605 fclose (script_fp);
1606 script_fp = NULL;
1608 else if (!(script_fp = fopen (p, "r")))
1610 log_error ("cannot open run file `%s': %s\n",
1611 p, strerror (errno));
1613 else if (opt.verbose)
1614 log_info ("running commands from `%s'\n", p);
1616 else if (!strcmp (cmd, "while"))
1618 if (loopidx+2 >= (int)DIM(loopstack))
1620 log_error ("blocks are nested too deep\n");
1621 /* We should better die or break all loop in this
1622 case as recovering from this error won't be
1623 easy. */
1625 else
1627 loopstack[loopidx+1].head = NULL;
1628 loopstack[loopidx+1].tail = &loopstack[loopidx+1].head;
1629 loopstack[loopidx+1].current = NULL;
1630 loopstack[loopidx+1].nestlevel = 1;
1631 loopstack[loopidx+1].oneshot = 0;
1632 loopstack[loopidx+1].condition = xstrdup (p);
1633 loopstack[loopidx+1].collecting = 1;
1636 else if (!strcmp (cmd, "if"))
1638 if (loopidx+2 >= (int)DIM(loopstack))
1640 log_error ("blocks are nested too deep\n");
1642 else
1644 /* Note that we need to evaluate the condition right
1645 away and not just at the end of the block as we
1646 do with a WHILE. */
1647 loopstack[loopidx+1].head = NULL;
1648 loopstack[loopidx+1].tail = &loopstack[loopidx+1].head;
1649 loopstack[loopidx+1].current = NULL;
1650 loopstack[loopidx+1].nestlevel = 1;
1651 loopstack[loopidx+1].oneshot = 1;
1652 loopstack[loopidx+1].condition = substitute_line_copy (p);
1653 loopstack[loopidx+1].collecting = 1;
1656 else if (!strcmp (cmd, "end"))
1658 if (loopidx < 0)
1659 log_error ("stray /end command encountered - ignored\n");
1660 else
1662 char *tmpcond;
1663 const char *value;
1664 long condition;
1666 /* Evaluate the condition. */
1667 tmpcond = xstrdup (loopstack[loopidx].condition);
1668 if (loopstack[loopidx].oneshot)
1670 xfree (loopstack[loopidx].condition);
1671 loopstack[loopidx].condition = xstrdup ("0");
1673 tmpline = substitute_line (tmpcond);
1674 value = tmpline? tmpline : tmpcond;
1675 condition = strtol (value, NULL, 0);
1676 xfree (tmpline);
1677 xfree (tmpcond);
1679 if (condition)
1681 /* Run loop. */
1682 loopstack[loopidx].current = loopstack[loopidx].head;
1684 else
1686 /* Cleanup. */
1687 while (loopstack[loopidx].head)
1689 loopline_t tmp = loopstack[loopidx].head->next;
1690 xfree (loopstack[loopidx].head);
1691 loopstack[loopidx].head = tmp;
1693 loopstack[loopidx].tail = NULL;
1694 loopstack[loopidx].current = NULL;
1695 loopstack[loopidx].nestlevel = 0;
1696 loopstack[loopidx].collecting = 0;
1697 loopstack[loopidx].oneshot = 0;
1698 xfree (loopstack[loopidx].condition);
1699 loopstack[loopidx].condition = NULL;
1700 loopidx--;
1704 else if (!strcmp (cmd, "bye"))
1706 break;
1708 else if (!strcmp (cmd, "sleep"))
1710 gnupg_sleep (1);
1712 else if (!strcmp (cmd, "help"))
1714 puts (
1715 "Available commands:\n"
1716 "/echo ARGS Echo ARGS.\n"
1717 "/let NAME VALUE Set variable NAME to VALUE.\n"
1718 "/showvar Show all variables.\n"
1719 "/definq NAME VAR Use content of VAR for inquiries with NAME.\n"
1720 "/definqfile NAME FILE Use content of FILE for inquiries with NAME.\n"
1721 "/definqprog NAME PGM Run PGM for inquiries with NAME.\n"
1722 "/datafile [NAME] Write all D line content to file NAME.\n"
1723 "/showdef Print all definitions.\n"
1724 "/cleardef Delete all definitions.\n"
1725 "/sendfd FILE MODE Open FILE and pass descriptor to server.\n"
1726 "/recvfd Receive FD from server and print.\n"
1727 "/open VAR FILE MODE Open FILE and assign the file descriptor to VAR.\n"
1728 "/close FD Close file with descriptor FD.\n"
1729 "/showopen Show descriptors of all open files.\n"
1730 "/serverpid Retrieve the pid of the server.\n"
1731 "/[no]hex Enable hex dumping of received data lines.\n"
1732 "/[no]decode Enable decoding of received data lines.\n"
1733 "/[no]subst Enable variable substitution.\n"
1734 "/run FILE Run commands from FILE.\n"
1735 "/if VAR Begin conditional block controlled by VAR.\n"
1736 "/while VAR Begin loop controlled by VAR.\n"
1737 "/end End loop or condition\n"
1738 "/bye Terminate gpg-connect-agent.\n"
1739 "/help Print this help.");
1741 else
1742 log_error (_("unknown command `%s'\n"), cmd );
1744 continue;
1747 if (opt.verbose && script_fp)
1748 puts (line);
1750 tmpline = opt.enable_varsubst? substitute_line (line) : NULL;
1751 if (tmpline)
1753 rc = assuan_write_line (ctx, tmpline);
1754 xfree (tmpline);
1756 else
1757 rc = assuan_write_line (ctx, line);
1758 if (rc)
1760 log_info (_("sending line failed: %s\n"), gpg_strerror (rc) );
1761 break;
1763 if (*line == '#' || !*line)
1764 continue; /* Don't expect a response for a comment line. */
1766 rc = read_and_print_response (ctx, (!ascii_strncasecmp (line, "HELP", 4)
1767 && (spacep (line+4) || !line[4])),
1768 &cmderr);
1769 if (rc)
1770 log_info (_("receiving line failed: %s\n"), gpg_strerror (rc) );
1771 if ((rc || cmderr) && script_fp)
1773 log_error ("stopping script execution\n");
1774 fclose (script_fp);
1775 script_fp = NULL;
1779 /* FIXME: If the last command was BYE or the server died for
1780 some other reason, we won't notice until we get the next
1781 input command. Probing the connection with a non-blocking
1782 read could help to notice termination or other problems
1783 early. */
1786 if (opt.verbose)
1787 log_info ("closing connection to agent\n");
1789 return 0;
1793 /* Handle an Inquire from the server. Return False if it could not be
1794 handled; in this case the caller shll complete the operation. LINE
1795 is the complete line as received from the server. This function
1796 may change the content of LINE. */
1797 static int
1798 handle_inquire (assuan_context_t ctx, char *line)
1800 const char *name;
1801 definq_t d;
1802 FILE *fp = NULL;
1803 char buffer[1024];
1804 int rc, n;
1806 /* Skip the command and trailing spaces. */
1807 for (; *line && !spacep (line); line++)
1809 while (spacep (line))
1810 line++;
1811 /* Get the name. */
1812 name = line;
1813 for (; *line && !spacep (line); line++)
1815 if (*line)
1816 *line++ = 0;
1818 /* Now match it against our list. The second loop is there to
1819 detect the match-all entry. */
1820 for (d=definq_list; d; d = d->next)
1821 if (d->name && !strcmp (d->name, name))
1822 break;
1823 if (!d)
1824 for (d=definq_list; d; d = d->next)
1825 if (!d->name)
1826 break;
1827 if (!d)
1829 if (opt.verbose)
1830 log_info ("no handler for inquiry `%s' found\n", name);
1831 return 0;
1834 if (d->is_var)
1836 char *tmpvalue = get_var_ext (d->file);
1837 rc = assuan_send_data (ctx, tmpvalue, strlen (tmpvalue));
1838 xfree (tmpvalue);
1839 if (rc)
1840 log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
1842 else
1844 if (d->is_prog)
1846 fp = popen (d->file, "r");
1847 if (!fp)
1848 log_error ("error executing `%s': %s\n",
1849 d->file, strerror (errno));
1850 else if (opt.verbose)
1851 log_error ("handling inquiry `%s' by running `%s'\n",
1852 name, d->file);
1854 else
1856 fp = fopen (d->file, "rb");
1857 if (!fp)
1858 log_error ("error opening `%s': %s\n", d->file, strerror (errno));
1859 else if (opt.verbose)
1860 log_error ("handling inquiry `%s' by returning content of `%s'\n",
1861 name, d->file);
1863 if (!fp)
1864 return 0;
1866 while ( (n = fread (buffer, 1, sizeof buffer, fp)) )
1868 rc = assuan_send_data (ctx, buffer, n);
1869 if (rc)
1871 log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
1872 break;
1875 if (ferror (fp))
1876 log_error ("error reading from `%s': %s\n", d->file, strerror (errno));
1879 rc = assuan_send_data (ctx, NULL, 0);
1880 if (rc)
1881 log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
1883 if (d->is_var)
1885 else if (d->is_prog)
1887 if (pclose (fp))
1888 log_error ("error running `%s': %s\n", d->file, strerror (errno));
1890 else
1891 fclose (fp);
1892 return 1;
1896 /* Read all response lines from server and print them. Returns 0 on
1897 success or an assuan error code. If WITHHASH istrue, comment lines
1898 are printed. Sets R_GOTERR to true if the command did not returned
1899 OK. */
1900 static int
1901 read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr)
1903 char *line;
1904 size_t linelen;
1905 gpg_error_t rc;
1906 int i, j;
1907 int need_lf = 0;
1909 *r_goterr = 0;
1910 for (;;)
1914 rc = assuan_read_line (ctx, &line, &linelen);
1915 if (rc)
1916 return rc;
1918 if ((withhash || opt.verbose > 1) && *line == '#')
1920 fwrite (line, linelen, 1, stdout);
1921 putchar ('\n');
1924 while (*line == '#' || !linelen);
1926 if (linelen >= 1
1927 && line[0] == 'D' && line[1] == ' ')
1929 if (current_datasink)
1931 const unsigned char *s;
1932 int c = 0;
1934 for (j=2, s=(unsigned char*)line+2; j < linelen; j++, s++ )
1936 if (*s == '%' && j+2 < linelen)
1938 s++; j++;
1939 c = xtoi_2 ( s );
1940 s++; j++;
1942 else
1943 c = *s;
1944 putc (c, current_datasink);
1947 else if (opt.hex)
1949 for (i=2; i < linelen; )
1951 int save_i = i;
1953 printf ("D[%04X] ", i-2);
1954 for (j=0; j < 16 ; j++, i++)
1956 if (j == 8)
1957 putchar (' ');
1958 if (i < linelen)
1959 printf (" %02X", ((unsigned char*)line)[i]);
1960 else
1961 fputs (" ", stdout);
1963 fputs (" ", stdout);
1964 i= save_i;
1965 for (j=0; j < 16; j++, i++)
1967 unsigned int c = ((unsigned char*)line)[i];
1968 if ( i >= linelen )
1969 putchar (' ');
1970 else if (isascii (c) && isprint (c) && !iscntrl (c))
1971 putchar (c);
1972 else
1973 putchar ('.');
1975 putchar ('\n');
1978 else if (opt.decode)
1980 const unsigned char *s;
1981 int need_d = 1;
1982 int c = 0;
1984 for (j=2, s=(unsigned char*)line+2; j < linelen; j++, s++ )
1986 if (need_d)
1988 fputs ("D ", stdout);
1989 need_d = 0;
1991 if (*s == '%' && j+2 < linelen)
1993 s++; j++;
1994 c = xtoi_2 ( s );
1995 s++; j++;
1997 else
1998 c = *s;
1999 if (c == '\n')
2000 need_d = 1;
2001 putchar (c);
2003 need_lf = (c != '\n');
2005 else
2007 fwrite (line, linelen, 1, stdout);
2008 putchar ('\n');
2011 else
2013 if (need_lf)
2015 if (!current_datasink || current_datasink != stdout)
2016 putchar ('\n');
2017 need_lf = 0;
2020 if (linelen >= 1
2021 && line[0] == 'S'
2022 && (line[1] == '\0' || line[1] == ' '))
2024 if (!current_datasink || current_datasink != stdout)
2026 fwrite (line, linelen, 1, stdout);
2027 putchar ('\n');
2030 else if (linelen >= 2
2031 && line[0] == 'O' && line[1] == 'K'
2032 && (line[2] == '\0' || line[2] == ' '))
2034 if (!current_datasink || current_datasink != stdout)
2036 fwrite (line, linelen, 1, stdout);
2037 putchar ('\n');
2039 set_int_var ("?", 0);
2040 return 0;
2042 else if (linelen >= 3
2043 && line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
2044 && (line[3] == '\0' || line[3] == ' '))
2046 int errval;
2048 errval = strtol (line+3, NULL, 10);
2049 if (!errval)
2050 errval = -1;
2051 set_int_var ("?", errval);
2052 if (!current_datasink || current_datasink != stdout)
2054 fwrite (line, linelen, 1, stdout);
2055 putchar ('\n');
2057 *r_goterr = 1;
2058 return 0;
2060 else if (linelen >= 7
2061 && line[0] == 'I' && line[1] == 'N' && line[2] == 'Q'
2062 && line[3] == 'U' && line[4] == 'I' && line[5] == 'R'
2063 && line[6] == 'E'
2064 && (line[7] == '\0' || line[7] == ' '))
2066 if (!current_datasink || current_datasink != stdout)
2068 fwrite (line, linelen, 1, stdout);
2069 putchar ('\n');
2071 if (!handle_inquire (ctx, line))
2072 assuan_write_line (ctx, "CANCEL");
2074 else if (linelen >= 3
2075 && line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
2076 && (line[3] == '\0' || line[3] == ' '))
2078 if (!current_datasink || current_datasink != stdout)
2080 fwrite (line, linelen, 1, stdout);
2081 putchar ('\n');
2083 /* Received from server, thus more responses are expected. */
2085 else
2086 return gpg_error (GPG_ERR_ASS_INV_RESPONSE);
2094 /* Connect to the agent and send the standard options. */
2095 static assuan_context_t
2096 start_agent (void)
2098 int rc = 0;
2099 char *infostr, *p;
2100 assuan_context_t ctx;
2101 session_env_t session_env;
2103 infostr = getenv ("GPG_AGENT_INFO");
2104 if (!infostr || !*infostr)
2106 char *sockname;
2108 rc = assuan_new (&ctx);
2109 if (rc)
2111 log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
2112 exit (1);
2115 /* Check whether we can connect at the standard socket. */
2116 sockname = make_filename (opt.homedir, "S.gpg-agent", NULL);
2117 rc = assuan_socket_connect (ctx, sockname, 0);
2119 #ifdef HAVE_W32_SYSTEM
2120 /* If we failed to connect under Windows, we fire up the agent. */
2121 if (gpg_err_code (rc) == GPG_ERR_ASS_CONNECT_FAILED)
2123 const char *agent_program;
2124 const char *argv[3];
2125 int save_rc = rc;
2127 if (opt.verbose)
2128 log_info (_("no running gpg-agent - starting one\n"));
2129 agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT);
2131 argv[0] = "--daemon";
2132 argv[1] = "--use-standard-socket";
2133 argv[2] = NULL;
2135 rc = gnupg_spawn_process_detached (agent_program, argv, NULL);
2136 if (rc)
2137 log_debug ("failed to start agent `%s': %s\n",
2138 agent_program, gpg_strerror (rc));
2139 else
2141 /* Give the agent some time to prepare itself. */
2142 gnupg_sleep (3);
2143 /* Now try again to connect the agent. */
2144 rc = assuan_new (&ctx);
2145 if (rc)
2147 log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
2148 exit (1);
2151 rc = assuan_socket_connect (ctx, sockname, 0);
2153 if (rc)
2154 rc = save_rc;
2156 #endif /*HAVE_W32_SYSTEM*/
2157 xfree (sockname);
2159 else
2161 int prot;
2162 int pid;
2164 infostr = xstrdup (infostr);
2165 if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr)
2167 log_error (_("malformed GPG_AGENT_INFO environment variable\n"));
2168 xfree (infostr);
2169 exit (1);
2171 *p++ = 0;
2172 pid = atoi (p);
2173 while (*p && *p != PATHSEP_C)
2174 p++;
2175 prot = *p? atoi (p+1) : 0;
2176 if (prot != 1)
2178 log_error (_("gpg-agent protocol version %d is not supported\n"),
2179 prot);
2180 xfree (infostr);
2181 exit (1);
2184 rc = assuan_new (&ctx);
2185 if (rc)
2187 log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
2188 exit (1);
2191 rc = assuan_socket_connect (ctx, infostr, pid);
2192 xfree (infostr);
2195 if (rc)
2197 log_error ("can't connect to the agent: %s\n", gpg_strerror (rc));
2198 exit (1);
2201 if (opt.verbose)
2202 log_info ("connection to agent established\n");
2204 rc = assuan_transact (ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL);
2205 if (rc)
2207 log_error (_("error sending %s command: %s\n"), "RESET",
2208 gpg_strerror (rc));
2209 exit (1);
2212 session_env = session_env_new ();
2213 if (!session_env)
2214 log_fatal ("error allocating session environment block: %s\n",
2215 strerror (errno));
2217 rc = send_pinentry_environment (ctx, GPG_ERR_SOURCE_DEFAULT,
2218 NULL, NULL, session_env);
2219 session_env_release (session_env);
2220 if (rc)
2222 log_error (_("error sending standard options: %s\n"), gpg_strerror (rc));
2223 exit (1);
2226 return ctx;