Skip to content

Commit

Permalink
Merge pull request #67 from chezmoi-sh/add-password-hash
Browse files Browse the repository at this point in the history
✨ (yaldap): Add password hash mecanism
  • Loading branch information
xunleii committed Feb 17, 2024
2 parents d0004b2 + 8e34a28 commit 4882214
Show file tree
Hide file tree
Showing 41 changed files with 490 additions and 84 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/merge_group,pull_request.all.lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5.0.0
with:
go-version: 1.21
- uses: golangci/golangci-lint-action@3cfe3a4abbb849e10058ce4af15d205b6da42804 # v4.0.0
with:
version: latest
args: --help # Just force the action to download the latest version of golangci-lint

- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: trunk-io/trunk-action@97ecd21fe6c743bf7a606791584b683a7995c70e # v1.1.9
2 changes: 2 additions & 0 deletions .github/workflows/merge_group,pull_request.go.test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ on:
- go.mod
- go.sum
- .github/workflows/pull_request,push.go.test.yaml
push:
branches: [main]

permissions: read-all

Expand Down
8 changes: 4 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ RUN set -eux; \
# └───────────────────────────────────────────────────────────────────────────┘
FROM docker.io/library/alpine:3.19.1

# renovate: datasource=github-tags depName=xunleii/yaldap versioning=semver
# renovate: datasource=github-tags depName=chezmoi-sh/yaldap versioning=semver
ARG YALDAP_VERSION="v0.1.2"

# renovate: datasource=repology depName=alpine_3_19/ca-certificates versioning=loose
Expand All @@ -47,7 +47,7 @@ ENV PATH=/opt/yaldap:${PATH}

USER yaldap
WORKDIR /opt/yaldap
ENTRYPOINT [ "yaldap" ]
ENTRYPOINT yaldap

EXPOSE 389
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
Expand All @@ -59,10 +59,10 @@ LABEL \
org.opencontainers.image.authors="xunleii <xunleii@users.noreply.github.com>" \
org.opencontainers.image.created="01/01/1970T00:00:00.000" \
org.opencontainers.image.description="Your identity, your rules." \
org.opencontainers.image.documentation="https://github.com/xunleii/yaldap" \
org.opencontainers.image.documentation="https://github.com/chezmoi-sh/yaldap" \
org.opencontainers.image.licenses="AGPL-3.0" \
org.opencontainers.image.revision="" \
org.opencontainers.image.source="" \
org.opencontainers.image.title="yaldap" \
org.opencontainers.image.url="https://github.com/xunleii/yaldap" \
org.opencontainers.image.url="https://github.com/chezmoi-sh/yaldap" \
org.opencontainers.image.version=${YALDAP_VERSION}
28 changes: 23 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

yaLDAP is an easy-to-use LDAP server using YAML file as directory definition.

![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/xunleii/yaldap)
[![Go](https://github.com/xunleii/yaldap/actions/workflows/pull_request,push.go.test.yaml/badge.svg)](https://github.com/xunleii/yaldap/actions/workflows/pull_request,push.go.test.yaml)
[![CodeQL](https://github.com/xunleii/yaldap/actions/workflows/pull_request,push,schedule.codeql.yaml/badge.svg)](https://github.com/xunleii/yaldap/actions/workflows/pull_request,push,schedule.codeql.yaml)
[![codecov](https://codecov.io/gh/xunleii/yaldap/branch/main/graph/badge.svg?token=20J4XPYH1H)](https://codecov.io/gh/xunleii/yaldap)
[![Go Report Card](https://goreportcard.com/badge/github.com/xunleii/yaldap)](https://goreportcard.com/report/github.com/xunleii/yaldap)
![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/chezmoi-sh/yaldap)
[![Test code (Go)](https://github.com/chezmoi-sh/yaldap/actions/workflows/merge_group,pull_request.go.test.yaml/badge.svg?event=push)](https://github.com/chezmoi-sh/yaldap/actions/workflows/merge_group,pull_request.go.test.yaml)
[![CodeQL](https://github.com/chezmoi-sh/yaldap/actions/workflows/pull_request,push,schedule.codeql.yaml/badge.svg)](https://github.com/chezmoi-sh/yaldap/actions/workflows/pull_request,push,schedule.codeql.yaml)
[![codecov](https://codecov.io/gh/chezmoi-sh/yaldap/branch/main/graph/badge.svg?token=20J4XPYH1H)](https://codecov.io/gh/chezmoi-sh/yaldap)
[![Go Report Card](https://goreportcard.com/badge/github.com/chezmoi-sh/yaldap)](https://goreportcard.com/report/github.com/chezmoi-sh/yaldap)

_Sometimes, we just need a simple LDAP compatible server to store user/group information and other information.
For this purpose, many simple LDAP server exists and manage user/group in a better way than yaLDAP. However, no one can
Expand Down Expand Up @@ -103,4 +103,22 @@ dc:org: #dn: dc=org
userPassword: eve
```

### Hashed passwords

In order to avoid storing clear text passwords in the YAML file, yaLDAP supports hashed passwords.
Currently, only `argon2`, `bcrypt`, `pbkdf2` and `scrypt` are supported.

#### How to hash a password

```sh
echo -n "<password>" | yaldap tools hash <alogrithm> [<options>] -
```

For example, to hash a password using `bcrypt` and a cost of 10:

```sh
$ echo -n "password" | yaldap tools hash bcrypt --rounds 10 -
$bcrypt$v=0$r=10$$243261243130247935525748646434736f52794a2e474f3162714856755331496c616e54384b4d387346494a746c6b3141776e7a6c36736f377a6471
```

## Contribution
22 changes: 17 additions & 5 deletions cmd/yaldap/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,38 @@ import (
"os"

"github.com/alecthomas/kong"
"github.com/xunleii/yaldap/pkg/cmd"
"github.com/chezmoi-sh/yaldap/pkg/cmd"
)

// yaLDAP represents the main application struct, interpretted by kong.
type yaLDAP struct {
cmd.Base `embed:""`

Server cmd.Server `cmd:"" name:"run" help:"Start the yaLDAP server"`
Tools cmd.Tools `cmd:"" name:"tools" help:"yaLDAP utilities"`
}

func main() {
var server cmd.Server
var yaldap yaLDAP

yaldap.Server.Base = &yaldap.Base
yaldap.Tools.Base = &yaldap.Base

// Parse command-line arguments using kong.
ctx := kong.Parse(
&server,
&yaldap,
kong.Name("yaldap"),
kong.Description(`
yaLDAP is an LDAP server that is backed by different read-only data sources,
such as YAML files. It is intended to be lightweight, secure and easy to configure.
See https://github.com/xunleii/yaldap for more information.
See https://github.com/chezmoi-sh/yaldap for more information.
`),
kong.UsageOnError(),
)

if err := ctx.Run(); err != nil {
server.Logger().Error(err.Error())
yaldap.Logger().Error(err.Error())
os.Exit(1)
}
}
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/xunleii/yaldap
module github.com/chezmoi-sh/yaldap

go 1.21

Expand All @@ -14,6 +14,7 @@ require (
github.com/prometheus/common v0.47.0
github.com/puzpuzpuz/xsync/v3 v3.0.2
github.com/stretchr/testify v1.8.4
go.pact.im/x/phcformat v0.0.6
golang.org/x/exp v0.0.0-20240205201215-2c58cdc269a3
golang.org/x/sync v0.3.0
gopkg.in/yaml.v3 v3.0.1
Expand All @@ -34,11 +35,13 @@ require (
github.com/prometheus/procfs v0.12.0 // indirect
github.com/shopspring/decimal v1.2.0 // indirect
github.com/spf13/cast v1.3.1 // indirect
go.pact.im/x/option v0.0.6 // indirect
google.golang.org/protobuf v1.32.0 // indirect
)

require (
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
github.com/aldy505/phc-crypto v1.2.0
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.16.0 // indirect
github.com/google/uuid v1.6.0 // indirect
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7Y
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
github.com/aldy505/phc-crypto v1.2.0 h1:IbovWYUDUqqqI1wva9U2+sMJ4HABK5L32pScoJw2tc4=
github.com/aldy505/phc-crypto v1.2.0/go.mod h1:tpy0uE4Cqb7I6LUO7BLihCdX56MxvZylsZ1LIzuRw0M=
github.com/alecthomas/assert/v2 v2.1.0 h1:tbredtNcQnoSd3QBhQWI7QZ3XHOVkw1Moklp2ojoH/0=
github.com/alecthomas/assert/v2 v2.1.0/go.mod h1:b/+1DI2Q6NckYi+3mXyH3wFb8qG37K/DuK80n7WefXA=
github.com/alecthomas/kong v0.8.1 h1:acZdn3m4lLRobeh3Zi2S2EpnXTd1mOL6U7xVml+vfkY=
Expand Down Expand Up @@ -100,6 +102,10 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.pact.im/x/option v0.0.6 h1:8lam/SPqUxr/AhQV8S6pNs+2npB+Fcwgmfwqea6vrik=
go.pact.im/x/option v0.0.6/go.mod h1:mpzKc/UIz4m3X4/47trnsCXP15YoUJsAcSZTiqTkmqA=
go.pact.im/x/phcformat v0.0.6 h1:1Vww+WEVbTTxyr+SLSsHaI3zCYwOe7KmY/8RRZ4RVgU=
go.pact.im/x/phcformat v0.0.6/go.mod h1:q+HHj0v7P1fA3WObC9Ts7YvAm21Jmviw+Kep/DlJjRc=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
Expand Down
2 changes: 1 addition & 1 deletion internal/ldap/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"sync"
"time"

ldap "github.com/chezmoi-sh/yaldap/pkg/ldap/directory"
xsync "github.com/puzpuzpuz/xsync/v3"
ldap "github.com/xunleii/yaldap/pkg/ldap/directory"
)

type (
Expand Down
4 changes: 2 additions & 2 deletions internal/ldap/auth/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ import (
"testing"
"time"

ldap "github.com/chezmoi-sh/yaldap/pkg/ldap/directory"
"github.com/jimlambrt/gldap"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
ldap "github.com/xunleii/yaldap/pkg/ldap/directory"
)

type mockLDAPObject map[string][]string

func (o mockLDAPObject) DN() string { return "" }
func (o mockLDAPObject) Attributes() ldap.Attributes { return ldap.Attributes(o) }
func (o mockLDAPObject) Search(gldap.Scope, string) ([]ldap.Object, error) { return nil, nil }
func (o mockLDAPObject) Bind(string) bool { return false }
func (o mockLDAPObject) Bind(string) (bool, error) { return false, nil }
func (o mockLDAPObject) CanSearchOn(string) bool { return true }

func TestSessions_NewSession(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"slices"

"github.com/alecthomas/kong"
"github.com/chezmoi-sh/yaldap/pkg/utils"
"github.com/prometheus/common/version"
"github.com/xunleii/yaldap/pkg/utils"
)

type (
Expand Down
4 changes: 2 additions & 2 deletions pkg/cmd/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import (
"testing"

"github.com/alecthomas/kong"
"github.com/chezmoi-sh/yaldap/pkg/cmd"
"github.com/chezmoi-sh/yaldap/pkg/utils"
"github.com/stretchr/testify/assert"
"github.com/xunleii/yaldap/pkg/cmd"
"github.com/xunleii/yaldap/pkg/utils"
)

func TestLogger_Format(t *testing.T) {
Expand Down
12 changes: 6 additions & 6 deletions pkg/cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ import (
"time"

"github.com/alecthomas/kong"
"github.com/chezmoi-sh/yaldap/internal/ldap/auth"
"github.com/chezmoi-sh/yaldap/pkg/ldap"
"github.com/chezmoi-sh/yaldap/pkg/ldap/directory"
yamldir "github.com/chezmoi-sh/yaldap/pkg/ldap/directory/yaml"
"github.com/chezmoi-sh/yaldap/pkg/utils"
"github.com/jimlambrt/gldap"
"github.com/xunleii/yaldap/internal/ldap/auth"
"github.com/xunleii/yaldap/pkg/ldap"
"github.com/xunleii/yaldap/pkg/ldap/directory"
yamldir "github.com/xunleii/yaldap/pkg/ldap/directory/yaml"
"github.com/xunleii/yaldap/pkg/utils"
"golang.org/x/sync/errgroup"
)

type Server struct {
Base `embed:""`
*Base `kong:"-"`

ListenAddr string `name:"listen-address" help:"Address to listen on" default:":389"`

Expand Down
9 changes: 6 additions & 3 deletions pkg/cmd/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package cmd
import (
"crypto/tls"
"fmt"
"log/slog"
"net"
"os"
"testing"
Expand All @@ -18,9 +17,10 @@ import (

func TestServer_Defaults(t *testing.T) {
var actual, expected Server
actual.Base = &Base{}
expected.Base = &Base{}

expected.ListenAddr = ":389"
expected.Base.Log.Format = "json"
expected.Base.Log.Level = LogLevel(slog.LevelInfo)
expected.Backend.Name = "yaml"
expected.Backend.URL = "file://../ldap/directory/yaml/fixtures/basic.yaml" //nolint:goconst
expected.SessionTTL = 168 * time.Hour
Expand All @@ -34,6 +34,7 @@ func TestServer_Defaults(t *testing.T) {

func TestServer_YAML_Simple(t *testing.T) {
server := Server{ListenAddr: fmt.Sprintf("localhost:%d", freePort(t))}
server.Base = &Base{}
server.Base.Log.Format = "test"
server.Backend.Name = "yaml"
server.Backend.URL = "file://../ldap/directory/yaml/fixtures/basic.yaml"
Expand Down Expand Up @@ -63,6 +64,7 @@ func TestServer_YAML_WithTLS(t *testing.T) {
require.NoError(t, err)

server := Server{ListenAddr: fmt.Sprintf("localhost:%d", freePort(t))}
server.Base = &Base{}
server.Base.Log.Format = "test"
server.Backend.Name = "yaml"
server.Backend.URL = "file://../ldap/directory/yaml/fixtures/basic.yaml"
Expand Down Expand Up @@ -98,6 +100,7 @@ func TestServer_YAML_WithMutualTLS(t *testing.T) {
require.NoError(t, err)

server := Server{ListenAddr: fmt.Sprintf("localhost:%d", freePort(t))}
server.Base = &Base{}
server.Base.Log.Format = "test"
server.Backend.Name = "yaml"
server.Backend.URL = "file://../ldap/directory/yaml/fixtures/basic.yaml"
Expand Down

0 comments on commit 4882214

Please sign in to comment.