v1.0.0
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
// Package ssh builds and runs SSH port-forwarding commands.
|
||||
package ssh
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"git.scuroneko.dev/ScuroNeko/est/internal/config"
|
||||
)
|
||||
|
||||
func buildRemoteToLocalString(sourceIP, remoteIP string, sourcePort, remotePort uint16) string {
|
||||
if sourceIP == "" {
|
||||
sourceIP = "127.0.0.1"
|
||||
}
|
||||
if remoteIP == "" {
|
||||
remoteIP = "127.0.0.1"
|
||||
}
|
||||
return fmt.Sprintf("%s:%d:%s:%d", sourceIP, sourcePort, remoteIP, remotePort)
|
||||
}
|
||||
func buildLocalToRemoteString(sourceIP, remoteIP string, sourcePort, remotePort uint16) string {
|
||||
if sourceIP == "" {
|
||||
sourceIP = "127.0.0.1"
|
||||
}
|
||||
if remoteIP == "" {
|
||||
remoteIP = "127.0.0.1"
|
||||
}
|
||||
return fmt.Sprintf("%s:%d:%s:%d", remoteIP, remotePort, sourceIP, sourcePort)
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrEmptyHost is returned when a tunnel has no SSH destination.
|
||||
ErrEmptyHost = errors.New("empty host")
|
||||
// ErrEmptyLocalPort is returned when a tunnel has no local port.
|
||||
ErrEmptyLocalPort = errors.New("empty local port")
|
||||
// ErrEmptyRemotePort is returned when a tunnel has no remote port.
|
||||
ErrEmptyRemotePort = errors.New("empty remote port")
|
||||
)
|
||||
|
||||
func validateArgs(entry config.ProxyEntry) error {
|
||||
if entry.Host == "" {
|
||||
return ErrEmptyHost
|
||||
}
|
||||
if entry.LocalPort == 0 {
|
||||
return ErrEmptyLocalPort
|
||||
}
|
||||
if entry.RemotePort == 0 {
|
||||
return ErrEmptyRemotePort
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func prepareArgs(configPath string, entry config.ProxyEntry) ([]string, error) {
|
||||
if err := validateArgs(entry); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
args := []string{"-N", "-T", "-o", "ExitOnForwardFailure=yes"}
|
||||
if configPath != "" {
|
||||
args = append(args, "-F", configPath)
|
||||
} else if configPath = getConfigOrEmpty(); configPath != "" {
|
||||
args = append(args, "-F", configPath)
|
||||
}
|
||||
if entry.IdentityFile != "" {
|
||||
args = append(args, "-i", entry.IdentityFile)
|
||||
}
|
||||
switch entry.Direction {
|
||||
case config.LocalToRemote:
|
||||
args = append(args, "-R", buildLocalToRemoteString(entry.LocalIP, entry.RemoteIP, entry.LocalPort, entry.RemotePort))
|
||||
case config.RemoteToLocal:
|
||||
args = append(args, "-L", buildRemoteToLocalString(entry.LocalIP, entry.RemoteIP, entry.LocalPort, entry.RemotePort))
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid direction: %v; should be ltr on rtl", entry.Direction)
|
||||
}
|
||||
if entry.Host != "" {
|
||||
args = append(args, entry.Host)
|
||||
}
|
||||
return args, nil
|
||||
}
|
||||
Reference in New Issue
Block a user