Project

General

Profile

Feature #2456 » ipsec.widget.php

Chris Baker, 04/08/2017 01:58 PM

 
1
<?php
2
/*
3
 * ipsec.widget.php
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2016 Rubicon Communications, LLC (Netgate)
7
 * Copyright (c) 2004-2005 T. Lechat <dev@lechat.org> (BSD 2 clause)
8
 * Copyright (c) 2007 Jonathan Watt <jwatt@jwatt.org> (BSD 2 clause)
9
 * Copyright (c) 2007 Scott Dale (BSD 2 clause)
10
 * All rights reserved.
11
 *
12
 * originally part of m0n0wall (http://m0n0.ch/wall)
13
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
14
 * All rights reserved.
15
 *
16
 * Redistribution and use in source and binary forms, with or without
17
 * modification, are permitted provided that the following conditions are met:
18
 *
19
 * 1. Redistributions of source code must retain the above copyright notice,
20
 *    this list of conditions and the following disclaimer.
21
 *
22
 * 2. Redistributions in binary form must reproduce the above copyright
23
 *    notice, this list of conditions and the following disclaimer in
24
 *    the documentation and/or other materials provided with the
25
 *    distribution.
26
 *
27
 * 3. All advertising materials mentioning features or use of this software
28
 *    must display the following acknowledgment:
29
 *    "This product includes software developed by the pfSense Project
30
 *    for use in the pfSense® software distribution. (http://www.pfsense.org/).
31
 *
32
 * 4. The names "pfSense" and "pfSense Project" must not be used to
33
 *    endorse or promote products derived from this software without
34
 *    prior written permission. For written permission, please contact
35
 *    coreteam@pfsense.org.
36
 *
37
 * 5. Products derived from this software may not be called "pfSense"
38
 *    nor may "pfSense" appear in their names without prior written
39
 *    permission of the Electric Sheep Fencing, LLC.
40
 *
41
 * 6. Redistributions of any form whatsoever must retain the following
42
 *    acknowledgment:
43
 *
44
 * "This product includes software developed by the pfSense Project
45
 * for use in the pfSense software distribution (http://www.pfsense.org/).
46
 *
47
 * THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
48
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
50
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
51
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
52
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
53
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
54
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
56
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
57
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
58
 * OF THE POSSIBILITY OF SUCH DAMAGE.
59
 */
60

    
61
$nocsrf = true;
62

    
63
require_once("guiconfig.inc");
64
require_once("functions.inc");
65
require_once("ipsec.inc");
66

    
67
// Compose the table contents and pass it back to the ajax caller
68
if ($_REQUEST && $_REQUEST['ajax']) {
69

    
70
	if (isset($config['ipsec']['phase1'])) {
71
		$spd = ipsec_dump_spd();
72
		$sad = ipsec_dump_sad();
73
		$mobile = ipsec_dump_mobile();
74
		$ipsec_status = ipsec_list_sa();
75

    
76
		$activecounter = 0;
77
		$inactivecounter = 0;
78

    
79
		$ipsec_detail_array = array();
80
		$ikenum = array();
81
		if (isset($config['ipsec']['phase2'])) {
82
			foreach ($config['ipsec']['phase2'] as $ph2ent) {
83
				if (!ipsec_lookup_phase1($ph2ent,$ph1ent)) {
84
					continue;
85
				}
86

    
87
				if ($ph2ent['remoteid']['type'] == "mobile" || isset($ph1ent['mobile'])) {
88
					continue;
89
				}
90

    
91
				if (isset($ph1ent['disabled']) || isset($ph2ent['disabled'])) {
92
					continue;
93
				}
94

    
95
				if (empty($ph1ent['iketype']) || $ph1ent['iketype'] == 'ikev1') {
96
					if (!isset($ikenum[$ph1ent['ikeid']])) {
97
						$ikenum[$ph1ent['ikeid']] = 0;
98
					} else {
99
						$ikenum[$ph1ent['ikeid']]++;
100
					}
101

    
102
					$ikeid = "con{$ph1ent['ikeid']}00" . $ikenum[$ph1ent['ikeid']];
103
				} else {
104
					if (isset($ikenum[$ph1ent['ikeid']])) {
105
						continue;
106
					}
107

    
108
					$ikeid = "con{$ph1ent['ikeid']}";
109
					$ikenum[$ph1ent['ikeid']] = true;
110
				}
111

    
112
				$found = false;
113
				foreach ($ipsec_status as $id => $ikesa) {
114
					if (isset($ikesa['child-sas'])) {
115
						foreach ($ikesa['child-sas'] as $childid => $childsa) {
116
							if ($ikeid == $childid) {
117
								$found = true;
118
								break;
119
							}
120
						}
121
					} else if ($ikeid == $id) {
122
						$found = true;
123
					}
124

    
125
					if ($found === true) {
126
						if ($ikesa['state'] == 'ESTABLISHED') {
127
							/* tunnel is up */
128
							$iconfn = "true";
129
							$activecounter++;
130
						} else {
131
							/* tunnel is down */
132
							$iconfn = "false";
133
							$inactivecounter++;
134
						}
135
						break;
136
					}
137
				}
138

    
139
				if ($found === false) {
140
					/* tunnel is down */
141
					$iconfn = "false";
142
					$inactivecounter++;
143
				}
144

    
145
				$ipsec_detail_array[] = array('src' => convert_friendly_interface_to_friendly_descr($ph1ent['interface']),
146
						'dest' => $ph1ent['remote-gateway'],
147
						'remote-subnet' => ipsec_idinfo_to_text($ph2ent['remoteid']),
148
						'descr' => $ph2ent['descr'],
149
						'status' => $iconfn);
150
			}
151
		}
152
		unset($ikenum);
153
	}
154

    
155
	// Only generate the data for the tab that is currently being viewed
156
	switch ($_REQUEST['tab']) {
157
		case "Overview" :
158
			print("	<tr>\n");
159
			print(		"<td>" . $activecounter . "</td>\n");
160
			print(		"<td>" . $inactivecounter . "</td>\n");
161
			print(		"<td>" . (is_array($mobile['pool']) ? htmlspecialchars($mobile['pool'][0]['usage']) : '0') . "</td>\n");
162
			print(	"</tr>\n");
163
		break;
164

    
165
		case "tunnel" :
166
			foreach ($ipsec_detail_array as $ipsec) {
167
				print("	<tr>\n");
168
				print(		"<td>" . htmlspecialchars($ipsec['src']) . "</td>\n");
169
				print(		"<td>" . $ipsec['remote-subnet'] . "<br />(" . htmlspecialchars($ipsec['dest']) . ")</td>\n");
170
				print(		"<td>" . htmlspecialchars($ipsec['descr']) . "</td>\n");
171

    
172
				if ($ipsec['status'] == "true") {
173
					print('<td><i class="fa fa-arrow-up text-success"></i></td>' . "\n");
174
				} else {
175
					print('<td><i class="fa fa-arrow-down text-danger"></i></td>' . "\n");
176
				}
177

    
178
				print(	"</tr>\n");
179
			}
180
		break;
181

    
182
		case "mobile" :
183
			if (!is_array($mobile['pool'])) {
184
				break;
185
			}
186
			foreach ($mobile['pool'] as $pool) {
187
				if (!is_array($pool['lease'])) {
188
					continue;
189
				}
190

    
191
				foreach ($pool['lease'] as $muser) {
192
					print("	<tr>\n");
193
					print(		"<td>" . htmlspecialchars($muser['id']) . "</td>\n");
194
					print(		"<td>" . htmlspecialchars($muser['host']) . "</td>\n");
195
					print(		"<td>" . htmlspecialchars($muser['status']) . "</td>\n");
196
					print("	</tr>\n");
197
				}
198
			}
199
		break;
200
	}
201

    
202
	exit;
203
}
204

    
205
if ($_POST) {
206

    
207
        if (!is_array($user_settings["widgets"]["ipsec_widget"])) {
208
                $user_settings["widgets"]["ipsec_widget"] = array();
209
        }
210
        if (isset($_POST["newdefaulttab6"])) {
211
                $user_settings["widgets"]["ipsec_widget"]["newdefaulttab6"] = $_POST["newdefaulttab6"];
212
        }
213
        save_widget_settings($_SESSION['Username'], $user_settings["widgets"], gettext("Updated gateways widget settings via dashboard."));
214
        header("Location: /");
215
        exit(0);
216
}
217
$NewDefaultTab = $user_settings["widgets"]["ipsec_widget"]["newdefaulttab6"];
218
$TunnelDefault = false;
219
$OverviewDefault = false;
220
$MobileDefault = false;
221
$TunnelDisplay ="none";
222
$OverviewDisplay ="none";
223
$MobileDisplay ="none";
224

    
225
switch($NewDefaultTab) {
226
	case "Overview" :
227
		$OverviewDefault = true;
228
		$OverviewDisplay = "block";
229
	break;
230
	case "tunnel" :
231
		$TunnelDefault = true;
232
		$TunnelDisplay = "block";
233
	break;
234
	case "mobile" :
235
		$MobileDefault = true;
236
		$MobileDisplay = "block";
237
	break;
238
}
239

    
240
if (isset($config['ipsec']['phase1'])) {
241
	$tab_array = array();
242
	$tab_array[] = array(gettext("Overview"), $OverviewDefault, "ipsec-Overview");
243
	$tab_array[] = array(gettext("Tunnels"), $TunnelDefault, "ipsec-tunnel");
244
	$tab_array[] = array(gettext("Mobile"), $MobileDefault, "ipsec-mobile");
245

    
246
	display_widget_tabs($tab_array);
247
}
248

    
249
$mobile = ipsec_dump_mobile();
250
$widgetperiod = isset($config['widgets']['period']) ? $config['widgets']['period'] * 1000 : 10000;
251

    
252
if (isset($config['ipsec']['phase2'])): ?>
253
<div id="ipsec-Overview" style="display:<?=$OverviewDisplay;?>;"  class="table-responsive">
254
	<table class="table table-striped table-hover">
255
		<thead>
256
		<tr>
257
			<th><?=gettext("Active Tunnels")?></th>
258
			<th><?=gettext("Inactive Tunnels")?></th>
259
			<th><?=gettext("Mobile Users")?></th>
260
		</tr>
261
		</thead>
262
		<tbody>
263
			<tr><td colspan="3"><?=gettext("Retrieving overview data ")?><i class="fa fa-cog fa-spin"></i></td></tr>
264
		</tbody>
265
	</table>
266
</div>
267
<div class="table-responsive" id="ipsec-tunnel" style="display:<?=$TunnelDisplay;?>;">
268
	<table class="table table-striped table-hover">
269
	<thead>
270
	<tr>
271
		<th><?=gettext("Source")?></th>
272
		<th><?=gettext("Destination")?></th>
273
		<th><?=gettext("Description")?></th>
274
		<th><?=gettext("Status")?></th>
275
	</tr>
276
	</thead>
277
	<tbody>
278
		<tr><td colspan="4"><?=gettext("Retrieving tunnel data ")?><i class="fa fa-cog fa-spin"></i></td></tr>
279
	</tbody>
280
	</table>
281
</div>
282

    
283
	<?php if (is_array($mobile['pool'])): ?>
284
<div id="ipsec-mobile" style="display:<?=$MobileDisplay;?>;" class="table-responsive">
285
		<table class="table table-striped table-hover">
286
		<thead>
287
		<tr>
288
			<th><?=gettext("User")?></th>
289
			<th><?=gettext("IP")?></th>
290
			<th><?=gettext("Status")?></th>
291
		</tr>
292
		</thead>
293
		<tbody>
294
			<tr><td colspan="3"><?=gettext("Retrieving mobile data ")?><i class="fa fa-cog fa-spin"></i></td></tr>
295
		</tbody>
296
		</table>
297
	</div>
298
	<?php endif;?>
299
<?php else: ?>
300
	<div>
301
		<h5 style="padding-left:10px;"><?=gettext("There are no configured IPsec Tunnels")?></h5>
302
		<p  style="padding-left:10px;"><?=gettext('IPsec can be configured <a href="vpn_ipsec.php">here</a>.')?></p>
303
	</div>
304
<?php endif;
305

    
306
// This function was in index.php It seems that the ipsec widget is the only place it is used
307
// so now it lives here. It wouldn't hurt to update this function and the tab display, but it
308
// looks OK for now. The display_widget_tabs() function in guiconfig.inc would need to be updated to match
309
?>
310
<div id="widget-<?=$widgetname?>_panel-footer" class="panel-footer collapse">
311
<input type="hidden" id="ipsec-config" name="ipsec-config" value="" />
312
<div id="ipsec-settings" class="widgetconfigdiv" >
313
  <form action="/widgets/widgets/ipsec.widget.php" method="post" name="ipsec_widget_iform" id="ipsec_widget_iform">
314
                Display:
315

    
316
                                <select class="form-control" id="newdefaulttab6" name="newdefaulttab6">
317
                                <?php
318
                                        if($user_settings["widgets"]["ipsec_widget"]["newdefaulttab6"] === "Overview") {
319
                                                echo '<option value="Overview" selected>Overview</option>';
320
                                                echo '<option value="tunnel">tunnel</option>';
321
                                                echo '<option value="mobile">mobile</option>';
322
                                         } elseif ($user_settings["widgets"]["ipsec_widget"]["newdefaulttab6"] === "tunnel") {
323
                                                echo '<option value="Overview">Overview</option>';
324
                                                echo '<option value="tunnel" selected>tunnel</option>';
325
                                                echo '<option value="mobile">mobile</option>';
326
                                        } else {
327
                                                echo '<option value="Overview">Overview</option>';
328
                                                echo '<option value="tunnel">tunnel</option>';
329
                                                echo '<option value="mobile" selected>mobile</option>';
330
                                        }
331
                                ?>
332
                                </select>
333
                      
334

    
335
		<button id="submit_settings" name="submit_settings" type="submit" onclick="return updatePref();" class="btn btn-primary btn-sm" value="<?=gettext('Save Settings')?>">
336
                        <i class="fa fa-save icon-embed-btn"></i>
337
                        <?=gettext('Save Settings')?>
338
                </button>
339

    
340

    
341
</form>
342
</div>
343
</div>
344

    
345
<script type="text/javascript">
346
//<![CDATA[
347
var els = document.querySelectorAll("a[href='#widget-ipsec_panel-footer']");
348
        for (var i = 0, l = els.length; i < l; i++) {
349
  					var el = els[i];
350
  					el.className = el.className.replace("hidden", "").trim()
351
			}
352
        
353
curtab = "<?=$NewDefaultTab;?>";
354
function changeTabDIV(selectedDiv) {
355
	var dashpos = selectedDiv.indexOf("-");
356
	var tabclass = selectedDiv.substring(0, dashpos);
357
	curtab = selectedDiv.substring(dashpos+1, 20);
358
	d = document;
359

    
360
	//get deactive tabs first
361
	tabclass = tabclass + "-class-tabdeactive";
362

    
363
	var tabs = document.getElementsByClassName(tabclass);
364
	var incTabSelected = selectedDiv + "-deactive";
365

    
366
	for (i = 0; i < tabs.length; i++) {
367
		var tab = tabs[i].id;
368
		dashpos = tab.lastIndexOf("-");
369
		var tab2 = tab.substring(0, dashpos) + "-deactive";
370

    
371
		if (tab2 == incTabSelected) {
372
			tablink = d.getElementById(tab2);
373
			tablink.style.display = "none";
374
			tab2 = tab.substring(0, dashpos) + "-active";
375
			tablink = d.getElementById(tab2);
376
			tablink.style.display = "table-cell";
377

    
378
			//now show main div associated with link clicked
379
			tabmain = d.getElementById(selectedDiv);
380
			tabmain.style.display = "block";
381
		} else {
382
			tab2 = tab.substring(0, dashpos) + "-deactive";
383
			tablink = d.getElementById(tab2);
384
			tablink.style.display = "table-cell";
385
			tab2 = tab.substring(0, dashpos) + "-active";
386
			tablink = d.getElementById(tab2);
387
			tablink.style.display = "none";
388

    
389
			//hide sections we don't want to see
390
			tab2 = tab.substring(0, dashpos);
391
			tabmain = d.getElementById(tab2);
392
			tabmain.style.display = "none";
393
		}
394
	}
395
}
396
function get_ipsec_stats() {
397
	var ajaxRequest;
398

    
399
	ajaxRequest = $.ajax({
400
			url: "/widgets/widgets/ipsec.widget.php",
401
			type: "post",
402
			data: {
403
					ajax: "ajax",
404
					tab:  curtab
405
				  }
406
		});
407

    
408
	// Deal with the results of the above ajax call
409
	ajaxRequest.done(function (response, textStatus, jqXHR) {
410

    
411
		$('tbody', '#ipsec-' + curtab).html(response);
412

    
413
		// and do it again
414
		setTimeout(get_ipsec_stats, "<?=$widgetperiod?>");
415
	});
416
}
417
events.push(function(){
418
	// Start polling for updates some small random number of seconds from now (so that all the widgets don't
419
	// hit the server at exactly the same time)
420
	setTimeout(get_ipsec_stats, Math.floor((Math.random() * 10000) + 1000));
421
});
422
//]]>
423
</script>
424

    
(2-2/2)