Skip to content

Instantly share code, notes, and snippets.

@alexanderankin
Last active November 11, 2023 01:00
Show Gist options
  • Save alexanderankin/649a18592157c01d9bbd9fe4452fc349 to your computer and use it in GitHub Desktop.
Save alexanderankin/649a18592157c01d9bbd9fe4452fc349 to your computer and use it in GitHub Desktop.

ubuntu packages:

  • slapd
  • ldap-utils

programs:

/usr/sbin/slapacl
/usr/sbin/slapadd
/usr/sbin/slapauth
/usr/sbin/slapcat
/usr/sbin/slapd
/usr/sbin/slapdn
/usr/sbin/slapindex
/usr/sbin/slapmodify
/usr/sbin/slappasswd
/usr/sbin/slapschema
/usr/sbin/slaptest

/usr/bin/ldapcompare
/usr/bin/ldapdelete
/usr/bin/ldapexop
/usr/bin/ldapmodify
/usr/bin/ldapmodrdn
/usr/bin/ldappasswd
/usr/bin/ldapsearch
/usr/bin/ldapurl
/usr/bin/ldapwhoami
/usr/bin/ldapadd

slappasswd:

$ slappasswd help
Usage: slappasswd [options]
  -c format	crypt(3) salt format
  -g		generate random password
  -h hash	password scheme
  -n		omit trailing newline
  -o <opt>[=val] specify an option with a(n optional) value
  	module-path=<pathspec>
  	module-load=<filename>
  -s secret	new password
  -u		generate RFC2307 values (default)
  -v		increase verbosity
  -T file	read file for new password
[ $(slappasswd -h '{SHA}' -s secret) == \
  '{SHA}'$(echo -n secret | sha1sum |  xxd -r -p | base64) ] \
  || echo "slappasswd -h '{SHA}' not working as expected"
#!/usr/bin/env python
# slappasswd -h '{SSHA}' explainer:
# works with python3.11
# from https://www.openldap.org/faq/data/cache/347.html
from argparse import ArgumentParser
from base64 import (urlsafe_b64encode as encode, urlsafe_b64decode as decode)
from hashlib import sha1
from os import urandom


def make_secret(password: str):
    salt = urandom(4)
    h = sha1(password.encode())
    h.update(salt)
    return "{SSHA}" + encode(h.digest() + salt).decode()


def check_password(challenge_password: str, password: str):
    challenge_bytes = decode(challenge_password[6:])
    digest = challenge_bytes[:20]
    salt = challenge_bytes[20:]
    hr = sha1(password.encode())
    hr.update(salt)
    return digest == hr.digest()


def main():
    parser = ArgumentParser()
    commands = parser.add_subparsers(dest='command', required=True)
    create_parser = commands.add_parser('create')
    create_parser.add_argument('-s', '--secret', help='secret value to encode', required=True)
    check_parser = commands.add_parser('check')
    check_parser.add_argument('-c', '--challenge', help='encoded secret', required=True)
    check_parser.add_argument('-s', '--secret', help='secret to check', required=True)
    args = parser.parse_args()
    {
        'create': lambda: print(make_secret(args.secret)),
        'check': lambda: print(check_password(args.challenge, args.secret)),
    }[args.command]()


if __name__ == '__main__':
    # import sys
    # sys.argv = ['', 'check', '-c', '{SSHA}fiV7G0i7bryYyGhFE0unJKzsKE0-DLeg', '-s', 'secret']
    # sys.argv = ['', 'create', '-s', 'secret']
    main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment