* preset-passphrase.c (preset_passphrase): Handle --passphrase.

* Makefile.am (gpg_preset_passphrase_LDADD): Reorder libs so that
pwquery may use stuff from jnlib.  Conditionally add -lwsock2
(gpg_protect_tool_LDADD): Ditto.

* preset-passphrase.c (main): Use default_homedir().
(main) [W32]: Initialize sockets.

* simple-pwquery.c (agent_open) [W32]: Implement for W32.
(readline) [W32]: Use recv instead of read.
(writen) [W32]: Use send instead of write.
(my_stpcpy): Define a stpcpy replacement so that this file
continues to be self-contained.
(agent_send_all_options) [W32]: Don't call ttyname.

* gnupg-badge-openpgp.eps, gnupg-badge-openpgp.jpg: New
* gnupg.texi: Add a logo.
* sysnotes.texi: New.

* gpgsm.c (main): Use default_homedir().
(main) [W32]: Default to disabled CRL checks.

* gpgconf-comp.c (get_config_pathname) [DOSISH]: Detect absolute
pathnames with a drive letter.
This commit is contained in:
Werner Koch 2004-12-21 19:05:15 +00:00
parent 7b9e5a343f
commit 01f3f25158
25 changed files with 8986 additions and 31 deletions

View File

@ -1,8 +1,33 @@
2004-12-21 Werner Koch <wk@g10code.com>
* preset-passphrase.c (preset_passphrase): Handle --passphrase.
* Makefile.am (gpg_preset_passphrase_LDADD): Reorder libs so that
pwquery may use stuff from jnlib. Conditionally add -lwsock2
(gpg_protect_tool_LDADD): Ditto.
* preset-passphrase.c (main): Use default_homedir().
(main) [W32]: Initialize sockets.
2004-12-21 Marcus Brinkmann <marcus@g10code.de>
* Makefile.am (libexec_PROGRAMS): Add gpg-preset-passphrase.
(gpg_preset_passphrase_SOURCES, gpg_preset_passphrase_LDADD): New
targets.
* agent.h (opt): New member allow_cache_passphrase.
* cache.c (housekeeping): Check if R->ttl is not negative.
(agent_put_cache): Allow ttl to be negative.
* command.c (parse_hexstring): Allow something to follow the
hexstring.
(cmd_cache_passphrase): New function.
(register_commands): Add it.
* gpg-agent.c: Handle --allow-preset-passphrase.
* preset-passphrase.c: New file.
2004-12-21 Werner Koch <wk@g10code.com>
* gpg-agent.c (main): Use default_homedir().
* protect-tool.c (main): Ditto.
* protect-tool.c (main): Ditto.
2004-12-20 Werner Koch <wk@g10code.com>

View File

@ -19,7 +19,7 @@
## Process this file with automake to produce Makefile.in
bin_PROGRAMS = gpg-agent
libexec_PROGRAMS = gpg-protect-tool
libexec_PROGRAMS = gpg-protect-tool gpg-preset-passphrase
AM_CPPFLAGS = -I$(top_srcdir)/common -I$(top_srcdir)/intl
@ -53,8 +53,20 @@ gpg_protect_tool_SOURCES = \
protect.c \
minip12.c minip12.h
gpg_protect_tool_LDADD = ../jnlib/libjnlib.a \
../common/libcommon.a ../common/libsimple-pwquery.a \
gpg_protect_tool_LDADD = ../common/libsimple-pwquery.a \
../jnlib/libjnlib.a ../common/libcommon.a \
$(LIBGCRYPT_LIBS) -lgpg-error @LIBINTL@
if HAVE_W32_SYSTEM
gpg_protect_tool_LDADD += -lwsock32
endif
gpg_preset_passphrase_SOURCES = \
preset-passphrase.c
gpg_preset_passphrase_LDADD = ../common/libsimple-pwquery.a \
../jnlib/libjnlib.a ../common/libcommon.a \
$(LIBGCRYPT_LIBS) -lgpg-error @LIBINTL@
if HAVE_W32_SYSTEM
gpg_preset_passphrase_LDADD += -lwsock32
endif

View File

@ -63,6 +63,7 @@ struct {
int ignore_cache_for_signing;
int allow_mark_trusted;
int allow_preset_passphrase;
int keep_tty; /* don't switch the TTY (for pinentry) on request */
int keep_display; /* don't switch the DISPLAY (for pinentry) on request */
} opt;

View File

@ -39,7 +39,7 @@ struct cache_item_s {
ITEM next;
time_t created;
time_t accessed;
int ttl; /* max. lifetime given in seonds */
int ttl; /* max. lifetime given in seonds, -1 one means infinite */
int lockcount;
struct secret_data_s *pw;
char key[1];
@ -88,7 +88,8 @@ housekeeping (void)
/* first expire the actual data */
for (r=thecache; r; r = r->next)
{
if (!r->lockcount && r->pw && r->accessed + r->ttl < current)
if (!r->lockcount && r->pw
&& r->ttl >= 0 && r->accessed + r->ttl < current)
{
if (DBG_CACHE)
log_debug (" expired `%s' (%ds after last access)\n",
@ -118,7 +119,7 @@ housekeeping (void)
Expire old and unused entries after 30 minutes */
for (rprev=NULL, r=thecache; r; )
{
if (!r->pw && r->accessed + 60*30 < current)
if (!r->pw && r->ttl >= 0 && r->accessed + 60*30 < current)
{
if (r->lockcount)
{
@ -194,7 +195,7 @@ agent_put_cache (const char *key, const char *data, int ttl)
log_debug ("agent_put_cache `%s'\n", key);
housekeeping ();
if (ttl < 1)
if (ttl == 1)
ttl = opt.def_cache_ttl;
if (!ttl)
return 0;

View File

@ -141,7 +141,7 @@ parse_hexstring (ASSUAN_CONTEXT ctx, const char *string, size_t *len)
/* parse the hash value */
for (p=string, n=0; hexdigitp (p); p++, n++)
;
if (*p)
if (*p != ' ' && *p != '\t' && *p)
return set_error (Parameter_Error, "invalid hexstring");
if ((n&1))
return set_error (Parameter_Error, "odd number of digits");
@ -741,6 +741,64 @@ cmd_passwd (ASSUAN_CONTEXT ctx, char *line)
return map_to_assuan_status (rc);
}
/* PRESET_PASSPHRASE <hexstring_with_keygrip> <timeout> <passwd>
Set the cached passphrase/PIN for the key identified by the keygrip
to passwd for the given time, where -1 means infinite and 0 means
the default (currently only a timeout of -1 is allowed, which means
to never expire it). If passwd is not provided, ask for it via the
pinentry module. */
static int
cmd_preset_passphrase (ASSUAN_CONTEXT ctx, char *line)
{
int rc;
unsigned char grip[20];
char *grip_clear = NULL;
char *passphrase = NULL;
int ttl;
if (!opt.allow_preset_passphrase)
return gpg_error (GPG_ERR_NOT_SUPPORTED);
rc = parse_keygrip (ctx, line, grip);
if (rc)
return rc;
/* FIXME: parse_keygrip should return a tail pointer. */
grip_clear = line;
while (*line && (*line != ' ' && *line != '\t'))
line++;
if (!*line)
return map_to_assuan_status (gpg_error (GPG_ERR_MISSING_VALUE));
*line = '\0';
line++;
while (*line && (*line == ' ' || *line == '\t'))
line++;
/* Currently, only infinite timeouts are allowed. */
ttl = -1;
if (line[0] != '-' || line[1] != '1')
return map_to_assuan_status (gpg_error (GPG_ERR_NOT_IMPLEMENTED));
line++;
line++;
while (!(*line != ' ' && *line != '\t'))
line++;
/* If there is a passphrase, use it. Currently, a passphrase is
required. */
if (*line)
passphrase = line;
else
return map_to_assuan_status (gpg_error (GPG_ERR_NOT_IMPLEMENTED));
rc = agent_put_cache (grip_clear, passphrase, ttl);
if (rc)
log_error ("command preset_passwd failed: %s\n", gpg_strerror (rc));
return map_to_assuan_status (rc);
}
/* SCD <commands to pass to the scdaemon>
@ -837,6 +895,7 @@ register_commands (ASSUAN_CONTEXT ctx)
{ "PKDECRYPT", cmd_pkdecrypt },
{ "GENKEY", cmd_genkey },
{ "GET_PASSPHRASE", cmd_get_passphrase },
{ "PRESET_PASSPHRASE", cmd_preset_passphrase },
{ "CLEAR_PASSPHRASE", cmd_clear_passphrase },
{ "GET_CONFIRMATION", cmd_get_confirmation },
{ "LISTTRUSTED", cmd_listtrusted },

View File

@ -89,6 +89,7 @@ enum cmd_and_opt_values
oIgnoreCacheForSigning,
oAllowMarkTrusted,
oAllowPresetPassphrase,
oKeepTTY,
oKeepDISPLAY
};
@ -141,6 +142,8 @@ static ARGPARSE_OPTS opts[] = {
N_("do not use the PIN cache when signing")},
{ oAllowMarkTrusted, "allow-mark-trusted", 0,
N_("allow clients to mark keys as \"trusted\"")},
{ oAllowPresetPassphrase, "allow-preset-passphrase", 0,
N_("allow presetting passphrase")},
{0}
};
@ -392,6 +395,8 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
case oAllowMarkTrusted: opt.allow_mark_trusted = 1; break;
case oAllowPresetPassphrase: opt.allow_preset_passphrase = 1; break;
default:
return 0; /* not handled */
}

293
agent/preset-passphrase.c Normal file
View File

@ -0,0 +1,293 @@
/* preset-passphrase.c - A tool to preset a passphrase.
* Copyright (C) 2004 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
* GnuPG is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* GnuPG is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <sys/stat.h>
#include <unistd.h>
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
#ifdef HAVE_LANGINFO_CODESET
#include <langinfo.h>
#endif
#ifdef HAVE_DOSISH_SYSTEM
#include <fcntl.h> /* for setmode() */
#endif
#ifdef HAVE_W32_SYSTEM
#include <windows.h> /* To initialize the sockets. fixme */
#endif
#define JNLIB_NEED_LOG_LOGV
#include "agent.h"
#include "minip12.h"
#include "simple-pwquery.h"
#include "i18n.h"
#include "sysutils.h"
enum cmd_and_opt_values
{ aNull = 0,
oVerbose = 'v',
oPassphrase = 'P',
oPreset = 'c',
oForget = 'f',
oNoVerbose = 500,
oHomedir,
aTest };
static const char *opt_homedir;
static const char *opt_passphrase;
static ARGPARSE_OPTS opts[] = {
{ 301, NULL, 0, N_("@Options:\n ") },
{ oVerbose, "verbose", 0, "verbose" },
{ oPassphrase, "passphrase", 2, "|STRING|use passphrase STRING" },
{ oPreset, "preset", 256, "preset passphrase"},
{ oForget, "forget", 256, "forget passphrase"},
{ oHomedir, "homedir", 2, "@" },
{0}
};
static const char *
my_strusage (int level)
{
const char *p;
switch (level)
{
case 11: p = "gpg-preset-passphrase (GnuPG)";
break;
case 13: p = VERSION; break;
case 17: p = PRINTABLE_OS_NAME; break;
case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n");
break;
case 1:
case 40:
p = _("Usage: gpg-preset-passphrase [options] KEYGRIP (-h for help)\n");
break;
case 41:
p = _("Syntax: gpg-preset-passphrase [options] KEYGRIP\n"
"Password cache maintenance\n");
break;
default: p = NULL;
}
return p;
}
static void
i18n_init (void)
{
#ifdef USE_SIMPLE_GETTEXT
set_gettext_file( PACKAGE_GT );
#else
#ifdef ENABLE_NLS
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE_GT, LOCALEDIR);
textdomain (PACKAGE_GT);
#endif
#endif
}
static gpg_error_t
map_spwq_error (int err)
{
switch (err)
{
case 0:
return 0;
case SPWQ_OUT_OF_CORE:
return gpg_error_from_errno (ENOMEM);
case SPWQ_IO_ERROR:
return gpg_error_from_errno (EIO);
case SPWQ_PROTOCOL_ERROR:
return gpg_error (GPG_ERR_PROTOCOL_VIOLATION);
case SPWQ_ERR_RESPONSE:
return gpg_error (GPG_ERR_INV_RESPONSE);
case SPWQ_NO_AGENT:
return gpg_error (GPG_ERR_NO_AGENT);
case SPWQ_SYS_ERROR:
return gpg_error_from_errno (errno);
case SPWQ_GENERAL_ERROR:
default:
return gpg_error (GPG_ERR_GENERAL);
}
}
static void
preset_passphrase (const char *keygrip)
{
int rc;
char *line;
/* FIXME: Use secure memory. */
char passphrase[500];
if (!opt_passphrase)
{
rc = read (0, passphrase, sizeof (passphrase) - 1);
if (rc < 0)
{
log_error ("reading passphrase failed: %s\n",
gpg_strerror (gpg_error_from_errno (errno)));
return;
}
passphrase[rc] = '\0';
line = strchr (passphrase, '\n');
if (line)
{
line--;
if (line > passphrase && line[-1] == '\r')
line--;
*line = '\0';
}
/* FIXME: How to handle empty passwords? */
}
rc = asprintf (&line, "PRESET_PASSPHRASE %s -1 %s\n", keygrip,
opt_passphrase? opt_passphrase : passphrase);
if (rc < 0)
{
log_error ("caching passphrase failed: %s\n",
gpg_strerror (gpg_error_from_errno (errno)));
return;
}
if (!opt_passphrase)
wipememory (passphrase, sizeof (passphrase));
rc = map_spwq_error (simple_query (line));
if (rc)
{
log_error ("caching passphrase failed: %s\n", gpg_strerror (rc));
return;
}
wipememory (line, strlen (line));
free (line);
}
static void
forget_passphrase (const char *keygrip)
{
int rc;
char *line;
rc = asprintf (&line, "CLEAR_PASSPHRASE %s\n", keygrip);
if (rc < 0)
{
log_error ("clearing passphrase failed: %s\n",
gpg_strerror (gpg_error_from_errno (errno)));
return;
}
free (line);
}
int
main (int argc, char **argv)
{
ARGPARSE_ARGS pargs;
int cmd = 0;
const char *keygrip = NULL;
set_strusage (my_strusage);
log_set_prefix ("gpg-preset-passphrase", 1);
/* Try to auto set the character set. */
set_native_charset (NULL);
#ifdef HAVE_W32_SYSTEM
/* Fixme: Need to initialize the Windows sockets: This should be
moved to another place and we should make sure that it won't get
doen twice, like when Pth is used too. */
{
WSADATA wsadat;
WSAStartup (0x202, &wsadat);
}
#endif
i18n_init ();
opt_homedir = default_homedir ();
pargs.argc = &argc;
pargs.argv = &argv;
pargs.flags= 1; /* (do not remove the args) */
while (arg_parse (&pargs, opts) )
{
switch (pargs.r_opt)
{
case oVerbose: opt.verbose++; break;
case oHomedir: opt_homedir = pargs.r.ret_str; break;
case oPreset: cmd = oPreset; break;
case oForget: cmd = oForget; break;
case oPassphrase: opt_passphrase = pargs.r.ret_str; break;
default : pargs.err = 2; break;
}
}
if (log_get_errorcount(0))
exit(2);
if (argc == 1)
keygrip = *argv;
else
usage (1);
if (cmd == oPreset)
preset_passphrase (keygrip);
else if (cmd == oForget)
forget_passphrase (keygrip);
else
log_error ("one of the options --preset or --forget must be given\n");
agent_exit (0);
return 8; /*NOTREACHED*/
}
void
agent_exit (int rc)
{
rc = rc? rc : log_get_errorcount(0)? 2 : 0;
exit (rc);
}

View File

@ -1,3 +1,17 @@
2004-12-21 Werner Koch <wk@g10code.com>
* simple-pwquery.c (agent_open) [W32]: Implement for W32.
(readline) [W32]: Use recv instead of read.
(writen) [W32]: Use send instead of write.
(my_stpcpy): Define a stpcpy replacement so that this file
continues to be self-contained.
(agent_send_all_options) [W32]: Don't call ttyname.
2004-12-21 Marcus Brinkmann <marcus@g10code.de>
* simple-pwquery.h (simple_query): Add prototype.
* simple-pwquery.c (simple_query): New function.
2004-12-21 Werner Koch <wk@g10code.com>
* signal.c (got_fatal_signal, got_usr_signal)

View File

@ -1,5 +1,5 @@
/* simple-pwquery.c - A simple password query cleint for gpg-agent
* Copyright (C) 2002 Free Software Foundation, Inc.
* Copyright (C) 2002, 2004 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@ -40,6 +40,10 @@
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
#ifdef HAVE_W32_SYSTEM
#include "../jnlib/w32-afunix.h"
#endif
#define SIMPLE_PWQUERY_IMPLEMENTATION 1
#include "simple-pwquery.h"
@ -63,6 +67,25 @@
#endif
#ifndef HAVE_STPCPY
static char *
my_stpcpy(char *a,const char *b)
{
while( *b )
*a++ = *b++;
*a = 0;
return (char*)a;
}
#define stpcpy(a,b) my_stpcpy((a), (b))
#endif
/* Write NBYTES of BUF to file descriptor FD. */
static int
writen (int fd, const void *buf, size_t nbytes)
@ -72,7 +95,11 @@ writen (int fd, const void *buf, size_t nbytes)
while (nleft > 0)
{
nwritten = write( fd, buf, nleft );
#ifdef HAVE_W32_SYSTEM
nwritten = send (fd, buf, nleft, 0);
#else
nwritten = write (fd, buf, nleft);
#endif
if (nwritten < 0)
{
if (errno == EINTR)
@ -102,7 +129,11 @@ readline (int fd, char *buf, size_t buflen)
while (nleft > 0)
{
#ifdef HAVE_W32_SYSTEM
int n = recv (fd, buf, nleft, 0);
#else
int n = read (fd, buf, nleft);
#endif
if (n < 0)
{
if (errno == EINTR)
@ -182,8 +213,10 @@ agent_send_all_options (int fd)
}
dft_ttyname = getenv ("GPG_TTY");
#ifndef HAVE_W32_SYSTEM
if ((!dft_ttyname || !*dft_ttyname) && ttyname (0))
dft_ttyname = ttyname (0);
#endif
if (dft_ttyname && *dft_ttyname)
{
if ((rc=agent_send_option (fd, "ttyname", dft_ttyname)))
@ -259,9 +292,6 @@ agent_send_all_options (int fd)
static int
agent_open (int *rfd)
{
#ifdef HAVE_W32_SYSTEM
return SPWQ_NO_AGENT; /* FIXME */
#else
int rc;
int fd;
char *infostr, *p;
@ -286,7 +316,7 @@ agent_open (int *rfd)
strcpy (p, infostr);
infostr = p;
if ( !(p = strchr ( infostr, ':')) || p == infostr
if ( !(p = strchr ( infostr, PATHSEP_C)) || p == infostr
|| (p-infostr)+1 >= sizeof client_addr.sun_path )
{
#ifdef SPWQ_USE_LOGGING
@ -296,7 +326,7 @@ agent_open (int *rfd)
}
*p++ = 0;
while (*p && *p != ':')
while (*p && *p != PATHSEP_C)
p++;
prot = *p? atoi (p+1) : 0;
if ( prot != 1)
@ -306,8 +336,13 @@ agent_open (int *rfd)
#endif
return SPWQ_PROTOCOL_ERROR;
}
if( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 )
#ifdef HAVE_W32_SYSTEM
fd = _w32_sock_new (AF_UNIX, SOCK_STREAM, 0);
#else
fd = socket (AF_UNIX, SOCK_STREAM, 0);
#endif
if (fd == -1)
{
#ifdef SPWQ_USE_LOGGING
log_error ("can't create socket: %s\n", strerror(errno) );
@ -321,7 +356,12 @@ agent_open (int *rfd)
len = (offsetof (struct sockaddr_un, sun_path)
+ strlen(client_addr.sun_path) + 1);
if (connect (fd, (struct sockaddr*)&client_addr, len ) == -1)
#ifdef HAVE_W32_SYSTEM
rc = _w32_sock_connect (fd, (struct sockaddr*)&client_addr, len );
#else
rc = connect (fd, (struct sockaddr*)&client_addr, len );
#endif
if (rc == -1)
{
#ifdef SPWQ_USE_LOGGING
log_error ( _("can't connect to `%s': %s\n"), infostr, strerror (errno));
@ -353,12 +393,11 @@ agent_open (int *rfd)
*rfd = fd;
return 0;
#endif
}
/* Copy text to BUFFER and escape as required. Return a pointer to
the end of the new buffer. NOte that BUFFER must be large enough
the end of the new buffer. Note that BUFFER must be large enough
to keep the entire text; allocataing it 3 times the size of TEXT
is sufficient. */
static char *
@ -505,3 +544,64 @@ simple_pwquery (const char *cacheid,
spwq_free (pw);
return result;
}
/* Perform the simple query QUERY (which must be new-line and 0
terminated) and return the error code. */
int
simple_query (const char *query)
{
int fd = -1;
int nread;
char response[500];
int rc;
rc = agent_open (&fd);
if (rc)
goto leave;
rc = writen (fd, query, strlen (query));
if (rc)
goto leave;
/* get response */
nread = readline (fd, response, 499);
if (nread < 0)
{
rc = -nread;
goto leave;
}
if (nread < 3)
{
rc = SPWQ_PROTOCOL_ERROR;
goto leave;
}
if (response[0] == 'O' && response[1] == 'K')
/* OK, do nothing. */;
else if ((nread > 7 && !memcmp (response, "ERR 111", 7)
&& (response[7] == ' ' || response[7] == '\n') )
|| ((nread > 4 && !memcmp (response, "ERR ", 4)
&& (strtoul (response+4, NULL, 0) & 0xffff) == 99)) )
{
/* 111 is the old Assuan code for canceled which might still
be in use by old installations. 99 is GPG_ERR_CANCELED as
used by modern gpg-agents; 0xffff is used to mask out the
error source. */
#ifdef SPWQ_USE_LOGGING
log_info (_("canceled by user\n") );
#endif
}
else
{
#ifdef SPWQ_USE_LOGGING
log_error (_("problem with the agent\n"));
#endif
rc = SPWQ_ERR_RESPONSE;
}
leave:
if (fd != -1)
close (fd);
return rc;
}

View File

@ -57,6 +57,9 @@ char *simple_pwquery (const char *cacheid,
const char *description,
int *errorcode);
/* Perform the simple query QUERY (which must be new-line and 0
terminated) and return the error code. */
int simple_query (const char *query);
#define SPWQ_OUT_OF_CORE 1
#define SPWQ_IO_ERROR 2

View File

@ -1,3 +1,9 @@
2004-12-21 Werner Koch <wk@g10code.com>
* gnupg-badge-openpgp.eps, gnupg-badge-openpgp.jpg: New
* gnupg.texi: Add a logo.
* sysnotes.texi: New.
2004-11-05 Werner Koch <wk@g10code.com>
* debugging.texi (Common Problems): Curses pinentry problem.

View File

@ -1,4 +1,4 @@
# Copyright (C) 2002 Free Software Foundation, Inc.
# Copyright (C) 2002, 2004 Free Software Foundation, Inc.
#
# This file is part of GnuPG.
#
@ -18,11 +18,14 @@
## Process this file with automake to produce Makefile.in
EXTRA_DIST = gnupg-badge-openpgp.eps gnupg-badge-openpgp.jpg
info_TEXINFOS = gnupg.texi
gnupg_TEXINFOS = \
gpg.texi gpgsm.texi gpg-agent.texi scdaemon.texi assuan.texi \
tools.texi debugging.texi glossary.texi contrib.texi gpl.texi
tools.texi debugging.texi glossary.texi contrib.texi gpl.texi \
sysnotes.texi
DISTCLEANFILES = gnupg.tmp gnupg.ops

7798
doc/gnupg-badge-openpgp.eps Normal file

File diff suppressed because it is too large Load Diff

BIN
doc/gnupg-badge-openpgp.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

View File

@ -82,8 +82,16 @@ Boston, MA 02111-1307 USA
@title Using the GNU Privacy Guard
@subtitle Version @value{VERSION}
@subtitle @value{UPDATED}
@sp 6
@image{gnupg-badge-openpgp,8cm,,The GnuPG Logo}
@sp 6
@author Werner Koch @code{(wk@@gnupg.org)}
@page
@vskip 0pt plus 1filll
@copyrightnotice{}
@ -111,6 +119,7 @@ the administration and the architecture.
Developer information
* Assuan:: Description of the Assuan protocol.
* System Notes:: Notes pertaining to certain OSes.
Miscellaneous
@ -133,6 +142,7 @@ Indices
@include scdaemon.texi
@include assuan.texi
@include sysnotes.texi
@include tools.texi
@include debugging.texi

View File

@ -135,7 +135,7 @@ below the home directory of the user.
Set the name of the home directory to @var{dir}. If his option is not
used, the home directory defaults to @file{~/.gnupg}. It is only
recognized when given on the command line. It also overrides any home
directory stated through the environment variable @var{GNUPGHOME} or
directory stated through the environment variable @env{GNUPGHOME} or
(on W32 systems) by means on the Registry entry
@var{HKCU\Software\GNU\GnuPG:HomeDir}.

View File

@ -241,7 +241,7 @@ below the home directory of the user.
Set the name of the home directory to @var{dir}. If his option is not
used, the home directory defaults to @file{~/.gnupg}. It is only
recognized when given on the command line. It also overrides any home
directory stated through the environment variable @var{GNUPGHOME} or
directory stated through the environment variable @env{GNUPGHOME} or
(on W32 systems) by means on the Registry entry
@var{HKCU\Software\GNU\GnuPG:HomeDir}.

View File

@ -86,7 +86,7 @@ below the home directory of the user.
Set the name of the home directory to @var{dir}. If his option is not
used, the home directory defaults to @file{~/.gnupg}. It is only
recognized when given on the command line. It also overrides any home
directory stated through the environment variable @var{GNUPGHOME} or
directory stated through the environment variable @env{GNUPGHOME} or
(on W32 systems) by means on the Registry entry
@var{HKCU\Software\GNU\GnuPG:HomeDir}.

107
doc/sysnotes.texi Normal file
View File

@ -0,0 +1,107 @@
@c Copyright (C) 2004 Free Software Foundation, Inc.
@c This is part of the GnuPG manual.
@c For copying conditions, see the file gnupg.texi.
@node System Notes
@chapter Notes pertaining to certain OSes.
GnuPG has been developed on GNU/Linux systems and is know to work on
almost all Free OSes. All modern POSIX systems should be supproted
right now, however there are probably a lot of smaller glitches we need
to fix first. The major problem areas are:
@itemize
@item
For logging to sockets and other internal operations the
@code{fopencookie} function (@code{funopen} under *BSD) is used. This
is a very convient function which makes it possible to create outputs in
a structures and easy maintainable way. The drawback however is that
most proprietary OSes don't support this function. At g10@tie{}Code we
have looked into several ways on how to overcome this limitation but no
sufficiently easy and maintainable way has been found. Porting
@emph{glibc} to a general POSIX system is of course an option and would
make writing portable software much easier; this it has not yet been
done and the system administrator wouldneed to cope with the GNU
specific admin things in addition to the generic ones of his system.
We have now settled to use explicit stdio wrappers with a functionality
similar to funopen. Although the code for this has already been written
(@emph{libestream}), we have not yet changed GnuPG to use it.
This means that on systems not supporting either @code{funopen} or
@code{fopencookie}, logging to a socket won't work, prompts are not
formatted as pretty as theyshould be and @command{gpgsm}'s
@code{LISTKEYS} Assuan command does not work.
@item
We are planning to use file descriptor passing for interprocess
communication. This will allow us save a lot of resources and improve
performance of certain operations a lot. Systems not supporting this
won't gain these benefits but we try to keep them working the satndard
way as it is done today.
@item
We require more or less full POSIX compatibility. This has been
arround for 15 years now and thus we don't believe it makes sense to
support non POSIX systems anymore. Well, we of course the usual
workarounds for near POSIX systems well be applied.
There is one exception of this rule: Systems based the Microsoft Windows
API (called here @emph{W32}) will be supported to some extend.
@end itemize
@menu
* W32 Notes:: Microsoft Windows Notes
@end menu
@node W32 Notes
@section Microsoft Windows Notes
The port to Microsoft Windows based OSes is pretty new and has some
limitations we might remove over time. Note, that we have not yet done
any security audit and you should not use any valuable private key. In
particular, @strong{using it on a box with more than one user, might
lead to a key compromise}.
@noindent
Current limitations are:
@itemize
@item
The @code{LISTKEYS} Assuan command of @command{gpgsm} is not supported.
Using the command line options @option{--list-keys} or
@option{--list-secret-keys} does however work.
@item
No support for CRL checks. By default the option
@option{--disable-crl-checks} has been turned on and the log will show
an appropriate warning message. The reason for this is that the
separate CRL checking daemin (@command{dirmngr}) has not been ported to
W32.
@item
@command{gpgconf} does not create backup files, so in case of trouble
your configuration file might get lost.
@item
@command{watchgnupg} is not available. Logging to sockets is not
possible.
@item
The periodical smartcard status checking done by @command{scdaemon} is
not yet supported.
@item
Detached running of the gpg-agent is not directly supported. It needs
to be started in a console and left alone then.
@end itemize

View File

@ -12,10 +12,11 @@ GnuPG comes with a couple of smaller tools:
* addgnupghome:: Create .gnupg home directories.
* gpgconf:: Modify .gnupg home directories.
* gpgsm-gencert.sh:: Generate an X.509 certificate request.
* gpg-preset-passphrase:: Put a passphrase into the cache.
@end menu
@c
@c WATHCGNUPG
@c WATCHGNUPG
@c
@node watchgnupg
@section Read logs from a socket
@ -593,3 +594,504 @@ whicl will be printed to stdout.
@c
@c GPG-PRESET-PASSPHRASE
@c
@node gpg-preset-passphrase
@section Put a passphrase into the cache.
XXXX
The @command{gpgconf} is a utility to automatically and reasonable
safely query and modify configuration files in the @file{.gnupg} home
directory. It is designed not to be invoked manually by the user, but
automatically by graphical user interfaces (GUI).@footnote{Please note
that currently no locking is done, so concurrent access should be
avoided. There are some precautions to avoid corruption with
concurrent usage, but results may be inconsistent and some changes may
get lost. The stateless design makes it difficult to provide more
guarantees.}
@command{gpgconf} provides access to the configuration of one or more
components of the GnuPG system. These components correspond more or
less to the programs that exist in the GnuPG framework, like GnuPG,
GPGSM, DirMngr, etc. But this is not a strict one-to-one
relationship. Not all configuration options are available through
@command{gpgconf}. @command{gpgconf} provides a generic and abstract
method to access the most important configuration options that can
feasibly be controlled via such a mechanism.
@command{gpgconf} can be used to gather and change the options
available in each component, and can also provide their default
values. @command{gpgconf} will give detailed type information that
can be used to restrict the user's input without making an attempt to
commit the changes.
@command{gpgconf} provides the backend of a configuration editor. The
configuration editor would usually be a graphical user interface
program, that allows to display the current options, their default
values, and allows the user to make changes to the options. These
changes can then be made active with @command{gpgconf} again. Such a
program that uses @command{gpgconf} in this way will be called GUI
throughout this section.
@menu
* Invoking gpgconf:: List of all commands and options.
* Format conventions:: Formatting conventions relevant for all commands.
* Listing components:: List all gpgconf components.
* Listing options:: List all options of a component.
* Changing options:: Changing options of a component.
@end menu
@node Invoking gpgconf
@subsection Invoking gpgconf
One of the following commands must be given:
@table @gnupgtabopt
@item --list-components
List all components. This is the default command used if none is
specified.
@item --list-options @var{component}
List all options of the component @var{component}.
@item --change-options @var{component}
Change the options of the component @var{component}.
@end table
The following options may be used:
@table @gnupgtabopt
@c FIXME: Not yet supported.
@c @item -o @var{file}
@c @itemx --output @var{file}
@c Use @var{file} as output file.
@item -v
@itemx --verbose
Outputs additional information while running. Specifically, this
extends numerical field values by human-readable descriptions.
@c FIXME: Not yet supported.
@c @item -n
@c @itemx --dry-run
@c Do not actually change anything. Useful together with
@c @code{--change-options} for testing purposes.
@item -r
@itemx --runtime
Only used together with @code{--change-options}. If one of the
modified options can be changed in a running daemon process, signal
the running daemon to ask it to reparse its configuration file after
changing.
This means that the changes will take effect at run-time, as far as
this is possible. Otherwise, they will take effect at the next start
of the respective backend programs.
@end table
@node Format conventions
@subsection Format conventions
Some lines in the output of @command{gpgconf} contain a list of
colon-separated fields. The following conventions apply:
@itemize @bullet
@item
The GUI program is required to strip off trailing newline and/or
carriage return characters from the output.
@item
@command{gpgconf} will never leave out fields. If a certain version
provides a certain field, this field will always be present in all
@command{gpgconf} versions from that time on.
@item
Future versions of @command{gpgconf} might append fields to the list.
New fields will always be separated from the previously last field by
a colon separator. The GUI should be prepared to parse the last field
it knows about up until a colon or end of line.
@item
Not all fields are defined under all conditions. You are required to
ignore the content of undefined fields.
@end itemize
There are several standard types for the content of a field:
@table @asis
@item verbatim
Some fields contain strings that are not escaped in any way. Such
fields are described to be used @emph{verbatim}. These fields will
never contain a colon character (for obvious reasons). No de-escaping
or other formatting is required to use the field content. This is for
easy parsing of the output, when it is known that the content can
never contain any special characters.
@item percent-escaped
Some fields contain strings that are described to be
@emph{percent-escaped}. Such strings need to be de-escaped before
their content can be presented to the user. A percent-escaped string
is de-escaped by replacing all occurences of @code{%XY} by the byte
that has the hexadecimal value @code{XY}. @code{X} and @code{Y} are
from the set @code{0-9a-f}.
@item localised
Some fields contain strings that are described to be @emph{localised}.
Such strings are translated to the active language and formatted in
the active character set.
@item @w{unsigned number}
Some fields contain an @emph{unsigned number}. This number will
always fit into a 32-bit unsigned integer variable. The number may be
followed by a space, followed by a human readable description of that
value (if the verbose option is used). You should ignore everything
in the field that follows the number.
@item @w{signed number}
Some fields contain a @emph{signed number}. This number will always
fit into a 32-bit signed integer variable. The number may be followed
by a space, followed by a human readable description of that value (if
the verbose option is used). You should ignore everything in the
field that follows the number.
@item option
Some fields contain an @emph{option} argument. The format of an
option argument depends on the type of the option and on some flags:
@table @asis
@item no argument
The simplest case is that the option does not take an argument at all
(@var{type} @code{0}). Then the option argument is an unsigned number
that specifies how often the option occurs. If the @code{list} flag
is not set, then the only valid number is @code{1}. Options that do
not take an argument never have the @code{default} or @code{optional
arg} flag set.
@item number
If the option takes a number argument (@var{alt-type} is @code{2} or
@code{3}), and it can only occur once (@code{list} flag is not set),
then the option argument is either empty (only allowed if the argument
is optional), or it is a number. A number is a string that begins
with an optional minus character, followed by one or more digits. The
number must fit into an integer variable (unsigned or signed,
depending on @var{alt-type}).
@item number list
If the option takes a number argument and it can occur more than once,
then the option argument is either empty, or it is a comma-separated
list of numbers as described above.
@item string
If the option takes a string argument (@var{alt-type} is 1), and it
can only occur once (@code{list} flag is not set) then the option
argument is either empty (only allowed if the argument is optional),
or it starts with a double quote character (@code{"}) followed by a
percent-escaped string that is the argument value. Note that there is
only a leading double quote character, no trailing one. The double
quote character is only needed to be able to differentiate between no
value and the empty string as value.
@item string list
If the option takes a number argument and it can occur more than once,
then the option argument is either empty, or it is a comma-separated
list of string arguments as described above.
@end table
@end table
The active language and character set are currently determined from
the locale environment of the @command{gpgconf} program.
@c FIXME: Document the active language and active character set. Allow
@c to change it via the command line?
@node Listing components
@subsection Listing components
The command @code{--list-components} will list all components that can
be configured with @command{gpgconf}. Usually, one component will
correspond to one GnuPG-related program and contain the options of
that programs configuration file that can be modified using
@command{gpgconf}. However, this is not necessarily the case. A
component might also be a group of selected options from several
programs, or contain entirely virtual options that have a special
effect rather than changing exactly one option in one configuration
file.
A component is a set of configuration options that semantically belong
together. Furthermore, several changes to a component can be made in
an atomic way with a single operation. The GUI could for example
provide a menu with one entry for each component, or a window with one
tabulator sheet per component.
The command argument @code{--list-components} lists all available
components, one per line. The format of each line is:
@code{@var{name}:@var{description}}
@table @var
@item name
This field contains a name tag of the component. The name tag is used
to specify the component in all communication with @command{gpgconf}.
The name tag is to be used @emph{verbatim}. It is thus not in any
escaped format.
@item description
The @emph{string} in this field contains a human-readable description
of the component. It can be displayed to the user of the GUI for
informational purposes. It is @emph{percent-escaped} and
@emph{localized}.
@end table
Example:
@example
$ gpgconf --list-components
gpg:GPG for OpenPGP
gpg-agent:GPG Agent
scdaemon:Smartcard Daemon
gpgsm:GPG for S/MIME
dirmngr:Directory Manager
@end example
@node Listing options
@subsection Listing options
Every component contains one or more options. Options may be gathered
into option groups to allow the GUI to give visual hints to the user
about which options are related.
The command argument @code{@w{--list-options @var{component}}} lists
all options (and the groups they belong to) in the component
@var{component}, one per line. @var{component} must be the string in
the field @var{name} in the output of the @code{--list-components}
command.
There is one line for each option and each group. First come all
options that are not in any group. Then comes a line describing a
group. Then come all options that belong into each group. Then comes
the next group and so on. There does not need to be any group (and in
this case the output will stop after the last non-grouped option).
The format of each line is:
@code{@var{name}:@var{flags}:@var{level}:@var{description}:@var{type}:@var{alt-type}:@var{argname}:@var{default}:@var{argdef}:@var{value}}
@table @var
@item name
This field contains a name tag for the group or option. The name tag
is used to specify the group or option in all communication with
@command{gpgconf}. The name tag is to be used @emph{verbatim}. It is
thus not in any escaped format.
@item flags
The flags field contains an @emph{unsigned number}. Its value is the
OR-wise combination of the following flag values:
@table @code
@item group (1)
If this flag is set, this is a line describing a group and not an
option.
@end table
The following flag values are only defined for options (that is, if
the @code{group} flag is not used).
@table @code
@item optional arg (2)
If this flag is set, the argument is optional. This is never set for
@var{type} @code{0} (none) options.
@item list (4)
If this flag is set, the option can be given multiple times.
@item runtime (8)
If this flag is set, the option can be changed at runtime.
@item default (16)
If this flag is set, a default value is available.
@item default desc (32)
If this flag is set, a (runtime) default is available. This and the
@code{default} flag are mutually exclusive.
@item no arg desc (64)
If this flag is set, and the @code{optional arg} flag is set, then the
option has a special meaning if no argument is given.
@end table
@item level
This field is defined for options and for groups. It contains an
@emph{unsigned number} that specifies the expert level under which
this group or option should be displayed. The following expert levels
are defined for options (they have analogous meaning for groups):
@table @code
@item basic (0)
This option should always be offered to the user.
@item advanced (1)
This option may be offered to advanced users.
@item expert (2)
This option should only be offered to expert users.
@item invisible (3)
This option should normally never be displayed, not even to expert
users.
@item internal (4)
This option is for internal use only. Ignore it.
@end table
The level of a group will always be the lowest level of all options it
contains.
@item description
This field is defined for options and groups. The @emph{string} in
this field contains a human-readable description of the option or
group. It can be displayed to the user of the GUI for informational
purposes. It is @emph{percent-escaped} and @emph{localized}.
@item type
This field is only defined for options. It contains an @emph{unsigned
number} that specifies the type of the option's argument, if any. The
following types are defined:
Basic types:
@table @code
@item none (0)
No argument allowed.
@item string (1)
An @emph{unformatted string}.
@item int32 (2)
A @emph{signed number}.
@item uint32 (3)
An @emph{unsigned number}.
@end table
Complex types:
@table @code
@item pathname (32)
A @emph{string} that describes the pathname of a file. The file does
not necessarily need to exist.
@item ldap server (33)
A @emph{string} that describes an LDAP server in the format:
@code{@var{hostname}:@var{port}:@var{username}:@var{password}:@var{base_dn}}
@end table
More types will be added in the future. Please see the @var{alt-type}
field for information on how to cope with unknown types.
@item alt-type
This field is identical to @var{type}, except that only the types
@code{0} to @code{31} are allowed. The GUI is expected to present the
user the option in the format specified by @var{type}. But if the
argument type @var{type} is not supported by the GUI, it can still
display the option in the more generic basic type @var{alt-type}. The
GUI must support all the defined basic types to be able to display all
options. More basic types may be added in future versions. If the
GUI encounters a basic type it doesn't support, it should report an
error and abort the operation.
@item argname
This field is only defined for options with an argument type
@var{type} that is not @code{0}. In this case it may contain a
@emph{percent-escaped} and @emph{localised string} that gives a short
name for the argument. The field may also be empty, though, in which
case a short name is not known.
@item default
This field is defined only for options. Its format is that of an
@emph{option argument} (@xref{Format conventions}, for details). If
the default value is empty, then no default is known. Otherwise, the
value specifies the default value for this option. Note that this
field is also meaningful if the option itself does not take a real
argument.
@item argdef
This field is defined only for options for which the @code{optional
arg} flag is set. If the @code{no arg desc} flag is not set, its
format is that of an @emph{option argument} (@xref{Format
conventions}, for details). If the default value is empty, then no
default is known. Otherwise, the value specifies the default value
for this option. If the @code{no arg desc} flag is set, the field is
either empty or contains a description of the effect of this option if
no argument is given. Note that this field is also meaningful if the
option itself does not take a real argument.
@item value
This field is defined only for options. Its format is that of an
@emph{option argument}. If it is empty, then the option is not
explicitely set in the current configuration, and the default applies
(if any). Otherwise, it contains the current value of the option.
Note that this field is also meaningful if the option itself does not
take a real argument.
@end table
@node Changing options
@subsection Changing options
The command @w{@code{--change-options @var{component}}} will attempt
to change the options of the component @var{component} to the
specified values. @var{component} must be the string in the field
@var{name} in the output of the @code{--list-components} command. You
have to provide the options that shall be changed in the following
format on standard input:
@code{@var{name}:@var{flags}:@var{new-value}}
@table @var
@item name
This is the name of the option to change. @var{name} must be the
string in the field @var{name} in the output of the
@code{--list-options} command.
@item flags
The flags field contains an @emph{unsigned number}. Its value is the
OR-wise combination of the following flag values:
@table @code
@item default (16)
If this flag is set, the option is deleted and the default value is
used instead (if applicable).
@end table
@item new-value
The new value for the option. This field is only defined if the
@code{default} flag is not set. The format is that of an @emph{option
argument}. If it is empty (or the field is omitted), the default
argument is used (only allowed if the argument is optional for this
option). Otherwise, the option will be set to the specified value.
@end table
Examples:
To set the force option, which is of basic type @code{none (0)}:
@example
$ echo 'force:0:1' | gpgconf --change-options dirmngr
@end example
To delete the force option:
@example
$ echo 'force:16:' | gpgconf --change-options dirmngr
@end example
The @code{--runtime} option can influence when the changes take
effect.

View File

@ -49,17 +49,18 @@ _w32_sock_connect (int sockfd, struct sockaddr * addr, int addrlen)
struct sockaddr_in myaddr;
struct sockaddr_un * unaddr;
FILE * fp;
int port = 0;
int port;
unaddr = (struct sockaddr_un *)addr;
fp = fopen (unaddr->sun_path, "rb");
if (!fp)
return -1;
return -1;
fscanf (fp, "%d", &port);
fclose (fp);
/* XXX: set errno in this case */
if (port < 0 || port > 65535)
return -1;
return -1;
myaddr.sin_family = AF_INET;
myaddr.sin_port = port;

View File

@ -1,6 +1,7 @@
2004-12-21 Werner Koch <wk@g10code.com>
* gpgsm.c (main): Use default_homedir().
(main) [W32]: Default to disabled CRL checks.
2004-12-20 Werner Koch <wk@g10code.com>

View File

@ -757,6 +757,9 @@ main ( int argc, char **argv)
opt.def_cipher_algoid = "1.2.840.113549.3.7"; /*des-EDE3-CBC*/
opt.homedir = default_homedir ();
#ifdef HAVE_W32_SYSTEM
opt.no_crl_checks = 1;
#endif
/* First check whether we have a config file on the commandline */
orig_argc = argc;

View File

@ -1,3 +1,8 @@
2004-12-21 Werner Koch <wk@g10code.com>
* gpgconf-comp.c (get_config_pathname) [DOSISH]: Detect absolute
pathnames with a drive letter.
2004-12-15 Werner Koch <wk@g10code.com>
* Makefile.am (bin_PROGRAMS) [W32]: Do not build watchgnupg.

View File

@ -1272,7 +1272,13 @@ get_config_pathname (gc_component_t component, gc_backend_t backend)
else
pathname = "";
#ifdef HAVE_DOSISH_SYSTEM
if (!(pathname[0]
&& pathname[1] == ':'
&& (pathname[2] == '/' || pathname[2] == '\\')))
#else
if (pathname[0] != '/')
#endif
gc_error (1, 0, "Option %s, needed by backend %s, is not absolute",
gc_backend[backend].option_config_filename,
gc_backend[backend].name);