From 390f6acbcd720f8e3b3224f4582817e071742bde Mon Sep 17 00:00:00 2001 From: Bolke de Bruin <bolke@xs4all.nl> Date: Tue, 23 Aug 2022 22:31:41 +0200 Subject: [PATCH] Add support for PAM authentication --- .github/workflows/go.yml | 2 +- Makefile | 4 ++- cmd/auth/auth.go | 72 +++++++++++++++++++++++++++++++++++++++ cmd/auth/proto/auth.proto | 14 ++++++++ go.mod | 5 ++- 5 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 cmd/auth/auth.go create mode 100644 cmd/auth/proto/auth.proto diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index ecb0797..8a08082 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -16,7 +16,7 @@ jobs: - name: Set up Go 1.x uses: actions/setup-go@v2 with: - go-version: ^1.16 + go-version: ^1.19 id: go - name: Check out code into the Go module directory diff --git a/Makefile b/Makefile index 03148c0..d3f6539 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ BINDIR := $(CURDIR)/bin INSTALL_PATH ?= /usr/local/bin BINNAME ?= rdpgw +BINNAME2 ?= auth # Rebuild the binary if any of these files change SRC := $(shell find . -type f -name '*.go' -print) go.mod go.sum @@ -35,6 +36,7 @@ build: $(BINDIR)/$(BINNAME) $(BINDIR)/$(BINNAME): $(SRC) go build $(GOFLAGS) -trimpath -tags '$(TAGS)' -ldflags '$(LDFLAGS)' -o '$(BINDIR)'/$(BINNAME) ./cmd/rdpgw + go build $(GOFLAGS) -trimpath -tags '$(TAGS)' -ldflags '$(LDFLAGS)' -o '$(BINDIR)'/$(BINNAME2) ./cmd/auth # ------------------------------------------------------------------------------ # install @@ -48,7 +50,7 @@ install: build .PHONY: mod mod: - go mod tidy -compat=1.17 + go mod tidy -compat=1.19 # ------------------------------------------------------------------------------ # test diff --git a/cmd/auth/auth.go b/cmd/auth/auth.go new file mode 100644 index 0000000..611762d --- /dev/null +++ b/cmd/auth/auth.go @@ -0,0 +1,72 @@ +package main + +import ( + "errors" + "github.com/golang/protobuf/proto" + ipc "github.com/james-barrow/golang-ipc" + "github.com/msteinert/pam" + "github.com/thought-machine/go-flags" + "log" +) + +var opts struct { + serviceName string `short:"s" long:"service" default:"rdpgw" description:"the PAM service name to use"` +} + +func auth(service, user, passwd string) error { + t, err := pam.StartFunc(service, user, func(s pam.Style, msg string) (string, error) { + switch s { + case pam.PromptEchoOff: + return passwd, nil + case pam.PromptEchoOn, pam.ErrorMsg, pam.TextInfo: + return "", nil + } + return "", errors.New("unrecognized PAM message style") + }) + + if err != nil { + return err + } + + if err = t.Authenticate(0); err != nil { + return err + } + + return nil +} + +func main() { + _, err := flags.Parse(&opts) + if err != nil { + panic(err) + } + + config := &ipc.ServerConfig{UnmaskPermissions: true} + sc, err := ipc.StartServer("rdpgw-auth", config) + for { + msg, err := sc.Read() + if err != nil { + log.Printf("server error, %s", err) + continue + } + if msg.MsgType > 0 { + req := &UserPass{} + if err = proto.Unmarshal(msg.Data, req); err != nil { + log.Printf("cannot unmarshal request %s", string(msg.Data)) + continue + } + err := auth(opts.serviceName, req.Username, req.Password) + if err != nil { + res := &Response{Status: "cannot authenticate"} + out, err := proto.Marshal(res) + if err != nil { + log.Fatalf("cannot marshal response due to %s", err) + } + sc.Write(1, out) + } + } + } + if err != nil { + log.Printf("cannot authenticate due to %s", err) + } +} diff --git a/cmd/auth/proto/auth.proto b/cmd/auth/proto/auth.proto new file mode 100644 index 0000000..acc33a2 --- /dev/null +++ b/cmd/auth/proto/auth.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package main; + +option go_package = "./auth;main"; + +message UserPass { + string username = 1; + string password = 2; +} + +message Response { + string status = 1; +} \ No newline at end of file diff --git a/go.mod b/go.mod index 5536858..1922f09 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,15 @@ module github.com/bolkedebruin/rdpgw -go 1.17 +go 1.19 require ( github.com/coreos/go-oidc/v3 v3.2.0 github.com/go-jose/go-jose/v3 v3.0.0 github.com/gorilla/sessions v1.2.1 github.com/gorilla/websocket v1.5.0 + github.com/james-barrow/golang-ipc v1.0.0 github.com/knadh/koanf v1.4.2 + github.com/msteinert/pam v1.0.0 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/prometheus/client_golang v1.12.1 github.com/thought-machine/go-flags v1.6.1 @@ -15,6 +17,7 @@ require ( ) require ( + github.com/Microsoft/go-winio v0.4.16 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect -- GitLab