Skip to content
Snippets Groups Projects
main.go 3.8 KiB
Newer Older
  • Learn to ignore specific revisions
  • Bolke de Bruin's avatar
    Bolke de Bruin committed
    package main
    
    import (
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    	"crypto/tls"
    
    	"github.com/bolkedebruin/rdpgw/api"
    
    	"github.com/bolkedebruin/rdpgw/client"
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    	"github.com/bolkedebruin/rdpgw/config"
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    	"github.com/bolkedebruin/rdpgw/protocol"
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    	"github.com/bolkedebruin/rdpgw/security"
    
    	"github.com/coreos/go-oidc/v3/oidc"
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    	"github.com/prometheus/client_golang/prometheus/promhttp"
    
    	"github.com/spf13/cobra"
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    	"log"
    	"net/http"
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    	"os"
    	"strconv"
    
    var cmd = &cobra.Command{
    	Use:	"rdpgw",
    	Long:	"Remote Desktop Gateway",
    }
    
    var (
    	configFile	string
    )
    
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    var conf config.Configuration
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    func main() {
    
    	cmd.PersistentFlags().StringVarP(&configFile, "conf", "c", "rdpgw.yaml",  "config file (json, yaml, ini)")
    
    	conf = config.Load(configFile)
    
    	// set security keys
    	security.SigningKey = []byte(conf.Security.TokenSigningKey)
    
    
    	ctx := context.Background()
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    	provider, err := oidc.NewProvider(ctx, conf.OpenId.ProviderUrl)
    
    	if err != nil {
    		log.Fatalf("Cannot get oidc provider: %s", err)
    	}
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    	oidcConfig := &oidc.Config{
    
    		ClientID: conf.OpenId.ClientId,
    
    	verifier := provider.Verifier(oidcConfig)
    
    	oauthConfig := oauth2.Config{
    
    		ClientID: conf.OpenId.ClientId,
    		ClientSecret: conf.OpenId.ClientSecret,
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    		RedirectURL: "https://" + conf.Server.GatewayAddress + "/callback",
    
    		Endpoint: provider.Endpoint(),
    		Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
    	}
    
    
    	api := &api.Config{
    		GatewayAddress: conf.Server.GatewayAddress,
    		OAuth2Config: &oauthConfig,
    		TokenVerifier: verifier,
    
    		TokenGenerator: security.GeneratePAAToken,
    
    		SessionKey: []byte(conf.Server.SessionKey),
    
    		SessionEncryptionKey: []byte(conf.Server.SessionEncryptionKey),
    
    		Hosts: conf.Server.Hosts,
    
    		NetworkAutoDetect: conf.Client.NetworkAutoDetect,
    		UsernameTemplate: conf.Client.UsernameTemplate,
    		BandwidthAutoDetect: conf.Client.BandwidthAutoDetect,
    		ConnectionType: conf.Client.ConnectionType,
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    	if conf.Server.CertFile == "" || conf.Server.KeyFile == "" {
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    		log.Fatal("Both certfile and keyfile need to be specified")
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    	//mux := http.NewServeMux()
    	//mux.HandleFunc("*", HelloServer)
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    	log.Printf("Starting remote desktop gateway server")
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    	cfg := &tls.Config{}
    	tlsDebug := os.Getenv("SSLKEYLOGFILE")
    	if tlsDebug != "" {
    		w, err := os.OpenFile(tlsDebug, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
    		if err != nil {
    			log.Fatalf("Cannot open key log file %s for writing %s", tlsDebug, err)
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    		}
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    		log.Printf("Key log file set to: %s", tlsDebug)
    		cfg.KeyLogWriter = w
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    	}
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    
    	cert, err := tls.LoadX509KeyPair(conf.Server.CertFile, conf.Server.KeyFile)
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    	if err != nil {
    		log.Fatal(err)
    	}
    	cfg.Certificates = append(cfg.Certificates, cert)
    	server := http.Server{
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    		Addr:      ":" + strconv.Itoa(conf.Server.Port),
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    		TLSConfig: cfg,
    
    		TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler)), // disable http2
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    	// create the gateway
    	handlerConfig := protocol.HandlerConf{
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    		IdleTimeout: conf.Caps.IdleTimeout,
    		TokenAuth: conf.Caps.TokenAuth,
    		SmartCardAuth: conf.Caps.SmartCardAuth,
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    		RedirectFlags: protocol.RedirectFlags{
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    			Clipboard: conf.Caps.EnableClipboard,
    			Drive: conf.Caps.EnableDrive,
    			Printer: conf.Caps.EnablePrinter,
    			Port: conf.Caps.EnablePort,
    			Pnp: conf.Caps.EnablePnp,
    			DisableAll: conf.Caps.DisableRedirect,
    			EnableAll: conf.Caps.RedirectAll,
    
    		VerifyTunnelCreate: security.VerifyPAAToken,
    
    		VerifyServerFunc: security.VerifyServerFunc,
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    	}
    	gw := protocol.Gateway{
    		HandlerConf: &handlerConfig,
    	}
    
    
    	http.Handle("/remoteDesktopGateway/", client.EnrichContext(http.HandlerFunc(gw.HandleGatewayProtocol)))
    	http.Handle("/connect", client.EnrichContext(api.Authenticated(http.HandlerFunc(api.HandleDownload))))
    
    	http.Handle("/metrics", promhttp.Handler())
    
    	http.HandleFunc("/callback", api.HandleCallback)
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    	err = server.ListenAndServeTLS("", "")
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    	if err != nil {
    		log.Fatal("ListenAndServe: ", err)
    	}
    
    Bolke de Bruin's avatar
    Bolke de Bruin committed
    }