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

@ -15,4 +15,5 @@ setup(name='twik',
entry_points = {
'console_scripts': ['twik = twik.run:main'],
},
)
)

View File

@ -7,8 +7,7 @@ class SimpleTest(unittest.TestCase):
def testPasswordAphanumericAndSpecialChars(self):
for chars in range(4, 27):
password = self.t.getpassword('tag',
'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', chars, 1)
password = self.t.getpassword('tag', 'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', chars, 1)
if chars == 4:
self.assertEqual(password, 'm3/I')
if chars == 8:
@ -23,8 +22,7 @@ class SimpleTest(unittest.TestCase):
def testPasswordAlphanumeric(self):
for chars in range(4, 27):
password = self.t.getpassword('tag',
'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', chars, 2)
password = self.t.getpassword('tag', 'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', chars, 2)
if chars == 4:
self.assertEqual(password, 'm31I')
if chars == 8:
@ -38,8 +36,7 @@ class SimpleTest(unittest.TestCase):
def testPasswordNumeric(self):
for chars in range(4, 27):
password = self.t.getpassword('tag',
'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', chars, 3)
password = self.t.getpassword('tag', 'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', chars, 3)
if chars == 4:
self.assertEqual(password, '4315')
if chars == 8:
@ -53,17 +50,14 @@ class SimpleTest(unittest.TestCase):
def testSize(self):
for chars in range(4, 27):
password = self.t.getpassword('tag',
'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', chars, 1)
password = self.t.getpassword('tag', 'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', chars, 1)
self.assertEqual(len(password), chars)
def testSizeWrong(self):
password = self.t.getpassword('tag',
'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', 100, 1)
password = self.t.getpassword('tag', 'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', 100, 1)
self.assertEqual(password, None)
def testSize(self):
password = self.t.getpassword('tag',
'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', 0, 1)
password = self.t.getpassword('tag', 'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', 0, 1)
self.assertEqual(password, None)
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
along with Twik. If not, see <http://www.gnu.org/licenses/>.
"""
from util import Util
from twik import Twik
from .util import Util
from .twik import Twik
import getpass
import argparse
import sys
@ -34,7 +34,7 @@ def main():
parser.add_argument("tag", type=str,
help="generate password for a specified tag")
parser.add_argument("-c", "--chars", type=int,
choices=range(4, 27),
choices=list(range(4, 27)),
metavar="[4-26]",
help="length of generated password [4-26]. Default: 12")
parser.add_argument("-p", "--profile", type=str, default=None,
@ -53,16 +53,18 @@ def main():
try:
master_key = getpass.getpass(prompt='Master Key: ')
except KeyboardInterrupt:
print "^C"
print("^C")
raise SystemExit(0)
twik = Twik()
password = twik.getpassword(args.tag, util.get_privatekey(), master_key,
util.get_chars(), util.get_passord_type())
print "Your password is %s" % password
print(password, end='')
print('', file=sys.stderr)
if __name__ == "__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/>.
"""
from hashlib import sha1
from util import Util
import hmac
import getpass
import argparse
import base64
import getpass
import hmac
import sys
from hashlib import sha1
from .util import Util
class Twik(object):
@ -41,7 +43,7 @@ class Twik(object):
char = ord(mhash[tmp])
if char >= ord(cstart) and char < ord(cstart) + cnum:
return mhash
head = mhash[:pos] if pos > 0 else ""
head = mhash[:pos] if pos > 0 else ''
inject = ((seed + ord(mhash[pos])) % cnum) + ord(cstart)
tail = mhash[pos+1:] if (pos + 1 < len(mhash)) else mhash
return head + chr(inject) + tail
@ -54,7 +56,7 @@ class Twik(object):
if not inputchars[i].isdigit() and not inputchars[i].isalpha():
inputchars[i] = chr(((seed + pivot) % 26 + ord('A')))
pivot = i + 1
return "".join(inputchars)
return ''.join(inputchars)
def converttodigits(self, mhash, seed, length):
inputchars = list(mhash)
@ -64,28 +66,26 @@ class Twik(object):
inputchars[i] = chr(((seed + ord(inputchars[pivot])) % 10 +
ord('0')))
pivot = i + 1
return "".join(inputchars)
return ''.join(inputchars)
def generatehash(self, tag, key, length, password_type):
digest = hmac.new(key, tag, sha1).digest()
mhash = digest.encode('base64')[:-2]
digest = hmac.new(str.encode(key), str.encode(tag), sha1).digest()
mhash = base64.b64encode(digest)[:-1]
mhash = mhash.decode('utf-8')
seed = sum([ord(i) for i in mhash])
seed = 0
for i in range(0, len(mhash)):
seed += ord(mhash[i])
"""NUMERIC"""
# NUMERIC
if password_type == 3:
mhash = self.converttodigits(mhash, seed, length)
else:
mhash = self.injectcharacter(mhash, 0, 4, seed, length, '0', 10)
"""ALPHANUMERIC_AND_SPECIAL_CHARS"""
# ALPHANUMERIC_AND_SPECIAL_CHARS
if password_type == 1:
mhash = self.injectcharacter(mhash, 1, 4, seed, length, '!', 15)
mhash = self.injectcharacter(mhash, 2, 4, seed, length, 'A', 26)
mhash = self.injectcharacter(mhash, 3, 4, seed, length, 'a', 26)
"""ALPHANUMERIC"""
# ALPHANUMERIC
if password_type == 2:
mhash = self.removespecialcharacters(mhash, seed, length)
@ -99,4 +99,5 @@ class Twik(object):
password = self.generatehash(mhash, master_key, length, password_type)
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/>.
"""
import configparser
import os.path
import ConfigParser
import sys
from random import SystemRandom
def privatekeygenerator():
@ -55,7 +56,7 @@ class Util(object):
"""
homedir = os.path.expanduser('~')
self.filename = os.path.join(homedir, '.twik.conf')
self.config = ConfigParser.ConfigParser()
self.config = configparser.ConfigParser()
self.config.read(self.filename)
self.tag = tag
self.chars = chars
@ -83,7 +84,7 @@ class Util(object):
break
if self.profile == None:
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'):
private_key = self.config.get(self.profile, 'private_key')
@ -104,29 +105,29 @@ class Util(object):
if self.profile == 'Personal':
self.config.set(self.profile, 'default', 1)
self.writeconfig()
print 'New profile is generated'
print('New profile is generated')
self.config.read(self.filename)
return private_key
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:
self.chars = self.config.getint(self.profile, config_key)
else:
if self.chars == None and self.config.has_option(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()
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
return self.chars
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:
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'):
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()
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
return self.pass_type
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
# vim: tabstop=4 shiftwidth=4 softtabstop=4