示例#1
0
func opensshOptions(options *Options, commandKind opensshCommandKind) []string {
	args := append([]string{}, opensshCommonOptions...)
	if options == nil {
		options = &Options{}
	}
	if len(options.proxyCommand) > 0 {
		args = append(args, "-o", "ProxyCommand "+utils.CommandString(options.proxyCommand...))
	}
	if !options.passwordAuthAllowed {
		args = append(args, "-o", "PasswordAuthentication no")
	}

	// We must set ServerAliveInterval or the server may
	// think we've become unresponsive on long running
	// command executions such as "apt-get upgrade".
	args = append(args, "-o", "ServerAliveInterval 30")

	if options.allocatePTY {
		args = append(args, "-t", "-t") // twice to force
	}
	if options.knownHostsFile != "" {
		args = append(args, "-o", "UserKnownHostsFile "+utils.CommandString(options.knownHostsFile))
	}
	identities := append([]string{}, options.identities...)
	if pk := PrivateKeyFiles(); len(pk) > 0 {
		// Add client keys as implicit identities
		identities = append(identities, pk...)
	}
	// If any identities are specified, the
	// default ones must be explicitly specified.
	if len(identities) > 0 {
		// Restrict SSH to only the explicitly provided identity files.
		// Otherwise we may run out of authentication attempts if the
		// user has many identity files.
		args = append(args, "-o", "IdentitiesOnly yes")
		for _, identity := range defaultIdentities {
			path, err := utils.NormalizePath(identity)
			if err != nil {
				logger.Warningf("failed to normalize path %q: %v", identity, err)
				continue
			}
			if _, err := os.Stat(path); err == nil {
				identities = append(identities, path)
			}
		}
	}
	for _, identity := range identities {
		args = append(args, "-i", identity)
	}
	if options.port != 0 {
		port := fmt.Sprint(options.port)
		if commandKind == scpKind {
			// scp uses -P instead of -p (-p means preserve).
			args = append(args, "-P", port)
		} else {
			args = append(args, "-p", port)
		}
	}
	return args
}
示例#2
0
// Command implements Client.Command.
func (c *OpenSSHClient) Command(host string, command []string, options *Options) *Cmd {
	args := opensshOptions(options, sshKind)
	args = append(args, host)
	if len(command) > 0 {
		args = append(args, command...)
	}
	bin, args := sshpassWrap("ssh", args)
	logger.Debugf("running: %s %s", bin, utils.CommandString(args...))
	return &Cmd{impl: &opensshCmd{exec.Command(bin, args...)}}
}
示例#3
0
func opensshOptions(options *Options, commandKind opensshCommandKind) []string {
	args := append([]string{}, opensshCommonOptions...)
	if options == nil {
		options = &Options{}
	}
	if len(options.proxyCommand) > 0 {
		args = append(args, "-o", "ProxyCommand "+utils.CommandString(options.proxyCommand...))
	}
	if !options.passwordAuthAllowed {
		args = append(args, "-o", "PasswordAuthentication no")
	}
	if options.allocatePTY {
		args = append(args, "-t", "-t") // twice to force
	}
	identities := append([]string{}, options.identities...)
	if pk := PrivateKeyFiles(); len(pk) > 0 {
		// Add client keys as implicit identities
		identities = append(identities, pk...)
	}
	// If any identities are specified, the
	// default ones must be explicitly specified.
	if len(identities) > 0 {
		for _, identity := range defaultIdentities {
			path, err := utils.NormalizePath(identity)
			if err != nil {
				logger.Warningf("failed to normalize path %q: %v", identity, err)
				continue
			}
			if _, err := os.Stat(path); err == nil {
				identities = append(identities, path)
			}
		}
	}
	for _, identity := range identities {
		args = append(args, "-i", identity)
	}
	if options.port != 0 {
		port := fmt.Sprint(options.port)
		if commandKind == scpKind {
			// scp uses -P instead of -p (-p means preserve).
			args = append(args, "-P", port)
		} else {
			args = append(args, "-p", port)
		}
	}
	return args
}
示例#4
0
// Copy implements Client.Copy.
func (c *OpenSSHClient) Copy(args []string, userOptions *Options) error {
	var options Options
	if userOptions != nil {
		options = *userOptions
		options.allocatePTY = false // doesn't make sense for scp
	}
	allArgs := opensshOptions(&options, scpKind)
	allArgs = append(allArgs, args...)
	bin, allArgs := sshpassWrap("scp", allArgs)
	cmd := exec.Command(bin, allArgs...)
	var stderr bytes.Buffer
	cmd.Stderr = &stderr
	logger.Debugf("running: %s %s", bin, utils.CommandString(args...))
	if err := cmd.Run(); err != nil {
		stderr := strings.TrimSpace(stderr.String())
		if len(stderr) > 0 {
			err = fmt.Errorf("%v (%v)", err, stderr)
		}
		return err
	}
	return nil
}
示例#5
0
// Command implements Client.Command.
func (c *GoCryptoClient) Command(host string, command []string, options *Options) *Cmd {
	shellCommand := utils.CommandString(command...)
	signers := c.signers
	if len(signers) == 0 {
		signers = privateKeys()
	}
	user, host := splitUserHost(host)
	port := sshDefaultPort
	var proxyCommand []string
	if options != nil {
		if options.port != 0 {
			port = options.port
		}
		proxyCommand = options.proxyCommand
	}
	logger.Tracef(`running (equivalent of): ssh "%s@%s" -p %d '%s'`, user, host, port, shellCommand)
	return &Cmd{impl: &goCryptoCommand{
		signers:      signers,
		user:         user,
		addr:         net.JoinHostPort(host, strconv.Itoa(port)),
		command:      shellCommand,
		proxyCommand: proxyCommand,
	}}
}
示例#6
0
func (*utilsSuite) TestCommandString(c *gc.C) {
	type test struct {
		args     []string
		expected string
	}
	tests := []test{
		{nil, ""},
		{[]string{"a"}, "a"},
		{[]string{"a$"}, `"a\$"`},
		{[]string{""}, ""},
		{[]string{"\\"}, `"\\"`},
		{[]string{"a", "'b'"}, "a 'b'"},
		{[]string{"a b"}, `"a b"`},
		{[]string{"a", `"b"`}, `a "\"b\""`},
		{[]string{"a", `"b\"`}, `a "\"b\\\""`},
		{[]string{"a\n"}, "\"a\n\""},
	}
	for i, test := range tests {
		c.Logf("test %d: %q", i, test.args)
		result := utils.CommandString(test.args...)
		c.Assert(result, gc.Equals, test.expected)
	}
}

func (*utilsSuite) TestReadSHA256AndReadFileSHA256(c *gc.C) {
	sha256Tests := []struct {
		content string
		sha256  string
	}{{
		content: "",
		sha256:  "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
	}, {
		content: "some content",
		sha256:  "290f493c44f5d63d06b374d0a5abd292fae38b92cab2fae5efefe1b0e9347f56",
	}, {
		content: "foo",
		sha256:  "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae",
	}, {
		content: "Foo",
		sha256:  "1cbec737f863e4922cee63cc2ebbfaafcd1cff8b790d8cfd2e6a5d550b648afa",
	}, {
		content: "multi\nline\ntext\nhere",
		sha256:  "c384f11c0294280792a44d9d6abb81f9fd991904cb7eb851a88311b04114231e",
	}}

	tempDir := c.MkDir()
	for i, test := range sha256Tests {
		c.Logf("test %d: %q -> %q", i, test.content, test.sha256)
		buf := bytes.NewBufferString(test.content)
		hash, size, err := utils.ReadSHA256(buf)
		c.Check(err, gc.IsNil)
		c.Check(hash, gc.Equals, test.sha256)
		c.Check(int(size), gc.Equals, len(test.content))

		tempFileName := filepath.Join(tempDir, fmt.Sprintf("sha256-%d", i))
		err = ioutil.WriteFile(tempFileName, []byte(test.content), 0644)
		c.Check(err, gc.IsNil)
		fileHash, fileSize, err := utils.ReadFileSHA256(tempFileName)
		c.Check(err, gc.IsNil)
		c.Check(fileHash, gc.Equals, hash)
		c.Check(fileSize, gc.Equals, size)
	}
}
示例#7
0
func opensshOptions(options *Options, commandKind opensshCommandKind) []string {
	if options == nil {
		options = &Options{}
	}
	var args []string

	var hostChecks string
	switch options.strictHostKeyChecking {
	case StrictHostChecksYes:
		hostChecks = "yes"
	case StrictHostChecksNo:
		hostChecks = "no"
	case StrictHostChecksAsk:
		hostChecks = "ask"
	default:
		// StrictHostChecksUnset and invalid values are handled the
		// same way (the option doesn't get included).
	}
	if hostChecks != "" {
		args = append(args, "-o", "StrictHostKeyChecking "+hostChecks)
	}

	if len(options.proxyCommand) > 0 {
		args = append(args, "-o", "ProxyCommand "+utils.CommandString(options.proxyCommand...))
	}

	if !options.passwordAuthAllowed {
		args = append(args, "-o", "PasswordAuthentication no")
	}

	// We must set ServerAliveInterval or the server may
	// think we've become unresponsive on long running
	// command executions such as "apt-get upgrade".
	args = append(args, "-o", "ServerAliveInterval 30")

	if options.allocatePTY {
		args = append(args, "-t", "-t") // twice to force
	}
	if options.knownHostsFile != "" {
		args = append(args, "-o", "UserKnownHostsFile "+utils.CommandString(options.knownHostsFile))
	}
	identities := append([]string{}, options.identities...)
	if pk := PrivateKeyFiles(); len(pk) > 0 {
		// Add client keys as implicit identities
		identities = append(identities, pk...)
	}
	// If any identities are specified, the
	// default ones must be explicitly specified.
	if len(identities) > 0 {
		for _, identity := range defaultIdentities {
			path, err := utils.NormalizePath(identity)
			if err != nil {
				logger.Warningf("failed to normalize path %q: %v", identity, err)
				continue
			}
			if _, err := os.Stat(path); err == nil {
				identities = append(identities, path)
			}
		}
	}
	for _, identity := range identities {
		args = append(args, "-i", identity)
	}
	if options.port != 0 {
		port := fmt.Sprint(options.port)
		if commandKind == scpKind {
			// scp uses -P instead of -p (-p means preserve).
			args = append(args, "-P", port)
		} else {
			args = append(args, "-p", port)
		}
	}
	return args
}