Compare commits

..

No commits in common. "1c491559557fd74025eac88b6cd7fe7ffcb1fbc0" and "ec3a51c23e396dc6693588ad3590df4dceec6d16" have entirely different histories.

4 changed files with 51 additions and 57 deletions

View File

@ -6,10 +6,11 @@ The functionality is heavily inspired by [HSXKPasswd](https://github.com/bbussch
# Why # Why
Because Randall Munroe says so. Because Randall Munroe says so.
![xkcd](https://imgs.xkcd.com/comics/password_strength.png "XKCD") ![alt text][xkcd]
[xkcd]: http://imgs.xkcd.com/comics/password_strength.png
# Requirements # Requirements
Python 3 as well as my-/hunspell-dictionaries for the language(s) you want to use. Python 2 or 3 as well as myspell-dictionaries for the language(s) you want to use.
# What # What
A password/passphrase generator. See below for some example usage. A password/passphrase generator. See below for some example usage.
@ -20,27 +21,25 @@ $ sudo python3 setup.py install
... ...
$ pwgen --help $ pwgen --help
usage: pwgen [-h] [--quiet] [--generate-config] [--config-file CONFIG_FILE] [--myspell-dir MYSPELL_DIR] [--encoding ENCODING] usage: pwgen [-h] [--generate-config] [--config-file CONFIG_FILE]
[--unmunch-bin UNMUNCH_BIN] [--lang LANG] [--word-min-char WORD_MIN_CHAR] [--word-max-char WORD_MAX_CHAR] [--words WORDS] [--myspell-dir MYSPELL_DIR] [--lang LANG]
[--capitalize {true,false,random}] [--separators SEPARATORS] [--trailing-digits TRAILING_DIGITS] [--word-min-char WORD_MIN_CHAR] [--word-max-char WORD_MAX_CHAR]
[--leading-digits LEADING_DIGITS] [--special-chars SPECIAL_CHARS] [--trailing-chars TRAILING_CHARS] [--words WORDS] [--capitalize {true,false,random}]
[--leading-chars LEADING_CHARS] [--passwords PASSWORDS] [--max-length MAX_LENGTH] [--separators SEPARATORS] [--trailing-digits TRAILING_DIGITS]
[--leading-digits LEADING_DIGITS] [--special-chars SPECIAL_CHARS]
[--trailing-chars TRAILING_CHARS] [--leading-chars LEADING_CHARS]
[--passwords PASSWORDS] [--max-length MAX_LENGTH]
Generate passwords Generate passwords
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
--quiet, -q Only echo the generated passwords.
--generate-config, -g --generate-config, -g
Generate configuration file and then exit Generate configuration file and then exit
--config-file CONFIG_FILE, -c CONFIG_FILE --config-file CONFIG_FILE, -c CONFIG_FILE
Configuration file to use Configuration file to use
--myspell-dir MYSPELL_DIR, -i MYSPELL_DIR --myspell-dir MYSPELL_DIR, -i MYSPELL_DIR
Directory containing myspell dictionaries Directory containing myspell dictionaries
--encoding ENCODING, -e ENCODING
Character encoding of the directory
--unmunch-bin UNMUNCH_BIN, -u UNMUNCH_BIN
Path to my/hunspell unmunch binary
--lang LANG, -l LANG Dictionary language to use --lang LANG, -l LANG Dictionary language to use
--word-min-char WORD_MIN_CHAR, -m WORD_MIN_CHAR --word-min-char WORD_MIN_CHAR, -m WORD_MIN_CHAR
Minimum number of characters in a word Minimum number of characters in a word
@ -59,13 +58,17 @@ optional arguments:
--special-chars SPECIAL_CHARS, -S SPECIAL_CHARS --special-chars SPECIAL_CHARS, -S SPECIAL_CHARS
Possible characters to use as extra special characters Possible characters to use as extra special characters
--trailing-chars TRAILING_CHARS, -p TRAILING_CHARS --trailing-chars TRAILING_CHARS, -p TRAILING_CHARS
Number of special characters to add at the end of the passphrase Number of special characters to add at the end of the
passphrase
--leading-chars LEADING_CHARS, -P LEADING_CHARS --leading-chars LEADING_CHARS, -P LEADING_CHARS
Number of special characters to add at the start of the passphrase Number of special characters to add at the start of
the passphrase
--passwords PASSWORDS, -n PASSWORDS --passwords PASSWORDS, -n PASSWORDS
Number of passwords to generate Number of passwords to generate
--max-length MAX_LENGTH, -L MAX_LENGTH --max-length MAX_LENGTH, -L MAX_LENGTH
Maximum length of the generated passwords. Full-knowledge entropy calculation doesn't work when this is set. Maximum length of the generated passwords. Full-
knowledge entropy calculation doesn't work when this
is set.
$ pwgen -g --myspell-dir /usr/share/hunspell --lang sv_SE $ pwgen -g --myspell-dir /usr/share/hunspell --lang sv_SE
Missing configuration file; generating a new at /home/user/.pwgen.cfg Missing configuration file; generating a new at /home/user/.pwgen.cfg
@ -84,3 +87,7 @@ Blind entropy Password
======================== ========================
``` ```
# TODO
* documentation
* webservice

View File

@ -10,10 +10,6 @@ default_config_file=os.path.expanduser('~/.pwgen.cfg')
def main(): def main():
parser = argparse.ArgumentParser(description='Generate passwords') parser = argparse.ArgumentParser(description='Generate passwords')
parser.add_argument(
'--quiet', '-q',
action='store_true',
help='Only echo the generated passwords.')
parser.add_argument( parser.add_argument(
'--generate-config', '-g', '--generate-config', '-g',
action='store_true', action='store_true',
@ -26,12 +22,6 @@ def main():
parser.add_argument( parser.add_argument(
'--myspell-dir', '-i', '--myspell-dir', '-i',
help='Directory containing myspell dictionaries') help='Directory containing myspell dictionaries')
parser.add_argument(
'--encoding', '-e',
help="Character encoding of the directory")
parser.add_argument(
'--unmunch-bin', '-u',
help="Path to my/hunspell unmunch binary")
parser.add_argument( parser.add_argument(
'--lang', '-l', '--lang', '-l',
@ -89,9 +79,6 @@ def main():
args = vars(parser.parse_args()) args = vars(parser.parse_args())
quiet = args['quiet']
del args['quiet']
config_file = args['config_file'] config_file = args['config_file']
del args['config_file'] del args['config_file']
@ -113,10 +100,6 @@ def main():
pwds, seen_entropy = pwgen.generate_passwords(conf) pwds, seen_entropy = pwgen.generate_passwords(conf)
if (quiet):
for pw in pwds.keys():
print(pw)
else:
print("Generated {} passwords".format(len(pwds))) print("Generated {} passwords".format(len(pwds)))
if seen_entropy: if seen_entropy:
print("Full-knowledge entropy is {0:.2g}".format(seen_entropy)) print("Full-knowledge entropy is {0:.2g}".format(seen_entropy))

View File

@ -1,13 +1,21 @@
#!/usr/bin/python3 #!/usr/bin/python3
import configparser
import locale
import math import math
import os import os
import sys import sys
import subprocess import subprocess
if sys.version_info[0] < 3:
import ConfigParser as configparser
else:
import configparser
if sys.version_info >= (3, 6):
do_seed = False
import secrets as random import secrets as random
else:
do_seed = True
import random
class DictReadError(Exception): class DictReadError(Exception):
pass pass
@ -27,8 +35,6 @@ def update_config(
lang='en_US', lang='en_US',
word_min_char=2, word_min_char=2,
word_max_char=0, word_max_char=0,
unmunch_bin='',
encoding='',
words=4, words=4,
capitalize='random', capitalize='random',
@ -57,8 +63,6 @@ def update_config(
set_if_defined(conf, 'dictionary', 'lang', lang) set_if_defined(conf, 'dictionary', 'lang', lang)
set_if_defined(conf, 'dictionary', 'word_min_char', word_min_char) set_if_defined(conf, 'dictionary', 'word_min_char', word_min_char)
set_if_defined(conf, 'dictionary', 'word_max_char', word_max_char) set_if_defined(conf, 'dictionary', 'word_max_char', word_max_char)
set_if_defined(conf, 'dictionary', 'unmunch_bin', unmunch_bin)
set_if_defined(conf, 'dictionary', 'encoding', encoding)
if not conf.has_section('passwords'): if not conf.has_section('passwords'):
conf.add_section('passwords') conf.add_section('passwords')
@ -87,9 +91,6 @@ def _read_dictionary(conf):
dict_file = os.path.join(conf.get('dictionary', 'myspell_dir'), '{}.dic'.format(conf.get('dictionary', 'lang'))) dict_file = os.path.join(conf.get('dictionary', 'myspell_dir'), '{}.dic'.format(conf.get('dictionary', 'lang')))
aff_file = os.path.join(conf.get('dictionary', 'myspell_dir'), '{}.aff'.format(conf.get('dictionary', 'lang'))) aff_file = os.path.join(conf.get('dictionary', 'myspell_dir'), '{}.aff'.format(conf.get('dictionary', 'lang')))
unmunch_bin = conf.get('dictionary', 'unmunch_bin') unmunch_bin = conf.get('dictionary', 'unmunch_bin')
encoding = conf.get('dictionary', 'encoding')
if not encoding:
encoding = locale.getpreferredencoding(False)
words = set() words = set()
chars = 0 chars = 0
if os.path.exists(aff_file) and unmunch_bin: if os.path.exists(aff_file) and unmunch_bin:
@ -103,7 +104,7 @@ def _read_dictionary(conf):
if proc.returncode != 0: if proc.returncode != 0:
raise DictReadError('Unmunching dictionaries failed') raise DictReadError('Unmunching dictionaries failed')
for word in out.splitlines(): for word in out.splitlines():
save = word.strip().decode(encoding) save = word.strip().decode('utf-8')
if not save: if not save:
continue continue
first_char = save[:1] first_char = save[:1]
@ -119,7 +120,7 @@ def _read_dictionary(conf):
words.add(save) words.add(save)
chars += len(save) chars += len(save)
else: else:
with open(dict_file, encoding=encoding, mode='r') as f: with open(dict_file, 'r') as f:
for line in f: for line in f:
if not line: if not line:
continue continue
@ -152,6 +153,8 @@ def generate_passwords(conf):
capitalize = conf.get('passwords', 'capitalize') capitalize = conf.get('passwords', 'capitalize')
max_len = conf.getint('passwords', 'max_length') max_len = conf.getint('passwords', 'max_length')
if do_seed:
random.seed()
res = {} res = {}
dict_data = _read_dictionary(conf) dict_data = _read_dictionary(conf)

View File

@ -8,23 +8,24 @@ except ImportError:
import pwgen import pwgen
version = '1.0' version = '0.1'
setup( setup(
name='pwgen', name='pwgen',
version=str(version), version=str(version),
description="Passphrase generator", description="Passphrase generator",
author="Fredrik Eriksson", author="Fredrik Eriksson",
author_email="feffe@fulh.ax", author_email="pwgen@wb9.se",
url="https://gitea.fulh.ax/feffe/pwgen", url="https://github.com/fredrik-eriksson/pwgen",
platforms=['any'], platforms=['any'],
license='BSD', license='BSD',
packages=['pwgen'], packages=['pwgen'],
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable' 'Development Status :: 1 - Planning',
'Environment :: Console', 'Environment :: Console',
'Intended Audience :: System Administrators', 'Intended Audience :: System Administrators',
'License :: OSI Approved :: BSD License', 'License :: OSI Approved :: BSD License',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3',
'Topic :: Utilities', 'Topic :: Utilities',
], ],