[Pkg-gnupg-commit] [libassuan] 63/437: 2002-11-24 Neal H. Walfield <neal at cs.uml.edu>
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 5d0f173af5f4036a3793392899836b0fe7a01376
Author: Neal Walfield <neal at walfield.org>
Date: Sun Nov 24 18:27:59 2002 +0000
2002-11-24 Neal H. Walfield <neal at cs.uml.edu>
* assuan.h (assuan_sendfd): New prototype.
(assuan_receivefd): New prototype.
* assuan-buffer.c (assuan_sendfd): New function.
(assuan_receivefd): New function.
* assuan-handler.c (parse_cmd_input_output): Recognize incoming
file descriptors and act appropriately.
* assuan-defs.h (struct assuan_io): Add fields sendfd and
receivefd.
(struct assuan_context_s): Add fields pendingfds and
pendingfdscount.
* assuan-pipe-server.c (_assuan_new_context): Update IO to reflect
new features.
* assuan-domain-connect.c (do_deinit): Cleanup any unreceived file
descriptors.
(domain_reader): Receive file descriptors.
(domain_sendfd): New function.
(domain_receivefd): New function.
(_assuan_domain_init): Update initialization code to reflect new
features.
---
src/ChangeLog | 22 ++++++++
src/assuan-buffer.c | 20 ++++++++
src/assuan-defs.h | 8 ++-
src/assuan-domain-connect.c | 121 ++++++++++++++++++++++++++++++++++++++++++--
src/assuan-handler.c | 35 ++++++++-----
src/assuan-pipe-server.c | 3 +-
src/assuan.h | 6 +++
7 files changed, 194 insertions(+), 21 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index eeb286d..c88d884 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,25 @@
+2002-11-24 Neal H. Walfield <neal at cs.uml.edu>
+
+ * assuan.h (assuan_sendfd): New prototype.
+ (assuan_receivefd): New prototype.
+ * assuan-buffer.c (assuan_sendfd): New function.
+ (assuan_receivefd): New function.
+ * assuan-handler.c (parse_cmd_input_output): Recognize incoming
+ file descriptors and act appropriately.
+ * assuan-defs.h (struct assuan_io): Add fields sendfd and
+ receivefd.
+ (struct assuan_context_s): Add fields pendingfds and
+ pendingfdscount.
+ * assuan-pipe-server.c (_assuan_new_context): Update IO to reflect
+ new features.
+ * assuan-domain-connect.c (do_deinit): Cleanup any unreceived file
+ descriptors.
+ (domain_reader): Receive file descriptors.
+ (domain_sendfd): New function.
+ (domain_receivefd): New function.
+ (_assuan_domain_init): Update initialization code to reflect new
+ features.
+
2002-11-24 Neal H. Walfield <neal at g10code.de>
* assuan-domain-connect.c (do_finish): Remove.
diff --git a/src/assuan-buffer.c b/src/assuan-buffer.c
index 8ccd3bd..bbe3990 100644
--- a/src/assuan-buffer.c
+++ b/src/assuan-buffer.c
@@ -437,3 +437,23 @@ assuan_send_data (ASSUAN_CONTEXT ctx, const void *buffer, size_t length)
return 0;
}
+
+AssuanError
+assuan_sendfd (ASSUAN_CONTEXT ctx, int fd)
+{
+ if (! ctx->io->sendfd)
+ return set_error (ctx, Not_Implemented,
+ "server does not support sending and receiving "
+ "of file descriptors");
+ return ctx->io->sendfd (ctx, fd);
+}
+
+AssuanError
+assuan_receivefd (ASSUAN_CONTEXT ctx, int *fd)
+{
+ if (! ctx->io->receivefd)
+ return set_error (ctx, Not_Implemented,
+ "server does not support sending and receiving "
+ "of file descriptors");
+ return ctx->io->receivefd (ctx, fd);
+}
diff --git a/src/assuan-defs.h b/src/assuan-defs.h
index 6e11bbb..5766024 100644
--- a/src/assuan-defs.h
+++ b/src/assuan-defs.h
@@ -43,6 +43,10 @@ struct assuan_io
ssize_t (*read) (ASSUAN_CONTEXT, void *, size_t);
/* Routine to write to output_fd. */
ssize_t (*write) (ASSUAN_CONTEXT, const void *, size_t);
+ /* Send a file descriptor. */
+ AssuanError (*sendfd) (ASSUAN_CONTEXT, int);
+ /* Receive a file descriptor. */
+ AssuanError (*receivefd) (ASSUAN_CONTEXT, int *);
};
struct assuan_context_s
@@ -109,6 +113,9 @@ struct assuan_context_s
/* Memory allocated. */
int domainbufferallocated;
+ int *pendingfds;
+ int pendingfdscount;
+
void (*deinit_handler)(ASSUAN_CONTEXT);
int (*accept_handler)(ASSUAN_CONTEXT);
int (*finish_handler)(ASSUAN_CONTEXT);
@@ -176,6 +183,5 @@ ssize_t _assuan_simple_read (ASSUAN_CONTEXT ctx, void *buffer, size_t size);
ssize_t _assuan_simple_write (ASSUAN_CONTEXT ctx, const void *buffer,
size_t size);
-
#endif /*ASSUAN_DEFS_H*/
diff --git a/src/assuan-domain-connect.c b/src/assuan-domain-connect.c
index d50ba1e..b4ce519 100644
--- a/src/assuan-domain-connect.c
+++ b/src/assuan-domain-connect.c
@@ -63,6 +63,17 @@ do_deinit (ASSUAN_CONTEXT ctx)
free (ctx->domainbuffer);
}
+ if (ctx->pendingfds)
+ {
+ int i;
+
+ assert (ctx->pendingfdscount > 0);
+ for (i = 0; i < ctx->pendingfdscount; i ++)
+ close (ctx->pendingfds[i]);
+
+ free (ctx->pendingfds);
+ }
+
unlink (ctx->myaddr.sun_path);
}
@@ -80,6 +91,11 @@ domain_reader (ASSUAN_CONTEXT ctx, void *buf, size_t buflen)
struct msghdr msg;
struct iovec iovec;
struct sockaddr_un sender;
+ struct
+ {
+ struct cmsghdr hdr;
+ int fd;
+ } cmsg;
memset (&msg, 0, sizeof (msg));
@@ -91,8 +107,8 @@ domain_reader (ASSUAN_CONTEXT ctx, void *buf, size_t buflen)
msg.msg_iovlen = 1;
iovec.iov_base = ctx->domainbuffer;
iovec.iov_len = ctx->domainbufferallocated;
- msg.msg_control = 0;
- msg.msg_controllen = 0;
+ msg.msg_control = &cmsg;
+ msg.msg_controllen = sizeof cmsg;
/* Peek first: if the buffer we have is too small then it
will be truncated. */
@@ -144,8 +160,8 @@ domain_reader (ASSUAN_CONTEXT ctx, void *buf, size_t buflen)
msg.msg_iovlen = 1;
iovec.iov_base = ctx->domainbuffer;
iovec.iov_len = ctx->domainbufferallocated;
- msg.msg_control = 0;
- msg.msg_controllen = 0;
+ msg.msg_control = &cmsg;
+ msg.msg_controllen = sizeof cmsg;
if (strcmp (ctx->serveraddr.sun_path,
((struct sockaddr_un *) msg.msg_name)->sun_path) != 0)
@@ -167,6 +183,30 @@ domain_reader (ASSUAN_CONTEXT ctx, void *buf, size_t buflen)
ctx->domainbuffersize = len;
ctx->domainbufferoffset = 0;
+
+ if (sizeof (cmsg) == msg.msg_controllen)
+ /* We received a file descriptor. */
+ {
+ void *tmp;
+
+ tmp = realloc (ctx->pendingfds,
+ sizeof (int) * (ctx->pendingfdscount + 1));
+ if (! tmp)
+ {
+ LOGERROR1 ("domain_reader: %s\n", strerror (errno));
+ return -1;
+ }
+
+ ctx->pendingfds = tmp;
+ ctx->pendingfds[ctx->pendingfdscount ++]
+ = * (int *) CMSG_DATA (&cmsg.hdr);
+
+ LOGERROR1 ("Received file descriptor %d from peer.\n",
+ ctx->pendingfds[ctx->pendingfdscount - 1]);
+ }
+
+ if (len == 0)
+ goto start;
}
/* Return some data to the user. */
@@ -212,6 +252,74 @@ domain_writer (ASSUAN_CONTEXT ctx, const void *buf, size_t buflen)
return len;
}
+static AssuanError
+domain_sendfd (ASSUAN_CONTEXT ctx, int fd)
+{
+ struct msghdr msg;
+ struct
+ {
+ struct cmsghdr hdr;
+ int fd;
+ } cmsg;
+ int 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 = 0;
+ msg.msg_iov = 0;
+
+ cmsg.hdr.cmsg_level = SOL_SOCKET;
+ cmsg.hdr.cmsg_type = SCM_RIGHTS;
+ cmsg.hdr.cmsg_len = sizeof (cmsg);
+
+ msg.msg_control = &cmsg;
+ msg.msg_controllen = sizeof (cmsg);
+
+ * (int *) CMSG_DATA (&cmsg.hdr) = fd;
+
+ len = sendmsg (ctx->outbound.fd, &msg, 0);
+ if (len < 0)
+ {
+ LOGERROR1 ("domain_sendfd: %s\n", strerror (errno));
+ return ASSUAN_General_Error;
+ }
+ else
+ return 0;
+}
+
+static AssuanError
+domain_receivefd (ASSUAN_CONTEXT ctx, int *fd)
+{
+ if (ctx->pendingfds == 0)
+ {
+ LOGERROR ("No pending file descriptors!\n");
+ return ASSUAN_General_Error;
+ }
+
+ *fd = ctx->pendingfds[0];
+ if (-- ctx->pendingfdscount == 0)
+ {
+ free (ctx->pendingfds);
+ ctx->pendingfds = 0;
+ }
+ else
+ /* Fix the array. */
+ {
+ memmove (ctx->pendingfds, ctx->pendingfds + 1,
+ ctx->pendingfdscount * sizeof (int));
+ ctx->pendingfds = realloc (ctx->pendingfds,
+ ctx->pendingfdscount * sizeof (int));
+ }
+
+ return 0;
+}
+
+
+
/* 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. */
@@ -220,7 +328,8 @@ _assuan_domain_init (ASSUAN_CONTEXT *r_ctx,
int rendezvousfd,
pid_t peer)
{
- static struct assuan_io io = { domain_reader, domain_writer };
+ static struct assuan_io io = { domain_reader, domain_writer,
+ domain_sendfd, domain_receivefd };
AssuanError err;
ASSUAN_CONTEXT ctx;
@@ -262,6 +371,8 @@ _assuan_domain_init (ASSUAN_CONTEXT *r_ctx,
ctx->domainbufferoffset = 0;
ctx->domainbuffersize = 0;
ctx->domainbufferallocated = 0;
+ ctx->pendingfds = 0;
+ ctx->pendingfdscount = 0;
/* Get usable name and bind to it. */
diff --git a/src/assuan-handler.c b/src/assuan-handler.c
index 6ddfe88..16838b2 100644
--- a/src/assuan-handler.c
+++ b/src/assuan-handler.c
@@ -154,20 +154,27 @@ parse_cmd_input_output (ASSUAN_CONTEXT ctx, char *line, int *rfd)
{
char *endp;
- if (strncmp (line, "FD=", 3))
- return set_error (ctx, Syntax_Error, "FD=<n> expected");
- line += 3;
- if (!digitp (*line))
- return set_error (ctx, Syntax_Error, "number required");
- *rfd = strtoul (line, &endp, 10);
- /* remove that argument so that a notify handler won't see it */
- memset (line, ' ', endp? (endp-line):strlen(line));
-
- if (*rfd == ctx->inbound.fd)
- return set_error (ctx, Parameter_Conflict, "fd same as inbound fd");
- if (*rfd == ctx->outbound.fd)
- return set_error (ctx, Parameter_Conflict, "fd same as outbound fd");
- return 0;
+ if (strncmp (line, "FD", 2) != 0 || (line[2] != '=' && line[2] != '\0'))
+ return set_error (ctx, Syntax_Error, "FD[=<n>] expected");
+ line += 2;
+ if (*line == '=')
+ {
+ line ++;
+ if (!digitp (*line))
+ return set_error (ctx, Syntax_Error, "number required");
+ *rfd = strtoul (line, &endp, 10);
+ /* remove that argument so that a notify handler won't see it */
+ memset (line, ' ', endp? (endp-line):strlen(line));
+
+ if (*rfd == ctx->inbound.fd)
+ return set_error (ctx, Parameter_Conflict, "fd same as inbound fd");
+ if (*rfd == ctx->outbound.fd)
+ return set_error (ctx, Parameter_Conflict, "fd same as outbound fd");
+ return 0;
+ }
+ else
+ /* Our peer has sent the file descriptor. */
+ return assuan_receivefd (ctx, rfd);
}
/* Format is INPUT FD=<n> */
diff --git a/src/assuan-pipe-server.c b/src/assuan-pipe-server.c
index a0bb3bd..ba269b0 100644
--- a/src/assuan-pipe-server.c
+++ b/src/assuan-pipe-server.c
@@ -51,7 +51,8 @@ int
_assuan_new_context (ASSUAN_CONTEXT *r_ctx)
{
static struct assuan_io io = { _assuan_simple_read,
- _assuan_simple_write };
+ _assuan_simple_write,
+ 0, 0 };
ASSUAN_CONTEXT ctx;
int rc;
diff --git a/src/assuan.h b/src/assuan.h
index 1972702..59cb153 100644
--- a/src/assuan.h
+++ b/src/assuan.h
@@ -229,6 +229,12 @@ AssuanError assuan_write_line (ASSUAN_CONTEXT ctx, const char *line );
AssuanError assuan_send_data (ASSUAN_CONTEXT ctx,
const void *buffer, size_t length);
+/* The file descriptor must be pending before assuan_receivefd is
+ call. This means that assuan_sendfd should be called *before* the
+ trigger is sent (normally via assuan_send_data ("I sent you a
+ descriptor")). */
+AssuanError assuan_sendfd (ASSUAN_CONTEXT ctx, int fd);
+AssuanError assuan_receivefd (ASSUAN_CONTEXT ctx, int *fd);
/*-- assuan-util.c --*/
void assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
--
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