Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows build support #124

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
BINDIR := $(CURDIR)/bin
INSTALL_PATH ?= /usr/local/bin
BINNAME ?= rdpgw
BINNAME2 ?= rdpgw-auth

ifneq ($(GOOS),windows)
BINNAME ?= rdpgw
BINNAME2 ?= rdpgw-auth
else
BINNAME ?= rdpgw.exe
BINNAME2 ?= rdpgw-auth.exe
endif

# Rebuild the binary if any of these files change
SRC := $(shell find . -type f -name '*.go' -print) go.mod go.sum
Expand Down
99 changes: 0 additions & 99 deletions cmd/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,13 @@ package main

import (
"context"
"errors"
"fmt"
"github.com/bolkedebruin/rdpgw/cmd/auth/config"
"github.com/bolkedebruin/rdpgw/cmd/auth/database"
"github.com/bolkedebruin/rdpgw/cmd/auth/ntlm"
"github.com/bolkedebruin/rdpgw/shared/auth"
"github.com/msteinert/pam/v2"
"github.com/thought-machine/go-flags"
"google.golang.org/grpc"
"log"
"net"
"os"
"syscall"
)

const (
protocol = "unix"
)

var opts struct {
ServiceName string `short:"n" long:"name" default:"rdpgw" description:"the PAM service name to use"`
SocketAddr string `short:"s" long:"socket" default:"/tmp/rdpgw-auth.sock" description:"the location of the socket"`
ConfigFile string `short:"c" long:"conf" default:"rdpgw-auth.yaml" description:"users config file for NTLM (yaml)"`
}

type AuthServiceImpl struct {
auth.UnimplementedAuthenticateServer

Expand All @@ -45,49 +27,6 @@ func NewAuthService(serviceName string, database database.Database) auth.Authent
return s
}

func (s *AuthServiceImpl) Authenticate(ctx context.Context, message *auth.UserPass) (*auth.AuthResponse, error) {
t, err := pam.StartFunc(s.serviceName, message.Username, func(s pam.Style, msg string) (string, error) {
switch s {
case pam.PromptEchoOff:
return message.Password, nil
case pam.PromptEchoOn, pam.ErrorMsg, pam.TextInfo:
return "", nil
}
return "", errors.New("unrecognized PAM message style")
})

r := &auth.AuthResponse{}
r.Authenticated = false

if err != nil {
log.Printf("Error authenticating user: %s due to: %s", message.Username, err)
r.Error = err.Error()
return r, err
}
defer func() {
err := t.End()
if err != nil {
fmt.Fprintf(os.Stderr, "end: %v\n", err)
os.Exit(1)
}
}()
if err = t.Authenticate(0); err != nil {
log.Printf("Authentication for user: %s failed due to: %s", message.Username, err)
r.Error = err.Error()
return r, nil
}

if err = t.AcctMgmt(0); err != nil {
log.Printf("Account authorization for user: %s failed due to %s", message.Username, err)
r.Error = err.Error()
return r, nil
}

log.Printf("User: %s authenticated", message.Username)
r.Authenticated = true
return r, nil
}

func (s *AuthServiceImpl) NTLM(ctx context.Context, message *auth.NtlmRequest) (*auth.NtlmResponse, error) {
r, err := s.ntlm.Authenticate(message)

Expand All @@ -101,41 +40,3 @@ func (s *AuthServiceImpl) NTLM(ctx context.Context, message *auth.NtlmRequest) (

return r, err
}

func main() {
_, err := flags.Parse(&opts)
if err != nil {
var fErr *flags.Error
if errors.As(err, &fErr) {
if fErr.Type == flags.ErrHelp {
fmt.Printf("Acknowledgements:\n")
fmt.Printf(" - This product includes software developed by the Thomson Reuters Global Resources. (go-ntlm - https://github.com/m7913d/go-ntlm - BSD-4 License)\n")
}
}
return
}

conf = config.Load(opts.ConfigFile)

log.Printf("Starting auth server on %s", opts.SocketAddr)
cleanup := func() {
if _, err := os.Stat(opts.SocketAddr); err == nil {
if err := os.RemoveAll(opts.SocketAddr); err != nil {
log.Fatal(err)
}
}
}
cleanup()

oldUmask := syscall.Umask(0)
listener, err := net.Listen(protocol, opts.SocketAddr)
syscall.Umask(oldUmask)
if err != nil {
log.Fatal(err)
}
server := grpc.NewServer()
db := database.NewConfig(conf.Users)
service := NewAuthService(opts.ServiceName, db)
auth.RegisterAuthenticateServer(server, service)
server.Serve(listener)
}
110 changes: 110 additions & 0 deletions cmd/auth/auth_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// +build !windows

package main

import (
"context"
"errors"
"fmt"
"github.com/bolkedebruin/rdpgw/cmd/auth/config"
"github.com/bolkedebruin/rdpgw/cmd/auth/database"
"github.com/bolkedebruin/rdpgw/shared/auth"
"github.com/thought-machine/go-flags"
"github.com/msteinert/pam/v2"
"google.golang.org/grpc"
"log"
"net"
"os"
"syscall"
)

const (
protocol = "unix"
)

var opts struct {
ServiceName string `short:"n" long:"name" default:"rdpgw" description:"the PAM service name to use"`
SocketAddr string `short:"s" long:"socket" default:"/tmp/rdpgw-auth.sock" description:"the location of the socket"`
ConfigFile string `short:"c" long:"conf" default:"rdpgw-auth.yaml" description:"users config file for NTLM (yaml)"`
}

func (s *AuthServiceImpl) Authenticate(ctx context.Context, message *auth.UserPass) (*auth.AuthResponse, error) {
t, err := pam.StartFunc(s.serviceName, message.Username, func(s pam.Style, msg string) (string, error) {
switch s {
case pam.PromptEchoOff:
return message.Password, nil
case pam.PromptEchoOn, pam.ErrorMsg, pam.TextInfo:
return "", nil
}
return "", errors.New("unrecognized PAM message style")
})

r := &auth.AuthResponse{}
r.Authenticated = false

if err != nil {
log.Printf("Error authenticating user: %s due to: %s", message.Username, err)
r.Error = err.Error()
return r, err
}
defer func() {
err := t.End()
if err != nil {
fmt.Fprintf(os.Stderr, "end: %v\n", err)
os.Exit(1)
}
}()
if err = t.Authenticate(0); err != nil {
log.Printf("Authentication for user: %s failed due to: %s", message.Username, err)
r.Error = err.Error()
return r, nil
}

if err = t.AcctMgmt(0); err != nil {
log.Printf("Account authorization for user: %s failed due to %s", message.Username, err)
r.Error = err.Error()
return r, nil
}

log.Printf("User: %s authenticated", message.Username)
r.Authenticated = true
return r, nil
}

func main() {
_, err := flags.Parse(&opts)
if err != nil {
var fErr *flags.Error
if errors.As(err, &fErr) {
if fErr.Type == flags.ErrHelp {
fmt.Printf("Acknowledgements:\n")
fmt.Printf(" - This product includes software developed by the Thomson Reuters Global Resources. (go-ntlm - https://github.com/m7913d/go-ntlm - BSD-4 License)\n")
}
}
return
}

conf = config.Load(opts.ConfigFile)

log.Printf("Starting auth server on %s", opts.SocketAddr)
cleanup := func() {
if _, err := os.Stat(opts.SocketAddr); err == nil {
if err := os.RemoveAll(opts.SocketAddr); err != nil {
log.Fatal(err)
}
}
}
cleanup()

oldUmask := syscall.Umask(0)
listener, err := net.Listen(protocol, opts.SocketAddr)
syscall.Umask(oldUmask)
if err != nil {
log.Fatal(err)
}
server := grpc.NewServer()
db := database.NewConfig(conf.Users)
service := NewAuthService(opts.ServiceName, db)
auth.RegisterAuthenticateServer(server, service)
server.Serve(listener)
}
63 changes: 63 additions & 0 deletions cmd/auth/auth_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// +build windows

package main

import (
"errors"
"fmt"
"github.com/bolkedebruin/rdpgw/cmd/auth/config"
"github.com/bolkedebruin/rdpgw/cmd/auth/database"
"github.com/bolkedebruin/rdpgw/shared/auth"
"github.com/thought-machine/go-flags"
"google.golang.org/grpc"
"log"
"net"
"os"
)

const (
protocol = "tcp"
)

var opts struct {
ServiceName string `short:"n" long:"name" default:"rdpgw" description:"the PAM service name to use"`
SocketAddr string `short:"s" long:"socket" default:"127.0.0.1:3000" description:"the location of the socket"`
ConfigFile string `short:"c" long:"conf" default:"rdpgw-auth.yaml" description:"users config file for NTLM (yaml)"`
}


func main() {
_, err := flags.Parse(&opts)
if err != nil {
var fErr *flags.Error
if errors.As(err, &fErr) {
if fErr.Type == flags.ErrHelp {
fmt.Printf("Acknowledgements:\n")
fmt.Printf(" - This product includes software developed by the Thomson Reuters Global Resources. (go-ntlm - https://github.com/m7913d/go-ntlm - BSD-4 License)\n")
}
}
return
}

conf = config.Load(opts.ConfigFile)

log.Printf("Starting auth server on %s", opts.SocketAddr)
cleanup := func() {
if _, err := os.Stat(opts.SocketAddr); err == nil {
if err := os.RemoveAll(opts.SocketAddr); err != nil {
log.Fatal(err)
}
}
}
cleanup()

listener, err := net.Listen(protocol, opts.SocketAddr)
if err != nil {
log.Fatal(err)
}
server := grpc.NewServer()
db := database.NewConfig(conf.Users)
service := NewAuthService(opts.ServiceName, db)
auth.RegisterAuthenticateServer(server, service)
server.Serve(listener)
}
Loading