예제 #1
0
func proxyCommand(host *config.Host, command string) error {
	command = commandApplyHost(command, host)
	args, err := shlex.Split(command)
	logrus.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()
}
예제 #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
// LoadFile loads the content of a configuration file in the Config object
func (c *Config) LoadFile(filename string) error {
	// Resolve '~' and '$HOME'
	filepath, err := expandUser(filename)
	if err != nil {
		return err
	}
	logrus.Debugf("Loading config file '%s'", filepath)

	// Anti-loop protection
	if _, ok := c.includedFiles[filepath]; ok {
		logrus.Debugf("File %s already loaded", filepath)
		return nil
	}
	c.includedFiles[filepath] = false

	// Read file
	source, err := os.Open(filepath)
	if err != nil {
		return err
	}

	// Load config stream
	err = c.LoadConfig(source)
	if err != nil {
		return err
	}

	// Successful loading
	c.includedFiles[filepath] = true

	// Handling includes
	for _, include := range c.Includes {
		c.LoadFiles(include)
	}

	return nil
}
예제 #4
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)
}