1 /* gpg-connect-agent.c - Tool to connect to the agent.
2 * Copyright (C) 2005, 2007, 2008 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
32 #include "../common/util.h"
33 #include "../common/asshelp.h"
34 #include "../common/sysutils.h"
35 #include "../common/membuf.h"
36 #include "../common/ttyio.h"
37 #ifdef HAVE_W32_SYSTEM
38 # include "../common/exechelp.h"
42 #define CONTROL_D ('D' - 'A' + 1)
43 #define octdigitp(p) (*(p) >= '0' && *(p) <= '7')
45 /* Constants to identify the commands and options. */
46 enum cmd_and_opt_values
65 /* The list of commands and options. */
66 static ARGPARSE_OPTS opts
[] = {
67 ARGPARSE_group (301, N_("@\nOptions:\n ")),
69 ARGPARSE_s_n (oVerbose
, "verbose", N_("verbose")),
70 ARGPARSE_s_n (oQuiet
, "quiet", N_("quiet")),
71 ARGPARSE_s_n (oHex
, "hex", N_("print data out hex encoded")),
72 ARGPARSE_s_n (oDecode
,"decode", N_("decode received data lines")),
73 ARGPARSE_s_s (oRawSocket
, "raw-socket",
74 N_("|NAME|connect to Assuan socket NAME")),
75 ARGPARSE_s_n (oExec
, "exec",
76 N_("run the Assuan server given on the command line")),
77 ARGPARSE_s_n (oNoExtConnect
, "no-ext-connect",
78 N_("do not use extended connect mode")),
79 ARGPARSE_s_s (oRun
, "run",
80 N_("|FILE|run commands from FILE on startup")),
81 ARGPARSE_s_n (oSubst
, "subst", N_("run /subst on startup")),
83 ARGPARSE_s_n (oNoVerbose
, "no-verbose", "@"),
84 ARGPARSE_s_s (oHomedir
, "homedir", "@" ),
90 /* We keep all global options in the structure OPT. */
93 int verbose
; /* Verbosity level. */
94 int quiet
; /* Be extra quiet. */
95 const char *homedir
; /* Configuration directory name */
96 int hex
; /* Print data lines in hex format. */
97 int decode
; /* Decode received data lines. */
98 const char *raw_socket
; /* Name of socket to connect in raw mode. */
99 int exec
; /* Run the pgm given on the command line. */
100 unsigned int connect_flags
; /* Flags used for connecting. */
101 int enable_varsubst
; /* Set if variable substitution is enabled. */
102 int trim_leading_spaces
;
107 /* Definitions for /definq commands and a global linked list with all
111 struct definq_s
*next
;
112 char *name
; /* Name of inquiry or NULL for any name. */
113 int is_var
; /* True if FILE is a variable name. */
114 int is_prog
; /* True if FILE is a program to run. */
115 char file
[1]; /* Name of file or program. */
117 typedef struct definq_s
*definq_t
;
119 static definq_t definq_list
;
120 static definq_t
*definq_list_tail
= &definq_list
;
123 /* Variable definitions and glovbal table. */
126 struct variable_s
*next
;
127 char *value
; /* Malloced value - always a string. */
128 char name
[1]; /* Name of the variable. */
130 typedef struct variable_s
*variable_t
;
132 static variable_t variable_table
;
135 /* To implement loops we store entire lines in a linked list. */
138 struct loopline_s
*next
;
141 typedef struct loopline_s
*loopline_t
;
144 /* This is used to store the pid of the server. */
145 static pid_t server_pid
= (pid_t
)(-1);
147 /* The current datasink file or NULL. */
148 static FILE *current_datasink
;
150 /* A list of open file descriptors. */
154 #ifdef HAVE_W32_SYSTEM
157 } open_fd_table
[256];
160 /*-- local prototypes --*/
161 static char *substitute_line_copy (const char *buffer
);
162 static int read_and_print_response (assuan_context_t ctx
, int withhash
,
164 static assuan_context_t
start_agent (void);
169 /* Print usage information and and provide strings for help. */
171 my_strusage( int level
)
177 case 11: p
= "gpg-connect-agent (GnuPG)";
179 case 13: p
= VERSION
; break;
180 case 17: p
= PRINTABLE_OS_NAME
; break;
181 case 19: p
= _("Please report bugs to <@EMAIL@>.\n"); break;
184 case 40: p
= _("Usage: gpg-connect-agent [options] (-h for help)");
187 p
= _("Syntax: gpg-connect-agent [options]\n"
188 "Connect to a running agent and send commands\n");
190 case 31: p
= "\nHome: "; break;
191 case 32: p
= opt
.homedir
; break;
192 case 33: p
= "\n"; break;
194 default: p
= NULL
; break;
208 buffer
= xmalloc (size
+1);
209 if (getcwd (buffer
, size
) == buffer
)
219 /* Unescape STRING and returned the malloced result. The surrounding
220 quotes must already be removed from STRING. */
222 unescape_string (const char *string
)
224 const unsigned char *s
;
231 for (s
= (const unsigned char*)string
, esc
=0; *s
; s
++)
245 case '\\': n
++; break;
247 if (s
[1] && s
[2] && hexdigitp (s
+1) && hexdigitp (s
+2))
253 && octdigitp (s
) && octdigitp (s
+1) && octdigitp (s
+2))
265 buffer
= xmalloc (n
+1);
266 d
= (unsigned char*)buffer
;
267 for (s
= (const unsigned char*)string
, esc
=0; *s
; s
++)
273 case 'b': *d
++ = '\b'; break;
274 case 't': *d
++ = '\t'; break;
275 case 'v': *d
++ = '\v'; break;
276 case 'n': *d
++ = '\n'; break;
277 case 'f': *d
++ = '\f'; break;
278 case 'r': *d
++ = '\r'; break;
279 case '"': *d
++ = '\"'; break;
280 case '\'': *d
++ = '\''; break;
281 case '\\': *d
++ = '\\'; break;
283 if (s
[1] && s
[2] && hexdigitp (s
+1) && hexdigitp (s
+2))
293 && octdigitp (s
) && octdigitp (s
+1) && octdigitp (s
+2))
295 *d
++ = (atoi_1 (s
)*64) + (atoi_1 (s
+1)*8) + atoi_1 (s
+2);
312 /* Do the percent unescaping and return a newly malloced string.
313 If WITH_PLUS is set '+' characters will be changed to space. */
315 unpercent_string (const char *string
, int with_plus
)
317 const unsigned char *s
;
318 unsigned char *buffer
, *p
;
322 for (s
=(const unsigned char *)string
; *s
; s
++)
324 if (*s
== '%' && s
[1] && s
[2])
330 else if (with_plus
&& *s
== '+')
336 buffer
= xmalloc (n
+1);
338 for (s
=(const unsigned char *)string
; *s
; s
++)
340 if (*s
== '%' && s
[1] && s
[2])
346 else if (with_plus
&& *s
== '+')
352 return (char*)buffer
;
360 set_var (const char *name
, const char *value
)
364 for (var
= variable_table
; var
; var
= var
->next
)
365 if (!strcmp (var
->name
, name
))
369 var
= xmalloc (sizeof *var
+ strlen (name
));
371 strcpy (var
->name
, name
);
372 var
->next
= variable_table
;
373 variable_table
= var
;
376 var
->value
= value
? xstrdup (value
) : NULL
;
382 set_int_var (const char *name
, int value
)
386 snprintf (numbuf
, sizeof numbuf
, "%d", value
);
387 set_var (name
, numbuf
);
391 /* Return the value of a variable. That value is valid until a
392 variable of the name is changed. Return NULL if not found. Note
393 that envvars are copied to our variable list at the first access
394 and not at oprogram start. */
396 get_var (const char *name
)
403 for (var
= variable_table
; var
; var
= var
->next
)
404 if (!strcmp (var
->name
, name
))
406 if (!var
&& (s
= getenv (name
)))
407 return set_var (name
, s
);
408 if (!var
|| !var
->value
)
414 /* Perform some simple arithmentic operations. Caller must release
415 the return value. On error the return value is NULL. */
417 arithmetic_op (int operator, const char *operands
)
422 while ( spacep (operands
) )
426 result
= strtol (operands
, NULL
, 0);
427 while (*operands
&& !spacep (operands
) )
434 while ( spacep (operands
) )
438 value
= strtol (operands
, NULL
, 0);
439 while (*operands
&& !spacep (operands
) )
443 case '+': result
+= value
; break;
444 case '-': result
-= value
; break;
445 case '*': result
*= value
; break;
456 case '!': result
= !value
; break;
457 case '|': result
= result
|| value
; break;
458 case '&': result
= result
&& value
; break;
460 log_error ("unknown arithmetic operator `%c'\n", operator);
464 snprintf (numbuf
, sizeof numbuf
, "%ld", result
);
465 return xstrdup (numbuf
);
470 /* Extended version of get_var. This returns a malloced string and
471 understand the function syntax: "func args".
473 Defined functions are
475 get - Return a value described by the next argument:
476 cwd - The current working directory.
477 homedir - The gnupg homedir.
478 sysconfdir - GnuPG's system configuration directory.
479 bindir - GnuPG's binary directory.
480 libdir - GnuPG's library directory.
481 libexecdir - GnuPG's library directory for executable files.
482 datadir - GnuPG's data directory.
483 serverpid - The PID of the current server.
486 Remove C-style escapes from string. Note that "\0" and
487 "\x00" terminate the string implictly. Use "\x7d" to
488 represent the closing brace. The args start right after
489 the first space after the function name.
493 Remove percent style ecaping from string. Note that "%00
494 terminates the string implicitly. Use "%7d" to represetn
495 the closing brace. The args start right after the first
496 space after the function name. "unpercent+" also maps '+'
501 Escape the args using the percent style. Tabs, formfeeds,
502 linefeeds and carriage returns are also escaped.
503 "percent+" also maps spaces to plus characters.
506 Assuming ARG is an integer, return the gpg-error code.
509 Assuming ARG is an integer, return the gpg-error source.
512 Assuming ARG is an integer return a formatted fpf error string.
515 Example: get_var_ext ("get sysconfdir") -> "/etc/gnupg"
519 get_var_ext (const char *name
)
521 static int recursion_count
;
525 char *free_me
= NULL
;
528 if (recursion_count
> 50)
530 log_error ("variables nested too deeply\n");
535 free_me
= opt
.enable_varsubst
? substitute_line_copy (name
) : NULL
;
538 for (s
=name
; *s
&& !spacep (s
); s
++)
543 result
= s
? xstrdup (s
): NULL
;
545 else if ( (s
- name
) == 3 && !strncmp (name
, "get", 3))
549 if (!strcmp (s
, "cwd"))
551 result
= gnu_getcwd ();
553 log_error ("getcwd failed: %s\n", strerror (errno
));
555 else if (!strcmp (s
, "homedir"))
556 result
= make_filename (opt
.homedir
, NULL
);
557 else if (!strcmp (s
, "sysconfdir"))
558 result
= xstrdup (gnupg_sysconfdir ());
559 else if (!strcmp (s
, "bindir"))
560 result
= xstrdup (gnupg_bindir ());
561 else if (!strcmp (s
, "libdir"))
562 result
= xstrdup (gnupg_libdir ());
563 else if (!strcmp (s
, "libexecdir"))
564 result
= xstrdup (gnupg_libexecdir ());
565 else if (!strcmp (s
, "datadir"))
566 result
= xstrdup (gnupg_datadir ());
567 else if (!strcmp (s
, "serverpid"))
568 result
= xasprintf ("%d", (int)server_pid
);
571 log_error ("invalid argument `%s' for variable function `get'\n", s
);
572 log_info ("valid are: cwd, "
573 "{home,bin,lib,libexec,data}dir, serverpid\n");
577 else if ( (s
- name
) == 8 && !strncmp (name
, "unescape", 8))
580 result
= unescape_string (s
);
582 else if ( (s
- name
) == 9 && !strncmp (name
, "unpercent", 9))
585 result
= unpercent_string (s
, 0);
587 else if ( (s
- name
) == 10 && !strncmp (name
, "unpercent+", 10))
590 result
= unpercent_string (s
, 1);
592 else if ( (s
- name
) == 7 && !strncmp (name
, "percent", 7))
595 result
= percent_escape (s
, "\t\r\n\f\v");
597 else if ( (s
- name
) == 8 && !strncmp (name
, "percent+", 8))
600 result
= percent_escape (s
, "\t\r\n\f\v");
601 for (p
=result
; *p
; p
++)
605 else if ( (s
- name
) == 7 && !strncmp (name
, "errcode", 7))
608 intvalue
= (int)strtol (s
, NULL
, 0);
609 result
= xasprintf ("%d", gpg_err_code (intvalue
));
611 else if ( (s
- name
) == 9 && !strncmp (name
, "errsource", 9))
614 intvalue
= (int)strtol (s
, NULL
, 0);
615 result
= xasprintf ("%d", gpg_err_source (intvalue
));
617 else if ( (s
- name
) == 9 && !strncmp (name
, "errstring", 9))
620 intvalue
= (int)strtol (s
, NULL
, 0);
621 result
= xasprintf ("%s <%s>",
622 gpg_strerror (intvalue
), gpg_strsource (intvalue
));
624 else if ( (s
- name
) == 1 && strchr ("+-*/%!|&", *name
))
626 result
= arithmetic_op (*name
, s
+1);
630 log_error ("unknown variable function `%.*s'\n", (int)(s
-name
), name
);
640 /* Substitute variables in LINE and return a new allocated buffer if
641 required. The function might modify LINE if the expanded version
644 substitute_line (char *buffer
)
655 p
= strchr (line
, '$');
657 return result
; /* No more variables. */
659 if (p
[1] == '$') /* Escaped dollar sign. */
661 memmove (p
, p
+1, strlen (p
+1)+1);
669 for (pend
=p
+2; *pend
; pend
++)
673 else if (*pend
== '}')
680 return result
; /* Unclosed - don't substitute. */
684 for (pend
=p
+1; *pend
&& !spacep (pend
) && *pend
!= '$' ; pend
++)
687 if (p
[1] == '{' && *pend
== '}')
691 freeme
= get_var_ext (p
+2);
699 value
= get_var (p
+1);
703 value
= get_var (p
+1);
706 valuelen
= strlen (value
);
707 if (valuelen
<= pend
- p
)
709 memcpy (p
, value
, valuelen
);
713 memmove (p
, p
+n
, strlen (p
+n
)+1);
718 char *src
= result
? result
: buffer
;
721 dst
= xmalloc (strlen (src
) + valuelen
+ 1);
723 memcpy (dst
, src
, n
);
724 memcpy (dst
+ n
, value
, valuelen
);
726 strcpy (dst
+ n
, pend
);
737 /* Same as substitute_line but do not modify BUFFER. */
739 substitute_line_copy (const char *buffer
)
743 p
= xstrdup (buffer
?buffer
:"");
744 result
= substitute_line (p
);
754 assign_variable (char *line
, int syslet
)
756 char *name
, *p
, *tmp
, *free_me
, *buffer
;
760 for (p
=name
; *p
&& !spacep (p
); p
++)
768 set_var (name
, NULL
); /* Remove variable. */
771 free_me
= opt
.enable_varsubst
? substitute_line_copy (p
) : NULL
;
774 buffer
= xmalloc (4 + strlen (p
) + 1);
775 strcpy (stpcpy (buffer
, "get "), p
);
776 tmp
= get_var_ext (buffer
);
784 tmp
= opt
.enable_varsubst
? substitute_line_copy (p
) : NULL
;
797 show_variables (void)
801 for (var
= variable_table
; var
; var
= var
->next
)
803 printf ("%-20s %s\n", var
->name
, var
->value
);
807 /* Store an inquire response pattern. Note, that this function may
808 change the content of LINE. We assume that leading white spaces
809 are already removed. */
811 add_definq (char *line
, int is_var
, int is_prog
)
818 for (p
=name
; *p
&& !spacep (p
); p
++)
825 d
= xmalloc (sizeof *d
+ strlen (p
) );
828 d
->is_prog
= is_prog
;
829 if ( !strcmp (name
, "*"))
832 d
->name
= xstrdup (name
);
835 *definq_list_tail
= d
;
836 definq_list_tail
= &d
->next
;
840 /* Show all inquiry defintions. */
846 for (d
=definq_list
; d
; d
= d
->next
)
848 printf ("%-20s %c %s\n",
849 d
->name
, d
->is_var
? 'v' : d
->is_prog
? 'p':'f', d
->file
);
850 for (d
=definq_list
; d
; d
= d
->next
)
852 printf ("%-20s %c %s\n", "*",
853 d
->is_var
? 'v': d
->is_prog
? 'p':'f', d
->file
);
857 /* Clear all inquiry definitions. */
863 definq_t tmp
= definq_list
->next
;
864 xfree (definq_list
->name
);
868 definq_list_tail
= &definq_list
;
873 do_sendfd (assuan_context_t ctx
, char *line
)
876 char *name
, *mode
, *p
;
881 for (p
=name
; *p
&& !spacep (p
); p
++)
894 for (p
=mode
; *p
&& !spacep (p
); p
++)
901 fp
= fopen (name
, mode
);
904 log_error ("can't open `%s' in \"%s\" mode: %s\n",
905 name
, mode
, strerror (errno
));
911 log_error ("file `%s' opened in \"%s\" mode, fd=%d\n",
914 rc
= assuan_sendfd (ctx
, INT2FD (fd
) );
916 log_error ("sending descriptor %d failed: %s\n", fd
, gpg_strerror (rc
));
922 do_recvfd (assuan_context_t ctx
, char *line
)
926 log_info ("This command has not yet been implemented\n");
934 char *varname
, *name
, *mode
, *p
;
937 #ifdef HAVE_W32_SYSTEM
938 if (server_pid
== (pid_t
)(-1))
940 log_error ("the pid of the server is unknown\n");
941 log_info ("use command \"/serverpid\" first\n");
946 /* Get variable name. */
948 for (p
=varname
; *p
&& !spacep (p
); p
++)
957 for (p
=name
; *p
&& !spacep (p
); p
++)
970 for (p
=mode
; *p
&& !spacep (p
); p
++)
977 fp
= fopen (name
, mode
);
980 log_error ("can't open `%s' in \"%s\" mode: %s\n",
981 name
, mode
, strerror (errno
));
985 if (fd
>= 0 && fd
< DIM (open_fd_table
))
987 open_fd_table
[fd
].inuse
= 1;
988 #ifdef HAVE_W32_SYSTEM
990 HANDLE prochandle
, handle
, newhandle
;
992 handle
= (void*)_get_osfhandle (fd
);
994 prochandle
= OpenProcess (PROCESS_DUP_HANDLE
, FALSE
, server_pid
);
997 log_error ("failed to open the server process\n");
1002 if (!DuplicateHandle (GetCurrentProcess(), handle
,
1003 prochandle
, &newhandle
, 0,
1004 TRUE
, DUPLICATE_SAME_ACCESS
))
1006 log_error ("failed to duplicate the handle\n");
1008 CloseHandle (prochandle
);
1011 CloseHandle (prochandle
);
1012 open_fd_table
[fd
].handle
= newhandle
;
1015 log_info ("file `%s' opened in \"%s\" mode, fd=%d (libc=%d)\n",
1016 name
, mode
, (int)open_fd_table
[fd
].handle
, fd
);
1017 set_int_var (varname
, (int)open_fd_table
[fd
].handle
);
1020 log_info ("file `%s' opened in \"%s\" mode, fd=%d\n",
1022 set_int_var (varname
, fd
);
1027 log_error ("can't put fd %d into table\n", fd
);
1034 do_close (char *line
)
1036 int fd
= atoi (line
);
1038 #ifdef HAVE_W32_SYSTEM
1041 for (i
=0; i
< DIM (open_fd_table
); i
++)
1042 if ( open_fd_table
[i
].inuse
&& open_fd_table
[i
].handle
== (void*)fd
)
1044 if (i
< DIM (open_fd_table
))
1048 log_error ("given fd (system handle) has not been opened\n");
1053 if (fd
< 0 || fd
>= DIM (open_fd_table
))
1055 log_error ("invalid fd\n");
1059 if (!open_fd_table
[fd
].inuse
)
1061 log_error ("given fd has not been opened\n");
1064 #ifdef HAVE_W32_SYSTEM
1065 CloseHandle (open_fd_table
[fd
].handle
); /* Close duped handle. */
1068 open_fd_table
[fd
].inuse
= 0;
1077 for (i
=0; i
< DIM (open_fd_table
); i
++)
1078 if (open_fd_table
[i
].inuse
)
1080 #ifdef HAVE_W32_SYSTEM
1081 printf ("%-15d (libc=%d)\n", (int)open_fd_table
[i
].handle
, i
);
1083 printf ("%-15d\n", i
);
1091 getinfo_pid_cb (void *opaque
, const void *buffer
, size_t length
)
1093 membuf_t
*mb
= opaque
;
1094 put_membuf (mb
, buffer
, length
);
1098 /* Get the pid of the server and store it locally. */
1100 do_serverpid (assuan_context_t ctx
)
1106 init_membuf (&mb
, 100);
1107 rc
= assuan_transact (ctx
, "GETINFO pid", getinfo_pid_cb
, &mb
,
1108 NULL
, NULL
, NULL
, NULL
);
1109 put_membuf (&mb
, "", 1);
1110 buffer
= get_membuf (&mb
, NULL
);
1112 log_error ("command \"%s\" failed: %s\n",
1113 "GETINFO pid", gpg_strerror (rc
));
1116 server_pid
= (pid_t
)strtoul (buffer
, NULL
, 10);
1118 log_info ("server's PID is %lu\n", (unsigned long)server_pid
);
1124 /* gpg-connect-agent's entry point. */
1126 main (int argc
, char **argv
)
1128 ARGPARSE_ARGS pargs
;
1129 int no_more_options
= 0;
1130 assuan_context_t ctx
;
1136 const char *opt_run
= NULL
;
1137 FILE *script_fp
= NULL
;
1138 int use_tty
, keep_line
;
1144 unsigned int nestlevel
;
1149 char **cmdline_commands
= NULL
;
1151 gnupg_rl_initialize ();
1152 set_strusage (my_strusage
);
1153 log_set_prefix ("gpg-connect-agent", 1);
1155 /* Make sure that our subsystems are ready. */
1157 init_common_subsystems ();
1159 assuan_set_gpg_err_source (0);
1162 opt
.homedir
= default_homedir ();
1163 opt
.connect_flags
= 1; /* Use extended connect mode. */
1165 /* Parse the command line. */
1168 pargs
.flags
= 1; /* Do not remove the args. */
1169 while (!no_more_options
&& optfile_parse (NULL
, NULL
, NULL
, &pargs
, opts
))
1171 switch (pargs
.r_opt
)
1173 case oQuiet
: opt
.quiet
= 1; break;
1174 case oVerbose
: opt
.verbose
++; break;
1175 case oNoVerbose
: opt
.verbose
= 0; break;
1176 case oHomedir
: opt
.homedir
= pargs
.r
.ret_str
; break;
1177 case oHex
: opt
.hex
= 1; break;
1178 case oDecode
: opt
.decode
= 1; break;
1179 case oRawSocket
: opt
.raw_socket
= pargs
.r
.ret_str
; break;
1180 case oExec
: opt
.exec
= 1; break;
1181 case oNoExtConnect
: opt
.connect_flags
&= ~(1); break;
1182 case oRun
: opt_run
= pargs
.r
.ret_str
; break;
1184 opt
.enable_varsubst
= 1;
1185 opt
.trim_leading_spaces
= 1;
1188 default: pargs
.err
= 2; break;
1192 if (log_get_errorcount (0))
1195 use_tty
= (isatty ( fileno (stdin
)) && isatty (fileno (stdout
)));
1201 log_error (_("option \"%s\" requires a program "
1202 "and optional arguments\n"), "--exec" );
1207 cmdline_commands
= argv
;
1209 if (opt
.exec
&& opt
.raw_socket
)
1210 log_info (_("option \"%s\" ignored due to \"%s\"\n"),
1211 "--raw-socket", "--exec");
1213 if (opt_run
&& !(script_fp
= fopen (opt_run
, "r")))
1215 log_error ("cannot open run file `%s': %s\n",
1216 opt_run
, strerror (errno
));
1225 no_close
[0] = fileno (stderr
);
1226 no_close
[1] = log_get_fd ();
1229 rc
= assuan_new (&ctx
);
1232 log_error ("assuan_new failed: %s\n", gpg_strerror (rc
));
1236 rc
= assuan_pipe_connect_ext (ctx
, *argv
, (const char **)argv
,
1237 no_close
, NULL
, NULL
,
1241 log_error ("assuan_pipe_connect_ext failed: %s\n",
1247 log_info ("server `%s' started\n", *argv
);
1250 else if (opt
.raw_socket
)
1252 rc
= assuan_new (&ctx
);
1255 log_error ("assuan_new failed: %s\n", gpg_strerror (rc
));
1259 rc
= assuan_socket_connect_ext (ctx
, opt
.raw_socket
, 0,
1263 log_error ("can't connect to socket `%s': %s\n",
1264 opt
.raw_socket
, gpg_strerror (rc
));
1269 log_info ("connection to socket `%s' established\n", opt
.raw_socket
);
1272 ctx
= start_agent ();
1274 /* See whether there is a line pending from the server (in case
1275 assuan did not run the initial handshaking). */
1276 if (assuan_pending_line (ctx
))
1278 rc
= read_and_print_response (ctx
, 0, &cmderr
);
1280 log_info (_("receiving line failed: %s\n"), gpg_strerror (rc
) );
1284 for (loopidx
=0; loopidx
< DIM (loopstack
); loopidx
++)
1285 loopstack
[loopidx
].collecting
= 0;
1293 size_t maxlength
= 2048;
1295 assert (loopidx
< (int)DIM (loopstack
));
1296 if (loopidx
>= 0 && loopstack
[loopidx
].current
)
1300 line
= xstrdup (loopstack
[loopidx
].current
->line
);
1302 /* Never go beyond of the final /end. */
1303 if (loopstack
[loopidx
].current
->next
)
1304 loopstack
[loopidx
].current
= loopstack
[loopidx
].current
->next
;
1305 else if (!strncmp (line
, "/end", 4) && (!line
[4]||spacep(line
+4)))
1308 log_fatal ("/end command vanished\n");
1310 else if (cmdline_commands
&& *cmdline_commands
&& !script_fp
)
1314 line
= xstrdup (*cmdline_commands
);
1320 else if (use_tty
&& !script_fp
)
1324 line
= tty_get ("> ");
1326 if (n
==1 && *line
== CONTROL_D
)
1340 n
= read_line (script_fp
? script_fp
:stdin
,
1341 &line
, &linesize
, &maxlength
);
1345 log_error (_("error reading input: %s\n"), strerror (errno
));
1350 log_error ("stopping script execution\n");
1363 log_info ("end of script\n");
1370 log_error (_("line too long - skipped\n"));
1373 if (memchr (line
, 0, n
))
1374 log_info (_("line shortened due to embedded Nul character\n"));
1375 if (line
[n
-1] == '\n')
1378 if (opt
.trim_leading_spaces
)
1380 const char *s
= line
;
1393 if (loopidx
+1 >= 0 && loopstack
[loopidx
+1].collecting
)
1397 ll
= xmalloc (sizeof *ll
+ strlen (line
));
1399 strcpy (ll
->line
, line
);
1400 *loopstack
[loopidx
+1].tail
= ll
;
1401 loopstack
[loopidx
+1].tail
= &ll
->next
;
1403 if (!strncmp (line
, "/end", 4) && (!line
[4]||spacep(line
+4)))
1404 loopstack
[loopidx
+1].nestlevel
--;
1405 else if (!strncmp (line
, "/while", 6) && (!line
[6]||spacep(line
+6)))
1406 loopstack
[loopidx
+1].nestlevel
++;
1408 if (loopstack
[loopidx
+1].nestlevel
)
1410 /* We reached the corresponding /end. */
1411 loopstack
[loopidx
+1].collecting
= 0;
1417 /* Handle control commands. */
1420 for (p
=cmd
; *p
&& !spacep (p
); p
++)
1426 if (!strcmp (cmd
, "let"))
1428 assign_variable (p
, 0);
1430 else if (!strcmp (cmd
, "slet"))
1432 /* Deprecated - never used in a released version. */
1433 assign_variable (p
, 1);
1435 else if (!strcmp (cmd
, "showvar"))
1439 else if (!strcmp (cmd
, "definq"))
1441 tmpline
= opt
.enable_varsubst
? substitute_line (p
) : NULL
;
1444 add_definq (tmpline
, 1, 0);
1448 add_definq (p
, 1, 0);
1450 else if (!strcmp (cmd
, "definqfile"))
1452 tmpline
= opt
.enable_varsubst
? substitute_line (p
) : NULL
;
1455 add_definq (tmpline
, 0, 0);
1459 add_definq (p
, 0, 0);
1461 else if (!strcmp (cmd
, "definqprog"))
1463 tmpline
= opt
.enable_varsubst
? substitute_line (p
) : NULL
;
1466 add_definq (tmpline
, 0, 1);
1470 add_definq (p
, 0, 1);
1472 else if (!strcmp (cmd
, "datafile"))
1476 if (current_datasink
)
1478 if (current_datasink
!= stdout
)
1479 fclose (current_datasink
);
1480 current_datasink
= NULL
;
1482 tmpline
= opt
.enable_varsubst
? substitute_line (p
) : NULL
;
1483 fname
= tmpline
? tmpline
: p
;
1484 if (fname
&& !strcmp (fname
, "-"))
1485 current_datasink
= stdout
;
1486 else if (fname
&& *fname
)
1488 current_datasink
= fopen (fname
, "wb");
1489 if (!current_datasink
)
1490 log_error ("can't open `%s': %s\n",
1491 fname
, strerror (errno
));
1495 else if (!strcmp (cmd
, "showdef"))
1499 else if (!strcmp (cmd
, "cleardef"))
1503 else if (!strcmp (cmd
, "echo"))
1505 tmpline
= opt
.enable_varsubst
? substitute_line (p
) : NULL
;
1514 else if (!strcmp (cmd
, "sendfd"))
1516 tmpline
= opt
.enable_varsubst
? substitute_line (p
) : NULL
;
1519 do_sendfd (ctx
, tmpline
);
1526 else if (!strcmp (cmd
, "recvfd"))
1528 tmpline
= opt
.enable_varsubst
? substitute_line (p
) : NULL
;
1531 do_recvfd (ctx
, tmpline
);
1538 else if (!strcmp (cmd
, "open"))
1540 tmpline
= opt
.enable_varsubst
? substitute_line (p
) : NULL
;
1549 else if (!strcmp (cmd
, "close"))
1551 tmpline
= opt
.enable_varsubst
? substitute_line (p
) : NULL
;
1560 else if (!strcmp (cmd
, "showopen"))
1564 else if (!strcmp (cmd
, "serverpid"))
1568 else if (!strcmp (cmd
, "hex"))
1570 else if (!strcmp (cmd
, "nohex"))
1572 else if (!strcmp (cmd
, "decode"))
1574 else if (!strcmp (cmd
, "nodecode"))
1576 else if (!strcmp (cmd
, "subst"))
1578 opt
.enable_varsubst
= 1;
1579 opt
.trim_leading_spaces
= 1;
1581 else if (!strcmp (cmd
, "nosubst"))
1582 opt
.enable_varsubst
= 0;
1583 else if (!strcmp (cmd
, "run"))
1587 for (p2
=p
; *p2
&& !spacep (p2
); p2
++)
1595 log_error ("syntax error in run command\n");
1604 log_error ("cannot nest run commands - stop\n");
1608 else if (!(script_fp
= fopen (p
, "r")))
1610 log_error ("cannot open run file `%s': %s\n",
1611 p
, strerror (errno
));
1613 else if (opt
.verbose
)
1614 log_info ("running commands from `%s'\n", p
);
1616 else if (!strcmp (cmd
, "while"))
1618 if (loopidx
+2 >= (int)DIM(loopstack
))
1620 log_error ("blocks are nested too deep\n");
1621 /* We should better die or break all loop in this
1622 case as recovering from this error won't be
1627 loopstack
[loopidx
+1].head
= NULL
;
1628 loopstack
[loopidx
+1].tail
= &loopstack
[loopidx
+1].head
;
1629 loopstack
[loopidx
+1].current
= NULL
;
1630 loopstack
[loopidx
+1].nestlevel
= 1;
1631 loopstack
[loopidx
+1].oneshot
= 0;
1632 loopstack
[loopidx
+1].condition
= xstrdup (p
);
1633 loopstack
[loopidx
+1].collecting
= 1;
1636 else if (!strcmp (cmd
, "if"))
1638 if (loopidx
+2 >= (int)DIM(loopstack
))
1640 log_error ("blocks are nested too deep\n");
1644 /* Note that we need to evaluate the condition right
1645 away and not just at the end of the block as we
1647 loopstack
[loopidx
+1].head
= NULL
;
1648 loopstack
[loopidx
+1].tail
= &loopstack
[loopidx
+1].head
;
1649 loopstack
[loopidx
+1].current
= NULL
;
1650 loopstack
[loopidx
+1].nestlevel
= 1;
1651 loopstack
[loopidx
+1].oneshot
= 1;
1652 loopstack
[loopidx
+1].condition
= substitute_line_copy (p
);
1653 loopstack
[loopidx
+1].collecting
= 1;
1656 else if (!strcmp (cmd
, "end"))
1659 log_error ("stray /end command encountered - ignored\n");
1666 /* Evaluate the condition. */
1667 tmpcond
= xstrdup (loopstack
[loopidx
].condition
);
1668 if (loopstack
[loopidx
].oneshot
)
1670 xfree (loopstack
[loopidx
].condition
);
1671 loopstack
[loopidx
].condition
= xstrdup ("0");
1673 tmpline
= substitute_line (tmpcond
);
1674 value
= tmpline
? tmpline
: tmpcond
;
1675 condition
= strtol (value
, NULL
, 0);
1682 loopstack
[loopidx
].current
= loopstack
[loopidx
].head
;
1687 while (loopstack
[loopidx
].head
)
1689 loopline_t tmp
= loopstack
[loopidx
].head
->next
;
1690 xfree (loopstack
[loopidx
].head
);
1691 loopstack
[loopidx
].head
= tmp
;
1693 loopstack
[loopidx
].tail
= NULL
;
1694 loopstack
[loopidx
].current
= NULL
;
1695 loopstack
[loopidx
].nestlevel
= 0;
1696 loopstack
[loopidx
].collecting
= 0;
1697 loopstack
[loopidx
].oneshot
= 0;
1698 xfree (loopstack
[loopidx
].condition
);
1699 loopstack
[loopidx
].condition
= NULL
;
1704 else if (!strcmp (cmd
, "bye"))
1708 else if (!strcmp (cmd
, "sleep"))
1712 else if (!strcmp (cmd
, "help"))
1715 "Available commands:\n"
1716 "/echo ARGS Echo ARGS.\n"
1717 "/let NAME VALUE Set variable NAME to VALUE.\n"
1718 "/showvar Show all variables.\n"
1719 "/definq NAME VAR Use content of VAR for inquiries with NAME.\n"
1720 "/definqfile NAME FILE Use content of FILE for inquiries with NAME.\n"
1721 "/definqprog NAME PGM Run PGM for inquiries with NAME.\n"
1722 "/datafile [NAME] Write all D line content to file NAME.\n"
1723 "/showdef Print all definitions.\n"
1724 "/cleardef Delete all definitions.\n"
1725 "/sendfd FILE MODE Open FILE and pass descriptor to server.\n"
1726 "/recvfd Receive FD from server and print.\n"
1727 "/open VAR FILE MODE Open FILE and assign the file descriptor to VAR.\n"
1728 "/close FD Close file with descriptor FD.\n"
1729 "/showopen Show descriptors of all open files.\n"
1730 "/serverpid Retrieve the pid of the server.\n"
1731 "/[no]hex Enable hex dumping of received data lines.\n"
1732 "/[no]decode Enable decoding of received data lines.\n"
1733 "/[no]subst Enable variable substitution.\n"
1734 "/run FILE Run commands from FILE.\n"
1735 "/if VAR Begin conditional block controlled by VAR.\n"
1736 "/while VAR Begin loop controlled by VAR.\n"
1737 "/end End loop or condition\n"
1738 "/bye Terminate gpg-connect-agent.\n"
1739 "/help Print this help.");
1742 log_error (_("unknown command `%s'\n"), cmd
);
1747 if (opt
.verbose
&& script_fp
)
1750 tmpline
= opt
.enable_varsubst
? substitute_line (line
) : NULL
;
1753 rc
= assuan_write_line (ctx
, tmpline
);
1757 rc
= assuan_write_line (ctx
, line
);
1760 log_info (_("sending line failed: %s\n"), gpg_strerror (rc
) );
1763 if (*line
== '#' || !*line
)
1764 continue; /* Don't expect a response for a comment line. */
1766 rc
= read_and_print_response (ctx
, (!ascii_strncasecmp (line
, "HELP", 4)
1767 && (spacep (line
+4) || !line
[4])),
1770 log_info (_("receiving line failed: %s\n"), gpg_strerror (rc
) );
1771 if ((rc
|| cmderr
) && script_fp
)
1773 log_error ("stopping script execution\n");
1779 /* FIXME: If the last command was BYE or the server died for
1780 some other reason, we won't notice until we get the next
1781 input command. Probing the connection with a non-blocking
1782 read could help to notice termination or other problems
1787 log_info ("closing connection to agent\n");
1793 /* Handle an Inquire from the server. Return False if it could not be
1794 handled; in this case the caller shll complete the operation. LINE
1795 is the complete line as received from the server. This function
1796 may change the content of LINE. */
1798 handle_inquire (assuan_context_t ctx
, char *line
)
1806 /* Skip the command and trailing spaces. */
1807 for (; *line
&& !spacep (line
); line
++)
1809 while (spacep (line
))
1813 for (; *line
&& !spacep (line
); line
++)
1818 /* Now match it against our list. The second loop is there to
1819 detect the match-all entry. */
1820 for (d
=definq_list
; d
; d
= d
->next
)
1821 if (d
->name
&& !strcmp (d
->name
, name
))
1824 for (d
=definq_list
; d
; d
= d
->next
)
1830 log_info ("no handler for inquiry `%s' found\n", name
);
1836 char *tmpvalue
= get_var_ext (d
->file
);
1837 rc
= assuan_send_data (ctx
, tmpvalue
, strlen (tmpvalue
));
1840 log_error ("sending data back failed: %s\n", gpg_strerror (rc
) );
1846 fp
= popen (d
->file
, "r");
1848 log_error ("error executing `%s': %s\n",
1849 d
->file
, strerror (errno
));
1850 else if (opt
.verbose
)
1851 log_error ("handling inquiry `%s' by running `%s'\n",
1856 fp
= fopen (d
->file
, "rb");
1858 log_error ("error opening `%s': %s\n", d
->file
, strerror (errno
));
1859 else if (opt
.verbose
)
1860 log_error ("handling inquiry `%s' by returning content of `%s'\n",
1866 while ( (n
= fread (buffer
, 1, sizeof buffer
, fp
)) )
1868 rc
= assuan_send_data (ctx
, buffer
, n
);
1871 log_error ("sending data back failed: %s\n", gpg_strerror (rc
) );
1876 log_error ("error reading from `%s': %s\n", d
->file
, strerror (errno
));
1879 rc
= assuan_send_data (ctx
, NULL
, 0);
1881 log_error ("sending data back failed: %s\n", gpg_strerror (rc
) );
1885 else if (d
->is_prog
)
1888 log_error ("error running `%s': %s\n", d
->file
, strerror (errno
));
1896 /* Read all response lines from server and print them. Returns 0 on
1897 success or an assuan error code. If WITHHASH istrue, comment lines
1898 are printed. Sets R_GOTERR to true if the command did not returned
1901 read_and_print_response (assuan_context_t ctx
, int withhash
, int *r_goterr
)
1914 rc
= assuan_read_line (ctx
, &line
, &linelen
);
1918 if ((withhash
|| opt
.verbose
> 1) && *line
== '#')
1920 fwrite (line
, linelen
, 1, stdout
);
1924 while (*line
== '#' || !linelen
);
1927 && line
[0] == 'D' && line
[1] == ' ')
1929 if (current_datasink
)
1931 const unsigned char *s
;
1934 for (j
=2, s
=(unsigned char*)line
+2; j
< linelen
; j
++, s
++ )
1936 if (*s
== '%' && j
+2 < linelen
)
1944 putc (c
, current_datasink
);
1949 for (i
=2; i
< linelen
; )
1953 printf ("D[%04X] ", i
-2);
1954 for (j
=0; j
< 16 ; j
++, i
++)
1959 printf (" %02X", ((unsigned char*)line
)[i
]);
1961 fputs (" ", stdout
);
1963 fputs (" ", stdout
);
1965 for (j
=0; j
< 16; j
++, i
++)
1967 unsigned int c
= ((unsigned char*)line
)[i
];
1970 else if (isascii (c
) && isprint (c
) && !iscntrl (c
))
1978 else if (opt
.decode
)
1980 const unsigned char *s
;
1984 for (j
=2, s
=(unsigned char*)line
+2; j
< linelen
; j
++, s
++ )
1988 fputs ("D ", stdout
);
1991 if (*s
== '%' && j
+2 < linelen
)
2003 need_lf
= (c
!= '\n');
2007 fwrite (line
, linelen
, 1, stdout
);
2015 if (!current_datasink
|| current_datasink
!= stdout
)
2022 && (line
[1] == '\0' || line
[1] == ' '))
2024 if (!current_datasink
|| current_datasink
!= stdout
)
2026 fwrite (line
, linelen
, 1, stdout
);
2030 else if (linelen
>= 2
2031 && line
[0] == 'O' && line
[1] == 'K'
2032 && (line
[2] == '\0' || line
[2] == ' '))
2034 if (!current_datasink
|| current_datasink
!= stdout
)
2036 fwrite (line
, linelen
, 1, stdout
);
2039 set_int_var ("?", 0);
2042 else if (linelen
>= 3
2043 && line
[0] == 'E' && line
[1] == 'R' && line
[2] == 'R'
2044 && (line
[3] == '\0' || line
[3] == ' '))
2048 errval
= strtol (line
+3, NULL
, 10);
2051 set_int_var ("?", errval
);
2052 if (!current_datasink
|| current_datasink
!= stdout
)
2054 fwrite (line
, linelen
, 1, stdout
);
2060 else if (linelen
>= 7
2061 && line
[0] == 'I' && line
[1] == 'N' && line
[2] == 'Q'
2062 && line
[3] == 'U' && line
[4] == 'I' && line
[5] == 'R'
2064 && (line
[7] == '\0' || line
[7] == ' '))
2066 if (!current_datasink
|| current_datasink
!= stdout
)
2068 fwrite (line
, linelen
, 1, stdout
);
2071 if (!handle_inquire (ctx
, line
))
2072 assuan_write_line (ctx
, "CANCEL");
2074 else if (linelen
>= 3
2075 && line
[0] == 'E' && line
[1] == 'N' && line
[2] == 'D'
2076 && (line
[3] == '\0' || line
[3] == ' '))
2078 if (!current_datasink
|| current_datasink
!= stdout
)
2080 fwrite (line
, linelen
, 1, stdout
);
2083 /* Received from server, thus more responses are expected. */
2086 return gpg_error (GPG_ERR_ASS_INV_RESPONSE
);
2094 /* Connect to the agent and send the standard options. */
2095 static assuan_context_t
2100 assuan_context_t ctx
;
2101 session_env_t session_env
;
2103 infostr
= getenv ("GPG_AGENT_INFO");
2104 if (!infostr
|| !*infostr
)
2108 rc
= assuan_new (&ctx
);
2111 log_error ("assuan_new failed: %s\n", gpg_strerror (rc
));
2115 /* Check whether we can connect at the standard socket. */
2116 sockname
= make_filename (opt
.homedir
, "S.gpg-agent", NULL
);
2117 rc
= assuan_socket_connect (ctx
, sockname
, 0);
2119 #ifdef HAVE_W32_SYSTEM
2120 /* If we failed to connect under Windows, we fire up the agent. */
2121 if (gpg_err_code (rc
) == GPG_ERR_ASS_CONNECT_FAILED
)
2123 const char *agent_program
;
2124 const char *argv
[3];
2128 log_info (_("no running gpg-agent - starting one\n"));
2129 agent_program
= gnupg_module_name (GNUPG_MODULE_NAME_AGENT
);
2131 argv
[0] = "--daemon";
2132 argv
[1] = "--use-standard-socket";
2135 rc
= gnupg_spawn_process_detached (agent_program
, argv
, NULL
);
2137 log_debug ("failed to start agent `%s': %s\n",
2138 agent_program
, gpg_strerror (rc
));
2141 /* Give the agent some time to prepare itself. */
2143 /* Now try again to connect the agent. */
2144 rc
= assuan_new (&ctx
);
2147 log_error ("assuan_new failed: %s\n", gpg_strerror (rc
));
2151 rc
= assuan_socket_connect (ctx
, sockname
, 0);
2156 #endif /*HAVE_W32_SYSTEM*/
2164 infostr
= xstrdup (infostr
);
2165 if ( !(p
= strchr (infostr
, PATHSEP_C
)) || p
== infostr
)
2167 log_error (_("malformed GPG_AGENT_INFO environment variable\n"));
2173 while (*p
&& *p
!= PATHSEP_C
)
2175 prot
= *p
? atoi (p
+1) : 0;
2178 log_error (_("gpg-agent protocol version %d is not supported\n"),
2184 rc
= assuan_new (&ctx
);
2187 log_error ("assuan_new failed: %s\n", gpg_strerror (rc
));
2191 rc
= assuan_socket_connect (ctx
, infostr
, pid
);
2197 log_error ("can't connect to the agent: %s\n", gpg_strerror (rc
));
2202 log_info ("connection to agent established\n");
2204 rc
= assuan_transact (ctx
, "RESET", NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
2207 log_error (_("error sending %s command: %s\n"), "RESET",
2212 session_env
= session_env_new ();
2214 log_fatal ("error allocating session environment block: %s\n",
2217 rc
= send_pinentry_environment (ctx
, GPG_ERR_SOURCE_DEFAULT
,
2218 NULL
, NULL
, session_env
);
2219 session_env_release (session_env
);
2222 log_error (_("error sending standard options: %s\n"), gpg_strerror (rc
));