Skip to content

Instantly share code, notes, and snippets.

@marete
Created May 28, 2013 17:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marete/5664392 to your computer and use it in GitHub Desktop.
Save marete/5664392 to your computer and use it in GitHub Desktop.
A simple Go program demonstrating two applications of code.google.com/p/go.crypto/ssh: Authentication using public key crypto and the tunneling of a HTTP request through the resulting SSH connection. In this gist, the remote SSH server is on localhost and the HTTP URL tunneled over the established secure connection is http://localhost:6060. But,…
package main
import (
"code.google.com/p/go.crypto/ssh"
"crypto"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
//"fmt"
"io"
"io/ioutil"
"os"
"log"
"net/http"
"os/user"
"path"
)
type keychain struct {
key *rsa.PrivateKey
}
func (k *keychain) Key(i int) (interface{}, error) {
if i != 0 {
return nil, nil
}
return &k.key.PublicKey, nil
}
func (k *keychain) Sign(i int, rand io.Reader, data []byte) (sig []byte, err error) {
hashFunc := crypto.SHA1
h := hashFunc.New()
h.Write(data)
digest := h.Sum(nil)
return rsa.SignPKCS1v15(rand, k.key, hashFunc, digest)
}
func main() {
u, err := user.Current()
if err != nil {
panic(err)
}
idRSAFileName := path.Join(u.HomeDir, ".ssh", "id_rsa")
idRSAFile, err := os.Open(idRSAFileName)
if err != nil {
panic(err)
}
defer idRSAFile.Close()
privateKey, err := ioutil.ReadAll(idRSAFile)
if err != nil {
panic(err)
}
block, _ := pem.Decode(privateKey)
if block == nil {
log.Fatalln("No PEM encoded block found in", idRSAFile.Name())
}
rsakey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
log.Fatalln(err)
}
clientKey := &keychain{rsakey}
clientConfig := &ssh.ClientConfig{
User: u.Username,
Auth: []ssh.ClientAuth{
ssh.ClientAuthKeyring(clientKey),
},
}
client, err := ssh.Dial("tcp", "localhost:22", clientConfig)
if err != nil {
log.Fatalln("Failed to dial: " + err.Error())
}
tr := &http.Transport {
Dial: client.Dial,
}
httpClient := &http.Client {
Transport: tr,
}
resp, err := httpClient.Get("http://localhost:6060")
if err != nil {
log.Fatalln(err)
}
defer resp.Body.Close()
_, err = io.Copy(os.Stdout, resp.Body)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment