处理唤起 MacOS 安全窗口的 shell 命令的 Ruby 方式

发布于 2024-12-03 20:42:40 字数 1957 浏览 2 评论 0原文

我有一个简单的问题,我想看看这里的人是否可以帮助我。目前,我正在编写一些测试自动化来处理一个简单的内部命令行工具,该工具转储智能卡的内容。在转储此智能卡信息的过程中,它会调用 PIN 输入窗口,用户需要输入 PIN 码信息才能解锁智能卡。我遇到的问题有两个方面。

  1. 如何在 ruby​​ 中处理这样的弹出窗口?这是通过 rb_appscript 完成的吗?或者类似的东西?如果这是可能的(我无法弄清楚),那么如何获取该窗口的 id、名称等,然后捕获文本输入事件?看起来很难。

  2. 只有当您有“多个”PIN 窗口需要处理时,这种情况才会发生。对于 CAC 卡,有一个解锁 PIN 事件,可以通过一个名为“安全”的简单钥匙串 cli 在脚本的早期轻松处理该事件:

此事件:

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

如果在卡转储之前调用,将解锁钥匙串并在没有 PIN 提示的情况下转储卡。

但是,如果该卡是 PIV 卡,tokend 中似乎存在一个错误,会在卡内提供 4 个以上的 PIN 提示以获取证书。因此上述命令仅适用于一次解锁事件。我尝试过连续发送 4 个解锁事件,但这似乎无法处理它。我被困在一个 PIN 输入窗口中,如下所示:

在此处输入图像描述

我很好奇人们会如何在 Ruby 中处理此操作,可以通过我不知道的另一个 ruby​​ gem 的 rb_appscript 来完成吗?你能把这个串起来吗?

这是我的代码,请原谅硬编码,但我现在只是在嘲笑:

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

我正在查看 gem 'session' 和其他一些交互式 shell gem,但它们似乎无法处理这个问题。如果我能找到一种方法在 ruby​​ 代码中处理该窗口,那至少可以让我破解所有 PIN 提示?或者有一个循环来查找那些弹出窗口,在弹出窗口中输入卡的 PIN 码,我至少会处理这个问题。

任何帮助将不胜感激。


我想我明白你在说什么..但由于这是一个并行进程,也就是说,事件需要被捕获,我不确定这是否

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

有效,因为一个 ruby​​ 进程正在运行。我想我可以把它放在一个循环中并以这种方式寻找窗口?但是,不太确定

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

酒解孤独 2024-12-10 20:42:41

除非应用程序明确提供 AppleScript 函数,否则您无法使用 Appscript,在本例中我对此非常怀疑。您可以打开 AppleScript 编辑器,然后查看应用程序的库,以查看它提供的所有可用功能。就您而言,您可能需要像 Keyboard Maestro 这样的东西,它可以模拟键盘输入。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文