feat: build guacd connection params per protocol
This commit is contained in:
@@ -8,6 +8,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/mrhid6/vantage/server/internal/models"
|
||||
)
|
||||
|
||||
func sessionHMACKey() ([]byte, error) {
|
||||
@@ -67,3 +69,50 @@ func VerifySessionToken(token string) (string, error) {
|
||||
}
|
||||
return string(sid), nil
|
||||
}
|
||||
|
||||
type GuacParams struct {
|
||||
Protocol string
|
||||
Params map[string]string
|
||||
}
|
||||
|
||||
func portOr(v, def int) string {
|
||||
if v == 0 {
|
||||
v = def
|
||||
}
|
||||
return strconv.Itoa(v)
|
||||
}
|
||||
|
||||
// BuildGuacParams assembles the guacd connection parameter map for a protocol.
|
||||
// privateKey is the decrypted SSH private key (ssh only); rdpUser/rdpPass are
|
||||
// used for rdp. None of these values are persisted or logged by the caller.
|
||||
func BuildGuacParams(srv *models.Server, protocol, privateKey, rdpUser, rdpPass string) (*GuacParams, error) {
|
||||
host := srv.IPAddress
|
||||
switch protocol {
|
||||
case "ssh":
|
||||
p := map[string]string{
|
||||
"hostname": host,
|
||||
"port": portOr(srv.SSHPort, 22),
|
||||
}
|
||||
if privateKey != "" {
|
||||
p["private-key"] = privateKey
|
||||
}
|
||||
return &GuacParams{Protocol: "ssh", Params: p}, nil
|
||||
case "rdp":
|
||||
return &GuacParams{Protocol: "rdp", Params: map[string]string{
|
||||
"hostname": host,
|
||||
"port": portOr(srv.RDPPort, 3389),
|
||||
"username": rdpUser,
|
||||
"password": rdpPass,
|
||||
"security": "any",
|
||||
"ignore-cert": "true",
|
||||
}}, nil
|
||||
case "vnc":
|
||||
return &GuacParams{Protocol: "vnc", Params: map[string]string{
|
||||
"hostname": host,
|
||||
"port": "5900",
|
||||
"password": rdpPass,
|
||||
}}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported protocol %q", protocol)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package services
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/mrhid6/vantage/server/internal/models"
|
||||
)
|
||||
|
||||
func TestSessionTokenRoundTrip(t *testing.T) {
|
||||
@@ -41,3 +43,41 @@ func TestSessionTokenTampered(t *testing.T) {
|
||||
t.Fatalf("expected signature error, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildGuacParamsSSH(t *testing.T) {
|
||||
srv := &models.Server{IPAddress: "10.0.0.5", SSHPort: 22}
|
||||
p, err := BuildGuacParams(srv, "ssh", "PRIVATE-KEY-DATA", "", "")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if p.Protocol != "ssh" {
|
||||
t.Fatalf("protocol %q", p.Protocol)
|
||||
}
|
||||
if p.Params["hostname"] != "10.0.0.5" || p.Params["port"] != "22" {
|
||||
t.Fatalf("bad host/port: %+v", p.Params)
|
||||
}
|
||||
if p.Params["private-key"] != "PRIVATE-KEY-DATA" {
|
||||
t.Fatalf("missing private-key")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildGuacParamsRDP(t *testing.T) {
|
||||
srv := &models.Server{IPAddress: "10.0.0.9", RDPPort: 3389}
|
||||
p, err := BuildGuacParams(srv, "rdp", "", "administrator", "s3cret")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if p.Params["port"] != "3389" || p.Params["username"] != "administrator" || p.Params["password"] != "s3cret" {
|
||||
t.Fatalf("bad rdp params: %+v", p.Params)
|
||||
}
|
||||
if p.Params["ignore-cert"] != "true" {
|
||||
t.Fatalf("expected ignore-cert=true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildGuacParamsUnknownProtocol(t *testing.T) {
|
||||
srv := &models.Server{IPAddress: "10.0.0.9"}
|
||||
if _, err := BuildGuacParams(srv, "telnet", "", "", ""); err == nil {
|
||||
t.Fatalf("expected error for unknown protocol")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user