From 8dd2cbec4dd1c00b41d027489e78d579a695e3cf Mon Sep 17 00:00:00 2001 From: tuunit Date: Sun, 12 Jan 2025 16:57:15 +0100 Subject: [PATCH] fix: systemd socket support build handling for windows --- CHANGELOG.md | 1 + pkg/http/server.go | 45 +++------------------------ pkg/http/systemd_socket.go | 55 +++++++++++++++++++++++++++++++++ pkg/http/systemd_unsupported.go | 17 ++++++++++ 4 files changed, 77 insertions(+), 41 deletions(-) create mode 100644 pkg/http/systemd_socket.go create mode 100644 pkg/http/systemd_unsupported.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 86a6ef86..538e484d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ - [#2800](https://github.com/oauth2-proxy/oauth2-proxy/pull/2800) doc: add some opencontainer labels to docker image (@halkeye) - [#2755](https://github.com/oauth2-proxy/oauth2-proxy/pull/2755) feat: add X-Envoy-External-Address as supported header (@bjencks) - [#1985](https://github.com/oauth2-proxy/oauth2-proxy/pull/1985) feat: add support for systemd socket (@isodude) +- [#2916](https://github.com/oauth2-proxy/oauth2-proxy/pull/2916) fix: systemd socket support build handling for windows (@tuunit) - [#2300](https://github.com/oauth2-proxy/oauth2-proxy/pull/2300) fix: add fix for websocket path rewrite (@rekup) - [#2821](https://github.com/oauth2-proxy/oauth2-proxy/pull/2821) feat: add CF-Connecting-IP as supported real ip header (@ondrejsika) - [#2620](https://github.com/oauth2-proxy/oauth2-proxy/pull/2620) fix: update code_verifier to use recommended method (@vishvananda) diff --git a/pkg/http/server.go b/pkg/http/server.go index 1cd4f039..fe76427a 100644 --- a/pkg/http/server.go +++ b/pkg/http/server.go @@ -8,24 +8,14 @@ import ( "net" "net/http" "os" - "strconv" "strings" "time" - "github.com/coreos/go-systemd/activation" + "golang.org/x/sync/errgroup" + "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options" "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options/util" "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/logger" - "golang.org/x/sync/errgroup" -) - -// listenFdsStart corresponds to `SD_LISTEN_FDS_START`. -// Since the 3 first file descriptors in every linux process is -// stdin, stdout and stderr. The first usable file descriptor is 3. -// systemd-socket-activate will always assume that the first socket will be -// 3 and the rest follow. -const ( - listenFdsStart = 3 ) // Server represents an HTTP or HTTPS server. @@ -83,27 +73,6 @@ type server struct { fdFiles []*os.File } -// convert a string filedescriptor to an actual listener -func (s *server) fdToListener(bindAddress string) (net.Listener, error) { - fd, err := strconv.Atoi(bindAddress) - if err != nil { - return nil, fmt.Errorf("listen failed: fd with name is not implemented yet") - } - fdIndex := fd - listenFdsStart - - if len(s.fdFiles) == 0 { - s.fdFiles = activation.Files(true) - } - - l := len(s.fdFiles) - - if fdIndex < 0 || fdIndex >= l || l == 0 { - return nil, fmt.Errorf("listen failed: fd outside of range of available file descriptors") - } - - return net.FileListener(s.fdFiles[fdIndex]) -} - // setupListener sets the server listener if the HTTP server is enabled. // The HTTP server can be disabled by setting the BindAddress to "-" or by // leaving it empty. @@ -120,13 +89,7 @@ func (s *server) setupListener(opts Opts) error { // to the program is indeed a net.Listener and starts using it // without setting up a new listener. if strings.HasPrefix(strings.ToLower(opts.BindAddress), "fd:") { - listenAddr := opts.BindAddress[3:] - listener, err := s.fdToListener(listenAddr) - if err != nil { - err = fmt.Errorf("listen (%s, %s) failed: %v", "file", listenAddr, err) - } - s.listener = listener - return err + return s.checkSystemdSocketSupport(opts) } networkType := getNetworkScheme(opts.BindAddress) @@ -134,7 +97,7 @@ func (s *server) setupListener(opts Opts) error { listener, err := net.Listen(networkType, listenAddr) if err != nil { - return fmt.Errorf("listen (%s, %s) failed: %v", networkType, listenAddr, err) + return fmt.Errorf("listen (%s, %s) failed: %w", networkType, listenAddr, err) } s.listener = listener diff --git a/pkg/http/systemd_socket.go b/pkg/http/systemd_socket.go new file mode 100644 index 00000000..b0627f3f --- /dev/null +++ b/pkg/http/systemd_socket.go @@ -0,0 +1,55 @@ +//go:build !windows +// +build !windows + +package http + +import ( + "errors" + "fmt" + "net" + "strconv" + + "github.com/coreos/go-systemd/activation" +) + +// listenFdsStart corresponds to `SD_LISTEN_FDS_START`. +// Since the 3 first file descriptors in every linux process is +// stdin, stdout and stderr. The first usable file descriptor is 3. +// systemd-socket-activate will always assume that the first socket will be +// 3 and the rest follow. +const ( + listenFdsStart = 3 +) + +// convert a string filedescriptor to an actual listener +func (s *server) fdToListener(bindAddress string) (net.Listener, error) { + fd, err := strconv.Atoi(bindAddress) + if err != nil { + return nil, errors.New("listen failed: fd with name is not implemented yet") + } + fdIndex := fd - listenFdsStart + + if len(s.fdFiles) == 0 { + s.fdFiles = activation.Files(true) + } + + l := len(s.fdFiles) + + if fdIndex < 0 || fdIndex >= l || l == 0 { + return nil, errors.New("listen failed: fd outside of range of available file descriptors") + } + + return net.FileListener(s.fdFiles[fdIndex]) +} + +func (s *server) checkSystemdSocketSupport(opts Opts) error { + listenAddr := opts.BindAddress[3:] + listener, err := s.fdToListener(listenAddr) + if err != nil { + err = fmt.Errorf("listen (file, %s) failed: %w", listenAddr, err) + return err + } + + s.listener = listener + return nil +} diff --git a/pkg/http/systemd_unsupported.go b/pkg/http/systemd_unsupported.go new file mode 100644 index 00000000..3fe163f3 --- /dev/null +++ b/pkg/http/systemd_unsupported.go @@ -0,0 +1,17 @@ +//go:build windows +// +build windows + +package http + +import ( + "fmt" + "strings" +) + +func (s *server) checkSystemdSocketSupport(opts Opts) error { + if strings.HasPrefix(strings.ToLower(opts.BindAddress), "fd:") { + listenAddr := opts.BindAddress[3:] + return fmt.Errorf("listen (file, %s) failed: systemd sockets are not supported on windows", listenAddr) + } + return nil +}