mirror of
https://github.com/bolkedebruin/rdpgw.git
synced 2026-03-30 23:46:36 +00:00
Add templating option for RDP files
This commit is contained in:
204
cmd/rdpgw/rdp/rdp.go
Normal file
204
cmd/rdpgw/rdp/rdp.go
Normal file
@@ -0,0 +1,204 @@
|
||||
package rdp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/fatih/structs"
|
||||
"log"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
CRLF = "\r\n"
|
||||
)
|
||||
|
||||
const (
|
||||
SourceNTLM int = iota
|
||||
SourceSmartCard
|
||||
SourceCurrent
|
||||
SourceBasic
|
||||
SourceUserSelect
|
||||
SourceCookie
|
||||
)
|
||||
|
||||
type RdpSettings struct {
|
||||
GatewayHostname string `rdp:"gatewayhostname"`
|
||||
FullAddress string `rdp:"full address"`
|
||||
AlternateFullAddress string `rdp:"alternate full address"`
|
||||
Username string `rdp:"username"`
|
||||
Domain string `rdp:"domain"`
|
||||
GatewayCredentialsSource int `rdp:"gatewaycredentialssource" default:"0"`
|
||||
GatewayCredentialMethod int `rdp:"gatewayprofileusagemethod" default:"0"`
|
||||
GatewayUsageMethod int `rdp:"gatewayusagemethod" default:"0"`
|
||||
GatewayAccessToken string `rdp:"gatewayaccesstoken"`
|
||||
PromptCredentialsOnce bool `rdp:"promptcredentialonce" default:"true"`
|
||||
AuthenticationLevel int `rdp:"authentication level" default:"3"`
|
||||
EnableCredSSPSupport bool `rdp:"enablecredsspsupport" default:"true"`
|
||||
EnableRdsAasAuth bool `rdp:"enablerdsaadauth" default:"false"`
|
||||
DisableConnectionSharing bool `rdp:"disableconnectionsharing" default:"false"`
|
||||
AlternateShell string `rdp:"alternate shell"`
|
||||
AutoReconnectionEnabled bool `rdp:"autoreconnectionenabled" default:"true"`
|
||||
BandwidthAutodetect bool `rdp:"bandwidthautodetect" default:"true"`
|
||||
NetworkAutodetect bool `rdp:"networkautodetect" default:"true"`
|
||||
Compression bool `rdp:"compression" default:"true"`
|
||||
VideoPlaybackMode bool `rdp:"videoplaybackmode" default:"true"`
|
||||
ConnectionType int `rdp:"connection type" default:"2"`
|
||||
AudioCaptureMode bool `rdp:"audiocapturemode" default:"false"`
|
||||
EncodeRedirectedVideoCapture bool `rdp:"encode redirected video capture" default:"true"`
|
||||
RedirectedVideoCaptureEncodingQuality int `rdp:"redirected video capture encoding quality" default:"0"`
|
||||
AudioMode int `rdp:"audiomode" default:"0"`
|
||||
CameraStoreRedirect string `rdp:"camerastoredirect" default:"false"`
|
||||
DeviceStoreRedirect string `rdp:"devicestoredirect" default:"false"`
|
||||
DriveStoreRedirect string `rdp:"drivestoredirect" default:"false"`
|
||||
KeyboardHook int `rdp:"keyboardhook" default:"2"`
|
||||
RedirectClipboard bool `rdp:"redirectclipboard" default:"true"`
|
||||
RedirectComPorts bool `rdp:"redirectcomports" default:"false"`
|
||||
RedirectLocation bool `rdp:"redirectlocation" default:"false"`
|
||||
RedirectPrinters bool `rdp:"redirectprinters" default:"true"`
|
||||
RedirectSmartcards bool `rdp:"redirectsmartcards" default:"true"`
|
||||
RedirectWebAuthn bool `rdp:"redirectwebauthn" default:"true"`
|
||||
UsbDeviceStoRedirect string `rdp:"usbdevicestoredirect"`
|
||||
UseMultimon bool `rdp:"use multimon" default:"false"`
|
||||
SelectedMonitors string `rdp:"selectedmonitors"`
|
||||
MaximizeToCurrentDisplays bool `rdp:"maximizetocurrentdisplays" default:"false"`
|
||||
SingleMonInWindowedMode bool `rdp:"singlemoninwindowedmode" default:"0"`
|
||||
ScreenModeId int `rdp:"screen mode id" default:"2"`
|
||||
SmartSizing bool `rdp:"smart sizing" default:"false"`
|
||||
DynamicResolution bool `rdp:"dynamic resolution" default:"true"`
|
||||
DesktopSizeId int `rdp:"desktop size id"`
|
||||
DesktopHeight int `rdp:"desktopheight"`
|
||||
DesktopWidth int `rdp:"desktopwidth"`
|
||||
DesktopScaleFactor int `rdp:"desktopscalefactor"`
|
||||
BitmapCacheSize int `rdp:"bitmapcachesize" default:"1500"`
|
||||
RemoteApplicationCmdLine string `rdp:"remoteapplicationcmdline"`
|
||||
RemoteAppExpandWorkingDir bool `rdp:"remoteapplicationexpandworkingdir" default:"true"`
|
||||
RemoteApplicationFile string `rdp:"remoteapplicationfile" default:"true"`
|
||||
RemoteApplicationIcon string `rdp:"remoteapplicationicon"`
|
||||
RemoteApplicationMode bool `rdp:"remoteapplicationmode" default:"true"`
|
||||
RemoteApplicationName string `rdp:"remoteapplicationname"`
|
||||
RemoteApplicationProgram string `rdp:"remoteapplicationprogram"`
|
||||
}
|
||||
|
||||
type RdpBuilder struct {
|
||||
Settings RdpSettings
|
||||
}
|
||||
|
||||
func NewRdp() *RdpBuilder {
|
||||
c := RdpSettings{}
|
||||
|
||||
initStruct(&c)
|
||||
|
||||
return &RdpBuilder{
|
||||
Settings: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (rb *RdpBuilder) String() string {
|
||||
var sb strings.Builder
|
||||
|
||||
addStructToString(rb.Settings, &sb)
|
||||
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func addStructToString(st interface{}, sb *strings.Builder) {
|
||||
s := structs.New(st)
|
||||
for _, f := range s.Fields() {
|
||||
if isZero(f) {
|
||||
continue
|
||||
}
|
||||
sb.WriteString(f.Tag("rdp"))
|
||||
sb.WriteString(":")
|
||||
|
||||
switch f.Kind() {
|
||||
case reflect.String:
|
||||
sb.WriteString("s:")
|
||||
sb.WriteString(f.Value().(string))
|
||||
case reflect.Int:
|
||||
sb.WriteString("i:")
|
||||
fmt.Fprintf(sb, "%d", f.Value())
|
||||
case reflect.Bool:
|
||||
sb.WriteString("i:")
|
||||
if f.Value().(bool) {
|
||||
sb.WriteString("1")
|
||||
} else {
|
||||
sb.WriteString("0")
|
||||
|
||||
}
|
||||
}
|
||||
sb.WriteString(CRLF)
|
||||
}
|
||||
}
|
||||
|
||||
func isZero(f *structs.Field) bool {
|
||||
t := f.Tag("default")
|
||||
if t == "" {
|
||||
return f.IsZero()
|
||||
}
|
||||
|
||||
switch f.Kind() {
|
||||
case reflect.String:
|
||||
if f.Value().(string) != t {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
case reflect.Int:
|
||||
i, err := strconv.Atoi(t)
|
||||
if err != nil {
|
||||
log.Fatalf("runtime error: default %s is not an integer", t)
|
||||
}
|
||||
if f.Value().(int) != i {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
case reflect.Bool:
|
||||
b := false
|
||||
if t == "true" || t == "1" {
|
||||
b = true
|
||||
}
|
||||
if f.Value().(bool) != b {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
return f.IsZero()
|
||||
}
|
||||
|
||||
func initStruct(st interface{}) {
|
||||
s := structs.New(st)
|
||||
for _, f := range s.Fields() {
|
||||
t := f.Tag("default")
|
||||
if t == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
err := setVariable(f, t)
|
||||
if err != nil {
|
||||
log.Fatalf("cannot init rdp struct: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setVariable(f *structs.Field, v string) error {
|
||||
switch f.Kind() {
|
||||
case reflect.String:
|
||||
return f.Set(v)
|
||||
case reflect.Int:
|
||||
i, err := strconv.Atoi(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return f.Set(i)
|
||||
case reflect.Bool:
|
||||
b := false
|
||||
if v == "true" || v == "1" {
|
||||
b = true
|
||||
}
|
||||
return f.Set(b)
|
||||
default:
|
||||
return errors.New("invalid field type")
|
||||
}
|
||||
}
|
||||
40
cmd/rdpgw/rdp/rdp_test.go
Normal file
40
cmd/rdpgw/rdp/rdp_test.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package rdp
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
GatewayHostName = "my.yahoo.com"
|
||||
)
|
||||
|
||||
func TestRdpBuilder(t *testing.T) {
|
||||
builder := NewRdp()
|
||||
builder.Settings.GatewayHostname = "my.yahoo.com"
|
||||
builder.Settings.AutoReconnectionEnabled = true
|
||||
builder.Settings.SmartSizing = true
|
||||
|
||||
s := builder.String()
|
||||
if !strings.Contains(s, "gatewayhostname:s:"+GatewayHostName+CRLF) {
|
||||
t.Fatalf("%s does not contain `gatewayhostname:s:%s", s, GatewayHostName)
|
||||
}
|
||||
if strings.Contains(s, "autoreconnectionenabled") {
|
||||
t.Fatalf("autoreconnectionenabled is in %s, but is default value", s)
|
||||
}
|
||||
if !strings.Contains(s, "smart sizing:i:1"+CRLF) {
|
||||
t.Fatalf("%s does not contain smart sizing:i:1", s)
|
||||
|
||||
}
|
||||
log.Printf(builder.String())
|
||||
}
|
||||
|
||||
func TestInitStruct(t *testing.T) {
|
||||
conn := RdpSettings{}
|
||||
initStruct(&conn)
|
||||
|
||||
if conn.PromptCredentialsOnce != true {
|
||||
t.Fatalf("conn.PromptCredentialsOnce != true")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user