Пример #1
0
// remoteCmdOutput runs the given command on a remote server at the given hostname as the given user.
func remoteCmdOutput(username, hostname, cmd string, privateKey []byte) (b []byte, err error) {
	p, err := ssh.ParseRawPrivateKey(privateKey)
	if err != nil {
		return b, err
	}
	s, err := ssh.NewSignerFromKey(p)
	if err != nil {
		return b, err
	}
	pub := ssh.PublicKeys(s)
	clientConfig := &ssh.ClientConfig{
		User: username,
		Auth: []ssh.AuthMethod{pub},
	}
	client, err := ssh.Dial("tcp", hostname, clientConfig)
	if err != nil {
		return b, errors.New("ERROR: Failed to dial: " + err.Error())
	}
	defer client.Close()
	session, err := client.NewSession()
	if err != nil {
		return b, errors.New("ERROR: Failed to create session: " + err.Error())
	}
	defer session.Close()
	b, err = session.Output(cmd)
	if err != nil {
		return b, fmt.Errorf("ERROR: Failed to run cmd on host %s: %s", hostname, err.Error())
	}
	return b, nil
}
Пример #2
0
func (g GitConfig) HideKey() GitConfig {
	if g.Key == "" {
		return g
	}
	key, err := ssh.ParseRawPrivateKey([]byte(g.Key))
	if err != nil {
		g.Key = secretReplacement
		return g
	}

	privKey, ok := key.(*rsa.PrivateKey)
	if !ok {
		g.Key = secretReplacement
		return g
	}

	pubKey, err := ssh.NewPublicKey(&privKey.PublicKey)
	if err != nil {
		g.Key = secretReplacement
		return g
	}

	g.Key = string(ssh.MarshalAuthorizedKey(pubKey))
	return g
}
Пример #3
0
func (e *Environment) startProxyKeyring() (string, error) {
	keyring, err := NewProxyKeyring(os.Getenv("SSH_AUTH_SOCK"))
	if err != nil {
		return "", err
	}

	// load ssh keys
	for comment, key := range e.SSHKeys {
		addedKey := agent.AddedKey{
			Comment: comment,
		}

		addedKey.PrivateKey, err = ssh.ParseRawPrivateKey([]byte(key))
		if err != nil {
			return "", err
		}

		err := keyring.Add(addedKey)
		if err != nil {
			return "", err
		}
	}

	sock, err := keyring.Listen()
	if err != nil {
		return "", err
	}

	go keyring.Serve()

	return sock, err
}
Пример #4
0
// ParseKey reads the given RSA private key and create a public one for it.
func ParseKey(pem string) (*Key, error) {
	p, err := ioutil.ReadFile(pem)
	if err != nil {
		return nil, err
	}
	key, err := ssh.ParseRawPrivateKey(p)
	if err != nil {
		return nil, err
	}
	rsaKey, ok := key.(*rsa.PrivateKey)
	if !ok {
		return nil, fmt.Errorf("%q is not a RSA key", pem)
	}
	pub, err := ssh.NewPublicKey(&rsaKey.PublicKey)
	if err != nil {
		return nil, err
	}
	// Compute key fingerprint.
	var buf bytes.Buffer
	for _, b := range md5.Sum(pub.Marshal()) {
		fmt.Fprintf(&buf, "%0.2x:", b)
	}
	return &Key{
		Label:       strings.TrimSuffix(filepath.Base(pem), ".pem"),               // trim .pem file extension
		Key:         string(bytes.TrimRight(ssh.MarshalAuthorizedKey(pub), "\n")), // trim newline
		Fingerprint: string(bytes.TrimRight(buf.Bytes(), ":")),                    // trim dangling colon
		Note:        "{}",
		Tags:        make(Tags),
	}, nil
}
Пример #5
0
//export c_ParseRawPrivateKey
func c_ParseRawPrivateKey(pemBytes []byte) (uint64, int, *C.char) {
	pkey, err := ssh.ParseRawPrivateKey(pemBytes)
	if err != nil {
		return IH, ErrorCodeInternal, C.CString(err.Error())
	}
	// pointer is received - no need for &
	return uint64(RegisterObject(pkey)), ErrorCodeSuccess, nil
}
Пример #6
0
func (s *StepGetPassword) Run(state multistep.StateBag) multistep.StepAction {
	config := state.Get("config").(Config)
	ui := state.Get("ui").(packer.Ui)

	// Skip if we're not using winrm
	if s.Comm.Type != "winrm" {
		log.Printf("[INFO] Not using winrm communicator, skipping get password...")
		return multistep.ActionContinue
	}

	// If we already have a password, skip it
	if s.Comm.WinRMPassword != "" {
		ui.Say("Skipping waiting for password since WinRM password set...")
		return multistep.ActionContinue
	}

	// We need the v2 compute client
	computeClient, err := config.computeV2Client()
	if err != nil {
		err = fmt.Errorf("Error initializing compute client: %s", err)
		state.Put("error", err)
		return multistep.ActionHalt
	}

	ui.Say("Waiting for password since WinRM password is not set...")
	server := state.Get("server").(*servers.Server)
	var password string

	privateKey, err := ssh.ParseRawPrivateKey([]byte(state.Get("privateKey").(string)))
	if err != nil {
		err = fmt.Errorf("Error parsing private key: %s", err)
		state.Put("error", err)
		return multistep.ActionHalt
	}

	for ; password == "" && err == nil; password, err = servers.GetPassword(computeClient, server.ID).ExtractPassword(privateKey.(*rsa.PrivateKey)) {

		// Check for an interrupt in between attempts.
		if _, ok := state.GetOk(multistep.StateCancelled); ok {
			return multistep.ActionHalt
		}

		log.Printf("Retrying to get a administrator password evry 5 seconds.")
		time.Sleep(5 * time.Second)
	}

	ui.Message(fmt.Sprintf("Password retrieved!"))
	s.Comm.WinRMPassword = password

	// In debug-mode, we output the password
	if s.Debug {
		ui.Message(fmt.Sprintf(
			"Password (since debug is enabled) \"%s\"", s.Comm.WinRMPassword))
	}

	return multistep.ActionContinue
}
Пример #7
0
func (d *SDeployKeys) ParsePrivateKey(b []byte) (*rsa.PrivateKey, error) {
	in, err := ssh.ParseRawPrivateKey(b)
	if err != nil {
		return nil, errors.New("Invalid RSA private key format")
	}
	privKey := in.(*rsa.PrivateKey)
	return privKey, nil

}
Пример #8
0
func clientAuth(pemData []byte) (ssh.AuthMethod, error) {
	privKey, err := ssh.ParseRawPrivateKey(pemData)
	if err != nil {
		return nil, err
	}
	signer, err := ssh.NewSignerFromKey(privKey)
	if err != nil {
		return nil, err
	}
	return ssh.PublicKeys(signer), nil
}
Пример #9
0
func loadKey(file string) (interface{}, error) {
	buf, err := ioutil.ReadFile(file)
	if err != nil {
		return nil, err
	}

	key, err := ssh.ParseRawPrivateKey(buf)
	if err != nil {
		return nil, err
	}

	return key, nil
}
Пример #10
0
// Ok - return decrypted password when private key is given.
// Decrytion can be verified by:
//   echo "<enc_pwd>" | base64 -D | openssl rsautl -decrypt -inkey <privateKey.pem>
func TestExtractPassword_decrypted_pwd(t *testing.T) {

	privateKey, err := ssh.ParseRawPrivateKey([]byte(`
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAo1ODZgwMVdTJYim9UYuYhowoPMhGEuV5IRZjcJ315r7RBSC+
yEiBb1V+jhf+P8fzAyU35lkBzZGDr7E3jxSesbOuYT8cItQS4ErUnI1LGuqvMxwv
X3GMyE/HmOcaiODF1XZN3Ur5pMJdVknnmczgUsW0hT98Udrh3MQn9WSuh/6LRy6+
x1QsKHOCLFPnkhWa3LKyxmpQq/Gvhz+6NLe+gt8MFullA5mKQxBJ/K6laVHeaMlw
JG3GCX0EZhRlvzoV8koIBKZtbKFolFr8ZtxBm3R5LvnyrtOvp22sa+xeItUT5kG1
ZnbGNdK87oYW+VigEUfzT/+8R1i6E2QIXoeZiQIDAQABAoIBAQCVZ70IqbbTAW8j
RAlyQh/J3Qal65LmkFJJKUDX8TfT1/Q/G6BKeMEmxm+Zrmsfj1pHI1HKftt+YEG1
g4jOc09kQXkgbmnfll6aHPn3J+1vdwXD3GGdjrL5PrnYrngAhJWU2r8J0x8hT8ew
OrUJZXhDX6XuSpAAFRmOKUZgXbSmo4X+LZX76ACnarselJt5FL724ECvpWJ7xxC4
FMzvp4RqMmNFvv/Uq9lE/EmoSk4dviYyIZZ16DbDNyc9k/sGqCAMktCEwZ3EQm//
S5bkNhgP6oUXjluWy53aPRgykEylgDWo5SSdSEyKnw/fciU0xdprA9JrBGIcTyHS
/k2kgD4xAoGBANTkJ88Q0YrxX3fZNZVqcn00XKTxPGmxN5LRs7eV743q30AxK5Db
QU8iwaAA1IKUWV5DLhgUTNsDCOPUPue4aOSBD3/sj+WEmvIhj7afDL5didkYHsqf
fDnhFHq7y/3i57d428C7BwwR79pGWVyi7vH3pfu9A1iwl1aNOae+zvbVAoGBAMRm
AmwQ9fJ3Qc44jysFK/yliLRGdShjkMMah5G3JlrelwfPtwPwEL2EHHhJB/C1acMs
n6Q6RaoF6WNSZUY65ksQg7aPOYf2X0FTFwQJvwDJ4qlWjmq7w+tQ0AoGJG+dVUmQ
zHZ/Y+HokSXzz9c4oevk4v/rMgAQ00WHrTdtIhnlAoGBALIJJ72D7CkNGHCq5qPQ
xHQukPejgolFGhufYXM7YX3GmPMe67cVlTVv9Isxhoa5N0+cUPT0LR3PGOUm/4Bb
eOT3hZXOqLwhvE6XgI8Rzd95bClwgXekDoh80dqeKMdmta961BQGlKskaPiacmsF
G1yhZV70P9Mwwy8vpbLB4GUNAoGAbTwbjsWkNfa0qCF3J8NZoszjCvnBQfSW2J1R
1+8ZKyNwt0yFi3Ajr3TibNiZzPzp1T9lj29FvfpJxA9Y+sXZvthxmcFxizix5GB1
ha5yCNtA8VSOI7lJkAFDpL+j1lyYyjD6N9JE2KqEyKoh6J+8F7sXsqW7CqRRDfQX
mKNfey0CgYEAxcEoNoADN2hRl7qY9rbQfVvQb3RkoQkdHhl9gpLFCcV32IP8R4xg
09NbQK5OmgcIuZhLVNzTmUHJbabEGeXqIFIV0DsqECAt3WzbDyKQO23VJysFD46c
KSde3I0ybDz7iS2EtceKB7m4C0slYd+oBkm4efuF00rCOKDwpFq45m0=
-----END RSA PRIVATE KEY-----
`))
	if err != nil {
		t.Fatalf("Error parsing private key: %s\n", err)
	}

	var dejson interface{}
	sejson := []byte(`{"password":"******"}`)

	err = json.Unmarshal(sejson, &dejson)
	fmt.Printf("%v\n", dejson)
	if err != nil {
		t.Fatalf("%s", err)
	}
	resp := servers.GetPasswordResult{gophercloud.Result{Body: dejson}}

	pwd, err := resp.ExtractPassword(privateKey.(*rsa.PrivateKey))
	th.AssertNoErr(t, err)
	th.AssertEquals(t, "ruZKK0tqxRfYm5t7lSJq", pwd)
}
Пример #11
0
func init() {
	var err error

	n := len(testdata.PEMBytes)
	testPrivateKeys = make(map[string]interface{}, n)
	testSigners = make(map[string]ssh.Signer, n)
	testPublicKeys = make(map[string]ssh.PublicKey, n)
	for t, k := range testdata.PEMBytes {
		testPrivateKeys[t], err = ssh.ParseRawPrivateKey(k)
		if err != nil {
			panic(fmt.Sprintf("Unable to parse test key %s: %v", t, err))
		}
		testSigners[t], err = ssh.NewSignerFromKey(testPrivateKeys[t])
		if err != nil {
			panic(fmt.Sprintf("Unable to create signer for test key %s: %v", t, err))
		}
		testPublicKeys[t] = testSigners[t].PublicKey()
	}

	// Create a cert and sign it for use in tests.
	testCert := &ssh.Certificate{
		Nonce:           []byte{},                       // To pass reflect.DeepEqual after marshal & parse, this must be non-nil
		ValidPrincipals: []string{"gopher1", "gopher2"}, // increases test coverage
		ValidAfter:      0,                              // unix epoch
		ValidBefore:     ssh.CertTimeInfinity,           // The end of currently representable time.
		Reserved:        []byte{},                       // To pass reflect.DeepEqual after marshal & parse, this must be non-nil
		Key:             testPublicKeys["ecdsa"],
		SignatureKey:    testPublicKeys["rsa"],
		Permissions: ssh.Permissions{
			CriticalOptions: map[string]string{},
			Extensions:      map[string]string{},
		},
	}
	testCert.SignCert(rand.Reader, testSigners["rsa"])
	testPrivateKeys["cert"] = testPrivateKeys["ecdsa"]
	testSigners["cert"], err = ssh.NewCertSigner(testCert, testSigners["ecdsa"])
	if err != nil {
		panic(fmt.Sprintf("Unable to create certificate signer: %v", err))
	}
}
Пример #12
0
func (r *SSHCmd) UsePrivateKey(path string) error {
	if r.connected {
		return fmt.Errorf("Cannot add authentication methods while being connected")
	}
	content, err := ioutil.ReadFile(path)
	if err != nil {
		return err
	}
	privateKey, err := ssh.ParseRawPrivateKey(content)
	if err != nil {
		return err
	}
	signer, err := ssh.NewSignerFromKey(privateKey)
	if err != nil {
		return err
	}

	authMethod := ssh.PublicKeys(signer)
	r.config.Auth = append(r.config.Auth, authMethod)

	return nil
}
Пример #13
0
// PrivateKey sets the server's private key and host key.
func PrivateKey(pemData []byte) func(*Server) error {
	return func(s *Server) error {
		privKey, err := ssh.ParseRawPrivateKey(pemData)
		if err != nil {
			return err
		}
		hostKey, err := ssh.NewSignerFromKey(privKey)
		if err != nil {
			return err
		}
		pubKey := hostKey.PublicKey()

		s.SSH.AddHostKey(hostKey)
		s.SSH.PublicKeyCallback = func(c ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
			if bytes.Equal(key.Marshal(), pubKey.Marshal()) {
				return nil, nil
			}
			return nil, errors.New("public key rejected")
		}

		return nil
	}
}
Пример #14
0
func newSSHServer(
	support *SupportServices,
	shutdownBroadcast <-chan struct{}) (*sshServer, error) {

	privateKey, err := ssh.ParseRawPrivateKey([]byte(support.Config.SSHPrivateKey))
	if err != nil {
		return nil, psiphon.ContextError(err)
	}

	// TODO: use cert (ssh.NewCertSigner) for anti-fingerprint?
	signer, err := ssh.NewSignerFromKey(privateKey)
	if err != nil {
		return nil, psiphon.ContextError(err)
	}

	return &sshServer{
		support:              support,
		shutdownBroadcast:    shutdownBroadcast,
		sshHostKey:           signer,
		nextClientID:         1,
		acceptedClientCounts: make(map[string]int64),
		clients:              make(map[sshClientID]*sshClient),
	}, nil
}
Пример #15
0
// runSSHServer runs an SSH or Obfuscated SSH server. In the Obfuscated SSH case, an
// ObfuscatedSSHConn is layered in front of the client TCP connection; otherwise, both
// modes are identical.
//
// runSSHServer listens on the designated port and spawns new goroutines to handle
// each client connection. It halts when shutdownBroadcast is signaled. A list of active
// clients is maintained, and when halting all clients are first shutdown.
//
// Each client goroutine handles its own obfuscation (optional), SSH handshake, SSH
// authentication, and then looping on client new channel requests. At this time, only
// "direct-tcpip" channels, dynamic port fowards, are expected and supported.
//
// A new goroutine is spawned to handle each port forward. Each port forward tracks its
// bytes transferred. Overall per-client stats for connection duration, GeoIP, number of
// port forwards, and bytes transferred are tracked and logged when the client shuts down.
func runSSHServer(
	config *Config, useObfuscation bool, shutdownBroadcast <-chan struct{}) error {

	privateKey, err := ssh.ParseRawPrivateKey([]byte(config.SSHPrivateKey))
	if err != nil {
		return psiphon.ContextError(err)
	}

	// TODO: use cert (ssh.NewCertSigner) for anti-fingerprint?
	signer, err := ssh.NewSignerFromKey(privateKey)
	if err != nil {
		return psiphon.ContextError(err)
	}

	sshServer := &sshServer{
		config:            config,
		useObfuscation:    useObfuscation,
		shutdownBroadcast: shutdownBroadcast,
		sshHostKey:        signer,
		nextClientID:      1,
		clients:           make(map[sshClientID]*sshClient),
	}

	var serverPort int
	if useObfuscation {
		serverPort = config.ObfuscatedSSHServerPort
	} else {
		serverPort = config.SSHServerPort
	}

	listener, err := net.Listen(
		"tcp", fmt.Sprintf("%s:%d", config.ServerIPAddress, serverPort))
	if err != nil {
		return psiphon.ContextError(err)
	}

	log.WithContextFields(
		LogFields{
			"useObfuscation": useObfuscation,
			"port":           serverPort,
		}).Info("starting")

	err = nil
	errors := make(chan error)
	waitGroup := new(sync.WaitGroup)

	waitGroup.Add(1)
	go func() {
		defer waitGroup.Done()

	loop:
		for {
			conn, err := listener.Accept()

			select {
			case <-shutdownBroadcast:
				if err == nil {
					conn.Close()
				}
				break loop
			default:
			}

			if err != nil {
				if e, ok := err.(net.Error); ok && e.Temporary() {
					log.WithContextFields(LogFields{"error": err}).Error("accept failed")
					// Temporary error, keep running
					continue
				}

				select {
				case errors <- psiphon.ContextError(err):
				default:
				}

				break loop
			}

			// process each client connection concurrently
			go sshServer.handleClient(conn.(*net.TCPConn))
		}

		sshServer.stopClients()

		log.WithContextFields(
			LogFields{"useObfuscation": useObfuscation}).Info("stopped")
	}()

	select {
	case <-shutdownBroadcast:
	case err = <-errors:
	}

	listener.Close()

	waitGroup.Wait()

	log.WithContextFields(
		LogFields{"useObfuscation": useObfuscation}).Info("exiting")

	return err
}