mirror of git://git.gnupg.org/gnupg.git
Lock scdaemon to CCID if once found.
This solves a problem where ccid was used, the card unplugged and then scdaemon tries to find a new (plugged in) reader and thus will eventually try PC/SC over and over again. Also added an explicit --kill command to gpgconf.
This commit is contained in:
parent
90dcc0c3ad
commit
7c03c8cc65
|
@ -61,7 +61,7 @@ watchgnupg --force ~/.gnupg/S.log
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
This starts it on the current terminal for listening on the socket
|
This starts it on the current terminal for listening on the socket
|
||||||
@file{~/.gnupg/S.log}.
|
@file{~/.gnupg/S.log}.
|
||||||
|
|
||||||
@mansect options
|
@mansect options
|
||||||
@noindent
|
@noindent
|
||||||
|
@ -69,7 +69,7 @@ This starts it on the current terminal for listening on the socket
|
||||||
|
|
||||||
@table @gnupgtabopt
|
@table @gnupgtabopt
|
||||||
|
|
||||||
@item --force
|
@item --force
|
||||||
@opindex force
|
@opindex force
|
||||||
Delete an already existing socket file.
|
Delete an already existing socket file.
|
||||||
|
|
||||||
|
@ -129,9 +129,9 @@ name for remote debugging.
|
||||||
|
|
||||||
@mansect see also
|
@mansect see also
|
||||||
@ifset isman
|
@ifset isman
|
||||||
@command{gpg}(1),
|
@command{gpg}(1),
|
||||||
@command{gpgsm}(1),
|
@command{gpgsm}(1),
|
||||||
@command{gpg-agent}(1),
|
@command{gpg-agent}(1),
|
||||||
@command{scdaemon}(1)
|
@command{scdaemon}(1)
|
||||||
@end ifset
|
@end ifset
|
||||||
@include see-also-note.texi
|
@include see-also-note.texi
|
||||||
|
@ -150,7 +150,7 @@ name for remote debugging.
|
||||||
@node addgnupghome
|
@node addgnupghome
|
||||||
@section Create .gnupg home directories.
|
@section Create .gnupg home directories.
|
||||||
@ifset manverb
|
@ifset manverb
|
||||||
.B addgnupghome
|
.B addgnupghome
|
||||||
\- Create .gnupg home directories
|
\- Create .gnupg home directories
|
||||||
@end ifset
|
@end ifset
|
||||||
|
|
||||||
|
@ -197,7 +197,7 @@ addgnupghome account1 account2 ... accountn
|
||||||
.br
|
.br
|
||||||
.B gpgconf
|
.B gpgconf
|
||||||
.RI [ options ]
|
.RI [ options ]
|
||||||
.B \-\-list-options
|
.B \-\-list-options
|
||||||
.I component
|
.I component
|
||||||
.br
|
.br
|
||||||
.B gpgconf
|
.B gpgconf
|
||||||
|
@ -301,10 +301,17 @@ is given, check that file instead.
|
||||||
|
|
||||||
@item --reload [@var{component}]
|
@item --reload [@var{component}]
|
||||||
@opindex reload
|
@opindex reload
|
||||||
Reload all or the given component. This is basically the sam as sending
|
Reload all or the given component. This is basically the same as sending
|
||||||
a SIGHUP to the component. Components which don't support reloading are
|
a SIGHUP to the component. Components which don't support reloading are
|
||||||
ignored.
|
ignored.
|
||||||
|
|
||||||
|
@item --kill [@var{component}]
|
||||||
|
@opindex kill
|
||||||
|
Kill the given component. Components which support killing are
|
||||||
|
gpg-agent and scdaemon. Components which don't support reloading are
|
||||||
|
ignored. Note that as of now reload and kill have the same effect for
|
||||||
|
scdaemon.
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
|
||||||
|
@ -570,7 +577,7 @@ configuration file. It is @emph{percent-escaped}.
|
||||||
|
|
||||||
@item line
|
@item line
|
||||||
If an error occurred in the configuration file, this field has the line
|
If an error occurred in the configuration file, this field has the line
|
||||||
number of the failing statement in the configuration file.
|
number of the failing statement in the configuration file.
|
||||||
It is an @emph{unsigned number}.
|
It is an @emph{unsigned number}.
|
||||||
|
|
||||||
@item error
|
@item error
|
||||||
|
@ -867,7 +874,7 @@ effect.
|
||||||
@subsection Listing global options
|
@subsection Listing global options
|
||||||
|
|
||||||
Sometimes it is useful for applications to look at the global options
|
Sometimes it is useful for applications to look at the global options
|
||||||
file @file{gpgconf.conf}.
|
file @file{gpgconf.conf}.
|
||||||
The colon separated listing format is record oriented and uses the first
|
The colon separated listing format is record oriented and uses the first
|
||||||
field to identify the record type:
|
field to identify the record type:
|
||||||
|
|
||||||
|
@ -936,9 +943,9 @@ no feature to change the global option file through @command{gpgconf}.
|
||||||
|
|
||||||
@mansect see also
|
@mansect see also
|
||||||
@ifset isman
|
@ifset isman
|
||||||
@command{gpg}(1),
|
@command{gpg}(1),
|
||||||
@command{gpgsm}(1),
|
@command{gpgsm}(1),
|
||||||
@command{gpg-agent}(1),
|
@command{gpg-agent}(1),
|
||||||
@command{scdaemon}(1),
|
@command{scdaemon}(1),
|
||||||
@command{dirmngr}(1)
|
@command{dirmngr}(1)
|
||||||
@end ifset
|
@end ifset
|
||||||
|
@ -989,7 +996,7 @@ applygnupgdefaults
|
||||||
@ifset manverb
|
@ifset manverb
|
||||||
.B gpgsm-gencert.sh
|
.B gpgsm-gencert.sh
|
||||||
\- Generate an X.509 certificate request
|
\- Generate an X.509 certificate request
|
||||||
@end ifset
|
@end ifset
|
||||||
|
|
||||||
@mansect synopsis
|
@mansect synopsis
|
||||||
@ifset manverb
|
@ifset manverb
|
||||||
|
@ -1008,8 +1015,8 @@ which will be printed to stdout.
|
||||||
|
|
||||||
@mansect see also
|
@mansect see also
|
||||||
@ifset isman
|
@ifset isman
|
||||||
@command{gpgsm}(1),
|
@command{gpgsm}(1),
|
||||||
@command{gpg-agent}(1),
|
@command{gpg-agent}(1),
|
||||||
@command{scdaemon}(1)
|
@command{scdaemon}(1)
|
||||||
@end ifset
|
@end ifset
|
||||||
@include see-also-note.texi
|
@include see-also-note.texi
|
||||||
|
@ -1096,7 +1103,7 @@ The following additional options may be used:
|
||||||
@item -v
|
@item -v
|
||||||
@itemx --verbose
|
@itemx --verbose
|
||||||
@opindex verbose
|
@opindex verbose
|
||||||
Output additional information while running.
|
Output additional information while running.
|
||||||
|
|
||||||
@item -P @var{string}
|
@item -P @var{string}
|
||||||
@itemx --passphrase @var{string}
|
@itemx --passphrase @var{string}
|
||||||
|
@ -1108,9 +1115,9 @@ for other users.
|
||||||
|
|
||||||
@mansect see also
|
@mansect see also
|
||||||
@ifset isman
|
@ifset isman
|
||||||
@command{gpg}(1),
|
@command{gpg}(1),
|
||||||
@command{gpgsm}(1),
|
@command{gpgsm}(1),
|
||||||
@command{gpg-agent}(1),
|
@command{gpg-agent}(1),
|
||||||
@command{scdaemon}(1)
|
@command{scdaemon}(1)
|
||||||
@end ifset
|
@end ifset
|
||||||
@include see-also-note.texi
|
@include see-also-note.texi
|
||||||
|
@ -1169,7 +1176,7 @@ The following options may be used:
|
||||||
@item -v
|
@item -v
|
||||||
@itemx --verbose
|
@itemx --verbose
|
||||||
@opindex verbose
|
@opindex verbose
|
||||||
Output additional information while running.
|
Output additional information while running.
|
||||||
|
|
||||||
@item -q
|
@item -q
|
||||||
@item --quiet
|
@item --quiet
|
||||||
|
@ -1186,7 +1193,7 @@ Specify the agent program to be started if none is running.
|
||||||
|
|
||||||
@item -S
|
@item -S
|
||||||
@itemx --raw-socket @var{name}
|
@itemx --raw-socket @var{name}
|
||||||
@opindex S
|
@opindex S
|
||||||
@opindex raw-socket
|
@opindex raw-socket
|
||||||
Connect to socket @var{name} assuming this is an Assuan style server.
|
Connect to socket @var{name} assuming this is an Assuan style server.
|
||||||
Do not run any special initializations or environment checks. This may
|
Do not run any special initializations or environment checks. This may
|
||||||
|
@ -1209,7 +1216,7 @@ connects to the assuan server in extended mode to allow descriptor
|
||||||
passing. This option makes it use the old mode.
|
passing. This option makes it use the old mode.
|
||||||
|
|
||||||
@item --run @var{file}
|
@item --run @var{file}
|
||||||
@opindex run
|
@opindex run
|
||||||
Run the commands from @var{file} at startup and then continue with the
|
Run the commands from @var{file} at startup and then continue with the
|
||||||
regular input method. Note, that commands given on the command line are
|
regular input method. Note, that commands given on the command line are
|
||||||
executed after this file.
|
executed after this file.
|
||||||
|
@ -1251,7 +1258,7 @@ Variables are referenced by prefixing the name with a dollar sign and
|
||||||
optionally include the name in curly braces. The rules for a valid name
|
optionally include the name in curly braces. The rules for a valid name
|
||||||
are identically to those of the standard bourne shell. This is not yet
|
are identically to those of the standard bourne shell. This is not yet
|
||||||
enforced but may be in the future. When used with curly braces no
|
enforced but may be in the future. When used with curly braces no
|
||||||
leading or trailing white space is allowed.
|
leading or trailing white space is allowed.
|
||||||
|
|
||||||
If a variable is not found, it is searched in the environment and if
|
If a variable is not found, it is searched in the environment and if
|
||||||
found copied to the table of variables.
|
found copied to the table of variables.
|
||||||
|
@ -1264,7 +1271,7 @@ following functions are available:
|
||||||
@item get
|
@item get
|
||||||
Return a value described by the argument. Available arguments are:
|
Return a value described by the argument. Available arguments are:
|
||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
@item cwd
|
@item cwd
|
||||||
The current working directory.
|
The current working directory.
|
||||||
@item homedir
|
@item homedir
|
||||||
|
@ -1431,7 +1438,7 @@ Print a list of available control commands.
|
||||||
|
|
||||||
@ifset isman
|
@ifset isman
|
||||||
@mansect see also
|
@mansect see also
|
||||||
@command{gpg-agent}(1),
|
@command{gpg-agent}(1),
|
||||||
@command{scdaemon}(1)
|
@command{scdaemon}(1)
|
||||||
@include see-also-note.texi
|
@include see-also-note.texi
|
||||||
@end ifset
|
@end ifset
|
||||||
|
@ -1452,8 +1459,8 @@ Print a list of available control commands.
|
||||||
@mansect synopsis
|
@mansect synopsis
|
||||||
@ifset manverb
|
@ifset manverb
|
||||||
.B dirmngr-client
|
.B dirmngr-client
|
||||||
.RI [ options ]
|
.RI [ options ]
|
||||||
.RI [ certfile | pattern ]
|
.RI [ certfile | pattern ]
|
||||||
@end ifset
|
@end ifset
|
||||||
|
|
||||||
@mansect description
|
@mansect description
|
||||||
|
@ -1478,7 +1485,7 @@ dirmngr-client <@var{acert}
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
Where @var{acert} is one DER encoded (binary) X.509 certificates to be
|
Where @var{acert} is one DER encoded (binary) X.509 certificates to be
|
||||||
tested.
|
tested.
|
||||||
@ifclear isman
|
@ifclear isman
|
||||||
The return value of this command is
|
The return value of this command is
|
||||||
@end ifclear
|
@end ifclear
|
||||||
|
@ -1489,7 +1496,7 @@ The return value of this command is
|
||||||
@end ifset
|
@end ifset
|
||||||
@table @code
|
@table @code
|
||||||
|
|
||||||
@item 0
|
@item 0
|
||||||
The certificate under question is valid; i.e. there is a valid CRL
|
The certificate under question is valid; i.e. there is a valid CRL
|
||||||
available and it is not listed tehre or teh OCSP request returned that
|
available and it is not listed tehre or teh OCSP request returned that
|
||||||
that certificate is valid.
|
that certificate is valid.
|
||||||
|
@ -1673,7 +1680,7 @@ configured with @samp{--enable-symcryptrun} at build time.
|
||||||
@command{symcryptrun} is invoked this way:
|
@command{symcryptrun} is invoked this way:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
symcryptrun --class CLASS --program PROGRAM --keyfile KEYFILE
|
symcryptrun --class CLASS --program PROGRAM --keyfile KEYFILE
|
||||||
[--decrypt | --encrypt] [inputfile]
|
[--decrypt | --encrypt] [inputfile]
|
||||||
@end example
|
@end example
|
||||||
@mancont
|
@mancont
|
||||||
|
@ -1685,12 +1692,12 @@ For decryption vice versa.
|
||||||
@var{CLASS} describes the calling conventions of the external tool.
|
@var{CLASS} describes the calling conventions of the external tool.
|
||||||
Currently it must be given as @samp{confucius}. @var{PROGRAM} is
|
Currently it must be given as @samp{confucius}. @var{PROGRAM} is
|
||||||
the full filename of that external tool.
|
the full filename of that external tool.
|
||||||
|
|
||||||
For the class @samp{confucius} the option @option{--keyfile} is
|
For the class @samp{confucius} the option @option{--keyfile} is
|
||||||
required; @var{keyfile} is the name of a file containing the secret key,
|
required; @var{keyfile} is the name of a file containing the secret key,
|
||||||
which may be protected by a passphrase. For detailed calling
|
which may be protected by a passphrase. For detailed calling
|
||||||
conventions, see the source code.
|
conventions, see the source code.
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
Note, that @command{gpg-agent} must be running before starting
|
Note, that @command{gpg-agent} must be running before starting
|
||||||
@command{symcryptrun}.
|
@command{symcryptrun}.
|
||||||
|
@ -1702,7 +1709,7 @@ The following additional options may be used:
|
||||||
@item -v
|
@item -v
|
||||||
@itemx --verbose
|
@itemx --verbose
|
||||||
@opindex verbose
|
@opindex verbose
|
||||||
Output additional information while running.
|
Output additional information while running.
|
||||||
|
|
||||||
@item -q
|
@item -q
|
||||||
@item --quiet
|
@item --quiet
|
||||||
|
@ -1724,22 +1731,22 @@ information to STDERR.
|
||||||
The possible exit status codes of @command{symcryptrun} are:
|
The possible exit status codes of @command{symcryptrun} are:
|
||||||
|
|
||||||
@table @code
|
@table @code
|
||||||
@item 0
|
@item 0
|
||||||
Success.
|
Success.
|
||||||
@item 1
|
@item 1
|
||||||
Some error occured.
|
Some error occured.
|
||||||
@item 2
|
@item 2
|
||||||
No valid passphrase was provided.
|
No valid passphrase was provided.
|
||||||
@item 3
|
@item 3
|
||||||
The operation was canceled by the user.
|
The operation was canceled by the user.
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@mansect see also
|
@mansect see also
|
||||||
@ifset isman
|
@ifset isman
|
||||||
@command{gpg}(1),
|
@command{gpg}(1),
|
||||||
@command{gpgsm}(1),
|
@command{gpgsm}(1),
|
||||||
@command{gpg-agent}(1),
|
@command{gpg-agent}(1),
|
||||||
@end ifset
|
@end ifset
|
||||||
@include see-also-note.texi
|
@include see-also-note.texi
|
||||||
|
|
||||||
|
@ -1747,8 +1754,8 @@ The possible exit status codes of @command{symcryptrun} are:
|
||||||
@c
|
@c
|
||||||
@c GPG-ZIP
|
@c GPG-ZIP
|
||||||
@c
|
@c
|
||||||
@c The original manpage on which this section is based was written
|
@c The original manpage on which this section is based was written
|
||||||
@c by Colin Tuckley <colin@tuckley.org> and Daniel Leidert
|
@c by Colin Tuckley <colin@tuckley.org> and Daniel Leidert
|
||||||
@c <daniel.leidert@wgdd.de> for the Debian distribution (but may be used by
|
@c <daniel.leidert@wgdd.de> for the Debian distribution (but may be used by
|
||||||
@c others).
|
@c others).
|
||||||
@manpage gpg-zip.1
|
@manpage gpg-zip.1
|
||||||
|
@ -1880,8 +1887,7 @@ gpg-zip --list-archive test1
|
||||||
|
|
||||||
@mansect see also
|
@mansect see also
|
||||||
@ifset isman
|
@ifset isman
|
||||||
@command{gpg}(1),
|
@command{gpg}(1),
|
||||||
@command{tar}(1),
|
@command{tar}(1),
|
||||||
@end ifset
|
@end ifset
|
||||||
@include see-also-note.texi
|
@include see-also-note.texi
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
2011-02-23 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* apdu.c (apdu_open_reader): Lock in to CCID if used once.
|
||||||
|
|
||||||
2011-01-25 NIIBE Yutaka <gniibe@fsij.org>,
|
2011-01-25 NIIBE Yutaka <gniibe@fsij.org>,
|
||||||
Grant Olson <kgo@grant-olson.net> (wk)
|
Grant Olson <kgo@grant-olson.net> (wk)
|
||||||
|
|
||||||
|
|
18
scd/apdu.c
18
scd/apdu.c
|
@ -1,5 +1,6 @@
|
||||||
/* apdu.c - ISO 7816 APDU functions and low level I/O
|
/* apdu.c - ISO 7816 APDU functions and low level I/O
|
||||||
* Copyright (C) 2003, 2004, 2008, 2009, 2010 Free Software Foundation, Inc.
|
* Copyright (C) 2003, 2004, 2008, 2009, 2010,
|
||||||
|
* 2011 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
|
@ -2355,12 +2356,25 @@ apdu_open_reader (const char *portstr, int *r_no_service)
|
||||||
#ifdef HAVE_LIBUSB
|
#ifdef HAVE_LIBUSB
|
||||||
if (!opt.disable_ccid)
|
if (!opt.disable_ccid)
|
||||||
{
|
{
|
||||||
|
static int once_available;
|
||||||
int i;
|
int i;
|
||||||
const char *s;
|
const char *s;
|
||||||
|
|
||||||
slot = open_ccid_reader (portstr);
|
slot = open_ccid_reader (portstr);
|
||||||
if (slot != -1)
|
if (slot != -1)
|
||||||
return slot; /* got one */
|
{
|
||||||
|
once_available = 1;
|
||||||
|
return slot; /* got one */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we ever loaded successfully loaded a CCID reader we never
|
||||||
|
want to fallback to another driver. This solves a problem
|
||||||
|
where ccid was used, the card unplugged and then scdaemon
|
||||||
|
tries to find a new reader and will eventually try PC/SC over
|
||||||
|
and over again. To reset this flag "gpgconf --kill scdaemon"
|
||||||
|
can be used. */
|
||||||
|
if (once_available)
|
||||||
|
return -1;
|
||||||
|
|
||||||
/* If a CCID reader specification has been given, the user does
|
/* If a CCID reader specification has been given, the user does
|
||||||
not want a fallback to other drivers. */
|
not want a fallback to other drivers. */
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
2011-02-23 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* gpgconf.c: Add command --kill.
|
||||||
|
* gpgconf-comp.c (gc_component_kill): New.
|
||||||
|
(gpg_agent_runtime_change, scdaemon_runtime_change): Add kill flag.
|
||||||
|
|
||||||
2011-02-03 Werner Koch <wk@g10code.com>
|
2011-02-03 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* watchgnupg.c (print_version): Update copyright year.
|
* watchgnupg.c (print_version): Update copyright year.
|
||||||
|
@ -1247,7 +1253,7 @@
|
||||||
|
|
||||||
|
|
||||||
Copyright 2003, 2004, 2005, 2006, 2007, 2008,
|
Copyright 2003, 2004, 2005, 2006, 2007, 2008,
|
||||||
2009, 2010 Free Software Foundation, Inc.
|
2009, 2010, 2011 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is free software; as a special exception the author gives
|
This file is free software; as a special exception the author gives
|
||||||
unlimited permission to copy and/or distribute it, with or without
|
unlimited permission to copy and/or distribute it, with or without
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* gpgconf-comp.c - Configuration utility for GnuPG.
|
/* gpgconf-comp.c - Configuration utility for GnuPG.
|
||||||
* Copyright (C) 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
* Copyright (C) 2004, 2007, 2008, 2009, 2010,
|
||||||
|
* 2011 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
|
@ -104,8 +105,8 @@ gc_error (int status, int errnum, const char *fmt, ...)
|
||||||
|
|
||||||
|
|
||||||
/* Forward declaration. */
|
/* Forward declaration. */
|
||||||
static void gpg_agent_runtime_change (void);
|
static void gpg_agent_runtime_change (int killflag);
|
||||||
static void scdaemon_runtime_change (void);
|
static void scdaemon_runtime_change (int killflag);
|
||||||
|
|
||||||
/* Backend configuration. Backends are used to decide how the default
|
/* Backend configuration. Backends are used to decide how the default
|
||||||
and current value of an option can be determined, and how the
|
and current value of an option can be determined, and how the
|
||||||
|
@ -163,8 +164,9 @@ static struct
|
||||||
available. */
|
available. */
|
||||||
char module_name;
|
char module_name;
|
||||||
|
|
||||||
/* The runtime change callback. */
|
/* The runtime change callback. If KILLFLAG is true the component
|
||||||
void (*runtime_change) (void);
|
is killed and not just reloaded. */
|
||||||
|
void (*runtime_change) (int killflag);
|
||||||
|
|
||||||
/* The option name for the configuration filename of this backend.
|
/* The option name for the configuration filename of this backend.
|
||||||
This must be an absolute filename. It can be an option from a
|
This must be an absolute filename. It can be an option from a
|
||||||
|
@ -182,13 +184,13 @@ static struct
|
||||||
NULL, "gpgconf-gpg.conf" },
|
NULL, "gpgconf-gpg.conf" },
|
||||||
{ "GPGSM", "gpgsm", GNUPG_MODULE_NAME_GPGSM,
|
{ "GPGSM", "gpgsm", GNUPG_MODULE_NAME_GPGSM,
|
||||||
NULL, "gpgconf-gpgsm.conf" },
|
NULL, "gpgconf-gpgsm.conf" },
|
||||||
{ "GPG Agent", "gpg-agent", GNUPG_MODULE_NAME_AGENT,
|
{ "GPG Agent", "gpg-agent", GNUPG_MODULE_NAME_AGENT,
|
||||||
gpg_agent_runtime_change, "gpgconf-gpg-agent.conf" },
|
gpg_agent_runtime_change, "gpgconf-gpg-agent.conf" },
|
||||||
{ "SCDaemon", "scdaemon", GNUPG_MODULE_NAME_SCDAEMON,
|
{ "SCDaemon", "scdaemon", GNUPG_MODULE_NAME_SCDAEMON,
|
||||||
scdaemon_runtime_change, "gpgconf-scdaemon.conf" },
|
scdaemon_runtime_change, "gpgconf-scdaemon.conf" },
|
||||||
{ "DirMngr", "dirmngr", GNUPG_MODULE_NAME_DIRMNGR,
|
{ "DirMngr", "dirmngr", GNUPG_MODULE_NAME_DIRMNGR,
|
||||||
NULL, "gpgconf-dirmngr.conf" },
|
NULL, "gpgconf-dirmngr.conf" },
|
||||||
{ "DirMngr LDAP Server List", NULL, 0,
|
{ "DirMngr LDAP Server List", NULL, 0,
|
||||||
NULL, "ldapserverlist-file", "LDAP Server" },
|
NULL, "ldapserverlist-file", "LDAP Server" },
|
||||||
{ "Pinentry", "pinentry", GNUPG_MODULE_NAME_PINENTRY,
|
{ "Pinentry", "pinentry", GNUPG_MODULE_NAME_PINENTRY,
|
||||||
NULL, "gpgconf-pinentry.conf" },
|
NULL, "gpgconf-pinentry.conf" },
|
||||||
|
@ -405,17 +407,17 @@ struct gc_option
|
||||||
/* A gettext domain in which the following description can be found.
|
/* A gettext domain in which the following description can be found.
|
||||||
If this is NULL, then DESC is not translated. Valid for groups
|
If this is NULL, then DESC is not translated. Valid for groups
|
||||||
and options.
|
and options.
|
||||||
|
|
||||||
Note that we try to keep the description of groups within the
|
Note that we try to keep the description of groups within the
|
||||||
gnupg domain.
|
gnupg domain.
|
||||||
|
|
||||||
IMPORTANT: If you add a new domain please make sure to add a code
|
IMPORTANT: If you add a new domain please make sure to add a code
|
||||||
set switching call to the function my_dgettext further below. */
|
set switching call to the function my_dgettext further below. */
|
||||||
const char *desc_domain;
|
const char *desc_domain;
|
||||||
|
|
||||||
/* A gettext description for this group or option. If it starts
|
/* A gettext description for this group or option. If it starts
|
||||||
with a '|', then the string up to the next '|' describes the
|
with a '|', then the string up to the next '|' describes the
|
||||||
argument, and the description follows the second '|'.
|
argument, and the description follows the second '|'.
|
||||||
|
|
||||||
In general enclosing these description in N_() is not required
|
In general enclosing these description in N_() is not required
|
||||||
because the description should be identical to the one in the
|
because the description should be identical to the one in the
|
||||||
|
@ -516,7 +518,7 @@ static gc_option_t gc_options_gpg_agent[] =
|
||||||
GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
|
GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC,
|
||||||
"gnupg", N_("Options controlling the security") },
|
"gnupg", N_("Options controlling the security") },
|
||||||
{ "default-cache-ttl", GC_OPT_FLAG_RUNTIME,
|
{ "default-cache-ttl", GC_OPT_FLAG_RUNTIME,
|
||||||
GC_LEVEL_BASIC, "gnupg",
|
GC_LEVEL_BASIC, "gnupg",
|
||||||
"|N|expire cached PINs after N seconds",
|
"|N|expire cached PINs after N seconds",
|
||||||
GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
|
GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
|
||||||
{ "default-cache-ttl-ssh", GC_OPT_FLAG_RUNTIME,
|
{ "default-cache-ttl-ssh", GC_OPT_FLAG_RUNTIME,
|
||||||
|
@ -528,7 +530,7 @@ static gc_option_t gc_options_gpg_agent[] =
|
||||||
N_("|N|set maximum PIN cache lifetime to N seconds"),
|
N_("|N|set maximum PIN cache lifetime to N seconds"),
|
||||||
GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
|
GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
|
||||||
{ "max-cache-ttl-ssh", GC_OPT_FLAG_RUNTIME,
|
{ "max-cache-ttl-ssh", GC_OPT_FLAG_RUNTIME,
|
||||||
GC_LEVEL_EXPERT, "gnupg",
|
GC_LEVEL_EXPERT, "gnupg",
|
||||||
N_("|N|set maximum SSH key lifetime to N seconds"),
|
N_("|N|set maximum SSH key lifetime to N seconds"),
|
||||||
GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
|
GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
|
||||||
{ "ignore-cache-for-signing", GC_OPT_FLAG_RUNTIME,
|
{ "ignore-cache-for-signing", GC_OPT_FLAG_RUNTIME,
|
||||||
|
@ -544,16 +546,16 @@ static gc_option_t gc_options_gpg_agent[] =
|
||||||
{ "Passphrase policy",
|
{ "Passphrase policy",
|
||||||
GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
|
GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
|
||||||
"gnupg", N_("Options enforcing a passphrase policy") },
|
"gnupg", N_("Options enforcing a passphrase policy") },
|
||||||
{ "enforce-passphrase-constraints", GC_OPT_FLAG_RUNTIME,
|
{ "enforce-passphrase-constraints", GC_OPT_FLAG_RUNTIME,
|
||||||
GC_LEVEL_EXPERT, "gnupg",
|
GC_LEVEL_EXPERT, "gnupg",
|
||||||
N_("do not allow to bypass the passphrase policy"),
|
N_("do not allow to bypass the passphrase policy"),
|
||||||
GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
|
GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
|
||||||
{ "min-passphrase-len", GC_OPT_FLAG_RUNTIME,
|
{ "min-passphrase-len", GC_OPT_FLAG_RUNTIME,
|
||||||
GC_LEVEL_ADVANCED, "gnupg",
|
GC_LEVEL_ADVANCED, "gnupg",
|
||||||
N_("|N|set minimal required length for new passphrases to N"),
|
N_("|N|set minimal required length for new passphrases to N"),
|
||||||
GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
|
GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
|
||||||
{ "min-passphrase-nonalpha", GC_OPT_FLAG_RUNTIME,
|
{ "min-passphrase-nonalpha", GC_OPT_FLAG_RUNTIME,
|
||||||
GC_LEVEL_EXPERT, "gnupg",
|
GC_LEVEL_EXPERT, "gnupg",
|
||||||
N_("|N|require at least N non-alpha characters for a new passphrase"),
|
N_("|N|require at least N non-alpha characters for a new passphrase"),
|
||||||
GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
|
GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
|
||||||
{ "check-passphrase-pattern", GC_OPT_FLAG_RUNTIME,
|
{ "check-passphrase-pattern", GC_OPT_FLAG_RUNTIME,
|
||||||
|
@ -561,11 +563,11 @@ static gc_option_t gc_options_gpg_agent[] =
|
||||||
"gnupg", N_("|FILE|check new passphrases against pattern in FILE"),
|
"gnupg", N_("|FILE|check new passphrases against pattern in FILE"),
|
||||||
GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG_AGENT },
|
GC_ARG_TYPE_FILENAME, GC_BACKEND_GPG_AGENT },
|
||||||
{ "max-passphrase-days", GC_OPT_FLAG_RUNTIME,
|
{ "max-passphrase-days", GC_OPT_FLAG_RUNTIME,
|
||||||
GC_LEVEL_EXPERT, "gnupg",
|
GC_LEVEL_EXPERT, "gnupg",
|
||||||
N_("|N|expire the passphrase after N days"),
|
N_("|N|expire the passphrase after N days"),
|
||||||
GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
|
GC_ARG_TYPE_UINT32, GC_BACKEND_GPG_AGENT },
|
||||||
{ "enable-passphrase-history", GC_OPT_FLAG_RUNTIME,
|
{ "enable-passphrase-history", GC_OPT_FLAG_RUNTIME,
|
||||||
GC_LEVEL_EXPERT, "gnupg",
|
GC_LEVEL_EXPERT, "gnupg",
|
||||||
N_("do not allow the reuse of old passphrases"),
|
N_("do not allow the reuse of old passphrases"),
|
||||||
GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
|
GC_ARG_TYPE_NONE, GC_BACKEND_GPG_AGENT },
|
||||||
|
|
||||||
|
@ -686,7 +688,7 @@ static gc_option_t gc_options_gpg[] =
|
||||||
(GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_NO_CHANGE), GC_LEVEL_INVISIBLE,
|
(GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_NO_CHANGE), GC_LEVEL_INVISIBLE,
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
|
GC_ARG_TYPE_STRING, GC_BACKEND_GPG },
|
||||||
|
|
||||||
|
|
||||||
{ "Debug",
|
{ "Debug",
|
||||||
GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
|
GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED,
|
||||||
|
@ -849,7 +851,7 @@ static gc_option_t gc_options_dirmngr[] =
|
||||||
{ "csh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
|
{ "csh", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC,
|
||||||
"dirmngr", "csh-style command output",
|
"dirmngr", "csh-style command output",
|
||||||
GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
|
GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR },
|
||||||
|
|
||||||
{ "Configuration",
|
{ "Configuration",
|
||||||
GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
|
GC_OPT_FLAG_GROUP, GC_LEVEL_EXPERT,
|
||||||
"gnupg", N_("Options controlling the configuration") },
|
"gnupg", N_("Options controlling the configuration") },
|
||||||
|
@ -1047,17 +1049,17 @@ struct error_line_s
|
||||||
|
|
||||||
/* Engine specific support. */
|
/* Engine specific support. */
|
||||||
static void
|
static void
|
||||||
gpg_agent_runtime_change (void)
|
gpg_agent_runtime_change (int killflag)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
const char *pgmname;
|
const char *pgmname;
|
||||||
const char *argv[2];
|
const char *argv[2];
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
|
pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT);
|
||||||
argv[0] = "reloadagent";
|
argv[0] = killflag? "KILLAGENT" : "RELOADAGENT";
|
||||||
argv[1] = NULL;
|
argv[1] = NULL;
|
||||||
|
|
||||||
err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
|
err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
|
||||||
if (!err)
|
if (!err)
|
||||||
err = gnupg_wait_process (pgmname, pid, 1, NULL);
|
err = gnupg_wait_process (pgmname, pid, 1, NULL);
|
||||||
|
@ -1069,13 +1071,15 @@ gpg_agent_runtime_change (void)
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
scdaemon_runtime_change (void)
|
scdaemon_runtime_change (int killflag)
|
||||||
{
|
{
|
||||||
gpg_error_t err;
|
gpg_error_t err;
|
||||||
const char *pgmname;
|
const char *pgmname;
|
||||||
const char *argv[6];
|
const char *argv[6];
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
|
(void)killflag; /* For scdaemon kill and reload are synonyms. */
|
||||||
|
|
||||||
/* We use "GETINFO app_running" to see whether the agent is already
|
/* We use "GETINFO app_running" to see whether the agent is already
|
||||||
running and kill it only in this case. This avoids an explicit
|
running and kill it only in this case. This avoids an explicit
|
||||||
starting of the agent in case it is not yet running. There is
|
starting of the agent in case it is not yet running. There is
|
||||||
|
@ -1088,7 +1092,7 @@ scdaemon_runtime_change (void)
|
||||||
argv[3] = "scd killscd";
|
argv[3] = "scd killscd";
|
||||||
argv[4] = "/end";
|
argv[4] = "/end";
|
||||||
argv[5] = NULL;
|
argv[5] = NULL;
|
||||||
|
|
||||||
err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
|
err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid);
|
||||||
if (!err)
|
if (!err)
|
||||||
err = gnupg_wait_process (pgmname, pid, 1, NULL);
|
err = gnupg_wait_process (pgmname, pid, 1, NULL);
|
||||||
|
@ -1099,6 +1103,35 @@ scdaemon_runtime_change (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Unconditionally restart COMPONENT. */
|
||||||
|
void
|
||||||
|
gc_component_kill (int component)
|
||||||
|
{
|
||||||
|
int runtime[GC_BACKEND_NR];
|
||||||
|
gc_option_t *option;
|
||||||
|
gc_backend_t backend;
|
||||||
|
|
||||||
|
/* Set a flag for the backends to be reloaded. */
|
||||||
|
for (backend = 0; backend < GC_BACKEND_NR; backend++)
|
||||||
|
runtime[backend] = 0;
|
||||||
|
|
||||||
|
if (component >= 0)
|
||||||
|
{
|
||||||
|
assert (component < GC_COMPONENT_NR);
|
||||||
|
option = gc_component[component].options;
|
||||||
|
for (; option && option->name; option++)
|
||||||
|
runtime[option->backend] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do the restart for the selected backends. */
|
||||||
|
for (backend = 0; backend < GC_BACKEND_NR; backend++)
|
||||||
|
{
|
||||||
|
if (runtime[backend] && gc_backend[backend].runtime_change)
|
||||||
|
(*gc_backend[backend].runtime_change) (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Unconditionally reload COMPONENT or all components if COMPONENT is -1. */
|
/* Unconditionally reload COMPONENT or all components if COMPONENT is -1. */
|
||||||
void
|
void
|
||||||
gc_component_reload (int component)
|
gc_component_reload (int component)
|
||||||
|
@ -1110,7 +1143,7 @@ gc_component_reload (int component)
|
||||||
/* Set a flag for the backends to be reloaded. */
|
/* Set a flag for the backends to be reloaded. */
|
||||||
for (backend = 0; backend < GC_BACKEND_NR; backend++)
|
for (backend = 0; backend < GC_BACKEND_NR; backend++)
|
||||||
runtime[backend] = 0;
|
runtime[backend] = 0;
|
||||||
|
|
||||||
if (component == -1)
|
if (component == -1)
|
||||||
{
|
{
|
||||||
for (component = 0; component < GC_COMPONENT_NR; component++)
|
for (component = 0; component < GC_COMPONENT_NR; component++)
|
||||||
|
@ -1129,10 +1162,10 @@ gc_component_reload (int component)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do the reload for all selected backends. */
|
/* Do the reload for all selected backends. */
|
||||||
for (backend = 0; backend < GC_BACKEND_NR; backend++)
|
for (backend = 0; backend < GC_BACKEND_NR; backend++)
|
||||||
{
|
{
|
||||||
if (runtime[backend] && gc_backend[backend].runtime_change)
|
if (runtime[backend] && gc_backend[backend].runtime_change)
|
||||||
(*gc_backend[backend].runtime_change) ();
|
(*gc_backend[backend].runtime_change) (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1152,7 +1185,7 @@ my_dgettext (const char *domain, const char *msgid)
|
||||||
{
|
{
|
||||||
static int switched_codeset;
|
static int switched_codeset;
|
||||||
char *text;
|
char *text;
|
||||||
|
|
||||||
if (!switched_codeset)
|
if (!switched_codeset)
|
||||||
{
|
{
|
||||||
switched_codeset = 1;
|
switched_codeset = 1;
|
||||||
|
@ -1172,7 +1205,7 @@ my_dgettext (const char *domain, const char *msgid)
|
||||||
{
|
{
|
||||||
static int switched_codeset;
|
static int switched_codeset;
|
||||||
char *text;
|
char *text;
|
||||||
|
|
||||||
if (!switched_codeset)
|
if (!switched_codeset)
|
||||||
{
|
{
|
||||||
switched_codeset = 1;
|
switched_codeset = 1;
|
||||||
|
@ -1180,7 +1213,7 @@ my_dgettext (const char *domain, const char *msgid)
|
||||||
|
|
||||||
bindtextdomain ("dirmngr", LOCALEDIR);
|
bindtextdomain ("dirmngr", LOCALEDIR);
|
||||||
bind_textdomain_codeset ("dirmngr", "utf-8");
|
bind_textdomain_codeset ("dirmngr", "utf-8");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note: This is a hack to actually use the gnupg2 domain as
|
/* Note: This is a hack to actually use the gnupg2 domain as
|
||||||
|
@ -1225,7 +1258,7 @@ gc_percent_escape (const char *src)
|
||||||
*(dst++) = '%';
|
*(dst++) = '%';
|
||||||
*(dst++) = '2';
|
*(dst++) = '2';
|
||||||
*(dst++) = '5';
|
*(dst++) = '5';
|
||||||
}
|
}
|
||||||
else if (*src == ':')
|
else if (*src == ':')
|
||||||
{
|
{
|
||||||
/* The colon is used as field separator. */
|
/* The colon is used as field separator. */
|
||||||
|
@ -1281,7 +1314,7 @@ percent_deescape (const char *src)
|
||||||
|
|
||||||
*(dst++) = (char) val;
|
*(dst++) = (char) val;
|
||||||
src += 3;
|
src += 3;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*(dst++) = *(src++);
|
*(dst++) = *(src++);
|
||||||
}
|
}
|
||||||
|
@ -1374,7 +1407,7 @@ collect_error_output (estream_t fp, const char *tag)
|
||||||
buffer[pos - (c == '\n')] = 0;
|
buffer[pos - (c == '\n')] = 0;
|
||||||
if (cont_line)
|
if (cont_line)
|
||||||
; /*Ignore continuations of previous line. */
|
; /*Ignore continuations of previous line. */
|
||||||
else if (!strncmp (buffer, tag, taglen) && buffer[taglen] == ':')
|
else if (!strncmp (buffer, tag, taglen) && buffer[taglen] == ':')
|
||||||
{
|
{
|
||||||
/* "gpgsm: foo:4: bla" */
|
/* "gpgsm: foo:4: bla" */
|
||||||
/* Yep, we are interested in this line. */
|
/* Yep, we are interested in this line. */
|
||||||
|
@ -1424,7 +1457,7 @@ collect_error_output (estream_t fp, const char *tag)
|
||||||
cont_line = (c != '\n');
|
cont_line = (c != '\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We ignore error lines not terminated by a LF. */
|
/* We ignore error lines not terminated by a LF. */
|
||||||
return errlines;
|
return errlines;
|
||||||
}
|
}
|
||||||
|
@ -1483,16 +1516,16 @@ gc_component_check_options (int component, estream_t out, const char *conf_file)
|
||||||
else
|
else
|
||||||
argv[i++] = "--gpgconf-test";
|
argv[i++] = "--gpgconf-test";
|
||||||
argv[i++] = NULL;
|
argv[i++] = NULL;
|
||||||
|
|
||||||
result = 0;
|
result = 0;
|
||||||
errlines = NULL;
|
errlines = NULL;
|
||||||
err = gnupg_spawn_process (pgmname, argv, GPG_ERR_SOURCE_DEFAULT, NULL, 0,
|
err = gnupg_spawn_process (pgmname, argv, GPG_ERR_SOURCE_DEFAULT, NULL, 0,
|
||||||
NULL, NULL, &errfp, &pid);
|
NULL, NULL, &errfp, &pid);
|
||||||
if (err)
|
if (err)
|
||||||
result |= 1; /* Program could not be run. */
|
result |= 1; /* Program could not be run. */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
errlines = collect_error_output (errfp,
|
errlines = collect_error_output (errfp,
|
||||||
gc_component[component].name);
|
gc_component[component].name);
|
||||||
if (gnupg_wait_process (pgmname, pid, 1, &exitcode))
|
if (gnupg_wait_process (pgmname, pid, 1, &exitcode))
|
||||||
{
|
{
|
||||||
|
@ -1504,12 +1537,12 @@ gc_component_check_options (int component, estream_t out, const char *conf_file)
|
||||||
gnupg_release_process (pid);
|
gnupg_release_process (pid);
|
||||||
es_fclose (errfp);
|
es_fclose (errfp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the program could not be run, we can't tell whether
|
/* If the program could not be run, we can't tell whether
|
||||||
the config file is good. */
|
the config file is good. */
|
||||||
if (result & 1)
|
if (result & 1)
|
||||||
result |= 2;
|
result |= 2;
|
||||||
|
|
||||||
if (out)
|
if (out)
|
||||||
{
|
{
|
||||||
const char *desc;
|
const char *desc;
|
||||||
|
@ -1617,7 +1650,7 @@ list_one_option (const gc_option_t *option, estream_t out)
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
{
|
{
|
||||||
es_putc (' ', out);
|
es_putc (' ', out);
|
||||||
|
|
||||||
if (!option->flags)
|
if (!option->flags)
|
||||||
es_fprintf (out, "none");
|
es_fprintf (out, "none");
|
||||||
else
|
else
|
||||||
|
@ -1649,7 +1682,7 @@ list_one_option (const gc_option_t *option, estream_t out)
|
||||||
|
|
||||||
/* The description field. */
|
/* The description field. */
|
||||||
es_fprintf (out, ":%s", desc ? gc_percent_escape (desc) : "");
|
es_fprintf (out, ":%s", desc ? gc_percent_escape (desc) : "");
|
||||||
|
|
||||||
/* The type field. */
|
/* The type field. */
|
||||||
es_fprintf (out, ":%u", option->arg_type);
|
es_fprintf (out, ":%u", option->arg_type);
|
||||||
if (opt.verbose)
|
if (opt.verbose)
|
||||||
|
@ -1690,7 +1723,7 @@ list_one_option (const gc_option_t *option, estream_t out)
|
||||||
/* List all options of the component COMPONENT. */
|
/* List all options of the component COMPONENT. */
|
||||||
void
|
void
|
||||||
gc_component_list_options (int component, estream_t out)
|
gc_component_list_options (int component, estream_t out)
|
||||||
{
|
{
|
||||||
const gc_option_t *option = gc_component[component].options;
|
const gc_option_t *option = gc_component[component].options;
|
||||||
|
|
||||||
while (option && option->name)
|
while (option && option->name)
|
||||||
|
@ -1713,7 +1746,7 @@ gc_component_list_options (int component, estream_t out)
|
||||||
different active options, and because it is hard to
|
different active options, and because it is hard to
|
||||||
maintain manually, we calculate it here. The value in
|
maintain manually, we calculate it here. The value in
|
||||||
the global static table is ignored. */
|
the global static table is ignored. */
|
||||||
|
|
||||||
while (group_option->name)
|
while (group_option->name)
|
||||||
{
|
{
|
||||||
if (group_option->flags & GC_OPT_FLAG_GROUP)
|
if (group_option->flags & GC_OPT_FLAG_GROUP)
|
||||||
|
@ -1788,7 +1821,7 @@ get_config_filename (gc_component_t component, gc_backend_t backend)
|
||||||
#if HAVE_W32CE_SYSTEM
|
#if HAVE_W32CE_SYSTEM
|
||||||
if (!(filename[0] == '/' || filename[0] == '\\'))
|
if (!(filename[0] == '/' || filename[0] == '\\'))
|
||||||
#elif defined(HAVE_DOSISH_SYSTEM)
|
#elif defined(HAVE_DOSISH_SYSTEM)
|
||||||
if (!(filename[0]
|
if (!(filename[0]
|
||||||
&& filename[1] == ':'
|
&& filename[1] == ':'
|
||||||
&& (filename[2] == '/' || filename[2] == '\\')))
|
&& (filename[2] == '/' || filename[2] == '\\')))
|
||||||
#else
|
#else
|
||||||
|
@ -1819,8 +1852,8 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
|
||||||
estream_t config;
|
estream_t config;
|
||||||
char *config_filename;
|
char *config_filename;
|
||||||
|
|
||||||
pgmname = (gc_backend[backend].module_name
|
pgmname = (gc_backend[backend].module_name
|
||||||
? gnupg_module_name (gc_backend[backend].module_name)
|
? gnupg_module_name (gc_backend[backend].module_name)
|
||||||
: gc_backend[backend].program );
|
: gc_backend[backend].program );
|
||||||
argv[0] = "--gpgconf-list";
|
argv[0] = "--gpgconf-list";
|
||||||
argv[1] = NULL;
|
argv[1] = NULL;
|
||||||
|
@ -1839,7 +1872,7 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
|
||||||
char *linep;
|
char *linep;
|
||||||
unsigned long flags = 0;
|
unsigned long flags = 0;
|
||||||
char *default_value = NULL;
|
char *default_value = NULL;
|
||||||
|
|
||||||
/* Strip newline and carriage return, if present. */
|
/* Strip newline and carriage return, if present. */
|
||||||
while (length > 0
|
while (length > 0
|
||||||
&& (line[length - 1] == '\n' || line[length - 1] == '\r'))
|
&& (line[length - 1] == '\n' || line[length - 1] == '\r'))
|
||||||
|
@ -1848,7 +1881,7 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
|
||||||
linep = strchr (line, ':');
|
linep = strchr (line, ':');
|
||||||
if (linep)
|
if (linep)
|
||||||
*(linep++) = '\0';
|
*(linep++) = '\0';
|
||||||
|
|
||||||
/* Extract additional flags. Default to none. */
|
/* Extract additional flags. Default to none. */
|
||||||
if (linep)
|
if (linep)
|
||||||
{
|
{
|
||||||
|
@ -1928,7 +1961,7 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
|
||||||
char *name;
|
char *name;
|
||||||
char *value;
|
char *value;
|
||||||
gc_option_t *option;
|
gc_option_t *option;
|
||||||
|
|
||||||
name = line;
|
name = line;
|
||||||
while (*name == ' ' || *name == '\t')
|
while (*name == ' ' || *name == '\t')
|
||||||
name++;
|
name++;
|
||||||
|
@ -2015,7 +2048,7 @@ retrieve_options_from_program (gc_component_t component, gc_backend_t backend)
|
||||||
|
|
||||||
|
|
||||||
/* Retrieve the options for the component COMPONENT from backend
|
/* Retrieve the options for the component COMPONENT from backend
|
||||||
BACKEND, which we already know is of type file list. */
|
BACKEND, which we already know is of type file list. */
|
||||||
static void
|
static void
|
||||||
retrieve_options_from_file (gc_component_t component, gc_backend_t backend)
|
retrieve_options_from_file (gc_component_t component, gc_backend_t backend)
|
||||||
{
|
{
|
||||||
|
@ -2115,7 +2148,7 @@ gc_component_retrieve_options (int component)
|
||||||
component = 0;
|
component = 0;
|
||||||
assert (component < GC_COMPONENT_NR);
|
assert (component < GC_COMPONENT_NR);
|
||||||
}
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
option = gc_component[component].options;
|
option = gc_component[component].options;
|
||||||
|
@ -2125,16 +2158,16 @@ gc_component_retrieve_options (int component)
|
||||||
if (!(option->flags & GC_OPT_FLAG_GROUP))
|
if (!(option->flags & GC_OPT_FLAG_GROUP))
|
||||||
{
|
{
|
||||||
backend = option->backend;
|
backend = option->backend;
|
||||||
|
|
||||||
if (backend_seen[backend])
|
if (backend_seen[backend])
|
||||||
{
|
{
|
||||||
option++;
|
option++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
backend_seen[backend] = 1;
|
backend_seen[backend] = 1;
|
||||||
|
|
||||||
assert (backend != GC_BACKEND_ANY);
|
assert (backend != GC_BACKEND_ANY);
|
||||||
|
|
||||||
if (gc_backend[backend].program)
|
if (gc_backend[backend].program)
|
||||||
retrieve_options_from_program (component, backend);
|
retrieve_options_from_program (component, backend);
|
||||||
else
|
else
|
||||||
|
@ -2161,7 +2194,7 @@ option_check_validity (gc_option_t *option, unsigned long flags,
|
||||||
if (!option->active)
|
if (!option->active)
|
||||||
gc_error (1, 0, "option %s not supported by backend %s",
|
gc_error (1, 0, "option %s not supported by backend %s",
|
||||||
option->name, gc_backend[option->backend].name);
|
option->name, gc_backend[option->backend].name);
|
||||||
|
|
||||||
if (option->new_flags || option->new_value)
|
if (option->new_flags || option->new_value)
|
||||||
gc_error (1, 0, "option %s already changed", option->name);
|
gc_error (1, 0, "option %s already changed", option->name);
|
||||||
|
|
||||||
|
@ -2816,10 +2849,10 @@ change_options_program (gc_component_t component, gc_backend_t backend,
|
||||||
== GC_ARG_TYPE_STRING)
|
== GC_ARG_TYPE_STRING)
|
||||||
{
|
{
|
||||||
char *end;
|
char *end;
|
||||||
|
|
||||||
assert (*arg == '"');
|
assert (*arg == '"');
|
||||||
arg++;
|
arg++;
|
||||||
|
|
||||||
end = strchr (arg, ',');
|
end = strchr (arg, ',');
|
||||||
if (end)
|
if (end)
|
||||||
*end = '\0';
|
*end = '\0';
|
||||||
|
@ -3000,16 +3033,16 @@ gc_component_change_options (int component, estream_t in, estream_t out)
|
||||||
char *linep;
|
char *linep;
|
||||||
unsigned long flags = 0;
|
unsigned long flags = 0;
|
||||||
char *new_value = "";
|
char *new_value = "";
|
||||||
|
|
||||||
/* Strip newline and carriage return, if present. */
|
/* Strip newline and carriage return, if present. */
|
||||||
while (length > 0
|
while (length > 0
|
||||||
&& (line[length - 1] == '\n' || line[length - 1] == '\r'))
|
&& (line[length - 1] == '\n' || line[length - 1] == '\r'))
|
||||||
line[--length] = '\0';
|
line[--length] = '\0';
|
||||||
|
|
||||||
linep = strchr (line, ':');
|
linep = strchr (line, ':');
|
||||||
if (linep)
|
if (linep)
|
||||||
*(linep++) = '\0';
|
*(linep++) = '\0';
|
||||||
|
|
||||||
/* Extract additional flags. Default to none. */
|
/* Extract additional flags. Default to none. */
|
||||||
if (linep)
|
if (linep)
|
||||||
{
|
{
|
||||||
|
@ -3019,20 +3052,20 @@ gc_component_change_options (int component, estream_t in, estream_t out)
|
||||||
end = strchr (linep, ':');
|
end = strchr (linep, ':');
|
||||||
if (end)
|
if (end)
|
||||||
*(end++) = '\0';
|
*(end++) = '\0';
|
||||||
|
|
||||||
gpg_err_set_errno (0);
|
gpg_err_set_errno (0);
|
||||||
flags = strtoul (linep, &tail, 0);
|
flags = strtoul (linep, &tail, 0);
|
||||||
if (errno)
|
if (errno)
|
||||||
gc_error (1, errno, "malformed flags in option %s", line);
|
gc_error (1, errno, "malformed flags in option %s", line);
|
||||||
if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
|
if (!(*tail == '\0' || *tail == ':' || *tail == ' '))
|
||||||
gc_error (1, 0, "garbage after flags in option %s", line);
|
gc_error (1, 0, "garbage after flags in option %s", line);
|
||||||
|
|
||||||
linep = end;
|
linep = end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't allow setting of the no change flag. */
|
/* Don't allow setting of the no change flag. */
|
||||||
flags &= ~GC_OPT_FLAG_NO_CHANGE;
|
flags &= ~GC_OPT_FLAG_NO_CHANGE;
|
||||||
|
|
||||||
/* Extract default value, if present. Default to empty if not. */
|
/* Extract default value, if present. Default to empty if not. */
|
||||||
if (linep)
|
if (linep)
|
||||||
{
|
{
|
||||||
|
@ -3043,18 +3076,18 @@ gc_component_change_options (int component, estream_t in, estream_t out)
|
||||||
new_value = linep;
|
new_value = linep;
|
||||||
linep = end;
|
linep = end;
|
||||||
}
|
}
|
||||||
|
|
||||||
option = find_option (component, line, GC_BACKEND_ANY);
|
option = find_option (component, line, GC_BACKEND_ANY);
|
||||||
if (!option)
|
if (!option)
|
||||||
gc_error (1, 0, "unknown option %s", line);
|
gc_error (1, 0, "unknown option %s", line);
|
||||||
|
|
||||||
if ((option->flags & GC_OPT_FLAG_NO_CHANGE))
|
if ((option->flags & GC_OPT_FLAG_NO_CHANGE))
|
||||||
{
|
{
|
||||||
gc_error (0, 0, "ignoring new value for option %s",
|
gc_error (0, 0, "ignoring new value for option %s",
|
||||||
option->name);
|
option->name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
change_one_value (option, runtime, flags, new_value);
|
change_one_value (option, runtime, flags, new_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3100,10 +3133,10 @@ gc_component_change_options (int component, estream_t in, estream_t out)
|
||||||
&src_filename[option->backend],
|
&src_filename[option->backend],
|
||||||
&dest_filename[option->backend],
|
&dest_filename[option->backend],
|
||||||
&orig_filename[option->backend]);
|
&orig_filename[option->backend]);
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
option++;
|
option++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3192,14 +3225,14 @@ gc_component_change_options (int component, estream_t in, estream_t out)
|
||||||
|
|
||||||
/* If it all worked, notify the daemons of the changes. */
|
/* If it all worked, notify the daemons of the changes. */
|
||||||
if (opt.runtime)
|
if (opt.runtime)
|
||||||
for (backend = 0; backend < GC_BACKEND_NR; backend++)
|
for (backend = 0; backend < GC_BACKEND_NR; backend++)
|
||||||
{
|
{
|
||||||
if (runtime[backend] && gc_backend[backend].runtime_change)
|
if (runtime[backend] && gc_backend[backend].runtime_change)
|
||||||
(*gc_backend[backend].runtime_change) ();
|
(*gc_backend[backend].runtime_change) (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move the per-process backup file into its place. */
|
/* Move the per-process backup file into its place. */
|
||||||
for (backend = 0; backend < GC_BACKEND_NR; backend++)
|
for (backend = 0; backend < GC_BACKEND_NR; backend++)
|
||||||
if (orig_filename[backend])
|
if (orig_filename[backend])
|
||||||
{
|
{
|
||||||
char *backup_filename;
|
char *backup_filename;
|
||||||
|
@ -3236,7 +3269,7 @@ key_matches_user_or_group (char *user)
|
||||||
*group++ = 0;
|
*group++ = 0;
|
||||||
|
|
||||||
#ifdef HAVE_W32_SYSTEM
|
#ifdef HAVE_W32_SYSTEM
|
||||||
/* Under Windows we don't support groups. */
|
/* Under Windows we don't support groups. */
|
||||||
if (group && *group)
|
if (group && *group)
|
||||||
gc_error (0, 0, _("Note that group specifications are ignored\n"));
|
gc_error (0, 0, _("Note that group specifications are ignored\n"));
|
||||||
#ifndef HAVE_W32CE_SYSTEM
|
#ifndef HAVE_W32CE_SYSTEM
|
||||||
|
@ -3384,7 +3417,7 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
|
||||||
gc_option_t *option_info = NULL;
|
gc_option_t *option_info = NULL;
|
||||||
char *p;
|
char *p;
|
||||||
int is_continuation;
|
int is_continuation;
|
||||||
|
|
||||||
lineno++;
|
lineno++;
|
||||||
key = line;
|
key = line;
|
||||||
while (*key == ' ' || *key == '\t')
|
while (*key == ' ' || *key == '\t')
|
||||||
|
@ -3549,26 +3582,26 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
|
||||||
*group++ = 0;
|
*group++ = 0;
|
||||||
if ((p = strchr (group, ':')))
|
if ((p = strchr (group, ':')))
|
||||||
*p = 0; /* We better strip any extra stuff. */
|
*p = 0; /* We better strip any extra stuff. */
|
||||||
}
|
}
|
||||||
|
|
||||||
es_fprintf (listfp, "k:%s:", gc_percent_escape (key));
|
es_fprintf (listfp, "k:%s:", gc_percent_escape (key));
|
||||||
es_fprintf (listfp, "%s\n", group? gc_percent_escape (group):"");
|
es_fprintf (listfp, "%s\n", group? gc_percent_escape (group):"");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* All other lines are rule records. */
|
/* All other lines are rule records. */
|
||||||
es_fprintf (listfp, "r:::%s:%s:%s:",
|
es_fprintf (listfp, "r:::%s:%s:%s:",
|
||||||
gc_component[component_id].name,
|
gc_component[component_id].name,
|
||||||
option_info->name? option_info->name : "",
|
option_info->name? option_info->name : "",
|
||||||
flags? flags : "");
|
flags? flags : "");
|
||||||
if (value != empty)
|
if (value != empty)
|
||||||
es_fprintf (listfp, "\"%s", gc_percent_escape (value));
|
es_fprintf (listfp, "\"%s", gc_percent_escape (value));
|
||||||
|
|
||||||
es_putc ('\n', listfp);
|
es_putc ('\n', listfp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check whether the key matches but do this only if we are not
|
/* Check whether the key matches but do this only if we are not
|
||||||
running in syntax check mode. */
|
running in syntax check mode. */
|
||||||
if ( update
|
if ( update
|
||||||
&& !result && !listfp
|
&& !result && !listfp
|
||||||
&& (got_match || (key && key_matches_user_or_group (key))) )
|
&& (got_match || (key && key_matches_user_or_group (key))) )
|
||||||
{
|
{
|
||||||
|
@ -3632,9 +3665,9 @@ gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults,
|
||||||
|
|
||||||
if (opt.runtime)
|
if (opt.runtime)
|
||||||
{
|
{
|
||||||
for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)
|
for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++)
|
||||||
if (runtime[backend_id] && gc_backend[backend_id].runtime_change)
|
if (runtime[backend_id] && gc_backend[backend_id].runtime_change)
|
||||||
(*gc_backend[backend_id].runtime_change) ();
|
(*gc_backend[backend_id].runtime_change) (0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* gpgconf.c - Configuration utility for GnuPG
|
/* gpgconf.c - Configuration utility for GnuPG
|
||||||
* Copyright (C) 2003, 2007, 2009 Free Software Foundation, Inc.
|
* Copyright (C) 2003, 2007, 2009, 2011 Free Software Foundation, Inc.
|
||||||
*
|
*
|
||||||
* This file is part of GnuPG.
|
* This file is part of GnuPG.
|
||||||
*
|
*
|
||||||
|
@ -49,6 +49,7 @@ enum cmd_and_opt_values
|
||||||
aListConfig,
|
aListConfig,
|
||||||
aCheckConfig,
|
aCheckConfig,
|
||||||
aListDirs,
|
aListDirs,
|
||||||
|
aKill,
|
||||||
aReload
|
aReload
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -57,7 +58,7 @@ enum cmd_and_opt_values
|
||||||
static ARGPARSE_OPTS opts[] =
|
static ARGPARSE_OPTS opts[] =
|
||||||
{
|
{
|
||||||
{ 300, NULL, 0, N_("@Commands:\n ") },
|
{ 300, NULL, 0, N_("@Commands:\n ") },
|
||||||
|
|
||||||
{ aListComponents, "list-components", 256, N_("list all components") },
|
{ aListComponents, "list-components", 256, N_("list all components") },
|
||||||
{ aCheckPrograms, "check-programs", 256, N_("check all programs") },
|
{ aCheckPrograms, "check-programs", 256, N_("check all programs") },
|
||||||
{ aListOptions, "list-options", 256, N_("|COMPONENT|list options") },
|
{ aListOptions, "list-options", 256, N_("|COMPONENT|list options") },
|
||||||
|
@ -72,9 +73,10 @@ static ARGPARSE_OPTS opts[] =
|
||||||
{ aCheckConfig, "check-config", 256,
|
{ aCheckConfig, "check-config", 256,
|
||||||
N_("check global configuration file") },
|
N_("check global configuration file") },
|
||||||
{ aReload, "reload", 256, N_("reload all or a given component")},
|
{ aReload, "reload", 256, N_("reload all or a given component")},
|
||||||
|
{ aKill, "kill", 256, N_("kill a given component")},
|
||||||
|
|
||||||
{ 301, NULL, 0, N_("@\nOptions:\n ") },
|
{ 301, NULL, 0, N_("@\nOptions:\n ") },
|
||||||
|
|
||||||
{ oOutput, "output", 2, N_("use as output file") },
|
{ oOutput, "output", 2, N_("use as output file") },
|
||||||
{ oVerbose, "verbose", 0, N_("verbose") },
|
{ oVerbose, "verbose", 0, N_("verbose") },
|
||||||
{ oQuiet, "quiet", 0, N_("quiet") },
|
{ oQuiet, "quiet", 0, N_("quiet") },
|
||||||
|
@ -180,6 +182,7 @@ main (int argc, char **argv)
|
||||||
case aListConfig:
|
case aListConfig:
|
||||||
case aCheckConfig:
|
case aCheckConfig:
|
||||||
case aReload:
|
case aReload:
|
||||||
|
case aKill:
|
||||||
cmd = pargs.r_opt;
|
cmd = pargs.r_opt;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -189,9 +192,9 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
if (log_get_errorcount (0))
|
if (log_get_errorcount (0))
|
||||||
exit (2);
|
exit (2);
|
||||||
|
|
||||||
fname = argc ? *argv : NULL;
|
fname = argc ? *argv : NULL;
|
||||||
|
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case aListComponents:
|
case aListComponents:
|
||||||
|
@ -240,6 +243,34 @@ main (int argc, char **argv)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case aKill:
|
||||||
|
if (!fname)
|
||||||
|
{
|
||||||
|
es_fputs (_("usage: gpgconf [options] "), es_stderr);
|
||||||
|
es_putc ('\n', es_stderr);
|
||||||
|
es_fputs (_("Need one component argument"), es_stderr);
|
||||||
|
es_putc ('\n', es_stderr);
|
||||||
|
exit (2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Kill a given component. */
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
idx = gc_component_find (fname);
|
||||||
|
if (idx < 0)
|
||||||
|
{
|
||||||
|
es_fputs (_("Component not found"), es_stderr);
|
||||||
|
es_putc ('\n', es_stderr);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gc_component_kill (idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case aReload:
|
case aReload:
|
||||||
if (!fname)
|
if (!fname)
|
||||||
{
|
{
|
||||||
|
@ -288,7 +319,7 @@ main (int argc, char **argv)
|
||||||
if (gc_process_gpgconf_conf (NULL, 1, 1, NULL))
|
if (gc_process_gpgconf_conf (NULL, 1, 1, NULL))
|
||||||
exit (1);
|
exit (1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case aListDirs:
|
case aListDirs:
|
||||||
/* Show the system configuration directories for gpgconf. */
|
/* Show the system configuration directories for gpgconf. */
|
||||||
get_outfp (&outfp);
|
get_outfp (&outfp);
|
||||||
|
@ -342,6 +373,5 @@ main (int argc, char **argv)
|
||||||
if (es_fclose (outfp))
|
if (es_fclose (outfp))
|
||||||
gc_error (1, errno, "error closing `%s'", opt.outfile);
|
gc_error (1, errno, "error closing `%s'", opt.outfile);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,9 @@ char *gc_percent_escape (const char *src);
|
||||||
|
|
||||||
void gc_error (int status, int errnum, const char *fmt, ...);
|
void gc_error (int status, int errnum, const char *fmt, ...);
|
||||||
|
|
||||||
|
/* Kill given component. */
|
||||||
|
void gc_component_kill (int component);
|
||||||
|
|
||||||
/* Reload given component. */
|
/* Reload given component. */
|
||||||
void gc_component_reload (int component);
|
void gc_component_reload (int component);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue