atomicshop 2.15.11__py3-none-any.whl → 3.10.5__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.
Files changed (221) hide show
  1. atomicshop/__init__.py +1 -1
  2. atomicshop/{addons/mains → a_mains}/FACT/update_extract.py +3 -2
  3. atomicshop/a_mains/dns_gateway_setting.py +11 -0
  4. atomicshop/a_mains/get_local_tcp_ports.py +85 -0
  5. atomicshop/a_mains/github_wrapper.py +11 -0
  6. atomicshop/a_mains/install_ca_certificate.py +172 -0
  7. atomicshop/a_mains/process_from_port.py +119 -0
  8. atomicshop/a_mains/set_default_dns_gateway.py +90 -0
  9. atomicshop/a_mains/update_config_toml.py +38 -0
  10. atomicshop/basics/ansi_escape_codes.py +3 -1
  11. atomicshop/basics/argparse_template.py +2 -0
  12. atomicshop/basics/booleans.py +27 -30
  13. atomicshop/basics/bytes_arrays.py +43 -0
  14. atomicshop/basics/classes.py +149 -1
  15. atomicshop/basics/enums.py +2 -2
  16. atomicshop/basics/exceptions.py +5 -1
  17. atomicshop/basics/list_of_classes.py +29 -0
  18. atomicshop/basics/multiprocesses.py +374 -50
  19. atomicshop/basics/strings.py +72 -3
  20. atomicshop/basics/threads.py +14 -0
  21. atomicshop/basics/tracebacks.py +13 -3
  22. atomicshop/certificates.py +153 -52
  23. atomicshop/config_init.py +11 -6
  24. atomicshop/console_user_response.py +7 -14
  25. atomicshop/consoles.py +9 -0
  26. atomicshop/datetimes.py +1 -1
  27. atomicshop/diff_check.py +3 -3
  28. atomicshop/dns.py +128 -3
  29. atomicshop/etws/_pywintrace_fix.py +17 -0
  30. atomicshop/etws/trace.py +40 -42
  31. atomicshop/etws/traces/trace_dns.py +56 -44
  32. atomicshop/etws/traces/trace_tcp.py +130 -0
  33. atomicshop/file_io/csvs.py +27 -5
  34. atomicshop/file_io/docxs.py +34 -17
  35. atomicshop/file_io/file_io.py +31 -17
  36. atomicshop/file_io/jsons.py +49 -0
  37. atomicshop/file_io/tomls.py +139 -0
  38. atomicshop/filesystem.py +616 -291
  39. atomicshop/get_process_list.py +3 -3
  40. atomicshop/http_parse.py +149 -93
  41. atomicshop/ip_addresses.py +6 -1
  42. atomicshop/mitm/centered_settings.py +132 -0
  43. atomicshop/mitm/config_static.py +207 -0
  44. atomicshop/mitm/config_toml_editor.py +55 -0
  45. atomicshop/mitm/connection_thread_worker.py +875 -357
  46. atomicshop/mitm/engines/__parent/parser___parent.py +4 -17
  47. atomicshop/mitm/engines/__parent/recorder___parent.py +108 -51
  48. atomicshop/mitm/engines/__parent/requester___parent.py +116 -0
  49. atomicshop/mitm/engines/__parent/responder___parent.py +75 -114
  50. atomicshop/mitm/engines/__reference_general/parser___reference_general.py +10 -7
  51. atomicshop/mitm/engines/__reference_general/recorder___reference_general.py +5 -5
  52. atomicshop/mitm/engines/__reference_general/requester___reference_general.py +47 -0
  53. atomicshop/mitm/engines/__reference_general/responder___reference_general.py +95 -13
  54. atomicshop/mitm/engines/create_module_template.py +58 -14
  55. atomicshop/mitm/import_config.py +359 -139
  56. atomicshop/mitm/initialize_engines.py +160 -80
  57. atomicshop/mitm/message.py +64 -23
  58. atomicshop/mitm/mitm_main.py +892 -0
  59. atomicshop/mitm/recs_files.py +183 -0
  60. atomicshop/mitm/shared_functions.py +4 -10
  61. atomicshop/mitm/ssh_tester.py +82 -0
  62. atomicshop/mitm/statistic_analyzer.py +136 -40
  63. atomicshop/mitm/statistic_analyzer_helper/moving_average_helper.py +265 -83
  64. atomicshop/monitor/checks/dns.py +1 -1
  65. atomicshop/networks.py +671 -0
  66. atomicshop/on_exit.py +39 -9
  67. atomicshop/package_mains_processor.py +84 -0
  68. atomicshop/permissions/permissions.py +22 -0
  69. atomicshop/permissions/ubuntu_permissions.py +239 -0
  70. atomicshop/permissions/win_permissions.py +33 -0
  71. atomicshop/print_api.py +24 -42
  72. atomicshop/process.py +24 -6
  73. atomicshop/process_poller/process_pool.py +0 -1
  74. atomicshop/process_poller/simple_process_pool.py +204 -5
  75. atomicshop/python_file_patcher.py +1 -1
  76. atomicshop/python_functions.py +27 -75
  77. atomicshop/speech_recognize.py +8 -0
  78. atomicshop/ssh_remote.py +158 -172
  79. atomicshop/system_resource_monitor.py +61 -47
  80. atomicshop/system_resources.py +8 -8
  81. atomicshop/tempfiles.py +1 -2
  82. atomicshop/urls.py +6 -0
  83. atomicshop/venvs.py +28 -0
  84. atomicshop/versioning.py +27 -0
  85. atomicshop/web.py +98 -27
  86. atomicshop/web_apis/google_custom_search.py +44 -0
  87. atomicshop/web_apis/google_llm.py +188 -0
  88. atomicshop/websocket_parse.py +450 -0
  89. atomicshop/wrappers/certauthw/certauth.py +1 -0
  90. atomicshop/wrappers/cryptographyw.py +29 -8
  91. atomicshop/wrappers/ctyping/etw_winapi/const.py +97 -47
  92. atomicshop/wrappers/ctyping/etw_winapi/etw_functions.py +178 -49
  93. atomicshop/wrappers/ctyping/file_details_winapi.py +67 -0
  94. atomicshop/wrappers/ctyping/msi_windows_installer/cabs.py +2 -1
  95. atomicshop/wrappers/ctyping/msi_windows_installer/extract_msi_main.py +2 -2
  96. atomicshop/wrappers/ctyping/setup_device.py +466 -0
  97. atomicshop/wrappers/ctyping/win_console.py +39 -0
  98. atomicshop/wrappers/dockerw/dockerw.py +113 -2
  99. atomicshop/wrappers/elasticsearchw/config_basic.py +0 -12
  100. atomicshop/wrappers/elasticsearchw/elastic_infra.py +75 -0
  101. atomicshop/wrappers/elasticsearchw/elasticsearchw.py +2 -20
  102. atomicshop/wrappers/factw/get_file_data.py +12 -5
  103. atomicshop/wrappers/factw/install/install_after_restart.py +89 -5
  104. atomicshop/wrappers/factw/install/pre_install_and_install_before_restart.py +20 -14
  105. atomicshop/wrappers/githubw.py +537 -54
  106. atomicshop/wrappers/loggingw/consts.py +1 -1
  107. atomicshop/wrappers/loggingw/filters.py +23 -0
  108. atomicshop/wrappers/loggingw/formatters.py +12 -0
  109. atomicshop/wrappers/loggingw/handlers.py +214 -107
  110. atomicshop/wrappers/loggingw/loggers.py +19 -0
  111. atomicshop/wrappers/loggingw/loggingw.py +860 -22
  112. atomicshop/wrappers/loggingw/reading.py +134 -112
  113. atomicshop/wrappers/mongodbw/mongo_infra.py +31 -0
  114. atomicshop/wrappers/mongodbw/mongodbw.py +1324 -36
  115. atomicshop/wrappers/netshw.py +271 -0
  116. atomicshop/wrappers/playwrightw/engine.py +34 -19
  117. atomicshop/wrappers/playwrightw/infra.py +5 -0
  118. atomicshop/wrappers/playwrightw/javascript.py +7 -3
  119. atomicshop/wrappers/playwrightw/keyboard.py +14 -0
  120. atomicshop/wrappers/playwrightw/scenarios.py +172 -5
  121. atomicshop/wrappers/playwrightw/waits.py +9 -7
  122. atomicshop/wrappers/powershell_networking.py +80 -0
  123. atomicshop/wrappers/psutilw/processes.py +37 -1
  124. atomicshop/wrappers/psutilw/psutil_networks.py +85 -0
  125. atomicshop/wrappers/pyopensslw.py +9 -2
  126. atomicshop/wrappers/pywin32w/cert_store.py +116 -0
  127. atomicshop/wrappers/pywin32w/win_event_log/fetch.py +174 -0
  128. atomicshop/wrappers/pywin32w/win_event_log/subscribes/process_create.py +3 -105
  129. atomicshop/wrappers/pywin32w/win_event_log/subscribes/process_terminate.py +3 -57
  130. atomicshop/wrappers/pywin32w/wmis/msft_netipaddress.py +113 -0
  131. atomicshop/wrappers/pywin32w/wmis/win32_networkadapterconfiguration.py +259 -0
  132. atomicshop/wrappers/pywin32w/wmis/win32networkadapter.py +112 -0
  133. atomicshop/wrappers/pywin32w/wmis/wmi_helpers.py +236 -0
  134. atomicshop/wrappers/socketw/accepter.py +21 -7
  135. atomicshop/wrappers/socketw/certificator.py +216 -150
  136. atomicshop/wrappers/socketw/creator.py +190 -50
  137. atomicshop/wrappers/socketw/dns_server.py +491 -182
  138. atomicshop/wrappers/socketw/exception_wrapper.py +45 -52
  139. atomicshop/wrappers/socketw/process_getter.py +86 -0
  140. atomicshop/wrappers/socketw/receiver.py +144 -102
  141. atomicshop/wrappers/socketw/sender.py +65 -35
  142. atomicshop/wrappers/socketw/sni.py +334 -165
  143. atomicshop/wrappers/socketw/socket_base.py +134 -0
  144. atomicshop/wrappers/socketw/socket_client.py +137 -95
  145. atomicshop/wrappers/socketw/socket_server_tester.py +11 -7
  146. atomicshop/wrappers/socketw/socket_wrapper.py +717 -116
  147. atomicshop/wrappers/socketw/ssl_base.py +15 -14
  148. atomicshop/wrappers/socketw/statistics_csv.py +148 -17
  149. atomicshop/wrappers/sysmonw.py +1 -1
  150. atomicshop/wrappers/ubuntu_terminal.py +65 -26
  151. atomicshop/wrappers/win_auditw.py +189 -0
  152. atomicshop/wrappers/winregw/__init__.py +0 -0
  153. atomicshop/wrappers/winregw/winreg_installed_software.py +58 -0
  154. atomicshop/wrappers/winregw/winreg_network.py +232 -0
  155. {atomicshop-2.15.11.dist-info → atomicshop-3.10.5.dist-info}/METADATA +31 -51
  156. atomicshop-3.10.5.dist-info/RECORD +306 -0
  157. {atomicshop-2.15.11.dist-info → atomicshop-3.10.5.dist-info}/WHEEL +1 -1
  158. atomicshop/_basics_temp.py +0 -101
  159. atomicshop/a_installs/win/fibratus.py +0 -9
  160. atomicshop/a_installs/win/mongodb.py +0 -9
  161. atomicshop/a_installs/win/pycharm.py +0 -9
  162. atomicshop/addons/a_setup_scripts/install_psycopg2_ubuntu.sh +0 -3
  163. atomicshop/addons/a_setup_scripts/install_pywintrace_0.3.cmd +0 -2
  164. atomicshop/addons/mains/__pycache__/install_fibratus_windows.cpython-312.pyc +0 -0
  165. atomicshop/addons/mains/__pycache__/msi_unpacker.cpython-312.pyc +0 -0
  166. atomicshop/addons/mains/install_docker_rootless_ubuntu.py +0 -11
  167. atomicshop/addons/mains/install_docker_ubuntu_main_sudo.py +0 -11
  168. atomicshop/addons/mains/install_elastic_search_and_kibana_ubuntu.py +0 -10
  169. atomicshop/addons/mains/install_wsl_ubuntu_lts_admin.py +0 -9
  170. atomicshop/addons/package_setup/CreateWheel.cmd +0 -7
  171. atomicshop/addons/package_setup/Setup in Edit mode.cmd +0 -6
  172. atomicshop/addons/package_setup/Setup.cmd +0 -7
  173. atomicshop/archiver/_search_in_zip.py +0 -189
  174. atomicshop/archiver/archiver.py +0 -34
  175. atomicshop/archiver/search_in_archive.py +0 -250
  176. atomicshop/archiver/sevenz_app_w.py +0 -86
  177. atomicshop/archiver/sevenzs.py +0 -44
  178. atomicshop/archiver/zips.py +0 -293
  179. atomicshop/file_types.py +0 -24
  180. atomicshop/mitm/config_editor.py +0 -37
  181. atomicshop/mitm/engines/create_module_template_example.py +0 -13
  182. atomicshop/mitm/initialize_mitm_server.py +0 -268
  183. atomicshop/pbtkmultifile_argparse.py +0 -88
  184. atomicshop/permissions.py +0 -151
  185. atomicshop/script_as_string_processor.py +0 -38
  186. atomicshop/ssh_scripts/process_from_ipv4.py +0 -37
  187. atomicshop/ssh_scripts/process_from_port.py +0 -27
  188. atomicshop/wrappers/_process_wrapper_curl.py +0 -27
  189. atomicshop/wrappers/_process_wrapper_tar.py +0 -21
  190. atomicshop/wrappers/dockerw/install_docker.py +0 -209
  191. atomicshop/wrappers/elasticsearchw/infrastructure.py +0 -265
  192. atomicshop/wrappers/elasticsearchw/install_elastic.py +0 -232
  193. atomicshop/wrappers/ffmpegw.py +0 -125
  194. atomicshop/wrappers/fibratusw/install.py +0 -81
  195. atomicshop/wrappers/mongodbw/infrastructure.py +0 -53
  196. atomicshop/wrappers/mongodbw/install_mongodb.py +0 -190
  197. atomicshop/wrappers/msiw.py +0 -149
  198. atomicshop/wrappers/nodejsw/install_nodejs.py +0 -139
  199. atomicshop/wrappers/process_wrapper_pbtk.py +0 -16
  200. atomicshop/wrappers/psutilw/networks.py +0 -45
  201. atomicshop/wrappers/pycharmw.py +0 -81
  202. atomicshop/wrappers/socketw/base.py +0 -59
  203. atomicshop/wrappers/socketw/get_process.py +0 -107
  204. atomicshop/wrappers/wslw.py +0 -191
  205. atomicshop-2.15.11.dist-info/RECORD +0 -302
  206. /atomicshop/{addons/mains → a_mains}/FACT/factw_fact_extractor_docker_image_main_sudo.py +0 -0
  207. /atomicshop/{addons → a_mains/addons}/PlayWrightCodegen.cmd +0 -0
  208. /atomicshop/{addons → a_mains/addons}/ScriptExecution.cmd +0 -0
  209. /atomicshop/{addons → a_mains/addons}/inits/init_to_import_all_modules.py +0 -0
  210. /atomicshop/{addons → a_mains/addons}/process_list/ReadMe.txt +0 -0
  211. /atomicshop/{addons → a_mains/addons}/process_list/compile.cmd +0 -0
  212. /atomicshop/{addons → a_mains/addons}/process_list/compiled/Win10x64/process_list.dll +0 -0
  213. /atomicshop/{addons → a_mains/addons}/process_list/compiled/Win10x64/process_list.exp +0 -0
  214. /atomicshop/{addons → a_mains/addons}/process_list/compiled/Win10x64/process_list.lib +0 -0
  215. /atomicshop/{addons → a_mains/addons}/process_list/process_list.cpp +0 -0
  216. /atomicshop/{archiver → permissions}/__init__.py +0 -0
  217. /atomicshop/{wrappers/fibratusw → web_apis}/__init__.py +0 -0
  218. /atomicshop/wrappers/{nodejsw → pywin32w/wmis}/__init__.py +0 -0
  219. /atomicshop/wrappers/pywin32w/{wmi_win32process.py → wmis/win32process.py} +0 -0
  220. {atomicshop-2.15.11.dist-info → atomicshop-3.10.5.dist-info/licenses}/LICENSE.txt +0 -0
  221. {atomicshop-2.15.11.dist-info → atomicshop-3.10.5.dist-info}/top_level.txt +0 -0
@@ -5,9 +5,10 @@ https://oidref.com/1.3.6.1.5.5.7.3.1
5
5
 
6
6
 
7
7
  import ssl
8
+ from typing import Literal, Any
8
9
 
9
10
  from .wrappers import cryptographyw
10
- from .print_api import print_api
11
+ from .wrappers.pywin32w import cert_store
11
12
 
12
13
 
13
14
  # Valid for 3 years from now
@@ -16,72 +17,172 @@ from .print_api import print_api
16
17
  SECONDS_NOT_AFTER_3_YEARS = 3 * 365 * 24 * 60 * 60
17
18
 
18
19
 
19
- def is_certificate_in_store(certificate, issuer_only: bool = False, thumbprint_only: bool = False):
20
+ def get_pem_certificate_from_string(certificate: str) -> str:
20
21
  """
21
- The function will check if the certificate is installed in the Windows certificate store.
22
-
23
- :param certificate: x509 object, certificate to check.
24
- :param issuer_only: bool, if True, will check only by the certificate issuer common name is installed in the store.
25
- The problem that the issuer common name is not unique, so it can be installed multiple times.
26
- :param thumbprint_only: bool, if True, will check only by the certificate thumbprint is installed in the store.
27
- The problem that searching by the thumbprint will not tell you if there are multiple certificates with the same
28
- issuer name.
29
- :return: bool, True if certificate is installed, False if not.
22
+ Some PEM certificates can contain a private key. This function will return only the certificate part.
23
+
24
+ :param certificate: string, PEM certificate.
25
+ :return: string, certificate part.
30
26
  """
31
27
 
32
- # Make sure the certificate is x509.Certificate object.
33
- certificate = cryptographyw.convert_object_to_x509(certificate)
34
- # Get the certificate thumbprint.
35
- thumbprint = cryptographyw.get_sha1_thumbprint_from_x509(certificate)
36
- issuer_common_name: str = cryptographyw.get_issuer_common_name_from_x509(certificate)
28
+ certificate_lines = certificate.split('\n')
29
+ certificate_part = ''
30
+ start = False
31
+ for line in certificate_lines:
32
+ if 'BEGIN CERTIFICATE' in line:
33
+ start = True
34
+ if start:
35
+ certificate_part += line + '\n'
36
+ if 'END CERTIFICATE' in line:
37
+ break
37
38
 
38
- # for store in ["CA", "ROOT", "MY"]:
39
- for cert, encoding, trust in ssl.enum_certificates("ROOT"):
40
- store_certificate = cryptographyw.convert_object_to_x509(cert)
41
- store_issuer_common_name: str = cryptographyw.get_issuer_common_name_from_x509(store_certificate)
42
- store_thumbprint = cryptographyw.get_sha1_thumbprint_from_x509(store_certificate)
43
-
44
- if issuer_only:
45
- if store_issuer_common_name == issuer_common_name:
46
- return True, certificate
47
- elif thumbprint_only:
48
- if store_thumbprint == thumbprint:
49
- return True, certificate
50
- elif not issuer_only and not thumbprint_only:
51
- if store_thumbprint == thumbprint and store_issuer_common_name == issuer_common_name:
52
- return True, certificate
39
+ return certificate_part
53
40
 
54
41
 
55
- def get_certificates_by_issuer_name(issuer_name: str, print_kwargs: dict = None):
42
+ def write_crt_certificate_file_in_pem_format_from_pem_file(
43
+ pem_file_path: str,
44
+ crt_file_path: str
45
+ ):
56
46
  """
57
- The function will return all certificates with the specified issuer name.
47
+ The function will read the PEM certificate file and write it to the CRT file in PEM format.
48
+ The function is used to convert the PEM certificate file to the CRT file.
58
49
 
59
- :param issuer_name: string, issuer name to search for.
60
- :param print_kwargs: dict, that contains all the arguments for 'print_api' function.
50
+ Basically the point here is that the CRT file is the same as the PEM file, but the extension is different,
51
+ and it doesn't support integrated private key.
61
52
 
62
- :return: list, of certificates with the specified issuer name.
53
+ :param pem_file_path: string, path to the PEM certificate file.
54
+ :param crt_file_path: string, path to the CRT certificate file.
63
55
  """
64
56
 
65
- if not print_kwargs:
66
- print_kwargs = {}
57
+ with open(pem_file_path, 'r') as f:
58
+ certificate_string = f.read()
67
59
 
68
- certificates_list = []
60
+ certificate_pem = get_pem_certificate_from_string(certificate_string)
61
+
62
+ with open(crt_file_path, 'w') as f:
63
+ f.write(certificate_pem)
64
+
65
+
66
+ def is_certificate_in_store(
67
+ certificate: Any = None,
68
+ by_cert_issuer: bool = True,
69
+ by_cert_thumbprint: bool = True,
70
+ issuer_name: str = None,
71
+ store_location: str = "ROOT",
72
+ print_kwargs: dict = None
73
+ ) -> tuple[bool, list]:
74
+ """
75
+ The function will check if the CA certificate is installed in the Windows certificate Trusted Root store.
76
+ NO ADMIN RIGHTS NEEDED.
77
+
78
+ :param certificate: x509 object, certificate to check. You can search by certificate or by issuer name.
79
+ Supported types:
80
+ string that is path to file will be imported as bytes object abd converted to x509.Certificate
81
+ After check if it's PEM or DER format.
82
+ string that is PEM certificate will be converted to bytes, then x509.Certificate
83
+ bytes of PEM or DER will be converted to x509.Certificate.
84
+ x509.Certificate will be returned as is.
85
+ :param by_cert_issuer: bool, if True, will check only by the certificate issuer common name is installed in the store.
86
+ The problem if the search will be by issuer alone, that the issuer common name is not unique,
87
+ so it can be installed multiple times.
88
+ :param by_cert_thumbprint: bool, if True, will check only by the certificate thumbprint is installed in the store.
89
+ The problem that searching by the thumbprint alone will not tell you if there are multiple
90
+ certificates with the same issuer name.
91
+ :param issuer_name: string, issuer name to search for. You can search by certificate or by issuer name.
92
+ :param store_location: string, store location to search in. Default is "ROOT".
93
+ :param print_kwargs: dict, print_api kwargs.
94
+ :return: tuple(bool - True if certificate is installed and False if not, list of certificates found)
95
+ """
96
+
97
+ if not by_cert_issuer and not by_cert_thumbprint:
98
+ raise ValueError('At least one of the parameters "by_issuer" or "by_thumbprint" must be True.')
99
+
100
+ if not certificate and not issuer_name:
101
+ raise ValueError('At least one of the parameters "certificate" or "issuer_name" must be provided.')
102
+ elif certificate and issuer_name:
103
+ raise ValueError('Only one of the parameters "certificate" or "issuer_name" must be provided.')
104
+
105
+ if certificate:
106
+ # Make sure the certificate is x509.Certificate object.
107
+ certificate_x509 = cryptographyw.convert_object_to_x509(certificate, print_kwargs=print_kwargs)
108
+ # Get the certificate thumbprint.
109
+ provided_thumbprint = cryptographyw.get_sha1_thumbprint_from_x509(certificate_x509)
110
+ provided_issuer_common_name: str = cryptographyw.get_issuer_common_name_from_x509(certificate_x509)
111
+ elif issuer_name:
112
+ provided_thumbprint = None
113
+ provided_issuer_common_name = issuer_name
114
+ else:
115
+ raise ValueError('At least one of the parameters "certificate" or "issuer_name" must be provided.')
69
116
 
70
- for cert, encoding, trust in ssl.enum_certificates("ROOT"):
117
+ # Iterate over all certificates in the store specifically in the ROOT.
118
+ # for store in ["CA", "ROOT", "MY"]:
119
+ result_found_list: list = []
120
+ found: bool = False
121
+ for cert, encoding, trust in ssl.enum_certificates(store_location):
122
+ # Some certificates in the store can have zero or negative serial number.
123
+ # We will skip them, since they're deprecated by the cryptography library.
71
124
  store_certificate = cryptographyw.convert_object_to_x509(cert)
125
+ if not store_certificate:
126
+ continue
127
+
72
128
  store_issuer_common_name: str = cryptographyw.get_issuer_common_name_from_x509(store_certificate)
129
+ store_thumbprint = cryptographyw.get_sha1_thumbprint_from_x509(store_certificate)
73
130
 
74
- if store_issuer_common_name == issuer_name:
75
- certificates_list.append(store_certificate)
131
+ if certificate:
132
+ if by_cert_issuer and not by_cert_thumbprint:
133
+ if store_issuer_common_name == provided_issuer_common_name:
134
+ result_found_list.append(store_certificate)
135
+ found = True
136
+ elif by_cert_thumbprint and not by_cert_issuer:
137
+ if store_thumbprint == provided_thumbprint:
138
+ result_found_list.append(store_certificate)
139
+ found = True
140
+ elif by_cert_issuer and by_cert_thumbprint:
141
+ if store_thumbprint == provided_thumbprint and store_issuer_common_name == provided_issuer_common_name:
142
+ result_found_list.append(store_certificate)
143
+ found = True
144
+ elif issuer_name:
145
+ if store_issuer_common_name == provided_issuer_common_name:
146
+ result_found_list.append(store_certificate)
147
+ found = True
148
+
149
+ return found, result_found_list
150
+
151
+
152
+ def delete_certificate_by_issuer_name(
153
+ issuer_name: str,
154
+ store_location: Literal[
155
+ "ROOT",
156
+ "CA",
157
+ "MY"] = "ROOT",
158
+ print_kwargs: dict = None
159
+ ):
160
+ """
161
+ NEED ADMIN RIGHTS.
162
+ The function will remove all certificates with the specified issuer name.
163
+ There can be several certificates with this name.
76
164
 
77
- if certificates_list:
78
- for certificate_single in certificates_list:
79
- issuer_name = cryptographyw.get_issuer_common_name_from_x509(certificate_single)
80
- thumbprint = cryptographyw.get_sha1_thumbprint_from_x509(certificate_single)
81
- message = f'Issuer name: {issuer_name} | Thumbprint: {thumbprint}'
82
- print_api(message, **print_kwargs)
83
- else:
84
- message = f'No certificates with issuer name: {issuer_name}'
85
- print_api(message, **print_kwargs)
165
+ :param issuer_name: string, issuer name to search for.
166
+ :param store_location: string, store location to search in. Default is "ROOT".
167
+ :param print_kwargs: dict, print_api kwargs.
168
+ """
169
+
170
+ cert_store.delete_certificate_by_issuer_name(issuer_name, store_location, print_kwargs)
171
+
172
+
173
+ def install_certificate_file(
174
+ file_path: str,
175
+ store_location: Literal[
176
+ "ROOT", "CA", "MY"] = "ROOT",
177
+ print_kwargs: dict = None
178
+ ):
179
+ """
180
+ The function will install the certificate from the file to the specified store location.
181
+ NEED ADMIN RIGHTS.
182
+
183
+ :param file_path: string, full file path to the certificate file.
184
+ :param store_location: string, store location to install the certificate. Default is "ROOT".
185
+ :param print_kwargs: dict, print_api kwargs.
186
+ """
86
187
 
87
- return certificates_list
188
+ cert_store.install_certificate_file(file_path, store_location, print_kwargs)
atomicshop/config_init.py CHANGED
@@ -2,13 +2,17 @@ import os
2
2
 
3
3
  from .file_io import tomls
4
4
  from . import filesystem
5
- from .print_api import print_api
5
+ from . import print_api
6
6
 
7
7
  CONFIG_FILE_NAME = 'config.toml'
8
8
  CONFIG: dict = dict()
9
9
 
10
10
 
11
- def get_config(script_directory: str = None, config_file_name: str = CONFIG_FILE_NAME) -> dict:
11
+ def get_config(
12
+ script_directory: str = None,
13
+ config_file_name: str = CONFIG_FILE_NAME,
14
+ print_kwargs: dict = None
15
+ ) -> dict:
12
16
  """
13
17
  Get the config file content.
14
18
 
@@ -16,6 +20,7 @@ def get_config(script_directory: str = None, config_file_name: str = CONFIG_FILE
16
20
  get the working directory instead.
17
21
  :param config_file_name: string, name of the config file. Default is 'config.toml' as specified in the constant:
18
22
  'CONFIG_FILE_NAME'.
23
+ :param print_kwargs: dict, additional arguments to pass to the print function. Default is None.
19
24
  :return: dict.
20
25
  """
21
26
 
@@ -25,7 +30,7 @@ def get_config(script_directory: str = None, config_file_name: str = CONFIG_FILE
25
30
  if not script_directory:
26
31
  script_directory = filesystem.get_working_directory()
27
32
 
28
- CONFIG = tomls.read_toml_file(f'{script_directory}{os.sep}{config_file_name}')
33
+ CONFIG = tomls.read_toml_file(f'{script_directory}{os.sep}{config_file_name}', **(print_kwargs or {}))
29
34
  return CONFIG
30
35
 
31
36
 
@@ -45,7 +50,7 @@ def write_config(
45
50
  'CONFIG_FILE_NAME'.
46
51
  :param print_message: boolean, if True, the function will print the message about the created config file.
47
52
  Also, it will wait for the user to press Enter to exit the script.
48
- If False, the function will not print anything and will not exit..
53
+ If False, the function will not print anything and will not exit.
49
54
  :return:
50
55
  """
51
56
 
@@ -62,7 +67,7 @@ def write_config(
62
67
  tomls.write_toml_file(config, f'{script_directory}{os.sep}{config_file_name}')
63
68
 
64
69
  if print_message:
65
- print_api(f"Created config file: {config_file_path}", color="yellow")
66
- print_api(f"You need to fill it with details.", color="yellow")
70
+ print_api.print_api(f"Created config file: {config_file_path}", color="yellow")
71
+ print_api.print_api(f"You need to fill it with details.", color="yellow")
67
72
  input("Press Enter to exit.")
68
73
  exit()
@@ -1,11 +1,12 @@
1
- # v1.0.2 - 26.03.2023 20:40
2
1
  import sys
3
2
 
4
3
 
5
- def query_positive_negative(question_string: str,
6
- add_first_values_to_question: bool = True,
7
- positive_answers: list = None,
8
- negative_answers: list = None) -> bool:
4
+ def query_positive_negative(
5
+ question_string: str,
6
+ add_first_values_to_question: bool = True,
7
+ positive_answers: list = None,
8
+ negative_answers: list = None
9
+ ) -> bool:
9
10
  """
10
11
  Ask for "yes" / "no" input to a question that is passed as a "question_string".
11
12
  Returns 'True' for 'positive' answers and 'False' for 'negative' answers.
@@ -31,10 +32,8 @@ def query_positive_negative(question_string: str,
31
32
  if add_first_values_to_question:
32
33
  question_string = f'{question_string} [{positive_answers[0]}/{negative_answers[0]}]'
33
34
 
34
- # Defining variable as False for While loop to run
35
- right_answer = False
36
35
  # As long as "right_answer" is False the loop will execute again
37
- while not right_answer:
36
+ while True:
38
37
  # Print the passed question
39
38
  print(question_string)
40
39
  # Get the input from the console in lowercase
@@ -42,22 +41,16 @@ def query_positive_negative(question_string: str,
42
41
 
43
42
  # If the gathered value is in "Yes" answers array
44
43
  if choice in positive_answers:
45
- # "right_answer" variable is True, so the loop will not execute again
46
- right_answer = True
47
44
  # Function will return True
48
45
  return True
49
46
  # Else If the gathered value is in "No" answers array
50
47
  elif choice in negative_answers:
51
- # "right_answer" variable is True, so the loop will not execute again
52
- right_answer = True
53
48
  # Function will return False
54
49
  return False
55
50
  # If the gathered input is not in the arrays
56
51
  else:
57
52
  # Then output to console the message
58
53
  print("Please respond with either:", positive_answers, negative_answers)
59
- # "right_answer" variable stays False, so the loop will execute again
60
- right_answer = False
61
54
 
62
55
 
63
56
  def do_you_want_to_continue_yn(message: str) -> None:
atomicshop/consoles.py ADDED
@@ -0,0 +1,9 @@
1
+ import msvcrt
2
+
3
+
4
+ # === WINDOWS ONLY FUNCTIONS ===========================================================================================
5
+ def wait_any_key(prompt="Press any key to continue..."):
6
+ print(prompt, end="", flush=True)
7
+ msvcrt.getch() # waits for one key press (no Enter needed)
8
+ print() # move to next line
9
+ # === EOF WINDOWS ONLY FUNCTIONS =======================================================================================
atomicshop/datetimes.py CHANGED
@@ -74,7 +74,7 @@ def get_datetime_from_complex_string_by_pattern(
74
74
  complex_string: str,
75
75
  date_pattern: str
76
76
  ) -> tuple[
77
- Union[datetime, None],
77
+ Union[datetime.datetime, None],
78
78
  Union[str, None],
79
79
  Union[float, None]
80
80
  ]:
atomicshop/diff_check.py CHANGED
@@ -54,9 +54,9 @@ class DiffChecker:
54
54
  function input for that object. So, not always you know what your object type during class initialization.
55
55
  :param check_object_display_name: string, name of the object to display in the message.
56
56
  If not specified, the provided 'check_object' will be displayed.
57
- :param aggregation: boolean, if True, the object will be aggregated with other objects in the list of objects.
58
- Meaning, that the object will be checked against the existing objects in the list, and if it is not
59
- in the list, it will be added to the list. If it is in the list, it will be ignored.
57
+ #:param aggregation: boolean, if True, the object will be aggregated with other objects in the list of objects.
58
+ # Meaning, that the object will be checked against the existing objects in the list, and if it is not
59
+ # in the list, it will be added to the list. If it is in the list, it will be ignored.
60
60
  :param input_file_path: string, full file path for storing input file for current state of objects,
61
61
  to check later if this state isn't updated. If this variable is left empty, all the content will be saved
62
62
  in memory and input file will not be used.
atomicshop/dns.py CHANGED
@@ -1,6 +1,14 @@
1
+ import socket
2
+ import argparse
3
+
4
+ # noinspection PyPackageRequirements
1
5
  import dns.resolver
2
6
 
3
- from .print_api import print_api
7
+ from . import print_api
8
+ from . import networks
9
+ from .permissions import permissions
10
+ from .wrappers.pywin32w.wmis import win32networkadapter
11
+ from .wrappers import netshw
4
12
 
5
13
 
6
14
  # Defining Dictionary of Numeric to String DNS Query Types.
@@ -52,10 +60,127 @@ def resolve_dns_localhost(domain_name: str, dns_servers_list: list = None, print
52
60
  # Get only the first entry of the list of IPs [0]
53
61
  connection_ip = function_server_address[0].to_text()
54
62
  message = f"Resolved to [{connection_ip}]"
55
- print_api(message, **print_kwargs)
63
+ print_api.print_api(message, **print_kwargs)
56
64
  except dns.resolver.NXDOMAIN:
57
65
  message = f"Domain {domain_name} doesn't exist - Couldn't resolve with {dns_servers_list}."
58
- print_api(message, **print_kwargs, error_type=True, logger_method='error')
66
+ print_api.print_api(message, **print_kwargs, error_type=True, logger_method='error')
59
67
  pass
60
68
 
61
69
  return connection_ip
70
+
71
+
72
+ def get_default_dns_gateway() -> tuple[bool, list[str]]:
73
+ """
74
+ Get the default DNS gateway from the system.
75
+ :return: tuple(is dynamic boolean, list of DNS server IPv4s).
76
+ """
77
+
78
+ interfaces_with_dns_settings: list[dict] = netshw.get_netsh_ipv4()
79
+
80
+ default_interface_ipv4 = socket.gethostbyname(socket.gethostname())
81
+ is_dynamic, dns_servers = None, None
82
+ for interface in interfaces_with_dns_settings:
83
+ if default_interface_ipv4 in interface['ip_addresses']:
84
+ is_dynamic = interface['dns_mode']
85
+ dns_servers = interface['dns_servers']
86
+ break
87
+
88
+ return is_dynamic, dns_servers
89
+
90
+
91
+ def get_default_dns_gateway_with_dns_resolver() -> list[str]:
92
+ """
93
+ Get the default DNS gateway from the system using dns.resolver.
94
+ :return: tuple(is dynamic boolean, list of DNS server IPv4s).
95
+ """
96
+
97
+ resolver = dns.resolver.Resolver()
98
+ dns_servers = list(resolver.nameservers)
99
+ return dns_servers
100
+
101
+
102
+ def set_interface_dns_gateway_static(
103
+ interface_name: str,
104
+ dns_servers: list[str]
105
+ ) -> None:
106
+ """
107
+ Set the DNS servers for a network adapter.
108
+ :param interface_name: string, adapter name as shown in the network settings.
109
+ :param dns_servers: list of strings, DNS server IPv4 addresses.
110
+ :return: None
111
+ """
112
+
113
+ win32networkadapter.set_dns_server(interface_name=interface_name, dns_servers=dns_servers)
114
+
115
+
116
+ def set_interface_dns_gateway_dynamic(
117
+ interface_name: str = None
118
+ ) -> None:
119
+ """
120
+ Set the DNS servers for a network adapter to obtain them automatically from DHCP.
121
+ :param interface_name: string, adapter name as shown in the network settings.
122
+ :return: None
123
+ """
124
+
125
+ win32networkadapter.set_dns_server(
126
+ interface_name=interface_name, dns_servers=None)
127
+
128
+
129
+ def default_dns_gateway_main() -> int:
130
+ """
131
+ Main function for the default DNS gateway manipulations.
132
+ :return: None
133
+ """
134
+
135
+ argparse_obj = argparse.ArgumentParser(description="Get/Set the DNS gateway for the network adapter.")
136
+ arg_action_group = argparse_obj.add_mutually_exclusive_group(required=True)
137
+ arg_action_group.add_argument(
138
+ '-g', '--get', action='store_true', help='Get the default DNS gateway for the system.')
139
+ arg_action_group.add_argument(
140
+ '-s', '--set', type=str, nargs='+',
141
+ help='Set static DNS gateway for the system, provide values with spaces between each value.\n'
142
+ ' Example: -s 8.8.8.8 1.1.1.1.')
143
+ arg_action_group.add_argument(
144
+ '-d', '--dynamic', action='store_true',
145
+ help='Set the DNS gateway to obtain automatically from DHCP.')
146
+
147
+ arg_interface_group = argparse_obj.add_mutually_exclusive_group()
148
+ arg_interface_group.add_argument(
149
+ '-in', '--interface_name', type=str, help='Network Interface name as shown in the network settings.')
150
+ arg_interface_group.add_argument(
151
+ '-id', '--interface_default', action='store_true', help='Use the default network interface.')
152
+
153
+ args = argparse_obj.parse_args()
154
+
155
+ if (args.set or args.dynamic) and not (args.interface_name or args.interface_default):
156
+ print_api.print_api(
157
+ "Please provide the interface name [-in] or use the default interface [-id].", color='red')
158
+ return 1
159
+
160
+ if args.set or args.dynamic:
161
+ if not permissions.is_admin():
162
+ print_api.print_api("You need to run this script as an administrator", color='red')
163
+ return 1
164
+
165
+ def get_interface_name() -> str:
166
+ if args.interface_default:
167
+ return networks.get_default_interface_name()
168
+ else:
169
+ return args.interface_name
170
+
171
+ if args.get:
172
+ is_dynamic, dns_servers = get_default_dns_gateway()
173
+
174
+ if is_dynamic:
175
+ is_dynamic_string = 'Dynamic'
176
+ else:
177
+ is_dynamic_string = 'Static'
178
+ print_api.print_api(f'DNS Gateway: {is_dynamic_string} - {dns_servers}', color='blue')
179
+ elif args.set:
180
+ # dns_servers_list: list = args.dns_servers.split(',')
181
+ set_interface_dns_gateway_static(
182
+ dns_servers=args.set, interface_name=get_interface_name())
183
+ elif args.dynamic:
184
+ set_interface_dns_gateway_dynamic(interface_name=get_interface_name())
185
+
186
+ return 0
@@ -0,0 +1,17 @@
1
+ """
2
+ Need to fix the
3
+ etw.etw
4
+ file, in the
5
+ EventConsumer._unpackSimpleType
6
+ function.
7
+ """
8
+ """
9
+ data = formatted_data.value
10
+ # Convert the formatted data if necessary
11
+ if isinstance(data, str):
12
+ if data.endswith(' '):
13
+ data = data[:-1]
14
+ else:
15
+ if out_type in tdh.TDH_CONVERTER_LOOKUP and type(data) != tdh.TDH_CONVERTER_LOOKUP[out_type]:
16
+ data = tdh.TDH_CONVERTER_LOOKUP[out_type](data)
17
+ """