mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
Let scdaemon call a script on status changes
This commit is contained in:
parent
44393f2ce7
commit
6374763c98
2
NEWS
2
NEWS
@ -12,6 +12,8 @@ Noteworthy changes in version 1.9.23
|
|||||||
* API change in gpg-agent's pkdecrypt command. Thus an older gpgsm
|
* API change in gpg-agent's pkdecrypt command. Thus an older gpgsm
|
||||||
may not be used with the current gpg-agent.
|
may not be used with the current gpg-agent.
|
||||||
|
|
||||||
|
* The scdaemon will now call a script on reader status changes.
|
||||||
|
|
||||||
|
|
||||||
Noteworthy changes in version 1.9.22 (2006-07-27)
|
Noteworthy changes in version 1.9.22 (2006-07-27)
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
|
5
TODO
5
TODO
@ -80,9 +80,6 @@ might want to have an agent context for each service request
|
|||||||
* doc/
|
* doc/
|
||||||
** Explain how to setup a root CA key as trusted
|
** Explain how to setup a root CA key as trusted
|
||||||
** Explain how trustlist.txt might be managed.
|
** Explain how trustlist.txt might be managed.
|
||||||
** Write a script to generate man pages from texi.
|
|
||||||
In progress (yatm)
|
|
||||||
|
|
||||||
|
|
||||||
* Windows port
|
* Windows port
|
||||||
** gpgsm's LISTKEYS does not yet work
|
** gpgsm's LISTKEYS does not yet work
|
||||||
@ -91,8 +88,6 @@ might want to have an agent context for each service request
|
|||||||
This means we can't reread a configuration
|
This means we can't reread a configuration
|
||||||
** No card status notifications.
|
** No card status notifications.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
* sm/
|
* sm/
|
||||||
** check that we issue NO_SECKEY xxx if a -u key was not found
|
** check that we issue NO_SECKEY xxx if a -u key was not found
|
||||||
We don't. The messages retruned are also wrong (recipient vs. signer).
|
We don't. The messages retruned are also wrong (recipient vs. signer).
|
||||||
|
@ -193,7 +193,7 @@ atfork_cb (void *opaque, int where)
|
|||||||
|
|
||||||
/* Fork off the SCdaemon if this has not already been done. Lock the
|
/* Fork off the SCdaemon if this has not already been done. Lock the
|
||||||
daemon and make sure that a proper context has been setup in CTRL.
|
daemon and make sure that a proper context has been setup in CTRL.
|
||||||
Thsi fucntion might also lock the daemon, which means that the
|
This function might also lock the daemon, which means that the
|
||||||
caller must call unlock_scd after this fucntion has returned
|
caller must call unlock_scd after this fucntion has returned
|
||||||
success and the actual Assuan transaction been done. */
|
success and the actual Assuan transaction been done. */
|
||||||
static int
|
static int
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
2006-09-07 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* exechelp.c (gnupg_spawn_process): Factor out post fork code to ..
|
||||||
|
(do_exec): .. new function. Allow passing of -1 for the fds.
|
||||||
|
(gnupg_spawn_process): Terminate gcrypt's secure memory in the child.
|
||||||
|
(gnupg_spawn_process_detached): New.
|
||||||
|
|
||||||
2006-09-06 Werner Koch <wk@g10code.com>
|
2006-09-06 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* maperror.c: Removed.
|
* maperror.c: Removed.
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#ifdef USE_GNU_PTH
|
#ifdef USE_GNU_PTH
|
||||||
#include <pth.h>
|
#include <pth.h>
|
||||||
#endif
|
#endif
|
||||||
@ -159,6 +160,67 @@ create_inheritable_pipe (int filedes[2])
|
|||||||
#endif /*HAVE_W32_SYSTEM*/
|
#endif /*HAVE_W32_SYSTEM*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef HAVE_W32_SYSTEM
|
||||||
|
/* The exec core used right after the fork. This will never return. */
|
||||||
|
static void
|
||||||
|
do_exec (const char *pgmname, const char *argv[],
|
||||||
|
int fd_in, int fd_out, int fd_err,
|
||||||
|
void (*preexec)(void) )
|
||||||
|
{
|
||||||
|
char **arg_list;
|
||||||
|
int n, i, j;
|
||||||
|
int fds[3];
|
||||||
|
|
||||||
|
fds[0] = fd_in;
|
||||||
|
fds[1] = fd_out;
|
||||||
|
fds[2] = fd_err;
|
||||||
|
|
||||||
|
/* Create the command line argument array. */
|
||||||
|
i = 0;
|
||||||
|
if (argv)
|
||||||
|
while (argv[i])
|
||||||
|
i++;
|
||||||
|
arg_list = xcalloc (i+2, sizeof *arg_list);
|
||||||
|
arg_list[0] = strrchr (pgmname, '/');
|
||||||
|
if (arg_list[0])
|
||||||
|
arg_list[0]++;
|
||||||
|
else
|
||||||
|
arg_list[0] = xstrdup (pgmname);
|
||||||
|
if (argv)
|
||||||
|
for (i=0,j=1; argv[i]; i++, j++)
|
||||||
|
arg_list[j] = (char*)argv[i];
|
||||||
|
|
||||||
|
/* Connect the standard files. */
|
||||||
|
for (i=0; i <= 2; i++)
|
||||||
|
{
|
||||||
|
if (fds[i] == -1 )
|
||||||
|
{
|
||||||
|
fds[i] = open ("/dev/null", i? O_WRONLY : O_RDONLY);
|
||||||
|
if (fds[i] == -1)
|
||||||
|
log_fatal ("failed to open `%s': %s\n",
|
||||||
|
"/dev/null", strerror (errno));
|
||||||
|
}
|
||||||
|
else if (fds[i] != i && dup2 (fds[i], i) == -1)
|
||||||
|
log_fatal ("dup2 std%s failed: %s\n",
|
||||||
|
i==0?"in":i==1?"out":"err", strerror (errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close all other files. */
|
||||||
|
n = sysconf (_SC_OPEN_MAX);
|
||||||
|
if (n < 0)
|
||||||
|
n = MAX_OPEN_FDS;
|
||||||
|
for (i=3; i < n; i++)
|
||||||
|
close(i);
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
if (preexec)
|
||||||
|
preexec ();
|
||||||
|
execv (pgmname, arg_list);
|
||||||
|
/* No way to print anything, as we have closed all streams. */
|
||||||
|
_exit (127);
|
||||||
|
}
|
||||||
|
#endif /*!HAVE_W32_SYSTEM*/
|
||||||
|
|
||||||
|
|
||||||
/* Fork and exec the PGMNAME, connect the file descriptor of INFILE to
|
/* Fork and exec the PGMNAME, connect the file descriptor of INFILE to
|
||||||
stdin, write the output to OUTFILE, return a new stream in
|
stdin, write the output to OUTFILE, return a new stream in
|
||||||
@ -325,47 +387,10 @@ gnupg_spawn_process (const char *pgmname, const char *argv[],
|
|||||||
|
|
||||||
if (!*pid)
|
if (!*pid)
|
||||||
{
|
{
|
||||||
/* Child. */
|
gcry_control (GCRYCTL_TERM_SECMEM);
|
||||||
char **arg_list;
|
/* Run child. */
|
||||||
int n, i, j;
|
do_exec (pgmname, argv, fd, fdout, rp[1], preexec);
|
||||||
|
/*NOTREACHED*/
|
||||||
/* Create the command line argument array. */
|
|
||||||
for (i=0; argv[i]; i++)
|
|
||||||
;
|
|
||||||
arg_list = xcalloc (i+2, sizeof *arg_list);
|
|
||||||
arg_list[0] = strrchr (pgmname, '/');
|
|
||||||
if (arg_list[0])
|
|
||||||
arg_list[0]++;
|
|
||||||
else
|
|
||||||
arg_list[0] = xstrdup (pgmname);
|
|
||||||
for (i=0,j=1; argv[i]; i++, j++)
|
|
||||||
arg_list[j] = (char*)argv[i];
|
|
||||||
|
|
||||||
/* Connect the infile to stdin. */
|
|
||||||
if (fd != 0 && dup2 (fd, 0) == -1)
|
|
||||||
log_fatal ("dup2 stdin failed: %s\n", strerror (errno));
|
|
||||||
|
|
||||||
/* Connect the outfile to stdout. */
|
|
||||||
if (fdout != 1 && dup2 (fdout, 1) == -1)
|
|
||||||
log_fatal ("dup2 stdout failed: %s\n", strerror (errno));
|
|
||||||
|
|
||||||
/* Connect stderr to our pipe. */
|
|
||||||
if (rp[1] != 2 && dup2 (rp[1], 2) == -1)
|
|
||||||
log_fatal ("dup2 stderr failed: %s\n", strerror (errno));
|
|
||||||
|
|
||||||
/* Close all other files. */
|
|
||||||
n = sysconf (_SC_OPEN_MAX);
|
|
||||||
if (n < 0)
|
|
||||||
n = MAX_OPEN_FDS;
|
|
||||||
for (i=3; i < n; i++)
|
|
||||||
close(i);
|
|
||||||
errno = 0;
|
|
||||||
|
|
||||||
if (preexec)
|
|
||||||
preexec ();
|
|
||||||
execv (pgmname, arg_list);
|
|
||||||
/* No way to print anything, as we have closed all streams. */
|
|
||||||
_exit (127);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Parent. */
|
/* Parent. */
|
||||||
@ -481,3 +506,64 @@ gnupg_wait_process (const char *pgmname, pid_t pid)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Spawn a new process and immediatley detach from it. The name of
|
||||||
|
the program to exec is PGMNAME and its arguments are in ARGV (the
|
||||||
|
programname is automatically passed as first argument).
|
||||||
|
Environment strings in ENVP are set. An error is returned if
|
||||||
|
pgmname is not executable; to make this work it is necessary to
|
||||||
|
provide an absolute file name. All standard file descriptors are
|
||||||
|
connected to /dev/null. */
|
||||||
|
gpg_error_t
|
||||||
|
gnupg_spawn_process_detached (const char *pgmname, const char *argv[],
|
||||||
|
const char *envp[] )
|
||||||
|
{
|
||||||
|
#ifdef HAVE_W32_SYSTEM
|
||||||
|
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||||
|
#else
|
||||||
|
pid_t pid;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (getuid() != geteuid())
|
||||||
|
return gpg_error (GPG_ERR_BUG);
|
||||||
|
|
||||||
|
if (access (pgmname, X_OK))
|
||||||
|
return gpg_error_from_errno (errno);
|
||||||
|
|
||||||
|
#ifdef USE_GNU_PTH
|
||||||
|
pid = pth_fork? pth_fork () : fork ();
|
||||||
|
#else
|
||||||
|
pid = fork ();
|
||||||
|
#endif
|
||||||
|
if (pid == (pid_t)(-1))
|
||||||
|
{
|
||||||
|
log_error (_("error forking process: %s\n"), strerror (errno));
|
||||||
|
return gpg_error_from_errno (errno);
|
||||||
|
}
|
||||||
|
if (!pid)
|
||||||
|
{
|
||||||
|
gcry_control (GCRYCTL_TERM_SECMEM);
|
||||||
|
if (setsid() == -1 || chdir ("/"))
|
||||||
|
_exit (1);
|
||||||
|
pid = fork (); /* Double fork to let init takes over the new child. */
|
||||||
|
if (pid == (pid_t)(-1))
|
||||||
|
_exit (1);
|
||||||
|
if (pid)
|
||||||
|
_exit (0); /* Let the parent exit immediately. */
|
||||||
|
|
||||||
|
if (envp)
|
||||||
|
for (i=0; envp[i]; i++)
|
||||||
|
putenv (xstrdup (envp[i]));
|
||||||
|
|
||||||
|
do_exec (pgmname, argv, -1, -1, -1, NULL);
|
||||||
|
|
||||||
|
/*NOTREACHED*/
|
||||||
|
}
|
||||||
|
|
||||||
|
if (waitpid (pid, NULL, 0) == -1)
|
||||||
|
log_error ("waitpid failed in gnupg_spawn_process_detached: %s",
|
||||||
|
strerror (errno));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#endif /* !HAVE_W32_SYSTEM*/
|
||||||
|
}
|
||||||
|
@ -43,4 +43,16 @@ gpg_error_t gnupg_spawn_process (const char *pgmname, const char *argv[],
|
|||||||
gpg_error_t gnupg_wait_process (const char *pgmname, pid_t pid);
|
gpg_error_t gnupg_wait_process (const char *pgmname, pid_t pid);
|
||||||
|
|
||||||
|
|
||||||
|
/* Spawn a new process and immediatley detach from it. The name of
|
||||||
|
the program to exec is PGMNAME and its arguments are in ARGV (the
|
||||||
|
programname is automatically passed as first argument).
|
||||||
|
Environment strings in ENVP are set. An error is returned if
|
||||||
|
pgmname is not executable; to make this work it is necessary to
|
||||||
|
provide an absolute file name. */
|
||||||
|
gpg_error_t gnupg_spawn_process_detached (const char *pgmname,
|
||||||
|
const char *argv[],
|
||||||
|
const char *envp[] );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /*GNUPG_COMMON_EXECHELP_H*/
|
#endif /*GNUPG_COMMON_EXECHELP_H*/
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
2006-09-07 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* scdaemon.texi (Scdaemon Configuration): New.
|
||||||
|
|
||||||
|
* examples/scd-event: Event handler for sdaemon.
|
||||||
|
* examples/: New directory
|
||||||
|
|
||||||
2006-08-22 Werner Koch <wk@g10code.com>
|
2006-08-22 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* yat2m.c (parse_file): Added code to skip a line after @mansect.
|
* yat2m.c (parse_file): Added code to skip a line after @mansect.
|
||||||
|
@ -19,13 +19,16 @@
|
|||||||
|
|
||||||
## Process this file with automake to produce Makefile.in
|
## Process this file with automake to produce Makefile.in
|
||||||
|
|
||||||
|
examples=examples/scd-event
|
||||||
|
|
||||||
EXTRA_DIST = DETAILS HACKING TRANSLATE OpenPGP KEYSERVER samplekeys.asc \
|
EXTRA_DIST = DETAILS HACKING TRANSLATE OpenPGP KEYSERVER samplekeys.asc \
|
||||||
gnupg-badge-openpgp.eps gnupg-badge-openpgp.jpg \
|
gnupg-badge-openpgp.eps gnupg-badge-openpgp.jpg \
|
||||||
gnupg-badge-openpgp.pdf \
|
gnupg-badge-openpgp.pdf \
|
||||||
gnupg-card-architecture.eps gnupg-card-architecture.png \
|
gnupg-card-architecture.eps gnupg-card-architecture.png \
|
||||||
gnupg-card-architecture.pdf \
|
gnupg-card-architecture.pdf \
|
||||||
faq.raw FAQ faq.html gnupg7.texi \
|
faq.raw FAQ faq.html gnupg7.texi \
|
||||||
opt-homedir.texi see-also-note.texi
|
opt-homedir.texi see-also-note.texi \
|
||||||
|
$(examples)
|
||||||
|
|
||||||
BUILT_SOURCES = gnupg-card-architecture.eps gnupg-card-architecture.png \
|
BUILT_SOURCES = gnupg-card-architecture.eps gnupg-card-architecture.png \
|
||||||
gnupg-card-architecture.pdf FAQ faq.html
|
gnupg-card-architecture.pdf FAQ faq.html
|
||||||
|
102
doc/examples/scd-event
Executable file
102
doc/examples/scd-event
Executable file
@ -0,0 +1,102 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Sample script for scdaemon event mechanism.
|
||||||
|
|
||||||
|
#exec >>/tmp/scd-event.log
|
||||||
|
|
||||||
|
PGM=scd-event
|
||||||
|
|
||||||
|
reader_port=
|
||||||
|
old_code=0x0000
|
||||||
|
new_code=0x0000
|
||||||
|
status=
|
||||||
|
|
||||||
|
tick='`'
|
||||||
|
prev=
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
arg="$1"
|
||||||
|
case $arg in
|
||||||
|
-*=*) optarg=$(echo "X$arg" | sed -e '1s/^X//' -e 's/[-_a-zA-Z0-9]*=//')
|
||||||
|
;;
|
||||||
|
*) optarg=
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
if [ -n "$prev" ]; then
|
||||||
|
eval "$prev=\$arg"
|
||||||
|
prev=
|
||||||
|
shift
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
case $arg in
|
||||||
|
--help|-h)
|
||||||
|
cat <<EOF
|
||||||
|
Usage: $PGM [options]
|
||||||
|
$PGM is called by scdaemon on card reader status changes
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--reader-port N Reports change for port N
|
||||||
|
--old-code 0xNNNN Previous status code
|
||||||
|
--old-code 0xNNNN Current status code
|
||||||
|
--status USABLE|ACTIVE|PRESENT}NOCARD
|
||||||
|
Human readable status code
|
||||||
|
|
||||||
|
Environment:
|
||||||
|
|
||||||
|
GNUPGHOME=DIR Set to the active hmedir
|
||||||
|
|
||||||
|
EOF
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
--reader-port)
|
||||||
|
prev=reader_port
|
||||||
|
;;
|
||||||
|
--reader-port=*)
|
||||||
|
reader_port="$optarg"
|
||||||
|
;;
|
||||||
|
--old-code)
|
||||||
|
prev=old_code
|
||||||
|
;;
|
||||||
|
--old-code=*)
|
||||||
|
old_code="$optarg"
|
||||||
|
;;
|
||||||
|
--new-code)
|
||||||
|
prev=new_code
|
||||||
|
;;
|
||||||
|
--new-code=*)
|
||||||
|
new_code="$optarg"
|
||||||
|
;;
|
||||||
|
--status)
|
||||||
|
prev=status
|
||||||
|
;;
|
||||||
|
--new-code=*)
|
||||||
|
status="$optarg"
|
||||||
|
;;
|
||||||
|
|
||||||
|
-*)
|
||||||
|
echo "$PGM: invalid option $tick$arg'" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
if [ -n "$prev" ]; then
|
||||||
|
echo "$PGM: argument missing for option $tick$prev'" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat <<EOF
|
||||||
|
========================
|
||||||
|
port: $reader_port
|
||||||
|
old-code: $old_code
|
||||||
|
new-code: $new_code
|
||||||
|
status: $status
|
||||||
|
EOF
|
||||||
|
|
||||||
|
if [ x$status = xUSABLE ]; then
|
||||||
|
gpg --batch --card-status 2>&1
|
||||||
|
fi
|
||||||
|
|
@ -48,6 +48,7 @@ options.
|
|||||||
* Scdaemon Commands:: List of all commands.
|
* Scdaemon Commands:: List of all commands.
|
||||||
* Scdaemon Options:: List of all options.
|
* Scdaemon Options:: List of all options.
|
||||||
* Card applications:: Description of card applications.
|
* Card applications:: Description of card applications.
|
||||||
|
* Scdaemon Configuration:: Configuration files.
|
||||||
* Scdaemon Examples:: Some usage examples.
|
* Scdaemon Examples:: Some usage examples.
|
||||||
* Scdaemon Protocol:: The protocol the daemon uses.
|
* Scdaemon Protocol:: The protocol the daemon uses.
|
||||||
@end menu
|
@end menu
|
||||||
@ -320,6 +321,41 @@ This is common fraqmework for smart card applications. It is used by
|
|||||||
@command{gpgsm}.
|
@command{gpgsm}.
|
||||||
|
|
||||||
|
|
||||||
|
@c *******************************************
|
||||||
|
@c *************** ****************
|
||||||
|
@c *************** FILES ****************
|
||||||
|
@c *************** ****************
|
||||||
|
@c *******************************************
|
||||||
|
@mansect files
|
||||||
|
@node Scdaemon Configuration
|
||||||
|
@section Configuration files
|
||||||
|
|
||||||
|
There are a few configuration files to control certain aspects of
|
||||||
|
@command{scdaemons}'s operation. Unless noted, they are expected in the
|
||||||
|
current home directory (@pxref{option --homedir}).
|
||||||
|
|
||||||
|
@table @file
|
||||||
|
|
||||||
|
@item scdaemon.conf
|
||||||
|
@cindex scdaemon.conf
|
||||||
|
This is the standard configuration file read by @command{scdaemon} on
|
||||||
|
startup. It may contain any valid long option; the leading two dashes
|
||||||
|
may not be entered and the option may not be abbreviated. This default
|
||||||
|
name may be changed on the command line (@pxref{option --options}).
|
||||||
|
|
||||||
|
@item scd-event
|
||||||
|
@cindex scd-event
|
||||||
|
If this file is present and executable, it will be called on veyer card
|
||||||
|
reader's status changed. An example of this script is provided with the
|
||||||
|
distribution
|
||||||
|
|
||||||
|
@item reader_@var{n}.status
|
||||||
|
This file is created by @command{sdaemon} to let other applications now
|
||||||
|
about reader status changes. Its use is now deprecated in favor of
|
||||||
|
@file{scd-event}.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
|
|
||||||
@c
|
@c
|
||||||
@c Examples
|
@c Examples
|
||||||
@ -339,7 +375,7 @@ $ scdaemon --server -v
|
|||||||
@c
|
@c
|
||||||
@c Assuan Protocol
|
@c Assuan Protocol
|
||||||
@c
|
@c
|
||||||
@mansect assuan
|
@manpause
|
||||||
@node Scdaemon Protocol
|
@node Scdaemon Protocol
|
||||||
@section Scdaemon's Assuan Protocol
|
@section Scdaemon's Assuan Protocol
|
||||||
|
|
||||||
@ -621,3 +657,11 @@ Using the option @code{--more} handles the card status word MORE_DATA
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@mansect see also
|
||||||
|
@ifset isman
|
||||||
|
@command{gpg-agent}(1),
|
||||||
|
@command{gpgsm}(1),
|
||||||
|
@command{gpg2}(1)
|
||||||
|
@end ifset
|
||||||
|
@include see-also-note.texi
|
||||||
|
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
2006-09-07 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
|
* command.c (update_reader_status_file): Execute an event handler
|
||||||
|
if available.
|
||||||
|
|
||||||
2006-09-06 Werner Koch <wk@g10code.com>
|
2006-09-06 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* apdu.c (pcsc_end_transaction):
|
* apdu.c (pcsc_end_transaction):
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <ksba.h>
|
#include <ksba.h>
|
||||||
#include "app-common.h"
|
#include "app-common.h"
|
||||||
#include "apdu.h" /* Required for apdu_*_reader (). */
|
#include "apdu.h" /* Required for apdu_*_reader (). */
|
||||||
|
#include "exechelp.h"
|
||||||
|
|
||||||
/* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
|
/* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
|
||||||
#define MAXLEN_PIN 100
|
#define MAXLEN_PIN 100
|
||||||
@ -1778,6 +1779,47 @@ update_reader_status_file (void)
|
|||||||
}
|
}
|
||||||
xfree (fname);
|
xfree (fname);
|
||||||
|
|
||||||
|
/* If a status script is executable, run it. */
|
||||||
|
{
|
||||||
|
const char *args[9], *envs[2];
|
||||||
|
char numbuf1[30], numbuf2[3], numbuf3[30];
|
||||||
|
char *homestr, *envstr;
|
||||||
|
gpg_error_t err;
|
||||||
|
|
||||||
|
homestr = make_filename (opt.homedir, NULL);
|
||||||
|
if (asprintf (&envstr, "GNUPGHOME=%s", homestr) < 0)
|
||||||
|
log_error ("out of core while building environment\n");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
envs[0] = envstr;
|
||||||
|
envs[1] = NULL;
|
||||||
|
|
||||||
|
sprintf (numbuf1, "%d", ss->slot);
|
||||||
|
sprintf (numbuf2, "0x%04X", ss->status);
|
||||||
|
sprintf (numbuf3, "0x%04X", status);
|
||||||
|
args[0] = "--reader-port";
|
||||||
|
args[1] = numbuf1;
|
||||||
|
args[2] = "--old-code";
|
||||||
|
args[3] = numbuf2;
|
||||||
|
args[4] = "--new-code";
|
||||||
|
args[5] = numbuf3;
|
||||||
|
args[6] = "--status";
|
||||||
|
args[7] = ((status & 1)? "USABLE":
|
||||||
|
(status & 4)? "ACTIVE":
|
||||||
|
(status & 2)? "PRESENT": "NOCARD");
|
||||||
|
args[8] = NULL;
|
||||||
|
|
||||||
|
fname = make_filename (opt.homedir, "scd-event", NULL);
|
||||||
|
err = gnupg_spawn_process_detached (fname, args, envs);
|
||||||
|
if (err && gpg_err_code (err) != GPG_ERR_ENOENT)
|
||||||
|
log_error ("failed to run event handler `%s': %s\n",
|
||||||
|
fname, gpg_strerror (err));
|
||||||
|
xfree (fname);
|
||||||
|
free (envstr);
|
||||||
|
}
|
||||||
|
xfree (homestr);
|
||||||
|
}
|
||||||
|
|
||||||
/* Set the card removed flag for all current sessions. We
|
/* Set the card removed flag for all current sessions. We
|
||||||
will set this on any card change because a reset or
|
will set this on any card change because a reset or
|
||||||
SERIALNO request must be done in any case. */
|
SERIALNO request must be done in any case. */
|
||||||
@ -1802,6 +1844,7 @@ update_reader_status_file (void)
|
|||||||
kill (pid, signo);
|
kill (pid, signo);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user