aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gpgme/ChangeLog13
-rw-r--r--gpgme/engine-gpgsm.c113
-rw-r--r--gpgme/engine-gpgsm.h6
-rw-r--r--gpgme/engine.c8
4 files changed, 106 insertions, 34 deletions
diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog
index d500acae..bf9796d2 100644
--- a/gpgme/ChangeLog
+++ b/gpgme/ChangeLog
@@ -1,10 +1,21 @@
2001-12-13 Werner Koch <[email protected]>
+ * engine-gpgsm.c (_gpgme_gpgsm_set_colon_line_handler): New.
+ (gpgsm_status_handler): Pass datalines to a colon handler
+ * engine.c (_gpgme_engine_set_colon_line_handler): Set the colon
+ handler for gpgsm.
+
* engine-gpgsm.c (_gpgme_gpgsm_op_keylist): Allow NULL for
pattern.
(gpgsm_assuan_simple_command): Removed underscore from
assuan_write_line.
- (_gpgme_gpgsm_start): Ditto.
+ (_gpgme_gpgsm_start): Ditto.
+ (gpgsm_assuan_simple_command): Replaced interal Assuan read
+ function by the new assuan_read_line. Removed the use of the
+ internal header.
+ (gpgsm_status_handler): Ditto. Use the new assuan_pending_line.
+ (_gpgme_gpgsm_start): Use the documented way to get an fd from
+ assuan.
* keylist.c (keylist_colon_handler): Handle "crt" records
* key.h (gpgme_key_s): Add an x509 flag.
diff --git a/gpgme/engine-gpgsm.c b/gpgme/engine-gpgsm.c
index ea3cd0d6..38ce87d8 100644
--- a/gpgme/engine-gpgsm.c
+++ b/gpgme/engine-gpgsm.c
@@ -36,13 +36,6 @@
#include <assert.h>
#include <fcntl.h> /* FIXME */
-/* FIXME */
-#include "../assuan/assuan-defs.h"
-#undef xtrymalloc
-#undef xtrycalloc
-#undef xtryrealloc
-#undef xfree
-
#include "rungpg.h"
#include "status-table.h"
@@ -58,6 +51,11 @@
#include "assuan.h"
+#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
+ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
+#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
+
+
struct gpgsm_object_s
{
ASSUAN_CONTEXT assuan_ctx;
@@ -80,14 +78,19 @@ struct gpgsm_object_s
GpgStatusHandler fnc;
void *fnc_value;
} status;
+
+ struct
+ {
+ GpgColonLineHandler fnc;
+ void *fnc_value;
+ } colon;
};
const char *
_gpgme_gpgsm_get_version (void)
{
-#warning version check is disabled
- static const char *gpgsm_version = "0.0.1";
+ static const char *gpgsm_version;
/* FIXME: Locking. */
if (!gpgsm_version)
@@ -192,25 +195,27 @@ _gpgme_gpgsm_release (GpgsmObject gpgsm)
}
static AssuanError
-gpgsm_assuan_simple_command (ASSUAN_CONTEXT ctx, char *line)
+gpgsm_assuan_simple_command (ASSUAN_CONTEXT ctx, char *cmd)
{
AssuanError err;
+ char *line;
+ size_t linelen;
- err = assuan_write_line (ctx, line);
+ err = assuan_write_line (ctx, cmd);
if (err)
return err;
do
{
- err = _assuan_read_line (ctx);
+ err = assuan_read_line (ctx, &line, &linelen);
if (err)
return err;
}
- while (*ctx->inbound.line == '#' || !ctx->inbound.linelen);
+ while (*line == '#' || !linelen);
- if (ctx->inbound.linelen >= 2
- && ctx->inbound.line[0] == 'O' && ctx->inbound.line[1] == 'K'
- && (ctx->inbound.line[2] == '\0' || ctx->inbound.line[2] == ' '))
+ if (linelen >= 2
+ && line[0] == 'O' && line[1] == 'K'
+ && (line[2] == '\0' || line[2] == ' '))
return 0;
else
return ASSUAN_General_Error;
@@ -477,21 +482,17 @@ gpgsm_status_handler (void *opaque, int pid, int fd)
{
int err;
GpgsmObject gpgsm = opaque;
- ASSUAN_CONTEXT actx = gpgsm->assuan_ctx;
char *line;
- int linelen;
+ size_t linelen;
do
{
- assert (fd == gpgsm->assuan_ctx->inbound.fd);
-
- err = _assuan_read_line (gpgsm->assuan_ctx);
- line = actx->inbound.line;
- linelen = strlen (line);
+ err = assuan_read_line (gpgsm->assuan_ctx, &line, &linelen);
- if ((linelen >= 2
- && line[0] == 'O' && line[1] == 'K'
- && (line[2] == '\0' || line[2] == ' '))
+ if (err
+ || (linelen >= 2
+ && line[0] == 'O' && line[1] == 'K'
+ && (line[2] == '\0' || line[2] == ' '))
|| (linelen >= 3
&& line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
&& (line[3] == '\0' || line[3] == ' ')))
@@ -501,9 +502,41 @@ gpgsm_status_handler (void *opaque, int pid, int fd)
gpgsm->status.fnc (gpgsm->status.fnc_value, STATUS_EOF, "");
return 1;
}
- /* FIXME: Parse the status and call the handler. */
-
+
if (linelen > 2
+ && line[0] == 'D' && line[1] == ' '
+ && gpgsm->colon.fnc )
+ {
+ unsigned char *s, *d;
+
+ line += 2;
+ linelen -= 2;
+ /* Hmmm, we are using the colon handler even for plain
+ inline data - strange name for that fucntion but for
+ historic reasons we keep it */
+ for (s=d=line; linelen; linelen--)
+ {
+ if (*s == '%' && linelen > 2)
+ { /* handle escaping */
+ s++;
+ *d++ = xtoi_2 (s);
+ s += 2;
+ linelen -= 2;
+ }
+ else
+ *d++ = *s++;
+ }
+ *d = 0; /* add a hidden string terminator */
+
+ /* fixme: should we handle the return code? */
+ /* fixme: Hmmm: we can't use this for binary data because we
+ assume this is a string. For the current usage of colon
+ output it is correct */
+ /* FIXME: we need extra bufferring to pass colon lines line
+ by line */
+ gpgsm->colon.fnc (gpgsm->colon.fnc_value, line);
+ }
+ else if (linelen > 2
&& line[0] == 'S' && line[1] == ' ')
{
struct status_table_s t, *r;
@@ -528,7 +561,7 @@ gpgsm_status_handler (void *opaque, int pid, int fd)
fprintf (stderr, "[UNKNOWN STATUS]%s %s", t.name, rest);
}
}
- while (gpgsm->assuan_ctx->inbound.attic.linelen);
+ while (assuan_pending_line (gpgsm->assuan_ctx));
return 0;
}
@@ -543,19 +576,39 @@ _gpgme_gpgsm_set_status_handler (GpgsmObject gpgsm,
gpgsm->status.fnc_value = fnc_value;
}
+void
+_gpgme_gpgsm_set_colon_line_handler (GpgsmObject gpgsm,
+ GpgColonLineHandler fnc, void *fnc_value)
+{
+ assert (gpgsm);
+
+ gpgsm->colon.fnc = fnc;
+ gpgsm->colon.fnc_value = fnc_value;
+}
+
GpgmeError
_gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque)
{
GpgmeError err = 0;
pid_t pid;
+ int fdlist[5];
+ int nfds;
if (!gpgsm)
return mk_error (Invalid_Value);
pid = assuan_get_pid (gpgsm->assuan_ctx);
+ /* We need to know the fd used by assuan for reads. We do this by
+ using the assumption that the first returned fd from
+ assuan_get_active_fds() is always this one. */
+ nfds = assuan_get_active_fds (gpgsm->assuan_ctx, 0 /* read fds */,
+ fdlist, DIM (fdlist));
+ if (nfds < 1)
+ return mk_error (General_Error);
err = _gpgme_register_pipe_handler (opaque, gpgsm_status_handler, gpgsm, pid,
- gpgsm->assuan_ctx->inbound.fd, 1);
+ fdlist[0], 1);
+
if (gpgsm->input_fd != -1)
{
diff --git a/gpgme/engine-gpgsm.h b/gpgme/engine-gpgsm.h
index bd6dd1e7..9ebd8d7b 100644
--- a/gpgme/engine-gpgsm.h
+++ b/gpgme/engine-gpgsm.h
@@ -33,6 +33,8 @@ void _gpgme_gpgsm_release (GpgsmObject gpg);
void _gpgme_gpgsm_set_status_handler (GpgsmObject gpgsm,
GpgStatusHandler fnc, void *fnc_value);
+void _gpgme_gpgsm_set_colon_line_handler (GpgsmObject gpgsm,
+ GpgColonLineHandler fnc, void *fnc_value) ;
GpgmeError _gpgme_gpgsm_op_decrypt (GpgsmObject gpgsm, GpgmeData ciph,
GpgmeData plain);
GpgmeError _gpgme_gpgsm_op_delete (GpgsmObject gpgsm, GpgmeKey key,
@@ -57,3 +59,7 @@ GpgmeError _gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig,
GpgmeError _gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque);
#endif /* ENGINE_GPGSM_H */
+
+
+
+
diff --git a/gpgme/engine.c b/gpgme/engine.c
index 08fb9515..025832bb 100644
--- a/gpgme/engine.c
+++ b/gpgme/engine.c
@@ -226,11 +226,13 @@ GpgmeError _gpgme_engine_set_colon_line_handler (EngineObject engine,
switch (engine->protocol)
{
case GPGME_PROTOCOL_OpenPGP:
- return _gpgme_gpg_set_colon_line_handler (engine->engine.gpg, fnc,
- fnc_value);
+ return _gpgme_gpg_set_colon_line_handler (engine->engine.gpg,
+ fnc, fnc_value);
case GPGME_PROTOCOL_CMS:
- /* FIXME */
+ _gpgme_gpgsm_set_colon_line_handler (engine->engine.gpgsm,
+ fnc, fnc_value);
break;
+
default:
break;
}