forked from Deuxfleurs/bottin
Compare commits
9 commits
Author | SHA1 | Date | |
---|---|---|---|
1d338a9cc1 | |||
e9bf550e02 | |||
55ef7530ae | |||
a2be316d91 | |||
9cab98d2ce | |||
de71260bbf | |||
0ef8313a67 | |||
|
9ce0d22c99 | ||
|
f05e41c9aa |
14 changed files with 465 additions and 44 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -2,3 +2,5 @@ bottin
|
|||
bottin.static
|
||||
config.json
|
||||
test/test
|
||||
result
|
||||
ldap.json
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
---
|
||||
kind: pipeline
|
||||
name: bottin
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: golang:stretch
|
||||
|
@ -12,14 +8,8 @@ steps:
|
|||
- go test -i -c -o test
|
||||
|
||||
- name: test_bottin
|
||||
image: consul:latest
|
||||
image: consul:1.15.4
|
||||
environment:
|
||||
BOTTIN_DEFAULT_ADMIN_PW: priZ4Cg0x5NkSyiIN/MpvWw4ZEy8f8s1
|
||||
commands:
|
||||
- ash test/runner.sh
|
||||
|
||||
---
|
||||
kind: signature
|
||||
hmac: ff246a04c3df8a2f39c8b446dea920622d61950e6caaac886931bdb05d0706ed
|
||||
|
||||
...
|
|
@ -1,5 +0,0 @@
|
|||
FROM scratch
|
||||
|
||||
ADD bottin.static /bottin
|
||||
|
||||
ENTRYPOINT ["/bottin"]
|
15
README.md
15
README.md
|
@ -1,6 +1,6 @@
|
|||
# Bottin
|
||||
|
||||
[![Build Status](https://drone.deuxfleurs.fr/api/badges/Deuxfleurs/bottin/status.svg?ref=refs/heads/main)](https://drone.deuxfleurs.fr/Deuxfleurs/bottin)
|
||||
[![status-badge](https://woodpecker.deuxfleurs.fr/api/badges/38/status.svg)](https://woodpecker.deuxfleurs.fr/repos/38)
|
||||
|
||||
<img src="https://git.deuxfleurs.fr/Deuxfleurs/bottin/raw/branch/main/bottin.png" style="height: 150px; display: block; margin-left: auto; margin-right: auto" />
|
||||
|
||||
|
@ -24,7 +24,7 @@ Features:
|
|||
- Access control through an ACL (hardcoded in the configuration file)
|
||||
|
||||
|
||||
A Docker image is provided on the [Docker hub](https://hub.docker.com/r/lxpz/bottin_amd64).
|
||||
A Docker image is provided on the [Docker hub](https://hub.docker.com/r/dxflrs/bottin) (built in `default.nix`).
|
||||
An example for running Bottin on a Nomad cluster can be found in `bottin.hcl.example`.
|
||||
|
||||
Bottin takes a single command line argument, `-config <filename>`, which is the
|
||||
|
@ -44,6 +44,17 @@ Bottin requires go 1.13 or later.
|
|||
To build Bottin, clone this repository outside of your `$GOPATH`.
|
||||
Then, run `make` in the root of the repo.
|
||||
|
||||
## Releasing
|
||||
|
||||
```bash
|
||||
nix-build -A bin
|
||||
nix-build -A docker
|
||||
```
|
||||
|
||||
```bash
|
||||
docker load < $(nix-build -A docker)
|
||||
docker push dxflrs/bottin:???
|
||||
```
|
||||
|
||||
## Server initialization
|
||||
|
||||
|
|
55
default.nix
Normal file
55
default.nix
Normal file
|
@ -0,0 +1,55 @@
|
|||
let
|
||||
pkgsSrc = fetchTarball {
|
||||
# As of 2022-07-19
|
||||
url = "https://github.com/NixOS/nixpkgs/archive/d2db10786f27619d5519b12b03fb10dc8ca95e59.tar.gz";
|
||||
sha256 = "0s9gigs3ylnq5b94rfcmxvrmmr3kzhs497gksajf638d5bv7zcl5";
|
||||
};
|
||||
gomod2nix = fetchGit {
|
||||
url = "https://github.com/tweag/gomod2nix.git";
|
||||
ref = "master";
|
||||
rev = "40d32f82fc60d66402eb0972e6e368aeab3faf58";
|
||||
};
|
||||
|
||||
pkgs = import pkgsSrc {
|
||||
overlays = [
|
||||
(self: super: {
|
||||
gomod = super.callPackage "${gomod2nix}/builder/" { };
|
||||
})
|
||||
];
|
||||
};
|
||||
in rec {
|
||||
bin = pkgs.gomod.buildGoApplication {
|
||||
pname = "bottin-bin";
|
||||
version = "0.1.0";
|
||||
src = builtins.filterSource
|
||||
(path: type: (builtins.match ".*/test/.*\\.(go|sum|mod)" path) == null)
|
||||
./.;
|
||||
modules = ./gomod2nix.toml;
|
||||
|
||||
CGO_ENABLED=0;
|
||||
|
||||
meta = with pkgs.lib; {
|
||||
description = "A cloud-native LDAP server backed by a Consul datastore";
|
||||
homepage = "https://git.deuxfleurs.fr/Deuxfleurs/bottin";
|
||||
license = licenses.gpl3Plus;
|
||||
platforms = platforms.linux;
|
||||
};
|
||||
};
|
||||
pkg = pkgs.stdenv.mkDerivation {
|
||||
pname = "bottin";
|
||||
version = "0.1.0";
|
||||
unpackPhase = "true";
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/
|
||||
cp ${bin}/bin/bottin $out/bottin
|
||||
'';
|
||||
};
|
||||
docker = pkgs.dockerTools.buildImage {
|
||||
name = "dxflrs/bottin";
|
||||
config = {
|
||||
Entrypoint = [ "${pkg}/bottin" ];
|
||||
WorkingDir = "/";
|
||||
};
|
||||
};
|
||||
}
|
79
flake.lock
Normal file
79
flake.lock
Normal file
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"nodes": {
|
||||
"gomod2nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs",
|
||||
"utils": "utils"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1655245309,
|
||||
"narHash": "sha256-d/YPoQ/vFn1+GTmSdvbSBSTOai61FONxB4+Lt6w/IVI=",
|
||||
"owner": "tweag",
|
||||
"repo": "gomod2nix",
|
||||
"rev": "40d32f82fc60d66402eb0972e6e368aeab3faf58",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "tweag",
|
||||
"repo": "gomod2nix",
|
||||
"rev": "40d32f82fc60d66402eb0972e6e368aeab3faf58",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1653581809,
|
||||
"narHash": "sha256-Uvka0V5MTGbeOfWte25+tfRL3moECDh1VwokWSZUdoY=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "83658b28fe638a170a19b8933aa008b30640fbd1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1669764884,
|
||||
"narHash": "sha256-1qWR/5+WtqxSedrFbUbM3zPMO7Ec2CGWaxtK4z4DdvY=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "0244e143dc943bcf661fdaf581f01eb0f5000fcf",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "0244e143dc943bcf661fdaf581f01eb0f5000fcf",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"gomod2nix": "gomod2nix",
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
}
|
||||
},
|
||||
"utils": {
|
||||
"locked": {
|
||||
"lastModified": 1653893745,
|
||||
"narHash": "sha256-0jntwV3Z8//YwuOjzhV2sgJJPt+HY6KhU7VZUL0fKZQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "1ed9fb1935d260de5fe1c2f7ee0ebaae17ed2fa1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
39
flake.nix
Normal file
39
flake.nix
Normal file
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
description = "A cloud-native LDAP server backed by a Consul datastore";
|
||||
|
||||
inputs.nixpkgs.url = "github:nixos/nixpkgs/0244e143dc943bcf661fdaf581f01eb0f5000fcf";
|
||||
inputs.gomod2nix.url = "github:tweag/gomod2nix/40d32f82fc60d66402eb0972e6e368aeab3faf58";
|
||||
|
||||
outputs = { self, nixpkgs, gomod2nix }:
|
||||
let
|
||||
pkgs = import nixpkgs {
|
||||
system = "x86_64-linux";
|
||||
overlays = [
|
||||
(self: super: {
|
||||
gomod = super.callPackage "${gomod2nix}/builder/" { };
|
||||
})
|
||||
];
|
||||
};
|
||||
bottin = pkgs.gomod.buildGoApplication {
|
||||
pname = "bottin";
|
||||
version = "0.1.0";
|
||||
src = builtins.filterSource
|
||||
(path: type: (builtins.match ".*/test/.*\\.(go|sum|mod)" path) == null)
|
||||
./.;
|
||||
modules = ./gomod2nix.toml;
|
||||
|
||||
CGO_ENABLED=0;
|
||||
|
||||
meta = with pkgs.lib; {
|
||||
description = "A cloud-native LDAP server backed by a Consul datastore";
|
||||
homepage = "https://git.deuxfleurs.fr/Deuxfleurs/bottin";
|
||||
license = licenses.gpl3Plus;
|
||||
platforms = platforms.linux;
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
packages.x86_64-linux.bottin = bottin;
|
||||
packages.x86_64-linux.default = self.packages.x86_64-linux.bottin;
|
||||
};
|
||||
}
|
2
go.mod
2
go.mod
|
@ -3,9 +3,9 @@ module bottin
|
|||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/go-ldap/ldap/v3 v3.3.0
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/hashicorp/consul/api v1.3.0
|
||||
github.com/jsimonetti/pwscheme v0.0.0-20220125093853-4d9895f5db73
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 // indirect
|
||||
)
|
||||
|
|
10
go.sum
10
go.sum
|
@ -1,5 +1,3 @@
|
|||
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
|
@ -9,11 +7,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||
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/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.1 h1:pDbRAunXzIUXfx4CB2QJFv5IuPiuoW+sWvr/Us009o8=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||
github.com/go-ldap/ldap v2.5.1+incompatible h1:Opaoft5zMW8IU/VRULB0eGMBQ9P5buRvCW6sFTRmMn8=
|
||||
github.com/go-ldap/ldap/v3 v3.3.0 h1:lwx+SJpgOHd8tG6SumBQZXCmNX51zM8B1cfxJ5gv4tQ=
|
||||
github.com/go-ldap/ldap/v3 v3.3.0/go.mod h1:iYS1MdmrmceOJ1QOTnRXrIs7i3kloqtmGQjRvjKpyMg=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
|
@ -49,6 +42,8 @@ github.com/hashicorp/memberlist v0.1.3 h1:EmmoJme1matNzb+hMpDuR/0sbJSUisxyqBGG67
|
|||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/jsimonetti/pwscheme v0.0.0-20220125093853-4d9895f5db73 h1:ZhC4QngptYaGx53+ph1RjxcH8fkCozBaY+935TNX4i8=
|
||||
github.com/jsimonetti/pwscheme v0.0.0-20220125093853-4d9895f5db73/go.mod h1:t0Q9JvoMTfTYdAWIk2MF69iz+Qpdk9D+PgVu6fVmaDI=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
|
@ -88,6 +83,7 @@ golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 h1:vEg9joUBmeBcK9iSJftGNf
|
|||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
|
153
gomod2nix.toml
Normal file
153
gomod2nix.toml
Normal file
|
@ -0,0 +1,153 @@
|
|||
schema = 3
|
||||
|
||||
[mod]
|
||||
[mod."github.com/armon/circbuf"]
|
||||
version = "v0.0.0-20150827004946-bbbad097214e"
|
||||
hash = "sha256-klQjllsJZqZ2KPNx1mZT9XP+UAJkuBhmTnZdNlAflEM="
|
||||
[mod."github.com/armon/go-metrics"]
|
||||
version = "v0.0.0-20180917152333-f0300d1749da"
|
||||
hash = "sha256-+zqX1hlJgc+IrXRzBQDMhR8GYQdc0Oj6PiIDfctgh44="
|
||||
[mod."github.com/armon/go-radix"]
|
||||
version = "v0.0.0-20180808171621-7fddfc383310"
|
||||
hash = "sha256-ZHU4pyBqHHRuQJuYr2K+LqeAnLX9peX07cmSYK+GDHk="
|
||||
[mod."github.com/bgentry/speakeasy"]
|
||||
version = "v0.1.0"
|
||||
hash = "sha256-Gt1vj6CFovLnO6wX5u2O4UfecY9V2J9WGw1ez4HMrgk="
|
||||
[mod."github.com/davecgh/go-spew"]
|
||||
version = "v1.1.1"
|
||||
hash = "sha256-nhzSUrE1fCkN0+RL04N4h8jWmRFPPPWbCuDc7Ss0akI="
|
||||
[mod."github.com/fatih/color"]
|
||||
version = "v1.7.0"
|
||||
hash = "sha256-4In7ef7it7d+6oGUJ3pkD0V+lsL40hVtYdy2KD2ovn0="
|
||||
[mod."github.com/google/btree"]
|
||||
version = "v0.0.0-20180813153112-4030bb1f1f0c"
|
||||
hash = "sha256-5gr0RMnlvrzCke3kwpkf92WvW3x5nnKZesoulyoYRC0="
|
||||
[mod."github.com/google/uuid"]
|
||||
version = "v1.1.1"
|
||||
hash = "sha256-66PXC/RCPUyhS9PhkIPQFR3tbM2zZYDNPGXN7JJj3UE="
|
||||
[mod."github.com/hashicorp/consul/api"]
|
||||
version = "v1.3.0"
|
||||
hash = "sha256-fMORNFAWK2GkRbBl/KzNHrvtCfwz/7P66HzDaE4GnuE="
|
||||
[mod."github.com/hashicorp/consul/sdk"]
|
||||
version = "v0.3.0"
|
||||
hash = "sha256-lF47JPGfmeGjpuQw9VSNs2Mi+G7FQLKrrHteX3iXfpU="
|
||||
[mod."github.com/hashicorp/errwrap"]
|
||||
version = "v1.0.0"
|
||||
hash = "sha256-LGSLrefkABG1kH1i+GUWiD2/ggJxiZEJ+D2YNbhZjmo="
|
||||
[mod."github.com/hashicorp/go-cleanhttp"]
|
||||
version = "v0.5.1"
|
||||
hash = "sha256-c54zcHr9THj3MQk7hrDQcpjOcQi1MvXZ4Kpin6EbfR4="
|
||||
[mod."github.com/hashicorp/go-immutable-radix"]
|
||||
version = "v1.0.0"
|
||||
hash = "sha256-JmNxdGaJG63Ty/sVnPjqvTyA4/k5wkzZ/QvpMK2uduw="
|
||||
[mod."github.com/hashicorp/go-msgpack"]
|
||||
version = "v0.5.3"
|
||||
hash = "sha256-2OUYjD/Jt12TFBrtH0wRqg+lzRljDxSIhk2CqBLUczo="
|
||||
[mod."github.com/hashicorp/go-multierror"]
|
||||
version = "v1.0.0"
|
||||
hash = "sha256-iXzjerl96o7QDiSwQjbak8R/t+YzZeoUqm59TCmy3gI="
|
||||
[mod."github.com/hashicorp/go-rootcerts"]
|
||||
version = "v1.0.0"
|
||||
hash = "sha256-4NZJAT5/vocyto+dv6FmW4kFiYldmNvewowsYK/LiTI="
|
||||
[mod."github.com/hashicorp/go-sockaddr"]
|
||||
version = "v1.0.0"
|
||||
hash = "sha256-orG+SHVsp5lgNRCErmhMLABVFQ3ZWfYIJ/4LTFzlvao="
|
||||
[mod."github.com/hashicorp/go-syslog"]
|
||||
version = "v1.0.0"
|
||||
hash = "sha256-YRuq6oPMwAFVY7mvwpMDvZqGwNnb5CjBYyKI/x5mbCc="
|
||||
[mod."github.com/hashicorp/go-uuid"]
|
||||
version = "v1.0.1"
|
||||
hash = "sha256-s1wIvBu37z4U3qK9sdUR1CtbD39N6RwfX4HgDCpCa0s="
|
||||
[mod."github.com/hashicorp/go.net"]
|
||||
version = "v0.0.1"
|
||||
hash = "sha256-JKal3E+wPO+Hk838opKV4HHKB4O72Xy+77ncXlLkWRk="
|
||||
[mod."github.com/hashicorp/golang-lru"]
|
||||
version = "v0.5.0"
|
||||
hash = "sha256-Lo0UyOZQ89iK0Ui3Hfk5VkWqxEzLw6Lclq4EM8VlYoo="
|
||||
[mod."github.com/hashicorp/logutils"]
|
||||
version = "v1.0.0"
|
||||
hash = "sha256-e8t8Dm8sp/PzKClN1TOmFcrTAWNh4mZHSW7cAjVx3Bw="
|
||||
[mod."github.com/hashicorp/mdns"]
|
||||
version = "v1.0.0"
|
||||
hash = "sha256-ravx4tklQG43OEjPiJn68iJM9ODZ6hgU0idFCEOiJGM="
|
||||
[mod."github.com/hashicorp/memberlist"]
|
||||
version = "v0.1.3"
|
||||
hash = "sha256-IsxqevYulPt+2VGtlq068Jyq1YfIk4Ohh9TgakIGxnc="
|
||||
[mod."github.com/hashicorp/serf"]
|
||||
version = "v0.8.2"
|
||||
hash = "sha256-diRxWOouFLTO75f2E9NlrKgie/qsT+gOOrrbf4tACHw="
|
||||
[mod."github.com/jsimonetti/pwscheme"]
|
||||
version = "v0.0.0-20220125093853-4d9895f5db73"
|
||||
hash = "sha256-YF3RKU/4CWvLPgGzUd7Hk/2+41OUFuRWZgzQuqcsKg0="
|
||||
[mod."github.com/konsorten/go-windows-terminal-sequences"]
|
||||
version = "v1.0.1"
|
||||
hash = "sha256-Nwp+Cza9dIu3ogVGip6wyOjWwwaq+2hU3eYIe4R7kNE="
|
||||
[mod."github.com/mattn/go-colorable"]
|
||||
version = "v0.0.9"
|
||||
hash = "sha256-fVPF8VxbdggLAZnaexMl6Id1WjXKImzVySxKfa+ukts="
|
||||
[mod."github.com/mattn/go-isatty"]
|
||||
version = "v0.0.3"
|
||||
hash = "sha256-9ogEEd8/kl/dImldzdBmTFdepvB0dVXEzN4o8bEqhBs="
|
||||
[mod."github.com/miekg/dns"]
|
||||
version = "v1.0.14"
|
||||
hash = "sha256-OeijUgBaEmDapclTxfvjIqrjh4qZu3+DQpHelGGI4aA="
|
||||
[mod."github.com/mitchellh/cli"]
|
||||
version = "v1.0.0"
|
||||
hash = "sha256-4nG7AhRcjTRCwUCdnaNaFrAKDxEEoiihaCA4lk+uM8U="
|
||||
[mod."github.com/mitchellh/go-homedir"]
|
||||
version = "v1.0.0"
|
||||
hash = "sha256-eGmBNNTuDSMwicjTNgB54IEJuK1tgOLDJ3NHTpQCHzg="
|
||||
[mod."github.com/mitchellh/go-testing-interface"]
|
||||
version = "v1.0.0"
|
||||
hash = "sha256-/Dpv/4i5xuK8hDH+q8YTdF6Jg6NNtfO4Wqig2JCWgrY="
|
||||
[mod."github.com/mitchellh/gox"]
|
||||
version = "v0.4.0"
|
||||
hash = "sha256-GV3LYxzJt8YVbnSac2orlj2QR3MX/YIDrLkSkPhsjuA="
|
||||
[mod."github.com/mitchellh/iochan"]
|
||||
version = "v1.0.0"
|
||||
hash = "sha256-b5Tp7cw/e8mL++IjsebbmKWXtb9Hrzu4Fc6M4tZKFhU="
|
||||
[mod."github.com/mitchellh/mapstructure"]
|
||||
version = "v1.1.2"
|
||||
hash = "sha256-OU9HZYHtl0qaqMFd84w7snkkRuRY6UMSsfCnL5HYdw0="
|
||||
[mod."github.com/pascaldekloe/goe"]
|
||||
version = "v0.0.0-20180627143212-57f6aae5913c"
|
||||
hash = "sha256-2KUjqrEC/BwkTZRxImazcI/C3H7QmXfNrlt8slwdDbc="
|
||||
[mod."github.com/pkg/errors"]
|
||||
version = "v0.8.1"
|
||||
hash = "sha256-oe3iddfoLRwpC3ki5fifHf2ZFprtg99iNak50shiuDw="
|
||||
[mod."github.com/pmezard/go-difflib"]
|
||||
version = "v1.0.0"
|
||||
hash = "sha256-/FtmHnaGjdvEIKAJtrUfEhV7EVo5A/eYrtdnUkuxLDA="
|
||||
[mod."github.com/posener/complete"]
|
||||
version = "v1.1.1"
|
||||
hash = "sha256-heyPMSBzVlx7ZKgTyzl/xmUfZw3EZCcvGFGrRMIbIr8="
|
||||
[mod."github.com/ryanuber/columnize"]
|
||||
version = "v0.0.0-20160712163229-9b3edd62028f"
|
||||
hash = "sha256-RLUQcU6Z03upKe08v6rjn9/tkyrQsgmpdEmBtWaLQfk="
|
||||
[mod."github.com/sean-/seed"]
|
||||
version = "v0.0.0-20170313163322-e2103e2c3529"
|
||||
hash = "sha256-RQQTjvf8Y91jP5FGOyEnGMFw7zCrcSnUU4eH2CXKkT4="
|
||||
[mod."github.com/sirupsen/logrus"]
|
||||
version = "v1.4.2"
|
||||
hash = "sha256-3QzWUsapCmg3F7JqUuINT3/UG097uzLff6iCcCgQ43o="
|
||||
[mod."github.com/stretchr/objx"]
|
||||
version = "v0.1.1"
|
||||
hash = "sha256-HdGVZCuy7VprC5W9UxGbDmXqsKADMjpEDht7ilGVLco="
|
||||
[mod."github.com/stretchr/testify"]
|
||||
version = "v1.3.0"
|
||||
hash = "sha256-+mSebBNccNcxbY462iKTNTWmd5ZuUkUqFebccn3EtIA="
|
||||
[mod."golang.org/x/crypto"]
|
||||
version = "v0.0.0-20200604202706-70a84ac30bf9"
|
||||
hash = "sha256-I5ov2lV6ubB3H3pn6DFN1VPLyxeLfPUaOx2PJ9K1KH8="
|
||||
[mod."golang.org/x/net"]
|
||||
version = "v0.0.0-20190404232315-eb5bcb51f2a3"
|
||||
hash = "sha256-kwP+BDfPsZEeeceyg4H5LgdTDT8O8YWbkpCkpyuPJJo="
|
||||
[mod."golang.org/x/sync"]
|
||||
version = "v0.0.0-20181221193216-37e7f081c4d4"
|
||||
hash = "sha256-FUpv9bmGLDEjCxXdvR0CRDqOKRY0xrHRPzOsyQyvYK0="
|
||||
[mod."golang.org/x/sys"]
|
||||
version = "v0.0.0-20190422165155-953cdadca894"
|
||||
hash = "sha256-YkQjSZaiVFxrmXYSKmqrGeIO3RZ95fc3dWyCaR+SosY="
|
||||
[mod."golang.org/x/text"]
|
||||
version = "v0.3.0"
|
||||
hash = "sha256-0FFbaxF1ZuAQF3sCcA85e8MO6prFeHint36inija4NY="
|
37
main.go
37
main.go
|
@ -12,8 +12,8 @@ import (
|
|||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
ldap "bottin/ldapserver"
|
||||
message "bottin/goldap"
|
||||
ldap "bottin/ldapserver"
|
||||
|
||||
consul "github.com/hashicorp/consul/api"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
@ -320,7 +320,6 @@ func (server *Server) init() error {
|
|||
return err
|
||||
}
|
||||
|
||||
|
||||
admin_pass_str, environnement_variable_exist := os.LookupEnv("BOTTIN_DEFAULT_ADMIN_PW")
|
||||
if !environnement_variable_exist {
|
||||
admin_pass := make([]byte, 8)
|
||||
|
@ -333,7 +332,11 @@ func (server *Server) init() error {
|
|||
server.logger.Debug("BOTTIN_DEFAULT_ADMIN_PW environment variable is set, using it for admin's password")
|
||||
}
|
||||
|
||||
admin_pass_hash := SSHAEncode([]byte(admin_pass_str))
|
||||
admin_pass_hash, err := SSHAEncode(admin_pass_str)
|
||||
if err != nil {
|
||||
server.logger.Error("can't create admin password")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
admin_dn := "cn=admin," + server.config.Suffix
|
||||
admin_attributes := Entry{
|
||||
|
@ -434,8 +437,8 @@ func (server *Server) handleBindInternal(state *State, r *message.BindRequest) (
|
|||
}
|
||||
|
||||
for _, hash := range passwd {
|
||||
valid := SSHAMatches(hash, []byte(r.AuthenticationSimple()))
|
||||
if valid {
|
||||
valid, err := SSHAMatches(hash, string(r.AuthenticationSimple()))
|
||||
if valid && err == nil {
|
||||
groups, err := server.getAttribute(string(r.Name()), ATTR_MEMBEROF)
|
||||
if err != nil {
|
||||
return ldap.LDAPResultOperationsError, err
|
||||
|
@ -444,8 +447,32 @@ func (server *Server) handleBindInternal(state *State, r *message.BindRequest) (
|
|||
user: string(r.Name()),
|
||||
groups: groups,
|
||||
}
|
||||
|
||||
updatePasswordHash(string(r.AuthenticationSimple()), hash, server, string(r.Name()))
|
||||
|
||||
return ldap.LDAPResultSuccess, nil
|
||||
} else {
|
||||
return ldap.LDAPResultInvalidCredentials, fmt.Errorf("can't authenticate: %w", err)
|
||||
}
|
||||
}
|
||||
return ldap.LDAPResultInvalidCredentials, fmt.Errorf("No password match")
|
||||
}
|
||||
|
||||
// Update the hash if it's not already SSHA512
|
||||
func updatePasswordHash(password string, currentHash string, server *Server, dn string) {
|
||||
hashType, err := determineHashType(currentHash)
|
||||
if err != nil {
|
||||
server.logger.Errorf("can't determine hash type of password")
|
||||
return
|
||||
}
|
||||
if hashType != SSHA512 {
|
||||
reencodedPassword, err := SSHAEncode(password)
|
||||
if err != nil {
|
||||
server.logger.Errorf("can't encode password")
|
||||
return
|
||||
}
|
||||
server.putAttributes(dn, Entry{
|
||||
ATTR_USERPASSWORD: []string{reencodedPassword},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
5
read.go
5
read.go
|
@ -213,10 +213,11 @@ func (server *Server) handleSearchInternal(state *State, w ldap.ResponseWriter,
|
|||
continue
|
||||
}
|
||||
// Send result
|
||||
resultVals := []message.AttributeValue{}
|
||||
for _, v := range val {
|
||||
e.AddAttribute(message.AttributeDescription(attr),
|
||||
message.AttributeValue(v))
|
||||
resultVals = append(resultVals, message.AttributeValue(v))
|
||||
}
|
||||
e.AddAttribute(message.AttributeDescription(attr), resultVals...)
|
||||
}
|
||||
w.Write(e)
|
||||
}
|
||||
|
|
70
ssha.go
70
ssha.go
|
@ -1,25 +1,79 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
//"github.com/jsimonetti/pwscheme/ssha"
|
||||
"github.com/jsimonetti/pwscheme/ssha256"
|
||||
"github.com/jsimonetti/pwscheme/ssha512"
|
||||
)
|
||||
|
||||
const (
|
||||
SSHA = "{SSHA}"
|
||||
SSHA256 = "{SSHA256}"
|
||||
SSHA512 = "{SSHA512}"
|
||||
)
|
||||
|
||||
// Encode encodes the string to ssha512
|
||||
func SSHAEncode(rawPassPhrase string) (string, error) {
|
||||
return ssha512.Generate(rawPassPhrase, 16)
|
||||
}
|
||||
|
||||
// Matches matches the encoded password and the raw password
|
||||
func SSHAMatches(encodedPassPhrase string, rawPassPhrase string) (bool, error) {
|
||||
hashType, err := determineHashType(encodedPassPhrase)
|
||||
if err != nil {
|
||||
return false, errors.New("invalid password hash stored")
|
||||
}
|
||||
|
||||
var is_ok bool
|
||||
switch hashType {
|
||||
case SSHA:
|
||||
is_ok = LegacySSHAMatches(encodedPassPhrase, []byte(rawPassPhrase))
|
||||
return is_ok, nil
|
||||
//return ssha.Validate(rawPassPhrase, encodedPassPhrase)
|
||||
case SSHA256:
|
||||
return ssha256.Validate(rawPassPhrase, encodedPassPhrase)
|
||||
case SSHA512:
|
||||
return ssha512.Validate(rawPassPhrase, encodedPassPhrase)
|
||||
}
|
||||
|
||||
return false, errors.New("no matching hash type found")
|
||||
}
|
||||
|
||||
func determineHashType(hash string) (string, error) {
|
||||
if len(hash) >= 7 && strings.ToUpper(string(hash[0:6])) == SSHA {
|
||||
return SSHA, nil
|
||||
}
|
||||
if len(hash) >= 10 && strings.ToUpper(string(hash[0:9])) == SSHA256 {
|
||||
return SSHA256, nil
|
||||
}
|
||||
if len(hash) >= 10 && strings.ToUpper(string(hash[0:9])) == SSHA512 {
|
||||
return SSHA512, nil
|
||||
}
|
||||
|
||||
return "", errors.New("no valid hash found")
|
||||
}
|
||||
|
||||
// --- legacy
|
||||
|
||||
// Encode encodes the []byte of raw password
|
||||
func SSHAEncode(rawPassPhrase []byte) string {
|
||||
hash := makeSSHAHash(rawPassPhrase, makeSalt())
|
||||
func LegacySSHAEncode(rawPassPhrase []byte) string {
|
||||
hash := legacyMakeSSHAHash(rawPassPhrase, legacyMakeSalt())
|
||||
b64 := base64.StdEncoding.EncodeToString(hash)
|
||||
return fmt.Sprintf("{ssha}%s", b64)
|
||||
}
|
||||
|
||||
// Matches matches the encoded password and the raw password
|
||||
func SSHAMatches(encodedPassPhrase string, rawPassPhrase []byte) bool {
|
||||
func LegacySSHAMatches(encodedPassPhrase string, rawPassPhrase []byte) bool {
|
||||
if !strings.EqualFold(encodedPassPhrase[:6], "{ssha}") {
|
||||
return false
|
||||
}
|
||||
|
@ -30,7 +84,7 @@ func SSHAMatches(encodedPassPhrase string, rawPassPhrase []byte) bool {
|
|||
}
|
||||
salt := bhash[20:]
|
||||
|
||||
newssha := makeSSHAHash(rawPassPhrase, salt)
|
||||
newssha := legacyMakeSSHAHash(rawPassPhrase, salt)
|
||||
|
||||
if bytes.Compare(newssha, bhash) != 0 {
|
||||
return false
|
||||
|
@ -39,7 +93,7 @@ func SSHAMatches(encodedPassPhrase string, rawPassPhrase []byte) bool {
|
|||
}
|
||||
|
||||
// makeSalt make a 32 byte array containing random bytes.
|
||||
func makeSalt() []byte {
|
||||
func legacyMakeSalt() []byte {
|
||||
sbytes := make([]byte, 32)
|
||||
_, err := rand.Read(sbytes)
|
||||
if err != nil {
|
||||
|
@ -49,7 +103,7 @@ func makeSalt() []byte {
|
|||
}
|
||||
|
||||
// makeSSHAHash make hasing using SHA-1 with salt. This is not the final output though. You need to append {SSHA} string with base64 of this hash.
|
||||
func makeSSHAHash(passphrase, salt []byte) []byte {
|
||||
func legacyMakeSSHAHash(passphrase, salt []byte) []byte {
|
||||
sha := sha1.New()
|
||||
sha.Write(passphrase)
|
||||
sha.Write(salt)
|
||||
|
|
23
write.go
23
write.go
|
@ -7,8 +7,9 @@ import (
|
|||
|
||||
ldap "bottin/ldapserver"
|
||||
|
||||
consul "github.com/hashicorp/consul/api"
|
||||
message "bottin/goldap"
|
||||
|
||||
consul "github.com/hashicorp/consul/api"
|
||||
)
|
||||
|
||||
// Generic item modification function --------
|
||||
|
@ -38,7 +39,7 @@ func (server *Server) putAttributes(dn string, attrs Entry) error {
|
|||
|
||||
// Retreieve previously existing attributes, which we will use to delete
|
||||
// entries with the wrong case
|
||||
previous_pairs, _, err := server.kv.List(prefix + "/attribute=", &server.readOpts)
|
||||
previous_pairs, _, err := server.kv.List(prefix+"/attribute=", &server.readOpts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -65,6 +66,24 @@ func (server *Server) putAttributes(dn string, attrs Entry) error {
|
|||
}
|
||||
}
|
||||
|
||||
// if the password is not yet hashed we hash it
|
||||
if k == ATTR_USERPASSWORD {
|
||||
tmpValues := []string{}
|
||||
for _, pw := range values {
|
||||
_, err := determineHashType(pw)
|
||||
if err != nil {
|
||||
encodedPassword, err := SSHAEncode(pw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tmpValues = append(tmpValues, encodedPassword)
|
||||
} else {
|
||||
tmpValues = append(tmpValues, pw)
|
||||
}
|
||||
}
|
||||
values = tmpValues
|
||||
}
|
||||
|
||||
// If we have zero values, delete associated k/v pair
|
||||
// Otherwise, write new values
|
||||
if len(values) == 0 {
|
||||
|
|
Loading…
Reference in a new issue