aboutsummaryrefslogtreecommitdiffstats
path: root/assuan
diff options
context:
space:
mode:
Diffstat (limited to 'assuan')
-rw-r--r--assuan/ChangeLog36
-rw-r--r--assuan/assuan-buffer.c43
-rw-r--r--assuan/assuan-client.c41
-rw-r--r--assuan/assuan-defs.h10
-rw-r--r--assuan/assuan-handler.c8
-rw-r--r--assuan/assuan-inquire.c38
-rw-r--r--assuan/assuan-pipe-server.c1
-rw-r--r--assuan/assuan-socket-server.c18
-rw-r--r--assuan/assuan.h16
9 files changed, 181 insertions, 30 deletions
diff --git a/assuan/ChangeLog b/assuan/ChangeLog
index 290fef58..2b95d56d 100644
--- a/assuan/ChangeLog
+++ b/assuan/ChangeLog
@@ -1,3 +1,39 @@
+2002-04-04 Werner Koch <[email protected]>
+
+ * assuan-buffer.c (my_log_prefix): New. Use it for all i/o debug
+ output.
+
+2002-03-06 Werner Koch <[email protected]>
+
+ * assuan-client.c (_assuan_read_from_server): Detect END.
+ (assuan_transact): Pass it to the data callback.
+
+2002-02-27 Werner Koch <[email protected]>
+
+ * assuan-client.c (assuan_transact): Add 2 more arguments to
+ support status lines. Passing NULL yields the old behaviour.
+
+ * assuan-handler.c (process_request): Flush data lines send
+ without using the data fp.
+
+2002-02-14 Werner Koch <[email protected]>
+
+ * assuan-inquire.c (assuan_inquire): Check for a cancel command
+ and return ASSUAN_Canceled. Allow for non-data inquiry.
+
+ * assuan.h: Add a few token specific error codes.
+
+2002-02-13 Werner Koch <[email protected]>
+
+ * assuan-defs.h (assuan_context_s): New var CLIENT_PID.
+ * assuan-pipe-server.c (_assuan_new_context): set default value.
+ * assuan-socket-server.c (accept_connection): get the actual pid.
+
+2002-02-12 Werner Koch <[email protected]>
+
+ * assuan-buffer.c (writen,readline) [USE_GNU_PT]: Use pth_read/write.
+ * assuan-socket-server.c (accept_connection) [USE_GNU_PTH]: Ditto.
+
2002-02-01 Marcus Brinkmann <[email protected]>
* Makefile.am (MOSTLYCLEANFILES): New variable.
diff --git a/assuan/assuan-buffer.c b/assuan/assuan-buffer.c
index bd088174..29f94794 100644
--- a/assuan/assuan-buffer.c
+++ b/assuan/assuan-buffer.c
@@ -25,16 +25,37 @@
#include <errno.h>
#include <unistd.h>
#include <assert.h>
-
+#ifdef USE_GNU_PTH
+# include <pth.h>
+#endif
#include "assuan-defs.h"
+#ifdef HAVE_JNLIB_LOGGING
+#include "../jnlib/logging.h"
+#endif
+
+
+static const char *
+my_log_prefix (void)
+{
+#ifdef HAVE_JNLIB_LOGGING
+ return log_get_prefix (NULL);
+#else
+ return "";
+#endif
+}
+
static int
writen ( int fd, const char *buffer, size_t length )
{
while (length)
{
+#ifdef USE_GNU_PTH
+ int nwritten = pth_write (fd, buffer, length);
+#else
int nwritten = write (fd, buffer, length);
+#endif
if (nwritten < 0)
{
@@ -59,7 +80,11 @@ readline (int fd, char *buf, size_t buflen, int *r_nread, int *eof)
*r_nread = 0;
while (nleft > 0)
{
+#ifdef USE_GNU_PTH
+ int n = pth_read (fd, buf, nleft);
+#else
int n = read (fd, buf, nleft);
+#endif
if (n < 0)
{
if (errno == EINTR)
@@ -122,15 +147,15 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
if (rc)
{
if (ctx->log_fp)
- fprintf (ctx->log_fp, "%p <- [Error: %s]\n",
- ctx, strerror (errno));
+ fprintf (ctx->log_fp, "%s[%p] <- [Error: %s]\n",
+ my_log_prefix (), 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);
+ fprintf (ctx->log_fp, "%s[%p] <- [EOF]\n", my_log_prefix (),ctx);
return -1;
}
@@ -163,7 +188,7 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
ctx->inbound.linelen = n;
if (ctx->log_fp)
{
- fprintf (ctx->log_fp, "%p <- ", ctx);
+ fprintf (ctx->log_fp, "%s[%p] <- ", my_log_prefix (), ctx);
if (ctx->confidential)
fputs ("[Confidential data not shown]", ctx->log_fp);
else
@@ -177,7 +202,7 @@ _assuan_read_line (ASSUAN_CONTEXT ctx)
}
if (ctx->log_fp)
- fprintf (ctx->log_fp, "%p <- [Invalid line]\n", ctx);
+ fprintf (ctx->log_fp, "%s[%p] <- [Invalid line]\n", my_log_prefix (), ctx);
*line = 0;
ctx->inbound.linelen = 0;
return ctx->inbound.eof? ASSUAN_Line_Not_Terminated : ASSUAN_Line_Too_Long;
@@ -229,7 +254,7 @@ assuan_write_line (ASSUAN_CONTEXT ctx, const char *line )
/* fixme: we should do some kind of line buffering */
if (ctx->log_fp)
{
- fprintf (ctx->log_fp, "%p -> ", ctx);
+ fprintf (ctx->log_fp, "%s[%p] -> ", my_log_prefix (), ctx);
if (ctx->confidential)
fputs ("[Confidential data not shown]", ctx->log_fp);
else
@@ -300,7 +325,7 @@ _assuan_cookie_write_data (void *cookie, const char *buffer, size_t size)
{
if (ctx->log_fp)
{
- fprintf (ctx->log_fp, "%p -> ", ctx);
+ fprintf (ctx->log_fp, "%s[%p] -> ", my_log_prefix (), ctx);
if (ctx->confidential)
fputs ("[Confidential data not shown]", ctx->log_fp);
else
@@ -345,7 +370,7 @@ _assuan_cookie_write_flush (void *cookie)
{
if (ctx->log_fp)
{
- fprintf (ctx->log_fp, "%p -> ", ctx);
+ fprintf (ctx->log_fp, "%s[%p] -> ", my_log_prefix (), ctx);
if (ctx->confidential)
fputs ("[Confidential data not shown]", ctx->log_fp);
else
diff --git a/assuan/assuan-client.c b/assuan/assuan-client.c
index d56357dc..6c7a6e3e 100644
--- a/assuan/assuan-client.c
+++ b/assuan/assuan-client.c
@@ -57,6 +57,15 @@ _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off)
*okay = 2; /* data line */
*off = 2;
}
+ else if (linelen >= 1
+ && line[0] == 'S'
+ && (line[1] == '\0' || line[1] == ' '))
+ {
+ *okay = 4;
+ *off = 1;
+ while (line[*off] == ' ')
+ ++*off;
+ }
else if (linelen >= 2
&& line[0] == 'O' && line[1] == 'K'
&& (line[2] == '\0' || line[2] == ' '))
@@ -86,6 +95,13 @@ _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off)
while (line[*off] == ' ')
++*off;
}
+ else if (linelen >= 3
+ && line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
+ && (line[3] == '\0' || line[3] == ' '))
+ {
+ *okay = 5; /* end line */
+ *off = 3;
+ }
else
rc = ASSUAN_Invalid_Response;
return rc;
@@ -101,6 +117,8 @@ _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off)
* @data_cb_arg: first argument passed to @data_cb
* @inquire_cb: Callback function for a inquire response
* @inquire_cb_arg: first argument passed to @inquire_cb
+ * @status_cb: Callback function for a status response
+ * @status_cb_arg: first argument passed to @status_cb
*
* FIXME: Write documentation
*
@@ -114,7 +132,9 @@ assuan_transact (ASSUAN_CONTEXT ctx,
AssuanError (*data_cb)(void *, const void *, size_t),
void *data_cb_arg,
AssuanError (*inquire_cb)(void*, const char *),
- void *inquire_cb_arg)
+ void *inquire_cb_arg,
+ AssuanError (*status_cb)(void*, const char *),
+ void *status_cb_arg)
{
int rc, okay, off;
unsigned char *line;
@@ -181,6 +201,25 @@ assuan_transact (ASSUAN_CONTEXT ctx,
goto again;
}
}
+ else if (okay == 4)
+ {
+ if (status_cb)
+ rc = status_cb (status_cb_arg, line);
+ if (!rc)
+ goto again;
+ }
+ else if (okay == 5)
+ {
+ if (!data_cb)
+ rc = ASSUAN_No_Data_Callback;
+ else
+ {
+ rc = data_cb (data_cb_arg, NULL, 0);
+ if (!rc)
+ goto again;
+ }
+ }
return rc;
}
+
diff --git a/assuan/assuan-defs.h b/assuan/assuan-defs.h
index 7d55aabd..6c502bf9 100644
--- a/assuan/assuan-defs.h
+++ b/assuan/assuan-defs.h
@@ -77,6 +77,9 @@ struct assuan_context_s {
In socket mode, the pid of the server */
int listen_fd; /* The fd we are listening on (used by socket servers) */
+ pid_t client_pid; /* for a socket server the PID of the client or -1
+ if not available */
+
void (*deinit_handler)(ASSUAN_CONTEXT);
int (*accept_handler)(ASSUAN_CONTEXT);
int (*finish_handler)(ASSUAN_CONTEXT);
@@ -92,7 +95,6 @@ struct assuan_context_s {
void (*input_notify_fnc)(ASSUAN_CONTEXT, const char *);
void (*output_notify_fnc)(ASSUAN_CONTEXT, const char *);
-
int input_fd; /* set by INPUT command */
int output_fd; /* set by OUTPUT command */
@@ -135,9 +137,3 @@ void _assuan_log_sanitized_string (const char *string);
#endif /*ASSUAN_DEFS_H*/
-
-
-
-
-
-
diff --git a/assuan/assuan-handler.c b/assuan/assuan-handler.c
index 1c8aded7..69b34b4f 100644
--- a/assuan/assuan-handler.c
+++ b/assuan/assuan-handler.c
@@ -464,6 +464,12 @@ process_request (ASSUAN_CONTEXT ctx)
if (!rc && ctx->outbound.data.error)
rc = ctx->outbound.data.error;
}
+ else /* flush any data send w/o using the data fp */
+ {
+ assuan_send_data (ctx, NULL, 0);
+ if (!rc && ctx->outbound.data.error)
+ rc = ctx->outbound.data.error;
+ }
/* Error handling */
if (!rc)
{
@@ -478,7 +484,7 @@ process_request (ASSUAN_CONTEXT ctx)
{
char errline[256];
- if (rc < 100)
+ if (rc < 100)
sprintf (errline, "ERR %d server fault (%.50s)",
ASSUAN_Server_Fault, assuan_strerror (rc));
else
diff --git a/assuan/assuan-inquire.c b/assuan/assuan-inquire.c
index 933091e1..2bac1303 100644
--- a/assuan/assuan-inquire.c
+++ b/assuan/assuan-inquire.c
@@ -126,9 +126,10 @@ free_membuf (struct membuf *mb)
* @keyword: The keyword used for the inquire
* @r_buffer: Returns an allocated buffer
* @r_length: Returns the length of this buffer
- * @maxlen: If no 0, the size limit of the inquired data.
+ * @maxlen: If not 0, the size limit of the inquired data.
*
- * A Server may use this to Send an inquire
+ * A Server may use this to Send an inquire. r_buffer, r_length and
+ * maxlen may all be NULL/0 to indicate that no real data is expected.
*
* Return value: 0 on success or an ASSUAN error code
**/
@@ -141,9 +142,12 @@ assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword,
char cmdbuf[100];
unsigned char *line, *p;
int linelen;
+ int nodataexpected;
- if (!ctx || !keyword || (10 + strlen (keyword) >= sizeof (cmdbuf))
- || !r_buffer || !r_length )
+ if (!ctx || !keyword || (10 + strlen (keyword) >= sizeof (cmdbuf)))
+ return ASSUAN_Invalid_Value;
+ nodataexpected = !r_buffer && !r_length && !maxlen;
+ if (!nodataexpected && (!r_buffer || !r_length))
return ASSUAN_Invalid_Value;
if (!ctx->is_server)
return ASSUAN_Not_A_Server;
@@ -151,7 +155,10 @@ assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword,
return ASSUAN_Nested_Commands;
ctx->in_inquire = 1;
- init_membuf (&mb, maxlen? maxlen:1024, maxlen);
+ if (nodataexpected)
+ memset (&mb, 0, sizeof mb); /* avoid compiler warnings */
+ else
+ init_membuf (&mb, maxlen? maxlen:1024, maxlen);
strcpy (stpcpy (cmdbuf, "INQUIRE "), keyword);
rc = assuan_write_line (ctx, cmdbuf);
@@ -172,7 +179,12 @@ assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword,
if (line[0] == 'E' && line[1] == 'N' && line[2] == 'D'
&& (!line[3] || line[3] == ' '))
break; /* END command received*/
- if (line[0] != 'D' || line[1] != ' ')
+ if (line[0] == 'C' && line[1] == 'A' && line[2] == 'N')
+ {
+ rc = ASSUAN_Canceled;
+ goto leave;
+ }
+ if (line[0] != 'D' || line[1] != ' ' || nodataexpected)
{
rc = ASSUAN_Unexpected_Command;
goto leave;
@@ -205,13 +217,17 @@ assuan_inquire (ASSUAN_CONTEXT ctx, const char *keyword,
goto leave;
}
}
-
- *r_buffer = get_membuf (&mb, r_length);
- if (!*r_buffer)
- rc = ASSUAN_Out_Of_Core;
+
+ if (!nodataexpected)
+ {
+ *r_buffer = get_membuf (&mb, r_length);
+ if (!*r_buffer)
+ rc = ASSUAN_Out_Of_Core;
+ }
leave:
- free_membuf (&mb);
+ if (!nodataexpected)
+ free_membuf (&mb);
ctx->in_inquire = 0;
return rc;
}
diff --git a/assuan/assuan-pipe-server.c b/assuan/assuan-pipe-server.c
index d15f54f5..5c5d1248 100644
--- a/assuan/assuan-pipe-server.c
+++ b/assuan/assuan-pipe-server.c
@@ -64,6 +64,7 @@ _assuan_new_context (ASSUAN_CONTEXT *r_ctx)
ctx->outbound.fd = -1;
ctx->listen_fd = -1;
+ ctx->client_pid = (pid_t)-1;
/* use the pipe server handler as a default */
ctx->deinit_handler = deinit_pipe_server;
ctx->accept_handler = accept_connection;
diff --git a/assuan/assuan-socket-server.c b/assuan/assuan-socket-server.c
index 6ad6455e..39dd84a1 100644
--- a/assuan/assuan-socket-server.c
+++ b/assuan/assuan-socket-server.c
@@ -25,6 +25,9 @@
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
+#ifdef USE_GNU_PTH
+# include <pth.h>
+#endif
#include "assuan-defs.h"
@@ -35,13 +38,28 @@ accept_connection (ASSUAN_CONTEXT ctx)
struct sockaddr_un clnt_addr;
size_t len = sizeof clnt_addr;
+ ctx->client_pid = (pid_t)-1;
+#ifdef USE_GNU_PTH
+ fd = pth_accept (ctx->listen_fd, (struct sockaddr*)&clnt_addr, &len );
+#else
fd = accept (ctx->listen_fd, (struct sockaddr*)&clnt_addr, &len );
+#endif
if (fd == -1)
{
ctx->os_errno = errno;
return ASSUAN_Accept_Failed;
}
+#ifdef HAVE_SO_PEERCRED
+ {
+ struct ucred cr;
+ int cl = sizeof cr;
+
+ if ( !getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cl) )
+ ctx->client_pid = cr.pid;
+ }
+#endif
+
ctx->inbound.fd = fd;
ctx->inbound.eof = 0;
ctx->inbound.linelen = 0;
diff --git a/assuan/assuan.h b/assuan/assuan.h
index 5971d81b..a9340019 100644
--- a/assuan/assuan.h
+++ b/assuan/assuan.h
@@ -73,6 +73,12 @@ typedef enum {
ASSUAN_Inquire_Unknown = 120,
ASSUAN_Inquire_Error = 121,
ASSUAN_Invalid_Option = 122,
+ ASSUAN_Invalid_Index = 123,
+ ASSUAN_Unexpected_Status = 124,
+ ASSUAN_Unexpected_Data = 125,
+ ASSUAN_Invalid_Status = 126,
+
+ ASSUAN_Not_Confirmed = 128,
ASSUAN_Bad_Certificate = 201,
ASSUAN_Bad_Certificate_Path = 202,
@@ -89,6 +95,12 @@ typedef enum {
ASSUAN_CRL_Too_Old = 303,
ASSUAN_Not_Trusted = 304,
+ ASSUAN_Card_Error = 401,
+ ASSUAN_Invalid_Card = 402,
+ ASSUAN_No_PKCS15_App = 403,
+ ASSUAN_Card_Not_Present = 404,
+ ASSUAN_Invalid_Id = 405
+
} AssuanError;
/* This is a list of pre-registered ASSUAN commands */
@@ -178,7 +190,9 @@ assuan_transact (ASSUAN_CONTEXT ctx,
AssuanError (*data_cb)(void *, const void *, size_t),
void *data_cb_arg,
AssuanError (*inquire_cb)(void*, const char *),
- void *inquire_cb_arg);
+ void *inquire_cb_arg,
+ AssuanError (*status_cb)(void*, const char *),
+ void *status_cb_arg);
/*-- assuan-inquire.c --*/