mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-21 10:09: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>
|
||||
|
||||
* tlv.c, tlv.h: Move to ../common/.
|
||||
|
@ -38,6 +38,7 @@ scdaemon_SOURCES = \
|
||||
apdu.c apdu.h \
|
||||
ccid-driver.c ccid-driver.h \
|
||||
iso7816.c iso7816.h \
|
||||
statusfd.c statusfd.h \
|
||||
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
|
||||
#include "ccid-driver.h"
|
||||
#endif
|
||||
#include "statusfd.h"
|
||||
|
||||
/* Maximum length allowed as a PIN; used for INQUIRE NEEDPIN */
|
||||
#define MAXLEN_PIN 100
|
||||
@ -1649,6 +1650,34 @@ cmd_apdu (assuan_context_t ctx, char *line)
|
||||
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 },
|
||||
{ "RESTART", cmd_restart },
|
||||
{ "APDU", cmd_apdu },
|
||||
{ "STATUSFD", cmd_statusfd },
|
||||
{ NULL }
|
||||
};
|
||||
int i, rc;
|
||||
@ -1719,7 +1749,7 @@ scd_command_handler (ctrl_t ctrl, int fd)
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = assuan_init_socket_server_ext (&ctx, fd, 2);
|
||||
rc = assuan_init_socket_server_ext (&ctx, fd, 3);
|
||||
}
|
||||
if (rc)
|
||||
{
|
||||
@ -1880,6 +1910,15 @@ update_reader_status_file (void)
|
||||
log_info ("updating status of slot %d to 0x%04X\n",
|
||||
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
|
||||
depends on how client sessions will associate the reader
|
||||
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