|
From: <jda...@us...> - 2010-08-18 13:40:58
|
Revision: 509
http://pyscard.svn.sourceforge.net/pyscard/?rev=509&view=rev
Author: jdaussel
Date: 2010-08-18 13:40:51 +0000 (Wed, 18 Aug 2010)
Log Message:
-----------
Added partial support of remote pcsc readers with pyro
Added Paths:
-----------
trunk/pyscard/src/smartcard/pyro/
trunk/pyscard/src/smartcard/pyro/PyroReader.py
trunk/pyscard/src/smartcard/pyro/__init__.py
trunk/pyscard/src/smartcard/pyro/server/
trunk/pyscard/src/smartcard/pyro/server/PyroDaemon.py
trunk/pyscard/src/smartcard/pyro/server/PyroEventServer.py
trunk/pyscard/src/smartcard/pyro/server/PyroNameServer.py
trunk/pyscard/src/smartcard/pyro/server/RemoteCardConnection.py
trunk/pyscard/src/smartcard/pyro/server/RemoteReaderServer.py
trunk/pyscard/src/smartcard/pyro/server/__init__.py
Added: trunk/pyscard/src/smartcard/pyro/PyroReader.py
===================================================================
--- trunk/pyscard/src/smartcard/pyro/PyroReader.py (rev 0)
+++ trunk/pyscard/src/smartcard/pyro/PyroReader.py 2010-08-18 13:40:51 UTC (rev 509)
@@ -0,0 +1,90 @@
+"""PyroReaderClient: concrete reader class for Remote Readers
+
+__author__ = "gemalto http://www.gemalto.com"
+
+Copyright 2001-2010 gemalto
+Author: Jean-Daniel Aussel, mailto:jea...@ge...
+
+This file is part of pyscard.
+
+pyscard is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+pyscard 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with pyscard; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+"""
+
+import Pyro.core
+import Pyro.naming
+
+from smartcard.Exceptions import CardConnectionException, NoCardException
+from smartcard.reader.Reader import Reader
+from smartcard.reader.ReaderFactory import ReaderFactory
+
+class PyroReader(Reader):
+ """Remote reader class."""
+ def __init__( self, readername ):
+ """Constructs a new Remote Reader client implementation from a Pyro URI."""
+ ns=Pyro.naming.NameServerLocator().getNS()
+ self.uri = ns.resolve(':pyscard.smartcard.readers.'+readername)
+ self.reader = Pyro.core.getAttrProxyForURI(self.uri)
+ self.name = self.reader.name
+
+ def addtoreadergroup( self, groupname ):
+ """Add reader to a reader group."""
+ self.reader.addtoreadergroup( groupname )
+
+ def removefromreadergroup( self, groupname ):
+ """Remove a reader from a reader group"""
+ self.reader.removefromreadergroup( groupname )
+
+ def createConnection( self ):
+ """Return a card connection thru a remote reader."""
+ uri = self.reader.createConnection()
+ return Pyro.core.getAttrProxyForURI(uri)
+
+ class Factory:
+ def create(readername):
+ return PyroReader( readername )
+ create = staticmethod(create)
+
+ def readers(groups=[]):
+ readernames = []
+ try:
+ ns=Pyro.naming.NameServerLocator().getNS()
+ readernames = ns.list(':pyscard.smartcard.readers')
+ except Pyro.errors.NamingError:
+ print 'Warning: pyro name server not found'
+
+ remotereaders=[]
+ for readername in readernames:
+ remotereaders.append( PyroReader.Factory.create(readername[0]) )
+
+ return remotereaders
+ readers = staticmethod(readers)
+
+if __name__ == '__main__':
+ SELECT = [0xA0, 0xA4, 0x00, 0x00, 0x02]
+ DF_TELECOM = [0x7F, 0x10]
+ from smartcard.util import *
+
+ remotereaders = PyroReader.readers()
+ for reader in remotereaders:
+ try:
+ print reader.name, ', uri: ', reader.uri
+ connection = reader.createConnection()
+ connection.connect()
+ print toHexString( connection.getATR() )
+ data, sw1, sw2 = connection.transmit(SELECT + DF_TELECOM)
+ print "%X %X" % (sw1, sw2)
+ except NoCardException,x:
+ print 'no card in reader'
+
Added: trunk/pyscard/src/smartcard/pyro/__init__.py
===================================================================
--- trunk/pyscard/src/smartcard/pyro/__init__.py (rev 0)
+++ trunk/pyscard/src/smartcard/pyro/__init__.py 2010-08-18 13:40:51 UTC (rev 509)
@@ -0,0 +1 @@
+
Added: trunk/pyscard/src/smartcard/pyro/server/PyroDaemon.py
===================================================================
--- trunk/pyscard/src/smartcard/pyro/server/PyroDaemon.py (rev 0)
+++ trunk/pyscard/src/smartcard/pyro/server/PyroDaemon.py 2010-08-18 13:40:51 UTC (rev 509)
@@ -0,0 +1,92 @@
+"""PyroDaemon: Wrapper class around pyro daemon
+
+__author__ = "gemalto http://www.gemalto.com"
+
+Copyright 2001-2010 gemalto
+Author: Jean-Daniel Aussel, mailto:jea...@ge...
+
+This file is part of pyscard.
+
+pyscard is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+pyscard 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with pyscard; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+"""
+
+import signal
+from threading import Thread
+import time
+
+import Pyro.core
+import Pyro.naming
+
+class PyroDaemon:
+ """Singleton class to wrap the pyro daemon."""
+
+ class _PyroDaemon:
+ """The pyro daemon actual wrapper class.
+
+ A single instance of this class is created
+ by the public PyroDaemon class.
+ """
+ def __init__(self):
+ self.daemon = Pyro.core.Daemon()
+ self.handler = signal.signal( signal.SIGINT, self )
+ ns=Pyro.naming.NameServerLocator().getNS()
+ self.daemon.useNameServer(ns)
+
+ def __call__(self, signame, sf):
+ """Ctrl+c handler that will gracefully shutdown the server
+ upon Ctrl+C signal"""
+ print 'PyroDaemon Ctrl+C handler'
+ self.daemon.shutdown(True)
+ time.sleep(1)
+ self.handler( signame, sf )
+
+ def connect(self,object,name=None):
+ return self.daemon.connect(object,name)
+
+ def disconnect(self,object):
+ return self.daemon.disconnect(object)
+
+ def start(self):
+ """start pyro daemon."""
+ self.daemon.requestLoop()
+
+ # the singleton
+ instance = None
+
+ def __init__(self):
+ if not PyroDaemon.instance:
+ PyroDaemon.instance = PyroDaemon._PyroDaemon()
+
+ def __getattr__( self, name ):
+ return getattr( self.instance, name )
+
+class PyroDaemonThread(Thread):
+ """Thread running the Pyro daemon server.
+ """
+
+ def __init__(self):
+ """Initialize pyro event server with command line arguments.
+ For a complete list of command line arguments, see pyro documentation
+ for pyro-es start script."""
+ Thread.__init__( self )
+ self.setDaemon( True )
+ self.setName( 'smartcard.pyro.server.PyroDaemonThread' )
+ self.daemon = PyroDaemon()
+
+ def run(self):
+ """Starts Pyro daemon."""
+ self.daemon.start()
+
+
Added: trunk/pyscard/src/smartcard/pyro/server/PyroEventServer.py
===================================================================
--- trunk/pyscard/src/smartcard/pyro/server/PyroEventServer.py (rev 0)
+++ trunk/pyscard/src/smartcard/pyro/server/PyroEventServer.py 2010-08-18 13:40:51 UTC (rev 509)
@@ -0,0 +1,103 @@
+"""Utility class to start/stop Pyro Event Server.
+
+__author__ = "http://www.gemalto.com"
+
+Copyright 2001-2010 gemalto
+Author: Jean-Daniel Aussel, mailto:jea...@ge...
+
+This file is part of pyscard.
+
+pyscard is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+pyscard 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with pyscard; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+"""
+
+import signal
+import sys
+from threading import Thread
+import time
+
+import Pyro.EventService.Server
+import Pyro.naming
+import Pyro.nsc
+import Pyro.util
+
+class PyroEventServer(Thread):
+ """Thread running the Pyro Event server.
+ """
+
+ def __init__(self,args=[]):
+ """Initialize pyro event server with command line arguments.
+ For a complete list of command line arguments, see pyro documentation
+ for pyro-es start script."""
+ Thread.__init__( self )
+ self.setDaemon( True )
+ self.setName( 'smartcard.pyro.server.PyroEventServer' )
+ self.args = args
+ self.handler = signal.signal( signal.SIGINT, self )
+ self.starter = None
+
+ def run(self):
+ """Starts Pyro naming server with command line arguments (see pyro documentation)
+ """
+ args=[]
+ for arg in self.args: args.append(arg)
+ Args = Pyro.util.ArgParser()
+ Args.parse(args,'hkmrvxn:p:b:c:d:s:i:1:2:')
+
+ hostname = Args.getOpt('n',None)
+ identification = Args.getOpt('i',None)
+ port = None
+ useNameServer = True
+
+ if port:
+ port=int(port)
+ norange = (port==0)
+
+ self.starter = Pyro.EventService.Server.EventServiceStarter(identification=identification)
+ self.starter.start(hostname,port,useNameServer=useNameServer,norange=norange)
+
+ def stop(self):
+ """Shutdown pyro event server."""
+ pass
+
+ def waitStarted(self):
+ """wait until name server is started."""
+ started = False
+ while not started:
+ if self.starter!=None:
+ started = self.starter.waitUntilStarted(0.5)
+
+ def __call__(self, signame, sf):
+ """Ctrl+c handler that will gracefully shutdown the server
+ upon Ctrl+C signal"""
+ print 'PyroEventServer Ctrl+C handler'
+ self.stop()
+ time.sleep(1)
+ self.handler( signame, sf )
+
+
+if __name__ == '__main__':
+ import sys
+ from smartcard.pyro.server.PyroNameServer import PyroNameServer
+ pn = PyroNameServer(sys.argv[1:])
+ pn.start()
+ pn.waitStarted()
+ pe = PyroEventServer(sys.argv[1:])
+ pe.start()
+ pe.waitStarted()
+ pn.listall()
+ pe.stop()
+ pn.stop()
+
+
Added: trunk/pyscard/src/smartcard/pyro/server/PyroNameServer.py
===================================================================
--- trunk/pyscard/src/smartcard/pyro/server/PyroNameServer.py (rev 0)
+++ trunk/pyscard/src/smartcard/pyro/server/PyroNameServer.py 2010-08-18 13:40:51 UTC (rev 509)
@@ -0,0 +1,118 @@
+"""Utility class to start/stop Pyro Name Server.
+
+__author__ = "http://www.gemalto.com"
+
+Copyright 2001-2010 gemalto
+Author: Jean-Daniel Aussel, mailto:jea...@ge...
+
+This file is part of pyscard.
+
+pyscard is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+pyscard 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with pyscard; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+"""
+
+import signal
+import sys
+from threading import Thread
+import time
+
+import Pyro.naming
+import Pyro.nsc
+import Pyro.util
+
+class PyroNameServer(Thread):
+ """Thread running the Pyro Name server.
+ """
+
+ def __init__(self,args=[]):
+ """Initialize pyro name server with command line arguments.
+ For a complete list of command line arguments, see pyro documentation
+ for pyro-ns start script."""
+ Thread.__init__( self )
+ self.setDaemon( True )
+ self.setName( 'smartcard.pyro.server.PyroNameServer' )
+ self.args = args
+ self.handler = signal.signal( signal.SIGINT, self )
+
+ _args=[]
+ for arg in self.args: _args.append(arg)
+ Args = Pyro.util.ArgParser()
+ Args.parse(_args,'hkmrvxn:p:b:c:d:s:i:1:2:')
+ self.host = Args.getOpt('n',None)
+ self.bcport = Args.getOpt('b',None)
+ self.bcaddr = Args.getOpt('c',None)
+ self.identification = Args.getOpt('i',None)
+
+ def getShutdownArgs(self):
+ """return command line arguments for shutting down the
+ server; this command line is built from the name server
+ startup arguments."""
+ shutdownArgs = []
+ if self.host: shutdownArgs += [ '-h', self.host ]
+ if self.bcport: shutdownArgs += [ '-p', self.bcport ]
+ if self.bcaddr: shutdownArgs += [ '-c', self.bcaddr ]
+ if self.identification: shutdownArgs += [ '-i', self.identification ]
+
+ return shutdownArgs
+
+ def listall(self):
+ """List pyro namespace."""
+ args = self.getShutdownArgs() + ['listall']
+ Pyro.nsc.main( args )
+
+ def ping(self):
+ """Ping pyro naming server."""
+ args = self.getShutdownArgs() + ['ping']
+ Pyro.nsc.main( args )
+
+ def run(self):
+ """Starts Pyro naming server with command line arguments (see pyro documentation)
+ """
+ args=[]
+ for arg in self.args: args.append(arg)
+ Pyro.naming.main( args )
+
+ def stop(self):
+ """Shutdown pyro naming server."""
+ args = self.getShutdownArgs() + ['shutdown']
+ Pyro.nsc.main( args )
+ self.join()
+
+ def waitStarted(self):
+ """wait until name server is started."""
+ ns = None
+ while not ns:
+ try:
+ time.sleep(3)
+ ns=Pyro.naming.NameServerLocator(identification=self.identification).getNS()
+ except Pyro.errors.NamingError as er:
+ pass
+
+ def __call__(self, signame, sf):
+ """Ctrl+c handler that will gracefully shutdown the server
+ upon Ctrl+C signal"""
+ print 'PyroNameServer Ctrl+C handler'
+ self.stop()
+ time.sleep(1)
+ self.handler( signame, sf )
+
+
+if __name__ == '__main__':
+ import sys
+ pt = PyroNameServer( sys.argv[1:] )
+ pt.start()
+ pt.waitStarted()
+ pt.stop()
+
+
Added: trunk/pyscard/src/smartcard/pyro/server/RemoteCardConnection.py
===================================================================
--- trunk/pyscard/src/smartcard/pyro/server/RemoteCardConnection.py (rev 0)
+++ trunk/pyscard/src/smartcard/pyro/server/RemoteCardConnection.py 2010-08-18 13:40:51 UTC (rev 509)
@@ -0,0 +1,44 @@
+"""RemoteCardConnection class manages connections to a remote reader
+thru pyro (http://www.xs4all.nl/~irmen/pyro3/).
+
+__author__ = "http://www.gemalto.com"
+
+Copyright 2001-2010 gemalto
+Author: Jean-Daniel Aussel, mailto:jea...@ge...
+
+This file is part of pyscard.
+
+pyscard is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+pyscard 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with pyscard; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+"""
+
+import Pyro.core
+import Pyro.naming
+
+from smartcard.CardConnection import CardConnection
+from smartcard.CardConnectionDecorator import CardConnectionDecorator
+from smartcard.Exceptions import CardConnectionException, NoCardException
+from smartcard.Observer import Observable
+
+class RemoteCardConnection(CardConnectionDecorator,Pyro.core.ObjBase):
+ """Remote connection class. Handles connection with a card inserted inside a remote PC."""
+
+ def __init__(self, cardConnectionComponent):
+ """Construct a new remote card connection.
+
+ connection: the reader connection
+ """
+ Pyro.core.ObjBase.__init__(self)
+ CardConnectionDecorator.__init__( self, cardConnectionComponent )
+
Added: trunk/pyscard/src/smartcard/pyro/server/RemoteReaderServer.py
===================================================================
--- trunk/pyscard/src/smartcard/pyro/server/RemoteReaderServer.py (rev 0)
+++ trunk/pyscard/src/smartcard/pyro/server/RemoteReaderServer.py 2010-08-18 13:40:51 UTC (rev 509)
@@ -0,0 +1,121 @@
+"""RemoteReaderServer: monitor local readers and publish them as pyro
+Remote Readers.
+
+__author__ = "gemalto http://www.gemalto.com"
+
+Copyright 2001-2010 gemalto
+Author: Jean-Daniel Aussel, mailto:jea...@ge...
+
+This file is part of pyscard.
+
+pyscard is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+pyscard 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with pyscard; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+"""
+
+try:
+ import Pyro.core
+ import Pyro.naming
+except:
+ print 'You need pyro (python remote objects) at http://www.xs4all.nl/~irmen/pyro3/'
+ import sys
+ sys.exit()
+
+import signal
+import time
+
+import smartcard.System
+from smartcard.reader.Reader import Reader
+from smartcard.ReaderMonitoring import ReaderMonitor, ReaderObserver
+from smartcard.pyro.server.RemoteCardConnection import RemoteCardConnection
+from smartcard.pyro.server import PyroDaemon
+from smartcard.pyro.server import PyroNameServer
+
+class RemoteReader(Reader,Pyro.core.ObjBase):
+ """Remote reader class that embeds a local reader."""
+
+ def __init__(self,reader):
+ """Encapsulate a local reader and publish as a pyro remote reader.
+
+ reader: the local reader to publish remotely
+ """
+ Pyro.core.ObjBase.__init__(self)
+ self.readerobj = reader
+ self.name = reader.name
+
+ def addtoreadergroup( self, groupname ):
+ """Add reader to a reader group."""
+ self.readerobj.reader.addtoreadergroup( groupname )
+
+ def removefromreadergroup( self, groupname ):
+ """Remove a reader from a reader group"""
+ self.readerobj.reader.removefromreadergroup( groupname )
+
+ def createConnection( self ):
+ """Return a card connection thru the reader."""
+ connection = RemoteCardConnection( self.readerobj.createConnection() )
+ daemon = PyroDaemon.PyroDaemon()
+ uri = daemon.connect(connection)
+ return uri
+
+
+
+class RemoteReaderServer(ReaderObserver):
+ """Monitor local readers, and publish them as remote pyro readers.
+ """
+ def __init__(self):
+ """Starts pyro name server and constructs reader name space."""
+ self.pn = PyroNameServer.PyroNameServer()
+ self.pn.start()
+ self.pn.waitStarted()
+
+ Pyro.core.initServer()
+ self.ns=Pyro.naming.NameServerLocator().getNS()
+ try:
+ self.ns.createGroup(':pyscard')
+ self.ns.createGroup(':pyscard.smartcard')
+ self.ns.createGroup(':pyscard.smartcard.readers')
+ except Pyro.errors.NamingError as error:
+ print error
+ self.daemon = PyroDaemon.PyroDaemon()
+ self.remotereaders = {}
+
+ def start(self):
+ """Start pyro daemon and accept incoming requests."""
+ self.daemon.start()
+
+
+ def update(self, observable, (addedreaders, removedreaders)):
+ """Called when a local reader is added or removed.
+ Create remote pyro reader objects for added readers.
+ Delete remote pyro reader objects for removed readers."""
+ for reader in addedreaders:
+ remotereader = RemoteReader(reader)
+ self.remotereaders[reader.name] = remotereader
+ name = "".join(reader.name.split(' '))
+ name = ":pyscard.smartcard.readers."+"".join(name.split('.'))
+ uri = self.daemon.connect(remotereader,name)
+ for reader in removedreaders:
+ remotereader = self.remotereaders[reader.name]
+ self.daemon.disconnect(remotereader)
+ del self.remotereaders[reader.name]
+ self.pn.listall()
+
+
+if __name__ == '__main__':
+ readerserver = RemoteReaderServer()
+ readermonitor = ReaderMonitor()
+ readermonitor.addObserver(readerserver)
+ print 'Reader remote server up and running',
+ print 'Please enter Ctrl+C to stop and exit...'
+ readerserver.start()
Added: trunk/pyscard/src/smartcard/pyro/server/__init__.py
===================================================================
--- trunk/pyscard/src/smartcard/pyro/server/__init__.py (rev 0)
+++ trunk/pyscard/src/smartcard/pyro/server/__init__.py 2010-08-18 13:40:51 UTC (rev 509)
@@ -0,0 +1 @@
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|