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
139
140
141
|
'''
A shared resource that takes care of sending
& receiving data from a connection. Handling
the security, but also the packaging of data.
Verified: 2021 February 8
* Follows PEP8
* Tested Platforms
* Windows 10
* Third Party Modules
* cryptography
'''
from shared.state import Static
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.fernet import Fernet
import base64
import time
import json
import zlib
class Data:
BUFFER_SIZE = 81920
__SECRET = Fernet(base64.urlsafe_b64encode(PBKDF2HMAC(
algorithm=hashes.SHA256(), length=32,
salt=Static.SALT.encode(Static.ENCODING),
iterations=100000, backend=default_backend()
).derive(Static.SECRET.encode(Static.ENCODING))))
__COMPRESSION_LEVEL = 6
__HEADER_SIZE = 10
@staticmethod
def send(conn, request='', serialize=True):
if serialize:
request = Data.__serialize(request)
request = Data.__compress(request)
request = Data.__encrypt(request)
conn.sendall('{:<{}}'.format(
len(request), Data.__HEADER_SIZE
).encode(Static.ENCODING) + request)
@staticmethod
def recv(conn, server_sided=False, deserialize=True):
mode = [True, 0, ''.encode(Static.ENCODING)]
if server_sided:
timer = time.time()
while True:
data = conn.recv(Data.BUFFER_SIZE)
if mode[0]:
mode[:2] = False, int(data[:Data.__HEADER_SIZE])
mode[2] += data
if len(mode[2]) - Data.__HEADER_SIZE == mode[1]:
response = mode[2][Data.__HEADER_SIZE:]
response = Data.__decrypt(response)
response = Data.__decompress(response)
if deserialize:
response = Data.__deserialize(response)
return response
if server_sided:
if time.time() - timer > Static.TIMEOUT:
raise TimeoutError('Client Response Timeout')
@staticmethod
def parse(message, **kwargs):
headers = {
'status': None,
'raw': False,
'end': False
}
for header in headers:
if header in kwargs:
headers.update({header: kwargs[header]})
del kwargs[header]
return {
'message': message,
'headers': headers,
**kwargs
}
@staticmethod
def lower(request, include_original=True):
message = request['message']
if include_original:
return (message, message.lower())
else:
return message.lower()
@staticmethod
def message(data=''):
return {'message': data}
@staticmethod
def b64encode(data):
return base64.b64encode(data).decode(Static.ENCODING)
@staticmethod
def b64decode(data):
return base64.b64decode(data.encode(Static.ENCODING))
@staticmethod
def __serialize(data):
return json.dumps(data).encode(Static.ENCODING)
@staticmethod
def __deserialize(data):
return json.loads(data.decode(Static.ENCODING))
@staticmethod
def __compress(data):
return zlib.compress(data, Data.__COMPRESSION_LEVEL)
@staticmethod
def __decompress(data):
return zlib.decompress(data)
@staticmethod
def __encrypt(data):
return Data.__SECRET.encrypt(data)
@staticmethod
def __decrypt(data):
return Data.__SECRET.decrypt(data)
|