mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
Implemented the STATUSFD mechanism.
2007-08-16 Moritz Schulte <moritz@g10code.com> * command.c: Include "statusfd.h". (cmd_statusfd): New function. (register_commands): New entry for STATUSFD command. (update_reader_status_file): Call statusfd_event_card_inserted and statusfd_event_card_removed on events. (scd_command_handler): Pass flags=3 to assuan_init_socket_server_ext (enabling fd passing). * statusfd.c, statusfd.h: New files. * Makefile.am (scdaemon_SOURCES): Added statusfd.c, statusfd.h. * NOTES-STATUSFD: New file.
This commit is contained in:
parent
fe750f0c7c
commit
62039d815e
@ -1,3 +1,16 @@
|
|||||||
|
2007-08-16 Moritz Schulte <moritz@g10code.com>
|
||||||
|
|
||||||
|
* command.c: Include "statusfd.h".
|
||||||
|
(cmd_statusfd): New function.
|
||||||
|
(register_commands): New entry for STATUSFD command.
|
||||||
|
(update_reader_status_file): Call statusfd_event_card_inserted and
|
||||||
|
statusfd_event_card_removed on events.
|
||||||
|
(scd_command_handler): Pass flags=3 to
|
||||||
|
assuan_init_socket_server_ext (enabling fd passing).
|
||||||
|
* statusfd.c, statusfd.h: New files.
|
||||||
|
* Makefile.am (scdaemon_SOURCES): Added statusfd.c, statusfd.h.
|
||||||
|
* NOTES-STATUSFD: New file.
|
||||||
|
|
||||||
2007-08-07 Werner Koch <wk@g10code.com>
|
2007-08-07 Werner Koch <wk@g10code.com>
|
||||||
|
|
||||||
* tlv.c, tlv.h: Move to ../common/.
|
* tlv.c, tlv.h: Move to ../common/.
|
||||||
|
@ -38,6 +38,7 @@ scdaemon_SOURCES = \
|
|||||||
apdu.c apdu.h \
|
apdu.c apdu.h \
|
||||||
ccid-driver.c ccid-driver.h \
|
ccid-driver.c ccid-driver.h \
|
||||||
iso7816.c iso7816.h \
|
iso7816.c iso7816.h \
|
||||||
|
statusfd.c statusfd.h \
|
||||||
app.c app-common.h app-help.c $(card_apps)
|
app.c app-common.h app-help.c $(card_apps)
|
||||||
|
|
||||||
|
|
||||||
|
36
scd/NOTES-STATUSFD
Normal file
36
scd/NOTES-STATUSFD
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
Description of the statusfd mechanism:
|
||||||
|
|
||||||
|
Applications can now ask scdaemon to be notified about certain events
|
||||||
|
(card inserted/removed) on a specified file descriptor.
|
||||||
|
|
||||||
|
This is how it works:
|
||||||
|
|
||||||
|
Run gpg-agent in daemon mode.
|
||||||
|
Figure out scdaemons socket:
|
||||||
|
|
||||||
|
|
||||||
|
moritz@pink:~/g10/hacks/gnupg-mo/build/scd$ gpg-connect-agent
|
||||||
|
SCD GETINFO socket_name
|
||||||
|
D /tmp/gpg-QZRVNr/S.scdaemon
|
||||||
|
OK
|
||||||
|
|
||||||
|
Connect to scdaemon and register a status file descriptor:
|
||||||
|
|
||||||
|
moritz@pink:~/g10/hacks/gnupg-mo/build/scd$ gpg-connect-agent -S /tmp/gpg-QZRVNr/S.scdaemon
|
||||||
|
/sendfd /tmp/scd-events w
|
||||||
|
STATUSFD
|
||||||
|
OK
|
||||||
|
moritz@pink:~/g10/hacks/gnupg-mo/build/scd$
|
||||||
|
|
||||||
|
|
||||||
|
Watch the log file as you remove/insert the smartcard:
|
||||||
|
|
||||||
|
moritz@pink:~/g10/hacks/gnupg-mo/build/scd$ tail -f /tmp/scd-events
|
||||||
|
CARD REMOVED
|
||||||
|
CARD INSERTED
|
||||||
|
CARD REMOVED
|
||||||
|
CARD INSERTED
|
||||||
|
^C
|
||||||
|
moritz@pink:~/g10/hacks/gnupg-mo/build/scd$
|
||||||
|
|
||||||
|
That's it for now.
|
@ -40,6 +40,7 @@
|
|||||||
#ifdef HAVE_LIBUSB
|
#ifdef HAVE_LIBUSB
|
||||||
#include "ccid-driver.h"
|
#include "ccid-driver.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "statusfd.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
|
||||||
@ -1649,6 +1650,34 @@ cmd_apdu (assuan_context_t ctx, char *line)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* STATUSFD
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
cmd_statusfd (assuan_context_t ctx, char *line)
|
||||||
|
{
|
||||||
|
ctrl_t ctrl = assuan_get_pointer (ctx);
|
||||||
|
int rc;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
/* FIXME, moritz, locking? */
|
||||||
|
if ( IS_LOCKED (ctrl) )
|
||||||
|
return gpg_error (GPG_ERR_LOCKED);
|
||||||
|
|
||||||
|
rc = assuan_receivefd (ctx, &fd);
|
||||||
|
if (rc)
|
||||||
|
/* FIXME, moritz, proper error message for client? */
|
||||||
|
goto leave;
|
||||||
|
|
||||||
|
rc = statusfd_register (fd);
|
||||||
|
|
||||||
|
leave:
|
||||||
|
|
||||||
|
if (rc)
|
||||||
|
close (fd);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1683,6 +1712,7 @@ register_commands (assuan_context_t ctx)
|
|||||||
{ "GETINFO", cmd_getinfo },
|
{ "GETINFO", cmd_getinfo },
|
||||||
{ "RESTART", cmd_restart },
|
{ "RESTART", cmd_restart },
|
||||||
{ "APDU", cmd_apdu },
|
{ "APDU", cmd_apdu },
|
||||||
|
{ "STATUSFD", cmd_statusfd },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
int i, rc;
|
int i, rc;
|
||||||
@ -1719,7 +1749,7 @@ scd_command_handler (ctrl_t ctrl, int fd)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rc = assuan_init_socket_server_ext (&ctx, fd, 2);
|
rc = assuan_init_socket_server_ext (&ctx, fd, 3);
|
||||||
}
|
}
|
||||||
if (rc)
|
if (rc)
|
||||||
{
|
{
|
||||||
@ -1880,6 +1910,15 @@ update_reader_status_file (void)
|
|||||||
log_info ("updating status of slot %d to 0x%04X\n",
|
log_info ("updating status of slot %d to 0x%04X\n",
|
||||||
ss->slot, status);
|
ss->slot, status);
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Broadcast on statusfds. */
|
||||||
|
|
||||||
|
if ((! (ss->status & 2)) && (status & 2))
|
||||||
|
statusfd_event_card_inserted (0);
|
||||||
|
if ((ss->status & 2) && (! (status & 2)))
|
||||||
|
statusfd_event_card_removed (0);
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: Should this be IDX instead of ss->slot? This
|
/* FIXME: Should this be IDX instead of ss->slot? This
|
||||||
depends on how client sessions will associate the reader
|
depends on how client sessions will associate the reader
|
||||||
status with their session. */
|
status with their session. */
|
||||||
|
139
scd/statusfd.c
Normal file
139
scd/statusfd.c
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
/* statusfd.c - SCdaemon status fd handling
|
||||||
|
* Copyright (C) 2007 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* AUTHOR: Moritz Schulte <moritz@g10code.com>. */
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <pth.h>
|
||||||
|
|
||||||
|
#include "scdaemon.h"
|
||||||
|
#include "statusfd.h"
|
||||||
|
|
||||||
|
struct statusfd_s
|
||||||
|
{
|
||||||
|
FILE *stream;
|
||||||
|
struct statusfd_s *next, **prevp;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct statusfd_s *statusfd_t;
|
||||||
|
|
||||||
|
static statusfd_t statusfd_list;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
statusfd_add (FILE *stream)
|
||||||
|
{
|
||||||
|
statusfd_t statusfd_obj;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
statusfd_obj = xtrymalloc (sizeof (*statusfd_obj));
|
||||||
|
|
||||||
|
if (statusfd_obj)
|
||||||
|
{
|
||||||
|
statusfd_obj->stream = stream;
|
||||||
|
statusfd_obj->next = statusfd_list;
|
||||||
|
statusfd_obj->prevp = &statusfd_list;
|
||||||
|
if (statusfd_list)
|
||||||
|
statusfd_list->prevp = &statusfd_obj->next;
|
||||||
|
statusfd_list = statusfd_obj;
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rc = gpg_error_from_syserror ();
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
statusfd_remove (statusfd_t statusfd)
|
||||||
|
{
|
||||||
|
*statusfd->prevp = statusfd->next;
|
||||||
|
if (statusfd->next)
|
||||||
|
statusfd->next->prevp = statusfd->prevp;
|
||||||
|
|
||||||
|
xfree (statusfd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
statusfd_broadcast (const char *fmt, ...)
|
||||||
|
{
|
||||||
|
statusfd_t statusfd = statusfd_list;
|
||||||
|
statusfd_t statusfd_next;
|
||||||
|
int ret;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start (ap, fmt);
|
||||||
|
|
||||||
|
while (statusfd)
|
||||||
|
{
|
||||||
|
ret = vfprintf (statusfd->stream, fmt, ap);
|
||||||
|
if (ret >= 0)
|
||||||
|
ret = fflush (statusfd->stream);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
/* Error on this statusfd stream, remove it. */
|
||||||
|
/* FIXME: only remove on certain errros? -moritz */
|
||||||
|
|
||||||
|
statusfd_next = statusfd->next;
|
||||||
|
statusfd_remove (statusfd);
|
||||||
|
statusfd = statusfd_next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
statusfd = statusfd->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end (ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
statusfd_register (int fd)
|
||||||
|
{
|
||||||
|
FILE *stream;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
stream = fdopen (fd, "a");
|
||||||
|
if (! stream)
|
||||||
|
rc = gpg_error_from_syserror ();
|
||||||
|
else
|
||||||
|
rc = statusfd_add (stream);
|
||||||
|
|
||||||
|
if (rc && stream)
|
||||||
|
fclose (stream);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
statusfd_event_card_inserted (int slot)
|
||||||
|
{
|
||||||
|
statusfd_broadcast ("CARD INSERTED\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
statusfd_event_card_removed (int slot)
|
||||||
|
{
|
||||||
|
statusfd_broadcast ("CARD REMOVED\n");
|
||||||
|
}
|
28
scd/statusfd.h
Normal file
28
scd/statusfd.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/* statusfd.h - SCdaemon status fd handling
|
||||||
|
* Copyright (C) 2007 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef GNUPG_SCD_STATUSFD_H
|
||||||
|
#define GNUPG_SCD_STATUSFD_H
|
||||||
|
|
||||||
|
int statusfd_register (int fd);
|
||||||
|
void statusfd_event_card_inserted (int slot);
|
||||||
|
void statusfd_event_card_removed (int slot);
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user