[Freeipa-devel] [freeipa PR#317][comment] Unify password generation across FreeIPA
tiran
freeipa-github-notification at redhat.com
Thu Dec 8 17:37:27 UTC 2016
URL: https://github.com/freeipa/freeipa/pull/317
Title: #317: Unify password generation across FreeIPA
tiran commented:
"""
```
#!/usr/bin/python3
import math
import random
import string
class TokenGenerator(object):
"""Simple, tunable token generator
TokenGenerator(uppercase=3, lowercase=3, digits=0, special=None)
At least 3 upper and 3 lower case ASCII chars, may contain digits, no
special chars.
128 bits entropy: secure
256 bits of entropy: secure enough if you care about quantum computers
"""
uppercase = frozenset(string.ascii_uppercase)
lowercase = frozenset(string.ascii_lowercase)
digits = frozenset(string.digits)
# without: = # ' " \ `
special = frozenset('!$%&()*+,-./:;<>?@[]^_{|}~')
def __init__(self, uppercase=1, lowercase=1, digits=1, special=1):
self.rng = random.SystemRandom()
self.requirements = dict(
uppercase=uppercase,
lowercase=lowercase,
digits=digits,
special=special
)
chars = set()
for symclass, req in self.requirements.items():
if req is not None:
chars.update(getattr(self, symclass))
self.chars = tuple(chars)
def __call__(self, entropy_bits=128):
length = int(math.ceil(entropy_bits / math.log(len(self.chars), 2)))
while True:
token = ''.join(self.rng.choice(self.chars) for _ in range(length))
tokenset = set(token)
token_ok = True
for symclass, req in self.requirements.items():
if req is None or req <= 0:
continue
reqchars = getattr(self, symclass)
if len(tokenset.intersection(reqchars)) < req:
token_ok = False
break
if token_ok:
return token
if __name__ == '__main__':
pwgen = TokenGenerator(special=None)
for i in range(100):
print(pwgen())
```
"""
See the full comment at https://github.com/freeipa/freeipa/pull/317#issuecomment-265803218
More information about the Freeipa-devel
mailing list