@ -1,35 +1,42 @@
import os
import os
import base64
import base64
import copy
import copy
import secrets
import yaml
import yaml
from cryptography . exceptions import AlreadyFinalized
from cryptography . exceptions import InvalidTag
from cryptography . exceptions import InvalidTag
from cryptography . exceptions import UnsupportedAlgorithm
from cryptography . hazmat . backends import default_backend
from cryptography . hazmat . backends import default_backend
from cryptography . hazmat . primitives import hashes
from cryptography . hazmat . primitives import hashes
from cryptography . hazmat . primitives . ciphers . aead import AESGCM
from cryptography . hazmat . primitives . ciphers . aead import AESGCM
from cryptography . hazmat . primitives . kdf . pbkdf2 import PBKDF2HMAC
from cryptography . hazmat . primitives . kdf . pbkdf2 import PBKDF2HMAC
# TODO make the config actually safe, hard-coded encryption password is BAD (but a bit better than plaintext)
class ConfigReader :
class ConfigReader :
kdf = None
kdf = None
nonce = None
nonce = None
CONFIG_VERSION = 3
CONFIG_VERSION = 4
def __init__ ( self , root_folder : str , password : str ):
def __init__ ( self , root_folder : str ):
if root_folder is None :
if root_folder is None :
raise Exception ( " No root folder was defined! " )
raise Exception ( " No root folder was defined! " )
self . __key = None
self . __key = None
self . __aesgcm = None
self . __aesgcm = None
self . data = { }
self . data = { }
self . __password = password
self . __config_location = os . path . join ( root_folder , " .artnet " , " artnet.config " )
self . __config_location = os . path . join ( root_folder , " .artnet " , " artnet.config " )
self . __config_key_location = os . path . join ( root_folder , " .artnet " , " artnet_config.key " )
try :
password = self . try_get_config_password ( )
except FileNotFoundError as e :
if not os . path . exists ( self . __config_location ) :
self . generate_config_key_file ( )
password = self . try_get_config_password ( )
else :
raise e
ConfigReader . __create_kdf ( )
ConfigReader . __create_kdf ( )
self . __key = ConfigReader . kdf . derive ( bytes ( password . encode ( ' utf-8 ' ) ) )
self . __key = ConfigReader . kdf . derive ( bytes ( password . encode ( ' utf-8 ' ) ) )
@ -43,6 +50,35 @@ class ConfigReader:
self . create_default_config ( )
self . create_default_config ( )
self . read_config ( )
self . read_config ( )
def try_get_config_password ( self ) - > str :
"""
Attempts to read the config encryption password from the default location
"""
if os . path . exists ( self . __config_key_location ) and os . path . isfile ( self . __config_key_location ) :
with open ( self . __config_key_location , " r " ) as file :
password = file . readline ( )
file . close ( )
return password
else :
raise FileNotFoundError ( f " The config encryption key file could not be found! "
f " FileNotFound: { self . __config_key_location } " )
def generate_config_key_file ( self ) :
"""
Tries to generate a new pseudo - random generated key file for encrypting the config file .
The key is in plain text and therefore not ideal .
"""
if not os . path . exists ( self . __config_key_location ) and not os . path . exists ( self . __config_location ) :
with open ( self . __config_key_location , " w " ) as file :
file . write ( secrets . token_hex ( 100 ) )
file . close ( )
else :
raise Exception ( " Something went terribly wrong! "
" Tried to create new config key file although the key file or config file aready exists! "
" Perhaps old config? " )
def update_config ( self ) :
def update_config ( self ) :
"""
"""
Update the written config with the local settings
Update the written config with the local settings