diff options
| author | Shulhan <ms@kilabit.info> | 2023-07-23 20:55:48 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2023-07-23 21:00:46 +0700 |
| commit | 37494be23811c845a90da8d04eb43fdd0723d31a (patch) | |
| tree | 8cf07f953fe8d073552278f4353f6e8a3062e523 | |
| parent | dcc33a41e7eeab8fbcaa0372a8f64299e85f2cb2 (diff) | |
| download | pakakeh.go-37494be23811c845a90da8d04eb43fdd0723d31a.tar.xz | |
ssh/config: move setting the Section field into method
Instead of setting them inside the Config, move them into the method
set under Section so we can re-use them later.
This changes also move the constants for key under Host or Match into
Section file.
| -rw-r--r-- | lib/ssh/config/config.go | 181 | ||||
| -rw-r--r-- | lib/ssh/config/section.go | 193 |
2 files changed, 196 insertions, 178 deletions
diff --git a/lib/ssh/config/config.go b/lib/ssh/config/config.go index ba79fba4..9e0d7450 100644 --- a/lib/ssh/config/config.go +++ b/lib/ssh/config/config.go @@ -9,7 +9,6 @@ import ( "errors" "fmt" "os" - "strconv" "strings" ) @@ -20,103 +19,6 @@ const ( const ( keyHost = "host" keyMatch = "match" - - // List of valid keys in Host or Match section. - keyAddKeysToAgent = "addkeystoagent" - keyAddressFamily = "addressfamily" - keyBatchMode = "batchmode" - keyBindAddress = "bindaddress" - keyBindInterface = "bindinterface" - keyCASignatureAlgorithms = "casignaturealgorithms" - keyCanonicalDomains = "canonicaldomains" - keyCanonicalizeFallbackLocal = "canonicalizefallbacklocal" - keyCanonicalizeHostname = "canonicalizehostname" - keyCanonicalizeMaxDots = "canonicalizemaxdots" - keyCanonicalizePermittedCNAMEs = "canonicalizepermittedcnames" - keyCertificateFile = "certificatefile" - keyChallengeResponseAuthentication = "challengeresponseauthentication" - keyCheckHostIP = "checkhostip" - keyClearAllForwardings = "clearallforwardings" - keyCompression = "compression" - keyConnectTimeout = "connecttimeout" - keyConnectionAttempts = "connectionattempts" - keyHostname = "hostname" - keyIdentityAgent = "identityagent" - keyIdentityFile = "identityfile" - keyPort = "port" - keySendEnv = "sendenv" - keySetEnv = "setenv" - keyUser = "user" - keyVisualHostKey = "visualhostkey" - keyXAuthLocation = "xauthlocation" -) - -// TODO: list of keys that are not implemented yet due to hard or -// unknown how to test it. -// nolint: deadcode,varcheck -const ( - keyCiphers = "ciphers" - keyControlMaster = "controlmaster" - keyControlPath = "controlpath" - keyControlPersist = "controlpersist" - keyDynamicForward = "dynamicforward" - keyEnableSSHKeysign = "enablesshkeysign" - keyEscapeChar = "escapechar" - keyExitOnForwardFailure = "keyexitonforwardfailure" - keyFingerprintHash = "fingerprinthash" - keyForwardAgent = "forwardagent" - keyForwardX11 = "forwardx11" - keyForwardX11Timeout = "forwardx11timeout" - keyForwardX11Trusted = "forwardx11trusted" - keyGatewayPorts = "gatewayports" - keyGlobalKnownHostsFile = "globalknownhostsfile" - keyGSSAPIAuthentication = "gssapiauthentication" - keyGSSAPIDelegateCredentials = "gssapidelegatecredentials" - keyHashKnownHosts = "hashknownhosts" - keyHostBasedAuthentication = "hostbasedauthentication" - keyHostBaseKeyTypes = "hostbasedkeytypes" - keyHostKeyAlgorithms = "hostkeyalgorithms" - keyHostKeyAlias = "hostkeyalias" - keyIdentitiesOnly = "identitiesonly" - keyIgnoreUnknown = "ignoreunknown" - keyInclude = "include" - keyIPQoS = "ipqos" - keyKbdInteractiveAuthentication = "kbdinteractiveauthentication" - keyKbdInteractiveDevices = "kbdinteractivedevices" - keyKexAlgorithms = "kexalgorithms" - keyLocalCommand = "localcommand" - keyLocalForward = "localforward" - keyLogLevel = "loglevel" - keyMACs = "macs" - keyNoHostAuthenticationForLocalhost = "nohostauthenticationforlocalhost" - keyNumberOfPasswordPrompts = "numberofpasswordprompts" - keyPasswordAuthentication = "passwordauthentication" - keyPermitLocalCommand = "permitlocalcommand" - keyPKCS11Provider = "pkcs11provider" - keyPreferredAuthentications = "preferredauthentications" - keyProxyCommand = "proxycommand" - keyProxyJump = "proxyjump" - keyProxyUseFdpass = "proxyusefdpass" - keyPubkeyAcceptedKeyTypes = "pubkeyacceptedkeytypes" - keyPubkeyAuthentication = "pubkeyauthentication" - keyRekeyLimit = "rekeylimit" - keyRemoteCommand = "remotecommand" - keyRemoteForward = "remoteforward" - keyRequestTTY = "requesttty" - keyRevokeHostKeys = "revokehostkeys" - keyServerAliveCountMax = "serveralivecountmax" - keyServerAliveInterval = "serveraliveinterval" - keyStreamLocalBindMask = "streamlocalbindmask" - keyStreamLocalBindUnlink = "streamlocalbindunlink" - keyStrictHostKeyChecking = "stricthostkeychecking" - keySyslogFacility = "syslogfacility" - keyTCPKeepAlive = "tcpkeepalive" - keyTunnel = "tunnel" - keyTunnelDevince = "tunneldevice" - keyUpdatehostKeys = "updatehostkeys" - keyUseKeychain = "usekeychain" - keyUserKnownHostsFile = "userknownhostsfile" - keyVerifyHostKeyDNS = "verifyhostkeydns" ) var ( @@ -181,79 +83,18 @@ func Load(file string) (cfg *Config, err error) { section = nil } section, err = newSectionMatch(value) - case keyAddKeysToAgent: - err = section.setAddKeysToAgent(value) - case keyAddressFamily: - err = section.setAddressFamily(value) - case keyBatchMode: - section.IsBatchMode, err = parseBool(key, value) - case keyBindAddress: - section.BindAddress = value - case keyBindInterface: - section.BindInterface = value - case keyCanonicalDomains: - section.CanonicalDomains = strings.Fields(value) - case keyCanonicalizeFallbackLocal: - section.IsCanonicalizeFallbackLocal, err = parseBool(key, value) - case keyCanonicalizeHostname: - err = section.setCanonicalizeHostname(value) - case keyCanonicalizeMaxDots: - section.CanonicalizeMaxDots, err = strconv.Atoi(value) - - case keyCanonicalizePermittedCNAMEs: - err = section.setCanonicalizePermittedCNAMEs(value) - - case keyCASignatureAlgorithms: - section.setCASignatureAlgorithms(value) - - case keyCertificateFile: - section.CertificateFile = append( - section.CertificateFile, - value) - - case keyChallengeResponseAuthentication: - section.IsChallengeResponseAuthentication, err = parseBool(key, value) - - case keyCheckHostIP: - section.IsCheckHostIP, err = parseBool(key, value) - - case keyClearAllForwardings: - section.IsClearAllForwardings, err = parseBool(key, value) - case keyCompression: - section.UseCompression, err = parseBool(key, value) - case keyConnectionAttempts: - section.ConnectionAttempts, err = strconv.Atoi(value) - case keyConnectTimeout: - section.ConnectTimeout, err = strconv.Atoi(value) - - case keyIdentityAgent: - section.setIdentityAgent(value) - case keyIdentityFile: - if section.useDefaultIdentityFile { - section.IdentityFile = []string{value} - section.useDefaultIdentityFile = false - } else { - section.IdentityFile = append( - section.IdentityFile, value) + if err != nil { + return nil, fmt.Errorf("%s %s line %d: %w", logp, file, x+1, err) + } + default: + if section == nil { + // No "Host" or "Match" define yet. + continue + } + err = section.set(cfg, key, value) + if err != nil { + return nil, fmt.Errorf("%s %s line %d: %w", logp, file, x+1, err) } - - case keyHostname: - section.Hostname = value - case keyPort: - section.Port = value - case keySendEnv: - section.setSendEnv(cfg.envs, value) - case keySetEnv: - section.setEnv(value) - case keyUser: - section.User = value - case keyVisualHostKey: - section.UseVisualHostKey, err = parseBool(key, value) - case keyXAuthLocation: - section.XAuthLocation = value - } - if err != nil { - return nil, fmt.Errorf("%s %s line %d: %w", logp, file, x+1, err) } } if section != nil { diff --git a/lib/ssh/config/section.go b/lib/ssh/config/section.go index f048aaad..b346b47d 100644 --- a/lib/ssh/config/section.go +++ b/lib/ssh/config/section.go @@ -9,21 +9,123 @@ import ( "fmt" "os" "path/filepath" + "strconv" "strings" "golang.org/x/crypto/ssh" "golang.org/x/term" ) +// List of valid keys in Host or Match section. +const ( + keyAddKeysToAgent = "addkeystoagent" + keyAddressFamily = "addressfamily" + keyBatchMode = "batchmode" + keyBindAddress = "bindaddress" + keyBindInterface = "bindinterface" + keyCASignatureAlgorithms = "casignaturealgorithms" + keyCanonicalDomains = "canonicaldomains" + keyCanonicalizeFallbackLocal = "canonicalizefallbacklocal" + keyCanonicalizeHostname = "canonicalizehostname" + keyCanonicalizeMaxDots = "canonicalizemaxdots" + keyCanonicalizePermittedCNAMEs = "canonicalizepermittedcnames" + keyCertificateFile = "certificatefile" + keyChallengeResponseAuthentication = "challengeresponseauthentication" + keyCheckHostIP = "checkhostip" + keyClearAllForwardings = "clearallforwardings" + keyCompression = "compression" + keyConnectTimeout = "connecttimeout" + keyConnectionAttempts = "connectionattempts" + keyHostname = "hostname" + keyIdentityAgent = "identityagent" + keyIdentityFile = "identityfile" + keyPort = "port" + keySendEnv = "sendenv" + keySetEnv = "setenv" + keyUser = "user" + keyVisualHostKey = "visualhostkey" + keyXAuthLocation = "xauthlocation" +) + +// TODO: list of keys that are not implemented yet due to hard or +// unknown how to test it. +// nolint: deadcode,varcheck +const ( + keyCiphers = "ciphers" + keyControlMaster = "controlmaster" + keyControlPath = "controlpath" + keyControlPersist = "controlpersist" + keyDynamicForward = "dynamicforward" + keyEnableSSHKeysign = "enablesshkeysign" + keyEscapeChar = "escapechar" + keyExitOnForwardFailure = "keyexitonforwardfailure" + keyFingerprintHash = "fingerprinthash" + keyForwardAgent = "forwardagent" + keyForwardX11 = "forwardx11" + keyForwardX11Timeout = "forwardx11timeout" + keyForwardX11Trusted = "forwardx11trusted" + keyGatewayPorts = "gatewayports" + keyGlobalKnownHostsFile = "globalknownhostsfile" + keyGSSAPIAuthentication = "gssapiauthentication" + keyGSSAPIDelegateCredentials = "gssapidelegatecredentials" + keyHashKnownHosts = "hashknownhosts" + keyHostBasedAuthentication = "hostbasedauthentication" + keyHostBaseKeyTypes = "hostbasedkeytypes" + keyHostKeyAlgorithms = "hostkeyalgorithms" + keyHostKeyAlias = "hostkeyalias" + keyIdentitiesOnly = "identitiesonly" + keyIgnoreUnknown = "ignoreunknown" + keyInclude = "include" + keyIPQoS = "ipqos" + keyKbdInteractiveAuthentication = "kbdinteractiveauthentication" + keyKbdInteractiveDevices = "kbdinteractivedevices" + keyKexAlgorithms = "kexalgorithms" + keyLocalCommand = "localcommand" + keyLocalForward = "localforward" + keyLogLevel = "loglevel" + keyMACs = "macs" + keyNoHostAuthenticationForLocalhost = "nohostauthenticationforlocalhost" + keyNumberOfPasswordPrompts = "numberofpasswordprompts" + keyPasswordAuthentication = "passwordauthentication" + keyPermitLocalCommand = "permitlocalcommand" + keyPKCS11Provider = "pkcs11provider" + keyPreferredAuthentications = "preferredauthentications" + keyProxyCommand = "proxycommand" + keyProxyJump = "proxyjump" + keyProxyUseFdpass = "proxyusefdpass" + keyPubkeyAcceptedKeyTypes = "pubkeyacceptedkeytypes" + keyPubkeyAuthentication = "pubkeyauthentication" + keyRekeyLimit = "rekeylimit" + keyRemoteCommand = "remotecommand" + keyRemoteForward = "remoteforward" + keyRequestTTY = "requesttty" + keyRevokeHostKeys = "revokehostkeys" + keyServerAliveCountMax = "serveralivecountmax" + keyServerAliveInterval = "serveraliveinterval" + keyStreamLocalBindMask = "streamlocalbindmask" + keyStreamLocalBindUnlink = "streamlocalbindunlink" + keyStrictHostKeyChecking = "stricthostkeychecking" + keySyslogFacility = "syslogfacility" + keyTCPKeepAlive = "tcpkeepalive" + keyTunnel = "tunnel" + keyTunnelDevince = "tunneldevice" + keyUpdatehostKeys = "updatehostkeys" + keyUseKeychain = "usekeychain" + keyUserKnownHostsFile = "userknownhostsfile" + keyVerifyHostKeyDNS = "verifyhostkeydns" +) + +// Valid values for AddKeysToAgent. const ( - // Valid values for AddKeysToAgent. valueAsk = "ask" valueConfirm = "confirm" valueNo = "no" valueYes = "yes" valueAlways = "always" +) - // Valid values for AddressFamily. +// Valid values for AddressFamily. +const ( valueAny = "any" valueInet = "inet" valueInet6 = "inet6" @@ -261,13 +363,90 @@ func (section *Section) init(workDir, homeDir string) { } } +func (section *Section) merge(other *Section) { +} + +// set the section field by raw key and value. +func (section *Section) set(cfg *Config, key, value string) (err error) { + switch key { + case keyAddKeysToAgent: + err = section.setAddKeysToAgent(value) + case keyAddressFamily: + err = section.setAddressFamily(value) + case keyBatchMode: + section.IsBatchMode, err = parseBool(key, value) + case keyBindAddress: + section.BindAddress = value + case keyBindInterface: + section.BindInterface = value + case keyCanonicalDomains: + section.CanonicalDomains = strings.Fields(value) + case keyCanonicalizeFallbackLocal: + section.IsCanonicalizeFallbackLocal, err = parseBool(key, value) + case keyCanonicalizeHostname: + err = section.setCanonicalizeHostname(value) + case keyCanonicalizeMaxDots: + section.CanonicalizeMaxDots, err = strconv.Atoi(value) + + case keyCanonicalizePermittedCNAMEs: + err = section.setCanonicalizePermittedCNAMEs(value) + + case keyCASignatureAlgorithms: + section.setCASignatureAlgorithms(value) + + case keyCertificateFile: + section.CertificateFile = append(section.CertificateFile, value) + + case keyChallengeResponseAuthentication: + section.IsChallengeResponseAuthentication, err = parseBool(key, value) + + case keyCheckHostIP: + section.IsCheckHostIP, err = parseBool(key, value) + + case keyClearAllForwardings: + section.IsClearAllForwardings, err = parseBool(key, value) + case keyCompression: + section.UseCompression, err = parseBool(key, value) + case keyConnectionAttempts: + section.ConnectionAttempts, err = strconv.Atoi(value) + case keyConnectTimeout: + section.ConnectTimeout, err = strconv.Atoi(value) + + case keyIdentityAgent: + section.setIdentityAgent(value) + + case keyIdentityFile: + if section.useDefaultIdentityFile { + section.IdentityFile = []string{value} + section.useDefaultIdentityFile = false + } else { + section.IdentityFile = append(section.IdentityFile, value) + } + + case keyHostname: + section.Hostname = value + case keyPort: + section.Port = value + case keySendEnv: + section.setSendEnv(cfg.envs, value) + case keySetEnv: + section.setEnv(value) + case keyUser: + section.User = value + case keyVisualHostKey: + section.UseVisualHostKey, err = parseBool(key, value) + case keyXAuthLocation: + section.XAuthLocation = value + } + return err +} + func (section *Section) setAddKeysToAgent(val string) (err error) { switch val { case valueAsk, valueConfirm, valueNo, valueYes: section.AddKeysToAgent = val default: - return fmt.Errorf("%s: invalid value %q", keyAddKeysToAgent, - val) + return fmt.Errorf("%s: invalid value %q", keyAddKeysToAgent, val) } return nil } @@ -277,8 +456,7 @@ func (section *Section) setAddressFamily(val string) (err error) { case valueAny, valueInet, valueInet6: section.AddressFamily = val default: - return fmt.Errorf("%s: invalid value %q", keyAddressFamily, - val) + return fmt.Errorf("%s: invalid value %q", keyAddressFamily, val) } return nil } @@ -296,8 +474,7 @@ func (section *Section) setCanonicalizeHostname(val string) (err error) { func (section *Section) setCanonicalizePermittedCNAMEs(val string) (err error) { sourceTarget := strings.Split(val, ":") if len(sourceTarget) != 2 { - return fmt.Errorf("%s: invalid rule", - keyCanonicalizePermittedCNAMEs) + return fmt.Errorf("%s: invalid rule", keyCanonicalizePermittedCNAMEs) } listSource := strings.Split(sourceTarget[0], ",") |
