mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-04 18:59:08 +01:00
feat: use pointers for connkeywords keys
This makes it easier for the ssh keywords to be overridden.
This commit is contained in:
parent
ab5e7b5bd9
commit
ef99e95d42
1
frontend/types/gotypes.d.ts
vendored
1
frontend/types/gotypes.d.ts
vendored
@ -139,6 +139,7 @@ declare global {
|
|||||||
blockdef: BlockDef;
|
blockdef: BlockDef;
|
||||||
rtopts?: RuntimeOpts;
|
rtopts?: RuntimeOpts;
|
||||||
magnified?: boolean;
|
magnified?: boolean;
|
||||||
|
ephemeral?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
// wshrpc.CommandCreateSubBlockData
|
// wshrpc.CommandCreateSubBlockData
|
||||||
|
@ -152,7 +152,7 @@ func createPublicKeyCallback(connCtx context.Context, sshKeywords *wshrpc.ConnKe
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
signer, err := ssh.NewSignerFromKey(unencryptedPrivateKey)
|
signer, err := ssh.NewSignerFromKey(unencryptedPrivateKey)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if sshKeywords.SshAddKeysToAgent && agentClient != nil {
|
if safeDeref(sshKeywords.SshAddKeysToAgent) && agentClient != nil {
|
||||||
agentClient.Add(agent.AddedKey{
|
agentClient.Add(agent.AddedKey{
|
||||||
PrivateKey: unencryptedPrivateKey,
|
PrivateKey: unencryptedPrivateKey,
|
||||||
})
|
})
|
||||||
@ -166,7 +166,7 @@ func createPublicKeyCallback(connCtx context.Context, sshKeywords *wshrpc.ConnKe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// batch mode deactivates user input
|
// batch mode deactivates user input
|
||||||
if sshKeywords.SshBatchMode {
|
if safeDeref(sshKeywords.SshBatchMode) {
|
||||||
// skip this key and try with the next
|
// skip this key and try with the next
|
||||||
return createDummySigner()
|
return createDummySigner()
|
||||||
}
|
}
|
||||||
@ -195,7 +195,7 @@ func createPublicKeyCallback(connCtx context.Context, sshKeywords *wshrpc.ConnKe
|
|||||||
// skip this key and try with the next
|
// skip this key and try with the next
|
||||||
return createDummySigner()
|
return createDummySigner()
|
||||||
}
|
}
|
||||||
if sshKeywords.SshAddKeysToAgent && agentClient != nil {
|
if safeDeref(sshKeywords.SshAddKeysToAgent) && agentClient != nil {
|
||||||
agentClient.Add(agent.AddedKey{
|
agentClient.Add(agent.AddedKey{
|
||||||
PrivateKey: unencryptedPrivateKey,
|
PrivateKey: unencryptedPrivateKey,
|
||||||
})
|
})
|
||||||
@ -551,12 +551,27 @@ func createHostKeyCallback(sshKeywords *wshrpc.ConnKeywords) (ssh.HostKeyCallbac
|
|||||||
return waveHostKeyCallback, hostKeyAlgorithms, nil
|
return waveHostKeyCallback, hostKeyAlgorithms, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func safeDeref[T any](x *T) T {
|
||||||
|
if x == nil {
|
||||||
|
var safeOut T
|
||||||
|
return safeOut
|
||||||
|
}
|
||||||
|
return *x
|
||||||
|
}
|
||||||
|
|
||||||
|
func ptr[T any](x T) *T {
|
||||||
|
return &x
|
||||||
|
}
|
||||||
|
|
||||||
func createClientConfig(connCtx context.Context, sshKeywords *wshrpc.ConnKeywords, debugInfo *ConnectionDebugInfo) (*ssh.ClientConfig, error) {
|
func createClientConfig(connCtx context.Context, sshKeywords *wshrpc.ConnKeywords, debugInfo *ConnectionDebugInfo) (*ssh.ClientConfig, error) {
|
||||||
remoteName := sshKeywords.SshUser + "@" + xknownhosts.Normalize(sshKeywords.SshHostName+":"+sshKeywords.SshPort)
|
chosenUser := safeDeref(sshKeywords.SshUser)
|
||||||
|
chosenHostName := safeDeref(sshKeywords.SshHostName)
|
||||||
|
chosenPort := safeDeref(sshKeywords.SshPort)
|
||||||
|
remoteName := chosenUser + xknownhosts.Normalize(chosenHostName+":"+chosenPort)
|
||||||
|
|
||||||
var authSockSigners []ssh.Signer
|
var authSockSigners []ssh.Signer
|
||||||
var agentClient agent.ExtendedAgent
|
var agentClient agent.ExtendedAgent
|
||||||
conn, err := net.Dial("unix", sshKeywords.SshIdentityAgent)
|
conn, err := net.Dial("unix", safeDeref(sshKeywords.SshIdentityAgent))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to open Identity Agent Socket: %v", err)
|
log.Printf("Failed to open Identity Agent Socket: %v", err)
|
||||||
} else {
|
} else {
|
||||||
@ -577,9 +592,9 @@ func createClientConfig(connCtx context.Context, sshKeywords *wshrpc.ConnKeyword
|
|||||||
|
|
||||||
// note: batch mode turns off interactive input
|
// note: batch mode turns off interactive input
|
||||||
authMethodActiveMap := map[string]bool{
|
authMethodActiveMap := map[string]bool{
|
||||||
"publickey": sshKeywords.SshPubkeyAuthentication,
|
"publickey": safeDeref(sshKeywords.SshPubkeyAuthentication),
|
||||||
"keyboard-interactive": sshKeywords.SshKbdInteractiveAuthentication && !sshKeywords.SshBatchMode,
|
"keyboard-interactive": safeDeref(sshKeywords.SshKbdInteractiveAuthentication) && !safeDeref(sshKeywords.SshBatchMode),
|
||||||
"password": sshKeywords.SshPasswordAuthentication && !sshKeywords.SshBatchMode,
|
"password": safeDeref(sshKeywords.SshPasswordAuthentication) && !safeDeref(sshKeywords.SshBatchMode),
|
||||||
}
|
}
|
||||||
|
|
||||||
var authMethods []ssh.AuthMethod
|
var authMethods []ssh.AuthMethod
|
||||||
@ -600,9 +615,9 @@ func createClientConfig(connCtx context.Context, sshKeywords *wshrpc.ConnKeyword
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
networkAddr := sshKeywords.SshHostName + ":" + sshKeywords.SshPort
|
networkAddr := chosenHostName + ":" + chosenPort
|
||||||
return &ssh.ClientConfig{
|
return &ssh.ClientConfig{
|
||||||
User: sshKeywords.SshUser,
|
User: chosenUser,
|
||||||
Auth: authMethods,
|
Auth: authMethods,
|
||||||
HostKeyCallback: hostKeyCallback,
|
HostKeyCallback: hostKeyCallback,
|
||||||
HostKeyAlgorithms: hostKeyAlgorithms(networkAddr),
|
HostKeyAlgorithms: hostKeyAlgorithms(networkAddr),
|
||||||
@ -646,9 +661,10 @@ func ConnectToClient(connCtx context.Context, opts *SSHOpts, currentClient *ssh.
|
|||||||
return nil, debugInfo.JumpNum, ConnectionError{ConnectionDebugInfo: debugInfo, Err: err}
|
return nil, debugInfo.JumpNum, ConnectionError{ConnectionDebugInfo: debugInfo, Err: err}
|
||||||
}
|
}
|
||||||
|
|
||||||
connFlags.SshUser = opts.SSHUser
|
connFlags.SshUser = &opts.SSHUser
|
||||||
connFlags.SshHostName = opts.SSHHost
|
connFlags.SshHostName = &opts.SSHHost
|
||||||
connFlags.SshPort = fmt.Sprintf("%d", opts.SSHPort)
|
portStr := fmt.Sprintf("%d", opts.SSHPort)
|
||||||
|
connFlags.SshPort = &portStr
|
||||||
|
|
||||||
rawName := opts.String()
|
rawName := opts.String()
|
||||||
savedKeywords, ok := wconfig.ReadFullConfig().Connections[rawName]
|
savedKeywords, ok := wconfig.ReadFullConfig().Connections[rawName]
|
||||||
@ -684,7 +700,7 @@ func ConnectToClient(connCtx context.Context, opts *SSHOpts, currentClient *ssh.
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, debugInfo.JumpNum, ConnectionError{ConnectionDebugInfo: debugInfo, Err: err}
|
return nil, debugInfo.JumpNum, ConnectionError{ConnectionDebugInfo: debugInfo, Err: err}
|
||||||
}
|
}
|
||||||
networkAddr := sshKeywords.SshHostName + ":" + sshKeywords.SshPort
|
networkAddr := safeDeref(sshKeywords.SshHostName) + ":" + safeDeref(sshKeywords.SshPort)
|
||||||
client, err := connectInternal(connCtx, networkAddr, clientConfig, debugInfo.CurrentClient)
|
client, err := connectInternal(connCtx, networkAddr, clientConfig, debugInfo.CurrentClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return client, debugInfo.JumpNum, ConnectionError{ConnectionDebugInfo: debugInfo, Err: err}
|
return client, debugInfo.JumpNum, ConnectionError{ConnectionDebugInfo: debugInfo, Err: err}
|
||||||
@ -695,32 +711,33 @@ func ConnectToClient(connCtx context.Context, opts *SSHOpts, currentClient *ssh.
|
|||||||
func combineSshKeywords(userProvidedOpts *wshrpc.ConnKeywords, configKeywords *wshrpc.ConnKeywords, savedKeywords *wshrpc.ConnKeywords) (*wshrpc.ConnKeywords, error) {
|
func combineSshKeywords(userProvidedOpts *wshrpc.ConnKeywords, configKeywords *wshrpc.ConnKeywords, savedKeywords *wshrpc.ConnKeywords) (*wshrpc.ConnKeywords, error) {
|
||||||
sshKeywords := &wshrpc.ConnKeywords{}
|
sshKeywords := &wshrpc.ConnKeywords{}
|
||||||
|
|
||||||
if userProvidedOpts.SshUser != "" {
|
if safeDeref(userProvidedOpts.SshUser) != "" {
|
||||||
sshKeywords.SshUser = userProvidedOpts.SshUser
|
sshKeywords.SshUser = userProvidedOpts.SshUser
|
||||||
} else if configKeywords.SshUser != "" {
|
} else if safeDeref(configKeywords.SshUser) != "" {
|
||||||
sshKeywords.SshUser = configKeywords.SshUser
|
sshKeywords.SshUser = configKeywords.SshUser
|
||||||
} else {
|
} else {
|
||||||
user, err := user.Current()
|
user, err := user.Current()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get user for ssh: %+v", err)
|
return nil, fmt.Errorf("failed to get user for ssh: %+v", err)
|
||||||
}
|
}
|
||||||
sshKeywords.SshUser = user.Username
|
sshKeywords.SshUser = ptr(user.Username)
|
||||||
}
|
}
|
||||||
|
|
||||||
// we have to check the host value because of the weird way
|
// we have to check the host value because of the weird way
|
||||||
// we store the pattern as the hostname for imported remotes
|
// we store the pattern as the hostname for imported remotes
|
||||||
if configKeywords.SshHostName != "" {
|
if safeDeref(configKeywords.SshHostName) != "" {
|
||||||
sshKeywords.SshHostName = configKeywords.SshHostName
|
sshKeywords.SshHostName = configKeywords.SshHostName
|
||||||
} else {
|
} else {
|
||||||
sshKeywords.SshHostName = userProvidedOpts.SshHostName
|
sshKeywords.SshHostName = userProvidedOpts.SshHostName
|
||||||
}
|
}
|
||||||
|
|
||||||
if userProvidedOpts.SshPort != "0" && userProvidedOpts.SshPort != "22" {
|
userPort := safeDeref(userProvidedOpts.SshPort)
|
||||||
|
if userPort != "" && userPort != "0" && userPort != "22" {
|
||||||
sshKeywords.SshPort = userProvidedOpts.SshPort
|
sshKeywords.SshPort = userProvidedOpts.SshPort
|
||||||
} else if configKeywords.SshPort != "" && configKeywords.SshPort != "22" {
|
} else if userPort != "" && userPort != "22" {
|
||||||
sshKeywords.SshPort = configKeywords.SshPort
|
sshKeywords.SshPort = configKeywords.SshPort
|
||||||
} else {
|
} else {
|
||||||
sshKeywords.SshPort = "22"
|
sshKeywords.SshPort = ptr("22")
|
||||||
}
|
}
|
||||||
|
|
||||||
// use internal config ones
|
// use internal config ones
|
||||||
@ -760,19 +777,19 @@ func findSshConfigKeywords(hostPattern string) (*wshrpc.ConnKeywords, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sshKeywords.SshUser = trimquotes.TryTrimQuotes(userRaw)
|
sshKeywords.SshUser = ptr(trimquotes.TryTrimQuotes(userRaw))
|
||||||
|
|
||||||
hostNameRaw, err := WaveSshConfigUserSettings().GetStrict(hostPattern, "HostName")
|
hostNameRaw, err := WaveSshConfigUserSettings().GetStrict(hostPattern, "HostName")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sshKeywords.SshHostName = trimquotes.TryTrimQuotes(hostNameRaw)
|
sshKeywords.SshHostName = ptr(trimquotes.TryTrimQuotes(hostNameRaw))
|
||||||
|
|
||||||
portRaw, err := WaveSshConfigUserSettings().GetStrict(hostPattern, "Port")
|
portRaw, err := WaveSshConfigUserSettings().GetStrict(hostPattern, "Port")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sshKeywords.SshPort = trimquotes.TryTrimQuotes(portRaw)
|
sshKeywords.SshPort = ptr(trimquotes.TryTrimQuotes(portRaw))
|
||||||
|
|
||||||
identityFileRaw := WaveSshConfigUserSettings().GetAll(hostPattern, "IdentityFile")
|
identityFileRaw := WaveSshConfigUserSettings().GetAll(hostPattern, "IdentityFile")
|
||||||
for i := 0; i < len(identityFileRaw); i++ {
|
for i := 0; i < len(identityFileRaw); i++ {
|
||||||
@ -784,26 +801,26 @@ func findSshConfigKeywords(hostPattern string) (*wshrpc.ConnKeywords, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sshKeywords.SshBatchMode = (strings.ToLower(trimquotes.TryTrimQuotes(batchModeRaw)) == "yes")
|
sshKeywords.SshBatchMode = ptr(strings.ToLower(trimquotes.TryTrimQuotes(batchModeRaw)) == "yes")
|
||||||
|
|
||||||
// we currently do not support host-bound or unbound but will use yes when they are selected
|
// we currently do not support host-bound or unbound but will use yes when they are selected
|
||||||
pubkeyAuthenticationRaw, err := WaveSshConfigUserSettings().GetStrict(hostPattern, "PubkeyAuthentication")
|
pubkeyAuthenticationRaw, err := WaveSshConfigUserSettings().GetStrict(hostPattern, "PubkeyAuthentication")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sshKeywords.SshPubkeyAuthentication = (strings.ToLower(trimquotes.TryTrimQuotes(pubkeyAuthenticationRaw)) != "no")
|
sshKeywords.SshPubkeyAuthentication = ptr(strings.ToLower(trimquotes.TryTrimQuotes(pubkeyAuthenticationRaw)) != "no")
|
||||||
|
|
||||||
passwordAuthenticationRaw, err := WaveSshConfigUserSettings().GetStrict(hostPattern, "PasswordAuthentication")
|
passwordAuthenticationRaw, err := WaveSshConfigUserSettings().GetStrict(hostPattern, "PasswordAuthentication")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sshKeywords.SshPasswordAuthentication = (strings.ToLower(trimquotes.TryTrimQuotes(passwordAuthenticationRaw)) != "no")
|
sshKeywords.SshPasswordAuthentication = ptr(strings.ToLower(trimquotes.TryTrimQuotes(passwordAuthenticationRaw)) != "no")
|
||||||
|
|
||||||
kbdInteractiveAuthenticationRaw, err := WaveSshConfigUserSettings().GetStrict(hostPattern, "KbdInteractiveAuthentication")
|
kbdInteractiveAuthenticationRaw, err := WaveSshConfigUserSettings().GetStrict(hostPattern, "KbdInteractiveAuthentication")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sshKeywords.SshKbdInteractiveAuthentication = (strings.ToLower(trimquotes.TryTrimQuotes(kbdInteractiveAuthenticationRaw)) != "no")
|
sshKeywords.SshKbdInteractiveAuthentication = ptr(strings.ToLower(trimquotes.TryTrimQuotes(kbdInteractiveAuthenticationRaw)) != "no")
|
||||||
|
|
||||||
// these are parsed as a single string and must be separated
|
// these are parsed as a single string and must be separated
|
||||||
// these are case sensitive in openssh so they are here too
|
// these are case sensitive in openssh so they are here too
|
||||||
@ -816,7 +833,7 @@ func findSshConfigKeywords(hostPattern string) (*wshrpc.ConnKeywords, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sshKeywords.SshAddKeysToAgent = (strings.ToLower(trimquotes.TryTrimQuotes(addKeysToAgentRaw)) == "yes")
|
sshKeywords.SshAddKeysToAgent = ptr(strings.ToLower(trimquotes.TryTrimQuotes(addKeysToAgentRaw)) == "yes")
|
||||||
|
|
||||||
identityAgentRaw, err := WaveSshConfigUserSettings().GetStrict(hostPattern, "IdentityAgent")
|
identityAgentRaw, err := WaveSshConfigUserSettings().GetStrict(hostPattern, "IdentityAgent")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -831,7 +848,7 @@ func findSshConfigKeywords(hostPattern string) (*wshrpc.ConnKeywords, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sshKeywords.SshIdentityAgent = agentPath
|
sshKeywords.SshIdentityAgent = ptr(agentPath)
|
||||||
} else {
|
} else {
|
||||||
log.Printf("unable to find SSH_AUTH_SOCK: %v\n", err)
|
log.Printf("unable to find SSH_AUTH_SOCK: %v\n", err)
|
||||||
}
|
}
|
||||||
@ -840,7 +857,7 @@ func findSshConfigKeywords(hostPattern string) (*wshrpc.ConnKeywords, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sshKeywords.SshIdentityAgent = agentPath
|
sshKeywords.SshIdentityAgent = ptr(agentPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
proxyJumpRaw, err := WaveSshConfigUserSettings().GetStrict(hostPattern, "ProxyJump")
|
proxyJumpRaw, err := WaveSshConfigUserSettings().GetStrict(hostPattern, "ProxyJump")
|
||||||
|
@ -290,6 +290,7 @@ type CommandCreateBlockData struct {
|
|||||||
BlockDef *waveobj.BlockDef `json:"blockdef"`
|
BlockDef *waveobj.BlockDef `json:"blockdef"`
|
||||||
RtOpts *waveobj.RuntimeOpts `json:"rtopts,omitempty"`
|
RtOpts *waveobj.RuntimeOpts `json:"rtopts,omitempty"`
|
||||||
Magnified bool `json:"magnified,omitempty"`
|
Magnified bool `json:"magnified,omitempty"`
|
||||||
|
Ephemeral bool `json:"ephemeral,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CommandCreateSubBlockData struct {
|
type CommandCreateSubBlockData struct {
|
||||||
@ -468,17 +469,17 @@ type ConnKeywords struct {
|
|||||||
TermFontFamily string `json:"term:fontfamily,omitempty"`
|
TermFontFamily string `json:"term:fontfamily,omitempty"`
|
||||||
TermTheme string `json:"term:theme,omitempty"`
|
TermTheme string `json:"term:theme,omitempty"`
|
||||||
|
|
||||||
SshUser string `json:"ssh:user,omitempty"`
|
SshUser *string `json:"ssh:user,omitempty"`
|
||||||
SshHostName string `json:"ssh:hostname,omitempty"`
|
SshHostName *string `json:"ssh:hostname,omitempty"`
|
||||||
SshPort string `json:"ssh:port,omitempty"`
|
SshPort *string `json:"ssh:port,omitempty"`
|
||||||
SshIdentityFile []string `json:"ssh:identityfile,omitempty"`
|
SshIdentityFile []string `json:"ssh:identityfile,omitempty"`
|
||||||
SshBatchMode bool `json:"ssh:batchmode,omitempty"`
|
SshBatchMode *bool `json:"ssh:batchmode,omitempty"`
|
||||||
SshPubkeyAuthentication bool `json:"ssh:pubkeyauthentication,omitempty"`
|
SshPubkeyAuthentication *bool `json:"ssh:pubkeyauthentication,omitempty"`
|
||||||
SshPasswordAuthentication bool `json:"ssh:passwordauthentication,omitempty"`
|
SshPasswordAuthentication *bool `json:"ssh:passwordauthentication,omitempty"`
|
||||||
SshKbdInteractiveAuthentication bool `json:"ssh:kbdinteractiveauthentication,omitempty"`
|
SshKbdInteractiveAuthentication *bool `json:"ssh:kbdinteractiveauthentication,omitempty"`
|
||||||
SshPreferredAuthentications []string `json:"ssh:preferredauthentications,omitempty"`
|
SshPreferredAuthentications []string `json:"ssh:preferredauthentications,omitempty"`
|
||||||
SshAddKeysToAgent bool `json:"ssh:addkeystoagent,omitempty"`
|
SshAddKeysToAgent *bool `json:"ssh:addkeystoagent,omitempty"`
|
||||||
SshIdentityAgent string `json:"ssh:identityagent,omitempty"`
|
SshIdentityAgent *string `json:"ssh:identityagent,omitempty"`
|
||||||
SshProxyJump []string `json:"ssh:proxyjump,omitempty"`
|
SshProxyJump []string `json:"ssh:proxyjump,omitempty"`
|
||||||
SshUserKnownHostsFile []string `json:"ssh:userknownhostsfile,omitempty"`
|
SshUserKnownHostsFile []string `json:"ssh:userknownhostsfile,omitempty"`
|
||||||
SshGlobalKnownHostsFile []string `json:"ssh:globalknownhostsfile,omitempty"`
|
SshGlobalKnownHostsFile []string `json:"ssh:globalknownhostsfile,omitempty"`
|
||||||
|
Loading…
Reference in New Issue
Block a user