summaryrefslogtreecommitdiffstats
path: root/assuan
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2002-01-19 19:20:15 +0100
committerWerner Koch <wk@gnupg.org>2002-01-19 19:20:15 +0100
commitf58da1883a7d62d75a0b24f05c911c96febc0a85 (patch)
treed7a80bddeb9e3e30594485ae577677db0f06a893 /assuan
parent* gpg-agent.c: Removed unused cruft and implement the socket (diff)
downloadgnupg2-f58da1883a7d62d75a0b24f05c911c96febc0a85.tar.xz
gnupg2-f58da1883a7d62d75a0b24f05c911c96febc0a85.zip
* assuan-buffer.c (_assuan_read_line): Add output logging.
(assuan_write_line): Ditto. (_assuan_cookie_write_data): Ditto. (_assuan_cookie_write_flush): Ditto. * assuan-util.c (_assuan_log_print_buffer): New. (assuan_set_log_stream): New. (assuan_begin_confidential): New. (assuan_end_confidential): New. * assuan-defs.h: Add a few handler variables. * assuan-pipe-server.c (assuan_deinit_pipe_server): Removed. (deinit_pipe_server): New. (assuan_deinit_server): New. Changed all callers to use this. * assuan-listen.c (assuan_accept): Use the accept handler. * assuan-handler.c (process_request): Use the close Handler. * assuan-socket-server.c: New.
Diffstat (limited to 'assuan')
-rw-r--r--assuan/ChangeLog19
-rw-r--r--assuan/Makefile.am3
-rw-r--r--assuan/assuan-buffer.c56
-rw-r--r--assuan/assuan-connect.c6
-rw-r--r--assuan/assuan-defs.h15
-rw-r--r--assuan/assuan-handler.c4
-rw-r--r--assuan/assuan-listen.c10
-rw-r--r--assuan/assuan-pipe-server.c33
-rw-r--r--assuan/assuan-socket-server.c121
-rw-r--r--assuan/assuan-util.c54
-rw-r--r--assuan/assuan.h9
11 files changed, 311 insertions, 19 deletions
diff --git a/assuan/ChangeLog b/assuan/ChangeLog
index 87c88fef7..3c3fdcd23 100644
--- a/assuan/ChangeLog
+++ b/assuan/ChangeLog
@@ -1,3 +1,22 @@
+2002-01-19 Werner Koch <wk@gnupg.org>
+
+ * assuan-buffer.c (_assuan_read_line): Add output logging.
+ (assuan_write_line): Ditto.
+ (_assuan_cookie_write_data): Ditto.
+ (_assuan_cookie_write_flush): Ditto.
+ * assuan-util.c (_assuan_log_print_buffer): New.
+ (assuan_set_log_stream): New.
+ (assuan_begin_confidential): New.
+ (assuan_end_confidential): New.
+
+ * assuan-defs.h: Add a few handler variables.
+ * assuan-pipe-server.c (assuan_deinit_pipe_server): Removed.
+ (deinit_pipe_server): New.
+ (assuan_deinit_server): New. Changed all callers to use this.
+ * assuan-listen.c (assuan_accept): Use the accept handler.
+ * assuan-handler.c (process_request): Use the close Handler.
+ * assuan-socket-server.c: New.
+
2002-01-14 Werner Koch <wk@gnupg.org>
* assuan-client.c (_assuan_read_from_server): Skip spaces after
diff --git a/assuan/Makefile.am b/assuan/Makefile.am
index bc14e8f60..c4d117e09 100644
--- a/assuan/Makefile.am
+++ b/assuan/Makefile.am
@@ -38,7 +38,8 @@ libassuan_a_SOURCES = \
assuan-listen.c \
assuan-connect.c \
assuan-client.c \
- assuan-pipe-server.c
+ assuan-pipe-server.c \
+ assuan-socket-server.c
assuan-errors.c : assuan.h
diff --git a/assuan/assuan-buffer.c b/assuan/assuan-buffer.c
index 399d11dbf..bd0881743 100644
--- a/assuan/assuan-buffer.c
+++ b/assuan/assuan-buffer.c
@@ -20,6 +20,7 @@
#include <config.h>
#include <stdlib.h>
+#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
@@ -119,10 +120,17 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
rc = readline (ctx->inbound.fd, line, LINELENGTH,
&nread, &ctx->inbound.eof);
if (rc)
- return ASSUAN_Read_Error;
+ {
+ if (ctx->log_fp)
+ fprintf (ctx->log_fp, "%p <- [Error: %s]\n",
+ ctx, strerror (errno));
+ return ASSUAN_Read_Error;
+ }
if (!nread)
{
assert (ctx->inbound.eof);
+ if (ctx->log_fp)
+ fprintf (ctx->log_fp, "%p <- [EOF]\n", ctx);
return -1;
}
@@ -153,10 +161,23 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
n--;
line[n] = 0;
ctx->inbound.linelen = n;
+ if (ctx->log_fp)
+ {
+ fprintf (ctx->log_fp, "%p <- ", ctx);
+ if (ctx->confidential)
+ fputs ("[Confidential data not shown]", ctx->log_fp);
+ else
+ _assuan_log_print_buffer (ctx->log_fp,
+ ctx->inbound.line,
+ ctx->inbound.linelen);
+ putc ('\n', ctx->log_fp);
+ }
return 0;
}
}
+ if (ctx->log_fp)
+ fprintf (ctx->log_fp, "%p <- [Invalid line]\n", ctx);
*line = 0;
ctx->inbound.linelen = 0;
return ctx->inbound.eof? ASSUAN_Line_Not_Terminated : ASSUAN_Line_Too_Long;
@@ -206,6 +227,17 @@ assuan_write_line (ASSUAN_CONTEXT ctx, const char *line )
return ASSUAN_Invalid_Value;
/* fixme: we should do some kind of line buffering */
+ if (ctx->log_fp)
+ {
+ fprintf (ctx->log_fp, "%p -> ", ctx);
+ if (ctx->confidential)
+ fputs ("[Confidential data not shown]", ctx->log_fp);
+ else
+ _assuan_log_print_buffer (ctx->log_fp,
+ line, strlen (line));
+ putc ('\n', ctx->log_fp);
+ }
+
rc = writen (ctx->outbound.fd, line, strlen(line));
if (rc)
rc = ASSUAN_Write_Error;
@@ -266,6 +298,17 @@ _assuan_cookie_write_data (void *cookie, const char *buffer, size_t size)
if (linelen >= LINELENGTH-2-2)
{
+ if (ctx->log_fp)
+ {
+ fprintf (ctx->log_fp, "%p -> ", ctx);
+ if (ctx->confidential)
+ fputs ("[Confidential data not shown]", ctx->log_fp);
+ else
+ _assuan_log_print_buffer (ctx->log_fp,
+ ctx->outbound.data.line,
+ linelen);
+ putc ('\n', ctx->log_fp);
+ }
*line++ = '\n';
linelen++;
if (writen (ctx->outbound.fd, ctx->outbound.data.line, linelen))
@@ -300,6 +343,17 @@ _assuan_cookie_write_flush (void *cookie)
line += linelen;
if (linelen)
{
+ if (ctx->log_fp)
+ {
+ fprintf (ctx->log_fp, "%p -> ", ctx);
+ if (ctx->confidential)
+ fputs ("[Confidential data not shown]", ctx->log_fp);
+ else
+ _assuan_log_print_buffer (ctx->log_fp,
+ ctx->outbound.data.line,
+ linelen);
+ putc ('\n', ctx->log_fp);
+ }
*line++ = '\n';
linelen++;
if (writen (ctx->outbound.fd, ctx->outbound.data.line, linelen))
diff --git a/assuan/assuan-connect.c b/assuan/assuan-connect.c
index 613b54a13..53b742fc9 100644
--- a/assuan/assuan-connect.c
+++ b/assuan/assuan-connect.c
@@ -133,7 +133,7 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[],
close (rp[1]);
close (wp[0]);
close (wp[1]);
- assuan_deinit_pipe_server (*ctx); /* FIXME: Common code should be factored out. */
+ assuan_deinit_server (*ctx); /* FIXME: Common code should be factored out. */
return ASSUAN_General_Error;
}
@@ -221,7 +221,7 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[],
{
if ((*ctx)->pid != -1)
waitpid ((*ctx)->pid, NULL, 0); /* FIXME Check return value. */
- assuan_deinit_pipe_server (*ctx); /* FIXME: Common code should be factored out. */
+ assuan_deinit_server (*ctx); /* FIXME: Common code should be factored out. */
}
return err;
@@ -234,7 +234,7 @@ assuan_pipe_disconnect (ASSUAN_CONTEXT ctx)
close (ctx->inbound.fd);
close (ctx->outbound.fd);
waitpid (ctx->pid, NULL, 0); /* FIXME Check return value. */
- assuan_deinit_pipe_server (ctx);
+ assuan_deinit_server (ctx);
}
pid_t
diff --git a/assuan/assuan-defs.h b/assuan/assuan-defs.h
index 07f56e32e..d19e6b9cc 100644
--- a/assuan/assuan-defs.h
+++ b/assuan/assuan-defs.h
@@ -35,7 +35,9 @@ struct cmdtbl_s {
struct assuan_context_s {
AssuanError err_no;
const char *err_str;
+ int os_errno; /* last system error number used with certain error codes*/
+ int confidential;
int is_server; /* set if this is context belongs to a server */
int in_inquire;
char *hello_line;
@@ -43,6 +45,8 @@ struct assuan_context_s {
void *user_pointer; /* for assuan_[gs]et_pointer () */
+ FILE *log_fp;
+
struct {
int fd;
int eof;
@@ -69,7 +73,12 @@ struct assuan_context_s {
int pipe_mode; /* We are in pipe mode, i.e. we can handle just one
connection and must terminate then */
- pid_t pid; /* In pipe mode, the pid of the child server process. */
+ pid_t pid; /* In pipe mode, the pid of the child server process. */
+ int listen_fd; /* The fd we are listening on (used by socket servers) */
+
+ void (*deinit_handler)(ASSUAN_CONTEXT);
+ int (*accept_handler)(ASSUAN_CONTEXT);
+ int (*finish_handler)(ASSUAN_CONTEXT);
struct cmdtbl_s *cmdtbl;
size_t cmdtbl_used; /* used entries */
@@ -85,8 +94,6 @@ struct assuan_context_s {
int input_fd; /* set by INPUT command */
int output_fd; /* set by OUTPUT command */
-
-
};
@@ -115,6 +122,8 @@ void _assuan_free (void *p);
#define set_error(c,e,t) assuan_set_error ((c), ASSUAN_ ## e, (t))
+void _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length);
+
#endif /*ASSUAN_DEFS_H*/
diff --git a/assuan/assuan-handler.c b/assuan/assuan-handler.c
index ce7476a6a..db9749e50 100644
--- a/assuan/assuan-handler.c
+++ b/assuan/assuan-handler.c
@@ -387,12 +387,13 @@ process_request (ASSUAN_CONTEXT ctx)
else if (rc == -1)
{ /* No error checking because the peer may have already disconnect */
assuan_write_line (ctx, "OK closing connection");
+ ctx->finish_handler (ctx);
}
else
{
char errline[256];
- if (rc < 100)
+ if (rc < 100)
sprintf (errline, "ERR %d server fault (%.50s)",
ASSUAN_Server_Fault, assuan_strerror (rc));
else
@@ -405,6 +406,7 @@ process_request (ASSUAN_CONTEXT ctx)
rc = assuan_write_line (ctx, errline);
}
+ ctx->confidential = 0;
if (ctx->okay_line)
{
xfree (ctx->okay_line);
diff --git a/assuan/assuan-listen.c b/assuan/assuan-listen.c
index 57fe4b669..db63ad2bf 100644
--- a/assuan/assuan-listen.c
+++ b/assuan/assuan-listen.c
@@ -69,15 +69,13 @@ assuan_accept (ASSUAN_CONTEXT ctx)
if (!ctx)
return ASSUAN_Invalid_Value;
- /* fixme: cancel existing connection */
if (ctx->pipe_mode > 1)
return -1; /* second invocation for pipemode -> terminate */
+ ctx->finish_handler (ctx);
- if (!ctx->pipe_mode)
- {
-
- /* fixme: wait for request */
- }
+ rc = ctx->accept_handler (ctx);
+ if (rc)
+ return rc;
/* send the hello */
rc = assuan_write_line (ctx, ctx->hello_line? ctx->hello_line
diff --git a/assuan/assuan-pipe-server.c b/assuan/assuan-pipe-server.c
index 58f981a09..c283a925f 100644
--- a/assuan/assuan-pipe-server.c
+++ b/assuan/assuan-pipe-server.c
@@ -24,6 +24,26 @@
#include "assuan-defs.h"
+static void
+deinit_pipe_server (ASSUAN_CONTEXT ctx)
+{
+ /* nothing to do for this simple server */
+}
+
+static int
+accept_connection (ASSUAN_CONTEXT ctx)
+{
+ /* This is a NOP for a pipe server */
+ return 0;
+}
+
+static int
+finish_connection (ASSUAN_CONTEXT ctx)
+{
+ /* This is a NOP for a pipe server */
+ return 0;
+}
+
int
assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2])
@@ -43,6 +63,10 @@ assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2])
ctx->outbound.fd = filedes[1];
ctx->pipe_mode = 1;
+ ctx->listen_fd = -1;
+ ctx->deinit_handler = deinit_pipe_server;
+ ctx->accept_handler = accept_connection;
+ ctx->finish_handler = finish_connection;
rc = _assuan_register_std_commands (ctx);
if (rc)
@@ -52,11 +76,16 @@ assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2])
return rc;
}
+
void
-assuan_deinit_pipe_server (ASSUAN_CONTEXT ctx)
+assuan_deinit_server (ASSUAN_CONTEXT ctx)
{
if (ctx)
{
+ /* We use this function pointer to avoid linking other server
+ when not needed but still allow for a generic deinit function */
+ ctx->deinit_handler (ctx);
+ ctx->deinit_handler = NULL;
xfree (ctx->hello_line);
xfree (ctx->okay_line);
xfree (ctx);
@@ -70,5 +99,3 @@ assuan_deinit_pipe_server (ASSUAN_CONTEXT ctx)
-
-
diff --git a/assuan/assuan-socket-server.c b/assuan/assuan-socket-server.c
new file mode 100644
index 000000000..6ad6455e9
--- /dev/null
+++ b/assuan/assuan-socket-server.c
@@ -0,0 +1,121 @@
+/* assuan-socket-server.c - Assuan socket based server
+ * Copyright (C) 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include "assuan-defs.h"
+
+static int
+accept_connection (ASSUAN_CONTEXT ctx)
+{
+ int fd;
+ struct sockaddr_un clnt_addr;
+ size_t len = sizeof clnt_addr;
+
+ fd = accept (ctx->listen_fd, (struct sockaddr*)&clnt_addr, &len );
+ if (fd == -1)
+ {
+ ctx->os_errno = errno;
+ return ASSUAN_Accept_Failed;
+ }
+
+ ctx->inbound.fd = fd;
+ ctx->inbound.eof = 0;
+ ctx->inbound.linelen = 0;
+ ctx->inbound.attic.linelen = 0;
+ ctx->inbound.attic.pending = 0;
+
+ ctx->outbound.fd = fd;
+ ctx->outbound.data.linelen = 0;
+ ctx->outbound.data.error = 0;
+
+ ctx->confidential = 0;
+
+ return 0;
+}
+
+static int
+finish_connection (ASSUAN_CONTEXT ctx)
+{
+ if (ctx->inbound.fd != -1)
+ {
+ close (ctx->inbound.fd);
+ }
+ ctx->inbound.fd = -1;
+ ctx->outbound.fd = -1;
+ return 0;
+}
+
+
+static void
+deinit_socket_server (ASSUAN_CONTEXT ctx)
+{
+ finish_connection (ctx);
+}
+
+
+
+/* Initialize a server for the socket LISTEN_FD which has already be
+ put into listen mode */
+int
+assuan_init_socket_server (ASSUAN_CONTEXT *r_ctx, int listen_fd)
+{
+ ASSUAN_CONTEXT ctx;
+ int rc;
+
+ *r_ctx = NULL;
+ ctx = xtrycalloc (1, sizeof *ctx);
+ if (!ctx)
+ return ASSUAN_Out_Of_Core;
+ ctx->is_server = 1;
+ ctx->input_fd = -1;
+ ctx->output_fd = -1;
+
+ ctx->inbound.fd = -1;
+ ctx->outbound.fd = -1;
+
+ ctx->listen_fd = listen_fd;
+ ctx->deinit_handler = deinit_socket_server;
+ ctx->accept_handler = accept_connection;
+ ctx->finish_handler = finish_connection;
+
+ rc = _assuan_register_std_commands (ctx);
+ if (rc)
+ xfree (ctx);
+ else
+ *r_ctx = ctx;
+ return rc;
+}
+
+
+
+
+
+
+
+
+
+
diff --git a/assuan/assuan-util.c b/assuan/assuan-util.c
index 3eeee9ab9..96cd68d4e 100644
--- a/assuan/assuan-util.c
+++ b/assuan/assuan-util.c
@@ -96,3 +96,57 @@ assuan_get_pointer (ASSUAN_CONTEXT ctx)
return ctx? ctx->user_pointer : NULL;
}
+
+void
+assuan_set_log_stream (ASSUAN_CONTEXT ctx, FILE *fp)
+{
+ if (ctx)
+ {
+ if (ctx->log_fp)
+ fflush (ctx->log_fp);
+ ctx->log_fp = fp;
+ }
+}
+
+
+void
+assuan_begin_confidential (ASSUAN_CONTEXT ctx)
+{
+ if (ctx)
+ {
+ ctx->confidential = 1;
+ }
+}
+
+void
+assuan_end_confidential (ASSUAN_CONTEXT ctx)
+{
+ if (ctx)
+ {
+ ctx->confidential = 0;
+ }
+}
+
+void
+_assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length)
+{
+ const unsigned char *s;
+ int n;
+
+ for (n=length,s=buffer; n; n--, s++)
+ {
+ if (*s < ' ' || (*s >= 0x7f && *s <= 0xa0))
+ break;
+ }
+ s = buffer;
+ if (!n && *s != '[')
+ fwrite (buffer, length, 1, fp);
+ else
+ {
+ putc ('[', fp);
+ for (n=0; n < length; n++, s++)
+ fprintf (fp, " %02x", *s);
+ putc (' ', fp);
+ putc (']', fp);
+ }
+}
diff --git a/assuan/assuan.h b/assuan/assuan.h
index 477e2ded9..3382283cc 100644
--- a/assuan/assuan.h
+++ b/assuan/assuan.h
@@ -47,6 +47,7 @@ typedef enum {
ASSUAN_No_Data_Callback = 12,
ASSUAN_No_Inquire_Callback = 13,
ASSUAN_Connect_Failed = 14,
+ ASSUAN_Accept_Failed = 15,
/* error codes above 99 are meant as status codes */
ASSUAN_Not_Implemented = 100,
@@ -146,7 +147,10 @@ AssuanError assuan_close_output_fd (ASSUAN_CONTEXT ctx);
/*-- assuan-pipe-server.c --*/
int assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2]);
-void assuan_deinit_pipe_server (ASSUAN_CONTEXT ctx);
+void assuan_deinit_server (ASSUAN_CONTEXT ctx);
+
+/*-- assuan-socket-server.c --*/
+int assuan_init_socket_server (ASSUAN_CONTEXT *r_ctx, int listen_fd);
/*-- assuan-connect.c --*/
@@ -182,10 +186,13 @@ AssuanError assuan_send_data (ASSUAN_CONTEXT ctx,
void assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
void *(*new_realloc_func)(void *p, size_t n),
void (*new_free_func)(void*) );
+void assuan_set_log_stream (ASSUAN_CONTEXT ctx, FILE *fp);
int assuan_set_error (ASSUAN_CONTEXT ctx, int err, const char *text);
void assuan_set_pointer (ASSUAN_CONTEXT ctx, void *pointer);
void *assuan_get_pointer (ASSUAN_CONTEXT ctx);
+void assuan_begin_confidential (ASSUAN_CONTEXT ctx);
+void assuan_end_confidential (ASSUAN_CONTEXT ctx);
/*-- assuan-errors.c (built) --*/
const char *assuan_strerror (AssuanError err);