[svn] GnuPG - r4588 - in trunk: agent scd tools
svn author wk
cvs at cvs.gnupg.org
Tue Oct 2 18:31:09 CEST 2007
Author: wk
Date: 2007-10-02 18:30:58 +0200 (Tue, 02 Oct 2007)
New Revision: 4588
Modified:
trunk/agent/ChangeLog
trunk/agent/command.c
trunk/scd/ChangeLog
trunk/scd/command.c
trunk/tools/ChangeLog
trunk/tools/gpg-connect-agent.c
trunk/tools/no-libgcrypt.c
Log:
Extended gpg-connect-agent.
New "GETINFO pid" command for scdaemon and gpg-agent.
Modified: trunk/agent/ChangeLog
===================================================================
--- trunk/agent/ChangeLog 2007-10-01 14:48:39 UTC (rev 4587)
+++ trunk/agent/ChangeLog 2007-10-02 16:30:58 UTC (rev 4588)
@@ -1,3 +1,7 @@
+2007-10-02 Werner Koch <wk at g10code.com>
+
+ * command.c (cmd_getinfo): Add "pid" subcommand.
+
2007-10-01 Werner Koch <wk at g10code.com>
* agent.h (struct server_control_s): Remove unused CONNECTION_FD.
Modified: trunk/agent/command.c
===================================================================
--- trunk/agent/command.c 2007-10-01 14:48:39 UTC (rev 4587)
+++ trunk/agent/command.c 2007-10-02 16:30:58 UTC (rev 4588)
@@ -1344,6 +1344,7 @@
Supported values for WHAT are:
version - Return the version of the program.
+ pid - Return the process id of the server.
socket_name - Return the name of the socket.
ssh_socket_name - Return the name of the ssh socket.
@@ -1358,6 +1359,13 @@
const char *s = VERSION;
rc = assuan_send_data (ctx, s, strlen (s));
}
+ else if (!strcmp (line, "pid"))
+ {
+ char numbuf[50];
+
+ snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
+ rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
+ }
else if (!strcmp (line, "socket_name"))
{
const char *s = get_agent_socket_name ();
Modified: trunk/scd/ChangeLog
===================================================================
--- trunk/scd/ChangeLog 2007-10-01 14:48:39 UTC (rev 4587)
+++ trunk/scd/ChangeLog 2007-10-02 16:30:58 UTC (rev 4588)
@@ -1,3 +1,7 @@
+2007-10-02 Werner Koch <wk at g10code.com>
+
+ * command.c (cmd_getinfo): Add "pid" subcommand.
+
2007-10-01 Werner Koch <wk at g10code.com>
* scdaemon.c (create_server_socket): Use Assuan socket wrappers
Modified: trunk/scd/command.c
===================================================================
--- trunk/scd/command.c 2007-10-01 14:48:39 UTC (rev 4587)
+++ trunk/scd/command.c 2007-10-02 16:30:58 UTC (rev 4588)
@@ -1452,6 +1452,7 @@
Supported values of WHAT are:
version - Return the version of the program.
+ pid - Return the process id of the server.
socket_name - Return the name of the socket.
@@ -1476,6 +1477,13 @@
const char *s = VERSION;
rc = assuan_send_data (ctx, s, strlen (s));
}
+ else if (!strcmp (line, "pid"))
+ {
+ char numbuf[50];
+
+ snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ());
+ rc = assuan_send_data (ctx, numbuf, strlen (numbuf));
+ }
else if (!strcmp (line, "socket_name"))
{
const char *s = scd_get_socket_name ();
Modified: trunk/tools/ChangeLog
===================================================================
--- trunk/tools/ChangeLog 2007-10-01 14:48:39 UTC (rev 4587)
+++ trunk/tools/ChangeLog 2007-10-02 16:30:58 UTC (rev 4588)
@@ -1,3 +1,13 @@
+2007-10-02 Werner Koch <wk at g10code.com>
+
+ * no-libgcrypt.c (gcry_malloc_secure): New.
+
+ * gpg-connect-agent.c (set_var, set_int_var, get_var)
+ (substitute_line, show_variables, assign_variable)
+ (do_open, do_close, do_showopen): New.
+ (main): Add new commands /nosubst, /subst, /let, /showvar, /open,
+ /close and /showopen.
+
2007-10-01 Werner Koch <wk at g10code.com>
* gpg-connect-agent.c (do_sendfd): Use INT2FD for assuan_sendfd.
Modified: trunk/tools/gpg-connect-agent.c
===================================================================
--- trunk/tools/gpg-connect-agent.c 2007-10-01 14:48:39 UTC (rev 4587)
+++ trunk/tools/gpg-connect-agent.c 2007-10-02 16:30:58 UTC (rev 4588)
@@ -30,8 +30,8 @@
#include "../common/util.h"
#include "../common/asshelp.h"
#include "../common/sysutils.h"
+#include "../common/membuf.h"
-
/* Constants to identify the commands and options. */
enum cmd_and_opt_values
{
@@ -82,6 +82,7 @@
const char *raw_socket; /* Name of socket to connect in raw mode. */
int exec; /* Run the pgm given on the command line. */
unsigned int connect_flags; /* Flags used for connecting. */
+ int enable_varsubst; /* Set if variable substitution is enabled. */
} opt;
@@ -101,7 +102,31 @@
static definq_t *definq_list_tail = &definq_list;
+/* Variable definitions and glovbal table. */
+struct variable_s
+{
+ struct variable_s *next;
+ char *value; /* Malloced value - always a string. */
+ char name[1]; /* Name of the variable. */
+};
+typedef struct variable_s *variable_t;
+static variable_t variable_table;
+
+/* This is used to store the pid of the server. */
+static pid_t server_pid = (pid_t)(-1);
+
+
+/* A list of open file descriptors. */
+static struct
+{
+ int inuse;
+#ifdef HAVE_W32_SYSTEM
+ HANDLE handle;
+#endif
+} open_fd_table[256];
+
+
/*-- local prototypes --*/
static int read_and_print_response (assuan_context_t ctx);
static assuan_context_t start_agent (void);
@@ -139,7 +164,163 @@
return p;
}
+
+static void
+set_var (const char *name, const char *value)
+{
+ variable_t var;
+ for (var = variable_table; var; var = var->next)
+ if (!strcmp (var->name, name))
+ break;
+ if (!var)
+ {
+ var = xmalloc (sizeof *var + strlen (name));
+ var->value = NULL;
+ strcpy (var->name, name);
+ var->next = variable_table;
+ variable_table = var;
+ }
+ xfree (var->value);
+ var->value = value? xstrdup (value) : NULL;
+}
+
+
+static void
+set_int_var (const char *name, int value)
+{
+ char numbuf[35];
+
+ snprintf (numbuf, sizeof numbuf, "%d", value);
+ set_var (name, numbuf);
+}
+
+/* Return the value of a variable. That value is valid until a
+ variable of the name is changed. Return NULL if not found. */
+static const char *
+get_var (const char *name)
+{
+ variable_t var;
+
+ for (var = variable_table; var; var = var->next)
+ if (!strcmp (var->name, name))
+ break;
+ if (!var || !var->value)
+ return NULL;
+ return var->value;
+}
+
+
+
+/* Substitute variables in LINE and return a new allocated buffer if
+ required. The function might modify LINE if the expanded version
+ fits into it. */
+static char *
+substitute_line (char *buffer)
+{
+ char *line = buffer;
+ char *p, *pend;
+ const char *value;
+ size_t valuelen, n;
+ char *result = NULL;
+
+ while (*line)
+ {
+ p = strchr (line, '$');
+ if (!p)
+ return result; /* No more variables. */
+
+ if (p[1] == '$') /* Escaped dollar sign. */
+ {
+ memmove (p, p+1, strlen (p+1)+1);
+ line = p + 1;
+ continue;
+ }
+ for (pend=p+1; *pend && !spacep (pend) && *pend != '$' ; pend++)
+ ;
+ if (*pend)
+ {
+ int save = *pend;
+ *pend = 0;
+ value = get_var (p+1);
+ *pend = save;
+ }
+ else
+ value = get_var (p+1);
+ if (!value)
+ value = "";
+ valuelen = strlen (value);
+ if (valuelen <= pend - p)
+ {
+ memcpy (p, value, valuelen);
+ p += valuelen;
+ n = pend - p;
+ if (n)
+ memmove (p, p+n, strlen (p+n)+1);
+ line = p;
+ }
+ else
+ {
+ char *src = result? result : buffer;
+ char *dst;
+
+ dst = xmalloc (strlen (src) + valuelen + 1);
+ n = p - src;
+ memcpy (dst, src, n);
+ memcpy (dst + n, value, valuelen);
+ n += valuelen;
+ strcpy (dst + n, pend);
+ line = dst + n;
+ free (result);
+ result = dst;
+ }
+ }
+ return result;
+}
+
+
+
+static void
+assign_variable (char *line)
+{
+ char *name, *p, *tmp;
+
+ /* Get the name. */
+ name = line;
+ for (p=name; *p && !spacep (p); p++)
+ ;
+ if (*p)
+ *p++ = 0;
+ while (spacep (p))
+ p++;
+
+ if (!*p)
+ set_var (name, NULL); /* Remove variable. */
+ else
+ {
+ tmp = opt.enable_varsubst? substitute_line (p) : NULL;
+ if (tmp)
+ {
+ set_var (name, tmp);
+ xfree (tmp);
+ }
+ else
+ set_var (name, p);
+ }
+}
+
+
+static void
+show_variables (void)
+{
+ variable_t var;
+
+ for (var = variable_table; var; var = var->next)
+ if (var->value)
+ printf ("%-20s %s\n", var->name, var->value);
+}
+
+
/* Store an inquire response pattern. Note, that this function may
change the content of LINE. We assume that leading white spaces
are already removed. */
@@ -246,7 +427,7 @@
rc = assuan_sendfd (ctx, INT2FD (fd) );
if (rc)
- log_error ("sednig descriptor %d failed: %s\n", fd, gpg_strerror (rc));
+ log_error ("sending descriptor %d failed: %s\n", fd, gpg_strerror (rc));
fclose (fp);
}
@@ -258,6 +439,200 @@
}
+static void
+do_open (char *line)
+{
+ FILE *fp;
+ char *varname, *name, *mode, *p;
+ int fd;
+
+#ifdef HAVE_W32_SYSTEM
+ if (server_pid == (pid_t)(-1))
+ {
+ log_error ("the pid of the server is unknown\n");
+ log_info ("use command \"/serverpid\" first\n");
+ return;
+ }
+#endif
+
+ /* Get variable name. */
+ varname = line;
+ for (p=varname; *p && !spacep (p); p++)
+ ;
+ if (*p)
+ *p++ = 0;
+ while (spacep (p))
+ p++;
+
+ /* Get file name. */
+ name = p;
+ for (p=name; *p && !spacep (p); p++)
+ ;
+ if (*p)
+ *p++ = 0;
+ while (spacep (p))
+ p++;
+
+ /* Get mode. */
+ mode = p;
+ if (!*mode)
+ mode = "r";
+ else
+ {
+ for (p=mode; *p && !spacep (p); p++)
+ ;
+ if (*p)
+ *p++ = 0;
+ }
+
+ /* Open and send. */
+ fp = fopen (name, mode);
+ if (!fp)
+ {
+ log_error ("can't open `%s' in \"%s\" mode: %s\n",
+ name, mode, strerror (errno));
+ return;
+ }
+ fd = fileno (fp);
+ if (fd >= 0 && fd < DIM (open_fd_table))
+ {
+ open_fd_table[fd].inuse = 1;
+#ifdef HAVE_W32_SYSTEM
+ {
+ HANDLE prochandle, handle, newhandle;
+
+ handle = (void*)_get_osfhandle (fd);
+
+ prochandle = OpenProcess (PROCESS_DUP_HANDLE, FALSE, server_pid);
+ if (!prochandle)
+ {
+ log_error ("failed to open the server process\n");
+ close (fd);
+ return;
+ }
+
+ if (!DuplicateHandle (GetCurrentProcess(), handle,
+ prochandle, &newhandle, 0,
+ TRUE, DUPLICATE_SAME_ACCESS ))
+ {
+ log_error ("failed to duplicate the handle\n");
+ close (fd);
+ CloseHandle (prochandle);
+ return;
+ }
+ CloseHandle (prochandle);
+ open_fd_table[fd].handle = newhandle;
+ }
+ if (opt.verbose)
+ log_info ("file `%s' opened in \"%s\" mode, fd=%d (libc=%d)\n",
+ name, mode, (int)open_fd_table[fd].handle, fd);
+ set_int_var (varname, (int)open_fd_table[fd].handle);
+#else
+ if (opt.verbose)
+ log_info ("file `%s' opened in \"%s\" mode, fd=%d\n",
+ name, mode, fd);
+ set_int_var (varname, fd);
+#endif
+ }
+ else
+ {
+ log_error ("can't put fd %d into table\n", fd);
+ close (fd);
+ }
+}
+
+
+static void
+do_close (char *line)
+{
+ int fd = atoi (line);
+
+#ifdef HAVE_W32_SYSTEM
+ int i;
+
+ for (i=0; i < DIM (open_fd_table); i++)
+ if ( open_fd_table[i].inuse && open_fd_table[i].handle == (void*)fd)
+ break;
+ if (i < DIM (open_fd_table))
+ fd = i;
+ else
+ {
+ log_error ("given fd (system handle) has not been opened\n");
+ return;
+ }
+#endif
+
+ if (fd < 0 || fd >= DIM (open_fd_table))
+ {
+ log_error ("invalid fd\n");
+ return;
+ }
+
+ if (!open_fd_table[fd].inuse)
+ {
+ log_error ("given fd has not been opened\n");
+ return;
+ }
+#ifdef HAVE_W32_SYSTEM
+ CloseHandle (open_fd_table[fd].handle); /* Close duped handle. */
+#endif
+ close (fd);
+ open_fd_table[fd].inuse = 0;
+}
+
+
+static void
+do_showopen (void)
+{
+ int i;
+
+ for (i=0; i < DIM (open_fd_table); i++)
+ if (open_fd_table[i].inuse)
+ {
+#ifdef HAVE_W32_SYSTEM
+ printf ("%-15d (libc=%d)\n", (int)open_fd_table[i].handle, i);
+#else
+ printf ("%-15d\n", i);
+#endif
+ }
+}
+
+
+
+static int
+getinfo_pin_cb (void *opaque, const void *buffer, size_t length)
+{
+ membuf_t *mb = opaque;
+ put_membuf (mb, buffer, length);
+ return 0;
+}
+
+/* Get the pid of the server and store it locally. */
+static void
+do_serverpid (assuan_context_t ctx)
+{
+ int rc;
+ membuf_t mb;
+ char *buffer;
+
+ init_membuf (&mb, 100);
+ rc = assuan_transact (ctx, "GETINFO pid", getinfo_pin_cb, &mb,
+ NULL, NULL, NULL, NULL);
+ put_membuf (&mb, "", 1);
+ buffer = get_membuf (&mb, NULL);
+ if (rc || !buffer)
+ log_error ("command \"%s\" failed: %s\n",
+ "GETINFO pid", gpg_strerror (rc));
+ else
+ {
+ server_pid = (pid_t)strtoul (buffer, NULL, 10);
+ if (opt.verbose)
+ log_info ("server's PID is %lu\n", (unsigned long)server_pid);
+ }
+ xfree (buffer);
+}
+
+
/* gpg-connect-agent's entry point. */
int
main (int argc, char **argv)
@@ -266,6 +641,7 @@
int no_more_options = 0;
assuan_context_t ctx;
char *line, *p;
+ char *tmpline;
size_t linesize;
int rc;
@@ -406,8 +782,16 @@
*p++ = 0;
while (spacep (p))
p++;
- if (!strcmp (cmd, "definqfile"))
+ if (!strcmp (cmd, "let"))
{
+ assign_variable (p);
+ }
+ else if (!strcmp (cmd, "showvar"))
+ {
+ show_variables ();
+ }
+ else if (!strcmp (cmd, "definqfile"))
+ {
add_definq (p, 0);
}
else if (!strcmp (cmd, "definqprog"))
@@ -424,7 +808,14 @@
}
else if (!strcmp (cmd, "echo"))
{
- puts (p);
+ tmpline = opt.enable_varsubst? substitute_line (p) : NULL;
+ if (tmpline)
+ {
+ puts (tmpline);
+ xfree (tmpline);
+ }
+ else
+ puts (p);
}
else if (!strcmp (cmd, "sendfd"))
{
@@ -436,6 +827,22 @@
do_recvfd (ctx, p);
continue;
}
+ else if (!strcmp (cmd, "open"))
+ {
+ do_open (p);
+ }
+ else if (!strcmp (cmd, "close"))
+ {
+ do_close (p);
+ }
+ else if (!strcmp (cmd, "showopen"))
+ {
+ do_showopen ();
+ }
+ else if (!strcmp (cmd, "serverpid"))
+ {
+ do_serverpid (ctx);
+ }
else if (!strcmp (cmd, "hex"))
opt.hex = 1;
else if (!strcmp (cmd, "nohex"))
@@ -444,11 +851,17 @@
opt.decode = 1;
else if (!strcmp (cmd, "nodecode"))
opt.decode = 0;
+ else if (!strcmp (cmd, "subst"))
+ opt.enable_varsubst = 1;
+ else if (!strcmp (cmd, "nosubst"))
+ opt.enable_varsubst = 0;
else if (!strcmp (cmd, "help"))
{
puts (
"Available commands:\n"
"/echo ARGS Echo ARGS.\n"
+"/let NAME VALUE Set variable NAME to VALUE.\n"
+"/showvar Show all variables.\n"
"/definqfile NAME FILE\n"
" Use content of FILE for inquiries with NAME.\n"
" NAME may be \"*\" to match any inquiry.\n"
@@ -458,9 +871,14 @@
"/showdef Print all definitions.\n"
"/cleardef Delete all definitions.\n"
"/sendfd FILE MODE Open FILE and pass descriptor to server.\n"
-"/recvfd Receive FD from server and print. \n"
+"/recvfd Receive FD from server and print.\n"
+"/open VAR FILE MODE Open FILE and assign the descrptor to VAR.\n"
+"/close FD Close file with descriptor FD.\n"
+"/showopen Show descriptors of all open files.\n"
+"/serverpid Retrieve the pid of the server.\n"
"/[no]hex Enable hex dumping of received data lines.\n"
"/[no]decode Enable decoding of received data lines.\n"
+"/[no]subst Enable varibale substitution.\n"
"/help Print this help.");
}
else
@@ -468,8 +886,15 @@
continue;
}
-
- rc = assuan_write_line (ctx, line);
+
+ tmpline = opt.enable_varsubst? substitute_line (line) : NULL;
+ if (tmpline)
+ {
+ rc = assuan_write_line (ctx, tmpline);
+ xfree (tmpline);
+ }
+ else
+ rc = assuan_write_line (ctx, line);
if (rc)
{
log_info (_("sending line failed: %s\n"), gpg_strerror (rc) );
Modified: trunk/tools/no-libgcrypt.c
===================================================================
--- trunk/tools/no-libgcrypt.c 2007-10-01 14:48:39 UTC (rev 4587)
+++ trunk/tools/no-libgcrypt.c 2007-10-02 16:30:58 UTC (rev 4588)
@@ -38,6 +38,12 @@
}
void *
+gcry_malloc_secure (size_t n)
+{
+ return malloc (n);
+}
+
+void *
gcry_xmalloc (size_t n)
{
void *p = malloc (n);
More information about the Gnupg-commits
mailing list