From e927f988b68a2041847e71729b7808fd135e06d0 Mon Sep 17 00:00:00 2001 From: Robin Thellend Date: Wed, 15 Oct 2025 09:37:59 -0700 Subject: [PATCH 1/3] Allow @ in username --- go/internal/app/ssh.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/go/internal/app/ssh.go b/go/internal/app/ssh.go index e3c9bd5..5d99389 100644 --- a/go/internal/app/ssh.go +++ b/go/internal/app/ssh.go @@ -159,8 +159,16 @@ func (a *App) runSSH(ctx context.Context, target, keyName, command string, forwa return session.Wait() } +func parseUserHost(target string) (string, string, bool) { + p := strings.LastIndex(target, "@") + if p == -1 { + return target, "", false + } + return target[:p], target[p+1:], true +} + func (a *App) sshClient(ctx context.Context, target, keyName, jumpHosts string) (*ssh.Client, error) { - username, hostname, ok := strings.Cut(target, "@") + username, hostname, ok := parseUserHost(target) if !ok { return nil, fmt.Errorf("invalid target %q", target) } @@ -171,7 +179,7 @@ func (a *App) sshClient(ctx context.Context, target, keyName, jumpHosts string) if jumpHosts != "" { for _, jh := range strings.Split(jumpHosts, ",") { jh = strings.TrimSpace(jh) - u, h, ok := strings.Cut(jh, "@") + u, h, ok := parseUserHost(jh) if !ok { u = username h = jh From b0043df139bb9c52ecc4e7a819ad70d0c7eb9938 Mon Sep 17 00:00:00 2001 From: Robin Thellend Date: Wed, 15 Oct 2025 09:42:00 -0700 Subject: [PATCH 2/3] Add comment --- go/internal/app/ssh.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/go/internal/app/ssh.go b/go/internal/app/ssh.go index 5d99389..0f1d4af 100644 --- a/go/internal/app/ssh.go +++ b/go/internal/app/ssh.go @@ -159,6 +159,10 @@ func (a *App) runSSH(ctx context.Context, target, keyName, command string, forwa return session.Wait() } +// parseUserHost splits a string in the form "user@host" at the last '@'. +// This allows the user part to contain '@' characters. +// If no '@' is present, it returns the original string as the first return +// value, an empty string as the second, and false. func parseUserHost(target string) (string, string, bool) { p := strings.LastIndex(target, "@") if p == -1 { From 93ad61f6d2792fff18c08ad2875c546d26c824d3 Mon Sep 17 00:00:00 2001 From: Robin Thellend Date: Wed, 15 Oct 2025 09:43:14 -0700 Subject: [PATCH 3/3] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 316fa72..9d79a6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### :wrench: Misc +* Allow @ in usernames. * Add browserify to the devDependencies in xterm/package.json. ## v0.8.0