[Pkg-gnupg-commit] [libassuan] 61/437: 2002-11-24 Neal H. Walfield <neal at g10code.de>

Eric Dorland eric at moszumanska.debian.org
Fri May 22 05:33:24 UTC 2015


This is an automated email from the git hooks/post-receive script.

eric pushed a commit to branch master
in repository libassuan.

commit a7cfdeee902750b4550edfb956417c3aebbaad60
Author: Neal Walfield <neal at walfield.org>
Date:   Sun Nov 24 06:34:12 2002 +0000

    2002-11-24  Neal H. Walfield  <neal at g10code.de>
    
    	* assuan.h: Add prototype for assuan_domain_connect and
    	assuan_init_domain_server.
    	* assuan-defs.h: Include <unistd.h>.
    	Add prototype for _assuan_domain_init.
    	* assuan-domain-connect.c: New file.
    	* assuan-domain-server.c: New file.
    	* Makefile.am (libassuan_a_SOURCES): Add assuan-domain-connect.c
    	and assuan-domain-server.c
---
 src/ChangeLog               |  13 +-
 src/Makefile.am             |   4 +-
 src/assuan-defs.h           |  10 +-
 src/assuan-domain-connect.c | 371 ++++++++++++++++++++++++++++++++++++++++++++
 src/assuan-domain-server.c  |  52 +++++++
 src/assuan.h                |  22 ++-
 6 files changed, 467 insertions(+), 5 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index 0057cd8..2a2355f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,4 +1,15 @@
-2002-11-23  Neal H. Walfield  <neal at cs.uml.edu>
+2002-11-24  Neal H. Walfield  <neal at g10code.de>
+
+	* assuan.h: Add prototype for assuan_domain_connect and
+	assuan_init_domain_server.
+	* assuan-defs.h: Include <unistd.h>.
+	Add prototype for _assuan_domain_init.
+	* assuan-domain-connect.c: New file.
+	* assuan-domain-server.c: New file.
+	* Makefile.am (libassuan_a_SOURCES): Add assuan-domain-connect.c
+	and assuan-domain-server.c
+
+2002-11-23  Neal H. Walfield  <neal at g10code.de>
 
 	* Makefile.am (libassuan_a_SOURCES): Add assuan-io.c.
 	* assuan-io.c: Restore.
diff --git a/src/Makefile.am b/src/Makefile.am
index a095d2f..f741a25 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -43,7 +43,9 @@ libassuan_a_SOURCES = \
 	assuan-socket-server.c \
 	assuan-pipe-connect.c \
 	assuan-socket-connect.c \
-	assuan-io.c
+	assuan-io.c \
+	assuan-domain-connect.c \
+	assuan-domain-server.c
 
 assuan-errors.c : assuan.h
 	$(srcdir)/mkerrors < $(srcdir)/assuan.h > assuan-errors.c
diff --git a/src/assuan-defs.h b/src/assuan-defs.h
index 3a705ec..6e11bbb 100644
--- a/src/assuan-defs.h
+++ b/src/assuan-defs.h
@@ -24,6 +24,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/un.h>
+#include <unistd.h>
 
 #include "assuan.h"
 
@@ -130,12 +131,17 @@ struct assuan_context_s
   struct assuan_io *io;
 };
 
-
-
 /*-- assuan-pipe-server.c --*/
 int _assuan_new_context (ASSUAN_CONTEXT *r_ctx);
 void _assuan_release_context (ASSUAN_CONTEXT ctx);
 
+/*-- assuan-domain-connect.c --*/
+/* Make a connection to the Unix domain socket NAME and return a new
+   Assuan context in CTX.  SERVER_PID is currently not used but may
+   become handy in the future.  */
+AssuanError _assuan_domain_init (ASSUAN_CONTEXT *r_ctx,
+				 int rendezvousfd,
+				 pid_t peer);
 
 /*-- assuan-handler.c --*/
 int _assuan_register_std_commands (ASSUAN_CONTEXT ctx);
diff --git a/src/assuan-domain-connect.c b/src/assuan-domain-connect.c
new file mode 100644
index 0000000..86f85e2
--- /dev/null
+++ b/src/assuan-domain-connect.c
@@ -0,0 +1,371 @@
+/* assuan-domain-connect.c - Assuan unix domain socket based client
+ *	Copyright (C) 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Assuan.
+ *
+ * Assuan is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Assuan is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <alloca.h>
+#include <string.h>
+#include <assert.h>
+
+#include "assuan-defs.h"
+
+#ifdef HAVE_JNLIB_LOGGING
+#include "../jnlib/logging.h"
+#define LOGERROR(a)      log_error ((a))
+#define LOGERROR1(a,b)   log_error ((a), (b))
+#define LOGERROR2(a,b,c) log_error ((a), (b), (c))
+#define LOGERRORX(a)     log_printf ((a))
+#else
+#define LOGERROR(a)      fprintf (stderr, (a))
+#define LOGERROR1(a,b)   fprintf (stderr, (a), (b))
+#define LOGERROR2(a,b,c) fprintf (stderr, (a), (b), (c))
+#define LOGERRORX(a)     fputs ((a), stderr)
+#endif
+
+static int
+do_finish (ASSUAN_CONTEXT ctx)
+{
+  return 0;
+}
+
+static void
+do_deinit (ASSUAN_CONTEXT ctx)
+{
+  if (ctx->inbound.fd != -1)
+    close (ctx->inbound.fd);
+  ctx->inbound.fd = -1;
+  ctx->outbound.fd = -1;
+
+  if (ctx->domainbuffer)
+    {
+      assert (ctx->domainbufferallocated);
+      free (ctx->domainbuffer);
+    }
+
+  /* XXX: Do we want to do this?  Most likely.  */
+  unlink (ctx->myaddr.sun_path);
+}
+
+
+/* Read from the socket server.  */
+static ssize_t
+domain_reader (ASSUAN_CONTEXT ctx, void *buf, size_t buflen)
+{
+  int len = ctx->domainbuffersize;
+
+ start:
+  if (len == 0)
+    /* No data is buffered.  */
+    {
+      struct msghdr msg;
+      struct iovec iovec;
+      struct sockaddr_un sender;
+
+      memset (&msg, 0, sizeof (msg));
+
+      for (;;)
+	{
+	  msg.msg_name = &sender;
+	  msg.msg_namelen = sizeof (struct sockaddr_un);
+	  msg.msg_iov = &iovec;
+	  msg.msg_iovlen = 1;
+	  iovec.iov_base = ctx->domainbuffer;
+	  iovec.iov_len = ctx->domainbufferallocated;
+	  msg.msg_control = 0;
+	  msg.msg_controllen = 0;
+
+	  /* Peek first: if the buffer we have is too small then it
+	     will be truncated.  */
+	  len = recvmsg (ctx->inbound.fd, &msg, MSG_PEEK);
+	  if (len < 0)
+	    {
+	      printf ("domain_reader: %m\n");
+	      return -1;
+	    }
+
+	  if (strcmp (ctx->serveraddr.sun_path,
+		      ((struct sockaddr_un *) msg.msg_name)->sun_path) != 0)
+	    {
+	      /* XXX: Arg.  Not from whom we expected!  What do we
+		 want to do?  Should we just ignore it?  Either way,
+		 we still need to consume the message.  */
+	      break;
+	    }
+
+	  if (msg.msg_flags & MSG_TRUNC)
+	    /* Enlarge the buffer and try again.  */
+	    {
+	      int size = ctx->domainbufferallocated;
+	      void *tmp;
+
+	      if (size == 0)
+		size = 4 * 1024;
+	      else
+		size *= 2;
+
+	      tmp = malloc (size);
+	      if (! tmp)
+		return -1;
+
+	      free (ctx->domainbuffer);
+	      ctx->domainbuffer = tmp;
+	      ctx->domainbufferallocated = size;
+	    }
+	  else
+	    /* We have enough space!  */
+	    break;
+	}
+
+      /* Now we have to actually consume it (remember, we only
+	 peeked).  */
+      msg.msg_name = &sender;
+      msg.msg_namelen = sizeof (struct sockaddr_un);
+      msg.msg_iov = &iovec;
+      msg.msg_iovlen = 1;
+      iovec.iov_base = ctx->domainbuffer;
+      iovec.iov_len = ctx->domainbufferallocated;
+      msg.msg_control = 0;
+      msg.msg_controllen = 0;
+
+      if (strcmp (ctx->serveraddr.sun_path,
+		  ((struct sockaddr_un *) msg.msg_name)->sun_path) != 0)
+	{
+	  /* XXX: Arg.  Not from whom we expected!  What do we want to
+	     do?  Should we just ignore it?  We shall do the latter
+	     for the moment.  */
+	  LOGERROR1 ("Not setup to receive messages from: `%s'.",
+		     ((struct sockaddr_un *) msg.msg_name)->sun_path);
+	  goto start;
+	}
+
+      len = recvmsg (ctx->inbound.fd, &msg, 0);
+      if (len < 0)
+	{
+	  LOGERROR1 ("domain_reader: %s\n", strerror (errno));
+	  return -1;
+	}
+
+      ctx->domainbuffersize = len;
+      ctx->domainbufferoffset = 0;
+    }
+
+  /* Return some data to the user.  */
+
+  if (len > buflen)
+    /* We have more than the user requested.  */
+    len = buflen;
+
+  memcpy (buf, ctx->domainbuffer + ctx->domainbufferoffset, len);
+  ctx->domainbuffersize -= len;
+  assert (ctx->domainbuffersize >= 0);
+  ctx->domainbufferoffset += len;
+  assert (ctx->domainbufferoffset <= ctx->domainbufferallocated);
+
+  return len;
+}
+
+/* Write to the pipe server.  */
+static ssize_t
+domain_writer (ASSUAN_CONTEXT ctx, const void *buf, size_t buflen)
+{
+  struct msghdr msg;
+  struct iovec iovec;
+  ssize_t len;
+
+  memset (&msg, 0, sizeof (msg));
+
+  msg.msg_name = &ctx->serveraddr;
+  msg.msg_namelen = offsetof (struct sockaddr_un, sun_path)
+    + strlen (ctx->serveraddr.sun_path) + 1;
+
+  msg.msg_iovlen = 1;
+  msg.msg_iov = &iovec;
+  iovec.iov_base = (void *) buf;
+  iovec.iov_len = buflen;
+  msg.msg_control = 0;
+  msg.msg_controllen = 0;
+
+  len = sendmsg (ctx->outbound.fd, &msg, 0);
+  if (len < 0)
+    LOGERROR1 ("domain_writer: %s\n", strerror (errno));
+
+  return len;
+}
+
+/* Make a connection to the Unix domain socket NAME and return a new
+   Assuan context in CTX.  SERVER_PID is currently not used but may
+   become handy in the future.  */
+AssuanError
+_assuan_domain_init (ASSUAN_CONTEXT *r_ctx,
+		     int rendezvousfd,
+		     pid_t peer)
+{
+  static struct assuan_io io = { domain_reader, domain_writer };
+
+  AssuanError err;
+  ASSUAN_CONTEXT ctx;
+  int fd;
+  size_t len;
+  int tries;
+
+  if (!r_ctx)
+    return ASSUAN_Invalid_Value;
+  *r_ctx = NULL;
+
+  err = _assuan_new_context (&ctx); 
+  if (err)
+    return err;
+
+  /* Save it in case we need it later.  */
+  ctx->pid = peer;
+  ctx->deinit_handler = do_deinit;
+  ctx->finish_handler = do_finish;
+
+  fd = socket (PF_LOCAL, SOCK_DGRAM, 0);
+  if (fd == -1)
+    {
+      LOGERROR1 ("can't create socket: %s\n", strerror (errno));
+      _assuan_release_context (ctx);
+      return ASSUAN_General_Error;
+    }
+
+  ctx->inbound.fd = fd;
+  ctx->outbound.fd = fd;
+  ctx->io = &io;
+
+  ctx->domainbuffer = 0;
+  ctx->domainbufferoffset = 0;
+  ctx->domainbuffersize = 0;
+  ctx->domainbufferallocated = 0;
+
+  /* Get usable name and bind to it.  */
+
+  for (tries = 0; tries < TMP_MAX; tries ++)
+    {
+      char *p;
+      /* XXX: L_tmpnam must be shorter than sizeof (sun_path)!  */
+      char buf[L_tmpnam];
+
+      p = tmpnam (buf);
+      if (! p)
+	{
+	  LOGERROR ("cannot determine an appropriate temporary file "
+		    "name.  DOS in progress?\n");
+	  _assuan_release_context (ctx);
+	  close (fd);
+	  return ASSUAN_General_Error;
+	}
+	  
+      memset (&ctx->myaddr, 0, sizeof ctx->myaddr);
+      ctx->myaddr.sun_family = AF_LOCAL;
+      len = strlen (buf) + 1;
+      memcpy (ctx->myaddr.sun_path, buf, len);
+      len += offsetof (struct sockaddr_un, sun_path);
+
+      err = bind (fd, (struct sockaddr *) &ctx->myaddr, len);
+      if (! err)
+	break;
+    }
+
+  if (err)
+    {
+      LOGERROR2 ("can't bind to `%s': %s\n", ctx->myaddr.sun_path,
+		 strerror (errno));
+      _assuan_release_context (ctx);
+      close (fd);
+      return ASSUAN_Connect_Failed;
+    }
+
+  /* Rendezvous with our peer.  */
+  {
+    FILE *fp;
+    char *p;
+
+    fp = fdopen (rendezvousfd, "w+");
+    if (! fp)
+      {
+	LOGERROR1 ("can't open rendezvous port: %s\n", strerror (errno));
+	return ASSUAN_Connect_Failed;
+      }
+
+    /* Send our address.  */
+    fprintf (fp, "%s\n", ctx->myaddr.sun_path);
+    fflush (fp);
+
+    /* And receive our peer's.  */
+    memset (&ctx->serveraddr, 0, sizeof ctx->serveraddr);
+    for (p = ctx->serveraddr.sun_path;
+	 p < (ctx->serveraddr.sun_path
+	      + sizeof ctx->serveraddr.sun_path - 1);
+	 p ++)
+      {
+	*p = fgetc (fp);
+	if (*p == '\n')
+	  break;
+      }
+    *p = '\0';
+    fclose (fp);
+
+    ctx->serveraddr.sun_family = AF_LOCAL;
+  }
+
+  *r_ctx = ctx;
+  return 0;
+}
+
+AssuanError
+assuan_domain_connect (ASSUAN_CONTEXT *r_ctx,
+		       int rendezvousfd,
+		       pid_t peer)
+{
+  AssuanError aerr;
+  int okay, off;
+
+  aerr = _assuan_domain_init (r_ctx, rendezvousfd, peer);
+  if (aerr)
+    return aerr;
+
+  /* Initial handshake.  */
+  aerr = _assuan_read_from_server (*r_ctx, &okay, &off);
+  if (aerr)
+    LOGERROR1 ("can't connect to server: %s\n", assuan_strerror (aerr));
+  else if (okay != 1)
+    {
+      LOGERROR ("can't connect to server: `");
+      _assuan_log_sanitized_string ((*r_ctx)->inbound.line);
+      LOGERRORX ("'\n");
+      aerr = ASSUAN_Connect_Failed;
+    }
+
+  if (aerr)
+    assuan_disconnect (*r_ctx);
+
+  return aerr;
+}
diff --git a/src/assuan-domain-server.c b/src/assuan-domain-server.c
new file mode 100644
index 0000000..506ee05
--- /dev/null
+++ b/src/assuan-domain-server.c
@@ -0,0 +1,52 @@
+/* assuan-socket-server.c - Assuan socket based server
+ *	Copyright (C) 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Assuan.
+ *
+ * Assuan is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Assuan is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <unistd.h>
+
+#include "assuan-defs.h"
+
+static int
+accept_connection (ASSUAN_CONTEXT ctx)
+{
+  /* NOP.  */
+  return 0;
+}
+
+/* Initialize a server.  */
+AssuanError
+assuan_init_domain_server (ASSUAN_CONTEXT *r_ctx,
+			   int rendezvousfd,
+			   pid_t peer)
+{
+  AssuanError err;
+
+  err = _assuan_domain_init (r_ctx, rendezvousfd, peer);
+  if (err)
+    return err;
+
+  (*r_ctx)->is_server = 1;
+  (*r_ctx)->accept_handler = accept_connection;
+
+  return 0;
+}
diff --git a/src/assuan.h b/src/assuan.h
index d8b874e..1972702 100644
--- a/src/assuan.h
+++ b/src/assuan.h
@@ -23,7 +23,7 @@
 
 #include <stdio.h>
 #include <sys/types.h>
-#include <unistd.h> /* for ssize_t */
+#include <unistd.h>
 
 #ifdef __cplusplus
 extern "C" { 
@@ -181,6 +181,26 @@ AssuanError assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name,
 AssuanError assuan_socket_connect (ASSUAN_CONTEXT *ctx, const char *name,
                                    pid_t server_pid);
 
+/*-- assuan-domain-connect.c --*/
+
+/* Connect to a Unix domain socket server.  RENDEZVOUSFD is
+   bidirectional file descriptor (normally returned via socketpair)
+   which the client can use to rendezvous with the server.  SERVER s
+   the server's pid.  */
+AssuanError assuan_domain_connect (ASSUAN_CONTEXT *r_ctx,
+				   int rendezvousfd,
+				   pid_t server);
+
+/*-- assuan-domain-server.c --*/
+
+/* RENDEZVOUSFD is a bidirectional file descriptor (normally returned
+   via socketpair) that the domain server can use to rendezvous with
+   the client.  CLIENT is the client's pid.  */
+AssuanError assuan_init_domain_server (ASSUAN_CONTEXT *r_ctx,
+				       int rendezvousfd,
+				       pid_t client);
+
+
 /*-- assuan-connect.c --*/
 void assuan_disconnect (ASSUAN_CONTEXT ctx);
 pid_t assuan_get_pid (ASSUAN_CONTEXT ctx);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-gnupg/libassuan.git



More information about the Pkg-gnupg-commit mailing list