summaryrefslogtreecommitdiffstats
path: root/assuan
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2001-12-12 10:17:23 +0100
committerWerner Koch <wk@gnupg.org>2001-12-12 10:17:23 +0100
commitd0eb9ade2cb54c5c414de71ca1eacc9d8574c129 (patch)
treeeb5d6b30dc8971e3a27e651d009bb9fd1ff46b4e /assuan
parentImplemented encryption in server mode. (diff)
downloadgnupg2-d0eb9ade2cb54c5c414de71ca1eacc9d8574c129.tar.xz
gnupg2-d0eb9ade2cb54c5c414de71ca1eacc9d8574c129.zip
* assuan-connect.c (assuan_pipe_connect): Implemented the inital
handshake. * assuan-client.c (read_from_server): Renamed to (_assuan_read_from_server): this and made external. * assuan-listen.c (assuan_set_hello_line): New. (assuan_accept): Use a custom hello line is available. * assuan-buffer.c (assuan_read_line): New. (assuan_pending_line): New. (_assuan_write_line): Renamed to .. (assuan_write_line): this, made public and changed all callers.
Diffstat (limited to 'assuan')
-rw-r--r--assuan/ChangeLog15
-rw-r--r--assuan/assuan-buffer.c48
-rw-r--r--assuan/assuan-client.c12
-rw-r--r--assuan/assuan-connect.c41
-rw-r--r--assuan/assuan-defs.h6
-rw-r--r--assuan/assuan-handler.c10
-rw-r--r--assuan/assuan-inquire.c2
-rw-r--r--assuan/assuan-listen.c30
-rw-r--r--assuan/assuan-pipe-server.c7
-rw-r--r--assuan/assuan.h8
10 files changed, 135 insertions, 44 deletions
diff --git a/assuan/ChangeLog b/assuan/ChangeLog
index 28f1b2f4f..9b08c2b4c 100644
--- a/assuan/ChangeLog
+++ b/assuan/ChangeLog
@@ -1,3 +1,18 @@
+2001-12-12 Werner Koch <wk@gnupg.org>
+
+ * assuan-connect.c (assuan_pipe_connect): Implemented the inital
+ handshake.
+ * assuan-client.c (read_from_server): Renamed to
+ (_assuan_read_from_server): this and made external.
+
+ * assuan-listen.c (assuan_set_hello_line): New.
+ (assuan_accept): Use a custom hello line is available.
+
+ * assuan-buffer.c (assuan_read_line): New.
+ (assuan_pending_line): New.
+ (_assuan_write_line): Renamed to ..
+ (assuan_write_line): this, made public and changed all callers.
+
2001-12-04 Werner Koch <wk@gnupg.org>
* assuan-connect.c (assuan_pipe_connect): Add more error reporting.
diff --git a/assuan/assuan-buffer.c b/assuan/assuan-buffer.c
index eec4876f8..50900c425 100644
--- a/assuan/assuan-buffer.c
+++ b/assuan/assuan-buffer.c
@@ -123,16 +123,25 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
return -1;
}
+ ctx->inbound.attic.pending = 0;
for (n=0; n < nread; n++)
{
if (line[n] == '\n')
{
if (n+1 < nread)
{
+ char *s, *d;
+ int i;
+
n++;
/* we have to copy the rest because the handlers are
allowed to modify the passed buffer */
- memcpy (ctx->inbound.attic.line, line+n, nread-n);
+ for (d=ctx->inbound.attic.line, s=line+n, i=nread-n; i; i--)
+ {
+ if (*s=='\n')
+ ctx->inbound.attic.pending = 1;
+ *d++ = *s++;
+ }
ctx->inbound.attic.linelen = nread-n;
n--;
}
@@ -150,12 +159,43 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
}
+/* Read the next line from the client or server and return a pointer
+ to a buffer with holding that line. linelen returns the length of
+ the line. This buffer is valid until another read operation is
+ done on this buffer. The caller is allowed to modify this buffer.
+ He should only use the buffer if the function returns without an
+ error.
+
+ Returns: 0 on success or an assuan error code
+ See also: assuan_pending_line().
+*/
+AssuanError
+assuan_read_line (ASSUAN_CONTEXT ctx, char **line, size_t *linelen)
+{
+ if (!ctx)
+ return ASSUAN_Invalid_Value;
+ *line = ctx->inbound.line;
+ *linelen = ctx->inbound.linelen;
+ return _assuan_read_line (ctx);
+}
-int
-_assuan_write_line (ASSUAN_CONTEXT ctx, const char *line )
+/* Return true when a full line is pending for a read, without the need
+ for actual IO */
+int
+assuan_pending_line (ASSUAN_CONTEXT ctx)
+{
+ return ctx && ctx->inbound.attic.pending;
+}
+
+
+AssuanError
+assuan_write_line (ASSUAN_CONTEXT ctx, const char *line )
{
int rc;
+
+ if (!ctx)
+ return ASSUAN_Invalid_Value;
/* fixme: we should do some kind of line buffering */
rc = writen (ctx->outbound.fd, line, strlen(line));
@@ -297,7 +337,7 @@ assuan_send_data (ASSUAN_CONTEXT ctx, const void *buffer, size_t length)
if (ctx->outbound.data.error)
return ctx->outbound.data.error;
if (!ctx->is_server)
- return _assuan_write_line (ctx, "END");
+ return assuan_write_line (ctx, "END");
}
else
{
diff --git a/assuan/assuan-client.c b/assuan/assuan-client.c
index 03c7c099a..a555cf339 100644
--- a/assuan/assuan-client.c
+++ b/assuan/assuan-client.c
@@ -32,8 +32,8 @@
#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
-static AssuanError
-read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off)
+AssuanError
+_assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off)
{
char *line;
int linelen;
@@ -114,12 +114,12 @@ assuan_transact (ASSUAN_CONTEXT ctx,
unsigned char *line;
int linelen;
- rc = _assuan_write_line (ctx, command);
+ rc = assuan_write_line (ctx, command);
if (rc)
return rc;
again:
- rc = read_from_server (ctx, &okay, &off);
+ rc = _assuan_read_from_server (ctx, &okay, &off);
if (rc)
return rc; /* error reading from server */
@@ -162,8 +162,8 @@ assuan_transact (ASSUAN_CONTEXT ctx,
{
if (!inquire_cb)
{
- _assuan_write_line (ctx, "END"); /* get out of inquire mode */
- read_from_server (ctx, &okay, &off); /* dummy read the response */
+ assuan_write_line (ctx, "END"); /* get out of inquire mode */
+ _assuan_read_from_server (ctx, &okay, &off); /* dummy read */
rc = ASSUAN_No_Inquire_Callback;
}
else
diff --git a/assuan/assuan-connect.c b/assuan/assuan-connect.c
index abc5d74e2..683c7f060 100644
--- a/assuan/assuan-connect.c
+++ b/assuan/assuan-connect.c
@@ -40,6 +40,7 @@
#endif
#ifdef HAVE_JNLIB_LOGGING
+#include "../jnlib/logging.h"
#define LOGERROR1(a,b) log_error ((a), (b))
#else
#define LOGERROR1(a,b) fprintf (stderr, (a), (b))
@@ -188,35 +189,37 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[])
close (rp[1]);
close (wp[0]);
- _assuan_read_line (*ctx); /* FIXME: Handshake. */
-#if 0 /* old stuff */
- inbound.eof = 0;
- inbound.linelen = 0;
- inbound.attic.linelen = 0;
+ /* initial handshake */
+ {
+ int okay, off;
+
+ err = _assuan_read_from_server (*ctx, &okay, &off);
+ if (err)
+ {
+ LOGERROR1 ("can't connect server: %s\n", assuan_strerror (err));
+ }
+ else if (okay != 1)
+ {
+ LOGERROR1 ("can't connect server: `%s'\n", (*ctx)->inbound.line);
+ err = ASSUAN_Connect_Failed;
+ }
+ }
- /* The server is available - read the greeting */
- rc = read_from_agent (&okay);
- if (rc)
- {
- log_error ("can't connect to the agent: %s\n", gnupg_strerror (rc));
- }
- else if (!okay)
+ if (err)
{
- log_error ("can't connect to the agent: %s\n", inbound.line);
- rc = seterr (No_Agent);
+ 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. */
}
- else
-#endif
-
- return 0;
+ return err;
}
void
assuan_pipe_disconnect (ASSUAN_CONTEXT ctx)
{
- _assuan_write_line (ctx, "BYE");
+ assuan_write_line (ctx, "BYE");
close (ctx->inbound.fd);
close (ctx->outbound.fd);
waitpid (ctx->pid, NULL, 0); /* FIXME Check return value. */
diff --git a/assuan/assuan-defs.h b/assuan/assuan-defs.h
index 5d61707a5..e0a38a8f0 100644
--- a/assuan/assuan-defs.h
+++ b/assuan/assuan-defs.h
@@ -38,6 +38,7 @@ struct assuan_context_s {
int is_server; /* set if this is context belongs to a server */
int in_inquire;
+ char *hello_line;
void *user_pointer; /* for assuan_[gs]et_pointer () */
@@ -51,6 +52,7 @@ struct assuan_context_s {
struct {
char line[LINELENGTH];
int linelen ;
+ int pending; /* i.e. at least one line is available in the attic */
} attic;
} inbound;
@@ -91,12 +93,12 @@ struct assuan_context_s {
int _assuan_register_std_commands (ASSUAN_CONTEXT ctx);
/*-- assuan-buffer.c --*/
-int _assuan_write_line (ASSUAN_CONTEXT ctx, const char *line);
int _assuan_read_line (ASSUAN_CONTEXT ctx);
int _assuan_cookie_write_data (void *cookie, const char *buffer, size_t size);
int _assuan_cookie_write_flush (void *cookie);
-
+/*-- assuan-client.c --*/
+AssuanError _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off);
/*-- assuan-util.c --*/
diff --git a/assuan/assuan-handler.c b/assuan/assuan-handler.c
index aee2407b2..c8be909d2 100644
--- a/assuan/assuan-handler.c
+++ b/assuan/assuan-handler.c
@@ -377,11 +377,11 @@ process_request (ASSUAN_CONTEXT ctx)
/* Error handling */
if (!rc)
{
- rc = _assuan_write_line (ctx, "OK");
+ rc = assuan_write_line (ctx, "OK");
}
else if (rc == -1)
{ /* No error checking because the peer may have already disconnect */
- _assuan_write_line (ctx, "OK Bye, bye - hope to meet you again");
+ assuan_write_line (ctx, "OK Hope to meet you again");
}
else
{
@@ -397,7 +397,7 @@ process_request (ASSUAN_CONTEXT ctx)
sprintf (errline, "ERR %d %.50s%s%.100s",
rc, assuan_strerror (rc), text? " - ":"", text?text:"");
}
- rc = _assuan_write_line (ctx, errline);
+ rc = assuan_write_line (ctx, errline);
}
return rc;
@@ -538,7 +538,7 @@ assuan_write_status (ASSUAN_CONTEXT ctx, const char *keyword, const char *text)
strcat (buffer, " ");
strcat (buffer, text);
}
- _assuan_write_line (ctx, buffer);
+ assuan_write_line (ctx, buffer);
}
else if ( (helpbuf = xtrymalloc (n)) )
{
@@ -549,7 +549,7 @@ assuan_write_status (ASSUAN_CONTEXT ctx, const char *keyword, const char *text)
strcat (helpbuf, " ");
strcat (helpbuf, text);
}
- _assuan_write_line (ctx, helpbuf);
+ assuan_write_line (ctx, helpbuf);
xfree (helpbuf);
}
}
diff --git a/assuan/assuan-inquire.c b/assuan/assuan-inquire.c
index c4514dfcc..8fec77ef8 100644
--- a/assuan/assuan-inquire.c
+++ b/assuan/assuan-inquire.c
@@ -151,7 +151,7 @@ assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword,
init_membuf (&mb, maxlen? maxlen:1024, maxlen);
strcpy (stpcpy (cmdbuf, "INQUIRE "), keyword);
- rc = _assuan_write_line (ctx, cmdbuf);
+ rc = assuan_write_line (ctx, cmdbuf);
if (rc)
goto leave;
diff --git a/assuan/assuan-listen.c b/assuan/assuan-listen.c
index f8ccb2708..822ef32cd 100644
--- a/assuan/assuan-listen.c
+++ b/assuan/assuan-listen.c
@@ -25,6 +25,28 @@
#include "assuan-defs.h"
+AssuanError
+assuan_set_hello_line (ASSUAN_CONTEXT ctx, const char *line)
+{
+ if (!ctx)
+ return ASSUAN_Invalid_Value;
+ if (!line)
+ {
+ xfree (ctx->hello_line);
+ ctx->hello_line = NULL;
+ }
+ else
+ {
+ char *buf = xtrymalloc (3+strlen(line)+1);
+ if (!buf)
+ return ASSUAN_Out_Of_Core;
+ strcpy (buf, "OK ");
+ strcpy (buf+3, line);
+ xfree (ctx->hello_line);
+ ctx->hello_line = buf;
+ }
+ return 0;
+}
/**
@@ -38,7 +60,7 @@
* Return value: 0 on success or an error if the connection could for
* some reason not be established.
**/
-int
+AssuanError
assuan_accept (ASSUAN_CONTEXT ctx)
{
int rc;
@@ -57,9 +79,8 @@ assuan_accept (ASSUAN_CONTEXT ctx)
}
/* send the hello */
-
- rc = _assuan_write_line (ctx,
- "OK Hello dear client - what can I do for you?");
+ rc = assuan_write_line (ctx, ctx->hello_line? ctx->hello_line
+ : "OK Your orders please");
if (rc)
return rc;
@@ -70,6 +91,7 @@ assuan_accept (ASSUAN_CONTEXT ctx)
}
+
int
assuan_get_input_fd (ASSUAN_CONTEXT ctx)
{
diff --git a/assuan/assuan-pipe-server.c b/assuan/assuan-pipe-server.c
index 58d9aa142..2a9b829aa 100644
--- a/assuan/assuan-pipe-server.c
+++ b/assuan/assuan-pipe-server.c
@@ -55,7 +55,11 @@ assuan_init_pipe_server (ASSUAN_CONTEXT *r_ctx, int filedes[2])
void
assuan_deinit_pipe_server (ASSUAN_CONTEXT ctx)
{
- xfree (ctx);
+ if (ctx)
+ {
+ xfree (ctx->hello_line);
+ xfree (ctx);
+ }
}
@@ -67,4 +71,3 @@ assuan_deinit_pipe_server (ASSUAN_CONTEXT ctx)
-
diff --git a/assuan/assuan.h b/assuan/assuan.h
index 8b805dd10..f97493dc0 100644
--- a/assuan/assuan.h
+++ b/assuan/assuan.h
@@ -46,6 +46,7 @@ typedef enum {
ASSUAN_Invalid_Response = 11,
ASSUAN_No_Data_Callback = 12,
ASSUAN_No_Inquire_Callback = 13,
+ ASSUAN_Connect_Failed = 14,
/* error codes above 99 are meant as status codes */
ASSUAN_Not_Implemented = 100,
@@ -130,7 +131,8 @@ void assuan_write_status (ASSUAN_CONTEXT ctx,
/*-- assuan-listen.c --*/
-int assuan_accept (ASSUAN_CONTEXT ctx);
+AssuanError assuan_set_hello_line (ASSUAN_CONTEXT ctx, const char *line);
+AssuanError assuan_accept (ASSUAN_CONTEXT ctx);
int assuan_get_input_fd (ASSUAN_CONTEXT ctx);
int assuan_get_output_fd (ASSUAN_CONTEXT ctx);
@@ -161,6 +163,10 @@ AssuanError assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword,
char **r_buffer, size_t *r_length, size_t maxlen);
/*-- assuan-buffer.c --*/
+AssuanError assuan_read_line (ASSUAN_CONTEXT ctx,
+ char **line, size_t *linelen);
+int assuan_pending_line (ASSUAN_CONTEXT ctx);
+AssuanError assuan_write_line (ASSUAN_CONTEXT ctx, const char *line );
AssuanError assuan_send_data (ASSUAN_CONTEXT ctx,
const void *buffer, size_t length);