Project

General

Profile

Feature #12963 » nmap_scan-v18.patch

Phil Wardt, 03/31/2022 04:03 PM

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
require_once("guiconfig.inc");
22
/* require_once("pfsense-utils.inc"); */
23
require_once("ipsec.inc");
24

  
25
if ($_POST['downloadbtn'] == gettext("Download Results")) {
26
	$nocsrf = true;
27
}
28

  
29
$fp = "/root/";
30
$fn = "nmap.result";
31
$fe = "nmap.error"; // stderr
32
$max_display_size = 50*1024*1024; // 50MB limit on GUI results display. See https://redmine.pfsense.org/issues/9239
33

  
34
$interfaces = get_configured_interface_with_descr();
35
if (ipsec_enabled()) {
36
	$interfaces['enc0'] = "IPsec";
37
}
38
$interfaces['lo0'] = "Localhost";
39

  
40
foreach (array('server' => gettext('OpenVPN Server'), 'client' => gettext('OpenVPN Client')) as $mode => $mode_descr) {
41
	if (is_array($config['openvpn']["openvpn-{$mode}"])) {
42
		foreach ($config['openvpn']["openvpn-{$mode}"] as $id => $setting) {
43
			if (!isset($setting['disable'])) {
44
				$interfaces['ovpn' . substr($mode, 0, 1) . $setting['vpnid']] = $mode_descr . ": ".htmlspecialchars($setting['description']);
45
			}
46
		}
47
	}
48
}
49

  
50
$interfaces = array_merge($interfaces, interface_ipsec_vti_list_all());
51
$interfaces = array_merge(array('' => 'Auto detect (default)'), $interfaces);
52

  
53
$scan_types = array(
54
	'syn' => gettext('TCP SYN'),
55
	'connect' => gettext('TCP Connect()'),
56
	'ack' => gettext('TCP ACK'),
57
	'window' => gettext('TCP Window'),
58
	'udp' => gettext('UDP'),
59
	'icmp' => gettext('No Port Scan'),
60
	'arp' => gettext('ARP Ping'),
61
	'ipscan' => gettext('IP Protocol'),
62
	'sctpinit' => gettext('SCTP INIT'),
63
	'sctpecho' => gettext('SCTP COOKIE ECHO'),
64
	'listscan' => gettext('List Only')
65
);
66

  
67
function nmap_get_running_process(){
68
	$processcheck = (trim(shell_exec("/bin/ps axw -O pid= | /usr/bin/grep '/usr/local/bin/[n]map.*{$fn}'")));
69
	return $processcheck;
70
}
71

  
72
// Return a ports array from a nmap -p arg value format
73
// we strip ranges (-) and types (T:, U:, P:, S:)
74
// port names with '-' like 'netbios-ssn' are supported
75
function get_ports_array($port_post) {
76
	$ports_array = array();
77

  
78
	// get ports from the comma separated form input
79
	if (strpos($port_post, ',') === false) {
80
		$ports_array = array($port_post);
81
	} else {
82
		$ports_array = explode(',', $port_post);
83
	}
84

  
85
	$port_max_ranges = array();
86
	foreach ($ports_array as &$p) {
87
		if (preg_match('/^(T:|U:|P:|S:)/', $p) === 1) {
88
			$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
89
		}
90

  
91
		// keep only inner and outer ports from a ports range
92
		// if the inner/outer port range limit is omitted, set corresponding port value to '*'
93
		if ($p === '-') {
94
        	$p = '*';
95
        } elseif (strpos($p, '-') !== false && preg_match('/^[0-9\-]+$/', $p) === 1) {
96
			// port ranges must be in the format of 'numeric-numeric'
97
			$port_ranges = explode('-', $p, 2);
98
			$p = strlen($port_ranges[0]) ? $port_ranges[0] : '*';
99
            $port_max_ranges[] = strlen($port_ranges[1]) ? $port_ranges[1] : '*';
100
		}
101
	}
102
	unset($p);
103
	$ports_array = array_merge($ports_array, $port_max_ranges);
104

  
105
	return $ports_array;
106
}
107

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

  
123
	if ($_POST['startbtn'] != "") {
124
		$action = gettext("Start");
125

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

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

  
146
		if ($udpscan) {
147
			if ($scantype !== 'syn' && $scantype !== 'connect' && $scantype !== 'ack' && $scantype !== 'window') {
148
				$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");
149
			}
150
		}
151

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

  
164
		if(strlen($ports) > 0) {
165
			if (strpos($ports, '*') !== false) {
166
				$input_errors[] = gettext("Ports cannot contain an asterix '*'.");
167
			} else {
168
				$ports_arr = get_ports_array($ports);
169
				foreach ($ports_arr as $p) {
170
					if ($p === '*') {
171
						continue;
172
					} elseif (strlen($p) === 0) {
173
						$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:)");
174
					} elseif (is_numericint($p) && intval($p) === 0) {
175
						continue;//nmap allows scanning of port 0 if explicitely specified
176
					} elseif (!is_port($p)) {
177
						$input_errors[] = gettext("Port: '") . escapeshellarg($p) . gettext("' is not a valid port.");
178
					} elseif ($scantype === 'ipscan' && is_numericint($p) && intval($p) > 255) {
179
						$input_errors[] = gettext("Port number must be an integer between 0 and 255 when using IP Protocol Scan method");
180
					}
181
				}
182
			}
183
		}
184

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

  
191
		// process scan options only if no input errors
192
		if (!count($input_errors)) {
193
			$do_nmapscan = true;
194

  
195
			$nmap_options = "";
196

  
197
			// prevent use of any deprecated option
198
			//$nmap_options .= " -d";
199

  
200
			if ($enable_ipv6) {
201
				$nmap_options .= " -6";
202
			}
203

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

  
241
			// allow TCP + UDP combined scans
242
			if ($udpscan) {
243
				$nmap_options .= " -sU";
244
			}
245

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

  
257
			if(strlen($ports) > 0) {
258
				$nmap_options .= " -p " . escapeshellarg($ports);
259
			}
260

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

  
265
			if ($traceroute) {
266
				$nmap_options .= " --traceroute";
267
			}
268

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

  
272
			if (!empty($interface)) {
273
				$nmap_options .= " -e " . get_real_interface($interface);
274
			}
275

  
276
			if(strlen($excludehosts) > 0) {
277
				$nmap_options .= " --exclude " . escapeshellarg($excludehosts);
278
			}
279

  
280
			foreach ($hostnames_array as $host_entry) {
281
				$nmap_options .= " " . escapeshellarg($host_entry);
282
			}
283
		}
284
	} elseif ($_POST['stopbtn'] != "") {
285
		$action = gettext("Stop");
286

  
287
		/* check if nmap scan is already running */
288
		$processes_running = nmap_get_running_process();
289
		$processisrunning = ($processes_running != "");
290

  
291
		//explode processes into an array, (delimiter is new line)
292
		$processes_running_array = explode("\n", $processes_running);
293

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

  
309
		//download file
310
		send_user_download('file', $fp.$fn);
311
	} elseif ($_POST['clearbtn'] != "") {
312
		$action = gettext("Delete");
313

  
314
		//delete previous nmap results file if it exists
315
		unlink_if_exists($fp.$fn);
316
		unlink_if_exists($fp.$fe);
317
	}
318
}
319

  
320
$pgtitle = array("Package", "Diagnostics: Nmap");
321
include("head.inc");
322

  
323
/*
324
$tab_array = array();
325
$tab_array[] = array(gettext("Nmap Scan"), true, "/nmap_scan.php");
326
display_top_tabs($tab_array);
327
*/
328

  
329
if ($input_errors) {
330
	print_input_errors($input_errors);
331
}
332

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

  
335
$section = new Form_Section('General Options');
336

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

  
346
			'<span class="infoblock" style="font-size:90%"><br />',
347
			'<p style="margin:0px;padding:0px">',
348
			'<br />',
349
			'</p></span>');
350

  
351
$section->addInput(new Form_Select(
352
	'interface',
353
	'Interface',
354
	$interface,
355
	$interfaces
356
))->setHelp('Select the source interface here.');
357

  
358
$section->addInput(new Form_Select(
359
	'scantype',
360
	'*Scan Type',
361
	$scantype,
362
	$scan_types
363
))->setHelp('Select the scan type.%1$s' .
364
			'%2$s%3$s%4$sTCP SYN (-sS):%5$s The default and most popular scan option.%6$s' .
365

  
366
			'%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. ' .
367
			'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' .
368

  
369
			'%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. ' .
370
			'It is used to map out firewall rulesets, determining whether they are stateful or not and which ports are filtered.%6$s' .
371

  
372
			'%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, ' .
373
			'rather than always printing unfiltered when a RST is returned.%6$s' .
374

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

  
377
			'%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". ' .
378
			'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' .
379

  
380
			'%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. ' .
381
			'It also avoids filling source host ARP table space with invalid entries.%6$s' .
382

  
383
			'%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. ' .
384
			'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, ' .
385
			'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' .
386

  
387
			'%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' .
388

  
389
			'%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, ' .
390
			'but send an ABORT if the port is closed.%6$s' .
391

  
392
			'%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. ' .
393
			'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. ' .
394
			'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',
395

  
396
			'<span class="infoblock" style="font-size:90%"><br />',
397
			'<p style="margin:0px;padding:0px">',
398
			'<ul>',
399
			'<li><b>',
400
			'</b>',
401
			'</li>',
402
			'</ul></p></span>');
403

  
404
$section->addInput(new Form_Checkbox(
405
	'udpscan',
406
	'UDP Scan',
407
	'Combines an UDP scan (-sU) with a TCP scan method',
408
	$_POST['udpscan']
409
))->setHelp('Only possible if a TCP scan method was selected.%1$s' .
410
			'%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' .
411
			'This option is valid only in combination with a TCP scan method (SYN, Connect(), ACK, Window).%3$s',
412

  
413
			'<span class="infoblock" style="font-size:90%"><br />',
414
			'<p style="margin:0px;padding:0px">',
415
			'<br />',
416
			'</p></span>');
417

  
418
$section->addInput(new Form_Checkbox(
419
	'noping',
420
	'-Pn',
421
	'Treat all hosts as online (No ping).',
422
	$_POST['noping']
423
))->setHelp('Allow scanning of networks that do not answer echo requests.%1$s' .
424
			'%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. ' .
425
			'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' .
426
			'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' .
427
			'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' .
428
			'By default, Nmap sends an ICMP echo request and a TCP ACK packet to port 80.%4$s',
429

  
430
			'<span class="infoblock" style="font-size:90%"><br />',
431
			'<p style="margin:0px;padding:0px">',
432
			'<br />',
433
			'</p></span>');
434

  
435
$section->addInput(new Form_Checkbox(
436
	'servicever',
437
	'-sV',
438
	'Attempt to identify service versions',
439
	$_POST['servicever']
440
))->setHelp('Try to detect services running on discoverd ports.%1$s' .
441
			'%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' .
442
			'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' .
443
			'Nmap tries to determine the service protocol (e.g. ftp, ssh, telnet, http), the application name (e.g. ISC Bind, Apache httpd, Solaris telnetd), ' .
444
			'the version number, and sometimes miscellaneous details like whether an X server is open to connections or the SSH protocol version).%4$s',
445

  
446
			'<span class="infoblock" style="font-size:90%"><br />',
447
			'<p style="margin:0px;padding:0px">',
448
			'<br />',
449
			'</p></span>');
450

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

  
461
			'<span class="infoblock" style="font-size:90%"><br />',
462
			'<p style="margin:0px;padding:0px">',
463
			'<br />',
464
			'</p></span>');
465

  
466
$form->add($section);
467

  
468
$section = new Form_Section('Advanced Options');
469

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

  
479
			'<span class="infoblock" style="font-size:90%"><br />',
480
			'<p style="margin:0px;padding:0px">',
481
			'<br />',
482
			'</p></span>');
483

  
484
$section->addInput(new Form_Input(
485
	'ports',
486
	'Port',
487
	'text',
488
	$ports
489
))->setHelp('Only scan specified ports.%1$s' .
490
			'%2$sEx: 22; 1-65535; ssh; U:53,111,137,T:21-25,80,139,8080,P:9.%3$s' .
491
			'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' .
492
			'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. ' .
493
			'So you can specify -p- to scan ports from 1 through 65535. Scanning port zero is allowed if you specify it explicitly.%3$s' .
494
			'For IP protocol scanning (-sO), this option specifies the protocol numbers you wish to scan for (0–255).%3$s' .
495
			'Note: SCTP (S:) specifier is not supported in GUI.%4$s',
496

  
497
			'<span class="infoblock" style="font-size:90%"><br />',
498
			'<p style="margin:0px;padding:0px">',
499
			'<br />',
500
			'</p></span>');
501

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

  
512
			'<span class="infoblock" style="font-size:90%"><br />',
513
			'<p style="margin:0px;padding:0px">',
514
			'<br />',
515
			'</p></span>');
516

  
517
$section->addInput(new Form_Checkbox(
518
	'traceroute',
519
	'--traceroute',
520
	'Trace hop path to each host',
521
	$_POST['traceroute']
522
));
523

  
524
$form->add($section);
525

  
526
/* check if nmap scan is already running */
527
$processes_running = nmap_get_running_process();
528
$processisrunning = ($processes_running != "");
529

  
530
if ($processisrunning or $do_nmapscan) {
531
	$form->addGlobal(new Form_Button(
532
		'stopbtn',
533
		'Stop',
534
		null,
535
		'fa-stop-circle'
536
	))->addClass('btn-warning');
537

  
538
	$form->addGlobal(new Form_Button(
539
		'refreshbtn',
540
		'Refresh Results',
541
		null,
542
		'fa-retweet'
543
	))->addClass('btn-primary');
544
} else {
545
	$form->addGlobal(new Form_Button(
546
		'startbtn',
547
		'Start',
548
		null,
549
		'fa-play-circle'
550
	))->addClass('btn-success');
551

  
552
	if (file_exists($fp.$fn) or file_exists($fp.$fe)) {
553
		$form->addGlobal(new Form_Button(
554
			'viewbtn',
555
			'View Results',
556
			null,
557
			'fa-file-text-o'
558
		))->addClass('btn-primary');
559

  
560
		$form->addGlobal(new Form_Button(
561
			'downloadbtn',
562
			'Download Results',
563
			null,
564
			'fa-download'
565
		))->addClass('btn-primary');
566

  
567
		$form->addGlobal(new Form_Button(
568
			'clearbtn',
569
			'Clear Results',
570
			null,
571
			'fa-trash'
572
		))->addClass('btn-danger');
573
	}
574
}
575

  
576
if (file_exists($fp.$fn)) {
577
	$section->addInput(new Form_StaticText(
578
		'Last scan results',
579
		date("F jS, Y g:i:s a.", filemtime($fp.$fn))
580
	));
581
}
582

  
583
if (file_exists($fp.$fe) && filesize($fp.$fe) > 0) {
584
	$section->addInput(new Form_StaticText(
585
		'Last scan error',
586
		date("F jS, Y g:i:s a.", filemtime($fp.$fe))
587
	));
588
}
589

  
590
print($form);
591

  
592
if ($do_nmapscan) {
593
	$cmd = "/usr/local/bin/nmap {$nmap_options} >/dev/null 2>{$fp}{$fe} &";
594
	exec($cmd);
595
	print_info_box(gettext('Nmap scan is running' . '<br />' . 'Press info button to show command'), 'info');
596
	?>
597
	<div class="infoblock">
598
	<? print_info_box(gettext('Command line') . ': ' . htmlspecialchars($cmd), 'info', false); ?>
599
	</div>
600
	<?php
601

  
602
} elseif ($action == gettext("View") || $action == gettext("Stop")) {
603
		if (file_exists($fp.$fe) && filesize($fp.$fe) > 0) {
604
?>
605

  
606
<div class="panel panel-default">
607
	<div class="panel-heading"><h2 class="panel-title"><?=gettext('Scan Errors')?></h2></div>
608
	<div class="panel-body">
609
		<div class="form-group">
610
<?php
611

  
612
			print('<textarea class="form-control" rows="10" style="font-size: 13px; font-family: consolas,monaco,roboto mono,liberation mono,courier;">');
613
			if (filesize($fp.$fe) > $max_display_size) {
614
				print(gettext("Nmap scan error file is too large to display in the GUI.") .
615
					"\n" .
616
					gettext("Download the file, or view it in the console or ssh shell.") .
617
					"\n" .
618
					gettext("Error file: {$fp}{$fe}"));
619
			} else {
620
				print(file_get_contents($fp.$fe));
621
			}
622
			print('</textarea>');
623

  
624
?>
625
		</div>
626
	</div>
627
</div>
628
<?php
629
		}
630

  
631
?>
632

  
633
<div class="panel panel-default">
634
	<div class="panel-heading"><h2 class="panel-title"><?=gettext('Scan Results')?></h2></div>
635
	<div class="panel-body">
636
		<div class="form-group">
637
<?php
638

  
639
		print('<textarea class="form-control" rows="20" style="font-size: 13px; font-family: consolas,monaco,roboto mono,liberation mono,courier;">');
640
		if (file_exists($fp.$fn) && (filesize($fp.$fn) > $max_display_size)) {
641
			print(gettext("Nmap scan results file is too large to display in the GUI.") .
642
				"\n" .
643
				gettext("Download the file, or view it in the console or ssh shell.") .
644
				"\n" .
645
				gettext("Results file: {$fp}{$fn}"));
646
		} elseif (!file_exists($fp.$fn) || (filesize($fp.$fn) === 0)) {
647
			print(gettext("No nmap scan results to display."));
648
		} else {
649
			print(file_get_contents($fp.$fn));
650
		}
651
		print('</textarea>');
652

  
653
?>
654
		</div>
655
	</div>
656
</div>
657
<?php
658
}
659

  
660
include("foot.inc");
(26-26/30)