Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for retrieving all IdentityFile directives #28

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
22 changes: 17 additions & 5 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ var _ = version

type configFinder func() string

type config interface {
getinternal(alias, key string) string
}

var _ config = &UserSettings{}
var _ config = &Config{}

// UserSettings checks ~/.ssh and /etc/ssh for configuration files. The config
// files are parsed and cached the first time Get() or GetStrict() is called.
type UserSettings struct {
Expand Down Expand Up @@ -180,6 +187,10 @@ func (u *UserSettings) Get(alias, key string) string {
return val
}

func (u *UserSettings) getinternal(alias, key string) string {
return u.Get(alias, key)
}

// GetAll retrieves zero or more directives for key for the given alias. GetAll
// returns nil if no value was found, or if IgnoreErrors is false and we could
// not parse the configuration file. Use GetStrict to disambiguate the latter
Expand Down Expand Up @@ -237,11 +248,7 @@ func (u *UserSettings) GetAllStrict(alias, key string) ([]string, error) {
if err2 != nil || val2 != nil {
return val2, err2
}
// TODO: IdentityFile has multiple default values that we should return.
if def := Default(key); def != "" {
return []string{def}, nil
}
return []string{}, nil
return DefaultAll(key, alias, u), nil
}

func (u *UserSettings) doLoadConfigs() {
Expand Down Expand Up @@ -365,6 +372,11 @@ func (c *Config) Get(alias, key string) (string, error) {
return "", nil
}

func (c *Config) getinternal(alias, key string) string {
v, _ := c.Get(alias, key)
return v
}

// GetAll returns all values in the configuration that match the alias and
// contains key, or nil if none are present.
func (c *Config) GetAll(alias, key string) ([]string, error) {
Expand Down
3 changes: 1 addition & 2 deletions config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,7 @@ func TestGetIdentities(t *testing.T) {
t.Errorf("expected nil err, got %v", err)
}
if len(val) != len(defaultProtocol2Identities) {
// TODO: return the right values here.
log.Printf("expected defaults, got %v", val)
t.Errorf("expected defaults, got %v", val)
} else {
for i, v := range defaultProtocol2Identities {
if val[i] != v {
Expand Down
20 changes: 20 additions & 0 deletions validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,26 @@ func Default(keyword string) string {
return defaults[strings.ToLower(keyword)]
}

// DefaultAll returns the default value for the given keyword, but as a slice. If
// there is no default for the keyword, nil is returned.
//
// Some multi-valued settings have different defaults based on other settings, so
// you must provide the host alias and a config to retrieve a setting from
func DefaultAll(keyword string, alias string, cfg config) []string {
if strings.ToLower(keyword) == "identityfile" && cfg.getinternal(alias, "Protocol") == "2" {
def := make([]string, len(defaultProtocol2Identities))
copy(def, defaultProtocol2Identities)
return def
}

def := Default(keyword)
if def != "" {
return []string{def}
}

return nil
}

// Arguments where the value must be "yes" or "no" and *only* yes or no.
var yesnos = map[string]bool{
strings.ToLower("BatchMode"): true,
Expand Down