Build LDAP services w/ Go

Overview

gldap

Go Reference Coverage Go Report Card


gldap is a framework for building LDAP services. Among other things, it defines abstractions for:

  • Server: supports both LDAP and LDAPS (TLS) protocols as well as the StartTLS requests.
  • Request: represents an LDAP request (bind, search, extended, etc) along with the inbound request message.
  • ResponseWriter: allows you to compose request responses.
  • Mux: an ldap request multiplexer. It matches the inbound request against a list of registered route handlers.
  • HandlerFunc: handlers provided to the Mux which serve individual ldap requests.

Example:

package main

import (
	"context"
	"log"
	"os"
	"os/signal"
	"syscall"

	"github.com/jimlambrt/gldap"
)

func main() {
	// create a new server
	s, err := gldap.NewServer()
	if err != nil {
		log.Fatalf("unable to create server: %s", err.Error())
	}

	// create a router and add a bind handler
	r, err := gldap.NewMux()
	if err != nil {
		log.Fatalf("unable to create router: %s", err.Error())
	}
	r.Bind(bindHandler)
	r.Search(searchHandler)
	s.Router(r)
	go s.Run(":10389") // listen on port 10389

	// stop server gracefully when ctrl-c, sigint or sigterm occurs
	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
	defer stop()
	select {
	case <-ctx.Done():
		log.Printf("\nstopping directory")
		s.Stop()
	}
}

func bindHandler(w *gldap.ResponseWriter, r *gldap.Request) {
	resp := r.NewBindResponse(
		gldap.WithResponseCode(gldap.ResultInvalidCredentials),
	)
	defer func() {
		w.Write(resp)
	}()

	m, err := r.GetSimpleBindMessage()
	if err != nil {
		log.Printf("not a simple bind message: %s", err)
		return
	}

	if m.UserName == "alice" {
		resp.SetResultCode(gldap.ResultSuccess)
		log.Println("bind success")
		return
	}

func searchHandler(w *gldap.ResponseWriter, r *gldap.Request) {
	resp := r.NewSearchDoneResponse()
	defer func() {
		w.Write(resp)
	}()
	m, err := r.GetSearchMessage()
	if err != nil {
		log.Printf("not a search message: %s", err)
		return
	}
	log.Printf("search base dn: %s", m.BaseDN)
	log.Printf("search scope: %d", m.Scope)
	log.Printf("search filter: %s", m.Filter)

	if strings.Contains(m.Filter, "uid=alice") || m.BaseDN == "uid=alice,ou=people,cn=example,dc=org" {
		entry := r.NewSearchResponseEntry(
			"uid=alice,ou=people,cn=example,dc=org",
			gldap.WithAttributes(map[string][]string{
				"objectclass": {"top", "person", "organizationalPerson", "inetOrgPerson"},
				"uid":         {"alice"},
				"cn":          {"alice eve smith"},
				"givenname":   {"alice"},
				"sn":          {"smith"},
				"ou":          {"people"},
				"description": {"friend of Rivest, Shamir and Adleman"},
				"password":    {"{SSHA}U3waGJVC7MgXYc0YQe7xv7sSePuTP8zN"},
			}),
		)
		entry.AddAttribute("email", []string{"[email protected]"})
		w.Write(entry)
		resp.SetResultCode(gldap.ResultSuccess)
	}
	if m.BaseDN == "ou=people,cn=example,dc=org" {
		entry := r.NewSearchResponseEntry(
			"ou=people,cn=example,dc=org",
			gldap.WithAttributes(map[string][]string{
				"objectclass": {"organizationalUnit"},
				"ou":          {"people"},
			}),
		)
		w.Write(entry)
		resp.SetResultCode(gldap.ResultSuccess)
	}
	return
}

Road map

Currently supported features:

  • ldap, ldaps and mTLS connections
  • StartTLS Requests
  • Bind Requests
    • Simple Auth (user/pass)
  • Search Requests
  • Modify Requests
  • Add Requests
  • Delete Requests
  • Unbind Requests

Future features

At this point, we may wait until issues are opened before planning new features given that all the basic LDAP operations are supported.


gldap.testdirectory

Go Reference

The testdirectory package built using gldap which provides an in-memory test LDAP service with capabilities which make writing tests that depend on an LDAP service much easier.

testdirectory is also a great working example of how you can use gldap to build a custom ldap server to meet your specific needs.

Example:

// this testdirectory example demonstrates how can start a test directory for 
// your unit tests which will automatically stop when the test is complete. 
func TestExample(t *testing.T) {

	// start a test directory running ldaps on an available free port (defaults)
	// that allows anon binds (a default override)
	td := testdirectory.Start(t,
		testdirectory.WithDefaults(&testdirectory.Defaults{AllowAnonymousBind: true}),
	)
	// create some test new user entries (using defaults for ou, password, etc)
	users := testdirectory.NewUsers(t, []string{"alice", "bob"})
	// set the test directories user entries
	td.SetUsers(users...)

	// INSERT your tests here....
}
Comments
  • Support for mapping user after a Bind request

    Support for mapping user after a Bind request

    Is your feature request related to a problem? Please describe. I am creating an LDAP server using gldap and I can't figure out how to ensure that a user performing a search operation has been successfully authenticated just before.

    Describe the solution you'd like It might be helpful to provide at least the connection ID on each message to know "who" (i.e. which connection) made the request.

    Describe alternatives you've considered I tried to use any accessible information on the request message to bypass that, but couldn't find anything that would help.

    opened by xunleii 3
  • Support Bind request controls

    Support Bind request controls

    Is your feature request related to a problem? Please describe.

    Currently, there's no way to receive Controls on inbound Bind requests or send Controls back with Bind responses.

    Describe the solution you'd like

    Add support for Controls on both Bind requests and responses.

    enhancement 
    opened by jimlambrt 1
  • feature: support for deleting an entry

    feature: support for deleting an entry

    PR includes:

    • chore: clean up a few cut/paste errors from previous commits
    • docs: updated docs based on effort to add the "delete" cmd
    • feature: support for deleting an entry
    opened by jimlambrt 0
  • Quality improvements in:  testdirectory and packets

    Quality improvements in: testdirectory and packets

    This PR includes:

    • tests (testdirectory): additional testingT unit tests
    • tests (testdirectory): additional fixture unit tests
    • tests (testdirectory): additional options unit tests
    • fix (packet): properly assert search attribute packets
    • tests (testdirectory): additional directory unit tests
    • chore: updates from "make fmt"
    opened by jimlambrt 0
  • Quality improvements in: conn, decodeControl, Entry and EntryAttribute

    Quality improvements in: conn, decodeControl, Entry and EntryAttribute

    This PR includes:

    • fix: check netConn properly when initializing a conn
    • fix: check the shutdown ctx when creating a new conn
    • chore: remove extra blank line found with gofumpt
    • fix: improve decodeControl(...) data validation
    • feature: support WithWriter option for PrettyPrint
    • tests: improve Entry/EntryAttribute unit tests
    opened by jimlambrt 0
  • refactor: clean up some control bits

    refactor: clean up some control bits

    The following now validate their parameters and use options: NewControlString(...) NewControlManageDsaIT(...) NewControlMicrosoftShowDeleted(...) NewControlMicrosoftServerLinkTTL(...) NewControlMicrosoftShowDeleted(...) NewControlPaging(...)

    opened by jimlambrt 0
  • Support search request Controls

    Support search request Controls

    Is your feature request related to a problem? Please describe.

    Currently, there's no way to receive Controls on inbound Search requests or send Controls back with Search responses.

    Describe the solution you'd like

    Add support for Controls on both Search requests and responses.

    enhancement 
    opened by jimlambrt 0
  • Support for Unbind

    Support for Unbind

    Is your feature request related to a problem? Please describe. Currently, there's no way to unbind from a server. Even if you send an unbind request, the server will continue to serve requests for the connection

    Describe the solution you'd like Add support for an Unbind request and stop serving requests for any connection that receives an unbind request.

    enhancement 
    opened by jimlambrt 0
  • refactor: clean up tests, exports, docs, data races.

    refactor: clean up tests, exports, docs, data races.

    chore: "go mod tidy" updates

    tests (Server): add a reasonable level of unit tests

    defect (Server): protect against listener data races

    docs: Add some more godocs

    refactor (Server/configOptions): update WithDisablePanicRecovery Passing true for this option is redundant.

    chore (SIDBytes): remove commented code

    defect: trying to resolve: https://github.com/golang/go/issues/41572

    refactor: stop exporting newMessage(...)

    refactor (Mux): remove Routes() method

    refactor: prevent data races when writing responses

    refactor (route): use the Op() receiver method

    opened by jimlambrt 0
  • Support for both LDAP and LDAP3 clients

    Support for both LDAP and LDAP3 clients

    Is your feature request related to a problem? Please describe. Currently, we only support binding with an LDAP3 client and clients using the previous version of the protocol are unable to bind.

    Describe the solution you'd like Support both LDAP and LDAP3 clients but allow the developer an option to only support LDAP3 if they wish via a new Option when creating a NewServer. This new WithRequiredVersion option will have to be passed along from the Server to each new conn and then to each new request, so it can be enforced when the new message is created.

    enhancement 
    opened by jimlambrt 0
Releases(v0.1.1)
  • v0.1.1(Apr 3, 2022)

    This release includes:

    • feature: support for Unbind requests.
    • chore: matrix based workflow to test multiple versions of go: 1.18, 1.17, 1.16
    • chore: add go-report card and code coverage badge to README
    Source code(tar.gz)
    Source code(zip)
  • v0.1.0(Mar 14, 2022)

Owner
Jim
Software Engineer @hashicorp
Jim
Proof-of-Concept tool for CVE-2021-29156, an LDAP injection vulnerability in ForgeRock OpenAM v13.0.0.

CVE-2021-29156 Proof-of-Concept (c) 2021 GuidePoint Security Charlton Trezevant [email protected] Background Today GuidePoint

GuidePoint Security, LLC 2 Apr 13, 2022
Help fuzz various protocols and waits for ping backs Integrates LDAP server and JNDI payload

l9fuzz Fuzzes various protocols with JNDI LDAP payloads and listen for ping backs Features Low CPU/Memory footprint Integrated LDAP server Trace orign

null 11 Jan 13, 2022
null 8 Dec 20, 2021
Kerberoasting attack implementation in Golang using go-ldap and gokrb5

Goberoast Kerberoasting attack implementation in Golang using go-ldap and gokrb5. Build You can build the project by simply typing go build within the

null 0 Jan 19, 2022
PoC for running AWS services(kinesis, dynamodb, lambdas) locally with Localstack

hotdog-localstack-PoC PoC for running AWS services(kinesis, dynamodb, lambdas) locally with Localstack alias awslocal="aws --endpoint-url=http://local

Talha Altınel 37 Aug 4, 2022
Build awesome Golang desktop apps and beautiful interfaces with Vue.js, React.js, Framework 7, and more...

Guark Guark allows you to build beautiful user interfaces using modern web technologies such as Vue.js, React.js..., while your app logic handled and

Guark. 615 Sep 25, 2022
Build Go applications for IOS

go-build-for-ios Build Go applications for IOS This repository contains a PoC that lets you build any Go application for IOS platform. Cross-compilati

Marcin Tojek 20 Jul 18, 2022
A port scan and service weakpass brute tool build by golang.

A port scan and service weakpass brute tool build by golang.

M1ku 6 Aug 26, 2022
Build & Scan - Container Image

BSImage (build&scan image) Requirements Trivy Docker BSImage (shell script version) Usage of build (shell script version) ./bsimage.sh start <image:ta

Carlos Eduardo Vieira 1 Apr 12, 2022
GLAuth 1.7k Sep 30, 2022
A minimalistic LDAP server that is meant for test vulnerability to JNDI+LDAP injection attacks in Java, especially CVE-2021-44228.

jndi-ldap-test-server This is a minimalistic LDAP server that is meant for test vulnerability to JNDI+LDAP injection attacks in Java, especially CVE-2

Rakuten Group, Inc. 9 Aug 6, 2022
Mail-alias-resolve-ldap - Resolve mail alias addresses in LDAP

alias-resolve-ldap alias-resolve-ldap was written to be used as a hook for the c

Björn Busse 1 Jan 30, 2022
Go-ldap-pool - A simple connection pool for go-ldap

Basic connection pool for go-ldap This little library use the go-ldap library an

Vincent 2 May 9, 2022
Build LDAP services w/ Go

gldap gldap is a framework for building LDAP services. Among other things, it defines abstractions for: Server: supports both LDAP and LDAPS (TLS) pro

Jim 76 Sep 27, 2022
Basic LDAP v3 functionality for the GO programming language.

Basic LDAP v3 functionality for the GO programming language. Install For the latest version use: go get gopkg.in/ldap.v2 Import the latest version wi

null 137 May 24, 2022
HA LDAP based key/value solution for projects configuration storing with multi master replication support

Recon is the simple solution for storing configs of you application. There are no specified instruments, no specified data protocols. For the full power of Recon you only need curl.

Mikhail Panfilov 12 Jun 15, 2022
Basic LDAP v3 functionality for the GO programming language.

Basic LDAP v3 functionality for the GO programming language. The library implements the following specifications: https://tools.ietf.org/html/rfc4511

null 1.8k Sep 27, 2022
Proof-of-Concept tool for CVE-2021-29156, an LDAP injection vulnerability in ForgeRock OpenAM v13.0.0.

CVE-2021-29156 Proof-of-Concept (c) 2021 GuidePoint Security Charlton Trezevant [email protected] Background Today GuidePoint

GuidePoint Security, LLC 2 Apr 13, 2022
A system written in Golang to help ops team to automate the process of mapping Vault groups to LDAP Groups.

A system written in Golang to help ops team to automate the process of mapping Vault groups to LDAP Groups. This utility automatically adds LDAP Groups' members to the corresponding Vault Groups.

Rahul Indra 0 Nov 12, 2021
Help fuzz various protocols and waits for ping backs Integrates LDAP server and JNDI payload

l9fuzz Fuzzes various protocols with JNDI LDAP payloads and listen for ping backs Features Low CPU/Memory footprint Integrated LDAP server Trace orign

null 11 Jan 13, 2022