3

I have a simple problem that I'd like to see if people here can help me with. Currently, I'm writing some test automation to handle a simple in house command line tool that dumps the contents of a smartcard. In the process of dumping this smartcard info, it invokes a PIN entry window that a user will need to enter in their PIN code information for smartcard unlock. The problem I'm encountering is two fold.

  1. How do you handle a pop-up like that in ruby? Is this done via rb_appscript? or something similar? And if this is possible (which I wasn't able to figure out), how does one get the id, name, etc of that window and then trap for a text entry event? seems very difficult.

  2. This case really only comes true when you have "multiple" PIN windows to handle. For CAC cards, there is one unlock PIN event, which is easily handled early in the script by a simple keychain cli called "security":

This event:

security unlock-keychain -p "12345678" "CAC-4070-4443-223E-5555-2187"

If invoked before a dump of the card will unlock the keychain and dump the card without a PIN prompt.

However, if the card is a PIV card, there seems to be a bug in tokend that presents 4 more PIN prompts for certificates within the card. So the above command will only work for one unlock event. I've tried sending 4 unlock events in row and that doesn't seem to handle it. What I'm stuck with a PIN entry window that looks like this:

enter image description here

I'm curious how one would handle this action within Ruby, could this be done via rb_appscript of another ruby gem that I'm not aware of? Could you thread this?

Here is my code, pardon the hard coding, but I'm just mocking right now:

require "open3"

complex_switch = ["-D","-k", "--pkinit"]

id = "9999999999@mil"
pin = "1234567"

# PIV is problem child
piv_keychain = "PIV-ONCE.UPON.9999999999"
cac_keychain = "CAC-9999-9999-9999-0000-9999"

#complex switch smartcard iteration
complex_switch.count.times do |i|
  command = 'security unlock-keychain -p '+pin+' '+cac_keychain+' |sctool '+complex_switch[i]+' '+id
  io_bad = Open3.popen3(command){|stdin, stdout, stderr|stderr.read}
  io_good = Open3.popen3(command){|stdin, stdout, stderr|stdout.read}
   file = "/Users/wqc/Desktop/output/sc_switch"+complex_switch[i]+".txt"
  File.open(file, 'a') do |f|  
    f.print io_bad
    f.print io_good
  end
end

I was looking at the gem 'session' and some other interactive shell gems, but they don't seem to be able to handle this problem. If I could find a way to handle that window inside my ruby code, that would at least allow me to hack through all the PIN prompts? or have a loop that looks for those window pop-ups, enters in the PIN for the card in that pop-up, I will at least have this handled.

Any help here would be greatly appreciated.


I think I understand what you're saying.. but since this is a parallel process, that is, the event needs to be trapped, I'm not sure that this:

tell application "Keyboard Maestro Engine"
  do script "Name of Your Macro"
end tell

will work, as the one ruby process is running. I guess I could put it in a loop and look for the window that way?, however, not really sure

TheMaster
  • 45,448
  • 6
  • 62
  • 85
HM Stanley
  • 145
  • 4
  • 14
  • Please use comments under individual answers to comment, or edit your question to provide additional clarification as needed. Answers are reserved for just that, answers. Stack Overflow doesn't work like a typical forum :) – Tim Post Sep 20 '11 at 22:46

1 Answers1

0

You could not use Appscript unless the application explicitly makes an AppleScript function available, which I highly doubt in this case. You can open AppleScript Editor, and look at the Library for your application, to see all the functions it makes available. In your case, you probably need something like Keyboard Maestro, which can simulate keyboard input.

Stian Håklev
  • 1,240
  • 2
  • 14
  • 26
  • thanks for the note. However, is this "keyboard maestro" have a ruby cli or something I can invoke on the command line? that's really what I need, not another GUI with which to send event down, like automator, which I'm sure might work as well? – HM Stanley Sep 20 '11 at 19:32
  • actually, I think I understand what you're saying.. but since this is a parallel process, that is, the event needs to be trapped, I'm not sure that this: tell application "Keyboard Maestro Engine" do script "Name of Your Macro" end tell will work, as the one ruby process is running. I guess I could put it in a loop and look for the window that way?, however, not really sure – HM Stanley Sep 20 '11 at 19:45