// 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 }
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 }
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 }
// 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 }
//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 }
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 }
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 }
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 }
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 }
// 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) }
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)) } }
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 }
// 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 } }
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 }
// 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 }