/relevation/branches/1.3/devtools/setup.py.in |
---|
0,0 → 1,45 |
#!/usr/bin/env python |
# $Id$ |
# This script isn't used directly to generate the distributed files |
# since some files are generated from the source and the zip and tar.gz |
# differ. |
# GNU Make is used instead. |
from distutils.core import setup |
import distutils.command.install_scripts |
import shutil |
class my_install(distutils.command.install_scripts.install_scripts): |
''' Rename scripts that use the .py extension after installation. |
NOTE: breaks bdist_rpm |
Reference: http://stackoverflow.com/questions/4359231/rename-script-file-in-distutils |
''' |
def run(self): |
distutils.command.install_scripts.install_scripts.run(self) |
for script in self.get_outputs(): |
if script.endswith(".py"): |
shutil.move(script, script[:-3]) |
setup(name='relevation', |
version='@VERSION@', |
author='Toni Corvera', |
author_email='outlyer@gmail.com', |
url='http://p.outlyer.net/relevation', |
description='Command-line interface to query Revelation files', |
long_description= |
'''This is a command-line tool capable of retrieving passwords from a Revelation password file. |
Please note files can only be searched, not edited with this tool.''', |
license='BSD', |
package_dir={'': 'src'}, |
packages=['relevation'], |
scripts=['src/relevation.py'], |
cmdclass = {"install_scripts": my_install}, # hook |
data_files=[ |
('share/man/man1/', ['relevation.1']), |
#('share/doc/relevation', ['CHANGELOG']), |
('share/doc/relevation/extra', ['src/gui.py','devtools/checkpw.py','devtools/genpw.py']), |
] |
) |
# vim:set ts=4 et ai: # |
Property changes: |
Added: svn:keywords |
+Rev Id Date |
\ No newline at end of property |
/relevation/branches/1.3/devtools/genpw.py |
---|
0,0 → 1,156 |
#!/usr/bin/env python |
""" |
Simplistic Password Generator. |
""" |
# Relevation Password Printer |
# |
# Copyright (c) 2011,2012 Toni Corvera |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions are |
# met: |
# 1. Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# 2. Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# |
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
# AND EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
# POSSIBILITY OF SUCH DAMAGE. |
import random |
import string |
import locale |
import os |
import sys |
try: |
import checkpw |
DO_CHECK=True |
except ImportError: |
DO_CHECK=False |
DEFAULT_RESULTS = 20 |
DEFAULT_LENGTH = 8 |
#Letters and digits are repeated to favour them |
FAVOURED_SET = string.lowercase + string.digits #string.letters |
STDSET = string.uppercase + string.punctuation |
DEFAULT_CSET = FAVOURED_SET * 8 + STDSET |
# Taken from pwgen's list ("B8G6I1l0OQDS5Z2") |
REJECTS_SET = [ 'B','8', 'G','6', 'I','1','l', '0','O','Q','D', 'S','5', 'Z','2' ] |
DEFAULT_FORCE = '*' # Symbolic |
# The number of tries, when strong passwords are requested, before giving up |
# e.g. with length below 7 there won't be strong passwords |
STRIKES = 2048 |
def pwgen(length=DEFAULT_LENGTH, possible=DEFAULT_CSET, |
reject_ambiguous=False, force=DEFAULT_FORCE): |
''' |
pwgen(int, str, bool, [ str, str, ...]) -> str |
Generate a password. |
length - Password length |
possible - List of characters from where to pick |
reject_ambiguous - Reject characters that can be hard to tell from each other (e.g. 1 vs l vs I) |
force - List of forcible sets. Force at least one character of each set. |
''' |
pw = '' |
rejects = [] |
LENGTH = length |
if reject_ambiguous: |
rejects = REJECTS_SET |
if force == DEFAULT_FORCE: |
force = [ string.lowercase, string.uppercase, string.digits ] |
if type(force) != list: |
raise ValueError('force must be a list of strings') |
def pick_one(cset): |
''' |
Return a random character from cset |
''' |
c = random.choice(cset) |
while c in rejects: |
c = random.choice(cset) |
return c |
# Forcible includes |
for cset in force: |
pw += pick_one(cset) |
length -= 1 |
for i in range(length): |
pick = random.choice(possible) |
while pick in rejects: |
pick = random.choice(possible) |
pw += pick |
# Re-mix order (randomize forced-characters' position) |
if len(pw) > LENGTH: |
pw = pw[0:LENGTH] |
l = list(pw) |
random.shuffle(l) |
pw = ''.join(l) |
return pw |
def main(argv): |
rounds = DEFAULT_RESULTS |
length = DEFAULT_LENGTH |
cset = DEFAULT_CSET |
reject_ambiguous = False |
secure = False # When True, reject mediocre passwords and below |
# No need to use getopt or anything like it |
positional = [] |
for arg in argv: |
if arg in ( '-B', '--ambiguous' ): |
reject_ambiguous = True |
elif arg in ( '-s', '--secure' ): |
if not DO_CHECK: |
raise EnvironmentError('Can\'t generate secure-only password without checkpw.py') |
secure = True |
else: |
positional.append(arg) |
try: |
if len(positional) > 0: |
length = int(positional[0]) |
if len(positional) > 1: |
rounds = int(positional[1]) |
except ValueError: |
sys.stderr.write('Usage: %s [-B] [length] [num pw]\n' % os.path.basename(sys.argv[0])); |
sys.exit(2); |
def newpw(): |
return pwgen(length=length, reject_ambiguous=reject_ambiguous) |
for i in range(rounds): |
pw = newpw() |
if DO_CHECK: |
( score, verdict, _ ) = checkpw.check(pw) |
if secure: |
strikes_left = STRIKES |
while strikes_left > 0 and score < checkpw.STRONG_THRESHOLD: |
pw = newpw() |
( score, verdict, _ ) = checkpw.check(pw) |
strikes_left -= 1 |
if strikes_left == 0: |
print "Giving up: Too many weak passwords" |
sys.exit(1) |
print '%s\t%d\t%s' % ( pw, score, verdict) |
#print _ |
else: |
print pw |
if __name__ == '__main__': |
locale.setlocale(locale.LC_ALL, 'C') |
main(sys.argv[1:]) |
# vim:set ts=4 et ai: # |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/relevation/branches/1.3/devtools/checkpw.py |
---|
0,0 → 1,130 |
#!/usr/bin/env python |
""" |
Simplistic Password Strength Checker. |
""" |
# Relevation Password Printer |
# |
# Copyright (c) 2011, Toni Corvera |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions are |
# met: |
# 1. Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# 2. Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# |
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
# AND EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
# POSSIBILITY OF SUCH DAMAGE. |
# Based on |
# <http://www.geekwisdom.com/dyn/passwdmeter> |
# |-> <http://www.geekwisdom.com/js/passwordmeter.js> |
# (this is mostly based on the scoring system explained there, |
# and not on the actual implementation) |
import re |
import string |
import sys |
WEAK_THRESHOLD = 16 |
MEDIOCRE_THRESHOLD = 25 |
STRONG_THRESHOLD = 35 |
VERY_STRONG_THRESHOLD = 45 |
def check(pw): |
''' |
check(str) -> ( int score, str strength category, str description) |
''' |
score = 0 |
verdict = 'weak' |
log = '' |
# Password length |
length = len(pw) |
if length == 0: |
return ( 0, 'weak', 'empty password' ) |
if length < 5: |
score += 3 |
elif length < 8: |
score += 6 |
elif length < 16: |
score += 12 |
else: |
score += 18 |
log += '%d points for length (%d)\n' % (score, length) |
# Letters |
locase = re.search('[a-z]', pw) |
upcase = re.search('[A-Z]', pw) |
if (locase and upcase): |
score += 7 |
log += '7 points for mixed case\n' |
elif locase: |
score += 5 |
log += '5 points for all-lowercase letters\n' |
elif upcase: |
score += 5 |
log += '5 points for all-uppercase letters\n' |
else: # No letters at all |
pass |
# Numbers |
hasnums = re.search('\d', pw) |
if hasnums and re.search('\d.*\d.*\d', pw): |
score += 7 |
log += '7 points for at least three numbers\n' |
elif hasnums: |
score += 5 |
log += '5 points for at least one number\n' |
# Special Characters |
sch = string.punctuation |
hasspecial = re.search('[%s]' % sch, pw) |
if hasspecial and re.search('[%s].*[%s]' % ( sch, sch), pw): |
score += 10 |
log += '10 points for at least two special characters\n' |
elif hasspecial: |
score += 5 |
log += '5 points for at least one special character\n' |
# Combos |
hasletters = re.search('([a-z]|[A-Z])', pw) |
if hasnums and hasletters: |
score += 1 |
log += '1 combo point for mixed letters and numbers\n' |
if hasspecial: |
score += 2 |
log += '2 combo points for mixed letters, numbers and special characters\n' |
if upcase and locase: |
score += 2 |
log += '2 combo point for mixed case letters, numbers and special characters' |
# Verdict |
if score < WEAK_THRESHOLD: |
verdict = 'very weak' |
elif score < MEDIOCRE_THRESHOLD: |
verdict = 'weak' |
elif score < STRONG_THRESHOLD: |
verdict = 'mediocre' |
elif score < VERY_STRONG_THRESHOLD: |
verdict = 'strong' |
else: |
verdict = 'stronger' |
return ( score, verdict, log ) |
if __name__ == '__main__': |
for candidate in sys.argv[1:]: |
( score, verdict, descr ) = check(candidate) |
print '%s: %s\t%s' % ( candidate, score, verdict ) |
sys.stderr.write(descr) |
# vim:set ts=4 et ai: # |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
Added: svn:keywords |
+Rev Id Date |
\ No newline at end of property |
/relevation/branches/1.3/devtools/. |
---|
Property changes: |
Added: bugtraq:number |
+true |
\ No newline at end of property |