card: Implement the bulk of OpenPGP stuff into gpg-card-tool.
[gnupg.git] / tools / gpg-connect-agent.c
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
4  *
5  * This file is part of GnuPG.
6  *
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.
11  *
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.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see <https://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <ctype.h>
28 #include <assuan.h>
29 #include <unistd.h>
30 #include <assert.h>
31
32 #include "../common/i18n.h"
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"
40 #endif
41 #include "../common/init.h"
42
43
44 #define CONTROL_D ('D' - 'A' + 1)
45 #define octdigitp(p) (*(p) >= '0' && *(p) <= '7')
46
47 /* Constants to identify the commands and options. */
48 enum cmd_and_opt_values
49   {
50     aNull = 0,
51     oQuiet      = 'q',
52     oVerbose    = 'v',
53     oRawSocket  = 'S',
54     oTcpSocket  = 'T',
55     oExec       = 'E',
56     oRun        = 'r',
57     oSubst      = 's',
58
59     oNoVerbose  = 500,
60     oHomedir,
61     oAgentProgram,
62     oDirmngrProgram,
63     oHex,
64     oDecode,
65     oNoExtConnect,
66     oDirmngr,
67     oUIServer,
68     oNoAutostart,
69
70   };
71
72
73 /* The list of commands and options. */
74 static ARGPARSE_OPTS opts[] = {
75   ARGPARSE_group (301, N_("@\nOptions:\n ")),
76
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")),
94
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", "@"),
100
101   ARGPARSE_end ()
102 };
103
104
105 /* We keep all global options in the structure OPT.  */
106 struct
107 {
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;
124 } opt;
125
126
127
128 /* Definitions for /definq commands and a global linked list with all
129    the definitions. */
130 struct definq_s
131 {
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. */
137 };
138 typedef struct definq_s *definq_t;
139
140 static definq_t definq_list;
141 static definq_t *definq_list_tail = &definq_list;
142
143
144 /* Variable definitions and glovbal table.  */
145 struct variable_s
146 {
147   struct variable_s *next;
148   char *value;  /* Malloced value - always a string.  */
149   char name[1]; /* Name of the variable.  */
150 };
151 typedef struct variable_s *variable_t;
152
153 static variable_t variable_table;
154
155
156 /* To implement loops we store entire lines in a linked list.  */
157 struct loopline_s
158 {
159   struct loopline_s *next;
160   char line[1];
161 };
162 typedef struct loopline_s *loopline_t;
163
164
165 /* This is used to store the pid of the server.  */
166 static pid_t server_pid = (pid_t)(-1);
167
168 /* The current datasink file or NULL.  */
169 static FILE *current_datasink;
170
171 /* A list of open file descriptors. */
172 static struct
173 {
174   int inuse;
175 #ifdef HAVE_W32_SYSTEM
176   HANDLE handle;
177 #endif
178 } open_fd_table[256];
179
180
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,
184                                     int *r_goterr);
185 static assuan_context_t start_agent (void);
186
187
188
189 \f
190 /* Print usage information and provide strings for help. */
191 static const char *
192 my_strusage( int level )
193 {
194   const char *p;
195
196   switch (level)
197     {
198     case 11: p = "@GPG@-connect-agent (@GNUPG@)";
199       break;
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;
203
204     case 1:
205     case 40: p = _("Usage: @GPG@-connect-agent [options] (-h for help)");
206       break;
207     case 41:
208       p = _("Syntax: @GPG@-connect-agent [options]\n"
209             "Connect to a running agent and send commands\n");
210       break;
211     case 31: p = "\nHome: "; break;
212     case 32: p = gnupg_homedir (); break;
213     case 33: p = "\n"; break;
214
215     default: p = NULL; break;
216     }
217   return p;
218 }
219
220
221 /* Unescape STRING and returned the malloced result.  The surrounding
222    quotes must already be removed from STRING.  */
223 static char *
224 unescape_string (const char *string)
225 {
226   const unsigned char *s;
227   int esc;
228   size_t n;
229   char *buffer;
230   unsigned char *d;
231
232   n = 0;
233   for (s = (const unsigned char*)string, esc=0; *s; s++)
234     {
235       if (esc)
236         {
237           switch (*s)
238             {
239             case 'b':
240             case 't':
241             case 'v':
242             case 'n':
243             case 'f':
244             case 'r':
245             case '"':
246             case '\'':
247             case '\\': n++; break;
248             case 'x':
249               if (s[1] && s[2] && hexdigitp (s+1) && hexdigitp (s+2))
250                 n++;
251               break;
252
253             default:
254               if (s[1] && s[2]
255                   && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
256                 n++;
257               break;
258             }
259           esc = 0;
260         }
261       else if (*s == '\\')
262         esc = 1;
263       else
264         n++;
265     }
266
267   buffer = xmalloc (n+1);
268   d = (unsigned char*)buffer;
269   for (s = (const unsigned char*)string, esc=0; *s; s++)
270     {
271       if (esc)
272         {
273           switch (*s)
274             {
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;
284             case 'x':
285               if (s[1] && s[2] && hexdigitp (s+1) && hexdigitp (s+2))
286                 {
287                   s++;
288                   *d++ = xtoi_2 (s);
289                   s++;
290                 }
291               break;
292
293             default:
294               if (s[1] && s[2]
295                   && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
296                 {
297                   *d++ = (atoi_1 (s)*64) + (atoi_1 (s+1)*8) + atoi_1 (s+2);
298                   s += 2;
299                 }
300               break;
301             }
302           esc = 0;
303         }
304       else if (*s == '\\')
305         esc = 1;
306       else
307         *d++ = *s;
308     }
309   *d = 0;
310   return buffer;
311 }
312
313
314 /* Do the percent unescaping and return a newly malloced string.
315    If WITH_PLUS is set '+' characters will be changed to space. */
316 static char *
317 unpercent_string (const char *string, int with_plus)
318 {
319   const unsigned char *s;
320   unsigned char *buffer, *p;
321   size_t n;
322
323   n = 0;
324   for (s=(const unsigned char *)string; *s; s++)
325     {
326       if (*s == '%' && s[1] && s[2])
327         {
328           s++;
329           n++;
330           s++;
331         }
332       else if (with_plus && *s == '+')
333         n++;
334       else
335         n++;
336     }
337
338   buffer = xmalloc (n+1);
339   p = buffer;
340   for (s=(const unsigned char *)string; *s; s++)
341     {
342       if (*s == '%' && s[1] && s[2])
343         {
344           s++;
345           *p++ = xtoi_2 (s);
346           s++;
347         }
348       else if (with_plus && *s == '+')
349         *p++ = ' ';
350       else
351         *p++ = *s;
352     }
353   *p = 0;
354   return (char*)buffer;
355 }
356
357
358
359
360 \f
361 static const char *
362 set_var (const char *name, const char *value)
363 {
364   variable_t var;
365
366   for (var = variable_table; var; var = var->next)
367     if (!strcmp (var->name, name))
368       break;
369   if (!var)
370     {
371       var = xmalloc (sizeof *var + strlen (name));
372       var->value = NULL;
373       strcpy (var->name, name);
374       var->next = variable_table;
375       variable_table = var;
376     }
377   xfree (var->value);
378   var->value = value? xstrdup (value) : NULL;
379   return var->value;
380 }
381
382
383 static void
384 set_int_var (const char *name, int value)
385 {
386   char numbuf[35];
387
388   snprintf (numbuf, sizeof numbuf, "%d", value);
389   set_var (name, numbuf);
390 }
391
392
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.  */
397 static const char *
398 get_var (const char *name)
399 {
400   variable_t var;
401   const char *s;
402
403   if (!*name)
404     return "";
405   for (var = variable_table; var; var = var->next)
406     if (!strcmp (var->name, name))
407       break;
408   if (!var && (s = getenv (name)))
409     return set_var (name, s);
410   if (!var || !var->value)
411     return NULL;
412   return var->value;
413 }
414
415
416 /* Perform some simple arithmetic operations.  Caller must release
417    the return value.  On error the return value is NULL.  */
418 static char *
419 arithmetic_op (int operator, const char *operands)
420 {
421   long result, value;
422   char numbuf[35];
423
424   while ( spacep (operands) )
425     operands++;
426   if (!*operands)
427     return NULL;
428   result = strtol (operands, NULL, 0);
429   while (*operands && !spacep (operands) )
430     operands++;
431   if (operator == '!')
432     result = !result;
433
434   while (*operands)
435     {
436       while ( spacep (operands) )
437         operands++;
438       if (!*operands)
439         break;
440       value = strtol (operands, NULL, 0);
441       while (*operands && !spacep (operands) )
442         operands++;
443       switch (operator)
444         {
445         case '+': result += value; break;
446         case '-': result -= value; break;
447         case '*': result *= value; break;
448         case '/':
449           if (!value)
450             return NULL;
451           result /= value;
452           break;
453         case '%':
454           if (!value)
455             return NULL;
456           result %= value;
457           break;
458         case '!': result = !value; break;
459         case '|': result = result || value; break;
460         case '&': result = result && value; break;
461         default:
462           log_error ("unknown arithmetic operator '%c'\n", operator);
463           return NULL;
464         }
465     }
466   snprintf (numbuf, sizeof numbuf, "%ld", result);
467   return xstrdup (numbuf);
468 }
469
470
471
472 /* Extended version of get_var.  This returns a malloced string and
473    understand the function syntax: "func args".
474
475    Defined functions are
476
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.
486
487      unescape ARGS
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.
492
493      unpercent ARGS
494      unpercent+ ARGS
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 '+'
499            to space.
500
501      percent ARGS
502      percent+ ARGS
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.
506
507      errcode ARG
508            Assuming ARG is an integer, return the gpg-error code.
509
510      errsource ARG
511            Assuming ARG is an integer, return the gpg-error source.
512
513      errstring ARG
514            Assuming ARG is an integer return a formatted fpf error string.
515
516
517    Example: get_var_ext ("get sysconfdir") -> "/etc/gnupg"
518
519   */
520 static char *
521 get_var_ext (const char *name)
522 {
523   static int recursion_count;
524   const char *s;
525   char *result;
526   char *p;
527   char *free_me = NULL;
528   int intvalue;
529
530   if (recursion_count > 50)
531     {
532       log_error ("variables nested too deeply\n");
533       return NULL;
534     }
535
536   recursion_count++;
537   free_me = opt.enable_varsubst? substitute_line_copy (name) : NULL;
538   if (free_me)
539     name = free_me;
540   for (s=name; *s && !spacep (s); s++)
541     ;
542   if (!*s)
543     {
544       s = get_var (name);
545       result = s? xstrdup (s): NULL;
546     }
547   else if ( (s - name) == 3 && !strncmp (name, "get", 3))
548     {
549       while ( spacep (s) )
550         s++;
551       if (!strcmp (s, "cwd"))
552         {
553           result = gnupg_getcwd ();
554           if (!result)
555             log_error ("getcwd failed: %s\n", strerror (errno));
556         }
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);
571       else
572         {
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");
576           result = NULL;
577         }
578     }
579   else if ( (s - name) == 8 && !strncmp (name, "unescape", 8))
580     {
581       s++;
582       result = unescape_string (s);
583     }
584   else if ( (s - name) == 9 && !strncmp (name, "unpercent", 9))
585     {
586       s++;
587       result = unpercent_string (s, 0);
588     }
589   else if ( (s - name) == 10 && !strncmp (name, "unpercent+", 10))
590     {
591       s++;
592       result = unpercent_string (s, 1);
593     }
594   else if ( (s - name) == 7 && !strncmp (name, "percent", 7))
595     {
596       s++;
597       result = percent_escape (s, "+\t\r\n\f\v");
598     }
599   else if ( (s - name) == 8 && !strncmp (name, "percent+", 8))
600     {
601       s++;
602       result = percent_escape (s, "+\t\r\n\f\v");
603       for (p=result; *p; p++)
604         if (*p == ' ')
605           *p = '+';
606     }
607   else if ( (s - name) == 7 && !strncmp (name, "errcode", 7))
608     {
609       s++;
610       intvalue = (int)strtol (s, NULL, 0);
611       result = xasprintf ("%d", gpg_err_code (intvalue));
612     }
613   else if ( (s - name) == 9 && !strncmp (name, "errsource", 9))
614     {
615       s++;
616       intvalue = (int)strtol (s, NULL, 0);
617       result = xasprintf ("%d", gpg_err_source (intvalue));
618     }
619   else if ( (s - name) == 9 && !strncmp (name, "errstring", 9))
620     {
621       s++;
622       intvalue = (int)strtol (s, NULL, 0);
623       result = xasprintf ("%s <%s>",
624                           gpg_strerror (intvalue), gpg_strsource (intvalue));
625     }
626   else if ( (s - name) == 1 && strchr ("+-*/%!|&", *name))
627     {
628       result = arithmetic_op (*name, s+1);
629     }
630   else
631     {
632       log_error ("unknown variable function '%.*s'\n", (int)(s-name), name);
633       result = NULL;
634     }
635
636   xfree (free_me);
637   recursion_count--;
638   return result;
639 }
640
641
642 /* Substitute variables in LINE and return a new allocated buffer if
643    required.  The function might modify LINE if the expanded version
644    fits into it.  */
645 static char *
646 substitute_line (char *buffer)
647 {
648   char *line = buffer;
649   char *p, *pend;
650   const char *value;
651   size_t valuelen, n;
652   char *result = NULL;
653   char *freeme = NULL;
654
655   while (*line)
656     {
657       p = strchr (line, '$');
658       if (!p)
659         return result; /* No more variables.  */
660
661       if (p[1] == '$') /* Escaped dollar sign. */
662         {
663           memmove (p, p+1, strlen (p+1)+1);
664           line = p + 1;
665           continue;
666         }
667       if (p[1] == '{')
668         {
669           int count = 0;
670
671           for (pend=p+2; *pend; pend++)
672             {
673               if (*pend == '{')
674                 count++;
675               else if (*pend == '}')
676                 {
677                   if (--count < 0)
678                     break;
679                 }
680             }
681           if (!*pend)
682             return result; /* Unclosed - don't substitute.  */
683         }
684       else
685         {
686           for (pend=p+1; *pend && !spacep (pend) && *pend != '$' ; pend++)
687             ;
688         }
689       if (p[1] == '{' && *pend == '}')
690         {
691           int save = *pend;
692           *pend = 0;
693           freeme = get_var_ext (p+2);
694           value = freeme;
695           *pend++ = save;
696         }
697       else if (*pend)
698         {
699           int save = *pend;
700           *pend = 0;
701           value = get_var (p+1);
702           *pend = save;
703         }
704       else
705         value = get_var (p+1);
706       if (!value)
707         value = "";
708       valuelen = strlen (value);
709       if (valuelen <= pend - p)
710         {
711           memcpy (p, value, valuelen);
712           p += valuelen;
713           n = pend - p;
714           if (n)
715             memmove (p, p+n, strlen (p+n)+1);
716           line = p;
717         }
718       else
719         {
720           char *src = result? result : buffer;
721           char *dst;
722
723           dst = xmalloc (strlen (src) + valuelen + 1);
724           n = p - src;
725           memcpy (dst, src, n);
726           memcpy (dst + n, value, valuelen);
727           n += valuelen;
728           strcpy (dst + n, pend);
729           line = dst + n;
730           xfree (result);
731           result = dst;
732         }
733       xfree (freeme);
734       freeme = NULL;
735     }
736   return result;
737 }
738
739 /* Same as substitute_line but do not modify BUFFER.  */
740 static char *
741 substitute_line_copy (const char *buffer)
742 {
743   char *result, *p;
744
745   p = xstrdup (buffer?buffer:"");
746   result = substitute_line (p);
747   if (!result)
748     result = p;
749   else
750     xfree (p);
751   return result;
752 }
753
754
755 static void
756 assign_variable (char *line, int syslet)
757 {
758   char *name, *p, *tmp, *free_me, *buffer;
759
760   /* Get the  name. */
761   name = line;
762   for (p=name; *p && !spacep (p); p++)
763     ;
764   if (*p)
765     *p++ = 0;
766   while (spacep (p))
767     p++;
768
769   if (!*p)
770     set_var (name, NULL); /* Remove variable.  */
771   else if (syslet)
772     {
773       free_me = opt.enable_varsubst? substitute_line_copy (p) : NULL;
774       if (free_me)
775         p = free_me;
776       buffer = xmalloc (4 + strlen (p) + 1);
777       strcpy (stpcpy (buffer, "get "), p);
778       tmp = get_var_ext (buffer);
779       xfree (buffer);
780       set_var (name, tmp);
781       xfree (tmp);
782       xfree (free_me);
783     }
784   else
785     {
786       tmp = opt.enable_varsubst? substitute_line_copy (p) : NULL;
787       if (tmp)
788         {
789           set_var (name, tmp);
790           xfree (tmp);
791         }
792       else
793         set_var (name, p);
794     }
795 }
796
797
798 static void
799 show_variables (void)
800 {
801   variable_t var;
802
803   for (var = variable_table; var; var = var->next)
804     if (var->value)
805       printf ("%-20s %s\n", var->name, var->value);
806 }
807
808
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. */
812 static void
813 add_definq (char *line, int is_var, int is_prog)
814 {
815   definq_t d;
816   char *name, *p;
817
818   /* Get name. */
819   name = line;
820   for (p=name; *p && !spacep (p); p++)
821     ;
822   if (*p)
823     *p++ = 0;
824   while (spacep (p))
825     p++;
826
827   d = xmalloc (sizeof *d + strlen (p) );
828   strcpy (d->file, p);
829   d->is_var  = is_var;
830   d->is_prog = is_prog;
831   if ( !strcmp (name, "*"))
832     d->name = NULL;
833   else
834     d->name = xstrdup (name);
835
836   d->next = NULL;
837   *definq_list_tail = d;
838   definq_list_tail = &d->next;
839 }
840
841
842 /* Show all inquiry definitions. */
843 static void
844 show_definq (void)
845 {
846   definq_t d;
847
848   for (d=definq_list; d; d = d->next)
849     if (d->name)
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)
853     if (!d->name)
854       printf ("%-20s %c %s\n", "*",
855               d->is_var? 'v': d->is_prog? 'p':'f', d->file);
856 }
857
858
859 /* Clear all inquiry definitions. */
860 static void
861 clear_definq (void)
862 {
863   while (definq_list)
864     {
865       definq_t tmp = definq_list->next;
866       xfree (definq_list->name);
867       xfree (definq_list);
868       definq_list = tmp;
869     }
870   definq_list_tail = &definq_list;
871 }
872
873
874 static void
875 do_sendfd (assuan_context_t ctx, char *line)
876 {
877   FILE *fp;
878   char *name, *mode, *p;
879   int rc, fd;
880
881   /* Get file name. */
882   name = line;
883   for (p=name; *p && !spacep (p); p++)
884     ;
885   if (*p)
886     *p++ = 0;
887   while (spacep (p))
888     p++;
889
890   /* Get mode.  */
891   mode = p;
892   if (!*mode)
893     mode = "r";
894   else
895     {
896       for (p=mode; *p && !spacep (p); p++)
897         ;
898       if (*p)
899         *p++ = 0;
900     }
901
902   /* Open and send. */
903   fp = fopen (name, mode);
904   if (!fp)
905     {
906       log_error ("can't open '%s' in \"%s\" mode: %s\n",
907                  name, mode, strerror (errno));
908       return;
909     }
910   fd = fileno (fp);
911
912   if (opt.verbose)
913     log_error ("file '%s' opened in \"%s\" mode, fd=%d\n",
914                name, mode, fd);
915
916   rc = assuan_sendfd (ctx, INT2FD (fd) );
917   if (rc)
918     log_error ("sending descriptor %d failed: %s\n", fd, gpg_strerror (rc));
919   fclose (fp);
920 }
921
922
923 static void
924 do_recvfd (assuan_context_t ctx, char *line)
925 {
926   (void)ctx;
927   (void)line;
928   log_info ("This command has not yet been implemented\n");
929 }
930
931
932 static void
933 do_open (char *line)
934 {
935   FILE *fp;
936   char *varname, *name, *mode, *p;
937   int fd;
938
939 #ifdef HAVE_W32_SYSTEM
940   if (server_pid == (pid_t)(-1))
941     {
942       log_error ("the pid of the server is unknown\n");
943       log_info ("use command \"/serverpid\" first\n");
944       return;
945     }
946 #endif
947
948   /* Get variable name. */
949   varname = line;
950   for (p=varname; *p && !spacep (p); p++)
951     ;
952   if (*p)
953     *p++ = 0;
954   while (spacep (p))
955     p++;
956
957   /* Get file name. */
958   name = p;
959   for (p=name; *p && !spacep (p); p++)
960     ;
961   if (*p)
962     *p++ = 0;
963   while (spacep (p))
964     p++;
965
966   /* Get mode.  */
967   mode = p;
968   if (!*mode)
969     mode = "r";
970   else
971     {
972       for (p=mode; *p && !spacep (p); p++)
973         ;
974       if (*p)
975         *p++ = 0;
976     }
977
978   /* Open and send. */
979   fp = fopen (name, mode);
980   if (!fp)
981     {
982       log_error ("can't open '%s' in \"%s\" mode: %s\n",
983                  name, mode, strerror (errno));
984       return;
985     }
986   fd = dup (fileno (fp));
987   if (fd >= 0 && fd < DIM (open_fd_table))
988     {
989       open_fd_table[fd].inuse = 1;
990 #ifdef HAVE_W32CE_SYSTEM
991 # warning fixme: implement our pipe emulation.
992 #endif
993 #if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM)
994       {
995         HANDLE prochandle, handle, newhandle;
996
997         handle = (void*)_get_osfhandle (fd);
998
999         prochandle = OpenProcess (PROCESS_DUP_HANDLE, FALSE, server_pid);
1000         if (!prochandle)
1001           {
1002             log_error ("failed to open the server process\n");
1003             close (fd);
1004             return;
1005           }
1006
1007         if (!DuplicateHandle (GetCurrentProcess(), handle,
1008                               prochandle, &newhandle, 0,
1009                               TRUE, DUPLICATE_SAME_ACCESS ))
1010           {
1011             log_error ("failed to duplicate the handle\n");
1012             close (fd);
1013             CloseHandle (prochandle);
1014             return;
1015           }
1016         CloseHandle (prochandle);
1017         open_fd_table[fd].handle = newhandle;
1018       }
1019       if (opt.verbose)
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);
1023 #else
1024       if (opt.verbose)
1025         log_info ("file '%s' opened in \"%s\" mode, fd=%d\n",
1026                    name, mode, fd);
1027       set_int_var (varname, fd);
1028 #endif
1029     }
1030   else
1031     {
1032       log_error ("can't put fd %d into table\n", fd);
1033       if (fd != -1)
1034         close (fd); /* Table was full.  */
1035     }
1036   fclose (fp);
1037 }
1038
1039
1040 static void
1041 do_close (char *line)
1042 {
1043   int fd = atoi (line);
1044
1045 #ifdef HAVE_W32_SYSTEM
1046   int i;
1047
1048   for (i=0; i < DIM (open_fd_table); i++)
1049     if ( open_fd_table[i].inuse && open_fd_table[i].handle == (void*)fd)
1050       break;
1051   if (i < DIM (open_fd_table))
1052     fd = i;
1053   else
1054     {
1055       log_error ("given fd (system handle) has not been opened\n");
1056       return;
1057     }
1058 #endif
1059
1060   if (fd < 0 || fd >= DIM (open_fd_table))
1061     {
1062       log_error ("invalid fd\n");
1063       return;
1064     }
1065
1066   if (!open_fd_table[fd].inuse)
1067     {
1068       log_error ("given fd has not been opened\n");
1069       return;
1070     }
1071 #ifdef HAVE_W32_SYSTEM
1072   CloseHandle (open_fd_table[fd].handle); /* Close duped handle.  */
1073 #endif
1074   close (fd);
1075   open_fd_table[fd].inuse = 0;
1076 }
1077
1078
1079 static void
1080 do_showopen (void)
1081 {
1082   int i;
1083
1084   for (i=0; i < DIM (open_fd_table); i++)
1085     if (open_fd_table[i].inuse)
1086       {
1087 #ifdef HAVE_W32_SYSTEM
1088         printf ("%-15d (libc=%d)\n", (int)open_fd_table[i].handle, i);
1089 #else
1090         printf ("%-15d\n", i);
1091 #endif
1092       }
1093 }
1094
1095
1096
1097 static gpg_error_t
1098 getinfo_pid_cb (void *opaque, const void *buffer, size_t length)
1099 {
1100   membuf_t *mb = opaque;
1101   put_membuf (mb, buffer, length);
1102   return 0;
1103 }
1104
1105 /* Get the pid of the server and store it locally.  */
1106 static void
1107 do_serverpid (assuan_context_t ctx)
1108 {
1109   int rc;
1110   membuf_t mb;
1111   char *buffer;
1112
1113   init_membuf (&mb, 100);
1114   rc = assuan_transact (ctx, "GETINFO pid", getinfo_pid_cb, &mb,
1115                         NULL, NULL, NULL, NULL);
1116   put_membuf (&mb, "", 1);
1117   buffer = get_membuf (&mb, NULL);
1118   if (rc || !buffer)
1119     log_error ("command \"%s\" failed: %s\n",
1120                "GETINFO pid", gpg_strerror (rc));
1121   else
1122     {
1123       server_pid = (pid_t)strtoul (buffer, NULL, 10);
1124       if (opt.verbose)
1125         log_info ("server's PID is %lu\n", (unsigned long)server_pid);
1126     }
1127   xfree (buffer);
1128 }
1129
1130
1131 /* Return true if the command is either "HELP" or "SCD HELP".  */
1132 static int
1133 help_cmd_p (const char *line)
1134 {
1135   if (!ascii_strncasecmp (line, "SCD", 3)
1136       && (spacep (line+3) || !line[3]))
1137     {
1138       for (line += 3; spacep (line); line++)
1139         ;
1140     }
1141
1142   return (!ascii_strncasecmp (line, "HELP", 4)
1143           && (spacep (line+4) || !line[4]));
1144 }
1145
1146
1147 /* gpg-connect-agent's entry point. */
1148 int
1149 main (int argc, char **argv)
1150 {
1151   ARGPARSE_ARGS pargs;
1152   int no_more_options = 0;
1153   assuan_context_t ctx;
1154   char *line, *p;
1155   char *tmpline;
1156   size_t linesize;
1157   int rc;
1158   int cmderr;
1159   const char *opt_run = NULL;
1160   gpgrt_stream_t script_fp = NULL;
1161   int use_tty, keep_line;
1162   struct {
1163     int collecting;
1164     loopline_t head;
1165     loopline_t *tail;
1166     loopline_t current;
1167     unsigned int nestlevel;
1168     int oneshot;
1169     char *condition;
1170   } loopstack[20];
1171   int        loopidx;
1172   char **cmdline_commands = NULL;
1173
1174   early_system_init ();
1175   gnupg_rl_initialize ();
1176   set_strusage (my_strusage);
1177   log_set_prefix ("gpg-connect-agent", GPGRT_LOG_WITH_PREFIX);
1178
1179   /* Make sure that our subsystems are ready.  */
1180   i18n_init();
1181   init_common_subsystems (&argc, &argv);
1182
1183   assuan_set_gpg_err_source (0);
1184
1185
1186   opt.autostart = 1;
1187   opt.connect_flags = 1;
1188
1189   /* Parse the command line. */
1190   pargs.argc  = &argc;
1191   pargs.argv  = &argv;
1192   pargs.flags =  1;  /* Do not remove the args.  */
1193   while (!no_more_options && optfile_parse (NULL, NULL, NULL, &pargs, opts))
1194     {
1195       switch (pargs.r_opt)
1196         {
1197         case oQuiet:     opt.quiet = 1; break;
1198         case oVerbose:   opt.verbose++; break;
1199         case oNoVerbose: opt.verbose = 0; break;
1200         case oHomedir:   gnupg_set_homedir (pargs.r.ret_str); break;
1201         case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
1202         case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str;  break;
1203         case oNoAutostart:    opt.autostart = 0; break;
1204         case oHex:       opt.hex = 1; break;
1205         case oDecode:    opt.decode = 1; break;
1206         case oDirmngr:   opt.use_dirmngr = 1; break;
1207         case oUIServer:  opt.use_uiserver = 1; break;
1208         case oRawSocket: opt.raw_socket = pargs.r.ret_str; break;
1209         case oTcpSocket: opt.tcp_socket = pargs.r.ret_str; break;
1210         case oExec:      opt.exec = 1; break;
1211         case oNoExtConnect: opt.connect_flags &= ~(1); break;
1212         case oRun:       opt_run = pargs.r.ret_str; break;
1213         case oSubst:
1214           opt.enable_varsubst = 1;
1215           opt.trim_leading_spaces = 1;
1216           break;
1217
1218         default: pargs.err = 2; break;
1219         }
1220     }
1221
1222   if (log_get_errorcount (0))
1223     exit (2);
1224
1225   /* --uiserver is a shortcut for a specific raw socket.  This comes
1226        in particular handy on Windows. */
1227   if (opt.use_uiserver)
1228     {
1229       opt.raw_socket = make_absfilename (gnupg_homedir (), "S.uiserver", NULL);
1230     }
1231
1232   /* Print a warning if an argument looks like an option.  */
1233   if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
1234     {
1235       int i;
1236
1237       for (i=0; i < argc; i++)
1238         if (argv[i][0] == '-' && argv[i][1] == '-')
1239           log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
1240     }
1241
1242
1243   use_tty = (gnupg_isatty (fileno (stdin)) && gnupg_isatty (fileno (stdout)));
1244
1245   if (opt.exec)
1246     {
1247       if (!argc)
1248         {
1249           log_error (_("option \"%s\" requires a program "
1250                        "and optional arguments\n"), "--exec" );
1251           exit (1);
1252         }
1253     }
1254   else if (argc)
1255     cmdline_commands = argv;
1256
1257   if (opt.exec && opt.raw_socket)
1258     {
1259       opt.raw_socket = NULL;
1260       log_info (_("option \"%s\" ignored due to \"%s\"\n"),
1261                 "--raw-socket", "--exec");
1262     }
1263   if (opt.exec && opt.tcp_socket)
1264     {
1265       opt.tcp_socket = NULL;
1266       log_info (_("option \"%s\" ignored due to \"%s\"\n"),
1267                 "--tcp-socket", "--exec");
1268     }
1269   if (opt.tcp_socket && opt.raw_socket)
1270     {
1271       opt.tcp_socket = NULL;
1272       log_info (_("option \"%s\" ignored due to \"%s\"\n"),
1273                 "--tcp-socket", "--raw-socket");
1274     }
1275
1276   if (opt_run && !(script_fp = gpgrt_fopen (opt_run, "r")))
1277     {
1278       log_error ("cannot open run file '%s': %s\n",
1279                  opt_run, strerror (errno));
1280       exit (1);
1281     }
1282
1283
1284   if (opt.exec)
1285     {
1286       assuan_fd_t no_close[3];
1287
1288       no_close[0] = assuan_fd_from_posix_fd (es_fileno (es_stderr));
1289       no_close[1] = assuan_fd_from_posix_fd (log_get_fd ());
1290       no_close[2] = ASSUAN_INVALID_FD;
1291
1292       rc = assuan_new (&ctx);
1293       if (rc)
1294         {
1295           log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
1296           exit (1);
1297         }
1298
1299       rc = assuan_pipe_connect
1300         (ctx, *argv, (const char **)argv, no_close, NULL, NULL,
1301          (opt.connect_flags & 1) ? ASSUAN_PIPE_CONNECT_FDPASSING : 0);
1302       if (rc)
1303         {
1304           log_error ("assuan_pipe_connect_ext failed: %s\n",
1305                      gpg_strerror (rc));
1306           exit (1);
1307         }
1308
1309       if (opt.verbose)
1310         log_info ("server '%s' started\n", *argv);
1311
1312     }
1313   else if (opt.raw_socket)
1314     {
1315       rc = assuan_new (&ctx);
1316       if (rc)
1317         {
1318           log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
1319           exit (1);
1320         }
1321
1322       rc = assuan_socket_connect
1323         (ctx, opt.raw_socket, 0,
1324          (opt.connect_flags & 1) ? ASSUAN_SOCKET_CONNECT_FDPASSING : 0);
1325       if (rc)
1326         {
1327           log_error ("can't connect to socket '%s': %s\n",
1328                      opt.raw_socket, gpg_strerror (rc));
1329           exit (1);
1330         }
1331
1332       if (opt.verbose)
1333         log_info ("connection to socket '%s' established\n", opt.raw_socket);
1334     }
1335   else if (opt.tcp_socket)
1336     {
1337       char *url;
1338
1339       url = xstrconcat ("assuan://", opt.tcp_socket, NULL);
1340
1341       rc = assuan_new (&ctx);
1342       if (rc)
1343         {
1344           log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
1345           exit (1);
1346         }
1347
1348       rc = assuan_socket_connect (ctx, opt.tcp_socket, 0, 0);
1349       if (rc)
1350         {
1351           log_error ("can't connect to server '%s': %s\n",
1352                      opt.tcp_socket, gpg_strerror (rc));
1353           exit (1);
1354         }
1355
1356       if (opt.verbose)
1357         log_info ("connection to socket '%s' established\n", url);
1358
1359       xfree (url);
1360     }
1361   else
1362     ctx = start_agent ();
1363
1364   /* See whether there is a line pending from the server (in case
1365      assuan did not run the initial handshaking).  */
1366   if (assuan_pending_line (ctx))
1367     {
1368       rc = read_and_print_response (ctx, 0, &cmderr);
1369       if (rc)
1370         log_info (_("receiving line failed: %s\n"), gpg_strerror (rc) );
1371     }
1372
1373
1374   for (loopidx=0; loopidx < DIM (loopstack); loopidx++)
1375     loopstack[loopidx].collecting = 0;
1376   loopidx = -1;
1377   line = NULL;
1378   linesize = 0;
1379   keep_line = 1;
1380   for (;;)
1381     {
1382       int n;
1383       size_t maxlength = 2048;
1384
1385       assert (loopidx < (int)DIM (loopstack));
1386       if (loopidx >= 0 && loopstack[loopidx].current)
1387         {
1388           keep_line = 0;
1389           xfree (line);
1390           line = xstrdup (loopstack[loopidx].current->line);
1391           n = strlen (line);
1392           /* Never go beyond of the final /end.  */
1393           if (loopstack[loopidx].current->next)
1394             loopstack[loopidx].current = loopstack[loopidx].current->next;
1395           else if (!strncmp (line, "/end", 4) && (!line[4]||spacep(line+4)))
1396             ;
1397           else
1398             log_fatal ("/end command vanished\n");
1399         }
1400       else if (cmdline_commands && *cmdline_commands && !script_fp)
1401         {
1402           keep_line = 0;
1403           xfree (line);
1404           line = xstrdup (*cmdline_commands);
1405           cmdline_commands++;
1406           n = strlen (line);
1407           if (n >= maxlength)
1408             maxlength = 0;
1409         }
1410       else if (use_tty && !script_fp)
1411         {
1412           keep_line = 0;
1413           xfree (line);
1414           line = tty_get ("> ");
1415           n = strlen (line);
1416           if (n==1 && *line == CONTROL_D)
1417             n = 0;
1418           if (n >= maxlength)
1419             maxlength = 0;
1420         }
1421       else
1422         {
1423           if (!keep_line)
1424             {
1425               xfree (line);
1426               line = NULL;
1427               linesize = 0;
1428               keep_line = 1;
1429             }
1430           n = gpgrt_read_line (script_fp ? script_fp : gpgrt_stdin,
1431                                &line, &linesize, &maxlength);
1432         }
1433       if (n < 0)
1434         {
1435           log_error (_("error reading input: %s\n"), strerror (errno));
1436           if (script_fp)
1437             {
1438               gpgrt_fclose (script_fp);
1439               script_fp = NULL;
1440               log_error ("stopping script execution\n");
1441               continue;
1442             }
1443           exit (1);
1444         }
1445       if (!n)
1446         {
1447           /* EOF */
1448           if (script_fp)
1449             {
1450               gpgrt_fclose (script_fp);
1451               script_fp = NULL;
1452               if (opt.verbose)
1453                 log_info ("end of script\n");
1454               continue;
1455             }
1456           break;
1457         }
1458       if (!maxlength)
1459         {
1460           log_error (_("line too long - skipped\n"));
1461           continue;
1462         }
1463       if (memchr (line, 0, n))
1464         log_info (_("line shortened due to embedded Nul character\n"));
1465       if (line[n-1] == '\n')
1466         line[n-1] = 0;
1467
1468       if (opt.trim_leading_spaces)
1469         {
1470           const char *s = line;
1471
1472           while (spacep (s))
1473             s++;
1474           if (s != line)
1475             {
1476               for (p=line; *s;)
1477                 *p++ = *s++;
1478               *p = 0;
1479               n = p - line;
1480             }
1481         }
1482
1483       if (loopidx+1 >= 0 && loopstack[loopidx+1].collecting)
1484         {
1485           loopline_t ll;
1486
1487           ll = xmalloc (sizeof *ll + strlen (line));
1488           ll->next = NULL;
1489           strcpy (ll->line, line);
1490           *loopstack[loopidx+1].tail = ll;
1491           loopstack[loopidx+1].tail = &ll->next;
1492
1493           if (!strncmp (line, "/end", 4) && (!line[4]||spacep(line+4)))
1494             loopstack[loopidx+1].nestlevel--;
1495           else if (!strncmp (line, "/while", 6) && (!line[6]||spacep(line+6)))
1496             loopstack[loopidx+1].nestlevel++;
1497
1498           if (loopstack[loopidx+1].nestlevel)
1499             continue;
1500           /* We reached the corresponding /end.  */
1501           loopstack[loopidx+1].collecting = 0;
1502           loopidx++;
1503         }
1504
1505       if (*line == '/')
1506         {
1507           /* Handle control commands. */
1508           char *cmd = line+1;
1509
1510           for (p=cmd; *p && !spacep (p); p++)
1511             ;
1512           if (*p)
1513             *p++ = 0;
1514           while (spacep (p))
1515             p++;
1516           if (!strcmp (cmd, "let"))
1517             {
1518               assign_variable (p, 0);
1519             }
1520           else if (!strcmp (cmd, "slet"))
1521             {
1522               /* Deprecated - never used in a released version.  */
1523               assign_variable (p, 1);
1524             }
1525           else if (!strcmp (cmd, "showvar"))
1526             {
1527               show_variables ();
1528             }
1529           else if (!strcmp (cmd, "definq"))
1530             {
1531               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1532               if (tmpline)
1533                 {
1534                   add_definq (tmpline, 1, 0);
1535                   xfree (tmpline);
1536                 }
1537               else
1538                 add_definq (p, 1, 0);
1539             }
1540           else if (!strcmp (cmd, "definqfile"))
1541             {
1542               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1543               if (tmpline)
1544                 {
1545                   add_definq (tmpline, 0, 0);
1546                   xfree (tmpline);
1547                 }
1548               else
1549                 add_definq (p, 0, 0);
1550             }
1551           else if (!strcmp (cmd, "definqprog"))
1552             {
1553               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1554               if (tmpline)
1555                 {
1556                   add_definq (tmpline, 0, 1);
1557                   xfree (tmpline);
1558                 }
1559               else
1560                 add_definq (p, 0, 1);
1561             }
1562           else if (!strcmp (cmd, "datafile"))
1563             {
1564               const char *fname;
1565
1566               if (current_datasink)
1567                 {
1568                   if (current_datasink != stdout)
1569                     fclose (current_datasink);
1570                   current_datasink = NULL;
1571                 }
1572               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1573               fname = tmpline? tmpline : p;
1574               if (fname && !strcmp (fname, "-"))
1575                 current_datasink = stdout;
1576               else if (fname && *fname)
1577                 {
1578                   current_datasink = fopen (fname, "wb");
1579                   if (!current_datasink)
1580                     log_error ("can't open '%s': %s\n",
1581                                fname, strerror (errno));
1582                 }
1583               xfree (tmpline);
1584             }
1585           else if (!strcmp (cmd, "showdef"))
1586             {
1587               show_definq ();
1588             }
1589           else if (!strcmp (cmd, "cleardef"))
1590             {
1591               clear_definq ();
1592             }
1593           else if (!strcmp (cmd, "echo"))
1594             {
1595               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1596               if (tmpline)
1597                 {
1598                   puts (tmpline);
1599                   xfree (tmpline);
1600                 }
1601               else
1602                 puts (p);
1603             }
1604           else if (!strcmp (cmd, "sendfd"))
1605             {
1606               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1607               if (tmpline)
1608                 {
1609                   do_sendfd (ctx, tmpline);
1610                   xfree (tmpline);
1611                 }
1612               else
1613                 do_sendfd (ctx, p);
1614               continue;
1615             }
1616           else if (!strcmp (cmd, "recvfd"))
1617             {
1618               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1619               if (tmpline)
1620                 {
1621                   do_recvfd (ctx, tmpline);
1622                   xfree (tmpline);
1623                 }
1624               else
1625                 do_recvfd (ctx, p);
1626               continue;
1627             }
1628           else if (!strcmp (cmd, "open"))
1629             {
1630               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1631               if (tmpline)
1632                 {
1633                   do_open (tmpline);
1634                   xfree (tmpline);
1635                 }
1636               else
1637                 do_open (p);
1638             }
1639           else if (!strcmp (cmd, "close"))
1640             {
1641               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1642               if (tmpline)
1643                 {
1644                   do_close (tmpline);
1645                   xfree (tmpline);
1646                 }
1647               else
1648                 do_close (p);
1649             }
1650           else if (!strcmp (cmd, "showopen"))
1651             {
1652               do_showopen ();
1653             }
1654           else if (!strcmp (cmd, "serverpid"))
1655             {
1656               do_serverpid (ctx);
1657             }
1658           else if (!strcmp (cmd, "hex"))
1659             opt.hex = 1;
1660           else if (!strcmp (cmd, "nohex"))
1661             opt.hex = 0;
1662           else if (!strcmp (cmd, "decode"))
1663             opt.decode = 1;
1664           else if (!strcmp (cmd, "nodecode"))
1665             opt.decode = 0;
1666           else if (!strcmp (cmd, "subst"))
1667             {
1668               opt.enable_varsubst = 1;
1669               opt.trim_leading_spaces = 1;
1670             }
1671           else if (!strcmp (cmd, "nosubst"))
1672             opt.enable_varsubst = 0;
1673           else if (!strcmp (cmd, "run"))
1674             {
1675               char *p2;
1676
1677               for (p2=p; *p2 && !spacep (p2); p2++)
1678                 ;
1679               if (*p2)
1680                 *p2++ = 0;
1681               while (spacep (p2))
1682                 p++;
1683               if (*p2)
1684                 {
1685                   log_error ("syntax error in run command\n");
1686                   if (script_fp)
1687                     {
1688                       gpgrt_fclose (script_fp);
1689                       script_fp = NULL;
1690                     }
1691                 }
1692               else if (script_fp)
1693                 {
1694                   log_error ("cannot nest run commands - stop\n");
1695                   gpgrt_fclose (script_fp);
1696                   script_fp = NULL;
1697                 }
1698               else if (!(script_fp = gpgrt_fopen (p, "r")))
1699                 {
1700                   log_error ("cannot open run file '%s': %s\n",
1701                              p, strerror (errno));
1702                 }
1703               else if (opt.verbose)
1704                 log_info ("running commands from '%s'\n", p);
1705             }
1706           else if (!strcmp (cmd, "while"))
1707             {
1708               if (loopidx+2 >= (int)DIM(loopstack))
1709                 {
1710                   log_error ("blocks are nested too deep\n");
1711                   /* We should better die or break all loop in this
1712                      case as recovering from this error won't be
1713                      easy.  */
1714                 }
1715               else
1716                 {
1717                   loopstack[loopidx+1].head = NULL;
1718                   loopstack[loopidx+1].tail = &loopstack[loopidx+1].head;
1719                   loopstack[loopidx+1].current = NULL;
1720                   loopstack[loopidx+1].nestlevel = 1;
1721                   loopstack[loopidx+1].oneshot = 0;
1722                   loopstack[loopidx+1].condition = xstrdup (p);
1723                   loopstack[loopidx+1].collecting = 1;
1724                 }
1725             }
1726           else if (!strcmp (cmd, "if"))
1727             {
1728               if (loopidx+2 >= (int)DIM(loopstack))
1729                 {
1730                   log_error ("blocks are nested too deep\n");
1731                 }
1732               else
1733                 {
1734                   /* Note that we need to evaluate the condition right
1735                      away and not just at the end of the block as we
1736                      do with a WHILE. */
1737                   loopstack[loopidx+1].head = NULL;
1738                   loopstack[loopidx+1].tail = &loopstack[loopidx+1].head;
1739                   loopstack[loopidx+1].current = NULL;
1740                   loopstack[loopidx+1].nestlevel = 1;
1741                   loopstack[loopidx+1].oneshot = 1;
1742                   loopstack[loopidx+1].condition = substitute_line_copy (p);
1743                   loopstack[loopidx+1].collecting = 1;
1744                 }
1745             }
1746           else if (!strcmp (cmd, "end"))
1747             {
1748               if (loopidx < 0)
1749                 log_error ("stray /end command encountered - ignored\n");
1750               else
1751                 {
1752                   char *tmpcond;
1753                   const char *value;
1754                   long condition;
1755
1756                   /* Evaluate the condition.  */
1757                   tmpcond = xstrdup (loopstack[loopidx].condition);
1758                   if (loopstack[loopidx].oneshot)
1759                     {
1760                       xfree (loopstack[loopidx].condition);
1761                       loopstack[loopidx].condition = xstrdup ("0");
1762                     }
1763                   tmpline = substitute_line (tmpcond);
1764                   value = tmpline? tmpline : tmpcond;
1765                   /* "true" or "yes" are commonly used to mean TRUE;
1766                      all other strings will evaluate to FALSE due to
1767                      the strtoul.  */
1768                   if (!ascii_strcasecmp (value, "true")
1769                       || !ascii_strcasecmp (value, "yes"))
1770                     condition = 1;
1771                   else
1772                     condition = strtol (value, NULL, 0);
1773                   xfree (tmpline);
1774                   xfree (tmpcond);
1775
1776                   if (condition)
1777                     {
1778                       /* Run loop.  */
1779                       loopstack[loopidx].current = loopstack[loopidx].head;
1780                     }
1781                   else
1782                     {
1783                       /* Cleanup.  */
1784                       while (loopstack[loopidx].head)
1785                         {
1786                           loopline_t tmp = loopstack[loopidx].head->next;
1787                           xfree (loopstack[loopidx].head);
1788                           loopstack[loopidx].head = tmp;
1789                         }
1790                       loopstack[loopidx].tail = NULL;
1791                       loopstack[loopidx].current = NULL;
1792                       loopstack[loopidx].nestlevel = 0;
1793                       loopstack[loopidx].collecting = 0;
1794                       loopstack[loopidx].oneshot = 0;
1795                       xfree (loopstack[loopidx].condition);
1796                       loopstack[loopidx].condition = NULL;
1797                       loopidx--;
1798                     }
1799                 }
1800             }
1801           else if (!strcmp (cmd, "bye"))
1802             {
1803               break;
1804             }
1805           else if (!strcmp (cmd, "sleep"))
1806             {
1807               gnupg_sleep (1);
1808             }
1809           else if (!strcmp (cmd, "help"))
1810             {
1811               puts (
1812 "Available commands:\n"
1813 "/echo ARGS             Echo ARGS.\n"
1814 "/let  NAME VALUE       Set variable NAME to VALUE.\n"
1815 "/showvar               Show all variables.\n"
1816 "/definq NAME VAR       Use content of VAR for inquiries with NAME.\n"
1817 "/definqfile NAME FILE  Use content of FILE for inquiries with NAME.\n"
1818 "/definqprog NAME PGM   Run PGM for inquiries with NAME.\n"
1819 "/datafile [NAME]       Write all D line content to file NAME.\n"
1820 "/showdef               Print all definitions.\n"
1821 "/cleardef              Delete all definitions.\n"
1822 "/sendfd FILE MODE      Open FILE and pass descriptor to server.\n"
1823 "/recvfd                Receive FD from server and print.\n"
1824 "/open VAR FILE MODE    Open FILE and assign the file descriptor to VAR.\n"
1825 "/close FD              Close file with descriptor FD.\n"
1826 "/showopen              Show descriptors of all open files.\n"
1827 "/serverpid             Retrieve the pid of the server.\n"
1828 "/[no]hex               Enable hex dumping of received data lines.\n"
1829 "/[no]decode            Enable decoding of received data lines.\n"
1830 "/[no]subst             Enable variable substitution.\n"
1831 "/run FILE              Run commands from FILE.\n"
1832 "/if VAR                Begin conditional block controlled by VAR.\n"
1833 "/while VAR             Begin loop controlled by VAR.\n"
1834 "/end                   End loop or condition\n"
1835 "/bye                   Terminate gpg-connect-agent.\n"
1836 "/help                  Print this help.");
1837             }
1838           else
1839             log_error (_("unknown command '%s'\n"), cmd );
1840
1841           continue;
1842         }
1843
1844       if (opt.verbose && script_fp)
1845         puts (line);
1846
1847       tmpline = opt.enable_varsubst? substitute_line (line) : NULL;
1848       if (tmpline)
1849         {
1850           rc = assuan_write_line (ctx, tmpline);
1851           xfree (tmpline);
1852         }
1853       else
1854         rc = assuan_write_line (ctx, line);
1855       if (rc)
1856         {
1857           log_info (_("sending line failed: %s\n"), gpg_strerror (rc) );
1858           break;
1859         }
1860       if (*line == '#' || !*line)
1861         continue; /* Don't expect a response for a comment line. */
1862
1863       rc = read_and_print_response (ctx, help_cmd_p (line), &cmderr);
1864       if (rc)
1865         log_info (_("receiving line failed: %s\n"), gpg_strerror (rc) );
1866       if ((rc || cmderr) && script_fp)
1867         {
1868           log_error ("stopping script execution\n");
1869           gpgrt_fclose (script_fp);
1870           script_fp = NULL;
1871         }
1872
1873
1874       /* FIXME: If the last command was BYE or the server died for
1875          some other reason, we won't notice until we get the next
1876          input command.  Probing the connection with a non-blocking
1877          read could help to notice termination or other problems
1878          early.  */
1879     }
1880
1881   if (opt.verbose)
1882     log_info ("closing connection to agent\n");
1883
1884   /* XXX: We would like to release the context here, but libassuan
1885      nicely says good bye to the server, which results in a SIGPIPE if
1886      the server died.  Unfortunately, libassuan does not ignore
1887      SIGPIPE when used with UNIX sockets, hence we simply leak the
1888      context here.  */
1889   if (0)
1890     assuan_release (ctx);
1891   else
1892     gpgrt_annotate_leaked_object (ctx);
1893   xfree (line);
1894   return 0;
1895 }
1896
1897
1898 /* Handle an Inquire from the server.  Return False if it could not be
1899    handled; in this case the caller shll complete the operation.  LINE
1900    is the complete line as received from the server.  This function
1901    may change the content of LINE. */
1902 static int
1903 handle_inquire (assuan_context_t ctx, char *line)
1904 {
1905   const char *name;
1906   definq_t d;
1907   FILE *fp = NULL;
1908   char buffer[1024];
1909   int rc, n;
1910
1911   /* Skip the command and trailing spaces. */
1912   for (; *line && !spacep (line); line++)
1913     ;
1914   while (spacep (line))
1915     line++;
1916   /* Get the name. */
1917   name = line;
1918   for (; *line && !spacep (line); line++)
1919     ;
1920   if (*line)
1921     *line++ = 0;
1922
1923   /* Now match it against our list.  The second loop is there to
1924      detect the match-all entry. */
1925   for (d=definq_list; d; d = d->next)
1926     if (d->name && !strcmp (d->name, name))
1927         break;
1928   if (!d)
1929     for (d=definq_list; d; d = d->next)
1930       if (!d->name)
1931         break;
1932   if (!d)
1933     {
1934       if (opt.verbose)
1935         log_info ("no handler for inquiry '%s' found\n", name);
1936       return 0;
1937     }
1938
1939   if (d->is_var)
1940     {
1941       char *tmpvalue = get_var_ext (d->file);
1942       if (tmpvalue)
1943         rc = assuan_send_data (ctx, tmpvalue, strlen (tmpvalue));
1944       else
1945         rc = assuan_send_data (ctx, "", 0);
1946       xfree (tmpvalue);
1947       if (rc)
1948         log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
1949     }
1950   else
1951     {
1952       if (d->is_prog)
1953         {
1954 #ifdef HAVE_W32CE_SYSTEM
1955           fp = NULL;
1956 #else
1957           fp = popen (d->file, "r");
1958 #endif
1959           if (!fp)
1960             log_error ("error executing '%s': %s\n",
1961                        d->file, strerror (errno));
1962           else if (opt.verbose)
1963             log_error ("handling inquiry '%s' by running '%s'\n",
1964                        name, d->file);
1965         }
1966       else
1967         {
1968           fp = fopen (d->file, "rb");
1969           if (!fp)
1970             log_error ("error opening '%s': %s\n", d->file, strerror (errno));
1971           else if (opt.verbose)
1972             log_error ("handling inquiry '%s' by returning content of '%s'\n",
1973                        name, d->file);
1974         }
1975       if (!fp)
1976         return 0;
1977
1978       while ( (n = fread (buffer, 1, sizeof buffer, fp)) )
1979         {
1980           rc = assuan_send_data (ctx, buffer, n);
1981           if (rc)
1982             {
1983               log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
1984               break;
1985             }
1986         }
1987       if (ferror (fp))
1988         log_error ("error reading from '%s': %s\n", d->file, strerror (errno));
1989     }
1990
1991   rc = assuan_send_data (ctx, NULL, 0);
1992   if (rc)
1993     log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
1994
1995   if (d->is_var)
1996     ;
1997   else if (d->is_prog)
1998     {
1999 #ifndef HAVE_W32CE_SYSTEM
2000       if (pclose (fp))
2001         log_error ("error running '%s': %s\n", d->file, strerror (errno));
2002 #endif
2003     }
2004   else
2005     fclose (fp);
2006   return 1;
2007 }
2008
2009
2010 /* Read all response lines from server and print them.  Returns 0 on
2011    success or an assuan error code.  If WITHHASH istrue, comment lines
2012    are printed.  Sets R_GOTERR to true if the command did not returned
2013    OK.  */
2014 static int
2015 read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr)
2016 {
2017   char *line;
2018   size_t linelen;
2019   gpg_error_t rc;
2020   int i, j;
2021   int need_lf = 0;
2022
2023   *r_goterr = 0;
2024   for (;;)
2025     {
2026       do
2027         {
2028           rc = assuan_read_line (ctx, &line, &linelen);
2029           if (rc)
2030             return rc;
2031
2032           if ((withhash || opt.verbose > 1) && *line == '#')
2033             {
2034               fwrite (line, linelen, 1, stdout);
2035               putchar ('\n');
2036             }
2037         }
2038       while (*line == '#' || !linelen);
2039
2040       if (linelen >= 1
2041           && line[0] == 'D' && line[1] == ' ')
2042         {
2043           if (current_datasink)
2044             {
2045               const unsigned char *s;
2046               int c = 0;
2047
2048               for (j=2, s=(unsigned char*)line+2; j < linelen; j++, s++ )
2049                 {
2050                   if (*s == '%' && j+2 < linelen)
2051                     {
2052                       s++; j++;
2053                       c = xtoi_2 ( s );
2054                       s++; j++;
2055                     }
2056                   else
2057                     c = *s;
2058                   putc (c, current_datasink);
2059                 }
2060             }
2061           else if (opt.hex)
2062             {
2063               for (i=2; i < linelen; )
2064                 {
2065                   int save_i = i;
2066
2067                   printf ("D[%04X] ", i-2);
2068                   for (j=0; j < 16 ; j++, i++)
2069                     {
2070                       if (j == 8)
2071                         putchar (' ');
2072                       if (i < linelen)
2073                         printf (" %02X", ((unsigned char*)line)[i]);
2074                       else
2075                         fputs ("   ", stdout);
2076                     }
2077                   fputs ("   ", stdout);
2078                   i= save_i;
2079                   for (j=0; j < 16; j++, i++)
2080                     {
2081                       unsigned int c = ((unsigned char*)line)[i];
2082                       if ( i >= linelen )
2083                         putchar (' ');
2084                       else if (isascii (c) && isprint (c) && !iscntrl (c))
2085                         putchar (c);
2086                       else
2087                         putchar ('.');
2088                     }
2089                   putchar ('\n');
2090                 }
2091             }
2092           else if (opt.decode)
2093             {
2094               const unsigned char *s;
2095               int need_d = 1;
2096               int c = 0;
2097
2098               for (j=2, s=(unsigned char*)line+2; j < linelen; j++, s++ )
2099                 {
2100                   if (need_d)
2101                     {
2102                       fputs ("D ", stdout);
2103                       need_d = 0;
2104                     }
2105                   if (*s == '%' && j+2 < linelen)
2106                     {
2107                       s++; j++;
2108                       c = xtoi_2 ( s );
2109                       s++; j++;
2110                     }
2111                   else
2112                     c = *s;
2113                   if (c == '\n')
2114                     need_d = 1;
2115                   putchar (c);
2116                 }
2117               need_lf = (c != '\n');
2118             }
2119           else
2120             {
2121               fwrite (line, linelen, 1, stdout);
2122               putchar ('\n');
2123             }
2124         }
2125       else
2126         {
2127           if (need_lf)
2128             {
2129               if (!current_datasink || current_datasink != stdout)
2130                 putchar ('\n');
2131               need_lf = 0;
2132             }
2133
2134           if (linelen >= 1
2135               && line[0] == 'S'
2136               && (line[1] == '\0' || line[1] == ' '))
2137             {
2138               if (!current_datasink || current_datasink != stdout)
2139                 {
2140                   fwrite (line, linelen, 1, stdout);
2141                   putchar ('\n');
2142                 }
2143             }
2144           else if (linelen >= 2
2145                    && line[0] == 'O' && line[1] == 'K'
2146                    && (line[2] == '\0' || line[2] == ' '))
2147             {
2148               if (!current_datasink || current_datasink != stdout)
2149                 {
2150                   fwrite (line, linelen, 1, stdout);
2151                   putchar ('\n');
2152                 }
2153               set_int_var ("?", 0);
2154               return 0;
2155             }
2156           else if (linelen >= 3
2157                    && line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
2158                    && (line[3] == '\0' || line[3] == ' '))
2159             {
2160               int errval;
2161
2162               errval = strtol (line+3, NULL, 10);
2163               if (!errval)
2164                 errval = -1;
2165               set_int_var ("?", errval);
2166               if (!current_datasink || current_datasink != stdout)
2167                 {
2168                   fwrite (line, linelen, 1, stdout);
2169                   putchar ('\n');
2170                 }
2171               *r_goterr = 1;
2172               return 0;
2173             }
2174           else if (linelen >= 7
2175                    && line[0] == 'I' && line[1] == 'N' && line[2] == 'Q'
2176                    && line[3] == 'U' && line[4] == 'I' && line[5] == 'R'
2177                    && line[6] == 'E'
2178                    && (line[7] == '\0' || line[7] == ' '))
2179             {
2180               if (!current_datasink || current_datasink != stdout)
2181                 {
2182                   fwrite (line, linelen, 1, stdout);
2183                   putchar ('\n');
2184                 }
2185               if (!handle_inquire (ctx, line))
2186                 assuan_write_line (ctx, "CANCEL");
2187             }
2188           else if (linelen >= 3
2189                    && line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
2190                    && (line[3] == '\0' || line[3] == ' '))
2191             {
2192               if (!current_datasink || current_datasink != stdout)
2193                 {
2194                   fwrite (line, linelen, 1, stdout);
2195                   putchar ('\n');
2196                 }
2197               /* Received from server, thus more responses are expected.  */
2198             }
2199           else
2200             return gpg_error (GPG_ERR_ASS_INV_RESPONSE);
2201         }
2202     }
2203 }
2204
2205
2206
2207
2208 /* Connect to the agent and send the standard options.  */
2209 static assuan_context_t
2210 start_agent (void)
2211 {
2212   gpg_error_t err;
2213   assuan_context_t ctx;
2214   session_env_t session_env;
2215
2216   session_env = session_env_new ();
2217   if (!session_env)
2218     log_fatal ("error allocating session environment block: %s\n",
2219                strerror (errno));
2220   if (opt.use_dirmngr)
2221     err = start_new_dirmngr (&ctx,
2222                              GPG_ERR_SOURCE_DEFAULT,
2223                              opt.dirmngr_program,
2224                              opt.autostart,
2225                              !opt.quiet, 0,
2226                              NULL, NULL);
2227   else
2228     err = start_new_gpg_agent (&ctx,
2229                                GPG_ERR_SOURCE_DEFAULT,
2230                                opt.agent_program,
2231                                NULL, NULL,
2232                                session_env,
2233                                opt.autostart,
2234                                !opt.quiet, 0,
2235                                NULL, NULL);
2236
2237   session_env_release (session_env);
2238   if (err)
2239     {
2240       if (!opt.autostart
2241           && (gpg_err_code (err)
2242               == (opt.use_dirmngr? GPG_ERR_NO_DIRMNGR : GPG_ERR_NO_AGENT)))
2243         {
2244           /* In the no-autostart case we don't make gpg-connect-agent
2245              fail on a missing server.  */
2246           log_info (opt.use_dirmngr?
2247                     _("no dirmngr running in this session\n"):
2248                     _("no gpg-agent running in this session\n"));
2249           exit (0);
2250         }
2251       else
2252         {
2253           log_error (_("error sending standard options: %s\n"),
2254                      gpg_strerror (err));
2255           exit (1);
2256         }
2257     }
2258
2259   return ctx;
2260 }