示例#1
0
func prepareHostControlPath(host, gateway *config.Host) error {
	controlPathDir := path.Dir(os.ExpandEnv(strings.Replace(host.ControlPath, "~", "$HOME", -1)))
	gatewayControlPath := path.Join(controlPathDir, gateway.Name())
	if config.BoolVal(host.ControlMasterMkdir) {
		return os.MkdirAll(gatewayControlPath, 0700)
	}
	return nil
}
示例#2
0
func proxyGo(host *config.Host) error {
	if host.Host == "" {
		host.Host = host.Name
	}

	if len(host.ResolveNameservers) > 0 {
		logrus.Debugf("Resolving host: '%s' using nameservers %s", host.Host, host.ResolveNameservers)
		// FIXME: resolve using custom dns server
		results, err := net.LookupAddr(host.Host)
		if err != nil {
			return err
		}
		if len(results) > 0 {
			host.Host = results[0]
		}
		logrus.Debugf("Resolved host is: %s", host.Host)
	}
	if host.ResolveCommand != "" {
		command := commandApplyHost(host.ResolveCommand, host)
		logrus.Debugf("Resolving host: '%s' using command: '%s'", host.Host, command)

		args, err := shlex.Split(command)
		if err != nil {
			return err
		}

		out, err := exec.Command(args[0], args[1:]...).Output()
		if err != nil {
			return err
		}

		host.Host = strings.TrimSpace(fmt.Sprintf("%s", out))
		logrus.Debugf("Resolved host is: %s", host.Host)
	}

	logrus.Debugf("Connecting to %s:%d", host.Host, host.Port)
	conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", host.Host, host.Port))
	if err != nil {
		return err
	}
	defer conn.Close()

	logrus.Debugf("Connected to %s:%d", host.Host, host.Port)

	// Create Stdio pipes
	c1 := readAndWrite(conn, os.Stdout)
	c2 := readAndWrite(os.Stdin, conn)

	select {
	case err = <-c1:
	case err = <-c2:
	}
	if err != nil {
		return err
	}

	return nil
}
示例#3
0
func proxyCommand(host *config.Host, command string) error {
	command = host.ExpandString(command)
	args, err := shlex.Split(command)
	Logger.Debugf("ProxyCommand: %s", command)
	if err != nil {
		return err
	}
	spawn := exec.Command(args[0], args[1:]...)
	spawn.Stdout = os.Stdout
	spawn.Stdin = os.Stdin
	spawn.Stderr = os.Stderr
	return spawn.Run()
}
示例#4
0
func proxy(host *config.Host, conf *config.Config, dryRun bool) error {
	if len(host.Gateways) > 0 {
		Logger.Debugf("Trying gateways: %s", host.Gateways)
		for _, gateway := range host.Gateways {
			if gateway == "direct" {
				err := proxyDirect(host, dryRun)
				if err != nil {
					Logger.Errorf("Failed to use 'direct' connection: %v", err)
				}
			} else {
				hostCopy := host.Clone()
				gatewayHost := conf.GetGatewaySafe(gateway)

				err := prepareHostControlPath(hostCopy, gatewayHost)
				if err != nil {
					return err
				}

				// FIXME: dynamically add "-v" flags

				var command string

				// FIXME: detect ssh client version and use netcat if too old
				// for now, the workaround is to configure the ProxyCommand of the host to "nc %h %p"

				if err = hostPrepare(hostCopy); err != nil {
					return err
				}

				if hostCopy.ProxyCommand != "" {
					command = "ssh %name -- " + hostCopy.ExpandString(hostCopy.ProxyCommand)
				} else {
					command = hostCopy.ExpandString("ssh -W %h:%p ") + "%name"
				}

				Logger.Debugf("Using gateway '%s': %s", gateway, command)
				err = proxyCommand(gatewayHost, command, dryRun)
				if err == nil {
					return nil
				}
				Logger.Errorf("Cannot use gateway '%s': %v", gateway, err)
			}
		}
		return fmt.Errorf("No such available gateway")
	}

	Logger.Debugf("Connecting without gateway")
	return proxyDirect(host, dryRun)
}
示例#5
0
func proxyCommand(host *config.Host, command string, dryRun bool) error {
	command = host.ExpandString(command)
	Logger.Debugf("ProxyCommand: %s", command)
	args, err := shlex.Split(command)
	if err != nil {
		return err
	}

	if dryRun {
		return fmt.Errorf("dry-run: Execute %s", args)
	}

	spawn := exec.Command(args[0], args[1:]...)
	spawn.Stdout = os.Stdout
	spawn.Stdin = os.Stdin
	spawn.Stderr = os.Stderr
	return spawn.Run()
}
示例#6
0
func proxy(host *config.Host, conf *config.Config, dryRun bool) error {
	if len(host.Gateways) > 0 {
		Logger.Debugf("Trying gateways: %s", host.Gateways)
		for _, gateway := range host.Gateways {
			if gateway == "direct" {
				err := proxyDirect(host, dryRun)
				if err != nil {
					Logger.Errorf("Failed to use 'direct' connection: %v", err)
				}
			} else {
				hostCopy := host.Clone()
				gatewayHost := conf.GetGatewaySafe(gateway)

				err := prepareHostControlPath(hostCopy, gatewayHost)
				if err != nil {
					return err
				}

				if hostCopy.ProxyCommand == "" {
					hostCopy.ProxyCommand = "nc %h %p"
				}
				// FIXME: dynamically add "-v" flags

				if err = hostPrepare(hostCopy); err != nil {
					return err
				}

				command := "ssh %name -- " + hostCopy.ExpandString(hostCopy.ProxyCommand)

				Logger.Debugf("Using gateway '%s': %s", gateway, command)
				err = proxyCommand(gatewayHost, command, dryRun)
				if err == nil {
					return nil
				}
				Logger.Errorf("Cannot use gateway '%s': %v", gateway, err)
			}
		}
		return fmt.Errorf("No such available gateway")
	}

	Logger.Debugf("Connecting without gateway")
	return proxyDirect(host, dryRun)
}
示例#7
0
func hostPrepare(host *config.Host) error {
	if host.HostName == "" {
		host.HostName = host.Name()
	}

	if len(host.ResolveNameservers) > 0 {
		Logger.Debugf("Resolving host: '%s' using nameservers %s", host.HostName, host.ResolveNameservers)
		// FIXME: resolve using custom dns server
		results, err := net.LookupAddr(host.HostName)
		if err != nil {
			return err
		}
		if len(results) > 0 {
			host.HostName = results[0]
		}
		Logger.Debugf("Resolved host is: %s", host.HostName)
	}

	if host.ResolveCommand != "" {
		command := host.ExpandString(host.ResolveCommand)
		Logger.Debugf("Resolving host: %q using command: %q", host.HostName, command)

		args, err := shlex.Split(command)
		if err != nil {
			return err
		}

		cmd := exec.Command(args[0], args[1:]...)
		var stdout bytes.Buffer
		var stderr bytes.Buffer
		cmd.Stdout = &stdout
		cmd.Stderr = &stderr
		if err := cmd.Run(); err != nil {
			Logger.Errorf("ResolveCommand failed: %s", stderr.String())
			return err
		}

		host.HostName = strings.TrimSpace(fmt.Sprintf("%s", stdout.String()))
		Logger.Debugf("Resolved host is: %s", host.HostName)
	}
	return nil
}
示例#8
0
func proxy(host *config.Host, conf *config.Config) error {
	if len(host.Gateways) > 0 {
		logrus.Debugf("Trying gateways: %s", host.Gateways)
		for _, gateway := range host.Gateways {
			if gateway == "direct" {
				err := proxyDirect(host)
				if err != nil {
					logrus.Errorf("Failed to use 'direct' connection")
				}
			} else {
				gatewayHost := conf.GetGatewaySafe(gateway)

				err := prepareHostControlPath(host, gatewayHost)
				if err != nil {
					return err
				}

				if host.ProxyCommand == "" {
					host.ProxyCommand = "nc %h %p"
				}
				command := "ssh %name -- " + commandApplyHost(host.ProxyCommand, host)

				logrus.Debugf("Using gateway '%s': %s", gateway, command)
				err = proxyCommand(gatewayHost, command)
				if err == nil {
					return nil
				}
				logrus.Errorf("Cannot use gateway '%s': %v", gateway, err)
			}
		}
		return fmt.Errorf("No such available gateway")
	}

	logrus.Debugf("Connecting without gateway")
	return proxyDirect(host)
}
示例#9
0
func hostPrepare(host *config.Host) error {
	if host.HostName == "" {
		host.HostName = host.Name()
	}

	if len(host.ResolveNameservers) > 0 {
		Logger.Debugf("Resolving host: '%s' using nameservers %s", host.HostName, host.ResolveNameservers)
		// FIXME: resolve using custom dns server
		results, err := net.LookupAddr(host.HostName)
		if err != nil {
			return err
		}
		if len(results) > 0 {
			host.HostName = results[0]
		}
		Logger.Debugf("Resolved host is: %s", host.HostName)
	}

	if host.ResolveCommand != "" {
		command := host.ExpandString(host.ResolveCommand)
		Logger.Debugf("Resolving host: %q using command: %q", host.HostName, command)

		args, err := shlex.Split(command)
		if err != nil {
			return err
		}

		out, err := exec.Command(args[0], args[1:]...).Output()
		if err != nil {
			return err
		}

		host.HostName = strings.TrimSpace(fmt.Sprintf("%s", out))
		Logger.Debugf("Resolved host is: %s", host.HostName)
	}
	return nil
}
示例#10
0
func commandApplyHost(command string, host *config.Host) string {
	command = strings.Replace(command, "%name", host.Name(), -1)
	command = strings.Replace(command, "%h", host.HostName, -1)
	command = strings.Replace(command, "%p", fmt.Sprintf("%d", host.Port), -1)
	return command
}