github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/vm/vmimpl/util.go (about) 1 // Copyright 2017 syzkaller project authors. All rights reserved. 2 // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4 package vmimpl 5 6 import ( 7 "fmt" 8 "time" 9 10 "github.com/google/syzkaller/pkg/log" 11 "github.com/google/syzkaller/pkg/osutil" 12 "github.com/google/syzkaller/sys/targets" 13 ) 14 15 // Sleep for d. 16 // If shutdown is in progress, return false prematurely. 17 func SleepInterruptible(d time.Duration) bool { 18 select { 19 case <-time.After(d): 20 return true 21 case <-Shutdown: 22 return false 23 } 24 } 25 26 type SSHOptions struct { 27 Addr string 28 Port int 29 User string 30 Key string 31 } 32 33 func WaitForSSH(timeout time.Duration, opts SSHOptions, OS string, stop chan error, systemSSHCfg, debug bool) error { 34 pwd := "pwd" 35 if OS == targets.Windows { 36 pwd = "dir" 37 } 38 startTime := time.Now() 39 SleepInterruptible(5 * time.Second) 40 for { 41 select { 42 case <-time.After(5 * time.Second): 43 case err := <-stop: 44 return err 45 case <-Shutdown: 46 return fmt.Errorf("shutdown in progress") 47 } 48 args := append(SSHArgs(debug, opts.Key, opts.Port, systemSSHCfg), opts.User+"@"+opts.Addr, pwd) 49 if debug { 50 log.Logf(0, "running ssh: %#v", args) 51 } 52 _, err := osutil.RunCmd(time.Minute, "", "ssh", args...) 53 if err == nil { 54 return nil 55 } 56 if debug { 57 log.Logf(0, "ssh failed: %v", err) 58 } 59 if time.Since(startTime) > timeout { 60 return &osutil.VerboseError{ 61 Err: ErrCantSSH, 62 Output: []byte(err.Error()), 63 } 64 } 65 } 66 } 67 68 var ErrCantSSH = fmt.Errorf("can't ssh into the instance") 69 70 func SSHArgs(debug bool, sshKey string, port int, systemSSHCfg bool) []string { 71 return sshArgs(debug, sshKey, "-p", port, 0, systemSSHCfg) 72 } 73 74 func SSHArgsForward(debug bool, sshKey string, port, forwardPort int, systemSSHCfg bool) []string { 75 return sshArgs(debug, sshKey, "-p", port, forwardPort, systemSSHCfg) 76 } 77 78 func SCPArgs(debug bool, sshKey string, port int, systemSSHCfg bool) []string { 79 return sshArgs(debug, sshKey, "-P", port, 0, systemSSHCfg) 80 } 81 82 func sshArgs(debug bool, sshKey, portArg string, port, forwardPort int, systemSSHCfg bool) []string { 83 args := []string{portArg, fmt.Sprint(port)} 84 if !systemSSHCfg { 85 args = append(args, 86 "-F", "/dev/null", 87 "-o", "UserKnownHostsFile=/dev/null", 88 "-o", "IdentitiesOnly=yes") 89 } 90 args = append(args, 91 "-o", "BatchMode=yes", 92 "-o", "StrictHostKeyChecking=no", 93 "-o", "ConnectTimeout=10", 94 ) 95 if sshKey != "" { 96 args = append(args, "-i", sshKey) 97 } 98 if forwardPort != 0 { 99 // Forward target port as part of the ssh connection (reverse proxy). 100 args = append(args, "-R", fmt.Sprintf("%v:127.0.0.1:%v", forwardPort, forwardPort)) 101 } 102 if debug { 103 args = append(args, "-v") 104 } 105 return args 106 }