Skip to content

Commit

Permalink
Create initial version of simple wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
tlbdk committed Nov 9, 2019
1 parent 69f57c1 commit 9e32614
Show file tree
Hide file tree
Showing 6 changed files with 218 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@

# Output of the go coverage tool, specifically when used with LiteIDE
*.out
.vscode
61 changes: 61 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package main

import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"syscall"

"github.com/connectedcars/auth-wrapper/ssh"
)

func main() {
sshKeyPath := os.Getenv("SSH_KEY_PATH")
sshKeyPassword := os.Getenv("SSH_KEY_PASSWORD")
os.Unsetenv("SSH_KEY_PATH")
os.Unsetenv("SSH_KEY_PASSWORD")

if sshKeyPath != "" {
privateKeyBytes, err := ioutil.ReadFile(sshKeyPath)
if err != nil {
fmt.Printf("Failed to read SSHPrivateKey from %s: %v\n", sshKeyPath, err)
os.Exit(1)
}
sshAuthSock, err := ssh.SetupAgent(privateKeyBytes, sshKeyPassword)
if err != nil {
fmt.Printf("Failed to start ssh agent server: %v\n", err)
os.Exit(1)
}
os.Setenv("SSH_AUTH_SOCK", sshAuthSock)
}

if len(os.Args) < 2 {
fmt.Println("auth-wrapper cmd args")
os.Exit(1)
}

// Setup exec command
command := os.Args[1]
args := os.Args[2:]
cmd := exec.Command(command, args...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr

if err := cmd.Start(); err != nil {
fmt.Printf("cmd.Start: %v\n", err)
os.Exit(1)
}

if err := cmd.Wait(); err != nil {
if exiterr, ok := err.(*exec.ExitError); ok {
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
os.Exit(status.ExitStatus())
}
} else {
fmt.Printf("cmd.Wait: %v\n", err)
os.Exit(1)
}
}
}
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module github.com/connectedcars/auth-wrapper

go 1.13

require golang.org/x/crypto v0.0.0-20191108234033-bd318be0434a
7 changes: 7 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191108234033-bd318be0434a h1:R/qVym5WAxsZWQqZCwDY/8sdVKV1m1WgU4/S5IRQAzc=
golang.org/x/crypto v0.0.0-20191108234033-bd318be0434a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
87 changes: 87 additions & 0 deletions ssh/sshagent.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package ssh

import (
"io/ioutil"
"log"
"math/rand"
"net"
"os"
"strings"

"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
)

// SetupAgent start an SSH Agent server and loads the given private key
func SetupAgent(privateKeyBytes []byte, passphrase string) (sshAuthSock string, error error) {
sshAgent := agent.NewKeyring()

privateKey, err := parsePrivateSSHKey(privateKeyBytes, passphrase)
if err != nil {
return "", err
}

err = sshAgent.Add(agent.AddedKey{PrivateKey: privateKey, Comment: "my private key"})
if err != nil {
return "", err
}

// Generate random filename
dir, err := ioutil.TempDir(os.TempDir(), "")
if err != nil {
log.Fatal(err)
}
sshAuthSock = dir + "/" + generateRandomString(8) + ".sock"

go func() {
// Open SSH agent socket
if err := os.RemoveAll(sshAuthSock); err != nil {
log.Fatal(err)
}
l, err := net.Listen("unix", sshAuthSock)
if err != nil {
log.Fatal(err)
}
defer l.Close()

// Accept new connections, dispatching them to an ssh agent server in the background
for {
conn, err := l.Accept()
if err != nil {
log.Fatal("accept error:", err)
}

go agent.ServeAgent(sshAgent, conn)
}
}()

return sshAuthSock, err
}

const letterBytes = "abcdefghijklmnopqrstuvwxyz"

func generateRandomString(n int) string {
b := make([]byte, n)
for i := range b {
b[i] = letterBytes[rand.Intn(len(letterBytes))]
}
return string(b)
}

func parsePrivateSSHKey(privateKeyBytes []byte, passphrase string) (interface{}, error) {
var err error
var privateKey interface{}
if strings.Contains(string(privateKeyBytes), "ENCRYPTED") {
privateKey, err = ssh.ParseRawPrivateKeyWithPassphrase(privateKeyBytes, []byte(passphrase))
if err != nil {
return nil, err
}
} else {
privateKey, err = ssh.ParseRawPrivateKey(privateKeyBytes)
if err != nil {
return nil, err
}
}

return privateKey, nil
}
57 changes: 57 additions & 0 deletions ssh/sshagent_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package ssh

import (
"testing"
)

var privateKeyBytes = []byte(`-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC8A6FGHDiWCSREAXCq6yBfNVr0xCVG2CzvktFNRpue+RXrGs/2
a6ySEJQb3IYquw7HlJgu6fg3WIWhOmHCjfpG0PrL4CRwbqQ2LaPPXhJErWYejcD8
Di00cF3677+G10KMZk9RXbmHtuBFZT98wxg8j+ZsBMqGM1+7yrWUvynswQIDAQAB
AoGAJMCk5vqfSRzyXOTXLGIYCuR4Kj6pdsbNSeuuRGfYBeR1F2c/XdFAg7D/8s5R
38p/Ih52/Ty5S8BfJtwtvgVY9ecf/JlU/rl/QzhG8/8KC0NG7KsyXklbQ7gJT8UT
Ojmw5QpMk+rKv17ipDVkQQmPaj+gJXYNAHqImke5mm/K/h0CQQDciPmviQ+DOhOq
2ZBqUfH8oXHgFmp7/6pXw80DpMIxgV3CwkxxIVx6a8lVH9bT/AFySJ6vXq4zTuV9
6QmZcZzDAkEA2j/UXJPIs1fQ8z/6sONOkU/BjtoePFIWJlRxdN35cZjXnBraX5UR
fFHkePv4YwqmXNqrBOvSu+w2WdSDci+IKwJAcsPRc/jWmsrJW1q3Ha0hSf/WG/Bu
X7MPuXaKpP/DkzGoUmb8ks7yqj6XWnYkPNLjCc8izU5vRwIiyWBRf4mxMwJBAILa
NDvRS0rjwt6lJGv7zPZoqDc65VfrK2aNyHx2PgFyzwrEOtuF57bu7pnvEIxpLTeM
z26i6XVMeYXAWZMTloMCQBbpGgEERQpeUknLBqUHhg/wXF6+lFA+vEGnkY+Dwab2
KCXFGd+SQ5GdUcEMe9isUH6DYj/6/yCDoFrXXmpQb+M=
-----END RSA PRIVATE KEY-----
`)

func TestSshAgent(t *testing.T) {
//privateKeyBytes, err := ioutil.ReadFile("/home/user/.ssh/id_rsa")
//if err != nil {
// t.Fatal(err)
//}

/* sshAuthSock, err := setupAgent(privateKeyBytes, "Qwerty1234")
if err != nil {
t.Error(err)
}
// Setup exec command
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
cmd := exec.CommandContext(ctx, "ssh", []string{"-v", "git@github.com"}...)
//cmd := exec.CommandContext(ctx, "ssh-add", []string{"-l"}...)
cmd.Env = []string{"SSH_AUTH_SOCK=" + sshAuthSock}
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Start()
if err != nil {
t.Error(err)
}
err = cmd.Wait()
if ctx.Err() == context.DeadlineExceeded {
t.Error("timed out")
}
if err != nil {
t.Error(err)
} */

}

0 comments on commit 9e32614

Please sign in to comment.