Update to python 3
This commit is contained in:
parent
432c3359c1
commit
03a3edbd5b
|
@ -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/
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
language: python
|
|
||||||
python:
|
|
||||||
- "2.7"
|
|
||||||
- "pypy"
|
|
||||||
install: python setup.py install
|
|
||||||
script: nosetests
|
|
25
setup.py
25
setup.py
|
@ -4,15 +4,16 @@ import sys, os
|
||||||
version = '0.5'
|
version = '0.5'
|
||||||
|
|
||||||
setup(name='twik',
|
setup(name='twik',
|
||||||
version=version,
|
version=version,
|
||||||
description="Twik is an application that makes it easier to generate secure and different passwords for each website.",
|
description="Twik is an application that makes it easier to generate secure and different passwords for each website.",
|
||||||
keywords='twik password hash',
|
keywords='twik password hash',
|
||||||
author='Alexandre Possebom',
|
author='Alexandre Possebom',
|
||||||
author_email='alexandrepossebom@gmail.com',
|
author_email='alexandrepossebom@gmail.com',
|
||||||
url='https://github.com/coxande/Twik',
|
url='https://github.com/coxande/Twik',
|
||||||
license='GPLv3',
|
license='GPLv3',
|
||||||
packages=['twik'],
|
packages=['twik'],
|
||||||
entry_points = {
|
entry_points = {
|
||||||
'console_scripts': ['twik = twik.run:main'],
|
'console_scripts': ['twik = twik.run:main'],
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
114
tests/test.py
114
tests/test.py
|
@ -2,73 +2,67 @@ import unittest
|
||||||
from twik import twik
|
from twik import twik
|
||||||
|
|
||||||
class SimpleTest(unittest.TestCase):
|
class SimpleTest(unittest.TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.t = twik.Twik()
|
self.t = twik.Twik()
|
||||||
|
|
||||||
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:
|
self.assertEqual(password, 'mb/5AsJ9')
|
||||||
self.assertEqual(password, 'mb/5AsJ9')
|
if chars == 12:
|
||||||
if chars == 12:
|
self.assertEqual(password, 'mb/5AsJ9Uon7')
|
||||||
self.assertEqual(password, 'mb/5AsJ9Uon7')
|
if chars == 22:
|
||||||
if chars == 22:
|
self.assertEqual(password, 'mb15As*9Uon7ZzvcsXMjpV')
|
||||||
self.assertEqual(password, 'mb15As*9Uon7ZzvcsXMjpV')
|
if chars == 26:
|
||||||
if chars == 26:
|
self.assertEqual(password, 'mb15AsJ9&on7ZzvcsXMjpVLTqQ')
|
||||||
self.assertEqual(password, 'mb15AsJ9&on7ZzvcsXMjpVLTqQ')
|
|
||||||
|
|
||||||
|
|
||||||
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:
|
self.assertEqual(password, 'mb15AsJ9')
|
||||||
self.assertEqual(password, 'mb15AsJ9')
|
if chars == 12:
|
||||||
if chars == 12:
|
self.assertEqual(password, 'mb15AsJ9Uon7')
|
||||||
self.assertEqual(password, 'mb15AsJ9Uon7')
|
if chars == 22:
|
||||||
if chars == 22:
|
self.assertEqual(password, 'mb15AsJ9Uon7ZzvcsXMjpV')
|
||||||
self.assertEqual(password, 'mb15AsJ9Uon7ZzvcsXMjpV')
|
if chars == 26:
|
||||||
if chars == 26:
|
self.assertEqual(password, 'mb15AsJ9Uon7ZzvcsXMjpVLTqQ')
|
||||||
self.assertEqual(password, 'mb15AsJ9Uon7ZzvcsXMjpVLTqQ')
|
|
||||||
|
|
||||||
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:
|
self.assertEqual(password, '43154099')
|
||||||
self.assertEqual(password, '43154099')
|
if chars == 12:
|
||||||
if chars == 12:
|
self.assertEqual(password, '431540992657')
|
||||||
self.assertEqual(password, '431540992657')
|
if chars == 22:
|
||||||
if chars == 22:
|
self.assertEqual(password, '4315409926570734032171')
|
||||||
self.assertEqual(password, '4315409926570734032171')
|
if chars == 26:
|
||||||
if chars == 26:
|
self.assertEqual(password, '43154099265707340321711986')
|
||||||
self.assertEqual(password, '43154099265707340321711986')
|
|
||||||
|
|
||||||
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', 'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', 0, 1)
|
||||||
password = self.t.getpassword('tag',
|
self.assertEqual(password, None)
|
||||||
'TFCY2AJI-NBPU-V01E-F7CP-PJIZNRKPF25W', 'foobar', 0, 1)
|
|
||||||
self.assertEqual(password, None)
|
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
self.t = None
|
self.t = None
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
||||||
|
|
74
twik/run.py
74
twik/run.py
|
@ -18,51 +18,53 @@ 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
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""
|
"""
|
||||||
ALPHANUMERIC_AND_SPECIAL_CHARS=1
|
ALPHANUMERIC_AND_SPECIAL_CHARS=1
|
||||||
ALPHANUMERIC=2
|
ALPHANUMERIC=2
|
||||||
NUMERIC=3
|
NUMERIC=3
|
||||||
"""
|
"""
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
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,
|
||||||
help="profile to use. Default:'Personal'")
|
help="profile to use. Default:'Personal'")
|
||||||
parser.add_argument("-t", "--passwordtype", type=int, choices=[1, 2, 3],
|
parser.add_argument("-t", "--passwordtype", type=int, choices=[1, 2, 3],
|
||||||
help='''
|
help='''
|
||||||
1 for ALPHANUMERIC_AND_SPECIAL_CHAR
|
1 for ALPHANUMERIC_AND_SPECIAL_CHAR
|
||||||
2 for ALPHANUMERIC
|
2 for ALPHANUMERIC
|
||||||
3 for NUMERIC
|
3 for NUMERIC
|
||||||
Default: 1
|
Default: 1
|
||||||
''')
|
''')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
util = Util(args.tag, args.chars, args.passwordtype, args.profile)
|
util = Util(args.tag, args.chars, args.passwordtype, args.profile)
|
||||||
|
|
||||||
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=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
|
||||||
|
|
123
twik/twik.py
123
twik/twik.py
|
@ -24,79 +24,80 @@ 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):
|
||||||
def injectcharacter(self, mhash, offset, reserved, seed, length, cstart, cnum):
|
def injectcharacter(self, mhash, offset, reserved, seed, length, cstart, cnum):
|
||||||
pos0 = seed % length
|
pos0 = seed % length
|
||||||
pos = (pos0 + offset) % length
|
pos = (pos0 + offset) % length
|
||||||
for i in range(0, length - reserved):
|
for i in range(0, length - reserved):
|
||||||
tmp = (pos0 + reserved + i) % length
|
tmp = (pos0 + reserved + i) % length
|
||||||
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
|
||||||
|
|
||||||
|
|
||||||
def removespecialcharacters(self, mhash, seed, length):
|
def removespecialcharacters(self, mhash, seed, length):
|
||||||
inputchars = list(mhash)
|
inputchars = list(mhash)
|
||||||
pivot = 0
|
pivot = 0
|
||||||
for i in range(0, length):
|
for i in range(0, length):
|
||||||
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)
|
||||||
pivot = 0
|
pivot = 0
|
||||||
for i in range(0, length):
|
for i in range(0, length):
|
||||||
if not inputchars[i].isdigit():
|
if not inputchars[i].isdigit():
|
||||||
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)):
|
if password_type == 3:
|
||||||
seed += ord(mhash[i])
|
mhash = self.converttodigits(mhash, seed, length)
|
||||||
|
else:
|
||||||
|
mhash = self.injectcharacter(mhash, 0, 4, seed, length, '0', 10)
|
||||||
|
# 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)
|
||||||
|
|
||||||
"""NUMERIC"""
|
# ALPHANUMERIC
|
||||||
if password_type == 3:
|
if password_type == 2:
|
||||||
mhash = self.converttodigits(mhash, seed, length)
|
mhash = self.removespecialcharacters(mhash, seed, length)
|
||||||
else:
|
|
||||||
mhash = self.injectcharacter(mhash, 0, 4, seed, length, '0', 10)
|
|
||||||
"""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"""
|
return mhash[:length]
|
||||||
if password_type == 2:
|
|
||||||
mhash = self.removespecialcharacters(mhash, seed, length)
|
|
||||||
|
|
||||||
return mhash[:length]
|
|
||||||
|
|
||||||
|
|
||||||
def getpassword(self, tag, private_key, master_key, length, password_type):
|
def getpassword(self, tag, private_key, master_key, length, password_type):
|
||||||
if length > 26 or length < 4:
|
if length > 26 or length < 4:
|
||||||
return None
|
return None
|
||||||
mhash = self.generatehash(private_key, tag, 24, 1)
|
mhash = self.generatehash(private_key, tag, 24, 1)
|
||||||
password = self.generatehash(mhash, master_key, length, password_type)
|
password = self.generatehash(mhash, master_key, length, password_type)
|
||||||
return password
|
return password
|
||||||
|
|
||||||
|
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
|
||||||
|
|
204
twik/util.py
204
twik/util.py
|
@ -24,123 +24,125 @@ 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():
|
||||||
"""
|
"""
|
||||||
Generate new private key
|
Generate new private key
|
||||||
"""
|
"""
|
||||||
subgroups_length = [8, 4, 4, 4, 12]
|
subgroups_length = [8, 4, 4, 4, 12]
|
||||||
subgroup_separator = '-'
|
subgroup_separator = '-'
|
||||||
allowed_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
allowed_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||||
systemrandom = SystemRandom()
|
systemrandom = SystemRandom()
|
||||||
allowedcharslength = len(allowed_chars)
|
allowedcharslength = len(allowed_chars)
|
||||||
key = ""
|
key = ""
|
||||||
for i in range(0, len(subgroups_length)):
|
for i in range(0, len(subgroups_length)):
|
||||||
for j in range(0, subgroups_length[i]):
|
for j in range(0, subgroups_length[i]):
|
||||||
key += allowed_chars[systemrandom.randrange(allowedcharslength)]
|
key += allowed_chars[systemrandom.randrange(allowedcharslength)]
|
||||||
if i < (len(subgroups_length) -1):
|
if i < (len(subgroups_length) -1):
|
||||||
key += subgroup_separator
|
key += subgroup_separator
|
||||||
return key
|
return key
|
||||||
|
|
||||||
class Util(object):
|
class Util(object):
|
||||||
"""
|
"""
|
||||||
Class for deal with config file
|
Class for deal with config file
|
||||||
"""
|
"""
|
||||||
def __init__(self, tag, chars, pass_type, profile):
|
def __init__(self, tag, chars, pass_type, profile):
|
||||||
"""
|
"""
|
||||||
Constructor
|
Constructor
|
||||||
"""
|
"""
|
||||||
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
|
||||||
self.profile = profile
|
self.profile = profile
|
||||||
self.pass_type = pass_type
|
self.pass_type = pass_type
|
||||||
#Initialize default values
|
#Initialize default values
|
||||||
self.get_privatekey()
|
self.get_privatekey()
|
||||||
|
|
||||||
def writeconfig(self):
|
def writeconfig(self):
|
||||||
"""
|
"""
|
||||||
Write config file
|
Write config file
|
||||||
"""
|
"""
|
||||||
with open(self.filename, 'w+') as fileconfig:
|
with open(self.filename, 'w+') as fileconfig:
|
||||||
self.config.write(fileconfig)
|
self.config.write(fileconfig)
|
||||||
|
|
||||||
def get_privatekey(self):
|
def get_privatekey(self):
|
||||||
"""
|
"""
|
||||||
Get private key if not exists create new one
|
Get private key if not exists create new one
|
||||||
"""
|
"""
|
||||||
private_key = ''
|
private_key = ''
|
||||||
if self.profile == None and len(self.config.sections()) > 0:
|
if self.profile == None and len(self.config.sections()) > 0:
|
||||||
for session in self.config.sections():
|
for session in self.config.sections():
|
||||||
if self.config.has_option(session, 'default') and self.config.getboolean(session, 'default') == True:
|
if self.config.has_option(session, 'default') and self.config.getboolean(session, 'default') == True:
|
||||||
self.profile = session
|
self.profile = session
|
||||||
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')
|
||||||
else:
|
else:
|
||||||
private_key = privatekeygenerator()
|
private_key = privatekeygenerator()
|
||||||
if self.profile == None:
|
if self.profile == None:
|
||||||
self.profile = 'Personal'
|
self.profile = 'Personal'
|
||||||
self.config.add_section(self.profile)
|
self.config.add_section(self.profile)
|
||||||
self.config.set(self.profile, 'private_key', private_key)
|
self.config.set(self.profile, 'private_key', private_key)
|
||||||
chars = self.chars
|
chars = self.chars
|
||||||
if chars == None:
|
if chars == None:
|
||||||
chars = 12
|
chars = 12
|
||||||
pass_type = self.pass_type
|
pass_type = self.pass_type
|
||||||
if pass_type == None:
|
if pass_type == None:
|
||||||
pass_type = 1
|
pass_type = 1
|
||||||
self.config.set(self.profile, 'chars', chars)
|
self.config.set(self.profile, 'chars', chars)
|
||||||
self.config.set(self.profile, 'password_type', pass_type)
|
self.config.set(self.profile, 'password_type', pass_type)
|
||||||
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)
|
||||||
else:
|
else:
|
||||||
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=4 shiftwidth=4 softtabstop=4
|
||||||
|
|
||||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
|
||||||
|
|
Loading…
Reference in New Issue