Compare commits
No commits in common. "fc147deb89a23c79935df7e41b4412facc931c6a" and "2b7709c2aed3eab22f213834bfa95677d3998d37" have entirely different histories.
fc147deb89
...
2b7709c2ae
@ -115,8 +115,11 @@ def credentials_ini_fmt(k, v):
|
|||||||
|
|
||||||
def credentials_ini(label, setting):
|
def credentials_ini(label, setting):
|
||||||
r = "[{}]\n".format(label)
|
r = "[{}]\n".format(label)
|
||||||
for k, v in setting.items():
|
dictitems = getattr(type(setting), "items", None)
|
||||||
r.append("{}={}\n".format(k, v))
|
if dictitems and callable(dictitems):
|
||||||
|
r += "\n".join([credentials_ini_fmt(k, v) for k, v in setting.items()])
|
||||||
|
else:
|
||||||
|
r += credentials_ini_fmt(label, str(setting))
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
@ -130,7 +133,6 @@ def main():
|
|||||||
epilog="",
|
epilog="",
|
||||||
add_help=True)
|
add_help=True)
|
||||||
parser.add_argument("-c", "--config", help="Use time localization settings from a pyhton config file (omit the .py extension)", default=None)
|
parser.add_argument("-c", "--config", help="Use time localization settings from a pyhton config file (omit the .py extension)", default=None)
|
||||||
parser.add_argument("-k", "--keyfile", help="Keyfile used for decryption", default=None)
|
|
||||||
parser.add_argument("--plain", help="Output credentials in plain ini format", action="store_true")
|
parser.add_argument("--plain", help="Output credentials in plain ini format", action="store_true")
|
||||||
parser.add_argument("--minimal", help="Only print OAuth credentials, ignoring encryption settings", action="store_true")
|
parser.add_argument("--minimal", help="Only print OAuth credentials, ignoring encryption settings", action="store_true")
|
||||||
arguments = parser.parse_args()
|
arguments = parser.parse_args()
|
||||||
@ -180,15 +182,11 @@ def main():
|
|||||||
ans = _input("Do you want to encrypt your credentials? (y/n)", default("encrypt"))
|
ans = _input("Do you want to encrypt your credentials? (y/n)", default("encrypt"))
|
||||||
if ans.upper() in ("Y", "YES"):
|
if ans.upper() in ("Y", "YES"):
|
||||||
encrypt = True
|
encrypt = True
|
||||||
salt, settings_server = encryption.settings_server_encrypt(settings_server, arguments.keyfile)
|
salt, settings_server = encryption.settings_server_encrypt_cfg(settings_server)
|
||||||
|
|
||||||
settings_encrypt = OrderedDict([
|
settings_encrypt = OrderedDict([
|
||||||
("encrypt", encrypt),
|
("encrypt", encrypt),
|
||||||
("salt", salt),
|
("salt", salt),
|
||||||
("keyfile", arguments.keyfile)
|
|
||||||
])
|
|
||||||
settings_reminder = OrderedDict([
|
|
||||||
("settings_reminder", reminder)
|
|
||||||
])
|
])
|
||||||
|
|
||||||
# Credential formatting functions
|
# Credential formatting functions
|
||||||
@ -198,7 +196,7 @@ def main():
|
|||||||
print("Copy to your config file!!!")
|
print("Copy to your config file!!!")
|
||||||
print(formatted_credentials("settings_server", settings_server))
|
print(formatted_credentials("settings_server", settings_server))
|
||||||
if not arguments.minimal:
|
if not arguments.minimal:
|
||||||
print("\n{}\n".format(formatted_credentials("settings_reminder", settings_reminder)))
|
print("\n{}\n".format(formatted_credentials("settings_reminder", reminder)))
|
||||||
print(formatted_credentials("settings_encrypt", settings_encrypt))
|
print(formatted_credentials("settings_encrypt", settings_encrypt))
|
||||||
|
|
||||||
print("Success :)")
|
print("Success :)")
|
||||||
|
@ -28,13 +28,15 @@ from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
|
|||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
|
||||||
class EncryptionFail(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class PasswordMismatch(Exception):
|
class PasswordMismatch(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# Salts
|
||||||
|
def generate_salt():
|
||||||
|
return os.urandom(16)
|
||||||
|
|
||||||
|
|
||||||
# Return string from bytes
|
# Return string from bytes
|
||||||
def salt_encode(b):
|
def salt_encode(b):
|
||||||
return base64.urlsafe_b64encode(b).decode()
|
return base64.urlsafe_b64encode(b).decode()
|
||||||
@ -70,7 +72,8 @@ def derive_key(password, salt):
|
|||||||
iterations=100000,
|
iterations=100000,
|
||||||
backend=default_backend()
|
backend=default_backend()
|
||||||
)
|
)
|
||||||
return base64.urlsafe_b64encode(kdf.derive(password))
|
r_key = base64.urlsafe_b64encode(kdf.derive(password))
|
||||||
|
return r_key
|
||||||
|
|
||||||
|
|
||||||
# Encryption functions
|
# Encryption functions
|
||||||
@ -96,62 +99,94 @@ def decrypt(token, key):
|
|||||||
# encryption_function: encrypt(message, key) : decrypt(token, key):
|
# encryption_function: encrypt(message, key) : decrypt(token, key):
|
||||||
# Returns settings_server_decrypted dictionary with Byte() values. Will need to use
|
# Returns settings_server_decrypted dictionary with Byte() values. Will need to use
|
||||||
# ChangeEncodingDict to make them strings (recommended cfg file friendly)
|
# ChangeEncodingDict to make them strings (recommended cfg file friendly)
|
||||||
def encrypt_settings(settings_server, password, salt, encryption_function):
|
def __settings_server(password, salt, settings_server, encryption_function):
|
||||||
key = derive_key(password, salt)
|
key = derive_key(password, salt)
|
||||||
settings_server_decrypted = OrderedDict()
|
settings_server_decrypted = OrderedDict()
|
||||||
for setting in settings_server:
|
for setting in settings_server:
|
||||||
settings_server_decrypted[setting] = encryption_function(settings_server[setting], key)
|
settings_server_decrypted[setting] = encryption_function(settings_server[setting], key)
|
||||||
return settings_server_decrypted
|
return settings_server_decrypted
|
||||||
|
|
||||||
def get_keyfile(keyfile=None):
|
|
||||||
if keyfile is not None:
|
|
||||||
with open(keyfile, "rb") as f:
|
|
||||||
return f.read()
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
# Returns (salt, settings_server)
|
||||||
|
def _settings_server_encrypt(settings_server):
|
||||||
|
salt = generate_salt()
|
||||||
|
password = getpass.getpass("Enter password: ")
|
||||||
|
password2 = getpass.getpass("Retype Password: ")
|
||||||
|
|
||||||
def get_pass(q):
|
|
||||||
try:
|
|
||||||
return getpass.getpass(q).encode()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
raise EncryptionFail("\nQuitting...")
|
|
||||||
|
|
||||||
|
|
||||||
def settings_server_encrypt(settings_server, keyfile=None):
|
|
||||||
try:
|
|
||||||
settings_server = encode_dict(settings_server)
|
|
||||||
salt = os.urandom(16)
|
|
||||||
password = get_keyfile(keyfile)
|
|
||||||
if password is None:
|
|
||||||
password = get_pass("Enter password: ")
|
|
||||||
password2 = get_pass("Enter password: ")
|
|
||||||
if password != password2:
|
if password != password2:
|
||||||
raise PasswordMismatch("Passwords do not match")
|
raise PasswordMismatch
|
||||||
encrypted = encrypt_settings(settings_server, password, salt, encrypt)
|
|
||||||
return salt_encode(salt), decode_dict(encrypted)
|
settings_server_encrypted = __settings_server(password.encode(), salt, encode_dict(settings_server), encrypt)
|
||||||
except PasswordMismatch as e:
|
|
||||||
raise EncryptionFail(str(e))
|
return salt, settings_server_encrypted
|
||||||
except Exception as e:
|
|
||||||
err = str(e)
|
|
||||||
raise EncryptionFail("Encrypt Error: {}".format(err))
|
|
||||||
|
|
||||||
|
|
||||||
def settings_server_decrypt(settings_server, settings_encrypt, keyfile=None):
|
# Returns (settings_server)
|
||||||
try:
|
def _settings_server_decrypt(settings_server, settings_encrypt):
|
||||||
if not settings_encrypt["encrypt"]:
|
settings_server_encoded = encode_dict(settings_server)
|
||||||
return settings_server
|
if settings_encrypt["encrypt"]:
|
||||||
settings_server = encode_dict(settings_server)
|
|
||||||
password = get_keyfile(keyfile or settings_encrypt["keyfile"]) or get_pass("Enter password: ")
|
|
||||||
salt = salt_decode(settings_encrypt["salt"])
|
salt = salt_decode(settings_encrypt["salt"])
|
||||||
decrypted = encrypt_settings(settings_server, password, salt, decrypt)
|
password = getpass.getpass("Enter password: ")
|
||||||
return decode_dict(decrypted)
|
return __settings_server(password.encode(), salt, settings_server_encoded, decrypt)
|
||||||
except base64.binascii.Error:
|
else:
|
||||||
raise EncryptionFail("Salt is invalid")
|
return settings_server_encoded
|
||||||
|
|
||||||
|
|
||||||
|
# Wrapper function that will catch exceptions and exit
|
||||||
|
def settings_server_new(function, **kwargs):
|
||||||
|
try:
|
||||||
|
return function(**kwargs)
|
||||||
|
|
||||||
|
# If the user cancels the login
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\nQuitting...")
|
||||||
|
|
||||||
|
# If the user passwords do not match (encrypt)
|
||||||
|
except PasswordMismatch:
|
||||||
|
print("Passwords do not match...")
|
||||||
|
|
||||||
|
# Incorrect password entered (decrypt)
|
||||||
except InvalidToken:
|
except InvalidToken:
|
||||||
raise EncryptionFail("Password or token is incorrect")
|
print("Password or Token Incorrect...")
|
||||||
|
|
||||||
|
# Probably the salt value got modified
|
||||||
|
except base64.binascii.Error:
|
||||||
|
print("Salt is invalid...")
|
||||||
|
|
||||||
|
# Some other kind of fuck up
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
err = str(e)
|
print("Unknown exception occurred...")
|
||||||
raise EncryptionFail("Decrypt Error: {}".format(err))
|
print(e)
|
||||||
|
|
||||||
|
# Exit if an exception was thrown
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
# Glue functions that package **kwargs automatically
|
||||||
|
def settings_server_encrypt(settings_server):
|
||||||
|
kwargs = {"settings_server": settings_server}
|
||||||
|
return settings_server_new(_settings_server_encrypt, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def settings_server_decrypt(settings_server, settings_encrypt):
|
||||||
|
kwargs = {
|
||||||
|
"settings_server": settings_server,
|
||||||
|
"settings_encrypt": settings_encrypt
|
||||||
|
}
|
||||||
|
return settings_server_new(_settings_server_decrypt, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
# The _cfg functions should return a regular string
|
||||||
|
# These are the functions that should interface with the bot a return a plain string
|
||||||
|
# settings_server ordered dictionary
|
||||||
|
def settings_server_encrypt_cfg(settings_server):
|
||||||
|
salt, settings_server = settings_server_encrypt(settings_server)
|
||||||
|
return salt_encode(salt), decode_dict(settings_server)
|
||||||
|
|
||||||
|
|
||||||
|
def settings_server_decrypt_cfg(settings_server, settings_encrypt):
|
||||||
|
settings_server = settings_server_decrypt(settings_server, settings_encrypt)
|
||||||
|
return decode_dict(settings_server)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
@ -167,7 +202,6 @@ def main():
|
|||||||
parser.add_argument("--encrypt", help="Generate encrypted authentication.", action="store_true")
|
parser.add_argument("--encrypt", help="Generate encrypted authentication.", action="store_true")
|
||||||
parser.add_argument("--decrypt", help="Decrypt encrypted authentication", action="store_true")
|
parser.add_argument("--decrypt", help="Decrypt encrypted authentication", action="store_true")
|
||||||
parser.add_argument("--recrypt", help="Recrypt encrypted authentication", action="store_true")
|
parser.add_argument("--recrypt", help="Recrypt encrypted authentication", action="store_true")
|
||||||
parser.add_argument("-k", "--keyfile", help="Keyfile used for decryption", default=None)
|
|
||||||
parser.add_argument("-c", "--cfg", help="Specify config file.", default=default_cfg)
|
parser.add_argument("-c", "--cfg", help="Specify config file.", default=default_cfg)
|
||||||
|
|
||||||
arguments = parser.parse_args()
|
arguments = parser.parse_args()
|
||||||
@ -180,28 +214,25 @@ def main():
|
|||||||
import importlib
|
import importlib
|
||||||
cfg = importlib.import_module(arguments.cfg)
|
cfg = importlib.import_module(arguments.cfg)
|
||||||
settings_server = cfg.settings_server
|
settings_server = cfg.settings_server
|
||||||
settings_encrypt = cfg.settings_encrypt
|
settings_encrypt = None
|
||||||
keyfile = arguments.keyfile or settings_encrypt["keyfile"]
|
|
||||||
|
|
||||||
if arguments.decrypt and arguments.encrypt:
|
if arguments.decrypt and arguments.encrypt:
|
||||||
print("Re-encrypting")
|
print("Re-encrypting")
|
||||||
|
|
||||||
if arguments.decrypt: # arguments.decrypt
|
if arguments.decrypt: # arguments.decrypt
|
||||||
print("Decrypt...")
|
print("Decrypt...")
|
||||||
settings_server = settings_server_decrypt(settings_server, settings_encrypt, arguments.keyfile)
|
settings_server = settings_server_decrypt_cfg(cfg.settings_server, cfg.settings_encrypt)
|
||||||
settings_encrypt = OrderedDict([
|
settings_encrypt = OrderedDict([
|
||||||
("encrypt", False),
|
("encrypt", False),
|
||||||
("salt", settings_encrypt["salt"]),
|
("salt", cfg.settings_encrypt["encrypt"])
|
||||||
("keyfile", arguments.keyfile)
|
|
||||||
])
|
])
|
||||||
|
|
||||||
if arguments.encrypt:
|
if arguments.encrypt:
|
||||||
print("Encrypt...")
|
print("Encrypt...")
|
||||||
salt, settings_server = settings_server_encrypt(settings_server, keyfile)
|
salt, settings_server = settings_server_encrypt_cfg(settings_server)
|
||||||
settings_encrypt = OrderedDict([
|
settings_encrypt = OrderedDict([
|
||||||
("encrypt", True),
|
("encrypt", True),
|
||||||
("salt", salt),
|
("salt", salt)
|
||||||
("keyfile", arguments.keyfile)
|
|
||||||
])
|
])
|
||||||
|
|
||||||
print("settings_server = {}".format(pformat(settings_server)))
|
print("settings_server = {}".format(pformat(settings_server)))
|
||||||
@ -210,8 +241,4 @@ def main():
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
try:
|
|
||||||
sys.exit(main())
|
sys.exit(main())
|
||||||
except EncryptionFail as e:
|
|
||||||
print(e)
|
|
||||||
sys.exit(1)
|
|
||||||
|
Loading…
Reference in New Issue
Block a user