Update to python 3

This commit is contained in:
Pavle Portic 2019-05-29 13:44:26 +02:00
parent 432c3359c1
commit 03a3edbd5b
Signed by: TheEdgeOfRage
GPG Key ID: 6758ACE46AA2A849
7 changed files with 395 additions and 276 deletions

125
.gitignore vendored Normal file
View File

@ -0,0 +1,125 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/

View File

@ -1,6 +0,0 @@
language: python
python:
- "2.7"
- "pypy"
install: python setup.py install
script: nosetests

View File

@ -16,3 +16,4 @@ setup(name='twik',
'console_scripts': ['twik = twik.run:main'], 'console_scripts': ['twik = twik.run:main'],
}, },
) )

View File

@ -7,8 +7,7 @@ class SimpleTest(unittest.TestCase):
def testPasswordAphanumericAndSpecialChars(self): def testPasswordAphanumericAndSpecialChars(self):
for chars in range(4, 27): for chars in range(4, 27):
password = self.t.getpassword('tag', password = self.t.getpassword('tag', 'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', chars, 1)
'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', chars, 1)
if chars == 4: if chars == 4:
self.assertEqual(password, 'm3/I') self.assertEqual(password, 'm3/I')
if chars == 8: if chars == 8:
@ -23,8 +22,7 @@ class SimpleTest(unittest.TestCase):
def testPasswordAlphanumeric(self): def testPasswordAlphanumeric(self):
for chars in range(4, 27): for chars in range(4, 27):
password = self.t.getpassword('tag', password = self.t.getpassword('tag', 'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', chars, 2)
'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', chars, 2)
if chars == 4: if chars == 4:
self.assertEqual(password, 'm31I') self.assertEqual(password, 'm31I')
if chars == 8: if chars == 8:
@ -38,8 +36,7 @@ class SimpleTest(unittest.TestCase):
def testPasswordNumeric(self): def testPasswordNumeric(self):
for chars in range(4, 27): for chars in range(4, 27):
password = self.t.getpassword('tag', password = self.t.getpassword('tag', 'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', chars, 3)
'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', chars, 3)
if chars == 4: if chars == 4:
self.assertEqual(password, '4315') self.assertEqual(password, '4315')
if chars == 8: if chars == 8:
@ -53,17 +50,14 @@ class SimpleTest(unittest.TestCase):
def testSize(self): def testSize(self):
for chars in range(4, 27): for chars in range(4, 27):
password = self.t.getpassword('tag', password = self.t.getpassword('tag', 'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', chars, 1)
'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', chars, 1)
self.assertEqual(len(password), chars) self.assertEqual(len(password), chars)
def testSizeWrong(self): def testSizeWrong(self):
password = self.t.getpassword('tag', password = self.t.getpassword('tag', 'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', 100, 1)
'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', 100, 1)
self.assertEqual(password, None) self.assertEqual(password, None)
def testSize(self): def testSize(self):
password = self.t.getpassword('tag', password = self.t.getpassword('tag', 'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', 0, 1)
'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', 0, 1)
self.assertEqual(password, None) self.assertEqual(password, None)
def tearDown(self): def tearDown(self):

View File

@ -18,8 +18,8 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Twik. If not, see <http://www.gnu.org/licenses/>. along with Twik. If not, see <http://www.gnu.org/licenses/>.
""" """
from util import Util from .util import Util
from twik import Twik from .twik import Twik
import getpass import getpass
import argparse import argparse
import sys import sys
@ -34,7 +34,7 @@ def main():
parser.add_argument("tag", type=str, parser.add_argument("tag", type=str,
help="generate password for a specified tag") help="generate password for a specified tag")
parser.add_argument("-c", "--chars", type=int, parser.add_argument("-c", "--chars", type=int,
choices=range(4, 27), choices=list(range(4, 27)),
metavar="[4-26]", metavar="[4-26]",
help="length of generated password [4-26]. Default: 12") help="length of generated password [4-26]. Default: 12")
parser.add_argument("-p", "--profile", type=str, default=None, parser.add_argument("-p", "--profile", type=str, default=None,
@ -53,16 +53,18 @@ def main():
try: try:
master_key = getpass.getpass(prompt='Master Key: ') master_key = getpass.getpass(prompt='Master Key: ')
except KeyboardInterrupt: except KeyboardInterrupt:
print "^C" print("^C")
raise SystemExit(0) raise SystemExit(0)
twik = Twik() twik = Twik()
password = twik.getpassword(args.tag, util.get_privatekey(), master_key, password = twik.getpassword(args.tag, util.get_privatekey(), master_key,
util.get_chars(), util.get_passord_type()) util.get_chars(), util.get_passord_type())
print "Your password is %s" % password print(password, end='')
print('', file=sys.stderr)
if __name__ == "__main__": if __name__ == "__main__":
main() main()
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 # vim: tabstop=4 shiftwidth=4 softtabstop=4

View File

@ -24,12 +24,14 @@ You should have received a copy of the GNU General Public License
along with Twik. If not, see <http://www.gnu.org/licenses/>. along with Twik. If not, see <http://www.gnu.org/licenses/>.
""" """
from hashlib import sha1
from util import Util
import hmac
import getpass
import argparse import argparse
import base64
import getpass
import hmac
import sys import sys
from hashlib import sha1
from .util import Util
class Twik(object): class Twik(object):
@ -41,7 +43,7 @@ class Twik(object):
char = ord(mhash[tmp]) char = ord(mhash[tmp])
if char >= ord(cstart) and char < ord(cstart) + cnum: if char >= ord(cstart) and char < ord(cstart) + cnum:
return mhash return mhash
head = mhash[:pos] if pos > 0 else "" head = mhash[:pos] if pos > 0 else ''
inject = ((seed + ord(mhash[pos])) % cnum) + ord(cstart) inject = ((seed + ord(mhash[pos])) % cnum) + ord(cstart)
tail = mhash[pos+1:] if (pos + 1 < len(mhash)) else mhash tail = mhash[pos+1:] if (pos + 1 < len(mhash)) else mhash
return head + chr(inject) + tail return head + chr(inject) + tail
@ -54,7 +56,7 @@ class Twik(object):
if not inputchars[i].isdigit() and not inputchars[i].isalpha(): if not inputchars[i].isdigit() and not inputchars[i].isalpha():
inputchars[i] = chr(((seed + pivot) % 26 + ord('A'))) inputchars[i] = chr(((seed + pivot) % 26 + ord('A')))
pivot = i + 1 pivot = i + 1
return "".join(inputchars) return ''.join(inputchars)
def converttodigits(self, mhash, seed, length): def converttodigits(self, mhash, seed, length):
inputchars = list(mhash) inputchars = list(mhash)
@ -64,28 +66,26 @@ class Twik(object):
inputchars[i] = chr(((seed + ord(inputchars[pivot])) % 10 + inputchars[i] = chr(((seed + ord(inputchars[pivot])) % 10 +
ord('0'))) ord('0')))
pivot = i + 1 pivot = i + 1
return "".join(inputchars) return ''.join(inputchars)
def generatehash(self, tag, key, length, password_type): def generatehash(self, tag, key, length, password_type):
digest = hmac.new(key, tag, sha1).digest() digest = hmac.new(str.encode(key), str.encode(tag), sha1).digest()
mhash = digest.encode('base64')[:-2] mhash = base64.b64encode(digest)[:-1]
mhash = mhash.decode('utf-8')
seed = sum([ord(i) for i in mhash])
seed = 0 # NUMERIC
for i in range(0, len(mhash)):
seed += ord(mhash[i])
"""NUMERIC"""
if password_type == 3: if password_type == 3:
mhash = self.converttodigits(mhash, seed, length) mhash = self.converttodigits(mhash, seed, length)
else: else:
mhash = self.injectcharacter(mhash, 0, 4, seed, length, '0', 10) mhash = self.injectcharacter(mhash, 0, 4, seed, length, '0', 10)
"""ALPHANUMERIC_AND_SPECIAL_CHARS""" # ALPHANUMERIC_AND_SPECIAL_CHARS
if password_type == 1: if password_type == 1:
mhash = self.injectcharacter(mhash, 1, 4, seed, length, '!', 15) mhash = self.injectcharacter(mhash, 1, 4, seed, length, '!', 15)
mhash = self.injectcharacter(mhash, 2, 4, seed, length, 'A', 26) mhash = self.injectcharacter(mhash, 2, 4, seed, length, 'A', 26)
mhash = self.injectcharacter(mhash, 3, 4, seed, length, 'a', 26) mhash = self.injectcharacter(mhash, 3, 4, seed, length, 'a', 26)
"""ALPHANUMERIC""" # ALPHANUMERIC
if password_type == 2: if password_type == 2:
mhash = self.removespecialcharacters(mhash, seed, length) mhash = self.removespecialcharacters(mhash, seed, length)
@ -99,4 +99,5 @@ class Twik(object):
password = self.generatehash(mhash, master_key, length, password_type) password = self.generatehash(mhash, master_key, length, password_type)
return password return password
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 # vim: tabstop=4 shiftwidth=4 softtabstop=4

View File

@ -24,8 +24,9 @@ You should have received a copy of the GNU General Public License
along with Twik. If not, see <http://www.gnu.org/licenses/>. along with Twik. If not, see <http://www.gnu.org/licenses/>.
""" """
import configparser
import os.path import os.path
import ConfigParser import sys
from random import SystemRandom from random import SystemRandom
def privatekeygenerator(): def privatekeygenerator():
@ -55,7 +56,7 @@ class Util(object):
""" """
homedir = os.path.expanduser('~') homedir = os.path.expanduser('~')
self.filename = os.path.join(homedir, '.twik.conf') self.filename = os.path.join(homedir, '.twik.conf')
self.config = ConfigParser.ConfigParser() self.config = configparser.ConfigParser()
self.config.read(self.filename) self.config.read(self.filename)
self.tag = tag self.tag = tag
self.chars = chars self.chars = chars
@ -83,7 +84,7 @@ class Util(object):
break break
if self.profile == None: if self.profile == None:
self.profile = self.config.sections()[0] self.profile = self.config.sections()[0]
print 'Using profile : %s' % self.profile print(f'Using profile: {self.profile}', file=sys.stderr)
if self.profile and self.config.has_option(self.profile, 'private_key'): if self.profile and self.config.has_option(self.profile, 'private_key'):
private_key = self.config.get(self.profile, 'private_key') private_key = self.config.get(self.profile, 'private_key')
@ -104,29 +105,29 @@ class Util(object):
if self.profile == 'Personal': if self.profile == 'Personal':
self.config.set(self.profile, 'default', 1) self.config.set(self.profile, 'default', 1)
self.writeconfig() self.writeconfig()
print 'New profile is generated' print('New profile is generated')
self.config.read(self.filename) self.config.read(self.filename)
return private_key return private_key
def get_chars(self): def get_chars(self):
config_key = '%s_chars' % self.tag config_key = f'{self.tag}_chars'
if self.config.has_option(self.profile, config_key) and self.chars == None: if self.config.has_option(self.profile, config_key) and self.chars == None:
self.chars = self.config.getint(self.profile, config_key) self.chars = self.config.getint(self.profile, config_key)
else: else:
if self.chars == None and self.config.has_option(self.profile, 'chars'): if self.chars == None and self.config.has_option(self.profile, 'chars'):
self.chars = self.config.getint(self.profile, 'chars') self.chars = self.config.getint(self.profile, 'chars')
self.config.set(self.profile, config_key, self.chars) self.config.set(self.profile, config_key, str(self.chars))
self.writeconfig() self.writeconfig()
if self.chars < 4 or self.chars > 26: if self.chars < 4 or self.chars > 26:
print 'invalid password length value from configuration using default' print('invalid password length value from configuration using default')
self.chars = 12 self.chars = 12
return self.chars return self.chars
def get_passord_type(self): def get_passord_type(self):
config_key = '%s_password_type' % self.tag config_key = f'{self.tag}_password_type'
if self.config.has_option(self.profile, config_key) and self.pass_type == None: if self.config.has_option(self.profile, config_key) and self.pass_type == None:
self.pass_type = self.config.getint(self.profile, config_key) self.pass_type = self.config.getint(self.profile, config_key)
@ -134,13 +135,14 @@ class Util(object):
if self.pass_type == None and self.config.has_option(self.profile, 'password_type'): if self.pass_type == None and self.config.has_option(self.profile, 'password_type'):
self.pass_type = self.config.getint(self.profile, 'password_type') self.pass_type = self.config.getint(self.profile, 'password_type')
self.config.set(self.profile, config_key, self.pass_type) self.config.set(self.profile, config_key, str(self.pass_type))
self.writeconfig() self.writeconfig()
if self.pass_type < 1 or self.pass_type > 3: if self.pass_type < 1 or self.pass_type > 3:
print 'invalid password type value from configuration using default' print('invalid password type value from configuration using default')
self.pass_type = 1 self.pass_type = 1
return self.pass_type return self.pass_type
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 # vim: tabstop=4 shiftwidth=4 softtabstop=4