1998-04-07 18:16:10 +00:00
|
|
|
/* misc.c - miscellaneous functions
|
2005-08-21 20:58:46 +00:00
|
|
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
|
|
|
* 2005 Free Software Foundation, Inc.
|
1998-04-07 18:16:10 +00:00
|
|
|
*
|
1998-12-23 12:41:40 +00:00
|
|
|
* This file is part of GnuPG.
|
1998-04-07 18:16:10 +00:00
|
|
|
*
|
1998-12-23 12:41:40 +00:00
|
|
|
* GnuPG is free software; you can redistribute it and/or modify
|
1998-04-07 18:16:10 +00:00
|
|
|
* 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.
|
|
|
|
*
|
1998-12-23 12:41:40 +00:00
|
|
|
* GnuPG is distributed in the hope that it will be useful,
|
1998-04-07 18:16:10 +00:00
|
|
|
* 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
|
2005-05-31 08:39:18 +00:00
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
|
|
|
* USA.
|
1998-04-07 18:16:10 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2002-06-29 13:46:34 +00:00
|
|
|
#include <unistd.h>
|
1998-07-14 17:10:28 +00:00
|
|
|
#include <errno.h>
|
1998-12-17 17:36:05 +00:00
|
|
|
#if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
|
* armor.c, g10.c, kbnode.c, misc.c, pkclist.c, sign.c, build-packet.c,
getkey.c, keydb.c, openfile.c, plaintext.c, status.c, gpgv.c, keygen.c,
options.h, sig-check.c, tdbio.h, encode.c, mainproc.c, parse-packet.c,
signal.c, textfilter.c: Edit all preprocessor instructions to remove
whitespace before the '#'. This is not required by C89, but there are some
compilers out there that don't like it.
2003-05-24 21:50:33 +00:00
|
|
|
#include <asm/sysinfo.h>
|
|
|
|
#include <asm/unistd.h>
|
1998-05-15 18:49:19 +00:00
|
|
|
#endif
|
1998-07-14 17:10:28 +00:00
|
|
|
#ifdef HAVE_SETRLIMIT
|
* armor.c, g10.c, kbnode.c, misc.c, pkclist.c, sign.c, build-packet.c,
getkey.c, keydb.c, openfile.c, plaintext.c, status.c, gpgv.c, keygen.c,
options.h, sig-check.c, tdbio.h, encode.c, mainproc.c, parse-packet.c,
signal.c, textfilter.c: Edit all preprocessor instructions to remove
whitespace before the '#'. This is not required by C89, but there are some
compilers out there that don't like it.
2003-05-24 21:50:33 +00:00
|
|
|
#include <time.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/resource.h>
|
1998-07-14 17:10:28 +00:00
|
|
|
#endif
|
2004-10-13 18:10:06 +00:00
|
|
|
#ifdef ENABLE_SELINUX_HACKS
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#endif
|
2004-11-03 20:03:46 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
#include <time.h>
|
|
|
|
#include <process.h>
|
2005-01-20 11:42:03 +00:00
|
|
|
#include <windows.h>
|
|
|
|
#include <shlobj.h>
|
|
|
|
#ifndef CSIDL_APPDATA
|
|
|
|
#define CSIDL_APPDATA 0x001a
|
2004-11-03 20:03:46 +00:00
|
|
|
#endif
|
2005-01-20 11:42:03 +00:00
|
|
|
#ifndef CSIDL_LOCAL_APPDATA
|
|
|
|
#define CSIDL_LOCAL_APPDATA 0x001c
|
|
|
|
#endif
|
|
|
|
#ifndef CSIDL_FLAG_CREATE
|
|
|
|
#define CSIDL_FLAG_CREATE 0x8000
|
|
|
|
#endif
|
2005-02-15 11:02:32 +00:00
|
|
|
#include "errors.h"
|
|
|
|
#include "dynload.h"
|
2005-01-20 11:42:03 +00:00
|
|
|
#endif /*_WIN32*/
|
|
|
|
|
1998-04-07 18:16:10 +00:00
|
|
|
#include "util.h"
|
|
|
|
#include "main.h"
|
2002-06-29 13:46:34 +00:00
|
|
|
#include "photoid.h"
|
1998-06-15 15:41:04 +00:00
|
|
|
#include "options.h"
|
1998-11-10 12:59:59 +00:00
|
|
|
#include "i18n.h"
|
2004-09-15 18:41:36 +00:00
|
|
|
#include "cardglue.h"
|
1998-04-07 18:16:10 +00:00
|
|
|
|
2004-10-13 18:10:06 +00:00
|
|
|
|
2005-01-20 11:42:03 +00:00
|
|
|
|
|
|
|
|
2004-10-13 18:10:06 +00:00
|
|
|
#ifdef ENABLE_SELINUX_HACKS
|
|
|
|
/* A object and a global variable to keep track of files marked as
|
|
|
|
secured. */
|
|
|
|
struct secured_file_item
|
|
|
|
{
|
|
|
|
struct secured_file_item *next;
|
|
|
|
ino_t ino;
|
|
|
|
dev_t dev;
|
|
|
|
};
|
|
|
|
static struct secured_file_item *secured_files;
|
|
|
|
#endif /*ENABLE_SELINUX_HACKS*/
|
|
|
|
|
|
|
|
|
|
|
|
|
1998-12-17 17:36:05 +00:00
|
|
|
#if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
|
1998-05-15 18:49:19 +00:00
|
|
|
static int
|
|
|
|
setsysinfo(unsigned long op, void *buffer, unsigned long size,
|
|
|
|
int *start, void *arg, unsigned long flag)
|
|
|
|
{
|
|
|
|
return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
trap_unaligned(void)
|
|
|
|
{
|
|
|
|
unsigned int buf[2];
|
|
|
|
|
|
|
|
buf[0] = SSIN_UACPROC;
|
|
|
|
buf[1] = UAC_SIGBUS | UAC_NOPRINT;
|
|
|
|
setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
void
|
|
|
|
trap_unaligned(void)
|
|
|
|
{ /* dummy */
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2000-09-18 14:35:34 +00:00
|
|
|
int
|
1998-07-14 17:10:28 +00:00
|
|
|
disable_core_dumps()
|
|
|
|
{
|
* armor.c, g10.c, kbnode.c, misc.c, pkclist.c, sign.c, build-packet.c,
getkey.c, keydb.c, openfile.c, plaintext.c, status.c, gpgv.c, keygen.c,
options.h, sig-check.c, tdbio.h, encode.c, mainproc.c, parse-packet.c,
signal.c, textfilter.c: Edit all preprocessor instructions to remove
whitespace before the '#'. This is not required by C89, but there are some
compilers out there that don't like it.
2003-05-24 21:50:33 +00:00
|
|
|
#ifdef HAVE_DOSISH_SYSTEM
|
2000-09-18 14:35:34 +00:00
|
|
|
return 0;
|
* armor.c, g10.c, kbnode.c, misc.c, pkclist.c, sign.c, build-packet.c,
getkey.c, keydb.c, openfile.c, plaintext.c, status.c, gpgv.c, keygen.c,
options.h, sig-check.c, tdbio.h, encode.c, mainproc.c, parse-packet.c,
signal.c, textfilter.c: Edit all preprocessor instructions to remove
whitespace before the '#'. This is not required by C89, but there are some
compilers out there that don't like it.
2003-05-24 21:50:33 +00:00
|
|
|
#else
|
|
|
|
#ifdef HAVE_SETRLIMIT
|
1998-07-14 17:10:28 +00:00
|
|
|
struct rlimit limit;
|
|
|
|
|
|
|
|
limit.rlim_cur = 0;
|
|
|
|
limit.rlim_max = 0;
|
1998-12-29 13:47:31 +00:00
|
|
|
if( !setrlimit( RLIMIT_CORE, &limit ) )
|
2000-09-18 14:35:34 +00:00
|
|
|
return 0;
|
|
|
|
if( errno != EINVAL && errno != ENOSYS )
|
1998-11-10 12:59:59 +00:00
|
|
|
log_fatal(_("can't disable core dumps: %s\n"), strerror(errno) );
|
* armor.c, g10.c, kbnode.c, misc.c, pkclist.c, sign.c, build-packet.c,
getkey.c, keydb.c, openfile.c, plaintext.c, status.c, gpgv.c, keygen.c,
options.h, sig-check.c, tdbio.h, encode.c, mainproc.c, parse-packet.c,
signal.c, textfilter.c: Edit all preprocessor instructions to remove
whitespace before the '#'. This is not required by C89, but there are some
compilers out there that don't like it.
2003-05-24 21:50:33 +00:00
|
|
|
#endif
|
2000-09-18 14:35:34 +00:00
|
|
|
return 1;
|
* armor.c, g10.c, kbnode.c, misc.c, pkclist.c, sign.c, build-packet.c,
getkey.c, keydb.c, openfile.c, plaintext.c, status.c, gpgv.c, keygen.c,
options.h, sig-check.c, tdbio.h, encode.c, mainproc.c, parse-packet.c,
signal.c, textfilter.c: Edit all preprocessor instructions to remove
whitespace before the '#'. This is not required by C89, but there are some
compilers out there that don't like it.
2003-05-24 21:50:33 +00:00
|
|
|
#endif
|
1998-07-14 17:10:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-10-13 18:10:06 +00:00
|
|
|
/* For the sake of SELinux we want to restrict access through gpg to
|
|
|
|
certain files we keep under our own control. This function
|
|
|
|
registers such a file and is_secured_file may then be used to
|
|
|
|
check whether a file has ben registered as secured. */
|
|
|
|
void
|
|
|
|
register_secured_file (const char *fname)
|
|
|
|
{
|
|
|
|
#ifdef ENABLE_SELINUX_HACKS
|
|
|
|
struct stat buf;
|
|
|
|
struct secured_file_item *sf;
|
|
|
|
|
|
|
|
/* Note that we stop immediatley if something goes wrong here. */
|
|
|
|
if (stat (fname, &buf))
|
|
|
|
log_fatal (_("fstat of `%s' failed in %s: %s\n"), fname,
|
|
|
|
"register_secured_file", strerror (errno));
|
|
|
|
/* log_debug ("registering `%s' i=%lu.%lu\n", fname, */
|
|
|
|
/* (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
|
|
|
|
for (sf=secured_files; sf; sf = sf->next)
|
|
|
|
{
|
|
|
|
if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
|
|
|
|
return; /* Already registered. */
|
|
|
|
}
|
|
|
|
|
|
|
|
sf = xmalloc (sizeof *sf);
|
|
|
|
sf->ino = buf.st_ino;
|
|
|
|
sf->dev = buf.st_dev;
|
|
|
|
sf->next = secured_files;
|
|
|
|
secured_files = sf;
|
|
|
|
#endif /*ENABLE_SELINUX_HACKS*/
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Remove a file registerd as secure. */
|
|
|
|
void
|
|
|
|
unregister_secured_file (const char *fname)
|
|
|
|
{
|
|
|
|
#ifdef ENABLE_SELINUX_HACKS
|
|
|
|
struct stat buf;
|
|
|
|
struct secured_file_item *sf, *sfprev;
|
|
|
|
|
|
|
|
if (stat (fname, &buf))
|
|
|
|
{
|
|
|
|
log_error (_("fstat of `%s' failed in %s: %s\n"), fname,
|
|
|
|
"unregister_secured_file", strerror (errno));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
/* log_debug ("unregistering `%s' i=%lu.%lu\n", fname, */
|
|
|
|
/* (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
|
|
|
|
for (sfprev=NULL,sf=secured_files; sf; sfprev=sf, sf = sf->next)
|
|
|
|
{
|
|
|
|
if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
|
|
|
|
{
|
|
|
|
if (sfprev)
|
|
|
|
sfprev->next = sf->next;
|
|
|
|
else
|
|
|
|
secured_files = sf->next;
|
|
|
|
xfree (sf);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /*ENABLE_SELINUX_HACKS*/
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return true if FD is corresponds to a secured file. Using -1 for
|
|
|
|
FS is allowed and will return false. */
|
|
|
|
int
|
|
|
|
is_secured_file (int fd)
|
|
|
|
{
|
|
|
|
#ifdef ENABLE_SELINUX_HACKS
|
|
|
|
struct stat buf;
|
|
|
|
struct secured_file_item *sf;
|
|
|
|
|
|
|
|
if (fd == -1)
|
|
|
|
return 0; /* No file descriptor so it can't be secured either. */
|
|
|
|
|
|
|
|
/* Note that we print out a error here and claim that a file is
|
|
|
|
secure if something went wrong. */
|
|
|
|
if (fstat (fd, &buf))
|
|
|
|
{
|
|
|
|
log_error (_("fstat(%d) failed in %s: %s\n"), fd,
|
|
|
|
"is_secured_file", strerror (errno));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
/* log_debug ("is_secured_file (%d) i=%lu.%lu\n", fd, */
|
|
|
|
/* (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
|
|
|
|
for (sf=secured_files; sf; sf = sf->next)
|
|
|
|
{
|
|
|
|
if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
|
|
|
|
return 1; /* Yes. */
|
|
|
|
}
|
|
|
|
#endif /*ENABLE_SELINUX_HACKS*/
|
|
|
|
return 0; /* No. */
|
|
|
|
}
|
|
|
|
|
2004-10-14 07:11:57 +00:00
|
|
|
/* Return true if FNAME is corresponds to a secured file. Using NULL,
|
|
|
|
"" or "-" for FS is allowed and will return false. This function is
|
|
|
|
used before creating a file, thus it won't fail if the file does
|
|
|
|
not exist. */
|
|
|
|
int
|
|
|
|
is_secured_filename (const char *fname)
|
|
|
|
{
|
|
|
|
#ifdef ENABLE_SELINUX_HACKS
|
|
|
|
struct stat buf;
|
|
|
|
struct secured_file_item *sf;
|
|
|
|
|
|
|
|
if (iobuf_is_pipe_filename (fname) || !*fname)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* Note that we print out a error here and claim that a file is
|
|
|
|
secure if something went wrong. */
|
|
|
|
if (stat (fname, &buf))
|
|
|
|
{
|
|
|
|
if (errno == ENOENT || errno == EPERM || errno == EACCES)
|
|
|
|
return 0;
|
|
|
|
log_error (_("fstat of `%s' failed in %s: %s\n"), fname,
|
|
|
|
"is_secured_filename", strerror (errno));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
/* log_debug ("is_secured_filename (%s) i=%lu.%lu\n", fname, */
|
|
|
|
/* (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
|
|
|
|
for (sf=secured_files; sf; sf = sf->next)
|
|
|
|
{
|
|
|
|
if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
|
|
|
|
return 1; /* Yes. */
|
|
|
|
}
|
|
|
|
#endif /*ENABLE_SELINUX_HACKS*/
|
|
|
|
return 0; /* No. */
|
|
|
|
}
|
|
|
|
|
2004-10-13 18:10:06 +00:00
|
|
|
|
1998-07-14 17:10:28 +00:00
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
u16
|
|
|
|
checksum_u16( unsigned n )
|
1999-12-08 21:03:03 +00:00
|
|
|
{
|
2002-06-29 13:46:34 +00:00
|
|
|
u16 a;
|
1999-12-08 21:03:03 +00:00
|
|
|
|
1998-06-15 15:41:04 +00:00
|
|
|
a = (n >> 8) & 0xff;
|
|
|
|
a += n & 0xff;
|
1998-04-07 18:16:10 +00:00
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
2002-09-11 07:27:54 +00:00
|
|
|
|
1998-04-07 18:16:10 +00:00
|
|
|
u16
|
|
|
|
checksum( byte *p, unsigned n )
|
|
|
|
{
|
|
|
|
u16 a;
|
|
|
|
|
|
|
|
for(a=0; n; n-- )
|
|
|
|
a += *p++;
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
u16
|
|
|
|
checksum_mpi( MPI a )
|
|
|
|
{
|
|
|
|
u16 csum;
|
|
|
|
byte *buffer;
|
2002-06-29 13:46:34 +00:00
|
|
|
unsigned nbytes;
|
|
|
|
unsigned nbits;
|
|
|
|
|
|
|
|
buffer = mpi_get_buffer( a, &nbytes, NULL );
|
|
|
|
nbits = mpi_get_nbits(a);
|
2002-09-11 07:27:54 +00:00
|
|
|
csum = checksum_u16( nbits );
|
2002-06-29 13:46:34 +00:00
|
|
|
csum += checksum( buffer, nbytes );
|
2005-07-27 18:10:56 +00:00
|
|
|
xfree( buffer );
|
1998-04-07 18:16:10 +00:00
|
|
|
return csum;
|
|
|
|
}
|
|
|
|
|
1998-06-25 10:19:08 +00:00
|
|
|
u32
|
|
|
|
buffer_to_u32( const byte *buffer )
|
|
|
|
{
|
|
|
|
unsigned long a;
|
|
|
|
a = *buffer << 24;
|
|
|
|
a |= buffer[1] << 16;
|
|
|
|
a |= buffer[2] << 8;
|
|
|
|
a |= buffer[3];
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
1998-12-10 19:20:47 +00:00
|
|
|
void
|
|
|
|
print_pubkey_algo_note( int algo )
|
|
|
|
{
|
2004-11-03 20:35:28 +00:00
|
|
|
if(algo >= 100 && algo <= 110)
|
|
|
|
{
|
|
|
|
static int warn=0;
|
|
|
|
if(!warn)
|
|
|
|
{
|
|
|
|
warn=1;
|
|
|
|
log_info(_("WARNING: using experimental public key algorithm %s\n"),
|
|
|
|
pubkey_algo_to_string(algo));
|
|
|
|
}
|
|
|
|
}
|
1998-12-10 19:20:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
print_cipher_algo_note( int algo )
|
|
|
|
{
|
2004-11-03 20:35:28 +00:00
|
|
|
if(algo >= 100 && algo <= 110)
|
|
|
|
{
|
|
|
|
static int warn=0;
|
|
|
|
if(!warn)
|
|
|
|
{
|
|
|
|
warn=1;
|
|
|
|
log_info(_("WARNING: using experimental cipher algorithm %s\n"),
|
|
|
|
cipher_algo_to_string(algo));
|
1998-12-10 19:20:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
print_digest_algo_note( int algo )
|
|
|
|
{
|
2004-11-03 20:35:28 +00:00
|
|
|
if(algo >= 100 && algo <= 110)
|
|
|
|
{
|
|
|
|
static int warn=0;
|
|
|
|
if(!warn)
|
|
|
|
{
|
|
|
|
warn=1;
|
|
|
|
log_info(_("WARNING: using experimental digest algorithm %s\n"),
|
|
|
|
digest_algo_to_string(algo));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(algo==DIGEST_ALGO_MD5)
|
|
|
|
log_info(_("WARNING: digest algorithm %s is deprecated\n"),
|
|
|
|
digest_algo_to_string(algo));
|
1998-12-10 19:20:47 +00:00
|
|
|
}
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
/* Return a string which is used as a kind of process ID */
|
|
|
|
const byte *
|
|
|
|
get_session_marker( size_t *rlen )
|
|
|
|
{
|
|
|
|
static byte marker[SIZEOF_UNSIGNED_LONG*2];
|
|
|
|
static int initialized;
|
|
|
|
|
|
|
|
if ( !initialized ) {
|
|
|
|
volatile ulong aa, bb; /* we really want the uninitialized value */
|
|
|
|
ulong a, b;
|
|
|
|
|
|
|
|
initialized = 1;
|
|
|
|
/* also this marker is guessable it is not easy to use this
|
|
|
|
* for a faked control packet because an attacker does not
|
|
|
|
* have enough control about the time the verification does
|
|
|
|
* take place. Of course, we can add just more random but
|
|
|
|
* than we need the random generator even for verification
|
|
|
|
* tasks - which does not make sense. */
|
|
|
|
a = aa ^ (ulong)getpid();
|
|
|
|
b = bb ^ (ulong)time(NULL);
|
|
|
|
memcpy( marker, &a, SIZEOF_UNSIGNED_LONG );
|
|
|
|
memcpy( marker+SIZEOF_UNSIGNED_LONG, &b, SIZEOF_UNSIGNED_LONG );
|
|
|
|
}
|
|
|
|
*rlen = sizeof(marker);
|
|
|
|
return marker;
|
|
|
|
}
|
2000-07-14 17:34:53 +00:00
|
|
|
|
1999-10-26 12:14:37 +00:00
|
|
|
/****************
|
|
|
|
* Wrapper around the libgcrypt function with addional checks on
|
2000-09-18 14:35:34 +00:00
|
|
|
* openPGP contraints for the algo ID.
|
1999-10-26 12:14:37 +00:00
|
|
|
*/
|
|
|
|
int
|
|
|
|
openpgp_cipher_test_algo( int algo )
|
|
|
|
{
|
|
|
|
if( algo < 0 || algo > 110 )
|
2002-06-29 13:46:34 +00:00
|
|
|
return G10ERR_CIPHER_ALGO;
|
|
|
|
return check_cipher_algo(algo);
|
1999-10-26 12:14:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
1999-11-13 16:43:23 +00:00
|
|
|
openpgp_pk_test_algo( int algo, unsigned int usage_flags )
|
1999-10-26 12:14:37 +00:00
|
|
|
{
|
|
|
|
if( algo < 0 || algo > 110 )
|
2002-06-29 13:46:34 +00:00
|
|
|
return G10ERR_PUBKEY_ALGO;
|
|
|
|
return check_pubkey_algo2( algo, usage_flags );
|
1999-10-26 12:14:37 +00:00
|
|
|
}
|
|
|
|
|
2000-09-18 14:35:34 +00:00
|
|
|
int
|
|
|
|
openpgp_pk_algo_usage ( int algo )
|
|
|
|
{
|
2002-06-29 13:46:34 +00:00
|
|
|
int use = 0;
|
2000-09-18 14:35:34 +00:00
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
/* they are hardwired in gpg 1.0 */
|
2000-09-18 14:35:34 +00:00
|
|
|
switch ( algo ) {
|
2002-06-29 13:46:34 +00:00
|
|
|
case PUBKEY_ALGO_RSA:
|
2005-08-27 03:09:40 +00:00
|
|
|
use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH;
|
2000-09-18 14:35:34 +00:00
|
|
|
break;
|
2002-06-29 13:46:34 +00:00
|
|
|
case PUBKEY_ALGO_RSA_E:
|
|
|
|
use = PUBKEY_USAGE_ENC;
|
2000-09-18 14:35:34 +00:00
|
|
|
break;
|
2002-06-29 13:46:34 +00:00
|
|
|
case PUBKEY_ALGO_RSA_S:
|
2005-08-27 03:09:40 +00:00
|
|
|
use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG;
|
2000-09-18 14:35:34 +00:00
|
|
|
break;
|
2002-06-29 13:46:34 +00:00
|
|
|
case PUBKEY_ALGO_ELGAMAL_E:
|
|
|
|
use = PUBKEY_USAGE_ENC;
|
2000-09-18 14:35:34 +00:00
|
|
|
break;
|
2002-06-29 13:46:34 +00:00
|
|
|
case PUBKEY_ALGO_DSA:
|
2005-08-27 03:09:40 +00:00
|
|
|
use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
|
2000-09-18 14:35:34 +00:00
|
|
|
break;
|
|
|
|
default:
|
2002-06-29 13:46:34 +00:00
|
|
|
break;
|
2000-09-18 14:35:34 +00:00
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
return use;
|
2000-09-18 14:35:34 +00:00
|
|
|
}
|
|
|
|
|
1999-10-26 12:14:37 +00:00
|
|
|
int
|
|
|
|
openpgp_md_test_algo( int algo )
|
|
|
|
{
|
|
|
|
if( algo < 0 || algo > 110 )
|
2002-06-29 13:46:34 +00:00
|
|
|
return G10ERR_DIGEST_ALGO;
|
|
|
|
return check_digest_algo(algo);
|
1999-10-26 12:14:37 +00:00
|
|
|
}
|
|
|
|
|
2003-02-22 13:00:18 +00:00
|
|
|
#ifdef USE_IDEA
|
2002-06-29 13:46:34 +00:00
|
|
|
/* Special warning for the IDEA cipher */
|
|
|
|
void
|
|
|
|
idea_cipher_warn(int show)
|
1999-11-13 16:43:23 +00:00
|
|
|
{
|
2002-06-29 13:46:34 +00:00
|
|
|
static int warned=0;
|
|
|
|
|
|
|
|
if(!warned || show)
|
|
|
|
{
|
|
|
|
log_info(_("the IDEA cipher plugin is not present\n"));
|
2006-03-22 16:43:59 +00:00
|
|
|
log_info(_("please see %s for more information\n"),
|
|
|
|
"http://www.gnupg.org/faq/why-not-idea.html");
|
2002-06-29 13:46:34 +00:00
|
|
|
warned=1;
|
|
|
|
}
|
1999-11-13 16:43:23 +00:00
|
|
|
}
|
2003-02-22 13:00:18 +00:00
|
|
|
#endif
|
1999-11-13 16:43:23 +00:00
|
|
|
|
2004-09-15 18:41:36 +00:00
|
|
|
static unsigned long get_signature_count(PKT_secret_key *sk)
|
|
|
|
{
|
|
|
|
#ifdef ENABLE_CARD_SUPPORT
|
|
|
|
if(sk && sk->is_protected && sk->protect.s2k.mode==1002)
|
|
|
|
{
|
|
|
|
struct agent_card_info_s info;
|
|
|
|
if(agent_scd_getattr("SIG-COUNTER",&info)==0)
|
|
|
|
return info.sig_counter;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* How to do this without a card? */
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-07-27 18:10:56 +00:00
|
|
|
/* Expand %-strings. Returns a string which must be xfreed. Returns
|
2002-06-29 13:46:34 +00:00
|
|
|
NULL if the string cannot be expanded (too large). */
|
|
|
|
char *
|
|
|
|
pct_expando(const char *string,struct expando_args *args)
|
1999-11-13 16:43:23 +00:00
|
|
|
{
|
2002-06-29 13:46:34 +00:00
|
|
|
const char *ch=string;
|
|
|
|
int idx=0,maxlen=0,done=0;
|
|
|
|
u32 pk_keyid[2]={0,0},sk_keyid[2]={0,0};
|
|
|
|
char *ret=NULL;
|
|
|
|
|
|
|
|
if(args->pk)
|
|
|
|
keyid_from_pk(args->pk,pk_keyid);
|
|
|
|
|
|
|
|
if(args->sk)
|
|
|
|
keyid_from_sk(args->sk,sk_keyid);
|
|
|
|
|
* parse-packet.c (parse_signature): No need to reserve 8 bytes for the
unhashed signature cache any longer.
* misc.c (pct_expando): Add two new expandos - signer's fingerprint (%g),
and signer's primary fingerprint (%p).
* Makefile.am: Include W32LIBS where appropriate.
* g10.c (main): Add --rfc2440 alias for --openpgp since in a few months,
they won't be the same thing.
* keyserver.c (parse_keyserver_uri): Accept "http" as an alias for "hkp",
since it is occasionally written that way. (keyserver_spawn): Use
ascii_isspace to avoid locale issues.
* keygen.c (ask_user_id): Make --allow-freeform-uid apply to the email
field as well as the name field, and allow mixing fields when it is set.
* options.skel: Use subkeys.pgp.net as the default keyserver.
* trustdb.c (validate_one_keyblock): Certifications on revoked or expired
uids do not count in the web of trust.
* signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
sigprocmask() if we have sigset_t, and only use sigaction() if we have
struct sigaction. This is for Forte c89 on Solaris which seems to define
only the function call half of the two pairs by default.
(pause_on_sigusr): Typo. (do_block): If we can't use sigprocmask() and
sigset_t, try to get the number of signals from NSIG as well as MAXSIG,
and if we can't, fail with an explanation.
* signal.c, tdbio.c: Comment out the transaction code. It was not used in
this version, and was causing some build problems on quasi-posix platforms
(Solaris and Forte c89).
* keylist.c (list_keyblock_colon): Don't include validity values when
listing secret keys since they can be incorrect and/or misleading. This
is a temporary kludge, and will be handled properly in 1.9/2.0.
* mainproc.c (check_sig_and_print): Only show the "key available from"
preferred keyserver line if the key is not currently present.
* keyedit.c (sign_uids): Do not sign expired uids without --expert (same
behavior as revoked uids). Do not allow signing a user ID without a
self-signature. --expert overrides. Add additional prompt to the
signature level question. (menu_expire): When changing expiration dates,
don't replace selfsigs on revoked uids since this would effectively
unrevoke them. There is also no point in replacing expired selfsigs.
This is bug #181
* g10.c (add_notation_data): Make sure that only ascii is passed to
iscntrl. Noted by Christian Biere.
* getkey.c (classify_user_id2): Replaced isspace by spacep
* keygen.c (ask_user_id): Ditto. (get_parameter_algo): Ditto.
* keyedit.c (keyedit_menu): Ditto.
* tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/.
* revoke.c (ask_revocation_reason):
* keyserver.c (keyserver_spawn): Dito.
2003-07-10 14:30:07 +00:00
|
|
|
/* This is used so that %k works in photoid command strings in
|
|
|
|
--list-secret-keys (which of course has a sk, but no pk). */
|
2002-06-29 13:46:34 +00:00
|
|
|
if(!args->pk && args->sk)
|
|
|
|
keyid_from_sk(args->sk,pk_keyid);
|
|
|
|
|
|
|
|
while(*ch!='\0')
|
|
|
|
{
|
|
|
|
char *str=NULL;
|
|
|
|
|
|
|
|
if(!done)
|
|
|
|
{
|
|
|
|
/* 8192 is way bigger than we'll need here */
|
|
|
|
if(maxlen>=8192)
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
maxlen+=1024;
|
2005-07-27 18:10:56 +00:00
|
|
|
ret=xrealloc(ret,maxlen);
|
2002-06-29 13:46:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
done=0;
|
|
|
|
|
|
|
|
if(*ch=='%')
|
|
|
|
{
|
|
|
|
switch(*(ch+1))
|
|
|
|
{
|
|
|
|
case 's': /* short key id */
|
|
|
|
if(idx+8<maxlen)
|
|
|
|
{
|
|
|
|
sprintf(&ret[idx],"%08lX",(ulong)sk_keyid[1]);
|
|
|
|
idx+=8;
|
|
|
|
done=1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'S': /* long key id */
|
|
|
|
if(idx+16<maxlen)
|
|
|
|
{
|
|
|
|
sprintf(&ret[idx],"%08lX%08lX",
|
|
|
|
(ulong)sk_keyid[0],(ulong)sk_keyid[1]);
|
|
|
|
idx+=16;
|
|
|
|
done=1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'k': /* short key id */
|
|
|
|
if(idx+8<maxlen)
|
|
|
|
{
|
|
|
|
sprintf(&ret[idx],"%08lX",(ulong)pk_keyid[1]);
|
|
|
|
idx+=8;
|
|
|
|
done=1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'K': /* long key id */
|
|
|
|
if(idx+16<maxlen)
|
|
|
|
{
|
|
|
|
sprintf(&ret[idx],"%08lX%08lX",
|
|
|
|
(ulong)pk_keyid[0],(ulong)pk_keyid[1]);
|
|
|
|
idx+=16;
|
|
|
|
done=1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2004-09-15 18:41:36 +00:00
|
|
|
case 'c': /* signature count from card, if any. */
|
|
|
|
if(idx+10<maxlen)
|
|
|
|
{
|
|
|
|
sprintf(&ret[idx],"%lu",get_signature_count(args->sk));
|
|
|
|
idx+=strlen(&ret[idx]);
|
|
|
|
done=1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
* parse-packet.c (parse_signature): No need to reserve 8 bytes for the
unhashed signature cache any longer.
* misc.c (pct_expando): Add two new expandos - signer's fingerprint (%g),
and signer's primary fingerprint (%p).
* Makefile.am: Include W32LIBS where appropriate.
* g10.c (main): Add --rfc2440 alias for --openpgp since in a few months,
they won't be the same thing.
* keyserver.c (parse_keyserver_uri): Accept "http" as an alias for "hkp",
since it is occasionally written that way. (keyserver_spawn): Use
ascii_isspace to avoid locale issues.
* keygen.c (ask_user_id): Make --allow-freeform-uid apply to the email
field as well as the name field, and allow mixing fields when it is set.
* options.skel: Use subkeys.pgp.net as the default keyserver.
* trustdb.c (validate_one_keyblock): Certifications on revoked or expired
uids do not count in the web of trust.
* signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
sigprocmask() if we have sigset_t, and only use sigaction() if we have
struct sigaction. This is for Forte c89 on Solaris which seems to define
only the function call half of the two pairs by default.
(pause_on_sigusr): Typo. (do_block): If we can't use sigprocmask() and
sigset_t, try to get the number of signals from NSIG as well as MAXSIG,
and if we can't, fail with an explanation.
* signal.c, tdbio.c: Comment out the transaction code. It was not used in
this version, and was causing some build problems on quasi-posix platforms
(Solaris and Forte c89).
* keylist.c (list_keyblock_colon): Don't include validity values when
listing secret keys since they can be incorrect and/or misleading. This
is a temporary kludge, and will be handled properly in 1.9/2.0.
* mainproc.c (check_sig_and_print): Only show the "key available from"
preferred keyserver line if the key is not currently present.
* keyedit.c (sign_uids): Do not sign expired uids without --expert (same
behavior as revoked uids). Do not allow signing a user ID without a
self-signature. --expert overrides. Add additional prompt to the
signature level question. (menu_expire): When changing expiration dates,
don't replace selfsigs on revoked uids since this would effectively
unrevoke them. There is also no point in replacing expired selfsigs.
This is bug #181
* g10.c (add_notation_data): Make sure that only ascii is passed to
iscntrl. Noted by Christian Biere.
* getkey.c (classify_user_id2): Replaced isspace by spacep
* keygen.c (ask_user_id): Ditto. (get_parameter_algo): Ditto.
* keyedit.c (keyedit_menu): Ditto.
* tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/.
* revoke.c (ask_revocation_reason):
* keyserver.c (keyserver_spawn): Dito.
2003-07-10 14:30:07 +00:00
|
|
|
case 'p': /* primary pk fingerprint of a sk */
|
|
|
|
case 'f': /* pk fingerprint */
|
|
|
|
case 'g': /* sk fingerprint */
|
2002-06-29 13:46:34 +00:00
|
|
|
{
|
|
|
|
byte array[MAX_FINGERPRINT_LEN];
|
|
|
|
size_t len;
|
|
|
|
int i;
|
|
|
|
|
* parse-packet.c (parse_signature): No need to reserve 8 bytes for the
unhashed signature cache any longer.
* misc.c (pct_expando): Add two new expandos - signer's fingerprint (%g),
and signer's primary fingerprint (%p).
* Makefile.am: Include W32LIBS where appropriate.
* g10.c (main): Add --rfc2440 alias for --openpgp since in a few months,
they won't be the same thing.
* keyserver.c (parse_keyserver_uri): Accept "http" as an alias for "hkp",
since it is occasionally written that way. (keyserver_spawn): Use
ascii_isspace to avoid locale issues.
* keygen.c (ask_user_id): Make --allow-freeform-uid apply to the email
field as well as the name field, and allow mixing fields when it is set.
* options.skel: Use subkeys.pgp.net as the default keyserver.
* trustdb.c (validate_one_keyblock): Certifications on revoked or expired
uids do not count in the web of trust.
* signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
sigprocmask() if we have sigset_t, and only use sigaction() if we have
struct sigaction. This is for Forte c89 on Solaris which seems to define
only the function call half of the two pairs by default.
(pause_on_sigusr): Typo. (do_block): If we can't use sigprocmask() and
sigset_t, try to get the number of signals from NSIG as well as MAXSIG,
and if we can't, fail with an explanation.
* signal.c, tdbio.c: Comment out the transaction code. It was not used in
this version, and was causing some build problems on quasi-posix platforms
(Solaris and Forte c89).
* keylist.c (list_keyblock_colon): Don't include validity values when
listing secret keys since they can be incorrect and/or misleading. This
is a temporary kludge, and will be handled properly in 1.9/2.0.
* mainproc.c (check_sig_and_print): Only show the "key available from"
preferred keyserver line if the key is not currently present.
* keyedit.c (sign_uids): Do not sign expired uids without --expert (same
behavior as revoked uids). Do not allow signing a user ID without a
self-signature. --expert overrides. Add additional prompt to the
signature level question. (menu_expire): When changing expiration dates,
don't replace selfsigs on revoked uids since this would effectively
unrevoke them. There is also no point in replacing expired selfsigs.
This is bug #181
* g10.c (add_notation_data): Make sure that only ascii is passed to
iscntrl. Noted by Christian Biere.
* getkey.c (classify_user_id2): Replaced isspace by spacep
* keygen.c (ask_user_id): Ditto. (get_parameter_algo): Ditto.
* keyedit.c (keyedit_menu): Ditto.
* tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/.
* revoke.c (ask_revocation_reason):
* keyserver.c (keyserver_spawn): Dito.
2003-07-10 14:30:07 +00:00
|
|
|
if((*(ch+1))=='p' && args->sk)
|
|
|
|
{
|
|
|
|
if(args->sk->is_primary)
|
|
|
|
fingerprint_from_sk(args->sk,array,&len);
|
|
|
|
else if(args->sk->main_keyid[0] || args->sk->main_keyid[1])
|
|
|
|
{
|
|
|
|
PKT_public_key *pk=
|
2005-07-27 18:10:56 +00:00
|
|
|
xmalloc_clear(sizeof(PKT_public_key));
|
* parse-packet.c (parse_signature): No need to reserve 8 bytes for the
unhashed signature cache any longer.
* misc.c (pct_expando): Add two new expandos - signer's fingerprint (%g),
and signer's primary fingerprint (%p).
* Makefile.am: Include W32LIBS where appropriate.
* g10.c (main): Add --rfc2440 alias for --openpgp since in a few months,
they won't be the same thing.
* keyserver.c (parse_keyserver_uri): Accept "http" as an alias for "hkp",
since it is occasionally written that way. (keyserver_spawn): Use
ascii_isspace to avoid locale issues.
* keygen.c (ask_user_id): Make --allow-freeform-uid apply to the email
field as well as the name field, and allow mixing fields when it is set.
* options.skel: Use subkeys.pgp.net as the default keyserver.
* trustdb.c (validate_one_keyblock): Certifications on revoked or expired
uids do not count in the web of trust.
* signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
sigprocmask() if we have sigset_t, and only use sigaction() if we have
struct sigaction. This is for Forte c89 on Solaris which seems to define
only the function call half of the two pairs by default.
(pause_on_sigusr): Typo. (do_block): If we can't use sigprocmask() and
sigset_t, try to get the number of signals from NSIG as well as MAXSIG,
and if we can't, fail with an explanation.
* signal.c, tdbio.c: Comment out the transaction code. It was not used in
this version, and was causing some build problems on quasi-posix platforms
(Solaris and Forte c89).
* keylist.c (list_keyblock_colon): Don't include validity values when
listing secret keys since they can be incorrect and/or misleading. This
is a temporary kludge, and will be handled properly in 1.9/2.0.
* mainproc.c (check_sig_and_print): Only show the "key available from"
preferred keyserver line if the key is not currently present.
* keyedit.c (sign_uids): Do not sign expired uids without --expert (same
behavior as revoked uids). Do not allow signing a user ID without a
self-signature. --expert overrides. Add additional prompt to the
signature level question. (menu_expire): When changing expiration dates,
don't replace selfsigs on revoked uids since this would effectively
unrevoke them. There is also no point in replacing expired selfsigs.
This is bug #181
* g10.c (add_notation_data): Make sure that only ascii is passed to
iscntrl. Noted by Christian Biere.
* getkey.c (classify_user_id2): Replaced isspace by spacep
* keygen.c (ask_user_id): Ditto. (get_parameter_algo): Ditto.
* keyedit.c (keyedit_menu): Ditto.
* tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/.
* revoke.c (ask_revocation_reason):
* keyserver.c (keyserver_spawn): Dito.
2003-07-10 14:30:07 +00:00
|
|
|
|
|
|
|
if(get_pubkey_fast(pk,args->sk->main_keyid)==0)
|
|
|
|
fingerprint_from_pk(pk,array,&len);
|
|
|
|
else
|
|
|
|
memset(array,0,(len=MAX_FINGERPRINT_LEN));
|
|
|
|
free_public_key(pk);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
memset(array,0,(len=MAX_FINGERPRINT_LEN));
|
|
|
|
}
|
|
|
|
else if((*(ch+1))=='f' && args->pk)
|
2002-06-29 13:46:34 +00:00
|
|
|
fingerprint_from_pk(args->pk,array,&len);
|
* parse-packet.c (parse_signature): No need to reserve 8 bytes for the
unhashed signature cache any longer.
* misc.c (pct_expando): Add two new expandos - signer's fingerprint (%g),
and signer's primary fingerprint (%p).
* Makefile.am: Include W32LIBS where appropriate.
* g10.c (main): Add --rfc2440 alias for --openpgp since in a few months,
they won't be the same thing.
* keyserver.c (parse_keyserver_uri): Accept "http" as an alias for "hkp",
since it is occasionally written that way. (keyserver_spawn): Use
ascii_isspace to avoid locale issues.
* keygen.c (ask_user_id): Make --allow-freeform-uid apply to the email
field as well as the name field, and allow mixing fields when it is set.
* options.skel: Use subkeys.pgp.net as the default keyserver.
* trustdb.c (validate_one_keyblock): Certifications on revoked or expired
uids do not count in the web of trust.
* signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
sigprocmask() if we have sigset_t, and only use sigaction() if we have
struct sigaction. This is for Forte c89 on Solaris which seems to define
only the function call half of the two pairs by default.
(pause_on_sigusr): Typo. (do_block): If we can't use sigprocmask() and
sigset_t, try to get the number of signals from NSIG as well as MAXSIG,
and if we can't, fail with an explanation.
* signal.c, tdbio.c: Comment out the transaction code. It was not used in
this version, and was causing some build problems on quasi-posix platforms
(Solaris and Forte c89).
* keylist.c (list_keyblock_colon): Don't include validity values when
listing secret keys since they can be incorrect and/or misleading. This
is a temporary kludge, and will be handled properly in 1.9/2.0.
* mainproc.c (check_sig_and_print): Only show the "key available from"
preferred keyserver line if the key is not currently present.
* keyedit.c (sign_uids): Do not sign expired uids without --expert (same
behavior as revoked uids). Do not allow signing a user ID without a
self-signature. --expert overrides. Add additional prompt to the
signature level question. (menu_expire): When changing expiration dates,
don't replace selfsigs on revoked uids since this would effectively
unrevoke them. There is also no point in replacing expired selfsigs.
This is bug #181
* g10.c (add_notation_data): Make sure that only ascii is passed to
iscntrl. Noted by Christian Biere.
* getkey.c (classify_user_id2): Replaced isspace by spacep
* keygen.c (ask_user_id): Ditto. (get_parameter_algo): Ditto.
* keyedit.c (keyedit_menu): Ditto.
* tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/.
* revoke.c (ask_revocation_reason):
* keyserver.c (keyserver_spawn): Dito.
2003-07-10 14:30:07 +00:00
|
|
|
else if((*(ch+1))=='g' && args->sk)
|
|
|
|
fingerprint_from_sk(args->sk,array,&len);
|
2002-06-29 13:46:34 +00:00
|
|
|
else
|
* parse-packet.c (parse_signature): No need to reserve 8 bytes for the
unhashed signature cache any longer.
* misc.c (pct_expando): Add two new expandos - signer's fingerprint (%g),
and signer's primary fingerprint (%p).
* Makefile.am: Include W32LIBS where appropriate.
* g10.c (main): Add --rfc2440 alias for --openpgp since in a few months,
they won't be the same thing.
* keyserver.c (parse_keyserver_uri): Accept "http" as an alias for "hkp",
since it is occasionally written that way. (keyserver_spawn): Use
ascii_isspace to avoid locale issues.
* keygen.c (ask_user_id): Make --allow-freeform-uid apply to the email
field as well as the name field, and allow mixing fields when it is set.
* options.skel: Use subkeys.pgp.net as the default keyserver.
* trustdb.c (validate_one_keyblock): Certifications on revoked or expired
uids do not count in the web of trust.
* signal.c (init_one_signal, pause_on_sigusr, do_block): Only use
sigprocmask() if we have sigset_t, and only use sigaction() if we have
struct sigaction. This is for Forte c89 on Solaris which seems to define
only the function call half of the two pairs by default.
(pause_on_sigusr): Typo. (do_block): If we can't use sigprocmask() and
sigset_t, try to get the number of signals from NSIG as well as MAXSIG,
and if we can't, fail with an explanation.
* signal.c, tdbio.c: Comment out the transaction code. It was not used in
this version, and was causing some build problems on quasi-posix platforms
(Solaris and Forte c89).
* keylist.c (list_keyblock_colon): Don't include validity values when
listing secret keys since they can be incorrect and/or misleading. This
is a temporary kludge, and will be handled properly in 1.9/2.0.
* mainproc.c (check_sig_and_print): Only show the "key available from"
preferred keyserver line if the key is not currently present.
* keyedit.c (sign_uids): Do not sign expired uids without --expert (same
behavior as revoked uids). Do not allow signing a user ID without a
self-signature. --expert overrides. Add additional prompt to the
signature level question. (menu_expire): When changing expiration dates,
don't replace selfsigs on revoked uids since this would effectively
unrevoke them. There is also no point in replacing expired selfsigs.
This is bug #181
* g10.c (add_notation_data): Make sure that only ascii is passed to
iscntrl. Noted by Christian Biere.
* getkey.c (classify_user_id2): Replaced isspace by spacep
* keygen.c (ask_user_id): Ditto. (get_parameter_algo): Ditto.
* keyedit.c (keyedit_menu): Ditto.
* tdbdump.c (import_ownertrust): Ditto. s/isxdigit/hexdigitp/.
* revoke.c (ask_revocation_reason):
* keyserver.c (keyserver_spawn): Dito.
2003-07-10 14:30:07 +00:00
|
|
|
memset(array,0,(len=MAX_FINGERPRINT_LEN));
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
|
|
if(idx+(len*2)<maxlen)
|
|
|
|
{
|
|
|
|
for(i=0;i<len;i++)
|
|
|
|
{
|
|
|
|
sprintf(&ret[idx],"%02X",array[i]);
|
|
|
|
idx+=2;
|
|
|
|
}
|
|
|
|
done=1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 't': /* e.g. "jpg" */
|
|
|
|
str=image_type_to_string(args->imagetype,0);
|
|
|
|
/* fall through */
|
|
|
|
|
|
|
|
case 'T': /* e.g. "image/jpeg" */
|
|
|
|
if(str==NULL)
|
|
|
|
str=image_type_to_string(args->imagetype,2);
|
|
|
|
|
|
|
|
if(idx+strlen(str)<maxlen)
|
|
|
|
{
|
|
|
|
strcpy(&ret[idx],str);
|
|
|
|
idx+=strlen(str);
|
|
|
|
done=1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case '%':
|
|
|
|
if(idx+1<maxlen)
|
|
|
|
{
|
|
|
|
ret[idx++]='%';
|
|
|
|
ret[idx]='\0';
|
|
|
|
done=1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* Any unknown %-keys (like %i, %o, %I, and %O) are
|
|
|
|
passed through for later expansion. Note this also
|
|
|
|
handles the case where the last character in the
|
|
|
|
string is a '%' - the terminating \0 will end up here
|
|
|
|
and properly terminate the string. */
|
|
|
|
default:
|
|
|
|
if(idx+2<maxlen)
|
|
|
|
{
|
|
|
|
ret[idx++]='%';
|
|
|
|
ret[idx++]=*(ch+1);
|
|
|
|
ret[idx]='\0';
|
|
|
|
done=1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(done)
|
|
|
|
ch++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(idx+1<maxlen)
|
|
|
|
{
|
|
|
|
ret[idx++]=*ch;
|
|
|
|
ret[idx]='\0';
|
|
|
|
done=1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(done)
|
|
|
|
ch++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
fail:
|
2005-07-27 18:10:56 +00:00
|
|
|
xfree(ret);
|
2002-06-29 13:46:34 +00:00
|
|
|
return NULL;
|
1999-11-13 16:43:23 +00:00
|
|
|
}
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
void
|
|
|
|
deprecated_warning(const char *configname,unsigned int configlineno,
|
|
|
|
const char *option,const char *repl1,const char *repl2)
|
1999-12-31 11:44:29 +00:00
|
|
|
{
|
2002-06-29 13:46:34 +00:00
|
|
|
if(configname)
|
|
|
|
{
|
|
|
|
if(strncmp("--",option,2)==0)
|
|
|
|
option+=2;
|
2000-01-24 11:55:49 +00:00
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
if(strncmp("--",repl1,2)==0)
|
|
|
|
repl1+=2;
|
|
|
|
|
|
|
|
log_info(_("%s:%d: deprecated option \"%s\"\n"),
|
|
|
|
configname,configlineno,option);
|
2000-01-24 11:55:49 +00:00
|
|
|
}
|
2002-06-29 13:46:34 +00:00
|
|
|
else
|
|
|
|
log_info(_("WARNING: \"%s\" is a deprecated option\n"),option);
|
|
|
|
|
|
|
|
log_info(_("please use \"%s%s\" instead\n"),repl1,repl2);
|
|
|
|
}
|
|
|
|
|
2005-04-11 18:24:09 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
deprecated_command (const char *name)
|
|
|
|
{
|
|
|
|
log_info(_("WARNING: \"%s\" is a deprecated command - do not use it\n"),
|
|
|
|
name);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
const char *
|
|
|
|
compress_algo_to_string(int algo)
|
|
|
|
{
|
2004-02-10 22:42:34 +00:00
|
|
|
const char *s=NULL;
|
2000-01-24 11:55:49 +00:00
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
switch(algo)
|
|
|
|
{
|
* misc.c (compress_algo_to_string, string_to_compress_algo,
check_compress_algo): Add bzip2.
* compress.c (compress_filter): Make static to help force the use of
push_compress_filter. Remove default algorithm setting since that is done
in push_compress_filter now.
* main.h: Use named algorithm.
* filter.h, compress.c (push_compress_filter, push_compress_filter2): New.
Figure out which is the appropriate compression filter to use, and push it
into place.
* compress.c (handle_compressed), encode.c (encode_simple, encode_crypt),
sign.c (sign_file, sign_symencrypt_file), import.c (read_block), export.c
(do_export): Use push_compress_filter instead of pushing the compression
filter ourselves.
* compress-bz2.c: New. Bzlib versions of the compression filter routines.
* Makefile.am: Include compress-bz2.c if bz2lib is available.
2003-10-31 05:39:02 +00:00
|
|
|
case COMPRESS_ALGO_NONE:
|
2003-11-21 01:11:25 +00:00
|
|
|
s=_("Uncompressed");
|
2002-06-29 13:46:34 +00:00
|
|
|
break;
|
2000-07-25 15:38:12 +00:00
|
|
|
|
* misc.c (compress_algo_to_string, string_to_compress_algo,
check_compress_algo): Add bzip2.
* compress.c (compress_filter): Make static to help force the use of
push_compress_filter. Remove default algorithm setting since that is done
in push_compress_filter now.
* main.h: Use named algorithm.
* filter.h, compress.c (push_compress_filter, push_compress_filter2): New.
Figure out which is the appropriate compression filter to use, and push it
into place.
* compress.c (handle_compressed), encode.c (encode_simple, encode_crypt),
sign.c (sign_file, sign_symencrypt_file), import.c (read_block), export.c
(do_export): Use push_compress_filter instead of pushing the compression
filter ourselves.
* compress-bz2.c: New. Bzlib versions of the compression filter routines.
* Makefile.am: Include compress-bz2.c if bz2lib is available.
2003-10-31 05:39:02 +00:00
|
|
|
case COMPRESS_ALGO_ZIP:
|
2002-06-29 13:46:34 +00:00
|
|
|
s="ZIP";
|
|
|
|
break;
|
|
|
|
|
* misc.c (compress_algo_to_string, string_to_compress_algo,
check_compress_algo): Add bzip2.
* compress.c (compress_filter): Make static to help force the use of
push_compress_filter. Remove default algorithm setting since that is done
in push_compress_filter now.
* main.h: Use named algorithm.
* filter.h, compress.c (push_compress_filter, push_compress_filter2): New.
Figure out which is the appropriate compression filter to use, and push it
into place.
* compress.c (handle_compressed), encode.c (encode_simple, encode_crypt),
sign.c (sign_file, sign_symencrypt_file), import.c (read_block), export.c
(do_export): Use push_compress_filter instead of pushing the compression
filter ourselves.
* compress-bz2.c: New. Bzlib versions of the compression filter routines.
* Makefile.am: Include compress-bz2.c if bz2lib is available.
2003-10-31 05:39:02 +00:00
|
|
|
case COMPRESS_ALGO_ZLIB:
|
2002-06-29 13:46:34 +00:00
|
|
|
s="ZLIB";
|
|
|
|
break;
|
* misc.c (compress_algo_to_string, string_to_compress_algo,
check_compress_algo): Add bzip2.
* compress.c (compress_filter): Make static to help force the use of
push_compress_filter. Remove default algorithm setting since that is done
in push_compress_filter now.
* main.h: Use named algorithm.
* filter.h, compress.c (push_compress_filter, push_compress_filter2): New.
Figure out which is the appropriate compression filter to use, and push it
into place.
* compress.c (handle_compressed), encode.c (encode_simple, encode_crypt),
sign.c (sign_file, sign_symencrypt_file), import.c (read_block), export.c
(do_export): Use push_compress_filter instead of pushing the compression
filter ourselves.
* compress-bz2.c: New. Bzlib versions of the compression filter routines.
* Makefile.am: Include compress-bz2.c if bz2lib is available.
2003-10-31 05:39:02 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_BZIP2
|
|
|
|
case COMPRESS_ALGO_BZIP2:
|
|
|
|
s="BZIP2";
|
|
|
|
break;
|
|
|
|
#endif
|
2002-06-29 13:46:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return s;
|
1999-12-31 11:44:29 +00:00
|
|
|
}
|
|
|
|
|
2002-11-03 00:00:42 +00:00
|
|
|
int
|
|
|
|
string_to_compress_algo(const char *string)
|
|
|
|
{
|
2003-11-21 01:11:25 +00:00
|
|
|
/* NOTE TO TRANSLATOR: See doc/TRANSLATE about this string. */
|
|
|
|
if(match_multistr(_("uncompressed|none"),string))
|
|
|
|
return 0;
|
|
|
|
else if(ascii_strcasecmp(string,"uncompressed")==0)
|
2002-11-03 00:00:42 +00:00
|
|
|
return 0;
|
2003-11-15 22:31:58 +00:00
|
|
|
else if(ascii_strcasecmp(string,"none")==0)
|
|
|
|
return 0;
|
2002-11-03 00:00:42 +00:00
|
|
|
else if(ascii_strcasecmp(string,"zip")==0)
|
|
|
|
return 1;
|
|
|
|
else if(ascii_strcasecmp(string,"zlib")==0)
|
|
|
|
return 2;
|
* misc.c (compress_algo_to_string, string_to_compress_algo,
check_compress_algo): Add bzip2.
* compress.c (compress_filter): Make static to help force the use of
push_compress_filter. Remove default algorithm setting since that is done
in push_compress_filter now.
* main.h: Use named algorithm.
* filter.h, compress.c (push_compress_filter, push_compress_filter2): New.
Figure out which is the appropriate compression filter to use, and push it
into place.
* compress.c (handle_compressed), encode.c (encode_simple, encode_crypt),
sign.c (sign_file, sign_symencrypt_file), import.c (read_block), export.c
(do_export): Use push_compress_filter instead of pushing the compression
filter ourselves.
* compress-bz2.c: New. Bzlib versions of the compression filter routines.
* Makefile.am: Include compress-bz2.c if bz2lib is available.
2003-10-31 05:39:02 +00:00
|
|
|
#ifdef HAVE_BZIP2
|
|
|
|
else if(ascii_strcasecmp(string,"bzip2")==0)
|
|
|
|
return 3;
|
|
|
|
#endif
|
2002-11-03 00:00:42 +00:00
|
|
|
else if(ascii_strcasecmp(string,"z0")==0)
|
|
|
|
return 0;
|
|
|
|
else if(ascii_strcasecmp(string,"z1")==0)
|
|
|
|
return 1;
|
|
|
|
else if(ascii_strcasecmp(string,"z2")==0)
|
|
|
|
return 2;
|
* misc.c (compress_algo_to_string, string_to_compress_algo,
check_compress_algo): Add bzip2.
* compress.c (compress_filter): Make static to help force the use of
push_compress_filter. Remove default algorithm setting since that is done
in push_compress_filter now.
* main.h: Use named algorithm.
* filter.h, compress.c (push_compress_filter, push_compress_filter2): New.
Figure out which is the appropriate compression filter to use, and push it
into place.
* compress.c (handle_compressed), encode.c (encode_simple, encode_crypt),
sign.c (sign_file, sign_symencrypt_file), import.c (read_block), export.c
(do_export): Use push_compress_filter instead of pushing the compression
filter ourselves.
* compress-bz2.c: New. Bzlib versions of the compression filter routines.
* Makefile.am: Include compress-bz2.c if bz2lib is available.
2003-10-31 05:39:02 +00:00
|
|
|
#ifdef HAVE_BZIP2
|
|
|
|
else if(ascii_strcasecmp(string,"z3")==0)
|
|
|
|
return 3;
|
|
|
|
#endif
|
2002-11-03 00:00:42 +00:00
|
|
|
else
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2002-06-29 13:46:34 +00:00
|
|
|
int
|
|
|
|
check_compress_algo(int algo)
|
|
|
|
{
|
* misc.c (compress_algo_to_string, string_to_compress_algo,
check_compress_algo): Add bzip2.
* compress.c (compress_filter): Make static to help force the use of
push_compress_filter. Remove default algorithm setting since that is done
in push_compress_filter now.
* main.h: Use named algorithm.
* filter.h, compress.c (push_compress_filter, push_compress_filter2): New.
Figure out which is the appropriate compression filter to use, and push it
into place.
* compress.c (handle_compressed), encode.c (encode_simple, encode_crypt),
sign.c (sign_file, sign_symencrypt_file), import.c (read_block), export.c
(do_export): Use push_compress_filter instead of pushing the compression
filter ourselves.
* compress-bz2.c: New. Bzlib versions of the compression filter routines.
* Makefile.am: Include compress-bz2.c if bz2lib is available.
2003-10-31 05:39:02 +00:00
|
|
|
#ifdef HAVE_BZIP2
|
|
|
|
if(algo>=0 && algo<=3)
|
|
|
|
return 0;
|
|
|
|
#else
|
2002-06-29 13:46:34 +00:00
|
|
|
if(algo>=0 && algo<=2)
|
|
|
|
return 0;
|
* misc.c (compress_algo_to_string, string_to_compress_algo,
check_compress_algo): Add bzip2.
* compress.c (compress_filter): Make static to help force the use of
push_compress_filter. Remove default algorithm setting since that is done
in push_compress_filter now.
* main.h: Use named algorithm.
* filter.h, compress.c (push_compress_filter, push_compress_filter2): New.
Figure out which is the appropriate compression filter to use, and push it
into place.
* compress.c (handle_compressed), encode.c (encode_simple, encode_crypt),
sign.c (sign_file, sign_symencrypt_file), import.c (read_block), export.c
(do_export): Use push_compress_filter instead of pushing the compression
filter ourselves.
* compress-bz2.c: New. Bzlib versions of the compression filter routines.
* Makefile.am: Include compress-bz2.c if bz2lib is available.
2003-10-31 05:39:02 +00:00
|
|
|
#endif
|
2002-06-29 13:46:34 +00:00
|
|
|
|
|
|
|
return G10ERR_COMPR_ALGO;
|
|
|
|
}
|
2002-11-25 04:24:41 +00:00
|
|
|
|
|
|
|
int
|
|
|
|
default_cipher_algo(void)
|
|
|
|
{
|
|
|
|
if(opt.def_cipher_algo)
|
|
|
|
return opt.def_cipher_algo;
|
|
|
|
else if(opt.personal_cipher_prefs)
|
|
|
|
return opt.personal_cipher_prefs[0].value;
|
|
|
|
else
|
|
|
|
return opt.s2k_cipher_algo;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* There is no default_digest_algo function, but see
|
2003-11-15 22:31:58 +00:00
|
|
|
sign.c:hash_for() */
|
2002-11-25 04:24:41 +00:00
|
|
|
|
|
|
|
int
|
|
|
|
default_compress_algo(void)
|
|
|
|
{
|
2003-11-15 22:31:58 +00:00
|
|
|
if(opt.compress_algo!=-1)
|
|
|
|
return opt.compress_algo;
|
2002-11-25 04:24:41 +00:00
|
|
|
else if(opt.personal_compress_prefs)
|
|
|
|
return opt.personal_compress_prefs[0].value;
|
|
|
|
else
|
|
|
|
return DEFAULT_COMPRESS_ALGO;
|
|
|
|
}
|
* packet.h, build-packet.c (build_sig_subpkt), export.c
(do_export_stream), import.c (remove_bad_stuff, import), parse-packet.c
(dump_sig_subpkt, parse_one_sig_subpkt): Remove vestigal code for the old
sig cache subpacket. This wasn't completely harmless as it caused
subpacket 101 to disappear on import and export.
* options.h, armor.c, cipher.c, g10.c, keyedit.c, pkclist.c, sign.c,
encode.c, getkey.c, revoke.c: The current flags for different levels of
PGP-ness are massively complex. This is step one in simplifying them. No
functional change yet, just use a macro to check for compliance level.
* sign.c (sign_file): Fix bug that causes spurious compression preference
warning.
* sign.c (clearsign_file): Fix bug that prevents proper warning message
from appearing when clearsigning in --pgp2 mode with a non-v3 RSA key.
* main.h, misc.c (compliance_option_string, compliance_string,
compliance_failure), pkclist.c (build_pk_list), sign.c (sign_file,
clearsign_file), encode.c (encode_crypt, write_pubkey_enc_from_list): New
functions to put the "this message may not be usable...." warning in one
place.
* options.h, g10.c (main): Part two of the simplification. Use a single
enum to indicate what we are compliant to (1991, 2440, PGPx, etc.)
* g10.c (main): Show errors for failure in export, send-keys, recv-keys,
and refresh-keys.
* options.h, g10.c (main): Give algorithm warnings for algorithms chosen
against the --pgpX and --openpgp rules.
* keydb.h, pkclist.c (algo_available): Make TIGER192 invalid in --openpgp
mode.
* sign.c (sign_file), pkclist.c (algo_available): Allow passing a hint of
0.
2003-05-03 04:07:45 +00:00
|
|
|
|
|
|
|
const char *
|
|
|
|
compliance_option_string(void)
|
|
|
|
{
|
|
|
|
switch(opt.compliance)
|
|
|
|
{
|
|
|
|
case CO_RFC2440:
|
|
|
|
return "--openpgp";
|
|
|
|
case CO_PGP2:
|
|
|
|
return "--pgp2";
|
|
|
|
case CO_PGP6:
|
|
|
|
return "--pgp6";
|
|
|
|
case CO_PGP7:
|
|
|
|
return "--pgp7";
|
|
|
|
case CO_PGP8:
|
|
|
|
return "--pgp8";
|
|
|
|
default:
|
|
|
|
return "???";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char *
|
|
|
|
compliance_string(void)
|
|
|
|
{
|
|
|
|
switch(opt.compliance)
|
|
|
|
{
|
|
|
|
case CO_RFC2440:
|
|
|
|
return "OpenPGP";
|
|
|
|
case CO_PGP2:
|
|
|
|
return "PGP 2.x";
|
|
|
|
case CO_PGP6:
|
|
|
|
return "PGP 6.x";
|
|
|
|
case CO_PGP7:
|
|
|
|
return "PGP 7.x";
|
|
|
|
case CO_PGP8:
|
|
|
|
return "PGP 8.x";
|
|
|
|
default:
|
|
|
|
return "???";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
compliance_failure(void)
|
|
|
|
{
|
|
|
|
log_info(_("this message may not be usable by %s\n"),compliance_string());
|
|
|
|
opt.compliance=CO_GNUPG;
|
|
|
|
}
|
2003-05-31 21:52:16 +00:00
|
|
|
|
2004-04-16 15:19:35 +00:00
|
|
|
/* Break a string into successive option pieces. Accepts single word
|
|
|
|
options and key=value argument options. */
|
2004-02-14 05:03:45 +00:00
|
|
|
char *
|
2004-04-16 15:19:35 +00:00
|
|
|
optsep(char **stringp)
|
2004-02-14 05:03:45 +00:00
|
|
|
{
|
2004-04-16 02:57:20 +00:00
|
|
|
char *tok,*end;
|
2004-02-14 05:03:45 +00:00
|
|
|
|
|
|
|
tok=*stringp;
|
|
|
|
if(tok)
|
|
|
|
{
|
2004-04-16 02:57:20 +00:00
|
|
|
end=strpbrk(tok," ,=");
|
|
|
|
if(end)
|
2004-02-14 05:03:45 +00:00
|
|
|
{
|
|
|
|
int sawequals=0;
|
2004-04-16 02:57:20 +00:00
|
|
|
char *ptr=end;
|
2004-02-14 05:03:45 +00:00
|
|
|
|
2004-04-16 02:57:20 +00:00
|
|
|
/* what we need to do now is scan along starting with *end,
|
|
|
|
If the next character we see (ignoring spaces) is an =
|
2004-02-14 05:03:45 +00:00
|
|
|
sign, then there is an argument. */
|
|
|
|
|
2004-04-16 02:57:20 +00:00
|
|
|
while(*ptr)
|
2004-02-14 05:03:45 +00:00
|
|
|
{
|
2004-04-16 02:57:20 +00:00
|
|
|
if(*ptr=='=')
|
2004-02-14 05:03:45 +00:00
|
|
|
sawequals=1;
|
2004-04-16 02:57:20 +00:00
|
|
|
else if(*ptr!=' ')
|
2004-02-14 05:03:45 +00:00
|
|
|
break;
|
2004-04-16 02:57:20 +00:00
|
|
|
ptr++;
|
2004-02-14 05:03:45 +00:00
|
|
|
}
|
|
|
|
|
2004-07-28 04:12:50 +00:00
|
|
|
/* There is an argument, so grab that too. At this point,
|
|
|
|
ptr points to the first character of the argument. */
|
2004-02-14 05:03:45 +00:00
|
|
|
if(sawequals)
|
2004-07-28 04:12:50 +00:00
|
|
|
{
|
|
|
|
/* Is it a quoted argument? */
|
|
|
|
if(*ptr=='"')
|
|
|
|
{
|
|
|
|
ptr++;
|
|
|
|
end=strchr(ptr,'"');
|
|
|
|
if(end)
|
|
|
|
end++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
end=strpbrk(ptr," ,");
|
|
|
|
}
|
2004-04-16 02:57:20 +00:00
|
|
|
|
2004-07-28 04:12:50 +00:00
|
|
|
if(end && *end)
|
2004-02-14 05:03:45 +00:00
|
|
|
{
|
2004-04-16 02:57:20 +00:00
|
|
|
*end='\0';
|
|
|
|
*stringp=end+1;
|
2004-02-14 05:03:45 +00:00
|
|
|
}
|
2004-04-16 02:57:20 +00:00
|
|
|
else
|
|
|
|
*stringp=NULL;
|
2004-02-14 05:03:45 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
*stringp=NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return tok;
|
|
|
|
}
|
|
|
|
|
2004-04-16 15:19:35 +00:00
|
|
|
/* Breaks an option value into key and value. Returns NULL if there
|
|
|
|
is no value. Note that "string" is modified to remove the =value
|
|
|
|
part. */
|
2004-04-16 02:57:20 +00:00
|
|
|
char *
|
2004-04-16 15:19:35 +00:00
|
|
|
argsplit(char *string)
|
2004-04-16 02:57:20 +00:00
|
|
|
{
|
2004-04-16 15:19:35 +00:00
|
|
|
char *equals,*arg=NULL;
|
2004-04-16 02:57:20 +00:00
|
|
|
|
2004-04-16 15:19:35 +00:00
|
|
|
equals=strchr(string,'=');
|
|
|
|
if(equals)
|
2004-04-16 02:57:20 +00:00
|
|
|
{
|
2004-07-28 15:36:23 +00:00
|
|
|
char *quote,*space;
|
2004-04-16 02:57:20 +00:00
|
|
|
|
2004-07-28 15:36:23 +00:00
|
|
|
*equals='\0';
|
|
|
|
arg=equals+1;
|
|
|
|
|
|
|
|
/* Quoted arg? */
|
|
|
|
quote=strchr(arg,'"');
|
|
|
|
if(quote)
|
2004-04-16 15:19:35 +00:00
|
|
|
{
|
2004-07-28 15:36:23 +00:00
|
|
|
arg=quote+1;
|
|
|
|
|
|
|
|
quote=strchr(arg,'"');
|
|
|
|
if(quote)
|
|
|
|
*quote='\0';
|
2004-04-16 02:57:20 +00:00
|
|
|
}
|
2004-04-16 15:19:35 +00:00
|
|
|
else
|
|
|
|
{
|
2004-07-28 15:36:23 +00:00
|
|
|
size_t spaces;
|
|
|
|
|
|
|
|
/* Trim leading spaces off of the arg */
|
|
|
|
spaces=strspn(arg," ");
|
|
|
|
arg+=spaces;
|
2004-04-16 15:19:35 +00:00
|
|
|
}
|
|
|
|
|
2004-07-28 15:36:23 +00:00
|
|
|
/* Trim tailing spaces off of the tag */
|
|
|
|
space=strchr(string,' ');
|
2004-04-16 15:19:35 +00:00
|
|
|
if(space)
|
2004-07-28 15:36:23 +00:00
|
|
|
*space='\0';
|
2004-04-16 02:57:20 +00:00
|
|
|
}
|
|
|
|
|
2004-04-16 15:19:35 +00:00
|
|
|
return arg;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return the length of the initial token, leaving off any
|
|
|
|
argument. */
|
|
|
|
static size_t
|
|
|
|
optlen(const char *s)
|
|
|
|
{
|
|
|
|
char *end=strpbrk(s," =");
|
|
|
|
|
|
|
|
if(end)
|
|
|
|
return end-s;
|
|
|
|
else
|
|
|
|
return strlen(s);
|
2004-04-16 02:57:20 +00:00
|
|
|
}
|
|
|
|
|
2003-05-31 21:52:16 +00:00
|
|
|
int
|
2003-12-28 03:46:43 +00:00
|
|
|
parse_options(char *str,unsigned int *options,
|
|
|
|
struct parse_options *opts,int noisy)
|
2003-05-31 21:52:16 +00:00
|
|
|
{
|
2004-04-16 15:19:35 +00:00
|
|
|
char *tok;
|
2003-05-31 21:52:16 +00:00
|
|
|
|
2005-09-07 15:53:03 +00:00
|
|
|
if (str && !strcmp (str, "help"))
|
|
|
|
{
|
2005-09-14 22:31:21 +00:00
|
|
|
int i,maxlen=0;
|
2005-09-07 15:53:03 +00:00
|
|
|
|
2005-09-14 22:31:21 +00:00
|
|
|
/* Figure out the longest option name so we can line these up
|
|
|
|
neatly. */
|
2005-09-07 15:53:03 +00:00
|
|
|
for(i=0;opts[i].name;i++)
|
2005-09-14 22:31:21 +00:00
|
|
|
if(opts[i].help && maxlen<strlen(opts[i].name))
|
|
|
|
maxlen=strlen(opts[i].name);
|
|
|
|
|
|
|
|
for(i=0;opts[i].name;i++)
|
|
|
|
if(opts[i].help)
|
|
|
|
printf("%s%*s%s\n",opts[i].name,
|
2005-10-14 04:07:13 +00:00
|
|
|
maxlen+2-(int)strlen(opts[i].name),"",_(opts[i].help));
|
2005-09-14 22:31:21 +00:00
|
|
|
|
|
|
|
g10_exit(0);
|
2005-09-07 15:53:03 +00:00
|
|
|
}
|
|
|
|
|
2004-04-16 15:19:35 +00:00
|
|
|
while((tok=optsep(&str)))
|
2003-05-31 21:52:16 +00:00
|
|
|
{
|
|
|
|
int i,rev=0;
|
2003-10-10 03:05:05 +00:00
|
|
|
char *otok=tok;
|
2003-05-31 21:52:16 +00:00
|
|
|
|
|
|
|
if(tok[0]=='\0')
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if(ascii_strncasecmp("no-",tok,3)==0)
|
|
|
|
{
|
|
|
|
rev=1;
|
|
|
|
tok+=3;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(i=0;opts[i].name;i++)
|
|
|
|
{
|
2004-04-16 15:19:35 +00:00
|
|
|
size_t toklen=optlen(tok);
|
2003-10-10 03:05:05 +00:00
|
|
|
|
|
|
|
if(ascii_strncasecmp(opts[i].name,tok,toklen)==0)
|
2003-05-31 21:52:16 +00:00
|
|
|
{
|
2003-10-10 03:05:05 +00:00
|
|
|
/* We have a match, but it might be incomplete */
|
|
|
|
if(toklen!=strlen(opts[i].name))
|
|
|
|
{
|
|
|
|
int j;
|
|
|
|
|
|
|
|
for(j=i+1;opts[j].name;j++)
|
|
|
|
{
|
|
|
|
if(ascii_strncasecmp(opts[j].name,tok,toklen)==0)
|
|
|
|
{
|
2003-12-28 03:46:43 +00:00
|
|
|
if(noisy)
|
|
|
|
log_info(_("ambiguous option `%s'\n"),otok);
|
2003-10-10 03:05:05 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-05-31 21:52:16 +00:00
|
|
|
if(rev)
|
2004-02-15 00:04:32 +00:00
|
|
|
{
|
|
|
|
*options&=~opts[i].bit;
|
|
|
|
if(opts[i].value)
|
|
|
|
*opts[i].value=NULL;
|
|
|
|
}
|
2003-05-31 21:52:16 +00:00
|
|
|
else
|
2004-02-15 00:04:32 +00:00
|
|
|
{
|
|
|
|
*options|=opts[i].bit;
|
|
|
|
if(opts[i].value)
|
2004-04-16 15:19:35 +00:00
|
|
|
*opts[i].value=argsplit(tok);
|
2004-02-15 00:04:32 +00:00
|
|
|
}
|
2003-05-31 21:52:16 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!opts[i].name)
|
2003-10-10 03:05:05 +00:00
|
|
|
{
|
2003-12-28 03:46:43 +00:00
|
|
|
if(noisy)
|
|
|
|
log_info(_("unknown option `%s'\n"),otok);
|
2003-10-10 03:05:05 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2003-05-31 21:52:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
2005-01-20 11:42:03 +00:00
|
|
|
|
|
|
|
|
2005-05-24 12:39:42 +00:00
|
|
|
/* Return a new malloced string by unescaping the string S. Escaping
|
|
|
|
is percent escaping and '+'/space mapping. A binary nul will
|
|
|
|
silently be replaced by a 0xFF. */
|
|
|
|
char *
|
|
|
|
unescape_percent_string (const unsigned char *s)
|
|
|
|
{
|
|
|
|
char *buffer, *d;
|
|
|
|
|
|
|
|
buffer = d = xmalloc (strlen (s)+1);
|
|
|
|
while (*s)
|
|
|
|
{
|
|
|
|
if (*s == '%' && s[1] && s[2])
|
|
|
|
{
|
|
|
|
s++;
|
|
|
|
*d = xtoi_2 (s);
|
|
|
|
if (!*d)
|
|
|
|
*d = '\xff';
|
|
|
|
d++;
|
|
|
|
s += 2;
|
|
|
|
}
|
|
|
|
else if (*s == '+')
|
|
|
|
{
|
|
|
|
*d++ = ' ';
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
*d++ = *s++;
|
|
|
|
}
|
|
|
|
*d = 0;
|
|
|
|
return buffer;
|
2005-07-28 18:59:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
has_invalid_email_chars (const char *s)
|
|
|
|
{
|
|
|
|
int at_seen=0;
|
2006-03-01 18:16:55 +00:00
|
|
|
const char *valid_chars=
|
|
|
|
"01234567890_-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
2005-07-28 18:59:36 +00:00
|
|
|
|
|
|
|
for ( ; *s; s++ )
|
|
|
|
{
|
|
|
|
if ( *s & 0x80 )
|
|
|
|
return 1;
|
|
|
|
if ( *s == '@' )
|
|
|
|
at_seen=1;
|
|
|
|
else if ( !at_seen && !( !!strchr( valid_chars, *s ) || *s == '+' ) )
|
|
|
|
return 1;
|
|
|
|
else if ( at_seen && !strchr( valid_chars, *s ) )
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
2005-05-24 12:39:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-08-05 14:46:59 +00:00
|
|
|
/* Check whether NAME represents a valid mailbox according to
|
|
|
|
RFC822. Returns true if so. */
|
|
|
|
int
|
|
|
|
is_valid_mailbox (const char *name)
|
|
|
|
{
|
|
|
|
return !( !name
|
|
|
|
|| !*name
|
|
|
|
|| has_invalid_email_chars (name)
|
|
|
|
|| string_count_chr (name,'@') != 1
|
|
|
|
|| *name == '@'
|
|
|
|
|| name[strlen(name)-1] == '@'
|
|
|
|
|| name[strlen(name)-1] == '.'
|
|
|
|
|| strstr (name, "..") );
|
|
|
|
}
|
2005-05-24 12:39:42 +00:00
|
|
|
|
|
|
|
|
2005-02-15 11:02:32 +00:00
|
|
|
/* This is a helper function to load a Windows function from either of
|
|
|
|
one DLLs. */
|
|
|
|
#ifdef HAVE_W32_SYSTEM
|
|
|
|
static HRESULT
|
|
|
|
w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e)
|
|
|
|
{
|
|
|
|
static int initialized;
|
2005-03-30 10:39:13 +00:00
|
|
|
static HRESULT (WINAPI * func)(HWND,int,HANDLE,DWORD,LPSTR);
|
2005-02-15 11:02:32 +00:00
|
|
|
|
|
|
|
if (!initialized)
|
|
|
|
{
|
|
|
|
static char *dllnames[] = { "shell32.dll", "shfolder.dll", NULL };
|
|
|
|
void *handle;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
initialized = 1;
|
|
|
|
|
|
|
|
for (i=0, handle = NULL; !handle && dllnames[i]; i++)
|
|
|
|
{
|
|
|
|
handle = dlopen (dllnames[i], RTLD_LAZY);
|
|
|
|
if (handle)
|
|
|
|
{
|
|
|
|
func = dlsym (handle, "SHGetFolderPathA");
|
|
|
|
if (!func)
|
|
|
|
{
|
|
|
|
dlclose (handle);
|
|
|
|
handle = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (func)
|
|
|
|
return func (a,b,c,d,e);
|
|
|
|
else
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
#endif /*HAVE_W32_SYSTEM*/
|
|
|
|
|
|
|
|
|
2005-01-20 11:42:03 +00:00
|
|
|
/* Set up the default home directory. The usual --homedir option
|
|
|
|
should be parsed later. */
|
|
|
|
char *
|
|
|
|
default_homedir (void)
|
|
|
|
{
|
|
|
|
char *dir;
|
|
|
|
|
|
|
|
dir = getenv("GNUPGHOME");
|
|
|
|
#ifdef HAVE_W32_SYSTEM
|
|
|
|
if (!dir || !*dir)
|
|
|
|
dir = read_w32_registry_string (NULL, "Software\\GNU\\GnuPG", "HomeDir");
|
|
|
|
if (!dir || !*dir)
|
|
|
|
{
|
|
|
|
char path[MAX_PATH];
|
|
|
|
|
|
|
|
/* It might be better to use LOCAL_APPDATA because this is
|
|
|
|
defined as "non roaming" and thus more likely to be kept
|
|
|
|
locally. For private keys this is desired. However, given
|
|
|
|
that many users copy private keys anyway forth and back,
|
|
|
|
using a system roaming serives might be better than to let
|
|
|
|
them do it manually. A security conscious user will anyway
|
|
|
|
use the registry entry to have better control. */
|
2005-02-15 11:02:32 +00:00
|
|
|
if (w32_shgetfolderpath (NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE,
|
|
|
|
NULL, 0, path) >= 0)
|
2005-01-20 11:42:03 +00:00
|
|
|
{
|
|
|
|
char *tmp = xmalloc (strlen (path) + 6 +1);
|
|
|
|
strcpy (stpcpy (tmp, path), "\\gnupg");
|
|
|
|
dir = tmp;
|
|
|
|
|
|
|
|
/* Try to create the directory if it does not yet
|
|
|
|
exists. */
|
|
|
|
if (access (dir, F_OK))
|
|
|
|
CreateDirectory (dir, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /*HAVE_W32_SYSTEM*/
|
|
|
|
if (!dir || !*dir)
|
|
|
|
dir = GNUPG_HOMEDIR;
|
|
|
|
|
|
|
|
return dir;
|
|
|
|
}
|
2005-07-19 08:50:28 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* Return the name of the libexec directory. The name is allocated in
|
|
|
|
a static area on the first use. This function won't fail. */
|
|
|
|
const char *
|
|
|
|
get_libexecdir (void)
|
|
|
|
{
|
|
|
|
#ifdef HAVE_W32_SYSTEM
|
|
|
|
static int got_dir;
|
2005-07-22 16:28:40 +00:00
|
|
|
static char dir[MAX_PATH+5];
|
2005-07-19 08:50:28 +00:00
|
|
|
|
|
|
|
if (!got_dir)
|
|
|
|
{
|
2005-07-22 16:28:40 +00:00
|
|
|
char *p;
|
|
|
|
|
|
|
|
if ( !GetModuleFileName ( NULL, dir, MAX_PATH) )
|
2005-07-19 08:50:28 +00:00
|
|
|
{
|
2005-07-22 16:28:40 +00:00
|
|
|
log_debug ("GetModuleFileName failed: %s\n", w32_strerror (0));
|
|
|
|
*dir = 0;
|
2005-07-19 08:50:28 +00:00
|
|
|
}
|
|
|
|
got_dir = 1;
|
2005-07-22 16:28:40 +00:00
|
|
|
p = strrchr (dir, DIRSEP_C);
|
|
|
|
if (p)
|
|
|
|
*p = 0;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
log_debug ("bad filename `%s' returned for this process\n", dir);
|
|
|
|
*dir = 0;
|
|
|
|
}
|
2005-07-19 08:50:28 +00:00
|
|
|
}
|
|
|
|
|
2005-07-22 16:28:40 +00:00
|
|
|
if (*dir)
|
2005-07-19 08:50:28 +00:00
|
|
|
return dir;
|
|
|
|
/* Fallback to the hardwired value. */
|
|
|
|
#endif /*HAVE_W32_SYSTEM*/
|
|
|
|
|
|
|
|
return GNUPG_LIBEXECDIR;
|
|
|
|
}
|
2005-08-21 20:58:46 +00:00
|
|
|
|
2005-08-27 03:09:40 +00:00
|
|
|
/* Similar to access(2), but uses PATH to find the file. */
|
2005-08-21 20:58:46 +00:00
|
|
|
int
|
|
|
|
path_access(const char *file,int mode)
|
|
|
|
{
|
|
|
|
char *envpath;
|
|
|
|
int ret=-1;
|
|
|
|
|
|
|
|
envpath=getenv("PATH");
|
|
|
|
|
2006-01-22 21:40:20 +00:00
|
|
|
if(!envpath
|
|
|
|
#ifdef HAVE_DRIVE_LETTERS
|
|
|
|
|| (((file[0]>='A' && file[0]<='Z')
|
|
|
|
|| (file[0]>='a' && file[0]<='z'))
|
|
|
|
&& file[1]==':')
|
|
|
|
#else
|
|
|
|
|| file[0]=='/'
|
|
|
|
#endif
|
|
|
|
)
|
2005-08-21 20:58:46 +00:00
|
|
|
return access(file,mode);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* At least as large as, but most often larger than we need. */
|
|
|
|
char *buffer=xmalloc(strlen(envpath)+1+strlen(file)+1);
|
|
|
|
char *split,*item,*path=xstrdup(envpath);
|
|
|
|
|
|
|
|
split=path;
|
|
|
|
|
|
|
|
while((item=strsep(&split,PATHSEP_S)))
|
|
|
|
{
|
|
|
|
strcpy(buffer,item);
|
|
|
|
strcat(buffer,"/");
|
|
|
|
strcat(buffer,file);
|
|
|
|
ret=access(buffer,mode);
|
|
|
|
if(ret==0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
xfree(path);
|
|
|
|
xfree(buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|