[svn] GnuPG - r4564 - branches/GNUPG-TRUNK-MO-HACKS/scd

svn author mo cvs at cvs.gnupg.org
Thu Aug 16 14:44:47 CEST 2007


Author: mo
Date: 2007-08-16 14:44:17 +0200 (Thu, 16 Aug 2007)
New Revision: 4564

Added:
   branches/GNUPG-TRUNK-MO-HACKS/scd/NOTES-STATUSFD
   branches/GNUPG-TRUNK-MO-HACKS/scd/statusfd.c
   branches/GNUPG-TRUNK-MO-HACKS/scd/statusfd.h
Modified:
   branches/GNUPG-TRUNK-MO-HACKS/scd/ChangeLog
   branches/GNUPG-TRUNK-MO-HACKS/scd/Makefile.am
   branches/GNUPG-TRUNK-MO-HACKS/scd/command.c
Log:
Implemented the STATUSFD mechanism.

2007-08-16  Moritz Schulte  <moritz at 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.



Modified: branches/GNUPG-TRUNK-MO-HACKS/scd/ChangeLog
===================================================================
--- branches/GNUPG-TRUNK-MO-HACKS/scd/ChangeLog	2007-08-16 12:18:44 UTC (rev 4563)
+++ branches/GNUPG-TRUNK-MO-HACKS/scd/ChangeLog	2007-08-16 12:44:17 UTC (rev 4564)
@@ -1,3 +1,16 @@
+2007-08-16  Moritz Schulte  <moritz at 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 at g10code.com>
 
 	* tlv.c, tlv.h:  Move to ../common/.

Modified: branches/GNUPG-TRUNK-MO-HACKS/scd/Makefile.am
===================================================================
--- branches/GNUPG-TRUNK-MO-HACKS/scd/Makefile.am	2007-08-16 12:18:44 UTC (rev 4563)
+++ branches/GNUPG-TRUNK-MO-HACKS/scd/Makefile.am	2007-08-16 12:44:17 UTC (rev 4564)
@@ -38,6 +38,7 @@
 	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)
 
 

Added: branches/GNUPG-TRUNK-MO-HACKS/scd/NOTES-STATUSFD
===================================================================
--- branches/GNUPG-TRUNK-MO-HACKS/scd/NOTES-STATUSFD	2007-08-16 12:18:44 UTC (rev 4563)
+++ branches/GNUPG-TRUNK-MO-HACKS/scd/NOTES-STATUSFD	2007-08-16 12:44:17 UTC (rev 4564)
@@ -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 at 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 at pink:~/g10/hacks/gnupg-mo/build/scd$ gpg-connect-agent -S /tmp/gpg-QZRVNr/S.scdaemon
+/sendfd /tmp/scd-events w
+STATUSFD
+OK
+moritz at pink:~/g10/hacks/gnupg-mo/build/scd$ 
+
+
+Watch the log file as you remove/insert the smartcard:
+
+moritz at pink:~/g10/hacks/gnupg-mo/build/scd$ tail -f /tmp/scd-events 
+CARD REMOVED
+CARD INSERTED
+CARD REMOVED
+CARD INSERTED
+^C
+moritz at pink:~/g10/hacks/gnupg-mo/build/scd$ 
+
+That's it for now.

Modified: branches/GNUPG-TRUNK-MO-HACKS/scd/command.c
===================================================================
--- branches/GNUPG-TRUNK-MO-HACKS/scd/command.c	2007-08-16 12:18:44 UTC (rev 4563)
+++ branches/GNUPG-TRUNK-MO-HACKS/scd/command.c	2007-08-16 12:44:17 UTC (rev 4564)
@@ -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,9 +1650,37 @@
   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;
+}
+
+
+
+
 
 /* Tell the assuan library about our commands */
 static int
@@ -1683,6 +1712,7 @@
     { "GETINFO",      cmd_getinfo },
     { "RESTART",      cmd_restart },
     { "APDU",         cmd_apdu },
+    { "STATUSFD",     cmd_statusfd },
     { NULL }
   };
   int i, rc;
@@ -1719,7 +1749,7 @@
     }
   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 @@
           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.  */

Added: branches/GNUPG-TRUNK-MO-HACKS/scd/statusfd.c
===================================================================
--- branches/GNUPG-TRUNK-MO-HACKS/scd/statusfd.c	2007-08-16 12:18:44 UTC (rev 4563)
+++ branches/GNUPG-TRUNK-MO-HACKS/scd/statusfd.c	2007-08-16 12:44:17 UTC (rev 4564)
@@ -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 at 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");
+}

Added: branches/GNUPG-TRUNK-MO-HACKS/scd/statusfd.h
===================================================================
--- branches/GNUPG-TRUNK-MO-HACKS/scd/statusfd.h	2007-08-16 12:18:44 UTC (rev 4563)
+++ branches/GNUPG-TRUNK-MO-HACKS/scd/statusfd.h	2007-08-16 12:44:17 UTC (rev 4564)
@@ -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




More information about the Gnupg-commits mailing list