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