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.

Files changed (66) hide show
  1. atomicshop/__init__.py +1 -1
  2. atomicshop/a_installs/ubuntu/pycharm.py +7 -0
  3. atomicshop/a_installs/win/pycharm.py +2 -2
  4. atomicshop/{addons/mains/install_wsl_ubuntu_lts_admin.py → a_installs/win/wsl_ubuntu_lts.py} +1 -0
  5. atomicshop/{addons/mains → a_mains}/FACT/update_extract.py +3 -2
  6. atomicshop/a_mains/dns_gateway_setting.py +11 -0
  7. atomicshop/basics/booleans.py +14 -5
  8. atomicshop/dns.py +104 -0
  9. atomicshop/file_io/docxs.py +8 -0
  10. atomicshop/file_io/tomls.py +133 -0
  11. atomicshop/filesystem.py +5 -4
  12. atomicshop/get_process_list.py +3 -3
  13. atomicshop/mitm/config_static.py +195 -0
  14. atomicshop/mitm/config_toml_editor.py +55 -0
  15. atomicshop/mitm/connection_thread_worker.py +54 -90
  16. atomicshop/mitm/import_config.py +148 -139
  17. atomicshop/mitm/initialize_engines.py +7 -2
  18. atomicshop/mitm/initialize_mitm_server.py +162 -107
  19. atomicshop/mitm/shared_functions.py +0 -1
  20. atomicshop/mitm/statistic_analyzer.py +13 -1
  21. atomicshop/mitm/statistic_analyzer_helper/moving_average_helper.py +54 -14
  22. atomicshop/permissions/__init__.py +0 -0
  23. atomicshop/permissions/permissions.py +22 -0
  24. atomicshop/{permissions.py → permissions/ubuntu_permissions.py} +4 -54
  25. atomicshop/permissions/win_permissions.py +33 -0
  26. atomicshop/script_as_string_processor.py +5 -1
  27. atomicshop/wrappers/cryptographyw.py +3 -3
  28. atomicshop/wrappers/dockerw/install_docker.py +6 -5
  29. atomicshop/wrappers/elasticsearchw/install_elastic.py +2 -1
  30. atomicshop/wrappers/factw/install/pre_install_and_install_before_restart.py +5 -4
  31. atomicshop/wrappers/mongodbw/install_mongodb.py +2 -1
  32. atomicshop/wrappers/msiw.py +2 -3
  33. atomicshop/wrappers/psutilw/networks.py +25 -1
  34. atomicshop/wrappers/pycharmw/__init__.py +0 -0
  35. atomicshop/wrappers/pycharmw/ubuntu.py +38 -0
  36. atomicshop/wrappers/{pycharmw.py → pycharmw/win.py} +2 -2
  37. atomicshop/wrappers/pywin32w/wmis/__init__.py +0 -0
  38. atomicshop/wrappers/pywin32w/wmis/helpers.py +127 -0
  39. atomicshop/wrappers/pywin32w/wmis/win32networkadapter.py +167 -0
  40. atomicshop/wrappers/socketw/accepter.py +8 -8
  41. atomicshop/wrappers/socketw/base.py +13 -0
  42. atomicshop/wrappers/socketw/certificator.py +202 -149
  43. atomicshop/wrappers/socketw/creator.py +15 -35
  44. atomicshop/wrappers/socketw/dns_server.py +155 -102
  45. atomicshop/wrappers/socketw/exception_wrapper.py +8 -27
  46. atomicshop/wrappers/socketw/get_process.py +115 -95
  47. atomicshop/wrappers/socketw/sni.py +298 -164
  48. atomicshop/wrappers/socketw/socket_client.py +5 -12
  49. atomicshop/wrappers/socketw/socket_server_tester.py +1 -1
  50. atomicshop/wrappers/socketw/socket_wrapper.py +328 -72
  51. atomicshop/wrappers/socketw/statistics_csv.py +94 -16
  52. atomicshop/wrappers/ubuntu_terminal.py +6 -6
  53. atomicshop/wrappers/wslw.py +1 -0
  54. {atomicshop-2.15.13.dist-info → atomicshop-2.16.1.dist-info}/METADATA +1 -1
  55. {atomicshop-2.15.13.dist-info → atomicshop-2.16.1.dist-info}/RECORD +63 -54
  56. atomicshop/addons/mains/__pycache__/install_fibratus_windows.cpython-312.pyc +0 -0
  57. atomicshop/addons/mains/__pycache__/msi_unpacker.cpython-312.pyc +0 -0
  58. atomicshop/mitm/config_editor.py +0 -37
  59. /atomicshop/{addons/mains/install_docker_rootless_ubuntu.py → a_installs/ubuntu/docker_rootless.py} +0 -0
  60. /atomicshop/{addons/mains/install_docker_ubuntu_main_sudo.py → a_installs/ubuntu/docker_sudo.py} +0 -0
  61. /atomicshop/{addons/mains/install_elastic_search_and_kibana_ubuntu.py → a_installs/ubuntu/elastic_search_and_kibana.py} +0 -0
  62. /atomicshop/{addons/mains → a_mains}/FACT/factw_fact_extractor_docker_image_main_sudo.py +0 -0
  63. /atomicshop/wrappers/pywin32w/{wmi_win32process.py → wmis/win32process.py} +0 -0
  64. {atomicshop-2.15.13.dist-info → atomicshop-2.16.1.dist-info}/LICENSE.txt +0 -0
  65. {atomicshop-2.15.13.dist-info → atomicshop-2.16.1.dist-info}/WHEEL +0 -0
  66. {atomicshop-2.15.13.dist-info → atomicshop-2.16.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,167 @@
1
+ from typing import Union
2
+
3
+ import win32com.client
4
+
5
+ from . import helpers
6
+ from ...psutilw import networks
7
+ from ....print_api import print_api
8
+
9
+
10
+ class NetworkAdapterNotFoundError(Exception):
11
+ pass
12
+
13
+
14
+ def list_network_adapters() -> list:
15
+ # Initialize the WMI client
16
+ wmi = win32com.client.Dispatch('WbemScripting.SWbemLocator')
17
+ wmi_service = wmi.ConnectServer('.', 'root\\cimv2')
18
+
19
+ # Query all network adapters
20
+ adapters = wmi_service.ExecQuery("SELECT * FROM Win32_NetworkAdapter")
21
+
22
+ # Print adapter descriptions
23
+ # for adapter in adapters:
24
+ # print(f"Description: {adapter.Description}, IPEnabled: {adapter.IPEnabled}")
25
+ return list(adapters)
26
+
27
+
28
+ def get_default_network_adapter():
29
+ """
30
+ Get the default network adapter.
31
+ :return:
32
+ """
33
+
34
+ default_connection_name_dict: dict = networks.get_default_connection_name()
35
+ # Get the first key from the dictionary.
36
+ default_connection_name: str = list(default_connection_name_dict.keys())[0]
37
+ adapters = list_network_adapters()
38
+
39
+ for adapter in adapters:
40
+ if default_connection_name == adapter.NetConnectionID:
41
+ return adapter
42
+
43
+ raise NetworkAdapterNotFoundError("Default network adapter not found.")
44
+
45
+
46
+ def get_wmi_network_configuration(
47
+ use_default_interface: bool = False,
48
+ connection_name: str = None,
49
+ mac_address: str = None
50
+ ) -> tuple:
51
+ """
52
+ Get the WMI network configuration for a network adapter.
53
+ :param use_default_interface: bool, if True, the default network interface will be used.
54
+ This is the adapter that your internet is being used from.
55
+ :param connection_name: string, adapter name as shown in the network settings.
56
+ :param mac_address: string, MAC address of the adapter. Format: '00:00:00:00:00:00'.
57
+ :return: tuple(Win32_NetworkAdapterConfiguration, Win32_NetworkAdapter)
58
+ """
59
+
60
+ if use_default_interface and connection_name:
61
+ raise ValueError("Only one of 'use_default_interface' or 'connection_name' must be provided.")
62
+ elif not use_default_interface and not connection_name:
63
+ raise ValueError("Either 'use_default_interface' or 'connection_name' must be provided.")
64
+
65
+ adapters = list_network_adapters()
66
+
67
+ current_adapter = None
68
+ if use_default_interface:
69
+ default_connection_name_dict: dict = networks.get_default_connection_name()
70
+ # Get the first key from the dictionary.
71
+ connection_name: str = list(default_connection_name_dict.keys())[0]
72
+
73
+ if connection_name is None and mac_address is None:
74
+ raise ValueError("Either 'connection_name' or 'mac_address' must be provided.")
75
+ elif connection_name and mac_address:
76
+ raise ValueError("Only one of 'connection_name' or 'mac_address' must be provided.")
77
+
78
+ if connection_name:
79
+ for adapter in adapters:
80
+ if connection_name == adapter.NetConnectionID:
81
+ current_adapter = adapter
82
+ break
83
+
84
+ if not current_adapter:
85
+ raise NetworkAdapterNotFoundError(f"Adapter with connection name '{connection_name}' not found.")
86
+ elif mac_address:
87
+ for adapter in adapters:
88
+ if mac_address == adapter.MACAddress:
89
+ current_adapter = adapter
90
+ break
91
+
92
+ if current_adapter is None:
93
+ raise NetworkAdapterNotFoundError(f"Adapter with MAC address '{mac_address}' not found.")
94
+
95
+ # Initialize the WMI client
96
+ wmi = win32com.client.Dispatch('WbemScripting.SWbemLocator')
97
+ wmi_service = wmi.ConnectServer('.', 'root\\cimv2')
98
+
99
+ # Query the network adapter configurations
100
+ query = f"SELECT * FROM Win32_NetworkAdapterConfiguration WHERE Index='{current_adapter.DeviceID}'"
101
+ adapter_configs = wmi_service.ExecQuery(query)
102
+
103
+ # Check if the adapter exists
104
+ if len(adapter_configs) == 0:
105
+ raise NetworkAdapterNotFoundError(f"Adapter with connection name '{connection_name}' not found.")
106
+
107
+ return adapter_configs[0], current_adapter
108
+
109
+
110
+ def set_dns_server(
111
+ dns_servers: Union[list[str], None],
112
+ use_default_interface: bool = False,
113
+ connection_name: str = None,
114
+ mac_address: str = None
115
+ ):
116
+ """
117
+ Set the DNS servers for a network adapter.
118
+ :param dns_servers: list of strings, DNS server IPv4 addresses.
119
+ None, if you want to remove the DNS servers and make the interface to obtain them automatically from DHCP.
120
+ list[str], if you want to set the DNS servers manually to the list of strings.
121
+ :param use_default_interface: bool, if True, the default network interface will be used.
122
+ This is the adapter that your internet is being used from.
123
+ :param connection_name: string, adapter name as shown in the network settings.
124
+ :param mac_address: string, MAC address of the adapter. Format: '00:00:00:00:00:00'.
125
+ :return:
126
+ """
127
+
128
+ adapter_config, current_adapter = get_wmi_network_configuration(
129
+ use_default_interface=use_default_interface, connection_name=connection_name, mac_address=mac_address)
130
+
131
+ print_api(f"Adapter [{current_adapter.Description}], Connection name [{current_adapter.NetConnectionID}]\n"
132
+ f"Setting DNS servers to {dns_servers}", color='blue')
133
+
134
+ # Set DNS servers
135
+ helpers.call_method(adapter_config, 'SetDNSServerSearchOrder', dns_servers)
136
+
137
+
138
+ def is_adapter_dns_gateway_from_dhcp(
139
+ use_default_interface: bool = False,
140
+ connection_name: str = None,
141
+ mac_address: str = None
142
+ ) -> bool:
143
+ """
144
+ Check if the adapter is set to obtain the DNS servers automatically from DHCP.
145
+ :param use_default_interface: bool, if True, the default network interface will be used.
146
+ This is the adapter that your internet is being used from.
147
+ :param connection_name: string, adapter name as shown in the network settings.
148
+ :param mac_address: string, MAC address of the adapter. Format: '00:00:00:00:00:00'.
149
+ :return: bool, True if DHCP is enabled, False otherwise.
150
+ """
151
+
152
+ adapter_config, current_adapter = get_wmi_network_configuration(
153
+ use_default_interface=use_default_interface, connection_name=connection_name, mac_address=mac_address)
154
+
155
+ # If DHCP is not enabled.
156
+ if not adapter_config.DHCPEnabled:
157
+ # Then it is obvious that DNS Gateway is also Statis.
158
+ return False
159
+ # If DHCP is enabled.
160
+ else:
161
+ # Then we need to check if Default IP gateway is the same as DNS Gateway, if so.
162
+ if adapter_config.DefaultIPGateway == adapter_config.DNSServerSearchOrder:
163
+ # Then it is set dynamically from DHCP.
164
+ return True
165
+ else:
166
+ # If not, so it is static.
167
+ return False
@@ -2,17 +2,12 @@ from . import exception_wrapper
2
2
 
3
3
 
4
4
  @exception_wrapper.connection_exception_decorator
5
- def accept_connection(socket_object, dns_domain, print_kwargs: dict = None):
5
+ def accept_connection(socket_object, domain_from_dns_server, print_kwargs: dict = None):
6
6
  """
7
7
  Accept connection from client.
8
8
  This function is wrapped with exception wrapper.
9
9
  After you execute the function, you can get the error message if there was any with:
10
10
  error_message = accept_connection.message
11
-
12
- :param socket_object:
13
- :param dns_domain:
14
- :param print_kwargs:
15
- :return:
16
11
  """
17
12
 
18
13
  client_socket = None
@@ -33,8 +28,13 @@ def accept_connection(socket_object, dns_domain, print_kwargs: dict = None):
33
28
  return client_socket, client_address_tuple
34
29
 
35
30
 
36
- def accept_connection_with_error(socket_object, dns_domain, print_kwargs: dict = None):
37
- client_socket, client_address_tuple = accept_connection(socket_object, dns_domain, print_kwargs=print_kwargs)
31
+ def accept_connection_with_error(
32
+ socket_object,
33
+ domain_from_dns_server,
34
+ print_kwargs: dict = None
35
+ ):
36
+ client_socket, client_address_tuple = accept_connection(
37
+ socket_object, domain_from_dns_server, print_kwargs=print_kwargs)
38
38
  error_message = accept_connection.message
39
39
 
40
40
  return client_socket, client_address_tuple, error_message
@@ -1,6 +1,11 @@
1
1
  import socket
2
2
 
3
3
 
4
+ LOCALHOST_IPV4: str = '127.0.0.1'
5
+ DEFAULT_IPV4: str = socket.gethostbyname(socket.gethostname())
6
+ THIS_DEVICE_IP_LIST: list = [LOCALHOST_IPV4, DEFAULT_IPV4]
7
+
8
+
4
9
  def get_local_network_interfaces_ip_address(family_type: str = None, ip_only: bool = False) -> list:
5
10
  """
6
11
  Return list of IP addresses of local network interfaces.
@@ -57,3 +62,11 @@ def get_source_destination(socket_object):
57
62
  def set_socket_timeout(socket_object, seconds: int = 1):
58
63
  # Setting timeout on the socket before "accept()" drastically slows down connections.
59
64
  socket_object.settimeout(seconds)
65
+
66
+
67
+ def get_default_ip_address() -> str:
68
+ """
69
+ Get the default IP address of the system.
70
+ :return: string.
71
+ """
72
+ return socket.gethostbyname(socket.gethostname())
@@ -1,169 +1,222 @@
1
1
  import os
2
2
  import sys
3
3
 
4
+ from cryptography import x509
5
+
4
6
  from . import creator, base, socket_client
5
7
  from .. import pyopensslw, cryptographyw
6
8
  from ..certauthw.certauthw import CertAuthWrapper
7
9
  from ...print_api import print_api
10
+ from ... import filesystem
11
+
12
+
13
+ class Certificator:
14
+ """
15
+ Certificator class is used to create and manage certificates, wrapping ssl contexts and sockets.
16
+ """
17
+ def __init__(
18
+ self,
19
+ ca_certificate_name: str,
20
+ ca_certificate_filepath: str,
21
+ default_server_certificate_usage: bool,
22
+ default_server_certificate_name: str,
23
+ default_server_certificate_directory: str,
24
+ default_certificate_domain_list: list,
25
+ sni_server_certificates_cache_directory: str,
26
+ sni_get_server_certificate_from_server_socket: bool,
27
+ sni_server_certificate_from_server_socket_download_directory: str,
28
+ custom_server_certificate_usage: bool,
29
+ custom_server_certificate_path: str,
30
+ custom_private_key_path: str,
31
+ forwarding_dns_service_ipv4_list___only_for_localhost: list,
32
+ skip_extension_id_list: list,
33
+ tls: bool
34
+ ):
35
+ self.ca_certificate_name = ca_certificate_name
36
+ self.ca_certificate_filepath = ca_certificate_filepath
37
+ self.default_server_certificate_usage = default_server_certificate_usage
38
+ self.default_server_certificate_name = default_server_certificate_name
39
+ self.default_server_certificate_directory = default_server_certificate_directory
40
+ self.default_certificate_domain_list = default_certificate_domain_list
41
+ self.sni_server_certificates_cache_directory = sni_server_certificates_cache_directory
42
+ self.sni_get_server_certificate_from_server_socket = sni_get_server_certificate_from_server_socket
43
+ self.sni_server_certificate_from_server_socket_download_directory = (
44
+ sni_server_certificate_from_server_socket_download_directory)
45
+ self.custom_server_certificate_usage = custom_server_certificate_usage
46
+ self.custom_server_certificate_path = custom_server_certificate_path
47
+ self.custom_private_key_path = custom_private_key_path
48
+ self.forwarding_dns_service_ipv4_list___only_for_localhost = (
49
+ forwarding_dns_service_ipv4_list___only_for_localhost)
50
+ self.skip_extension_id_list = skip_extension_id_list
51
+ self.tls = tls
52
+
53
+ # noinspection PyTypeChecker
54
+ self.certauth_wrapper: CertAuthWrapper = None
55
+
56
+ def initialize_certauth_create_use_ca_certificate(self, server_certificate_directory: str):
57
+ """
58
+ Initialize CertAuthWrapper and create CA certificate if it doesn't exist.
59
+ :return:
60
+ """
61
+ # Initialize CertAuthWrapper.
62
+ certauth_wrapper = CertAuthWrapper(
63
+ ca_certificate_name=self.ca_certificate_name,
64
+ ca_certificate_filepath=self.ca_certificate_filepath,
65
+ server_certificate_directory=server_certificate_directory
66
+ )
8
67
 
9
-
10
- # noinspection PyTypeChecker
11
- CERTAUTH_WRAPPER: CertAuthWrapper = None
12
-
13
-
14
- def initialize_certauth_create_use_ca_certificate(config: dict):
15
- # Initialize CertAuthWrapper.
16
- if config['certificates']['default_server_certificate_usage']:
17
- server_certificate_directory = config['certificates']['default_server_certificate_directory']
18
- else:
19
- server_certificate_directory = config['certificates']['sni_server_certificates_cache_directory']
20
-
21
- certauth_wrapper = CertAuthWrapper(
22
- ca_certificate_name=config['certificates']['ca_certificate_name'],
23
- ca_certificate_filepath=config['certificates']['ca_certificate_filepath'],
24
- server_certificate_directory=server_certificate_directory
25
- )
26
-
27
- # Create CA certificate if it doesn't exist.
28
- certauth_wrapper.create_use_ca_certificate()
29
-
30
- return certauth_wrapper
31
-
32
-
33
- # noinspection PyTypeChecker
34
- def select_server_ssl_context_certificate(config: dict, print_kwargs: dict = None):
35
- # We need to nullify the variable, since we have several checks if the variable was set or not.
36
- server_certificate_file_path: str = None
37
- server_private_key_file_path: str = None
38
-
39
- # Creating if non-existent/overwriting default server certificate.
40
- # 'server_certificate_filepath' will be assigned there.
41
- if config['certificates']['default_server_certificate_usage']:
42
- server_certificate_file_path, default_server_certificate_san = \
43
- create_overwrite_default_server_certificate_ca_signed(config=config)
44
-
45
- # Check if default certificate was created.
46
- if server_certificate_file_path:
47
- message = f"Default Server Certificate was created / overwritten: {server_certificate_file_path}"
48
- print_api(message, **print_kwargs)
49
-
50
- message = \
51
- f"Default Server Certificate current 'Subject Alternative Names': {default_server_certificate_san}"
52
- print_api(message, **print_kwargs)
53
- else:
54
- message = f"Couldn't create / overwrite Default Server Certificate: {server_certificate_file_path}"
55
- print_api(message, error_type=True, logger_method='critical', **print_kwargs)
56
- sys.exit()
68
+ # Create CA certificate if it doesn't exist.
69
+ certauth_wrapper.create_use_ca_certificate()
70
+
71
+ return certauth_wrapper
72
+
73
+ # noinspection PyTypeChecker
74
+ def select_server_ssl_context_certificate(
75
+ self,
76
+ print_kwargs: dict = None
77
+ ):
78
+ """
79
+ This function selects between the default certificate and custom certificate for the sll context.
80
+ Returns the selected certificate file path and the private key file path.
81
+ """
82
+ # We need to nullify the variable, since we have several checks if the variable was set or not.
83
+ server_certificate_file_path: str = None
84
+ server_private_key_file_path: str = None
85
+
86
+ # Creating if non-existent/overwriting default server certificate.
87
+ if self.default_server_certificate_usage:
88
+ # Creating if non-existent/overwriting default server certificate.
89
+ server_certificate_file_path, default_server_certificate_san = \
90
+ self.create_overwrite_default_server_certificate_ca_signed()
91
+
92
+ # Check if default certificate was created.
93
+ if server_certificate_file_path:
94
+ message = f"Default Server Certificate was created / overwritten: {server_certificate_file_path}"
95
+ print_api(message, **(print_kwargs or {}))
96
+
97
+ message = \
98
+ f"Default Server Certificate current 'Subject Alternative Names': {default_server_certificate_san}"
99
+ print_api(message, **(print_kwargs or {}))
100
+ else:
101
+ message = f"Couldn't create / overwrite Default Server Certificate: {server_certificate_file_path}"
102
+ print_api(message, error_type=True, logger_method='critical', **(print_kwargs or {}))
103
+ sys.exit()
57
104
 
58
105
  # Assigning 'certificate_path' to 'custom_certificate_path' if usage was set.
59
- if config['certificates']['custom_server_certificate_usage']:
60
- server_certificate_file_path = config['certificates']['custom_server_certificate_path']
106
+ if self.custom_server_certificate_usage:
107
+ server_certificate_file_path = self.custom_server_certificate_path
61
108
  # Since 'ssl_context.load_cert_chain' uses 'keypath' as 'None' if certificate contains private key.
62
109
  # We'd like to leave it that way and don't fetch empty string from 'config'.
63
- if config['certificates']['custom_private_key_path']:
64
- server_private_key_file_path = config['certificates']['custom_private_key_path']
65
-
66
- return server_certificate_file_path, server_private_key_file_path
110
+ if self.custom_private_key_path:
111
+ server_private_key_file_path = self.custom_private_key_path
67
112
 
113
+ return server_certificate_file_path, server_private_key_file_path
68
114
 
69
- def create_overwrite_default_server_certificate_ca_signed(config: dict):
70
- global CERTAUTH_WRAPPER
71
- CERTAUTH_WRAPPER = initialize_certauth_create_use_ca_certificate(config=config)
115
+ def create_overwrite_default_server_certificate_ca_signed(self):
116
+ """
117
+ Create or overwrite default server certificate.
118
+ :return:
119
+ """
72
120
 
73
- domain_list = config['certificates']['domains_all_times']
74
- server_certificate_file_name_no_extension = config['certificates']['default_server_certificate_name']
75
-
76
- server_certificate_file_path, default_server_certificate_san = \
77
- CERTAUTH_WRAPPER.create_overwrite_server_certificate_ca_signed_return_path_and_san(
78
- domain_list=domain_list,
79
- server_certificate_file_name_no_extension=server_certificate_file_name_no_extension
121
+ self.certauth_wrapper = self.initialize_certauth_create_use_ca_certificate(
122
+ server_certificate_directory=self.default_server_certificate_directory
80
123
  )
81
124
 
82
- return server_certificate_file_path, default_server_certificate_san
83
-
84
-
85
- def create_use_sni_server_certificate_ca_signed(sni_received_dict: dict, config: dict, print_kwargs: dict = None):
86
- global CERTAUTH_WRAPPER
87
-
88
- # === Connect to the domain and get the certificate. ===========================================================
89
- certificate_from_socket_x509 = None
90
- if config['certificates']['sni_get_server_certificate_from_server_socket']:
91
- # Generate PEM certificate file path string for downloaded certificates. Signed certificates will go to the
92
- # 'certs' folder.
93
- certificate_from_socket_file_path: str = \
94
- config['certificates']['sni_server_certificate_from_server_socket_download_directory'] + \
95
- os.sep + sni_received_dict['destination_name'] + ".pem"
96
- # Get client ip.
97
- client_ip = base.get_source_address_from_socket(sni_received_dict['ssl_socket'])[0]
98
-
99
- # If we're on localhost, then use external services list in order to resolve the domain:
100
- if client_ip == "127.0.0.1":
101
- service_client = socket_client.SocketClient(
102
- service_name=sni_received_dict['destination_name'],
103
- service_port=base.get_destination_address_from_socket(sni_received_dict['ssl_socket'])[1],
104
- dns_servers_list=config['tcp']['forwarding_dns_service_ipv4_list___only_for_localhost'])
105
- # If we're not on localhost, then connect to domain directly.
106
- else:
107
- service_client = socket_client.SocketClient(
108
- service_name=sni_received_dict['destination_name'],
109
- service_port=base.get_destination_address_from_socket(sni_received_dict['ssl_socket'])[1])
110
-
111
- # Get certificate from socket and convert to X509 cryptography module object.
112
- certificate_from_socket_x509_cryptography_object = service_client.get_certificate_from_server(
113
- save_as_file=True, cert_file_path=certificate_from_socket_file_path, cert_output_type='cryptography'
114
- )
125
+ server_certificate_file_name_no_extension = self.default_server_certificate_name
115
126
 
116
- # skip_extensions = ['1.3.6.1.5.5.7.3.2', '2.5.29.31', '1.3.6.1.5.5.7.1.1']
117
-
118
- # If certificate was downloaded successfully, then remove extensions if they were provided.
119
- # If certificate was downloaded successfully and no extensions to skip were provided, then use it as is.
120
- if certificate_from_socket_x509_cryptography_object and config['skip_extensions']:
121
- # Copy extensions from old certificate to new certificate, without specified extensions.
122
- certificate_from_socket_x509_cryptography_object, _ = \
123
- cryptographyw.copy_extensions_from_old_cert_to_new_cert(
124
- certificate_from_socket_x509_cryptography_object,
125
- skip_extensions=config['skip_extensions'],
126
- print_kwargs=print_kwargs
127
+ server_certificate_file_path, default_server_certificate_san = \
128
+ self.certauth_wrapper.create_overwrite_server_certificate_ca_signed_return_path_and_san(
129
+ domain_list=self.default_certificate_domain_list,
130
+ server_certificate_file_name_no_extension=server_certificate_file_name_no_extension
131
+ )
132
+
133
+ return server_certificate_file_path, default_server_certificate_san
134
+
135
+ def create_use_sni_server_certificate_ca_signed(
136
+ self,
137
+ sni_received_parameters,
138
+ print_kwargs: dict = None
139
+ ):
140
+ # === Connect to the domain and get the certificate. ===========================================================
141
+ certificate_from_socket_x509 = None
142
+ if self.sni_get_server_certificate_from_server_socket:
143
+ # Generate PEM certificate file path string for downloaded certificates. Signed certificates will go to the
144
+ # 'certs' folder.
145
+ certificate_from_socket_file_path: str = \
146
+ self.sni_server_certificate_from_server_socket_download_directory + \
147
+ os.sep + sni_received_parameters.destination_name + ".pem"
148
+ # Get client ip.
149
+ client_ip = base.get_source_address_from_socket(sni_received_parameters.ssl_socket)[0]
150
+
151
+ # If we're on localhost, then use external services list in order to resolve the domain:
152
+ if client_ip in base.THIS_DEVICE_IP_LIST:
153
+ service_client = socket_client.SocketClient(
154
+ service_name=sni_received_parameters.destination_name,
155
+ service_port=base.get_destination_address_from_socket(sni_received_parameters.ssl_socket)[1],
156
+ tls=self.tls,
157
+ dns_servers_list=self.forwarding_dns_service_ipv4_list___only_for_localhost)
158
+ # If we're not on localhost, then connect to domain directly.
159
+ else:
160
+ service_client = socket_client.SocketClient(
161
+ service_name=sni_received_parameters.destination_name,
162
+ service_port=base.get_destination_address_from_socket(sni_received_parameters.ssl_socket)[1],
163
+ tls=self.tls
127
164
  )
128
165
 
129
- # If certificate was downloaded successfully, then convert it to pyopenssl object.
130
- if certificate_from_socket_x509_cryptography_object:
131
- # Convert X509 cryptography module object to pyopenssl, since certauth uses pyopenssl.
132
- certificate_from_socket_x509 = \
133
- pyopensslw.convert_cryptography_object_to_pyopenssl(certificate_from_socket_x509_cryptography_object)
134
-
135
- # === EOF Get certificate from the domain. =====================================================================
136
-
137
- # If CertAuthWrapper wasn't initialized yet, it means that CA wasn't created/loaded yet.
138
- if not CERTAUTH_WRAPPER:
139
- CERTAUTH_WRAPPER = initialize_certauth_create_use_ca_certificate(config=config)
140
- # try:
141
- # Create if non-existent / read existing server certificate.
142
- sni_server_certificate_file_path = CERTAUTH_WRAPPER.create_read_server_certificate_ca_signed(
143
- sni_received_dict['destination_name'], certificate_from_socket_x509)
144
-
145
- message = f"SNI Handler: port " \
146
- f"{base.get_destination_address_from_socket(sni_received_dict['ssl_socket'])[1]}: " \
147
- f"Using certificate: {sni_server_certificate_file_path}"
148
- print_api(message, **print_kwargs)
149
-
150
- # except Exception as e:
151
- # message = \
152
- # f"SNI Handler: Undocumented exception while creating / using certificate for a domain: {e}"
153
- # print_api(
154
- # message, error_type=True, logger_method="critical", traceback_string=True, oneline=True,
155
- # logger=self.logger)
156
- # pass
157
-
158
- # try:
159
- # You need to build new context and exchange the context that being inherited from the main socket,
160
- # or else the context will receive previous certificate each time.
161
- sni_received_dict['ssl_socket'].context = \
162
- creator.create_server_ssl_context___load_certificate_and_key(sni_server_certificate_file_path, None)
163
- # except Exception as e:
164
- # message = \
165
- # f"SNI Handler: Undocumented exception while creating and assigning new SSLContext: {e}"
166
- # print_api(
167
- # message, error_type=True, logger_method="critical", traceback_string=True, oneline=True,
168
- # logger=self.logger)
169
- # pass
166
+ # If certificate from socket exists, then we don't need to get it from the socket and write to file.
167
+ # and we will return None, since no certificate was fetched.
168
+ # noinspection PyTypeChecker
169
+ certificate_from_socket_x509_cryptography_object: x509.Certificate = None
170
+ if not filesystem.is_file_exists(certificate_from_socket_file_path):
171
+ print_api("Certificate from socket doesn't exist, fetching.", **(print_kwargs or {}))
172
+ # Get certificate from socket and convert to X509 cryptography module object.
173
+ certificate_from_socket_x509_cryptography_object: x509.Certificate = (
174
+ service_client.get_certificate_from_server(
175
+ save_as_file=True, cert_file_path=certificate_from_socket_file_path,
176
+ cert_output_type='cryptography')
177
+ )
178
+ else:
179
+ print_api("The Certificate from socket already exists, not fetching", **(print_kwargs or {}))
180
+ certificate_from_socket_x509_cryptography_object: x509.Certificate = (
181
+ cryptographyw.convert_object_to_x509(certificate_from_socket_file_path))
182
+
183
+ # skip_extensions = ['1.3.6.1.5.5.7.3.2', '2.5.29.31', '1.3.6.1.5.5.7.1.1']
184
+
185
+ # If certificate was downloaded successfully, then remove extensions if they were provided.
186
+ # If certificate was downloaded successfully and no extensions to skip were provided, then use it as is.
187
+ if certificate_from_socket_x509_cryptography_object and self.skip_extension_id_list:
188
+ # Copy extensions from old certificate to new certificate, without specified extensions.
189
+ certificate_from_socket_x509_cryptography_object, _ = \
190
+ cryptographyw.copy_extensions_from_old_cert_to_new_cert(
191
+ certificate_from_socket_x509_cryptography_object,
192
+ skip_extensions=self.skip_extension_id_list,
193
+ print_kwargs=print_kwargs
194
+ )
195
+
196
+ # If certificate was downloaded successfully, then convert it to pyopenssl object.
197
+ if certificate_from_socket_x509_cryptography_object:
198
+ # Convert X509 cryptography module object to pyopenssl, since certauth uses pyopenssl.
199
+ certificate_from_socket_x509 = \
200
+ pyopensslw.convert_cryptography_object_to_pyopenssl(
201
+ certificate_from_socket_x509_cryptography_object)
202
+
203
+ # === EOF Get certificate from the domain. =====================================================================
204
+
205
+ # If CertAuthWrapper wasn't initialized yet, it means that CA wasn't created/loaded yet.
206
+ if not self.certauth_wrapper:
207
+ self.certauth_wrapper = self.initialize_certauth_create_use_ca_certificate(
208
+ server_certificate_directory=self.sni_server_certificates_cache_directory)
209
+ # try:
210
+ # Create if non-existent / read existing server certificate.
211
+ sni_server_certificate_file_path = self.certauth_wrapper.create_read_server_certificate_ca_signed(
212
+ sni_received_parameters.destination_name, certificate_from_socket_x509)
213
+
214
+ message = f"SNI Handler: port " \
215
+ f"{base.get_destination_address_from_socket(sni_received_parameters.ssl_socket)[1]}: " \
216
+ f"Using certificate: {sni_server_certificate_file_path}"
217
+ print_api(message, **print_kwargs)
218
+
219
+ # You need to build new context and exchange the context that being inherited from the main socket,
220
+ # or else the context will receive previous certificate each time.
221
+ sni_received_parameters.ssl_socket.context = \
222
+ creator.create_server_ssl_context___load_certificate_and_key(sni_server_certificate_file_path, None)