github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/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  func WaitForSSH(debug bool, timeout time.Duration, addr, sshKey, sshUser, OS string, port int, stop chan error,
    27  	systemSSHCfg bool) error {
    28  	pwd := "pwd"
    29  	if OS == targets.Windows {
    30  		pwd = "dir"
    31  	}
    32  	startTime := time.Now()
    33  	SleepInterruptible(5 * time.Second)
    34  	for {
    35  		select {
    36  		case <-time.After(5 * time.Second):
    37  		case err := <-stop:
    38  			return err
    39  		case <-Shutdown:
    40  			return fmt.Errorf("shutdown in progress")
    41  		}
    42  		args := append(SSHArgs(debug, sshKey, port, systemSSHCfg), sshUser+"@"+addr, pwd)
    43  		if debug {
    44  			log.Logf(0, "running ssh: %#v", args)
    45  		}
    46  		_, err := osutil.RunCmd(time.Minute, "", "ssh", args...)
    47  		if err == nil {
    48  			return nil
    49  		}
    50  		if debug {
    51  			log.Logf(0, "ssh failed: %v", err)
    52  		}
    53  		if time.Since(startTime) > timeout {
    54  			return &osutil.VerboseError{Title: "can't ssh into the instance", Output: []byte(err.Error())}
    55  		}
    56  	}
    57  }
    58  
    59  func SSHArgs(debug bool, sshKey string, port int, systemSSHCfg bool) []string {
    60  	return sshArgs(debug, sshKey, "-p", port, 0, systemSSHCfg)
    61  }
    62  
    63  func SSHArgsForward(debug bool, sshKey string, port, forwardPort int, systemSSHCfg bool) []string {
    64  	return sshArgs(debug, sshKey, "-p", port, forwardPort, systemSSHCfg)
    65  }
    66  
    67  func SCPArgs(debug bool, sshKey string, port int, systemSSHCfg bool) []string {
    68  	return sshArgs(debug, sshKey, "-P", port, 0, systemSSHCfg)
    69  }
    70  
    71  func sshArgs(debug bool, sshKey, portArg string, port, forwardPort int, systemSSHCfg bool) []string {
    72  	args := []string{portArg, fmt.Sprint(port)}
    73  	if !systemSSHCfg {
    74  		args = append(args,
    75  			"-F", "/dev/null",
    76  			"-o", "UserKnownHostsFile=/dev/null",
    77  			"-o", "IdentitiesOnly=yes")
    78  	}
    79  	args = append(args,
    80  		"-o", "BatchMode=yes",
    81  		"-o", "StrictHostKeyChecking=no",
    82  		"-o", "ConnectTimeout=10",
    83  	)
    84  	if sshKey != "" {
    85  		args = append(args, "-i", sshKey)
    86  	}
    87  	if forwardPort != 0 {
    88  		// Forward target port as part of the ssh connection (reverse proxy).
    89  		args = append(args, "-R", fmt.Sprintf("%v:127.0.0.1:%v", forwardPort, forwardPort))
    90  	}
    91  	if debug {
    92  		args = append(args, "-v")
    93  	}
    94  	return args
    95  }