Skip to content

Commit a3a7d44

Browse files
committed
Adapt scp source and target arguments for legacy openssh
This commit restricts use of URIs in scp command to openssh clients starting from v8.0. On legacy clients the old syntax is used. For pre v8.0 openSSH clients only commands involving a single instance are allowed. Signed-off-by: David Cassany <[email protected]>
1 parent 9029b1c commit a3a7d44

File tree

2 files changed

+21
-6
lines changed

2 files changed

+21
-6
lines changed

cmd/limactl/copy.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"os/exec"
88
"strings"
99

10+
"github.com/coreos/go-semver/semver"
1011
"github.com/lima-vm/lima/pkg/osutil"
1112
"github.com/lima-vm/lima/pkg/sshutil"
1213
"github.com/lima-vm/lima/pkg/store"
@@ -51,18 +52,22 @@ func copyAction(cmd *cobra.Command, args []string) error {
5152
return err
5253
}
5354
instDirs := make(map[string]string)
55+
scpFlags := []string{}
5456
scpArgs := []string{}
5557
debug, err := cmd.Flags().GetBool("debug")
5658
if err != nil {
5759
return err
5860
}
5961
if debug {
60-
scpArgs = append(scpArgs, "-v")
62+
scpFlags = append(scpFlags, "-v")
6163
}
6264
if recursive {
63-
scpArgs = append(scpArgs, "-r")
65+
scpFlags = append(scpFlags, "-r")
66+
}
67+
legacySSH := false
68+
if sshutil.DetectOpenSSHVersion().LessThan(*semver.New("8.0.0")) {
69+
legacySSH = true
6470
}
65-
scpArgs = append(scpArgs, "-3", "--")
6671
for _, arg := range args {
6772
path := strings.Split(arg, ":")
6873
switch len(path) {
@@ -80,12 +85,22 @@ func copyAction(cmd *cobra.Command, args []string) error {
8085
if inst.Status == store.StatusStopped {
8186
return fmt.Errorf("instance %q is stopped, run `limactl start %s` to start the instance", instName, instName)
8287
}
83-
scpArgs = append(scpArgs, fmt.Sprintf("scp://%[email protected]:%d/%s", u.Username, inst.SSHLocalPort, path[1]))
88+
if legacySSH {
89+
scpFlags = append(scpFlags, "-P", fmt.Sprintf("%d", inst.SSHLocalPort))
90+
scpArgs = append(scpArgs, fmt.Sprintf("%[email protected]:%s", u.Username, path[1]))
91+
} else {
92+
scpArgs = append(scpArgs, fmt.Sprintf("scp://%[email protected]:%d/%s", u.Username, inst.SSHLocalPort, path[1]))
93+
}
8494
instDirs[instName] = inst.Dir
8595
default:
8696
return fmt.Errorf("path %q contains multiple colons", arg)
8797
}
8898
}
99+
if legacySSH && len(instDirs) > 1 {
100+
return fmt.Errorf("More than one (instance) host is involved in this command, this is only supported for openSSH v8.0 or higher")
101+
}
102+
scpFlags = append(scpFlags, "-3", "--")
103+
scpArgs = append(scpFlags, scpArgs...)
89104

90105
var sshOpts []string
91106
if len(instDirs) == 1 {

pkg/sshutil/sshutil.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ func CommonOpts(useDotSSH bool) ([]string, error) {
178178

179179
sshInfo.Do(func() {
180180
sshInfo.aesAccelerated = detectAESAcceleration()
181-
sshInfo.openSSHVersion = detectOpenSSHVersion()
181+
sshInfo.openSSHVersion = DetectOpenSSHVersion()
182182
})
183183

184184
// Only OpenSSH version 8.1 and later support adding ciphers to the front of the default set
@@ -246,7 +246,7 @@ func ParseOpenSSHVersion(version []byte) *semver.Version {
246246
return &semver.Version{}
247247
}
248248

249-
func detectOpenSSHVersion() semver.Version {
249+
func DetectOpenSSHVersion() semver.Version {
250250
var (
251251
v semver.Version
252252
stderr bytes.Buffer

0 commit comments

Comments
 (0)