exploitfarm 2.0.0__tar.gz → 2.1.0__tar.gz

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 (54) hide show
  1. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/PKG-INFO +1 -1
  2. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/__init__.py +1 -1
  3. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/tui/startxploit.py +30 -13
  4. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm.egg-info/PKG-INFO +1 -1
  5. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/setup.py +1 -1
  6. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/MANIFEST.in +0 -0
  7. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/README.md +0 -0
  8. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/__main__.py +0 -0
  9. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/_init_exposed.py +0 -0
  10. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/attack_storage.py +0 -0
  11. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/autotune.py +0 -0
  12. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/connection.py +0 -0
  13. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/core_orchestration.py +0 -0
  14. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/local_executor.py +0 -0
  15. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/models/__init__.py +0 -0
  16. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/models/client.py +0 -0
  17. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/models/dbtypes.py +0 -0
  18. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/models/enums.py +0 -0
  19. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/models/exploit.py +0 -0
  20. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/models/exploit_template.py +0 -0
  21. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/models/flags.py +0 -0
  22. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/models/groups.py +0 -0
  23. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/models/response.py +0 -0
  24. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/models/service.py +0 -0
  25. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/models/submitter.py +0 -0
  26. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/models/teams.py +0 -0
  27. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/team_provider.py +0 -0
  28. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/tui/__init__.py +0 -0
  29. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/tui/config.py +0 -0
  30. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/tui/exploitdownload.py +0 -0
  31. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/tui/exploitinit.py +0 -0
  32. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/tui/group_prejoin.py +0 -0
  33. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/tui/group_select.py +0 -0
  34. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/tui/login.py +0 -0
  35. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/tui/shared_attack_group.py +0 -0
  36. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/tui/template.py +0 -0
  37. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/utils/__init__.py +0 -0
  38. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/utils/cmd.py +0 -0
  39. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/utils/config.py +0 -0
  40. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/utils/exploit.py +0 -0
  41. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/utils/paths.py +0 -0
  42. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/utils/reqs.py +0 -0
  43. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/utils/templates.py +0 -0
  44. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/utils/threadpool.py +0 -0
  45. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/utils/windows_close_fix.py +0 -0
  46. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/xfarm.py +0 -0
  47. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm/xploit.py +0 -0
  48. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm.egg-info/SOURCES.txt +0 -0
  49. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm.egg-info/dependency_links.txt +0 -0
  50. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm.egg-info/requires.txt +0 -0
  51. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/exploitfarm.egg-info/top_level.txt +0 -0
  52. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/requirements.txt +0 -0
  53. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/setup.cfg +0 -0
  54. {exploitfarm-2.0.0 → exploitfarm-2.1.0}/xfarm +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: exploitfarm
3
- Version: 2.0.0
3
+ Version: 2.1.0
4
4
  Summary: Exploit Farm client
5
5
  Home-page: https://github.com/pwnzer0tt1/exploitfarm
6
6
  Author: Pwnzer0tt1
@@ -1,5 +1,5 @@
1
1
  def _get_version():
2
- v = "2.0.0" if "{" not in "2.0.0" else "0.0.0"
2
+ v = "2.1.0" if "{" not in "2.1.0" else "0.0.0"
3
3
  if v == "0.0.0":
4
4
  import os
5
5
  env_v = os.getenv("EXPLOITFARM_VERSION")
@@ -170,7 +170,7 @@ class XploitRun(App[int]):
170
170
  width: 100%;
171
171
  }
172
172
  #status_text{
173
- height: 4;
173
+ height: auto;
174
174
  }
175
175
  .num_box{
176
176
  margin: 0 8;
@@ -369,9 +369,11 @@ class XploitRun(App[int]):
369
369
  [self.table.update_cell(row_key=team_key, column_key=self.column_keys[i], value=cols[i]) for i in range(len(self.column_keys))]
370
370
  except CellDoesNotExist:
371
371
  self.table.add_row(*cols, height=3, key=team_key)
372
- for key in self.table.rows.keys():
373
- if key.value not in used_keys:
374
- self.table.remove_row(row_key=key.value)
372
+ # Collect stale keys before removing them -- removing while iterating
373
+ # `self.table.rows.keys()` mutates that same dict mid-iteration.
374
+ stale_keys = [key.value for key in self.table.rows.keys() if key.value not in used_keys]
375
+ for key in stale_keys:
376
+ self.table.remove_row(row_key=key)
375
377
 
376
378
  def update_info_content(self):
377
379
  if g.exec.group is None:
@@ -396,22 +398,35 @@ class XploitRun(App[int]):
396
398
  queued_attacks.update(f"{g.exec.info.submitter_flags_in_queue}")
397
399
 
398
400
 
401
+ def _init_table(self):
402
+ self.table = self.query_one(DataTable)
403
+ self.table.clear()
404
+ self.column_keys = self.table.add_columns(*[Text(text="\n\n"+ele, justify="center") for ele in self.COLUMNS])
405
+
406
+ def _refresh_tick(self):
407
+ self.update_header_info()
408
+ self.update_table_content()
409
+ if g.exec.group:
410
+ self.update_info_content()
411
+
399
412
  def update_data(self):
413
+ # This whole method runs in a worker thread (see on_ready below), but every one of
414
+ # these calls mutates live Textual widgets (DataTable rows/cells, Label content, ...).
415
+ # Textual's compositor renders on the app's event-loop thread, and widget mutation
416
+ # triggers a refresh/cache-clear as a side effect -- doing that concurrently with a
417
+ # render in progress races the compositor's styles cache (observed as a spurious
418
+ # KeyError deep in _styles_cache.py). call_from_thread marshals each mutation onto the
419
+ # app thread so it can never overlap a render pass.
400
420
  try:
401
- self.table = self.query_one(DataTable)
402
- self.table.rows.clear()
403
- self.column_keys = self.table.add_columns(*[Text(text="\n\n"+ele, justify="center") for ele in self.COLUMNS])
421
+ self.call_from_thread(self._init_table)
404
422
  while True:
405
423
  #Wait for configurations
406
424
  if g.exec.config.status is None:
407
425
  if g.exec.exit_event.wait(timeout=0.3):
408
426
  return
409
427
  continue
410
-
411
- self.update_header_info()
412
- self.update_table_content()
413
- if g.exec.group:
414
- self.update_info_content()
428
+
429
+ self.call_from_thread(self._refresh_tick)
415
430
 
416
431
  if g.exec.exit_event.wait(timeout=0.3):
417
432
  return
@@ -420,12 +435,14 @@ class XploitRun(App[int]):
420
435
  g.exec.print_queue.put(traceback.format_exc())
421
436
 
422
437
  def update_log(self):
438
+ # Same reasoning as update_data: this runs in a worker thread, but Log.write() mutates
439
+ # a live widget, so it has to be marshaled onto the app thread too.
423
440
  logger = self.query_one("#log", Log)
424
441
  while True:
425
442
  if g.exec.exit_event.is_set():
426
443
  return
427
444
  log = g.exec.print_queue.get()
428
- logger.write(str(log ), scroll_end=False)
445
+ self.call_from_thread(logger.write, str(log), scroll_end=False)
429
446
 
430
447
  def exit_listener(self):
431
448
  if g.exec.exit_event.wait():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: exploitfarm
3
- Version: 2.0.0
3
+ Version: 2.1.0
4
4
  Summary: Exploit Farm client
5
5
  Home-page: https://github.com/pwnzer0tt1/exploitfarm
6
6
  Author: Pwnzer0tt1
@@ -10,7 +10,7 @@ with open("requirements.txt", "r", encoding="utf-8") as f:
10
10
  if not ele.strip().startswith("#") and ele.strip() != ""
11
11
  ]
12
12
 
13
- VERSION = "2.0.0"
13
+ VERSION = "2.1.0"
14
14
 
15
15
  setuptools.setup(
16
16
  name="exploitfarm",
File without changes
File without changes
File without changes
File without changes