Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBaseSubprocessScanner.py
More file actions
Latest commit
157 lines (137 loc) · 5.24 KB
/
Copy pathBaseSubprocessScanner.py
File metadata and controls
157 lines (137 loc) · 5.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
importshutil
importsubprocess
importtime
fromqueueimportQueue
fromtypingimportList, Tuple, Optional, Callable
fromScannerInterfaceimportScannerInterface
classBaseSubprocessScanner(ScannerInterface):
"""Classe de base factorisant la logique commune de gestion des sous-processus."""
def_get_command_path(self, command: str, fallback_paths: List[str] =None) ->str:
"""
Trouve le chemin de la commande avec shutil.which() ou fallback.
Args:
command: Nom de la commande (ex: 'curl')
fallback_paths: Liste de chemins de secours (ex: ['/usr/bin/curl', '/bin/curl'])
Returns:
Chemin complet de la commande
Raises:
FileNotFoundError: Si la commande n'est pas trouvée
"""
# Essayer shutil.which()
cmd_path=shutil.which(command)
ifcmd_path:
returncmd_path
# Essayer les fallbacks
iffallback_paths:
forpathinfallback_paths:
ifshutil.which(path):
returnpath
raiseFileNotFoundError(f"Commande '{command}' introuvable. Installez-la ou vérifiez votre PATH.")
def_run_command(
self,
cmd: List[str],
ip: str,
port: int,
thread_id: str,
event_queue: Queue,
stop_flag: Callable[[], bool],
timeout: int=5,
capture_output: bool=True
) ->Tuple[bool, Optional[str], List[str]]:
"""
Exécute une commande subprocess avec gestion d'erreurs et timeouts.
Args:
cmd: Commande à exécuter (liste de tokens)
ip: IP cible
port: Port cible
thread_id: ID du thread
event_queue: Queue pour les événements
stop_flag: Flag d'arrêt
timeout: Timeout en secondes
capture_output: Si True, capture stdout/stderr
Returns:
Tuple (success, error_msg, output_lines)
- success: True si la commande s'est exécutée sans erreur fatale
- error_msg: Message d'erreur si échec, None sinon
- output_lines: Lignes de sortie (stdout + stderr)
"""
cmd_str=" ".join(cmd)
event_queue.put({
'event': 'thread_update',
'data': {
'thread_id': thread_id,
'message': f"[{time.ctime()}] Début du scan de {ip}:{port} avec {cmd_str}"
}
})
try:
ifcapture_output:
process=subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
text=True
)
else:
process=subprocess.Popen(cmd)
# Enregistrer le processus dans le process_manager
ifself.process_managerisnotNone:
scanner_type=self.__class__.__name__.replace("Scanner", "").lower()
self.process_manager.register(
process,
scanner_type,
self.strategy,
ip,
thread_id
)
exceptExceptionase:
error_msg=f"Erreur lancement commande : {str(e)}"
event_queue.put({
'event': 'thread_update',
'data': {
'thread_id': thread_id,
'message': f"[{time.ctime()}] {error_msg}"
}
})
returnFalse, error_msg, []
# Attendre la fin du processus avec timeout
try:
ifcapture_output:
stdout, _=process.communicate(timeout=timeout)
output_lines=stdout.splitlines() ifstdoutelse []
else:
process.wait(timeout=timeout)
output_lines= []
event_queue.put({
'event': 'thread_update',
'data': {
'thread_id': thread_id,
'message': f"[{time.ctime()}] Scan terminé pour port {port}"
}
})
returnTrue, None, output_lines
exceptsubprocess.TimeoutExpired:
process.kill()
ifcapture_output:
stdout, _=process.communicate()
output_lines=stdout.splitlines() ifstdoutelse []
else:
output_lines= []
event_queue.put({
'event': 'thread_update',
'data': {
'thread_id': thread_id,
'message': f"[{time.ctime()}] Scan timeout après {timeout}s pour port {port}"
}
})
returnFalse, "Timeout", output_lines
def_send_output_to_queue(self, output_lines: List[str], thread_id: str, event_queue: Queue):
"""Envoie les lignes de sortie à la queue d'événements."""
forlineinoutput_lines:
ifline.strip():
event_queue.put({
'event': 'thread_update',
'data': {
'thread_id': thread_id,
'message': f"[{time.ctime()}] {line.strip()}"
}
})