forked from pinae/ctSESAM-python-memorizing
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpreference_manager.py
138 lines (119 loc) · 4.14 KB
/
preference_manager.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
The preference manager handles the access to the settings file.
"""
import os
PASSWORD_SETTINGS_FILE = os.path.expanduser('~/.config/ct/ctSESAM.pws')
class PreferenceManager(object):
"""
:param settings_file: Filename of the settings file. Defaults to PASSWORD_SETTINGS_FILE as defined in the source
:type settings_file: str
"""
def __init__(self, settings_file=PASSWORD_SETTINGS_FILE):
self.data = b''
self.settings_file = settings_file
self.read_file()
def read_file(self):
"""
Read the settings file.
"""
if os.path.isfile(self.settings_file):
with open(self.settings_file, 'rb') as f:
self.data = f.read()
def get_salt(self):
"""
Reads the salt.
:return: the salt
:rtype: bytes
"""
return self.data[:32]
def store_salt(self, salt):
"""
Writes the salt into the first 32 bytes of the file.
:param salt: 32 bytes salt
:type salt: bytes
"""
if type(salt) != bytes:
raise TypeError("The salt must be bytes.")
if len(salt) != 32:
raise ValueError("The salt has to be 32 bytes.")
if os.path.isfile(self.settings_file):
with open(self.settings_file, 'rb+') as f:
f.seek(0)
f.write(salt)
else:
if not os.path.exists(os.path.dirname(self.settings_file)):
os.makedirs(os.path.dirname(self.settings_file))
with open(self.settings_file, 'wb') as f:
f.write(salt)
self.data = salt + self.data[32:]
self.set_hidden()
def get_kgk_block(self):
"""
Reads the kgk_block.
:return: 112 bytes of kgk data
:rtype: bytes
"""
return self.data[32:144]
def store_kgk_block(self, kgk_block):
"""
Writes the kgk_block into bytes 32 to 143.
:param kgk_block: encrypted kgk data
:type kgk_block: bytes
"""
if type(kgk_block) != bytes:
raise TypeError("The kgk_block must be bytes.")
if len(kgk_block) != 112:
raise ValueError("The kgk_block has to be 112 bytes.")
if os.path.isfile(self.settings_file):
with open(self.settings_file, 'rb+') as f:
f.seek(32)
f.write(kgk_block)
else:
if not os.path.exists(os.path.dirname(self.settings_file)):
os.makedirs(os.path.dirname(self.settings_file))
with open(self.settings_file, 'wb') as f:
f.write(b'\x00'*32)
f.write(kgk_block)
self.data = self.data[:32] + kgk_block + self.data[144:]
self.set_hidden()
def get_settings_data(self):
"""
Reads the settings data.
:return: encrypted settings
:rtype: bytes
"""
return self.data[144:]
def store_settings_data(self, settings_data):
"""
Writes the settings data after byte 144.
:param settings_data: encrypted settings data
:type settings_data: bytes
"""
if type(settings_data) != bytes:
raise TypeError("The kgk_block must be bytes.")
if os.path.isfile(self.settings_file):
with open(self.settings_file, 'rb+') as f:
f.seek(144)
f.write(settings_data)
f.truncate()
else:
if not os.path.exists(os.path.dirname(self.settings_file)):
os.makedirs(os.path.dirname(self.settings_file))
with open(self.settings_file, 'wb') as f:
f.write(b'\x00'*144)
f.write(settings_data)
self.data = self.data[:144] + settings_data
self.set_hidden()
# noinspection PyUnresolvedReferences
def set_hidden(self):
"""
Hides the settings file if possible.
"""
try:
import win32con
import win32api
win32api.SetFileAttributes(self.settings_file, win32con.FILE_ATTRIBUTE_HIDDEN)
except ImportError:
pass