Last active
August 29, 2015 14:02
-
-
Save jordic/a09183c5887ec0aca212 to your computer and use it in GitHub Desktop.
tunnel.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
// based on gist | |
// https://gist.github.com/ir4y/11146415 | |
// http://stackoverflow.com/questions/21417223/simple-ssh-port-forward-in-golang | |
import ( | |
"code.google.com/p/go.crypto/ssh" | |
"code.google.com/p/gopass" | |
"fmt" | |
"io" | |
"log" | |
"net" | |
) | |
func copy_network(in net.Conn, out net.Conn) { | |
buf := make([]byte, 10240) | |
for { | |
n, err := in.Read(buf) | |
if io.EOF == err { | |
log.Printf("io.EOF") | |
return | |
} else if nil != err { | |
log.Printf("resend err\n", err) | |
return | |
} | |
out.Write(buf[:n]) | |
} | |
} | |
// Builds a tunnel agains server_address, with username | |
// | |
func Use_tunnel(username string, server_addrs string, | |
quit chan bool, wait chan bool) { | |
pass, err := gopass.GetPass("Enter a password: ") | |
config := &ssh.ClientConfig{ | |
User: username, | |
Auth: []ssh.AuthMethod{ | |
ssh.Password(pass), | |
}, | |
} | |
// remote connection | |
conn, err := ssh.Dial("tcp", server_addrs, config) | |
if err != nil { | |
log.Fatalf("Unable to connect %s", err) | |
} | |
//local catcher | |
local, err := net.Listen("tcp", "localhost:3306") | |
if err != nil { | |
log.Fatalf("Unable to connect %s", err) | |
} | |
// ssh connection is ready? | |
wait <- true | |
fmt.Println("ssh connection ready") | |
for { | |
l, err := local.Accept() | |
if err != nil { | |
//log.Fatalf("listen Accept failed %s", err) | |
fmt.Println("Continue with error") | |
return | |
} | |
//fmt.Println("iterating from tunnel, ") | |
go func() { | |
remote, err := conn.Dial("tcp", "localhost:3306") | |
if err != nil { | |
log.Fatalf("Unable to connect %s", err) | |
} | |
go copy_network(l, remote) | |
go copy_network(remote, l) | |
if <-quit { | |
fmt.Println("quiting from channel quit") | |
conn.Close() | |
remote.Close() | |
local.Close() | |
return | |
} | |
}() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment