-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
141 lines (116 loc) · 3.19 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package main
import (
"fmt"
"io"
"log"
"net"
"os"
"strconv"
"github.com/joho/godotenv"
"github.com/TheLazarusNetwork/TunnelClient/client"
"github.com/TheLazarusNetwork/TunnelClient/cmd"
"github.com/TheLazarusNetwork/TunnelClient/core"
"golang.org/x/crypto/ssh"
)
type Endpoint struct {
Host string
Port int
}
func (endpoint *Endpoint) String() string {
return fmt.Sprintf("%s:%d", endpoint.Host, endpoint.Port)
}
// From https://sosedoff.com/2015/05/25/ssh-port-forwarding-with-go.html
// Handle local client connections and tunnel data to the remote server
// Will use io.Copy - http://golang.org/pkg/io/#Copy
func handleClient(client net.Conn, remote net.Conn) {
defer client.Close()
chDone := make(chan bool)
// Start remote -> local data transfer
go func() {
_, err := io.Copy(client, remote)
if err != nil {
log.Println(fmt.Sprintf("error while copy remote->local: %s", err))
}
chDone <- true
}()
// Start local -> remote data transfer
go func() {
_, err := io.Copy(remote, client)
if err != nil {
log.Println(fmt.Sprintf("error while copy local->remote: %s", err))
}
chDone <- true
}()
<-chDone
}
func main() {
// Load enviornment variables
err := godotenv.Load()
if err != nil {
log.Fatalf("Error in reading the config file: %v", err)
}
// get command line argument values
port, host := cmd.Command()
// local service to be forwarded
portInt, _ := strconv.Atoi(port)
localEndpoint := Endpoint{
Host: host,
Port: portInt,
}
// remote SSH server
serverEndpoint := Endpoint{
Host: os.Getenv("NETWORK_DOMAIN"),
Port: 22,
}
// get user api key
var apiKey string
fmt.Print("Enter API Key Provided: ")
fmt.Scanf("%s", &apiKey)
// check validity of user
status := core.CheckUser(apiKey)
if status == "invalid" {
fmt.Println("API Key invalid")
return
} else {
fmt.Println("Welcome " + os.Getenv("USER_NAME"))
}
// display the tunnels available
fmt.Println("Available Tunnels are: ")
fmt.Println(os.Getenv("TUNNELS"))
// choose tunnel to be used
var name string
fmt.Print("Enter from above Tunnel Name you want to used: ")
fmt.Scanf("%s", &name)
// remote forwarding port (on remote SSH server network)
tunnelPort, _ := strconv.Atoi(os.Getenv("TUNNEL_PORT"))
remoteEndpoint := Endpoint{
Host: "localhost",
Port: tunnelPort,
}
// create a ssh configuration
sshConfig := client.Conn()
// Connect to SSH remote server using serverEndpoint
serverConn, err := ssh.Dial("tcp", serverEndpoint.String(), sshConfig)
if err != nil {
log.Fatalln(fmt.Printf("Dial INTO remote server error: %s", err))
}
// Listen on remote server port
listener, err := serverConn.Listen("tcp", remoteEndpoint.String())
if err != nil {
log.Fatalln(fmt.Printf("Listen open port ON remote server error: %s", err))
}
defer listener.Close()
// handle incoming connections on reverse forwarded tunnel
for {
// Open a (local) connection to localEndpoint whose content will be forwarded so serverEndpoint
local, err := net.Dial("tcp", localEndpoint.String())
if err != nil {
log.Fatalln(fmt.Printf("Dial INTO local service error: %s", err))
}
client, err := listener.Accept()
if err != nil {
log.Fatalln(err)
}
handleClient(client, local)
}
}