Project

General

Profile

Feature #12963 » nmap_scan-v21.patch

Phil Wardt, 04/02/2022 04:02 AM

View differences:

src/usr/local/www/nmap_scan.php
1
<?php
2
/*
3
 * nmap_scan.php
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2022-2022 Rubicon Communications, LLC (Netgate)
7
 * All rights reserved.
8
 *
9
 * Licensed under the Apache License, Version 2.0 (the "License");
10
 * you may not use this file except in compliance with the License.
11
 * You may obtain a copy of the License at
12
 *
13
 * http://www.apache.org/licenses/LICENSE-2.0
14
 *
15
 * Unless required by applicable law or agreed to in writing, software
16
 * distributed under the License is distributed on an "AS IS" BASIS,
17
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
 * See the License for the specific language governing permissions and
19
 * limitations under the License.
20
 */
21

  
22
function nmap_get_running_process($f){
23
	$processcheck = trim(shell_exec("/bin/ps axw -O pid= | /usr/bin/grep '/usr/local/bin/[n]map.*{$f}'"));
24
	return $processcheck;
25
}
26

  
27
// Return a ports array from a nmap -p arg value format
28
// we strip ranges (-) and types (T:, U:, P:, S:)
29
// port names with '-' like 'netbios-ssn' are supported
30
function get_ports_array($port_post) {
31
	$ports_array = array();
32

  
33
	// get ports from the comma separated form input
34
	if (strpos($port_post, ',') === false) {
35
		$ports_array = array($port_post);
36
	} else {
37
		$ports_array = explode(',', $port_post);
38
	}
39

  
40
	$port_max_ranges = array();
41
	foreach ($ports_array as &$p) {
42
		if (preg_match('/^(T:|U:|P:|S:)/', $p) === 1) {
43
			$p = substr($p, 2);//if empty, we keep it as it is an illegal nmap syntax. On function return, empty ports will evaluate as invalid
44
		}
45

  
46
		// keep only inner and outer ports from a ports range
47
		// if the inner/outer port range limit is omitted, set corresponding port value to '*'
48
		if ($p === '-') {
49
			$p = '*';
50
		} elseif (strpos($p, '-') !== false && preg_match('/^[0-9\-]+$/', $p) === 1) {
51
			// port ranges must be in the format of 'numeric-numeric'
52
			$port_ranges = explode('-', $p, 2);
53
			$p = strlen($port_ranges[0]) ? $port_ranges[0] : '*';
54
			$port_max_ranges[] = strlen($port_ranges[1]) ? $port_ranges[1] : '*';
55
		}
56
	}
57
	unset($p);
58
	$ports_array = array_merge($ports_array, $port_max_ranges);
59

  
60
	return $ports_array;
61
}
62

  
63
if ($_POST['downloadbtn'] == gettext("Download Results")) {
64
	$nocsrf = true;
65
}
66

  
67
$pgtitle = array("Package", "Diagnostics: Nmap");
68
require_once("guiconfig.inc");
69
/* require_once("pfsense-utils.inc"); */
70
require_once("ipsec.inc");
71

  
72
$fp = "/root/";
73
$fn = "nmap.result";
74
$fe = "nmap.error"; // stderr
75
$max_display_size = 50*1024*1024; // 50MB limit on GUI results display. See https://redmine.pfsense.org/issues/9239
76

  
77
$interfaces = get_configured_interface_with_descr();
78
if (ipsec_enabled()) {
79
	$interfaces['enc0'] = "IPsec";
80
}
81
$interfaces['lo0'] = "Localhost";
82

  
83
foreach (array('server' => gettext('OpenVPN Server'), 'client' => gettext('OpenVPN Client')) as $mode => $mode_descr) {
84
	if (is_array($config['openvpn']["openvpn-{$mode}"])) {
85
		foreach ($config['openvpn']["openvpn-{$mode}"] as $id => $setting) {
86
			if (!isset($setting['disable'])) {
87
				$interfaces['ovpn' . substr($mode, 0, 1) . $setting['vpnid']] = $mode_descr . ": ".htmlspecialchars($setting['description']);
88
			}
89
		}
90
	}
91
}
92

  
93
$interfaces = array_merge($interfaces, interface_ipsec_vti_list_all());
94
$interfaces = array_merge(array('' => 'Auto detect (default)'), $interfaces);
95

  
96
$scan_types = array(
97
	'syn' => gettext('TCP SYN'),
98
	'connect' => gettext('TCP Connect()'),
99
	'ack' => gettext('TCP ACK'),
100
	'window' => gettext('TCP Window'),
101
	'udp' => gettext('UDP'),
102
	'icmp' => gettext('No Port Scan'),
103
	'arp' => gettext('ARP Ping'),
104
	'ipscan' => gettext('IP Protocol'),
105
	'sctpinit' => gettext('SCTP INIT'),
106
	'sctpecho' => gettext('SCTP COOKIE ECHO'),
107
	'listscan' => gettext('List Only')
108
);
109

  
110
$input_errors = array();
111
$do_nmapscan = false;
112
if ($_POST) {
113
	$hostnames = $_POST['hostnames'];
114
	$interface = $_POST['interface'];
115
	$scantype = $_POST['scantype'];
116
	$udpscan = isset($_POST['udpscan']);
117
	$noping = isset($_POST['noping']);
118
	$servicever = isset($_POST['servicever']);
119
	$osdetect = isset($_POST['osdetect']);
120
	$excludehosts = $_POST['excludehosts'];
121
	$ports = $_POST['ports'];
122
	$topports = $_POST['topports'];
123
	$nodns = isset($_POST['nodns']);
124
	$traceroute = isset($_POST['traceroute']);
125

  
126
	if ($_POST['startbtn'] != "") {
127
		$action = gettext("Start");
128

  
129
		// check for input errors
130
		if (strlen($hostnames) === 0) {
131
			$input_errors[] = gettext("You must enter an IP address or host name to scan.");
132
		} else {
133
			$hostnames_array = explode(" ", $hostnames);
134
			foreach ($hostnames_array as $host_entry) {
135
				if (!(is_ipaddr($host_entry) || is_subnet($host_entry) || is_hostname($host_entry))) {
136
					$input_errors[] = gettext("Host: '") . escapeshellarg($host_entry) . gettext("' is not a valid IP address or host name.");
137
				} elseif (is_ipaddrv6($host_entry) || is_subnetv6($host_entry)) {
138
					$enable_ipv6 = true;
139
				}
140
			}
141
		}
142

  
143
		if(!empty($interface)) {
144
			if (!array_key_exists($interface, $interfaces)) {
145
				$input_errors[] = gettext("Invalid interface.");
146
			}
147
		}
148

  
149
		if ($udpscan) {
150
			if ($scantype !== 'syn' && $scantype !== 'connect' && $scantype !== 'ack' && $scantype !== 'window') {
151
				$input_errors[] = gettext("UDP Scan (-sU): This option cannot be used with '") . $scan_types[$scantype] . gettext("' scan type. UDP scan can only be combined with a TCP scan method");
152
			}
153
		}
154

  
155
		// Check advanced options
156
		if(strlen($excludehosts) > 0) {
157
			$excludehosts_array = explode(",", $excludehosts);
158
			foreach ($excludehosts_array as $host_entry) {
159
				if (strlen($host_entry) === 0) {
160
					$input_errors[] = gettext("Exclude Hosts: you cannot specify empty hosts in the list. Remove any extra or trailing commas !");
161
				} elseif (!(is_ipaddr($host_entry) || is_subnet($host_entry) || is_hostname($host_entry))) {
162
					$input_errors[] = gettext("Exclude Hosts: '") . escapeshellarg($host_entry) . gettext("' is not a valid IP address or host name.");
163
				}
164
			}
165
		}
166

  
167
		if(strlen($ports) > 0) {
168
			if (strpos($ports, '*') !== false) {
169
				$input_errors[] = gettext("Ports cannot contain an asterix '*'.");
170
			} else {
171
				$ports_arr = get_ports_array($ports);
172
				foreach ($ports_arr as $p) {
173
					if ($p === '*') {
174
						continue;
175
					} elseif (strlen($p) === 0) {
176
						$input_errors[] = gettext("Port: emtpy ports in list. Remove any extra or trailing commas. Also ensure that you type a port number/name after port specifiers (T:|U:|P:|S:)");
177
					} elseif (is_numericint($p) && intval($p) === 0) {
178
						continue;//nmap allows scanning of port 0 if explicitely specified
179
					} elseif (!is_port($p)) {
180
						$input_errors[] = gettext("Port: '") . escapeshellarg($p) . gettext("' is not a valid port.");
181
					} elseif ($scantype === 'ipscan' && is_numericint($p) && intval($p) > 255) {
182
						$input_errors[] = gettext("Port number must be an integer between 0 and 255 when using IP Protocol Scan method");
183
					}
184
				}
185
			}
186
		}
187

  
188
		if(strlen($topports) > 0) {
189
			if (!is_numericint($topports) || intval($topports) < 1 || intval($topports) > 65535) {
190
				$input_errors[] = gettext("--top-ports value must be an integer in the range 1-65535.");
191
			}
192
		}
193

  
194
		// process scan options only if no input errors
195
		if (!count($input_errors)) {
196
			$do_nmapscan = true;
197

  
198
			$nmap_options = "";
199

  
200
			// prevent use of any deprecated option
201
			//$nmap_options .= " -d";
202

  
203
			if ($enable_ipv6) {
204
				$nmap_options .= " -6";
205
			}
206

  
207
			// scan type
208
			switch($scantype) {
209
				case 'syn':
210
					$nmap_options .= " -sS";
211
					break;
212
				case 'connect':
213
					$nmap_options .= " -sT";
214
					break;
215
				case 'ack':
216
					$nmap_options .= " -sA";
217
					break;
218
				case 'window':
219
					$nmap_options .= " -sW";
220
					break;
221
				case 'udp':
222
					$nmap_options .= " -sU";
223
					break;
224
				case 'icmp':
225
					$nmap_options .= " -sn"; // previously -sP
226
					break;
227
				case 'arp':
228
					$nmap_options .= " -sn -PR";
229
					break;
230
				case 'ipscan':
231
					$nmap_options .= " -sO";
232
					break;
233
				case 'sctpinit':
234
					$nmap_options .= " -sY";
235
					break;
236
				case 'sctpecho':
237
					$nmap_options .= " -sZ";
238
					break;
239
				case 'listscan':
240
					$nmap_options .= " -sL";
241
					break;
242
			}
243

  
244
			// allow TCP + UDP combined scans
245
			if ($udpscan) {
246
				$nmap_options .= " -sU";
247
			}
248

  
249
			// scan options
250
			if ($noping) {
251
				$nmap_options .= " -Pn"; // previously -P0
252
			}
253
			if ($servicever) {
254
				$nmap_options .= " -sV";
255
			}
256
			if ($osdetect) {
257
				$nmap_options .= " -O";
258
			}
259

  
260
			if(strlen($ports) > 0) {
261
				$nmap_options .= " -p " . escapeshellarg($ports);
262
			}
263

  
264
			if(strlen($topports) > 0) {
265
				$nmap_options .= " --top-ports " . escapeshellarg($topports);
266
			}
267

  
268
			if ($nodns) {
269
				$nmap_options .= " -n";
270
			}
271

  
272
			if ($traceroute) {
273
				$nmap_options .= " --traceroute";
274
			}
275

  
276
			// append summary output to results file (doesn't contain stderr)
277
			$nmap_options .= " -oN {$fp}{$fn} --append-output";
278

  
279
			if (!empty($interface)) {
280
				$nmap_options .= " -e " . get_real_interface($interface);
281
			}
282

  
283
			if(strlen($excludehosts) > 0) {
284
				$nmap_options .= " --exclude " . escapeshellarg($excludehosts);
285
			}
286

  
287
			foreach ($hostnames_array as $host_entry) {
288
				$nmap_options .= " " . escapeshellarg($host_entry);
289
			}
290
		}
291
	} elseif ($_POST['stopbtn'] != "") {
292
		$action = gettext("Stop");
293

  
294
		/* check if nmap scan is already running */
295
		$processes_running = nmap_get_running_process($fn);
296
		$processisrunning = ($processes_running != "");
297

  
298
		//explode processes into an array, (delimiter is new line)
299
		$processes_running_array = explode("\n", $processes_running);
300

  
301
		if ($processisrunning != true) {
302
			$input_errors[] = gettext("Process nmap already completed. Check results below.");
303
		} else {
304
			//kill each of the nmap processes
305
			foreach ($processes_running_array as $process) {
306
				$process_id_pos = strpos($process, ' ');
307
				$process_id = substr($process, 0, $process_id_pos);
308
				exec("kill $process_id");
309
			}				
310
		}
311
	} elseif ($_POST['viewbtn'] != "" || $_POST['refreshbtn'] != "") {
312
		$action = gettext("View");
313
	} elseif ($_POST['downloadbtn'] != "") {
314
		$action = gettext("Download");
315

  
316
		//download file
317
		send_user_download('file', $fp.$fn);
318
	} elseif ($_POST['clearbtn'] != "") {
319
		$action = gettext("Delete");
320

  
321
		//delete previous nmap results file if it exists
322
		unlink_if_exists($fp.$fn);
323
		unlink_if_exists($fp.$fe);
324
	}
325
}
326

  
327
include("head.inc");
328

  
329
/*
330
$tab_array = array();
331
$tab_array[] = array(gettext("Nmap Scan"), true, "/nmap_scan.php");
332
display_top_tabs($tab_array);
333
*/
334

  
335
if ($input_errors) {
336
	print_input_errors($input_errors);
337
}
338

  
339
$form = new Form(false); // No button yet. We add those later depending on the required action
340

  
341
$section = new Form_Section('General Options');
342

  
343
$section->addInput(new Form_Input(
344
	'hostnames',
345
	'*IP or Hostname',
346
	'text',
347
	$hostnames
348
))->setHelp('Enter the IP addresses or hostnames that you would like to scan.%1$s' .
349
			'%2$sCan pass space separated hostnames, IP addresses, ranges, networks, etc.%3$s' .
350
			'Ex: scanme.nmap.org; microsoft.com/24 192.168.0.1 10.10.1.1; 10.0.0-255.1-254%4$s',
351

  
352
			'<span class="infoblock" style="font-size:90%"><br />',
353
			'<p style="margin:0px;padding:0px">',
354
			'<br />',
355
			'</p></span>');
356

  
357
$section->addInput(new Form_Select(
358
	'interface',
359
	'Interface',
360
	$interface,
361
	$interfaces
362
))->setHelp('Select the source interface here.');
363

  
364
$section->addInput(new Form_Select(
365
	'scantype',
366
	'*Scan Type',
367
	$scantype,
368
	$scan_types
369
))->setHelp('Select the scan type.%1$s' .
370
			'%2$s%3$s%4$sTCP SYN (-sS):%5$s The default and most popular scan option.%6$s' .
371

  
372
			'%4$sTCP connect (-sT):%5$s The default TCP scan type when SYN scan is not an option. This is the case when a user does not have raw packet privileges. ' .
373
			'This is the same high-level system call that web browsers, P2P clients, and most other network-enabled applications use to establish a connection.%6$s' .
374

  
375
			'%4$sTCP ACK (-sA):%5$s This scan is different than the others discussed so far in that it never determines open (or even open|filtered) ports. ' .
376
			'It is used to map out firewall rulesets, determining whether they are stateful or not and which ports are filtered.%6$s' .
377

  
378
			'%4$sTCP Window (-sW):%5$s Window scan is exactly the same as ACK scan except that it exploits an implementation detail of certain systems to differentiate open ports from closed ones, ' .
379
			'rather than always printing unfiltered when a RST is returned.%6$s' .
380

  
381
			'%4$sUDP scan (-sU):%5$s UDP scan works by sending an UDP packet to every targeted port.%6$s' .
382

  
383
			'%4$sNo port scan (-sn):%5$s This option tells Nmap not to do a port scan after host discovery, and only print out the available hosts that responded to the host discovery probes. This is often known as a "ping scan". ' .
384
			'However, to skip host discovery and port scan, while still allowing NSE to run, you can use the two options -Pn -sn together.%6$s' .
385

  
386
			'%4$sARP Ping (-sn -PR):%5$s ARP is only for directly connected ethernet LAN. On local networks, ARP scan takes just over a tenth of the time taken by its IP equivalent. ' .
387
			'It also avoids filling source host ARP table space with invalid entries.%6$s' .
388

  
389
			'%4$sIP protocol scan (-sO):%5$s IP protocol scan allows you to determine which IP protocols (TCP, ICMP, IGMP, etc.) are supported by target machines. ' .
390
			'This is not technically a port scan, since it cycles through IP protocol numbers rather than TCP or UDP port numbers. Yet it still uses the -p option to select scanned protocol numbers, ' .
391
			'reports its results within the normal port table format, and even uses the same underlying scan engine as the true port scanning methods.%6$s' .
392

  
393
			'%4$sSCTP INIT scan (-sY):%5$s Scan for services implementing SCTP. SCTP INIT scan is the SCTP equivalent of a TCP SYN scan.%6$s' .
394

  
395
			'%4$sSCTP COOKIE ECHO (-sZ):%5$s A more advanced SCTP scan. It takes advantage of the fact that SCTP implementations should silently drop packets containing COOKIE ECHO chunks on open ports, ' .
396
			'but send an ABORT if the port is closed.%6$s' .
397

  
398
			'%4$sList scan (-sL):%5$s List scan simply lists each target host on the network(s) specified, without sending any packets to the target hosts. ' .
399
			'By default, Nmap still performs reverse-DNS resolution on the hosts to learn their names. Nmap also reports the total number of IP addresses at the end. ' .
400
			'List scan is a good sanity check to ensure that you have proper IP addresses for your targets. A preliminary list scan helps confirm exactly what targets are being scanned.%6$s%7$s',
401

  
402
			'<span class="infoblock" style="font-size:90%"><br />',
403
			'<p style="margin:0px;padding:0px">',
404
			'<ul>',
405
			'<li><b>',
406
			'</b>',
407
			'</li>',
408
			'</ul></p></span>');
409

  
410
$section->addInput(new Form_Checkbox(
411
	'udpscan',
412
	'UDP Scan',
413
	'Combines an UDP scan (-sU) with a TCP scan method',
414
	$udpscan
415
))->setHelp('Only possible if a TCP scan method was selected.%1$s' .
416
			'%2$sUDP scan can be combined with a TCP scan type such as SYN scan (-sS) to check both protocols during the same run.%3$s' .
417
			'This option is valid only in combination with a TCP scan method (SYN, Connect(), ACK, Window).%4$s',
418

  
419
			'<span class="infoblock" style="font-size:90%"><br />',
420
			'<p style="margin:0px;padding:0px">',
421
			'<br />',
422
			'</p></span>');
423

  
424
$section->addInput(new Form_Checkbox(
425
	'noping',
426
	'-Pn',
427
	'Treat all hosts as online (No ping).',
428
	$noping
429
))->setHelp('Allow scanning of networks that do not answer echo requests.%1$s' .
430
			'%2$sThis option skips the Nmap discovery stage altogether. So if a class B target address space (/16) is specified on the command line, all 65,536 IP addresses are scanned. ' .
431
			'Proper host discovery is skipped as with the list scan, but instead of stopping and printing the target list, Nmap continues to perform requested functions as if each target IP is active.%3$s' .
432
			'microsoft.com is an example of such a network, and thus you should always use -P0 or -PT80 when port scanning microsoft.com.%3$s' .
433
			'Note the "ping" in this context may involve more than the traditional ICMP echo request packet. Nmap supports many such probes, including arbitrary combinations of TCP, UDP, and ICMP probes.%3$s' .
434
			'By default, Nmap sends an ICMP echo request and a TCP ACK packet to port 80.%4$s',
435

  
436
			'<span class="infoblock" style="font-size:90%"><br />',
437
			'<p style="margin:0px;padding:0px">',
438
			'<br />',
439
			'</p></span>');
440

  
441
$section->addInput(new Form_Checkbox(
442
	'servicever',
443
	'-sV',
444
	'Attempt to identify service versions',
445
	$servicever
446
))->setHelp('Try to detect services running on discoverd ports.%1$s' .
447
			'%2$sAfter TCP and/or UDP ports are discovered using one of the other scan types, version detection communicates with those ports to try and determine more about what is actually running.%3$s' .
448
			'A file called nmap-service-probes is used to determine the best probes for detecting various services and the match strings to expect.%3$s' .
449
			'Nmap tries to determine the service protocol (e.g. ftp, ssh, telnet, http), the application name (e.g. ISC Bind, Apache httpd, Solaris telnetd), ' .
450
			'the version number, and sometimes miscellaneous details like whether an X server is open to connections or the SSH protocol version).%4$s',
451

  
452
			'<span class="infoblock" style="font-size:90%"><br />',
453
			'<p style="margin:0px;padding:0px">',
454
			'<br />',
455
			'</p></span>');
456

  
457
$section->addInput(new Form_Checkbox(
458
	'osdetect',
459
	'-O',
460
	'Enable Operating System detection',
461
	$osdetect
462
))->setHelp('Try to identify remote host via TCP/IP fingerprinting.%1$s' .
463
			'%2$sIn other words, it uses techniques to detect subtleties in the underlying operating system network stack of the computers being scanned.%3$s' .
464
			'It uses this information to create a "fingerprint" which it compares with its database of known OS fingerprints ' .
465
			'(the nmap-os-fingerprints file) to determine the operating system of the target host.%4$s',
466

  
467
			'<span class="infoblock" style="font-size:90%"><br />',
468
			'<p style="margin:0px;padding:0px">',
469
			'<br />',
470
			'</p></span>');
471

  
472
$form->add($section);
473

  
474
$section = new Form_Section('Advanced Options');
475

  
476
$section->addInput(new Form_Input(
477
	'excludehosts',
478
	'Exclude Hosts',
479
	'text',
480
	$excludehosts
481
))->setHelp('Enter the IP addresses or hostnames that you would like to exclude from scan.%1$s' .
482
			'%2$sCan pass comma separated hostnames, IP addresses, ranges, networks, etc.%3$s' .
483
			'Ex: scanme.nmap.org,microsoft.com/24,192.168.0.1,10.10.1.1,10.0.0-255.1-254%4$s',
484

  
485
			'<span class="infoblock" style="font-size:90%"><br />',
486
			'<p style="margin:0px;padding:0px">',
487
			'<br />',
488
			'</p></span>');
489

  
490
$section->addInput(new Form_Input(
491
	'ports',
492
	'Port',
493
	'text',
494
	$ports
495
))->setHelp('Only scan specified ports.%1$s' .
496
			'%2$sEx: 22; 1-65535; ssh; U:53,111,137,T:21-25,80,139,8080,P:9.%3$s' .
497
			'When scanning a combination of protocols (e.g. TCP and UDP), you can specify a particular protocol by preceding the port numbers by T: for TCP, U: for UDP, or P: for IP Protocol.%3$s' .
498
			'Individual port numbers are OK, as are ranges separated by a hyphen (e.g. 1-1023). The beginning and/or end values of a range may be omitted, causing Nmap to use 1 and 65535, respectively. ' .
499
			'So you can specify -p- to scan ports from 1 through 65535. Scanning port zero is allowed if you specify it explicitly.%3$s' .
500
			'For IP protocol scanning (-sO), this option specifies the protocol numbers you wish to scan for (0–255).%3$s' .
501
			'Note: SCTP (S:) specifier is not supported in GUI.%4$s',
502

  
503
			'<span class="infoblock" style="font-size:90%"><br />',
504
			'<p style="margin:0px;padding:0px">',
505
			'<br />',
506
			'</p></span>');
507

  
508
$section->addInput(new Form_Input(
509
	'topports',
510
	'--top-ports',
511
	'text',
512
	$topports
513
))->setHelp('Only scan specified most common ports (1-65535).%1$s' .
514
			'%2$sNormally Nmap scans the most common 1,000 ports for each scanned protocol.%3$s' .
515
			'With this option, nmap will only scan the specified most common ports number.%3$s' .
516
			'Value of 100 would be equivalent to the option "-F (Fast (limited port) scan)" which scans the first 100 most common ports.%4$s',
517

  
518
			'<span class="infoblock" style="font-size:90%"><br />',
519
			'<p style="margin:0px;padding:0px">',
520
			'<br />',
521
			'</p></span>');
522

  
523
$section->addInput(new Form_Checkbox(
524
	'nodns',
525
	'-n',
526
	'No DNS Resolution',
527
	$nodns
528
));
529

  
530
$section->addInput(new Form_Checkbox(
531
	'traceroute',
532
	'--traceroute',
533
	'Trace hop path to each host',
534
	$traceroute
535
));
536

  
537
$form->add($section);
538

  
539
/* check if nmap scan is already running */
540
$processes_running = nmap_get_running_process($fn);
541
$processisrunning = ($processes_running != "");
542

  
543
if ($processisrunning or $do_nmapscan) {
544
	$form->addGlobal(new Form_Button(
545
		'stopbtn',
546
		'Stop',
547
		null,
548
		'fa-stop-circle'
549
	))->addClass('btn-warning');
550

  
551
	$form->addGlobal(new Form_Button(
552
		'refreshbtn',
553
		'Refresh Results',
554
		null,
555
		'fa-retweet'
556
	))->addClass('btn-primary');
557
} else {
558
	$form->addGlobal(new Form_Button(
559
		'startbtn',
560
		'Start',
561
		null,
562
		'fa-play-circle'
563
	))->addClass('btn-success');
564

  
565
	if (file_exists($fp.$fn) or file_exists($fp.$fe)) {
566
		$form->addGlobal(new Form_Button(
567
			'viewbtn',
568
			'View Results',
569
			null,
570
			'fa-file-text-o'
571
		))->addClass('btn-primary');
572

  
573
		$form->addGlobal(new Form_Button(
574
			'downloadbtn',
575
			'Download Results',
576
			null,
577
			'fa-download'
578
		))->addClass('btn-primary');
579

  
580
		$form->addGlobal(new Form_Button(
581
			'clearbtn',
582
			'Clear Results',
583
			null,
584
			'fa-trash'
585
		))->addClass('btn-danger');
586
	}
587
}
588

  
589
if (file_exists($fp.$fn)) {
590
	$section->addInput(new Form_StaticText(
591
		'Last scan results',
592
		date("F jS, Y g:i:s a.", filemtime($fp.$fn))
593
	));
594
}
595

  
596
if (file_exists($fp.$fe) && filesize($fp.$fe) > 0) {
597
	$section->addInput(new Form_StaticText(
598
		'Last scan error',
599
		date("F jS, Y g:i:s a.", filemtime($fp.$fe))
600
	));
601
}
602

  
603
print($form);
604

  
605
if ($do_nmapscan) {
606
	$cmd = "/usr/local/bin/nmap {$nmap_options} >/dev/null 2>{$fp}{$fe} &";
607
	exec($cmd);
608
	print_info_box(gettext('Nmap scan is running' . '<br />' . 'Press info button to show command'), 'info');
609
	?>
610
	<div class="infoblock">
611
	<? print_info_box(gettext('Command line') . ': ' . htmlspecialchars($cmd), 'info', false); ?>
612
	</div>
613
	<?php
614

  
615
} elseif ($action == gettext("View") || $action == gettext("Stop")) {
616
		if (file_exists($fp.$fe) && filesize($fp.$fe) > 0) {
617
?>
618

  
619
<div class="panel panel-default">
620
	<div class="panel-heading"><h2 class="panel-title"><?=gettext('Scan Errors')?></h2></div>
621
	<div class="panel-body">
622
		<div class="form-group">
623
<?php
624

  
625
			print('<textarea class="form-control" rows="10" style="font-size: 13px; font-family: consolas,monaco,roboto mono,liberation mono,courier;">');
626
			if (filesize($fp.$fe) > $max_display_size) {
627
				print(gettext("Nmap scan error file is too large to display in the GUI.") .
628
					"\n" .
629
					gettext("Download the file, or view it in the console or ssh shell.") .
630
					"\n" .
631
					gettext("Error file: {$fp}{$fe}"));
632
			} else {
633
				print(file_get_contents($fp.$fe));
634
			}
635
			print('</textarea>');
636

  
637
?>
638
		</div>
639
	</div>
640
</div>
641
<?php
642
		}
643

  
644
?>
645

  
646
<div class="panel panel-default">
647
	<div class="panel-heading"><h2 class="panel-title"><?=gettext('Scan Results')?></h2></div>
648
	<div class="panel-body">
649
		<div class="form-group">
650
<?php
651

  
652
		print('<textarea class="form-control" rows="20" style="font-size: 13px; font-family: consolas,monaco,roboto mono,liberation mono,courier;">');
653
		if (file_exists($fp.$fn) && (filesize($fp.$fn) > $max_display_size)) {
654
			print(gettext("Nmap scan results file is too large to display in the GUI.") .
655
				"\n" .
656
				gettext("Download the file, or view it in the console or ssh shell.") .
657
				"\n" .
658
				gettext("Results file: {$fp}{$fn}"));
659
		} elseif (!file_exists($fp.$fn) || (filesize($fp.$fn) === 0)) {
660
			print(gettext("No nmap scan results to display."));
661
		} else {
662
			print(file_get_contents($fp.$fn));
663
		}
664
		print('</textarea>');
665

  
666
?>
667
		</div>
668
	</div>
669
</div>
670
<?php
671
}
672

  
673
include("foot.inc");
(30-30/30)