chiark / gitweb /
asshelp.c: add a lot of debug logging
[gnupg2.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 "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 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 defintions. */
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 = 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       close (fd);
1034     }
1035 }
1036
1037
1038 static void
1039 do_close (char *line)
1040 {
1041   int fd = atoi (line);
1042
1043 #ifdef HAVE_W32_SYSTEM
1044   int i;
1045
1046   for (i=0; i < DIM (open_fd_table); i++)
1047     if ( open_fd_table[i].inuse && open_fd_table[i].handle == (void*)fd)
1048       break;
1049   if (i < DIM (open_fd_table))
1050     fd = i;
1051   else
1052     {
1053       log_error ("given fd (system handle) has not been opened\n");
1054       return;
1055     }
1056 #endif
1057
1058   if (fd < 0 || fd >= DIM (open_fd_table))
1059     {
1060       log_error ("invalid fd\n");
1061       return;
1062     }
1063
1064   if (!open_fd_table[fd].inuse)
1065     {
1066       log_error ("given fd has not been opened\n");
1067       return;
1068     }
1069 #ifdef HAVE_W32_SYSTEM
1070   CloseHandle (open_fd_table[fd].handle); /* Close duped handle.  */
1071 #endif
1072   close (fd);
1073   open_fd_table[fd].inuse = 0;
1074 }
1075
1076
1077 static void
1078 do_showopen (void)
1079 {
1080   int i;
1081
1082   for (i=0; i < DIM (open_fd_table); i++)
1083     if (open_fd_table[i].inuse)
1084       {
1085 #ifdef HAVE_W32_SYSTEM
1086         printf ("%-15d (libc=%d)\n", (int)open_fd_table[i].handle, i);
1087 #else
1088         printf ("%-15d\n", i);
1089 #endif
1090       }
1091 }
1092
1093
1094
1095 static gpg_error_t
1096 getinfo_pid_cb (void *opaque, const void *buffer, size_t length)
1097 {
1098   membuf_t *mb = opaque;
1099   put_membuf (mb, buffer, length);
1100   return 0;
1101 }
1102
1103 /* Get the pid of the server and store it locally.  */
1104 static void
1105 do_serverpid (assuan_context_t ctx)
1106 {
1107   int rc;
1108   membuf_t mb;
1109   char *buffer;
1110
1111   init_membuf (&mb, 100);
1112   rc = assuan_transact (ctx, "GETINFO pid", getinfo_pid_cb, &mb,
1113                         NULL, NULL, NULL, NULL);
1114   put_membuf (&mb, "", 1);
1115   buffer = get_membuf (&mb, NULL);
1116   if (rc || !buffer)
1117     log_error ("command \"%s\" failed: %s\n",
1118                "GETINFO pid", gpg_strerror (rc));
1119   else
1120     {
1121       server_pid = (pid_t)strtoul (buffer, NULL, 10);
1122       if (opt.verbose)
1123         log_info ("server's PID is %lu\n", (unsigned long)server_pid);
1124     }
1125   xfree (buffer);
1126 }
1127
1128
1129 /* Return true if the command is either "HELP" or "SCD HELP".  */
1130 static int
1131 help_cmd_p (const char *line)
1132 {
1133   if (!ascii_strncasecmp (line, "SCD", 3)
1134       && (spacep (line+3) || !line[3]))
1135     {
1136       for (line += 3; spacep (line); line++)
1137         ;
1138     }
1139
1140   return (!ascii_strncasecmp (line, "HELP", 4)
1141           && (spacep (line+4) || !line[4]));
1142 }
1143
1144
1145 /* gpg-connect-agent's entry point. */
1146 int
1147 main (int argc, char **argv)
1148 {
1149   ARGPARSE_ARGS pargs;
1150   int no_more_options = 0;
1151   assuan_context_t ctx;
1152   char *line, *p;
1153   char *tmpline;
1154   size_t linesize;
1155   int rc;
1156   int cmderr;
1157   const char *opt_run = NULL;
1158   FILE *script_fp = NULL;
1159   int use_tty, keep_line;
1160   struct {
1161     int collecting;
1162     loopline_t head;
1163     loopline_t *tail;
1164     loopline_t current;
1165     unsigned int nestlevel;
1166     int oneshot;
1167     char *condition;
1168   } loopstack[20];
1169   int        loopidx;
1170   char **cmdline_commands = NULL;
1171
1172   early_system_init ();
1173   gnupg_rl_initialize ();
1174   set_strusage (my_strusage);
1175   log_set_prefix ("gpg-connect-agent", GPGRT_LOG_WITH_PREFIX);
1176
1177   /* Make sure that our subsystems are ready.  */
1178   i18n_init();
1179   init_common_subsystems (&argc, &argv);
1180
1181   assuan_set_gpg_err_source (0);
1182
1183
1184   opt.autostart = 1;
1185   opt.connect_flags = 1;
1186
1187   /* Parse the command line. */
1188   pargs.argc  = &argc;
1189   pargs.argv  = &argv;
1190   pargs.flags =  1;  /* Do not remove the args.  */
1191   while (!no_more_options && optfile_parse (NULL, NULL, NULL, &pargs, opts))
1192     {
1193       switch (pargs.r_opt)
1194         {
1195         case oQuiet:     opt.quiet = 1; break;
1196         case oVerbose:   opt.verbose++; break;
1197         case oNoVerbose: opt.verbose = 0; break;
1198         case oHomedir:   gnupg_set_homedir (pargs.r.ret_str); break;
1199         case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
1200         case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str;  break;
1201         case oNoAutostart:    opt.autostart = 0; break;
1202         case oHex:       opt.hex = 1; break;
1203         case oDecode:    opt.decode = 1; break;
1204         case oDirmngr:   opt.use_dirmngr = 1; break;
1205         case oUIServer:  opt.use_uiserver = 1; break;
1206         case oRawSocket: opt.raw_socket = pargs.r.ret_str; break;
1207         case oTcpSocket: opt.tcp_socket = pargs.r.ret_str; break;
1208         case oExec:      opt.exec = 1; break;
1209         case oNoExtConnect: opt.connect_flags &= ~(1); break;
1210         case oRun:       opt_run = pargs.r.ret_str; break;
1211         case oSubst:
1212           opt.enable_varsubst = 1;
1213           opt.trim_leading_spaces = 1;
1214           break;
1215
1216         default: pargs.err = 2; break;
1217         }
1218     }
1219
1220   if (log_get_errorcount (0))
1221     exit (2);
1222
1223   /* --uiserver is a shortcut for a specific raw socket.  This comes
1224        in particular handy on Windows. */
1225   if (opt.use_uiserver)
1226     {
1227       opt.raw_socket = make_absfilename (gnupg_homedir (), "S.uiserver", NULL);
1228     }
1229
1230   /* Print a warning if an argument looks like an option.  */
1231   if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
1232     {
1233       int i;
1234
1235       for (i=0; i < argc; i++)
1236         if (argv[i][0] == '-' && argv[i][1] == '-')
1237           log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
1238     }
1239
1240
1241   use_tty = (gnupg_isatty (fileno (stdin)) && gnupg_isatty (fileno (stdout)));
1242
1243   if (opt.exec)
1244     {
1245       if (!argc)
1246         {
1247           log_error (_("option \"%s\" requires a program "
1248                        "and optional arguments\n"), "--exec" );
1249           exit (1);
1250         }
1251     }
1252   else if (argc)
1253     cmdline_commands = argv;
1254
1255   if (opt.exec && opt.raw_socket)
1256     {
1257       opt.raw_socket = NULL;
1258       log_info (_("option \"%s\" ignored due to \"%s\"\n"),
1259                 "--raw-socket", "--exec");
1260     }
1261   if (opt.exec && opt.tcp_socket)
1262     {
1263       opt.tcp_socket = NULL;
1264       log_info (_("option \"%s\" ignored due to \"%s\"\n"),
1265                 "--tcp-socket", "--exec");
1266     }
1267   if (opt.tcp_socket && opt.raw_socket)
1268     {
1269       opt.tcp_socket = NULL;
1270       log_info (_("option \"%s\" ignored due to \"%s\"\n"),
1271                 "--tcp-socket", "--raw-socket");
1272     }
1273
1274   if (opt_run && !(script_fp = fopen (opt_run, "r")))
1275     {
1276       log_error ("cannot open run file '%s': %s\n",
1277                  opt_run, strerror (errno));
1278       exit (1);
1279     }
1280
1281
1282   if (opt.exec)
1283     {
1284       assuan_fd_t no_close[3];
1285
1286       no_close[0] = assuan_fd_from_posix_fd (es_fileno (es_stderr));
1287       no_close[1] = assuan_fd_from_posix_fd (log_get_fd ());
1288       no_close[2] = ASSUAN_INVALID_FD;
1289
1290       rc = assuan_new (&ctx);
1291       if (rc)
1292         {
1293           log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
1294           exit (1);
1295         }
1296
1297       rc = assuan_pipe_connect
1298         (ctx, *argv, (const char **)argv, no_close, NULL, NULL,
1299          (opt.connect_flags & 1) ? ASSUAN_PIPE_CONNECT_FDPASSING : 0);
1300       if (rc)
1301         {
1302           log_error ("assuan_pipe_connect_ext failed: %s\n",
1303                      gpg_strerror (rc));
1304           exit (1);
1305         }
1306
1307       if (opt.verbose)
1308         log_info ("server '%s' started\n", *argv);
1309
1310     }
1311   else if (opt.raw_socket)
1312     {
1313       rc = assuan_new (&ctx);
1314       if (rc)
1315         {
1316           log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
1317           exit (1);
1318         }
1319
1320       rc = assuan_socket_connect
1321         (ctx, opt.raw_socket, 0,
1322          (opt.connect_flags & 1) ? ASSUAN_SOCKET_CONNECT_FDPASSING : 0);
1323       if (rc)
1324         {
1325           log_error ("can't connect to socket '%s': %s\n",
1326                      opt.raw_socket, gpg_strerror (rc));
1327           exit (1);
1328         }
1329
1330       if (opt.verbose)
1331         log_info ("connection to socket '%s' established\n", opt.raw_socket);
1332     }
1333   else if (opt.tcp_socket)
1334     {
1335       char *url;
1336
1337       url = xstrconcat ("assuan://", opt.tcp_socket, NULL);
1338
1339       rc = assuan_new (&ctx);
1340       if (rc)
1341         {
1342           log_error ("assuan_new failed: %s\n", gpg_strerror (rc));
1343           exit (1);
1344         }
1345
1346       rc = assuan_socket_connect (ctx, opt.tcp_socket, 0, 0);
1347       if (rc)
1348         {
1349           log_error ("can't connect to server '%s': %s\n",
1350                      opt.tcp_socket, gpg_strerror (rc));
1351           exit (1);
1352         }
1353
1354       if (opt.verbose)
1355         log_info ("connection to socket '%s' established\n", url);
1356
1357       xfree (url);
1358     }
1359   else
1360     ctx = start_agent ();
1361
1362   /* See whether there is a line pending from the server (in case
1363      assuan did not run the initial handshaking).  */
1364   if (assuan_pending_line (ctx))
1365     {
1366       rc = read_and_print_response (ctx, 0, &cmderr);
1367       if (rc)
1368         log_info (_("receiving line failed: %s\n"), gpg_strerror (rc) );
1369     }
1370
1371
1372   for (loopidx=0; loopidx < DIM (loopstack); loopidx++)
1373     loopstack[loopidx].collecting = 0;
1374   loopidx = -1;
1375   line = NULL;
1376   linesize = 0;
1377   keep_line = 1;
1378   for (;;)
1379     {
1380       int n;
1381       size_t maxlength = 2048;
1382
1383       assert (loopidx < (int)DIM (loopstack));
1384       if (loopidx >= 0 && loopstack[loopidx].current)
1385         {
1386           keep_line = 0;
1387           xfree (line);
1388           line = xstrdup (loopstack[loopidx].current->line);
1389           n = strlen (line);
1390           /* Never go beyond of the final /end.  */
1391           if (loopstack[loopidx].current->next)
1392             loopstack[loopidx].current = loopstack[loopidx].current->next;
1393           else if (!strncmp (line, "/end", 4) && (!line[4]||spacep(line+4)))
1394             ;
1395           else
1396             log_fatal ("/end command vanished\n");
1397         }
1398       else if (cmdline_commands && *cmdline_commands && !script_fp)
1399         {
1400           keep_line = 0;
1401           xfree (line);
1402           line = xstrdup (*cmdline_commands);
1403           cmdline_commands++;
1404           n = strlen (line);
1405           if (n >= maxlength)
1406             maxlength = 0;
1407         }
1408       else if (use_tty && !script_fp)
1409         {
1410           keep_line = 0;
1411           xfree (line);
1412           line = tty_get ("> ");
1413           n = strlen (line);
1414           if (n==1 && *line == CONTROL_D)
1415             n = 0;
1416           if (n >= maxlength)
1417             maxlength = 0;
1418         }
1419       else
1420         {
1421           if (!keep_line)
1422             {
1423               xfree (line);
1424               line = NULL;
1425               linesize = 0;
1426               keep_line = 1;
1427             }
1428           n = read_line (script_fp? script_fp:stdin,
1429                          &line, &linesize, &maxlength);
1430         }
1431       if (n < 0)
1432         {
1433           log_error (_("error reading input: %s\n"), strerror (errno));
1434           if (script_fp)
1435             {
1436               fclose (script_fp);
1437               script_fp = NULL;
1438               log_error ("stopping script execution\n");
1439               continue;
1440             }
1441           exit (1);
1442         }
1443       if (!n)
1444         {
1445           /* EOF */
1446           if (script_fp)
1447             {
1448               fclose (script_fp);
1449               script_fp = NULL;
1450               if (opt.verbose)
1451                 log_info ("end of script\n");
1452               continue;
1453             }
1454           break;
1455         }
1456       if (!maxlength)
1457         {
1458           log_error (_("line too long - skipped\n"));
1459           continue;
1460         }
1461       if (memchr (line, 0, n))
1462         log_info (_("line shortened due to embedded Nul character\n"));
1463       if (line[n-1] == '\n')
1464         line[n-1] = 0;
1465
1466       if (opt.trim_leading_spaces)
1467         {
1468           const char *s = line;
1469
1470           while (spacep (s))
1471             s++;
1472           if (s != line)
1473             {
1474               for (p=line; *s;)
1475                 *p++ = *s++;
1476               *p = 0;
1477               n = p - line;
1478             }
1479         }
1480
1481       if (loopidx+1 >= 0 && loopstack[loopidx+1].collecting)
1482         {
1483           loopline_t ll;
1484
1485           ll = xmalloc (sizeof *ll + strlen (line));
1486           ll->next = NULL;
1487           strcpy (ll->line, line);
1488           *loopstack[loopidx+1].tail = ll;
1489           loopstack[loopidx+1].tail = &ll->next;
1490
1491           if (!strncmp (line, "/end", 4) && (!line[4]||spacep(line+4)))
1492             loopstack[loopidx+1].nestlevel--;
1493           else if (!strncmp (line, "/while", 6) && (!line[6]||spacep(line+6)))
1494             loopstack[loopidx+1].nestlevel++;
1495
1496           if (loopstack[loopidx+1].nestlevel)
1497             continue;
1498           /* We reached the corresponding /end.  */
1499           loopstack[loopidx+1].collecting = 0;
1500           loopidx++;
1501         }
1502
1503       if (*line == '/')
1504         {
1505           /* Handle control commands. */
1506           char *cmd = line+1;
1507
1508           for (p=cmd; *p && !spacep (p); p++)
1509             ;
1510           if (*p)
1511             *p++ = 0;
1512           while (spacep (p))
1513             p++;
1514           if (!strcmp (cmd, "let"))
1515             {
1516               assign_variable (p, 0);
1517             }
1518           else if (!strcmp (cmd, "slet"))
1519             {
1520               /* Deprecated - never used in a released version.  */
1521               assign_variable (p, 1);
1522             }
1523           else if (!strcmp (cmd, "showvar"))
1524             {
1525               show_variables ();
1526             }
1527           else if (!strcmp (cmd, "definq"))
1528             {
1529               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1530               if (tmpline)
1531                 {
1532                   add_definq (tmpline, 1, 0);
1533                   xfree (tmpline);
1534                 }
1535               else
1536                 add_definq (p, 1, 0);
1537             }
1538           else if (!strcmp (cmd, "definqfile"))
1539             {
1540               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1541               if (tmpline)
1542                 {
1543                   add_definq (tmpline, 0, 0);
1544                   xfree (tmpline);
1545                 }
1546               else
1547                 add_definq (p, 0, 0);
1548             }
1549           else if (!strcmp (cmd, "definqprog"))
1550             {
1551               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1552               if (tmpline)
1553                 {
1554                   add_definq (tmpline, 0, 1);
1555                   xfree (tmpline);
1556                 }
1557               else
1558                 add_definq (p, 0, 1);
1559             }
1560           else if (!strcmp (cmd, "datafile"))
1561             {
1562               const char *fname;
1563
1564               if (current_datasink)
1565                 {
1566                   if (current_datasink != stdout)
1567                     fclose (current_datasink);
1568                   current_datasink = NULL;
1569                 }
1570               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1571               fname = tmpline? tmpline : p;
1572               if (fname && !strcmp (fname, "-"))
1573                 current_datasink = stdout;
1574               else if (fname && *fname)
1575                 {
1576                   current_datasink = fopen (fname, "wb");
1577                   if (!current_datasink)
1578                     log_error ("can't open '%s': %s\n",
1579                                fname, strerror (errno));
1580                 }
1581               xfree (tmpline);
1582             }
1583           else if (!strcmp (cmd, "showdef"))
1584             {
1585               show_definq ();
1586             }
1587           else if (!strcmp (cmd, "cleardef"))
1588             {
1589               clear_definq ();
1590             }
1591           else if (!strcmp (cmd, "echo"))
1592             {
1593               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1594               if (tmpline)
1595                 {
1596                   puts (tmpline);
1597                   xfree (tmpline);
1598                 }
1599               else
1600                 puts (p);
1601             }
1602           else if (!strcmp (cmd, "sendfd"))
1603             {
1604               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1605               if (tmpline)
1606                 {
1607                   do_sendfd (ctx, tmpline);
1608                   xfree (tmpline);
1609                 }
1610               else
1611                 do_sendfd (ctx, p);
1612               continue;
1613             }
1614           else if (!strcmp (cmd, "recvfd"))
1615             {
1616               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1617               if (tmpline)
1618                 {
1619                   do_recvfd (ctx, tmpline);
1620                   xfree (tmpline);
1621                 }
1622               else
1623                 do_recvfd (ctx, p);
1624               continue;
1625             }
1626           else if (!strcmp (cmd, "open"))
1627             {
1628               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1629               if (tmpline)
1630                 {
1631                   do_open (tmpline);
1632                   xfree (tmpline);
1633                 }
1634               else
1635                 do_open (p);
1636             }
1637           else if (!strcmp (cmd, "close"))
1638             {
1639               tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
1640               if (tmpline)
1641                 {
1642                   do_close (tmpline);
1643                   xfree (tmpline);
1644                 }
1645               else
1646                 do_close (p);
1647             }
1648           else if (!strcmp (cmd, "showopen"))
1649             {
1650               do_showopen ();
1651             }
1652           else if (!strcmp (cmd, "serverpid"))
1653             {
1654               do_serverpid (ctx);
1655             }
1656           else if (!strcmp (cmd, "hex"))
1657             opt.hex = 1;
1658           else if (!strcmp (cmd, "nohex"))
1659             opt.hex = 0;
1660           else if (!strcmp (cmd, "decode"))
1661             opt.decode = 1;
1662           else if (!strcmp (cmd, "nodecode"))
1663             opt.decode = 0;
1664           else if (!strcmp (cmd, "subst"))
1665             {
1666               opt.enable_varsubst = 1;
1667               opt.trim_leading_spaces = 1;
1668             }
1669           else if (!strcmp (cmd, "nosubst"))
1670             opt.enable_varsubst = 0;
1671           else if (!strcmp (cmd, "run"))
1672             {
1673               char *p2;
1674
1675               for (p2=p; *p2 && !spacep (p2); p2++)
1676                 ;
1677               if (*p2)
1678                 *p2++ = 0;
1679               while (spacep (p2))
1680                 p++;
1681               if (*p2)
1682                 {
1683                   log_error ("syntax error in run command\n");
1684                   if (script_fp)
1685                     {
1686                       fclose (script_fp);
1687                       script_fp = NULL;
1688                     }
1689                 }
1690               else if (script_fp)
1691                 {
1692                   log_error ("cannot nest run commands - stop\n");
1693                   fclose (script_fp);
1694                   script_fp = NULL;
1695                 }
1696               else if (!(script_fp = fopen (p, "r")))
1697                 {
1698                   log_error ("cannot open run file '%s': %s\n",
1699                              p, strerror (errno));
1700                 }
1701               else if (opt.verbose)
1702                 log_info ("running commands from '%s'\n", p);
1703             }
1704           else if (!strcmp (cmd, "while"))
1705             {
1706               if (loopidx+2 >= (int)DIM(loopstack))
1707                 {
1708                   log_error ("blocks are nested too deep\n");
1709                   /* We should better die or break all loop in this
1710                      case as recovering from this error won't be
1711                      easy.  */
1712                 }
1713               else
1714                 {
1715                   loopstack[loopidx+1].head = NULL;
1716                   loopstack[loopidx+1].tail = &loopstack[loopidx+1].head;
1717                   loopstack[loopidx+1].current = NULL;
1718                   loopstack[loopidx+1].nestlevel = 1;
1719                   loopstack[loopidx+1].oneshot = 0;
1720                   loopstack[loopidx+1].condition = xstrdup (p);
1721                   loopstack[loopidx+1].collecting = 1;
1722                 }
1723             }
1724           else if (!strcmp (cmd, "if"))
1725             {
1726               if (loopidx+2 >= (int)DIM(loopstack))
1727                 {
1728                   log_error ("blocks are nested too deep\n");
1729                 }
1730               else
1731                 {
1732                   /* Note that we need to evaluate the condition right
1733                      away and not just at the end of the block as we
1734                      do with a WHILE. */
1735                   loopstack[loopidx+1].head = NULL;
1736                   loopstack[loopidx+1].tail = &loopstack[loopidx+1].head;
1737                   loopstack[loopidx+1].current = NULL;
1738                   loopstack[loopidx+1].nestlevel = 1;
1739                   loopstack[loopidx+1].oneshot = 1;
1740                   loopstack[loopidx+1].condition = substitute_line_copy (p);
1741                   loopstack[loopidx+1].collecting = 1;
1742                 }
1743             }
1744           else if (!strcmp (cmd, "end"))
1745             {
1746               if (loopidx < 0)
1747                 log_error ("stray /end command encountered - ignored\n");
1748               else
1749                 {
1750                   char *tmpcond;
1751                   const char *value;
1752                   long condition;
1753
1754                   /* Evaluate the condition.  */
1755                   tmpcond = xstrdup (loopstack[loopidx].condition);
1756                   if (loopstack[loopidx].oneshot)
1757                     {
1758                       xfree (loopstack[loopidx].condition);
1759                       loopstack[loopidx].condition = xstrdup ("0");
1760                     }
1761                   tmpline = substitute_line (tmpcond);
1762                   value = tmpline? tmpline : tmpcond;
1763                   /* "true" or "yes" are commonly used to mean TRUE;
1764                      all other strings will evaluate to FALSE due to
1765                      the strtoul.  */
1766                   if (!ascii_strcasecmp (value, "true")
1767                       || !ascii_strcasecmp (value, "yes"))
1768                     condition = 1;
1769                   else
1770                     condition = strtol (value, NULL, 0);
1771                   xfree (tmpline);
1772                   xfree (tmpcond);
1773
1774                   if (condition)
1775                     {
1776                       /* Run loop.  */
1777                       loopstack[loopidx].current = loopstack[loopidx].head;
1778                     }
1779                   else
1780                     {
1781                       /* Cleanup.  */
1782                       while (loopstack[loopidx].head)
1783                         {
1784                           loopline_t tmp = loopstack[loopidx].head->next;
1785                           xfree (loopstack[loopidx].head);
1786                           loopstack[loopidx].head = tmp;
1787                         }
1788                       loopstack[loopidx].tail = NULL;
1789                       loopstack[loopidx].current = NULL;
1790                       loopstack[loopidx].nestlevel = 0;
1791                       loopstack[loopidx].collecting = 0;
1792                       loopstack[loopidx].oneshot = 0;
1793                       xfree (loopstack[loopidx].condition);
1794                       loopstack[loopidx].condition = NULL;
1795                       loopidx--;
1796                     }
1797                 }
1798             }
1799           else if (!strcmp (cmd, "bye"))
1800             {
1801               break;
1802             }
1803           else if (!strcmp (cmd, "sleep"))
1804             {
1805               gnupg_sleep (1);
1806             }
1807           else if (!strcmp (cmd, "help"))
1808             {
1809               puts (
1810 "Available commands:\n"
1811 "/echo ARGS             Echo ARGS.\n"
1812 "/let  NAME VALUE       Set variable NAME to VALUE.\n"
1813 "/showvar               Show all variables.\n"
1814 "/definq NAME VAR       Use content of VAR for inquiries with NAME.\n"
1815 "/definqfile NAME FILE  Use content of FILE for inquiries with NAME.\n"
1816 "/definqprog NAME PGM   Run PGM for inquiries with NAME.\n"
1817 "/datafile [NAME]       Write all D line content to file NAME.\n"
1818 "/showdef               Print all definitions.\n"
1819 "/cleardef              Delete all definitions.\n"
1820 "/sendfd FILE MODE      Open FILE and pass descriptor to server.\n"
1821 "/recvfd                Receive FD from server and print.\n"
1822 "/open VAR FILE MODE    Open FILE and assign the file descriptor to VAR.\n"
1823 "/close FD              Close file with descriptor FD.\n"
1824 "/showopen              Show descriptors of all open files.\n"
1825 "/serverpid             Retrieve the pid of the server.\n"
1826 "/[no]hex               Enable hex dumping of received data lines.\n"
1827 "/[no]decode            Enable decoding of received data lines.\n"
1828 "/[no]subst             Enable variable substitution.\n"
1829 "/run FILE              Run commands from FILE.\n"
1830 "/if VAR                Begin conditional block controlled by VAR.\n"
1831 "/while VAR             Begin loop controlled by VAR.\n"
1832 "/end                   End loop or condition\n"
1833 "/bye                   Terminate gpg-connect-agent.\n"
1834 "/help                  Print this help.");
1835             }
1836           else
1837             log_error (_("unknown command '%s'\n"), cmd );
1838
1839           continue;
1840         }
1841
1842       if (opt.verbose && script_fp)
1843         puts (line);
1844
1845       tmpline = opt.enable_varsubst? substitute_line (line) : NULL;
1846       if (tmpline)
1847         {
1848           rc = assuan_write_line (ctx, tmpline);
1849           xfree (tmpline);
1850         }
1851       else
1852         rc = assuan_write_line (ctx, line);
1853       if (rc)
1854         {
1855           log_info (_("sending line failed: %s\n"), gpg_strerror (rc) );
1856           break;
1857         }
1858       if (*line == '#' || !*line)
1859         continue; /* Don't expect a response for a comment line. */
1860
1861       rc = read_and_print_response (ctx, help_cmd_p (line), &cmderr);
1862       if (rc)
1863         log_info (_("receiving line failed: %s\n"), gpg_strerror (rc) );
1864       if ((rc || cmderr) && script_fp)
1865         {
1866           log_error ("stopping script execution\n");
1867           fclose (script_fp);
1868           script_fp = NULL;
1869         }
1870
1871
1872       /* FIXME: If the last command was BYE or the server died for
1873          some other reason, we won't notice until we get the next
1874          input command.  Probing the connection with a non-blocking
1875          read could help to notice termination or other problems
1876          early.  */
1877     }
1878
1879   if (opt.verbose)
1880     log_info ("closing connection to agent\n");
1881
1882   /* XXX: We would like to release the context here, but libassuan
1883      nicely says good bye to the server, which results in a SIGPIPE if
1884      the server died.  Unfortunately, libassuan does not ignore
1885      SIGPIPE when used with UNIX sockets, hence we simply leak the
1886      context here.  */
1887   if (0)
1888     assuan_release (ctx);
1889   else
1890     gpgrt_annotate_leaked_object (ctx);
1891   xfree (line);
1892   return 0;
1893 }
1894
1895
1896 /* Handle an Inquire from the server.  Return False if it could not be
1897    handled; in this case the caller shll complete the operation.  LINE
1898    is the complete line as received from the server.  This function
1899    may change the content of LINE. */
1900 static int
1901 handle_inquire (assuan_context_t ctx, char *line)
1902 {
1903   const char *name;
1904   definq_t d;
1905   FILE *fp = NULL;
1906   char buffer[1024];
1907   int rc, n;
1908
1909   /* Skip the command and trailing spaces. */
1910   for (; *line && !spacep (line); line++)
1911     ;
1912   while (spacep (line))
1913     line++;
1914   /* Get the name. */
1915   name = line;
1916   for (; *line && !spacep (line); line++)
1917     ;
1918   if (*line)
1919     *line++ = 0;
1920
1921   /* Now match it against our list.  The second loop is there to
1922      detect the match-all entry. */
1923   for (d=definq_list; d; d = d->next)
1924     if (d->name && !strcmp (d->name, name))
1925         break;
1926   if (!d)
1927     for (d=definq_list; d; d = d->next)
1928       if (!d->name)
1929         break;
1930   if (!d)
1931     {
1932       if (opt.verbose)
1933         log_info ("no handler for inquiry '%s' found\n", name);
1934       return 0;
1935     }
1936
1937   if (d->is_var)
1938     {
1939       char *tmpvalue = get_var_ext (d->file);
1940       if (tmpvalue)
1941         rc = assuan_send_data (ctx, tmpvalue, strlen (tmpvalue));
1942       else
1943         rc = assuan_send_data (ctx, "", 0);
1944       xfree (tmpvalue);
1945       if (rc)
1946         log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
1947     }
1948   else
1949     {
1950       if (d->is_prog)
1951         {
1952 #ifdef HAVE_W32CE_SYSTEM
1953           fp = NULL;
1954 #else
1955           fp = popen (d->file, "r");
1956 #endif
1957           if (!fp)
1958             log_error ("error executing '%s': %s\n",
1959                        d->file, strerror (errno));
1960           else if (opt.verbose)
1961             log_error ("handling inquiry '%s' by running '%s'\n",
1962                        name, d->file);
1963         }
1964       else
1965         {
1966           fp = fopen (d->file, "rb");
1967           if (!fp)
1968             log_error ("error opening '%s': %s\n", d->file, strerror (errno));
1969           else if (opt.verbose)
1970             log_error ("handling inquiry '%s' by returning content of '%s'\n",
1971                        name, d->file);
1972         }
1973       if (!fp)
1974         return 0;
1975
1976       while ( (n = fread (buffer, 1, sizeof buffer, fp)) )
1977         {
1978           rc = assuan_send_data (ctx, buffer, n);
1979           if (rc)
1980             {
1981               log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
1982               break;
1983             }
1984         }
1985       if (ferror (fp))
1986         log_error ("error reading from '%s': %s\n", d->file, strerror (errno));
1987     }
1988
1989   rc = assuan_send_data (ctx, NULL, 0);
1990   if (rc)
1991     log_error ("sending data back failed: %s\n", gpg_strerror (rc) );
1992
1993   if (d->is_var)
1994     ;
1995   else if (d->is_prog)
1996     {
1997 #ifndef HAVE_W32CE_SYSTEM
1998       if (pclose (fp))
1999         log_error ("error running '%s': %s\n", d->file, strerror (errno));
2000 #endif
2001     }
2002   else
2003     fclose (fp);
2004   return 1;
2005 }
2006
2007
2008 /* Read all response lines from server and print them.  Returns 0 on
2009    success or an assuan error code.  If WITHHASH istrue, comment lines
2010    are printed.  Sets R_GOTERR to true if the command did not returned
2011    OK.  */
2012 static int
2013 read_and_print_response (assuan_context_t ctx, int withhash, int *r_goterr)
2014 {
2015   char *line;
2016   size_t linelen;
2017   gpg_error_t rc;
2018   int i, j;
2019   int need_lf = 0;
2020
2021   *r_goterr = 0;
2022   for (;;)
2023     {
2024       do
2025         {
2026           rc = assuan_read_line (ctx, &line, &linelen);
2027           if (rc)
2028             return rc;
2029
2030           if ((withhash || opt.verbose > 1) && *line == '#')
2031             {
2032               fwrite (line, linelen, 1, stdout);
2033               putchar ('\n');
2034             }
2035         }
2036       while (*line == '#' || !linelen);
2037
2038       if (linelen >= 1
2039           && line[0] == 'D' && line[1] == ' ')
2040         {
2041           if (current_datasink)
2042             {
2043               const unsigned char *s;
2044               int c = 0;
2045
2046               for (j=2, s=(unsigned char*)line+2; j < linelen; j++, s++ )
2047                 {
2048                   if (*s == '%' && j+2 < linelen)
2049                     {
2050                       s++; j++;
2051                       c = xtoi_2 ( s );
2052                       s++; j++;
2053                     }
2054                   else
2055                     c = *s;
2056                   putc (c, current_datasink);
2057                 }
2058             }
2059           else if (opt.hex)
2060             {
2061               for (i=2; i < linelen; )
2062                 {
2063                   int save_i = i;
2064
2065                   printf ("D[%04X] ", i-2);
2066                   for (j=0; j < 16 ; j++, i++)
2067                     {
2068                       if (j == 8)
2069                         putchar (' ');
2070                       if (i < linelen)
2071                         printf (" %02X", ((unsigned char*)line)[i]);
2072                       else
2073                         fputs ("   ", stdout);
2074                     }
2075                   fputs ("   ", stdout);
2076                   i= save_i;
2077                   for (j=0; j < 16; j++, i++)
2078                     {
2079                       unsigned int c = ((unsigned char*)line)[i];
2080                       if ( i >= linelen )
2081                         putchar (' ');
2082                       else if (isascii (c) && isprint (c) && !iscntrl (c))
2083                         putchar (c);
2084                       else
2085                         putchar ('.');
2086                     }
2087                   putchar ('\n');
2088                 }
2089             }
2090           else if (opt.decode)
2091             {
2092               const unsigned char *s;
2093               int need_d = 1;
2094               int c = 0;
2095
2096               for (j=2, s=(unsigned char*)line+2; j < linelen; j++, s++ )
2097                 {
2098                   if (need_d)
2099                     {
2100                       fputs ("D ", stdout);
2101                       need_d = 0;
2102                     }
2103                   if (*s == '%' && j+2 < linelen)
2104                     {
2105                       s++; j++;
2106                       c = xtoi_2 ( s );
2107                       s++; j++;
2108                     }
2109                   else
2110                     c = *s;
2111                   if (c == '\n')
2112                     need_d = 1;
2113                   putchar (c);
2114                 }
2115               need_lf = (c != '\n');
2116             }
2117           else
2118             {
2119               fwrite (line, linelen, 1, stdout);
2120               putchar ('\n');
2121             }
2122         }
2123       else
2124         {
2125           if (need_lf)
2126             {
2127               if (!current_datasink || current_datasink != stdout)
2128                 putchar ('\n');
2129               need_lf = 0;
2130             }
2131
2132           if (linelen >= 1
2133               && line[0] == 'S'
2134               && (line[1] == '\0' || line[1] == ' '))
2135             {
2136               if (!current_datasink || current_datasink != stdout)
2137                 {
2138                   fwrite (line, linelen, 1, stdout);
2139                   putchar ('\n');
2140                 }
2141             }
2142           else if (linelen >= 2
2143                    && line[0] == 'O' && line[1] == 'K'
2144                    && (line[2] == '\0' || line[2] == ' '))
2145             {
2146               if (!current_datasink || current_datasink != stdout)
2147                 {
2148                   fwrite (line, linelen, 1, stdout);
2149                   putchar ('\n');
2150                 }
2151               set_int_var ("?", 0);
2152               return 0;
2153             }
2154           else if (linelen >= 3
2155                    && line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
2156                    && (line[3] == '\0' || line[3] == ' '))
2157             {
2158               int errval;
2159
2160               errval = strtol (line+3, NULL, 10);
2161               if (!errval)
2162                 errval = -1;
2163               set_int_var ("?", errval);
2164               if (!current_datasink || current_datasink != stdout)
2165                 {
2166                   fwrite (line, linelen, 1, stdout);
2167                   putchar ('\n');
2168                 }
2169               *r_goterr = 1;
2170               return 0;
2171             }
2172           else if (linelen >= 7
2173                    && line[0] == 'I' && line[1] == 'N' && line[2] == 'Q'
2174                    && line[3] == 'U' && line[4] == 'I' && line[5] == 'R'
2175                    && line[6] == 'E'
2176                    && (line[7] == '\0' || line[7] == ' '))
2177             {
2178               if (!current_datasink || current_datasink != stdout)
2179                 {
2180                   fwrite (line, linelen, 1, stdout);
2181                   putchar ('\n');
2182                 }
2183               if (!handle_inquire (ctx, line))
2184                 assuan_write_line (ctx, "CANCEL");
2185             }
2186           else if (linelen >= 3
2187                    && line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
2188                    && (line[3] == '\0' || line[3] == ' '))
2189             {
2190               if (!current_datasink || current_datasink != stdout)
2191                 {
2192                   fwrite (line, linelen, 1, stdout);
2193                   putchar ('\n');
2194                 }
2195               /* Received from server, thus more responses are expected.  */
2196             }
2197           else
2198             return gpg_error (GPG_ERR_ASS_INV_RESPONSE);
2199         }
2200     }
2201 }
2202
2203
2204
2205
2206 /* Connect to the agent and send the standard options.  */
2207 static assuan_context_t
2208 start_agent (void)
2209 {
2210   gpg_error_t err;
2211   assuan_context_t ctx;
2212   session_env_t session_env;
2213
2214   session_env = session_env_new ();
2215   if (!session_env)
2216     log_fatal ("error allocating session environment block: %s\n",
2217                strerror (errno));
2218   if (opt.use_dirmngr)
2219     err = start_new_dirmngr (&ctx,
2220                              GPG_ERR_SOURCE_DEFAULT,
2221                              opt.dirmngr_program,
2222                              opt.autostart,
2223                              !opt.quiet, 0,
2224                              NULL, NULL);
2225   else
2226     err = start_new_gpg_agent (&ctx,
2227                                GPG_ERR_SOURCE_DEFAULT,
2228                                opt.agent_program,
2229                                NULL, NULL,
2230                                session_env,
2231                                opt.autostart,
2232                                !opt.quiet, 0,
2233                                NULL, NULL);
2234
2235   session_env_release (session_env);
2236   if (err)
2237     {
2238       if (!opt.autostart
2239           && (gpg_err_code (err)
2240               == opt.use_dirmngr? GPG_ERR_NO_DIRMNGR : GPG_ERR_NO_AGENT))
2241         {
2242           /* In the no-autostart case we don't make gpg-connect-agent
2243              fail on a missing server.  */
2244           log_info (opt.use_dirmngr?
2245                     _("no dirmngr running in this session\n"):
2246                     _("no gpg-agent running in this session\n"));
2247           exit (0);
2248         }
2249       else
2250         {
2251           log_error (_("error sending standard options: %s\n"),
2252                      gpg_strerror (err));
2253           exit (1);
2254         }
2255     }
2256
2257   return ctx;
2258 }