Compare commits

..

No commits in common. "master" and "v1.1.0-stable" have entirely different histories.

12 changed files with 287 additions and 308 deletions

View File

@ -1,4 +1,4 @@
package Tunnel package main
import ( import (
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
@ -6,7 +6,7 @@ import (
"net" "net"
) )
func AcceptClients(connection net.Listener, config *ssh.ClientConfig, serverAddrString, remoteAddrString string) { func acceptClients(connection net.Listener, config *ssh.ClientConfig) {
// Endless loop // Endless loop
for { for {
@ -22,7 +22,7 @@ func AcceptClients(connection net.Listener, config *ssh.ClientConfig, serverAddr
log.Println(`Client accepted.`) log.Println(`Client accepted.`)
// Start the forwarding: // Start the forwarding:
go forward(localConn, config, serverAddrString, remoteAddrString) go forward(localConn, config)
} }
} }
} }

View File

@ -1,4 +1,4 @@
package Tunnel package main
const ( const (
maxRetriesLocal = 16 // How many retries are allowed to create the local end-point? maxRetriesLocal = 16 // How many retries are allowed to create the local end-point?

View File

@ -1,4 +1,4 @@
package Tunnel package main
import ( import (
"log" "log"
@ -6,7 +6,7 @@ import (
"time" "time"
) )
func CreateLocalEndPoint(localAddrString string) (localListener net.Listener) { func createLocalEndPoint() (localListener net.Listener) {
// Loop for the necessary retries // Loop for the necessary retries
for { for {

View File

@ -1,4 +1,4 @@
package Tunnel package main
import ( import (
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
@ -7,7 +7,7 @@ import (
"time" "time"
) )
func forward(localConn net.Conn, config *ssh.ClientConfig, serverAddrString, remoteAddrString string) { func forward(localConn net.Conn, config *ssh.ClientConfig) {
defer localConn.Close() defer localConn.Close()
currentRetriesServer := 0 currentRetriesServer := 0

View File

@ -1,11 +1,11 @@
package Tunnel package main
import ( import (
"log" "log"
) )
// Another auth. method. // Another auth. method.
func KeyboardInteractiveChallenge(user, instruction string, questions []string, echos []bool) (answers []string, err error) { func keyboardInteractiveChallenge(user, instruction string, questions []string, echos []bool) (answers []string, err error) {
// Log all the provided data: // Log all the provided data:
log.Println(`User: ` + user) log.Println(`User: ` + user)
@ -22,7 +22,7 @@ func KeyboardInteractiveChallenge(user, instruction string, questions []string,
// We expect that in this case (only one question is asked), that the server want to know the password ;-) // We expect that in this case (only one question is asked), that the server want to know the password ;-)
answers = make([]string, countQuestions, countQuestions) answers = make([]string, countQuestions, countQuestions)
answers[0] = callbackPassword answers[0] = password
} else if countQuestions > 1 { } else if countQuestions > 1 {

23
Main.go
View File

@ -2,18 +2,14 @@ package main
import ( import (
"fmt" "fmt"
"github.com/SommerEngineering/SSHTunnel/Tunnel"
"github.com/howeyc/gopass"
"golang.org/x/crypto/ssh" "golang.org/x/crypto/ssh"
"log"
"os"
"runtime" "runtime"
) )
func main() { func main() {
// Show the current version: // Show the current version:
log.Println(`SSHTunnel v1.3.0`) fmt.Println(`SSHTunnel v1.1.0`)
// Allow Go to use all CPUs: // Allow Go to use all CPUs:
runtime.GOMAXPROCS(runtime.NumCPU()) runtime.GOMAXPROCS(runtime.NumCPU())
@ -26,32 +22,25 @@ func main() {
if password == `` { if password == `` {
// Promt for the password: // Promt for the password:
fmt.Println(`Please provide the password for the connection:`) fmt.Println(`Please provide the password for the connection:`)
if pass, errPass := gopass.GetPasswd(); errPass != nil { fmt.Scanln(&password)
log.Println(`There was an error reading the password securely: ` + errPass.Error())
os.Exit(1)
return
} else {
password = string(pass)
}
} else { } else {
break break
} }
} }
// Create the SSH configuration: // Create the SSH configuration:
Tunnel.SetPassword4Callback(password)
config := &ssh.ClientConfig{ config := &ssh.ClientConfig{
User: username, User: username,
Auth: []ssh.AuthMethod{ Auth: []ssh.AuthMethod{
ssh.Password(password), ssh.Password(password),
ssh.PasswordCallback(Tunnel.PasswordCallback), ssh.PasswordCallback(passwordCallback),
ssh.KeyboardInteractive(Tunnel.KeyboardInteractiveChallenge), ssh.KeyboardInteractive(keyboardInteractiveChallenge),
}, },
} }
// Create the local end-point: // Create the local end-point:
localListener := Tunnel.CreateLocalEndPoint(localAddrString) localListener := createLocalEndPoint()
// Accept client connections (will block forever): // Accept client connections (will block forever):
Tunnel.AcceptClients(localListener, config, serverAddrString, remoteAddrString) acceptClients(localListener, config)
} }

6
PasswordCallback.go Normal file
View File

@ -0,0 +1,6 @@
package main
// Just a callback function for the password request.
func passwordCallback() (string, error) {
return password, nil
}

View File

@ -22,7 +22,6 @@ SSHTunnel is a tiny small program to tunnel something through a SSH without any
- At the moment, SSHTunnel uses only the password authentication methods. Therefore, it is currently not possible to use e.g. a certificate, etc. Nevertheless, the implementation of this feature is possible. - At the moment, SSHTunnel uses only the password authentication methods. Therefore, it is currently not possible to use e.g. a certificate, etc. Nevertheless, the implementation of this feature is possible.
- The configuration must be provided by using the command-line arguments. It is currently not possible to use e.g. a configuration file. - The configuration must be provided by using the command-line arguments. It is currently not possible to use e.g. a configuration file.
- You can avoid the password argument if you prefer to provide the password on demand. - You can avoid the password argument if you prefer to provide the password on demand.
- [Ocean Remote Connections](https://github.com/SommerEngineering/OceanRemoteConnections) is a simple GUI for SSH Tunnel, PuTTY, RDP and WinSCP.
### Download ### Download
Go and get the latest release from the [release page](https://github.com/SommerEngineering/SSHTunnel/releases). Go and get the latest release from the [release page](https://github.com/SommerEngineering/SSHTunnel/releases).

View File

@ -1,4 +1,4 @@
package Tunnel package main
import ( import (
"io" "io"

View File

@ -1,10 +0,0 @@
package Tunnel
// Just a callback function for the password request.
func PasswordCallback() (string, error) {
return callbackPassword, nil
}
func SetPassword4Callback(password string) {
callbackPassword = password
}

View File

@ -1,6 +0,0 @@
package Tunnel
var (
currentRetriesLocal = 0 // Check how many retries are occur for creating the local end-point
callbackPassword = ``
)

View File

@ -6,4 +6,5 @@ var (
serverAddrString = `` // The SSH server address serverAddrString = `` // The SSH server address
localAddrString = `` // The local end-point localAddrString = `` // The local end-point
remoteAddrString = `` // The remote end-point (on the SSH server's side) remoteAddrString = `` // The remote end-point (on the SSH server's side)
currentRetriesLocal = 0 // Check how many retries are occur for creating the local end-point
) )