aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sm/Makefile.am11
-rw-r--r--sm/gpgsm.c2
-rw-r--r--sm/gpgsm.h16
-rw-r--r--sm/import.c213
-rw-r--r--sm/misc.c41
-rwxr-xr-xsm/mkerrors72
-rw-r--r--sm/server.c182
-rw-r--r--sm/util.h4
8 files changed, 537 insertions, 4 deletions
diff --git a/sm/Makefile.am b/sm/Makefile.am
index 82a5e483a..47de0a8e3 100644
--- a/sm/Makefile.am
+++ b/sm/Makefile.am
@@ -22,12 +22,17 @@ bin_PROGRAMS = gpgsm
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl
LDFLAGS = @LDFLAGS@ $(LIBGCRYPT_LIBS)
+BUILT_SOURCES = errors.c
gpgsm_SOURCES = \
gpgsm.c gpgsm.h \
- util.h \
- server.c
+ util.h misc.c errors.c \
+ server.c \
+ import.c
-gpgsm_LDADD = ../jnlib/libjnlib.a ../assuan/libassuan.a
+gpgsm_LDADD = ../jnlib/libjnlib.a ../assuan/libassuan.a \
+ ../../libksba/src/.libs/libksba.a
+errors.c : gpgsm.h mkerrors
+ $(srcdir)/mkerrors < $(srcdir)/gpgsm.h > errors.c
diff --git a/sm/gpgsm.c b/sm/gpgsm.c
index 8b715f40a..972ce080c 100644
--- a/sm/gpgsm.c
+++ b/sm/gpgsm.c
@@ -477,7 +477,7 @@ main ( int argc, char **argv)
int orig_argc;
char **orig_argv;
const char *fname;
- char *username;
+ /* char *username;*/
int may_coredump;
STRLIST sl, remusr= NULL, locusr=NULL;
STRLIST nrings=NULL;
diff --git a/sm/gpgsm.h b/sm/gpgsm.h
index ac169336a..1c66e1032 100644
--- a/sm/gpgsm.h
+++ b/sm/gpgsm.h
@@ -23,6 +23,19 @@
#include "util.h"
+/* Error numbers */
+enum {
+ GPGSM_EOF = -1,
+ GPGSM_No_Error = 0,
+ GPGSM_General_Error = 1,
+ GPGSM_Out_Of_Core = 2,
+ GPGSM_Invalid_Value = 3,
+ GPGSM_IO_Error = 4,
+
+
+};
+
+
/* A large struct name "opt" to keep global flags */
struct {
unsigned int debug; /* debug flags (DBG_foo_VALUE) */
@@ -83,4 +96,7 @@ void gpgsm_exit (int rc);
void gpgsm_server (void);
+/*-- import.c --*/
+int gpgsm_import (int in_fd);
+
#endif /*GPGSM_H*/
diff --git a/sm/import.c b/sm/import.c
new file mode 100644
index 000000000..b3827e222
--- /dev/null
+++ b/sm/import.c
@@ -0,0 +1,213 @@
+/* import.c - Import certificates
+ * Copyright (C) 2001 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <time.h>
+#include <assert.h>
+
+#include <ksba.h>
+
+#include "gpgsm.h"
+
+struct reader_cb_parm_s {
+ FILE *fp;
+};
+
+
+static int
+reader_cb (void *cb_value, unsigned char *buffer, size_t count, size_t *nread)
+{
+ struct reader_cb_parm_s *parm = cb_value;
+ size_t n;
+ int c = 0;
+
+ *nread = 0;
+ if (!buffer)
+ return -1; /* not supported */
+
+ for (n=0; n < count; n++)
+ {
+ c = getc (parm->fp);
+ if (c == EOF)
+ {
+ if ( ferror (parm->fp) )
+ return -1;
+ if (n)
+ break; /* return what we have beofre an EOF */
+ return -1;
+ }
+ *buffer++ = c;
+ }
+
+ *nread = n;
+ return 0;
+}
+
+
+static void
+print_integer (unsigned char *p)
+{
+ unsigned long len;
+
+ if (!p)
+ fputs ("none", stdout);
+ else
+ {
+ len = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+ for (p+=4; len; len--, p++)
+ printf ("%02X", *p);
+ }
+}
+
+static void
+print_time (time_t t)
+{
+
+ if (!t)
+ fputs ("none", stdout);
+ else if ( t == (time_t)(-1) )
+ fputs ("error", stdout);
+ else
+ {
+ struct tm *tp;
+
+ tp = gmtime (&t);
+ printf ("%04d-%02d-%02d %02d:%02d:%02d",
+ 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday,
+ tp->tm_hour, tp->tm_min, tp->tm_sec);
+ assert (!tp->tm_isdst);
+ }
+}
+
+static void
+print_dn (char *p)
+{
+
+ if (!p)
+ fputs ("error", stdout);
+ else
+ printf ("`%s'", p);
+}
+
+
+
+
+int
+gpgsm_import (int in_fd)
+{
+ int rc;
+ KsbaReader reader = NULL;
+ KsbaCert cert = NULL;
+ struct reader_cb_parm_s rparm;
+
+ memset (&rparm, 0, sizeof rparm);
+
+ rparm.fp = fdopen ( dup (in_fd), "rb");
+ if (!rparm.fp)
+ {
+ log_error ("fdopen() failed: %s\n", strerror (errno));
+ rc = seterr (IO_Error);
+ goto leave;
+ }
+
+ /* setup a skaba reader which uses a callback function so that we can
+ strip off a base64 encoding when necessary */
+ reader = ksba_reader_new ();
+ if (!reader)
+ {
+ rc = seterr (Out_Of_Core);
+ goto leave;
+ }
+
+ rc = ksba_reader_set_cb (reader, reader_cb, &rparm );
+ if (rc)
+ {
+ ksba_reader_release (reader);
+ rc = map_ksba_err (rc);
+ goto leave;
+ }
+
+ cert = ksba_cert_new ();
+ if (!cert)
+ {
+ rc = seterr (Out_Of_Core);
+ goto leave;
+ }
+
+ rc = ksba_cert_read_der (cert, reader);
+ if (rc)
+ {
+ rc = map_ksba_err (rc);
+ goto leave;
+ }
+
+ {
+ unsigned char *p;
+ char *dn;
+ time_t t;
+
+ p = ksba_cert_get_serial (cert);
+ fputs ("serial: ", stdout);
+ print_integer (p);
+ ksba_free (p);
+ putchar ('\n');
+
+ t = ksba_cert_get_validity (cert, 0);
+ fputs ("notBefore: ", stdout);
+ print_time (t);
+ putchar ('\n');
+ t = ksba_cert_get_validity (cert, 1);
+ fputs ("notAfter: ", stdout);
+ print_time (t);
+ putchar ('\n');
+
+ dn = ksba_cert_get_issuer (cert);
+ fputs ("issuer: ", stdout);
+ print_dn (dn);
+ ksba_free (dn);
+ putchar ('\n');
+
+ dn = ksba_cert_get_subject (cert);
+ fputs ("subject: ", stdout);
+ print_dn (dn);
+ ksba_free (dn);
+ putchar ('\n');
+
+ printf ("hash algo: %d\n", ksba_cert_get_digest_algo (cert));
+
+ ksba_cert_hash (cert, NULL, NULL);
+ }
+
+ leave:
+ ksba_cert_release (cert);
+ ksba_reader_release (reader);
+ if (rparm.fp)
+ fclose (rparm.fp);
+ return rc;
+}
+
+
+
+
diff --git a/sm/misc.c b/sm/misc.c
new file mode 100644
index 000000000..c1bc346d1
--- /dev/null
+++ b/sm/misc.c
@@ -0,0 +1,41 @@
+/* misc.c - Miscellaneous fucntions
+ * Copyright (C) 2001 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 <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+
+#include <ksba.h>
+
+#include "util.h"
+
+
+/* Note: we might want to wrap this in a macro to get our hands on
+ the line and file wehre the error occired */
+int
+map_ksba_err (int err)
+{
+ return -1;
+}
+
diff --git a/sm/mkerrors b/sm/mkerrors
new file mode 100755
index 000000000..46c28e8c9
--- /dev/null
+++ b/sm/mkerrors
@@ -0,0 +1,72 @@
+#!/bin/sh
+# mkerrors - Extract error strings from gpgsm.h
+# and create C source for gpgsm_strerror
+# Copyright (C) 2001 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
+
+cat <<EOF
+/* Generated automatically by mkerrors */
+/* Do not edit! */
+
+#include <config.h>
+#include <stdio.h>
+#include "gpgsm.h"
+
+/**
+ * gpgsm_strerror:
+ * @err: Error code
+ *
+ * This function returns a textual representaion of the given
+ * errorcode. If this is an unknown value, a string with the value
+ * is returned (Beware: it is hold in a static buffer).
+ *
+ * Return value: String with the error description.
+ **/
+const char *
+gpgsm_strerror (int err)
+{
+ const char *s;
+ static char buf[25];
+
+ switch (err)
+ {
+EOF
+
+awk '
+/GPGSM_No_Error/ { okay=1 }
+!okay {next}
+/}/ { exit 0 }
+/GPGSM_[A-Za-z_]*/ { print_code($1) }
+
+
+function print_code( s )
+{
+printf " case %s: s=\"", s ;
+gsub(/_/, " ", s );
+printf "%s\"; break;\n", tolower(substr(s,7));
+}
+'
+
+cat <<EOF
+ default: sprintf (buf, "ec=%d", err ); s=buf; break;
+ }
+
+ return s;
+}
+
+EOF \ No newline at end of file
diff --git a/sm/server.c b/sm/server.c
index 51e7a3918..daea4962a 100644
--- a/sm/server.c
+++ b/sm/server.c
@@ -29,8 +29,153 @@
#include "gpgsm.h"
#include "../assuan/assuan.h"
+#define set_error(e,t) assuan_set_error (ctx, ASSUAN_ ## e, (t))
+/* RECIPIENT <userID>
+
+ Set the recipient for the encryption. <userID> should be the
+ internal representation of the key; the server may accept any other
+ way of specification [we will support this]. If this is a valid and
+ trusted recipient the server does respond with OK, otherwise the
+ return is an ERR with the reason why the recipient can't be used,
+ the encryption will then not be done for this recipient. IF the
+ policy is not to encrypt at all if not all recipients are valid, the
+ client has to take care of this. All RECIPIENT commands are
+ cumulative until a RESET or ENCRYPT command. */
+static int
+cmd_recipient (ASSUAN_CONTEXT ctx, char *line)
+{
+
+
+ return set_error (Not_Implemented, "fixme");
+}
+
+
+/* ENCRYPT [armor]
+
+ Do the actual encryption process. Takes the plaintext from the INPUT
+ command, writes to the ciphertext to the file descriptor set with
+ the OUTPUT command, take the recipients form all the recipients set
+ so far. If this command fails the clients should try to delete all
+ output currently done or otherwise mark it as invalid. GPGSM does
+ ensure that there won't be any security problem with leftover data
+ on the output in this case.
+
+ This command should in general not fail, as all necessary checks
+ have been done while setting the recipients. The input and output
+ pipes are closed.
+
+ The optional armor parameter may be used to request base64 encoded
+ output. */
+static int
+cmd_encrypt (ASSUAN_CONTEXT ctx, char *line)
+{
+
+
+ return set_error (Not_Implemented, "fixme");
+}
+
+/* DECRYPT
+
+ This performs the decrypt operation after doing some check on the
+ internal state. (e.g. that only needed data has been set). Because
+ it utilises the GPG-Agent for the session key decryption, there is
+ no need to ask the client for a protecting passphrase - GpgAgent
+ does take care of this but requesting this from the user. */
+static int
+cmd_decrypt (ASSUAN_CONTEXT ctx, char *line)
+{
+
+
+ return set_error (Not_Implemented, "fixme");
+}
+
+
+/* VERIFY
+
+ This does a verify operation on the message send to the input-FD.
+ The result is written out using status lines. If an output FD was
+ given, the signed text will be written to that.
+
+ The behavior for detached signatures has not yet been specified. */
+static int
+cmd_verify (ASSUAN_CONTEXT ctx, char *line)
+{
+
+
+ return set_error (Not_Implemented, "fixme");
+}
+
+
+/* SIGN
+
+ FIXME */
+static int
+cmd_sign (ASSUAN_CONTEXT ctx, char *line)
+{
+
+
+ return set_error (Not_Implemented, "fixme");
+}
+
+
+/* IMPORT
+
+ Import the certificates read form the input-fd, return status
+ message for each imported one. The import checks the validity of
+ the certificate but not of the path. It is possible to import
+ expired certificates. */
+static int
+cmd_import (ASSUAN_CONTEXT ctx, char *line)
+{
+ int fd = assuan_get_input_fd (ctx);
+
+ if (fd == -1)
+ return set_error (No_Input, NULL);
+
+ gpgsm_import (fd);
+
+ return 0;
+}
+
+
+
+
+/* Tell the assuan library about our commands */
+static int
+register_commands (ASSUAN_CONTEXT ctx)
+{
+ static struct {
+ const char *name;
+ int cmd_id;
+ int (*handler)(ASSUAN_CONTEXT, char *line);
+ } table[] = {
+ { "RECIPIENT", 0, cmd_recipient },
+ { "ENCRYPT", 0, cmd_encrypt },
+ { "DECRYPT", 0, cmd_decrypt },
+ { "VERIFY", 0, cmd_verify },
+ { "SIGN", 0, cmd_sign },
+ { "IMPORT", 0, cmd_import },
+ { "", ASSUAN_CMD_INPUT, NULL },
+ { "", ASSUAN_CMD_OUTPUT, NULL },
+ { NULL }
+ };
+ int i, j, rc;
+
+ for (i=j=0; table[i].name; i++)
+ {
+ rc = assuan_register_command (ctx,
+ table[i].cmd_id? table[i].cmd_id
+ : (ASSUAN_CMD_USER + j++),
+ table[i].name, table[i].handler);
+ if (rc)
+ return rc;
+ }
+ return 0;
+}
+
+/* Startup the server */
void
gpgsm_server (void)
{
@@ -50,7 +195,44 @@ gpgsm_server (void)
assuan_strerror(rc));
gpgsm_exit (2);
}
+ rc = register_commands (ctx);
+ if (rc)
+ {
+ log_error ("failed to the register commands with Assuan: %s\n",
+ assuan_strerror(rc));
+ gpgsm_exit (2);
+ }
+
+ log_info ("Assuan started\n");
+ for (;;)
+ {
+ rc = assuan_accept (ctx);
+ if (rc == -1)
+ {
+ log_info ("Assuan terminated\n");
+ break;
+ }
+ else if (rc)
+ {
+ log_info ("Assuan accept problem: %s\n", assuan_strerror (rc));
+ break;
+ }
+
+ rc = assuan_process (ctx);
+ if (rc)
+ {
+ log_info ("Assuan processing failed: %s\n", assuan_strerror (rc));
+ continue;
+ }
+ }
assuan_deinit_pipe_server (ctx);
}
+
+
+
+
+
+
+
diff --git a/sm/util.h b/sm/util.h
index d2ac4c18c..f3b4ab7b5 100644
--- a/sm/util.h
+++ b/sm/util.h
@@ -42,5 +42,9 @@
#define xstrdup(a) gcry_xstrdup ((a))
+#define seterr(a) (GPGSM_ ## a)
+
+/*-- misc.c --*/
+int map_ksba_err (int err);
#endif /*UTIL_H*/