Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion lib/config/fileconf.go
Original file line number Diff line number Diff line change
Expand Up @@ -1282,6 +1282,9 @@ type HardwareKey struct {
// SerialNumberValidation contains optional settings for hardware key
// serial number validation, including whether it is enabled.
SerialNumberValidation *HardwareKeySerialNumberValidation `yaml:"serial_number_validation,omitempty"`

// PINCacheTTL specifies how long to cache the user's PIV PIN.
PINCacheTTL time.Duration `yaml:"pin_cache_ttl,omitempty"`
}

func (h *HardwareKey) Parse() (*types.HardwareKey, error) {
Expand All @@ -1291,7 +1294,10 @@ func (h *HardwareKey) Parse() (*types.HardwareKey, error) {
}
}

hk := &types.HardwareKey{PIVSlot: string(h.PIVSlot)}
hk := &types.HardwareKey{
PIVSlot: string(h.PIVSlot),
PinCacheTTL: types.Duration(h.PINCacheTTL),
}

if h.SerialNumberValidation != nil {
var err error
Expand Down
113 changes: 113 additions & 0 deletions lib/config/fileconf_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,119 @@ func TestSSHSection(t *testing.T) {
}
}

func TestHardwareKeyConfig(t *testing.T) {
for _, tc := range []struct {
name string
mutate func(cfgMap)
expectReadError require.ErrorAssertionFunc
expectParseError require.ErrorAssertionFunc
expectHardwareKeyConfig *types.HardwareKey
}{
{
name: "OK empty",
mutate: func(cfg cfgMap) {
cfg["auth_service"].(cfgMap)["authentication"] = cfgMap{
"hardware_key": cfgMap{},
}
},
expectHardwareKeyConfig: &types.HardwareKey{},
},
{
name: "OK piv_slot",
mutate: func(cfg cfgMap) {
cfg["auth_service"].(cfgMap)["authentication"] = cfgMap{
"hardware_key": cfgMap{
"piv_slot": "9a",
},
}
},
expectHardwareKeyConfig: &types.HardwareKey{
PIVSlot: "9a",
},
},
{
name: "NOK piv_slot unsupported slot",
mutate: func(cfg cfgMap) {
cfg["auth_service"].(cfgMap)["authentication"] = cfgMap{
"hardware_key": cfgMap{
"piv_slot": "8f",
},
}
},
expectParseError: func(t require.TestingT, err error, i ...interface{}) {
require.Error(t, err)
require.True(t, trace.IsBadParameter(err), "got err = %v, want BadParameter", err)
},
},
{
name: "OK serial_number_validation",
mutate: func(cfg cfgMap) {
cfg["auth_service"].(cfgMap)["authentication"] = cfgMap{
"hardware_key": cfgMap{
"serial_number_validation": cfgMap{
"enabled": true,
"serial_number_trait_name": "custom_trait_name",
},
},
}
},
expectHardwareKeyConfig: &types.HardwareKey{
SerialNumberValidation: &types.HardwareKeySerialNumberValidation{
Enabled: true,
SerialNumberTraitName: "custom_trait_name",
},
},
},
{
name: "OK pin_cache_ttl",
mutate: func(cfg cfgMap) {
cfg["auth_service"].(cfgMap)["authentication"] = cfgMap{
"hardware_key": cfgMap{
"pin_cache_ttl": "1m",
},
}
},
expectHardwareKeyConfig: &types.HardwareKey{
PinCacheTTL: types.Duration(time.Minute),
},
},
{
name: "NOK pin_cache_ttl not a duration",
mutate: func(cfg cfgMap) {
cfg["auth_service"].(cfgMap)["authentication"] = cfgMap{
"hardware_key": cfgMap{
"pin_cache_ttl": "1minute",
},
}
},
expectReadError: require.Error,
},
} {
t.Run(tc.name, func(t *testing.T) {
text := bytes.NewBuffer(editConfig(t, tc.mutate))

cfg, err := ReadConfig(text)
if tc.expectReadError != nil {
tc.expectReadError(t, err)
return
}
require.NoError(t, err)

cap, err := cfg.Auth.Authentication.Parse()
if tc.expectParseError != nil {
tc.expectParseError(t, err)
return
}
require.NoError(t, err)

hardwareKeyConfig, err := cap.GetHardwareKey()
require.NoError(t, err)

require.Equal(t, tc.expectHardwareKeyConfig, hardwareKeyConfig)
})
}
}

func TestX11Config(t *testing.T) {
testCases := []struct {
desc string
Expand Down
Loading