Closed donferi closed 3 years ago
Try running expect
in debug mode (pass the -d
flag to the command in expect.sh
), and see what the output tells you. Specifically, look for what observed output doesn't match the expected output...
Interesting, it seems like it's not matching the PIN:
until the nError changing the PIN:
🤔
expect: does "passwd\r\ngpg: OpenPGP card no. <num> detected\r\n\r\n1 - change PIN\r\n2 - unblock PIN\r\n3 - change Admin PIN\r\n4 - set the Reset Code\r\nQ - quit\r\n\r\n" (spawn_id exp8) match exact string "Your selection? "? no
Your selection?
expect: does "passwd\r\ngpg: OpenPGP card no. <num> detected\r\n\r\n1 - change PIN\r\n2 - unblock PIN\r\n3 - change Admin PIN\r\n4 - set the Reset Code\r\nQ - quit\r\n\r\nYour selection? " (spawn_id exp8) match exact string "Your selection? "? yes
expect: set expect_out(0,string) "Your selection? "
expect: set expect_out(spawn_id) "exp8"
expect: set expect_out(buffer) "passwd\r\ngpg: OpenPGP card no. <num> detected\r\n\r\n1 - change PIN\r\n2 - unblock PIN\r\n3 - change Admin PIN\r\n4 - set the Reset Code\r\nQ - quit\r\n\r\nYour selection? "
send: sending "1\r" to { exp8 }
expect: does "" (spawn_id exp8) match exact string "PIN: "? no
1
expect: does "1\r\n" (spawn_id exp8) match exact string "PIN: "? no
Please enter the PIN
PIN:
Error changing the PIN: Timeout
1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit
expect: does "1\r\nError changing the PIN: Timeout\r\n\r\n1 - change PIN\r\n2 - unblock PIN\r\n3 - change Admin PIN\r\n4 - set the Reset Code\r\nQ - quit\r\n\r\n" (spawn_id exp8) match exact string "PIN: "? yes
expect: set expect_out(0,string) "PIN: "
expect: set expect_out(spawn_id) "exp8"
expect: set expect_out(buffer) "1\r\nError changing the PIN: "
send: sending "123456\r" to { exp8 }
expect: does "Timeout\r\n\r\n1 - change PIN\r\n2 - unblock PIN\r\n3 - change Admin PIN\r\n4 - set the Reset Code\r\nQ - quit\r\n\r\n" (spawn_id exp8) match exact string "PIN: "? no
Your selection? 123456
I'm sorry, but without knowing more about your setup or carefully looking through your output, it's hard to tell exactly what's happening.
As a temporary workaround, I recommend running the commands in the expect script manually. Sorry about that.
@donferi can you try to add a sleep 1
line 87 in expect.sh ?
@daisukixci Thanks for the help! Tried it out and got the same issue, seems like it's not sending the keys until the next expect operation, but that doesn't make a lot of sense 😂
1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit
expect: does "passwd\r\ngpg: OpenPGP card no. <num> detected\r\n\r\n1 - change PIN\r\n2 - unblock PIN\r\n3 - change Admin PIN\r\n4 - set the Reset Code\r\nQ - quit\r\n\r\n" (spawn_id exp8) match exact string "Your selection? "? no
Your selection?
expect: does "passwd\r\ngpg: OpenPGP card no. <num> detected\r\n\r\n1 - change PIN\r\n2 - unblock PIN\r\n3 - change Admin PIN\r\n4 - set the Reset Code\r\nQ - quit\r\n\r\nYour selection? " (spawn_id exp8) match exact string "Your selection? "? yes
expect: set expect_out(0,string) "Your selection? "
expect: set expect_out(spawn_id) "exp8"
expect: set expect_out(buffer) "passwd\r\ngpg: OpenPGP card no. <num> detected\r\n\r\n1 - change PIN\r\n2 - unblock PIN\r\n3 - change Admin PIN\r\n4 - set the Reset Code\r\nQ - quit\r\n\r\nYour selection? "
send: sending "1\r" to { exp8 }
Sleeping for 5 seconds
expect: does "" (spawn_id exp8) match exact string "PIN: "? no
1
expect: does "1\r\n" (spawn_id exp8) match exact string "PIN: "? no
Please enter the PIN
PIN:
Error changing the PIN: Timeout
1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit
expect: does "1\r\nError changing the PIN: Timeout\r\n\r\n1 - change PIN\r\n2 - unblock PIN\r\n3 - change Admin PIN\r\n4 - set the Reset Code\r\nQ - quit\r\n\r\n" (spawn_id exp8) match exact string "PIN: "? yes
expect: set expect_out(0,string) "PIN: "
expect: set expect_out(spawn_id) "exp8"
expect: set expect_out(buffer) "1\r\nError changing the PIN: "
send: sending "123456\r" to { exp8 }
expect: does "Timeout\r\n\r\n1 - change PIN\r\n2 - unblock PIN\r\n3 - change Admin PIN\r\n4 - set the Reset Code\r\nQ - quit\r\n\r\n" (spawn_id exp8) match exact string "PIN: "? no
Your selection? 123456
Will take a look this weekend
I haven't been able to reproduce with my keys. Can you share a bit of your configuration (hardware, OS and shell used). Can you share the all output please ?
In the meantime can you try with this expect.sh version
#!/usr/bin/env expect
#
# This Expect script was generated by autoexpect on Wed Aug 1 17:10:59 2018
# Expect and autoexpect were both written by Don Libes, NIST.
#
# Note that autoexpect does not guarantee a working script. It
# necessarily has to guess about certain things. Two reasons a script
# might fail are:
#
# 1) timing - A surprising number of programs (rn, ksh, zsh, telnet,
# etc.) and devices discard or ignore keystrokes that arrive "too
# quickly" after prompts. If you find your new script hanging up at
# one spot, try adding a short sleep just before the previous send.
# Setting "force_conservative" to 1 (see below) makes Expect do this
# automatically - pausing briefly before sending each character. This
# pacifies every program I know of. The -c flag makes the script do
# this in the first place. The -C flag allows you to define a
# character to toggle this mode off and on.
set force_conservative 1 ;# set to 1 to force conservative mode even if
;# script was not run conservatively originally
if {$force_conservative} {
set send_slow {1 .1}
proc send {ignore arg} {
sleep .1
exp_send -s -- $arg
}
}
#
# 2) differing output - Some programs produce different output each time
# they run. The "date" command is an obvious example. Another is
# ftp, if it produces throughput statistics at the end of a file
# transfer. If this causes a problem, delete these patterns or replace
# them with wildcards. An alternative is to use the -p flag (for
# "prompt") which makes Expect only look for the last line of output
# (i.e., the prompt). The -P flag allows you to define a character to
# toggle this mode off and on.
#
# Read the man page for more info.
#
# -Don
set timeout -1
match_max 100000
# https://stackoverflow.com/a/17060172
set TOUCH_POLICY [lindex $argv 0];
set PUK [lindex $argv 1];
set GPG_HOMEDIR [lindex $argv 2];
set PIN [lindex $argv 3];
set KEY_LENGTH [lindex $argv 4];
set REALNAME [lindex $argv 5];
set EMAIL [lindex $argv 6];
set COMMENT [lindex $argv 7];
# Turn off OTP.
send_user "Turning off YubiKey OTP:\n"
spawn ykman mode "FIDO+CCID"
expect {
"Mode is already FIDO+CCID, nothing to do..." {
expect eof
}
": " {
send -- "y\r"
expect eof
}
}
# Set up PIN, PUK, and then generate keys on card.
send_user "Now generating your GPG keys on the YubiKey itself.\n"
spawn gpg --homedir=$GPG_HOMEDIR --card-edit
expect -exact "gpg/card> "
send -- "admin\r"
# https://developers.yubico.com/PGP/Card_edit.html
sleep 2
expect -exact "gpg/card> "
send -- "passwd\r"
sleep 2
# Change PIN
expect -exact "Your selection? "
send -- "1\r"
sleep 2
# Default PIN
expect -exact "PIN: "
send -- "123456\r"
sleep 2
# New PIN
expect -exact "PIN: "
send -- "$PIN\r"
sleep 2
# Repeat new PIN
expect -exact "PIN: "
send -- "$PIN\r"
sleep 2
# Change PUK
expect -exact "Your selection? "
send -- "3\r"
sleep 2
# Default PUK
expect -exact "Admin PIN: "
send -- "12345678\r"
sleep 2
# New PUK
expect -exact "Admin PIN: "
send -- "$PUK\r"
sleep 2
# Repeat new PUK
expect -exact "Admin PIN: "
send -- "$PUK\r"
sleep 2
# Get out of passwd menu
expect -exact "Your selection? "
send -- "q\r"
# Set desired key attributes.
expect -exact "gpg/card> "
send -- "key-attr\r"
# Signature key.
expect -exact "Your selection? "
# RSA
send -- "1\r"
expect "What keysize do you want? (*) "
send -- "$KEY_LENGTH\r"
# Send new PUK
expect -exact "Admin PIN: "
send -- "$PUK\r"
# Encryption key.
expect -exact "Your selection? "
# RSA
send -- "1\r"
expect "What keysize do you want? (*) "
send -- "$KEY_LENGTH\r"
# Send new PUK
expect -exact "Admin PIN: "
send -- "$PUK\r"
# Authentication key.
expect -exact "Your selection? "
# RSA
send -- "1\r"
expect "What keysize do you want? (*) "
send -- "$KEY_LENGTH\r"
# Send new PUK
expect -exact "Admin PIN: "
send -- "$PUK\r"
# Time to generate.
expect -exact "gpg/card> "
send -- "generate\r"
expect -exact "Make off-card backup of encryption key? (Y/n) "
send -- "n\r"
# Send new PIN
expect -exact "PIN: "
send -- "$PIN\r"
expect -exact "Key is valid for? (0) "
send -- "10y\r"
expect -exact "Is this correct? (y/N) "
send -- "y\r"
expect -exact "Real name: "
send -- "$REALNAME\r"
expect -exact "Email address: "
send -- "$EMAIL\r"
expect -exact "Comment: "
send -- "$COMMENT\r"
expect -exact "Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? "
send -- "O\r"
# Send new PUK
expect -exact "Admin PIN: "
send -- "$PUK\r"
send_user "\nNow generating keys on card, lights will be flashing, this will take a few minutes, please wait...\n"
expect -exact "gpg/card> "
send -- "quit\r"
expect eof
# Turn on touch for SIGNATURES.
send_user "Now requiring you to touch your Yubikey to sign any message.\n"
spawn ykman openpgp set-touch sig $TOUCH_POLICY
expect -exact "Enter admin PIN: "
stty -echo
send -- "$PUK\r"
expect -exact "Set touch policy of signature key to $TOUCH_POLICY? \[y/N\]: "
send -- "y\r"
expect eof
# Turn on touch for AUTHENTICATION.
send_user "Now requiring you to touch your Yubikey to authenticate SSH.\n"
spawn ykman openpgp set-touch aut on
expect -exact "Enter admin PIN: "
stty -echo
send -- "$PUK\r"
expect -exact "Set touch policy of authentication key to on? \[y/N\]: "
send -- "y\r"
expect eof
# Turn on touch for ENCRYPTION.
send_user "Now requiring you to touch your Yubikey to encrypt any message.\n"
spawn ykman openpgp set-touch enc on
expect -exact "Enter admin PIN: "
stty -echo
send -- "$PUK\r"
expect -exact "Set touch policy of encryption key to on? \[y/N\]: "
send -- "y\r"
expect eof
# Touch for ATTESTATION works only for Yubico firmware >= 5.2.3.
# https://support.yubico.com/support/solutions/articles/15000027139-yubikey-5-2-3-enhancements-to-openpgp-3-4-support
Best to read his debug log or do a remote Zoom debugging session, I think...
Sorry for the late response, I'd be down for a Zoom / vscode remote debugging session. I'm on CST (GMT -6) timezone. I could do anytime as long is not in the middle of the night. Or I could post more info here, whatever you guys prefer 👍
Sorry for the long term issue :(, GPG has new version and we updated the expect script to make it compatible, @donferi are you able to test the new version available in https://github.com/DataDog/yubikey/pull/61
@daisukixci Thanks for the reply! Unfortunately I'm still getting the same issue.
@donferi can you try to add set stty_init -echo
to line 19 of expect.sh and try to run gpg.sh :man-bowing:
EDIT: made a branch https://github.com/DataDog/yubikey/pull/68 so you just have to checkout in it
@donferi a DD user find a way to fix similar error on his laptop, can you try to run the script this way GPG_TTY="" ./gpg.sh
I'm trying to get this awesome setup working but when running
./gpg.sh
it hangs when trying to change the PIN. It correctly selects the option1
but then it never types the pin, after it timesout I can see the123456
.Eg:
I tried bumping the sleep in
expect.sh
to1
, switching from zsh to bash, but I can't seem to figure out what is going on, I can't get it to type it at the right time.Any help would be greatly appreciated.