mirror of
https://github.com/glauth/glauth.git
synced 2026-10-27 06:26:59 +00:00
Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 251ec3ef66 | |||
| cf78b04400 | |||
| 0479c455fb | |||
| 156e917697 | |||
| 7832f9e94d | |||
| e8951481c8 | |||
| 4f5795965b | |||
| 752333e274 | |||
| 8d1ea390ba | |||
| 48981b9462 | |||
| 80314d335b | |||
| 2ee3dbf3c7 | |||
| d7069b027b | |||
| 882714c9dc | |||
| 07e59076e4 | |||
| 5147d1165a | |||
| 374041c358 | |||
| 5bdeb5118b | |||
| 319cc9a3c7 | |||
| 26cd4447c8 | |||
| 96a283fea2 | |||
| c07a1c978c | |||
| c1c57c62e9 | |||
| 700745e640 |
@@ -10,10 +10,10 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.21.x]
|
||||
go-version: [1.25.x]
|
||||
steps:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v4
|
||||
uses: actions/setup-go@v7
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
- name: Updating packages database
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
- name: Install CLI Dependencies
|
||||
run: sudo apt-get install -y ldap-utils oathtool libpam0g-dev
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v7
|
||||
- name: Fetch Go dependencies
|
||||
working-directory: ./v2
|
||||
run: go get -t -v ./...
|
||||
|
||||
@@ -24,18 +24,18 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
uses: github/codeql-action/init@v4
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
queries: +security-and-quality
|
||||
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
uses: github/codeql-action/autobuild@v4
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
uses: github/codeql-action/analyze@v4
|
||||
with:
|
||||
category: "/language:${{ matrix.language }}"
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
name: stale
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Daily, off the hour to avoid GitHub's scheduling congestion at :00
|
||||
- cron: '17 4 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v11
|
||||
with:
|
||||
days-before-stale: 60
|
||||
days-before-close: 14
|
||||
|
||||
stale-issue-label: stale
|
||||
stale-pr-label: stale
|
||||
|
||||
stale-issue-message: >
|
||||
This issue has had no activity for 60 days and has been marked stale.
|
||||
It will be closed in 14 days unless there is new activity. If it is
|
||||
still relevant, a comment saying so is enough to keep it open.
|
||||
|
||||
stale-pr-message: >
|
||||
This pull request has had no activity for 60 days and has been marked
|
||||
stale. It will be closed in 14 days unless there is new activity. If
|
||||
you intend to continue the work, a comment saying so is enough to keep
|
||||
it open.
|
||||
|
||||
close-issue-message: >
|
||||
Closing this issue after 14 days with no further activity. If it is
|
||||
still relevant, please comment and it can be reopened.
|
||||
|
||||
close-pr-message: >
|
||||
Closing this pull request after 14 days with no further activity.
|
||||
Please comment if you would like to pick the work back up.
|
||||
|
||||
# Never touch anything deliberately kept open.
|
||||
exempt-issue-labels: 'pinned,security,blocked,help wanted,good first issue'
|
||||
exempt-pr-labels: 'pinned,security,blocked,dependencies'
|
||||
exempt-all-milestones: true
|
||||
|
||||
# Restarts the clock when someone comments, so an active discussion is
|
||||
# never swept up.
|
||||
remove-stale-when-updated: true
|
||||
|
||||
# Oldest first, so the genuine backlog is handled before recent items.
|
||||
ascending: true
|
||||
+21
@@ -4,7 +4,9 @@ v2/bin
|
||||
v2/docker/assets/linux
|
||||
v2/gl.db
|
||||
v2/buildlogs
|
||||
.idea/
|
||||
.vscode/
|
||||
.DS_Store
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
@@ -19,3 +21,22 @@ go.work.sum
|
||||
# gomocks auto-generated
|
||||
**/mock_*.go
|
||||
|
||||
# Secrets & credentials
|
||||
*.pem
|
||||
*.key
|
||||
*.crt
|
||||
*.p12
|
||||
*.pfx
|
||||
*.env
|
||||
.env.*
|
||||
!.env.example
|
||||
*.tfvars
|
||||
credentials.json
|
||||
secrets.yaml
|
||||
secrets.yml
|
||||
|
||||
# Local GLAuth config that may contain bind passwords / secrets
|
||||
config/*.cfg
|
||||
!config/sample-simple.cfg
|
||||
!config/sample-*.cfg
|
||||
*.local.cfg
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"v2": "2.5.1"
|
||||
"v2": "2.5.4"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
# Contributing to GLAuth
|
||||
|
||||
Thanks for your interest in improving GLAuth! This guide covers how to set up your environment, submit changes, and work with the maintainers. Starting with GLAuth 2.4.0, we reworked and optimized the build workflow, and this contribution process reflects that.
|
||||
|
||||
## Getting Started
|
||||
|
||||
1. Fork the repository and clone your fork locally.
|
||||
2. Review the [Building](https://glauth.github.io/docs/building.html) docs to compile GLAuth from source.
|
||||
3. Review the [Testing](https://glauth.github.io/docs/testing.html) docs to run the test suite before submitting changes.
|
||||
4. Create a topic branch for your work off of `master`.
|
||||
|
||||
## Reporting Issues
|
||||
|
||||
- Open an issue on the [GLAuth issue tracker](https://github.com/glauth/glauth/issues) for bugs and feature requests.
|
||||
- Include your GLAuth version, configuration (with secrets redacted), and clear steps to reproduce.
|
||||
|
||||
## Preparing to Commit
|
||||
|
||||
Format your code automatically using `gofmt -d ./` before committing. If you forget this step, a subsequent pull request may fail.
|
||||
|
||||
## Writing Commit Messages
|
||||
|
||||
Commit messages must be semantically correct. We follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/).
|
||||
|
||||
A commit message contains a prefix, followed by a short explanation. It may also contain "footer" annotations, but these are not mandatory (though appreciated).
|
||||
|
||||
Please don't bundle multiple unrelated items in the same commit (e.g., a new feature and a bug fix).
|
||||
|
||||
### Commit Prefix
|
||||
|
||||
A prefix is written imperatively, for example:
|
||||
|
||||
```
|
||||
feat(plugins)!: Change the plugins API to allow NoSQL databases.
|
||||
```
|
||||
|
||||
This is a new feature (`feat`), optionally scoped to an area of GLAuth (`(plugins)`), with `!` warning of a breaking change.
|
||||
|
||||
A more innocuous change:
|
||||
|
||||
```
|
||||
chore: Add more comments in all modules.
|
||||
```
|
||||
|
||||
Available prefixes: `feat`, `fix`, `chore`, `build`, `ci`, `perf`, `refactor`, `test`, `style`.
|
||||
|
||||
### Commit Footer Annotations
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
Reviewed-by: John Romero <john@romero.com>
|
||||
Tested-by: Joel Spolsky <joel@joelonsoftware.com>
|
||||
BREAKING-CHANGE: I broke the plugin
|
||||
@@ -5,7 +5,7 @@
|
||||
"package-name": "GLAuth",
|
||||
"pull-request-title-pattern": "ci: release ${version}",
|
||||
"extra-files": [
|
||||
"v2/internal/version/const.go"
|
||||
"internal/version/const.go"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,5 +1,26 @@
|
||||
# Changelog
|
||||
|
||||
## [2.5.4](https://github.com/glauth/glauth/compare/GLAuth-v2.5.3...GLAuth-v2.5.4) (2026-09-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* revert pam plugin to msteinert/pam v1 ([#487](https://github.com/glauth/glauth/issues/487)) ([8d1ea39](https://github.com/glauth/glauth/commit/8d1ea390bacc74a54d9b2046e514b7e0336cb08b))
|
||||
|
||||
## [2.5.3](https://github.com/glauth/glauth/compare/GLAuth-v2.5.2...GLAuth-v2.5.3) (2026-09-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* remove repetitions, reduce waitForPort scope, restore arbitrary port ([5bdeb51](https://github.com/glauth/glauth/commit/5bdeb5118b0689d92c4a0d12aea63d8b8d153b71))
|
||||
|
||||
## [2.5.2](https://github.com/glauth/glauth/compare/GLAuth-v2.5.1...GLAuth-v2.5.2) (2026-07-25)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* check plugin compatibility at release time ([700745e](https://github.com/glauth/glauth/commit/700745e640c5371361a58ef3c90245a4637c5224))
|
||||
|
||||
## [2.5.1](https://github.com/glauth/glauth/compare/GLAuth-v2.5.0...GLAuth-v2.5.1) (2026-07-18)
|
||||
|
||||
|
||||
|
||||
+53
-7
@@ -2,7 +2,7 @@
|
||||
|
||||
MAKEFLAGS += --no-print-directory
|
||||
|
||||
VERSION=$(shell bin/linuxamd64/glauth --version)
|
||||
VERSION=$(shell if [ -x bin/linuxamd64/glauth ]; then bin/linuxamd64/glauth --version; else bin/glauth-linux-amd64 --version; fi)
|
||||
|
||||
GIT_COMMIT=$(shell git rev-list -1 HEAD )
|
||||
BUILD_TIME=$(shell date -u +%Y%m%d_%H%M%SZ)
|
||||
@@ -58,8 +58,21 @@ mocks:
|
||||
vet:
|
||||
-go vet ./...
|
||||
.PHONY: vet
|
||||
#seedplugindb: @ stage the sqlite plugin and seed its test database
|
||||
seedplugindb:
|
||||
@if [ -f bin/sqlite-linux-amd64.so ]; then \
|
||||
echo "- staging sqlite plugin and seeding gl.db"; \
|
||||
cp -f bin/sqlite-linux-amd64.so bin/sqlite.so; \
|
||||
rm -f gl.db; \
|
||||
glauth=$$(ls bin/$(GOOS)$(GOARCH)/glauth bin/glauth-$(GOOS)-$(GOARCH) 2>/dev/null | head -1); \
|
||||
"$$glauth" -c pkg/plugins/glauth-sqlite/sample-database.cfg >/dev/null 2>&1 & \
|
||||
pid=$$!; sleep 2; kill -TERM $$pid 2>/dev/null; wait $$pid 2>/dev/null || true; \
|
||||
sqlite3 gl.db < scripts/ci/seed-sqlite-plugin.sql; \
|
||||
fi
|
||||
.PHONY: seedplugindb
|
||||
|
||||
#test: @ runs package, root integration, and shell integration tests
|
||||
test: mocks vet
|
||||
test: mocks vet seedplugindb
|
||||
go test -v -cover -coverprofile coverage.out ./pkg/... ./internal/... .
|
||||
$(MAKE) runtest
|
||||
#all: @ run build process for all binaries
|
||||
@@ -119,6 +132,39 @@ format:
|
||||
devrun:
|
||||
go run ${BUILD_FILES} -c sample-simple.cfg
|
||||
|
||||
#testplugin: @ start GLAuth with a dynamically loaded plugin and stop it cleanly
|
||||
GLAUTH_BIN?=bin/glauth-linux-amd64
|
||||
PLUGIN_BIN?=bin/sqlite-linux-amd64.so
|
||||
PLUGIN_CONFIG?=pkg/plugins/glauth-sqlite/sample-database.cfg
|
||||
PLUGIN_LDAP_PORT?=13893
|
||||
PLUGIN_API_PORT?=15555
|
||||
|
||||
testplugin:
|
||||
@set -e; \
|
||||
test -x "$(GLAUTH_BIN)"; \
|
||||
test -r "$(PLUGIN_BIN)"; \
|
||||
test -f "$(PLUGIN_CONFIG)"; \
|
||||
tmpdir=$$(mktemp -d); \
|
||||
trap 'rm -rf "$$tmpdir"' EXIT; \
|
||||
sed \
|
||||
-e 's#^[[:space:]]*plugin = .*# plugin = "$(abspath $(PLUGIN_BIN))"#' \
|
||||
-e "s#^[[:space:]]*database = .*# database = \"$$tmpdir/gl.db\"#" \
|
||||
-e 's#listen = "0.0.0.0:3893"#listen = "127.0.0.1:$(PLUGIN_LDAP_PORT)"#' \
|
||||
-e 's#listen = "0.0.0.0:5555"#listen = "127.0.0.1:$(PLUGIN_API_PORT)"#' \
|
||||
"$(PLUGIN_CONFIG)" > "$$tmpdir/config.cfg"; \
|
||||
"$(GLAUTH_BIN)" -c "$$tmpdir/config.cfg" > "$$tmpdir/glauth.log" 2>&1 & \
|
||||
pid=$$!; \
|
||||
sleep 2; \
|
||||
if ! kill -0 "$$pid" 2>/dev/null; then \
|
||||
set +e; wait "$$pid"; status=$$?; set -e; \
|
||||
cat "$$tmpdir/glauth.log"; \
|
||||
exit $$status; \
|
||||
fi; \
|
||||
kill -TERM "$$pid"; \
|
||||
set +e; wait "$$pid"; status=$$?; set -e; \
|
||||
cat "$$tmpdir/glauth.log"; \
|
||||
exit $$status
|
||||
|
||||
mkbindir:
|
||||
@echo "create directory bin/$(GOOS)$(GOARCH)"
|
||||
@mkdir -p bin/$(GOOS)$(GOARCH)
|
||||
@@ -179,7 +225,7 @@ verify:
|
||||
@for binary in linux386 linuxamd64 linuxarm linuxarm64 linuxriscv64 darwinamd64 darwinarm64 win386 winamd64; do cd bin/$$binary && sha256sum glauth.sha256 -c && cd ../..; done
|
||||
|
||||
pull-plugin-dependencies:
|
||||
(for pkg in $$(cat $$M/go.mod | awk '/^require [a-z]/{print $$2} /^\)/{rblock=0} rblock{if($$4!="indirect" && $$1!~"glauth"){print $$1}} /^require \(/{rblock=1}'); do if [ "$$(grep $$pkg go.mod &>/dev/null)" = "" ]; then go get $$pkg; fi; done)
|
||||
(for pkg in $$(cat $$M/go.mod | awk '/^require [a-z]/{print $$2"@"$$3} /^\)/{rblock=0} rblock{if($$4!="indirect" && $$1!~"glauth"){print $$1"@"$$2}} /^require \(/{rblock=1}'); do if [ "$$(grep $${pkg%@*} go.mod 2>/dev/null)" = "" ]; then go get $$pkg; fi; done)
|
||||
|
||||
#prepare-plugins-buid: @ pull plugins dependencies for local building
|
||||
prepare-plugins-build:
|
||||
@@ -268,7 +314,7 @@ _checkdockerauth:
|
||||
builddockermain:
|
||||
$(if $(TAG),,$(error ❌ Must set TAG))
|
||||
$(if $(REPO),,$(error ❌ Must set REPO - glauth or other))
|
||||
@mkdir -p docker/assets/linux/amd64 docker/assets/linux/arm64 docker/assets/linux/arm/v7 && \
|
||||
@mkdir -p docker/assets/linux/amd64 docker/assets/linux/arm64 docker/assets/linux/arm/v7 docker/assets/linux/riscv64 && \
|
||||
cp -f bin/glauth-linux-amd64 docker/assets/linux/amd64/glauth && \
|
||||
cp -f bin/glauth-linux-arm64 docker/assets/linux/arm64/glauth && \
|
||||
cp -f bin/glauth-linux-arm-7 docker/assets/linux/arm/v7/glauth && \
|
||||
@@ -279,7 +325,7 @@ builddockermain:
|
||||
builddockerplugins:
|
||||
$(if $(TAG),,$(error ❌ Must set TAG))
|
||||
$(if $(REPO),,$(error ❌ Must set REPO - glauth or other))
|
||||
@mkdir -p docker/assets/linux/amd64 docker/assets/linux/arm64 docker/assets/linux/arm/v7 && \
|
||||
@mkdir -p docker/assets/linux/amd64 docker/assets/linux/arm64 docker/assets/linux/arm/v7 docker/assets/linux/riscv64 && \
|
||||
cp -f bin/sqlite-linux-amd64.so docker/assets/linux/amd64/sqlite.so && \
|
||||
cp -f bin/sqlite-linux-arm64.so docker/assets/linux/arm64/sqlite.so && \
|
||||
cp -f bin/sqlite-linux-arm-7.so docker/assets/linux/arm/v7/sqlite.so && \
|
||||
@@ -297,7 +343,7 @@ builddockerplugins:
|
||||
|
||||
builddocker: _checkdockerauth builddockermain builddockerplugins
|
||||
|
||||
buildeverything: prepbuild forget-embed _buildmain _buildplugins remember-embed _buildmainembeds builddocker
|
||||
buildeverything: prepbuild forget-embed _buildplugins _buildmain testplugin remember-embed _buildmainembeds builddocker
|
||||
|
||||
#testdocker: @ run integration test using docker
|
||||
testdocker:
|
||||
@@ -343,4 +389,4 @@ testdocker:
|
||||
prepbuild run test fast binaries setup getdeps runtest updatetest format devrun \
|
||||
linux386 linuxamd64 linuxarm linuxarm64 linuxriscv64 darwinamd64 darwinarm64 win386 winamd64 verify \
|
||||
pull-plugin pull-base-plugins forget-plugin forget-plugins buildmain buildplugin build \
|
||||
buildplugins builddockermain builddockerplugins builddocker testdocker buildeverything
|
||||
buildplugins builddockermain builddockerplugins builddocker testdocker testplugin buildeverything
|
||||
|
||||
+186
-142
@@ -1,6 +1,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
@@ -10,6 +12,9 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/glauth/ldap"
|
||||
"github.com/pquerna/otp/totp"
|
||||
)
|
||||
|
||||
type testEnv struct {
|
||||
@@ -36,6 +41,15 @@ func glauthBinary() string {
|
||||
if _, err := os.Stat(qualified); err == nil {
|
||||
return qualified
|
||||
}
|
||||
|
||||
distribution := filepath.Join("bin", "glauth-"+runtime.GOOS+"-"+runtime.GOARCH)
|
||||
if runtime.GOOS == "windows" {
|
||||
distribution += ".exe"
|
||||
}
|
||||
if _, err := os.Stat(distribution); err == nil {
|
||||
return distribution
|
||||
}
|
||||
|
||||
return "bin/glauth"
|
||||
}
|
||||
|
||||
@@ -88,11 +102,11 @@ func TestConfigBackendRejectsPasswordlessUserBinds(t *testing.T) {
|
||||
action = "search"
|
||||
object = "*"
|
||||
`, port)
|
||||
if err := os.WriteFile(configPath, []byte(config), 0600); err != nil {
|
||||
if err := os.WriteFile(configPath, []byte(config), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
svc := startSvc(SD, glauthBinary(), "-c", configPath)
|
||||
svc := startSvc(t, fmt.Sprintf("127.0.0.1:%d", port), glauthBinary(), "-c", configPath)
|
||||
defer stopSvc(svc)
|
||||
|
||||
bindDN := "cn=nopass,dc=glauth,dc=com"
|
||||
@@ -105,7 +119,7 @@ func TestConfigBackendRejectsPasswordlessUserBinds(t *testing.T) {
|
||||
{name: "empty password", password: "", want: "exit status 53"},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got := doRunGetFirst(0, "ldapsearch", "-LLL", "-H", fmt.Sprintf("ldap://127.0.0.1:%d", port), "-D", bindDN, "-w", tc.password, "-x", "-b", "dc=glauth,dc=com", "(cn=nopass)")
|
||||
got := runAndSelect(t, getFirst, "ldapsearch", "-LLL", "-H", fmt.Sprintf("ldap://127.0.0.1:%d", port), "-D", bindDN, "-w", tc.password, "-x", "-b", "dc=glauth,dc=com", "(cn=nopass)")
|
||||
if got != tc.want {
|
||||
t.Fatalf("bind result = %q, want %q", got, tc.want)
|
||||
}
|
||||
@@ -140,153 +154,139 @@ func ldapOnlyConfig(t *testing.T, source string) string {
|
||||
|
||||
contents = contents[:start] + sectionWithoutLDAPS + contents[end:]
|
||||
path := filepath.Join(t.TempDir(), filepath.Base(source))
|
||||
if err := os.WriteFile(path, []byte(contents), 0600); err != nil {
|
||||
if err := os.WriteFile(path, []byte(contents), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
func batteryOfTests(t *testing.T, env *testEnv) {
|
||||
// We aren't checking that "github.com/pquerna/otp/totp" creates correct values.
|
||||
// That's what their own tests are for.
|
||||
// We are checking that the totp code gets through glauth code successfully
|
||||
otpvalue, err := totp.GenerateCode("3hnvnk4ycv44glzigd6s25j4dougs3rk", time.Now())
|
||||
if err != nil {
|
||||
t.Fatal("Failed to generate totp code:", err)
|
||||
}
|
||||
|
||||
const addr = "ldap://127.0.0.1:3893"
|
||||
bind := func(dn, password string, rest ...string) []string {
|
||||
return append([]string{"-LLL", "-H", addr, "-D", dn, "-w", password, "-x"}, rest...)
|
||||
}
|
||||
svc := func(rest ...string) []string { return bind(env.svcdn, "mysecret", rest...) }
|
||||
otp := func(password string) []string {
|
||||
return bind(env.otpdn, password, "-bou=superheros,dc=glauth,dc=com", "cn=hackers")
|
||||
}
|
||||
|
||||
const (
|
||||
inSuperheros = "should find them in the 'superheros' group"
|
||||
listFromUser = "should get a list starting with the 'hackers' user"
|
||||
badCreds = "should get 'Invalid credentials(49)'"
|
||||
)
|
||||
|
||||
tests := []struct {
|
||||
Name string
|
||||
Path string
|
||||
Check func(t testing.TB)
|
||||
name string
|
||||
skip bool
|
||||
args []string
|
||||
line func(string) string
|
||||
want string
|
||||
msg string
|
||||
}{
|
||||
{
|
||||
Name: "searching for the 'hackers' user",
|
||||
Check: func(t testing.TB) {
|
||||
out := doRunGetFirst(RD, "ldapsearch", "-LLL", "-H", "ldap://localhost:3893", "-D", env.svcdn, "-w", "mysecret", "-x", "-bdc=glauth,dc=com", "cn=hackers")
|
||||
if got, want := out, env.expectedaccount; got != want {
|
||||
t.Fatalf("should find them in the 'superheros' group\ngot: %s\nwant: %s", got, want)
|
||||
}
|
||||
},
|
||||
name: "searching for the 'hackers' user",
|
||||
args: svc("-bdc=glauth,dc=com", "cn=hackers"),
|
||||
want: env.expectedaccount,
|
||||
msg: inSuperheros,
|
||||
},
|
||||
{
|
||||
Name: "searching for the 'hackers' user without binding with a group",
|
||||
Check: func(t testing.TB) {
|
||||
if env.svcdnnogroup == "" {
|
||||
t.SkipNow()
|
||||
}
|
||||
out := doRunGetFirst(RD, "ldapsearch", "-LLL", "-H", "ldap://localhost:3893", "-D", env.svcdnnogroup, "-w", "mysecret", "-x", "-bdc=glauth,dc=com", "cn=hackers")
|
||||
if got, want := out, env.expectedaccount; got != want {
|
||||
t.Fatalf("should find them in the 'superheros' group\ngot: %s\nwant: %s", got, want)
|
||||
}
|
||||
},
|
||||
name: "searching for the 'hackers' user without binding with a group",
|
||||
skip: env.svcdnnogroup == "",
|
||||
args: bind(env.svcdnnogroup, "mysecret", "-bdc=glauth,dc=com", "cn=hackers"),
|
||||
want: env.expectedaccount,
|
||||
msg: inSuperheros,
|
||||
},
|
||||
{
|
||||
Name: "searching for the 'hackers' user after binding using the account's UPN",
|
||||
Check: func(t testing.TB) {
|
||||
if !env.checkbindUPN {
|
||||
t.SkipNow()
|
||||
}
|
||||
out := doRunGetFirst(RD, "ldapsearch", "-LLL", "-H", "ldap://localhost:3893", "-D", "serviceuser@example.com", "-w", "mysecret", "-x", "-bdc=glauth,dc=com", "cn=hackers")
|
||||
if got, want := out, env.expectedaccount; got != want {
|
||||
t.Fatalf("should find them in the 'superheros' group\ngot: %s\nwant: %s", got, want)
|
||||
}
|
||||
},
|
||||
name: "searching for the 'hackers' user after binding using the account's UPN",
|
||||
skip: !env.checkbindUPN,
|
||||
args: bind("serviceuser@example.com", "mysecret", "-bdc=glauth,dc=com", "cn=hackers"),
|
||||
want: env.expectedaccount,
|
||||
msg: inSuperheros,
|
||||
},
|
||||
{
|
||||
Name: "querying the root SDE",
|
||||
Check: func(t testing.TB) {
|
||||
out := doRunGetSecond(RD, "ldapsearch", "-LLL", "-H", "ldap://localhost:3893", "-D", env.svcdn, "-w", "mysecret", "-x", "-s", "base", "(objectclass=*)")
|
||||
if got, want := out, env.expectedinfo; got != want {
|
||||
t.Fatalf("should get some meta information\ngot: %s\nwant: %s", got, want)
|
||||
}
|
||||
},
|
||||
name: "querying the root SDE",
|
||||
args: svc("-s", "base", "(objectclass=*)"),
|
||||
line: getSecond,
|
||||
want: env.expectedinfo,
|
||||
msg: "should get some meta information",
|
||||
},
|
||||
{
|
||||
Name: "querying the root SDE anonymously without authorizing in config file",
|
||||
Check: func(t testing.TB) {
|
||||
if !env.checkanonymousrootDSE {
|
||||
t.SkipNow()
|
||||
}
|
||||
out := doRunGetFirst(RD, "ldapsearch", "-LLL", "-H", "ldap://localhost:3893", "-x", "-s", "base", "(objectclass=*)")
|
||||
if got, want := out, "exit status 50"; got != want {
|
||||
t.Fatalf("should get error 50\ngot: %s\nwant: %s", got, want)
|
||||
}
|
||||
},
|
||||
name: "querying the root SDE anonymously without authorizing in config file",
|
||||
skip: !env.checkanonymousrootDSE,
|
||||
args: []string{"-LLL", "-H", addr, "-x", "-s", "base", "(objectclass=*)"},
|
||||
want: "exit status 50",
|
||||
msg: "should get error 50",
|
||||
},
|
||||
{
|
||||
Name: "enumerating posix groups",
|
||||
Check: func(t testing.TB) {
|
||||
out := doRunGetFirst(RD, "ldapsearch", "-LLL", "-H", "ldap://localhost:3893", "-D", env.svcdn, "-w", "mysecret", "-x", "-bdc=glauth,dc=com", "(objectclass=posixgroup)")
|
||||
if got, want := out, env.expectedgroup; got != want {
|
||||
t.Fatalf("should get a list starting with the 'superheros' group\ngot: %s\nwant: %s", got, want)
|
||||
}
|
||||
},
|
||||
name: "enumerating posix groups",
|
||||
args: svc("-bdc=glauth,dc=com", "(objectclass=posixgroup)"),
|
||||
want: env.expectedgroup,
|
||||
msg: "should get a list starting with the 'superheros' group",
|
||||
},
|
||||
{
|
||||
Name: "searching for members of the 'superheros' group",
|
||||
Check: func(t testing.TB) {
|
||||
out := doRunGetFirst(RD, "ldapsearch", "-LLL", "-H", "ldap://localhost:3893", "-D", env.svcdn, "-w", "mysecret", "-x", "-bdc=glauth,dc=com", "(memberOf=ou=superheros,ou=groups,dc=glauth,dc=com)")
|
||||
if got, want := out, env.expectedfirstaccount; got != want {
|
||||
t.Fatalf("should get a list starting with the 'hackers' user\ngot: %s\nwant: %s", got, want)
|
||||
}
|
||||
},
|
||||
name: "searching for members of the 'superheros' group",
|
||||
args: svc("-bdc=glauth,dc=com", "(memberOf=ou=superheros,ou=groups,dc=glauth,dc=com)"),
|
||||
want: env.expectedfirstaccount,
|
||||
msg: listFromUser,
|
||||
},
|
||||
{
|
||||
Name: "performing a complex search for members of 'superheros' group",
|
||||
Check: func(t testing.TB) {
|
||||
out := doRunGetFirst(RD, "ldapsearch", "-LLL", "-H", "ldap://localhost:3893", "-D", env.svcdn, "-w", "mysecret", "-x", "-bdc=glauth,dc=com", "(&(objectClass=*)(memberOf=ou=superheros,ou=groups,dc=glauth,dc=com))")
|
||||
if got, want := out, env.expectedfirstaccount; got != want {
|
||||
t.Fatalf("should get a list starting with the 'hackers' user\ngot: %s\nwant: %s", got, want)
|
||||
}
|
||||
},
|
||||
name: "performing a complex search for members of 'superheros' group",
|
||||
args: svc("-bdc=glauth,dc=com", "(&(objectClass=*)(memberOf=ou=superheros,ou=groups,dc=glauth,dc=com))"),
|
||||
want: env.expectedfirstaccount,
|
||||
msg: listFromUser,
|
||||
},
|
||||
{
|
||||
Name: "searching for the 'hacker' user using a TOTP-enabled account",
|
||||
Check: func(t testing.TB) {
|
||||
if !env.checkTOTP {
|
||||
t.SkipNow()
|
||||
}
|
||||
otpvalue := doRunGetFirst(RD, "oathtool", "--totp", "-b", "-d", "6", "3hnvnk4ycv44glzigd6s25j4dougs3rk")
|
||||
out := doRunGetFirst(RD, "ldapsearch", "-LLL", "-H", "ldap://localhost:3893", "-D", env.otpdn, "-w", "mysecret"+otpvalue, "-x", "-bou=superheros,dc=glauth,dc=com", "cn=hackers")
|
||||
if got, want := out, env.scopedaccount; got != want {
|
||||
t.Fatalf("should find them in in the 'superheros' group\ngot: %s\nwant: %s", got, want)
|
||||
}
|
||||
},
|
||||
name: "searching for the 'hacker' user using a TOTP-enabled account",
|
||||
skip: !env.checkTOTP,
|
||||
args: otp("mysecret" + otpvalue),
|
||||
want: env.scopedaccount,
|
||||
msg: inSuperheros,
|
||||
},
|
||||
{
|
||||
Name: "searching for the 'hacker' user using a TOTP-enabled account and no value",
|
||||
Check: func(t testing.TB) {
|
||||
if !env.checkTOTP {
|
||||
t.SkipNow()
|
||||
}
|
||||
out := doRunGetFirst(RD, "ldapsearch", "-LLL", "-H", "ldap://localhost:3893", "-D", env.otpdn, "-w", "mysecret", "-x", "-bou=superheros,dc=glauth,dc=com", "cn=hackers")
|
||||
if got, want := out, "exit status 49"; got != want {
|
||||
t.Fatalf("should get 'Invalid credentials(49)'\ngot: %s\nwant: %s", got, want)
|
||||
}
|
||||
},
|
||||
name: "searching for the 'hacker' user using a TOTP-enabled account and no value",
|
||||
skip: !env.checkTOTP,
|
||||
args: otp("mysecret"),
|
||||
want: "exit status 49",
|
||||
msg: badCreds,
|
||||
},
|
||||
{
|
||||
Name: "searching for the 'hacker' user using a TOTP-enabled account and the wrong value",
|
||||
Check: func(t testing.TB) {
|
||||
if !env.checkTOTP {
|
||||
t.SkipNow()
|
||||
}
|
||||
out := doRunGetFirst(RD, "ldapsearch", "-LLL", "-H", "ldap://localhost:3893", "-D", env.otpdn, "-w", "mysecret123456", "-x", "-bou=superheros,dc=glauth,dc=com", "cn=hackers")
|
||||
if got, want := out, "exit status 49"; got != want {
|
||||
t.Fatalf("should get 'Invalid credentials(49)'\ngot: %s\nwant: %s", got, want)
|
||||
}
|
||||
},
|
||||
name: "searching for the 'hacker' user using a TOTP-enabled account and the wrong value",
|
||||
skip: !env.checkTOTP,
|
||||
args: otp("mysecret123456"),
|
||||
want: "exit status 49",
|
||||
msg: badCreds,
|
||||
},
|
||||
{
|
||||
Name: "searching for the 'hacker' user",
|
||||
Check: func(t testing.TB) {
|
||||
if env.checkemployeetype == "" {
|
||||
t.SkipNow()
|
||||
}
|
||||
out := doRunGetSecond(RD, "ldapsearch", "-LLL", "-H", "ldap://localhost:3893", "-D", env.svcdn, "-w", "mysecret", "-x", "-bdc=glauth,dc=com", env.checkemployeetype, "employeetype")
|
||||
if got, want := out, "employeetype: Intern"; got != want {
|
||||
t.Fatalf("type should be 'Intern'\ngot: %s\nwant: %s", got, want)
|
||||
}
|
||||
},
|
||||
name: "searching for the 'hacker' user",
|
||||
skip: env.checkemployeetype == "",
|
||||
args: svc("-bdc=glauth,dc=com", env.checkemployeetype, "employeetype"),
|
||||
line: getSecond,
|
||||
want: "employeetype: Intern",
|
||||
msg: "type should be 'Intern'",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
tc.Check(t)
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if tc.skip {
|
||||
t.SkipNow()
|
||||
}
|
||||
line := tc.line
|
||||
if line == nil {
|
||||
line = getFirst
|
||||
}
|
||||
if got := runAndSelect(t, line, "ldapsearch", tc.args...); got != tc.want {
|
||||
t.Fatalf("%s\ngot: %s\nwant: %s", tc.msg, got, tc.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -307,14 +307,15 @@ func TestSampleSimple(t *testing.T) {
|
||||
checkemployeetype: "cn=hackers",
|
||||
}
|
||||
|
||||
svc := startSvc(SD, glauthBinary(), "-c", ldapOnlyConfig(t, "sample-simple.cfg"))
|
||||
svc := startSvc(t, "127.0.0.1:3893", glauthBinary(), "-c", ldapOnlyConfig(t, "sample-simple.cfg"))
|
||||
batteryOfTests(t, &env)
|
||||
stopSvc(svc)
|
||||
}
|
||||
|
||||
func TestSQLitePlugin(t *testing.T) {
|
||||
matchingLibrary := doRunGetFirst(RD, "ls", "bin/sqlite.so")
|
||||
if matchingLibrary != "bin/sqlite.so" {
|
||||
_, err := os.Stat("bin/sqlite.so")
|
||||
if err != nil {
|
||||
t.Log("Unable to find sqlite plugin")
|
||||
t.SkipNow()
|
||||
}
|
||||
|
||||
@@ -333,14 +334,20 @@ func TestSQLitePlugin(t *testing.T) {
|
||||
checkemployeetype: "",
|
||||
}
|
||||
|
||||
svc := startSvc(SD, glauthBinary(), "-c", "pkg/plugins/glauth-sqlite/sample-database.cfg")
|
||||
svc := startSvc(t, "127.0.0.1:3893", glauthBinary(), "-c", "pkg/plugins/glauth-sqlite/sample-database.cfg")
|
||||
batteryOfTests(t, &env)
|
||||
stopSvc(svc)
|
||||
}
|
||||
|
||||
func TestLdapInjection(t *testing.T) {
|
||||
matchingContainers := doRunGetFirst(RD, "sh", "-c", "docker ps | grep ldap-service | wc -l")
|
||||
out, err := doRun("sh", "-c", "docker ps | grep ldap-service | wc -l")
|
||||
if err != nil {
|
||||
t.Log("Unable to find docker container:", out)
|
||||
t.SkipNow()
|
||||
}
|
||||
matchingContainers := getFirst(out)
|
||||
if matchingContainers != "1" {
|
||||
t.Log("Unable to find docker container:", out)
|
||||
t.SkipNow()
|
||||
}
|
||||
|
||||
@@ -359,52 +366,89 @@ func TestLdapInjection(t *testing.T) {
|
||||
checkemployeetype: "",
|
||||
}
|
||||
|
||||
svc := startSvc(SD, glauthBinary(), "-c", "sample-ldap-injection.cfg")
|
||||
svc := startSvc(t, "127.0.0.1:3893", glauthBinary(), "-c", "sample-ldap-injection.cfg")
|
||||
batteryOfTests(t, &env)
|
||||
stopSvc(svc)
|
||||
}
|
||||
|
||||
// -----=============================================================================----
|
||||
|
||||
const SD = 3 // Start Delay
|
||||
const RD = 2 // Response Delay
|
||||
|
||||
func startSvc(delay time.Duration, name string, arg ...string) *exec.Cmd {
|
||||
cmd := exec.Command(name, arg...)
|
||||
cmd.Start()
|
||||
if delay != 0 {
|
||||
time.Sleep(time.Second * delay)
|
||||
func waitForPort(host string, timeout time.Duration) error {
|
||||
start := time.Now()
|
||||
for {
|
||||
conn, err := ldap.Dial("tcp", host)
|
||||
if err == nil {
|
||||
err = conn.Bind("_", "_")
|
||||
if err == nil {
|
||||
conn.Close()
|
||||
return fmt.Errorf("Successfully authenticated to glauth. This should not happen")
|
||||
}
|
||||
e := &ldap.Error{}
|
||||
if errors.As(err, &e) && e.ResultCode == 49 {
|
||||
conn.Close()
|
||||
return nil
|
||||
}
|
||||
conn.Close()
|
||||
// We have an error, it's probably a connection error or an error saying that ldap isn't setup yet
|
||||
// try again
|
||||
}
|
||||
if time.Since(start) > timeout {
|
||||
return fmt.Errorf("timeout waiting for port %s: %w", host, err)
|
||||
}
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
func startSvc(t *testing.T, addr string, name string, arg ...string) *exec.Cmd {
|
||||
cmd := exec.Command(name, arg...)
|
||||
cmd.Stderr = t.Output()
|
||||
cmd.Stdout = t.Output()
|
||||
if err := cmd.Start(); err != nil {
|
||||
t.Fatal("Failed to start glauth:", err)
|
||||
}
|
||||
if err := waitForPort(addr, time.Second*2); err != nil {
|
||||
t.Fatal("Failed to wait for glauth to start:", err)
|
||||
}
|
||||
// the port is listening but the ldap server may not be accepting connections yet
|
||||
// TODO: make glauth listen as the last part of the initialization that way as soon as it listens it can process connections
|
||||
return cmd
|
||||
}
|
||||
|
||||
func stopSvc(svc *exec.Cmd) {
|
||||
svc.Process.Kill()
|
||||
svc.Process.Wait()
|
||||
}
|
||||
|
||||
func doRunGetFirst(delay time.Duration, name string, arg ...string) string {
|
||||
out := strings.SplitN(doRun(delay, name, arg...), "\n", 2)
|
||||
if out == nil || len(out) < 1 {
|
||||
func getFirst(output string) string {
|
||||
out := strings.SplitN(output, "\n", 2)
|
||||
if len(out) < 1 {
|
||||
return "*fail*"
|
||||
}
|
||||
return out[0]
|
||||
}
|
||||
|
||||
func doRunGetSecond(delay time.Duration, name string, arg ...string) string {
|
||||
out := strings.SplitN(doRun(delay, name, arg...), "\n", 3)
|
||||
if out == nil || len(out) < 2 {
|
||||
func getSecond(output string) string {
|
||||
out := strings.SplitN(output, "\n", 3)
|
||||
if len(out) < 2 {
|
||||
return "*fail*"
|
||||
}
|
||||
return out[1]
|
||||
}
|
||||
|
||||
func doRun(delay time.Duration, name string, arg ...string) string {
|
||||
out, err := exec.Command(name, arg...).Output()
|
||||
func doRun(name string, arg ...string) (string, error) {
|
||||
out, err := exec.Command(name, arg...).CombinedOutput()
|
||||
if err != nil {
|
||||
return string(bytes.TrimSpace(out)), err
|
||||
}
|
||||
|
||||
return string(bytes.TrimSpace(out)), nil
|
||||
}
|
||||
|
||||
func runAndSelect(t testing.TB, pick func(string) string, name string, arg ...string) string {
|
||||
t.Helper()
|
||||
out, err := doRun(name, arg...)
|
||||
if err != nil {
|
||||
t.Log(out)
|
||||
return err.Error()
|
||||
}
|
||||
if delay != 0 {
|
||||
time.Sleep(time.Second * delay)
|
||||
}
|
||||
return strings.TrimSpace(string(out))
|
||||
return pick(out)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/glauth/glauth/v2
|
||||
|
||||
go 1.21
|
||||
go 1.25.0
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.3.2
|
||||
@@ -16,16 +16,16 @@ require (
|
||||
github.com/rs/zerolog v1.31.0
|
||||
github.com/uptrace/opentelemetry-go-extra/otelsql v0.2.3
|
||||
github.com/yaegashi/msgraph.go v0.1.4
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.21.1
|
||||
go.opentelemetry.io/otel v1.21.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0
|
||||
go.opentelemetry.io/otel/sdk v1.21.0
|
||||
go.opentelemetry.io/otel/trace v1.21.0
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.46.0
|
||||
go.opentelemetry.io/otel v1.46.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.46.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.46.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.46.0
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.46.0
|
||||
go.opentelemetry.io/otel/sdk v1.46.0
|
||||
go.opentelemetry.io/otel/trace v1.46.0
|
||||
go.uber.org/mock v0.4.0
|
||||
golang.org/x/crypto v0.18.0
|
||||
golang.org/x/crypto v0.55.0
|
||||
gopkg.in/amz.v3 v3.0.0-20201001071545-24fc1eceb27b
|
||||
)
|
||||
|
||||
@@ -33,13 +33,15 @@ require (
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect
|
||||
github.com/go-logr/logr v1.3.0 // indirect
|
||||
github.com/go-logr/logr v1.4.4 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.30.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
|
||||
@@ -47,13 +49,14 @@ require (
|
||||
github.com/prometheus/procfs v0.12.0 // indirect
|
||||
github.com/rickb777/date v1.12.4 // indirect
|
||||
github.com/rickb777/plural v1.2.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.21.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.0.0 // indirect
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
golang.org/x/sys v0.16.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
|
||||
google.golang.org/grpc v1.59.0 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.46.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.11.0 // indirect
|
||||
golang.org/x/net v0.58.0 // indirect
|
||||
golang.org/x/sys v0.47.0 // indirect
|
||||
golang.org/x/text v0.41.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260819154853-08b0e4226688 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688 // indirect
|
||||
google.golang.org/grpc v1.83.1 // indirect
|
||||
google.golang.org/protobuf v1.36.12 // indirect
|
||||
)
|
||||
|
||||
@@ -11,10 +11,16 @@ github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
|
||||
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
@@ -26,6 +32,9 @@ github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkPro
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
|
||||
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8=
|
||||
github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
@@ -35,14 +44,23 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 h1:5VipnvEpbqr2gA2VbM+nYVbkIF28c5ZQfqCBQ5g2xfk=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0/go.mod h1:Hyl3n6Twe1hvtd9XUXDec4pTvgMSEixRuQKPTMH2bNs=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.30.0 h1:/Tnpcb2E0Pz/tN9s3bfEY2Q8ePCEX9iuS+cneUwncnw=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.30.0/go.mod h1:zOBXOsUaBSjKgmH4OGzV1esUpR3oUSCPYVd2cUBjKYY=
|
||||
github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8=
|
||||
github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
@@ -89,26 +107,64 @@ github.com/yaegashi/msgraph.go v0.1.4/go.mod h1:vgeYhHa5skJt/3lTyjGXThTZhwbhRnGo
|
||||
github.com/yaegashi/wtz.go v0.0.2/go.mod h1:nOLA5QXsmdkRxBkP5tljhua13ADHCKirLBrzPf4PEJc=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.21.1 h1:f4beMGDKiVzg9IcX7/VuWVy+oGdjx3dNJ72YehmtY5k=
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.21.1/go.mod h1:U9jhkEl8d1LL+QXY7q3kneJWJugiN3kZJV2OWz3hkBY=
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.46.0 h1:uxl0SGcmuBkHj/Adl9oftEAyiawQBPL5RzMAmt/Yvq4=
|
||||
go.opentelemetry.io/contrib/propagators/jaeger v1.46.0/go.mod h1:LiOkxCIvoLofmRps7f8l0NkBtmObnAyQ5trteFs6wj8=
|
||||
go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
|
||||
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
|
||||
go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=
|
||||
go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
|
||||
go.opentelemetry.io/otel v1.46.0 h1:FHt5/CDyVxi/8IM1CH7VE/rRgq3kLHa2mSTVMO8AWyc=
|
||||
go.opentelemetry.io/otel v1.46.0/go.mod h1:Gj3SEScelsNC45tp4nSxRYlS+f5iez7W8XPMCt905kE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 h1:4YsVu3B8+3qtWYYrsUYgn0OG78pN0rnNPRGX4SbokQI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0/go.mod h1:+wnlSn0mD1ADVMe3v9Z/WIaiz6q6gL2J/ejaAmdmv80=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.46.0 h1:OFnwLJr+pF3iHrlGSzbxyuo6/6HyBlnlN1CWEJmBVcw=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.46.0/go.mod h1:716wFneO0ov19A2beH5hjfh9AK5z/VWNAtDijp1Y0/g=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0 h1:qazEJlUOQzhCpzQpFETGby7EdqjI1wsd0W+6Gg1SCTU=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0/go.mod h1:fOD2Yefuxixkx3ahVNf0O/PERb6r4OlbxfATVnYvzCo=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.46.0 h1:w53CDeOA/Kurp7yRsegSr6pbbr759dOvJ+yNmWM6Hxs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.46.0/go.mod h1:BOmGMCbAtvcJiSJ+hLuhgPLdDbimnraSl8irz3iY8sY=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkEZCJWobwBqMwC0cwCq8/wkkRy/OowZg5OArWZrM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0 h1:lgh3PiVrRUWMLOVSkQicxzZll5NjF1r+AtsX1XRIHw0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0/go.mod h1:5Cnhth3m/AgOeTgE3ex12pPmiu/gGtZit03kSzx9X7s=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.46.0 h1:KrC1YrQeSt46ITMWAbgQx1M1eV1/1TKzttrBzymPmss=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.46.0/go.mod h1:zDSEzoEqsOrgBeGvH66KRgxh90VonFyJqBHA0Pk3+rM=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 h1:VhlEQAPp9R1ktYfrPk5SOryw1e9LDDTZCbIPFrho0ec=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0/go.mod h1:kB3ufRbfU+CQ4MlUcqtW8Z7YEOBeK2DJ6CmR5rYYF3E=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.44.0 h1:bl2S7Ubua0Nms+D/gAmznQTd4dxxMA93aKbcpKqiTCs=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.44.0/go.mod h1:L0hRV50XdVIODHUfWEqGRCXQvj2rV82STVo12FMFBU0=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.46.0 h1:KdRxPiAoMptR3vfWzvjjvutTsSiwbC2uG0496rzZNfo=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.46.0/go.mod h1:K/qSA+3G7Eovxi4K09wzrAgkWRnosS0DAOZeEpve7sM=
|
||||
go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4=
|
||||
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
|
||||
go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo=
|
||||
go.opentelemetry.io/otel/metric v1.46.0 h1:yBnkXvgV7AXFILZc5K6IZe/CBFF3OS7BJ8ov6/lj0K8=
|
||||
go.opentelemetry.io/otel/metric v1.46.0/go.mod h1:iPmdWqifKUdzziPkvvzIJXITl56fQx2mGM/DHLB3/2o=
|
||||
go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
|
||||
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
|
||||
go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58=
|
||||
go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0=
|
||||
go.opentelemetry.io/otel/sdk v1.46.0 h1:h5CNQQjEbuQXY/JfZtgt3i7HVFV3aHPO2OAwO2eTYPI=
|
||||
go.opentelemetry.io/otel/sdk v1.46.0/go.mod h1:GAERFXFt5SYCEB+YiKUbMBeza6UaDH7GmGOZEfh2gSM=
|
||||
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
|
||||
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
|
||||
go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
|
||||
go.opentelemetry.io/otel/trace v1.46.0 h1:OULy7ccdJnZtJ0UDYFOIGaCmiWzJ8Vi2G/Rsu60qs1c=
|
||||
go.opentelemetry.io/otel/trace v1.46.0/go.mod h1:J7GAXweO77XSFkB/rmAqk9D6ihszhFjLU+d9WuUxDLI=
|
||||
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
|
||||
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
|
||||
go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g=
|
||||
go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk=
|
||||
go.opentelemetry.io/proto/otlp v1.11.0 h1:5rrYs0Ykyj50sdU/JU0x8etU+LubXWb+gED6TbEdMIk=
|
||||
go.opentelemetry.io/proto/otlp v1.11.0/go.mod h1:SmVizdCOAm3XBtG1g1NnOdhW6jtddT72hLMhv8VwA8E=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
|
||||
@@ -118,6 +174,10 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988=
|
||||
golang.org/x/crypto v0.52.0/go.mod h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc=
|
||||
golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M=
|
||||
golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -128,6 +188,10 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
|
||||
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
|
||||
golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To=
|
||||
golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -141,10 +205,18 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
|
||||
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
|
||||
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
|
||||
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
|
||||
golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
|
||||
golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200529172331-a64b76657301/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
@@ -159,14 +231,28 @@ google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ19
|
||||
google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d h1:DoPTO70H+bcDXcd39vOqb2viZxgqeBeSGtZ55yZU4/Q=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260819154853-08b0e4226688 h1:ax2KzoSRIZU/M0cIxri3pKxy99vniH1PVxWC6si/eZI=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260819154853-08b0e4226688/go.mod h1:1RJ9BQGyNdZwkGc1eTqkErfRZ6RJyYPHZo73BZ1vQqI=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688 h1:cYNAzI2sUwhmCcoj9TxvihSrqsxt6uIkj3rDRhSDmW4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260819154853-08b0e4226688/go.mod h1:DjtHYE8FKJLivXcBEjGwndXfIC23G0VpXiXKqG179uA=
|
||||
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
|
||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
|
||||
google.golang.org/grpc v1.83.1 h1:HIO0+BEtBP6soyqvqC8sNUjZ7bTs+0hFQuFF+RAy++Y=
|
||||
google.golang.org/grpc v1.83.1/go.mod h1:kDyl6SKsiHKt0uylY5gtn5cEjkrIOhQOGDgIc4JGwzQ=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
|
||||
google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/amz.v3 v3.0.0-20201001071545-24fc1eceb27b h1:tdSyAzD5FHJmZAZ13d5WexAo7YJkiyGphhzFfInMnDw=
|
||||
gopkg.in/amz.v3 v3.0.0-20201001071545-24fc1eceb27b/go.mod h1:cE0dCGx2UfBTjLFlzEx4EXJUmoX6BXBoX9GjKOvqha4=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
|
||||
@@ -2,4 +2,4 @@ package version
|
||||
|
||||
// Version is the tag of the latest release, it gets changed by the ci
|
||||
// process when a release is happening
|
||||
const Version = "v2.5.1" // x-release-please-version
|
||||
const Version = "v2.5.4" // x-release-please-version
|
||||
|
||||
@@ -44,12 +44,11 @@ func InitLogging(reqdebug bool, reqsyslog bool, reqstructlog bool) zerolog.Logge
|
||||
var logr zerolog.Logger
|
||||
if reqsyslog {
|
||||
s, err := syslog.New(syslog.LOG_INFO, "glauth")
|
||||
if err != nil {
|
||||
if err == nil {
|
||||
logr = zerolog.New(zerolog.SyslogLevelWriter(s)).Level(level).With().Timestamp().Logger()
|
||||
} else {
|
||||
fmt.Println("Unable to write to syslog: ignoring...")
|
||||
reqsyslog = false
|
||||
} else {
|
||||
writers := zerolog.MultiLevelWriter(mainWriter, zerolog.SyslogLevelWriter(s))
|
||||
logr = zerolog.New(writers).Level(level).With().Timestamp().Logger()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,14 +56,13 @@ func InitLogging(reqdebug bool, reqsyslog bool, reqstructlog bool) zerolog.Logge
|
||||
logr = zerolog.New(mainWriter).Level(level).With().Timestamp().Logger()
|
||||
}
|
||||
|
||||
log.SetOutput(customWriter{logr: logr, structlog: reqstructlog})
|
||||
log.SetOutput(customWriter{logr: logr})
|
||||
|
||||
return logr
|
||||
}
|
||||
|
||||
type customWriter struct {
|
||||
logr zerolog.Logger
|
||||
structlog bool
|
||||
logr zerolog.Logger
|
||||
}
|
||||
|
||||
func (e customWriter) Write(p []byte) (int, error) {
|
||||
@@ -76,10 +74,6 @@ func (e customWriter) Write(p []byte) (int, error) {
|
||||
if msg == "" {
|
||||
msg = strings.TrimSpace(string(p))
|
||||
}
|
||||
if e.structlog {
|
||||
fmt.Fprintf(os.Stderr, "{\"level\":\"info\",\"time\":\"%s\",\"message\":\"%s\"}\n", time.Now().Format(time.RFC1123Z), strings.Replace(strings.TrimSpace(msg), `"`, `\"`, -1))
|
||||
} else {
|
||||
e.logr.Info().Msg(msg)
|
||||
}
|
||||
e.logr.Info().Msg(msg)
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package logging
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
// customWriter adapts log output from libraries that emit unstructured text.
|
||||
// Everything it receives must go through the logger, so that it lands wherever
|
||||
// the logger points - notably syslog only, when syslog is enabled.
|
||||
func TestCustomWriterEmitsValidJSONThroughTheLogger(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
in string
|
||||
want string
|
||||
}{
|
||||
{"plain", "something happened", "something happened"},
|
||||
{"quotes", `bind for "cn=foo"`, `bind for "cn=foo"`},
|
||||
{"backslashes", `path C:\Users\x`, `path C:\Users\x`},
|
||||
{"control characters", "tab\there\nand a newline", "tab\there\nand a newline"},
|
||||
{
|
||||
"library timestamp prefix is stripped",
|
||||
"2026/09/13 16:50:54 connection closed",
|
||||
"connection closed",
|
||||
},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
w := customWriter{logr: zerolog.New(&buf).With().Timestamp().Logger()}
|
||||
|
||||
if _, err := w.Write([]byte(tc.in)); err != nil {
|
||||
t.Fatalf("Write: %v", err)
|
||||
}
|
||||
|
||||
// One record, one line: an unescaped newline would split this.
|
||||
if got := strings.Count(strings.TrimRight(buf.String(), "\n"), "\n"); got != 0 {
|
||||
t.Fatalf("expected a single log line, got %d extra newlines in %q", got, buf.String())
|
||||
}
|
||||
|
||||
var record struct {
|
||||
Level string `json:"level"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
if err := json.Unmarshal(buf.Bytes(), &record); err != nil {
|
||||
t.Fatalf("emitted invalid JSON (%v): %s", err, buf.String())
|
||||
}
|
||||
if record.Message != tc.want {
|
||||
t.Errorf("message = %q, want %q", record.Message, tc.want)
|
||||
}
|
||||
if record.Level != "info" {
|
||||
t.Errorf("level = %q, want %q", record.Level, "info")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@
|
||||
package logging
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
@@ -42,14 +41,13 @@ func InitLogging(reqdebug bool, reqsyslog bool, reqstructlog bool) zerolog.Logge
|
||||
|
||||
logr := zerolog.New(mainWriter).Level(level).With().Timestamp().Logger()
|
||||
|
||||
log.SetOutput(customWriter{logr: logr, structlog: reqstructlog})
|
||||
log.SetOutput(customWriter{logr: logr})
|
||||
|
||||
return logr
|
||||
}
|
||||
|
||||
type customWriter struct {
|
||||
logr zerolog.Logger
|
||||
structlog bool
|
||||
logr zerolog.Logger
|
||||
}
|
||||
|
||||
func (e customWriter) Write(p []byte) (int, error) {
|
||||
@@ -61,10 +59,6 @@ func (e customWriter) Write(p []byte) (int, error) {
|
||||
if msg == "" {
|
||||
msg = strings.TrimSpace(string(p))
|
||||
}
|
||||
if e.structlog {
|
||||
fmt.Fprintf(os.Stderr, "{\"level\":\"info\",\"time\":\"%s\",\"message\":\"%s\"}\n", time.Now().Format(time.RFC1123Z), strings.Replace(strings.TrimSpace(msg), `"`, `\"`, -1))
|
||||
} else {
|
||||
e.logr.Info().Msg(msg)
|
||||
}
|
||||
e.logr.Info().Msg(msg)
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
Submodule v2/pkg/plugins/glauth-mysql updated: 8e7354c160...37dae36d57
Submodule v2/pkg/plugins/glauth-pam updated: cfe63488a5...aed21903e1
Submodule v2/pkg/plugins/glauth-postgres updated: 013ae4c4de...81d4006ec2
Submodule v2/pkg/plugins/glauth-sqlite updated: f34a4dea13...fdfef39435
@@ -24,6 +24,22 @@ echo "Fixing CI_BUILD_DIR"
|
||||
|
||||
# This script requires that "$CI_BUILD_DIR" is set to the repo root
|
||||
|
||||
GOOS="$(go env GOOS)"
|
||||
GOARCH="$(go env GOARCH)"
|
||||
if [[ "$GOARCH" = "arm" ]]; then
|
||||
DIST_ARCH="arm-$(go env GOARM)"
|
||||
else
|
||||
DIST_ARCH="$GOARCH"
|
||||
fi
|
||||
GLAUTH_BINARY="$CI_BUILD_DIR/bin/$GOOS$GOARCH/glauth"
|
||||
if [[ ! -x "$GLAUTH_BINARY" ]]; then
|
||||
GLAUTH_BINARY="$CI_BUILD_DIR/bin/glauth-$GOOS-$DIST_ARCH"
|
||||
fi
|
||||
if [[ ! -x "$GLAUTH_BINARY" ]]; then
|
||||
echo "Unable to find a runnable GLAuth binary: $GLAUTH_BINARY"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Ensure ldap utils are installed (for example - when running this outside of CI)
|
||||
if [[ ! `which ldapsearch` ]]; then
|
||||
sudo apt-get -qq update && sudo apt-get -qq install -y ldap-utils || exit 1;
|
||||
@@ -33,11 +49,11 @@ fi
|
||||
echo "";
|
||||
echo ""
|
||||
echo "Version string of tested binary:"
|
||||
"$CI_BUILD_DIR/bin/$(go env GOOS)$(go env GOARCH)/glauth" --version
|
||||
"$GLAUTH_BINARY" --version
|
||||
echo ""
|
||||
|
||||
# Start in background, capture PID
|
||||
"$CI_BUILD_DIR/bin/$(go env GOOS)$(go env GOARCH)/glauth" -c "$CI_BUILD_DIR/scripts/ci/test-config.cfg" &> /dev/null &
|
||||
"$GLAUTH_BINARY" -c "$CI_BUILD_DIR/scripts/ci/test-config.cfg" &> /dev/null &
|
||||
|
||||
# Use this instead to see glauth logs while running
|
||||
# "$CI_BUILD_DIR/bin/$(go env GOOS)$(go env GOARCH)/glauth" -c "$CI_BUILD_DIR/scripts/ci/test-config.cfg" &
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
-- Seed data for TestSQLitePlugin. The schema itself is created by the plugin's
|
||||
-- CreateSchema() on first start, so this file only inserts rows.
|
||||
|
||||
INSERT INTO ldapgroups(name, gidnumber)
|
||||
VALUES('superheros', 5501);
|
||||
INSERT INTO ldapgroups(name, gidnumber)
|
||||
VALUES('svcaccts', 5502);
|
||||
INSERT INTO ldapgroups(name, gidnumber)
|
||||
VALUES('civilians', 5503);
|
||||
INSERT INTO ldapgroups(name, gidnumber)
|
||||
VALUES('caped', 5504);
|
||||
INSERT INTO ldapgroups(name, gidnumber)
|
||||
VALUES('lovesailing', 5505);
|
||||
INSERT INTO ldapgroups(name, gidnumber)
|
||||
VALUES('smoker', 5506);
|
||||
INSERT INTO includegroups(parentgroupid, includegroupid)
|
||||
VALUES(5503, 5501);
|
||||
INSERT INTO includegroups(parentgroupid, includegroupid)
|
||||
VALUES(5504, 5502);
|
||||
INSERT INTO includegroups(parentgroupid, includegroupid)
|
||||
VALUES(5504, 5501);
|
||||
INSERT INTO users(name, uidnumber, primarygroup, passsha256)
|
||||
VALUES('hackers', 5001, 5501,
|
||||
'6478579e37aff45f013e14eeb30b3cc56c72ccdc310123bcdf53e0333e3f416a');
|
||||
INSERT INTO users(name, uidnumber, primarygroup, passsha256)
|
||||
VALUES('johndoe', 5002, 5502,
|
||||
'6478579e37aff45f013e14eeb30b3cc56c72ccdc310123bcdf53e0333e3f416a');
|
||||
INSERT INTO users(name, mail, uidnumber, primarygroup, passsha256)
|
||||
VALUES('serviceuser', "serviceuser@example.com", 5003, 5502,
|
||||
'652c7dc687d98c9889304ed2e408c74b611e86a40caa51c4b43f1dd5913c5cd0');
|
||||
INSERT INTO users(name, uidnumber, primarygroup, passsha256, othergroups)
|
||||
VALUES('user4', 5004, 5504,
|
||||
'652c7dc687d98c9889304ed2e408c74b611e86a40caa51c4b43f1dd5913c5cd0',
|
||||
'5505,5506');
|
||||
INSERT INTO capabilities(userid, action, object)
|
||||
VALUES(5001, "search", "ou=superheros,dc=glauth,dc=com");
|
||||
INSERT INTO capabilities(userid, action, object)
|
||||
VALUES(5003, "search", "*");
|
||||
Reference in New Issue
Block a user