bbot 2.0.1.4654rc0__py3-none-any.whl → 2.3.0.5397rc0__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 bbot might be problematic. Click here for more details.

Files changed (270) hide show
  1. bbot/__init__.py +1 -1
  2. bbot/cli.py +3 -7
  3. bbot/core/config/files.py +0 -1
  4. bbot/core/config/logger.py +34 -4
  5. bbot/core/core.py +21 -6
  6. bbot/core/engine.py +9 -8
  7. bbot/core/event/base.py +162 -63
  8. bbot/core/helpers/bloom.py +10 -3
  9. bbot/core/helpers/command.py +9 -8
  10. bbot/core/helpers/depsinstaller/installer.py +89 -32
  11. bbot/core/helpers/depsinstaller/sudo_askpass.py +38 -2
  12. bbot/core/helpers/diff.py +10 -10
  13. bbot/core/helpers/dns/brute.py +18 -14
  14. bbot/core/helpers/dns/dns.py +16 -15
  15. bbot/core/helpers/dns/engine.py +159 -132
  16. bbot/core/helpers/dns/helpers.py +2 -2
  17. bbot/core/helpers/dns/mock.py +26 -8
  18. bbot/core/helpers/files.py +1 -1
  19. bbot/core/helpers/helper.py +7 -4
  20. bbot/core/helpers/interactsh.py +3 -3
  21. bbot/core/helpers/libmagic.py +65 -0
  22. bbot/core/helpers/misc.py +65 -22
  23. bbot/core/helpers/names_generator.py +17 -3
  24. bbot/core/helpers/process.py +0 -20
  25. bbot/core/helpers/regex.py +1 -1
  26. bbot/core/helpers/regexes.py +12 -6
  27. bbot/core/helpers/validators.py +1 -2
  28. bbot/core/helpers/web/client.py +1 -1
  29. bbot/core/helpers/web/engine.py +18 -13
  30. bbot/core/helpers/web/web.py +25 -116
  31. bbot/core/helpers/wordcloud.py +5 -5
  32. bbot/core/modules.py +36 -27
  33. bbot/core/multiprocess.py +58 -0
  34. bbot/core/shared_deps.py +46 -3
  35. bbot/db/sql/models.py +147 -0
  36. bbot/defaults.yml +15 -10
  37. bbot/errors.py +0 -8
  38. bbot/modules/anubisdb.py +2 -2
  39. bbot/modules/apkpure.py +63 -0
  40. bbot/modules/azure_tenant.py +2 -2
  41. bbot/modules/baddns.py +35 -19
  42. bbot/modules/baddns_direct.py +92 -0
  43. bbot/modules/baddns_zone.py +3 -8
  44. bbot/modules/badsecrets.py +4 -3
  45. bbot/modules/base.py +195 -51
  46. bbot/modules/bevigil.py +7 -7
  47. bbot/modules/binaryedge.py +7 -4
  48. bbot/modules/bufferoverrun.py +47 -0
  49. bbot/modules/builtwith.py +6 -10
  50. bbot/modules/bypass403.py +5 -5
  51. bbot/modules/c99.py +10 -7
  52. bbot/modules/censys.py +9 -13
  53. bbot/modules/certspotter.py +5 -3
  54. bbot/modules/chaos.py +9 -7
  55. bbot/modules/code_repository.py +1 -0
  56. bbot/modules/columbus.py +3 -3
  57. bbot/modules/crt.py +5 -3
  58. bbot/modules/deadly/dastardly.py +1 -1
  59. bbot/modules/deadly/ffuf.py +9 -9
  60. bbot/modules/deadly/nuclei.py +3 -3
  61. bbot/modules/deadly/vhost.py +4 -3
  62. bbot/modules/dehashed.py +1 -1
  63. bbot/modules/digitorus.py +1 -1
  64. bbot/modules/dnsbimi.py +145 -0
  65. bbot/modules/dnscaa.py +3 -3
  66. bbot/modules/dnsdumpster.py +4 -4
  67. bbot/modules/dnstlsrpt.py +144 -0
  68. bbot/modules/docker_pull.py +7 -5
  69. bbot/modules/dockerhub.py +2 -2
  70. bbot/modules/dotnetnuke.py +18 -19
  71. bbot/modules/emailformat.py +1 -1
  72. bbot/modules/extractous.py +122 -0
  73. bbot/modules/filedownload.py +9 -7
  74. bbot/modules/fullhunt.py +7 -4
  75. bbot/modules/generic_ssrf.py +5 -5
  76. bbot/modules/github_codesearch.py +3 -2
  77. bbot/modules/github_org.py +4 -4
  78. bbot/modules/github_workflows.py +4 -4
  79. bbot/modules/gitlab.py +2 -5
  80. bbot/modules/google_playstore.py +93 -0
  81. bbot/modules/gowitness.py +48 -50
  82. bbot/modules/hackertarget.py +5 -3
  83. bbot/modules/host_header.py +5 -5
  84. bbot/modules/httpx.py +1 -4
  85. bbot/modules/hunterio.py +3 -9
  86. bbot/modules/iis_shortnames.py +19 -30
  87. bbot/modules/internal/cloudcheck.py +27 -12
  88. bbot/modules/internal/dnsresolve.py +250 -276
  89. bbot/modules/internal/excavate.py +100 -64
  90. bbot/modules/internal/speculate.py +42 -33
  91. bbot/modules/internetdb.py +4 -2
  92. bbot/modules/ip2location.py +3 -5
  93. bbot/modules/ipneighbor.py +1 -1
  94. bbot/modules/ipstack.py +3 -8
  95. bbot/modules/jadx.py +87 -0
  96. bbot/modules/leakix.py +11 -10
  97. bbot/modules/myssl.py +2 -2
  98. bbot/modules/newsletters.py +2 -2
  99. bbot/modules/otx.py +5 -3
  100. bbot/modules/output/asset_inventory.py +7 -7
  101. bbot/modules/output/base.py +1 -1
  102. bbot/modules/output/csv.py +1 -2
  103. bbot/modules/output/http.py +20 -14
  104. bbot/modules/output/mysql.py +51 -0
  105. bbot/modules/output/neo4j.py +7 -2
  106. bbot/modules/output/postgres.py +49 -0
  107. bbot/modules/output/slack.py +0 -1
  108. bbot/modules/output/sqlite.py +29 -0
  109. bbot/modules/output/stdout.py +2 -2
  110. bbot/modules/output/teams.py +107 -6
  111. bbot/modules/paramminer_headers.py +5 -8
  112. bbot/modules/passivetotal.py +13 -13
  113. bbot/modules/portscan.py +32 -6
  114. bbot/modules/postman.py +50 -126
  115. bbot/modules/postman_download.py +220 -0
  116. bbot/modules/rapiddns.py +3 -8
  117. bbot/modules/report/asn.py +11 -11
  118. bbot/modules/robots.py +3 -3
  119. bbot/modules/securitytrails.py +7 -10
  120. bbot/modules/securitytxt.py +128 -0
  121. bbot/modules/shodan_dns.py +7 -9
  122. bbot/modules/sitedossier.py +1 -1
  123. bbot/modules/skymem.py +2 -2
  124. bbot/modules/social.py +2 -1
  125. bbot/modules/subdomaincenter.py +1 -1
  126. bbot/modules/subdomainradar.py +160 -0
  127. bbot/modules/telerik.py +8 -8
  128. bbot/modules/templates/bucket.py +1 -1
  129. bbot/modules/templates/github.py +22 -14
  130. bbot/modules/templates/postman.py +21 -0
  131. bbot/modules/templates/shodan.py +14 -13
  132. bbot/modules/templates/sql.py +95 -0
  133. bbot/modules/templates/subdomain_enum.py +53 -17
  134. bbot/modules/templates/webhook.py +2 -4
  135. bbot/modules/trickest.py +8 -37
  136. bbot/modules/trufflehog.py +18 -3
  137. bbot/modules/url_manipulation.py +3 -3
  138. bbot/modules/urlscan.py +1 -1
  139. bbot/modules/viewdns.py +1 -1
  140. bbot/modules/virustotal.py +8 -30
  141. bbot/modules/wafw00f.py +1 -1
  142. bbot/modules/wayback.py +1 -1
  143. bbot/modules/wpscan.py +17 -11
  144. bbot/modules/zoomeye.py +11 -6
  145. bbot/presets/baddns-thorough.yml +12 -0
  146. bbot/presets/fast.yml +16 -0
  147. bbot/presets/kitchen-sink.yml +1 -0
  148. bbot/presets/spider.yml +4 -0
  149. bbot/presets/subdomain-enum.yml +7 -7
  150. bbot/scanner/manager.py +5 -16
  151. bbot/scanner/preset/args.py +44 -26
  152. bbot/scanner/preset/environ.py +7 -2
  153. bbot/scanner/preset/path.py +7 -4
  154. bbot/scanner/preset/preset.py +36 -23
  155. bbot/scanner/scanner.py +176 -63
  156. bbot/scanner/target.py +236 -434
  157. bbot/scripts/docs.py +1 -1
  158. bbot/test/bbot_fixtures.py +22 -3
  159. bbot/test/conftest.py +132 -100
  160. bbot/test/fastapi_test.py +17 -0
  161. bbot/test/owasp_mastg.apk +0 -0
  162. bbot/test/run_tests.sh +4 -4
  163. bbot/test/test.conf +2 -0
  164. bbot/test/test_step_1/test_bbot_fastapi.py +82 -0
  165. bbot/test/test_step_1/test_bloom_filter.py +2 -0
  166. bbot/test/test_step_1/test_cli.py +138 -64
  167. bbot/test/test_step_1/test_dns.py +392 -70
  168. bbot/test/test_step_1/test_engine.py +17 -17
  169. bbot/test/test_step_1/test_events.py +203 -37
  170. bbot/test/test_step_1/test_helpers.py +64 -28
  171. bbot/test/test_step_1/test_manager_deduplication.py +1 -1
  172. bbot/test/test_step_1/test_manager_scope_accuracy.py +336 -338
  173. bbot/test/test_step_1/test_modules_basic.py +69 -71
  174. bbot/test/test_step_1/test_presets.py +184 -96
  175. bbot/test/test_step_1/test_python_api.py +7 -2
  176. bbot/test/test_step_1/test_regexes.py +35 -5
  177. bbot/test/test_step_1/test_scan.py +39 -5
  178. bbot/test/test_step_1/test_scope.py +5 -4
  179. bbot/test/test_step_1/test_target.py +243 -145
  180. bbot/test/test_step_1/test_web.py +48 -10
  181. bbot/test/test_step_2/module_tests/base.py +17 -20
  182. bbot/test/test_step_2/module_tests/test_module_anubisdb.py +1 -1
  183. bbot/test/test_step_2/module_tests/test_module_apkpure.py +71 -0
  184. bbot/test/test_step_2/module_tests/test_module_asset_inventory.py +0 -1
  185. bbot/test/test_step_2/module_tests/test_module_azure_realm.py +1 -1
  186. bbot/test/test_step_2/module_tests/test_module_baddns.py +6 -6
  187. bbot/test/test_step_2/module_tests/test_module_baddns_direct.py +62 -0
  188. bbot/test/test_step_2/module_tests/test_module_bevigil.py +29 -2
  189. bbot/test/test_step_2/module_tests/test_module_binaryedge.py +4 -2
  190. bbot/test/test_step_2/module_tests/test_module_bucket_amazon.py +2 -2
  191. bbot/test/test_step_2/module_tests/test_module_bucket_azure.py +1 -1
  192. bbot/test/test_step_2/module_tests/test_module_bufferoverrun.py +35 -0
  193. bbot/test/test_step_2/module_tests/test_module_builtwith.py +2 -2
  194. bbot/test/test_step_2/module_tests/test_module_bypass403.py +1 -1
  195. bbot/test/test_step_2/module_tests/test_module_c99.py +126 -0
  196. bbot/test/test_step_2/module_tests/test_module_censys.py +4 -1
  197. bbot/test/test_step_2/module_tests/test_module_cloudcheck.py +4 -0
  198. bbot/test/test_step_2/module_tests/test_module_code_repository.py +11 -1
  199. bbot/test/test_step_2/module_tests/test_module_columbus.py +1 -1
  200. bbot/test/test_step_2/module_tests/test_module_credshed.py +3 -3
  201. bbot/test/test_step_2/module_tests/test_module_dastardly.py +2 -1
  202. bbot/test/test_step_2/module_tests/test_module_dehashed.py +2 -2
  203. bbot/test/test_step_2/module_tests/test_module_digitorus.py +1 -1
  204. bbot/test/test_step_2/module_tests/test_module_discord.py +1 -1
  205. bbot/test/test_step_2/module_tests/test_module_dnsbimi.py +103 -0
  206. bbot/test/test_step_2/module_tests/test_module_dnsbrute.py +9 -10
  207. bbot/test/test_step_2/module_tests/test_module_dnsbrute_mutations.py +1 -2
  208. bbot/test/test_step_2/module_tests/test_module_dnscommonsrv.py +1 -2
  209. bbot/test/test_step_2/module_tests/test_module_dnsdumpster.py +4 -4
  210. bbot/test/test_step_2/module_tests/test_module_dnstlsrpt.py +64 -0
  211. bbot/test/test_step_2/module_tests/test_module_dotnetnuke.py +0 -8
  212. bbot/test/test_step_2/module_tests/test_module_excavate.py +17 -37
  213. bbot/test/test_step_2/module_tests/test_module_extractous.py +54 -0
  214. bbot/test/test_step_2/module_tests/test_module_ffuf_shortnames.py +1 -1
  215. bbot/test/test_step_2/module_tests/test_module_filedownload.py +14 -14
  216. bbot/test/test_step_2/module_tests/test_module_git_clone.py +2 -2
  217. bbot/test/test_step_2/module_tests/test_module_github_org.py +19 -8
  218. bbot/test/test_step_2/module_tests/test_module_github_workflows.py +1 -1
  219. bbot/test/test_step_2/module_tests/test_module_gitlab.py +9 -4
  220. bbot/test/test_step_2/module_tests/test_module_google_playstore.py +83 -0
  221. bbot/test/test_step_2/module_tests/test_module_gowitness.py +4 -4
  222. bbot/test/test_step_2/module_tests/test_module_host_header.py +1 -1
  223. bbot/test/test_step_2/module_tests/test_module_http.py +4 -4
  224. bbot/test/test_step_2/module_tests/test_module_httpx.py +10 -8
  225. bbot/test/test_step_2/module_tests/test_module_hunterio.py +68 -4
  226. bbot/test/test_step_2/module_tests/test_module_jadx.py +55 -0
  227. bbot/test/test_step_2/module_tests/test_module_json.py +24 -11
  228. bbot/test/test_step_2/module_tests/test_module_leakix.py +7 -3
  229. bbot/test/test_step_2/module_tests/test_module_mysql.py +76 -0
  230. bbot/test/test_step_2/module_tests/test_module_myssl.py +1 -1
  231. bbot/test/test_step_2/module_tests/test_module_neo4j.py +1 -1
  232. bbot/test/test_step_2/module_tests/test_module_newsletters.py +6 -6
  233. bbot/test/test_step_2/module_tests/test_module_ntlm.py +7 -7
  234. bbot/test/test_step_2/module_tests/test_module_oauth.py +1 -1
  235. bbot/test/test_step_2/module_tests/test_module_otx.py +1 -1
  236. bbot/test/test_step_2/module_tests/test_module_paramminer_cookies.py +1 -2
  237. bbot/test/test_step_2/module_tests/test_module_paramminer_getparams.py +0 -6
  238. bbot/test/test_step_2/module_tests/test_module_paramminer_headers.py +2 -9
  239. bbot/test/test_step_2/module_tests/test_module_passivetotal.py +3 -1
  240. bbot/test/test_step_2/module_tests/test_module_portscan.py +9 -8
  241. bbot/test/test_step_2/module_tests/test_module_postgres.py +74 -0
  242. bbot/test/test_step_2/module_tests/test_module_postman.py +84 -253
  243. bbot/test/test_step_2/module_tests/test_module_postman_download.py +439 -0
  244. bbot/test/test_step_2/module_tests/test_module_rapiddns.py +93 -1
  245. bbot/test/test_step_2/module_tests/test_module_securitytxt.py +50 -0
  246. bbot/test/test_step_2/module_tests/test_module_shodan_dns.py +20 -1
  247. bbot/test/test_step_2/module_tests/test_module_sitedossier.py +2 -2
  248. bbot/test/test_step_2/module_tests/test_module_smuggler.py +1 -1
  249. bbot/test/test_step_2/module_tests/test_module_social.py +11 -1
  250. bbot/test/test_step_2/module_tests/test_module_speculate.py +2 -6
  251. bbot/test/test_step_2/module_tests/test_module_splunk.py +4 -4
  252. bbot/test/test_step_2/module_tests/test_module_sqlite.py +18 -0
  253. bbot/test/test_step_2/module_tests/test_module_sslcert.py +1 -1
  254. bbot/test/test_step_2/module_tests/test_module_stdout.py +5 -3
  255. bbot/test/test_step_2/module_tests/test_module_subdomaincenter.py +1 -1
  256. bbot/test/test_step_2/module_tests/test_module_subdomainradar.py +208 -0
  257. bbot/test/test_step_2/module_tests/test_module_subdomains.py +1 -1
  258. bbot/test/test_step_2/module_tests/test_module_teams.py +8 -6
  259. bbot/test/test_step_2/module_tests/test_module_telerik.py +1 -1
  260. bbot/test/test_step_2/module_tests/test_module_trufflehog.py +317 -11
  261. bbot/test/test_step_2/module_tests/test_module_wayback.py +1 -1
  262. bbot/test/test_step_2/template_tests/test_template_subdomain_enum.py +135 -0
  263. {bbot-2.0.1.4654rc0.dist-info → bbot-2.3.0.5397rc0.dist-info}/METADATA +48 -18
  264. bbot-2.3.0.5397rc0.dist-info/RECORD +421 -0
  265. {bbot-2.0.1.4654rc0.dist-info → bbot-2.3.0.5397rc0.dist-info}/WHEEL +1 -1
  266. bbot/modules/unstructured.py +0 -163
  267. bbot/test/test_step_2/module_tests/test_module_unstructured.py +0 -102
  268. bbot-2.0.1.4654rc0.dist-info/RECORD +0 -385
  269. {bbot-2.0.1.4654rc0.dist-info → bbot-2.3.0.5397rc0.dist-info}/LICENSE +0 -0
  270. {bbot-2.0.1.4654rc0.dist-info → bbot-2.3.0.5397rc0.dist-info}/entry_points.txt +0 -0
bbot/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  # version placeholder (replaced by poetry-dynamic-versioning)
2
- __version__ = "v2.0.1.4654rc"
2
+ __version__ = "v2.3.0.5397rc"
3
3
 
4
4
  from .scanner import Scanner, Preset
bbot/cli.py CHANGED
@@ -29,7 +29,6 @@ scan_name = ""
29
29
 
30
30
 
31
31
  async def _main():
32
-
33
32
  import asyncio
34
33
  import traceback
35
34
  from contextlib import suppress
@@ -45,7 +44,6 @@ async def _main():
45
44
  global scan_name
46
45
 
47
46
  try:
48
-
49
47
  # start by creating a default scan preset
50
48
  preset = Preset(_log=True, name="bbot_cli_main")
51
49
  # parse command line arguments and merge into preset
@@ -81,7 +79,6 @@ async def _main():
81
79
 
82
80
  # if we're listing modules or their options
83
81
  if options.list_modules or options.list_module_options:
84
-
85
82
  # if no modules or flags are specified, enable everything
86
83
  if not (options.modules or options.output_modules or options.flags):
87
84
  for module, preloaded in preset.module_loader.preloaded().items():
@@ -133,8 +130,8 @@ async def _main():
133
130
  ]
134
131
  if deadly_modules and not options.allow_deadly:
135
132
  log.hugewarning(f"You enabled the following deadly modules: {','.join(deadly_modules)}")
136
- log.hugewarning(f"Deadly modules are highly intrusive")
137
- log.hugewarning(f"Please specify --allow-deadly to continue")
133
+ log.hugewarning("Deadly modules are highly intrusive")
134
+ log.hugewarning("Please specify --allow-deadly to continue")
138
135
  return False
139
136
 
140
137
  # --current-preset
@@ -172,9 +169,8 @@ async def _main():
172
169
  log.trace(f"Command: {' '.join(sys.argv)}")
173
170
 
174
171
  if sys.stdin.isatty():
175
-
176
172
  # warn if any targets belong directly to a cloud provider
177
- for event in scan.target.events:
173
+ for event in scan.target.seeds.events:
178
174
  if event.type == "DNS_NAME":
179
175
  cloudcheck_result = scan.helpers.cloudcheck(event.host)
180
176
  if cloudcheck_result:
bbot/core/config/files.py CHANGED
@@ -10,7 +10,6 @@ bbot_code_dir = Path(__file__).parent.parent.parent
10
10
 
11
11
 
12
12
  class BBOTConfigFiles:
13
-
14
13
  config_dir = (Path.home() / ".config" / "bbot").resolve()
15
14
  defaults_filename = (bbot_code_dir / "defaults.yml").resolve()
16
15
  config_filename = (config_dir / "bbot.yml").resolve()
@@ -1,3 +1,4 @@
1
+ import os
1
2
  import sys
2
3
  import atexit
3
4
  import logging
@@ -5,9 +6,11 @@ from copy import copy
5
6
  import multiprocessing
6
7
  import logging.handlers
7
8
  from pathlib import Path
9
+ from contextlib import suppress
8
10
 
9
11
  from ..helpers.misc import mkdir, error_and_exit
10
12
  from ...logger import colorize, loglevel_mapping
13
+ from ..multiprocess import SHARED_INTERPRETER_STATE
11
14
 
12
15
 
13
16
  debug_format = logging.Formatter("%(asctime)s [%(levelname)s] %(name)s %(filename)s:%(lineno)s %(message)s")
@@ -64,17 +67,44 @@ class BBOTLogger:
64
67
 
65
68
  self.listener = None
66
69
 
67
- self.process_name = multiprocessing.current_process().name
68
- if self.process_name == "MainProcess":
70
+ # if we haven't set up logging yet, do it now
71
+ if "_BBOT_LOGGING_SETUP" not in os.environ:
72
+ os.environ["_BBOT_LOGGING_SETUP"] = "1"
69
73
  self.queue = multiprocessing.Queue()
70
74
  self.setup_queue_handler()
71
75
  # Start the QueueListener
72
76
  self.listener = logging.handlers.QueueListener(self.queue, *self.log_handlers.values())
73
77
  self.listener.start()
74
- atexit.register(self.listener.stop)
78
+ atexit.register(self.cleanup_logging)
75
79
 
76
80
  self.log_level = logging.INFO
77
81
 
82
+ def cleanup_logging(self):
83
+ # Close the queue handler
84
+ with suppress(Exception):
85
+ self.queue_handler.close()
86
+
87
+ # Clean root logger
88
+ root_logger = logging.getLogger()
89
+ for handler in list(root_logger.handlers):
90
+ with suppress(Exception):
91
+ root_logger.removeHandler(handler)
92
+ with suppress(Exception):
93
+ handler.close()
94
+
95
+ # Clean all other loggers
96
+ for logger in logging.Logger.manager.loggerDict.values():
97
+ if hasattr(logger, "handlers"): # Logger, not PlaceHolder
98
+ for handler in list(logger.handlers):
99
+ with suppress(Exception):
100
+ logger.removeHandler(handler)
101
+ with suppress(Exception):
102
+ handler.close()
103
+
104
+ # Stop queue listener
105
+ with suppress(Exception):
106
+ self.listener.stop()
107
+
78
108
  def setup_queue_handler(self, logging_queue=None, log_level=logging.DEBUG):
79
109
  if logging_queue is None:
80
110
  logging_queue = self.queue
@@ -86,7 +116,7 @@ class BBOTLogger:
86
116
 
87
117
  self.core_logger.setLevel(log_level)
88
118
  # disable asyncio logging for child processes
89
- if self.process_name != "MainProcess":
119
+ if not SHARED_INTERPRETER_STATE.is_main_process:
90
120
  logging.getLogger("asyncio").setLevel(logging.ERROR)
91
121
 
92
122
  def addLoggingLevel(self, levelName, levelNum, methodName=None):
bbot/core/core.py CHANGED
@@ -6,6 +6,7 @@ from contextlib import suppress
6
6
  from omegaconf import OmegaConf
7
7
 
8
8
  from bbot.errors import BBOTError
9
+ from .multiprocess import SHARED_INTERPRETER_STATE
9
10
 
10
11
 
11
12
  DEFAULT_CONFIG = None
@@ -34,8 +35,6 @@ class BBOTCore:
34
35
  self._logger = None
35
36
  self._files_config = None
36
37
 
37
- self.bbot_sudo_pass = None
38
-
39
38
  self._config = None
40
39
  self._custom_config = None
41
40
 
@@ -43,9 +42,23 @@ class BBOTCore:
43
42
  self.logger
44
43
  self.log = logging.getLogger("bbot.core")
45
44
 
45
+ self._prep_multiprocessing()
46
+
47
+ def _prep_multiprocessing(self):
46
48
  import multiprocessing
49
+ from .helpers.process import BBOTProcess
50
+
51
+ if SHARED_INTERPRETER_STATE.is_main_process:
52
+ # if this is the main bbot process, set the logger and queue for the first time
53
+ from functools import partialmethod
47
54
 
48
- self.process_name = multiprocessing.current_process().name
55
+ BBOTProcess.__init__ = partialmethod(
56
+ BBOTProcess.__init__, log_level=self.logger.log_level, log_queue=self.logger.queue
57
+ )
58
+
59
+ # this makes our process class the default for process pools, etc.
60
+ mp_context = multiprocessing.get_context("spawn")
61
+ mp_context.Process = BBOTProcess
49
62
 
50
63
  @property
51
64
  def home(self):
@@ -93,7 +106,7 @@ class BBOTCore:
93
106
  if DEFAULT_CONFIG is None:
94
107
  self.default_config = self.files_config.get_default_config()
95
108
  # ensure bbot home dir
96
- if not "home" in self.default_config:
109
+ if "home" not in self.default_config:
97
110
  self.default_config["home"] = "~/.bbot"
98
111
  return DEFAULT_CONFIG
99
112
 
@@ -189,12 +202,14 @@ class BBOTCore:
189
202
  if os.environ.get("BBOT_TESTING", "") == "True":
190
203
  process = self.create_thread(*args, **kwargs)
191
204
  else:
192
- if self.process_name == "MainProcess":
205
+ if SHARED_INTERPRETER_STATE.is_scan_process:
193
206
  from .helpers.process import BBOTProcess
194
207
 
195
208
  process = BBOTProcess(*args, **kwargs)
196
209
  else:
197
- raise BBOTError(f"Tried to start server from process {self.process_name}")
210
+ import multiprocessing
211
+
212
+ raise BBOTError(f"Tried to start server from process {multiprocessing.current_process().name}")
198
213
  process.daemon = True
199
214
  return process
200
215
 
bbot/core/engine.py CHANGED
@@ -10,6 +10,7 @@ import traceback
10
10
  import contextlib
11
11
  import contextvars
12
12
  import zmq.asyncio
13
+ import multiprocessing
13
14
  from pathlib import Path
14
15
  from concurrent.futures import CancelledError
15
16
  from contextlib import asynccontextmanager, suppress
@@ -17,6 +18,7 @@ from contextlib import asynccontextmanager, suppress
17
18
  from bbot.core import CORE
18
19
  from bbot.errors import BBOTEngineError
19
20
  from bbot.core.helpers.async_helpers import get_event_loop
21
+ from bbot.core.multiprocess import SHARED_INTERPRETER_STATE
20
22
  from bbot.core.helpers.misc import rand_string, in_exception_chain
21
23
 
22
24
 
@@ -264,10 +266,8 @@ class EngineClient(EngineBase):
264
266
  return [s for s in self.CMDS if isinstance(s, str)]
265
267
 
266
268
  def start_server(self):
267
- import multiprocessing
268
-
269
269
  process_name = multiprocessing.current_process().name
270
- if process_name == "MainProcess":
270
+ if SHARED_INTERPRETER_STATE.is_scan_process:
271
271
  kwargs = dict(self.server_kwargs)
272
272
  # if we're in tests, we use a single event loop to avoid weird race conditions
273
273
  # this allows us to more easily mock http, etc.
@@ -641,8 +641,9 @@ class EngineServer(EngineBase):
641
641
  except BaseException as e:
642
642
  if isinstance(e, (TimeoutError, asyncio.exceptions.TimeoutError)):
643
643
  self.log.warning(f"{self.name}: Timeout after {timeout:,} seconds in finished_tasks({tasks})")
644
- for task in tasks:
644
+ for task in list(tasks):
645
645
  task.cancel()
646
+ self._await_cancelled_task(task)
646
647
  else:
647
648
  if not in_exception_chain(e, (KeyboardInterrupt, asyncio.CancelledError)):
648
649
  self.log.error(f"{self.name}: Unhandled exception in finished_tasks({tasks}): {e}")
@@ -664,9 +665,9 @@ class EngineServer(EngineBase):
664
665
  child_task.cancel()
665
666
 
666
667
  for task in [parent_task] + list(child_tasks):
667
- await self._cancel_task(task)
668
+ await self._await_cancelled_task(task)
668
669
 
669
- async def _cancel_task(self, task):
670
+ async def _await_cancelled_task(self, task):
670
671
  try:
671
672
  await asyncio.wait_for(task, timeout=10)
672
673
  except (TimeoutError, asyncio.exceptions.TimeoutError):
@@ -682,5 +683,5 @@ class EngineServer(EngineBase):
682
683
  for client_id in list(self.tasks):
683
684
  await self.cancel_task(client_id)
684
685
  for client_id, tasks in self.child_tasks.items():
685
- for task in tasks:
686
- await self._cancel_task(task)
686
+ for task in list(tasks):
687
+ await self._await_cancelled_task(task)