commit c650b2f74932b2e7042c2d0c4e47a254918463bc
Author: Ermal <eri@pfsense.org>
Date:   Mon Aug 18 21:18:10 2014 +0200

    Allow HASH algorithms to be empty for phase2 in case the encryption one is AES-GCM

diff --git a/etc/inc/vpn.inc b/etc/inc/vpn.inc
index 0b0335409..7839c8b0b 100644
--- a/etc/inc/vpn.inc
+++ b/etc/inc/vpn.inc
@@ -693,7 +693,7 @@ EOD;
 						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
 
 					if ($ph2ent['protocol'] == 'esp') {
-						if (is_array($ph2ent['encryption-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
+						if (is_array($ph2ent['encryption-algorithm-option'])) {
 							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
 								$ealg_id = $ealg['name'];
 								$ealg_kl = $ealg['keylen'];
@@ -709,9 +709,17 @@ EOD;
 									 * seconds wrecking bootup */
 									if ($key_hi != 0 and $key_lo !=0 and $key_step !=0) {
 										for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
-											foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
-												$halgo = str_replace('hmac_', '', $halgo);
-												$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
+											if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
+												foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
+													$halgo = str_replace('hmac_', '', $halgo);
+													$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
+													$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
+													if (!empty($modp))
+														$tmpealgo .= "-{$modp}";
+													$ealgoESPsp2arr[] = $tmpealgo;
+												}
+											} else {
+												$tmpealgo = "{$ealg_id}{$keylen}";
 												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
 												if (!empty($modp))
 													$tmpealgo .= "-{$modp}";
@@ -720,9 +728,17 @@ EOD;
 										}
 									}
 								} else {
-									foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
-										$halgo = str_replace('hmac_', '', $halgo);
-										$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
+									if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
+										foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
+											$halgo = str_replace('hmac_', '', $halgo);
+											$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
+											$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
+											if (!empty($modp))
+												$tmpealgo .= "-{$modp}";
+											$ealgoESPsp2arr[] = $tmpealgo;
+										}
+									} else {
+										$tmpealgo = "{$ealg_id}{$ealg_kl}";
 										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
 										if (!empty($modp))
 											$tmpealgo .= "-{$modp}";
@@ -732,7 +748,7 @@ EOD;
 							}
 						}
 					} else if ($ph2ent['protocol'] == 'ah') {
-						if (is_array($ph2ent['hash-algorithm-option'])) {
+						if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
 							$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
 							foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
 								$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
@@ -784,8 +800,10 @@ EOD;
 					$ipsecconf .= "\t{$ealgosp1}\n";
 				if (!empty($ealgoAHsp2arr))
 					$ipsecconf .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
-				if (!empty($ealgoESPsp2arr))
+				if (!empty($ealgoESPsp2arr)) {
+					file_put_contents("/var/etc/ipsec/dump_test", print_r($ealgoESPsp2arr, true));
 					$ipsecconf .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
+				}
 				if (!empty($authentication))
 					$ipsecconf .= "\t{$authentication}\n";
 				if (!empty($peerid_spec))
diff --git a/usr/local/www/vpn_ipsec_phase2.php b/usr/local/www/vpn_ipsec_phase2.php
index 8a7806516..370416ea3 100644
--- a/usr/local/www/vpn_ipsec_phase2.php
+++ b/usr/local/www/vpn_ipsec_phase2.php
@@ -127,8 +127,8 @@ if ($_POST) {
 		$input_errors[] = gettext("A valid ikeid must be specified.");
 
 	/* input validation */
-	$reqdfields = explode(" ", "localid_type halgos uniqid");
-	$reqdfieldsn = array(gettext("Local network type"),gettext("P2 Hash Algorithms"), gettext("Unique Identifier"));
+	$reqdfields = explode(" ", "localid_type uniqid");
+	$reqdfieldsn = array(gettext("Local network type"), gettext("Unique Identifier"));
 	if (!isset($pconfig['mobile'])){
 		$reqdfields[] = "remoteid_type";
 		$reqdfieldsn[] = gettext("Remote network type");
@@ -254,7 +254,17 @@ if ($_POST) {
 
 		if (!count($ealgos)) {
 			$input_errors[] = gettext("At least one encryption algorithm must be selected.");
+		} else {
+			if (empty($pconfig['halgo'])) {
+				foreach ($ealgos as $ealgo) {
+					if (!strpos($ealgo['name'], "gcm")) {
+						$input_errors[] = gettext("At least one hashing algorithm needs to be selected.");
+						break;
+					}
+				}
+			}
 		}
+		
 	}
 	if (($_POST['lifetime'] && !is_numeric($_POST['lifetime']))) {
 		$input_errors[] = gettext("The P2 lifetime must be an integer.");
@@ -277,7 +287,10 @@ if ($_POST) {
 
 		$ph2ent['protocol'] = $pconfig['proto'];
 		$ph2ent['encryption-algorithm-option'] = $ealgos;
-		$ph2ent['hash-algorithm-option'] = $pconfig['halgos'];
+		if (!empty($pconfig['halgos']))
+			$ph2ent['hash-algorithm-option'] = $pconfig['halgos'];
+		else
+			unset($ph2ent['hash-algorithm-option']);
 		$ph2ent['pfsgroup'] = $pconfig['pfsgroup'];
 		$ph2ent['lifetime'] = $pconfig['lifetime'];
 		$ph2ent['pinghost'] = $pconfig['pinghost'];
