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

$nocsrf = true;

require_once("guiconfig.inc");
require_once("functions.inc");
require_once("ipsec.inc");

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

	if (isset($config['ipsec']['phase1'])) {
		$spd = ipsec_dump_spd();
		$sad = ipsec_dump_sad();
		$mobile = ipsec_dump_mobile();
		$ipsec_status = ipsec_list_sa();

		$activecounter = 0;
		$inactivecounter = 0;

		$ipsec_detail_array = array();
		$ikenum = array();
		if (isset($config['ipsec']['phase2'])) {
			foreach ($config['ipsec']['phase2'] as $ph2ent) {
				if (!ipsec_lookup_phase1($ph2ent,$ph1ent)) {
					continue;
				}

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

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

				if (empty($ph1ent['iketype']) || $ph1ent['iketype'] == 'ikev1') {
					if (!isset($ikenum[$ph1ent['ikeid']])) {
						$ikenum[$ph1ent['ikeid']] = 0;
					} else {
						$ikenum[$ph1ent['ikeid']]++;
					}

					$ikeid = "con{$ph1ent['ikeid']}00" . $ikenum[$ph1ent['ikeid']];
				} else {
					if (isset($ikenum[$ph1ent['ikeid']])) {
						continue;
					}

					$ikeid = "con{$ph1ent['ikeid']}";
					$ikenum[$ph1ent['ikeid']] = true;
				}

				$found = false;
				foreach ($ipsec_status as $id => $ikesa) {
					if (isset($ikesa['child-sas'])) {
						foreach ($ikesa['child-sas'] as $childid => $childsa) {
							if ($ikeid == $childid) {
								$found = true;
								break;
							}
						}
					} else if ($ikeid == $id) {
						$found = true;
					}

					if ($found === true) {
						if ($ikesa['state'] == 'ESTABLISHED') {
							/* tunnel is up */
							$iconfn = "true";
							$activecounter++;
						} else {
							/* tunnel is down */
							$iconfn = "false";
							$inactivecounter++;
						}
						break;
					}
				}

				if ($found === false) {
					/* tunnel is down */
					$iconfn = "false";
					$inactivecounter++;
				}

				$ipsec_detail_array[] = array('src' => convert_friendly_interface_to_friendly_descr($ph1ent['interface']),
						'dest' => $ph1ent['remote-gateway'],
						'remote-subnet' => ipsec_idinfo_to_text($ph2ent['remoteid']),
						'descr' => $ph2ent['descr'],
						'status' => $iconfn);
			}
		}
		unset($ikenum);
	}

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

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

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

				print(	"</tr>\n");
			}
		break;

		case "mobile" :
			if (!is_array($mobile['pool'])) {
				break;
			}
			foreach ($mobile['pool'] as $pool) {
				if (!is_array($pool['lease'])) {
					continue;
				}

				foreach ($pool['lease'] as $muser) {
					print("	<tr>\n");
					print(		"<td>" . htmlspecialchars($muser['id']) . "</td>\n");
					print(		"<td>" . htmlspecialchars($muser['host']) . "</td>\n");
					print(		"<td>" . htmlspecialchars($muser['status']) . "</td>\n");
					print("	</tr>\n");
				}
			}
		break;
	}

	exit;
}

if ($_POST) {

        if (!is_array($user_settings["widgets"]["ipsec_widget"])) {
                $user_settings["widgets"]["ipsec_widget"] = array();
        }
        if (isset($_POST["newdefaulttab6"])) {
                $user_settings["widgets"]["ipsec_widget"]["newdefaulttab6"] = $_POST["newdefaulttab6"];
        }
        save_widget_settings($_SESSION['Username'], $user_settings["widgets"], gettext("Updated gateways widget settings via dashboard."));
        header("Location: /");
        exit(0);
}
$NewDefaultTab = $user_settings["widgets"]["ipsec_widget"]["newdefaulttab6"];
$TunnelDefault = false;
$OverviewDefault = false;
$MobileDefault = false;
$TunnelDisplay ="none";
$OverviewDisplay ="none";
$MobileDisplay ="none";

switch($NewDefaultTab) {
	case "Overview" :
		$OverviewDefault = true;
		$OverviewDisplay = "block";
	break;
	case "tunnel" :
		$TunnelDefault = true;
		$TunnelDisplay = "block";
	break;
	case "mobile" :
		$MobileDefault = true;
		$MobileDisplay = "block";
	break;
}

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

	display_widget_tabs($tab_array);
}

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

if (isset($config['ipsec']['phase2'])): ?>
<div id="ipsec-Overview" style="display:<?=$OverviewDisplay;?>;"  class="table-responsive">
	<table class="table table-striped table-hover">
		<thead>
		<tr>
			<th><?=gettext("Active Tunnels")?></th>
			<th><?=gettext("Inactive Tunnels")?></th>
			<th><?=gettext("Mobile Users")?></th>
		</tr>
		</thead>
		<tbody>
			<tr><td colspan="3"><?=gettext("Retrieving overview data ")?><i class="fa fa-cog fa-spin"></i></td></tr>
		</tbody>
	</table>
</div>
<div class="table-responsive" id="ipsec-tunnel" style="display:<?=$TunnelDisplay;?>;">
	<table class="table table-striped table-hover">
	<thead>
	<tr>
		<th><?=gettext("Source")?></th>
		<th><?=gettext("Destination")?></th>
		<th><?=gettext("Description")?></th>
		<th><?=gettext("Status")?></th>
	</tr>
	</thead>
	<tbody>
		<tr><td colspan="4"><?=gettext("Retrieving tunnel data ")?><i class="fa fa-cog fa-spin"></i></td></tr>
	</tbody>
	</table>
</div>

	<?php if (is_array($mobile['pool'])): ?>
<div id="ipsec-mobile" style="display:<?=$MobileDisplay;?>;" class="table-responsive">
		<table class="table table-striped table-hover">
		<thead>
		<tr>
			<th><?=gettext("User")?></th>
			<th><?=gettext("IP")?></th>
			<th><?=gettext("Status")?></th>
		</tr>
		</thead>
		<tbody>
			<tr><td colspan="3"><?=gettext("Retrieving mobile data ")?><i class="fa fa-cog fa-spin"></i></td></tr>
		</tbody>
		</table>
	</div>
	<?php endif;?>
<?php else: ?>
	<div>
		<h5 style="padding-left:10px;"><?=gettext("There are no configured IPsec Tunnels")?></h5>
		<p  style="padding-left:10px;"><?=gettext('IPsec can be configured <a href="vpn_ipsec.php">here</a>.')?></p>
	</div>
<?php endif;

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

                                <select class="form-control" id="newdefaulttab6" name="newdefaulttab6">
                                <?php
                                        if($user_settings["widgets"]["ipsec_widget"]["newdefaulttab6"] === "Overview") {
                                                echo '<option value="Overview" selected>Overview</option>';
                                                echo '<option value="tunnel">tunnel</option>';
                                                echo '<option value="mobile">mobile</option>';
                                         } elseif ($user_settings["widgets"]["ipsec_widget"]["newdefaulttab6"] === "tunnel") {
                                                echo '<option value="Overview">Overview</option>';
                                                echo '<option value="tunnel" selected>tunnel</option>';
                                                echo '<option value="mobile">mobile</option>';
                                        } else {
                                                echo '<option value="Overview">Overview</option>';
                                                echo '<option value="tunnel">tunnel</option>';
                                                echo '<option value="mobile" selected>mobile</option>';
                                        }
                                ?>
                                </select>
                      

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


</form>
</div>
</div>

<script type="text/javascript">
//<![CDATA[
var els = document.querySelectorAll("a[href='#widget-ipsec_panel-footer']");
        for (var i = 0, l = els.length; i < l; i++) {
  					var el = els[i];
  					el.className = el.className.replace("hidden", "").trim()
			}
        
curtab = "<?=$NewDefaultTab;?>";
function changeTabDIV(selectedDiv) {
	var dashpos = selectedDiv.indexOf("-");
	var tabclass = selectedDiv.substring(0, dashpos);
	curtab = selectedDiv.substring(dashpos+1, 20);
	d = document;

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

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

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

		if (tab2 == incTabSelected) {
			tablink = d.getElementById(tab2);
			tablink.style.display = "none";
			tab2 = tab.substring(0, dashpos) + "-active";
			tablink = d.getElementById(tab2);
			tablink.style.display = "table-cell";

			//now show main div associated with link clicked
			tabmain = d.getElementById(selectedDiv);
			tabmain.style.display = "block";
		} else {
			tab2 = tab.substring(0, dashpos) + "-deactive";
			tablink = d.getElementById(tab2);
			tablink.style.display = "table-cell";
			tab2 = tab.substring(0, dashpos) + "-active";
			tablink = d.getElementById(tab2);
			tablink.style.display = "none";

			//hide sections we don't want to see
			tab2 = tab.substring(0, dashpos);
			tabmain = d.getElementById(tab2);
			tabmain.style.display = "none";
		}
	}
}
function get_ipsec_stats() {
	var ajaxRequest;

	ajaxRequest = $.ajax({
			url: "/widgets/widgets/ipsec.widget.php",
			type: "post",
			data: {
					ajax: "ajax",
					tab:  curtab
				  }
		});

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

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

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

