smartcard 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/BUILD ADDED
@@ -0,0 +1,65 @@
1
+ = Builds are hard
2
+ +smartcard+ needs to talk to hardware (card readers), so it's bound to use a Ruby extension.
3
+ This means C, and platform-specific building nightmares. Read below for details.
4
+
5
+ = The build system
6
+ +smartcard+ uses {echoe}[http://blog.evanweaver.com/files/doc/fauna/echoe/] for builds. This
7
+ automates most of the building and packaging work, and can even push the gem to rubyforge,
8
+ with a bit of luck. Most used commands:
9
+ rake manifest # builds the manifest (do this after checking out)
10
+ rake package # builds the gem for your platform
11
+ rake mswin package # cross-builds the gem for Windows
12
+ rake test # builds the gem and runs the tests
13
+ rake docs # runs Rdoc to produce the docs
14
+
15
+ On the other hand, you have to <tt>gem install echoe</tt> to be able to build anything.
16
+
17
+ = Platform-specific information
18
+
19
+ == OSX
20
+
21
+ You need to install the Developer Tools to get gcc.
22
+
23
+ Leopard includes a working PC/SC provider, as well as a good driver for CCID readers.
24
+ Tiger's PC/SC implementation is broken and incomplete, so the Ruby extension code in +smartcard+
25
+ has a few hacks to work around that (look for the <tt>RB_SMARTCARD_OSX_TIGER_HACK</tt> define.
26
+ The following commands are broken / don't work:
27
+ * Smartcard::PCSC::Context#is_valid (always returs +true+)
28
+ * Smartcard::PCSC::Card#get_attribute (throws exception because it's not implemented)
29
+ * Smartcard::PCSC::Card#set_attribute (throws exception because it's not implemented)
30
+ * Smartcard::PCSC::Card#control (Tiger's API is broken, so the call will probably not work)
31
+
32
+ The developer team doesn't support or test against ports of +gcc+ or +pcsclite+,
33
+ but we success notifications are welcome.
34
+
35
+ == Windows
36
+
37
+ A lot of effort has been spent to make Windows builds as easy as possible.
38
+ +smartcard+ is currently built using a full edition of
39
+ {Visual Studio 2005}[http://msdn.microsoft.com/vstudio/], but all sources
40
+ indicate that {Visual C++ Express 2005}[http://www.microsoft.com/express/download/] works,
41
+ as long as you also install a Windows SDK (you're on your own for that). Visual Studio 2008
42
+ might work, but it hasn't been tested yet.
43
+
44
+ A summary of the hacks that have been done to get Windows builds working:
45
+ * removing the extension files from the gemspec at the "right time" so that +echoe+ compiles the extension, and the gem doesn't require re-compilation (see the +Rakefile+)
46
+ * adding the compiled extension to the file list in the gemspec
47
+ * adding code to <tt>extconf.rb</tt> to patch the +Makefile+ so a manifest is embedded in the extension dll (and ruby doesn't crash if it uses a different version of the C runtime)
48
+
49
+ == Linux
50
+
51
+ +smartcard+ is developed (and tested) against the
52
+ {MUSCLE project}[http://www.linuxnet.com/software.html]. If you go this route, you need to
53
+ get at least the {pcsclite library}[http://pcsclite.alioth.debian.org/] and a driver.
54
+ +smartcard+ developers use the {CCID driver}[http://pcsclite.alioth.debian.org/], which
55
+ works on most (new) readers.
56
+
57
+ === Ubuntu
58
+
59
+ Installing the following packages (and their dependencies) gets you going on Ubuntu (tested on 7.10):
60
+ * buildessentials
61
+ * libccid
62
+ * libpcsclite
63
+ * libpcsclite-dev
64
+ * pcscd
65
+ * pcsc-tools
data/CHANGELOG CHANGED
@@ -1,3 +1,7 @@
1
+ v0.2.1 Added OSX Tiger support
2
+ Many workarounds for Tiger's buggy/incomplete PC/SC.
3
+ Small bugfixes for PC/SC status constants.
4
+
1
5
  v0.2.0 Added automatic builds
2
6
  Rakefile for auto builds using echoe
3
7
  extconf.rb: hack to fix Windows makefiles
data/Manifest CHANGED
@@ -1,3 +1,4 @@
1
+ BUILD
1
2
  CHANGELOG
2
3
  ext/smartcard_pcsc/extconf.rb
3
4
  ext/smartcard_pcsc/pcsc.h
@@ -13,7 +14,7 @@ ext/smartcard_pcsc/pcsc_surrogate_reader.h
13
14
  ext/smartcard_pcsc/pcsc_surrogate_wintypes.h
14
15
  lib/smartcard.rb
15
16
  LICENSE
17
+ Manifest
16
18
  README
17
19
  test/test_all.rb
18
20
  tests/ts_pcsc_ext.rb
19
- Manifest
data/README CHANGED
@@ -1,22 +1,29 @@
1
- SUMMARY
1
+ +smartcard+ aims to become the standard support library for smart-card development on ruby.
2
+ Right now, the project offers a PC/SC binding that is working on ruby 1.8, under
3
+ Linux, OSX, and Windows. Future plans include a high level abstraction for the PC/SC binding
4
+ (plus any other bindings people need), and an interface for Java cards.
2
5
 
3
- 'smartcard' aims to become the de-facto support library for smart-card development on ruby.
4
- At the moment, 'smartcard' offers a PC/SC binding that is working on ruby 1.8, under
5
- linux, osx, and windows. Future plans include a high level abstraction for the PC/SC binding
6
- (and any other bindings people need), and an interface for Java cards.
6
+ = Installation
7
7
 
8
- LICENSE
8
+ gem install smartcard
9
+ Windows:: Select the <tt>win32</tt> gem.
10
+ OSX:: Install the Developer Tools to get +gcc+. Requires Tiger or Leopard.
11
+ UNIX:: You need a PC/SC provider. See the {BUILD file}[link://files/BUILD.html] for details. The file also contains package lists for popular distributions.
9
12
 
10
- 'smartcard' is released under the MIT license. This means you're free to do whatever you want
11
- with it. For the legalese version, please see the 'LICENSE' file.
13
+ = Documentation
12
14
 
13
- DOCUMENTATION
15
+ The documentation you see was generated with RDoc. If you install the +smartcard+ gem, you should be
16
+ able to use ri to see the documentation. If you're using the SVN version, you can <tt>rake doc</tt> to build
17
+ the HTML documentation yourself.
14
18
 
15
- The API is fully documented with RDoc. If you installed the 'smartcard' gem, you should be
16
- able to use ri to see the documentation. If you're using the SVN version, you can use rdoc to
17
- build the HTML and RI documentation yourself.
19
+ = License
18
20
 
19
- ACKNOWLEDGEMENTS
21
+ +smartcard+ is released under the MIT license. This means you're free to do whatever you want
22
+ with it. However, it'd be nice to let the developers know if you plan to include this in a
23
+ distribution (bragging rights are always good). The {LICENSE file}[link://files/LICENSE.html]
24
+ has the license in legalese.
20
25
 
21
- 'smartcard' was developed for Victor Costan while working as a Research Assistant for MIT.
22
- The work was sponsored by a grant from Quanta Computer Inc (www.quanta.com.tw)
26
+ = Acknowledgements
27
+
28
+ +smartcard+ is developed by Victor Costan while working as a Research Assistant for MIT.
29
+ The work is sponsored by a grant from Quanta Computer Inc (www.quanta.com.tw)
@@ -3,8 +3,14 @@ require 'mkmf'
3
3
  $CFLAGS ||= ''
4
4
  $LDFLAGS ||= ''
5
5
 
6
+ pcsc_defines = []
7
+
6
8
  if RUBY_PLATFORM =~ /darwin/
7
9
  $LDFLAGS += ' -framework PCSC'
10
+ darwin_version = `uname -r`
11
+ if darwin_version =~ /^8./
12
+ pcsc_defines.push 'RB_SMARTCARD_OSX_TIGER_HACK'
13
+ end
8
14
  elsif RUBY_PLATFORM =~ /win/
9
15
  have_library('winscard')
10
16
  else
@@ -23,8 +29,6 @@ pcsc_headers = []
23
29
  end
24
30
  end
25
31
 
26
- pcsc_defines = []
27
-
28
32
  File.open('pcsc_autogen.h', 'w') do |f|
29
33
  pcsc_defines.each { |d| f.write "\#define #{d}\n" }
30
34
  pcsc_headers.each { |h| f.write "\#include #{h}\n" }
@@ -192,6 +192,10 @@ static VALUE PCSC_Card_get_attribute(VALUE self, VALUE rbAttributeId) {
192
192
 
193
193
  attribute_id = NUM2UINT(rbAttributeId);
194
194
  attribute_length;
195
+ #if defined(RB_SMARTCARD_OSX_TIGER_HACK)
196
+ card->pcsc_error = SCARD_F_INTERNAL_ERROR;
197
+ rb_raise(rb_eRuntimeError, "SCardSetAttrib: not implemented in OSX Tiger");
198
+ #else
195
199
  card->pcsc_error = SCardGetAttrib(card->card_handle, attribute_id, NULL, &attribute_length);
196
200
  if(card->pcsc_error == SCARD_S_SUCCESS) {
197
201
  attribute_buffer = ALLOC_N(char, attribute_length);
@@ -206,6 +210,7 @@ static VALUE PCSC_Card_get_attribute(VALUE self, VALUE rbAttributeId) {
206
210
  }
207
211
  if(card->pcsc_error != SCARD_S_SUCCESS)
208
212
  rb_raise(rb_eRuntimeError, "SCardGetAttrib: %s", pcsc_stringify_error(card->pcsc_error));
213
+ #endif
209
214
  return Qnil;
210
215
  }
211
216
 
@@ -236,10 +241,15 @@ static VALUE PCSC_Card_set_attribute(VALUE self, VALUE rbAttributeId, VALUE rbAt
236
241
  rb_raise(rb_eArgError, "second argument (attribute buffer) does not convert to a String");
237
242
  return self;
238
243
  }
239
-
240
- card->pcsc_error = SCardSetAttrib(card->card_handle, attribute_id, (LPSTR)RSTRING(rbFinalAttributeValue)->ptr, RSTRING(rbFinalAttributeValue)->len);
244
+
245
+ #if defined(RB_SMARTCARD_OSX_TIGER_HACK)
246
+ card->pcsc_error = SCARD_F_INTERNAL_ERROR;
247
+ rb_raise(rb_eRuntimeError, "SCardSetAttrib: not implemented in OSX Tiger");
248
+ #else
249
+ card->pcsc_error = SCardSetAttrib(card->card_handle, attribute_id, (LPSTR)RSTRING(rbFinalAttributeValue)->ptr, RSTRING(rbFinalAttributeValue)->len);
241
250
  if(card->pcsc_error != SCARD_S_SUCCESS)
242
251
  rb_raise(rb_eRuntimeError, "SCardSetAttrib: %s", pcsc_stringify_error(card->pcsc_error));
252
+ #endif
243
253
  return self;
244
254
  }
245
255
 
@@ -343,10 +353,17 @@ static VALUE PCSC_Card_control(VALUE self, VALUE rbControlCode, VALUE rbSendData
343
353
  recv_length = NUM2UINT(rbMaxRecvBytes);
344
354
  recv_buffer = ALLOC_N(char, recv_length);
345
355
  if(recv_buffer == NULL) return Qnil;
346
-
356
+
357
+ #if defined(RB_SMARTCARD_OSX_TIGER_HACK)
358
+ /* TODO: this will compile and run, but it won't do anything useful */
359
+ card->pcsc_error = SCardControl(card->card_handle,
360
+ (LPSTR)RSTRING(rbFinalSendData)->ptr, RSTRING(rbFinalSendData)->len,
361
+ recv_buffer, &recv_length);
362
+ #else
347
363
  card->pcsc_error = SCardControl(card->card_handle, control_code,
348
364
  (LPSTR)RSTRING(rbFinalSendData)->ptr, RSTRING(rbFinalSendData)->len,
349
365
  recv_buffer, recv_length, &recv_length);
366
+ #endif
350
367
  if(card->pcsc_error != SCARD_S_SUCCESS) {
351
368
  xfree(recv_buffer);
352
369
  rb_raise(rb_eRuntimeError, "SCardControl: %s", pcsc_stringify_error(card->pcsc_error));
@@ -50,21 +50,21 @@ void Init_PCSC_Consts() {
50
50
  /* SCARD_F_COMM_ERROR : An internal communications error has been detected. */
51
51
  rb_define_const(mPcsc, "SCARD_F_COMM_ERROR", INT2NUM(SCARD_F_COMM_ERROR));
52
52
  /* SCARD_F_UNKNOWN_ERROR : An internal error has been detected, but the source is unknown. */
53
- rb_define_const(mPcsc, "SCARD_F_UNKNOWN_ERROR", INT2NUM(SCARD_E_TIMEOUT));
53
+ rb_define_const(mPcsc, "SCARD_F_UNKNOWN_ERROR", INT2NUM(SCARD_F_UNKNOWN_ERROR));
54
54
  /* SCARD_E_INVALID_ATR : An ATR obtained from the registry is not a valid ATR string. */
55
- rb_define_const(mPcsc, "SCARD_E_INVALID_ATR", INT2NUM(SCARD_E_TIMEOUT));
55
+ rb_define_const(mPcsc, "SCARD_E_INVALID_ATR", INT2NUM(SCARD_E_INVALID_ATR));
56
56
  /* SCARD_E_NOT_TRANSACTED : An attempt was made to end a non-existent transaction. */
57
- rb_define_const(mPcsc, "SCARD_E_NOT_TRANSACTED", INT2NUM(SCARD_E_TIMEOUT));
57
+ rb_define_const(mPcsc, "SCARD_E_NOT_TRANSACTED", INT2NUM(SCARD_E_NOT_TRANSACTED));
58
58
  /* SCARD_E_READER_UNAVAILABLE : The specified reader is not currently available for use. */
59
- rb_define_const(mPcsc, "SCARD_E_READER_UNAVAILABLE", INT2NUM(SCARD_E_TIMEOUT));
59
+ rb_define_const(mPcsc, "SCARD_E_READER_UNAVAILABLE", INT2NUM(SCARD_E_READER_UNAVAILABLE));
60
60
  /* SCARD_W_UNSUPPORTED_CARD : The reader cannot communicate with the card, due to ATR string configuration conflicts. */
61
- rb_define_const(mPcsc, "SCARD_W_UNSUPPORTED_CARD", INT2NUM(SCARD_E_TIMEOUT));
61
+ rb_define_const(mPcsc, "SCARD_W_UNSUPPORTED_CARD", INT2NUM(SCARD_W_UNSUPPORTED_CARD));
62
62
  /* SCARD_W_UNRESPONSIVE_CARD : The smart card is not responding to a reset. */
63
- rb_define_const(mPcsc, "SCARD_W_UNRESPONSIVE_CARD", INT2NUM(SCARD_E_TIMEOUT));
63
+ rb_define_const(mPcsc, "SCARD_W_UNRESPONSIVE_CARD", INT2NUM(SCARD_W_UNRESPONSIVE_CARD));
64
64
  /* SCARD_W_UNPOWERED_CARD : Power has been removed from the smart card, so that further communication is not possible. */
65
- rb_define_const(mPcsc, "SCARD_W_UNPOWERED_CARD", INT2NUM(SCARD_E_TIMEOUT));
65
+ rb_define_const(mPcsc, "SCARD_W_UNPOWERED_CARD", INT2NUM(SCARD_W_UNPOWERED_CARD));
66
66
  /* SCARD_W_RESET_CARD : The smart card has been reset, so any shared state information is invalid. */
67
- rb_define_const(mPcsc, "SCARD_W_RESET_CARD", INT2NUM(SCARD_E_TIMEOUT));
67
+ rb_define_const(mPcsc, "SCARD_W_RESET_CARD", INT2NUM(SCARD_W_RESET_CARD));
68
68
  /* SCARD_W_REMOVED_CARD : The smart card has been removed, so further communication is not possible. */
69
69
  rb_define_const(mPcsc, "SCARD_W_REMOVED_CARD", INT2NUM(SCARD_W_REMOVED_CARD));
70
70
  /* SCARD_E_PCI_TOO_SMALL : The PCI Receive buffer was too small. */
@@ -113,8 +113,10 @@ void Init_PCSC_Consts() {
113
113
  rb_define_const(mPcsc, "STATE_INUSE", INT2NUM(SCARD_STATE_INUSE));
114
114
  /* SCARD_STATE_MUTE : Unresponsive card. */
115
115
  rb_define_const(mPcsc, "STATE_MUTE", INT2NUM(SCARD_STATE_MUTE));
116
+ #if defined(SCARD_STATE_UNPOWERED)
116
117
  /* SCARD_STATE_UNPOWERED : Unpowered card. */
117
118
  rb_define_const(mPcsc, "STATE_UNPOWERED", INT2NUM(SCARD_STATE_UNPOWERED));
119
+ #endif /* SCARD_STATE_UNPOWERED */
118
120
 
119
121
  /* INFINITE : Infinite timeout. */
120
122
  rb_define_const(mPcsc, "INFINITE_TIMEOUT", INT2NUM(INFINITE));
@@ -89,8 +89,12 @@ static VALUE PCSC_Context_is_valid(VALUE self) {
89
89
  Data_Get_Struct(self, struct SCardContextEx, context);
90
90
  if(context == NULL) return self;
91
91
 
92
- context->pcsc_error = SCardIsValidContext(context->pcsc_context);
92
+ #if defined(RB_SMARTCARD_OSX_TIGER_HACK)
93
+ return Qtrue;
94
+ #else
95
+ context->pcsc_error = SCardIsValidContext(context->pcsc_context);
93
96
  return (context->pcsc_error == SCARD_S_SUCCESS) ? Qtrue : Qfalse;
97
+ #endif
94
98
  }
95
99
 
96
100
  /* :Document-method: list_reader_groups
data/smartcard.gemspec CHANGED
@@ -1,11 +1,11 @@
1
1
 
2
- # Gem::Specification for Smartcard-0.2.0
2
+ # Gem::Specification for Smartcard-0.2.1
3
3
  # Originally generated by Echoe
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = %q{smartcard}
7
- s.version = "0.2.0"
8
- s.date = %q{2007-11-18}
7
+ s.version = "0.2.1"
8
+ s.date = %q{2007-11-19}
9
9
  s.summary = %q{Interface with ISO 7816 smart cards.}
10
10
  s.require_paths = ["lib", "ext"]
11
11
  s.email = %q{victor@costan.us}
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
14
14
  s.description = %q{Interface with ISO 7816 smart cards.}
15
15
  s.has_rdoc = true
16
16
  s.authors = ["Victor Costan"]
17
- s.files = ["CHANGELOG", "ext/smartcard_pcsc/extconf.rb", "ext/smartcard_pcsc/pcsc.h", "ext/smartcard_pcsc/pcsc_card.c", "ext/smartcard_pcsc/pcsc_constants.c", "ext/smartcard_pcsc/pcsc_context.c", "ext/smartcard_pcsc/pcsc_io_request.c", "ext/smartcard_pcsc/pcsc_main.c", "ext/smartcard_pcsc/pcsc_multi_strings.c", "ext/smartcard_pcsc/pcsc_namespace.c", "ext/smartcard_pcsc/pcsc_reader_states.c", "ext/smartcard_pcsc/pcsc_surrogate_reader.h", "ext/smartcard_pcsc/pcsc_surrogate_wintypes.h", "lib/smartcard.rb", "LICENSE", "README", "test/test_all.rb", "tests/ts_pcsc_ext.rb", "Manifest", "smartcard.gemspec"]
17
+ s.files = ["BUILD", "CHANGELOG", "ext/smartcard_pcsc/extconf.rb", "ext/smartcard_pcsc/pcsc.h", "ext/smartcard_pcsc/pcsc_card.c", "ext/smartcard_pcsc/pcsc_constants.c", "ext/smartcard_pcsc/pcsc_context.c", "ext/smartcard_pcsc/pcsc_io_request.c", "ext/smartcard_pcsc/pcsc_main.c", "ext/smartcard_pcsc/pcsc_multi_strings.c", "ext/smartcard_pcsc/pcsc_namespace.c", "ext/smartcard_pcsc/pcsc_reader_states.c", "ext/smartcard_pcsc/pcsc_surrogate_reader.h", "ext/smartcard_pcsc/pcsc_surrogate_wintypes.h", "lib/smartcard.rb", "LICENSE", "Manifest", "README", "test/test_all.rb", "tests/ts_pcsc_ext.rb", "smartcard.gemspec"]
18
18
  s.test_files = ["test/test_all.rb"]
19
19
  s.extensions = ["ext/smartcard_pcsc/extconf.rb"]
20
20
  end
@@ -24,6 +24,7 @@ end
24
24
  #
25
25
  # # Needs the 'echoe' gem
26
26
  # require 'echoe'
27
+ # require 'pp'
27
28
  #
28
29
  # Echoe.new('smartcard') do |p|
29
30
  # p.project = 'smartcard' # rubyforge project
@@ -35,6 +36,7 @@ end
35
36
  #
36
37
  # p.need_tar_gz = false
37
38
  # p.clean_pattern += ['ext/**/*.manifest', 'ext/**/*_autogen.h']
39
+ # p.rdoc_pattern = /^(lib|bin|tasks|ext)|^BUILD|^README|^CHANGELOG|^TODO|^LICENSE|^COPYING$/
38
40
  #
39
41
  # p.eval = proc do |p|
40
42
  # case RUBY_PLATFORM
data/tests/ts_pcsc_ext.rb CHANGED
@@ -99,7 +99,11 @@ card0 = Smartcard::PCSC::Card.new(context, reader0, Smartcard::PCSC::SHARE_SHARE
99
99
  card0.begin_transaction
100
100
  card0.end_transaction Smartcard::PCSC::DISPOSITION_LEAVE
101
101
 
102
+ begin
102
103
  card0.reconnect Smartcard::PCSC::SHARE_EXCLUSIVE, Smartcard::PCSC::PROTOCOL_ANY, Smartcard::PCSC::INITIALIZATION_RESET
104
+ rescue RuntimeException => e
105
+ puts "Card.reconnect threw exception #{e}\n"
106
+ end
103
107
 
104
108
  card_status = card0.status
105
109
  pp card_status
@@ -132,4 +136,4 @@ end
132
136
 
133
137
  puts "Disconnecting and cleaning up\n"
134
138
  card0.disconnect Smartcard::PCSC::DISPOSITION_LEAVE
135
- context.release
139
+ context.release
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: smartcard
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.2.0
7
- date: 2007-11-18 00:00:00 -05:00
6
+ version: 0.2.1
7
+ date: 2007-11-19 00:00:00 -05:00
8
8
  summary: Interface with ISO 7816 smart cards.
9
9
  require_paths:
10
10
  - lib
@@ -30,6 +30,7 @@ post_install_message:
30
30
  authors:
31
31
  - Victor Costan
32
32
  files:
33
+ - BUILD
33
34
  - CHANGELOG
34
35
  - ext/smartcard_pcsc/extconf.rb
35
36
  - ext/smartcard_pcsc/pcsc.h
@@ -45,10 +46,10 @@ files:
45
46
  - ext/smartcard_pcsc/pcsc_surrogate_wintypes.h
46
47
  - lib/smartcard.rb
47
48
  - LICENSE
49
+ - Manifest
48
50
  - README
49
51
  - test/test_all.rb
50
52
  - tests/ts_pcsc_ext.rb
51
- - Manifest
52
53
  - smartcard.gemspec
53
54
  test_files:
54
55
  - test/test_all.rb