├── .gitignore
├── LGPL-2.1
├── Makefile.am
├── NEWS
├── TODO
├── bootstrap
├── configure.ac
├── doc
├── Makefile.am
├── README
├── doxygen-footer.html
├── doxygen.conf.in
└── opensc-logo.gif
├── etc
├── Info.plist
├── Makefile.am
├── init-script.in
├── openct-disable.fdi
├── openct-policy.fdi
├── openct.conf.in
├── openct.fdi
├── openct.hald.in
├── openct.udev.compat
├── openct.udev.in
├── openct.udev.modalias.in
├── openct.usermap
├── openct_pcmcia.in
├── openct_serial.in
├── openct_usb.in
├── openct_usb.mdev.in
└── reader.conf.in
├── m4
└── ac_create_stdint_h.m4
├── macos
├── Makefile.am
└── libtool-bundle
├── solaris
├── Makefile.client
├── Makefile.server
├── README
├── checkinstall.in
├── devices-openct-fabric.xml-dist
├── openct-fabric-dist
├── openct-hotplug-dist
├── openct.conf-dist
├── pkginfo.in
├── postinstall
├── preremove
└── proto
└── src
├── Makefile.am
├── ct
├── Makefile.am
├── buffer.c
├── client.c
├── error.c
├── libopenct.pc.in
├── mainloop.c
├── path.c
├── socket.c
├── status.c
└── tlv.c
├── ctapi
├── Makefile.am
├── ctapi.c
└── ctapi.h
├── ifd
├── Makefile.am
├── apdu.c
├── atr.c
├── atr.h
├── cardman.h
├── checksum.c
├── conf.c
├── ctbcs.c
├── ctbcs.h
├── device.c
├── driver.c
├── ifd-acr30u.c
├── ifd-cardman.c
├── ifd-ccid.c
├── ifd-cm4000.c
├── ifd-cyberjack.c
├── ifd-egate.c
├── ifd-epass3k.c
├── ifd-etoken.c
├── ifd-etoken64.c
├── ifd-eutron.c
├── ifd-gempc.c
├── ifd-ikey2k.c
├── ifd-ikey3k.c
├── ifd-kaan.c
├── ifd-pertosmart1030.c
├── ifd-pertosmart1038.c
├── ifd-rutoken.c
├── ifd-smartboard.c
├── ifd-smph.c
├── ifd-starkey.c
├── ifd-towitoko.c
├── ifd-wbeiuu.c
├── ifdhandler.c
├── ifdhandler.h
├── ifdproxy.c
├── init.c
├── internal.h
├── locks.c
├── manager.c
├── modules.c
├── pcmcia-block.c
├── pcmcia.c
├── process.c
├── proto-escape.c
├── proto-gbp.c
├── proto-sync.c
├── proto-t0.c
├── proto-t1.c
├── proto-trans.c
├── protocol.c
├── reader.c
├── ria-device.c
├── ria-server.c
├── ria.c
├── ria.h
├── serial.c
├── sys-bsd.c
├── sys-linux.c
├── sys-null.c
├── sys-osx.c
├── sys-solaris.c
├── sys-sunray.c
├── usb-descriptors.c
├── usb-descriptors.h
├── usb.c
└── utils.c
├── include
├── Makefile.am
└── openct
│ ├── Makefile.am
│ ├── apdu.h
│ ├── buffer.h
│ ├── conf.h
│ ├── device.h
│ ├── driver.h
│ ├── error.h
│ ├── ifd.h
│ ├── logging.h
│ ├── openct.h
│ ├── path.h
│ ├── protocol.h
│ ├── server.h
│ ├── socket.h
│ └── tlv.h
├── pcsc
├── Makefile.am
└── pcsc.c
└── tools
├── Makefile.am
├── openct-control.c
├── openct-tool.1.in
└── openct-tool.c
/.gitignore:
--------------------------------------------------------------------------------
1 | Makefile
2 | Makefile.in
3 | core
4 | archive
5 | acinclude.m4
6 | aclocal.m4
7 | autom4te.cache
8 | compile
9 | confdefs.h
10 | config.*
11 | configure
12 | conftest
13 | conftest.c
14 | depcomp
15 | install-sh
16 | libtool
17 | libtool.m4
18 | ltmain.sh
19 | missing
20 | mkinstalldirs
21 | so_locations
22 | stamp-h*
23 |
24 | .deps
25 | .libs
26 | .#*#
27 | .*.bak
28 | .*.orig
29 | .*.rej
30 | .*~
31 | #*#
32 | *.bak
33 | *.d
34 | *.def
35 | *.dll
36 | *.exe
37 | *.la
38 | *.lib
39 | *.lo
40 | *.o
41 | *.orig
42 | *.pdb
43 | *.rej
44 | *.u
45 | *.rc
46 | *.pc
47 | *~
48 | *.gz
49 | *.bz2
50 | *.[0-9]
51 | *.html
52 | *.gif
53 | *.css
54 | *.out
55 | *.loT
56 |
57 | etc/openct.udev
58 | etc/openct.udev.modalias
59 | etc/openct_usb.mdev
60 | m4/ltoptions.m4
61 | m4/ltsugar.m4
62 | m4/ltversion.m4
63 | m4/lt~obsolete.m4
64 | doc/doxygen.conf
65 | etc/init-script
66 | etc/openct.conf
67 | etc/openct.hald
68 | etc/openct_pcmcia
69 | etc/openct_serial
70 | etc/openct_usb
71 | etc/reader.conf
72 | src/ifd/ifdhandler
73 | src/ifd/ifdproxy
74 | src/include/openct/types.h
75 | src/tools/openct-control
76 | src/tools/openct-tool
77 |
--------------------------------------------------------------------------------
/Makefile.am:
--------------------------------------------------------------------------------
1 | AUTOMAKE_OPTIONS = foreign 1.10
2 | ACLOCAL_AMFLAGS = -I m4
3 |
4 | MAINTAINERCLEANFILES = \
5 | config.log config.status \
6 | $(srcdir)/Makefile.in \
7 | $(srcdir)/config.h.in $(srcdir)/config.h.in~ $(srcdir)/configure \
8 | $(srcdir)/install-sh $(srcdir)/ltmain.sh $(srcdir)/missing \
9 | $(srcdir)/depcomp $(srcdir)/aclocal.m4 $(srcdir)/compile \
10 | $(srcdir)/config.guess $(srcdir)/config.sub \
11 | $(srcdir)/m4/ltsugar.m4 $(srcdir)/m4/libtool.m4 \
12 | $(srcdir)/m4/ltversion.m4 $(srcdir)/m4/lt~obsolete.m4 \
13 | $(srcdir)/m4/ltoptions.m4 \
14 | $(srcdir)/packaged
15 | EXTRA_DIST = .gitignore
16 |
17 | SUBDIRS = etc macos src doc
18 |
19 | dist_noinst_SCRIPTS = bootstrap
20 | dist_noinst_DATA = LGPL-2.1 TODO \
21 | solaris/Makefile.client solaris/Makefile.server solaris/README \
22 | solaris/checkinstall.in solaris/devices-openct-fabric.xml-dist \
23 | solaris/openct-fabric-dist solaris/openct-hotplug-dist \
24 | solaris/openct.conf-dist solaris/pkginfo.in solaris/postinstall \
25 | solaris/preremove solaris/proto
26 | dist_doc_DATA = NEWS
27 |
28 | # Allow detection of packaged tarball
29 | dist-hook:
30 | echo > "$(distdir)/packaged"
31 |
--------------------------------------------------------------------------------
/TODO:
--------------------------------------------------------------------------------
1 | - sometimes the communication freezes, some packet does not
2 | reach the destination. can be proproduced with egate driver,
3 | cryptoflex card and opensc regression test init0004,6,
4 | but is not specific to these drivers and cards
5 | - improve pc/sc detection
6 | - error handling: use error codes everywhere
7 | - pin verification via keypad
8 | - ifdhandler should clear status file slot on exit
9 | - openct-control init: debug messages to syslog
10 | - rewrite USB layer, add native support for *BSD
11 | and MacOS X. Remove optional libusb dependency
12 | - CCID driver
13 |
--------------------------------------------------------------------------------
/bootstrap:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set -e
4 | set -x
5 | if test -f Makefile; then
6 | make distclean
7 | fi
8 | rm -rf *~ *.cache *.m4 config.guess config.log \
9 | config.status config.sub depcomp ltmain.sh
10 | autoreconf --verbose --install --force
11 |
--------------------------------------------------------------------------------
/doc/Makefile.am:
--------------------------------------------------------------------------------
1 | MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
2 |
3 | dist_doc_DATA = README
4 | dist_noinst_DATA = $(srcdir)/doxygen-footer.html $(srcdir)/*.gif
5 |
6 | if ENABLE_API_DOC
7 |
8 | apidoc_DATA=api.out/html/*
9 |
10 | api.out/html/*: api.out
11 | api.out: $(top_srcdir)/src/include/openct/*.h \
12 | $(srcdir)/*.gif \
13 | doxygen.conf
14 | -rm -fr api.out
15 | $(DOXYGEN) doxygen.conf
16 | cp "$(srcdir)"/*.gif api.out/html
17 |
18 | endif
19 |
20 | clean-local:
21 | -rm -fr api.out
22 |
--------------------------------------------------------------------------------
/doc/README:
--------------------------------------------------------------------------------
1 | This directory contains a snapshot of the OpenCT Wiki
2 | =====================================================
3 |
4 | The original wiki page is at http://www.opensc-project.org/openct/
5 | and includes a bug tracker and source browser.
6 |
7 | The wiki was transformed to html using the export-wiki shell
8 | script and xsl style sheet. The original version is at
9 | http://www.twdata.org/trac-howto/
10 |
11 | To update the documentation run "make dist" in the top
12 | directory of the source code. Note: to do so files are
13 | fetched from the network using wget and xsltproc is needed
14 | to transform the files. Also the API documentation is
15 | updated using doxygen. Make sure all these tools are
16 | installed.
17 |
--------------------------------------------------------------------------------
/doc/doxygen-footer.html:
--------------------------------------------------------------------------------
1 |
2 | libp11, Copyright (C) 2005 Olaf Kirch <okir@lst.de> |  |
3 |
--------------------------------------------------------------------------------
/doc/opensc-logo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenSC/openct/a4f3fcb91dcd78274dffb1b934e4a8c55dbb91a4/doc/opensc-logo.gif
--------------------------------------------------------------------------------
/etc/Info.plist:
--------------------------------------------------------------------------------
1 | ifdManufacturerString
2 | OpenCT Project (www.opensc-project.org/openct/)
3 | ifdProductString
4 | PC/SC Lite IFD wrapper for OpenCT
5 |
6 | ifdCapabilities
7 | 0x00000000
8 | ifdProtocolSupport
9 | 0x00000001
10 | ifdVersionNumber
11 | 0x00000001
12 |
13 | ifdVendorID
14 |
15 | 0x0973
16 | 0x0529
17 | 0x0529
18 | 0x0529
19 | 0x0529
20 | 0x073d
21 | 0x04b9
22 | 0x04b9
23 | 0x096e
24 | 0x03f0
25 | 0x046a
26 | 0x04e6
27 | 0x04e6
28 | 0x04e6
29 | 0x04e6
30 | 0x04e6
31 | 0x04e6
32 | 0x073d
33 | 0x076b
34 | 0x076b
35 | 0x076b
36 | 0x076b
37 | 0x076b
38 | 0x0783
39 | 0x08e6
40 | 0x08e6
41 | 0x08e6
42 | 0x0b97
43 | 0x0b97
44 | 0x0bf8
45 | 0x0dc3
46 | 0x0a89
47 | 0x072f
48 | 0x072f
49 | 0x072f
50 | 0x072f
51 | 0x072f
52 | 0x072f
53 | 0x104f
54 | 0x0c4b
55 | 0x0a89
56 | 0x0a89
57 |
58 |
59 | ifdProductID
60 |
61 | 0x0001
62 | 0x050c
63 | 0x0514
64 | 0x0600
65 | 0x0700
66 | 0x0005
67 | 0x1202
68 | 0x1300
69 | 0x0005
70 | 0x1024
71 | 0x0010
72 | 0x5115
73 | 0x5116
74 | 0x5117
75 | 0x511d
76 | 0xE001
77 | 0xE003
78 | 0x0c00
79 | 0x1021
80 | 0x3021
81 | 0x5121
82 | 0x5321
83 | 0x6622
84 | 0x0003
85 | 0x3437
86 | 0x3438
87 | 0x4433
88 | 0x7762
89 | 0x7772
90 | 0x1006
91 | 0x1004
92 | 0x0030
93 | 0x0001
94 | 0x8009
95 | 0x9000
96 | 0x9006
97 | 0x9007
98 | 0x90d0
99 | 0x0004
100 | 0x0100
101 | 0x0020
102 | 0x0012
103 |
104 |
105 | ifdFriendlyName
106 |
107 | Axalto/Schlumberger/Gemalo egate token
108 | Aladdin eToken PRO
109 | Aladdin eToken PRO
110 | Aladdin eToken PRO 64
111 | Aladdin eToken PRO NG OTP
112 | Eutron CryptoIdendity
113 | Rainbow iKey 2000
114 | Rainbow iKey 3000
115 | G&D Starkey 100
116 | Generic CCID Reader
117 | Generic CCID Reader
118 | Generic CCID Reader
119 | Generic CCID Reader
120 | Generic CCID Reader
121 | Generic CCID Reader
122 | Generic CCID Reader
123 | Generic CCID Reader
124 | Generic CCID Reader
125 | Generic CCID Reader
126 | Generic CCID Reader
127 | Generic CCID Reader
128 | Generic CCID Reader
129 | Generic CCID Reader
130 | Generic CCID Reader
131 | Generic CCID Reader
132 | Generic CCID Reader
133 | Generic CCID Reader
134 | Generic CCID Reader
135 | Generic CCID Reader
136 | Generic CCID Reader
137 | Generic CCID Reader
138 | Generic CCID Reader
139 | Pertosmart Card Reader
140 | Pertosmart Card Reader
141 | Pertosmart Card Reader
142 | Pertosmart Card Reader
143 | Pertosmart Card Reader
144 | Pertosmart Card Reader
145 | WB Electronics Inifinty USB Ulimited
146 | Cyberjack Reader
147 | Aktiv Rutoken S
148 | Aktiv uaToken S
149 |
150 |
--------------------------------------------------------------------------------
/etc/Makefile.am:
--------------------------------------------------------------------------------
1 | MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
2 |
3 | SUFFIXES = .in
4 |
5 | sources = openct.udev.in openct.udev.modalias.in openct.udev.compat openct_usb.mdev.in \
6 | openct.conf.in openct.hald.in reader.conf.in \
7 | init-script.in openct.hald.in openct_usb.mdev.in \
8 | openct_usb.in openct_pcmcia.in openct_serial.in
9 | generated_data = openct.udev openct.udev.modalias openct_usb.mdev \
10 | openct.conf openct.hald reader.conf
11 | noinst_generated_scripts = init-script openct.hald openct_usb.mdev
12 | udev_generated_scripts = openct_usb openct_pcmcia openct_serial
13 |
14 | CLEANFILES = $(generated_data) $(noinst_generated_scripts) $(udev_generated_scripts)
15 |
16 | nodist_noinst_SCRIPTS = $(noinst_generated_scripts)
17 | dist_noinst_DATA = Info.plist openct.fdi openct-policy.fdi openct-disable.fdi $(sources)
18 | nodist_noinst_DATA = $(generated_data)
19 |
20 | if ENABLE_UDEV
21 | nodist_udev_SCRIPTS = $(udev_generated_scripts)
22 | else
23 | nodist_noinst_SCRIPTS += $(udev_generated_scripts)
24 | endif
25 |
26 | if ENABLE_HOTPLUG
27 | hotplug_DATA = openct.usermap
28 | else
29 | dist_noinst_DATA += openct.usermap
30 | endif
31 |
32 |
33 | install-exec-hook: openct.conf
34 | $(MKDIR_P) "$(DESTDIR)$(sysconfdir)"
35 | if [ -f "$(DESTDIR)$(sysconfdir)/openct.conf" ]; then \
36 | $(INSTALL_DATA) openct.conf "$(DESTDIR)$(sysconfdir)/openct.conf.new"; \
37 | else \
38 | $(INSTALL_DATA) openct.conf "$(DESTDIR)$(sysconfdir)/openct.conf"; \
39 | fi
40 |
41 | .in:
42 | sed \
43 | -e 's|@bindir[@]|$(bindir)|g' \
44 | -e 's|@sbindir[@]|$(sbindir)|g' \
45 | -e 's|@libdir[@]|$(libdir)|g' \
46 | -e 's|@udevdir[@]|$(udevdir)|g' \
47 | -e 's|@localstatedir[@]|$(localstatedir)|g' \
48 | -e 's|@OPENCT_SOCKET_PATH[@]|@OPENCT_SOCKET_PATH@|g' \
49 | -e 's|@ENABLE_NON_PRIVILEGED[@]|@ENABLE_NON_PRIVILEGED@|g' \
50 | -e 's|@daemon_user[@]|@daemon_user@|g' \
51 | -e 's|@daemon_groups[@]|@daemon_groups@|g' \
52 | < "$<" > "$@"
53 |
54 | uninstall-hook:
55 | rm -f "$(DESTDIR)$(sysconfdir)/openct.conf"
56 |
--------------------------------------------------------------------------------
/etc/init-script.in:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | ### BEGIN INIT INFO
4 | # Provides: openct
5 | # Required-Start: $syslog
6 | # Required-Stop: $syslog
7 | # Should-Start: $local_fs
8 | # Should-Stop: $local_fs
9 | # Default-Start: 2 3 4 5
10 | # Default-Stop: 0 1 6
11 | # Short-Description: smart card terminal framework
12 | # Description: Initialize the OpenCT smart card terminal
13 | # framework.
14 | ### END INIT INFO
15 |
16 | PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
17 | DAEMON=@sbindir@/openct-control
18 | STATUS_DIR="@OPENCT_SOCKET_PATH@"
19 | STATUS_FILE="$STATUS_DIR/status"
20 | NAME=OpenCT
21 | DESC="smart card terminal framework"
22 |
23 | test -x $DAEMON || exit 0
24 |
25 | # create the directory for our status and socket files,
26 | # if it does not exist.
27 | if ! test -e "$STATUS_DIR"
28 | then
29 | mkdir "$STATUS_DIR"
30 |
31 | # maybe you also want to set owner ship and permissions here.
32 | # this example would assign the directory to a group "scard"
33 | # and set permissions so only users in that group can access
34 | # smart card readers via openct.
35 | #chown root:scard "$STATUS_DIR"
36 | #chmod 0750 "$STATUS_DIR"
37 | fi
38 |
39 | set -e
40 |
41 | case "$1" in
42 | start)
43 | echo -n "Starting $DESC: $NAME"
44 | $DAEMON init
45 | echo "."
46 | ;;
47 | stop)
48 | echo -n "Stopping $DESC: $NAME "
49 | if [ -f $STATUS_FILE ]; then
50 | $DAEMON shutdown
51 | rm -f $STATUS_FILE
52 | fi
53 | echo "."
54 | ;;
55 | #reload)
56 | #
57 | # If the daemon can reload its config files on the fly
58 | # for example by sending it SIGHUP, do it here.
59 | #
60 | # If the daemon responds to changes in its config file
61 | # directly anyway, make this a do-nothing entry.
62 | #
63 | # echo -n "Reloading $DESC configuration..."
64 | # start-stop-daemon --stop --signal 1 --quiet --pidfile \
65 | # @localstatedir@/run/$NAME.pid --exec $DAEMON
66 | # echo "done."
67 | #;;
68 | restart|force-reload)
69 | #
70 | # If the "reload" option is implemented, move the "force-reload"
71 | # option to the "reload" entry above. If not, "force-reload" is
72 | # just the same as "restart".
73 | #
74 | echo -n "Restarting $DESC: $NAME"
75 | if [ -f $STATUS_FILE ]; then
76 | $DAEMON shutdown
77 | rm -f $STATUS_FILE
78 | fi
79 | sleep 0.1
80 | $DAEMON init
81 | echo "."
82 | ;;
83 | *)
84 | N=/etc/init.d/$NAME
85 | # echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
86 | echo "Usage: $N {start|stop|restart|force-reload}" >&2
87 | exit 1
88 | ;;
89 | esac
90 |
91 | exit 0
92 |
--------------------------------------------------------------------------------
/etc/openct-disable.fdi:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | hald-addon-openct
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/etc/openct-policy.fdi:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | hald-addon-openct
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/etc/openct.conf.in:
--------------------------------------------------------------------------------
1 | # Set debug level
2 | debug = 0;
3 | #
4 | # Enable hot plugging
5 | hotplug = yes;
6 |
7 | #
8 | # Path to ifdhandler
9 | ifdhandler {
10 | program = @sbindir@/ifdhandler;
11 | #
12 | # Safe to disable force_poll:
13 | # >=linux-2.6.27.14
14 | # >=linux-2.6.28.3
15 | #
16 | force_poll = 1;
17 | @ENABLE_NON_PRIVILEGED@ user = @daemon_user@;
18 | @ENABLE_NON_PRIVILEGED@ groups = {
19 | @ENABLE_NON_PRIVILEGED@ @daemon_groups@,
20 | @ENABLE_NON_PRIVILEGED@ };
21 | };
22 |
23 | #
24 | # Configuration for ifdproxy (if you use it)
25 | ifdproxy {
26 | # server-port = @OPENCT_SOCKET_PATH@/.ifdproxy,
27 | # device-port = :6666;
28 | };
29 |
30 | # Configure static, non-hotplug aware readers here
31 | #
32 | # For a list of drivers try command 'ifdhandler -i', please
33 | # notice that not all drivers have serial device capability.
34 |
35 | #reader towitoko {
36 | # driver = towitoko;
37 | # device = serial:/dev/ttyS0;
38 | #};
39 |
40 | #reader gempc {
41 | # driver = gempc;
42 | # device = serial:/dev/ttyS0;
43 | #};
44 |
45 | #reader cm4000 {
46 | # driver = cm4000;
47 | # device = pcmcia:/dev/cmm0;
48 | #};
49 |
50 | #reader cm4040 {
51 | # driver = ccid;
52 | # device = pcmcia_block:/dev/cmx0;
53 | #};
54 |
55 | #reader pertosmart1030 {
56 | # driver = pertosmart1030;
57 | # device = serial:/dev/ttyS0;
58 | #};
59 |
60 | #
61 | # Hotplug IDs
62 | driver egate {
63 | ids = {
64 | usb:0973/0001,
65 | };
66 | };
67 |
68 | driver ePass3000 {
69 | ids = {
70 | usb:096e/0401,
71 | };
72 | };
73 |
74 | driver etoken {
75 | ids = {
76 | usb:0529/050c,
77 | usb:0529/0514,
78 | };
79 | };
80 | driver etoken64 {
81 | ids = {
82 | usb:0529/0600,
83 | usb:0529/0700,
84 | };
85 | };
86 | driver eutron {
87 | ids = {
88 | usb:073d/0005,
89 | };
90 | };
91 | driver ikey2k {
92 | ids = {
93 | usb:04b9/1202,
94 | };
95 | };
96 | driver ikey3k {
97 | ids = {
98 | usb:04b9/1300,
99 | };
100 | };
101 | driver starkey {
102 | ids = {
103 | usb:096e/0005,
104 | };
105 | };
106 | driver cardman {
107 | ids = {
108 | # usb:076b/0596, # OMNIKEY CardMan 2020
109 | # usb:076b/1784, # OMNIKEY CardMan 6020
110 | # usb:08d4/0009, # Fujitsu Siemens SCR USB Reader
111 | };
112 | };
113 | driver ccid {
114 | ids = {
115 | usb:03f0/1024, # HP Keyboard with CCID reader
116 | usb:046a/0010, # Cherry smartboard G83-6744
117 | usb:04e6/5115,
118 | usb:04e6/5116,
119 | usb:04e6/5117, # SCM Micro token size reader
120 | usb:04e6/511d, # SCM Micro SCR3311
121 | usb:04e6/E001,
122 | usb:04e6/E003,
123 | usb:073d/0c00, # Eutron SimPocket (doesn't work yet)
124 | usb:076b/1021, # OmniKey CardMan 1021
125 | usb:076b/3021,
126 | usb:076b/5121,
127 | usb:076b/5321, # OmniKey CardMan 5321
128 | usb:076b/6622, # OmniKey CardMan 6121
129 | usb:0783/0003,
130 | usb:08e6/3437, # Gemplus
131 | usb:08e6/3438, # Gemplus GemPC Key SmartCard Reader
132 | usb:08e6/4433, # Gemplus
133 | usb:0b97/7762, # O2 Micro, Inc. Oz776 SmartCard Reader
134 | usb:0b97/7772, # O2 Micro, Inc. Oz776 SmartCard Reader
135 | usb:0bf8/1006, # fujitsu siemens 3.5" drive size reader
136 | usb:0dc3/1004, # Athena Smartcard Solutions, Inc. ASEKey
137 | usb:0a89/0030, # Aktiv Rutoken ECP
138 | };
139 | };
140 | driver pertosmart1030 {
141 | ids = {
142 | usb:072f/0001,
143 | usb:072f/8009,
144 | };
145 | };
146 | driver pertosmart1038 {
147 | ids = {
148 | usb:072f/9000,
149 | usb:072f/9006, # ACS CryptoMate Token
150 | usb:072f/9007, # ACS ACR 100 SIMFlash
151 | usb:072f/90d0,
152 | };
153 | };
154 | #driver wbeiuu { # driver not working yet
155 | # ids = {
156 | # usb:104f/0004,
157 | # };
158 | #};
159 |
160 | # Tested with USBID 0c4b:0100. These are red readers: one with LCD,
161 | # another one without.
162 | driver cyberjack {
163 | ids = {
164 | usb:0c4b/0100,
165 | };
166 | };
167 | driver rutoken {
168 | ids = {
169 | usb:0a89/0020, # Aktiv Rutoken S
170 | usb:0a89/0012, # Aktiv uaToken S
171 | };
172 | };
173 |
--------------------------------------------------------------------------------
/etc/openct.fdi:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | true
9 |
10 |
11 |
12 |
13 |
14 | true
15 |
16 |
17 |
18 |
19 |
20 | true
21 |
22 |
23 |
24 |
25 |
26 | true
27 |
28 |
29 |
30 |
31 |
32 | true
33 |
34 |
35 |
36 |
37 |
38 | true
39 |
40 |
41 |
42 |
43 |
44 | true
45 |
46 |
47 |
48 |
49 |
50 | true
51 |
52 |
53 |
54 |
55 |
56 | true
57 |
58 |
59 |
60 |
61 |
62 | true
63 |
64 |
65 |
66 |
67 |
68 | true
69 |
70 |
71 |
72 |
73 |
74 | true
75 |
76 |
77 |
78 |
79 |
80 | true
81 |
82 |
83 |
84 |
85 |
86 | true
87 |
88 |
89 |
90 |
91 |
92 | true
93 |
94 |
95 |
96 |
97 |
98 | true
99 |
100 |
101 |
102 |
103 |
104 | true
105 |
106 |
107 |
108 |
109 |
110 | true
111 |
112 |
113 |
114 |
115 | true
116 |
117 |
118 |
119 |
120 |
121 | true
122 |
123 |
124 |
125 |
126 |
127 | true
128 |
129 |
130 |
131 |
132 |
133 | true
134 |
135 |
136 |
137 | smart_card_reader
138 | @info.parent:linux.device_file
139 | smart_card_reader
140 |
141 |
142 |
143 |
144 |
145 |
--------------------------------------------------------------------------------
/etc/openct.hald.in:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PRODUCT="`printf %x/%x/%x $HAL_PROP_USB_VENDOR_ID $HAL_PROP_USB_PRODUCT_ID \
4 | $HAL_PROP_USB_DEVICE_REVISION_BCD`"
5 |
6 | # this script is run by root, so you can use it to modify
7 | # owner, group and permissions of the device file.
8 | #
9 | # NOTE: Minor race condidion. udev creates nodes with o+r.
10 | #
11 | # commented out for now, every administrator/distribution
12 | # should apply the security policy it prefers.
13 | #
14 | # usualy openct is run as root.root, thus no changes are
15 | # necessary (well, a chmod o-r would be good). but if
16 | # you choose to run openct as a different user or group.
17 | # you need to setup permissions here.
18 | #
19 | #chmod o-r $HAL_PROP_SMART_CARD_READER_DEVICE_FILE
20 | #chown @USER@:@GROUP@ $HAL_PROP_SMART_CARD_READER_DEVICE_FILE
21 |
22 | if test -e "$HAL_PROP_SMART_CARD_READER_DEVICE_FILE"
23 | then
24 | exec @sbindir@/openct-control attach usb:$PRODUCT usb $HAL_PROP_SMART_CARD_READER_DEVICE_FILE
25 | fi
26 |
--------------------------------------------------------------------------------
/etc/openct.udev.compat:
--------------------------------------------------------------------------------
1 |
2 | # some distributions might not have a proper rule to set the name.
3 | # this is needed without USB_DEVICEFS the kernel doesn't tell us about
4 | # DEVICE. so we need to know the name of the device created by udev in
5 | # /dev/bus/usb.
6 | SUBSYSTEM=="usb", ACTION=="add", ENV{DEVTYPE}=="usb_device", \
7 | NAME="bus/usb/$env{BUSNUM}/$env{DEVNUM}", MODE="0644"
8 |
9 |
--------------------------------------------------------------------------------
/etc/openct.udev.in:
--------------------------------------------------------------------------------
1 | # udev rules file for openct
2 |
3 | # Update 2009-11-25
4 | # Thanks to Scott James Remnant and Martin Pitt for helping on irc
5 | # to figure out the new syntax / rules for udev.
6 |
7 | # COMPATIBILITY NOTES
8 | # new versions of udev want DRIVERS, older versions only support DRIVER
9 | # new versions of udev want SUBSYSTEMS, older versions only support BUS
10 | #
11 | # new combinations of udev and linux kernel do not create proper events
12 | # (or udev processes them "too fast" / race conditions) or similar.
13 | # as a result there is no way to get openct-control run when a usb smart
14 | # card reader is plugged in. restarting the init script will help as a
15 | # crude workaround.
16 | #
17 | SUBSYSTEM!="usb", GOTO="openct_usb_rules_end"
18 | ACTION!="add", GOTO="openct_usb_rules_end"
19 |
20 | # last file created by the kernel, if this is present everything should be
21 | # KERNEL=="[0-9]*:*", WAIT_FOR_ATTR="bInterfaceProtocol"
22 | # 2010-01-06 removed, as latest udev doesn't know WAIT_FOR_ATTR any more.
23 |
24 | # sleep for 100ms - the wait_for_sysfs might not be enough
25 | PROGRAM="/bin/sleep 0.1"
26 |
27 | # ccid
28 | ATTR{bInterfaceClass}=="0b", ATTR{bInterfaceSubClass}=="00", ATTR{bInterfaceProtocol}=="00", ATTRS{idVendor}=="?*" RUN+="@udevdir@/openct_usb /dev/$parent"
29 |
30 | # egate
31 | ATTR{idVendor}=="0973", ATTR{idProduct}=="0001", RUN+="@udevdir@/openct_usb /dev/$name"
32 | # eToken
33 | ATTR{idVendor}=="0529", ATTR{idProduct}=="050c", RUN+="@udevdir@/openct_usb /dev/$name"
34 | ATTR{idVendor}=="0529", ATTR{idProduct}=="0514", RUN+="@udevdir@/openct_usb /dev/$name"
35 | # eToken 64
36 | ATTR{idVendor}=="0529", ATTR{idProduct}=="0600", RUN+="@udevdir@/openct_usb /dev/$name"
37 | ATTR{idVendor}=="0529", ATTR{idProduct}=="0700", RUN+="@udevdir@/openct_usb /dev/$name"
38 | # eutron
39 | ATTR{idVendor}=="073d", ATTR{idProduct}=="0005", RUN+="@udevdir@/openct_usb /dev/$name"
40 | # ikey2k
41 | ATTR{idVendor}=="04b9", ATTR{idProduct}=="1200", RUN+="@udevdir@/openct_usb /dev/$name"
42 | # ikey3k
43 | ATTR{idVendor}=="04b9", ATTR{idProduct}=="1300", RUN+="@udevdir@/openct_usb /dev/$name"
44 | # starkey
45 | ATTR{idVendor}=="096e", ATTR{idProduct}=="0005", RUN+="@udevdir@/openct_usb /dev/$name"
46 | # cardman
47 | #ATTR{idVendor}=="076b", ATTR{idProduct}=="0596", RUN+="@udevdir@/openct_usb /dev/$name"
48 | #ATTR{idVendor}=="076b", ATTR{idProduct}=="1784", RUN+="@udevdir@/openct_usb /dev/$name"
49 | #ATTR{idVendor}=="08d4", ATTR{idProduct}=="0009", RUN+="@udevdir@/openct_usb /dev/$name"
50 |
51 | # spr 532 - ccid, but with wrong interface class (vendor) :(
52 | ATTR{idVendor}=="04e6", ATTR{idProduct}=="0003", RUN+="@udevdir@/openct_usb /dev/$name"
53 | ATTR{idVendor}=="04e6", ATTR{idProduct}=="E003", RUN+="@udevdir@/openct_usb /dev/$name"
54 | # pertosmart1030
55 | ATTR{idVendor}=="072f", ATTR{idProduct}=="0001", RUN+="@udevdir@/openct_usb /dev/$name"
56 | ATTR{idVendor}=="072f", ATTR{idProduct}=="8009", RUN+="@udevdir@/openct_usb /dev/$name"
57 | # pertosmart1038
58 | ATTR{idVendor}=="072f", ATTR{idProduct}=="9000", RUN+="@udevdir@/openct_usb /dev/$name"
59 | ATTR{idVendor}=="072f", ATTR{idProduct}=="9006", RUN+="@udevdir@/openct_usb /dev/$name"
60 | ATTR{idVendor}=="072f", ATTR{idProduct}=="9007", RUN+="@udevdir@/openct_usb /dev/$name"
61 | ATTR{idVendor}=="072f", ATTR{idProduct}=="90d0", RUN+="@udevdir@/openct_usb /dev/$name"
62 | # wbeiuu - driver not working yet.
63 | #ATTR{idVendor}=="104f", ATTR{idProduct}=="0004", RUN+="@udevdir@/openct_usb /dev/$name"
64 | # cyberjack
65 | ATTR{idVendor}=="0c4b", ATTR{idProduct}=="0100", RUN+="@udevdir@/openct_usb /dev/$name"
66 | # rutoken
67 | ATTR{idVendor}=="0a89", ATTR{idProduct}=="0020", RUN+="@udevdir@/openct_usb /dev/$name"
68 | ATTR{idVendor}=="0a89", ATTR{idProduct}=="0012", RUN+="@udevdir@/openct_usb /dev/$name"
69 | # ePass3000
70 | ATTR{idVendor}=="096e", ATTR{idProduct}=="0401", RUN+="@udevdir@/openct_usb /dev/$name"
71 |
72 | LABEL="openct_usb_rules_end"
73 |
74 | # udev pcmcia rules file for openct
75 | #
76 | SUBSYSTEMS!="pcmcia", GOTO="openct_pcmcia_rules_end"
77 | ACTION!="add", GOTO="openct_pcmcia_rules_end"
78 |
79 | # omnikey cardman 4040
80 | SUBSYSTEM=="cardman_4040", RUN+="@udevdir@/openct_pcmcia /dev/$name"
81 |
82 | # Gemplus PCMCIA Card
83 | DRIVERS=="serial_cs", ATTR{prod_id1}=="Gemplus", ATTR{prod_id2}=="SerialPort", ATTR{prod_id3}=="GemPC Card", RUN+="@udevdir@/openct_serial /dev/$name"
84 |
85 | LABEL="openct_pcmcia_rules_end"
86 |
--------------------------------------------------------------------------------
/etc/openct.udev.modalias.in:
--------------------------------------------------------------------------------
1 | # udev rules file for openct
2 | #
3 | # COMPATIBILITY NOTES
4 | # new versions of udev want DRIVERS, older versions only support DRIVER
5 | # new versions of udev want SUBSYSTEMS, older versions only support BUS
6 | #
7 | # new combinations of udev and linux kernel do not create proper events
8 | # (or udev processes them "too fast" / race conditions) or similar.
9 | # as a result there is no way to get openct-control run when a usb smart
10 | # card reader is plugged in. restarting the init script will help as a
11 | # crude workaround.
12 | #
13 | SUBSYSTEM!="usb", GOTO="openct_usb_rules_end"
14 | ACTION!="add", GOTO="openct_usb_rules_end"
15 |
16 | # egate
17 | ENV{MODALIAS}=="usb:v0973p0001*", RUN+="@udevdir@/openct_usb"
18 | # eToken
19 | ENV{MODALIAS}=="usb:v0529p050C*", RUN+="@udevdir@/openct_usb"
20 | ENV{MODALIAS}=="usb:v0529p0514*", RUN+="@udevdir@/openct_usb"
21 | # eToken 64
22 | ENV{MODALIAS}=="usb:v0529p0600*", RUN+="@udevdir@/openct_usb"
23 | ENV{MODALIAS}=="usb:v0529p0700*", RUN+="@udevdir@/openct_usb"
24 | # eutron
25 | ENV{MODALIAS}=="usb:v073Dp0005*", RUN+="@udevdir@/openct_usb"
26 | # ikey2k
27 | ENV{MODALIAS}=="usb:v04B9p1200*", RUN+="@udevdir@/openct_usb"
28 | # ikey3k
29 | ENV{MODALIAS}=="usb:v04B9p1300*", RUN+="@udevdir@/openct_usb"
30 | # starkey
31 | ENV{MODALIAS}=="usb:v096Ep0005*", RUN+="@udevdir@/openct_usb"
32 | # cardman
33 | #ENV{MODALIAS}=="usb:v076Bp0596*", RUN+="@udevdir@/openct_usb"
34 | #ENV{MODALIAS}=="usb:v076Bp1784*", RUN+="@udevdir@/openct_usb"
35 | #ENV{MODALIAS}=="usb:v08D4p0009*", RUN+="@udevdir@/openct_usb"
36 |
37 | # ccid
38 | ENV{MODALIAS}=="usb:*ic0Bisc00*", RUN+="@udevdir@/openct_usb"
39 |
40 | # spr 532 - ccid, but with wrong interface class (vendor) :(
41 | ENV{MODALIAS}=="usb:v04E6p0003*", RUN+="@udevdir@/openct_usb"
42 | ENV{MODALIAS}=="usb:v04E6pE003*", RUN+="@udevdir@/openct_usb"
43 | # pertosmart1030
44 | ENV{MODALIAS}=="usb:v072Fp0001*", RUN+="@udevdir@/openct_usb"
45 | ENV{MODALIAS}=="usb:v072Fp8009*", RUN+="@udevdir@/openct_usb"
46 | # pertosmart1038
47 | ENV{MODALIAS}=="usb:v072Fp9000*", RUN+="@udevdir@/openct_usb"
48 | ENV{MODALIAS}=="usb:v072Fp9006*", RUN+="@udevdir@/openct_usb"
49 | ENV{MODALIAS}=="usb:v072Fp9007*", RUN+="@udevdir@/openct_usb"
50 | ENV{MODALIAS}=="usb:v072Fp90D0*", RUN+="@udevdir@/openct_usb"
51 | # wbeiuu - driver not working yet
52 | #ENV{MODALIAS}=="usb:v104Fp0004*", RUN+="@udevdir@/openct_usb"
53 | # Rutoken S
54 | ENV{MODALIAS}=="usb:v0a89p0020*", RUN+="@udevdir@/openct_usb"
55 | # ePass3000
56 | ENV{MODALIAS}=="usb:v096ep0401*", RUN+="@udevdir@/openct_usb"
57 |
58 | LABEL="openct_usb_rules_end"
59 |
60 | # udev pcmcia rules file for openct
61 | #
62 | SUBSYSTEMS!="pcmcia", GOTO="openct_pcmcia_rules_end"
63 | ACTION!="add", GOTO="openct_pcmcia_rules_end"
64 |
65 | # omnikey cardman 4040
66 | SUBSYSTEM=="cardman_4040", RUN+="@udevdir@/openct_pcmcia"
67 |
68 | # Gemplus PCMCIA Card
69 | DRIVERS=="serial_cs", SYSFS{prod_id1}=="Gemplus", SYSFS{prod_id2}=="SerialPort", SYSFS{prod_id3}=="GemPC Card", RUN+="@udevdir@/openct_serial"
70 |
71 | LABEL="openct_pcmcia_rules_end"
72 |
--------------------------------------------------------------------------------
/etc/openct.usermap:
--------------------------------------------------------------------------------
1 | # note: this file is for the old linux hotplug mechanism without udev.
2 | # it is no longer properly maintained and not very much supported - I don't
3 | # have a machine left where I use it. All I can do is answer emails :(
4 |
5 | # module match_flags idVendor idProduct bcdDevice_lo bcdDevice_hi bDeviceClass bDeviceSubClass bDeviceProtocol bInterfaceClass bInterfaceSubClass bInterfaceProtocol driver_info
6 | # egate:
7 | openct 0x0003 0x0973 0x0001 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000
8 | #
9 | # eToken
10 | openct 0x0003 0x0529 0x050c 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000
11 | openct 0x0003 0x0529 0x0514 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000
12 | # eToken 64 / NG OTP
13 | openct 0x0003 0x0529 0x0600 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000
14 | openct 0x0003 0x0529 0x0700 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000
15 | # eutron
16 | openct 0x0003 0x073d 0x0005 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000
17 | # ikey2k
18 | openct 0x0003 0x04b9 0x1200 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000
19 | # ikey3k
20 | openct 0x0003 0x04b9 0x1300 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000
21 | # starkey
22 | openct 0x0003 0x096e 0x0005 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000
23 | # cardman
24 | #openct 0x0003 0x076b 0x0596 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000
25 | #openct 0x0003 0x076b 0x1784 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000
26 | #openct 0x0003 0x08d4 0x0009 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000
27 | # ccid
28 | openct 0x0380 0x0000 0x0000 0x0000 0x0000 0x00 0x00 0x00 0x0b 0x00 0x00 0x00000000
29 | # spr 532 - ccid, but with wrong interface class (vendor) :(
30 | openct 0x0003 0x04e6 0x0003 0x0000 0x0000 0x00 0x00 0x00 0x0b 0x00 0x00 0x00000000
31 | openct 0x0003 0x04e6 0xe003 0x0000 0x0000 0x00 0x00 0x00 0x0b 0x00 0x00 0x00000000
32 | # pertosmart1030
33 | openct 0x0003 0x072f 0x0001 0x0000 0x0000 0x00 0x00 0x00 0x0b 0x00 0x00 0x00000000
34 | openct 0x0003 0x072f 0x8009 0x0000 0x0000 0x00 0x00 0x00 0x0b 0x00 0x00 0x00000000
35 | # pertosmart1038
36 | openct 0x0003 0x072f 0x9000 0x0000 0x0000 0x00 0x00 0x00 0x0b 0x00 0x00 0x00000000
37 | openct 0x0003 0x072f 0x9006 0x0000 0x0000 0x00 0x00 0x00 0x0b 0x00 0x00 0x00000000
38 | openct 0x0003 0x072f 0x9007 0x0000 0x0000 0x00 0x00 0x00 0x0b 0x00 0x00 0x00000000
39 | openct 0x0003 0x072f 0x90d0 0x0000 0x0000 0x00 0x00 0x00 0x0b 0x00 0x00 0x00000000
40 | # wbeiuu - driver not working yet
41 | #openct 0x0003 0x104f 0x0004 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000
42 | # cyberjack
43 | openct 0x003 0x0c4b 0x0100 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000
44 | # rutoken
45 | openct 0x0003 0x0a89 0x0020 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000
46 | openct 0x0003 0x0a89 0x0012 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000
47 | # ePass3000
48 | openct 0x0003 0x096e 0x0401 0x0000 0x0000 0x00 0x00 0x00 0x00 0x00 0x00 0x00000000
49 |
--------------------------------------------------------------------------------
/etc/openct_pcmcia.in:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | test "$ACTION" = "add" || exit 0
4 | test -n "$DEVNAME" || exit 0
5 | test -e "@OPENCT_SOCKET_PATH@/status" || exit 0
6 |
7 | if [ -n "$DEVNAME" ]
8 | then
9 | @sbindir@/openct-control attach ccid pcmcia_block $DEVNAME
10 | exit 0
11 | fi
12 |
--------------------------------------------------------------------------------
/etc/openct_serial.in:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | test "$ACTION" = "add" || exit 0
4 | test -n "$DEVNAME" || exit 0
5 | test -e "@OPENCT_SOCKET_PATH@/status" || exit 0
6 |
7 | if [ -n "$DEVNAME" ]
8 | then
9 | @sbindir@/openct-control attach ccid serial $DEVNAME
10 | exit 0
11 | fi
12 |
--------------------------------------------------------------------------------
/etc/openct_usb.in:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # maybe udev passes the device name to us.
4 | if [ -n "$1" ]; then
5 | DEVNAME="$1"
6 | fi
7 |
8 | [ -n "$DEVPATH" ] || exit 0
9 | [ "$ACTION" = "add" ] || exit 0
10 | [ -e "@OPENCT_SOCKET_PATH@/status" ] || exit 0
11 |
12 | # try to get the device node from the parent device
13 | if [ -z "$DEVNAME" ]; then
14 | #
15 | # Guess udev info interface.
16 | # Newer udev uses udevadm
17 | #
18 | if which udevinfo > /dev/null 2>&1; then
19 | UDEVINFO="udevinfo"
20 | else
21 | UDEVINFO="udevadm info"
22 | fi
23 | DEVNAME=/dev/$($UDEVINFO --query=name --path=$(dirname $DEVPATH))
24 | fi
25 |
26 | # if udev supplied a device node directly from the usb-device, we use it,
27 | # because it is guaranteed to exist at the time we run
28 | if [ -n "$DEVNAME" -a -e "$DEVNAME" ]; then
29 | DEVICE="$DEVNAME"
30 | fi
31 |
32 | [ -n "$DEVICE" ] || exit 0
33 |
34 | if [ -z "$PRODUCT" -a -n "$MODALIAS" ]; then
35 | PRODUCT=$(echo $MODALIAS | sed -e 's/usb:v\(....\)p\(....\)d\(....\).*/\1\/\2\/\3/g' |tr A-F a-f)
36 | fi
37 |
38 | if [ -z "$PRODUCT" ]; then
39 | V=$(cat /sys$(dirname $DEVPATH)/idVendor | sed -e 's/^0*//')
40 | P=$(cat /sys$(dirname $DEVPATH)/idProduct | sed -e 's/^0*//')
41 | D=$(cat /sys$(dirname $DEVPATH)/bcdDevice | sed -e 's/^0*//')
42 | PRODUCT="$V/$P/$D"
43 | fi
44 |
45 | [ -n "$PRODUCT" ] || exit 0
46 |
47 | # we may neeed to wait for the device node, when usbfs is used
48 | for A in "0 1 2 3 4 5 6 7 8 9"; do
49 | if [ -e "$DEVICE" ]; then
50 | @sbindir@/openct-control attach usb:$PRODUCT usb $DEVICE
51 | exit 0
52 | fi
53 | sleep 0.1
54 | done
55 |
56 | echo "$0 waited for $DEVICE but it did not appear." | logger -p daemon.error
57 | exit 0
58 |
--------------------------------------------------------------------------------
/etc/openct_usb.mdev.in:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copy to /lib/mdev/openct_usb
5 | # Put the following in /etc/mdev.conf:
6 | # .* 0:0 0660 @/lib/mdev/openct_usb
7 | # For some strange reason "usb.*" does not catch the event.
8 | #
9 | [ -n "${DEVPATH}" ] || exit 0
10 | [ "${ACTION}" = "add" ] || exit 0
11 | [ "${DEVTYPE}" = "usb_device" ] || exit 0
12 |
13 | DEVICE="/dev/bus/usb/${BUSNUM}/${DEVNUM}"
14 |
15 | if ! [ -e "${DEVICE}" ]; then
16 | mkdir -p "$(dirname "${DEVICE}")"
17 | mknod "${DEVICE}" c ${MAJOR} ${MINOR}
18 | fi
19 |
20 | [ -e "@OPENCT_SOCKET_PATH@/status" ] || exit 0
21 |
22 | # Don't know why...
23 | sleep 1
24 |
25 | @sbindir@/openct-control attach "usb:${PRODUCT}" usb "${DEVICE}"
26 |
--------------------------------------------------------------------------------
/etc/reader.conf.in:
--------------------------------------------------------------------------------
1 | # OpenCT configuration file for pcsc-lite
2 | # http://www.opensc.org/openct/
3 |
4 | FRIENDLYNAME "OpenCT"
5 | DEVICENAME /dev/null
6 | LIBPATH @libdir@/openct-ifd.so
7 | CHANNELID 0
8 |
9 | # End of file
10 |
--------------------------------------------------------------------------------
/macos/Makefile.am:
--------------------------------------------------------------------------------
1 | MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
2 |
3 | dist_noinst_SCRIPTS = libtool-bundle
4 |
--------------------------------------------------------------------------------
/macos/libtool-bundle:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # A shell script to create MacOS X bundles
3 | # from files created by GNU libtool.
4 | # Incomplete, but works.
5 | #
6 | # $Id$
7 | #
8 | #
9 |
10 | set -e
11 | verbose=0
12 |
13 | verbose_msg ()
14 | {
15 | if [ $verbose -ne 0 ]; then
16 | echo "libtool-bundle: $@"
17 | fi
18 | }
19 |
20 | error_msg ()
21 | {
22 | echo 1>&2 "libtool-bundle: $@"
23 | }
24 |
25 | usage ()
26 | {
27 | error_msg "Usage: $0 [-e extra XML data] [Mach-O bundle file] [destination directory] "
28 | exit 1
29 | }
30 |
31 | case $1 in
32 | -e) shift; if [ "$1" ]; then extradata=$1; shift; else usage; fi; ;;
33 | esac
34 |
35 | [ $# -le 1 -o $# -ge 4 ] && usage
36 |
37 | sofile=$1
38 | [ ! -f $sofile ] && error_msg "Not a file or file not found: $sofile" && exit 1
39 | case "$sofile" in
40 | *.so*)
41 | # Assume it's ok
42 | ;;
43 | *)
44 | error_msg "Invalid bundle: $sofile"
45 | exit 1
46 | ;;
47 | esac
48 |
49 | destdir=$2
50 | [ ! -d $destdir -o ! -w $destdir ] && error_msg "Not a directory or no write access: $destdir" && exit 1
51 |
52 | name="$sofile"
53 | [ $# -eq 3 ] && name=$3
54 | name=`echo $name | sed -e "s@.*/@@" -e "s@\.so.*@@"`
55 | root="$destdir/${name}.bundle"
56 |
57 | verbose_msg "sofile: $sofile"
58 | verbose_msg "destdir: $destdir"
59 | verbose_msg "name: $name"
60 | verbose_msg "root: $root"
61 |
62 | arch=`uname`
63 | [ x$arch = xDarwin ] && arch=MacOS
64 | type="BNDL"
65 | creator="????"
66 |
67 | # Overwrite existing bundle
68 | [ -d "$root" ] && rm -rf "$root"
69 |
70 | mkdir -p "$root"/Contents/$arch
71 | cp "$sofile" "$root"/Contents/$arch/
72 | echo "$type$creator" > "$root"/Contents/PkgInfo
73 |
74 | create_info_plist ()
75 | {
76 | echo ""
77 | echo ""
78 | echo ""
79 | echo ""
80 | echo " CFBundleDevelopmentRegion"
81 | echo " English"
82 | echo " CFBundleExecutable"
83 | echo " `basename \"$sofile\"`"
84 | echo " CFBundleInfoDictionaryVersion"
85 | echo " 6.0"
86 | echo " CFBundleName"
87 | echo " $name"
88 | echo " CFBundlePackageType"
89 | echo " $type"
90 | echo " CFBundleSignature"
91 | echo " $creator"
92 | echo " CFBundleVersion"
93 | echo " 0.0.1d1"
94 | if [ "$extradata" ]; then
95 | echo ""
96 | [ -f "$extradata" ]; cat $extradata
97 | fi
98 | echo ""
99 | echo ""
100 | }
101 |
102 | create_info_plist > "$root"/Contents/Info.plist
103 |
104 | echo "Installed $sofile as $root"
105 |
--------------------------------------------------------------------------------
/solaris/Makefile.client:
--------------------------------------------------------------------------------
1 | PACKAGE=OSCopenct
2 | PACKAGE_NAME=openct
3 | CLASSES=none
4 | CATEGORY=drivers
5 | VENDOR=OSC
6 | EMAIL=william@wanders.org
7 | DATE=date
8 | PSTAMP=$(DATE:sh)
9 | VERSION=SVN
10 | PWD=pwd
11 | CONFIGURE_PREFIX=$(PWD:sh)/..
12 | CONFIGURE=${CONFIGURE_PREFIX}/configure
13 | CONFIGURE_ARGS=--prefix=/usr --sysconfdir=/etc/openct --enable-sunrayclient
14 | CONFIG_GUESS=${CONFIGURE_PREFIX}/config.guess
15 | UNAME_ARCH=/sbin/uname -p
16 | PLATFORM = $(CONFIG_GUESS:sh)
17 | ARCH = $(UNAME_ARCH:sh)
18 |
19 | build:
20 | @echo "Setup platform specific build directory ${PLATFORM}"
21 | mkdir -p build-${PLATFORM}
22 | ( cd build-${PLATFORM}; CC=cc ${CONFIGURE} ${CONFIGURE_ARGS}; make )
23 |
24 | dist:
25 | @echo "Setup platform specific dist directory dist-${PLATFORM}"
26 | mkdir -p dist-${PLATFORM}
27 | @echo "Performing Installing in dist directory"
28 | ( cd build-${PLATFORM}; make DESTDIR=`pwd`/../dist-${PLATFORM} install )
29 |
30 | package:
31 | @echo "Setup package meta files"
32 | -rm proto checkinstall pkginfo
33 | -sed "s|@ARCH@|${ARCH}|" checkinstall
34 | -( echo "PKG=\"${PACKAGE}\""; \
35 | echo "NAME=\"${PACKAGE_NAME}\""; \
36 | echo "VERSION=\"${VERSION}\""; \
37 | echo "ARCH=\"${ARCH}\""; \
38 | echo "CLASSES=\"${CLASSES}\""; \
39 | echo "CATEGORY=\"${CATEGORY}\""; \
40 | echo "VENDOR=\"${VENDOR}\""; \
41 | echo "PSTAMP=\"${PSTAMP}\""; \
42 | echo "EMAIL=\"${EMAIL}\""; \
43 | echo "ISTATES=\"S s 1 2 3\""; \
44 | echo "RSTATES=\"S s 1 2 3\""; \
45 | echo "BASEDIR=\"/\"" ) >pkginfo
46 | @echo "Setup package distribution"
47 | mkdir -p dist-${PLATFORM}/etc/openct
48 | -cp openct.conf-dist dist-${PLATFORM}/etc/openct/openct.conf
49 | -( pkgproto dist-${PLATFORM}= | sed -e "s|$(LOGNAME) other$$|root bin|" | egrep -v "(s|d) none (/|/etc|/var|/usr|/usr/local) "; \
50 | echo "i checkinstall=checkinstall"; \
51 | echo "i pkginfo=pkginfo" ) >proto
52 | @echo "Creating package"
53 | -pkgmk -o -r . -d . -f proto
54 | -pkgtrans -s . ${PACKAGE_NAME}-${VERSION}-${PLATFORM}.pkg ${PACKAGE}
55 |
56 | clean:
57 | rm -rf build-${PLATFORM}
58 | rm -rf dist-${PLATFORM}
59 | rm -rf ${PACKAGE}
60 | rm -f proto checkinstall pkginfo
61 |
62 | veryclean: clean
63 | rm -f ${PACKAGE_NAME}-${VERSION}-${PLATFORM}.pkg
64 |
--------------------------------------------------------------------------------
/solaris/Makefile.server:
--------------------------------------------------------------------------------
1 | PACKAGE=OSCutopenct
2 | PACKAGE_NAME=utopenct
3 | CLASSES=none
4 | CATEGORY=drivers
5 | VENDOR=OSC
6 | EMAIL=william@wanders.org
7 | DATE=date
8 | PSTAMP=$(DATE:sh)
9 | VERSION=SVN
10 | PWD=pwd
11 | CONFIGURE_PREFIX=$(PWD:sh)/..
12 | CONFIGURE=${CONFIGURE_PREFIX}/configure
13 | CONFIGURE_ARGS=--prefix=/opt/SUNWut --sysconfdir=/etc/opt/SUNWut/openct --enable-sunray
14 | CONFIG_GUESS=${CONFIGURE_PREFIX}/config.guess
15 | UNAME_ARCH=/sbin/uname -p
16 | PLATFORM = $(CONFIG_GUESS:sh)
17 | ARCH = $(UNAME_ARCH:sh)
18 |
19 | build:
20 | @echo "Setup platform specific build directory ${PLATFORM}"
21 | mkdir -p build-${PLATFORM}
22 | ( cd build-${PLATFORM}; CC=cc ${CONFIGURE} ${CONFIGURE_ARGS}; make )
23 |
24 | dist:
25 | @echo "Setup platform specific dist directory dist-${PLATFORM}"
26 | mkdir -p dist-${PLATFORM}
27 | @echo "Performing Installing in dist directory"
28 | ( cd build-${PLATFORM}; make DESTDIR=`pwd`/../dist-${PLATFORM} install )
29 |
30 | package:
31 | @echo "Setup package meta files"
32 | -rm proto checkinstall pkginfo
33 | -sed "s|@ARCH@|${ARCH}|" checkinstall
34 | -( echo "PKG=\"${PACKAGE}\""; \
35 | echo "NAME=\"${PACKAGE_NAME}\""; \
36 | echo "VERSION=\"${VERSION}\""; \
37 | echo "ARCH=\"${ARCH}\""; \
38 | echo "CLASSES=\"${CLASSES}\""; \
39 | echo "CATEGORY=\"${CATEGORY}\""; \
40 | echo "VENDOR=\"${VENDOR}\""; \
41 | echo "PSTAMP=\"${PSTAMP}\""; \
42 | echo "EMAIL=\"${EMAIL}\""; \
43 | echo "ISTATES=\"S s 1 2 3\""; \
44 | echo "RSTATES=\"S s 1 2 3\""; \
45 | echo "BASEDIR=\"/\"" ) >pkginfo
46 | @echo "Setup package distribution"
47 | mkdir -p dist-${PLATFORM}/etc/opt/SUNWut/openct
48 | -cp openct.conf-dist dist-${PLATFORM}/etc/opt/SUNWut/openct/openct.conf
49 | -( pkgproto dist-${PLATFORM}= | sed -e "s|$(LOGNAME) other$$|root bin|" | egrep -v "(s|d) none (/|/etc|/var|/usr|/usr/local) "; \
50 | echo "i checkinstall=checkinstall"; \
51 | echo "i pkginfo=pkginfo" ) >proto
52 | @echo "Creating package"
53 | -pkgmk -o -r . -d . -f proto
54 | -pkgtrans -s . ${PACKAGE_NAME}-${VERSION}-${PLATFORM}.pkg ${PACKAGE}
55 |
56 | clean:
57 | rm -rf build-${PLATFORM}
58 | rm -rf dist-${PLATFORM}
59 | rm -rf ${PACKAGE}
60 | rm -f proto checkinstall pkginfo
61 |
62 | veryclean: clean
63 | rm -f ${PACKAGE_NAME}-${VERSION}-${PLATFORM}.pkg
64 |
--------------------------------------------------------------------------------
/solaris/README:
--------------------------------------------------------------------------------
1 | Creating an installable package for Solaris Sunray (SRSS 3.1)
2 | =============================================================
3 |
4 | The files in this directory are an attempt to ease
5 | the building of openct packages for Solaris running
6 | as Sunray Server.
7 |
8 | The basic steps to create Solaris packages are:
9 | # make -f Makefile.server build
10 | # make -f Makefile.server dist
11 | # make -f Makefile.server package
12 | # make -f Makefile.client build
13 | # make -f Makefile.client dist
14 | # make -f Makefile.client package
15 |
16 | NOTE: If using the GNU compiler adjust the Makefile
17 |
18 | TODO:
19 |
20 | Start/stop utopenct service for active Sunrays.
21 |
--------------------------------------------------------------------------------
/solaris/checkinstall.in:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | expected_platform="@ARCH@"
4 | platform=`uname -p`
5 | if [ ${platform} != ${expected_platform} ]; then
6 | echo "This package must be installed on ${expected_platform}"
7 | exit 1
8 | fi
9 | exit 0
10 |
--------------------------------------------------------------------------------
/solaris/devices-openct-fabric.xml-dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
16 |
17 |
18 |
19 |
20 |
21 |
26 |
27 |
28 |
36 |
37 |
42 |
43 |
48 |
49 |
50 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | Solaris OpenCT fabric device configuration.
60 |
61 |
62 |
63 |
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/solaris/openct-fabric-dist:
--------------------------------------------------------------------------------
1 | #!/sbin/sh
2 | #
3 | # Copyright 2005 William Wanders. All rights reserved.
4 | # Use is subject to license terms.
5 | #
6 | # ident "@(#)openct-fabric 1.1 04/08/31 SMI"
7 | #
8 | # This script is used initialize and shutdown the OpenCT fabric
9 | #
10 |
11 | case "$1" in
12 | 'start')
13 | # Create directory for OpenCT fabric
14 | if [ ! -d /var/run/openct ]
15 | then
16 | mkdir -p /var/run/openct
17 | fi
18 |
19 | # Startup the OpenCT fabric
20 | if [ ! -f /var/run/openct/status ]
21 | then
22 | /usr/sbin/openct-control init
23 | fi
24 |
25 | # Add sysevent handler for hotplug support
26 | if syseventadm list \
27 | -v SUNW -p ddi -c EC_devfs -s ESC_devfs_devi_add \
28 | /usr/sbin/openct-hotplug '${di.path}' >/dev/null
29 | then
30 | echo "system eventhandler already added"
31 | else
32 | syseventadm add \
33 | -v SUNW -p ddi -c EC_devfs -s ESC_devfs_devi_add \
34 | /usr/sbin/openct-hotplug '${di.path}'
35 | fi
36 | ;;
37 | 'stop')
38 | # Remove sysevent handler for hotplug support
39 | if syseventadm list \
40 | -v SUNW -p ddi -c EC_devfs -s ESC_devfs_devi_add \
41 | /usr/sbin/openct-hotplug '${di.path}' >/dev/null
42 | then
43 | syseventadm remove \
44 | -v SUNW -p ddi -c EC_devfs -s ESC_devfs_devi_add \
45 | /usr/sbin/openct-hotplug '${di.path}'
46 | fi
47 |
48 | # Shutdown the OpenCT fabric
49 | if [ -f /var/run/openct/status ]
50 | then
51 | /usr/sbin/openct-control shutdown
52 | fi
53 |
54 | # Cleanup the OpenCT fabric directory
55 | if [ -d /var/run/openct ]
56 | then
57 | rm -rf /var/run/openct
58 | fi
59 | ;;
60 | 'status')
61 | /usr/sbin/openct-control status
62 | ;;
63 | *)
64 | echo "Usage: $0 { start | stop | status}"
65 | exit 1
66 | ;;
67 | esac
68 |
69 | exit $?
70 |
--------------------------------------------------------------------------------
/solaris/openct-hotplug-dist:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # USB Hotplug script for OpenCT on Solaris
4 | #
5 | # This script should be run by sysevent daemon (sysevent[conf]d).
6 | #
7 | # This can be configured by issuing the followin comand as "root".
8 | #
9 | # syseventadm add -v SUNW -p ddi -c EC_devfs -s ESC_devfs_devi_add \
10 | # /usr/sbin/openct-hotplug '${di.path}'
11 | #
12 | # The script will search for the applicable /dev link file for
13 | # the given device. If such link is found it means that the
14 | # device is bound in the system through the ugen device driver
15 | # and should be accessable by OpenCT. An openct-control command
16 | # is then issued to attach the device.
17 | #
18 | OPENCT_CONTROL=/usr/sbin/openct-control
19 | DEVICE=$1
20 |
21 | for CNTRL0 in `ls /devices$DEVICE:[0-9a-f]*.[0-9a-f]*.cntrl0 2>/dev/null`
22 | do
23 | #echo "CNTRL0=$CNTRL0"
24 | VENDOR_PRODUCT=`echo $CNTRL0 | sed "s|/devices$DEVICE:\([0-9a-f]*\.[0-9a-f]*\).cntrl0|\1|"`
25 | #echo "VENDOR_PRODUCT=$VENDOR_PRODUCT"
26 | for CNTRL0_INSTANCE in `ls /dev/usb/$VENDOR_PRODUCT/*/cntrl0 2>/dev/null`
27 | do
28 | #echo "CNTRL0_INSTANCE=$CNTRL0_INSTANCE"
29 | if `ls -l "$CNTRL0_INSTANCE" | grep "$DEVICE" >/dev/null`
30 | then
31 | #echo "$CNTRL0_INSTANCE points to /pci@1f,0/pci@5/usb@0,1/device@2"
32 | VENDOR=`echo $VENDOR_PRODUCT | sed "s|\([0-9a-f]*\)\.\([0-9a-f]*\)|\1|"`
33 | PRODUCT=`echo $VENDOR_PRODUCT | sed "s|\([0-9a-f]*\)\.\([0-9a-f]*\)|\2|"`
34 | #echo "VENDOR=$VENDOR"
35 | #echo "PRODUCT=$PRODUCT"
36 | ID_INSTANCE=`printf "usb:%04x/%04x" 0x$VENDOR 0x$PRODUCT`
37 | logger -i -p local0.notice -t openct-hotplug "$OPENCT_CONTROL attach $CNTRL0_INSTANCE $ID_INSTANCE"
38 | $OPENCT_CONTROL attach $CNTRL0_INSTANCE $ID_INSTANCE
39 | fi
40 | done
41 | done
42 | exit 0
43 |
--------------------------------------------------------------------------------
/solaris/openct.conf-dist:
--------------------------------------------------------------------------------
1 | # Set debug level
2 | debug = 0;
3 | #
4 | # Enable hot plugging
5 | hotplug = yes;
6 | #
7 | # Path to ifdhandler
8 | ifdhandler = /opt/SUNWut/sbin/ifdhandler;
9 |
10 | #
11 | # Configuration for ifdproxy (if you use it)
12 | ifdproxy {
13 | # server-port = /var/run/openct/.ifdproxy,
14 | # device-port = :6666;
15 | };
16 |
17 | # Configure static, non-hotplug aware readers here
18 | #
19 | # For a list of drivers try command 'ifdhandler -i', please
20 | # notice that not all drivers have serial device capability.
21 |
22 | #reader towitoko {
23 | # driver = towitoko;
24 | # device = serial:/dev/ttyS0;
25 | #};
26 |
27 | #
28 | # Hotplug IDs
29 | driver egate {
30 | ids = {
31 | usb:0973/0001,
32 | };
33 | };
34 | driver etoken {
35 | ids = {
36 | usb:0529/050c,
37 | usb:0529/0514,
38 | };
39 | };
40 | driver eutron {
41 | ids = {
42 | usb:073d/0005,
43 | };
44 | };
45 | driver ikey2k {
46 | ids = {
47 | usb:04b9/1202,
48 | };
49 | };
50 | driver ikey3k {
51 | ids = {
52 | usb:04b9/1300,
53 | };
54 | };
55 | driver cardman {
56 | ids = {
57 | usb:076b/0596, # OMNIKEY CardMan 2020
58 | usb:076b/1784, # OMNIKEY CardMan 6020
59 | usb:08d4/0009, # Fujitsu Siemens SCR USB Reader
60 | };
61 | };
62 | driver ccid {
63 | ids = {
64 | usb:08e6/3437,
65 | usb:08e6/3438,
66 | usb:08e6/4433,
67 | usb:04e6/5115,
68 | usb:04e6/E001,
69 | usb:04e6/E003,
70 | usb:076b/3021,
71 | usb:0783/0003,
72 | };
73 | };
74 |
75 |
--------------------------------------------------------------------------------
/solaris/pkginfo.in:
--------------------------------------------------------------------------------
1 | PKG="OSCopenct"
2 | NAME="openct"
3 | VERSION="@VERSION@"
4 | ARCH="@ARCH@"
5 | CLASSES="none"
6 | CATEGORY="drivers"
7 | VENDOR="OSC"
8 | PSTAMP="26thFeb2005"
9 | EMAIL="william@wanders.org"
10 | ISTATES="S s 1 2 3"
11 | RSTATES="S s 1 2 3"
12 | BASEDIR="/"
13 |
--------------------------------------------------------------------------------
/solaris/postinstall:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | svccfg import /var/svc/manifest/system/device/devices-openct-fabric.xml
4 | exit 0
5 |
--------------------------------------------------------------------------------
/solaris/preremove:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | svcadm disable openct-fabric
4 | svccfg delete openct-fabric
5 | exit 0
6 |
--------------------------------------------------------------------------------
/solaris/proto:
--------------------------------------------------------------------------------
1 | d none usr 0755 root sys
2 | d none usr/include 0755 root bin
3 | d none usr/include/openct 0755 root bin
4 | f none usr/include/openct/apdu.h 0644 root bin
5 | f none usr/include/openct/buffer.h 0644 root bin
6 | f none usr/include/openct/conf.h 0644 root bin
7 | f none usr/include/openct/device.h 0644 root bin
8 | f none usr/include/openct/driver.h 0644 root bin
9 | f none usr/include/openct/error.h 0644 root bin
10 | f none usr/include/openct/ifd.h 0644 root bin
11 | f none usr/include/openct/logging.h 0644 root bin
12 | f none usr/include/openct/openct.h 0644 root bin
13 | f none usr/include/openct/protocol.h 0644 root bin
14 | f none usr/include/openct/server.h 0644 root bin
15 | f none usr/include/openct/socket.h 0644 root bin
16 | f none usr/include/openct/tlv.h 0644 root bin
17 | f none usr/include/openct/types.h 0644 root bin
18 | f none usr/include/openct/ctapi.h 0644 root bin
19 | d none usr/lib 0755 root bin
20 | s none usr/lib/libopenct.so.0=libopenct.so.0.0.2
21 | f none usr/lib/libopenct.so.0.0.2 0755 root bin
22 | s none usr/lib/libopenct.so=libopenct.so.0.0.2
23 | d none usr/lib/pkgconfig 0755 root other
24 | f none usr/lib/pkgconfig/libopenct.pc 0644 root other
25 | f none usr/lib/libopenct.la 0755 root bin
26 | f none usr/lib/libopenct.a 0644 root bin
27 | s none usr/lib/libifd.so.0=libifd.so.0.0.2
28 | f none usr/lib/libifd.so.0.0.2 0755 root bin
29 | s none usr/lib/libifd.so=libifd.so.0.0.2
30 | f none usr/lib/libifd.la 0755 root bin
31 | f none usr/lib/libifd.a 0644 root bin
32 | f none usr/lib/libopenctapi.so 0755 root bin
33 | f none usr/lib/libopenctapi.la 0755 root bin
34 | f none usr/lib/libopenctapi.a 0644 root bin
35 | f none usr/lib/openct-ifd.so 0755 root bin
36 | f none usr/lib/openct-ifd.la 0755 root bin
37 | f none usr/lib/openct-ifd.a 0644 root bin
38 | d none usr/lib/openct-ifd.bundle 0755 root bin
39 | d none usr/lib/openct-ifd.bundle/Contents 0755 root bin
40 | d none usr/lib/openct-ifd.bundle/Contents/SunOS 0755 root bin
41 | f none usr/lib/openct-ifd.bundle/Contents/SunOS/openct-ifd 0755 root bin
42 | f none usr/lib/openct-ifd.bundle/Contents/PkgInfo 0644 root bin
43 | f none usr/lib/openct-ifd.bundle/Contents/Info.plist 0644 root bin
44 | d none usr/sbin 0755 root bin
45 | f none usr/sbin/ifdhandler 0755 root bin
46 | f none usr/sbin/ifdproxy 0755 root bin
47 | f none usr/sbin/openct-control 0755 root bin
48 | f none usr/sbin/openct-hotplug 0755 root bin
49 | d none usr/bin 0755 root bin
50 | f none usr/bin/openct-tool 0755 root bin
51 | d none etc 0755 root sys
52 | d none etc/openct 0755 root sys
53 | f none etc/openct/openct.conf 0644 root sys
54 | d none lib 0755 root bin
55 | d none lib/svc 0755 root bin
56 | d none lib/svc/method 0755 root bin
57 | f none lib/svc/method/openct-fabric 0755 root bin
58 | d none var 0755 root sys
59 | d none var/svc 0755 root sys
60 | d none var/svc/manifest 0755 root sys
61 | d none var/svc/manifest/system 0755 root sys
62 | d none var/svc/manifest/system/device 0755 root sys
63 | f none var/svc/manifest/system/device/devices-openct-fabric.xml 0644 root sys
64 | i checkinstall=checkinstall
65 | i postinstall=postinstall
66 | i preremove=preremove
67 | i pkginfo=pkginfo
68 |
--------------------------------------------------------------------------------
/src/Makefile.am:
--------------------------------------------------------------------------------
1 | MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
2 |
3 | # Order IS important
4 | SUBDIRS = include ct ifd tools ctapi pcsc
5 |
--------------------------------------------------------------------------------
/src/ct/Makefile.am:
--------------------------------------------------------------------------------
1 | MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
2 |
3 | lib_LTLIBRARIES = libopenct.la
4 | pkgconfig_DATA = libopenct.pc
5 |
6 | libopenct_la_SOURCES = \
7 | buffer.c client.c error.c mainloop.c path.c \
8 | socket.c status.c tlv.c
9 | libopenct_la_CFLAGS = $(AM_CFLAGS) \
10 | -I$(top_srcdir)/src/include \
11 | -I$(top_builddir)/src/include
12 | libopenct_la_LDFLAGS = \
13 | -version-info @OPENCT_LT_CURRENT@:@OPENCT_LT_REVISION@:@OPENCT_LT_AGE@ \
14 | -no-undefined
15 |
--------------------------------------------------------------------------------
/src/ct/buffer.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Buffer handling functions
3 | *
4 | * Copyright (C) 2003, Olaf Kirch
5 | */
6 |
7 | #ifdef HAVE_CONFIG_H
8 | #include
9 | #endif
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | void ct_buf_init(ct_buf_t * bp, void *mem, size_t len)
16 | {
17 | memset(bp, 0, sizeof(*bp));
18 | bp->base = (unsigned char *)mem;
19 | bp->size = len;
20 | }
21 |
22 | void ct_buf_set(ct_buf_t * bp, void *mem, size_t len)
23 | {
24 | ct_buf_init(bp, mem, len);
25 | bp->tail = len;
26 | }
27 |
28 | void ct_buf_clear(ct_buf_t * bp)
29 | {
30 | bp->head = bp->tail = 0;
31 | }
32 |
33 | int ct_buf_get(ct_buf_t * bp, void *mem, size_t len)
34 | {
35 | if (len > bp->tail - bp->head)
36 | return -1;
37 | if (mem)
38 | memcpy(mem, bp->base + bp->head, len);
39 | bp->head += len;
40 | return len;
41 | }
42 |
43 | int ct_buf_gets(ct_buf_t * bp, char *buffer, size_t size)
44 | {
45 | unsigned int n, avail;
46 | unsigned char *s;
47 |
48 | size -= 1; /* room for NUL byte */
49 |
50 | /* Limit string to what we have */
51 | avail = bp->tail - bp->head;
52 | if (size > avail)
53 | size = avail;
54 |
55 | /* Look for newline */
56 | s = bp->base + bp->head;
57 | for (n = 0; n < size && s[n] != '\n'; n++) ;
58 |
59 | /* Copy string (excluding newline) */
60 | memcpy(buffer, s, n);
61 | buffer[n] = '\0';
62 |
63 | /* And eat any characters that weren't copied
64 | * (including the newline)
65 | */
66 | while (n < avail && s[n++] != '\n') ;
67 |
68 | bp->head += n;
69 | return 0;
70 | }
71 |
72 | int ct_buf_put(ct_buf_t * bp, const void *mem, size_t len)
73 | {
74 | if (len > bp->size - bp->tail)
75 | ct_buf_compact(bp);
76 | if (len > bp->size - bp->tail) {
77 | bp->overrun = 1;
78 | return -1;
79 | }
80 | if (mem)
81 | memcpy(bp->base + bp->tail, mem, len);
82 | bp->tail += len;
83 | return len;
84 | }
85 |
86 | int ct_buf_push(ct_buf_t * bp, const void *mem, size_t len)
87 | {
88 | if (bp->head < len)
89 | return -1;
90 | bp->head -= len;
91 | if (mem)
92 | memcpy(bp->base + bp->head, mem, len);
93 | return len;
94 | }
95 |
96 | int ct_buf_putc(ct_buf_t * bp, int byte)
97 | {
98 | unsigned char c = byte;
99 |
100 | return ct_buf_put(bp, &c, 1);
101 | }
102 |
103 | int ct_buf_puts(ct_buf_t * bp, const char *string)
104 | {
105 | return ct_buf_put(bp, string, strlen(string));
106 | }
107 |
108 | unsigned int ct_buf_avail(ct_buf_t * bp)
109 | {
110 | return bp->tail - bp->head;
111 | }
112 |
113 | unsigned int ct_buf_tailroom(ct_buf_t * bp)
114 | {
115 | return bp->size - bp->tail;
116 | }
117 |
118 | unsigned int ct_buf_size(ct_buf_t * bp)
119 | {
120 | return bp->size;
121 | }
122 |
123 | void *ct_buf_head(ct_buf_t * bp)
124 | {
125 | return bp->base + bp->head;
126 | }
127 |
128 | void *ct_buf_tail(ct_buf_t * bp)
129 | {
130 | return bp->base + bp->tail;
131 | }
132 |
133 | int ct_buf_read(ct_buf_t * bp, int fd)
134 | {
135 | unsigned int count;
136 | int n;
137 |
138 | ct_buf_compact(bp);
139 |
140 | count = bp->size - bp->tail;
141 | if ((n = read(fd, bp->base + bp->tail, count)) < 0)
142 | return -1;
143 | bp->tail += n;
144 | return 0;
145 | }
146 |
147 | void ct_buf_compact(ct_buf_t * bp)
148 | {
149 | unsigned int count;
150 |
151 | if (bp->head == 0)
152 | return;
153 |
154 | count = bp->tail - bp->head;
155 | memmove(bp->base, bp->base + bp->head, count);
156 | bp->tail -= bp->head;
157 | bp->head = 0;
158 | }
159 |
160 | int ct_buf_overrun(ct_buf_t * bp)
161 | {
162 | return bp->overrun;
163 | }
164 |
--------------------------------------------------------------------------------
/src/ct/error.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Error handling
3 | *
4 | * Copyright (C) 2003, Olaf Kirch
5 | */
6 |
7 | #ifdef HAVE_CONFIG_H
8 | #include
9 | #endif
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | enum {
18 | DST_STDERR,
19 | DST_SYSLOG
20 | };
21 |
22 | static int log_open = 0;
23 | static int log_dest = DST_STDERR;
24 |
25 | static void ct_log_init(void)
26 | {
27 | if (!log_open) {
28 | openlog("ifdhandler", LOG_PID, LOG_DAEMON);
29 | log_open = 1;
30 | }
31 | }
32 |
33 | void ct_log_destination(const char *dest)
34 | {
35 | ct_log_init();
36 | if (!strcmp(dest, "@stderr")) {
37 | log_dest = DST_STDERR;
38 | } else if (!strcmp(dest, "@syslog")) {
39 | log_dest = DST_SYSLOG;
40 | } else {
41 | log_dest = DST_STDERR;
42 | ct_error("log destination %s not implemented yet", dest);
43 | }
44 | }
45 |
46 | void ct_error(const char *fmt, ...)
47 | {
48 | va_list ap;
49 | int n;
50 |
51 | va_start(ap, fmt);
52 | if (log_dest == DST_STDERR) {
53 | fprintf(stderr, "Error: ");
54 | vfprintf(stderr, fmt, ap);
55 | if (!(n = strlen(fmt)) || fmt[n - 1] != '\n')
56 | fprintf(stderr, "\n");
57 | } else {
58 | vsyslog(LOG_WARNING, fmt, ap);
59 | }
60 | va_end(ap);
61 | }
62 |
63 | void ct_debug(const char *fmt, ...)
64 | {
65 | va_list ap;
66 |
67 | va_start(ap, fmt);
68 | if (log_dest == DST_STDERR) {
69 | fprintf(stderr, "Debug: ");
70 | vfprintf(stderr, fmt, ap);
71 | fprintf(stderr, "\n");
72 | } else {
73 | vsyslog(LOG_DEBUG, fmt, ap);
74 | }
75 | va_end(ap);
76 | }
77 |
78 | const char *ct_hexdump(const void *data, size_t len)
79 | {
80 | static char string[1024];
81 | unsigned char *d = (unsigned char *)data;
82 | unsigned int i, left;
83 |
84 | string[0] = '\0';
85 | left = sizeof(string);
86 | for (i = 0; len--; i += 3) {
87 | if (i >= sizeof(string) - 4)
88 | break;
89 | snprintf(string + i, 4, " %02x", *d++);
90 | }
91 | return string;
92 | }
93 |
94 | #define DIM(v) (sizeof(v)/(sizeof((v)[0])))
95 |
96 | const char *ct_strerror(int rc)
97 | {
98 | const char *proto_errors[] = {
99 | "Invalid message",
100 | "Invalid command",
101 | "Missing argument",
102 | "Not connected to IFD handler",
103 | };
104 | const int proto_base = -IFD_ERROR_INVALID_MSG;
105 | const char *gen_errors[] = {
106 | "Success",
107 | "Generic error",
108 | "Command timed out",
109 | "Invalid slot",
110 | "Operation not supported",
111 | "Communication error",
112 | "No card present",
113 | "Reader already locked",
114 | "Reader not locked",
115 | "Invalid argument",
116 | "Out of memory",
117 | "Buffer too small",
118 | "Timeout on user input",
119 | "Operation aborted by user",
120 | "PIN mismatch",
121 | "Unable to reset card",
122 | "Device cannot perform requested operation",
123 | "Device was disconnected",
124 | "Card returned invalid ATR",
125 | };
126 | const int gen_base = -IFD_SUCCESS;
127 | const char *proxy_errors[] = {
128 | "Device already claimed",
129 | "Device busy",
130 | "Device not known",
131 | };
132 | const int proxy_base = -IFD_ERROR_ALREADY_CLAIMED;
133 | const char **errors = NULL, *msg = NULL;
134 | int count = 0, err_base = 0, error = rc;
135 | static char message[64];
136 |
137 | if (error < 0)
138 | error = -error;
139 | if (error >= proto_base) {
140 | errors = proto_errors;
141 | count = DIM(proto_errors);
142 | err_base = proto_base;
143 | } else if (error >= gen_base) {
144 | errors = gen_errors;
145 | count = DIM(gen_errors);
146 | err_base = gen_base;
147 | } else if (error >= proxy_base) {
148 | errors = proxy_errors;
149 | count = DIM(proxy_errors);
150 | err_base = proxy_base;
151 | }
152 | error -= err_base;
153 | if (error >= count || count == 0) {
154 | msg = message;
155 | snprintf(message, sizeof(message),
156 | "Unknown OpenCT error %d", -rc);
157 | } else {
158 | msg = errors[error];
159 | }
160 | return msg;
161 | }
162 |
--------------------------------------------------------------------------------
/src/ct/libopenct.pc.in:
--------------------------------------------------------------------------------
1 | prefix=@prefix@
2 | exec_prefix=@exec_prefix@
3 | libdir=@libdir@
4 | includedir=@includedir@
5 |
6 | Name: libopenct
7 | Description: libopenct
8 | Version: @VERSION@
9 | Libs: -L${libdir} -lopenct
10 | Cflags: -I${includedir}
11 |
12 |
--------------------------------------------------------------------------------
/src/ct/mainloop.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Resource manager daemon - main loop
3 | *
4 | * Copyright (C) 2003 Olaf Kirch
5 | */
6 |
7 | #ifdef HAVE_CONFIG_H
8 | #include
9 | #endif
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 |
19 | #include
20 | #include
21 | #include
22 |
23 | #define IFD_MAX_SOCKETS 256
24 |
25 | static ct_socket_t sock_head;
26 | static int leave_mainloop;
27 |
28 | void ct_mainloop_add_socket(ct_socket_t * sock)
29 | {
30 | if (sock)
31 | ct_socket_link(&sock_head, sock);
32 | }
33 |
34 | /*
35 | * Main loop
36 | */
37 | void ct_mainloop(void)
38 | {
39 | leave_mainloop = 0;
40 | while (!leave_mainloop) {
41 | struct pollfd pfd[IFD_MAX_SOCKETS + 1];
42 | ct_socket_t *poll_socket[IFD_MAX_SOCKETS];
43 | ct_socket_t *sock, *next;
44 | unsigned int nsockets = 0, npoll = 0;
45 | unsigned int n = 0, listening;
46 | int have_driver_with_poll = 0;
47 | int rc;
48 |
49 | /* Zap poll structure */
50 | memset(pfd, 0, sizeof(pfd));
51 |
52 | /* Count active sockets, and decide whether to
53 | * accept additional connections or not. */
54 | for (sock = sock_head.next; sock; sock = next) {
55 | next = sock->next;
56 | /* Kill any dead or excess sockets */
57 | if (sock->fd < 0 || nsockets == IFD_MAX_SOCKETS) {
58 | ct_socket_free(sock);
59 | } else {
60 | nsockets++;
61 | }
62 | }
63 | listening = (nsockets < IFD_MAX_SOCKETS) ? POLLIN : 0;
64 |
65 | /* Now loop over all sockets and set up the poll structs */
66 | for (sock = sock_head.next; sock; sock = sock->next) {
67 | poll_socket[npoll] = sock;
68 | if (sock->poll) {
69 | have_driver_with_poll = 1;
70 | if (sock->poll(sock, &pfd[npoll]) == 1)
71 | npoll++;
72 | } else {
73 | if (sock->listener)
74 | sock->events = listening;
75 |
76 | pfd[npoll].fd = sock->fd;
77 | pfd[npoll].events = sock->events;
78 | npoll++;
79 | }
80 | }
81 |
82 | if (npoll == 0)
83 | break;
84 |
85 | rc = poll(pfd, npoll, have_driver_with_poll ? 1000 : -1);
86 | if (rc < 0) {
87 | if (errno == EINTR)
88 | continue;
89 | ct_error("poll: %m");
90 | break;
91 | }
92 |
93 | for (n = 0; n < npoll; n++) {
94 | sock = poll_socket[n];
95 | if (sock->poll) {
96 | if (sock->poll(sock, &pfd[n]) < 0) {
97 | ct_socket_free(sock);
98 | continue;
99 | }
100 | continue;
101 | }
102 |
103 | if (pfd[n].revents & POLLERR) {
104 | if (sock->error(sock) < 0) {
105 | ct_socket_free(sock);
106 | continue;
107 | }
108 | }
109 | if (pfd[n].revents & POLLOUT) {
110 | if (sock->send(sock) < 0) {
111 | ct_socket_free(sock);
112 | continue;
113 | }
114 | }
115 | if (pfd[n].revents & POLLIN) {
116 | if ((rc = sock->recv(sock)) < 0) {
117 | ct_socket_free(sock);
118 | continue;
119 | }
120 | }
121 | }
122 | }
123 | }
124 |
125 | void ct_mainloop_leave(void)
126 | {
127 | leave_mainloop = 1;
128 | }
129 |
--------------------------------------------------------------------------------
/src/ct/path.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Path handling routines
3 | *
4 | * Copyright (C) 2006, Andreas Jellinghaus
5 | */
6 |
7 | #ifdef HAVE_CONFIG_H
8 | #include
9 | #endif
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | /*
16 | * Format path
17 | */
18 | int ct_format_path(char *path, const size_t pathlen, const char *file)
19 | {
20 | int rc;
21 |
22 | if (!file)
23 | return 0;
24 |
25 | #if defined (sunray) || defined (sunrayclient)
26 | {
27 | if (getenv("UTDEVROOT"))
28 | rc = snprintf(path, pathlen,
29 | "%s/openct/%s", getenv("UTDEVROOT"),
30 | file);
31 | else if (getenv("OPENCT_SOCKETDIR"))
32 | rc = snprintf(path, pathlen,
33 | "%s/%s", getenv("OPENCT_SOCKETDIR"),
34 | file);
35 | else
36 | rc = snprintf(path, pathlen,
37 | "%s/%s", OPENCT_SOCKET_PATH, file);
38 | }
39 | #else
40 | if (getenv("OPENCT_SOCKETDIR")) {
41 | rc = snprintf(path, pathlen,
42 | "%s/%s", getenv("OPENCT_SOCKETDIR"), file);
43 | } else {
44 | rc = snprintf(path, pathlen, "%s/%s", OPENCT_SOCKET_PATH, file);
45 | }
46 | #endif
47 | if (rc < 0) {
48 | /* hmm. error handling? */
49 | return 0;
50 |
51 | }
52 | if (rc >= pathlen) {
53 | /* truncated */
54 | return 0;
55 | }
56 |
57 | return 1;
58 | }
59 |
--------------------------------------------------------------------------------
/src/ct/status.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Shared status file for OpenCT readers
3 | *
4 | * Copyright (C) 2003 Olaf Kirch
5 | */
6 |
7 | #ifdef HAVE_CONFIG_H
8 | #include
9 | #endif
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 |
24 | #include
25 | #include
26 | #include
27 |
28 | static int ct_status_lock(void);
29 | static void ct_status_unlock(void);
30 |
31 | static void *ct_map_status(int flags, size_t * size)
32 | {
33 | struct stat stb;
34 | int fd, prot;
35 | void *addr = NULL;
36 | char status_path[PATH_MAX];
37 |
38 | if (!ct_format_path(status_path, PATH_MAX, "status")) {
39 | return NULL;
40 | }
41 |
42 | if ((fd = open(status_path, flags)) < 0) {
43 | ct_error("can't open %s: %s", status_path, strerror(errno));
44 | return NULL;
45 | }
46 |
47 | if (fstat(fd, &stb) < 0) {
48 | ct_error("unable to stat %s: %m", status_path);
49 | goto done;
50 | }
51 | *size = stb.st_size;
52 |
53 | prot = PROT_READ;
54 | if ((flags & O_ACCMODE) == O_RDWR)
55 | prot |= PROT_WRITE;
56 |
57 | addr = mmap(NULL, *size, prot, MAP_SHARED, fd, 0);
58 | if (addr == MAP_FAILED) {
59 | addr = NULL;
60 | }
61 |
62 | done:close(fd);
63 | return addr;
64 | }
65 |
66 | int ct_status_destroy(void)
67 | {
68 | char status_path[PATH_MAX];
69 |
70 | if (!ct_format_path(status_path, PATH_MAX, "status")) {
71 | return -1;
72 | }
73 |
74 | return unlink(status_path);
75 | }
76 |
77 | int ct_status_clear(unsigned int count, const char *owner)
78 | {
79 | int fd = -1;
80 | char status_path[PATH_MAX];
81 |
82 | if (!ct_format_path(status_path, PATH_MAX, "status")) {
83 | return -1;
84 | }
85 |
86 | unlink(status_path);
87 | if ((fd = open(status_path, O_RDWR | O_CREAT, 0644)) < 0
88 | || ftruncate(fd, count * sizeof(ct_info_t)) < 0
89 | || fchmod(fd, 0644) < 0) {
90 | ct_error("cannot create %s: %m", status_path);
91 | goto error;
92 | }
93 |
94 | if (owner != NULL) {
95 | struct passwd *p = getpwnam(owner);
96 |
97 | if (p == NULL) {
98 | ct_error("cannot parse user %s", owner);
99 | goto error;
100 | }
101 |
102 | if (fchown(fd, p->pw_uid, -1) == -1) {
103 | ct_error("cannot chown %s to %s: %m", status_path, owner);
104 | goto error;
105 | }
106 | }
107 |
108 | return 0;
109 |
110 | error:
111 |
112 | unlink(status_path);
113 | if (fd >= 0)
114 | close(fd);
115 | return -1;
116 | }
117 |
118 | int ct_status(const ct_info_t ** result)
119 | {
120 | static const ct_info_t *reader_status;
121 | static unsigned int num_status;
122 |
123 | if (reader_status == NULL) {
124 | size_t size;
125 |
126 | reader_status = (ct_info_t *) ct_map_status(O_RDONLY, &size);
127 | if (reader_status == NULL)
128 | return -1;
129 | num_status = size / sizeof(ct_info_t);
130 | }
131 |
132 | *result = reader_status;
133 | return num_status;
134 | }
135 |
136 | ct_info_t *ct_status_alloc_slot(int *num)
137 | {
138 | ct_info_t *info;
139 | size_t size;
140 | unsigned int n, max;
141 |
142 | info = (ct_info_t *) ct_map_status(O_RDWR, &size);
143 | if (info == NULL)
144 | return NULL;
145 |
146 | max = size / sizeof(ct_info_t);
147 | if (*num == -1) {
148 | sigset_t sigset;
149 |
150 | /* Block all signals while holding the lock */
151 | sigfillset(&sigset);
152 | sigprocmask(SIG_SETMASK, &sigset, &sigset);
153 |
154 | /* Lock the status file against concurrent access */
155 | ct_status_lock();
156 |
157 | /* find a free slot */
158 | for (n = 0; n < max; n++, info) {
159 | if (info[n].ct_pid == 0
160 | || (kill(info[n].ct_pid, 0) < 0
161 | && errno == ESRCH)) {
162 | *num = n;
163 | break;
164 | }
165 | }
166 |
167 | /* Done, unlock the file again */
168 | ct_status_unlock();
169 |
170 | /* unblock signals */
171 | sigprocmask(SIG_SETMASK, &sigset, NULL);
172 | } else if (*num >= max) {
173 | munmap((void *)info, size);
174 | return NULL;
175 | }
176 |
177 | memset(&info[*num], 0, sizeof(ct_info_t));
178 | info[*num].ct_pid = getpid();
179 |
180 | msync((void *)info, size, MS_SYNC);
181 | return info + *num;
182 | }
183 |
184 | #define ALIGN(x, size) (((caddr_t) (x)) - ((unsigned long) (x) % (size)))
185 | int ct_status_update(ct_info_t * status)
186 | {
187 | size_t size;
188 | caddr_t page;
189 |
190 | /* get the page this piece of data is sitting on */
191 | size = getpagesize();
192 | page = ALIGN(status, size);
193 |
194 | /* flush two pages if data spans two pages */
195 | if (page != ALIGN(status + 1, size))
196 | size <<= 1;
197 |
198 | if (msync(page, size, MS_SYNC) < 0) {
199 | ct_error("msync: %m");
200 | return -1;
201 | }
202 |
203 | return 0;
204 | }
205 |
206 | /*
207 | * Lock file handling
208 | */
209 | static int ct_status_lock(void)
210 | {
211 | int fd, retries = 10;
212 | int ret = -1;
213 | char status_lock_path[PATH_MAX];
214 | char status_temp_path[PATH_MAX];
215 |
216 | if (!ct_format_path(status_lock_path, PATH_MAX, "status.lock")) {
217 | return -1;
218 | }
219 |
220 | snprintf(status_temp_path, PATH_MAX,
221 | "%s.%u", status_lock_path, (unsigned int)getpid());
222 |
223 | if ((fd = open(status_temp_path, O_CREAT | O_RDWR, 0600)) < 0)
224 | return -1;
225 |
226 | while (retries--) {
227 | if (link(status_temp_path, status_lock_path) >= 0) {
228 | ret = 0;
229 | break;
230 | }
231 | }
232 |
233 | close(fd);
234 | unlink(status_temp_path);
235 | return ret;
236 | }
237 |
238 | static void ct_status_unlock(void)
239 | {
240 | char status_lock_path[PATH_MAX];
241 |
242 | if (!ct_format_path(status_lock_path, PATH_MAX, "status.lock")) {
243 | return;
244 | }
245 |
246 | unlink(status_lock_path);
247 | }
248 |
--------------------------------------------------------------------------------
/src/ct/tlv.c:
--------------------------------------------------------------------------------
1 | /*
2 | * TLV handling routines
3 | *
4 | * Copyright (C) 2003 Olaf Kirch
5 | */
6 |
7 | #ifdef HAVE_CONFIG_H
8 | #include
9 | #endif
10 | #ifdef HAVE_GETOPT_H
11 | #include
12 | #endif
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 |
19 | #include
20 |
21 | /*
22 | * Parse TLV data
23 | */
24 | int ct_tlv_parse(ct_tlv_parser_t * parser, ct_buf_t * bp)
25 | {
26 | unsigned int avail, len;
27 | unsigned char *p, tag;
28 |
29 | /* Code below relies on it */
30 | assert(((ifd_tag_t) - 1) == 255);
31 |
32 | while ((avail = ct_buf_avail(bp)) != 0) {
33 | unsigned int header = 2;
34 |
35 | if (avail < 2)
36 | return -1;
37 |
38 | p = (unsigned char *)ct_buf_head(bp);
39 | tag = p[0];
40 | len = p[1];
41 |
42 | if (tag & __CT_TAG_LARGE) {
43 | parser->use_large_tags = 1;
44 | tag &= ~__CT_TAG_LARGE;
45 | if (avail < 3)
46 | return -1;
47 | len = (len << 8) | p[header++];
48 | }
49 |
50 | if (len == 0 || header + len > avail)
51 | return -1;
52 |
53 | parser->val[tag] = p + header;
54 | parser->len[tag] = len;
55 |
56 | ct_buf_get(bp, NULL, header + len);
57 | }
58 |
59 | return 0;
60 | }
61 |
62 | /*
63 | * Extract TLV encoded items as strings, integers, etc.
64 | */
65 | int ct_tlv_get_string(ct_tlv_parser_t * parser, ifd_tag_t tag, char *buf,
66 | size_t size)
67 | {
68 | unsigned char *p;
69 | unsigned int len;
70 |
71 | if (!(p = parser->val[tag]))
72 | return 0;
73 |
74 | len = parser->len[tag];
75 | if (len > size - 1)
76 | len = size - 1;
77 | strncpy(buf, (const char *)p, len);
78 | buf[len] = '\0';
79 | return 1;
80 | }
81 |
82 | int ct_tlv_get_int(ct_tlv_parser_t * parser, ifd_tag_t tag, unsigned int *value)
83 | {
84 | unsigned char *p;
85 | unsigned int len;
86 |
87 | *value = 0;
88 | if (!(p = parser->val[tag]))
89 | return 0;
90 |
91 | len = parser->len[tag];
92 | while (len--) {
93 | *value <<= 8;
94 | *value |= *p++;
95 | }
96 |
97 | return 1;
98 | }
99 |
100 | int ct_tlv_get_opaque(ct_tlv_parser_t * parser, ifd_tag_t tag,
101 | unsigned char **data, size_t * lenp)
102 | {
103 | unsigned char *p;
104 |
105 | *data = NULL;
106 | *lenp = 0;
107 |
108 | if (!(p = parser->val[tag]))
109 | return 0;
110 | *lenp = parser->len[tag];
111 | *data = p;
112 | return 1;
113 | }
114 |
115 | int ct_tlv_get_bytes(ct_tlv_parser_t * parser, ifd_tag_t tag, void *buf,
116 | size_t size)
117 | {
118 | unsigned char *p;
119 | unsigned int len;
120 |
121 | if (!(p = parser->val[tag]))
122 | return 0;
123 | len = parser->len[tag];
124 | if (len > size)
125 | len = size;
126 | memcpy(buf, p, len);
127 | return len;
128 | }
129 |
130 | /*
131 | * Initialize a TLV data builder
132 | */
133 | void ct_tlv_builder_init(ct_tlv_builder_t * builder, ct_buf_t * bp,
134 | int large_tags)
135 | {
136 | memset(builder, 0, sizeof(*builder));
137 | builder->use_large_tags = large_tags;
138 | builder->buf = bp;
139 | }
140 |
141 | /*
142 | * TLV encode objects
143 | */
144 | void ct_tlv_put_int(ct_tlv_builder_t * builder, ifd_tag_t tag,
145 | unsigned int value)
146 | {
147 | int n;
148 |
149 | if (builder->error)
150 | return;
151 | ct_tlv_put_tag(builder, tag);
152 | for (n = 0; (value >> (n + 8)) != 0; n += 8) ;
153 | do {
154 | ct_tlv_add_byte(builder, value >> n);
155 | n -= 8;
156 | } while (n >= 0);
157 |
158 | builder->lenp = NULL;
159 | }
160 |
161 | void ct_tlv_put_string(ct_tlv_builder_t * builder, ifd_tag_t tag,
162 | const char *string)
163 | {
164 | if (builder->error)
165 | return;
166 |
167 | ct_tlv_put_tag(builder, tag);
168 | ct_tlv_add_bytes(builder, (const unsigned char *)string,
169 | strlen(string));
170 |
171 | builder->lenp = NULL;
172 | }
173 |
174 | void ct_tlv_put_opaque(ct_tlv_builder_t * builder, ifd_tag_t tag,
175 | const unsigned char *data, size_t len)
176 | {
177 | if (builder->error)
178 | return;
179 |
180 | ct_tlv_put_tag(builder, tag);
181 | ct_tlv_add_bytes(builder, data, len);
182 |
183 | builder->lenp = NULL;
184 | }
185 |
186 | void ct_tlv_put_tag(ct_tlv_builder_t * builder, ifd_tag_t tag)
187 | {
188 | ct_buf_t *bp = builder->buf;
189 |
190 | if (builder->error < 0)
191 | return;
192 | if (builder->use_large_tags)
193 | tag |= __CT_TAG_LARGE;
194 | if (ct_buf_putc(bp, tag) < 0)
195 | goto err;
196 | builder->len = 0;
197 | builder->lenp = (unsigned char *)ct_buf_tail(bp);
198 | if (ct_buf_putc(bp, 0) < 0
199 | || (builder->use_large_tags && ct_buf_putc(bp, 0) < 0))
200 | goto err;
201 | return;
202 |
203 | err:builder->error = -1;
204 | }
205 |
206 | void ct_tlv_add_byte(ct_tlv_builder_t * builder, unsigned char byte)
207 | {
208 | ct_tlv_add_bytes(builder, &byte, 1);
209 | }
210 |
211 | void ct_tlv_add_bytes(ct_tlv_builder_t * builder, const unsigned char *data,
212 | size_t num)
213 | {
214 | ct_buf_t *bp = builder->buf;
215 |
216 | if (builder->error < 0)
217 | return;
218 |
219 | if (!builder->lenp)
220 | goto error;
221 |
222 | builder->len += num;
223 | if (ct_buf_put(bp, data, num) < 0)
224 | goto error;
225 |
226 | if (builder->use_large_tags) {
227 | if (builder->len > 65535)
228 | goto error;
229 | builder->lenp[0] = builder->len >> 8;
230 | builder->lenp[1] = builder->len;
231 | } else {
232 | if (builder->len > 266)
233 | goto error;
234 | builder->lenp[0] = builder->len;
235 | }
236 | return;
237 |
238 | error:
239 | builder->error = -1;
240 | return;
241 | }
242 |
--------------------------------------------------------------------------------
/src/ctapi/Makefile.am:
--------------------------------------------------------------------------------
1 | MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
2 |
3 | openctinclude_HEADERS = ctapi.h
4 | lib_LTLIBRARIES = libopenctapi.la
5 |
6 | libopenctapi_la_SOURCES = ctapi.c ctapi.h
7 | libopenctapi_la_LIBADD = $(top_builddir)/src/ct/libopenct.la
8 | libopenctapi_la_CFLAGS = $(AM_CFLAGS) \
9 | -I$(top_srcdir)/src/include \
10 | -I$(top_builddir)/src/include
11 | libopenctapi_la_LDFLAGS = -avoid-version -no-undefined -module -shared
12 |
--------------------------------------------------------------------------------
/src/ctapi/ctapi.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Defines CT-API functions and returns
3 | *
4 | * Copyright (C) 1998, David Corcoran
5 | */
6 |
7 | #ifndef OPENCT_CTAPI_H
8 | #define OPENCT_CTAPI_H
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | #define MAX_APDULEN 1040
15 |
16 | char CT_init(unsigned short Ctn, /* Terminal Number */
17 | unsigned short pn /* Port Number */
18 | );
19 |
20 | char CT_close(unsigned short Ctn /* Terminal Number */
21 | );
22 |
23 | char CT_data(unsigned short ctn, /* Terminal Number */
24 | unsigned char *dad, /* Destination */
25 | unsigned char *sad, /* Source */
26 | unsigned short lc, /* Length of command */
27 | unsigned char *cmd, /* Command/Data Buffer */
28 | unsigned short *lr, /* Length of Response */
29 | unsigned char *rsp /* Response */
30 | );
31 |
32 | #define OK 0 /* Success */
33 | #define ERR_INVALID -1 /* Invalid Data */
34 | #define ERR_CT -8 /* CT Error */
35 | #define ERR_TRANS -10 /* Transmission Error */
36 | #define ERR_MEMORY -11 /* Memory Allocate Error */
37 | #define ERR_HOST -127 /* Abort by Host/OS */
38 | #define ERR_HTSI -128 /* HTSI Error */
39 |
40 | enum {
41 | CTAPI_DAD_ICC1 = 0,
42 | CTAPI_DAD_CT = 1,
43 | CTAPI_DAD_HOST = 2,
44 | CTAPI_DAD_ICC2 = 3
45 | };
46 |
47 | /*
48 | * CT-BCS commands
49 | */
50 | #define CTBCS_CLA 0x20
51 | #define CTBCS_CLA_2 0x80
52 | #define CTBCS_INS_RESET 0x11
53 | #define CTBCS_INS_REQUEST_ICC 0x12
54 | #define CTBCS_INS_STATUS 0x13
55 | #define CTBCS_INS_EJECT_ICC 0x15
56 | #define CTBCS_INS_INPUT 0x16
57 | #define CTBCS_INS_OUTPUT 0x17
58 | #define CTBCS_INS_PERFORM_VERIFICATION 0x18
59 | #define CTBCS_INS_MODIFY_VERIFICATION 0x19
60 | #define CTBCS_INS_SET_INTERFACE_PARAM 0x60
61 |
62 | /*
63 | * CT-BCS functional units (P1 byte)
64 | */
65 | #define CTBCS_UNIT_CT 0x00
66 | #define CTBCS_UNIT_INTERFACE1 0x01
67 | #define CTBCS_UNIT_INTERFACE2 0x02
68 | #define CTBCS_UNIT_DISPLAY 0x40
69 | #define CTBCS_UNIT_KEYPAD 0x50
70 |
71 | /*
72 | * P2 parameter for Reset CT: data to be returned
73 | */
74 | #define CTBCS_P2_RESET_NO_RESP 0x00 /* Return no data */
75 | #define CTBCS_P2_RESET_GET_ATR 0x01 /* Return complete ATR */
76 | #define CTBCS_P2_RESET_GET_HIST 0x02 /* Return historical bytes */
77 |
78 | /*
79 | * P2 parameter for Request ICC: data to be returned
80 | */
81 | #define CTBCS_P2_REQUEST_NO_RESP 0x00 /* Return no data */
82 | #define CTBCS_P2_REQUEST_GET_ATR 0x01 /* Return complete ATR */
83 | #define CTBCS_P2_REQUEST_GET_HIST 0x02 /* Return historical bytes */
84 |
85 | /*
86 | * P2 parameter for Get status: TAG of data object to return
87 | */
88 | #define CTBCS_P2_STATUS_MANUFACTURER 0x46 /* Return manufacturer DO */
89 | #define CTBCS_P2_STATUS_ICC 0x80 /* Return ICC DO */
90 |
91 | /*
92 | * P2 parameter for Input
93 | */
94 | #define CTBCS_P2_INPUT_ECHO 0x01 /* Echo input on display */
95 | #define CTBCS_P2_INPUT_ASTERISKS 0x02 /* Echo input as asterisks */
96 |
97 | /*
98 | * Tags for paramaters to input, output et al.
99 | */
100 | #define CTBCS_TAG_PROMPT 0x50
101 | #define CTBCS_TAG_VERIFY_CMD 0x52
102 | #define CTBCS_TAG_TIMEOUT 0x80
103 | #define CTBCS_TAG_TPP 0x22
104 | #define CTBCS_TAG_TPC 0x45
105 |
106 | /*
107 | * PIN command control flags
108 | */
109 | #define CTBCS_PIN_CONTROL_LEN_SHIFT 4
110 | #define CTBCS_PIN_CONTROL_LEN_MASK 0x0F
111 | #define CTBCS_PIN_CONTROL_ENCODE_ASCII 0x01
112 |
113 | /*
114 | * Status words returned by CTBCS
115 | */
116 |
117 | #define CTBCS_SW_BAD_LENGTH 0x6700
118 | #define CTBCS_SW_BAD_COMMAND 0x6900
119 | #define CTBCS_SW_NOT_EXECUTABLE 0x6985
120 | #define CTBCS_SW_BAD_PARAMS 0x6a00
121 | #define CTBCS_SW_NOT_SUPPORTED 0x6a80
122 | #define CTBCS_SW_INVALID_TLV 0x6a85
123 | #define CTBCS_SW_BAD_LE 0x6c00
124 | #define CTBCS_SW_BAD_INS 0x6d00
125 | #define CTBCS_SW_BAD_CLASS 0x6e00
126 | #define CTBCS_SW_BAD_ICC 0x6f00
127 | #define CTBCS_SW_SUCCESS 0x9000
128 |
129 | /*
130 | * Data returned by Get Status command
131 | */
132 | #define CTBCS_DATA_STATUS_NOCARD 0x00 /* No card present */
133 | #define CTBCS_DATA_STATUS_CARD 0x01 /* Card present */
134 | #define CTBCS_DATA_STATUS_CARD_CONNECT 0x05 /* Card present */
135 |
136 | #ifdef __cplusplus
137 | }
138 | #endif
139 | #endif /* OPENCT_CTAPI_H */
140 |
--------------------------------------------------------------------------------
/src/ifd/Makefile.am:
--------------------------------------------------------------------------------
1 | MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
2 |
3 | noinst_LTLIBRARIES = libifd.la
4 | sbin_PROGRAMS = ifdhandler ifdproxy
5 | noinst_HEADERS = atr.h ctbcs.h ifdhandler.h internal.h ria.h usb-descriptors.h
6 |
7 | libifd_la_SOURCES = \
8 | apdu.c atr.c checksum.c conf.c ctbcs.c device.c driver.c \
9 | init.c locks.c manager.c modules.c pcmcia.c pcmcia-block.c process.c protocol.c \
10 | reader.c serial.c usb.c usb-descriptors.c utils.c \
11 | \
12 | ifd-acr30u.c ifd-cardman.c ifd-ccid.c ifd-cm4000.c ifd-egate.c \
13 | ifd-etoken.c ifd-etoken64.c ifd-eutron.c ifd-gempc.c ifd-ikey2k.c \
14 | ifd-ikey3k.c ifd-kaan.c ifd-pertosmart1030.c ifd-pertosmart1038.c \
15 | ifd-smartboard.c ifd-smph.c ifd-starkey.c ifd-towitoko.c cardman.h \
16 | ifd-cyberjack.c ifd-rutoken.c ifd-epass3k.c \
17 | \
18 | proto-gbp.c proto-sync.c proto-t0.c proto-t1.c \
19 | proto-trans.c proto-escape.c \
20 | \
21 | sys-sunray.c sys-solaris.c sys-bsd.c sys-linux.c sys-null.c sys-osx.c \
22 | \
23 | ria.c
24 | # new driver not working yet: ifd-wbeiuu.c
25 | libifd_la_LIBADD = $(top_builddir)/src/ct/libopenct.la $(LTLIB_LIBS) $(OPTIONAL_LIBUSB_LIBS)
26 | libifd_la_CFLAGS = $(AM_CFLAGS) \
27 | -I$(top_srcdir)/src/include \
28 | -I$(top_builddir)/src/include \
29 | $(OPTIONAL_PCSC_CFLAGS) $(OPTIONAL_LIBUSB_CFLAGS) $(LTLIB_CFLAGS)
30 |
31 | ifdhandler_SOURCES = ifdhandler.c
32 | ifdhandler_LDADD = libifd.la
33 | ifdhandler_CFLAGS = $(AM_CFLAGS) \
34 | -I$(top_srcdir)/src/include \
35 | -I$(top_builddir)/src/include
36 |
37 | ifdproxy_SOURCES = ifdproxy.c ria-device.c ria-server.c
38 | ifdproxy_LDADD = libifd.la
39 | ifdproxy_CFLAGS = $(AM_CFLAGS) \
40 | -I$(top_srcdir)/src/include \
41 | -I$(top_builddir)/src/include
42 |
--------------------------------------------------------------------------------
/src/ifd/apdu.c:
--------------------------------------------------------------------------------
1 | /*
2 | * APDU handling
3 | *
4 | * Copyright (C) 2003, Olaf Kirch
5 | */
6 |
7 | #include "internal.h"
8 | #include
9 |
10 | /*
11 | * Check the APDU type and length
12 | */
13 | static int __ifd_apdu_check(const void *sbuf, size_t len, ifd_iso_apdu_t * iso)
14 | {
15 | unsigned char *data = (unsigned char *)sbuf;
16 | unsigned int b;
17 |
18 | memset(iso, 0, sizeof(*iso));
19 | if (len < 5) {
20 | iso->cse = IFD_APDU_CASE_1;
21 | return 0;
22 | }
23 |
24 | b = data[4];
25 | len -= 5;
26 |
27 | /* APDU + Le */
28 | if (len == 0) {
29 | iso->cse = IFD_APDU_CASE_2S;
30 | iso->le = b ? b : 256;
31 | return 0;
32 | }
33 |
34 | data += 5;
35 | if (b == 0)
36 | b = 256;
37 |
38 | iso->lc = b;
39 | iso->len = len;
40 | iso->data = data;
41 |
42 | /* APDU + Lc + data */
43 | if (len == b) {
44 | iso->cse = IFD_APDU_CASE_3S;
45 | return 0;
46 | }
47 |
48 | /* APDU + Lc + data + Le */
49 | if (len == b + 1) {
50 | iso->cse = IFD_APDU_CASE_4S;
51 | iso->le = data[b] ? data[b] : 256;
52 | iso->len--;
53 | return 0;
54 | }
55 |
56 | return -1;
57 | }
58 |
59 | int ifd_apdu_case(const void *buf, size_t len)
60 | {
61 | ifd_iso_apdu_t iso;
62 |
63 | if (__ifd_apdu_check(buf, len, &iso) < 0)
64 | return -1;
65 | return iso.cse;
66 | }
67 |
68 | /*
69 | * Convert internal APDU type to an ISO-7816-4 APDU
70 | */
71 | int ifd_iso_apdu_parse(const void *data, size_t len, ifd_iso_apdu_t * iso)
72 | {
73 | unsigned char *p;
74 |
75 | if (len < 4)
76 | return -1;
77 |
78 | if (__ifd_apdu_check(data, len, iso) < 0)
79 | return -1;
80 |
81 | p = (unsigned char *)data;
82 | iso->cla = *p++;
83 | iso->ins = *p++;
84 | iso->p1 = *p++;
85 | iso->p2 = *p++;
86 |
87 | return 0;
88 | }
89 |
--------------------------------------------------------------------------------
/src/ifd/atr.c:
--------------------------------------------------------------------------------
1 | /*
2 | * ATR parsing functions
3 | *
4 | * Copyright (C) 2004, Olaf Kirch
5 | */
6 |
7 | #include "internal.h"
8 | #include
9 | #include "atr.h"
10 |
11 | int ifd_atr_parse(ifd_atr_info_t * info, const unsigned char *atr, size_t len)
12 | {
13 | unsigned int m, n, k;
14 |
15 | ifd_debug(1, "atr=%s", ct_hexdump(atr, len));
16 |
17 | /* Initialize the atr_info struct */
18 | memset(info, 0, sizeof(*info));
19 | info->default_protocol = -1;
20 | for (n = 0; n < 3; n++) {
21 | info->TA[n] = -1;
22 | info->TB[n] = -1;
23 | info->TC[n] = -1;
24 | }
25 |
26 | if (len < 2 + (atr[1] & 0x0f))
27 | return IFD_ERROR_INVALID_ATR;
28 |
29 | /* Ignore hysterical bytes */
30 | len -= atr[1] & 0x0f;
31 |
32 | for (m = 0, n = 2; n < len; m++) {
33 | unsigned int TDi;
34 |
35 | /* TA1, TA2, TA3, TA4 are legal, TA5 wouldn't be */
36 | if (m > 3)
37 | return IFD_ERROR_INVALID_ATR;
38 |
39 | TDi = atr[n - 1];
40 | if (n != 2) {
41 | int prot;
42 |
43 | prot = TDi & 0x0f;
44 | if (info->default_protocol < 0)
45 | info->default_protocol = prot;
46 | info->supported_protocols |= (1 << prot);
47 | }
48 |
49 | k = ifd_count_bits(TDi & 0xF0);
50 | if (k == 0 || n + k > len)
51 | return IFD_ERROR_INVALID_ATR;
52 | if (TDi & 0x10)
53 | info->TA[m] = atr[n++];
54 | if (TDi & 0x20)
55 | info->TB[m] = atr[n++];
56 | if (TDi & 0x40)
57 | info->TC[m] = atr[n++];
58 | if (!(TDi & 0x80)) {
59 | /* If the ATR indicates we support anything
60 | * in addition to T=0, there'll be a TCK byte
61 | * at the end of the string.
62 | * For now, simply chop it off. Later we may
63 | * want to verify it.
64 | */
65 | if (info->supported_protocols & ~0x1)
66 | len--;
67 | if (n < len)
68 | return IFD_ERROR_INVALID_ATR;
69 | break;
70 | }
71 | n++;
72 | }
73 |
74 | /* ATR didn't list any supported protocols, so
75 | * we default to T=0 */
76 | if (info->supported_protocols == 0) {
77 | info->supported_protocols = 0x01;
78 | info->default_protocol = IFD_PROTOCOL_T0;
79 | }
80 |
81 | ifd_debug(1, "supported protocols=0x%x, default protocol=%d",
82 | info->supported_protocols, info->default_protocol);
83 | return 0;
84 | }
85 |
86 | /*
87 | * Given the ATR info and a selected protocol, build the PTS
88 | * string.
89 | */
90 | int ifd_build_pts(const ifd_atr_info_t * info, int protocol, unsigned char *buf,
91 | size_t len)
92 | {
93 | unsigned char ptsbuf[7], pck;
94 | size_t n, ptslen = 0;
95 |
96 | /* IFD_PROTOCOL_Tn is just n, so we take it easy here */
97 | if (!(info->supported_protocols & (1 << protocol))) {
98 | ct_error("Protocol not supported by card (according to ATR)");
99 | return IFD_ERROR_NOT_SUPPORTED;
100 | }
101 |
102 | ptsbuf[ptslen++] = 0xFF;
103 | ptsbuf[ptslen++] = protocol;
104 | if (info->TA[0] != -1) {
105 | ptsbuf[ptslen++] = info->TA[0];
106 | ptsbuf[1] |= 0x10;
107 | }
108 | if (info->TC[0] == 255) {
109 | ptsbuf[ptslen++] = 1;
110 | ptsbuf[1] |= 0x20;
111 | }
112 |
113 | for (n = 0, pck = 0; n < ptslen; n++)
114 | pck ^= ptsbuf[n];
115 | ptsbuf[ptslen++] = pck;
116 |
117 | if (ptslen > len)
118 | return IFD_ERROR_BUFFER_TOO_SMALL;
119 |
120 | memcpy(buf, ptsbuf, ptslen);
121 | return ptslen;
122 | }
123 |
124 | /* validate a PTS response according to ISO7816-3 */
125 | int
126 | ifd_verify_pts(ifd_atr_info_t * info,
127 | int protocol, const unsigned char *buf, size_t len)
128 | {
129 | int n, i;
130 | int ptsr[3];
131 | int pck;
132 |
133 | if (len < 3)
134 | return IFD_ERROR_BUFFER_TOO_SMALL;
135 |
136 | if (buf[0] != 0xFF)
137 | return IFD_ERROR_INCOMPATIBLE_DEVICE; /* not a pts response */
138 |
139 | for (n = 0, pck = 0; n < len; n++)
140 | pck ^= buf[n];
141 |
142 | if (pck)
143 | return IFD_ERROR_COMM_ERROR;
144 | for (i = 0; i < 3; i++)
145 | ptsr[i] = -1;
146 | for (i = 0, n = 2; i < 3 && n < len - 1; i++) {
147 | if (buf[1] & 1 << (i + 4))
148 | ptsr[i] = buf[n++];
149 | }
150 | if (n < len - 1) /* extra bytes in response */
151 | return IFD_ERROR_INCOMPATIBLE_DEVICE;
152 | if (info->TA[0] != -1 && ptsr[0] != info->TA[0])
153 | info->TA[0] = -1;
154 | if (info->TC[0] == 255 && (ptsr[1] == -1 || (ptsr[1] & 1) == 0))
155 | return IFD_ERROR_INCOMPATIBLE_DEVICE;
156 | return 0;
157 | }
158 |
159 | int ifd_pts_complete(const unsigned char *pts, size_t len)
160 | {
161 | unsigned int j = 2;
162 |
163 | if (j > len)
164 | return 0;
165 | j = +ifd_count_bits(pts[1] & 0x70);
166 | j++;
167 | if (j > len)
168 | return 0;
169 | return 1;
170 | }
171 |
--------------------------------------------------------------------------------
/src/ifd/atr.h:
--------------------------------------------------------------------------------
1 | /*
2 | * ATR type definitions
3 | *
4 | * Copyright (C) 2004, Olaf Kirch
5 | */
6 |
7 | #ifndef OPENCT_ATR_H
8 | #define OPENCT_ATR_H
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | typedef struct ifd_atr_info {
15 | /* The following contain -1 if the field wasn't present */
16 | int TA[4];
17 | int TB[4];
18 | int TC[4];
19 | unsigned int supported_protocols;
20 | int default_protocol;
21 | } ifd_atr_info_t;
22 |
23 | extern int ifd_atr_parse(ifd_atr_info_t *, const unsigned char *,
24 | size_t);
25 | extern int ifd_build_pts(const ifd_atr_info_t *, int, unsigned char *,
26 | size_t);
27 | extern int ifd_verify_pts(ifd_atr_info_t *, int,
28 | const unsigned char *, size_t);
29 | extern int ifd_pts_complete(const unsigned char *pts, size_t len);
30 |
31 | #ifdef __cplusplus
32 | }
33 | #endif
34 | #endif /* OPENCT_ATR_H */
35 |
--------------------------------------------------------------------------------
/src/ifd/cardman.h:
--------------------------------------------------------------------------------
1 | #ifndef _CARDMAN_H_
2 | #define _CARDMAN_H_
3 |
4 | #define MAX_ATR 33
5 |
6 | #define CM2020_MAX_DEV 16
7 | #define CM4000_MAX_DEV 4
8 |
9 | typedef struct atreq {
10 | int atr_len;
11 | unsigned char atr[64];
12 | int power_act;
13 | unsigned char bIFSD;
14 | unsigned char bIFSC;
15 | } atreq_t;
16 |
17 | typedef struct ptsreq {
18 | unsigned long protocol; /*T=0: 2^0, T=1: 2^1 */
19 | unsigned char flags;
20 | unsigned char pts1;
21 | unsigned char pts2;
22 | unsigned char pts3;
23 | } ptsreq_t;
24 |
25 | #define CM_IOC_MAGIC 'c'
26 | #define CM_IOC_MAXNR 255
27 |
28 | #define CM_IOCGSTATUS _IOR (CM_IOC_MAGIC, 0, unsigned char *)
29 | #define CM_IOCGATR _IOWR(CM_IOC_MAGIC, 1, atreq_t *)
30 | #define CM_IOCSPTS _IOW (CM_IOC_MAGIC, 2, ptsreq_t *)
31 | #define CM_IOCSRDR _IO (CM_IOC_MAGIC, 3)
32 | #define CM_IOCARDOFF _IO (CM_IOC_MAGIC, 4)
33 |
34 | #define CM_IOSDBGLVL _IOW(CM_IOC_MAGIC, 250, int*)
35 |
36 | /* card and device states */
37 | #define CM_CARD_INSERTED 0x01
38 | #define CM_CARD_POWERED 0x02
39 | #define CM_ATR_PRESENT 0x04
40 | #define CM_ATR_VALID 0x08
41 | #define CM_STATE_VALID 0x0f
42 | /* extra info only from CM4000 */
43 | #define CM_NO_READER 0x10
44 | #define CM_BAD_CARD 0x20
45 |
46 | #ifdef __KERNEL__
47 |
48 | /* USB can have 16 readers, while PCMCIA is allowed 4 slots */
49 |
50 | #define CM4000_MAX_DEV 4
51 |
52 | #ifdef __CM2020__
53 |
54 | #define MODULE_NAME "cardman_usb"
55 |
56 | #define CM2020_MAX_DEV 16
57 | #define CM2020_MINOR 224
58 |
59 | #define CM2020_REQT_WRITE 0x42
60 | #define CM2020_REQT_READ 0xc2
61 |
62 | #define CM2020_MODE_1 0x01
63 | #define CM2020_MODE_2 0x02
64 | #define CM2020_MODE_3 0x03
65 | #define CM2020_MODE_4 0x08
66 | #define CM2020_CARD_ON 0x10
67 | #define CM2020_CARD_OFF 0x11
68 | #define CM2020_GET_STATUS 0x20
69 | #define CM2020_STATUS_MASK 0xc0
70 | #define CM2020_STATUS_NO_CARD 0x00
71 | #define CM2020_STATUS_NOT_POWERD 0x40
72 | #define CM2020_STATUS_POWERD 0xc0
73 | #define CM2020_SET_PARAMETER 0x30
74 |
75 | #define CM2020_CARDON_COLD 0x00
76 | #define CM2020_CARDON_WARM 0x01
77 |
78 | #define CM2020_FREQUENCY_3_72MHZ 0x00
79 | #define CM2020_FREQUENCY_5_12MHZ 0x10
80 |
81 | #define CM2020_BAUDRATE_115200 0x0C
82 | #define CM2020_BAUDRATE_76800 0x08
83 | #define CM2020_BAUDRATE_57600 0x06
84 | #define CM2020_BAUDRATE_38400 0x04
85 | #define CM2020_BAUDRATE_28800 0x03
86 | #define CM2020_BAUDRATE_19200 0x02
87 | #define CM2020_BAUDRATE_9600 0x01
88 |
89 | #define CM2020_ODD_PARITY 0x80
90 |
91 | #define CM2020_CARD_ASYNC 0x00
92 |
93 | enum {
94 | CB_NOP,
95 | CB_SET_PARAMETER,
96 | CB_READ_STATUS,
97 | CB_READ_ATR,
98 | CB_WRITE_PTS,
99 | CB_READ_PTS,
100 | CB_WRITE_T1,
101 | CB_PROG_T1,
102 | CB_READ_T1,
103 | CB_WRITE_T0,
104 | CB_WRITE_T0_SW1SW2,
105 | CB_READ_T0,
106 | CB_READ_T0_DATA,
107 | CB_CARD_OFF,
108 | CB_T1MODE2
109 | };
110 |
111 | #define TIMEOUT_LEN 60000
112 | #define MAX_RBUF 512
113 |
114 | typedef struct usb_cardman {
115 |
116 | struct usb_device *dev;
117 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
118 | struct usb_interface *interface; /* the interface for this device */
119 | #endif
120 | struct task_struct *owner;
121 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20)
122 | struct usb_ctrlrequest *dr;
123 | #else
124 | devrequest *dr;
125 | #endif
126 | struct urb *irq, *ctrl, *rctl;
127 | unsigned char *ibuf, *cbuf, *rcbuf;
128 | wait_queue_head_t waitq;
129 |
130 | unsigned char atr[MAX_ATR];
131 | unsigned char atr_csum;
132 | unsigned char atr_len;
133 | unsigned char bIFSD, bIFSC;
134 | unsigned char ta1; /* TA(1) specifies Fi over b8 to b5, Di over b4 to b1 */
135 | unsigned char pts[4];
136 |
137 | unsigned char rbuf[MAX_RBUF];
138 | short rlen;
139 |
140 | int t1_reply_len;
141 |
142 | /* length of a T=0 packet, excl. the header length */
143 | unsigned char t0_data_len;
144 |
145 | /* relative data offset as we proceed through the packet */
146 | unsigned char t0_data_off;
147 |
148 | /* byte 2 of the T=0 header (INS from CLA INS ADR...) */
149 | unsigned char t0_ins;
150 |
151 | /* length of T=0 reply we expcet. 2 for a WriteT0, else
152 | * ReadT0 length + 2 (Sw1 Sw2)
153 | */
154 | unsigned short t0_expected_reply_len;
155 |
156 | int bInterval;
157 | unsigned char ctrlendp;
158 | unsigned char intendp;
159 | unsigned char card_state;
160 | int flags;
161 | int op;
162 | unsigned char proto;
163 | int ttl, ttl_hi, /* CWT */
164 | bwt, /* BWT */
165 | ptsttl; /* PTS retry */
166 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
167 | int open;
168 | int present;
169 | struct semaphore sem;
170 | int minor;
171 | #endif
172 | } usb_cardman_t;
173 | #endif /* __CM2020__ */
174 |
175 | #ifdef __CM4000__
176 |
177 | #define DEVICE_NAME "cmm"
178 | #define MODULE_NAME "cardman_cs"
179 |
180 | /* unofficial CM4000 ioctl */
181 | #define CM4000_IOCMONITOR _IO (CM_IOC_MAGIC, 251)
182 | #define CM4000_IOCDUMPATR _IO (CM_IOC_MAGIC, 252)
183 | #define CM4000_IOCDECUSECOUNT _IO (CM_IOC_MAGIC, 253)
184 | #define CM4000_IOCPOWERON _IO (CM_IOC_MAGIC, 254)
185 | #define CM4000_IOCGIOADDR _IOW(CM_IOC_MAGIC, 255, int*)
186 |
187 | #endif /* __CM4000__ */
188 |
189 | #endif /* __KERNEL__ */
190 | #endif /* _CARDMAN_H_ */
191 |
--------------------------------------------------------------------------------
/src/ifd/checksum.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Checksum handling
3 | *
4 | * Copyright Matthias Bruestle 1999-2002
5 | * For licensing, see the file LICENCE
6 | */
7 |
8 | #include "internal.h"
9 |
10 | #define min( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
11 |
12 | /* ISO STD 3309 */
13 | /* From: medin@catbyte.b30.ingr.com (Dave Medin)
14 | * Subject: CCITT checksums
15 | * Newsgroups: sci.electronics
16 | * Date: Mon, 7 Dec 1992 17:33:39 GMT
17 | */
18 |
19 | /* Correct Table? */
20 |
21 | static unsigned short crctab[256] = {
22 | 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
23 | 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
24 | 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
25 | 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
26 | 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
27 | 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
28 | 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
29 | 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
30 | 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
31 | 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
32 | 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
33 | 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
34 | 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
35 | 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
36 | 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
37 | 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
38 | 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
39 | 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
40 | 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
41 | 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
42 | 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
43 | 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
44 | 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
45 | 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
46 | 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
47 | 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
48 | 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
49 | 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
50 | 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
51 | 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
52 | 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
53 | 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
54 | };
55 |
56 | /*
57 | * Returns LRC of data.
58 | */
59 | unsigned int csum_lrc_compute(const uint8_t * in, size_t len, unsigned char *rc)
60 | {
61 | unsigned char lrc = 0;
62 |
63 | while (len--)
64 | lrc ^= *in++;
65 |
66 | if (rc)
67 | *rc = lrc;
68 | return 1;
69 | }
70 |
71 | /*
72 | * Compute CRC of data.
73 | */
74 | unsigned int
75 | csum_crc_compute(const uint8_t * data, size_t len, unsigned char *rc)
76 | {
77 | unsigned short v = 0xFFFF;
78 |
79 | while (len--) {
80 | v = ((v >> 8) & 0xFF) ^ crctab[(v ^ *data++) & 0xFF];
81 | }
82 |
83 | if (rc) {
84 | rc[0] = (v >> 8) & 0xFF;
85 | rc[1] = v & 0xFF;
86 | }
87 |
88 | return 2;
89 | }
90 |
--------------------------------------------------------------------------------
/src/ifd/ctbcs.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Build Extended CTBCS APDUs for those readers that
3 | * support them (such as Kobil Kaan).
4 | *
5 | * Copyright (C) 2003, Olaf Kirch
6 | */
7 |
8 | #include "internal.h"
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include "ctbcs.h"
14 |
15 | /*
16 | * Start building CTBCS apdu
17 | */
18 | void ctbcs_begin(ct_buf_t * bp, unsigned int ins, unsigned int p1,
19 | unsigned int p2)
20 | {
21 | ct_buf_putc(bp, 0x20);
22 | ct_buf_putc(bp, ins);
23 | ct_buf_putc(bp, p1);
24 | ct_buf_putc(bp, p2);
25 | ct_buf_putc(bp, 0);
26 | }
27 |
28 | /*
29 | * Finish CTBCS apdu
30 | */
31 | int ctbcs_finish(ct_buf_t * bp)
32 | {
33 | unsigned int len;
34 |
35 | if (ct_buf_overrun(bp))
36 | return IFD_ERROR_BUFFER_TOO_SMALL;
37 |
38 | len = ct_buf_avail(bp);
39 | bp->base[4] = len - 5; /* lc */
40 | return len;
41 | }
42 |
43 | /*
44 | * Output a string to the display
45 | */
46 | int ctbcs_build_output(unsigned char *cmd, size_t size, const char *message)
47 | {
48 | ct_buf_t buf;
49 |
50 | if (message == NULL)
51 | return IFD_ERROR_INVALID_ARG;
52 |
53 | ct_buf_init(&buf, cmd, size);
54 | ctbcs_begin(&buf, 0x17, 0x40, 0x00);
55 | ctbcs_add_message(&buf, message);
56 | return ctbcs_finish(&buf);
57 | }
58 |
59 | /*
60 | * Generic Verify APDU
61 | */
62 | static int ctbcs_build_verify_apdu(unsigned char *cmd, size_t size,
63 | unsigned char ins, unsigned char p1,
64 | const char *prompt, unsigned int timeout,
65 | const unsigned char *data, size_t data_len)
66 | {
67 | ct_buf_t buf;
68 |
69 | if (!data || !data_len)
70 | return IFD_ERROR_INVALID_ARG;
71 |
72 | if (prompt == NULL)
73 | return IFD_ERROR_INVALID_ARG;
74 | ct_buf_init(&buf, cmd, size);
75 | ctbcs_begin(&buf, ins, p1, 0x00);
76 |
77 | ctbcs_add_timeout(&buf, timeout);
78 | ctbcs_add_message(&buf, prompt);
79 |
80 | ct_buf_putc(&buf, 0x52);
81 | ct_buf_putc(&buf, data_len);
82 | ct_buf_put(&buf, data, data_len);
83 | if (ct_buf_overrun(&buf))
84 | return IFD_ERROR_BUFFER_TOO_SMALL;
85 |
86 | cmd[4] = ct_buf_avail(&buf) - 5; /* lc */
87 | return ct_buf_avail(&buf);
88 | }
89 |
90 | /*
91 | * Build Perform Verify APDU
92 | */
93 | int ctbcs_build_perform_verify_apdu(unsigned char *cmd, size_t size,
94 | unsigned int p1, const char *prompt,
95 | unsigned int timeout,
96 | const unsigned char *data, size_t data_len)
97 | {
98 | return ctbcs_build_verify_apdu(cmd, size, 0x18, p1,
99 | prompt, timeout, data, data_len);
100 | }
101 |
102 | /*
103 | * Build Modify Verify APDU
104 | */
105 | int ctbcs_build_modify_verify_apdu(unsigned char *cmd, size_t size,
106 | unsigned int p1, const char *prompt,
107 | unsigned int timeout,
108 | const unsigned char *data, size_t data_len)
109 | {
110 | return ctbcs_build_verify_apdu(cmd, size, 0x19, p1,
111 | prompt, timeout, data, data_len);
112 | }
113 |
114 | /*
115 | * Helper function add message/timeout arguments to command
116 | * buffer
117 | */
118 | int ctbcs_add_timeout(ct_buf_t * bp, unsigned int timeout)
119 | {
120 | if (!timeout)
121 | return 0;
122 | ct_buf_putc(bp, 0x80);
123 | ct_buf_putc(bp, 1);
124 | ct_buf_putc(bp, timeout);
125 | return ct_buf_avail(bp);
126 | }
127 |
128 | int ctbcs_add_message(ct_buf_t * bp, const char *message)
129 | {
130 | int n;
131 |
132 | if (!message || !strcmp(message, "@"))
133 | return 0;
134 |
135 | if ((n = strlen(message)) > 32)
136 | n = 32;
137 |
138 | ct_buf_putc(bp, 0x50);
139 | ct_buf_putc(bp, n);
140 | ct_buf_put(bp, message, n);
141 |
142 | return ct_buf_avail(bp);
143 | }
144 |
--------------------------------------------------------------------------------
/src/ifd/ctbcs.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Build Extended CTBCS APDUs for those readers that
3 | * support them (such as Kobil Kaan).
4 | *
5 | * Copyright (C) 2003, Olaf Kirch
6 | */
7 |
8 | #ifndef IFD_CTBCS_H
9 | #define IFD_CTBCS_H
10 |
11 | extern int ctbcs_build_output(unsigned char *cmd, size_t size,
12 | const char *message);
13 | extern int ctbcs_build_perform_verify_apdu(unsigned char *cmd, size_t size,
14 | unsigned int slot,
15 | const char *prompt,
16 | unsigned int timeout,
17 | const unsigned char *data,
18 | size_t data_len);
19 | extern int ctbcs_build_modify_verify_apdu(unsigned char *cmd, size_t size,
20 | unsigned int dest, const char *prompt,
21 | unsigned int timeout,
22 | const unsigned char *data,
23 | size_t data_len);
24 |
25 | extern void ctbcs_begin(ct_buf_t *, unsigned int, unsigned int, unsigned int);
26 | extern int ctbcs_finish(ct_buf_t *);
27 | extern int ctbcs_add_message(ct_buf_t *, const char *);
28 | extern int ctbcs_add_timeout(ct_buf_t *, unsigned int);
29 |
30 | #endif /* IFD_CTBCS_H */
31 |
--------------------------------------------------------------------------------
/src/ifd/device.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Generic IFD device layer
3 | *
4 | * Copyright (C) 2003 Olaf Kirch
5 | */
6 |
7 | #include "internal.h"
8 | #include
9 | #include
10 |
11 | /*
12 | * Open a device given the name
13 | */
14 | ifd_device_t *ifd_device_open(const char *name)
15 | {
16 | if (name == NULL) {
17 | ct_error("Null device");
18 | return NULL;
19 | }
20 |
21 | if (!strncmp(name, "serial:", 7))
22 | return ifd_open_serial(name + 7);
23 | if (!strncmp(name, "usb:", 4))
24 | return ifd_open_usb(name + 4);
25 | if (!strncmp(name, "remote:", 7))
26 | return ifd_open_remote(name + 7);
27 | if (!strncmp(name, "pcmcia:", 7))
28 | return ifd_open_pcmcia(name + 7);
29 | if (!strncmp(name, "pcmcia_block:", 13))
30 | return ifd_open_pcmcia_block(name + 13);
31 |
32 | ct_error("Unknown device type \"%s\"", name);
33 | return NULL;
34 | }
35 |
36 | /*
37 | * Create a new device struct
38 | * This is an internal function called by the different device
39 | * type handlers (serial, usb, etc)
40 | */
41 | ifd_device_t *ifd_device_new(const char *name, struct ifd_device_ops * ops,
42 | size_t size)
43 | {
44 | ifd_device_t *dev;
45 |
46 | dev = (ifd_device_t *) calloc(1, size);
47 | if (!dev) {
48 | ct_error("out of memory");
49 | return NULL;
50 | }
51 | dev->name = strdup(name);
52 | dev->ops = ops;
53 |
54 | return dev;
55 | }
56 |
57 | /*
58 | * Destroy a device handle
59 | */
60 | void ifd_device_free(ifd_device_t * dev)
61 | {
62 | if (dev->name)
63 | free(dev->name);
64 | memset(dev, 0, sizeof(*dev));
65 | free(dev);
66 | }
67 |
68 | /*
69 | * Miscellaneous device operations. These functions
70 | * just do a consistency check on the handle, and route
71 | * the call to the appropriate member function
72 | */
73 | int ifd_device_type(ifd_device_t * dev)
74 | {
75 | return dev->type;
76 | }
77 |
78 | int ifd_device_reset(ifd_device_t * dev)
79 | {
80 | if (!dev || !dev->ops || !dev->ops->reset)
81 | return IFD_ERROR_NOT_SUPPORTED;
82 | return dev->ops->reset(dev);
83 | }
84 |
85 | void ifd_device_set_hotplug(ifd_device_t * dev, int hotplug)
86 | {
87 | if (hotplug)
88 | dev->hotplug = 1;
89 | }
90 |
91 | int ifd_device_set_parameters(ifd_device_t * dev,
92 | const ifd_device_params_t * parms)
93 | {
94 | if (!dev || !dev->ops || !dev->ops->set_params)
95 | return IFD_ERROR_NOT_SUPPORTED;
96 | return dev->ops->set_params(dev, parms);
97 | }
98 |
99 | int ifd_device_get_parameters(ifd_device_t * dev, ifd_device_params_t * parms)
100 | {
101 | if (!dev || !dev->ops || !dev->ops->get_params)
102 | return IFD_ERROR_NOT_SUPPORTED;
103 | return dev->ops->get_params(dev, parms);
104 | }
105 |
106 | void ifd_device_flush(ifd_device_t * dev)
107 | {
108 | if (!dev || !dev->ops || !dev->ops->flush)
109 | return;
110 | dev->ops->flush(dev);
111 | }
112 |
113 | void ifd_device_send_break(ifd_device_t * dev, unsigned int usec)
114 | {
115 | if (!dev || !dev->ops || !dev->ops->send_break)
116 | return;
117 | dev->ops->send_break(dev, usec);
118 | }
119 |
120 | int ifd_device_send(ifd_device_t * dev, const unsigned char *data, size_t len)
121 | {
122 | if (!dev || !dev->ops || !dev->ops->send)
123 | return IFD_ERROR_NOT_SUPPORTED;
124 | return dev->ops->send(dev, data, len);
125 | }
126 |
127 | int ifd_device_control(ifd_device_t * dev, void *cmsg, size_t len)
128 | {
129 | if (!dev || !dev->ops || !dev->ops->control)
130 | return IFD_ERROR_NOT_SUPPORTED;
131 | return dev->ops->control(dev, cmsg, len);
132 | }
133 |
134 | int ifd_device_recv(ifd_device_t * dev, unsigned char *data, size_t len,
135 | long timeout)
136 | {
137 | if (timeout < 0)
138 | timeout = dev->timeout;
139 |
140 | if (!dev || !dev->ops || !dev->ops->recv)
141 | return IFD_ERROR_NOT_SUPPORTED;
142 | return dev->ops->recv(dev, data, len, timeout);
143 | }
144 |
145 | int ifd_device_transceive(ifd_device_t * dev, const void *sbuf, size_t slen,
146 | void *rbuf, size_t rlen, long timeout)
147 | {
148 | int rc;
149 |
150 | if (timeout < 0)
151 | timeout = dev->timeout;
152 |
153 | if (!dev || !dev->ops)
154 | return -1;
155 | if (dev->ops->transceive)
156 | return dev->ops->transceive(dev,
157 | sbuf, slen, rbuf, rlen, timeout);
158 |
159 | /* Fall back to send/recv */
160 | ifd_device_flush(dev);
161 | if ((rc = ifd_device_send(dev, (const unsigned char *)sbuf, slen)) < 0)
162 | return rc;
163 | return ifd_device_recv(dev, (unsigned char *)rbuf, rlen, timeout);
164 | }
165 |
166 | int ifd_device_poll_presence(ifd_device_t * dev, struct pollfd *pfd)
167 | {
168 | if (!dev || !dev->ops || !dev->ops->poll_presence)
169 | return 1;
170 | return dev->ops->poll_presence(dev, pfd);
171 | }
172 |
173 | int ifd_device_get_eventfd(ifd_device_t * dev, short *events)
174 | {
175 | if (!dev || !dev->ops)
176 | return -1;
177 | if (!dev->ops->get_eventfd)
178 | return -1;
179 | return dev->ops->get_eventfd(dev, events);
180 | }
181 |
182 | void ifd_device_close(ifd_device_t * dev)
183 | {
184 | if (!dev)
185 | return;
186 | if (dev->ops && dev->ops->close)
187 | dev->ops->close(dev);
188 | ifd_device_free(dev);
189 | }
190 |
191 | /*
192 | * Device ID handling
193 | */
194 | int ifd_device_id_parse(const char *str, ifd_devid_t * id)
195 | {
196 | unsigned int n;
197 |
198 | id->type = IFD_DEVICE_TYPE_OTHER;
199 |
200 | n = strcspn(str, ":");
201 | if (str[n] == ':') {
202 | if (!strncmp(str, "usb", n))
203 | id->type = IFD_DEVICE_TYPE_USB;
204 | else if (!strncmp(str, "pcmcia", n))
205 | id->type = IFD_DEVICE_TYPE_PCMCIA;
206 | else
207 | return -1;
208 | str += n + 1;
209 | }
210 |
211 | for (n = 0; *str && n < IFD_MAX_DEVID_PARTS; n++) {
212 | id->val[n] = strtoul(str, (char **)&str, 16);
213 | if (*str == '/')
214 | str++;
215 | }
216 |
217 | if (*str || n == 0)
218 | return -1;
219 | id->num = n;
220 | return 0;
221 | }
222 |
223 | int ifd_device_id_match(const ifd_devid_t * match, const ifd_devid_t * id)
224 | {
225 | if (id->type != match->type
226 | || id->num < match->num
227 | || memcmp(id->val, match->val, match->num * sizeof(id->val[0])))
228 | return 0;
229 | return 1;
230 | }
231 |
--------------------------------------------------------------------------------
/src/ifd/driver.c:
--------------------------------------------------------------------------------
1 | /**
2 | * @file
3 | * Generic driver functions.
4 | *
5 | * Copyright (C) 2003, Olaf Kirch
6 | */
7 |
8 | #include "internal.h"
9 | #include
10 | #include
11 |
12 | struct ifd_driver_info {
13 | struct ifd_driver_info *next;
14 |
15 | ifd_driver_t driver;
16 |
17 | unsigned int nids;
18 | ifd_devid_t *id;
19 | };
20 |
21 | static struct ifd_driver_info *list;
22 |
23 | /*
24 | * Find registered driver by name
25 | */
26 | static struct ifd_driver_info *find_by_name(const char *name, int create)
27 | {
28 | struct ifd_driver_info *ip;
29 |
30 | for (ip = list; ip; ip = ip->next) {
31 | if (!strcmp(ip->driver.name, name))
32 | return ip;
33 | }
34 |
35 | if (!create)
36 | return NULL;
37 |
38 | ip = (struct ifd_driver_info *)calloc(1, sizeof(*ip));
39 | if (!ip) {
40 | ct_error("out of memory");
41 | return NULL;
42 | }
43 | ip->driver.name = strdup(name);
44 | ip->next = list;
45 | list = ip;
46 |
47 | return ip;
48 | }
49 |
50 | /**
51 | * Register a driver.
52 | *
53 | * @param name Driver name.
54 | * @param ops Driver operations.
55 | */
56 | void ifd_driver_register(const char *name, struct ifd_driver_ops *ops)
57 | {
58 | struct ifd_driver_info *ip;
59 |
60 | ip = find_by_name(name, 1);
61 | if (ip->driver.ops == NULL)
62 | ip->driver.ops = ops;
63 | }
64 |
65 | /**
66 | * Add a device ID to a driver.
67 | *
68 | * @param id Device ID.
69 | * @param name Driver name.
70 | *
71 | * Device which support plug-and-play can be mapped to drivers based on the
72 | * device ID. This function adds a device ID to a driver, so that the driver
73 | * can be looked-up at device detection time. The driver doesn't have to be
74 | * registered before calling this function.
75 | *
76 | * Device IDs start with the device type followed by a semi-colon and by a
77 | * device type specific ID. The following device types are supported:
78 | *
79 | * @li USB usb:vendor_id/device_id
80 | *
81 | * @return Error code <0 if failure.
82 | */
83 | int ifd_driver_add_id(const char *id, const char *name)
84 | {
85 | struct ifd_driver_info *ip;
86 |
87 | ifd_debug(3, "ifd_driver_add_id(%s, %s)", id, name);
88 | ip = find_by_name(name, 1);
89 | if (!ip)
90 | return -1;
91 |
92 | ip->id = (ifd_devid_t *) realloc(ip->id,
93 | (ip->nids + 1) * sizeof(ifd_devid_t));
94 | if (!ip->id) {
95 | ct_error("out of memory");
96 | return IFD_ERROR_NO_MEMORY;
97 | }
98 | if (ifd_device_id_parse(id, &ip->id[ip->nids]) >= 0)
99 | ip->nids++;
100 |
101 | return 0;
102 | }
103 |
104 | /**
105 | * Get the driver name for a given device ID.
106 | *
107 | * @param id Device ID.
108 | *
109 | * @sa ifd_driver_add_id
110 | * @return Driver name or NULL if no driver is found.
111 | */
112 | const char *ifd_driver_for_id(ifd_devid_t * id)
113 | {
114 | struct ifd_driver_info *ip;
115 | unsigned int n;
116 |
117 | for (ip = list; ip; ip = ip->next) {
118 | for (n = 0; n < ip->nids; n++) {
119 | if (ifd_device_id_match(&ip->id[n], id))
120 | return ip->driver.name;
121 | }
122 | }
123 |
124 | return NULL;
125 | }
126 |
127 | /**
128 | * Lookup a driver by name.
129 | *
130 | * @param name Driver name.
131 | *
132 | * If the configuration parameter @a autoload is set, OpenCT will try to load
133 | * an external module for the requested driver.
134 | *
135 | * @return Pointer the the driver structure, or NULL if no driver is found.
136 | */
137 | const ifd_driver_t *ifd_driver_get(const char *name)
138 | {
139 | struct ifd_driver_info *ip;
140 | int retries = 2;
141 |
142 | while (retries--) {
143 | ip = find_by_name(name, ct_config.autoload);
144 | if (ip == NULL)
145 | break;
146 | if (ip->driver.ops != NULL)
147 | return &ip->driver;
148 | if (!ct_config.autoload || ifd_load_module("driver", name) < 0)
149 | break;
150 | }
151 |
152 | return NULL;
153 | }
154 |
155 | /**
156 | * Get a list of registered drivers.
157 | *
158 | * @param names Name array.
159 | * @param max Size of the name array.
160 | *
161 | * This function fills the array pointed by @a names with pointers to the
162 | * driver names. At most @a max entries are returned. The names must @b not
163 | * be freed by the caller.
164 | *
165 | * @return Number of driver names.
166 | */
167 | unsigned int ifd_drivers_list(const char **names, size_t max)
168 | {
169 | struct ifd_driver_info *ip;
170 | unsigned int n;
171 |
172 | for (ip = list, n = 0; ip && n < max; ip = ip->next, n++) {
173 | names[n] = ip->driver.name;
174 | }
175 | return n;
176 | }
177 |
--------------------------------------------------------------------------------
/src/ifd/ifd-cm4000.c:
--------------------------------------------------------------------------------
1 | /*
2 | * OMNIKEY CardMan Mobile PCMCIA 4000 Driver
3 | *
4 | * This driver is not yet complete, but at least it
5 | * spits out the ATR already.
6 | *
7 | * Copyright (C) 2005, Harald Welte
8 | *
9 | * Based on information from the cm4000 driver by Omnikey AG.
10 | */
11 |
12 | /* only available on linux */
13 | #ifdef linux
14 |
15 | #include "internal.h"
16 | #include "cardman.h"
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 |
23 | /*
24 | * Initialize the device
25 | */
26 | static int cm_open(ifd_reader_t * reader, const char *device_name)
27 | {
28 | ifd_device_t *dev;
29 | ifd_device_params_t params;
30 |
31 | reader->name = "OMNIKEY CardMan 4000";
32 | reader->nslots = 1;
33 | if (!(dev = ifd_device_open(device_name)))
34 | return -1;
35 | if (ifd_device_type(dev) != IFD_DEVICE_TYPE_PCMCIA) {
36 | ct_error("cm4000: device %s is not a PCMCIA device",
37 | device_name);
38 | ifd_device_close(dev);
39 | return -1;
40 | }
41 |
42 | reader->driver_data = NULL;
43 | reader->device = dev;
44 | dev->timeout = 2000;
45 |
46 | params = dev->settings;
47 | params.usb.interface = 0;
48 | if (ifd_device_set_parameters(dev, ¶ms) < 0) {
49 | ct_error("cm4000: setting parameters failed", device_name);
50 | ifd_device_close(dev);
51 | return -1;
52 | }
53 |
54 | return 0;
55 | }
56 |
57 | /*
58 | * Power up the card slot
59 | */
60 | static int cm_activate(ifd_reader_t * reader)
61 | {
62 | ifd_debug(1, "called.");
63 | return 0;
64 | }
65 |
66 | static int cm_deactivate(ifd_reader_t * reader)
67 | {
68 | ifd_debug(1, "called.");
69 | return 0;
70 | }
71 |
72 | /*
73 | * Card status
74 | */
75 | static int cm_card_status(ifd_reader_t * reader, int slot, int *status)
76 | {
77 | ifd_device_t *dev = reader->device;
78 | unsigned int cm_status = 0;
79 | int rc;
80 |
81 | *status = 0;
82 |
83 | ifd_debug(1, "called.");
84 | rc = ioctl(dev->fd, CM_IOCGSTATUS, &cm_status);
85 | if (rc != 0) {
86 | ifd_debug(1, "error during ioctl(CM_IOCGSTATUS): %d=%s",
87 | rc, strerror(errno));
88 | return -1;
89 | }
90 |
91 | if (cm_status & CM_ATR_PRESENT)
92 | *status = IFD_CARD_PRESENT;
93 |
94 | /* Hardware doesn't tell us about status change */
95 |
96 | ifd_debug(1, "card %spresent", *status ? "" : "not ");
97 | return 0;
98 | }
99 |
100 | /*
101 | * Reset
102 | */
103 | static int cm_card_reset(ifd_reader_t * reader, int slot, void *atr,
104 | size_t size)
105 | {
106 | ifd_device_t *dev = reader->device;
107 | struct atreq cmatr;
108 | int len;
109 |
110 | ioctl(dev->fd, 0x6304, 1);
111 | /* propriatary driver doesn't check return value here, too */
112 |
113 | /* CM_IOCGATR */
114 | if (ioctl(dev->fd, CM_IOCGATR, &cmatr) != 0) {
115 | ifd_debug(1, "error during ioctl(CM_IOCGATR)\n");
116 | return -1;
117 | }
118 |
119 | if (cmatr.atr_len == -1) {
120 | ifd_debug(1, "atr_len == -1\n");
121 | return -1;
122 | }
123 |
124 | len = cmatr.atr_len;
125 | if ((size_t) len > size)
126 | len = size;
127 |
128 | memcpy(atr, &cmatr.atr, len);
129 |
130 | return len;
131 | }
132 |
133 | static int cm_send(ifd_reader_t * reader, unsigned int dad,
134 | const unsigned char *buffer, size_t len)
135 | {
136 | ifd_device_t *dev = reader->device;
137 |
138 | return write(dev->fd, buffer, len);
139 | }
140 |
141 | static int cm_recv(ifd_reader_t * reader, unsigned int dad,
142 | unsigned char *buffer, size_t len, long timeout)
143 | {
144 | ifd_device_t *dev = reader->device;
145 |
146 | return read(dev->fd, buffer, len);
147 | }
148 |
149 | /*
150 | * Driver operations
151 | */
152 | static struct ifd_driver_ops cm4000_driver;
153 |
154 | /*
155 | * Initialize this module
156 | */
157 | void ifd_cm4000_register(void)
158 | {
159 | cm4000_driver.open = cm_open;
160 | cm4000_driver.activate = cm_activate;
161 | cm4000_driver.deactivate = cm_deactivate;
162 | cm4000_driver.card_reset = cm_card_reset;
163 | cm4000_driver.card_status = cm_card_status;
164 | cm4000_driver.send = cm_send;
165 | cm4000_driver.recv = cm_recv;
166 |
167 | ifd_driver_register("cm4000", &cm4000_driver);
168 | }
169 |
170 | #else
171 |
172 | /*
173 | * Initialize this module
174 | */
175 | void ifd_cm4000_register(void)
176 | {
177 | }
178 |
179 | #endif
180 |
--------------------------------------------------------------------------------
/src/ifd/ifd-etoken.c:
--------------------------------------------------------------------------------
1 | /*
2 | * eToken driver
3 | *
4 | * Copyright (C) 2003, Olaf Kirch
5 | *
6 | * Based on information from the etoken driver by
7 | * Andreas Jellinghaus .
8 | */
9 |
10 | #include "internal.h"
11 | #include
12 | #include
13 |
14 | #define ET_TIMEOUT 1000
15 |
16 | static int et_magic(ifd_device_t *);
17 |
18 | /*
19 | * Initialize the device
20 | */
21 | static int et_open(ifd_reader_t * reader, const char *device_name)
22 | {
23 | ifd_device_t *dev;
24 | ifd_device_params_t params;
25 |
26 | reader->name = "Aladdin eToken PRO";
27 | reader->nslots = 1;
28 | if (!(dev = ifd_device_open(device_name)))
29 | return -1;
30 | if (ifd_device_type(dev) != IFD_DEVICE_TYPE_USB) {
31 | ct_error("etoken: device %s is not a USB device", device_name);
32 | ifd_device_close(dev);
33 | return -1;
34 | }
35 |
36 | params = dev->settings;
37 | params.usb.interface = 0;
38 | if (ifd_device_set_parameters(dev, ¶ms) < 0) {
39 | ct_error("etoken: setting parameters failed", device_name);
40 | ifd_device_close(dev);
41 | return -1;
42 | }
43 |
44 | reader->device = dev;
45 |
46 | return 0;
47 | }
48 |
49 | /* Some magic incantations copied from Andreas
50 | * Jellinghaus' eToken driver
51 | * */
52 | static int et_magic(ifd_device_t * dev)
53 | {
54 | unsigned char cookie[] = { 0x00, 0x00, 0x01, 0x00, 0x88, 0x13 };
55 | unsigned char buffer[256];
56 |
57 | if (ifd_usb_control(dev, 0x40, 0x03, 0, 0, NULL, 0, -1) < 0
58 | || ifd_usb_control(dev, 0xc0, 0x83, 0, 0, buffer, 13, -1) != 13
59 | || ifd_usb_control(dev, 0x40, 0x02, 0, 0, cookie, sizeof(cookie),
60 | -1) < 0
61 | || ifd_usb_control(dev, 0xc0, 0x82, 0, 0, buffer, 1, -1) != 1
62 | || buffer[0] != 0)
63 | return -1;
64 |
65 | return 0;
66 | }
67 |
68 | /*
69 | * Power up the reader
70 | */
71 | static int et_activate(ifd_reader_t * reader)
72 | {
73 | return 0;
74 | }
75 |
76 | static int et_deactivate(ifd_reader_t * reader)
77 | {
78 | return -1;
79 | }
80 |
81 | /*
82 | * Card status - always present
83 | */
84 | static int et_card_status(ifd_reader_t * reader, int slot, int *status)
85 | {
86 | *status = IFD_CARD_PRESENT;
87 | return 0;
88 | }
89 |
90 | /*
91 | * Reset - nothing to be done?
92 | * We should do something to make it come back with all state zapped
93 | */
94 | static int et_card_reset(ifd_reader_t * reader, int slot, void *atr,
95 | size_t size)
96 | {
97 | ifd_device_t *dev = reader->device;
98 | unsigned char buffer[256];
99 | int rc, n, atrlen;
100 |
101 | /* Request the ATR */
102 | rc = ifd_usb_control(dev, 0x40, 0x01, 0, 0, NULL, 0, ET_TIMEOUT);
103 | if (rc < 0)
104 | goto failed;
105 |
106 | /* Receive the ATR */
107 | rc = ifd_usb_control(dev, 0xc0, 0x81, 0, 0, buffer, 0x23, ET_TIMEOUT);
108 | if (rc <= 0)
109 | goto failed;
110 |
111 | n = buffer[0];
112 | if (n + 1 > rc)
113 | goto failed;
114 | if (n > IFD_MAX_ATR_LEN)
115 | goto failed;
116 |
117 | if (n > size)
118 | n = size;
119 | atrlen = n;
120 | memcpy(atr, buffer + 1, atrlen);
121 |
122 | if (et_magic(dev) < 0)
123 | goto failed;
124 | return atrlen;
125 |
126 | failed:
127 | ct_error("etoken: failed to activate token");
128 | return -1;
129 | }
130 |
131 | /*
132 | * Send/receive routines
133 | */
134 | static int et_send(ifd_reader_t * reader, unsigned int dad,
135 | const unsigned char *buffer, size_t len)
136 | {
137 | return ifd_usb_control(reader->device, 0x40, 0x06, 0, 0,
138 | (void *)buffer, len, -1);
139 | }
140 |
141 | static int et_recv(ifd_reader_t * reader, unsigned int dad,
142 | unsigned char *buffer, size_t len, long timeout)
143 | {
144 | return ifd_usb_control(reader->device, 0xc0, 0x86, 0, 0,
145 | buffer, len, timeout);
146 | }
147 |
148 | static int et_get_eventfd(ifd_reader_t * reader, short *events)
149 | {
150 | ifd_debug(1, "called.");
151 |
152 | return ifd_device_get_eventfd(reader->device, events);
153 | }
154 |
155 | static int et_event(ifd_reader_t * reader, int *status, size_t status_size)
156 | {
157 | (void)reader;
158 | (void)status;
159 | (void)status_size;
160 |
161 | ifd_debug(1, "called.");
162 |
163 | return 0;
164 | }
165 |
166 | static int et_error(ifd_reader_t * reader)
167 | {
168 | (void)reader;
169 |
170 | ifd_debug(1, "called.");
171 |
172 | return IFD_ERROR_DEVICE_DISCONNECTED;
173 | }
174 |
175 | /*
176 | * Driver operations
177 | */
178 | static struct ifd_driver_ops etoken_driver;
179 |
180 | /*
181 | * Initialize this module
182 | */
183 | void ifd_etoken_register(void)
184 | {
185 | etoken_driver.open = et_open;
186 | etoken_driver.activate = et_activate;
187 | etoken_driver.deactivate = et_deactivate;
188 | etoken_driver.card_status = et_card_status;
189 | etoken_driver.card_reset = et_card_reset;
190 | etoken_driver.send = et_send;
191 | etoken_driver.recv = et_recv;
192 | etoken_driver.get_eventfd = et_get_eventfd;
193 | etoken_driver.event = et_event;
194 | etoken_driver.error = et_error;
195 |
196 | ifd_driver_register("etoken", &etoken_driver);
197 | }
198 |
--------------------------------------------------------------------------------
/src/ifd/ifd-etoken64.c:
--------------------------------------------------------------------------------
1 | /*
2 | * eToken 64 driver
3 | *
4 | * Copyright (C) 2005, Olaf Kirch
5 | * Copyright (C) 2005, Andreas Jellinghaus .
6 | */
7 |
8 | #include "internal.h"
9 | #include
10 | #include
11 |
12 | #define ET64_TIMEOUT 1000
13 |
14 | /*
15 | * Initialize the device
16 | */
17 | static int et64_open(ifd_reader_t * reader, const char *device_name)
18 | {
19 | ifd_device_t *dev;
20 | ifd_device_params_t params;
21 |
22 | reader->name = "Aladdin eToken PRO 64k";
23 | reader->nslots = 1;
24 | if (!(dev = ifd_device_open(device_name)))
25 | return -1;
26 | if (ifd_device_type(dev) != IFD_DEVICE_TYPE_USB) {
27 | ct_error("etoken64: device %s is not a USB device",
28 | device_name);
29 | ifd_device_close(dev);
30 | return -1;
31 | }
32 |
33 | params = dev->settings;
34 | params.usb.interface = 0;
35 | if (ifd_device_set_parameters(dev, ¶ms) < 0) {
36 | ct_error("etoken64: setting parameters failed", device_name);
37 | ifd_device_close(dev);
38 | return -1;
39 | }
40 |
41 | reader->device = dev;
42 |
43 | return 0;
44 | }
45 |
46 | /*
47 | * Power up the reader
48 | */
49 | static int et64_activate(ifd_reader_t * reader)
50 | {
51 | return 0;
52 | }
53 |
54 | static int et64_deactivate(ifd_reader_t * reader)
55 | {
56 | return -1;
57 | }
58 |
59 | /*
60 | * Card status - always present
61 | */
62 | static int et64_card_status(ifd_reader_t * reader, int slot, int *status)
63 | {
64 | *status = IFD_CARD_PRESENT;
65 | return 0;
66 | }
67 |
68 | /*
69 | * Reset - nothing to be done?
70 | * We should do something to make it come back with all state zapped
71 | */
72 | static int et64_card_reset(ifd_reader_t * reader, int slot, void *atr,
73 | size_t size)
74 | {
75 | ifd_device_t *dev = reader->device;
76 | unsigned char buffer[256];
77 | int rc, n, atrlen;
78 |
79 | /* Request the ATR */
80 | rc = ifd_usb_control(dev, 0x40, 0x01, 0, 0, NULL, 0, ET64_TIMEOUT);
81 | if (rc < 0)
82 | goto failed;
83 |
84 | /* Receive the ATR */
85 | rc = ifd_usb_control(dev, 0xc0, 0x81, 0, 0, buffer, 0x23, ET64_TIMEOUT);
86 | if (rc <= 0)
87 | goto failed;
88 |
89 | n = buffer[0];
90 | if (n + 1 > rc)
91 | goto failed;
92 | if (n > IFD_MAX_ATR_LEN)
93 | goto failed;
94 |
95 | if (n > size)
96 | n = size;
97 | atrlen = n;
98 | memcpy(atr, buffer + 1, atrlen);
99 |
100 | if (ifd_usb_control(dev, 0x40, 0x08, 0, 0, NULL, 0, -1) < 0
101 | || ifd_usb_control(dev, 0xc0, 0x88, 0, 0, buffer, 02, -1) != 02
102 | || ifd_usb_control(dev, 0x40, 0x03, 0, 0, NULL, 0, -1) < 0
103 | || ifd_usb_control(dev, 0xc0, 0x83, 0, 0, buffer, 1, -1) != 1
104 | || buffer[0] != 0)
105 | goto failed;
106 |
107 | return atrlen;
108 |
109 | failed:
110 | ct_error("etoken64: failed to activate token");
111 | return -1;
112 | }
113 |
114 | /*
115 | * Send/receive routines
116 | */
117 | static int et64_send(ifd_reader_t * reader, unsigned int dad,
118 | const unsigned char *buffer, size_t len)
119 | {
120 | return ifd_usb_control(reader->device, 0x40, 0x06, 0, 0,
121 | (void *)buffer, len, -1);
122 | }
123 |
124 | static int et64_recv(ifd_reader_t * reader, unsigned int dad,
125 | unsigned char *buffer, size_t len, long timeout)
126 | {
127 | return ifd_usb_control(reader->device, 0xc0, 0x86, 0, 0,
128 | buffer, len, timeout);
129 | }
130 |
131 | static int et64_get_eventfd(ifd_reader_t * reader, short *events)
132 | {
133 | ifd_debug(1, "called.");
134 |
135 | return ifd_device_get_eventfd(reader->device, events);
136 | }
137 |
138 | static int et64_event(ifd_reader_t * reader, int *status, size_t status_size)
139 | {
140 | (void)reader;
141 | (void)status;
142 | (void)status_size;
143 |
144 | ifd_debug(1, "called.");
145 |
146 | return 0;
147 | }
148 |
149 | static int et64_error(ifd_reader_t * reader)
150 | {
151 | (void)reader;
152 |
153 | ifd_debug(1, "called.");
154 |
155 | return IFD_ERROR_DEVICE_DISCONNECTED;
156 | }
157 |
158 | /*
159 | * Driver operations
160 | */
161 | static struct ifd_driver_ops etoken64_driver;
162 |
163 | /*
164 | * Initialize this module
165 | */
166 | void ifd_etoken64_register(void)
167 | {
168 | etoken64_driver.open = et64_open;
169 | etoken64_driver.activate = et64_activate;
170 | etoken64_driver.deactivate = et64_deactivate;
171 | etoken64_driver.card_status = et64_card_status;
172 | etoken64_driver.card_reset = et64_card_reset;
173 | etoken64_driver.send = et64_send;
174 | etoken64_driver.recv = et64_recv;
175 | etoken64_driver.get_eventfd = et64_get_eventfd;
176 | etoken64_driver.event = et64_event;
177 | etoken64_driver.error = et64_error;
178 |
179 | ifd_driver_register("etoken64", &etoken64_driver);
180 | }
181 |
--------------------------------------------------------------------------------
/src/ifd/ifd-ikey2k.c:
--------------------------------------------------------------------------------
1 | /*
2 | * driver for Rainbow iKey 2032 devices
3 | *
4 | * Copyright (C) 2003, Andreas Jellinghaus
5 | * Copyright (C) 2003, Olaf Kirch
6 | */
7 |
8 | #include "internal.h"
9 | #include
10 | #include
11 |
12 | /*
13 | * Initialize the device
14 | */
15 | static int ikey2k_open(ifd_reader_t * reader, const char *device_name)
16 | {
17 | ifd_device_t *dev;
18 | ifd_device_params_t params;
19 |
20 | reader->name = "Rainbow iKey 2032";
21 | reader->nslots = 1;
22 | if (!(dev = ifd_device_open(device_name)))
23 | return -1;
24 | if (ifd_device_type(dev) != IFD_DEVICE_TYPE_USB) {
25 | ct_error("ikey2k: device %s is not a USB device", device_name);
26 | ifd_device_close(dev);
27 | return -1;
28 | }
29 |
30 | params = dev->settings;
31 | params.usb.interface = 0;
32 | if (ifd_device_set_parameters(dev, ¶ms) < 0) {
33 | ct_error("ikey2k: setting parameters failed", device_name);
34 | ifd_device_close(dev);
35 | return -1;
36 | }
37 |
38 | reader->device = dev;
39 |
40 | return 0;
41 | }
42 |
43 | /*
44 | * Power up the reader
45 | */
46 | static int ikey2k_activate(ifd_reader_t * reader)
47 | {
48 | return 0;
49 | }
50 |
51 | static int ikey2k_deactivate(ifd_reader_t * reader)
52 | {
53 | return -1;
54 | }
55 |
56 | /*
57 | * Card status - always present
58 | */
59 | static int ikey2k_card_status(ifd_reader_t * reader, int slot, int *status)
60 | {
61 | *status = IFD_CARD_PRESENT;
62 | return 0;
63 | }
64 |
65 | /*
66 | * Reset - nothing to be done?
67 | * We should do something to make it come back with all state zapped
68 | */
69 | static int ikey2k_card_reset(ifd_reader_t * reader, int slot, void *atr,
70 | size_t size)
71 | {
72 | ifd_device_t *dev = reader->device;
73 | unsigned char buffer[256];
74 | int rc, atrlen;
75 |
76 | static unsigned char expect5[] =
77 | { 0x0d, 0x63, 0x00, 0x00, 0x2d, 0x2d, 0xc0, 0x80,
78 | 0x80, 0x60, 0x80, 0x01, 0x19
79 | };
80 |
81 | if (ifd_usb_control(dev, 0xc1, 0x00, 0, 0, buffer, 0x40, -1) != 13)
82 | goto failed;
83 |
84 | /* we've seen values of 0x03, 0x05 and 0x06 in position 3, and
85 | * since we don't know what they mean, we mask them here. */
86 | buffer[3] &= 0xF0;
87 |
88 | if (memcmp(buffer, expect5, sizeof(expect5)) != 0
89 | || ifd_usb_control(dev, 0x41, 0x16, 0, 0, buffer, 00, -1) != 0
90 | || ifd_usb_control(dev, 0xc1, 0x01, 0, 0, buffer, 02, -1) != 1
91 | || buffer[0] != 00)
92 | goto failed;
93 |
94 | rc = ifd_usb_control(dev, 0x41, 0x16, 0x1901, 0, buffer, 0, 1000);
95 | if (rc < 0)
96 | goto failed;
97 |
98 | rc = ifd_usb_control(dev, 0xc1, 0x01, 0, 0, buffer, 0x19, 1000);
99 | if (rc != 25)
100 | goto failed;
101 |
102 | rc = ifd_usb_control(dev, 0x41, 0x16, 0, 0, buffer, 0x0, 1000);
103 | if (rc != 0)
104 | goto failed;
105 |
106 | rc = ifd_usb_control(dev, 0xc1, 0x01, 0, 0, buffer, 0x02, 1000);
107 | if (rc != 1 || buffer[0] != 0)
108 | goto failed;
109 |
110 | rc = ifd_usb_control(dev, 0x41, 0x16, 0, 0, buffer, 0x0, 1000);
111 | if (rc != 0)
112 | goto failed;
113 |
114 | rc = ifd_usb_control(dev, 0xc1, 0x01, 0, 0, buffer, 0x20, 1000);
115 | if (rc != 1 || buffer[0] != 0)
116 | goto failed;
117 |
118 | rc = ifd_usb_control(dev, 0x41, 0x16, 0x1901, 0, buffer, 0, 1000);
119 | if (rc < 0)
120 | goto failed;
121 |
122 | rc = ifd_usb_control(dev, 0xc1, 0x01, 0, 0, buffer, 0x19, 1000);
123 | if (rc != 25)
124 | goto failed;
125 |
126 | /* yes, this is _currently_ dead code, as IFD_MAX_ATR_LEN
127 | * is higher than 25 ... */
128 | if (rc > IFD_MAX_ATR_LEN)
129 | goto failed;
130 |
131 | atrlen = rc;
132 | memcpy(atr, buffer, atrlen);
133 |
134 | return atrlen;
135 |
136 | failed:
137 | ct_error("ikey2k: failed to activate token");
138 | return -1;
139 | }
140 |
141 | /*
142 | * Select a protocol. We override this function to be able to set the T=1 IFSC
143 | */
144 | static int ikey2k_set_protocol(ifd_reader_t * reader, int nslot, int proto)
145 | {
146 | ifd_slot_t *slot = &reader->slot[nslot];
147 | int r;
148 |
149 | if (!(slot->proto = ifd_protocol_new(proto, reader, slot->dad)))
150 | return -1;
151 |
152 | if (proto == IFD_PROTOCOL_T1) {
153 | r = ifd_protocol_set_parameter(slot->proto,
154 | IFD_PROTOCOL_T1_IFSC, 256);
155 | if (r < 0)
156 | return r;
157 | }
158 |
159 | return 0;
160 | }
161 |
162 | /*
163 | * Send/receive routines
164 | */
165 | static int ikey2k_send(ifd_reader_t * reader, unsigned int dad,
166 | const unsigned char *buffer, size_t len)
167 | {
168 | int value, idx;
169 | value = buffer[1] << 8 | buffer[0];
170 | idx = buffer[3] << 8 | buffer[2];
171 |
172 | return ifd_usb_control(reader->device, 0x41, 0x17, value, idx,
173 | (void *)&buffer[4], len - 4, -1);
174 | }
175 |
176 | static int ikey2k_recv(ifd_reader_t * reader, unsigned int dad,
177 | unsigned char *buffer, size_t len, long timeout)
178 | {
179 | return ifd_usb_control(reader->device, 0xc1, 0x01, 0, 0,
180 | buffer, 255, timeout);
181 | }
182 |
183 | /*
184 | * Driver operations
185 | */
186 | static struct ifd_driver_ops ikey2k_driver;
187 |
188 | /*
189 | * Initialize this module
190 | */
191 | void ifd_ikey2k_register(void)
192 | {
193 | ikey2k_driver.open = ikey2k_open;
194 | ikey2k_driver.activate = ikey2k_activate;
195 | ikey2k_driver.deactivate = ikey2k_deactivate;
196 | ikey2k_driver.card_status = ikey2k_card_status;
197 | ikey2k_driver.card_reset = ikey2k_card_reset;
198 | ikey2k_driver.set_protocol = ikey2k_set_protocol;
199 | ikey2k_driver.send = ikey2k_send;
200 | ikey2k_driver.recv = ikey2k_recv;
201 |
202 | ifd_driver_register("ikey2k", &ikey2k_driver);
203 | }
204 |
--------------------------------------------------------------------------------
/src/ifd/ifd-ikey3k.c:
--------------------------------------------------------------------------------
1 | /*
2 | * driver for Rainbow iKey 3000 devices
3 | *
4 | * Copyright (C) 2003, Andreas Jellinghaus
5 | * Copyright (C) 2003, Olaf Kirch
6 | */
7 |
8 | #include "internal.h"
9 | #include
10 | #include
11 |
12 | /*
13 | * Initialize the device
14 | */
15 | static int ikey3k_open(ifd_reader_t * reader, const char *device_name)
16 | {
17 | ifd_device_t *dev;
18 | ifd_device_params_t params;
19 |
20 | reader->name = "Rainbow iKey 3000";
21 | reader->nslots = 1;
22 | if (!(dev = ifd_device_open(device_name)))
23 | return -1;
24 | if (ifd_device_type(dev) != IFD_DEVICE_TYPE_USB) {
25 | ct_error("ikey3k: device %s is not a USB device", device_name);
26 | ifd_device_close(dev);
27 | return -1;
28 | }
29 |
30 | params = dev->settings;
31 | params.usb.interface = 0;
32 | if (ifd_device_set_parameters(dev, ¶ms) < 0) {
33 | ct_error("ikey3k: setting parameters failed", device_name);
34 | ifd_device_close(dev);
35 | return -1;
36 | }
37 |
38 | reader->device = dev;
39 |
40 | return 0;
41 | }
42 |
43 | /*
44 | * Power up the reader
45 | */
46 | static int ikey3k_activate(ifd_reader_t * reader)
47 | {
48 | return 0;
49 | }
50 |
51 | static int ikey3k_deactivate(ifd_reader_t * reader)
52 | {
53 | return -1;
54 | }
55 |
56 | /*
57 | * Card status - always present
58 | */
59 | static int ikey3k_card_status(ifd_reader_t * reader, int slot, int *status)
60 | {
61 | *status = IFD_CARD_PRESENT;
62 | return 0;
63 | }
64 |
65 | /*
66 | * Reset - nothing to be done?
67 | * We should do something to make it come back with all state zapped
68 | */
69 | static int ikey3k_card_reset(ifd_reader_t * reader, int slot, void *atr,
70 | size_t size)
71 | {
72 | ifd_device_t *dev = reader->device;
73 | unsigned char buffer[256];
74 | int rc, n, atrlen;
75 |
76 | unsigned char expect5[] =
77 | { 0x0a, 0x61, 0x00, 0x07, 0x2d, 0x2d, 0xc0, 0x80, 0x80, 0x60 };
78 | unsigned char expect11[] = { 0xff, 0x11, 0x11, 0xff };
79 |
80 | if (ifd_usb_control(dev, 0xc1, 0x00, 0, 0, buffer, 0x40, -1) != 10
81 | || memcmp(buffer, expect5, sizeof(expect5)) != 0
82 | || ifd_usb_control(dev, 0x41, 0x16, 0, 0, buffer, 00, -1) != 0
83 | || ifd_usb_control(dev, 0xc1, 0x01, 0, 0, buffer, 02, -1) != 1
84 | || buffer[0] != 00)
85 | goto failed;
86 |
87 | rc = ifd_usb_control(dev, 0x41, 0x16, 0x2005, 0, buffer, 0, 1000);
88 | if (rc < 0)
89 | goto failed;
90 |
91 | rc = ifd_usb_control(dev, 0xc1, 0x01, 0, 0, buffer, 0x20, 1000);
92 | if (rc <= 0)
93 | goto failed;
94 |
95 | n = buffer[0];
96 | if (n + 1 > rc)
97 | goto failed;
98 | if (n > IFD_MAX_ATR_LEN)
99 | goto failed;
100 |
101 | if (n > size)
102 | n = size;
103 | atrlen = n;
104 | memcpy(atr, buffer + 1, atrlen);
105 |
106 | if (ifd_usb_control(dev, 0x41, 0x16, 0x0002, 0, buffer, 0, -1) != 0
107 | || ifd_usb_control(dev, 0xc1, 0x01, 0, 0, buffer, 04, -1) != 4
108 | || memcmp(buffer, expect11, sizeof(expect11)) != 0)
109 | goto failed;
110 |
111 | return atrlen;
112 |
113 | failed:
114 | ct_error("ikey3k: failed to activate token");
115 | return -1;
116 | }
117 |
118 | /*
119 | * Select a protocol. We override this function to be able to set the T=1 IFSC
120 | */
121 | static int ikey3k_set_protocol(ifd_reader_t * reader, int nslot, int proto)
122 | {
123 | ifd_slot_t *slot = &reader->slot[nslot];
124 | int r;
125 |
126 | if (!(slot->proto = ifd_protocol_new(proto, reader, slot->dad)))
127 | return -1;
128 |
129 | if (proto == IFD_PROTOCOL_T1) {
130 | r = ifd_protocol_set_parameter(slot->proto,
131 | IFD_PROTOCOL_T1_IFSC, 256);
132 | if (r < 0)
133 | return r;
134 | }
135 |
136 | return 0;
137 | }
138 |
139 | /*
140 | * Send/receive routines
141 | */
142 | static int ikey3k_send(ifd_reader_t * reader, unsigned int dad,
143 | const unsigned char *buffer, size_t len)
144 | {
145 | int value, idx;
146 | value = buffer[1] << 8 | buffer[0];
147 | idx = buffer[3] << 8 | buffer[2];
148 |
149 | return ifd_usb_control(reader->device, 0x41, 0x17, value, idx,
150 | (void *)&buffer[4], len - 4, -1);
151 | }
152 |
153 | static int ikey3k_recv(ifd_reader_t * reader, unsigned int dad,
154 | unsigned char *buffer, size_t len, long timeout)
155 | {
156 | return ifd_usb_control(reader->device, 0xc1, 0x01, 0, 0,
157 | buffer, 255, timeout);
158 | }
159 |
160 | /*
161 | * Driver operations
162 | */
163 | static struct ifd_driver_ops ikey3k_driver;
164 |
165 | /*
166 | * Initialize this module
167 | */
168 | void ifd_ikey3k_register(void)
169 | {
170 | ikey3k_driver.open = ikey3k_open;
171 | ikey3k_driver.activate = ikey3k_activate;
172 | ikey3k_driver.deactivate = ikey3k_deactivate;
173 | ikey3k_driver.card_status = ikey3k_card_status;
174 | ikey3k_driver.card_reset = ikey3k_card_reset;
175 | ikey3k_driver.set_protocol = ikey3k_set_protocol;
176 | ikey3k_driver.send = ikey3k_send;
177 | ikey3k_driver.recv = ikey3k_recv;
178 |
179 | ifd_driver_register("ikey3k", &ikey3k_driver);
180 | }
181 |
--------------------------------------------------------------------------------
/src/ifd/ifd-starkey.c:
--------------------------------------------------------------------------------
1 | /*
2 | * starkey driver
3 | *
4 | * Copyright (C) 2005, Andreas Jellinghaus
5 | */
6 |
7 | #include "internal.h"
8 | #include
9 | #include
10 |
11 | #define STARKEY_TIMEOUT 100000
12 |
13 | /*
14 | * Initialize the device
15 | */
16 | static int starkey_open(ifd_reader_t * reader, const char *device_name)
17 | {
18 | ifd_device_t *dev;
19 | ifd_device_params_t params;
20 |
21 | reader->name = "G&D Starkey 100";
22 | reader->nslots = 1;
23 | if (!(dev = ifd_device_open(device_name)))
24 | return -1;
25 | if (ifd_device_type(dev) != IFD_DEVICE_TYPE_USB) {
26 | ct_error("starkey: device %s is not a USB device", device_name);
27 | ifd_device_close(dev);
28 | return -1;
29 | }
30 |
31 | params = dev->settings;
32 | params.usb.interface = 0;
33 | if (ifd_device_set_parameters(dev, ¶ms) < 0) {
34 | ct_error("starkey: setting parameters failed", device_name);
35 | ifd_device_close(dev);
36 | return -1;
37 | }
38 |
39 | reader->device = dev;
40 |
41 | return 0;
42 | }
43 |
44 | /*
45 | * Power up the reader
46 | */
47 | static int starkey_activate(ifd_reader_t * reader)
48 | {
49 | return 0;
50 | }
51 |
52 | static int starkey_deactivate(ifd_reader_t * reader)
53 | {
54 | return -1;
55 | }
56 |
57 | /*
58 | * Card status - always present
59 | */
60 | static int starkey_card_status(ifd_reader_t * reader, int slot, int *status)
61 | {
62 | *status = IFD_CARD_PRESENT;
63 | return 0;
64 | }
65 |
66 | /*
67 | * Reset - nothing to be done?
68 | * We should do something to make it come back with all state zapped
69 | */
70 | static int starkey_card_reset(ifd_reader_t * reader, int slot, void *atr,
71 | size_t size)
72 | {
73 | ifd_device_t *dev = reader->device;
74 | unsigned char buffer[32];
75 | int rc, atrlen;
76 | ifd_usb_capture_t *cap;
77 |
78 | rc = ifd_usb_begin_capture(dev,
79 | IFD_USB_URB_TYPE_INTERRUPT, 0x81,
80 | sizeof(buffer), &cap);
81 | if (rc < 0)
82 | return rc;
83 |
84 | rc = ifd_usb_capture(dev, cap, buffer, sizeof(buffer), STARKEY_TIMEOUT);
85 |
86 | if (rc <= 0) {
87 | ct_error("starkey: failed to activate token");
88 | return -1;
89 | }
90 |
91 | memcpy(atr, buffer, rc);
92 | atrlen = rc;
93 | return atrlen;
94 | }
95 |
96 | /*
97 | * Send/receive routines
98 | */
99 | static int starkey_send(ifd_reader_t * reader, unsigned int dad,
100 | const unsigned char *buffer, size_t len)
101 | {
102 | return ifd_usb_control(reader->device, 0x40, 0x06, 0, 0,
103 | (void *)buffer, len, -1);
104 | }
105 |
106 | static int starkey_recv(ifd_reader_t * reader, unsigned int dad,
107 | unsigned char *buffer, size_t len, long timeout)
108 | {
109 | return ifd_usb_control(reader->device, 0xc0, 0x86, 0, 0,
110 | buffer, len, timeout);
111 | }
112 |
113 | /*
114 | * Driver operations
115 | */
116 | static struct ifd_driver_ops starkey_driver;
117 |
118 | /*
119 | * Initialize this module
120 | */
121 | void ifd_starkey_register(void)
122 | {
123 | starkey_driver.open = starkey_open;
124 | starkey_driver.activate = starkey_activate;
125 | starkey_driver.deactivate = starkey_deactivate;
126 | starkey_driver.card_status = starkey_card_status;
127 | starkey_driver.card_reset = starkey_card_reset;
128 | starkey_driver.send = starkey_send;
129 | starkey_driver.recv = starkey_recv;
130 |
131 | ifd_driver_register("starkey", &starkey_driver);
132 | }
133 |
--------------------------------------------------------------------------------
/src/ifd/ifdhandler.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Internal ifdhandler functions
3 | *
4 | * Copyright (C) 2003 Olaf Kirch
5 | */
6 |
7 | #ifndef IFD_IFDHANDLER_H
8 | #define IFD_IFDHANDLER_H
9 |
10 | #include
11 | #include
12 | #include
13 |
14 | extern int ifdhandler_process(ct_socket_t *, ifd_reader_t *,
15 | ct_buf_t *, ct_buf_t *);
16 | extern int ifdhandler_lock(ct_socket_t *, int, int, ct_lock_handle *);
17 | extern int ifdhandler_check_lock(ct_socket_t *, int, int);
18 | extern int ifdhandler_unlock(ct_socket_t *, int, ct_lock_handle);
19 | extern void ifdhandler_unlock_all(ct_socket_t *);
20 |
21 | #endif /* IFD_IFDHANDLER_H */
22 |
--------------------------------------------------------------------------------
/src/ifd/init.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Initialize the library
3 | *
4 | * Copyright (C) 2003 Olaf Kirch
5 | */
6 |
7 | #include "internal.h"
8 | #include
9 | #include
10 |
11 | static int configure_driver(ifd_conf_node_t * cf);
12 |
13 | int ifd_init(void)
14 | {
15 | unsigned int ival;
16 | char *sval;
17 | ifd_conf_node_t **nodes;
18 | int i, n;
19 |
20 | /* initialize ltdl */
21 | i = lt_dlinit();
22 | if (i != 0)
23 | ct_error("lt_dlinit returned %d", i);
24 |
25 | /* Register built-in drivers */
26 | ifd_acr30u_register();
27 | ifd_cardman_register();
28 | ifd_cm4000_register();
29 | ifd_egate_register();
30 | ifd_epass3k_register();
31 | ifd_etoken_register();
32 | ifd_etoken64_register();
33 | ifd_eutron_register();
34 | ifd_gempc_register();
35 | ifd_ikey2k_register();
36 | ifd_ikey3k_register();
37 | ifd_kaan_register();
38 | ifd_pertosmart_ac1030_register();
39 | ifd_pertosmart_ac1038_register();
40 | ifd_smartboard_register();
41 | ifd_smph_register();
42 | ifd_starkey_register();
43 | ifd_towitoko_register();
44 | ifd_rutoken_register();
45 | /* ifd_wbeiuu_register(); driver not working yet */
46 | ifd_cyberjack_register();
47 | /* ccid last */
48 | ifd_ccid_register();
49 |
50 | /* Register all builtin protocols */
51 | ifd_protocol_register(&ifd_protocol_t0);
52 | ifd_protocol_register(&ifd_protocol_t1);
53 | ifd_protocol_register(&ifd_protocol_gbp);
54 | ifd_protocol_register(&ifd_protocol_trans);
55 | ifd_protocol_register(&ifd_protocol_i2c_short);
56 | ifd_protocol_register(&ifd_protocol_i2c_long);
57 | ifd_protocol_register(&ifd_protocol_2wire);
58 | ifd_protocol_register(&ifd_protocol_3wire);
59 | ifd_protocol_register(&ifd_protocol_eurochip);
60 | ifd_protocol_register(&ifd_protocol_esc);
61 |
62 | if (ifd_conf_get_integer("debug", &ival) >= 0 && ival > ct_config.debug)
63 | ct_config.debug = ival;
64 |
65 | if (ifd_conf_get_string("ifdhandler.program", &sval) >= 0)
66 | ct_config.ifdhandler = sval;
67 |
68 | /* Register all driver information (use hotplug ids) */
69 | n = ifd_conf_get_nodes("driver", NULL, 0);
70 | if (n >= 0) {
71 | nodes = (ifd_conf_node_t **) calloc(n, sizeof(*nodes));
72 | if (!nodes) {
73 | ct_error("out of memory");
74 | return 1;
75 | }
76 | n = ifd_conf_get_nodes("driver", nodes, n);
77 | for (i = 0; i < n; i++) {
78 | if (configure_driver(nodes[i])) {
79 | free(nodes);
80 | return 1;
81 | }
82 | }
83 | free(nodes);
84 | }
85 | return 0;
86 | }
87 |
88 | /*
89 | * Configure a reader driver
90 | */
91 | static int configure_driver(ifd_conf_node_t * cf)
92 | {
93 | const char *driver;
94 | char **ids;
95 | int j, n;
96 |
97 | if (!(driver = cf->value))
98 | return 1;
99 | if ((n = ifd_conf_node_get_string_list(cf, "ids", NULL, 0)) >= 0) {
100 | ids = (char **)calloc(n, sizeof(char *));
101 | if (!ids) {
102 | ct_error("out of memory");
103 | return 1;
104 | }
105 | n = ifd_conf_node_get_string_list(cf, "ids", ids, n);
106 | for (j = 0; j < n; j++)
107 | ifd_driver_add_id(ids[j], driver);
108 | free(ids);
109 | }
110 | return 0;
111 | }
112 |
--------------------------------------------------------------------------------
/src/ifd/locks.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Locking functions - these are somewhat simplified
3 | * by the fact that we have one manager process per reader,
4 | * so we don't have to worry about different readers here,
5 | * just different slots.
6 | *
7 | * Copyright (C) 2003 Olaf Kirch
8 | *
9 | * FIXME - prevent denial of service from clients allocating
10 | * huge numbers of locks. There should be a maximum of one shared
11 | * and one exclusive lock per client.
12 | */
13 |
14 | #include "internal.h"
15 | #include
16 | #include "ifdhandler.h"
17 |
18 | typedef struct ct_lock {
19 | struct ct_lock *next;
20 | unsigned int slot;
21 | uid_t uid;
22 | ct_lock_handle handle;
23 | ct_socket_t *owner;
24 | int exclusive;
25 | } ct_lock_t;
26 |
27 | static ct_lock_t *locks;
28 | static unsigned int lock_handle = 0;
29 |
30 | /*
31 | * Try to establish a lock
32 | */
33 | int ifdhandler_lock(ct_socket_t * sock, int slot, int type,
34 | ct_lock_handle * res)
35 | {
36 | ct_lock_t *l;
37 | int rc;
38 |
39 | /* See if we have a locking conflict */
40 | if ((rc = ifdhandler_check_lock(sock, slot, type)) < 0)
41 | return rc;
42 |
43 | /* No conflict - grant lock and record this fact */
44 | l = (ct_lock_t *) calloc(1, sizeof(*l));
45 | if (!l) {
46 | ct_error("out of memory");
47 | return IFD_ERROR_NO_MEMORY;
48 | }
49 | l->exclusive = (type == IFD_LOCK_EXCLUSIVE);
50 | l->uid = sock->client_uid;
51 | l->handle = lock_handle++;
52 | l->owner = sock;
53 | l->slot = slot;
54 |
55 | l->next = locks;
56 | locks = l;
57 |
58 | ifd_debug(1, "granted %s lock %u for slot %u by uid=%u",
59 | l->exclusive ? "excl" : "shared", l->handle, l->slot, l->uid);
60 |
61 | *res = l->handle;
62 | return 0;
63 | }
64 |
65 | /*
66 | * Check if a slot is locked by someone else
67 | */
68 | int ifdhandler_check_lock(ct_socket_t * sock, int slot, int type)
69 | {
70 | ct_lock_t *l;
71 |
72 | for (l = locks; l; l = l->next) {
73 | if (l->slot != slot)
74 | continue;
75 |
76 | if (l->owner == sock)
77 | continue;
78 |
79 | if (l->exclusive
80 | || type == IFD_LOCK_EXCLUSIVE || l->uid != sock->client_uid)
81 | return IFD_ERROR_LOCKED;
82 | }
83 |
84 | return 0;
85 | }
86 |
87 | /*
88 | * Release a lock
89 | */
90 | int ifdhandler_unlock(ct_socket_t * sock, int slot, ct_lock_handle handle)
91 | {
92 | ct_lock_t *l, **lp;
93 |
94 | for (lp = &locks; (l = *lp) != NULL; lp = &l->next) {
95 | if (l->owner == sock && l->slot == slot && l->handle == handle) {
96 | ifd_debug(1,
97 | "released %s lock %u for slot %u by uid=%u",
98 | l->exclusive ? "excl" : "shared",
99 | l->handle, l->slot, l->uid);
100 |
101 | *lp = l->next;
102 | free(l);
103 | return 0;
104 | }
105 | }
106 |
107 | return IFD_ERROR_NOLOCK;
108 | }
109 |
110 | /*
111 | * Release all locks held by a client
112 | * (called when the client socket is closed)
113 | */
114 | void ifdhandler_unlock_all(ct_socket_t * sock)
115 | {
116 | ct_lock_t *l, **lp;
117 |
118 | lp = &locks;
119 | while ((l = *lp) != NULL) {
120 | if (l->owner == sock) {
121 | ifd_debug(1,
122 | "released %s lock %u for slot %u by uid=%u",
123 | l->exclusive ? "excl" : "shared",
124 | l->handle, l->slot, l->uid);
125 | *lp = l->next;
126 | free(l);
127 | } else {
128 | lp = &l->next;
129 | }
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/src/ifd/manager.c:
--------------------------------------------------------------------------------
1 | /*
2 | * IFD manager
3 | *
4 | * Copyright (C) 2003, Olaf Kirch
5 | */
6 |
7 | #include "internal.h"
8 | #include
9 | #include
10 |
11 | static ifd_reader_t *ifd_readers[OPENCT_MAX_READERS];
12 | static unsigned int ifd_reader_handle = 1;
13 |
14 | /*
15 | * Return number of readers available
16 | */
17 | int ifd_reader_count(void)
18 | {
19 | return OPENCT_MAX_READERS;
20 | }
21 |
22 | /*
23 | * Register a reader
24 | */
25 | int ifd_attach(ifd_reader_t * reader)
26 | {
27 | unsigned int slot;
28 |
29 | if (!reader)
30 | return -1;
31 | if (reader->num)
32 | return 0;
33 |
34 | for (slot = 0; slot < OPENCT_MAX_READERS; slot++) {
35 | if (!ifd_readers[slot])
36 | break;
37 | }
38 |
39 | if (slot >= OPENCT_MAX_READERS) {
40 | ct_error("Too many readers");
41 | return -1;
42 | }
43 |
44 | reader->handle = ifd_reader_handle++;
45 | reader->num = slot;
46 | ifd_readers[slot] = reader;
47 |
48 | return 0;
49 | }
50 |
51 | /*
52 | * Functions to look up registered readers
53 | */
54 | ifd_reader_t *ifd_reader_by_handle(unsigned int handle)
55 | {
56 | ifd_reader_t *reader;
57 | unsigned int i;
58 |
59 | for (i = 0; i < OPENCT_MAX_READERS; i++) {
60 | if ((reader = ifd_readers[i])
61 | && reader->handle == handle)
62 | return reader;
63 | }
64 | return NULL;
65 | }
66 |
67 | ifd_reader_t *ifd_reader_by_index(unsigned int idx)
68 | {
69 | ifd_reader_t *reader;
70 |
71 | if (idx >= OPENCT_MAX_READERS) {
72 | ct_error("ifd_reader_by_index: invalid index %u", idx);
73 | return NULL;
74 | }
75 | if (!(reader = ifd_readers[idx]))
76 | return NULL;
77 |
78 | return reader;
79 | }
80 |
81 | /*
82 | * Unregister a reader
83 | */
84 | void ifd_detach(ifd_reader_t * reader)
85 | {
86 | unsigned int slot;
87 |
88 | if (reader->num == 0)
89 | return;
90 |
91 | if ((slot = reader->num) >= OPENCT_MAX_READERS
92 | || ifd_readers[slot] != reader) {
93 | ct_error("ifd_detach: unknown reader");
94 | return;
95 | }
96 |
97 | ifd_readers[slot] = NULL;
98 | }
99 |
--------------------------------------------------------------------------------
/src/ifd/modules.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Module handling
3 | *
4 | * Copyright (C) 2003 Olaf Kirch
5 | */
6 |
7 | #include "internal.h"
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | static const char *ifd_module_path(const char *subdir)
16 | {
17 | static char path[PATH_MAX];
18 |
19 | if (!ct_config.modules_dir
20 | && !(ct_config.modules_dir = getenv("IFD_MODULES")))
21 | ct_config.modules_dir = OPENCT_MODULES_PATH;
22 |
23 | snprintf(path, sizeof(path), "%s/%ss", ct_config.modules_dir, subdir);
24 | return path;
25 | }
26 |
27 | int ifd_load_module(const char *type, const char *name)
28 | {
29 | const char *dirname;
30 | char path[PATH_MAX];
31 | lt_dlhandle handle;
32 | void (*init_func) (void);
33 |
34 | if (strstr(name, "..")) {
35 | ct_error("Illegal module path \"%s\"", name);
36 | return -1;
37 | }
38 |
39 | if (!strcmp(type, "driver")) {
40 | dirname = ct_config.driver_modules_dir;
41 | } else if (!strcmp(type, "protocol")) {
42 | dirname = ct_config.protocol_modules_dir;
43 | } else {
44 | ct_error("Unknown module type \"%s\"", type);
45 | return -1;
46 | }
47 |
48 | if (!dirname)
49 | dirname = ifd_module_path(type);
50 |
51 | #if defined(HAVE_DLFCN_H) && defined(__APPLE__)
52 | snprintf(path, sizeof(path), "%s/%s.so", dirname, name);
53 | #elif defined(__APPLE__)
54 | snprintf(path, sizeof(path), "%s/%s.bundle", dirname, name);
55 | #else
56 | snprintf(path, sizeof(path), "%s/%s.so", dirname, name);
57 | #endif
58 |
59 | handle = lt_dlopen(path);
60 | if (!handle) {
61 | ct_error("Failed to load %s: %s", path, lt_dlerror());
62 | return -1;
63 | }
64 |
65 | init_func = (void (*)(void))lt_dlsym(handle, "ifd_init_module");
66 | if (!init_func) {
67 | ct_error("%s: no function called ifd_init_module", path);
68 | lt_dlclose(handle);
69 | return -1;
70 | }
71 |
72 | init_func();
73 | return 0;
74 | }
75 |
--------------------------------------------------------------------------------
/src/ifd/pcmcia-block.c:
--------------------------------------------------------------------------------
1 | /*
2 | * I/O routines for pcmcia devices
3 | *
4 | * Copyright (C) 2003 Olaf Kirch
5 | * Copyright (C) 2005 Harald Welte
6 | */
7 |
8 | #include "internal.h"
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 |
18 | /*
19 | * Input/output routines
20 | */
21 | static int
22 | ifd_pcmcia_block_send(ifd_device_t * dev, const unsigned char *buffer,
23 | size_t len)
24 | {
25 | size_t total = len;
26 | int n;
27 |
28 | while (len) {
29 | n = write(dev->fd, buffer, len);
30 | if (n < 0) {
31 | ct_error("Error writing to %s: %m", dev->name);
32 | return -1;
33 | }
34 | buffer += n;
35 | len -= n;
36 | }
37 |
38 | return total;
39 | }
40 |
41 | static int
42 | ifd_pcmcia_block_recv(ifd_device_t * dev, unsigned char *buffer, size_t len,
43 | long timeout)
44 | {
45 | struct timeval begin;
46 | int n;
47 |
48 | struct pollfd pfd;
49 | long wait;
50 |
51 | gettimeofday(&begin, NULL);
52 |
53 | if ((wait = timeout - ifd_time_elapsed(&begin)) < 0)
54 | goto timeout;
55 |
56 | pfd.fd = dev->fd;
57 | pfd.events = POLLIN;
58 | n = poll(&pfd, 1, wait);
59 | if (n < 0) {
60 | ct_error("%s: error while waiting for input: %m", dev->name);
61 | return -1;
62 | }
63 | if (n == 0)
64 | goto timeout;
65 |
66 | n = read(dev->fd, buffer, len);
67 | if (n < 0) {
68 | ct_error("%s: failed to read from device: %m", dev->name);
69 | return -1;
70 | }
71 | if (ct_config.debug >= 9)
72 | ifd_debug(9, "pcmcia recv:%s", ct_hexdump(buffer, n));
73 |
74 | return n;
75 |
76 | timeout: /* Timeouts are a little special; they may happen e.g.
77 | * when trying to obtain the ATR */
78 | if (!ct_config.suppress_errors)
79 | ct_error("%s: timed out while waiting for input", dev->name);
80 | return IFD_ERROR_TIMEOUT;
81 | }
82 |
83 | /*
84 | * Set pcmcia params
85 | */
86 | static int ifd_pcmcia_block_set_params(ifd_device_t * dev,
87 | const ifd_device_params_t * params)
88 | {
89 | /* nothing to do so far */
90 | dev->settings = *params;
91 | return 0;
92 | }
93 |
94 | /*
95 | * Close the device
96 | */
97 | static void ifd_pcmcia_block_close(ifd_device_t * dev)
98 | {
99 | if (dev->fd >= 0)
100 | close(dev->fd);
101 | dev->fd = -1;
102 | }
103 |
104 | static struct ifd_device_ops ifd_pcmcia_block_ops;
105 |
106 | /*
107 | * Open serial device
108 | */
109 | ifd_device_t *ifd_open_pcmcia_block(const char *name)
110 | {
111 | ifd_device_t *dev;
112 | int fd;
113 |
114 | if ((fd = open(name, O_RDWR)) < 0) {
115 | ct_error("Unable to open %s: %m", name);
116 | return NULL;
117 | }
118 |
119 | ifd_pcmcia_block_ops.send = ifd_pcmcia_block_send;
120 | ifd_pcmcia_block_ops.recv = ifd_pcmcia_block_recv;
121 | ifd_pcmcia_block_ops.set_params = ifd_pcmcia_block_set_params;
122 | ifd_pcmcia_block_ops.close = ifd_pcmcia_block_close;
123 |
124 | dev = ifd_device_new(name, &ifd_pcmcia_block_ops, sizeof(*dev));
125 | dev->timeout = 1000; /* acceptable? */
126 | dev->type = IFD_DEVICE_TYPE_PCMCIA_BLOCK;
127 | dev->fd = fd;
128 |
129 | return dev;
130 | }
131 |
--------------------------------------------------------------------------------
/src/ifd/pcmcia.c:
--------------------------------------------------------------------------------
1 | /*
2 | * I/O routines for pcmcia devices
3 | *
4 | * Copyright (C) 2003 Olaf Kirch
5 | * Copyright (C) 2005 Harald Welte
6 | */
7 |
8 | #include "internal.h"
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 |
18 | /*
19 | * Input/output routines
20 | */
21 | static int ifd_pcmcia_send(ifd_device_t * dev, const unsigned char *buffer,
22 | size_t len)
23 | {
24 | size_t total = len;
25 | int n;
26 |
27 | while (len) {
28 | n = write(dev->fd, buffer, len);
29 | if (n < 0) {
30 | ct_error("Error writing to %s: %m", dev->name);
31 | return -1;
32 | }
33 | buffer += n;
34 | len -= n;
35 | }
36 |
37 | return total;
38 | }
39 |
40 | static int ifd_pcmcia_recv(ifd_device_t * dev, unsigned char *buffer,
41 | size_t len, long timeout)
42 | {
43 | size_t total = len, to_read;
44 | struct timeval begin;
45 | int n;
46 |
47 | gettimeofday(&begin, NULL);
48 |
49 | while (len) {
50 | struct pollfd pfd;
51 | long wait;
52 |
53 | if ((wait = timeout - ifd_time_elapsed(&begin)) < 0)
54 | goto timeout;
55 |
56 | pfd.fd = dev->fd;
57 | pfd.events = POLLIN;
58 | n = poll(&pfd, 1, wait);
59 | if (n < 0) {
60 | ct_error("%s: error while waiting for input: %m",
61 | dev->name);
62 | return -1;
63 | }
64 | if (n == 0)
65 | continue;
66 |
67 | to_read = len;
68 |
69 | n = read(dev->fd, buffer, to_read);
70 | if (n < 0) {
71 | ct_error("%s: failed to read from device: %m",
72 | dev->name);
73 | return -1;
74 | }
75 | if (ct_config.debug >= 9)
76 | ifd_debug(9, "pcmcia recv:%s", ct_hexdump(buffer, n));
77 | buffer += n;
78 | len -= n;
79 | }
80 |
81 | return total;
82 |
83 | timeout: /* Timeouts are a little special; they may happen e.g.
84 | * when trying to obtain the ATR */
85 | if (!ct_config.suppress_errors)
86 | ct_error("%s: timed out while waiting for input", dev->name);
87 | ifd_debug(9, "(%u bytes received so far)", total - len);
88 | return IFD_ERROR_TIMEOUT;
89 | }
90 |
91 | /*
92 | * Set pcmcia params
93 | */
94 | static int ifd_pcmcia_set_params(ifd_device_t * dev,
95 | const ifd_device_params_t * params)
96 | {
97 | /* nothing to do so far */
98 | dev->settings = *params;
99 | return 0;
100 | }
101 |
102 | /*
103 | * Close the device
104 | */
105 | static void ifd_pcmcia_close(ifd_device_t * dev)
106 | {
107 | if (dev->fd >= 0)
108 | close(dev->fd);
109 | dev->fd = -1;
110 | }
111 |
112 | static struct ifd_device_ops ifd_pcmcia_ops;
113 |
114 | /*
115 | * Open serial device
116 | */
117 | ifd_device_t *ifd_open_pcmcia(const char *name)
118 | {
119 | ifd_device_t *dev;
120 | int fd;
121 |
122 | if ((fd = open(name, O_RDWR)) < 0) {
123 | ct_error("Unable to open %s: %m", name);
124 | return NULL;
125 | }
126 |
127 | ifd_pcmcia_ops.send = ifd_pcmcia_send;
128 | ifd_pcmcia_ops.recv = ifd_pcmcia_recv;
129 | ifd_pcmcia_ops.set_params = ifd_pcmcia_set_params;
130 | ifd_pcmcia_ops.close = ifd_pcmcia_close;
131 |
132 | dev = ifd_device_new(name, &ifd_pcmcia_ops, sizeof(*dev));
133 | dev->timeout = 1000; /* acceptable? */
134 | dev->type = IFD_DEVICE_TYPE_PCMCIA;
135 | dev->fd = fd;
136 |
137 | return dev;
138 | }
139 |
--------------------------------------------------------------------------------
/src/ifd/proto-escape.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Escape protocol - simply pass everything to the reader driver's escape()
3 | *
4 | * This is required for exporting access to vendor-specific CCID extensions,
5 | * such as the Omnikey CardMan 5121 RFID support.
6 | *
7 | * The higher-level applications select a virtual slot (the last available slot
8 | * number). This virtual slot will automatically get the IFD_PROTOCOL_ESCAPE
9 | * assgigned to it and can then be used to transceive() data to/from the CCID.
10 | *
11 | * It's a bit ugly, but I was unable to come up with something cleaner.
12 | *
13 | * Copyright (C) 2005, Harald Welte
14 | */
15 |
16 | #include "internal.h"
17 | #include
18 | #include
19 | #include
20 |
21 | static int escape_init(ifd_protocol_t * prot)
22 | {
23 | ifd_reader_t *reader = prot->reader;
24 | const ifd_driver_t *drv;
25 |
26 | if (!reader || !(drv = reader->driver)
27 | || !drv->ops || !drv->ops->escape)
28 | return -1;
29 | return 0;
30 | }
31 |
32 | static void escape_release(ifd_protocol_t * prot)
33 | {
34 | /* NOP */
35 | }
36 |
37 | static int escape_set_param(ifd_protocol_t * prot, int type, long value)
38 | {
39 | ct_error("set_pameter not supported");
40 | return -1;
41 | }
42 |
43 | static int escape_get_param(ifd_protocol_t * prot, int type, long *result)
44 | {
45 | ct_error("get_pameter not supported");
46 | return -1;
47 | }
48 |
49 | static int
50 | escape_transceive(ifd_protocol_t * prot, int dad,
51 | const void *sbuf, size_t slen, void *rbuf, size_t rlen)
52 | {
53 | ifd_reader_t *reader = prot->reader;
54 | const ifd_driver_t *drv = reader->driver;
55 |
56 | return drv->ops->escape(reader, dad, sbuf, slen, rbuf, rlen);
57 | }
58 |
59 | struct ifd_protocol_ops ifd_protocol_esc = {
60 | IFD_PROTOCOL_ESCAPE, /* id */
61 | "escape", /* name */
62 | sizeof(ifd_protocol_t), /* size */
63 | escape_init, /* init */
64 | escape_release, /* release */
65 | escape_set_param, /* set_param */
66 | escape_get_param, /* get_param */
67 | NULL, /* resynchronize */
68 | escape_transceive, /* transceive */
69 | NULL, /* sync_read */
70 | NULL, /* sync_write */
71 | };
72 |
--------------------------------------------------------------------------------
/src/ifd/proto-trans.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Transparent protocol - simply pass everything to the reader driver
3 | *
4 | * Copyright (C) 2003, Olaf Kirch
5 | */
6 |
7 | #include "internal.h"
8 | #include
9 | #include
10 | #include
11 |
12 | /*
13 | * Attach t0 protocol
14 | */
15 | static int trans_init(ifd_protocol_t * prot)
16 | {
17 | ifd_reader_t *reader = prot->reader;
18 | const ifd_driver_t *drv;
19 |
20 | if (!reader || !(drv = reader->driver)
21 | || !drv->ops || !drv->ops->transparent)
22 | return -1;
23 | return 0;
24 | }
25 |
26 | /*
27 | * Detach t0 protocol
28 | */
29 | static void trans_release(ifd_protocol_t * prot)
30 | {
31 | /* NOP */
32 | }
33 |
34 | /*
35 | * Get/set parmaters for T1 protocol
36 | */
37 | static int trans_set_param(ifd_protocol_t * prot, int type, long value)
38 | {
39 | ct_error("set_pameter not supported");
40 | return -1;
41 | }
42 |
43 | static int trans_get_param(ifd_protocol_t * prot, int type, long *result)
44 | {
45 | ct_error("get_pameter not supported");
46 | return -1;
47 | }
48 |
49 | /*
50 | * Transceive an APDU
51 | */
52 | static int trans_transceive(ifd_protocol_t * prot, int dad, const void *sbuf,
53 | size_t slen, void *rbuf, size_t rlen)
54 | {
55 | ifd_reader_t *reader = prot->reader;
56 | const ifd_driver_t *drv = reader->driver;
57 |
58 | return drv->ops->transparent(reader, dad, sbuf, slen, rbuf, rlen);
59 | }
60 |
61 | /*
62 | * Protocol struct
63 | */
64 | struct ifd_protocol_ops ifd_protocol_trans = {
65 | IFD_PROTOCOL_TRANSPARENT, /* id */
66 | "transparent", /* name */
67 | sizeof(ifd_protocol_t), /* size */
68 | trans_init, /* init */
69 | trans_release, /* release */
70 | trans_set_param, /* set_param */
71 | trans_get_param, /* get_param */
72 | NULL, /* resynchronize */
73 | trans_transceive, /* transceive */
74 | NULL, /* sync_read */
75 | NULL, /* sync_write */
76 | };
77 |
--------------------------------------------------------------------------------
/src/ifd/ria.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Access to remote IFD handlers
3 | *
4 | * Copyright (C) 2003, Olaf Kirch
5 | */
6 |
7 | #ifndef IFD_REMOTE_H
8 | #define IFD_REMOTE_H
9 |
10 | typedef struct ria_client {
11 | /* Socket for communication with ifdproxy */
12 | ct_socket_t *sock;
13 | uint32_t xid;
14 |
15 | /* queue for buffering data */
16 | ct_buf_t data;
17 |
18 | /* application data */
19 | void *user_data;
20 | } ria_client_t;
21 |
22 | #define RIA_NAME_MAX 32
23 | typedef struct ria_device {
24 | char address[RIA_NAME_MAX];
25 | char type[RIA_NAME_MAX / 2];
26 | char handle[RIA_NAME_MAX];
27 | char name[RIA_NAME_MAX];
28 | } ria_device_t;
29 |
30 | typedef struct ria_serial_conf {
31 | uint32_t speed;
32 | uint8_t bits;
33 | uint8_t stopbits;
34 | uint8_t parity;
35 | uint8_t check_parity;
36 | uint8_t dtr;
37 | uint8_t rts;
38 | } ria_serial_conf_t;
39 |
40 | enum {
41 | /* These are for the manager only */
42 | RIA_MGR_LIST = 0x00,
43 | RIA_MGR_INFO,
44 | RIA_MGR_CLAIM,
45 | RIA_MGR_REGISTER,
46 |
47 | __RIA_PEER_CMD_BASE = 0x10,
48 | RIA_RESET_DEVICE = 0x10,
49 | RIA_FLUSH_DEVICE,
50 | RIA_SEND_BREAK,
51 | RIA_SERIAL_GET_CONFIG,
52 | RIA_SERIAL_SET_CONFIG,
53 |
54 | RIA_DATA = 0x80
55 | };
56 |
57 | extern ria_client_t *ria_connect(const char *);
58 | extern void ria_free(ria_client_t *);
59 | extern int ria_send(ria_client_t *, unsigned char, const void *, size_t);
60 | extern int ria_command(ria_client_t *, unsigned char,
61 | const void *, size_t, void *, size_t, long timeout);
62 |
63 | extern int ria_svc_listen(const char *, int);
64 | extern ria_client_t *ria_export_device(const char *, const char *);
65 | extern int ria_register_device(ria_client_t *, const char *);
66 | extern void ria_print_packet(ct_socket_t *, int,
67 | const char *, header_t *, ct_buf_t *);
68 |
69 | #endif /* IFD_REMOTE_H */
70 |
--------------------------------------------------------------------------------
/src/ifd/sys-null.c:
--------------------------------------------------------------------------------
1 | /*
2 | * A void implementation for any platform
3 | *
4 | * Copyright (C) 2003 Olaf Kirch
5 | *
6 | * These functions need to be re-implemented for every
7 | * new platform.
8 | */
9 |
10 | #include "internal.h"
11 | #if !defined(sun) && !defined (__NetBSD__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__FreeBSD_kernel__) && !defined(__linux__) && !defined(__APPLE__) && !defined(__DragonFly__)
12 | #include
13 | #include
14 | #include
15 |
16 | /*
17 | * USB handling
18 | */
19 | int ifd_sysdep_usb_poll_presence(ifd_device_t * dev, struct pollfd *pfd)
20 | {
21 | #if 0
22 | if (pfd->revents & POLLHUP)
23 | return 0;
24 | pfd->fd = dev->fd;
25 | pfd->events = POLLHUP;
26 | return 1;
27 | #else
28 | return -1;
29 | #endif
30 | }
31 |
32 | int ifd_sysdep_usb_get_eventfd(ifd_device_t * dev, short *events)
33 | {
34 | return -1;
35 | }
36 |
37 | int ifd_sysdep_usb_control(ifd_device_t * dev, unsigned int requesttype,
38 | unsigned int request, unsigned int value,
39 | unsigned int index, void *data, size_t len,
40 | long timeout)
41 | {
42 | return -1;
43 | }
44 |
45 | int ifd_sysdep_usb_set_configuration(ifd_device_t * dev, int config)
46 | {
47 | return -1;
48 | }
49 |
50 | int ifd_sysdep_usb_set_interface(ifd_device_t * dev, int ifc, int alt)
51 | {
52 | return -1;
53 | }
54 |
55 | int ifd_sysdep_usb_claim_interface(ifd_device_t * dev, int interface)
56 | {
57 | return -1;
58 | }
59 |
60 | int ifd_sysdep_usb_release_interface(ifd_device_t * dev, int interface)
61 | {
62 | return -1;
63 | }
64 |
65 | /*
66 | * USB bulk transfer
67 | */
68 | int ifd_sysdep_usb_bulk(ifd_device_t * dev, int ep, void *buffer, size_t len,
69 | long timeout)
70 | {
71 | return -1;
72 | }
73 |
74 | /*
75 | * USB URB capture
76 | */
77 | struct ifd_usb_capture {
78 | int type;
79 | int endpoint;
80 | size_t maxpacket;
81 | unsigned int interface;
82 | };
83 |
84 | int ifd_sysdep_usb_begin_capture(ifd_device_t * dev, int type, int endpoint,
85 | size_t maxpacket, ifd_usb_capture_t ** capret)
86 | {
87 | return -1;
88 | }
89 |
90 | int ifd_sysdep_usb_capture_event(ifd_device_t * dev, ifd_usb_capture_t * cap,
91 | void *buffer, size_t len)
92 | {
93 | return IFD_ERROR_NOT_SUPPORTED;
94 | }
95 |
96 | int ifd_sysdep_usb_capture(ifd_device_t * dev, ifd_usb_capture_t * cap,
97 | void *buffer, size_t len, long timeout)
98 | {
99 | return -1;
100 | }
101 |
102 | int ifd_sysdep_usb_end_capture(ifd_device_t * dev, ifd_usb_capture_t * cap)
103 | {
104 | return -1;
105 | }
106 |
107 | int ifd_sysdep_usb_open(const char *device)
108 | {
109 | return -1;
110 | }
111 |
112 | int ifd_sysdep_usb_reset(ifd_device_t * dev)
113 | {
114 | return -1;
115 | }
116 |
117 | /*
118 | * Scan all usb devices to see if there is one we support
119 | */
120 | int ifd_scan_usb(void)
121 | {
122 | return 0;
123 | }
124 |
125 | #endif
126 |
--------------------------------------------------------------------------------
/src/ifd/sys-osx.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Mac OS X specific implementation - TO BE DONE
3 | *
4 | * Copyright (C) 2003 Olaf Kirch
5 | *
6 | */
7 |
8 | #include "internal.h"
9 | #if defined(__APPLE__)
10 | #include
11 | #include
12 | #include
13 |
14 | /*
15 | * USB handling
16 | */
17 | int ifd_sysdep_usb_poll_presence(ifd_device_t * dev, struct pollfd *pfd)
18 | {
19 | return -1;
20 | }
21 |
22 | int ifd_sysdep_usb_get_eventfd(ifd_device_t * dev, short *events)
23 | {
24 | return -1;
25 | }
26 |
27 | int ifd_sysdep_usb_control(ifd_device_t * dev, unsigned int requesttype,
28 | unsigned int request, unsigned int value,
29 | unsigned int index, void *data, size_t len,
30 | long timeout)
31 | {
32 | return -1;
33 | }
34 |
35 | int ifd_sysdep_usb_set_configuration(ifd_device_t * dev, int config)
36 | {
37 | return -1;
38 | }
39 |
40 | int ifd_sysdep_usb_set_interface(ifd_device_t * dev, int ifc, int alt)
41 | {
42 | return -1;
43 | }
44 |
45 | int ifd_sysdep_usb_claim_interface(ifd_device_t * dev, int interface)
46 | {
47 | return -1;
48 | }
49 |
50 | int ifd_sysdep_usb_release_interface(ifd_device_t * dev, int interface)
51 | {
52 | return -1;
53 | }
54 |
55 | /*
56 | * USB bulk transfer
57 | */
58 | int ifd_sysdep_usb_bulk(ifd_device_t * dev, int ep, void *buffer, size_t len,
59 | long timeout)
60 | {
61 | return -1;
62 | }
63 |
64 | /*
65 | * USB URB capture
66 | */
67 | struct ifd_usb_capture {
68 | int type;
69 | int endpoint;
70 | size_t maxpacket;
71 | unsigned int interface;
72 | };
73 |
74 | int ifd_sysdep_usb_begin_capture(ifd_device_t * dev, int type, int endpoint,
75 | size_t maxpacket, ifd_usb_capture_t ** capret)
76 | {
77 | return -1;
78 | }
79 |
80 | int ifd_sysdep_usb_capture_event(ifd_device_t * dev, ifd_usb_capture_t * cap,
81 | void *buffer, size_t len)
82 | {
83 | return IFD_ERROR_NOT_SUPPORTED;
84 | }
85 |
86 | int ifd_sysdep_usb_capture(ifd_device_t * dev, ifd_usb_capture_t * cap,
87 | void *buffer, size_t len, long timeout)
88 | {
89 | return -1;
90 | }
91 |
92 | int ifd_sysdep_usb_end_capture(ifd_device_t * dev, ifd_usb_capture_t * cap)
93 | {
94 | return -1;
95 | }
96 |
97 | int ifd_sysdep_usb_open(const char *device)
98 | {
99 | return -1;
100 | }
101 |
102 | int ifd_sysdep_usb_reset(ifd_device_t * dev)
103 | {
104 | return -1;
105 | }
106 |
107 | /*
108 | * Scan all usb devices to see if there is one we support
109 | */
110 | int ifd_scan_usb(void)
111 | {
112 | return 0;
113 | }
114 |
115 | #endif
116 |
--------------------------------------------------------------------------------
/src/ifd/usb-descriptors.h:
--------------------------------------------------------------------------------
1 | /*
2 | * USB Descriptor parsing functions
3 | *
4 | * Copyright (c) 2000-2001 Johannes Erdfelt
5 | * Copyright 2003, Chaskiel Grundman
6 | *
7 | * This header file is purely internal to OpenCT.
8 | */
9 | #ifndef __USB_DESCRIPTORS_H__
10 | #define __USB_DESCRIPTORS_H__
11 |
12 | #include
13 |
14 | /*
15 | * Descriptor types
16 | */
17 | #define IFD_USB_DT_DEVICE 0x01
18 | #define IFD_USB_DT_CONFIG 0x02
19 | #define IFD_USB_DT_STRING 0x03
20 | #define IFD_USB_DT_INTERFACE 0x04
21 | #define IFD_USB_DT_ENDPOINT 0x05
22 |
23 | /*
24 | * Descriptor sizes per descriptor type
25 | */
26 | #define IFD_USB_DT_DEVICE_SIZE 18
27 | #define IFD_USB_DT_CONFIG_SIZE 9
28 | #define IFD_USB_DT_INTERFACE_SIZE 9
29 | #define IFD_USB_DT_ENDPOINT_SIZE 7
30 | #define IFD_USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */
31 | #define IFD_USB_DT_HUB_NONVAR_SIZE 7
32 |
33 | struct ifd_usb_descriptor_header {
34 | uint8_t bLength;
35 | uint8_t bDescriptorType;
36 | };
37 |
38 | /* String descriptor */
39 | struct ifd_usb_string_descriptor {
40 | uint8_t bLength;
41 | uint8_t bDescriptorType;
42 | uint16_t wData[1];
43 | };
44 |
45 | /* Endpoint descriptor */
46 | #define IFD_USB_MAXENDPOINTS 32
47 | struct ifd_usb_endpoint_descriptor {
48 | uint8_t bLength;
49 | uint8_t bDescriptorType;
50 | uint8_t bEndpointAddress;
51 | uint8_t bmAttributes;
52 | uint16_t wMaxPacketSize;
53 | uint8_t bInterval;
54 | uint8_t bRefresh;
55 | uint8_t bSynchAddress;
56 |
57 | unsigned char *extra; /* Extra descriptors */
58 | int extralen;
59 | };
60 | #define IFD_USB_ENDPOINT_ADDRESS_MASK 0x0f /* in bEndpointAddress */
61 | #define IFD_USB_ENDPOINT_DIR_MASK 0x80
62 |
63 | #define IFD_USB_ENDPOINT_TYPE_MASK 0x03 /* in bmAttributes */
64 | #define IFD_USB_ENDPOINT_TYPE_CONTROL 0
65 | #define IFD_USB_ENDPOINT_TYPE_ISOCHRONOUS 1
66 | #define IFD_USB_ENDPOINT_TYPE_BULK 2
67 | #define IFD_USB_ENDPOINT_TYPE_INTERRUPT 3
68 |
69 | /* Interface descriptor */
70 | #define IFD_USB_MAXINTERFACES 32
71 | struct ifd_usb_interface_descriptor {
72 | uint8_t bLength;
73 | uint8_t bDescriptorType;
74 | uint8_t bInterfaceNumber;
75 | uint8_t bAlternateSetting;
76 | uint8_t bNumEndpoints;
77 | uint8_t bInterfaceClass;
78 | uint8_t bInterfaceSubClass;
79 | uint8_t bInterfaceProtocol;
80 | uint8_t iInterface;
81 |
82 | struct ifd_usb_endpoint_descriptor *endpoint;
83 |
84 | unsigned char *extra; /* Extra descriptors */
85 | int extralen;
86 | };
87 |
88 | #define IFD_USB_MAXALTSETTING 128 /* Hard limit */
89 | struct ifd_usb_interface {
90 | struct ifd_usb_interface_descriptor *altsetting;
91 |
92 | int num_altsetting;
93 | };
94 |
95 | /* Configuration descriptor information.. */
96 | #define IFD_USB_MAXCONFIG 8
97 | struct ifd_usb_config_descriptor {
98 | uint8_t bLength;
99 | uint8_t bDescriptorType;
100 | uint16_t wTotalLength;
101 | uint8_t bNumInterfaces;
102 | uint8_t bConfigurationValue;
103 | uint8_t iConfiguration;
104 | uint8_t bmAttributes;
105 | uint8_t MaxPower;
106 |
107 | struct ifd_usb_interface *interface;
108 |
109 | unsigned char *extra; /* Extra descriptors */
110 | int extralen;
111 | };
112 |
113 | /* Device descriptor */
114 | struct ifd_usb_device_descriptor {
115 | uint8_t bLength;
116 | uint8_t bDescriptorType;
117 | uint16_t bcdUSB;
118 | uint8_t bDeviceClass;
119 | uint8_t bDeviceSubClass;
120 | uint8_t bDeviceProtocol;
121 | uint8_t bMaxPacketSize0;
122 | uint16_t idVendor;
123 | uint16_t idProduct;
124 | uint16_t bcdDevice;
125 | uint8_t iManufacturer;
126 | uint8_t iProduct;
127 | uint8_t iSerialNumber;
128 | uint8_t bNumConfigurations;
129 | };
130 | #define IFD_USB_REQ_GET_DESCRIPTOR 0x06
131 |
132 | #define IFD_USB_TYPE_STANDARD (0x00 << 5)
133 | #define IFD_USB_TYPE_CLASS (0x01 << 5)
134 | #define IFD_USB_TYPE_VENDOR (0x02 << 5)
135 | #define IFD_USB_TYPE_RESERVED (0x03 << 5)
136 |
137 | #define IFD_USB_RECIP_DEVICE 0x00
138 | #define IFD_USB_RECIP_INTERFACE 0x01
139 | #define IFD_USB_RECIP_ENDPOINT 0x02
140 | #define IFD_USB_RECIP_OTHER 0x03
141 |
142 | #define IFD_USB_ENDPOINT_IN 0x80
143 | #define IFD_USB_ENDPOINT_OUT 0x00
144 |
145 | #define IFD_USB_LE16_TO_CPU(x) do { unsigned char *y=(unsigned char *)(&x); x = (y[1] << 8) | y[0] ; } while(0)
146 |
147 | extern int ifd_usb_get_device(ifd_device_t * dev,
148 | struct ifd_usb_device_descriptor *d);
149 |
150 | extern int ifd_usb_get_config(ifd_device_t * dev,
151 | int n, struct ifd_usb_config_descriptor *c);
152 | extern void ifd_usb_free_configuration(struct ifd_usb_config_descriptor *c);
153 |
154 | #endif
155 |
--------------------------------------------------------------------------------
/src/ifd/utils.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Utility functions
3 | *
4 | * Copyright (C) 2003, Olaf Kirch
5 | */
6 |
7 | #include "internal.h"
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | #ifndef __GNUC__
21 | void ifd_debug(int level, const char *fmt, ...)
22 | {
23 | va_list ap;
24 | char str[2048];
25 |
26 | va_start(ap, fmt);
27 | vsnprintf(str, sizeof(str), fmt, ap);
28 | if (level <= ct_config.debug)
29 | ct_debug(str);
30 | va_end(ap);
31 | }
32 | #endif
33 |
34 | unsigned int ifd_count_bits(unsigned int word)
35 | {
36 | static unsigned int bcount[16] = {
37 | 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
38 | };
39 | unsigned int num;
40 |
41 | for (num = 0; word; word >>= 4)
42 | num += bcount[word & 0xF];
43 | return num;
44 | }
45 |
46 | void ifd_revert_bits(unsigned char *data, size_t len)
47 | {
48 | unsigned char j, k, c, d;
49 |
50 | while (len--) {
51 | c = *data;
52 | for (j = 1, k = 0x80, d = 0; k != 0; j <<= 1, k >>= 1) {
53 | if (c & j)
54 | d |= k;
55 | }
56 | *data++ = d ^ 0xFF;
57 | }
58 | }
59 |
60 | #ifndef timersub
61 | # define timersub(a, b, result) \
62 | do { \
63 | (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
64 | (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
65 | if ((result)->tv_usec < 0) { \
66 | --(result)->tv_sec; \
67 | (result)->tv_usec += 1000000; \
68 | } \
69 | } while (0)
70 | #endif
71 |
72 | /* return time elapsed since "then" in miliseconds */
73 | long ifd_time_elapsed(struct timeval *then)
74 | {
75 | struct timeval now, delta;
76 |
77 | gettimeofday(&now, NULL);
78 | timersub(&now, then, &delta);
79 | return delta.tv_sec * 1000 + (delta.tv_usec / 1000);
80 | }
81 |
82 | /*
83 | * Spawn an ifdhandler
84 | */
85 | int ifd_spawn_handler(const char *driver, const char *devtype, int idx)
86 | {
87 | const char *argv[16];
88 | char reader[16], debug[10];
89 | char *type, *device;
90 | int argc, n;
91 | pid_t pid;
92 | char *user = NULL;
93 | int force_poll = 1;
94 |
95 | ifd_debug(1, "driver=%s, devtype=%s, index=%d", driver, devtype, idx);
96 |
97 | if ((pid = fork()) < 0) {
98 | ct_error("fork failed: %m");
99 | return 0;
100 | }
101 |
102 | if (pid != 0) {
103 | /* We're the parent process. The child process should
104 | * call daemon(), causing the process to exit
105 | * immediately after allocating a slot in the status
106 | * file. We wait for it here to make sure USB devices
107 | * don't claim a slot reserved for another device */
108 | waitpid(pid, NULL, 0);
109 | return 1;
110 | }
111 |
112 | argc = 0;
113 | argv[argc++] = ct_config.ifdhandler;
114 |
115 | if (idx >= 0) {
116 | snprintf(reader, sizeof(reader), "-r%u", idx);
117 | argv[argc++] = reader;
118 | } else {
119 | argv[argc++] = "-H";
120 | }
121 |
122 | if (ct_config.debug) {
123 | if ((n = ct_config.debug) > 6)
124 | n = 6;
125 | debug[n + 1] = '\0';
126 | while (n--)
127 | debug[n + 1] = 'd';
128 | debug[0] = '-';
129 | argv[argc++] = debug;
130 | }
131 |
132 | ifd_conf_get_bool("ifdhandler.force_poll", &force_poll);
133 | if (force_poll) {
134 | argv[argc++] = "-p";
135 | }
136 |
137 | type = strdup(devtype);
138 | device = strtok(type, ":");
139 | device = strtok(NULL, ":");
140 | if (!device || !type) {
141 | ct_error("failed to parse devtype %s", devtype);
142 | exit(1);
143 | }
144 |
145 | argv[argc++] = driver;
146 | argv[argc++] = type;
147 | argv[argc++] = device;
148 | argv[argc] = NULL;
149 |
150 | n = getdtablesize();
151 | while (--n > 2)
152 | close(n);
153 |
154 | if ((n = ifd_conf_get_string_list("ifdhandler.groups", NULL, 0)) > 0) {
155 | char **groups = (char **)calloc(n, sizeof(char *));
156 | gid_t *gids = (gid_t *)calloc(n, sizeof(gid_t));
157 | int j;
158 | if (!groups || !gids) {
159 | ct_error("out of memory");
160 | exit(1);
161 | }
162 | n = ifd_conf_get_string_list("ifdhandler.groups", groups, n);
163 | for (j = 0; j < n; j++) {
164 | struct group *g = getgrnam(groups[j]);
165 | if (g == NULL) {
166 | ct_error("failed to parse group %s", groups[j]);
167 | exit(1);
168 | }
169 | gids[j] = g->gr_gid;
170 | }
171 | if (setgroups(n-1, &gids[1]) == -1) {
172 | ct_error("failed set groups %m");
173 | exit(1);
174 | }
175 | if (setgid(gids[0]) == -1) {
176 | ct_error("failed setgid %d %m", gids[0]);
177 | exit(1);
178 | }
179 | free(groups);
180 | free(gids);
181 | }
182 |
183 | if (ifd_conf_get_string("ifdhandler.user", &user) >= 0) {
184 | struct passwd *p = getpwnam(user);
185 |
186 | if (p == NULL) {
187 | ct_error("failed to parse user %s", user);
188 | exit(1);
189 | }
190 |
191 | if (setuid(p->pw_uid) == -1) {
192 | ct_error("failed to set*uid user %s %m", user);
193 | exit(1);
194 | }
195 | }
196 |
197 | execv(ct_config.ifdhandler, (char **)argv);
198 | ct_error("failed to execute %s: %m", ct_config.ifdhandler);
199 | exit(1);
200 | }
201 |
202 | /*
203 | * Replacement for the BSD daemon() function
204 | */
205 | #ifndef HAVE_DAEMON
206 | int daemon(int nochdir, int noclose)
207 | {
208 | pid_t pid;
209 |
210 | pid = fork();
211 |
212 | /* In case of fork is error. */
213 | if (pid < 0)
214 | return -1;
215 |
216 | /* In case of this is parent process. */
217 | if (pid != 0)
218 | exit(0);
219 |
220 | /* Become session leader and get pid. */
221 | pid = setsid();
222 |
223 | if (pid < -1) {
224 | perror("setsid");
225 | return -1;
226 | }
227 |
228 | /* Change directory to root. */
229 | if (!nochdir)
230 | chdir("/");
231 |
232 | /* File descriptor close. */
233 | if (!noclose) {
234 | int fd;
235 |
236 | fd = open("/dev/null", O_RDWR, 0);
237 | if (fd != -1) {
238 | dup2(fd, STDIN_FILENO);
239 | dup2(fd, STDOUT_FILENO);
240 | dup2(fd, STDERR_FILENO);
241 | if (fd > 2)
242 | close(fd);
243 | }
244 | }
245 | umask(0027);
246 | return 0;
247 | }
248 | #endif
249 |
--------------------------------------------------------------------------------
/src/include/Makefile.am:
--------------------------------------------------------------------------------
1 | MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
2 |
3 | SUBDIRS = openct
4 |
--------------------------------------------------------------------------------
/src/include/openct/Makefile.am:
--------------------------------------------------------------------------------
1 | MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
2 | DISTCLEANFILES = types.h
3 |
4 | openctinclude_HEADERS = \
5 | apdu.h buffer.h conf.h device.h driver.h error.h ifd.h \
6 | logging.h openct.h path.h protocol.h server.h socket.h tlv.h
7 | nodist_openctinclude_HEADERS = $(builddir)/types.h
8 |
--------------------------------------------------------------------------------
/src/include/openct/apdu.h:
--------------------------------------------------------------------------------
1 | /*
2 | * APDU type definitions
3 | *
4 | * Copyright (C) 2003, Olaf Kirch
5 | */
6 |
7 | #ifndef OPENCT_APDU_H
8 | #define OPENCT_APDU_H
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | typedef struct ifd_iso_apdu {
15 | unsigned char cse, cla, ins, p1, p2;
16 | unsigned int lc, le;
17 | unsigned int sw;
18 | void * data;
19 | size_t len;
20 |
21 | /* xxx go away */
22 | unsigned char * rcv_buf;
23 | unsigned int rcv_len;
24 | } ifd_iso_apdu_t;
25 |
26 | enum {
27 | IFD_APDU_CASE_1 = 0x00,
28 | IFD_APDU_CASE_2S = 0x01,
29 | IFD_APDU_CASE_3S = 0x02,
30 | IFD_APDU_CASE_4S = 0x03,
31 | IFD_APDU_CASE_2E = 0x10,
32 | IFD_APDU_CASE_3E = 0x20,
33 | IFD_APDU_CASE_4E = 0x30,
34 |
35 | IFD_APDU_BAD = -1
36 | };
37 |
38 | #define IFD_APDU_CASE_LC(c) ((c) & 0x02)
39 | #define IFD_APDU_CASE_LE(c) ((c) & 0x01)
40 |
41 | extern int ifd_iso_apdu_parse(const void *, size_t, ifd_iso_apdu_t *);
42 | extern int ifd_apdu_case(const void *, size_t);
43 |
44 | #ifdef __cplusplus
45 | }
46 | #endif
47 |
48 | #endif /* OPENCT_APDU_H */
49 |
--------------------------------------------------------------------------------
/src/include/openct/buffer.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Buffer handling functions of the IFD handler library
3 | *
4 | * Copyright (C) 2003, Olaf Kirch
5 | */
6 |
7 | #ifndef OPENCT_BUFFER_H
8 | #define OPENCT_BUFFER_H
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | #include
15 |
16 | typedef struct ct_buf {
17 | unsigned char * base;
18 | unsigned int head, tail, size;
19 | unsigned int overrun;
20 | } ct_buf_t;
21 |
22 | extern void ct_buf_init(ct_buf_t *, void *, size_t);
23 | extern void ct_buf_set(ct_buf_t *, void *, size_t);
24 | extern void ct_buf_clear(ct_buf_t *);
25 | extern int ct_buf_get(ct_buf_t *, void *, size_t);
26 | extern int ct_buf_gets(ct_buf_t *, char *, size_t);
27 | extern int ct_buf_put(ct_buf_t *, const void *, size_t);
28 | extern int ct_buf_putc(ct_buf_t *, int);
29 | extern int ct_buf_puts(ct_buf_t *, const char *);
30 | extern int ct_buf_push(ct_buf_t *, const void *, size_t);
31 | extern unsigned int ct_buf_avail(ct_buf_t *);
32 | extern unsigned int ct_buf_tailroom(ct_buf_t *);
33 | extern unsigned int ct_buf_size(ct_buf_t *);
34 | extern void * ct_buf_head(ct_buf_t *);
35 | extern void * ct_buf_tail(ct_buf_t *);
36 | extern int ct_buf_read(ct_buf_t *, int);
37 | extern void ct_buf_compact(ct_buf_t *);
38 | extern int ct_buf_overrun(ct_buf_t *);
39 |
40 | #ifdef __cplusplus
41 | }
42 | #endif
43 |
44 | #endif /* OPENCT_BUFFER_H */
45 |
--------------------------------------------------------------------------------
/src/include/openct/conf.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Configuration stuff for IFD library
3 | *
4 | * Copyright (C) 2003, Olaf Kirch
5 | */
6 |
7 | #ifndef OPENCT_CONF_H
8 | #define OPENCT_CONF_H
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | extern struct ct_config {
15 | int debug;
16 | int autoload;
17 | int hotplug;
18 | int suppress_errors;
19 | const char * ifdhandler;
20 | const char * modules_dir;
21 | const char * driver_modules_dir;
22 | const char * protocol_modules_dir;
23 | const char * socket_dir;
24 | } ct_config;
25 |
26 | typedef struct ifd_conf_node {
27 | struct ifd_conf_node *next;
28 | struct ifd_conf_node *children;
29 | char * name;
30 | char * value;
31 | } ifd_conf_node_t;
32 |
33 | extern int ifd_config_parse(const char *);
34 | extern int ifd_conf_get_string(const char *, char **);
35 | extern int ifd_conf_get_integer(const char *, unsigned int *);
36 | extern int ifd_conf_get_bool(const char *, unsigned int *);
37 | extern int ifd_conf_get_string_list(const char *, char **, size_t);
38 | extern int ifd_conf_get_nodes(const char *, ifd_conf_node_t **, size_t);
39 | extern int ifd_conf_node_get_string(ifd_conf_node_t *,
40 | const char *, char **);
41 | extern int ifd_conf_node_get_integer(ifd_conf_node_t *,
42 | const char *, unsigned int *);
43 | extern int ifd_conf_node_get_bool(ifd_conf_node_t *,
44 | const char *, unsigned int *);
45 | extern int ifd_conf_node_get_string_list(ifd_conf_node_t *,
46 | const char *, char **, size_t);
47 | extern int ifd_conf_node_get_nodes(ifd_conf_node_t *,
48 | const char *, ifd_conf_node_t **, size_t);
49 |
50 | #ifdef __cplusplus
51 | }
52 | #endif
53 |
54 | #endif /* OPENCT_CONF_H */
55 |
--------------------------------------------------------------------------------
/src/include/openct/device.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Device functions of the IFD handler library
3 | *
4 | * Copyright (C) 2003, Olaf Kirch
5 | */
6 |
7 | #ifndef OPENCT_DEVICE_H
8 | #define OPENCT_DEVICE_H
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | #include
15 |
16 | struct pollfd; /* for poll_presence */
17 |
18 | /* Types of devices supported by libifd */
19 | enum {
20 | IFD_DEVICE_TYPE_SERIAL = 0,
21 | IFD_DEVICE_TYPE_USB,
22 | IFD_DEVICE_TYPE_PS2,
23 | IFD_DEVICE_TYPE_PCMCIA,
24 | IFD_DEVICE_TYPE_PCMCIA_BLOCK,
25 | IFD_DEVICE_TYPE_OTHER
26 | };
27 |
28 | union ifd_device_params {
29 | struct {
30 | unsigned int speed;
31 | int bits;
32 | int stopbits;
33 | int parity;
34 | int check_parity;
35 | unsigned int rts : 1,
36 | dtr : 1;
37 | } serial;
38 | struct {
39 | int configuration;
40 | int interface;
41 | int altsetting;
42 | int ep_o;
43 | int ep_i;
44 | int ep_intr;
45 | } usb;
46 | };
47 |
48 | enum {
49 | IFD_SERIAL_PARITY_NONE = 0,
50 | IFD_SERIAL_PARITY_ODD = 1,
51 | IFD_SERIAL_PARITY_EVEN = 2
52 | };
53 | #define IFD_SERIAL_PARITY_TOGGLE(n) ((n)? ((n) ^ 3) : 0)
54 |
55 | #define IFD_MAX_DEVID_PARTS 5
56 | typedef struct ifd_devid {
57 | int type;
58 | unsigned int num;
59 | unsigned int val[IFD_MAX_DEVID_PARTS];
60 | } ifd_devid_t;
61 |
62 | /*
63 | * Control messages to be sent through
64 | * ifd_device_control must always have a guard word
65 | * that contains the device type.
66 | */
67 | enum {
68 | IFD_USB_URB_TYPE_ISO = 0,
69 | IFD_USB_URB_TYPE_INTERRUPT = 1,
70 | IFD_USB_URB_TYPE_CONTROL = 2,
71 | IFD_USB_URB_TYPE_BULK = 3
72 | };
73 | typedef struct ifd_usb_capture ifd_usb_capture_t;
74 |
75 | extern ifd_device_t * ifd_device_open(const char *);
76 | extern void ifd_device_close(ifd_device_t *);
77 | extern int ifd_device_type(ifd_device_t *);
78 | extern int ifd_device_reset(ifd_device_t *);
79 | extern void ifd_device_flush(ifd_device_t *);
80 | extern void ifd_device_send_break(ifd_device_t *, unsigned int);
81 | extern int ifd_device_identify(const char *, char *, size_t);
82 | extern int ifd_device_get_parameters(ifd_device_t *,
83 | ifd_device_params_t *);
84 | extern int ifd_device_set_parameters(ifd_device_t *,
85 | const ifd_device_params_t *);
86 | extern int ifd_device_transceive(ifd_device_t *,
87 | const void *, size_t,
88 | void *, size_t, long);
89 | extern int ifd_device_send(ifd_device_t *, const unsigned char *, size_t);
90 | extern int ifd_device_recv(ifd_device_t *, unsigned char *, size_t, long);
91 | extern int ifd_device_control(ifd_device_t *, void *, size_t);
92 | extern void ifd_device_set_hotplug(ifd_device_t *, int);
93 | extern int ifd_device_get_eventfd(ifd_device_t *, short *events);
94 | extern int ifd_device_poll_presence(ifd_device_t *,
95 | struct pollfd *);
96 |
97 | extern int ifd_device_id_parse(const char *, ifd_devid_t *);
98 | extern int ifd_device_id_match(const ifd_devid_t *,
99 | const ifd_devid_t *);
100 |
101 | extern int ifd_usb_control(ifd_device_t *,
102 | unsigned int requesttype,
103 | unsigned int request,
104 | unsigned int value,
105 | unsigned int index,
106 | void *data, size_t len,
107 | long timeout);
108 | extern int ifd_usb_begin_capture(ifd_device_t *,
109 | int type, int endpoint,
110 | size_t maxpacket,
111 | ifd_usb_capture_t **);
112 | extern int ifd_usb_capture_event(ifd_device_t *,
113 | ifd_usb_capture_t *,
114 | void *buffer, size_t len);
115 | extern int ifd_usb_capture(ifd_device_t *,
116 | ifd_usb_capture_t *,
117 | void *buffer, size_t len,
118 | long timeout);
119 | extern int ifd_usb_end_capture(ifd_device_t *,
120 | ifd_usb_capture_t *);
121 |
122 | extern void ifd_serial_send_break(ifd_device_t *, unsigned int usec);
123 | extern int ifd_serial_get_cts(ifd_device_t *);
124 | extern int ifd_serial_get_dsr(ifd_device_t *);
125 | extern int ifd_serial_get_dtr(ifd_device_t *);
126 |
127 | #ifdef __cplusplus
128 | }
129 | #endif
130 |
131 | #endif /* OPENCT_DEVICE_H */
132 |
--------------------------------------------------------------------------------
/src/include/openct/error.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Error codes
3 | *
4 | * Copyright (C) 2003, Olaf Kirch
5 | */
6 |
7 | #ifndef OPENCT_ERROR_H
8 | #define OPENCT_ERROR_H
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | #define IFD_SUCCESS 0
15 | #define IFD_ERROR_GENERIC -1
16 | #define IFD_ERROR_TIMEOUT -2
17 | #define IFD_ERROR_INVALID_SLOT -3
18 | #define IFD_ERROR_NOT_SUPPORTED -4
19 | #define IFD_ERROR_COMM_ERROR -5
20 | #define IFD_ERROR_NO_CARD -6
21 | #define IFD_ERROR_LOCKED -7
22 | #define IFD_ERROR_NOLOCK -8
23 | #define IFD_ERROR_INVALID_ARG -9
24 | #define IFD_ERROR_NO_MEMORY -10
25 | #define IFD_ERROR_BUFFER_TOO_SMALL -11
26 | #define IFD_ERROR_USER_TIMEOUT -12
27 | #define IFD_ERROR_USER_ABORT -13
28 | #define IFD_ERROR_PIN_MISMATCH -14
29 | #define IFD_ERROR_NO_ATR -15
30 | #define IFD_ERROR_INCOMPATIBLE_DEVICE -16
31 | #define IFD_ERROR_DEVICE_DISCONNECTED -17
32 | #define IFD_ERROR_INVALID_ATR -18
33 |
34 | /* for application/resource manager protocol */
35 | #define IFD_ERROR_INVALID_MSG -100
36 | #define IFD_ERROR_INVALID_CMD -101
37 | #define IFD_ERROR_MISSING_ARG -102
38 | #define IFD_ERROR_NOT_CONNECTED -103
39 |
40 | /* Specific error codes for proxy protocol */
41 | #define IFD_ERROR_ALREADY_CLAIMED -200
42 | #define IFD_ERROR_DEVICE_BUSY -201
43 | #define IFD_ERROR_UNKNOWN_DEVICE -202
44 |
45 | extern const char * ct_strerror(int);
46 |
47 | #ifdef __cplusplus
48 | }
49 | #endif
50 |
51 | #endif /* OPENCT_ERROR_H */
52 |
--------------------------------------------------------------------------------
/src/include/openct/ifd.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Core functions of the IFD handler library
3 | *
4 | * Copyright (C) 2003, Olaf Kirch
5 | */
6 |
7 | #ifndef OPENCT_IFD_H
8 | #define OPENCT_IFD_H
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | #include
15 | #include
16 | #include
17 |
18 | typedef struct ifd_device ifd_device_t;
19 | typedef union ifd_device_params ifd_device_params_t;
20 |
21 | enum {
22 | IFD_PROTOCOL_DEFAULT = -1,
23 | IFD_PROTOCOL_T0 = 0,
24 | IFD_PROTOCOL_T1,
25 | IFD_PROTOCOL_2WIRE = 16,
26 | IFD_PROTOCOL_3WIRE,
27 | IFD_PROTOCOL_I2C_SHORT,
28 | IFD_PROTOCOL_I2C_LONG,
29 | IFD_PROTOCOL_TLP, /* older Gemplus protocol */
30 | IFD_PROTOCOL_GBP, /* Gemplus block protocol */
31 | IFD_PROTOCOL_EUROCHIP, /* Eurochip Countercard */
32 | IFD_PROTOCOL_TCL, /* ISO 14443-4 T=CL */
33 | IFD_PROTOCOL_ESCAPE, /* Virtual 'escape' protocol */
34 | IFD_PROTOCOL_TRANSPARENT = 128
35 | };
36 |
37 | typedef struct ifd_protocol ifd_protocol_t;
38 |
39 | typedef struct ifd_driver {
40 | const char * name;
41 | struct ifd_driver_ops * ops;
42 | } ifd_driver_t;
43 |
44 | #define IFD_MAX_ATR_LEN 64
45 | typedef struct ifd_slot {
46 | unsigned int handle;
47 |
48 | int status;
49 | time_t next_update;
50 |
51 | unsigned char dad; /* address when using T=1 */
52 | unsigned int atr_len;
53 | unsigned char atr[IFD_MAX_ATR_LEN];
54 |
55 | ifd_protocol_t * proto;
56 | void * reader_data;
57 | } ifd_slot_t;
58 |
59 | typedef struct ifd_reader {
60 | unsigned int num;
61 | unsigned int handle;
62 |
63 | const char * name;
64 | unsigned int flags;
65 | unsigned int nslots;
66 | ifd_slot_t slot[OPENCT_MAX_SLOTS];
67 |
68 | const ifd_driver_t * driver;
69 | ifd_device_t * device;
70 | ct_info_t * status;
71 |
72 | /* In case the IFD needs to keep state */
73 | void * driver_data;
74 | } ifd_reader_t;
75 |
76 | #define IFD_READER_ACTIVE 0x0001
77 | #define IFD_READER_HOTPLUG 0x0002
78 | #define IFD_READER_DISPLAY 0x0100
79 | #define IFD_READER_KEYPAD 0x0200
80 |
81 | enum {
82 | IFD_PROTOCOL_RECV_TIMEOUT = 0x0000,
83 | IFD_PROTOCOL_BLOCK_ORIENTED,
84 |
85 | /* T=0 specific parameters */
86 | __IFD_PROTOCOL_T0_PARAM_BASE = IFD_PROTOCOL_T0 << 16,
87 |
88 | /* T=1 specific parameters */
89 | __IFD_PROTOCOL_T1_PARAM_BASE = IFD_PROTOCOL_T1 << 16,
90 | IFD_PROTOCOL_T1_BLOCKSIZE,
91 | IFD_PROTOCOL_T1_CHECKSUM_CRC,
92 | IFD_PROTOCOL_T1_CHECKSUM_LRC,
93 | IFD_PROTOCOL_T1_IFSC,
94 | IFD_PROTOCOL_T1_IFSD,
95 | IFD_PROTOCOL_T1_STATE,
96 | IFD_PROTOCOL_T1_MORE
97 | };
98 |
99 | enum {
100 | IFD_DAD_HOST = 0,
101 | IFD_DAD_IFD,
102 | IFD_DAD_ICC1,
103 | IFD_DAD_ICC2
104 | };
105 |
106 |
107 | extern int ifd_init(void);
108 |
109 | extern ifd_reader_t * ifd_open(const char *driver_name,
110 | const char *device_name);
111 | extern void ifd_close(ifd_reader_t *);
112 | extern int ifd_reader_count(void);
113 | extern int ifd_attach(ifd_reader_t *);
114 | extern void ifd_detach(ifd_reader_t *);
115 | extern ifd_reader_t * ifd_reader_by_handle(unsigned int handle);
116 | extern ifd_reader_t * ifd_reader_by_index(unsigned int index);
117 |
118 | extern int ifd_spawn_handler(const char *, const char *, int);
119 | extern int ifd_scan_usb(void);
120 |
121 | extern int ifd_activate(ifd_reader_t *);
122 | extern int ifd_deactivate(ifd_reader_t *);
123 | extern int ifd_output(ifd_reader_t *, const char *);
124 |
125 | extern int ifd_atr_complete(const unsigned char *, size_t);
126 |
127 | extern int ifd_set_protocol(ifd_reader_t *reader,
128 | unsigned int slot,
129 | int id);
130 | extern int ifd_card_command(ifd_reader_t *reader,
131 | unsigned int slot,
132 | const void *sbuf, size_t slen,
133 | void *rbuf, size_t rlen);
134 | extern int ifd_card_status(ifd_reader_t *reader,
135 | unsigned int slot,
136 | int *status);
137 | extern int ifd_card_reset(ifd_reader_t *reader,
138 | unsigned int slot,
139 | void *atr_buf,
140 | size_t atr_len);
141 | extern int ifd_card_request(ifd_reader_t *reader,
142 | unsigned int slot,
143 | time_t timeout,
144 | const char *message,
145 | void *atr_buf,
146 | size_t atr_len);
147 | extern int ifd_card_eject(ifd_reader_t *reader,
148 | unsigned int slot,
149 | time_t timeout,
150 | const char *message);
151 | extern int ifd_card_perform_verify(ifd_reader_t *reader,
152 | unsigned int slot,
153 | time_t timeout,
154 | const char *message,
155 | const unsigned char *data, size_t data_len,
156 | unsigned char *resp, size_t resp_len);
157 | extern int ifd_card_read_memory(ifd_reader_t *,
158 | unsigned int, unsigned short,
159 | unsigned char *, size_t);
160 | extern int ifd_card_write_memory(ifd_reader_t *,
161 | unsigned int, unsigned short,
162 | const unsigned char *, size_t);
163 |
164 | extern ifd_protocol_t * ifd_protocol_new(int id,
165 | ifd_reader_t *reader,
166 | unsigned int dad);
167 | extern int ifd_protocol_set_parameter(ifd_protocol_t *p,
168 | int type,
169 | long value);
170 | extern int ifd_protocol_get_parameter(ifd_protocol_t *p,
171 | int type,
172 | long *value);
173 | extern int ifd_protocol_read_memory(ifd_protocol_t *,
174 | int, unsigned short,
175 | unsigned char *, size_t);
176 | extern int ifd_protocol_write_memory(ifd_protocol_t *,
177 | int, unsigned short,
178 | const unsigned char *, size_t);
179 | extern void ifd_protocol_free(ifd_protocol_t *);
180 | extern int ifd_before_command(ifd_reader_t *);
181 | extern int ifd_after_command(ifd_reader_t *);
182 | extern int ifd_get_eventfd(ifd_reader_t *, short *);
183 | extern void ifd_poll(ifd_reader_t *);
184 | extern int id_event(ifd_reader_t *);
185 |
186 | /* Debugging macro */
187 | #ifdef __GNUC__
188 | #define ifd_debug(level, fmt, args...) \
189 | do { \
190 | if ((level) <= ct_config.debug) \
191 | ct_debug("%s: " fmt, __FUNCTION__ , ##args); \
192 | } while (0)
193 | #else
194 | extern void ifd_debug(int level, const char *fmt, ...);
195 | #endif
196 |
197 | #ifdef __cplusplus
198 | }
199 | #endif
200 |
201 | #endif /* OPENCT_IFD_H */
202 |
--------------------------------------------------------------------------------
/src/include/openct/logging.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Logging functions
3 | *
4 | * Copyright (C) 2003, Olaf Kirch
5 | */
6 |
7 | #ifndef OPENCT_LOGGING_H
8 | #define OPENCT_LOGGING_H
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | extern void ct_log_destination(const char *);
15 |
16 | extern void ct_error(const char *, ...);
17 | extern void ct_debug(const char *, ...);
18 |
19 | extern const char * ct_hexdump(const void *, size_t);
20 |
21 | #ifdef __cplusplus
22 | }
23 | #endif
24 |
25 | #endif /* OPENCT_LOGGING_H */
26 |
--------------------------------------------------------------------------------
/src/include/openct/openct.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Main OpenCT include file
3 | *
4 | * Copyright (C) 2003, Olaf Kirch
5 | */
6 |
7 | #ifndef OPENCT_OPENCT_H
8 | #define OPENCT_OPENCT_H
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | #include
15 |
16 | /* Various implementation limits */
17 | #define OPENCT_MAX_READERS 16
18 | #define OPENCT_MAX_SLOTS 8
19 |
20 | typedef struct ct_info {
21 | char ct_name[64];
22 | unsigned int ct_slots;
23 | unsigned int ct_card[OPENCT_MAX_SLOTS];
24 | unsigned ct_display : 1,
25 | ct_keypad : 1;
26 | pid_t ct_pid;
27 | } ct_info_t;
28 |
29 | typedef struct ct_handle ct_handle;
30 |
31 | #define IFD_CARD_PRESENT 0x0001
32 | #define IFD_CARD_STATUS_CHANGED 0x0002
33 |
34 | /* Lock types
35 | * - shared locks allow concurrent access from
36 | * other applications run by the same user.
37 | * Used e.g. by pkcs11 login.
38 | * - exclusive locks deny any access by other
39 | * applications.
40 | *
41 | * When a lock is granted, a lock handle is passed
42 | * to the client, which it must present in the
43 | * subsequent unlock call.
44 | */
45 | typedef unsigned int ct_lock_handle;
46 | enum {
47 | IFD_LOCK_SHARED,
48 | IFD_LOCK_EXCLUSIVE
49 | };
50 |
51 | /*
52 | * PIN encoding types
53 | */
54 | enum {
55 | IFD_PIN_ENCODING_BCD,
56 | IFD_PIN_ENCODING_ASCII
57 | };
58 |
59 | extern int ct_status(const ct_info_t **);
60 |
61 | extern int ct_reader_info(unsigned int, ct_info_t *);
62 | extern ct_handle * ct_reader_connect(unsigned int);
63 | extern void ct_reader_disconnect(ct_handle *);
64 | extern int ct_reader_status(ct_handle *, ct_info_t *);
65 | extern int ct_card_status(ct_handle *h, unsigned int slot, int *status);
66 | extern int ct_card_set_protocol(ct_handle *h, unsigned int slot,
67 | unsigned int protocol);
68 | extern int ct_card_reset(ct_handle *h, unsigned int slot,
69 | void *atr, size_t atr_len);
70 | extern int ct_card_request(ct_handle *h, unsigned int slot,
71 | unsigned int timeout, const char *message,
72 | void *atr, size_t atr_len);
73 | extern int ct_card_lock(ct_handle *h, unsigned int slot,
74 | int type, ct_lock_handle *);
75 | extern int ct_card_unlock(ct_handle *h, unsigned int slot,
76 | ct_lock_handle);
77 | extern int ct_card_transact(ct_handle *h, unsigned int slot,
78 | const void *apdu, size_t apdu_len,
79 | void *recv_buf, size_t recv_len);
80 | extern int ct_card_verify(ct_handle *h, unsigned int slot,
81 | unsigned int timeout, const char *prompt,
82 | unsigned int pin_encoding,
83 | unsigned int pin_length,
84 | unsigned int pin_offset,
85 | const void *send_buf, size_t send_len,
86 | void *recv_buf, size_t recv_len);
87 | extern int ct_card_read_memory(ct_handle *, unsigned int slot,
88 | unsigned short address,
89 | void *recv_buf, size_t recv_len);
90 | extern int ct_card_write_memory(ct_handle *, unsigned int slot,
91 | unsigned short address,
92 | const void *send_buf, size_t send_len);
93 |
94 | extern int ct_status_destroy(void);
95 | extern int ct_status_clear(unsigned int, const char *);
96 | extern ct_info_t * ct_status_alloc_slot(int *);
97 | extern int ct_status_update(ct_info_t *);
98 |
99 | #ifdef __cplusplus
100 | }
101 | #endif
102 |
103 | #endif /* OPENCT_OPENCT_H */
104 |
--------------------------------------------------------------------------------
/src/include/openct/path.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Path handling routines
3 | *
4 | * Copyright (C) 2006, Andreas Jellinghaus
5 | */
6 |
7 | #ifndef OPENCT_PATH_H
8 | #define OPENCT_PATH_H
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | extern int ct_format_path(char *path, const size_t pathlen, const char *file);
15 |
16 | #ifdef __cplusplus
17 | }
18 | #endif
19 | #endif /* OPENCT_PATH_H */
20 |
--------------------------------------------------------------------------------
/src/include/openct/protocol.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Protocol for communication between application and
3 | * resource manager
4 | *
5 | * Copyright (C) 2003, Olaf Kirch
6 | */
7 |
8 | #ifndef OPENCT_PROTOCOL_H
9 | #define OPENCT_PROTOCOL_H
10 |
11 | #ifdef __cplusplus
12 | extern "C" {
13 | #endif
14 |
15 | /*
16 | * A protocol message from client to server
17 | * consists of
18 | * - command byte
19 | * - unit byte
20 | * - optional data, TLV encoded
21 | */
22 |
23 | #define CT_CMD_STATUS 0x00
24 | #define CT_CMD_LOCK 0x01 /* prevent concurrent access */
25 | #define CT_CMD_UNLOCK 0x02
26 | #define CT_CMD_RESET 0x10
27 | #define CT_CMD_REQUEST_ICC 0x11
28 | #define CT_CMD_EJECT_ICC 0x12
29 | #define CT_CMD_OUTPUT 0x13
30 | #define CT_CMD_PERFORM_VERIFY 0x14
31 | #define CT_CMD_CHANGE_PIN 0x15
32 | #define CT_CMD_MEMORY_READ 0x16
33 | #define CT_CMD_MEMORY_WRITE 0x17
34 | #define CT_CMD_INPUT 0x18
35 | #define CT_CMD_TRANSACT_OLD 0x20 /* transceive APDU */
36 | #define CT_CMD_TRANSACT 0x21 /* transceive APDU */
37 | #define CT_CMD_SET_PROTOCOL 0x22
38 |
39 | #define CT_UNIT_ICC1 0x00
40 | #define CT_UNIT_ICC2 0x01
41 | #define CT_UNIT_ICC3 0x02
42 | #define CT_UNIT_ICC4 0x03
43 | #define CT_UNIT_READER 0x10
44 | #define CT_UNIT_DISPLAY 0x11
45 | #define CT_UNIT_KEYPAD 0x12
46 |
47 | /*
48 | * TLV items.
49 | */
50 | #define CT_TAG_READER_NAME 0x00 /* ASCII string */
51 | #define CT_TAG_READER_UNITS 0x01 /* list CT_UNIT_* bytes */
52 | #define CT_TAG_CARD_STATUS 0x02 /* IFD_CARD_* byte */
53 | #define CT_TAG_ATR 0x03 /* Answer to reset */
54 | #define CT_TAG_LOCK 0x04
55 | #define CT_TAG_CARD_RESPONSE 0x05 /* Card response to VERIFY etc */
56 | #define CT_TAG_TIMEOUT 0x80
57 | #define CT_TAG_MESSAGE 0x81
58 | #define CT_TAG_LOCKTYPE 0x82
59 | #define CT_TAG_PIN_DATA 0x83 /* CTBCS verify APDU */
60 | #define CT_TAG_CARD_REQUEST 0x84
61 | #define CT_TAG_ADDRESS 0x85
62 | #define CT_TAG_DATA 0x86
63 | #define CT_TAG_COUNT 0x87
64 | #define CT_TAG_PROTOCOL 0x88
65 |
66 | #define __CT_TAG_LARGE 0x40
67 |
68 | #ifdef __cplusplus
69 | }
70 | #endif
71 |
72 | #endif /* OPENCT_PROTOCOL_H */
73 |
--------------------------------------------------------------------------------
/src/include/openct/server.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Server side functionality
3 | *
4 | * Copyright (C) 2003, Olaf Kirch
5 | */
6 |
7 | #ifndef OPENCT_SERVER_H
8 | #define OPENCT_SERVER_H
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | #include
15 |
16 | extern void ct_mainloop_add_socket(ct_socket_t *);
17 | extern void ct_mainloop(void);
18 | extern void ct_mainloop_leave(void);
19 |
20 | #ifdef __cplusplus
21 | }
22 | #endif
23 |
24 | #endif /* OPENCT_SERVER_H */
25 |
--------------------------------------------------------------------------------
/src/include/openct/socket.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Socket type definitions
3 | *
4 | * Copyright (C) 2003, Olaf Kirch
5 | */
6 |
7 | #ifndef OPENCT_SOCKET_H
8 | #define OPENCT_SOCKET_H
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | #include
15 | #include
16 | #include
17 |
18 | /* forward decl */
19 | struct pollfd;
20 |
21 | typedef struct header {
22 | uint32_t xid;
23 | uint32_t dest;
24 | int16_t error;
25 | uint16_t count;
26 | } header_t;
27 |
28 | typedef struct ct_socket {
29 | struct ct_socket *next, *prev;
30 |
31 | int fd;
32 | int eof;
33 | ct_buf_t rbuf, sbuf;
34 |
35 | unsigned int use_large_tags : 1,
36 | use_network_byte_order : 1,
37 | listener : 1;
38 |
39 | /* events to poll for */
40 | int events;
41 |
42 | void * user_data;
43 | int (*poll)(struct ct_socket *, struct pollfd *);
44 | int (*error)(struct ct_socket *);
45 | int (*recv)(struct ct_socket *);
46 | int (*send)(struct ct_socket *);
47 | int (*process)(struct ct_socket *, header_t *,
48 | ct_buf_t *, ct_buf_t *);
49 | void (*close)(struct ct_socket *);
50 |
51 | pid_t client_id;
52 | uid_t client_uid;
53 | } ct_socket_t;
54 |
55 | #define CT_SOCKET_BUFSIZ 4096
56 |
57 | extern ct_socket_t * ct_socket_new(unsigned int);
58 | extern void ct_socket_free(ct_socket_t *);
59 | extern void ct_socket_reuseaddr(int);
60 | extern int ct_socket_connect(ct_socket_t *, const char *);
61 | extern int ct_socket_listen(ct_socket_t *, const char *, int);
62 | extern ct_socket_t * ct_socket_accept(ct_socket_t *);
63 | extern void ct_socket_close(ct_socket_t *);
64 | extern int ct_socket_call(ct_socket_t *, ct_buf_t *, ct_buf_t *);
65 | extern int ct_socket_flsbuf(ct_socket_t *, int);
66 | extern int ct_socket_filbuf(ct_socket_t *, long);
67 | extern int ct_socket_put_packet(ct_socket_t *,
68 | header_t *, ct_buf_t *);
69 | extern int ct_socket_puts(ct_socket_t *, const char *);
70 | extern int ct_socket_get_packet(ct_socket_t *,
71 | header_t *, ct_buf_t *);
72 | extern int ct_socket_gets(ct_socket_t *, char *, size_t);
73 | extern int ct_socket_send(ct_socket_t *, header_t *,
74 | ct_buf_t *);
75 | extern int ct_socket_recv(ct_socket_t *, header_t *,
76 | ct_buf_t *);
77 | extern int ct_socket_write(ct_socket_t *, void *, size_t);
78 | extern int ct_socket_read(ct_socket_t *, void *, size_t);
79 | extern void ct_socket_link(ct_socket_t *, ct_socket_t *);
80 | extern void ct_socket_unlink(ct_socket_t *);
81 | extern int ct_socket_getpeername(ct_socket_t *, char *, size_t);
82 |
83 | #ifdef __cplusplus
84 | }
85 | #endif
86 |
87 | #endif /* OPENCT_SOCKET_H */
88 |
--------------------------------------------------------------------------------
/src/include/openct/tlv.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Handle TLV encoded data
3 | *
4 | * Copyright (C) 2003, Olaf Kirch
5 | */
6 |
7 | #ifndef OPENCT_TLV_H
8 | #define OPENCT_TLV_H
9 |
10 | #ifdef __cplusplus
11 | extern "C" {
12 | #endif
13 |
14 | #include
15 | #include
16 |
17 | typedef unsigned char ifd_tag_t;
18 |
19 | typedef struct ct_tlv_parser {
20 | unsigned char use_large_tags;
21 | unsigned char * val[256];
22 | unsigned int len[256];
23 | } ct_tlv_parser_t;
24 |
25 | typedef struct ct_tlv_builder {
26 | int error;
27 | unsigned char use_large_tags;
28 | ct_buf_t * buf;
29 | unsigned int len;
30 | unsigned char * lenp;
31 | } ct_tlv_builder_t;
32 |
33 | extern int ct_tlv_parse(ct_tlv_parser_t *, ct_buf_t *);
34 | /* ct_tlv_get return 0 == not there, 1 == there */
35 | extern int ct_tlv_get_int(ct_tlv_parser_t *,
36 | ifd_tag_t, unsigned int *);
37 | extern int ct_tlv_get_string(ct_tlv_parser_t *,
38 | ifd_tag_t, char *, size_t);
39 | extern int ct_tlv_get_opaque(ct_tlv_parser_t *,
40 | ifd_tag_t, unsigned char **, size_t *);
41 | /* or number of bytes */
42 | extern int ct_tlv_get_bytes(ct_tlv_parser_t *,
43 | ifd_tag_t, void *, size_t);
44 |
45 | extern void ct_tlv_builder_init(ct_tlv_builder_t *, ct_buf_t *, int);
46 | extern void ct_tlv_put_int(ct_tlv_builder_t *,
47 | ifd_tag_t, unsigned int);
48 | extern void ct_tlv_put_string(ct_tlv_builder_t *,
49 | ifd_tag_t, const char *);
50 | extern void ct_tlv_put_opaque(ct_tlv_builder_t *, ifd_tag_t,
51 | const unsigned char *, size_t);
52 | extern void ct_tlv_put_tag(ct_tlv_builder_t *, ifd_tag_t);
53 | extern void ct_tlv_add_byte(ct_tlv_builder_t *, unsigned char);
54 | extern void ct_tlv_add_bytes(ct_tlv_builder_t *,
55 | const unsigned char *, size_t);
56 |
57 | #ifdef __cplusplus
58 | }
59 | #endif
60 |
61 | #endif /* OPENCT_TLV_H */
62 |
--------------------------------------------------------------------------------
/src/pcsc/Makefile.am:
--------------------------------------------------------------------------------
1 | MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
2 |
3 | if ENABLE_PCSC
4 | lib_LTLIBRARIES = openct-ifd.la
5 | endif
6 |
7 | openct_ifd_la_SOURCES = pcsc.c
8 | openct_ifd_la_LDFLAGS = -module -shared -avoid-version -no-undefined
9 | openct_ifd_la_LIBADD = $(PCSC_LIBS) $(top_builddir)/src/ctapi/libopenctapi.la
10 | openct_ifd_la_CFLAGS = $(AM_CFLAGS) \
11 | -I$(top_srcdir)/src/include \
12 | -I$(top_builddir)/src/include \
13 | -I$(top_srcdir)/src/ctapi \
14 | $(PCSC_CFLAGS)
15 |
16 | # Don't use ENABLE_BUNDLES for this case, pcsc-lite loads
17 | # USB drivers from MacOS X like bundles for all platforms
18 | install-exec-local: install-libLTLIBRARIES
19 | if ENABLE_PCSC
20 | if ENABLE_BUNDLES
21 | $(MKDIR_P) "$(DESTDIR)$(bundledir)"
22 | "$(top_srcdir)/macos/libtool-bundle" -e "$(top_srcdir)/etc/Info.plist" \
23 | "$(DESTDIR)$(libdir)/openct-ifd.so" "$(DESTDIR)$(bundledir)"
24 | endif
25 | endif
26 |
27 | uninstall-local: uninstall-libLTLIBRARIES
28 | if ENABLE_PCSC
29 | if ENABLE_BUNDLES
30 | rm -rf "$(DESTDIR)$(bundledir)/openct-ifd.bundle/"
31 | endif
32 | endif
33 |
--------------------------------------------------------------------------------
/src/tools/Makefile.am:
--------------------------------------------------------------------------------
1 | MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
2 |
3 | bin_PROGRAMS = openct-tool
4 | sbin_PROGRAMS = openct-control
5 | man1_MANS = openct-tool.1
6 |
7 | openct_tool_SOURCES = openct-tool.c
8 | openct_tool_LDADD = $(top_builddir)/src/ct/libopenct.la
9 | openct_tool_CFLAGS = $(AM_CFLAGS) \
10 | -I$(top_srcdir)/src/include \
11 | -I$(top_builddir)/src/include
12 |
13 | openct_control_SOURCES = openct-control.c
14 | openct_control_LDADD = $(top_builddir)/src/ifd/libifd.la $(top_builddir)/src/ct/libopenct.la
15 | openct_control_CFLAGS = $(AM_CFLAGS) \
16 | -I$(top_srcdir)/src/include \
17 | -I$(top_builddir)/src/include
18 |
--------------------------------------------------------------------------------
/src/tools/openct-tool.1.in:
--------------------------------------------------------------------------------
1 | .TH openct-tool "1" "May 2005" "OpenCT @VERSION@" "OpenCT"
2 | .SH NAME
3 | openct-tool \- OpenCT smart card utility
4 | .SH SYNOPSIS
5 | openct\-tool [options] command ...
6 | .SH OPTIONS
7 | .TP
8 | \fB\-d\fR
9 | enable debugging; repeat to increase verbosity
10 | .TP
11 | \fB\-f\fR \fIconfigfile\fR
12 | specify config file (default @openct_conf_path@)
13 | .TP
14 | \fB\-r\fR \fIreader\fR
15 | specify index of reader to use
16 | .TP
17 | \fB\-h\fR
18 | display this message
19 | .TP
20 | \fB\-v\fR
21 | display version and exit
22 | .SH COMMANDS
23 | .TP
24 | \fBlist\fR
25 | list all readers found
26 | .TP
27 | \fBatr\fR
28 | print ATR of card in selected reader
29 | .TP
30 | \fBwait\fR
31 | wait for card to be inserted
32 | .TP
33 | \fBrwait\fR
34 | wait for reader to be attached
35 | .TP
36 | \fBmf\fR
37 | try to select main folder of card
38 | .TP
39 | \fBread\fR
40 | dump memory of synchronous card
41 |
--------------------------------------------------------------------------------