46 lines
1.4 KiB
Go
46 lines
1.4 KiB
Go
|
package ssh
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"net"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/hashicorp/packer/communicator/ssh"
|
||
|
)
|
||
|
|
||
|
// ParseTunnelArgument parses an SSH tunneling argument compatible with the openssh client form.
|
||
|
// Valid formats:
|
||
|
// `port:host:hostport`
|
||
|
// NYI `[bind_address:]port:host:hostport`
|
||
|
func ParseTunnelArgument(forward string, direction ssh.TunnelDirection) (ssh.TunnelSpec, error) {
|
||
|
parts := strings.SplitN(forward, ":", 2)
|
||
|
if len(parts) != 2 {
|
||
|
return ssh.TunnelSpec{}, fmt.Errorf("Error parsing tunnel '%s': %v", forward, parts)
|
||
|
}
|
||
|
listeningPort, forwardingAddr := parts[0], parts[1]
|
||
|
|
||
|
_, sPort, err := net.SplitHostPort(forwardingAddr)
|
||
|
if err != nil {
|
||
|
return ssh.TunnelSpec{}, fmt.Errorf("Error parsing forwarding, must be a tcp address: %s", err)
|
||
|
}
|
||
|
_, err = strconv.Atoi(sPort)
|
||
|
if err != nil {
|
||
|
return ssh.TunnelSpec{}, fmt.Errorf("Error parsing forwarding port, must be a valid port: %s", err)
|
||
|
}
|
||
|
_, err = strconv.Atoi(listeningPort)
|
||
|
if err != nil {
|
||
|
return ssh.TunnelSpec{}, fmt.Errorf("Error parsing listening port, must be a valid port: %s", err)
|
||
|
}
|
||
|
|
||
|
return ssh.TunnelSpec{
|
||
|
Direction: direction,
|
||
|
ForwardAddr: forwardingAddr,
|
||
|
ForwardType: "tcp",
|
||
|
ListenAddr: fmt.Sprintf("localhost:%s", listeningPort),
|
||
|
ListenType: "tcp",
|
||
|
}, nil
|
||
|
// So we parsed all that, and are just going to ignore it now. We would
|
||
|
// have used the information to set the type here.
|
||
|
}
|