Skip to content

Commit a3e10b0

Browse files
committed
add support for choosing a serial
1 parent e614418 commit a3e10b0

File tree

6 files changed

+36
-6
lines changed

6 files changed

+36
-6
lines changed

cmd/profiles_rotate.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
func init() {
1212
profilesCmd.AddCommand(profilesRotateCmd)
1313
profilesRotateCmd.Flags().BoolP("yubikey", "y", false, "Store MFA on yubikey")
14+
profilesRotateCmd.Flags().String("serial", "", "Yubikey serial to use")
1415
}
1516

1617
var profilesRotateCmd = &cobra.Command{
@@ -30,10 +31,15 @@ func profilesRotateRunner(cmd *cobra.Command, args []string) error {
3031
return err
3132
}
3233

34+
serial, err := cmd.Flags().GetString("serial")
35+
if err != nil {
36+
return err
37+
}
38+
3339
var mfaPrompt creds.MfaPrompt
3440
if useYubikey {
3541
mfaPrompt = &creds.MultiMfaPrompt{Backends: []creds.MfaPrompt{
36-
yubikey.NewPrompt(),
42+
yubikey.NewPromptWithSerial(serial),
3743
&creds.DefaultMfaPrompt{},
3844
}}
3945
} else {

cmd/travel.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ func init() {
2424
travelCmd.Flags().String("profile", "", "Choose source profile to use")
2525
travelCmd.Flags().StringP("prompt", "p", "", "Choose prompt to use")
2626
travelCmd.Flags().BoolP("yubikey", "y", false, "Use Yubikey for MFA")
27+
travelCmd.Flags().String("serial", "", "Yubikey serial to use")
2728
travelCmd.Flags().String("service", "", "Service path for console URL")
2829
}
2930

@@ -56,6 +57,11 @@ func travelRunner(cmd *cobra.Command, args []string) error {
5657
return err
5758
}
5859

60+
serial, err := cmd.Flags().GetString("serial")
61+
if err != nil {
62+
return err
63+
}
64+
5965
servicePath, err := flags.GetString("service")
6066
if err != nil {
6167
return err
@@ -79,7 +85,7 @@ func travelRunner(cmd *cobra.Command, args []string) error {
7985
opts := travel.DefaultTraverseOptions()
8086
if useYubikey {
8187
opts.MfaPrompt = &creds.MultiMfaPrompt{Backends: []creds.MfaPrompt{
82-
yubikey.NewPrompt(),
88+
yubikey.NewPromptWithSerial(serial),
8389
&creds.DefaultMfaPrompt{},
8490
}}
8591
}

cmd/xargs.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ func init() {
2626
xargsCmd.Flags().String("profile", "", "Choose source profile to use")
2727
xargsCmd.Flags().StringP("prompt", "p", "", "Choose prompt to use")
2828
xargsCmd.Flags().BoolP("yubikey", "y", false, "Use Yubikey for MFA")
29+
xargsCmd.Flags().String("serial", "", "Yubikey serial to use")
2930
xargsCmd.Flags().StringP("command", "c", "", "Command to execute")
3031
xargsCmd.Flags().Bool("skipconfirm", false, "Skip confirmation prompt")
3132
}
@@ -59,6 +60,11 @@ func xargsRunner(cmd *cobra.Command, args []string) error {
5960
return err
6061
}
6162

63+
serial, err := cmd.Flags().GetString("serial")
64+
if err != nil {
65+
return err
66+
}
67+
6268
commandStr, err := flags.GetString("command")
6369
if err != nil {
6470
return err
@@ -85,7 +91,7 @@ func xargsRunner(cmd *cobra.Command, args []string) error {
8591
opts := travel.DefaultTraverseOptions()
8692
if useYubikey {
8793
opts.MfaPrompt = &creds.MultiMfaPrompt{Backends: []creds.MfaPrompt{
88-
yubikey.NewPrompt(),
94+
yubikey.NewPromptWithSerial(serial),
8995
&creds.DefaultMfaPrompt{},
9096
}}
9197
}

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ go 1.18
44

55
replace github.com/ktr0731/go-fuzzyfinder => github.com/akerl/go-fuzzyfinder v0.1.2-0.20200507171954-7f19dd52209e
66

7+
replace github.com/yawn/ykoath => github.com/akerl/ykoath v0.0.0-20230103063257-aefeeb4a3d6e
8+
79
require (
810
github.com/99designs/keyring v1.2.1
911
github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ github.com/akerl/speculate/v2 v2.6.2 h1:kj8z+2DScnqRiCBpvFgXvpvHH+u5pr1yV963tPvf
1919
github.com/akerl/speculate/v2 v2.6.2/go.mod h1:rDf7gUb/C3KFXqFzT/E2wFxW9u5e3mKJpkAL783wctg=
2020
github.com/akerl/timber/v2 v2.0.1 h1:hY4VCOJns7KsxwxP/ifSt3Rz9GZCfKewapaimObnA2E=
2121
github.com/akerl/timber/v2 v2.0.1/go.mod h1:jBjRGI2CWuvbZlrZkp1JO/X51pMlbg72NFy+Vnd59oI=
22+
github.com/akerl/ykoath v0.0.0-20230103063257-aefeeb4a3d6e h1:WpPMCdrKJvy5u4hX6rFGa+Ugy0mbTSBHYW8+gfRAX4Q=
23+
github.com/akerl/ykoath v0.0.0-20230103063257-aefeeb4a3d6e/go.mod h1:dcXMmLrvt6WFkySkG2k8ZEqxiTbu/TWSI4+/Cb54+Lg=
2224
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
2325
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
2426
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
@@ -178,8 +180,6 @@ github.com/vbauerster/mpb/v4 v4.12.2 h1:TsBs1nWRYF0m8cUH13pxNhOUqY6yKcOr2PeSYxp2
178180
github.com/vbauerster/mpb/v4 v4.12.2/go.mod h1:LVRGvMch8T4HQO3eg2pFPsACH9kO/O6fT/7vhGje3QE=
179181
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
180182
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
181-
github.com/yawn/ykoath v1.0.4 h1:kGYMr7um0mmLl/lnpgeH7+waQL9WyncsamMsVT/KWbQ=
182-
github.com/yawn/ykoath v1.0.4/go.mod h1:dcXMmLrvt6WFkySkG2k8ZEqxiTbu/TWSI4+/Cb54+Lg=
183183
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
184184
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
185185
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=

yubikey/main.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,22 @@ func homeDir() (string, error) {
6363
// Prompt defines a yubikey prompt object
6464
type Prompt struct {
6565
mapping map[string]string
66+
serial string
6667
}
6768

6869
// NewPrompt populates the yubikey mapping from a dotfile, if it exists
6970
func NewPrompt() *Prompt {
71+
return NewPromptWithSerial("")
72+
}
73+
74+
// NewPromptWithSerial creates a new prompt with a specific serial
75+
func NewPromptWithSerial(serial string) *Prompt {
7076
logger.InfoMsg("creating new yubikey prompt object")
7177
p := Prompt{}
78+
if serial != "" {
79+
logger.InfoMsgf("setting yubikey serial to %s", serial)
80+
p.serial = serial
81+
}
7282
file, err := mappingFile()
7383
if err != nil {
7484
logger.InfoMsgf("failed to load mapping file: %s", err)
@@ -205,7 +215,7 @@ func (p *Prompt) otpCode(name string) (string, error) {
205215

206216
func (p *Prompt) getDevice() (*ykoath.OATH, error) {
207217
logger.InfoMsg("creating new yubikey oath device")
208-
oath, err := ykoath.New()
218+
oath, err := ykoath.NewFromSerial(p.serial)
209219
if err != nil {
210220
return nil, err
211221
}

0 commit comments

Comments
 (0)