summaryrefslogtreecommitdiff
path: root/internal/ssh/ssh.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/ssh/ssh.go')
-rw-r--r--internal/ssh/ssh.go112
1 files changed, 112 insertions, 0 deletions
diff --git a/internal/ssh/ssh.go b/internal/ssh/ssh.go
new file mode 100644
index 0000000..77cc341
--- /dev/null
+++ b/internal/ssh/ssh.go
@@ -0,0 +1,112 @@
+package ssh
+
+import (
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/x509"
+ "github.com/mimecast/dtail/internal/logger"
+ "encoding/pem"
+ "fmt"
+ "io/ioutil"
+ "net"
+ "os"
+ "syscall"
+
+ gossh "golang.org/x/crypto/ssh"
+ "golang.org/x/crypto/ssh/agent"
+ "golang.org/x/crypto/ssh/terminal"
+)
+
+// GeneratePrivateRSAKey is used by the server to generate its key.
+func GeneratePrivateRSAKey(size int) (*rsa.PrivateKey, error) {
+ privateKey, err := rsa.GenerateKey(rand.Reader, size)
+ if err != nil {
+ return nil, err
+ }
+
+ err = privateKey.Validate()
+ if err != nil {
+ return nil, err
+ }
+
+ return privateKey, nil
+}
+
+// EncodePrivateKeyToPEM is a helper function for converting a key to PEM format.
+func EncodePrivateKeyToPEM(privateKey *rsa.PrivateKey) []byte {
+ derFormat := x509.MarshalPKCS1PrivateKey(privateKey)
+
+ block := pem.Block{
+ Type: "RSA PRIVATE KEY",
+ Headers: nil,
+ Bytes: derFormat,
+ }
+
+ return pem.EncodeToMemory(&block)
+}
+
+// Agent used for SSH auth.
+func Agent() (gossh.AuthMethod, error) {
+ sshAgent, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK"))
+ if err != nil {
+ return nil, err
+ }
+ agentClient := agent.NewClient(sshAgent)
+ keys, err := agentClient.List()
+ if err != nil {
+ return nil, err
+ }
+ for i, key := range keys {
+ logger.Debug("Public key", i, key)
+ }
+ return gossh.PublicKeysCallback(agentClient.Signers), nil
+}
+
+// EnterKeyPhrase is required to read phrase protected private keys.
+func EnterKeyPhrase(keyFile string) []byte {
+ fmt.Printf("Enter phrase for key %s: ", keyFile)
+ phrase, err := terminal.ReadPassword(int(syscall.Stdin))
+ if err != nil {
+ panic(err)
+ }
+ fmt.Printf("%s\n", string(phrase))
+ return phrase
+}
+
+// KeyFile returns the key as a SSH auth method.
+func KeyFile(keyFile string) (gossh.AuthMethod, error) {
+ buffer, err := ioutil.ReadFile(keyFile)
+ if err != nil {
+ return nil, err
+ }
+
+ key, err := gossh.ParsePrivateKey(buffer)
+ if err != nil {
+ return nil, err
+ }
+
+ // Key phrase support disabled as password will be printed to stdout!
+ /*
+ if err == nil {
+ return gossh.PublicKeys(key), nil
+ }
+
+ keyPhrase := EnterKeyPhrase(keyFile)
+ key, err = gossh.ParsePrivateKeyWithPassphrase(buffer, keyPhrase)
+ if err != nil {
+ return nil, err
+ }
+ */
+
+ return gossh.PublicKeys(key), nil
+}
+
+// PrivateKey returns the private key as a SSH auth method.
+func PrivateKey(keyFile string) (gossh.AuthMethod, error) {
+ signer, err := KeyFile(keyFile)
+ if err != nil {
+ logger.Debug(keyFile, err)
+ return nil, err
+ }
+ return gossh.AuthMethod(signer), nil
+}