Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F136002
tunnel.go
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
3 KB
Subscribers
None
tunnel.go
View Options
package
sshtunnel
import
(
"net"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/agent"
"fmt"
"io"
"os"
"log"
"sync"
"time"
)
type
SSHtunnel
struct
{
Local
[]
Endpoint
Server
*
Endpoint
Remote
[]
Endpoint
ErrorChans
[]
chan
error
ServerClient
*
ssh
.
Client
Config
*
ssh
.
ClientConfig
ServerConnection
*
ssh
.
ServerConfig
ExecPath
string
sync
.
Mutex
}
func
(
tunnel
*
SSHtunnel
)
Listen
(
localE
Endpoint
,
remoteE
Endpoint
,
errorChan
chan
error
)
{
log
.
Printf
(
"LocalEndpoint: %v, RemoteEndpoint: %v"
,
localE
,
remoteE
)
listener
,
err
:=
net
.
Listen
(
"tcp"
,
localE
.
String
())
if
err
!=
nil
{
return
}
for
{
conn
,
err
:=
listener
.
Accept
()
if
err
!=
nil
{
log
.
Println
(
"Cannot listen."
)
errorChan
<-
err
}
defer
listener
.
Close
()
log
.
Printf
(
"Localhost listen %s, Remote Connection: %s \n"
,
localE
.
String
(),
remoteE
.
String
())
go
tunnel
.
forward
(
conn
,
remoteE
)
}
}
func
(
tunnel
*
SSHtunnel
)
Start
()
error
{
var
err
error
tunnel
.
ErrorChans
=
make
([]
chan
error
,
len
(
tunnel
.
Local
))
//
tunnel
.
ServerClient
,
err
=
ssh
.
Dial
(
"tcp"
,
tunnel
.
Server
.
String
(),
tunnel
.
Config
)
if
err
!=
nil
{
fmt
.
Printf
(
"Server dial error: %s\n"
,
err
)
//log.Println("Sever dial error occurred. No Internet connection. Program exited.")
// if err == "ssh: handshake failed: ssh: unable to authenticate, attempted methods [password none], no supported methods remain" {
// fmt.Println(" Incorrect Password entered.")
os
.
Exit
(
1
)
return
err
}
//Keep alive
done
:=
make
(
chan
bool
)
go
tunnel
.
keepalive
(
done
)
//
for
i
,
_
:=
range
tunnel
.
Local
{
//defer listener.Close()
log
.
Printf
(
"Main - LocalEndpoint: %v, RemoteEndpoint: %v"
,
tunnel
.
Local
[
i
],
tunnel
.
Remote
[
i
])
go
tunnel
.
Listen
(
tunnel
.
Local
[
i
],
tunnel
.
Remote
[
i
],
tunnel
.
ErrorChans
[
i
])
}
for
{
for
_
,
c
:=
range
tunnel
.
ErrorChans
{
select
{
case
msg
:=
<-
c
:
log
.
Printf
(
"\n in tunnel.errorschans : %v"
,
msg
)
// case msg2:= <- done:
// log.Printf("%v", msg2)
// os.Exit(1)
default
:
//fmt.Println("No message received")
}
}
time
.
Sleep
(
time
.
Second
*
1
)
//TODO run ExecPath
}
return
err
}
func
(
tunnel
*
SSHtunnel
)
keepalive
(
done
chan
bool
)
{
for
{
// Create a session. It is one session per command.
session
,
err
:=
tunnel
.
ServerClient
.
NewSession
()
if
err
!=
nil
{
log
.
Print
(
"Unable to open keep alive session."
)
}
else
{
log
.
Print
(
"Keep alive session opened."
)
}
session
.
Close
()
select
{
case
message
:=
<-
done
:
if
message
==
true
{
break
}
default
:
}
time
.
Sleep
(
20000
*
time
.
Millisecond
)
}
}
//TODO refactor to accept remoteEndpoint
func
(
tunnel
*
SSHtunnel
)
forward
(
localConn
net
.
Conn
,
remoteEndpoint
Endpoint
)
{
var
err
error
log
.
Printf
(
"Connect with client. %s \n"
,
remoteEndpoint
.
String
())
remoteConn
,
err
:=
tunnel
.
ServerClient
.
Dial
(
"tcp"
,
remoteEndpoint
.
String
())
if
err
!=
nil
{
fmt
.
Printf
(
"Remote dial error: %s\n"
,
err
)
log
.
Println
(
"Remote dial error occurred. Trying to establish a new server connection."
)
tunnel
.
ServerClient
,
err
=
ssh
.
Dial
(
"tcp"
,
tunnel
.
Server
.
String
(),
tunnel
.
Config
)
return
}
log
.
Printf
(
"Remote connection: %v"
,
remoteConn
)
copyConn
:=
func
(
writer
,
reader
net
.
Conn
)
{
_
,
err
:=
io
.
Copy
(
writer
,
reader
)
if
err
!=
nil
{
log
.
Printf
(
"%s io.Copy error: %s \n"
,
remoteEndpoint
.
String
(),
err
)
}
}
go
copyConn
(
localConn
,
remoteConn
)
go
copyConn
(
remoteConn
,
localConn
)
}
func
SSHAgent
()
ssh
.
AuthMethod
{
if
sshAgent
,
err
:=
net
.
Dial
(
"unix"
,
os
.
Getenv
(
"SSH_AUTH_SOCK"
));
err
==
nil
{
return
ssh
.
PublicKeysCallback
(
agent
.
NewClient
(
sshAgent
).
Signers
)
}
return
nil
}
func
check
(
e
error
)
{
if
e
!=
nil
{
panic
(
e
)
}
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Feb 23, 2:54 PM (12 m, 14 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15192
Default Alt Text
tunnel.go (3 KB)
Attached To
rST sshtunnel
Event Timeline
Log In to Comment