diff options
author | Repo Admin <nobody@gnupg.org> | 2003-01-09 14:29:36 +0100 |
---|---|---|
committer | Repo Admin <nobody@gnupg.org> | 2003-01-09 14:29:36 +0100 |
commit | 7b6f1902d02b0cec4a12d7b44b8d4583baa5bc0b (patch) | |
tree | 6556ef3a9255ffea9ca1dce8015940d30aa9d890 /tests | |
parent | Taken from NewPG (diff) | |
download | gnupg2-7b6f1902d02b0cec4a12d7b44b8d4583baa5bc0b.tar.xz gnupg2-7b6f1902d02b0cec4a12d7b44b8d4583baa5bc0b.zip |
This commit was manufactured by cvs2svn to create branch
'GNUPG-1-9-BRANCH'.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/ChangeLog | 68 | ||||
-rw-r--r-- | tests/Makefile.am | 78 | ||||
-rw-r--r-- | tests/asschk.c | 1059 | ||||
-rwxr-xr-x | tests/inittests | 99 |
4 files changed, 1304 insertions, 0 deletions
diff --git a/tests/ChangeLog b/tests/ChangeLog new file mode 100644 index 000000000..c6b3b9af1 --- /dev/null +++ b/tests/ChangeLog @@ -0,0 +1,68 @@ +2002-12-04 Werner Koch <wk@gnupg.org> + + * inittests (gpgsm.conf): Fake system time. + +2002-10-31 Neal H. Walfield <neal@g10code.de> + + * Makefile.am (inittests.stamp): Do not set LD_LIBRARY_PATH here. + (TESTS_ENVIRONMENT): Do it here. And also frob $(LIBGCRYPT_LIBS) + and $(PTH_LIBS). + +2002-10-31 Neal H. Walfield <neal@g10code.de> + + * asschk.c (die): New macro. + (read_assuan): If in verbose mode, dump the string that was read. + (write_assuan): Be more verbose on failure. + +2002-09-04 Neal H. Walfield <neal@g10code.de> + + * Makefile.am (inittests.stamp): Do not set LD_LIBRARY_PATH, but + rather prepend it. Be more robust and prefer printf over echo -n. + +2002-09-04 Marcus Brinkmann <marcus@g10code.de> + + * asschk.c (start_server): Close the parent's file descriptors in + the child. + (read_assuan): Variable NREAD removed. Cut off the received line + currectly if more than one line was read. + +2002-09-03 Neal H. Walfield <neal@g10code.de> + + * Makefile.am (inittests.stamp): Construct an LD_LIBRARY_PATH from + LDFLAGS. + +2002-08-09 Werner Koch <wk@gnupg.org> + + * asschk.c (cmd_getenv): New. + (expand_line): Allow / as variable name delimiter. + * sm-sign+verify, sm-verify: Use $srcdir so that a VPATH build works. + + * Makefile.am: Fixes for make dist. + * samplekets/Makefile.am: New. + +2002-08-08 Werner Koch <wk@gnupg.org> + + * asschk.c: Added some new features. + * runtest, inittests: New. + * text-1.txt, text-2.txt, text-3.txt: New. + * text-1.osig.pem, text-1.dsig.pem, text-1.osig-bad.pem: New. + * text-2.osig.pem, text-2.osig-bad.pem: New. + * samplekeys : New directory + * sm-verify, sm-sign+verify: The first test scripts. + +2002-08-06 Werner Koch <wk@gnupg.org> + + * Makefile.am, asschk.c: New. + + + Copyright 2002 Free Software Foundation, Inc. + + This file is free software; as a special exception the author gives + unlimited permission to copy and/or distribute it, with or without + modifications, as long as this notice is preserved. + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY, to the extent permitted by law; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 000000000..622b5fe58 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,78 @@ +# Makefile.am -tests makefile for libxtime +# 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 + +## Process this file with automake to produce Makefile.in + +GPGSM = ../sm/gpgsm + +# We can't unset a variable here so we unset GPG_AGENT_INFO in runtest +TESTS_ENVIRONMENT = GNUPGHOME=`pwd` LC_ALL=C GPGSM=$(GPGSM) \ + LD_LIBRARY_PATH=$$(seen=0; \ + for i in $(LDFLAGS) $(LIBGCRYPT_LIBS) $(PTH_LIBS); \ + do \ + if echo "$$i" | egrep '^-L' >/dev/null 2>&1; \ + then \ + if test $$seen = 0; \ + then \ + seen=1; \ + else \ + printf ":"; \ + fi; \ + printf "%s" "$${i}" | sed 's/^-L//'; \ + fi; \ + done; \ + if test $$seen != 0 \ + && test x$${LD_LIBRARY_PATH} != x; \ + then \ + printf ":"; \ + fi; \ + printf "%s" "$${LD_LIBRARY_PATH}") $(srcdir)/runtest + +testscripts = sm-sign+verify sm-verify + +EXTRA_DIST = runtest inittests $(testscripts) \ + text-1.txt text-2.txt text-3.txt \ + text-1.osig.pem text-1.dsig.pem text-1.osig-bad.pem \ + text-2.osig.pem text-2.osig-bad.pem \ + samplekeys/32100C27173EF6E9C4E9A25D3D69F86D37A4F939.key \ + samplekeys/cert_g10code_pete1.pem \ + samplekeys/cert_g10code_test1.pem \ + samplekeys/cert_g10code_theo1.pem + +TESTS = $(testscripts) + +CLEANFILES = inittests.stamp x y y z out err + *.lock .\#lk* + +DISTCLEANFILES = pubring.kbx~ random_seed + +noinst_PROGRAMS = asschk + +asschk_SOURCES = asschk.c + + +all-local: inittests.stamp + +clean-local: + srcdir=$(srcdir) $(TESTS_ENVIRONMENT) $(srcdir)/inittests --clean + +inittests.stamp: inittests + srcdir=$(srcdir) $(TESTS_ENVIRONMENT) $(srcdir)/inittests + echo timestamp >./inittests.stamp + diff --git a/tests/asschk.c b/tests/asschk.c new file mode 100644 index 000000000..83a8ca5af --- /dev/null +++ b/tests/asschk.c @@ -0,0 +1,1059 @@ +/* asschk.c - Assuan Server Checker + * 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 + */ + +/* This is a simple stand-alone Assuan server test program. We don't + want to use the assuan library because we don't want to hide errors + in that library. + + The script language is line based. Empty lines or lines containing + only white spaces are ignored, line with a hash sign as first non + white space character are treated as comments. + + A simple macro mechanism is implemnted. Macros are expanded before + a line is processed but after comment processing. Macros are only + expanded once and non existing macros expand to the empty string. + A macro is dereferenced by prefixing its name with a dollar sign; + the end of the name is currently indicated by a white space, a + dollar sign or a slash. To use a dollor sign verbatim, double it. + + A macro is assigned by prefixing a statement with the macro name + and an equal sign. The value is assigned verbatim if it does not + resemble a command, otherwise the return value of the command will + get assigned. The command "let" may be used to assign values + unambigiously and it should be used if the value starts with a + letter. + + Conditions are not yes implemented except for a simple evaluation + which yields false for an empty string or the string "0". The + result may be negated by prefixing with a '!'. + + The general syntax of a command is: + + [<name> =] <statement> [<args>] + + If NAME is not specifed but the statement returns a value it is + assigned to the name "?" so that it can be referenced using "$?". + The following commands are implemented: + + let <value> + Return VALUE. + + echo <value> + Print VALUE. + + openfile <filename> + Open file FILENAME for read access and retrun the file descriptor. + + createfile <filename> + Create file FILENAME, open for write access and retrun the file + descriptor. + + pipeserver <program> + Connect to the Assuan server PROGRAM. + + send <line> + Send LINE to the server. + + expect-ok + Expect an OK response from the server. Status and data out put + is ignored. + + expect-err + Expect an ERR response from the server. Status and data out put + is ignored. + + count-status <code> + Initialize the assigned variable to 0 and assign it as an counter for + status code CODE. This command must be called with an assignment. + + quit + Terminate the process. + + quit-if <condition> + Terminate the process if CONDITION evaluates to true. + + fail-if <condition> + Terminate the process with an exit code of 1 if CONDITION + evaluates to true. + + cmpfiles <first> <second> + Returns true when the content of the files FIRST and SECOND match. + + getenv <name> + Return the value of the environment variable NAME. + +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <stdarg.h> +#include <assert.h> +#include <unistd.h> +#include <fcntl.h> + +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) +# define ATTR_PRINTF(f,a) __attribute__ ((format (printf,f,a))) +#else +# define ATTR_PRINTF(f,a) +#endif + +#define spacep(p) (*(p) == ' ' || *(p) == '\t') + +#define MAX_LINELEN 2048 + +typedef enum { + LINE_OK = 0, + LINE_ERR, + LINE_STAT, + LINE_DATA, + LINE_END, +} LINETYPE; + +typedef enum { + VARTYPE_SIMPLE = 0, + VARTYPE_FD, + VARTYPE_COUNTER +} VARTYPE; + + +struct variable_s { + struct variable_s *next; + VARTYPE type; + unsigned int count; + char *value; + char name[1]; +}; +typedef struct variable_s *VARIABLE; + + +static void die (const char *format, ...) ATTR_PRINTF(1,2); + + +/* Name of this program to be printed in error messages. */ +static const char *invocation_name; + +/* Talk a bit about what is going on. */ +static int opt_verbose; + +/* Option to ignore the echo command. */ +static int opt_no_echo; + +/* File descriptors used to communicate with the current server. */ +static int server_send_fd = -1; +static int server_recv_fd = -1; + +/* The Assuan protocol limits the line length to 1024, so we can + safely use a (larger) buffer. The buffer is filled using the + read_assuan(). */ +static char recv_line[MAX_LINELEN]; +/* Tell the status of the current line. */ +static LINETYPE recv_type; + +/* This is our variable storage. */ +static VARIABLE variable_list; + + +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + fflush (stdout); + fprintf (stderr, "%s: ", invocation_name); + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + putc ('\n', stderr); + + exit (1); +} + +#define die(format, args...) (die) ("%s: " format, __FUNCTION__ , ##args) + +static void +err (const char *format, ...) +{ + va_list arg_ptr; + + fflush (stdout); + fprintf (stderr, "%s: ", invocation_name); + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + putc ('\n', stderr); +} + +static void * +xmalloc (size_t n) +{ + void *p = malloc (n); + if (!p) + die ("out of core"); + return p; +} + +static void * +xcalloc (size_t n, size_t m) +{ + void *p = calloc (n, m); + if (!p) + die ("out of core"); + return p; +} + +static char * +xstrdup (const char *s) +{ + char *p = xmalloc (strlen (s)+1); + strcpy (p, s); + return p; +} + + +/* Write LENGTH bytes from BUFFER to FD. */ +static int +writen (int fd, const char *buffer, size_t length) +{ + while (length) + { + int nwritten = write (fd, buffer, length); + + if (nwritten < 0) + { + if (errno == EINTR) + continue; + return -1; /* write error */ + } + length -= nwritten; + buffer += nwritten; + } + return 0; /* okay */ +} + + + + +/* Assuan specific stuff. */ + +/* Read a line from FD, store it in the global recv_line, analyze the + type and store that in recv_type. The function terminates on a + communication error. Returns a pointer into the inputline to the + first byte of the arguments. The parsing is very strict to match + excalty what we want to send. */ +static char * +read_assuan (int fd) +{ + static char pending[MAX_LINELEN]; + static size_t pending_len; + size_t nleft = sizeof recv_line; + char *buf = recv_line; + char *p; + + while (nleft > 0) + { + int n; + + if (pending_len) + { + if (pending_len >= nleft) + die ("received line too large"); + memcpy (buf, pending, pending_len); + n = pending_len; + pending_len = 0; + } + else + n = read (fd, buf, nleft); + + if (opt_verbose) + { + int i; + printf ("%s: read \"", __FUNCTION__); + for (i = 0; i < n; i ++) + putc (buf[i], stdout); + printf ("\"\n"); + } + + if (n < 0) + { + if (errno == EINTR) + continue; + die ("reading fd %d failed: %s", fd, strerror (errno)); + } + else if (!n) + die ("received incomplete line on fd %d", fd); + p = buf; + nleft -= n; + buf += n; + + for (; n && *p != '\n'; n--, p++) + ; + if (n) + { + if (n>1) + { + n--; + memcpy (pending, p + 1, n); + pending_len = n; + } + *p = '\0'; + break; + } + } + if (!nleft) + die ("received line too large"); + + p = recv_line; + if (p[0] == 'O' && p[1] == 'K' && (p[2] == ' ' || !p[2])) + { + recv_type = LINE_OK; + p += 3; + } + else if (p[0] == 'E' && p[1] == 'R' && p[2] == 'R' + && (p[3] == ' ' || !p[3])) + { + recv_type = LINE_ERR; + p += 4; + } + else if (p[0] == 'S' && (p[1] == ' ' || !p[1])) + { + recv_type = LINE_STAT; + p += 2; + } + else if (p[0] == 'D' && p[1] == ' ') + { + recv_type = LINE_DATA; + p += 2; + } + else if (p[0] == 'E' && p[1] == 'N' && p[2] == 'D' && !p[3]) + { + recv_type = LINE_END; + p += 3; + } + else + die ("invalid line type (%.5s)", p); + + return p; +} + +/* Write LINE to the server using FD. It is expected that the line + contains the terminating linefeed as last character. */ +static void +write_assuan (int fd, const char *line) +{ + char buffer[1026]; + size_t n = strlen (line); + + if (n > 1024) + die ("line too long for Assuan protocol"); + strcpy (buffer, line); + if (!n || buffer[n-1] != '\n') + buffer[n++] = '\n'; + + if (writen (fd, buffer, n)) + die ("sending line (\"%s\") to %d failed: %s", buffer, fd, + strerror (errno)); +} + + +/* Start the server with path PGMNAME and connect its stdout and + strerr to a newly created pipes; the file descriptors are then + store in the gloabl variables SERVER_SEND_FD and + SERVER_RECV_FD. The initial handcheck is performed.*/ +static void +start_server (const char *pgmname) +{ + int rp[2]; + int wp[2]; + pid_t pid; + + if (pipe (rp) < 0) + die ("pipe creation failed: %s", strerror (errno)); + if (pipe (wp) < 0) + die ("pipe creation failed: %s", strerror (errno)); + + fflush (stdout); + fflush (stderr); + pid = fork (); + if (pid < 0) + die ("fork failed"); + + if (!pid) + { + const char *arg0; + + arg0 = strrchr (pgmname, '/'); + if (arg0) + arg0++; + else + arg0 = pgmname; + + if (wp[0] != STDIN_FILENO) + { + if (dup2 (wp[0], STDIN_FILENO) == -1) + die ("dup2 failed in child: %s", strerror (errno)); + close (wp[0]); + } + if (rp[1] != STDOUT_FILENO) + { + if (dup2 (rp[1], STDOUT_FILENO) == -1) + die ("dup2 failed in child: %s", strerror (errno)); + close (rp[1]); + } + if (!opt_verbose) + { + int fd = open ("/dev/null", O_WRONLY); + if (fd == -1) + die ("can't open `/dev/null': %s", strerror (errno)); + if (dup2 (fd, STDERR_FILENO) == -1) + die ("dup2 failed in child: %s", strerror (errno)); + close (fd); + } + + close (wp[1]); + close (rp[0]); + execl (pgmname, arg0, "--server", NULL); + die ("exec failed for `%s': %s", pgmname, strerror (errno)); + } + close (wp[0]); + close (rp[1]); + server_send_fd = wp[1]; + server_recv_fd = rp[0]; + + read_assuan (server_recv_fd); + if (recv_type != LINE_OK) + die ("no greating message"); +} + + + + + +/* Script intepreter. */ + +static void +unset_var (const char *name) +{ + VARIABLE var; + + for (var=variable_list; var && strcmp (var->name, name); var = var->next) + ; + if (!var) + return; +/* fprintf (stderr, "unsetting `%s'\n", name); */ + + if (var->type == VARTYPE_FD && var->value) + { + int fd; + + fd = atoi (var->value); + if (fd != -1 && fd != 0 && fd != 1 && fd != 2) + close (fd); + } + + free (var->value); + var->value = NULL; + var->type = 0; + var->count = 0; +} + + +static void +set_type_var (const char *name, const char *value, VARTYPE type) +{ + VARIABLE var; + + if (!name) + name = "?"; + for (var=variable_list; var && strcmp (var->name, name); var = var->next) + ; + if (!var) + { + var = xcalloc (1, sizeof *var + strlen (name)); + strcpy (var->name, name); + var->next = variable_list; + variable_list = var; + } + else + free (var->value); + + if (var->type == VARTYPE_FD && var->value) + { + int fd; + + fd = atoi (var->value); + if (fd != -1 && fd != 0 && fd != 1 && fd != 2) + close (fd); + } + + var->type = type; + var->count = 0; + if (var->type == VARTYPE_COUNTER) + { + /* We need some extra sapce as scratch area for get_var. */ + var->value = xmalloc (strlen (value) + 1 + 20); + strcpy (var->value, value); + } + else + var->value = xstrdup (value); +} + +static void +set_var (const char *name, const char *value) +{ + set_type_var (name, value, 0); +} + + +static const char * +get_var (const char *name) +{ + VARIABLE var; + + for (var=variable_list; var && strcmp (var->name, name); var = var->next) + ; + if (!var) + return NULL; + if (var->type == VARTYPE_COUNTER && var->value) + { /* Use the scratch space allocated by set_var. */ + char *p = var->value + strlen(var->value)+1; + sprintf (p, "%u", var->count); + return p; + } + else + return var->value; +} + + +/* Incremente all counter type variables with NAME in their VALUE. */ +static void +inc_counter (const char *name) +{ + VARIABLE var; + + if (!*name) + return; + for (var=variable_list; var; var = var->next) + { + if (var->type == VARTYPE_COUNTER + && var->value && !strcmp (var->value, name)) + var->count++; + } +} + + +/* Expand variables in LINE and return a new allocated buffer if + required. The function might modify LINE if the expanded version + fits into it. */ +static char * +expand_line (char *buffer) +{ + char *line = buffer; + char *p, *pend; + const char *value; + size_t valuelen, n; + char *result = NULL; + + while (*line) + { + p = strchr (line, '$'); + if (!p) + return result; /* nothing more to expand */ + + if (p[1] == '$') /* quoted */ + { + memmove (p, p+1, strlen (p+1)+1); + line = p + 1; + continue; + } + for (pend=p+1; *pend && !spacep (pend) + && *pend != '$' && *pend != '/'; pend++) + ; + if (*pend) + { + int save = *pend; + *pend = 0; + value = get_var (p+1); + *pend = save; + } + else + value = get_var (p+1); + if (!value) + value = ""; + valuelen = strlen (value); + if (valuelen <= pend - p) + { + memcpy (p, value, valuelen); + p += valuelen; + n = pend - p; + if (n) + memmove (p, p+n, strlen (p+n)+1); + line = p; + } + else + { + char *src = result? result : buffer; + char *dst; + + dst = xmalloc (strlen (src) + valuelen + 1); + n = p - src; + memcpy (dst, src, n); + memcpy (dst + n, value, valuelen); + n += valuelen; + strcpy (dst + n, pend); + line = dst + n; + free (result); + result = dst; + } + } + return result; +} + + +/* Evaluate COND and return the result. */ +static int +eval_boolean (const char *cond) +{ + int true = 1; + + for ( ; *cond == '!'; cond++) + true = !true; + if (!*cond || (*cond == '0' && !cond[1])) + return !true; + return true; +} + + + + + +static void +cmd_let (const char *assign_to, char *arg) +{ + set_var (assign_to, arg); +} + + +static void +cmd_echo (const char *assign_to, char *arg) +{ + if (!opt_no_echo) + printf ("%s\n", arg); +} + +static void +cmd_send (const char *assign_to, char *arg) +{ + if (opt_verbose) + fprintf (stderr, "sending `%s'\n", arg); + write_assuan (server_send_fd, arg); +} + +static void +handle_status_line (char *arg) +{ + char *p; + + for (p=arg; *p && !spacep (p); p++) + ; + if (*p) + { + int save = *p; + *p = 0; + inc_counter (arg); + *p = save; + } + else + inc_counter (arg); +} + +static void +cmd_expect_ok (const char *assign_to, char *arg) +{ + if (opt_verbose) + fprintf (stderr, "expecting OK\n"); + do + { + char *p = read_assuan (server_recv_fd); + if (opt_verbose > 1) + fprintf (stderr, "got line `%s'\n", recv_line); + if (recv_type == LINE_STAT) + handle_status_line (p); + } + while (recv_type != LINE_OK && recv_type != LINE_ERR); + if (recv_type != LINE_OK) + die ("expected OK but got `%s'", recv_line); +} + +static void +cmd_expect_err (const char *assign_to, char *arg) +{ + if (opt_verbose) + fprintf (stderr, "expecting ERR\n"); + do + { + char *p = read_assuan (server_recv_fd); + if (opt_verbose > 1) + fprintf (stderr, "got line `%s'\n", recv_line); + if (recv_type == LINE_STAT) + handle_status_line (p); + } + while (recv_type != LINE_OK && recv_type != LINE_ERR); + if (recv_type != LINE_ERR) + die ("expected ERR but got `%s'", recv_line); +} + +static void +cmd_count_status (const char *assign_to, char *arg) +{ + char *p; + + if (!*assign_to || !*arg) + die ("syntax error: count-status requires an argument and a variable"); + + for (p=arg; *p && !spacep (p); p++) + ; + if (*p) + { + for (*p++ = 0; spacep (p); p++) + ; + if (*p) + die ("cmpfiles: syntax error"); + } + set_type_var (assign_to, arg, VARTYPE_COUNTER); +} + +static void +cmd_openfile (const char *assign_to, char *arg) +{ + int fd; + char numbuf[20]; + + do + fd = open (arg, O_RDONLY); + while (fd == -1 && errno == EINTR); + if (fd == -1) + die ("error opening `%s': %s", arg, strerror (errno)); + + sprintf (numbuf, "%d", fd); + set_type_var (assign_to, numbuf, VARTYPE_FD); +} + +static void +cmd_createfile (const char *assign_to, char *arg) +{ + int fd; + char numbuf[20]; + + do + fd = open (arg, O_WRONLY|O_CREAT|O_TRUNC, 0666); + while (fd == -1 && errno == EINTR); + if (fd == -1) + die ("error creating `%s': %s", arg, strerror (errno)); + + sprintf (numbuf, "%d", fd); + set_type_var (assign_to, numbuf, VARTYPE_FD); +} + + +static void +cmd_pipeserver (const char *assign_to, char *arg) +{ + if (!*arg) + die ("syntax error: servername missing"); + + start_server (arg); +} + + +static void +cmd_quit_if(const char *assign_to, char *arg) +{ + if (eval_boolean (arg)) + exit (0); +} + +static void +cmd_fail_if(const char *assign_to, char *arg) +{ + if (eval_boolean (arg)) + exit (1); +} + + +static void +cmd_cmpfiles (const char *assign_to, char *arg) +{ + char *p = arg; + char *second; + FILE *fp1, *fp2; + char buffer1[2048]; /* note: both must be of equal size. */ + char buffer2[2048]; + size_t nread1, nread2; + int rc = 0; + + set_var (assign_to, "0"); + for (p=arg; *p && !spacep (p); p++) + ; + if (!*p) + die ("cmpfiles: syntax error"); + for (*p++ = 0; spacep (p); p++) + ; + second = p; + for (; *p && !spacep (p); p++) + ; + if (*p) + { + for (*p++ = 0; spacep (p); p++) + ; + if (*p) + die ("cmpfiles: syntax error"); + } + + fp1 = fopen (arg, "rb"); + if (!fp1) + { + err ("can't open `%s': %s", arg, strerror (errno)); + return; + } + fp2 = fopen (second, "rb"); + if (!fp2) + { + err ("can't open `%s': %s", second, strerror (errno)); + fclose (fp1); + return; + } + while ( (nread1 = fread (buffer1, 1, sizeof buffer1, fp1))) + { + if (ferror (fp1)) + break; + nread2 = fread (buffer2, 1, sizeof buffer2, fp2); + if (ferror (fp2)) + break; + if (nread1 != nread2 || memcmp (buffer1, buffer2, nread1)) + { + rc = 1; + break; + } + } + if (feof (fp1) && feof (fp2) && !rc) + { + if (opt_verbose) + err ("files match"); + set_var (assign_to, "1"); + } + else if (!rc) + err ("cmpfiles: read error: %s", strerror (errno)); + else + err ("cmpfiles: mismatch"); + fclose (fp1); + fclose (fp2); +} + +static void +cmd_getenv (const char *assign_to, char *arg) +{ + const char *s; + s = *arg? getenv (arg):""; + set_var (assign_to, s? s:""); +} + + + + +/* Process the current script line LINE. */ +static int +interpreter (char *line) +{ + static struct { + const char *name; + void (*fnc)(const char*, char*); + } cmdtbl[] = { + { "let" , cmd_let }, + { "echo" , cmd_echo }, + { "send" , cmd_send }, + { "expect-ok" , cmd_expect_ok }, + { "expect-err", cmd_expect_err }, + { "count-status", cmd_count_status }, + { "openfile" , cmd_openfile }, + { "createfile", cmd_createfile }, + { "pipeserver", cmd_pipeserver }, + { "quit" , NULL }, + { "quit-if" , cmd_quit_if }, + { "fail-if" , cmd_fail_if }, + { "cmpfiles" , cmd_cmpfiles }, + { "getenv" , cmd_getenv }, + { NULL } + }; + char *p, *save_p; + int i, save_c; + char *stmt = NULL; + char *assign_to = NULL; + char *must_free = NULL; + + for ( ;spacep (line); line++) + ; + if (!*line || *line == '#') + return 0; /* empty or comment */ + p = expand_line (line); + if (p) + { + must_free = p; + line = p; + for ( ;spacep (line); line++) + ; + if (!*line || *line == '#') + { + free (must_free); + return 0; /* empty or comment */ + } + } + for (p=line; *p && !spacep (p) && *p != '='; p++) + ; + if (*p == '=') + { + *p = 0; + assign_to = line; + } + else if (*p) + { + for (*p++ = 0; spacep (p); p++) + ; + if (*p == '=') + assign_to = line; + } + if (!*line) + die ("syntax error"); + stmt = line; + save_c = 0; + save_p = NULL; + if (assign_to) + { /* this is an assignment */ + for (p++; spacep (p); p++) + ; + if (!*p) + { + unset_var (assign_to); + free (must_free); + return 0; + } + stmt = p; + for (; *p && !spacep (p); p++) + ; + if (*p) + { + save_p = p; + save_c = *p; + for (*p++ = 0; spacep (p); p++) + ; + } + } + for (i=0; cmdtbl[i].name && strcmp (stmt, cmdtbl[i].name); i++) + ; + if (!cmdtbl[i].name) + { + if (!assign_to) + die ("invalid statement `%s'\n", stmt); + if (save_p) + *save_p = save_c; + set_var (assign_to, stmt); + free (must_free); + return 0; + } + + if (cmdtbl[i].fnc) + cmdtbl[i].fnc (assign_to, p); + free (must_free); + return cmdtbl[i].fnc? 0:1; +} + + + +int +main (int argc, char **argv) +{ + char buffer[2048]; + char *p, *pend; + + if (!argc) + invocation_name = "asschk"; + else + { + invocation_name = *argv++; + argc--; + p = strrchr (invocation_name, '/'); + if (p) + invocation_name = p+1; + } + + + set_var ("?","1"); /* defaults to true */ + + for (; argc; argc--, argv++) + { + p = *argv; + if (*p != '-') + break; + if (!strcmp (p, "--verbose")) + opt_verbose++; + else if (!strcmp (p, "--no-echo")) + opt_no_echo++; + else if (*p == '-' && p[1] == 'D') + { + p += 2; + pend = strchr (p, '='); + if (pend) + { + int tmp = *pend; + *pend = 0; + set_var (p, pend+1); + *pend = tmp; + } + else + set_var (p, "1"); + } + else if (*p == '-' && p[1] == '-' && !p[2]) + { + argc--; argv++; + break; + } + else + break; + } + if (argc) + die ("usage: asschk [--verbose] {-D<name>[=<value>]}"); + + + while (fgets (buffer, sizeof buffer, stdin)) + { + p = strchr (buffer,'\n'); + if (!p) + die ("incomplete script line"); + *p = 0; + if (interpreter (buffer)) + break; + fflush (stdout); + } + return 0; +} + diff --git a/tests/inittests b/tests/inittests new file mode 100755 index 000000000..05a94eb68 --- /dev/null +++ b/tests/inittests @@ -0,0 +1,99 @@ +#!/bin/sh +# Copyright (C) 2002 Free Software Foundation, Inc. +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This file is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +set -e + +sample_certs=' +cert_g10code_test1.pem +cert_g10code_pete1.pem +cert_g10code_theo1.pem +' + +private_keys=' +32100C27173EF6E9C4E9A25D3D69F86D37A4F939 +' + +clean_files=' +gpgsm.conf gpg-agent.conf trustlist.txt pubring.kbx +msg msg.sig msg.unsig +' + + +[ -z "$srcdir" ] && srcdir=. +[ -z "$GPGSM" ] && GPGSM=../sm/gpgsm + +if [ -d $srcdir/samplekeys ] \ + && grep TESTS_ENVIRONMENT Makefile >/dev/null 2>&1; then + : +else + # During make distclean the Makefile has already been removed, + # so we need this extra test. + if ! grep gnupg-test-directory testdir.stamp >/dev/null 2>&1; then + echo "inittests: please cd to the tests directory first" >&2 + exit 1 + fi +fi + +if [ "$1" = "--clean" ]; then + if [ -d private-keys-v1.d ]; then + rm private-keys-v1.d/* 2>/dev/null || true + rmdir private-keys-v1.d + fi + rm ${clean_files} testdir.stamp 2>/dev/null || true + exit 0 +fi + +if [ "$GNUPGHOME" != "`pwd`" ]; then + echo "inittests: please set GNUPGHOME to the test directory" >&2 + exit 1 +fi + +if [ -n "$GPG_AGENT_INFO" ]; then + echo "inittests: please unset GPG_AGENT_INFO" >&2 + exit 1 +fi + +# A stamp file used with --clean +echo gnupg-test-directory > testdir.stamp + + +# Create the private key directy if it does not exists and copy +# the sample keys. +[ -d private-keys-v1.d ] || mkdir private-keys-v1.d +for i in ${private_keys}; do + cat ${srcdir}/samplekeys/$i.key >private-keys-v1.d/$i.key +done + +# Create the configuration scripts +# Note, die to an expired test certificate, we need to use +# the faked system time option. +cat > gpgsm.conf <<EOF +no-secmem-warning +disable-crl-checks +agent-program ../agent/gpg-agent +faked-system-time 1038835799 +EOF + +cat > gpg-agent.conf <<EOF +no-grab +pinentry-program /home/wk/work/pinentry/gtk/pinentry-gtk +EOF + +cat > trustlist.txt <<EOF +# CN=test cert 1,OU=Aegypten Project,O=g10 Code GmbH,L=Düsseldorf,C=DE +3CF405464F66ED4A7DF45BBDD1E4282E33BDB76E S +EOF + +# Make sure that the sample certs are available but ignore errors here +# because we are not a test script. +for i in ${sample_certs}; do + $GPGSM --import ${srcdir}/samplekeys/$i || true +done |