atomicshop 2.15.13__py3-none-any.whl → 2.16.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of atomicshop might be problematic. Click here for more details.
- atomicshop/__init__.py +1 -1
- atomicshop/a_installs/ubuntu/pycharm.py +7 -0
- atomicshop/a_installs/win/pycharm.py +2 -2
- atomicshop/{addons/mains/install_wsl_ubuntu_lts_admin.py → a_installs/win/wsl_ubuntu_lts.py} +1 -0
- atomicshop/{addons/mains → a_mains}/FACT/update_extract.py +3 -2
- atomicshop/a_mains/dns_gateway_setting.py +11 -0
- atomicshop/basics/booleans.py +14 -5
- atomicshop/dns.py +104 -0
- atomicshop/file_io/docxs.py +8 -0
- atomicshop/file_io/tomls.py +133 -0
- atomicshop/filesystem.py +5 -4
- atomicshop/get_process_list.py +3 -3
- atomicshop/mitm/config_static.py +195 -0
- atomicshop/mitm/config_toml_editor.py +55 -0
- atomicshop/mitm/connection_thread_worker.py +54 -90
- atomicshop/mitm/import_config.py +148 -139
- atomicshop/mitm/initialize_engines.py +7 -2
- atomicshop/mitm/initialize_mitm_server.py +162 -107
- atomicshop/mitm/shared_functions.py +0 -1
- atomicshop/mitm/statistic_analyzer.py +13 -1
- atomicshop/mitm/statistic_analyzer_helper/moving_average_helper.py +54 -14
- atomicshop/permissions/__init__.py +0 -0
- atomicshop/permissions/permissions.py +22 -0
- atomicshop/{permissions.py → permissions/ubuntu_permissions.py} +4 -54
- atomicshop/permissions/win_permissions.py +33 -0
- atomicshop/script_as_string_processor.py +5 -1
- atomicshop/wrappers/cryptographyw.py +3 -3
- atomicshop/wrappers/dockerw/install_docker.py +6 -5
- atomicshop/wrappers/elasticsearchw/install_elastic.py +2 -1
- atomicshop/wrappers/factw/install/pre_install_and_install_before_restart.py +5 -4
- atomicshop/wrappers/mongodbw/install_mongodb.py +2 -1
- atomicshop/wrappers/msiw.py +2 -3
- atomicshop/wrappers/psutilw/networks.py +25 -1
- atomicshop/wrappers/pycharmw/__init__.py +0 -0
- atomicshop/wrappers/pycharmw/ubuntu.py +38 -0
- atomicshop/wrappers/{pycharmw.py → pycharmw/win.py} +2 -2
- atomicshop/wrappers/pywin32w/wmis/__init__.py +0 -0
- atomicshop/wrappers/pywin32w/wmis/helpers.py +127 -0
- atomicshop/wrappers/pywin32w/wmis/win32networkadapter.py +167 -0
- atomicshop/wrappers/socketw/accepter.py +8 -8
- atomicshop/wrappers/socketw/base.py +13 -0
- atomicshop/wrappers/socketw/certificator.py +202 -149
- atomicshop/wrappers/socketw/creator.py +15 -35
- atomicshop/wrappers/socketw/dns_server.py +155 -102
- atomicshop/wrappers/socketw/exception_wrapper.py +8 -27
- atomicshop/wrappers/socketw/get_process.py +115 -95
- atomicshop/wrappers/socketw/sni.py +298 -164
- atomicshop/wrappers/socketw/socket_client.py +5 -12
- atomicshop/wrappers/socketw/socket_server_tester.py +1 -1
- atomicshop/wrappers/socketw/socket_wrapper.py +328 -72
- atomicshop/wrappers/socketw/statistics_csv.py +94 -16
- atomicshop/wrappers/ubuntu_terminal.py +6 -6
- atomicshop/wrappers/wslw.py +1 -0
- {atomicshop-2.15.13.dist-info → atomicshop-2.16.1.dist-info}/METADATA +1 -1
- {atomicshop-2.15.13.dist-info → atomicshop-2.16.1.dist-info}/RECORD +63 -54
- atomicshop/addons/mains/__pycache__/install_fibratus_windows.cpython-312.pyc +0 -0
- atomicshop/addons/mains/__pycache__/msi_unpacker.cpython-312.pyc +0 -0
- atomicshop/mitm/config_editor.py +0 -37
- /atomicshop/{addons/mains/install_docker_rootless_ubuntu.py → a_installs/ubuntu/docker_rootless.py} +0 -0
- /atomicshop/{addons/mains/install_docker_ubuntu_main_sudo.py → a_installs/ubuntu/docker_sudo.py} +0 -0
- /atomicshop/{addons/mains/install_elastic_search_and_kibana_ubuntu.py → a_installs/ubuntu/elastic_search_and_kibana.py} +0 -0
- /atomicshop/{addons/mains → a_mains}/FACT/factw_fact_extractor_docker_image_main_sudo.py +0 -0
- /atomicshop/wrappers/pywin32w/{wmi_win32process.py → wmis/win32process.py} +0 -0
- {atomicshop-2.15.13.dist-info → atomicshop-2.16.1.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.15.13.dist-info → atomicshop-2.16.1.dist-info}/WHEEL +0 -0
- {atomicshop-2.15.13.dist-info → atomicshop-2.16.1.dist-info}/top_level.txt +0 -0
|
@@ -1,181 +1,315 @@
|
|
|
1
|
-
import sys
|
|
2
1
|
import ssl
|
|
2
|
+
from dataclasses import dataclass
|
|
3
3
|
|
|
4
4
|
from . import certificator, creator
|
|
5
5
|
from ...domains import get_domain_without_first_subdomain_if_no_subdomain_return_as_is
|
|
6
6
|
from ...print_api import print_api
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
@dataclass
|
|
10
|
+
class SNIReceivedParameters:
|
|
11
|
+
ssl_socket: ssl.SSLSocket
|
|
12
|
+
destination_name: str
|
|
13
|
+
ssl_context: ssl.SSLContext
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class SNIDefaultCertificateCreationError(Exception):
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class SNISetup:
|
|
13
21
|
"""
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
:param ssl_context:
|
|
17
|
-
:param config:
|
|
18
|
-
:param dns_domain: domain that was received from DNS Server that will be used if no SNI was passed.
|
|
19
|
-
:param sni_function_name: Reference to the function that will be called when SNI is present in the request.
|
|
20
|
-
:param use_default_sni_function: If True, will use default SNI function.
|
|
21
|
-
:param use_sni_extended: If True, will use extended SNI function.
|
|
22
|
-
:param print_kwargs: dict, that contains all the arguments for 'print_api' function.
|
|
23
|
-
:return:
|
|
22
|
+
Class to handle setting up SNI related features in socket and context.
|
|
24
23
|
"""
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
ca_certificate_name: str,
|
|
27
|
+
ca_certificate_filepath: str,
|
|
28
|
+
default_server_certificate_usage: bool,
|
|
29
|
+
default_server_certificate_name: str,
|
|
30
|
+
default_server_certificate_directory: str,
|
|
31
|
+
default_certificate_domain_list: list,
|
|
32
|
+
sni_custom_callback_function: callable,
|
|
33
|
+
sni_use_default_callback_function: bool,
|
|
34
|
+
sni_use_default_callback_function_extended: bool,
|
|
35
|
+
sni_add_new_domains_to_default_server_certificate: bool,
|
|
36
|
+
sni_create_server_certificate_for_each_domain: bool,
|
|
37
|
+
sni_server_certificates_cache_directory: str,
|
|
38
|
+
sni_get_server_certificate_from_server_socket: bool,
|
|
39
|
+
sni_server_certificate_from_server_socket_download_directory: str,
|
|
40
|
+
custom_server_certificate_usage: bool,
|
|
41
|
+
custom_server_certificate_path: str,
|
|
42
|
+
custom_private_key_path: str,
|
|
43
|
+
forwarding_dns_service_ipv4_list___only_for_localhost: list,
|
|
44
|
+
tls: bool,
|
|
45
|
+
domain_from_dns_server: str = None,
|
|
46
|
+
skip_extension_id_list: list = None
|
|
47
|
+
):
|
|
48
|
+
self.ca_certificate_name = ca_certificate_name
|
|
49
|
+
self.ca_certificate_filepath = ca_certificate_filepath
|
|
50
|
+
self.default_server_certificate_usage = default_server_certificate_usage
|
|
51
|
+
self.default_server_certificate_name = default_server_certificate_name
|
|
52
|
+
self.default_server_certificate_directory = default_server_certificate_directory
|
|
53
|
+
self.default_certificate_domain_list = default_certificate_domain_list
|
|
54
|
+
self.sni_custom_callback_function: callable = sni_custom_callback_function
|
|
55
|
+
self.sni_use_default_callback_function: bool = sni_use_default_callback_function
|
|
56
|
+
self.sni_use_default_callback_function_extended: bool = sni_use_default_callback_function_extended
|
|
57
|
+
self.sni_add_new_domains_to_default_server_certificate = sni_add_new_domains_to_default_server_certificate
|
|
58
|
+
self.sni_create_server_certificate_for_each_domain = sni_create_server_certificate_for_each_domain
|
|
59
|
+
self.sni_server_certificates_cache_directory = sni_server_certificates_cache_directory
|
|
60
|
+
self.sni_get_server_certificate_from_server_socket = sni_get_server_certificate_from_server_socket
|
|
61
|
+
self.sni_server_certificate_from_server_socket_download_directory = (
|
|
62
|
+
sni_server_certificate_from_server_socket_download_directory)
|
|
63
|
+
self.custom_server_certificate_usage = custom_server_certificate_usage
|
|
64
|
+
self.custom_server_certificate_path = custom_server_certificate_path
|
|
65
|
+
self.custom_private_key_path = custom_private_key_path
|
|
66
|
+
self.forwarding_dns_service_ipv4_list___only_for_localhost = (
|
|
67
|
+
forwarding_dns_service_ipv4_list___only_for_localhost)
|
|
68
|
+
self.domain_from_dns_server: str = domain_from_dns_server
|
|
69
|
+
self.skip_extension_id_list = skip_extension_id_list
|
|
70
|
+
self.tls = tls
|
|
71
|
+
|
|
72
|
+
self.certificator_instance = None
|
|
25
73
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
74
|
+
def wrap_socket_with_ssl_context_server_sni_extended(
|
|
75
|
+
self,
|
|
76
|
+
socket_object,
|
|
77
|
+
print_kwargs: dict = None
|
|
78
|
+
):
|
|
79
|
+
|
|
80
|
+
# Create SSL Socket to wrap the raw socket with.
|
|
81
|
+
ssl_context = creator.create_ssl_context_for_server()
|
|
82
|
+
|
|
83
|
+
self.certificator_instance = certificator.Certificator(
|
|
84
|
+
ca_certificate_name=self.ca_certificate_name,
|
|
85
|
+
ca_certificate_filepath=self.ca_certificate_filepath,
|
|
86
|
+
default_server_certificate_usage=self.default_server_certificate_usage,
|
|
87
|
+
default_server_certificate_name=self.default_server_certificate_name,
|
|
88
|
+
default_server_certificate_directory=self.default_server_certificate_directory,
|
|
89
|
+
default_certificate_domain_list=self.default_certificate_domain_list,
|
|
90
|
+
sni_server_certificates_cache_directory=self.sni_server_certificates_cache_directory,
|
|
91
|
+
sni_get_server_certificate_from_server_socket=self.sni_get_server_certificate_from_server_socket,
|
|
92
|
+
sni_server_certificate_from_server_socket_download_directory=(
|
|
93
|
+
self.sni_server_certificate_from_server_socket_download_directory),
|
|
94
|
+
custom_server_certificate_usage=self.custom_server_certificate_usage,
|
|
95
|
+
custom_server_certificate_path=self.custom_server_certificate_path,
|
|
96
|
+
custom_private_key_path=self.custom_private_key_path,
|
|
97
|
+
forwarding_dns_service_ipv4_list___only_for_localhost=(
|
|
98
|
+
self.forwarding_dns_service_ipv4_list___only_for_localhost),
|
|
99
|
+
skip_extension_id_list=self.skip_extension_id_list,
|
|
100
|
+
tls=self.tls
|
|
50
101
|
)
|
|
51
102
|
|
|
103
|
+
# Add SNI callback function to the SSL context.
|
|
104
|
+
self.add_sni_callback_function_to_ssl_context(ssl_context=ssl_context, print_kwargs=print_kwargs)
|
|
105
|
+
|
|
106
|
+
server_certificate_file_path, server_private_key_file_path = \
|
|
107
|
+
self.certificator_instance.select_server_ssl_context_certificate(print_kwargs=print_kwargs)
|
|
108
|
+
|
|
109
|
+
# If the user chose 'sni_create_server_certificate_for_each_domain = 1' in the configuration file,
|
|
110
|
+
# it means that 'self.server_certificate_file_path' will be empty, which is OK, since we'll inject
|
|
111
|
+
# dynamically created certificate from certs folder through SNI.
|
|
112
|
+
if server_certificate_file_path:
|
|
113
|
+
creator.load_certificate_and_key_into_server_ssl_context(
|
|
114
|
+
ssl_context, server_certificate_file_path, server_private_key_file_path,
|
|
115
|
+
print_kwargs=print_kwargs)
|
|
52
116
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
117
|
+
ssl_socket, error_message = creator.wrap_socket_with_ssl_context_server_with_error_message(
|
|
118
|
+
socket_object=socket_object, ssl_context=ssl_context, domain_from_dns_server=self.domain_from_dns_server,
|
|
119
|
+
print_kwargs=print_kwargs)
|
|
120
|
+
|
|
121
|
+
return ssl_socket, error_message
|
|
122
|
+
|
|
123
|
+
def add_sni_callback_function_to_ssl_context(
|
|
124
|
+
self,
|
|
125
|
+
ssl_context,
|
|
126
|
+
print_kwargs: dict = None
|
|
127
|
+
):
|
|
128
|
+
"""
|
|
129
|
+
Add SNI callback function reference to SSLContext object. Inplace.
|
|
130
|
+
|
|
131
|
+
:param ssl_context: SSLContext object.
|
|
132
|
+
:param print_kwargs: dict, that contains all the arguments for 'print_api' function.
|
|
133
|
+
:return:
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
|
+
# SNI - Server Name Indication: https://en.wikipedia.org/wiki/Server_Name_Indication
|
|
137
|
+
# SNI is extension to TLS protocol to tell the Server what is destination domain that the client is trying to
|
|
138
|
+
# connect. The server knowing the destination domain then can present to the client the appropriate certificate.
|
|
139
|
+
# "sni_callback" method: https://docs.python.org/3/library/ssl.html#ssl.SSLContext.sni_callback
|
|
140
|
+
# The method calls your custom function. If there is SNI present in the TLS request from the client, then the
|
|
141
|
+
# function will be called. Automatically providing 3 parameters from the system: ssl.SSLSocket, The destination
|
|
142
|
+
# server name, current ssl.SSLContext object.
|
|
143
|
+
# If you check the custom function it has all these variables mandatory, since this is what system provides and
|
|
144
|
+
# handled by the system, if SNI is existent.
|
|
145
|
+
# The function is actually called at "accept()" method of the "ssl.SSLSocket"
|
|
146
|
+
# This needs to be set only once on the listening socket
|
|
147
|
+
if self.sni_custom_callback_function:
|
|
148
|
+
ssl_context.sni_callback = self.sni_custom_callback_function
|
|
149
|
+
|
|
150
|
+
if self.sni_use_default_callback_function:
|
|
151
|
+
sni_handler_instance = SNIHandler(
|
|
152
|
+
sni_use_default_callback_function_extended=self.sni_use_default_callback_function_extended,
|
|
153
|
+
sni_add_new_domains_to_default_server_certificate=self.sni_add_new_domains_to_default_server_certificate,
|
|
154
|
+
sni_create_server_certificate_for_each_domain=self.sni_create_server_certificate_for_each_domain,
|
|
155
|
+
certificator_instance=self.certificator_instance,
|
|
156
|
+
domain_from_dns_server=self.domain_from_dns_server,
|
|
157
|
+
default_certificate_domain_list=self.default_certificate_domain_list
|
|
158
|
+
)
|
|
159
|
+
ssl_context.set_servername_callback(
|
|
160
|
+
sni_handler_instance.setup_sni_callback(print_kwargs=print_kwargs))
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
class SNIHandler:
|
|
59
164
|
"""
|
|
60
|
-
|
|
61
|
-
:param use_sni_extended: Use extended SNI function, besides the default one.
|
|
62
|
-
:param config:
|
|
63
|
-
:param dns_domain: domain that was received from DNS Server that will be used if no SNI was passed.
|
|
64
|
-
:param print_kwargs: dict, that contains all the arguments for 'print_api' function.
|
|
65
|
-
:return:
|
|
165
|
+
THe class is responsible for handling SNI callback execution.
|
|
66
166
|
"""
|
|
67
167
|
|
|
68
|
-
def
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
def
|
|
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
|
-
|
|
168
|
+
def __init__(
|
|
169
|
+
self,
|
|
170
|
+
sni_use_default_callback_function_extended: bool,
|
|
171
|
+
sni_add_new_domains_to_default_server_certificate: bool,
|
|
172
|
+
sni_create_server_certificate_for_each_domain: bool,
|
|
173
|
+
certificator_instance: certificator.Certificator,
|
|
174
|
+
domain_from_dns_server: str,
|
|
175
|
+
default_certificate_domain_list: list
|
|
176
|
+
):
|
|
177
|
+
self.sni_use_default_callback_function_extended = sni_use_default_callback_function_extended
|
|
178
|
+
self.sni_add_new_domains_to_default_server_certificate = sni_add_new_domains_to_default_server_certificate
|
|
179
|
+
self.sni_create_server_certificate_for_each_domain = sni_create_server_certificate_for_each_domain
|
|
180
|
+
self.certificator_instance = certificator_instance
|
|
181
|
+
self.domain_from_dns_server: str = domain_from_dns_server
|
|
182
|
+
self.default_certificate_domain_list = default_certificate_domain_list
|
|
183
|
+
|
|
184
|
+
# noinspection PyTypeChecker
|
|
185
|
+
self.sni_received_parameters: SNIReceivedParameters = None
|
|
186
|
+
|
|
187
|
+
# Server Name Indication (SNI) is an extension to the Transport Layer Security (TLS) computer networking protocol.
|
|
188
|
+
# Function to handle server's SSLContext's SNI callback function.
|
|
189
|
+
# This is actually called first during "accept()" method of the "ssl.SSLSocket" then comes accept itself.
|
|
190
|
+
# This happens in 'ssl.py' module in 'self._sslobj.do_handshake()' function.
|
|
191
|
+
def setup_sni_callback(
|
|
192
|
+
self,
|
|
193
|
+
print_kwargs: dict = None
|
|
194
|
+
):
|
|
195
|
+
"""
|
|
196
|
+
Setup SNI callback function.
|
|
197
|
+
:param print_kwargs: dict, that contains all the arguments for 'print_api' function.
|
|
198
|
+
:return:
|
|
199
|
+
"""
|
|
200
|
+
|
|
201
|
+
def sni_handle(
|
|
202
|
+
sni_ssl_socket: ssl.SSLSocket,
|
|
203
|
+
sni_destination_name: str,
|
|
204
|
+
sni_ssl_context: ssl.SSLContext):
|
|
205
|
+
# Set 'server_hostname' for the socket.
|
|
206
|
+
sni_ssl_socket.server_hostname = sni_destination_name
|
|
207
|
+
|
|
208
|
+
# If 'sni_execute_extended' was set to True.
|
|
209
|
+
if self.sni_use_default_callback_function_extended:
|
|
210
|
+
self.sni_received_parameters = SNIReceivedParameters(
|
|
211
|
+
ssl_socket=sni_ssl_socket,
|
|
212
|
+
destination_name=sni_destination_name,
|
|
213
|
+
ssl_context=sni_ssl_context
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
self.sni_handle_extended(print_kwargs=print_kwargs)
|
|
217
|
+
|
|
218
|
+
return sni_handle
|
|
219
|
+
|
|
220
|
+
def sni_handle_extended(
|
|
221
|
+
self,
|
|
222
|
+
print_kwargs: dict = None
|
|
223
|
+
):
|
|
224
|
+
# Set 'server_hostname' for the socket.
|
|
225
|
+
self.set_socket_server_hostname(print_kwargs=print_kwargs)
|
|
226
|
+
|
|
227
|
+
# If 'sni_default_server_certificates_addons' was set to 'True' in the 'config.ini'.
|
|
228
|
+
# This section will add all the new domains that hit the server to default certificate SAN with wildcard.
|
|
229
|
+
if self.sni_add_new_domains_to_default_server_certificate:
|
|
230
|
+
self.sni_add_domain_to_default_server_certificate(print_kwargs=print_kwargs)
|
|
231
|
+
|
|
232
|
+
# If SNI server certificate creation was set to 'True', we'll create certificate for each incoming domain if
|
|
233
|
+
# non-existent in certificates cache folder.
|
|
234
|
+
if self.sni_create_server_certificate_for_each_domain:
|
|
235
|
+
self.certificator_instance.create_use_sni_server_certificate_ca_signed(
|
|
236
|
+
sni_received_parameters=self.sni_received_parameters, print_kwargs=print_kwargs)
|
|
237
|
+
|
|
238
|
+
def set_socket_server_hostname(
|
|
239
|
+
self,
|
|
240
|
+
print_kwargs: dict = None
|
|
241
|
+
):
|
|
242
|
+
service_name_from_sni = None
|
|
243
|
+
|
|
244
|
+
# Try on general settings in the SNI function.
|
|
245
|
+
try:
|
|
246
|
+
# Check if SNI was passed.
|
|
247
|
+
if self.sni_received_parameters.destination_name:
|
|
248
|
+
service_name_from_sni = self.sni_received_parameters.destination_name
|
|
249
|
+
# If no SNI was passed.
|
|
250
|
+
else:
|
|
251
|
+
# If DNS server is enabled we'll get the domain from dns server.
|
|
252
|
+
if self.domain_from_dns_server:
|
|
253
|
+
service_name_from_sni = self.domain_from_dns_server
|
|
254
|
+
message = f"SNI Handler: No SNI was passed, using domain from DNS Server: {service_name_from_sni}"
|
|
255
|
+
print_api(message, **(print_kwargs or {}))
|
|
256
|
+
# If DNS server is disabled, the domain from dns server will be empty.
|
|
257
|
+
else:
|
|
258
|
+
message = f"SNI Handler: No SNI was passed, No domain passed from DNS Server. " \
|
|
259
|
+
f"Service name will be 'None'."
|
|
260
|
+
print_api(message, **(print_kwargs or {}))
|
|
261
|
+
|
|
262
|
+
# Setting "server_hostname" as a domain.
|
|
263
|
+
self.sni_received_parameters.ssl_socket.server_hostname = service_name_from_sni
|
|
264
|
+
message = \
|
|
265
|
+
f"SNI Handler: port {self.sni_received_parameters.ssl_socket.getsockname()[1]}: " \
|
|
266
|
+
f"Incoming connection for [{self.sni_received_parameters.ssl_socket.server_hostname}]"
|
|
267
|
+
print_api(message, **(print_kwargs or {}))
|
|
268
|
+
except Exception as exception_object:
|
|
269
|
+
message = f"SNI Handler: Undocumented exception general settings section: {exception_object}"
|
|
270
|
+
print_api(message, error_type=True, logger_method="error", traceback_string=True, oneline=True,
|
|
271
|
+
**(print_kwargs or {}))
|
|
272
|
+
pass
|
|
273
|
+
|
|
274
|
+
def sni_add_domain_to_default_server_certificate(
|
|
275
|
+
self,
|
|
276
|
+
print_kwargs: dict = None
|
|
277
|
+
):
|
|
278
|
+
# Check if incoming domain is already in the parent domains of 'domains_all_times' list.
|
|
279
|
+
if not any(x in self.sni_received_parameters.ssl_socket.server_hostname for x in
|
|
280
|
+
self.default_certificate_domain_list):
|
|
281
|
+
message = f"SNI Handler: Current domain is not in known domains list. Adding."
|
|
282
|
+
print_api(message, **(print_kwargs or {}))
|
|
283
|
+
# In the past was using 'certauth' to extract tlds, but it works only in online mode, so rewrote
|
|
284
|
+
# the function to disable online fetching of TLD snapshot.
|
|
285
|
+
# Initialize 'certauth' object.
|
|
286
|
+
# certificate_object = CertificateAuthority(certificate_ca_name, certificate_ca_filepath)
|
|
287
|
+
# Extract parent domain from the current SNI domain.
|
|
288
|
+
# parent_domain = certificate_object.get_wildcard_domain(service_name_from_sni)
|
|
289
|
+
|
|
290
|
+
# Extract parent domain from the current SNI domain.
|
|
291
|
+
parent_domain = get_domain_without_first_subdomain_if_no_subdomain_return_as_is(
|
|
292
|
+
self.sni_received_parameters.ssl_socket.server_hostname)
|
|
293
|
+
# Add the parent domain to the known domains list.
|
|
294
|
+
self.default_certificate_domain_list.append(parent_domain)
|
|
295
|
+
|
|
296
|
+
default_server_certificate_path, subject_alternate_names = \
|
|
297
|
+
self.certificator_instance.create_overwrite_default_server_certificate_ca_signed()
|
|
298
|
+
|
|
299
|
+
if default_server_certificate_path:
|
|
300
|
+
message = f"SNI Handler: Default Server Certificate was created / overwritten: " \
|
|
301
|
+
f"{default_server_certificate_path}"
|
|
302
|
+
print_api(message, **(print_kwargs or {}))
|
|
303
|
+
|
|
304
|
+
message = f"SNI Handler: Server Certificate current 'Subject Alternative Names': " \
|
|
305
|
+
f"{subject_alternate_names}"
|
|
306
|
+
print_api(message, **(print_kwargs or {}))
|
|
307
|
+
|
|
308
|
+
# Since new default certificate was created we need to create new SSLContext and add the certificate.
|
|
309
|
+
# You need to build new context and exchange the context that being inherited from the main socket,
|
|
310
|
+
# or else the context will receive previous certificate each time.
|
|
311
|
+
self.sni_received_parameters.ssl_socket.context = \
|
|
312
|
+
creator.create_server_ssl_context___load_certificate_and_key(default_server_certificate_path, None)
|
|
124
313
|
else:
|
|
125
|
-
message = f"
|
|
126
|
-
|
|
127
|
-
print_api(message, **print_kwargs)
|
|
128
|
-
|
|
129
|
-
# Setting "server_hostname" as a domain.
|
|
130
|
-
sni_received_dict['ssl_socket'].server_hostname = service_name_from_sni
|
|
131
|
-
message = \
|
|
132
|
-
f"SNI Handler: port {sni_received_dict['ssl_socket'].getsockname()[1]}: " \
|
|
133
|
-
f"Incoming connection for [{sni_received_dict['ssl_socket'].server_hostname}]"
|
|
134
|
-
print_api(message, **print_kwargs)
|
|
135
|
-
except Exception as exception_object:
|
|
136
|
-
message = f"SNI Handler: Undocumented exception general settings section: {exception_object}"
|
|
137
|
-
print_api(message, error_type=True, logger_method="error", traceback_string=True, oneline=True,
|
|
138
|
-
**print_kwargs)
|
|
139
|
-
pass
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
def sni_add_domain_to_default_server_certificate(sni_received_dict: dict, config: dict, print_kwargs: dict = None):
|
|
143
|
-
# Check if incoming domain is already in the parent domains of 'domains_all_times' list.
|
|
144
|
-
if not any(x in sni_received_dict['ssl_socket'].server_hostname for x in
|
|
145
|
-
config['certificates']['domains_all_times']):
|
|
146
|
-
message = f"SNI Handler: Current domain is not in known domains list. Adding."
|
|
147
|
-
print_api(message, **print_kwargs)
|
|
148
|
-
# In the past was using 'certauth' to extract tlds, but it works only in online mode, so rewrote
|
|
149
|
-
# the function to disable online fetching of TLD snapshot.
|
|
150
|
-
# Initialize 'certauth' object.
|
|
151
|
-
# certificate_object = CertificateAuthority(certificate_ca_name, certificate_ca_filepath)
|
|
152
|
-
# Extract parent domain from the current SNI domain.
|
|
153
|
-
# parent_domain = certificate_object.get_wildcard_domain(service_name_from_sni)
|
|
154
|
-
|
|
155
|
-
# Extract parent domain from the current SNI domain.
|
|
156
|
-
parent_domain = get_domain_without_first_subdomain_if_no_subdomain_return_as_is(
|
|
157
|
-
sni_received_dict['ssl_socket'].server_hostname)
|
|
158
|
-
# Add the parent domain to the known domains list.
|
|
159
|
-
config['certificates']['domains_all_times'].append(parent_domain)
|
|
160
|
-
|
|
161
|
-
default_server_certificate_path, subject_alternate_names = \
|
|
162
|
-
certificator.create_overwrite_default_server_certificate_ca_signed(config=config)
|
|
163
|
-
|
|
164
|
-
if default_server_certificate_path:
|
|
165
|
-
message = f"SNI Handler: Default Server Certificate was created / overwritten: " \
|
|
166
|
-
f"{default_server_certificate_path}"
|
|
167
|
-
print_api(message, **print_kwargs)
|
|
168
|
-
|
|
169
|
-
message = f"SNI Handler: Server Certificate current 'Subject Alternative Names': " \
|
|
170
|
-
f"{subject_alternate_names}"
|
|
171
|
-
print_api(message, **print_kwargs)
|
|
172
|
-
|
|
173
|
-
# Since new default certificate was created we need to create new SSLContext and add the certificate.
|
|
174
|
-
# You need to build new context and exchange the context that being inherited from the main socket,
|
|
175
|
-
# or else the context will receive previous certificate each time.
|
|
176
|
-
sni_received_dict['ssl_socket'].context = \
|
|
177
|
-
creator.create_server_ssl_context___load_certificate_and_key(default_server_certificate_path, None)
|
|
178
|
-
else:
|
|
179
|
-
message = f"Couldn't create / overwrite Default Server Certificate: {default_server_certificate_path}"
|
|
180
|
-
print_api(message, error_type=True, logger_method="critical", **print_kwargs)
|
|
181
|
-
sys.exit()
|
|
314
|
+
message = f"Couldn't create / overwrite Default Server Certificate: {default_server_certificate_path}"
|
|
315
|
+
raise SNIDefaultCertificateCreationError(message)
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import socket
|
|
2
2
|
import ssl
|
|
3
3
|
import time
|
|
4
|
+
from typing import Literal, Union
|
|
5
|
+
|
|
6
|
+
from cryptography import x509
|
|
4
7
|
|
|
5
8
|
from . import creator
|
|
6
9
|
from .receiver import Receiver
|
|
@@ -10,7 +13,6 @@ from .. import cryptographyw
|
|
|
10
13
|
from ..loggingw import loggingw
|
|
11
14
|
from ...print_api import print_api
|
|
12
15
|
from ...file_io import file_io
|
|
13
|
-
from ... import filesystem
|
|
14
16
|
|
|
15
17
|
import dns.resolver
|
|
16
18
|
|
|
@@ -323,9 +325,9 @@ class SocketClient:
|
|
|
323
325
|
self,
|
|
324
326
|
save_as_file: bool = False,
|
|
325
327
|
cert_file_path: str = None,
|
|
326
|
-
cert_output_type:
|
|
328
|
+
cert_output_type: Literal['der', 'cryptography'] = 'der',
|
|
327
329
|
**kwargs
|
|
328
|
-
):
|
|
330
|
+
) -> Union[x509.Certificate]:
|
|
329
331
|
"""
|
|
330
332
|
This function will get the certificate from the server and return it.
|
|
331
333
|
|
|
@@ -339,15 +341,6 @@ class SocketClient:
|
|
|
339
341
|
# If "save_as_file" is True, then "cert_file_path" must be provided, if not, raise an exception.
|
|
340
342
|
if save_as_file and not cert_file_path:
|
|
341
343
|
raise ValueError("If 'save_as_file' is True, then 'cert_file_path' must be provided.")
|
|
342
|
-
# If 'save_as_file' is True and 'cert_file_path' is provided, then check if the file exists.
|
|
343
|
-
# Since there is no point fetching the certificate from the socket if it already exists.
|
|
344
|
-
elif save_as_file and cert_file_path:
|
|
345
|
-
# If certificate from socket exists, then we don't need to get it from the socket and write to file.
|
|
346
|
-
# and we will return None, since no certificate was fetched.
|
|
347
|
-
if filesystem.is_file_exists(cert_file_path):
|
|
348
|
-
return None
|
|
349
|
-
else:
|
|
350
|
-
print_api("Certificate from socket doesn't exist, fetching.", logger=self.logger)
|
|
351
344
|
|
|
352
345
|
# Connect and get the connected socket.
|
|
353
346
|
server_socket_for_certificate = self.service_connection()
|
|
@@ -37,7 +37,7 @@ def get_key_values_from_json(json_dict: dict, extract_keys: list):
|
|
|
37
37
|
def execute_test(config_static):
|
|
38
38
|
# Import config ini file and read it to dict.
|
|
39
39
|
config_importer = ConfigParserWrapper(
|
|
40
|
-
file_name=config_static.CONFIG_INI_TESTER_FILE_NAME, directory_path=config_static.
|
|
40
|
+
file_name=config_static.CONFIG_INI_TESTER_FILE_NAME, directory_path=config_static.SCRIPT_DIRECTORY)
|
|
41
41
|
config_importer.read_to_dict()
|
|
42
42
|
# Convert keys.
|
|
43
43
|
config_importer.convert_string_values(
|