This commit was manufactured by cvs2svn to create tag 'V0-1-0'.

This commit is contained in:
Repo Admin 2000-11-20 20:17:36 +00:00
parent 354d2fca9e
commit 93e9f5ffe4
47 changed files with 5791 additions and 0 deletions

0
tags/V0-1-0/AUTHORS Normal file
View File

0
tags/V0-1-0/ChangeLog Normal file
View File

182
tags/V0-1-0/INSTALL Normal file
View File

@ -0,0 +1,182 @@
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another
architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields:
CPU-COMPANY-SYSTEM
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.

6
tags/V0-1-0/Makefile.am Normal file
View File

@ -0,0 +1,6 @@
EXTRA_DIST = README-alpha
SUBDIRS = gpgme tests

0
tags/V0-1-0/NEWS Normal file
View File

23
tags/V0-1-0/README Normal file
View File

@ -0,0 +1,23 @@
GPGME - GnuPG Made Easy
---------------------------
!!!! THIS IS WORK IN PROGRESS !!!
If you want to hack on it, start with one of the tests/t-foo programs.
You need the latest CVS version of GnuPG 1.0, see
http://www.gnupg.org/cvs-access.html . If you use passphrases for
your keys, you should get the gpg-agent which comes with the GnuPG
unstable version (either CVS HEAD or
ftp.gnupg.org/pub/gcrypt/alpha/gnupg/gnupg-1.1.2.tar.gz) and install
the agent from the agent subdirectory.
Please subscribe to the gnupg-devel@gnupg.org mailing list if you want
to do serious work.

1
tags/V0-1-0/README-alpha Normal file
View File

@ -0,0 +1 @@
THIS IS WORK IN PROGRESS !!!!

54
tags/V0-1-0/acconfig.h Normal file
View File

@ -0,0 +1,54 @@
/* acconfig.h - used by autoheader to make config.h.in
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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
*/
#ifndef GPGME_CONFIG_H
#define GPGME_CONFIG_H
/* need this, because some autoconf tests rely on this (e.g. stpcpy)
* and it should be used for new programs */
#define _GNU_SOURCE 1
/* To allow the use of gpgme in multithreaded programs we have to use
* special features from the library.
* IMPORTANT: gpgme is not yet fully reentrant and you should use it
* only from one thread. */
#define _REENTRANT 1
@TOP@
#undef HAVE_DRIVE_LETTERS
/* defined if we run on some of the PCDOS like systems (DOS, Windoze. OS/2)
* with special properties like no file modes */
#undef HAVE_DOSISH_SYSTEM
/* because the Unix gettext has to much overhead on MingW32 systems
* and these systems lack Posix functions, we use a simplified version
* of gettext */
#undef USE_SIMPLE_GETTEXT
/* Some systems have mkdir that takes a single argument. */
#undef MKDIR_TAKES_ONE_ARG
/* path to the gpg binary */
#undef GPG_PATH
@BOTTOM@
/* not yet needed #include "gpgme-defs.h"*/
#endif /*GPGME_CONFIG_H*/

23
tags/V0-1-0/acinclude.m4 Normal file
View File

@ -0,0 +1,23 @@
dnl Macros to configure gpgme
dnl GNUPG_FIX_HDR_VERSION(FILE, NAME)
dnl (wk 2000-11-17)
AC_DEFUN(GNUPG_FIX_HDR_VERSION,
[ sed "s/^#define $2 \".*/#define $2 \"$VERSION\"/" $srcdir/$1 > $srcdir/$1.tmp
if cmp -s $srcdir/$1 $srcdir/$1.tmp 2>/dev/null; then
rm -f $srcdir/$1.tmp
else
rm -f $srcdir/$1
if mv $srcdir/$1.tmp $srcdir/$1 ; then
:
else
AC_MSG_ERROR([[
*** Failed to fix the version string macro $2 in $1.
*** The old file has been saved as $1.tmp
]])
fi
AC_MSG_WARN([fixed the $2 macro in $1])
fi
])

110
tags/V0-1-0/configure.in Normal file
View File

@ -0,0 +1,110 @@
# configure.in for GPGME
#
dnl (Process this file with autoconf to produce a configure script.)
AC_REVISION($Revision$)dnl
AC_INIT(gpgme/gpgme.h)
AM_CONFIG_HEADER(config.h)
AM_MAINTAINER_MODE
#############################################
# Version numbers (Remember to change them just before a release)
# 1. No interfaces changed, only implementations (good): Increment REVISION.
# 2. Interfaces added, none removed (good): Increment CURRENT, increment
# AGE, set REVISION to 0.
# 3. Interfaces removed (BAD, breaks upward compatibility): Increment
# CURRENT, set AGE and REVISION to 0.
AM_INIT_AUTOMAKE(gpgme,0.1.0)
LIBGPGME_LT_CURRENT=0
LIBGPGME_LT_AGE=0
LIBGPGME_LT_REVISION=2
##############################################
AC_SUBST(LIBGPGME_LT_CURRENT)
AC_SUBST(LIBGPGME_LT_AGE)
AC_SUBST(LIBGPGME_LT_REVISION)
dnl
dnl Checks for programs
dnl
AC_ARG_PROGRAM
dnl Don't default to build static libs
AM_DISABLE_STATIC
AM_PROG_LIBTOOL
if test "$GCC" = yes; then
CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes"
fi
dnl
dnl Checks for libraries
dnl
dnl
dnl Checks for header files
dnl
dnl
dnl Checks for typedefs and structures
dnl
dnl
dnl Checks for compiler features
dnl
dnl
dnl Checks for library functions
dnl
dnl
dnl Checks for system services
dnl
AC_PATH_PROG(GPG, gpg)
if test -z "$GPG"; then
AC_MSG_ERROR([[
***
*** GnuPG not found. Please install GnuPG first.
*** See http://www.gnupg.org/download.html
***
]])
fi
AC_DEFINE_UNQUOTED(GPG_PATH, "$GPG")
dnl
dnl Create config files
dnl
dnl
dnl Make the version number in gpgme/gpgme.h the same as the one here.
dnl (this is easier than to have a *.in file just for one substitution)
GNUPG_FIX_HDR_VERSION(gpgme/gpgme.h, GPGME_VERSION)
dnl Substitution used for gpgme-config
GPGME_LIBS="-L${libdir} -lgpgme"
GPGME_CFLAGS=""
AC_SUBST(GPGME_LIBS)
AC_SUBST(GPGME_CFLAGS)
AC_OUTPUT_COMMANDS([
chmod +x gpgme/gpgme-config
])
AC_OUTPUT([
Makefile
gpgme/Makefile
gpgme/gpgme-config
tests/Makefile
])

View File

View File

@ -0,0 +1,38 @@
# Process this file with automake to produce Makefile.in
EXTRA_DIST = gpgme-config.in gpgme.m4 mkerrors mkstatus
BUILT_SOURCES = errors.c status-table.h
bin_SCRIPTS = gpgme-config
m4datadir = $(datadir)/aclocal
m4data_DATA = gpgme.m4
include_HEADERS = gpgme.h
lib_LTLIBRARIES = libgpgme.la
libgpgme_la_LDFLAGS = -version-info \
@LIBGPGME_LT_CURRENT@:@LIBGPGME_LT_REVISION@:@LIBGPGME_LT_AGE@
libgpgme_la_INCLUDES = -I$(top_srcdir)/lib
libgpgme_la_SOURCES = \
gpgme.h types.h util.h util.c \
context.h ops.h \
data.c recipient.c \
wait.c wait.h \
encrypt.c \
decrypt.c \
verify.c \
sign.c \
key.c key.h \
keylist.c \
rungpg.c rungpg.h status-table.h \
gpgme.c version.c errors.c
errors.c : gpgme.h
$(srcdir)/mkerrors < $(srcdir)/gpgme.h > errors.c
status-table.h : rungpg.h
$(srcdir)/mkstatus < $(srcdir)/rungpg.h > status-table.h

119
tags/V0-1-0/gpgme/context.h Normal file
View File

@ -0,0 +1,119 @@
/* context.h
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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
*/
#ifndef CONTEXT_H
#define CONTEXT_H
#include "gpgme.h"
#include "types.h"
#include "rungpg.h" /* for GpgObject */
typedef enum {
RESULT_TYPE_NONE = 0,
RESULT_TYPE_VERIFY,
RESULT_TYPE_DECRYPT,
RESULT_TYPE_SIGN,
} ResultType;
struct key_queue_item_s {
struct key_queue_item_s *next;
GpgmeKey key;
};
/* Currently we need it at several places, so we put the definition
* into this header file */
struct gpgme_context_s {
int initialized;
int pending; /* a gpg request is still pending */
/* at some points we need to allocate memory but we are not
* able to handle a malloc problem at that point, so we set this
* flag to indicate this condition */
int out_of_core;
GpgObject gpg; /* the running gpg process */
int verbosity; /* level of verbosity to use */
int use_armor;
int use_textmode;
/* GpgmePassphraseCb passphrase_cb;*/
/* void * passphrase_cb_value;*/
ResultType result_type;
union {
VerifyResult verify;
DecryptResult decrypt;
SignResult sign;
} result;
GpgmeData notation; /* last signature notation */
GpgmeKey tmp_key; /* used by keylist.c */
volatile int key_cond; /* something new is available */
struct key_queue_item_s *key_queue;
};
struct gpgme_data_s {
size_t len;
const char *data;
GpgmeDataType type;
GpgmeDataMode mode;
size_t readpos;
size_t writepos;
size_t private_len;
char *private_buffer;
};
struct user_id_s {
struct user_id_s *next;
int validity; /* 0 = undefined, 1 = not, 2 = marginal,
3 = full, 4 = ultimate */
char name[1];
};
struct gpgme_recipients_s {
struct user_id_s *list;
int checked; /* wether the recipients are all valid */
};
#define fail_on_pending_request(c) \
do { \
if (!(c)) return GPGME_Invalid_Value; \
if ((c)->pending) return GPGME_Busy; \
} while (0)
#define wait_on_request_or_fail(c) \
do { \
if (!(c)) return GPGME_Invalid_Value;\
if (!(c)->pending) return GPGME_No_Request; \
gpgme_wait ((c), 1); \
} while (0)
#endif /* CONTEXT_H */

488
tags/V0-1-0/gpgme/data.c Normal file
View File

@ -0,0 +1,488 @@
/* data.c
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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 <assert.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "util.h"
#include "context.h"
#include "ops.h"
#define ALLOC_CHUNK 1024
#define my_isdigit(a) ( (a) >='0' && (a) <= '9' )
#define my_isxdigit(a) ( my_isdigit((a)) \
|| ((a) >= 'A' && (a) <= 'F') \
|| ((a) >= 'f' && (a) <= 'f') )
GpgmeError
gpgme_data_new ( GpgmeData *r_dh )
{
GpgmeData dh;
if (!r_dh)
return mk_error (Invalid_Value);
*r_dh = NULL;
dh = xtrycalloc ( 1, sizeof *dh );
if (!dh)
return mk_error (Out_Of_Core);
dh->mode = GPGME_DATA_MODE_INOUT;
*r_dh = dh;
return 0;
}
/**
* gpgme_data_new_from_mem:
* @r_dh: Returns a new data object.
* @buffer: Initialize with this.
* @size: Size of the buffer
* @copy: Flag wether a copy of the buffer should be used.
*
* Create a new data object and initialize with data
* from the memory. A @copy with value %TRUE creates a copy of the
* memory, a value of %FALSE uses the original memory of @buffer and the
* caller has to make sure that this buffer is valid until gpgme_release_data()
* is called.
*
* Return value:
**/
GpgmeError
gpgme_data_new_from_mem ( GpgmeData *r_dh,
const char *buffer, size_t size, int copy )
{
GpgmeData dh;
GpgmeError err;
if (!r_dh || !buffer)
return mk_error (Invalid_Value);
*r_dh = NULL;
err = gpgme_data_new ( &dh );
if (err)
return err;
dh->len = size;
if (copy) {
dh->private_buffer = xtrymalloc ( size );
if ( !dh->private_buffer ) {
gpgme_data_release (dh);
return mk_error (Out_Of_Core);
}
dh->private_len = size;
memcpy (dh->private_buffer, buffer, size );
dh->data = dh->private_buffer;
dh->writepos = size;
}
else {
dh->data = buffer;
}
dh->type = GPGME_DATA_TYPE_MEM;
*r_dh = dh;
return 0;
}
GpgmeError
gpgme_data_new_from_file ( GpgmeData *r_dh, const char *fname, int copy )
{
GpgmeData dh;
GpgmeError err;
struct stat st;
FILE *fp;
if (!r_dh)
return mk_error (Invalid_Value);
*r_dh = NULL;
/* We only support copy for now - in future we might want to honor the
* copy flag and just store a file pointer */
if (!copy)
return mk_error (Not_Implemented);
if (!fname)
return mk_error (Invalid_Value);
err = gpgme_data_new ( &dh );
if (err)
return err;
fp = fopen (fname, "rb");
if (!fp) {
int save_errno = errno;
gpgme_data_release (dh);
errno = save_errno;
return mk_error (File_Error);
}
if( fstat(fileno(fp), &st) ) {
int save_errno = errno;
fclose (fp);
gpgme_data_release (dh);
errno = save_errno;
return mk_error (File_Error);
}
/* We should check the length of the file and don't allow for to
* large files */
dh->private_buffer = xtrymalloc ( st.st_size );
if ( !dh->private_buffer ) {
fclose (fp);
gpgme_data_release (dh);
return mk_error (Out_Of_Core);
}
dh->private_len = st.st_size;
if ( fread ( dh->private_buffer, dh->private_len, 1, fp ) != 1 ) {
int save_errno = errno;
fclose (fp);
gpgme_data_release (dh);
errno = save_errno;
return mk_error (File_Error);
}
fclose (fp);
dh->len = dh->private_len;
dh->data = dh->private_buffer;
dh->writepos = dh->len;
dh->type = GPGME_DATA_TYPE_MEM;
*r_dh = dh;
return 0;
}
/**
* gpgme_data_release:
* @dh: Data object
*
* Release the data object @dh. @dh may be NULL in which case nothing
* happens.
**/
void
gpgme_data_release ( GpgmeData dh )
{
if (dh) {
xfree (dh->private_buffer);
xfree (dh);
}
}
char *
_gpgme_data_release_and_return_string ( GpgmeData dh )
{
char *val = NULL;
if (dh) {
if ( _gpgme_data_append ( dh, "", 0 ) ) /* append EOS */
xfree (dh->private_buffer );
else {
val = dh->private_buffer;
if ( !val && dh->data ) {
val = xtrymalloc ( dh->len );
if ( val )
memcpy ( val, dh->data, dh->len );
}
}
xfree (dh);
}
return val;
}
char *
gpgme_data_release_and_get_mem ( GpgmeData dh, size_t *r_len )
{
char *val = NULL;
if (r_len)
*r_len = 0;
if (dh) {
size_t len = dh->len;
val = dh->private_buffer;
if ( !val && dh->data ) {
val = xtrymalloc ( len );
if ( val )
memcpy ( val, dh->data, len );
}
xfree (dh);
if (val && r_len )
*r_len = len;
}
return val;
}
GpgmeDataType
gpgme_data_get_type ( GpgmeData dh )
{
if ( !dh || !dh->data )
return GPGME_DATA_TYPE_NONE;
return dh->type;
}
void
_gpgme_data_set_mode ( GpgmeData dh, GpgmeDataMode mode )
{
assert (dh);
dh->mode = mode;
}
GpgmeDataMode
_gpgme_data_get_mode ( GpgmeData dh )
{
assert (dh);
return dh->mode;
}
GpgmeError
gpgme_data_rewind ( GpgmeData dh )
{
if ( !dh )
return mk_error (Invalid_Value);
/* Fixme: We should check whether rewinding does make sense for the
* data type */
dh->readpos = 0;
return 0;
}
GpgmeError
gpgme_data_read ( GpgmeData dh, char *buffer, size_t length, size_t *nread )
{
size_t nbytes;
if ( !dh )
return mk_error (Invalid_Value);
nbytes = dh->len - dh->readpos;
if ( !nbytes ) {
*nread = 0;
return mk_error(EOF);
}
if (nbytes > length)
nbytes = length;
memcpy ( buffer, dh->data + dh->readpos, nbytes );
*nread = nbytes;
dh->readpos += nbytes;
return 0;
}
/*
* This function does make sense when we know that it contains no nil chars.
*/
char *
_gpgme_data_get_as_string ( GpgmeData dh )
{
char *val = NULL;
if (dh) {
val = xtrymalloc ( dh->len+1 );
if ( val ) {
memcpy ( val, dh->data, dh->len );
val[dh->len] = 0;
}
}
return val;
}
GpgmeError
_gpgme_data_append ( GpgmeData dh, const char *buffer, size_t length )
{
assert (dh);
if ( dh->type == GPGME_DATA_TYPE_NONE ) {
/* convert it to a mem data type */
assert (!dh->private_buffer);
dh->type = GPGME_DATA_TYPE_MEM;
dh->private_len = length < ALLOC_CHUNK? ALLOC_CHUNK : length;
dh->private_buffer = xtrymalloc ( dh->private_len );
if (!dh->private_buffer) {
dh->private_len = 0;
return mk_error (Out_Of_Core);
}
dh->writepos = 0;
dh->data = dh->private_buffer;
}
else if ( dh->type != GPGME_DATA_TYPE_MEM )
return mk_error (Invalid_Type);
if ( dh->mode != GPGME_DATA_MODE_INOUT
&& dh->mode != GPGME_DATA_MODE_IN )
return mk_error (Invalid_Mode);
if ( !dh->private_buffer ) {
/* we have to copy it now */
assert (dh->data);
dh->private_len = dh->len+length;
if (dh->private_len < ALLOC_CHUNK)
dh->private_len = ALLOC_CHUNK;
dh->private_buffer = xtrymalloc ( dh->private_len );
if (!dh->private_buffer) {
dh->private_len = 0;
return mk_error (Out_Of_Core);
}
memcpy ( dh->private_buffer, dh->data, dh->len );
dh->writepos = dh->len;
dh->data = dh->private_buffer;
}
/* allocate more memory if needed */
if ( dh->writepos + length > dh->private_len ) {
char *p;
size_t newlen = dh->private_len
+ (dh->len < ALLOC_CHUNK? ALLOC_CHUNK : length);
p = xtryrealloc ( dh->private_buffer, newlen );
if ( !p )
return mk_error (Out_Of_Core);
dh->private_buffer = p;
dh->private_len = newlen;
dh->data = dh->private_buffer;
assert ( !(dh->writepos + length > dh->private_len) );
}
memcpy ( dh->private_buffer + dh->writepos, buffer, length );
dh->writepos += length;
dh->len += length;
return 0;
}
GpgmeError
_gpgme_data_append_string ( GpgmeData dh, const char *s )
{
return _gpgme_data_append ( dh, s, s? strlen(s):0 );
}
GpgmeError
_gpgme_data_append_for_xml ( GpgmeData dh,
const char *buffer, size_t len )
{
const char *text, *s;
size_t n;
int rc = 0;
if ( !dh || !buffer )
return mk_error (Invalid_Value);
do {
for (text=NULL, s=buffer, n=len; n && !text; s++, n-- ) {
if ( *s == '<' )
text = "&lt;";
else if ( *s == '>' )
text = "&gt;"; /* not sure whether this is really needed */
else if ( *s == '&' )
text = "&amp;";
else if ( !*s )
text = "&#00;";
}
if (text) {
s--; n++;
}
if (s != buffer)
rc = _gpgme_data_append ( dh, buffer, s-buffer );
if ( !rc && text) {
rc = _gpgme_data_append_string ( dh, text );
s++; n--;
}
buffer = s;
len = n;
} while ( !rc && len );
return rc;
}
/*
* Append a string to DATA and convert it so that the result will be
* valid XML.
*/
GpgmeError
_gpgme_data_append_string_for_xml ( GpgmeData dh, const char *string )
{
return _gpgme_data_append_for_xml ( dh, string, strlen (string) );
}
static int
hextobyte( const byte *s )
{
int c;
if( *s >= '0' && *s <= '9' )
c = 16 * (*s - '0');
else if( *s >= 'A' && *s <= 'F' )
c = 16 * (10 + *s - 'A');
else if( *s >= 'a' && *s <= 'f' )
c = 16 * (10 + *s - 'a');
else
return -1;
s++;
if( *s >= '0' && *s <= '9' )
c += *s - '0';
else if( *s >= 'A' && *s <= 'F' )
c += 10 + *s - 'A';
else if( *s >= 'a' && *s <= 'f' )
c += 10 + *s - 'a';
else
return -1;
return c;
}
/*
* Append a string with percent style (%XX) escape characters as XML
*/
GpgmeError
_gpgme_data_append_percentstring_for_xml ( GpgmeData dh, const char *string )
{
const byte *s;
byte *buf, *d;
int val;
GpgmeError err;
d = buf = xtrymalloc ( strlen (string) );
for (s=string; *s; s++ ) {
if ( *s == '%' && (val=hextobyte (s+1)) != -1 ) {
*d++ = val;
s += 2;
}
else
*d++ = *s;
}
err = _gpgme_data_append_for_xml ( dh, buf, d - buf );
xfree (buf);
return err;
}

196
tags/V0-1-0/gpgme/decrypt.c Normal file
View File

@ -0,0 +1,196 @@
/* decrypt.c - decrypt functions
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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 <assert.h>
#include "util.h"
#include "context.h"
#include "ops.h"
struct decrypt_result_s {
int no_passphrase;
int okay;
int failed;
};
void
_gpgme_release_decrypt_result ( DecryptResult res )
{
xfree (res);
}
static void
decrypt_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
{
if ( ctx->out_of_core )
return;
if ( ctx->result_type == RESULT_TYPE_NONE ) {
assert ( !ctx->result.decrypt );
ctx->result.decrypt = xtrycalloc ( 1, sizeof *ctx->result.decrypt );
if ( !ctx->result.decrypt ) {
ctx->out_of_core = 1;
return;
}
ctx->result_type = RESULT_TYPE_DECRYPT;
}
assert ( ctx->result_type == RESULT_TYPE_DECRYPT );
switch (code) {
case STATUS_EOF:
break;
case STATUS_NEED_PASSPHRASE:
case STATUS_NEED_PASSPHRASE_SYM:
fprintf (stderr, "Ooops: Need a passphrase - use the agent\n");
break;
case STATUS_MISSING_PASSPHRASE:
fprintf (stderr, "Missing passphrase - stop\n");;
ctx->result.decrypt->no_passphrase = 1;
break;
case STATUS_DECRYPTION_OKAY:
ctx->result.decrypt->okay = 1;
break;
case STATUS_DECRYPTION_FAILED:
ctx->result.decrypt->failed = 1;
break;
default:
/* ignore all other codes */
fprintf (stderr, "decrypt_status: code=%d not handled\n", code );
break;
}
}
GpgmeError
gpgme_op_decrypt_start ( GpgmeCtx c, GpgmeData ciph, GpgmeData plain )
{
int rc = 0;
int i;
fail_on_pending_request( c );
c->pending = 1;
_gpgme_release_result (c);
c->out_of_core = 0;
/* do some checks */
assert ( !c->gpg );
/* create a process object */
rc = _gpgme_gpg_new ( &c->gpg );
if (rc)
goto leave;
_gpgme_gpg_set_status_handler ( c->gpg, decrypt_status_handler, c );
/* build the commandline */
_gpgme_gpg_add_arg ( c->gpg, "--decrypt" );
for ( i=0; i < c->verbosity; i++ )
_gpgme_gpg_add_arg ( c->gpg, "--verbose" );
/* Check the supplied data */
if ( !ciph || gpgme_data_get_type (ciph) == GPGME_DATA_TYPE_NONE ) {
rc = mk_error (No_Data);
goto leave;
}
_gpgme_data_set_mode (ciph, GPGME_DATA_MODE_OUT );
if ( gpgme_data_get_type (plain) != GPGME_DATA_TYPE_NONE ) {
rc = mk_error (Invalid_Value);
goto leave;
}
_gpgme_data_set_mode (plain, GPGME_DATA_MODE_IN );
/* Tell the gpg object about the data */
_gpgme_gpg_add_arg ( c->gpg, "--output" );
_gpgme_gpg_add_arg ( c->gpg, "-" );
_gpgme_gpg_add_data ( c->gpg, plain, 1 );
_gpgme_gpg_add_data ( c->gpg, ciph, 0 );
/* and kick off the process */
rc = _gpgme_gpg_spawn ( c->gpg, c );
leave:
if (rc) {
c->pending = 0;
_gpgme_gpg_release ( c->gpg ); c->gpg = NULL;
}
return rc;
}
/**
* gpgme_op_decrypt:
* @c: The context
* @in: ciphertext input
* @out: plaintext output
*
* This function decrypts @in to @out.
* Other parameters are take from the context @c.
* The function does wait for the result.
*
* Return value: 0 on success or an errorcode.
**/
GpgmeError
gpgme_op_decrypt ( GpgmeCtx c, GpgmeData in, GpgmeData out )
{
GpgmeError err = gpgme_op_decrypt_start ( c, in, out );
if ( !err ) {
gpgme_wait (c, 1);
if ( c->result_type != RESULT_TYPE_DECRYPT )
err = mk_error (General_Error);
else if ( c->out_of_core )
err = mk_error (Out_Of_Core);
else {
assert ( c->result.decrypt );
if ( c->result.decrypt->no_passphrase )
err = mk_error (No_Passphrase);
else if ( c->result.decrypt->failed )
err = mk_error (Decryption_Failed);
else if (!c->result.decrypt->okay)
err = mk_error (No_Data);
}
c->pending = 0;
}
return err;
}

132
tags/V0-1-0/gpgme/encrypt.c Normal file
View File

@ -0,0 +1,132 @@
/* encrypt.c - encrypt functions
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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 <assert.h>
#include "util.h"
#include "context.h"
#include "ops.h"
static void
encrypt_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
{
fprintf (stderr, "encrypt_status: code=%d args=`%s'\n",
code, args );
}
GpgmeError
gpgme_op_encrypt_start ( GpgmeCtx c, GpgmeRecipients recp,
GpgmeData plain, GpgmeData ciph )
{
int rc = 0;
int i;
fail_on_pending_request( c );
c->pending = 1;
/* do some checks */
assert ( !c->gpg );
if ( !gpgme_recipients_count ( recp ) ) {
/* Fixme: In this case we should do symmentric encryption */
rc = mk_error (No_Recipients);
goto leave;
}
/* create a process object */
rc = _gpgme_gpg_new ( &c->gpg );
if (rc)
goto leave;
_gpgme_gpg_set_status_handler ( c->gpg, encrypt_status_handler, c );
/* build the commandline */
_gpgme_gpg_add_arg ( c->gpg, "--encrypt" );
if ( c->use_armor )
_gpgme_gpg_add_arg ( c->gpg, "--armor" );
for ( i=0; i < c->verbosity; i++ )
_gpgme_gpg_add_arg ( c->gpg, "--verbose" );
_gpgme_append_gpg_args_from_recipients ( recp, c->gpg );
/* Check the supplied data */
if ( gpgme_data_get_type (plain) == GPGME_DATA_TYPE_NONE ) {
rc = mk_error (No_Data);
goto leave;
}
_gpgme_data_set_mode (plain, GPGME_DATA_MODE_OUT );
if ( !ciph || gpgme_data_get_type (ciph) != GPGME_DATA_TYPE_NONE ) {
rc = mk_error (Invalid_Value);
goto leave;
}
_gpgme_data_set_mode (ciph, GPGME_DATA_MODE_IN );
/* Tell the gpg object about the data */
_gpgme_gpg_add_arg ( c->gpg, "--output" );
_gpgme_gpg_add_arg ( c->gpg, "-" );
_gpgme_gpg_add_data ( c->gpg, ciph, 1 );
_gpgme_gpg_add_arg ( c->gpg, "--" );
_gpgme_gpg_add_data ( c->gpg, plain, 0 );
/* and kick off the process */
rc = _gpgme_gpg_spawn ( c->gpg, c );
leave:
if (rc) {
c->pending = 0;
_gpgme_gpg_release ( c->gpg ); c->gpg = NULL;
}
return rc;
}
/**
* gpgme_op_encrypt:
* @c: The context
* @recp: A set of recipients
* @in: plaintext input
* @out: ciphertext output
*
* This function encrypts @in to @out for all recipients from
* @recp. Other parameters are take from the context @c.
* The function does wait for the result.
*
* Return value: 0 on success or an errorcode.
**/
GpgmeError
gpgme_op_encrypt ( GpgmeCtx c, GpgmeRecipients recp,
GpgmeData in, GpgmeData out )
{
int rc = gpgme_op_encrypt_start ( c, recp, in, out );
if ( !rc ) {
gpgme_wait (c, 1);
c->pending = 0;
}
return rc;
}

View File

@ -0,0 +1,93 @@
#!/bin/sh
prefix=@prefix@
exec_prefix=@exec_prefix@
exec_prefix_set=no
gpgme_libs="@GPGME_LIBS@"
gpgme_cflags="@GPGME_CFLAGS@"
usage()
{
cat <<EOF
Usage: gpgme-config [OPTIONS]
Options:
[--prefix[=DIR]]
[--exec-prefix[=DIR]]
[--version]
[--libs]
[--cflags]
EOF
exit $1
}
if test $# -eq 0; then
usage 1 1>&2
fi
while test $# -gt 0; do
case "$1" in
-*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
*) optarg= ;;
esac
case $1 in
--prefix=*)
prefix=$optarg
if test $exec_prefix_set = no ; then
exec_prefix=$optarg
fi
;;
--prefix)
echo_prefix=yes
;;
--exec-prefix=*)
exec_prefix=$optarg
exec_prefix_set=yes
;;
--exec-prefix)
echo_exec_prefix=yes
;;
--version)
echo "@VERSION@"
exit 0
;;
--cflags)
echo_cflags=yes
;;
--libs)
echo_libs=yes
;;
*)
usage 1 1>&2
;;
esac
shift
done
if test "$echo_prefix" = "yes"; then
echo $prefix
fi
if test "$echo_exec_prefix" = "yes"; then
echo $exec_prefix
fi
if test "$echo_cflags" = "yes"; then
if test "@includedir@" != "/usr/include" ; then
includes="-I@includedir@"
for i in $gpgme_cflags ; do
if test "$i" = "-I@includedir@" ; then
includes=""
fi
done
fi
echo $includes $gpgme_cflags
fi
if test "$echo_libs" = "yes"; then
echo ${gpgme_libs}
fi

View File

@ -0,0 +1,36 @@
/* gpgme-memory.h
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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
*/
#ifndef GPGME_MEMORY_H
#define GPGME_MEMORY_H
void *xmalloc ( size_t n );
void *xtrymalloc (size_t n );
void *xcalloc ( size_t n, size_t m );
void *xtrycalloc (size_t n, size_t m );
void *xrealloc (void *p, size_t n);
void *xtryrealloc (void *p, size_t n);
void xfree ( void *a );
#endif /* GPGME_MEMORY_H */

View File

@ -0,0 +1,38 @@
/* gpgme-types.h - GnuPG Made Easy
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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
*/
#ifndef GPGME_TYPES_H
#define GPGME_TYPES_H
#include "gpgme.h"
struct gpgme_context_s {
int initialized;
};
#endif /* GPGME_TYPES_H */

138
tags/V0-1-0/gpgme/gpgme.c Normal file
View File

@ -0,0 +1,138 @@
/* gpgme.c - GnuPG Made Easy
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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 "util.h"
#include "context.h"
#include "ops.h"
#define my_isdigit(a) ( (a) >='0' && (a) <= '9' )
#define my_isxdigit(a) ( my_isdigit((a)) \
|| ((a) >= 'A' && (a) <= 'F') \
|| ((a) >= 'f' && (a) <= 'f') )
/**
* gpgme_new:
* @r_ctx: Returns the new context
*
* Create a new context to be used with most of the other GPGME
* functions. Use gpgme_release_contect() to release all resources
*
* Return value: An error code
**/
GpgmeError
gpgme_new (GpgmeCtx *r_ctx)
{
GpgmeCtx c;
c = xtrycalloc ( 1, sizeof *c );
if (!c)
return mk_error (Out_Of_Core);
c->verbosity = 1;
c->use_armor = 1; /* fixme: reset this to 0 */
*r_ctx = c;
return 0;
}
/**
* gpgme_release:
* @c: Context to be released.
*
* Release all resources associated with the given context.
**/
void
gpgme_release ( GpgmeCtx c )
{
_gpgme_gpg_release ( c->gpg );
_gpgme_release_result ( c );
_gpgme_key_release ( c->tmp_key );
gpgme_data_release ( c->notation );
/* fixme: release the key_queue */
xfree ( c );
}
void
_gpgme_release_result ( GpgmeCtx c )
{
switch (c->result_type) {
case RESULT_TYPE_NONE:
break;
case RESULT_TYPE_VERIFY:
_gpgme_release_verify_result ( c->result.verify );
break;
case RESULT_TYPE_DECRYPT:
_gpgme_release_decrypt_result ( c->result.decrypt );
break;
case RESULT_TYPE_SIGN:
_gpgme_release_sign_result ( c->result.sign );
break;
}
c->result.verify = NULL;
c->result_type = RESULT_TYPE_NONE;
}
char *
gpgme_get_notation ( GpgmeCtx c )
{
if ( !c->notation )
return NULL;
return _gpgme_data_get_as_string ( c->notation );
}
void
gpgme_set_armor ( GpgmeCtx c, int yes )
{
if ( !c )
return; /* oops */
c->use_armor = yes;
}
void
gpgme_set_textmode ( GpgmeCtx c, int yes )
{
if ( !c )
return; /* oops */
c->use_textmode = yes;
}
#if 0
void
gpgme_set_passphrase_cb ( GpgmeCtx c, GpgmePassphraseCb fnc, void *fncval )
{
if ( c ) {
c->passphrase_cb = fnc;
c->passphrase_cb_value = fncval;
}
}
#endif

176
tags/V0-1-0/gpgme/gpgme.h Normal file
View File

@ -0,0 +1,176 @@
/* gpgme.h - GnuPG Made Easy
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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
*/
#ifndef GPGME_H
#define GPGME_H
#ifdef __cplusplus
extern "C" {
#if 0 /* just to make Emacs auto-indent happy */
}
#endif
#endif
/*
* The version of this header should match the one of the library
* It should not be used by a program because gpgme_check_version(NULL)
* does return the same version. The purpose of this macro is to
* let autoconf (using the AM_PATH_GPGME macro) check that this
* header matches the installed library.
* Warning: Do not edit the next line. configure will do that for you! */
#define GPGME_VERSION "0.1.0"
struct gpgme_context_s;
typedef struct gpgme_context_s *GpgmeCtx;
struct gpgme_data_s;
typedef struct gpgme_data_s *GpgmeData;
struct gpgme_recipients_s;
typedef struct gpgme_recipients_s *GpgmeRecipients;
struct gpgme_key_s;
typedef struct gpgme_key_s *GpgmeKey;
typedef enum {
GPGME_EOF = -1,
GPGME_No_Error = 0,
GPGME_General_Error = 1,
GPGME_Out_Of_Core = 2,
GPGME_Invalid_Value = 3,
GPGME_Busy = 4,
GPGME_No_Request = 5,
GPGME_Exec_Error = 6,
GPGME_Too_Many_Procs = 7,
GPGME_Pipe_Error = 8,
GPGME_No_Recipients = 9,
GPGME_No_Data = 10,
GPGME_Conflict = 11,
GPGME_Not_Implemented = 12,
GPGME_Read_Error = 13,
GPGME_Write_Error = 14,
GPGME_Invalid_Type = 15,
GPGME_Invalid_Mode = 16,
GPGME_File_Error = 17, /* errno is set in this case */
GPGME_Decryption_Failed = 18,
GPGME_No_Passphrase = 19,
} GpgmeError;
typedef enum {
GPGME_DATA_TYPE_NONE = 0,
GPGME_DATA_TYPE_MEM = 1,
GPGME_DATA_TYPE_FD = 2,
GPGME_DATA_TYPE_FILE = 3
} GpgmeDataType;
typedef enum {
GPGME_SIG_STAT_NONE = 0,
GPGME_SIG_STAT_GOOD = 1,
GPGME_SIG_STAT_BAD = 2,
GPGME_SIG_STAT_NOKEY = 3,
GPGME_SIG_STAT_NOSIG = 4,
GPGME_SIG_STAT_ERROR = 5
} GpgmeSigStat;
/*typedef GpgmeData (*GpgmePassphraseCb)( void *opaque, const char *desc );*/
/* Context management */
GpgmeError gpgme_new (GpgmeCtx *r_ctx);
void gpgme_release ( GpgmeCtx c );
GpgmeCtx gpgme_wait ( GpgmeCtx c, int hang );
char *gpgme_get_notation ( GpgmeCtx c );
void gpgme_set_armor ( GpgmeCtx c, int yes );
void gpgme_set_textmode ( GpgmeCtx c, int yes );
/*void gpgme_set_passphrase_cb ( GpgmeCtx c,
GpgmePassphraseCb fnc, void *fncval );*/
/* Functions to handle recipients */
GpgmeError gpgme_recipients_new (GpgmeRecipients *r_rset);
void gpgme_recipients_release ( GpgmeRecipients rset);
GpgmeError gpgme_recipients_add_name (GpgmeRecipients rset,
const char *name);
unsigned int gpgme_recipients_count ( const GpgmeRecipients rset );
/* Functions to handle data sources */
GpgmeError gpgme_data_new ( GpgmeData *r_dh );
GpgmeError gpgme_data_new_from_mem ( GpgmeData *r_dh,
const char *buffer, size_t size,
int copy );
GpgmeError gpgme_data_new_from_file ( GpgmeData *r_dh,
const char *fname,
int copy );
void gpgme_data_release ( GpgmeData dh );
char * gpgme_data_release_and_get_mem ( GpgmeData dh, size_t *r_len );
GpgmeDataType gpgme_data_get_type ( GpgmeData dh );
GpgmeError gpgme_data_rewind ( GpgmeData dh );
GpgmeError gpgme_data_read ( GpgmeData dh,
char *buffer, size_t length, size_t *nread );
/* Key functions */
char *gpgme_key_get_as_xml ( GpgmeKey key );
/* Basic GnuPG functions */
GpgmeError gpgme_op_encrypt_start ( GpgmeCtx c,
GpgmeRecipients recp,
GpgmeData in, GpgmeData out );
GpgmeError gpgme_op_decrypt_start ( GpgmeCtx c,
GpgmeData ciph, GpgmeData plain );
GpgmeError gpgme_op_sign_start ( GpgmeCtx c, GpgmeData in, GpgmeData out );
GpgmeError gpgme_op_verify_start ( GpgmeCtx c,
GpgmeData sig, GpgmeData text );
/* Key management functions */
GpgmeError gpgme_op_keylist_start ( GpgmeCtx c,
const char *pattern, int secret_only );
GpgmeError gpgme_op_keylist_next ( GpgmeCtx c, GpgmeKey *r_key );
/* Convenience functions for normal usage */
GpgmeError gpgme_op_encrypt ( GpgmeCtx c, GpgmeRecipients recp,
GpgmeData in, GpgmeData out );
GpgmeError gpgme_op_decrypt ( GpgmeCtx c, GpgmeData in, GpgmeData out );
GpgmeError gpgme_op_sign ( GpgmeCtx c, GpgmeData in, GpgmeData out );
GpgmeError gpgme_op_verify ( GpgmeCtx c, GpgmeData sig, GpgmeData text,
GpgmeSigStat *r_status );
/* miscellaneous functions */
const char *gpgme_check_version ( const char *req_version );
const char *gpgme_strerror (GpgmeError err);
#ifdef __cplusplus
}
#endif
#endif /* GPGME_H */

170
tags/V0-1-0/gpgme/gpgme.m4 Normal file
View File

@ -0,0 +1,170 @@
dnl Autoconf macros for libgpgme
dnl $Id$
# Configure paths for GPGME
# Shamelessly stolen from the one of XDELTA by Owen Taylor
# Werner Koch 2000-11-17
dnl AM_PATH_GPGME([MINIMUM-VERSION,
dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
dnl Test for gpgme, and define GPGME_CFLAGS and GPGME_LIBS
dnl
AC_DEFUN(AM_PATH_GPGME,
[dnl
dnl Get the cflags and libraries from the gpgme-config script
dnl
AC_ARG_WITH(gpgme-prefix,
[ --with-gpgme-prefix=PFX Prefix where gpgme is installed (optional)],
gpgme_config_prefix="$withval", gpgme_config_prefix="")
AC_ARG_ENABLE(gpgmetest,
[ --disable-gpgmetest Do not try to compile and run a test gpgme program],
, enable_gpgmetest=yes)
if test x$gpgme_config_prefix != x ; then
gpgme_config_args="$gpgme_config_args --prefix=$gpgme_config_prefix"
if test x${GPGME_CONFIG+set} != xset ; then
GPGME_CONFIG=$gpgme_config_prefix/bin/gpgme-config
fi
fi
AC_PATH_PROG(GPGME_CONFIG, gpgme-config, no)
min_gpgme_version=ifelse([$1], ,1.0.0,$1)
AC_MSG_CHECKING(for gpgme - version >= $min_gpgme_version)
no_gpgme=""
if test "$GPGME_CONFIG" = "no" ; then
no_gpgme=yes
else
GPGME_CFLAGS=`$GPGME_CONFIG $gpgme_config_args --cflags`
GPGME_LIBS=`$GPGME_CONFIG $gpgme_config_args --libs`
gpgme_config_version=`$GPGME_CONFIG $gpgme_config_args --version`
if test "x$enable_gpgmetest" = "xyes" ; then
ac_save_CFLAGS="$CFLAGS"
ac_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $GPGME_CFLAGS"
LIBS="$LIBS $GPGME_LIBS"
dnl
dnl Now check if the installed gpgme is sufficiently new. Also sanity
dnl checks the results of gpgme-config to some extent
dnl
rm -f conf.gpgmetest
AC_TRY_RUN([
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gpgme.h>
int
main ()
{
system ("touch conf.gpgmetest");
if( strcmp( gpgme_check_version(NULL), "$gpgme_config_version" ) )
{
printf("\n"
"*** 'gpgme-config --version' returned %s, but GPGME (%s) was found!\n",
"$gpgme_config_version", gpgme_check_version(NULL) );
printf(
"*** If gpgme-config was correct, then it is best to remove the old\n"
"*** version of GPGME. You may also be able to fix the error\n"
"*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n"
"*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n"
"*** required on your system.\n"
"*** If gpgme-config was wrong, set the environment variable GPGME_CONFIG\n"
"*** to point to the correct copy of gpgme-config, \n"
"*** and remove the file config.cache before re-running configure\n"
);
}
else if ( strcmp(gpgme_check_version(NULL), GPGME_VERSION ) )
{
printf("\n*** GPGME header file (version %s) does not match\n",
GPGME_VERSION);
printf("*** library (version %s)\n", gpgme_check_version(NULL) );
}
else
{
if ( gpgme_check_version( "$min_gpgme_version" ) )
return 0;
printf("no\n"
"*** An old version of GPGME (%s) was found.\n", gpgme_check_version(NULL) );
printf(
"*** You need a version of GPGME newer than %s.\n", "$min_gpgme_version" );
printf(
"*** The latest version of GPGME is always available at\n"
"*** ftp://ftp.gnupg.org/pub/gcrypt/alpha/gpgme/\n"
"*** \n"
"*** If you have already installed a sufficiently new version, this error\n"
"*** probably means that the wrong copy of the gpgme-config shell script is\n"
"*** being found. The easiest way to fix this is to remove the old version\n"
"*** of GPGME, but you can also set the GPGME_CONFIG environment to point to\n"
"*** the correct copy of gpgme-config. (In this case, you will have to\n"
"*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n"
"*** so that the correct libraries are found at run-time).\n"
);
}
return 1;
}
],, no_gpgme=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
if test "x$no_gpgme" = x ; then
AC_MSG_RESULT(yes)
ifelse([$2], , :, [$2])
else
if test -f conf.gpgmetest ; then
:
else
AC_MSG_RESULT(no)
fi
if test "$GPGME_CONFIG" = "no" ; then
echo "*** The gpgme-config script installed by GPGME could not be found"
echo "*** If GPGME was installed in PREFIX, make sure PREFIX/bin is in"
echo "*** your path, or set the GPGME_CONFIG environment variable to the"
echo "*** full path to gpgme-config."
else
if test -f conf.gpgmetest ; then
:
else
echo "*** Could not run gpgme test program, checking why..."
CFLAGS="$CFLAGS $GPGME_CFLAGS"
LIBS="$LIBS $GPGME_LIBS"
AC_TRY_LINK([
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gpgme.h>
], [ gpgme_check_version(NULL); return 0 ],
[
echo "*** The test program compiled, but did not run. This usually means"
echo "*** that the run-time linker is not finding GPGME or finding the wrong"
echo "*** version of GPGME. If it is not finding GPGME, you'll need to set your"
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
echo "*** to the installed location Also, make sure you have run ldconfig if"
echo "*** that is required on your system"
echo "***"
echo "*** If you have an old version installed, it is best to remove it,"
echo "*** although you may also be able to get things to work by"
echo "*** modifying LD_LIBRARY_PATH"
echo "***"
],
[
echo "*** The test program failed to compile or link. See the file config.log"
echo "*** for the exact error that occured. This usually means GPGME was"
echo "*** incorrectly installed or that you have moved GPGME since it was"
echo "*** installed. In the latter case, you may want to edit the"
echo "*** gpgme-config script: $GPGME_CONFIG"
])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
fi
fi
GPGME_CFLAGS=""
GPGME_LIBS=""
ifelse([$3], , :, [$3])
fi
AC_SUBST(GPGME_CFLAGS)
AC_SUBST(GPGME_LIBS)
rm -f conf.gpgmetest
])

287
tags/V0-1-0/gpgme/key.c Normal file
View File

@ -0,0 +1,287 @@
/* key.c - Key and keyList objects
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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 <assert.h>
#include "util.h"
#include "ops.h"
#include "key.h"
#define ALLOC_CHUNK 1024
#define my_isdigit(a) ( (a) >='0' && (a) <= '9' )
GpgmeError
_gpgme_key_new( GpgmeKey *r_key )
{
GpgmeKey key;
*r_key = NULL;
key = xtrycalloc ( 1, sizeof *key );
if (!key)
return mk_error (Out_Of_Core);
*r_key = key;
return 0;
}
void
_gpgme_key_release ( GpgmeKey key )
{
struct user_id_s *u, *u2;
if (!key)
return;
xfree (key->fingerprint);
for ( u = key->uids; u; u = u2 ) {
u2 = u->next;
xfree (u);
}
xfree (key);
}
/*
* Take a name from the --with-colon listing, remove certain escape sequences
* sequences and put it into the list of UIDs
*/
GpgmeError
_gpgme_key_append_name ( GpgmeKey key, const char *s )
{
struct user_id_s *uid;
char *d;
assert (key);
/* we can malloc a buffer of the same length, because the converted
* string will never be larger */
uid = xtrymalloc ( sizeof *uid + strlen (s) );
if ( !uid )
return mk_error (Out_Of_Core);
uid->validity = 0;
d = uid->name;
while ( *s ) {
if ( *s != '\\' )
*d++ = *s++;
else if ( s[1] == '\\' ) {
s++;
*d++ = *s++;
}
else if ( s[1] == 'n' ) {
s += 2;
*d++ = '\n';
}
else if ( s[1] == 'r' ) {
s += 2;
*d++ = '\r';
}
else if ( s[1] == 'v' ) {
s += 2;
*d++ = '\v';
}
else if ( s[1] == 'b' ) {
s += 2;
*d++ = '\b';
}
else if ( s[1] == '0' ) {
/* Hmmm: no way to express this */
s += 2;
*d++ = '\\';
*d++ = '\0';
}
else if ( s[1] == 'x' && my_isdigit (s[2]) && my_isdigit (s[3]) ) {
unsigned int val = (s[2]-'0')*16 + (s[3]-'0');
if ( !val ) {
*d++ = '\\';
*d++ = '\0';
}
else
*(byte*)d++ = val;
s += 3;
}
else { /* should not happen */
s++;
*d++ = '\\';
*d++ = *s++;
}
}
uid->next = key->uids;
key->uids = uid;
return 0;
}
static void
add_otag ( GpgmeData d, const char *tag )
{
_gpgme_data_append_string ( d, " <" );
_gpgme_data_append_string ( d, tag );
_gpgme_data_append_string ( d, ">" );
}
static void
add_ctag ( GpgmeData d, const char *tag )
{
_gpgme_data_append_string ( d, "</" );
_gpgme_data_append_string ( d, tag );
_gpgme_data_append_string ( d, ">\n" );
}
static void
add_tag_and_string ( GpgmeData d, const char *tag, const char *string )
{
add_otag (d, tag);
_gpgme_data_append_string_for_xml ( d, string );
add_ctag (d, tag);
}
static void
add_user_id_name ( GpgmeData d, const char *buf, size_t len )
{
while ( len && (buf[len-1] == ' ' || buf[len-1] == '\t') )
len--;
if (len) {
add_otag (d, "name" );
_gpgme_data_append_for_xml ( d, buf, len );
add_ctag (d, "name");
}
}
static void
add_user_id ( GpgmeData d, const char *string )
{
const char *s, *start=NULL;
int in_name = 0;
int in_email = 0;
int in_comment = 0;
for (s=string; *s; s++ ) {
if ( in_email ) {
if ( *s == '<' )
in_email++; /* not legal but anyway */
else if (*s== '>') {
if ( !--in_email ) {
_gpgme_data_append_for_xml ( d, start, s-start );
add_ctag (d, "email");
}
}
}
else if ( in_comment ) {
if ( *s == '(' )
in_comment++;
else if (*s== ')') {
if ( !--in_comment ) {
_gpgme_data_append_for_xml ( d, start, s-start );
add_ctag (d, "comment");
}
}
}
else if ( *s == '<' ) {
if ( in_name ) {
add_user_id_name (d, start, s-start );
in_name = 0;
}
in_email = 1;
add_otag ( d, "email" );
start = s+1;
}
else if ( *s == '(' ) {
if ( in_name ) {
add_user_id_name (d, start, s-start );
in_name = 0;
}
in_comment = 1;
add_otag ( d, "comment" );
start = s+1;
}
else if ( !in_name && *s != ' ' && *s != '\t' ) {
in_name = 1;
start = s;
}
}
if ( in_name )
add_user_id_name (d, start, s-start );
}
static void
add_tag_and_uint ( GpgmeData d, const char *tag, unsigned int val )
{
char buf[30];
sprintf (buf, "%u", val );
add_tag_and_string ( d, tag, buf );
}
static void
add_tag_and_time ( GpgmeData d, const char *tag, time_t val )
{
char buf[30];
if (!val || val == (time_t)-1 )
return;
sprintf (buf, "%lu", (unsigned long)val );
add_tag_and_string ( d, tag, buf );
}
char *
gpgme_key_get_as_xml ( GpgmeKey key )
{
GpgmeData d;
struct user_id_s *u;
if ( !key )
return NULL;
if ( gpgme_data_new ( &d ) )
return NULL;
_gpgme_data_append_string ( d, "<GnupgKeyblock>\n"
" <mainkey>\n" );
add_tag_and_string (d, "keyid", key->keyid );
if (key)
add_tag_and_string (d, "fpr", key->fingerprint );
add_tag_and_uint (d, "algo", key->key_algo );
add_tag_and_uint (d, "len", key->key_len );
add_tag_and_time (d, "created", key->timestamp );
/*add_tag_and_time (d, "expires", key->expires );*/
_gpgme_data_append_string (d, " </mainkey>\n");
/* No the user IDs */
for ( u = key->uids; u; u = u->next ) {
_gpgme_data_append_string (d, " <userid>\n");
add_tag_and_string ( d, "raw", u->name );
add_user_id ( d, u->name );
_gpgme_data_append_string (d, " </userid>\n");
}
_gpgme_data_append_string (d, " <subkey>\n");
_gpgme_data_append_string (d, " </subkey>\n");
_gpgme_data_append_string ( d, "</GnupgKeyblock>\n" );
return _gpgme_data_release_and_return_string (d);
}

54
tags/V0-1-0/gpgme/key.h Normal file
View File

@ -0,0 +1,54 @@
/* key.h
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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
*/
#ifndef KEY_H
#define KEY_H
#include <time.h>
#include "types.h"
#include "context.h"
struct gpgme_key_s {
struct {
unsigned int revoked:1 ;
unsigned int expired:1 ;
unsigned int disabled:1 ;
} flags;
unsigned int key_algo;
unsigned int key_len;
char keyid[16+1];
char *fingerprint; /* malloced hex digits */
time_t timestamp; /* -1 for invalid, 0 for not available */
struct user_id_s *uids;
};
GpgmeError _gpgme_key_append_name ( GpgmeKey key, const char *s );
#endif /* KEY_H */

384
tags/V0-1-0/gpgme/keylist.c Normal file
View File

@ -0,0 +1,384 @@
/* keylist.c - key listing
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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 <time.h>
#include <assert.h>
#include "util.h"
#include "context.h"
#include "ops.h"
#include "key.h"
#define my_isdigit(a) ( (a) >='0' && (a) <= '9' )
static void finish_key ( GpgmeCtx ctx );
static void
keylist_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
{
if ( ctx->out_of_core )
return;
switch (code) {
case STATUS_EOF:
if (ctx->tmp_key)
finish_key (ctx);
break;
default:
/* ignore all other codes */
fprintf (stderr, "keylist_status: code=%d not handled\n", code );
break;
}
}
static time_t
parse_timestamp ( char *p )
{
struct tm tm;
int i;
if (!*p )
return 0;
if (strlen(p) < 10 || p[4] != '-' || p[7] != '-' )
return (time_t)-1;
p[4] = 0;
p[7] = 0;
p[10] = 0; /* just in case the time part follows */
memset (&tm, 0, sizeof tm);
i = atoi (p);
if ( i < 1900 )
return (time_t)-1;
tm.tm_year = i - 1900;
i = atoi (p+5);
if ( i < 1 || i > 12 )
return (time_t)-1;
tm.tm_mon = i-1;
i = atoi (p+8);
if ( i < 1 || i > 31 )
return (time_t)-1;
tm.tm_mday = i;
return mktime (&tm);
}
static void
set_trust_info ( GpgmeKey key, const char *s )
{
/* look at letters and stop at the first digit */
for (; *s && !my_isdigit (*s); s++ ) {
switch (*s) {
case 'e': key->flags.expired = 1; break;
case 'r': key->flags.revoked = 1; break;
case 'd': key->flags.disabled = 1; break;
case 'n': key->uids->validity = 1; break;
case 'm': key->uids->validity = 2; break;
case 'f': key->uids->validity = 3; break;
case 'u': key->uids->validity = 4; break;
}
}
}
/* Note: we are allowed to modify line */
static void
keylist_colon_handler ( GpgmeCtx ctx, char *line )
{
char *p, *pend;
int field = 0;
enum {
RT_NONE, RT_SIG, RT_UID, RT_SUB, RT_PUB, RT_FPR, RT_SSB, RT_SEC
} rectype = RT_NONE;
GpgmeKey key = ctx->tmp_key;
int i;
const char *trust_info = NULL;
if ( ctx->out_of_core )
return;
if (!line)
return; /* EOF */
/*fprintf (stderr, "line=`%s'\n", line );*/
for (p = line; p; p = pend) {
field++;
pend = strchr (p, ':');
if (pend)
*pend++ = 0;
if ( field == 1 ) {
if ( !strcmp ( p, "sig" ) )
rectype = RT_SIG;
else if ( !strcmp ( p, "uid" ) && key ) {
rectype = RT_UID;
key = ctx->tmp_key;
}
else if ( !strcmp ( p, "sub" ) )
rectype = RT_SUB;
else if ( !strcmp ( p, "pub" ) ) {
/* start a new keyblock */
if ( _gpgme_key_new ( &key ) ) {
ctx->out_of_core=1; /* the only kind of error we can get */
return;
}
rectype = RT_PUB;
if ( ctx->tmp_key )
finish_key ( ctx );
assert ( !ctx->tmp_key );
ctx->tmp_key = key;
}
else if ( !strcmp ( p, "fpr" ) && key )
rectype = RT_FPR;
else if ( !strcmp ( p, "ssb" ) )
rectype = RT_SSB;
else if ( !strcmp ( p, "sec" ) )
rectype = RT_SEC;
else
rectype = RT_NONE;
}
else if ( rectype == RT_PUB /*|| rectype == RT_SUB*/ ) {
switch (field) {
case 2: /* trust info */
if ( rectype == RT_PUB )
trust_info = p; /*save for later */
break;
case 3: /* key length */
i = atoi (p);
if ( i > 1 ) /* ignore invalid values */
key->key_len = i;
break;
case 4: /* pubkey algo */
i = atoi (p);
if ( i > 1 && i < 128 )
key->key_algo = i;
break;
case 5: /* long keyid */
if ( strlen (p) == DIM(key->keyid)-1 )
strcpy (key->keyid, p);
break;
case 6: /* timestamp (1998-02-28) */
key->timestamp = parse_timestamp (p);
break;
case 7: /* valid for n days */
break;
case 8: /* reserved (LID) */
break;
case 9: /* ownertrust */
break;
case 10: /* This is the first name listed */
if ( rectype == RT_PUB ) {
if ( _gpgme_key_append_name ( key, p) )
ctx->out_of_core = 1;
else {
if (trust_info)
set_trust_info (key, trust_info);
}
}
break;
case 11: /* signature class */
break;
case 12:
pend = NULL; /* we can stop here */
break;
}
}
else if ( rectype == RT_UID ) {
switch (field) {
case 2: /* trust info */
trust_info = p; /*save for later */
break;
case 10: /* the 2nd, 3rd,... user ID */
if ( _gpgme_key_append_name ( key, p) )
ctx->out_of_core = 1;
else {
if (trust_info)
set_trust_info (key, trust_info);
}
pend = NULL; /* we can stop here */
break;
}
}
else if ( rectype == RT_FPR ) {
switch (field) {
case 10: /* fingerprint (take only the first one)*/
if ( !key->fingerprint && *p ) {
key->fingerprint = xtrystrdup (p);
if ( !key->fingerprint )
ctx->out_of_core = 1;
}
pend = NULL; /* that is all we want */
break;
}
}
}
}
/*
* We have read an entire key into ctx->tmp_key and should now finish
* it. It is assumed that this releases ctx->tmp_key.
*/
static void
finish_key ( GpgmeCtx ctx )
{
GpgmeKey key = ctx->tmp_key;
struct key_queue_item_s *q, *q2;
assert (key);
ctx->tmp_key = NULL;
q = xtrymalloc ( sizeof *q );
if ( !q ) {
_gpgme_key_release (key);
ctx->out_of_core = 1;
return;
}
q->key = key;
q->next = NULL;
/* fixme: lock queue */
if ( !(q2 = ctx->key_queue) )
ctx->key_queue = q;
else {
for ( ; q2->next; q2 = q2->next )
;
q2->next = q;
}
ctx->key_cond = 1;
/* fixme: unlock queue */
}
GpgmeError
gpgme_op_keylist_start ( GpgmeCtx c, const char *pattern, int secret_only )
{
GpgmeError rc = 0;
int i;
fail_on_pending_request( c );
c->pending = 1;
_gpgme_release_result (c);
c->out_of_core = 0;
if ( c->gpg ) {
_gpgme_gpg_release ( c->gpg );
c->gpg = NULL;
}
_gpgme_key_release (c->tmp_key);
c->tmp_key = NULL;
/* Fixme: release key_queue */
rc = _gpgme_gpg_new ( &c->gpg );
if (rc)
goto leave;
_gpgme_gpg_set_status_handler ( c->gpg, keylist_status_handler, c );
rc = _gpgme_gpg_set_colon_line_handler ( c->gpg,
keylist_colon_handler, c );
if (rc)
goto leave;
/* build the commandline */
for ( i=0; i < c->verbosity; i++ )
_gpgme_gpg_add_arg ( c->gpg, "--verbose" );
_gpgme_gpg_add_arg ( c->gpg, "--with-colons" );
_gpgme_gpg_add_arg ( c->gpg, "--with-fingerprint" );
/*_gpgme_gpg_add_arg ( c->gpg, "--fast-list-mode" );*/
_gpgme_gpg_add_arg ( c->gpg, secret_only?
"--list-secret-keys":"--list-keys" );
/* Tell the gpg object about the data */
_gpgme_gpg_add_arg ( c->gpg, "--" );
if (pattern && *pattern)
_gpgme_gpg_add_arg ( c->gpg, pattern );
/* and kick off the process */
rc = _gpgme_gpg_spawn ( c->gpg, c );
leave:
if (rc) {
c->pending = 0;
_gpgme_gpg_release ( c->gpg ); c->gpg = NULL;
}
return rc;
}
GpgmeError
gpgme_op_keylist_next ( GpgmeCtx c, GpgmeKey *r_key )
{
struct key_queue_item_s *q;
if (!r_key)
return mk_error (Invalid_Value);
*r_key = NULL;
if (!c)
return mk_error (Invalid_Value);
if ( !c->pending )
return mk_error (No_Request);
if ( c->out_of_core )
return mk_error (Out_Of_Core);
if ( !c->key_queue ) {
_gpgme_wait_on_condition (c, 1, &c->key_cond );
if ( c->out_of_core )
return mk_error (Out_Of_Core);
if ( !c->key_cond )
return mk_error (EOF);
c->key_cond = 0;
assert ( c->key_queue );
}
q = c->key_queue;
c->key_queue = q->next;
*r_key = q->key;
xfree (q);
return 0;
}

83
tags/V0-1-0/gpgme/mkerrors Executable file
View File

@ -0,0 +1,83 @@
#!/bin/sh
# mkerrors - Extract error strings from gpgme.h
# and create C source for gpgme_strerror
# Copyright (C) 2000 Werner Koch (dd9jn)
#
# This file is part of GPGME.
#
# GPGME 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.
#
# GPGME 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 <stdio.h>
#include "gpgme.h"
/**
* gpgme_strerror:
* @err: Error code
*
* This function returns a textual representaion of the given
* errocode. If this is an unknown value, a string with the value
* is returned (which is hold in a static buffer).
*
* Return value: String with the error description.
**/
const char *
gpgme_strerror (GpgmeError err)
{
const char *s;
static char buf[25];
switch (err) {
EOF
awk '
/GPGME_No_Error/ { okay=1 }
!okay {next}
/}/ { exit 0 }
/GPGME_[A-Za-z_]*/ { print_code($1) }
function print_code( s )
{
printf " case %s: s=\"", s ;
gsub(/_/, " ", s );
printf "%s\"; break;\n", substr(s,7);
}
'
cat <<EOF
default: sprintf (buf, "ec=%d", err ); s=buf; break;
}
return s;
}
EOF

55
tags/V0-1-0/gpgme/mkstatus Executable file
View File

@ -0,0 +1,55 @@
#!/bin/sh
# mkstatus - Extract error strings from rungpg.h
# and create a lookup table
# Copyright (C) 2000 Werner Koch (dd9jn)
#
# This file is part of GPGME.
#
# GPGME 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.
#
# GPGME 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 mkstatus */
/* Do not edit! */
struct status_table_s {
const char *name;
GpgStatusCode code;
};
static struct status_table_s status_table[] =
{
EOF
awk '
/STATUS_ENTER/ { okay=1 }
!okay {next}
/}/ { exit 0 }
/STATUS_[A-Za-z_]*/ { printf " { \"%s\", %s },\n", substr($1,8), $1 }
' | sort
cat <<EOF
{NULL, 0}
};
EOF

77
tags/V0-1-0/gpgme/ops.h Normal file
View File

@ -0,0 +1,77 @@
/* ops.h - internal operations stuff
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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
*/
#ifndef OPS_H
#define OPS_H
#include "types.h"
/*-- gpgme.c --*/
void _gpgme_release_result ( GpgmeCtx c );
/*-- wait.c --*/
GpgmeCtx _gpgme_wait_on_condition ( GpgmeCtx c,
int hang, volatile int *cond );
/*-- recipient.c --*/
void _gpgme_append_gpg_args_from_recipients (
const GpgmeRecipients rset,
GpgObject gpg );
/*-- data.c --*/
char * _gpgme_data_release_and_return_string ( GpgmeData dh );
GpgmeDataMode _gpgme_data_get_mode ( GpgmeData dh );
void _gpgme_data_set_mode ( GpgmeData dh, GpgmeDataMode mode );
char * _gpgme_data_get_as_string ( GpgmeData dh );
GpgmeError _gpgme_data_append ( GpgmeData dh,
const char *buffer, size_t length );
GpgmeError _gpgme_data_append_string ( GpgmeData dh, const char *s );
GpgmeError _gpgme_data_append_string_for_xml ( GpgmeData dh,
const char *s);
GpgmeError _gpgme_data_append_for_xml ( GpgmeData dh,
const char *buffer,
size_t len );
GpgmeError _gpgme_data_append_percentstring_for_xml ( GpgmeData dh,
const char *string );
/*-- key.c --*/
GpgmeError _gpgme_key_new( GpgmeKey *r_key );
void _gpgme_key_release ( GpgmeKey key );
/*-- verify.c --*/
void _gpgme_release_verify_result ( VerifyResult res );
/*-- decrypt.c --*/
void _gpgme_release_decrypt_result ( DecryptResult res );
/*-- sign.c --*/
void _gpgme_release_sign_result ( SignResult res );
#endif /* OPS_H */

View File

@ -0,0 +1,94 @@
/* recipient.c - mainatin recipient sets
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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 <assert.h>
#include "util.h"
#include "context.h"
#include "rungpg.h"
GpgmeError
gpgme_recipients_new (GpgmeRecipients *r_rset)
{
GpgmeRecipients rset;
rset = xtrycalloc ( 1, sizeof *rset );
if (!rset)
return mk_error (Out_Of_Core);
*r_rset = rset;
return 0;
}
void
gpgme_recipients_release ( GpgmeRecipients rset )
{
/* fixme: release the linked list */
xfree ( rset );
}
GpgmeError
gpgme_recipients_add_name (GpgmeRecipients rset, const char *name )
{
struct user_id_s *r;
if (!name || !rset )
return mk_error (Invalid_Value);
r = xtrymalloc ( sizeof *r + strlen (name) );
if (!r)
return mk_error (Out_Of_Core);
strcpy (r->name, name );
r->next = rset->list;
rset->list = r;
return 0;
}
unsigned int
gpgme_recipients_count ( const GpgmeRecipients rset )
{
struct user_id_s *r;
unsigned int count = 0;
if ( rset ) {
for (r=rset->list ; r; r = r->next )
count++;
}
return count;
}
void
_gpgme_append_gpg_args_from_recipients (
const GpgmeRecipients rset,
GpgObject gpg )
{
struct user_id_s *r;
assert (rset);
for (r=rset->list ; r; r = r->next ) {
_gpgme_gpg_add_arg ( gpg, "-r" );
_gpgme_gpg_add_arg ( gpg, r->name );
}
}

942
tags/V0-1-0/gpgme/rungpg.c Normal file
View File

@ -0,0 +1,942 @@
/* rungpg.c
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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 <assert.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <fcntl.h>
#include "gpgme.h"
#include "util.h"
#include "ops.h"
#include "wait.h"
#include "rungpg.h"
#include "context.h" /*temp hack until we have GpmeData methods to do I/O */
#include "status-table.h"
/* This type is used to build a list of gpg arguments and
* data sources/sinks */
struct arg_and_data_s {
struct arg_and_data_s *next;
GpgmeData data; /* If this is not NULL .. */
int dup_to;
char arg[1]; /* .. this is used */
};
struct fd_data_map_s {
GpgmeData data;
int inbound; /* true if this is used for reading from gpg */
int dup_to;
int fd; /* the fd to use */
int peer_fd; /* the outher side of the pipe */
};
struct gpg_object_s {
struct arg_and_data_s *arglist;
struct arg_and_data_s **argtail;
int arg_error;
struct {
int fd[2];
size_t bufsize;
char *buffer;
size_t readpos;
int eof;
GpgStatusHandler fnc;
void *fnc_value;
} status;
/* This is a kludge - see the comment at gpg_colon_line_handler */
struct {
int fd[2];
size_t bufsize;
char *buffer;
size_t readpos;
int eof;
GpgColonLineHandler fnc; /* this indicate use of this structrue */
void *fnc_value;
} colon;
char **argv;
struct fd_data_map_s *fd_data_map;
pid_t pid;
int running;
int exit_status;
int exit_signal;
};
static void kill_gpg ( GpgObject gpg );
static void free_argv ( char **argv );
static void free_fd_data_map ( struct fd_data_map_s *fd_data_map );
static int gpg_inbound_handler ( void *opaque, pid_t pid, int fd );
static int gpg_outbound_handler ( void *opaque, pid_t pid, int fd );
static int gpg_status_handler ( void *opaque, pid_t pid, int fd );
static GpgmeError read_status ( GpgObject gpg );
static int gpg_colon_line_handler ( void *opaque, pid_t pid, int fd );
static GpgmeError read_colon_line ( GpgObject gpg );
GpgmeError
_gpgme_gpg_new ( GpgObject *r_gpg )
{
GpgObject gpg;
int rc = 0;
gpg = xtrycalloc ( 1, sizeof *gpg );
if ( !gpg ) {
rc = mk_error (Out_Of_Core);
goto leave;
}
gpg->argtail = &gpg->arglist;
gpg->status.fd[0] = -1;
gpg->status.fd[1] = -1;
gpg->colon.fd[0] = -1;
gpg->colon.fd[1] = -1;
/* allocate the read buffer for the status pipe */
gpg->status.bufsize = 1024;
gpg->status.readpos = 0;
gpg->status.buffer = xtrymalloc (gpg->status.bufsize);
if (!gpg->status.buffer) {
rc = mk_error (Out_Of_Core);
goto leave;
}
/* In any case we need a status pipe - create it right here and
* don't handle it with our generic GpgmeData mechanism */
if (pipe (gpg->status.fd) == -1) {
rc = mk_error (Pipe_Error);
goto leave;
}
gpg->status.eof = 0;
_gpgme_gpg_add_arg ( gpg, "--status-fd" );
{
char buf[25];
sprintf ( buf, "%d", gpg->status.fd[1]);
_gpgme_gpg_add_arg ( gpg, buf );
}
_gpgme_gpg_add_arg ( gpg, "--batch" );
_gpgme_gpg_add_arg ( gpg, "--no-tty" );
leave:
if (rc) {
_gpgme_gpg_release (gpg);
*r_gpg = NULL;
}
else
*r_gpg = gpg;
return rc;
}
void
_gpgme_gpg_release ( GpgObject gpg )
{
if ( !gpg )
return;
xfree (gpg->status.buffer);
xfree (gpg->colon.buffer);
if ( gpg->argv )
free_argv (gpg->argv);
if (gpg->status.fd[0] != -1 )
close (gpg->status.fd[0]);
if (gpg->status.fd[1] != -1 )
close (gpg->status.fd[1]);
if (gpg->colon.fd[0] != -1 )
close (gpg->colon.fd[0]);
if (gpg->colon.fd[1] != -1 )
close (gpg->colon.fd[1]);
free_fd_data_map (gpg->fd_data_map);
kill_gpg (gpg); /* fixme: should be done asyncronously */
xfree (gpg);
}
static void
kill_gpg ( GpgObject gpg )
{
#if 0
if ( gpg->running ) {
/* still running? Must send a killer */
kill ( gpg->pid, SIGTERM);
sleep (2);
if ( !waitpid (gpg->pid, NULL, WNOHANG) ) {
/* pay the murderer better and then forget about it */
kill (gpg->pid, SIGKILL);
}
gpg->running = 0;
}
#endif
}
static int
set_nonblocking ( int fd )
{
int flags;
flags = fcntl (fd, F_GETFL, 0);
if (flags == -1)
return -1;
flags |= O_NONBLOCK;
return fcntl (fd, F_SETFL, flags);
}
GpgmeError
_gpgme_gpg_add_arg ( GpgObject gpg, const char *arg )
{
struct arg_and_data_s *a;
assert (gpg);
assert (arg);
a = xtrymalloc ( sizeof *a + strlen (arg) );
if ( !a ) {
gpg->arg_error = 1;
return mk_error(Out_Of_Core);
}
a->next = NULL;
a->data = NULL;
a->dup_to = -1;
strcpy ( a->arg, arg );
*gpg->argtail = a;
gpg->argtail = &a->next;
return 0;
}
GpgmeError
_gpgme_gpg_add_data ( GpgObject gpg, GpgmeData data, int dup_to )
{
struct arg_and_data_s *a;
assert (gpg);
assert (data);
a = xtrymalloc ( sizeof *a - 1 );
if ( !a ) {
gpg->arg_error = 1;
return mk_error(Out_Of_Core);
}
a->next = NULL;
a->data = data;
a->dup_to = dup_to;
*gpg->argtail = a;
gpg->argtail = &a->next;
return 0;
}
/*
* Note, that the status_handler is allowed to modifiy the args value
*/
void
_gpgme_gpg_set_status_handler ( GpgObject gpg,
GpgStatusHandler fnc, void *fnc_value )
{
assert (gpg);
gpg->status.fnc = fnc;
gpg->status.fnc_value = fnc_value;
}
/* Kludge to process --with-colon output */
GpgmeError
_gpgme_gpg_set_colon_line_handler ( GpgObject gpg,
GpgColonLineHandler fnc, void *fnc_value )
{
assert (gpg);
gpg->colon.bufsize = 1024;
gpg->colon.readpos = 0;
gpg->colon.buffer = xtrymalloc (gpg->colon.bufsize);
if (!gpg->colon.buffer) {
return mk_error (Out_Of_Core);
}
if (pipe (gpg->colon.fd) == -1) {
xfree (gpg->colon.buffer); gpg->colon.buffer = NULL;
return mk_error (Pipe_Error);
}
gpg->colon.eof = 0;
gpg->colon.fnc = fnc;
gpg->colon.fnc_value = fnc_value;
return 0;
}
static void
free_argv ( char **argv )
{
int i;
for (i=0; argv[i]; i++ )
xfree (argv[i]);
xfree (argv);
}
static void
free_fd_data_map ( struct fd_data_map_s *fd_data_map )
{
int i;
for (i=0; fd_data_map[i].data; i++ ) {
if ( fd_data_map[i].fd != -1 )
close (fd_data_map[i].fd);
if ( fd_data_map[i].peer_fd != -1 )
close (fd_data_map[i].peer_fd);
/* don't realease data because this is only a reference */
}
xfree (fd_data_map);
}
static GpgmeError
build_argv ( GpgObject gpg )
{
struct arg_and_data_s *a;
struct fd_data_map_s *fd_data_map;
size_t datac=0, argc=0;
char **argv;
int need_special = 0;
int use_agent = !!getenv ("GPG_AGENT_INFO");
if ( gpg->argv ) {
free_argv ( gpg->argv );
gpg->argv = NULL;
}
if (gpg->fd_data_map) {
free_fd_data_map (gpg->fd_data_map);
gpg->fd_data_map = NULL;
}
argc++; /* for argv[0] */
for ( a=gpg->arglist; a; a = a->next ) {
argc++;
if (a->data) {
/*fprintf (stderr, "build_argv: data\n" );*/
datac++;
if ( a->dup_to == -1 )
need_special = 1;
}
else {
/* fprintf (stderr, "build_argv: arg=`%s'\n", a->arg );*/
}
}
if ( need_special )
argc++;
if (use_agent)
argc++;
argv = xtrycalloc ( argc+1, sizeof *argv );
if (!argv)
return mk_error (Out_Of_Core);
fd_data_map = xtrycalloc ( datac+1, sizeof *fd_data_map );
if (!fd_data_map) {
free_argv (argv);
return mk_error (Out_Of_Core);
}
argc = datac = 0;
argv[argc] = xtrystrdup ( "gpg" ); /* argv[0] */
if (!argv[argc]) {
xfree (fd_data_map);
free_argv (argv);
return mk_error (Out_Of_Core);
}
argc++;
if ( need_special ) {
argv[argc] = xtrystrdup ( "--enable-special-filenames" );
if (!argv[argc]) {
xfree (fd_data_map);
free_argv (argv);
return mk_error (Out_Of_Core);
}
argc++;
}
if ( use_agent ) {
argv[argc] = xtrystrdup ( "--use-agent" );
if (!argv[argc]) {
xfree (fd_data_map);
free_argv (argv);
return mk_error (Out_Of_Core);
}
argc++;
}
for ( a=gpg->arglist; a; a = a->next ) {
if ( a->data ) {
switch ( _gpgme_data_get_mode (a->data) ) {
case GPGME_DATA_MODE_NONE:
case GPGME_DATA_MODE_INOUT:
xfree (fd_data_map);
free_argv (argv);
return mk_error (Invalid_Mode);
case GPGME_DATA_MODE_IN:
/* create a pipe to read from gpg */
fd_data_map[datac].inbound = 1;
break;
case GPGME_DATA_MODE_OUT:
/* create a pipe to pass it down to gpg */
fd_data_map[datac].inbound = 0;
break;
}
switch ( gpgme_data_get_type (a->data) ) {
case GPGME_DATA_TYPE_NONE:
if ( fd_data_map[datac].inbound )
break; /* allowed */
xfree (fd_data_map);
free_argv (argv);
return mk_error (Invalid_Type);
case GPGME_DATA_TYPE_MEM:
break;
case GPGME_DATA_TYPE_FD:
case GPGME_DATA_TYPE_FILE:
xfree (fd_data_map);
free_argv (argv);
return mk_error (Not_Implemented);
}
/* create a pipe */
{
int fds[2];
if (pipe (fds) == -1) {
xfree (fd_data_map);
free_argv (argv);
return mk_error (Pipe_Error);
}
/* if the data_type is FD, we have to do a dup2 here */
if (fd_data_map[datac].inbound) {
fd_data_map[datac].fd = fds[0];
fd_data_map[datac].peer_fd = fds[1];
}
else {
fd_data_map[datac].fd = fds[1];
fd_data_map[datac].peer_fd = fds[0];
}
}
fd_data_map[datac].data = a->data;
fd_data_map[datac].dup_to = a->dup_to;
if ( a->dup_to == -1 ) {
argv[argc] = xtrymalloc ( 25 );
if (!argv[argc]) {
xfree (fd_data_map);
free_argv (argv);
return mk_error (Out_Of_Core);
}
sprintf ( argv[argc], "-&%d", fd_data_map[datac].peer_fd );
argc++;
}
datac++;
}
else {
argv[argc] = xtrystrdup ( a->arg );
if (!argv[argc]) {
xfree (fd_data_map);
free_argv (argv);
return mk_error (Out_Of_Core);
}
argc++;
}
}
gpg->argv = argv;
gpg->fd_data_map = fd_data_map;
return 0;
}
GpgmeError
_gpgme_gpg_spawn( GpgObject gpg, void *opaque )
{
int rc;
int i;
pid_t pid;
if ( !gpg )
return mk_error (Invalid_Value);
/* Kludge, so that we don't need to check the return code of
* all the gpgme_gpg_add_arg(). we bail out here instead */
if ( gpg->arg_error )
return mk_error (Out_Of_Core);
rc = build_argv ( gpg );
if ( rc )
return rc;
fflush (stderr);
pid = fork ();
if (pid == -1) {
return mk_error (Exec_Error);
}
if ( !pid ) { /* child */
int duped_stdin = 0;
int duped_stderr = 0;
close (gpg->status.fd[0]);
if (gpg->colon.fnc) {
/* dup it to stdout */
if ( dup2 ( gpg->colon.fd[1], 1 ) == -1 ) {
fprintf (stderr,"dup2(colon, 1) failed: %s\n",
strerror (errno) );
_exit (8);
}
close (gpg->colon.fd[0]);
close (gpg->colon.fd[1]);
}
for (i=0; gpg->fd_data_map[i].data; i++ ) {
close (gpg->fd_data_map[i].fd);
gpg->fd_data_map[i].fd = -1;
if ( gpg->fd_data_map[i].dup_to != -1 ) {
if ( dup2 (gpg->fd_data_map[i].peer_fd,
gpg->fd_data_map[i].dup_to ) == -1 ) {
fprintf (stderr, "dup2 failed in child: %s\n",
strerror (errno));
_exit (8);
}
if ( gpg->fd_data_map[i].dup_to == 0 )
duped_stdin=1;
if ( gpg->fd_data_map[i].dup_to == 2 )
duped_stderr=1;
close ( gpg->fd_data_map[i].peer_fd );
}
}
if( !duped_stdin || !duped_stderr ) {
int fd = open ( "/dev/null", O_RDONLY );
if ( fd == -1 ) {
fprintf (stderr,"can't open `/dev/null': %s\n",
strerror (errno) );
_exit (8);
}
/* Make sure that gpg has a connected stdin */
if ( !duped_stdin ) {
if ( dup2 ( fd, 0 ) == -1 ) {
fprintf (stderr,"dup2(/dev/null, 0) failed: %s\n",
strerror (errno) );
_exit (8);
}
}
/* We normally don't want all the normal output */
if ( !duped_stderr ) {
if (!getenv ("GPGME_DEBUG") ) {
if ( dup2 ( fd, 2 ) == -1 ) {
fprintf (stderr,"dup2(dev/null, 2) failed: %s\n",
strerror (errno) );
_exit (8);
}
}
}
close (fd);
}
execv ( GPG_PATH, gpg->argv );
fprintf (stderr,"exec of gpg failed\n");
_exit (8);
}
/* parent */
gpg->pid = pid;
/*_gpgme_register_term_handler ( closure, closure_value, pid );*/
if ( gpg->status.fd[1] != -1 ) {
close (gpg->status.fd[1]);
gpg->status.fd[1] = -1;
}
if ( _gpgme_register_pipe_handler ( opaque, gpg_status_handler,
gpg, pid, gpg->status.fd[0], 1 ) ) {
/* FIXME: kill the child */
return mk_error (General_Error);
}
if ( gpg->colon.fd[1] != -1 ) {
close (gpg->colon.fd[1]);
gpg->colon.fd[1] = -1;
assert ( gpg->colon.fd[0] != -1 );
if ( _gpgme_register_pipe_handler ( opaque, gpg_colon_line_handler,
gpg, pid, gpg->colon.fd[0], 1 ) ) {
/* FIXME: kill the child */
return mk_error (General_Error);
}
}
for (i=0; gpg->fd_data_map[i].data; i++ ) {
close (gpg->fd_data_map[i].peer_fd);
gpg->fd_data_map[i].peer_fd = -1;
/* Due to problems with select and write we set outbound pipes
* to non-blocking */
if (!gpg->fd_data_map[i].inbound) {
set_nonblocking (gpg->fd_data_map[i].fd);
}
if ( _gpgme_register_pipe_handler (
opaque,
gpg->fd_data_map[i].inbound?
gpg_inbound_handler:gpg_outbound_handler,
gpg->fd_data_map[i].data,
pid, gpg->fd_data_map[i].fd,
gpg->fd_data_map[i].inbound )
) {
/* FIXME: kill the child */
return mk_error (General_Error);
}
}
/* fixme: check what data we can release here */
gpg->running = 1;
return 0;
}
static int
gpg_inbound_handler ( void *opaque, pid_t pid, int fd )
{
GpgmeData dh = opaque;
GpgmeError err;
int nread;
char buf[200];
assert ( _gpgme_data_get_mode (dh) == GPGME_DATA_MODE_IN );
do {
nread = read (fd, buf, 200 );
} while ( nread == -1 && errno == EINTR);
fprintf(stderr, "inbound on fd %d: nread=%d\n", fd, nread );
if ( nread < 0 ) {
fprintf (stderr, "read_mem_data: read failed on fd %d (n=%d): %s\n",
fd, nread, strerror (errno) );
return 1;
}
else if (!nread)
return 1; /* eof */
/* We could improve this with a GpgmeData function which takes
* the read function or provides a memory area for writing to it.
*/
err = _gpgme_data_append ( dh, buf, nread );
if ( err ) {
fprintf (stderr, "_gpgme_append_data failed: %s\n",
gpgme_strerror(err));
/* Fixme: we should close the pipe or read it to /dev/null in
* this case. Returnin EOF is not sufficient */
return 1;
}
return 0;
}
static int
write_mem_data ( GpgmeData dh, int fd )
{
size_t nbytes;
int nwritten;
nbytes = dh->len - dh->readpos;
if ( !nbytes ) {
fprintf (stderr, "write_mem_data(%d): closing\n", fd );
close (fd);
return 1;
}
/* FIXME: Arggg, the pipe blocks on large write request, although
* select told us that it is okay to write - need to figure out
* why this happens? Stevens says nothing about this problem (or
* is it my Linux kernel 2.4.0test1)
* To avoid that we have set the pipe to nonblocking.
*/
do {
fprintf (stderr, "write_mem_data(%d): about to write %d bytes len=%d rpos=%d\n",
fd, (int)nbytes, (int)dh->len, dh->readpos );
nwritten = write ( fd, dh->data+dh->readpos, nbytes );
fprintf (stderr, "write_mem_data(%d): wrote %d bytes\n", fd, nwritten );
} while ( nwritten == -1 && errno == EINTR );
if (nwritten == -1 && errno == EAGAIN )
return 0;
if ( nwritten < 1 ) {
fprintf (stderr, "write_mem_data(%d): write failed (n=%d): %s\n",
fd, nwritten, strerror (errno) );
close (fd);
return 1;
}
dh->readpos += nwritten;
return 0;
}
static int
gpg_outbound_handler ( void *opaque, pid_t pid, int fd )
{
GpgmeData dh = opaque;
assert ( _gpgme_data_get_mode (dh) == GPGME_DATA_MODE_OUT );
switch ( gpgme_data_get_type (dh) ) {
case GPGME_DATA_TYPE_MEM:
if ( write_mem_data ( dh, fd ) )
return 1; /* ready */
break;
default:
assert (0);
}
return 0;
}
static int
gpg_status_handler ( void *opaque, pid_t pid, int fd )
{
GpgObject gpg = opaque;
int rc = 0;
assert ( fd == gpg->status.fd[0] );
rc = read_status ( gpg );
if ( rc ) {
fprintf (stderr, "gpg_handler: read_status problem %d\n - stop", rc);
return 1;
}
return gpg->status.eof;
}
static int
status_cmp (const void *ap, const void *bp)
{
const struct status_table_s *a = ap;
const struct status_table_s *b = bp;
return strcmp (a->name, b->name);
}
/*
* Handle the status output of GnuPG. This function does read entire
* lines and passes them as C strings to the callback function (we can
* use C Strings because the status output is always UTF-8 encoded).
* Of course we have to buffer the lines to cope with long lines
* e.g. with a large user ID. Note: We can optimize this to only cope
* with status line code we know about and skip all other stuff
* without buffering (i.e. without extending the buffer). */
static GpgmeError
read_status ( GpgObject gpg )
{
char *p;
int nread;
size_t bufsize = gpg->status.bufsize;
char *buffer = gpg->status.buffer;
size_t readpos = gpg->status.readpos;
assert (buffer);
if (bufsize - readpos < 256) {
/* need more room for the read */
bufsize += 1024;
buffer = xtryrealloc (buffer, bufsize);
if ( !buffer )
return mk_error (Out_Of_Core);
}
do {
nread = read ( gpg->status.fd[0], buffer+readpos, bufsize-readpos );
} while (nread == -1 && errno == EINTR);
if (nread == -1)
return mk_error(Read_Error);
if (!nread) {
gpg->status.eof = 1;
if (gpg->status.fnc)
gpg->status.fnc ( gpg->status.fnc_value, STATUS_EOF, "" );
return 0;
}
while (nread > 0) {
for (p = buffer + readpos; nread; nread--, p++) {
if ( *p == '\n' ) {
/* (we require that the last line is terminated by a LF) */
*p = 0;
fprintf (stderr, "read_status: `%s'\n", buffer);
if (!strncmp (buffer, "[GNUPG:] ", 9 )
&& buffer[9] >= 'A' && buffer[9] <= 'Z'
&& gpg->status.fnc ) {
struct status_table_s t, *r;
char *rest;
rest = strchr (buffer+9, ' ');
if ( !rest )
rest = p; /* set to an empty string */
else
*rest++ = 0;
t.name = buffer+9;
/* (the status table as one extra element) */
r = bsearch ( &t, status_table, DIM(status_table)-1,
sizeof t, status_cmp );
if ( r ) {
gpg->status.fnc ( gpg->status.fnc_value,
r->code, rest);
}
}
/* To reuse the buffer for the next line we have to
* shift the remaining data to the buffer start and
* restart the loop Hmmm: We can optimize this
* function by looking forward in the buffer to see
* whether a second complete line is available and in
* this case avoid the memmove for this line. */
nread--; p++;
if (nread)
memmove (buffer, p, nread);
readpos = 0;
break; /* the for loop */
}
else
readpos++;
}
}
/* Update the gpg object. */
gpg->status.bufsize = bufsize;
gpg->status.buffer = buffer;
gpg->status.readpos = readpos;
return 0;
}
/*
* This colonline handler thing is not the clean way to do it.
* It might be better to enhance the GpgmeData object to act as
* a wrapper for a callback. Same goes for the status thing.
* For now we use this thing here becuase it is easier to implement.
*/
static int
gpg_colon_line_handler ( void *opaque, pid_t pid, int fd )
{
GpgObject gpg = opaque;
GpgmeError rc = 0;
assert ( fd == gpg->colon.fd[0] );
rc = read_colon_line ( gpg );
if ( rc ) {
fprintf (stderr, "gpg_colon_line_handler: "
"read problem %d\n - stop", rc);
return 1;
}
return gpg->status.eof;
}
static GpgmeError
read_colon_line ( GpgObject gpg )
{
char *p;
int nread;
size_t bufsize = gpg->colon.bufsize;
char *buffer = gpg->colon.buffer;
size_t readpos = gpg->colon.readpos;
assert (buffer);
if (bufsize - readpos < 256) {
/* need more room for the read */
bufsize += 1024;
buffer = xtryrealloc (buffer, bufsize);
if ( !buffer )
return mk_error (Out_Of_Core);
}
do {
nread = read ( gpg->colon.fd[0], buffer+readpos, bufsize-readpos );
} while (nread == -1 && errno == EINTR);
if (nread == -1)
return mk_error(Read_Error);
if (!nread) {
gpg->colon.eof = 1;
assert (gpg->colon.fnc);
gpg->colon.fnc ( gpg->colon.fnc_value, NULL );
return 0;
}
while (nread > 0) {
for (p = buffer + readpos; nread; nread--, p++) {
if ( *p == '\n' ) {
/* (we require that the last line is terminated by a
* LF) and we skip empty lines. Note: we use UTF8
* encoding and escaping of special characters
* We require at least one colon to cope with
* some other printed information.
*/
*p = 0;
if ( *buffer && strchr (buffer, ':') ) {
assert (gpg->colon.fnc);
gpg->colon.fnc ( gpg->colon.fnc_value, buffer );
}
/* To reuse the buffer for the next line we have to
* shift the remaining data to the buffer start and
* restart the loop Hmmm: We can optimize this
* function by looking forward in the buffer to see
* whether a second complete line is available and in
* this case avoid the memmove for this line. */
nread--; p++;
if (nread)
memmove (buffer, p, nread);
readpos = 0;
break; /* the for loop */
}
else
readpos++;
}
}
/* Update the gpg object. */
gpg->colon.bufsize = bufsize;
gpg->colon.buffer = buffer;
gpg->colon.readpos = readpos;
return 0;
}

111
tags/V0-1-0/gpgme/rungpg.h Normal file
View File

@ -0,0 +1,111 @@
/* rungpg.h - gpg calling functions
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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
*/
#ifndef RUNGPG_H
#define RUNGPG_H
#include "types.h"
typedef enum {
STATUS_EOF ,
/* mkstatus starts here */
STATUS_ENTER ,
STATUS_LEAVE ,
STATUS_ABORT ,
STATUS_GOODSIG ,
STATUS_BADSIG ,
STATUS_ERRSIG ,
STATUS_BADARMOR ,
STATUS_RSA_OR_IDEA ,
STATUS_SIGEXPIRED ,
STATUS_KEYREVOKED ,
STATUS_TRUST_UNDEFINED ,
STATUS_TRUST_NEVER ,
STATUS_TRUST_MARGINAL ,
STATUS_TRUST_FULLY ,
STATUS_TRUST_ULTIMATE ,
STATUS_SHM_INFO ,
STATUS_SHM_GET ,
STATUS_SHM_GET_BOOL ,
STATUS_SHM_GET_HIDDEN ,
STATUS_NEED_PASSPHRASE ,
STATUS_VALIDSIG ,
STATUS_SIG_ID ,
STATUS_ENC_TO ,
STATUS_NODATA ,
STATUS_BAD_PASSPHRASE ,
STATUS_NO_PUBKEY ,
STATUS_NO_SECKEY ,
STATUS_NEED_PASSPHRASE_SYM,
STATUS_DECRYPTION_FAILED ,
STATUS_DECRYPTION_OKAY ,
STATUS_MISSING_PASSPHRASE ,
STATUS_GOOD_PASSPHRASE ,
STATUS_GOODMDC ,
STATUS_BADMDC ,
STATUS_ERRMDC ,
STATUS_IMPORTED ,
STATUS_IMPORT_RES ,
STATUS_FILE_START ,
STATUS_FILE_DONE ,
STATUS_FILE_ERROR ,
STATUS_BEGIN_DECRYPTION ,
STATUS_END_DECRYPTION ,
STATUS_BEGIN_ENCRYPTION ,
STATUS_END_ENCRYPTION ,
STATUS_DELETE_PROBLEM ,
STATUS_GET_BOOL ,
STATUS_GET_LINE ,
STATUS_GET_HIDDEN ,
STATUS_GOT_IT ,
STATUS_PROGRESS ,
STATUS_SIG_CREATED ,
STATUS_SESSION_KEY ,
STATUS_NOTATION_NAME ,
STATUS_NOTATION_DATA ,
STATUS_POLICY_URL
} GpgStatusCode;
typedef void (*GpgStatusHandler)( GpgmeCtx, GpgStatusCode code, char *args );
typedef void (*GpgColonLineHandler)( GpgmeCtx, char *line );
GpgmeError _gpgme_gpg_new ( GpgObject *r_gpg );
void _gpgme_gpg_release ( GpgObject gpg );
GpgmeError _gpgme_gpg_add_arg ( GpgObject gpg, const char *arg );
GpgmeError _gpgme_gpg_add_data ( GpgObject gpg, GpgmeData data, int dup_to );
void _gpgme_gpg_set_status_handler ( GpgObject gpg,
GpgStatusHandler fnc,
void *fnc_value );
GpgmeError _gpgme_gpg_set_colon_line_handler ( GpgObject gpg,
GpgColonLineHandler fnc,
void *fnc_value );
GpgmeError _gpgme_gpg_spawn ( GpgObject gpg, void *opaque );
#endif /* RUNGPG_H */

190
tags/V0-1-0/gpgme/sign.c Normal file
View File

@ -0,0 +1,190 @@
/* sign.c - signing functions
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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 <assert.h>
#include "util.h"
#include "context.h"
#include "ops.h"
struct sign_result_s {
int no_passphrase;
int okay;
};
void
_gpgme_release_sign_result ( SignResult res )
{
xfree (res);
}
static void
sign_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
{
if ( ctx->out_of_core )
return;
if ( ctx->result_type == RESULT_TYPE_NONE ) {
assert ( !ctx->result.sign );
ctx->result.sign = xtrycalloc ( 1, sizeof *ctx->result.sign );
if ( !ctx->result.sign ) {
ctx->out_of_core = 1;
return;
}
ctx->result_type = RESULT_TYPE_SIGN;
}
assert ( ctx->result_type == RESULT_TYPE_SIGN );
switch (code) {
case STATUS_EOF:
break;
case STATUS_NEED_PASSPHRASE:
case STATUS_NEED_PASSPHRASE_SYM:
fprintf (stderr, "Ooops: Need a passphrase - use the agent\n");
break;
case STATUS_MISSING_PASSPHRASE:
fprintf (stderr, "Missing passphrase - stop\n");;
ctx->result.sign->no_passphrase = 1;
break;
case STATUS_SIG_CREATED:
/* fixme: we have no error return for multible signatures */
ctx->result.sign->okay =1;
break;
default:
fprintf (stderr, "sign_status: code=%d not handled\n", code );
break;
}
}
GpgmeError
gpgme_op_sign_start ( GpgmeCtx c, GpgmeData in, GpgmeData out )
{
int rc = 0;
int i;
fail_on_pending_request( c );
c->pending = 1;
_gpgme_release_result (c);
c->out_of_core = 0;
/* do some checks */
assert ( !c->gpg );
/* create a process object */
rc = _gpgme_gpg_new ( &c->gpg );
if (rc)
goto leave;
_gpgme_gpg_set_status_handler ( c->gpg, sign_status_handler, c );
/* build the commandline */
_gpgme_gpg_add_arg ( c->gpg, "--sign" );
_gpgme_gpg_add_arg ( c->gpg, "--detach" );
if ( c->use_armor )
_gpgme_gpg_add_arg ( c->gpg, "--armor" );
if ( c->use_textmode )
_gpgme_gpg_add_arg ( c->gpg, "--textmode" );
for ( i=0; i < c->verbosity; i++ )
_gpgme_gpg_add_arg ( c->gpg, "--verbose" );
/* Check the supplied data */
if ( gpgme_data_get_type (in) == GPGME_DATA_TYPE_NONE ) {
rc = mk_error (No_Data);
goto leave;
}
_gpgme_data_set_mode (in, GPGME_DATA_MODE_OUT );
if ( !out || gpgme_data_get_type (out) != GPGME_DATA_TYPE_NONE ) {
rc = mk_error (Invalid_Value);
goto leave;
}
_gpgme_data_set_mode (out, GPGME_DATA_MODE_IN );
/* Tell the gpg object about the data */
_gpgme_gpg_add_data ( c->gpg, in, 0 );
_gpgme_gpg_add_data ( c->gpg, out, 1 );
/* and kick off the process */
rc = _gpgme_gpg_spawn ( c->gpg, c );
leave:
if (rc) {
c->pending = 0;
_gpgme_gpg_release ( c->gpg ); c->gpg = NULL;
}
return rc;
}
/**
* gpgme_op_sign:
* @c: The context
* @in: Data to be signed
* @out: Detached signature
*
* Create a detached signature for @in and write it to @out.
* The data will be signed using either the default key or the ones
* defined through @c.
*
* Return value: 0 on success or an error code.
**/
GpgmeError
gpgme_op_sign ( GpgmeCtx c, GpgmeData in, GpgmeData out )
{
GpgmeError err = gpgme_op_sign_start ( c, in, out );
if ( !err ) {
gpgme_wait (c, 1);
if ( c->result_type != RESULT_TYPE_SIGN )
err = mk_error (General_Error);
else if ( c->out_of_core )
err = mk_error (Out_Of_Core);
else {
assert ( c->result.sign );
if ( c->result.sign->no_passphrase )
err = mk_error (No_Passphrase);
else if (!c->result.sign->okay)
err = mk_error (No_Data); /* Hmmm: choose a better error? */
}
c->pending = 0;
}
return err;
}

66
tags/V0-1-0/gpgme/types.h Normal file
View File

@ -0,0 +1,66 @@
/* types.h - Some type definitions
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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
*/
#ifndef TYPES_H
#define TYPES_H
#include "gpgme.h" /* external objects and prototypes */
typedef unsigned char byte;
typedef enum {
GPGME_DATA_MODE_NONE = 0,
GPGME_DATA_MODE_IN = 1,
GPGME_DATA_MODE_OUT = 2,
GPGME_DATA_MODE_INOUT = 3
} GpgmeDataMode;
/*
* Declaration of internal objects
*/
/*-- rungpg.c --*/
struct gpg_object_s;
typedef struct gpg_object_s *GpgObject;
/*-- verify.c --*/
struct verify_result_s;
typedef struct verify_result_s *VerifyResult;
/*-- decrypt.c --*/
struct decrypt_result_s;
typedef struct decrypt_result_s *DecryptResult;
/*-- sign.c --*/
struct sign_result_s;
typedef struct sign_result_s *SignResult;
/*-- key.c --*/
#endif /* TYPES_H */

63
tags/V0-1-0/gpgme/util.c Normal file
View File

@ -0,0 +1,63 @@
/* util.c
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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 <assert.h>
#include "util.h"
void *
_gpgme_malloc (size_t n )
{
return malloc (n);
}
void *
_gpgme_calloc (size_t n, size_t m )
{
return calloc (n, m);
}
void *
_gpgme_realloc (void *p, size_t n)
{
return realloc (p, n );
}
char *
_gpgme_strdup (const char *p)
{
return strdup (p);
}
void
_gpgme_free ( void *a )
{
free (a);
}

49
tags/V0-1-0/gpgme/util.h Normal file
View File

@ -0,0 +1,49 @@
/* util.h
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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
*/
#ifndef UTIL_H
#define UTIL_H
#include "types.h"
void *_gpgme_malloc (size_t n );
void *_gpgme_calloc (size_t n, size_t m );
void *_gpgme_realloc (void *p, size_t n);
char *_gpgme_strdup (const char *p);
void _gpgme_free ( void *a );
#define xtrymalloc(a) _gpgme_malloc((a))
#define xtrycalloc(a,b) _gpgme_calloc((a),(b))
#define xtryrealloc(a,b) _gpgme_realloc((a),(b))
#define xtrystrdup(a) _gpgme_strdup((a))
#define xfree(a) _gpgme_free((a))
#define mk_error(a) ( GPGME_##a )
#define DIM(v) (sizeof(v)/sizeof((v)[0]))
#define DIMof(type,member) DIM(((type *)0)->member)
#endif /* UTIL_H */

243
tags/V0-1-0/gpgme/verify.c Normal file
View File

@ -0,0 +1,243 @@
/* verify.c - signature verification
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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 <assert.h>
#include "util.h"
#include "context.h"
#include "ops.h"
struct verify_result_s {
GpgmeSigStat status;
GpgmeData notation; /* we store an XML fragment here */
int notation_in_data; /* private to add_notation() */
};
void
_gpgme_release_verify_result ( VerifyResult res )
{
gpgme_data_release ( res->notation );
xfree (res);
}
static void
add_notation ( GpgmeCtx ctx, GpgStatusCode code, const char *data )
{
GpgmeData dh = ctx->result.verify->notation;
if ( !dh ) {
if ( gpgme_data_new ( &dh ) ) {
ctx->out_of_core = 1;
return;
}
ctx->result.verify->notation = dh;
_gpgme_data_append_string (dh, " <notation>\n");
}
if ( code == STATUS_NOTATION_DATA ) {
if ( !ctx->result.verify->notation_in_data )
_gpgme_data_append_string (dh, " <data>");
_gpgme_data_append_percentstring_for_xml (dh, data);
ctx->result.verify->notation_in_data = 1;
return;
}
if ( ctx->result.verify->notation_in_data ) {
_gpgme_data_append_string (dh, "</data>\n");
ctx->result.verify->notation_in_data = 0;
}
if ( code == STATUS_NOTATION_NAME ) {
_gpgme_data_append_string (dh, " <name>");
_gpgme_data_append_percentstring_for_xml (dh, data);
_gpgme_data_append_string (dh, "</name>\n");
}
else if ( code == STATUS_POLICY_URL ) {
_gpgme_data_append_string (dh, " <policy>");
_gpgme_data_append_percentstring_for_xml (dh, data);
_gpgme_data_append_string (dh, "</policy>\n");
}
else {
assert (0);
}
}
static void
verify_status_handler ( GpgmeCtx ctx, GpgStatusCode code, char *args )
{
if ( ctx->out_of_core )
return;
if ( ctx->result_type == RESULT_TYPE_NONE ) {
assert ( !ctx->result.verify );
ctx->result.verify = xtrycalloc ( 1, sizeof *ctx->result.verify );
if ( !ctx->result.verify ) {
ctx->out_of_core = 1;
return;
}
ctx->result_type = RESULT_TYPE_VERIFY;
}
assert ( ctx->result_type == RESULT_TYPE_VERIFY );
/* FIXME: For now we handle only one signature */
/* FIXME: Collect useful information
and return them as XML */
switch (code) {
case STATUS_GOODSIG:
ctx->result.verify->status = GPGME_SIG_STAT_GOOD;
break;
case STATUS_BADSIG:
ctx->result.verify->status = GPGME_SIG_STAT_BAD;
break;
case STATUS_ERRSIG:
ctx->result.verify->status = GPGME_SIG_STAT_ERROR;
/* FIXME: distinguish between a regular error and a missing key.
* this is encoded in the args. */
break;
case STATUS_NOTATION_NAME:
case STATUS_NOTATION_DATA:
case STATUS_POLICY_URL:
add_notation ( ctx, code, args );
break;
default:
/* ignore all other codes */
fprintf (stderr, "verify_status: code=%d not handled\n", code );
break;
}
}
GpgmeError
gpgme_op_verify_start ( GpgmeCtx c, GpgmeData sig, GpgmeData text )
{
int rc = 0;
int i;
fail_on_pending_request( c );
c->pending = 1;
_gpgme_release_result (c);
c->out_of_core = 0;
/* create a process object.
* To optimize this, we should reuse an existing one and
* run gpg in the new --pipemode (I started with this but it is
* not yet finished) */
if ( c->gpg ) {
_gpgme_gpg_release ( c->gpg );
c->gpg = NULL;
}
rc = _gpgme_gpg_new ( &c->gpg );
if (rc)
goto leave;
_gpgme_gpg_set_status_handler ( c->gpg, verify_status_handler, c );
/* build the commandline */
_gpgme_gpg_add_arg ( c->gpg, "--verify" );
for ( i=0; i < c->verbosity; i++ )
_gpgme_gpg_add_arg ( c->gpg, "--verbose" );
/* Check the supplied data */
if ( gpgme_data_get_type (sig) == GPGME_DATA_TYPE_NONE ) {
rc = mk_error (No_Data);
goto leave;
}
if ( text && gpgme_data_get_type (text) == GPGME_DATA_TYPE_NONE ) {
rc = mk_error (No_Data);
goto leave;
}
_gpgme_data_set_mode (sig, GPGME_DATA_MODE_OUT );
if (text) /* detached signature */
_gpgme_data_set_mode (text, GPGME_DATA_MODE_OUT );
/* Tell the gpg object about the data */
_gpgme_gpg_add_arg ( c->gpg, "--" );
_gpgme_gpg_add_data ( c->gpg, sig, -1 );
if (text)
_gpgme_gpg_add_data ( c->gpg, text, 0 );
/* and kick off the process */
rc = _gpgme_gpg_spawn ( c->gpg, c );
leave:
if (rc) {
c->pending = 0;
_gpgme_gpg_release ( c->gpg ); c->gpg = NULL;
}
return rc;
}
GpgmeError
gpgme_op_verify ( GpgmeCtx c, GpgmeData sig, GpgmeData text,
GpgmeSigStat *r_stat )
{
int rc;
if ( !r_stat )
return mk_error (Invalid_Value);
gpgme_data_release (c->notation);
c->notation = NULL;
*r_stat = GPGME_SIG_STAT_NONE;
rc = gpgme_op_verify_start ( c, sig, text );
if ( !rc ) {
gpgme_wait (c, 1);
if ( c->result_type != RESULT_TYPE_VERIFY )
rc = mk_error (General_Error);
else if ( c->out_of_core )
rc = mk_error (Out_Of_Core);
else {
assert ( c->result.verify );
if ( c->result.verify->notation ) {
GpgmeData dh = c->result.verify->notation;
if ( c->result.verify->notation_in_data ) {
_gpgme_data_append_string (dh, "</data>\n");
c->result.verify->notation_in_data = 0;
}
_gpgme_data_append_string (dh, "</notation>\n");
c->notation = dh;
c->result.verify->notation = NULL;
}
*r_stat = c->result.verify->status;
}
c->pending = 0;
}
return rc;
}

391
tags/V0-1-0/gpgme/wait.c Normal file
View File

@ -0,0 +1,391 @@
/* wait.c
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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 <assert.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include "util.h"
#include "context.h"
#include "ops.h"
#include "wait.h"
#define DEBUG_SELECT_ENABLED 1
#if DEBUG_SELECT_ENABLED
# define DEBUG_SELECT(a) fprintf a
#else
# define DEBUG_SELECT(a) do { } while(0)
#endif
/* Fixme: implement the following stuff to make the code MT safe.
* To avoid the need to link against a specific threads lib, such
* an implementation should require the caller to register a function
* which does this task.
* enter_crit() and leave_crit() are used to embrace an area of code
* which should be executed only by one thread at a time.
* lock_xxxx() and unlock_xxxx() protect access to an data object.
* */
#define enter_crit() do { } while (0)
#define leave_crit() do { } while (0)
#define lock_queue() do { } while (0)
#define unlock_queue() do { } while (0)
struct wait_queue_item_s {
struct wait_queue_item_s *next;
volatile int used;
volatile int active;
int (*handler)(void*,pid_t,int);
void *handler_value;
pid_t pid;
int fd;
int inbound; /* this is an inbound data handler fd */
int exited;
int exit_status;
int exit_signal;
GpgmeCtx ctx;
};
static struct wait_queue_item_s wait_queue[SIZEOF_WAIT_QUEUE];
static int the_big_select ( void );
static void
init_wait_queue (void)
{
int i;
static int initialized = 0;
if ( initialized ) /* FIXME: This leads to a race */
return;
lock_queue ();
for (i=1; i < SIZEOF_WAIT_QUEUE; i++ )
wait_queue[i-1].next = &wait_queue[i];
initialized = 1;
unlock_queue();
}
static struct wait_queue_item_s *
queue_item_from_context ( GpgmeCtx ctx )
{
struct wait_queue_item_s *q;
for (q=wait_queue; q; q = q->next) {
if ( q->used && q->ctx == ctx )
return q;
}
return NULL;
}
static void
propagate_term_results ( const struct wait_queue_item_s *first_q )
{
struct wait_queue_item_s *q;
for (q=wait_queue; q; q = q->next) {
if ( q->used && q != first_q && !q->exited
&& q->pid == first_q->pid ) {
q->exited = first_q->exited;
q->exit_status = first_q->exit_status;
q->exit_signal = first_q->exit_signal;
}
}
}
static int
count_active_fds ( pid_t pid )
{
struct wait_queue_item_s *q;
int count = 0;
for (q=wait_queue; q; q = q->next) {
if ( q->used && q->active && q->pid == pid )
count++;
}
return count;
}
/* remove the given process from the queue */
static void
remove_process ( pid_t pid )
{
struct wait_queue_item_s *q;
for (q=wait_queue; q; q = q->next) {
if ( q->used ) {
close (q->fd);
q->handler = NULL;
q->ctx = NULL;
q->used = 0;
}
}
}
/**
* gpgme_wait:
* @c:
* @hang:
*
* Wait for a finished request, if @c is given the function does only
* wait on a finsihed request for that context, otherwise it will return
* on any request. When @hang is true the function will wait, otherwise
* it will return immediately when there is no pending finished request.
*
* Return value: Context of the finished request or NULL if @hang is false
* and no (or the given) request has finished.
**/
GpgmeCtx
gpgme_wait ( GpgmeCtx c, int hang )
{
return _gpgme_wait_on_condition ( c, hang, NULL );
}
GpgmeCtx
_gpgme_wait_on_condition ( GpgmeCtx c, int hang, volatile int *cond )
{
struct wait_queue_item_s *q;
init_wait_queue ();
do {
int did_work = the_big_select();
if ( cond && *cond )
hang = 0;
if ( !did_work ) {
int status;
/* We did no read/write - see whether this process is still
* alive */
assert (c); /* !c is not yet implemented */
q = queue_item_from_context ( c );
assert (q);
if (q->exited)
;
else if ( waitpid ( q->pid, &status, WNOHANG ) == q->pid ) {
q->exited = 1;
if ( WIFSIGNALED (status) ) {
q->exit_status = 4; /* Need some value here */
q->exit_signal = WTERMSIG (status);
}
else if ( WIFEXITED (status) ) {
q->exit_status = WEXITSTATUS (status);
}
else {
q->exited++;
q->exit_status = 4;
}
propagate_term_results (q);
}
if ( q->exited ) {
if ( !count_active_fds (q->pid) ) {
/* Hmmm, as long as we don't have a callback for
* the exit status, we have no use for these
* values and therefore we can remove this from
* the queue */
remove_process (q->pid);
hang = 0;
}
}
}
} while (hang);
return c;
}
/*
* We use this function to do the select stuff for all running
* gpgs. A future version might provide a facility to delegate
* those selects to the GDK select stuff.
* This function must be called only by one thread!!
* FIXME: The data structures and algorithms are stupid.
* Returns: 0 = nothing to run
* 1 = did run something
*/
static int
the_big_select ( void )
{
static fd_set readfds;
static fd_set writefds;
struct wait_queue_item_s *q;
int max_fd, n;
struct timeval timeout = { 1, 0 }; /* Use a one second timeout */
FD_ZERO ( &readfds );
FD_ZERO ( &writefds );
max_fd = 0;
DEBUG_SELECT ((stderr, "gpgme:select on [ "));
lock_queue ();
for ( q = wait_queue; q; q = q->next ) {
if ( q->used && q->active ) {
if (q->inbound) {
assert ( !FD_ISSET ( q->fd, &readfds ) );
FD_SET ( q->fd, &readfds );
DEBUG_SELECT ((stderr, "r%d ", q->fd ));
}
else {
assert ( !FD_ISSET ( q->fd, &writefds ) );
FD_SET ( q->fd, &writefds );
DEBUG_SELECT ((stderr, "w%d ", q->fd ));
}
if ( q->fd > max_fd )
max_fd = q->fd;
}
}
unlock_queue ();
DEBUG_SELECT ((stderr, "]\n" ));
n = select ( max_fd+1, &readfds, &writefds, NULL, &timeout );
if ( n <= 0 ) {
if ( n && errno != EINTR ) {
fprintf (stderr, "the_big_select: select failed: %s\n",
strerror (errno) );
}
return 0;
}
#if DEBUG_SELECT_ENABLED
{
int i;
fprintf (stderr, "gpgme:select OK [ " );
for (i=0; i <= max_fd; i++ ) {
if (FD_ISSET (i, &readfds) )
fprintf (stderr, "r%d ", i );
if (FD_ISSET (i, &writefds) )
fprintf (stderr, "w%d ", i );
}
fprintf (stderr, "]\n" );
}
#endif
/* something has to be done. Go over the queue and call
* the handlers */
restart:
while ( n ) {
lock_queue ();
for ( q = wait_queue; q; q = q->next ) {
if ( q->used && q->active && q->inbound
&& FD_ISSET (q->fd, &readfds ) ) {
FD_CLR (q->fd, &readfds );
assert (n);
n--;
unlock_queue ();
if ( q->handler (q->handler_value, q->pid, q->fd ) )
q->active = 0;
goto restart;
}
if ( q->used && q->active && !q->inbound
&& FD_ISSET (q->fd, &writefds ) ) {
FD_CLR (q->fd, &writefds );
assert (n);
n--;
unlock_queue ();
if ( q->handler (q->handler_value, q->pid, q->fd ) )
q->active = 0;
goto restart;
}
}
unlock_queue ();
}
return 1;
}
/*
* called by rungpg.c to register something for select()
*/
GpgmeError
_gpgme_register_pipe_handler( void *opaque,
int (*handler)(void*,pid_t,int),
void *handler_value,
pid_t pid, int fd, int inbound )
{
GpgmeCtx ctx = opaque;
struct wait_queue_item_s *q;
init_wait_queue();
assert (opaque);
assert (handler);
lock_queue ();
for ( q = wait_queue; q; q = q->next ) {
if ( !q->used ) {
q->used = 1;
q->active = 0;
break;
}
}
unlock_queue ();
if ( !q )
return mk_error (Too_Many_Procs);
q->fd = fd;
q->inbound = inbound;
q->handler = handler;
q->handler_value = handler_value;
q->pid = pid;
q->ctx = ctx;
/* and enable this entry for the next select */
q->exited = 0;
q->active = 1;
return 0;
}

42
tags/V0-1-0/gpgme/wait.h Normal file
View File

@ -0,0 +1,42 @@
/* wait.h - definitions for wait.c
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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
*/
#ifndef WAIT_H
#define WAIT_H
#include "gpgme.h"
#define SIZEOF_WAIT_QUEUE 10
GpgmeError _gpgme_register_pipe_handler(
void *opaque,
int (*handler)(void*,pid_t,int),
void *handler_value,
pid_t pid, int fd, int inbound );
#endif /* WAIT_H */

View File

@ -0,0 +1,40 @@
## Process this file with automake to create Makefile.in
TESTS_ENVIRONMENT = GNUPGHOME=.
TESTS = t-encrypt t-sign t-decrypt t-verify t-keylist
EXTRA_DIST = mkdemodirs pubdemo.asc secdemo.asc cipher-1.asc geheim.txt
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl
INCLUDES =
LDADD = ../gpgme/libgpgme.la
noinst_PROGRAMS = $(TESTS)
distclean-local:
$(srcdir)/mkdemodirs --clean
all-local: ./pubring.gpg ./secring.gpg
./pubring.gpg: $(srcdir)/pubdemo.asc
-gpg --homedir . --import $(srcdir)/pubdemo.asc
./secring.gpg: ./Alpha/Secret.gpg
-gpg --homedir . --import Alpha/Secret.gpg Zulu/Secret.gpg
./Alpha/Secret.gpg: secdemo.asc
srcdir=$(srcdir) $(srcdir)/mkdemodirs

View File

@ -0,0 +1,15 @@
-----BEGIN PGP MESSAGE-----
Version: GnuPG v1.0.4-2 (GNU/Linux)
Comment: For info see http://www.gnupg.org
hQEOA2rm1+5GqHH4EAP/Tcqiuhvrjj+RFBKnWn2A7f1ztV17U2EngYFy8TbZYGNp
JoMNdpA7GNZs7iqc/x1epaZDKfaQwWEtARZmK/4nlhB48N+oZeKTm7PXIkRPqrCZ
3fxJjCJaU0yrNGuO345DOr0QwDImVhubVEkfgs8yXK2Szx2G8X3LmiaILHAqA2oD
/1ZqjY8k+ovrLL/qe8un/NTwzSjKIPVGR6mhLFXmj8fnp2kSsbo+Bhh4MczTRR6l
SA32z25vcakKu2qn5Wa4yDcx9NcMt8RHXzmfMDLj6UFq99QqKeLK2ywcIpY9p/GL
fQyaf7r3HTVugBSaoOzegLJ+L7MfWohrStkMeLnJQnro0nYBjADVcUQuSS4N3lst
Df3XrxxA/iJvxt4F9K27u4tp5U1HDg1CIxVrkMs92LBri3S6ZtfjdoqQ7QghFwGP
Kw1lKiWayM6NH9rcCKSgk4kl4P/2l3f78XeFgiywN7UGeSoH3BLMSv9gSxl5KrAz
d2imhTMrfEvZ
=y4ng
-----END PGP MESSAGE-----

View File

@ -0,0 +1,2 @@
Wenn Sie dies lesen können, ist es wohl nicht
geheim genug.

44
tags/V0-1-0/tests/mkdemodirs Executable file
View File

@ -0,0 +1,44 @@
#!/bin/sh
set -e
GPG="gpg --batch --quiet --no-secmem-warning"
NAMES='Alpha Bravo Charlie Delta Echo Foxtrot Golf Hotel India
Juliet Kilo Lima Mike November Oscar Papa Quebec Romeo
Sierra Tango Uniform Victor Whisky XRay Yankee Zulu'
if [ "$1" = "--clean" ]; then
(for i in $NAMES; do
[ -d $i ] && rm -r $i
done) || true
exit 0
fi
[ -z "$srcdir" ] && srcdir="../tests"
$GPG --dearmor -o secdemo.gpg --yes $srcdir/secdemo.asc
$GPG --dearmor -o pubdemo.gpg --yes $srcdir/pubdemo.asc
[ -f ./tdb.tmp ] && rm ./tdb.tmp
GPGDEMO="$GPG --homedir . --trustdb-name ./tdb.tmp --no-default-keyring
--keyring pubdemo.gpg --secret-keyring secdemo.gpg"
echo -n "Creating:"
for name in $NAMES; do
echo -n " $name"
[ -d $name ] && rm -r $name
mkdir $name
$GPGDEMO --export-secret-key -o - $name > $name/Secret.gpg
$GPG --homedir $name --import $name/Secret.gpg
$GPGDEMO --export -o - $name > $name/Public.gpg
$GPG --homedir $name --import $name/Public.gpg
[ -f $name/pubring.gpg~ ] && rm $name/pubring.gpg~
done
echo "."
[ -f ./tdb.tmp ] && rm ./tdb.tmp
rm pubdemo.gpg secdemo.gpg

View File

@ -0,0 +1,121 @@
/* t-encrypt.c - regression test
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include "../gpgme/gpgme.h"
#define fail_if_err(a) do { if(a) { int my_errno = errno; \
fprintf (stderr, "%s:%d: GpgmeError %s\n", \
__FILE__, __LINE__, gpgme_strerror(a)); \
if ((a) == GPGME_File_Error) \
fprintf (stderr, "\terrno=`%s'\n", strerror (my_errno)); \
exit (1); } \
} while(0)
static void
print_data ( GpgmeData dh )
{
char buf[100];
size_t nread;
GpgmeError err;
err = gpgme_data_rewind ( dh );
fail_if_err (err);
while ( !(err = gpgme_data_read ( dh, buf, 100, &nread )) ) {
fwrite ( buf, nread, 1, stdout );
}
if (err != GPGME_EOF)
fail_if_err (err);
}
#if 0
static GpgmeData
passphrase_cb ( void *opaque, const char *description )
{
GpgmeData dh;
assert (NULL);
gpgme_data_new_from_mem ( &dh, "abc", 3, 0 );
return dh;
}
#endif
static char *
mk_fname ( const char *fname )
{
const char *srcdir = getenv ("srcdir");
char *buf;
if (!srcdir)
srcdir = ".";
buf = malloc (strlen(srcdir) + strlen(fname) + 2 );
if (!buf )
exit (8);
strcpy (buf, srcdir);
strcat (buf, "/");
strcat (buf, fname );
return buf;
}
int
main (int argc, char **argv )
{
GpgmeCtx ctx;
GpgmeError err;
GpgmeData in, out;
const char *cipher_1_asc = mk_fname ("cipher-1.asc");
do {
err = gpgme_new (&ctx);
fail_if_err (err);
#if 0
if ( !getenv("GPG_AGENT_INFO") {
gpgme_set_passphrase_cb ( ctx, passphrase_cb, NULL );
}
#endif
err = gpgme_data_new_from_file ( &in, cipher_1_asc, 1 );
fail_if_err (err);
err = gpgme_data_new ( &out );
fail_if_err (err);
err = gpgme_op_decrypt (ctx, in, out );
fail_if_err (err);
fflush (NULL);
fputs ("Begin Result:\n", stdout );
print_data (out);
fputs ("End Result.\n", stdout );
gpgme_data_release (in);
gpgme_data_release (out);
gpgme_release (ctx);
} while ( argc > 1 && !strcmp( argv[1], "--loop" ) );
return 0;
}

View File

@ -0,0 +1,95 @@
/* t-encrypt.c - regression test
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "../gpgme/gpgme.h"
#define fail_if_err(a) do { if(a) { \
fprintf (stderr, "%s:%d: GpgmeError %s\n", \
__FILE__, __LINE__, gpgme_strerror(a)); \
exit (1); } \
} while(0)
static void
print_data ( GpgmeData dh )
{
char buf[100];
size_t nread;
GpgmeError err;
err = gpgme_data_rewind ( dh );
fail_if_err (err);
while ( !(err = gpgme_data_read ( dh, buf, 100, &nread )) ) {
fwrite ( buf, nread, 1, stdout );
}
if (err != GPGME_EOF)
fail_if_err (err);
}
int
main (int argc, char **argv )
{
GpgmeCtx ctx;
GpgmeError err;
GpgmeData in, out;
GpgmeRecipients rset;
do {
err = gpgme_new (&ctx);
fail_if_err (err);
err = gpgme_data_new_from_mem ( &in, "Hallo Leute\n", 12, 0 );
fail_if_err (err);
err = gpgme_data_new ( &out );
fail_if_err (err);
err = gpgme_recipients_new (&rset);
fail_if_err (err);
err = gpgme_recipients_add_name (rset, "Bob");
fail_if_err (err);
err = gpgme_recipients_add_name (rset, "Alpha");
fail_if_err (err);
err = gpgme_op_encrypt (ctx, rset, in, out );
fail_if_err (err);
fflush (NULL);
fputs ("Begin Result:\n", stdout );
print_data (out);
fputs ("End Result.\n", stdout );
gpgme_recipients_release (rset);
gpgme_data_release (in);
gpgme_data_release (out);
gpgme_release (ctx);
} while ( argc > 1 && !strcmp( argv[1], "--loop" ) );
return 0;
}

View File

@ -0,0 +1,87 @@
/* t-keylist.c - regression test
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "../gpgme/gpgme.h"
#define fail_if_err(a) do { if(a) { \
fprintf (stderr, "%s:%d: GpgmeError %s\n", \
__FILE__, __LINE__, gpgme_strerror(a)); \
exit (1); } \
} while(0)
static void
doit ( GpgmeCtx ctx, const char *pattern )
{
GpgmeError err;
GpgmeKey key;
err = gpgme_op_keylist_start (ctx, pattern, 0 );
fail_if_err (err);
while ( !(err = gpgme_op_keylist_next ( ctx, &key )) ) {
char *p;
printf ("<!-- Begin key object (%p) -->\n", key );
p = gpgme_key_get_as_xml ( key );
if ( p )
fputs ( p, stdout );
else
fputs("<!-- Ooops: gpgme_key_get_as_xml failed -->\n", stdout );
printf ("<!-- End key object (%p) -->\n", key );
}
if ( err != GPGME_EOF )
fail_if_err (err);
}
int
main (int argc, char **argv )
{
GpgmeCtx ctx;
GpgmeError err;
int loop = 0;
const char *pattern;
if( argc ) {
argc--; argv++;
}
if (argc && !strcmp( *argv, "--loop" ) ) {
loop = 1;
argc--; argv++;
}
pattern = argc? *argv : NULL;
err = gpgme_new (&ctx);
fail_if_err (err);
do {
doit ( ctx, pattern );
} while ( loop );
gpgme_release (ctx);
return 0;
}

View File

@ -0,0 +1,89 @@
/* t-sign.c - regression test
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "../gpgme/gpgme.h"
#define fail_if_err(a) do { if(a) { \
fprintf (stderr, "%s:%d: GpgmeError %s\n", \
__FILE__, __LINE__, gpgme_strerror(a)); \
exit (1); } \
} while(0)
static void
print_data ( GpgmeData dh )
{
char buf[100];
size_t nread;
GpgmeError err;
err = gpgme_data_rewind ( dh );
fail_if_err (err);
while ( !(err = gpgme_data_read ( dh, buf, 100, &nread )) ) {
fwrite ( buf, nread, 1, stdout );
}
if (err != GPGME_EOF)
fail_if_err (err);
}
int
main (int argc, char **argv )
{
GpgmeCtx ctx;
GpgmeError err;
GpgmeData in, out;
do {
err = gpgme_new (&ctx);
fail_if_err (err);
err = gpgme_data_new_from_mem ( &in, "Hallo Leute\n", 12, 0 );
fail_if_err (err);
err = gpgme_data_new ( &out );
fail_if_err (err);
gpgme_set_textmode (ctx, 1);
gpgme_set_armor (ctx, 1);
err = gpgme_op_sign (ctx, in, out );
fail_if_err (err);
fflush (NULL);
fputs ("Begin Result:\n", stdout );
print_data (out);
fputs ("End Result.\n", stdout );
gpgme_data_release (in);
gpgme_data_release (out);
gpgme_release (ctx);
} while ( argc > 1 && !strcmp( argv[1], "--loop" ) );
return 0;
}

View File

@ -0,0 +1,144 @@
/* t-verify.c - regression test
* Copyright (C) 2000 Werner Koch (dd9jn)
*
* This file is part of GPGME.
*
* GPGME 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.
*
* GPGME 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "../gpgme/gpgme.h"
static const char test_text1[] = "Just GNU it!\n";
static const char test_text1f[]= "Just GNU it?\n";
static const char test_sig1[] =
#if 0
"-----BEGIN PGP SIGNATURE-----\n"
"\n"
"iEYEABECAAYFAjoKgjIACgkQLXJ8x2hpdzQMSwCeO/xUrhysZ7zJKPf/FyXA//u1\n"
"ZgIAn0204PBR7yxSdQx6CFxugstNqmRv\n"
"=yku6\n"
"-----END PGP SIGNATURE-----\n"
#elif 0
"-----BEGIN PGP SIGNATURE-----\n"
"Version: GnuPG v1.0.4-2 (GNU/Linux)\n"
"Comment: For info see http://www.gnupg.org\n"
"\n"
"iJcEABECAFcFAjoS8/E1FIAAAAAACAAkZm9vYmFyLjF0aGlzIGlzIGEgbm90YXRp\n"
"b24gZGF0YSB3aXRoIDIgbGluZXMaGmh0dHA6Ly93d3cuZ3Uub3JnL3BvbGljeS8A\n"
"CgkQLXJ8x2hpdzQLyQCbBW/fgU8ZeWSlWPM1F8umHX17bAAAoIfSNDSp5zM85XcG\n"
"iwxMrf+u8v4r\n"
"=88Zo\n"
"-----END PGP SIGNATURE-----\n"
#elif 1
"-----BEGIN PGP SIGNATURE-----\n"
"\n"
"iN0EABECAJ0FAjoS+i9FFIAAAAAAAwA5YmFyw7bDpMO8w58gZGFzIHdhcmVuIFVt\n"
"bGF1dGUgdW5kIGpldHp0IGVpbiBwcm96ZW50JS1aZWljaGVuNRSAAAAAAAgAJGZv\n"
"b2Jhci4xdGhpcyBpcyBhIG5vdGF0aW9uIGRhdGEgd2l0aCAyIGxpbmVzGhpodHRw\n"
"Oi8vd3d3Lmd1Lm9yZy9wb2xpY3kvAAoJEC1yfMdoaXc0JBIAoIiLlUsvpMDOyGEc\n"
"dADGKXF/Hcb+AKCJWPphZCphduxSvrzH0hgzHdeQaA==\n"
"=nts1\n"
"-----END PGP SIGNATURE-----\n"
#endif
;
#define fail_if_err(a) do { if(a) { \
fprintf (stderr, "%s:%d: GpgmeError %s\n", \
__FILE__, __LINE__, gpgme_strerror(a)); \
exit (1); } \
} while(0)
static void
print_sig_stat ( GpgmeSigStat status )
{
switch ( status ) {
case GPGME_SIG_STAT_NONE:
fputs ("Verification Status: None\n", stdout);
break;
case GPGME_SIG_STAT_NOSIG:
fputs ("Verification Status: No Signature\n", stdout);
break;
case GPGME_SIG_STAT_GOOD:
fputs ("Verification Status: Good\n", stdout);
break;
case GPGME_SIG_STAT_BAD:
fputs ("Verification Status: Bad\n", stdout);
break;
case GPGME_SIG_STAT_NOKEY:
fputs ("Verification Status: No Key\n", stdout);
break;
case GPGME_SIG_STAT_ERROR:
fputs ("Verification Status: Error\n", stdout);
break;
}
}
int
main (int argc, char **argv )
{
GpgmeCtx ctx;
GpgmeError err;
GpgmeData sig, text;
GpgmeSigStat status;
char *nota;
err = gpgme_new (&ctx);
fail_if_err (err);
do {
err = gpgme_data_new_from_mem ( &text,
test_text1, strlen (test_text1), 0 );
fail_if_err (err);
err = gpgme_data_new_from_mem ( &sig,
test_sig1, strlen (test_sig1), 0 );
fail_if_err (err);
puts ("checking a valid message:\n");
err = gpgme_op_verify (ctx, sig, text, &status );
print_sig_stat ( status );
fail_if_err (err);
if ( (nota=gpgme_get_notation (ctx)) )
printf ("---Begin Notation---\n%s---End Notation---\n", nota );
puts ("checking a manipulated message:\n");
gpgme_data_release (text);
err = gpgme_data_new_from_mem ( &text,
test_text1f, strlen (test_text1f), 0 );
fail_if_err (err);
gpgme_data_rewind ( sig );
err = gpgme_op_verify (ctx, sig, text, &status );
print_sig_stat ( status );
fail_if_err (err);
if ( (nota=gpgme_get_notation (ctx)) )
printf ("---Begin Notation---\n%s---End Notation---\n", nota );
gpgme_data_release (sig);
gpgme_data_release (text);
} while ( argc > 1 && !strcmp( argv[1], "--loop" ) );
gpgme_release (ctx);
return 0;
}