Revision 82bcf46c
Added by Steve Beaver over 4 years ago
src/usr/local/www/head.inc | ||
---|---|---|
347 | 347 |
$vpn_menu[] = array(gettext("OpenVPN"), "/vpn_openvpn_server.php"); |
348 | 348 |
//$vpn_menu[] = array(gettext("PPTP"), "/vpn_pptp.php"); |
349 | 349 |
$vpn_menu[] = array(gettext("L2TP"), "/vpn_l2tp.php"); |
350 |
$vpn_menu[] = array(gettext("Wireguard"), "/vpn_wg.php"); |
|
350 | 351 |
$vpn_menu = msort(array_merge($vpn_menu, return_ext_menu("VPN")), 0); |
351 | 352 |
|
352 | 353 |
// Status |
src/usr/local/www/vpn_wg.php | ||
---|---|---|
1 |
<?php |
|
2 |
/* |
|
3 |
* vpn_ipsec.php |
|
4 |
* |
|
5 |
* part of pfSense (https://www.pfsense.org) |
|
6 |
* Copyright (c) 2004-2013 BSD Perimeter |
|
7 |
* Copyright (c) 2013-2016 Electric Sheep Fencing |
|
8 |
* Copyright (c) 2014-2020 Rubicon Communications, LLC (Netgate) |
|
9 |
* All rights reserved. |
|
10 |
* |
|
11 |
* originally based on m0n0wall (http://m0n0.ch/wall) |
|
12 |
* Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>. |
|
13 |
* All rights reserved. |
|
14 |
* |
|
15 |
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
16 |
* you may not use this file except in compliance with the License. |
|
17 |
* You may obtain a copy of the License at |
|
18 |
* |
|
19 |
* http://www.apache.org/licenses/LICENSE-2.0 |
|
20 |
* |
|
21 |
* Unless required by applicable law or agreed to in writing, software |
|
22 |
* distributed under the License is distributed on an "AS IS" BASIS, |
|
23 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
24 |
* See the License for the specific language governing permissions and |
|
25 |
* limitations under the License. |
|
26 |
*/ |
|
27 |
|
|
28 |
##|+PRIV |
|
29 |
##|*IDENT=page-vpn-ipsec |
|
30 |
##|*NAME=VPN: IPsec |
|
31 |
##|*DESCR=Allow access to the 'VPN: IPsec' page. |
|
32 |
##|*MATCH=vpn_ipsec.php* |
|
33 |
##|-PRIV |
|
34 |
|
|
35 |
require_once("guiconfig.inc"); |
|
36 |
require_once("functions.inc"); |
|
37 |
require_once("filter.inc"); |
|
38 |
require_once("shaper.inc"); |
|
39 |
require_once("ipsec.inc"); |
|
40 |
require_once("vpn.inc"); |
|
41 |
|
|
42 |
init_config_arr(array('ipsec', 'phase1')); |
|
43 |
init_config_arr(array('ipsec', 'phase2')); |
|
44 |
$a_phase1 = &$config['ipsec']['phase1']; |
|
45 |
$a_phase2 = &$config['ipsec']['phase2']; |
|
46 |
|
|
47 |
|
|
48 |
if ($_POST['apply']) { |
|
49 |
$ipsec_dynamic_hosts = ipsec_configure(); |
|
50 |
ipsec_reload_package_hook(); |
|
51 |
/* reload the filter in the background */ |
|
52 |
$retval = 0; |
|
53 |
$retval |= filter_configure(); |
|
54 |
if ($ipsec_dynamic_hosts >= 0) { |
|
55 |
if (is_subsystem_dirty('ipsec')) { |
|
56 |
clear_subsystem_dirty('ipsec'); |
|
57 |
} |
|
58 |
} |
|
59 |
} else if (isset($_POST['del'])) { |
|
60 |
/* delete selected p1 entries */ |
|
61 |
if (is_array($_POST['p1entry']) && count($_POST['p1entry'])) { |
|
62 |
foreach ($_POST['p1entry'] as $p1entrydel) { |
|
63 |
unset($a_phase1[$p1entrydel]); |
|
64 |
} |
|
65 |
if (write_config(gettext("Deleted selected IPsec Phase 1 entries."))) { |
|
66 |
mark_subsystem_dirty('ipsec'); |
|
67 |
} |
|
68 |
} |
|
69 |
} else if (isset($_POST['delp2'])) { |
|
70 |
/* delete selected p2 entries */ |
|
71 |
if (is_array($_POST['p2entry']) && count($_POST['p2entry'])) { |
|
72 |
foreach ($_POST['p2entry'] as $p2entrydel) { |
|
73 |
if (is_interface_ipsec_vti_assigned($a_phase2[$p2entrydel]) && ($a_phase2[$p2entrydel]['mode'] == 'vti')) { |
|
74 |
$input_errors[] = gettext("Cannot delete a VTI Phase 2 while the interface is assigned. Remove the interface assignment before deleting this P2."); |
|
75 |
} else { |
|
76 |
ipsec_del_vtimap($a_phase2[$p2entrydel]); |
|
77 |
unset($a_phase2[$p2entrydel]); |
|
78 |
} |
|
79 |
} |
|
80 |
if (write_config(gettext("Deleted selected IPsec Phase 2 entries."))) { |
|
81 |
mark_subsystem_dirty('ipsec'); |
|
82 |
} |
|
83 |
} |
|
84 |
} else { |
|
85 |
/* yuck - IE won't send value attributes for image buttons, while Mozilla does - so we use .x/.y to find move button clicks instead... */ |
|
86 |
|
|
87 |
// TODO: this. is. nasty. |
|
88 |
unset($delbtn, $delbtnp2, $movebtn, $movebtnp2, $togglebtn, $togglebtnp2); |
|
89 |
foreach ($_POST as $pn => $pd) { |
|
90 |
if (preg_match("/del_(\d+)/", $pn, $matches)) { |
|
91 |
$delbtn = $matches[1]; |
|
92 |
} else if (preg_match("/delp2_(\d+)/", $pn, $matches)) { |
|
93 |
$delbtnp2 = $matches[1]; |
|
94 |
} else if (preg_match("/move_(\d+)/", $pn, $matches)) { |
|
95 |
$movebtn = $matches[1]; |
|
96 |
} else if (preg_match("/movep2_(\d+)/", $pn, $matches)) { |
|
97 |
$movebtnp2 = $matches[1]; |
|
98 |
} else if (preg_match("/toggle_(\d+)/", $pn, $matches)) { |
|
99 |
$togglebtn = $matches[1]; |
|
100 |
} else if (preg_match("/togglep2_(\d+)/", $pn, $matches)) { |
|
101 |
$togglebtnp2 = $matches[1]; |
|
102 |
} |
|
103 |
} |
|
104 |
|
|
105 |
$save = 1; |
|
106 |
|
|
107 |
/* move selected p1 entries before this */ |
|
108 |
if (isset($movebtn) && is_array($_POST['p1entry']) && count($_POST['p1entry'])) { |
|
109 |
$a_phase1_new = array(); |
|
110 |
|
|
111 |
/* copy all p1 entries < $movebtn and not selected */ |
|
112 |
for ($i = 0; $i < $movebtn; $i++) { |
|
113 |
if (!in_array($i, $_POST['p1entry'])) { |
|
114 |
$a_phase1_new[] = $a_phase1[$i]; |
|
115 |
} |
|
116 |
} |
|
117 |
|
|
118 |
/* copy all selected p1 entries */ |
|
119 |
for ($i = 0; $i < count($a_phase1); $i++) { |
|
120 |
if ($i == $movebtn) { |
|
121 |
continue; |
|
122 |
} |
|
123 |
if (in_array($i, $_POST['p1entry'])) { |
|
124 |
$a_phase1_new[] = $a_phase1[$i]; |
|
125 |
} |
|
126 |
} |
|
127 |
|
|
128 |
/* copy $movebtn p1 entry */ |
|
129 |
if ($movebtn < count($a_phase1)) { |
|
130 |
$a_phase1_new[] = $a_phase1[$movebtn]; |
|
131 |
} |
|
132 |
|
|
133 |
/* copy all p1 entries > $movebtn and not selected */ |
|
134 |
for ($i = $movebtn+1; $i < count($a_phase1); $i++) { |
|
135 |
if (!in_array($i, $_POST['p1entry'])) { |
|
136 |
$a_phase1_new[] = $a_phase1[$i]; |
|
137 |
} |
|
138 |
} |
|
139 |
if (count($a_phase1_new) > 0) { |
|
140 |
$a_phase1 = $a_phase1_new; |
|
141 |
} |
|
142 |
|
|
143 |
} else if (isset($movebtnp2) && is_array($_POST['p2entry']) && count($_POST['p2entry'])) { |
|
144 |
/* move selected p2 entries before this */ |
|
145 |
$a_phase2_new = array(); |
|
146 |
|
|
147 |
/* copy all p2 entries < $movebtnp2 and not selected */ |
|
148 |
for ($i = 0; $i < $movebtnp2; $i++) { |
|
149 |
if (!in_array($i, $_POST['p2entry'])) { |
|
150 |
$a_phase2_new[] = $a_phase2[$i]; |
|
151 |
} |
|
152 |
} |
|
153 |
|
|
154 |
/* copy all selected p2 entries */ |
|
155 |
for ($i = 0; $i < count($a_phase2); $i++) { |
|
156 |
if ($i == $movebtnp2) { |
|
157 |
continue; |
|
158 |
} |
|
159 |
if (in_array($i, $_POST['p2entry'])) { |
|
160 |
$a_phase2_new[] = $a_phase2[$i]; |
|
161 |
} |
|
162 |
} |
|
163 |
|
|
164 |
/* copy $movebtnp2 p2 entry */ |
|
165 |
if ($movebtnp2 < count($a_phase2)) { |
|
166 |
$a_phase2_new[] = $a_phase2[$movebtnp2]; |
|
167 |
} |
|
168 |
|
|
169 |
/* copy all p2 entries > $movebtnp2 and not selected */ |
|
170 |
for ($i = $movebtnp2+1; $i < count($a_phase2); $i++) { |
|
171 |
if (!in_array($i, $_POST['p2entry'])) { |
|
172 |
$a_phase2_new[] = $a_phase2[$i]; |
|
173 |
} |
|
174 |
} |
|
175 |
if (count($a_phase2_new) > 0) { |
|
176 |
$a_phase2 = $a_phase2_new; |
|
177 |
} |
|
178 |
|
|
179 |
} else if (isset($togglebtn)) { |
|
180 |
if (isset($a_phase1[$togglebtn]['disabled'])) { |
|
181 |
unset($a_phase1[$togglebtn]['disabled']); |
|
182 |
} else { |
|
183 |
if (ipsec_vti($a_phase1[$togglebtn], false, false)) { |
|
184 |
$input_errors[] = gettext("Cannot disable a Phase 1 with a child Phase 2 while the interface is assigned. Remove the interface assignment before disabling this P2."); |
|
185 |
} else { |
|
186 |
$a_phase1[$togglebtn]['disabled'] = true; |
|
187 |
} |
|
188 |
} |
|
189 |
} else if (isset($togglebtnp2)) { |
|
190 |
if (isset($a_phase2[$togglebtnp2]['disabled'])) { |
|
191 |
unset($a_phase2[$togglebtnp2]['disabled']); |
|
192 |
} else { |
|
193 |
if (is_interface_ipsec_vti_assigned($a_phase2[$togglebtnp2]) && ($a_phase2[$togglebtnp2]['mode'] == 'vti')) { |
|
194 |
$input_errors[] = gettext("Cannot disable a VTI Phase 2 while the interface is assigned. Remove the interface assignment before disabling this P2."); |
|
195 |
} else { |
|
196 |
$a_phase2[$togglebtnp2]['disabled'] = true; |
|
197 |
} |
|
198 |
} |
|
199 |
} else if (isset($delbtn)) { |
|
200 |
/* remove static route if interface is not WAN */ |
|
201 |
if ($a_phase1[$delbtn]['interface'] <> "wan") { |
|
202 |
route_del($a_phase1[$delbtn]['remote-gateway']); |
|
203 |
} |
|
204 |
|
|
205 |
/* remove all phase2 entries that match the ikeid */ |
|
206 |
$ikeid = $a_phase1[$delbtn]['ikeid']; |
|
207 |
$p1_has_vti = false; |
|
208 |
$delp2ids = array(); |
|
209 |
foreach ($a_phase2 as $p2index => $ph2tmp) { |
|
210 |
if ($ph2tmp['ikeid'] == $ikeid) { |
|
211 |
if (is_interface_ipsec_vti_assigned($ph2tmp)) { |
|
212 |
$p1_has_vti = true; |
|
213 |
} else { |
|
214 |
$delp2ids[] = $p2index; |
|
215 |
} |
|
216 |
} |
|
217 |
} |
|
218 |
|
|
219 |
if ($p1_has_vti) { |
|
220 |
$input_errors[] = gettext("Cannot delete a Phase 1 which contains an active VTI Phase 2 with an interface assigned. Remove the interface assignment before deleting this P1."); |
|
221 |
} else { |
|
222 |
foreach ($delp2ids as $dp2idx) { |
|
223 |
ipsec_del_vtimap($a_phase2[$dp2idx]); |
|
224 |
unset($a_phase2[$dp2idx]); |
|
225 |
} |
|
226 |
unset($a_phase1[$delbtn]); |
|
227 |
} |
|
228 |
|
|
229 |
} else if (isset($delbtnp2)) { |
|
230 |
if (is_interface_ipsec_vti_assigned($a_phase2[$delbtnp2]) && ($a_phase2[$delbtnp2]['mode'] == 'vti')) { |
|
231 |
$input_errors[] = gettext("Cannot delete a VTI Phase 2 while the interface is assigned. Remove the interface assignment before deleting this P2."); |
|
232 |
} else { |
|
233 |
ipsec_del_vtimap($a_phase2[$delbtnp2]); |
|
234 |
unset($a_phase2[$delbtnp2]); |
|
235 |
} |
|
236 |
} else { |
|
237 |
$save = 0; |
|
238 |
} |
|
239 |
|
|
240 |
if ($save === 1) { |
|
241 |
if (write_config(gettext("Saved configuration changes for IPsec tunnels."))) { |
|
242 |
mark_subsystem_dirty('ipsec'); |
|
243 |
} |
|
244 |
} |
|
245 |
} |
|
246 |
|
|
247 |
|
|
248 |
$pgtitle = array(gettext("VPN"), gettext("IPsec"), gettext("Tunnels")); |
|
249 |
$pglinks = array("", "@self", "@self"); |
|
250 |
$shortcut_section = "ipsec"; |
|
251 |
|
|
252 |
include("head.inc"); |
|
253 |
|
|
254 |
if ($input_errors) { |
|
255 |
print_input_errors($input_errors); |
|
256 |
} |
|
257 |
|
|
258 |
$tab_array = array(); |
|
259 |
$tab_array[] = array(gettext("Tunnels"), true, "vpn_ipsec.php"); |
|
260 |
$tab_array[] = array(gettext("Mobile Clients"), false, "vpn_ipsec_mobile.php"); |
|
261 |
$tab_array[] = array(gettext("Pre-Shared Keys"), false, "vpn_ipsec_keys.php"); |
|
262 |
$tab_array[] = array(gettext("Advanced Settings"), false, "vpn_ipsec_settings.php"); |
|
263 |
display_top_tabs($tab_array); |
|
264 |
|
|
265 |
if ($_POST['apply']) { |
|
266 |
print_apply_result_box($retval); |
|
267 |
} |
|
268 |
|
|
269 |
if (is_subsystem_dirty('ipsec')) { |
|
270 |
print_apply_box(gettext("The IPsec tunnel configuration has been changed.") . "<br />" . gettext("The changes must be applied for them to take effect.")); |
|
271 |
} |
|
272 |
?> |
|
273 |
|
|
274 |
<form name="mainform" method="post"> |
|
275 |
<div class="panel panel-default"> |
|
276 |
<div class="panel-heading"><h2 class="panel-title"><?=gettext('IPsec Tunnels')?></h2></div> |
|
277 |
<div class="panel-body table-responsive"> |
|
278 |
<table class="table table-striped table-hover"> |
|
279 |
<thead> |
|
280 |
<tr> |
|
281 |
<th> </th> |
|
282 |
<th> </th> |
|
283 |
<th><?=gettext("IKE")?></th> |
|
284 |
<th><?=gettext("Remote Gateway")?></th> |
|
285 |
<th><?=gettext("Mode")?></th> |
|
286 |
<th><?=gettext("P1 Protocol")?></th> |
|
287 |
<th><?=gettext("P1 Transforms")?></th> |
|
288 |
<th><?=gettext("P1 DH-Group")?></th> |
|
289 |
<th><?=gettext("P1 Description")?></th> |
|
290 |
<th><?=gettext("Actions")?></th> |
|
291 |
</tr> |
|
292 |
</thead> |
|
293 |
<tbody class="p1-entries"> |
|
294 |
<?php |
|
295 |
$iflabels = get_configured_interface_with_descr(false, true); |
|
296 |
$viplist = get_configured_vip_list(); |
|
297 |
foreach ($viplist as $vip => $address) { |
|
298 |
$iflabels[$vip] = $address; |
|
299 |
if (get_vip_descr($address)) { |
|
300 |
$iflabels[$vip] .= " (". get_vip_descr($address) .")"; |
|
301 |
} |
|
302 |
} |
|
303 |
$grouplist = return_gateway_groups_array(); |
|
304 |
foreach ($grouplist as $name => $group) { |
|
305 |
if ($group[0]['vip'] != "") { |
|
306 |
$vipif = $group[0]['vip']; |
|
307 |
} else { |
|
308 |
$vipif = $group[0]['int']; |
|
309 |
} |
|
310 |
$iflabels[$name] = "GW Group {$name}"; |
|
311 |
} |
|
312 |
|
|
313 |
$i = 0; foreach ($a_phase1 as $ph1ent): |
|
314 |
|
|
315 |
$iconfn = "pass"; |
|
316 |
|
|
317 |
$entryStatus = (isset($ph1ent['disabled']) ? 'disabled' : 'enabled'); |
|
318 |
|
|
319 |
if ($entryStatus == 'disabled') { |
|
320 |
$iconfn .= "_d"; |
|
321 |
} |
|
322 |
?> |
|
323 |
<tr id="fr<?=$i?>" onclick="fr_toggle(<?=$i?>)" id="frd<?=$i?>" ondblclick="document.location='vpn_ipsec_phase1.php?p1index=<?=$i?>'" class="<?= $entryStatus ?>"> |
|
324 |
<td> |
|
325 |
<input type="checkbox" id="frc<?=$i?>" onclick="fr_toggle(<?=$i?>)" name="p1entry[]" value="<?=$i?>" /> |
|
326 |
<a class="fa fa-anchor icon-pointer" id="Xmove_<?=$i?>" title="<?=gettext("Move checked entries to here")?>"></a> |
|
327 |
</td> |
|
328 |
<td> |
|
329 |
<button value="toggle_<?=$i?>" name="toggle_<?=$i?>" title="<?=gettext("click to toggle enabled/disabled status")?>" class="btn btn-xs btn-<?= ($entryStatus == 'disabled' ? 'success' : 'warning') ?>" type="submit"><?= ($entryStatus == 'disabled' ? 'Enable' : 'Disable') ?></button> |
|
330 |
</td> |
|
331 |
<td id="frd<?=$i?>"> |
|
332 |
<?php |
|
333 |
if (empty($ph1ent['iketype']) || $ph1ent['iketype'] == "ikev1") { |
|
334 |
echo "V1"; |
|
335 |
} elseif ($ph1ent['iketype'] == "ikev2") { |
|
336 |
echo "V2"; |
|
337 |
} elseif ($ph1ent['iketype'] == "auto") { |
|
338 |
echo "Auto"; |
|
339 |
} |
|
340 |
?> |
|
341 |
</td> |
|
342 |
<td> |
|
343 |
<?php |
|
344 |
if ($ph1ent['interface']) { |
|
345 |
if (isset($iflabels[$ph1ent['interface']])) { |
|
346 |
$if = htmlspecialchars($iflabels[$ph1ent['interface']]); |
|
347 |
} else { |
|
348 |
$if = sprintf("Interface not found: '%s'", $ph1ent['interface']); |
|
349 |
} |
|
350 |
} else { |
|
351 |
$if = "WAN"; |
|
352 |
} |
|
353 |
|
|
354 |
if (!isset($ph1ent['mobile'])) { |
|
355 |
echo $if."<br />".$ph1ent['remote-gateway']; |
|
356 |
} else { |
|
357 |
echo $if."<br /><strong>" . gettext("Mobile Client") . "</strong>"; |
|
358 |
} |
|
359 |
?> |
|
360 |
</td> |
|
361 |
<td id="frd<?=$i?>"> |
|
362 |
<?=$spans?> |
|
363 |
<?php |
|
364 |
if (empty($ph1ent['iketype']) || $ph1ent['iketype'] == "ikev1" || $ph1ent['iketype'] == "auto") { |
|
365 |
echo "{$ph1ent['mode']}"; |
|
366 |
} |
|
367 |
?> |
|
368 |
<?=$spane?> |
|
369 |
</td> |
|
370 |
<td id="frd<?=$i?>"> |
|
371 |
<?php |
|
372 |
$first = true; |
|
373 |
if (is_array($ph1ent['encryption']['item'])) { |
|
374 |
foreach($ph1ent['encryption']['item'] as $p1algo) { |
|
375 |
if (!$first) { |
|
376 |
echo "<br/>"; |
|
377 |
} |
|
378 |
echo $p1_ealgos[$p1algo['encryption-algorithm']['name']]['name']; |
|
379 |
if ($p1algo['encryption-algorithm']['keylen']) { |
|
380 |
echo " ({$p1algo['encryption-algorithm']['keylen']} " . gettext("bits") . ")"; |
|
381 |
} |
|
382 |
$first = false; |
|
383 |
} |
|
384 |
} |
|
385 |
?> |
|
386 |
</td> |
|
387 |
<td> |
|
388 |
<?php $first = true; |
|
389 |
if (is_array($ph1ent['encryption']['item'])) { |
|
390 |
foreach($ph1ent['encryption']['item'] as $p1algo) { |
|
391 |
if (!$first) { |
|
392 |
echo "<br/>"; |
|
393 |
} |
|
394 |
echo $p1_halgos[$p1algo['hash-algorithm']]; |
|
395 |
if (isset($ph1ent['prfselect_enable'])) { |
|
396 |
echo " / PRF" . $p1_halgos[$p1algo['prf-algorithm']]; |
|
397 |
} |
|
398 |
$first = false; |
|
399 |
} |
|
400 |
} |
|
401 |
?> |
|
402 |
</td> |
|
403 |
<td> |
|
404 |
<?php $first = true; |
|
405 |
if (is_array($ph1ent['encryption']['item'])) { |
|
406 |
foreach($ph1ent['encryption']['item'] as $p1algo) { |
|
407 |
if (!$first) { |
|
408 |
echo "<br/>"; |
|
409 |
} |
|
410 |
echo str_replace(" "," ",$p1_dhgroups[$p1algo['dhgroup']]); |
|
411 |
$first = false; |
|
412 |
} |
|
413 |
} |
|
414 |
?> |
|
415 |
</td> |
|
416 |
<td> |
|
417 |
<?=htmlspecialchars($ph1ent['descr'])?> |
|
418 |
</td> |
|
419 |
<td style="cursor: pointer;"> |
|
420 |
<!-- <a class="fa fa-anchor" id="Xmove_<?=$i?>" title="<?=gettext("Move checked entries to here")?>"></a> --> |
|
421 |
<button style="display: none;" class="btn btn-default btn-xs" type="submit" id="move_<?=$i?>" name="move_<?=$i?>" value="move_<?=$i?>"><?=gettext("Move checked entries to here")?></button> |
|
422 |
<a class="fa fa-pencil" href="vpn_ipsec_phase1.php?p1index=<?=$i?>" title="<?=gettext("Edit phase1 entry"); ?>"></a> |
|
423 |
<?php if (!isset($ph1ent['mobile'])): ?> |
|
424 |
<a class="fa fa-clone" href="vpn_ipsec_phase1.php?dup=<?=$i?>" title="<?=gettext("Copy phase1 entry"); ?>"></a> |
|
425 |
<?php endif; ?> |
|
426 |
<a class="fa fa-trash no-confirm" id="Xdel_<?=$i?>" title="<?=gettext('Delete phase1 entry'); ?>"></a> |
|
427 |
<button style="display: none;" class="btn btn-xs btn-warning" type="submit" id="del_<?=$i?>" name="del_<?=$i?>" value="del_<?=$i?>" title="<?=gettext('Delete phase1 entry'); ?>">delete</button> |
|
428 |
|
|
429 |
</td> |
|
430 |
</tr> |
|
431 |
<tr class="<?= $entryStatus ?>"> |
|
432 |
<td colspan="2"></td> |
|
433 |
<td colspan="7" class="contains-table"> |
|
434 |
<?php |
|
435 |
if (isset($_REQUEST["tdph2-{$i}-visible"])) { |
|
436 |
$tdph2_visible = htmlspecialchars($_REQUEST["tdph2-{$i}-visible"]); |
|
437 |
} else { |
|
438 |
$tdph2_visible = 0; |
|
439 |
} |
|
440 |
?> |
|
441 |
<input type="hidden" name="tdph2-<?=$i?>-visible" id="tdph2-<?=$i?>-visible" value="<?=$tdph2_visible?>" /> |
|
442 |
<div id="shph2but-<?=$i?>" <?=($tdph2_visible == '1' ? 'style="display:none"' : '')?>> |
|
443 |
<?php |
|
444 |
$phase2count=0; |
|
445 |
|
|
446 |
foreach ($a_phase2 as $ph2ent) { |
|
447 |
if ($ph2ent['ikeid'] != $ph1ent['ikeid']) { |
|
448 |
continue; |
|
449 |
} |
|
450 |
$phase2count++; |
|
451 |
} |
|
452 |
$fr_prefix = "frp2{$i}"; |
|
453 |
$fr_header = $fr_prefix . "header"; |
|
454 |
?> |
|
455 |
<button class="btn btn-info" type="button" onclick="show_phase2('tdph2-<?=$i?>','shph2but-<?=$i?>')" value="+"><i class="fa fa-plus-circle"></i> <?php printf(gettext("Show Phase 2 Entries (%s)"), $phase2count); ?></button> |
|
456 |
</div> |
|
457 |
<div id="tdph2-<?=$i?>" <?=($tdph2_visible != '1' ? 'style="display:none"' : '')?>> |
|
458 |
<table class="table table-striped table-hover"> |
|
459 |
<thead> |
|
460 |
<tr> |
|
461 |
<th> </th> |
|
462 |
<th> </th> |
|
463 |
<th><?=gettext("Mode"); ?></th> |
|
464 |
<th><?=gettext("Local Subnet"); ?></th> |
|
465 |
<th><?=gettext("Remote Subnet"); ?></th> |
|
466 |
<th><?=gettext("P2 Protocol"); ?></th> |
|
467 |
<th><?=gettext("P2 Transforms"); ?></th> |
|
468 |
<th><?=gettext("P2 Auth Methods"); ?></th> |
|
469 |
<th><?=gettext("P2 actions")?></th> |
|
470 |
</tr> |
|
471 |
</thead> |
|
472 |
<tbody class="p2-entries"> |
|
473 |
<?php $j = 0; foreach ($a_phase2 as $ph2index => $ph2ent): ?> |
|
474 |
<?php |
|
475 |
if ($ph2ent['ikeid'] != $ph1ent['ikeid']) { |
|
476 |
continue; |
|
477 |
} |
|
478 |
|
|
479 |
$fr_c = $fr_prefix . "c" . $j; |
|
480 |
$fr_d = $fr_prefix . "d" . $j; |
|
481 |
|
|
482 |
$iconfn = "pass"; |
|
483 |
$entryStatus = (isset($ph2ent['disabled']) || isset($ph1ent['disabled']) ? 'disabled' : 'enabled'); |
|
484 |
|
|
485 |
if ($entryStatus == 'disabled') { |
|
486 |
$iconfn .= "_d"; |
|
487 |
} |
|
488 |
?> |
|
489 |
<tr id="<?=$fr_prefix . $j?>" ondblclick="document.location='vpn_ipsec_phase2.php?p2index=<?=$ph2ent['uniqid']?>'" class="<?= $entryStatus ?>"> |
|
490 |
<td> |
|
491 |
<input type="checkbox" id="<?=$fr_c?>" name="p2entry[]" value="<?=$ph2index?>" onclick="fr_bgcolor('<?=$j?>', '<?=$fr_prefix?>')" /> |
|
492 |
<button class="fa fa-anchor button-icon" type="submit" name="movep2_<?=$j?>" value="movep2_<?=$j?>" title="<?=gettext("Move checked P2s here")?>"></button> |
|
493 |
</td> |
|
494 |
<td> |
|
495 |
<button value="togglep2_<?=$ph2index?>" name="togglep2_<?=$ph2index?>" title="<?=gettext("click to toggle enabled/disabled status")?>" class="btn btn-xs btn-<?= ($entryStatus == 'disabled'? 'success' : 'warning') ?>" type="submit"><?= ($entryStatus == 'disabled'? 'Enable' : 'Disable') ?></button> |
|
496 |
</td> |
|
497 |
<td id="<?=$fr_d?>" onclick="fr_toggle('<?=$j?>', '<?=$fr_prefix?>')"> |
|
498 |
<?=$ph2ent['mode']?> |
|
499 |
</td> |
|
500 |
<?php if (($ph2ent['mode'] == "tunnel") or ($ph2ent['mode'] == "tunnel6") or ($ph2ent['mode'] == "vti")): ?> |
|
501 |
<td id="<?=$fr_d?>" onclick="fr_toggle('<?=$j?>', '<?=$fr_prefix?>')"> |
|
502 |
<?=ipsec_idinfo_to_text($ph2ent['localid']); ?> |
|
503 |
</td> |
|
504 |
<td id="<?=$fr_d?>" onclick="fr_toggle('<?=$j?>', '<?=$fr_prefix?>')"> |
|
505 |
<?=ipsec_idinfo_to_text($ph2ent['remoteid']); ?> |
|
506 |
</td> |
|
507 |
<?php else: ?> |
|
508 |
<td colspan="2"></td> |
|
509 |
<?php endif; ?> |
|
510 |
<td id="<?=$fr_d?>" onclick="fr_toggle('<?=$j?>', '<?=$fr_prefix?>')"> |
|
511 |
<?=$p2_protos[$ph2ent['protocol']]; ?> |
|
512 |
</td> |
|
513 |
<td id="<?=$fr_d?>" onclick="fr_toggle('<?=$j?>', '<?=$fr_prefix?>')"> |
|
514 |
<?php |
|
515 |
foreach ($ph2ent['encryption-algorithm-option'] as $k => $ph2ea) { |
|
516 |
if ($k) { |
|
517 |
echo ", "; |
|
518 |
} |
|
519 |
echo $p2_ealgos[$ph2ea['name']]['name']; |
|
520 |
if ($ph2ea['keylen']) { |
|
521 |
if ($ph2ea['keylen'] == "auto") { |
|
522 |
echo " (" . gettext("auto") . ")"; |
|
523 |
} else { |
|
524 |
echo " ({$ph2ea['keylen']} " . gettext("bits") . ")"; |
|
525 |
} |
|
526 |
} |
|
527 |
} |
|
528 |
?> |
|
529 |
</td> |
|
530 |
<td id="<?=$fr_d?>" onclick="fr_toggle('<?=$j?>', '<?=$fr_prefix?>')"> |
|
531 |
<?php |
|
532 |
if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) { |
|
533 |
foreach ($ph2ent['hash-algorithm-option'] as $k => $ph2ha) { |
|
534 |
if ($k) { |
|
535 |
echo ", "; |
|
536 |
} |
|
537 |
echo $p2_halgos[$ph2ha]; |
|
538 |
} |
|
539 |
} |
|
540 |
?> |
|
541 |
</td> |
|
542 |
<td style="cursor: pointer;"> |
|
543 |
<!-- <button class="fa fa-anchor button-icon" type="submit" name="movep2_<?=$j?>" value="movep2_<?=$j?>" title="<?=gettext("Move checked P2s here")?>"></button> --> |
|
544 |
<a class="fa fa-pencil" href="vpn_ipsec_phase2.php?p2index=<?=$ph2ent['uniqid']?>" title="<?=gettext("Edit phase2 entry"); ?>"></a> |
|
545 |
<a class="fa fa-clone" href="vpn_ipsec_phase2.php?dup=<?=$ph2ent['uniqid']?>" title="<?=gettext("Add a new Phase 2 based on this one"); ?>"></a> |
|
546 |
<a class="fa fa-trash no-confirm" id="Xdelp2_<?=$ph2index?>" title="<?=gettext('Delete phase2 entry'); ?>"></a> |
|
547 |
<button style="display: none;" class="btn btn-xs btn-warning" type="submit" id="delp2_<?=$ph2index?>" name="delp2_<?=$ph2index?>" value="delp2_<?=$ph2index?>" title="<?=gettext('delete phase2 entry'); ?>">delete</button> |
|
548 |
</td> |
|
549 |
</tr> |
|
550 |
<?php $j++; endforeach; ?> |
|
551 |
<tr> |
|
552 |
<td></td> |
|
553 |
<td> |
|
554 |
<a class="btn btn-xs btn-success" href="vpn_ipsec_phase2.php?ikeid=<?=$ph1ent['ikeid']?><?php if (isset($ph1ent['mobile'])) echo "&mobile=true"?>"> |
|
555 |
<i class="fa fa-plus icon-embed-btn"></i> |
|
556 |
<?=gettext("Add P2")?> |
|
557 |
</a> |
|
558 |
</td> |
|
559 |
<td colspan="7"></td> |
|
560 |
</tr> |
|
561 |
</tbody> |
|
562 |
</table> |
|
563 |
</div> |
|
564 |
</td> |
|
565 |
</tr> |
|
566 |
<?php |
|
567 |
$i++; |
|
568 |
endforeach; // $a_phase1 as $ph1ent |
|
569 |
?> |
|
570 |
</tbody> |
|
571 |
</table> |
|
572 |
</div> |
|
573 |
</div> |
|
574 |
|
|
575 |
<nav class="action-buttons"> |
|
576 |
<?php |
|
577 |
/* |
|
578 |
if ($i !== 0): ?> |
|
579 |
<input type="submit" name="move_<?=$i?>" class="btn btn-default" value="<?=gettext("move selected phase1 entries to end")?>" /> |
|
580 |
<?php endif; |
|
581 |
*/ |
|
582 |
?> |
|
583 |
<a href="vpn_ipsec_phase1.php" class="btn btn-success btn-sm" usepost> |
|
584 |
<i class="fa fa-plus icon-embed-btn"></i> |
|
585 |
<?=gettext("Add P1")?> |
|
586 |
</a> |
|
587 |
<?php if ($i !== 0): ?> |
|
588 |
<button type="submit" name="del" class="btn btn-danger btn-sm" value="<?=gettext("Delete selected P1s")?>"> |
|
589 |
<i class="fa fa-trash icon-embed-btn"></i> |
|
590 |
<?=gettext("Delete P1s")?> |
|
591 |
</button> |
|
592 |
<?php endif; ?> |
|
593 |
</nav> |
|
594 |
</form> |
|
595 |
|
|
596 |
<div class="infoblock"> |
|
597 |
<?php print_info_box(sprintf(gettext('The IPsec status can be checked at %1$s%2$s%3$s.'), '<a href="status_ipsec.php">', gettext("Status:IPsec"), '</a>') . '<br />' . |
|
598 |
sprintf(gettext('IPsec debug mode can be enabled at %1$s%2$s%3$s.'), '<a href="vpn_ipsec_settings.php">', gettext("VPN:IPsec:Advanced Settings"), '</a>') . '<br />' . |
|
599 |
sprintf(gettext('IPsec can be set to prefer older SAs at %1$s%2$s%3$s.'), '<a href="vpn_ipsec_settings.php">', gettext("VPN:IPsec:Advanced Settings"), '</a>'), 'info', false); ?> |
|
600 |
</div> |
|
601 |
|
|
602 |
<script type="text/javascript"> |
|
603 |
//<![CDATA[ |
|
604 |
function show_phase2(id, buttonid) { |
|
605 |
document.getElementById(buttonid).innerHTML=''; |
|
606 |
document.getElementById(id).style.display = "block"; |
|
607 |
var visible = id + '-visible'; |
|
608 |
document.getElementById(visible).value = "1"; |
|
609 |
} |
|
610 |
|
|
611 |
events.push(function() { |
|
612 |
$('[id^=Xmove_]').click(function (event) { |
|
613 |
// ToDo: We POST shift="yes" if the user has the shift key depressed, but that is not yet used |
|
614 |
// by the $_POST code. It is intended to allow the user to choose to move stuff to the row before or |
|
615 |
// after the clicked anchor icon |
|
616 |
if (event.shiftKey) { |
|
617 |
$('form').append('<input type="hidden" id="shift" name="shift" value="yes" />'); |
|
618 |
} |
|
619 |
|
|
620 |
$('#' + event.target.id.slice(1)).click(); |
|
621 |
}); |
|
622 |
|
|
623 |
$('[id^=Xdel_]').click(function (event) { |
|
624 |
if (confirm("<?=gettext('Confirmation required to delete this P1 entry.')?>")) { |
|
625 |
$('#' + event.target.id.slice(1)).click(); |
|
626 |
} |
|
627 |
}); |
|
628 |
|
|
629 |
$('[id^=Xdelp2_]').click(function (event) { |
|
630 |
if (confirm("<?=gettext('Confirmation required to delete this P2 entry.')?>")) { |
|
631 |
$('#' + event.target.id.slice(1)).click(); |
|
632 |
} |
|
633 |
}); |
|
634 |
}); |
|
635 |
//]]> |
|
636 |
</script> |
|
637 |
|
|
638 |
<?php |
|
639 |
include("foot.inc"); |
src/usr/local/www/vpn_wg_edit.php | ||
---|---|---|
1 |
<?php |
|
2 |
|
|
3 |
/* |
|
4 |
* vpn_ipsec_phase1.php |
|
5 |
* |
|
6 |
* part of pfSense (https://www.pfsense.org) |
|
7 |
* Copyright (c) 2004-2013 BSD Perimeter |
|
8 |
* Copyright (c) 2013-2016 Electric Sheep Fencing |
|
9 |
* Copyright (c) 2014-2020 Rubicon Communications, LLC (Netgate) |
|
10 |
* Copyright (c) 2008 Shrew Soft Inc |
|
11 |
* All rights reserved. |
|
12 |
* |
|
13 |
* originally based on m0n0wall (http://m0n0.ch/wall) |
|
14 |
* Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>. |
|
15 |
* All rights reserved. |
|
16 |
* |
|
17 |
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
18 |
* you may not use this file except in compliance with the License. |
|
19 |
* You may obtain a copy of the License at |
|
20 |
* |
|
21 |
* http://www.apache.org/licenses/LICENSE-2.0 |
|
22 |
* |
|
23 |
* Unless required by applicable law or agreed to in writing, software |
|
24 |
* distributed under the License is distributed on an "AS IS" BASIS, |
|
25 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
26 |
* See the License for the specific language governing permissions and |
|
27 |
* limitations under the License. |
|
28 |
*/ |
|
29 |
|
|
30 |
##|+PRIV |
|
31 |
##|*IDENT=page-vpn-ipsec-editphase1 |
|
32 |
##|*NAME=VPN: IPsec: Edit Phase 1 |
|
33 |
##|*DESCR=Allow access to the 'VPN: IPsec: Edit Phase 1' page. |
|
34 |
##|*MATCH=vpn_ipsec_phase1.php* |
|
35 |
##|-PRIV |
|
36 |
|
|
37 |
require_once("functions.inc"); |
|
38 |
require_once("guiconfig.inc"); |
|
39 |
require_once("ipsec.inc"); |
|
40 |
require_once("vpn.inc"); |
|
41 |
require_once("filter.inc"); |
|
42 |
|
|
43 |
if ($_REQUEST['generatekey']) { |
|
44 |
$keyoutput = ""; |
|
45 |
$keystatus = ""; |
|
46 |
exec("/bin/dd status=none if=/dev/random bs=4096 count=1 | /usr/bin/openssl sha224 | /usr/bin/cut -f2 -d' '", $keyoutput, $keystatus); |
|
47 |
print json_encode(['pskey' => $keyoutput[0]]); |
|
48 |
exit; |
|
49 |
} |
|
50 |
|
|
51 |
init_config_arr(array('ipsec', 'phase1')); |
|
52 |
init_config_arr(array('ipsec', 'phase2')); |
|
53 |
init_config_arr(array('ipsec', 'vtimaps', 'item')); |
|
54 |
$a_phase1 = &$config['ipsec']['phase1']; |
|
55 |
$a_phase2 = &$config['ipsec']['phase2']; |
|
56 |
$a_vtimaps = &$config['ipsec']['vtimaps']['item']; |
|
57 |
|
|
58 |
if (is_numericint($_REQUEST['p1index'])) { |
|
59 |
$p1index = $_REQUEST['p1index']; |
|
60 |
} |
|
61 |
|
|
62 |
if (is_numericint($_REQUEST['dup'])) { |
|
63 |
$p1index = $_REQUEST['dup']; |
|
64 |
} |
|
65 |
|
|
66 |
if (isset($p1index) && $a_phase1[$p1index]) { |
|
67 |
// don't copy the ikeid on dup |
|
68 |
if (!isset($_REQUEST['dup']) || !is_numericint($_REQUEST['dup'])) { |
|
69 |
$pconfig['ikeid'] = $a_phase1[$p1index]['ikeid']; |
|
70 |
} |
|
71 |
|
|
72 |
$old_ph1ent = $a_phase1[$p1index]; |
|
73 |
|
|
74 |
$pconfig['disabled'] = isset($a_phase1[$p1index]['disabled']); |
|
75 |
|
|
76 |
if ($a_phase1[$p1index]['interface']) { |
|
77 |
$pconfig['interface'] = $a_phase1[$p1index]['interface']; |
|
78 |
} else { |
|
79 |
$pconfig['interface'] = "wan"; |
|
80 |
} |
|
81 |
|
|
82 |
list($pconfig['remotenet'], $pconfig['remotebits']) = explode("/", $a_phase1[$p1index]['remote-subnet']); |
|
83 |
|
|
84 |
if (isset($a_phase1[$p1index]['mobile'])) { |
|
85 |
$pconfig['mobile'] = 'true'; |
|
86 |
} else { |
|
87 |
$pconfig['remotegw'] = $a_phase1[$p1index]['remote-gateway']; |
|
88 |
$pconfig['ikeport'] = $a_phase1[$p1index]['ikeport']; |
|
89 |
$pconfig['nattport'] = $a_phase1[$p1index]['nattport']; |
|
90 |
} |
|
91 |
|
|
92 |
if (empty($a_phase1[$p1index]['iketype'])) { |
|
93 |
$pconfig['iketype'] = "ikev1"; |
|
94 |
} else { |
|
95 |
$pconfig['iketype'] = $a_phase1[$p1index]['iketype']; |
|
96 |
} |
|
97 |
$pconfig['mode'] = $a_phase1[$p1index]['mode']; |
|
98 |
$pconfig['protocol'] = $a_phase1[$p1index]['protocol']; |
|
99 |
$pconfig['myid_type'] = $a_phase1[$p1index]['myid_type']; |
|
100 |
$pconfig['myid_data'] = $a_phase1[$p1index]['myid_data']; |
|
101 |
$pconfig['peerid_type'] = $a_phase1[$p1index]['peerid_type']; |
|
102 |
$pconfig['peerid_data'] = $a_phase1[$p1index]['peerid_data']; |
|
103 |
$pconfig['encryption'] = $a_phase1[$p1index]['encryption']; |
|
104 |
$pconfig['rekey_time'] = $a_phase1[$p1index]['rekey_time']; |
|
105 |
$pconfig['reauth_time'] = $a_phase1[$p1index]['reauth_time']; |
|
106 |
$pconfig['over_time'] = $a_phase1[$p1index]['over_time']; |
|
107 |
$pconfig['authentication_method'] = $a_phase1[$p1index]['authentication_method']; |
|
108 |
|
|
109 |
if (($pconfig['authentication_method'] == "pre_shared_key") || |
|
110 |
($pconfig['authentication_method'] == "xauth_psk_server")) { |
|
111 |
$pconfig['pskey'] = $a_phase1[$p1index]['pre-shared-key']; |
|
112 |
} else { |
|
113 |
$pconfig['pkcs11certref'] = $a_phase1[$p1index]['pkcs11certref']; |
|
114 |
$pconfig['pkcs11pin'] = $a_phase1[$p1index]['pkcs11pin']; |
|
115 |
$pconfig['certref'] = $a_phase1[$p1index]['certref']; |
|
116 |
$pconfig['caref'] = $a_phase1[$p1index]['caref']; |
|
117 |
} |
|
118 |
|
|
119 |
$pconfig['descr'] = $a_phase1[$p1index]['descr']; |
|
120 |
$pconfig['nat_traversal'] = $a_phase1[$p1index]['nat_traversal']; |
|
121 |
$pconfig['mobike'] = $a_phase1[$p1index]['mobike']; |
|
122 |
|
|
123 |
if (isset($a_phase1[$p1index]['gw_duplicates'])) { |
|
124 |
$pconfig['gw_duplicates'] = true; |
|
125 |
} |
|
126 |
|
|
127 |
$pconfig['closeaction'] = $a_phase1[$p1index]['closeaction']; |
|
128 |
|
|
129 |
if (isset($a_phase1[$p1index]['responderonly'])) { |
|
130 |
$pconfig['responderonly'] = true; |
|
131 |
} |
|
132 |
|
|
133 |
if ($a_phase1[$p1index]['dpd_delay'] && $a_phase1[$p1index]['dpd_maxfail']) { |
|
134 |
$pconfig['dpd_enable'] = true; |
|
135 |
$pconfig['dpd_delay'] = $a_phase1[$p1index]['dpd_delay']; |
|
136 |
$pconfig['dpd_maxfail'] = $a_phase1[$p1index]['dpd_maxfail']; |
|
137 |
} |
|
138 |
|
|
139 |
if (isset($a_phase1[$p1index]['prfselect_enable'])) { |
|
140 |
$pconfig['prfselect_enable'] = 'yes'; |
|
141 |
} |
|
142 |
|
|
143 |
if (isset($a_phase1[$p1index]['splitconn'])) { |
|
144 |
$pconfig['splitconn'] = true; |
|
145 |
} |
|
146 |
|
|
147 |
if (isset($a_phase1[$p1index]['tfc_enable'])) { |
|
148 |
$pconfig['tfc_enable'] = true; |
|
149 |
} |
|
150 |
|
|
151 |
if (isset($a_phase1[$p1index]['tfc_bytes'])) { |
|
152 |
$pconfig['tfc_bytes'] = $a_phase1[$p1index]['tfc_bytes']; |
|
153 |
} |
|
154 |
} else { |
|
155 |
/* defaults */ |
|
156 |
$pconfig['interface'] = "wan"; |
|
157 |
if ($config['interfaces']['lan']) { |
|
158 |
$pconfig['localnet'] = "lan"; |
|
159 |
} |
|
160 |
$pconfig['mode'] = "main"; |
|
161 |
$pconfig['protocol'] = "inet"; |
|
162 |
$pconfig['myid_type'] = "myaddress"; |
|
163 |
$pconfig['peerid_type'] = "peeraddress"; |
|
164 |
$pconfig['authentication_method'] = "pre_shared_key"; |
|
165 |
$pconfig['reauth_time'] = "28800"; |
|
166 |
$pconfig['nat_traversal'] = 'on'; |
|
167 |
$pconfig['mobike'] = 'off'; |
|
168 |
$pconfig['prfselect_enable'] = false; |
|
169 |
$pconfig['dpd_enable'] = true; |
|
170 |
$pconfig['iketype'] = "ikev1"; |
|
171 |
|
|
172 |
/* mobile client */ |
|
173 |
if ($_REQUEST['mobile']) { |
|
174 |
$pconfig['mobile'] = true; |
|
175 |
$pconfig['mode'] = "aggressive"; |
|
176 |
} |
|
177 |
} |
|
178 |
// default value for new P1 and failsafe to always have at least 1 encryption item for the Form_ListItem |
|
179 |
if (!is_array($pconfig['encryption']['item']) || count($pconfig['encryption']['item']) == 0) { |
|
180 |
$item = array(); |
|
181 |
$item['encryption-algorithm'] = array('name' => "aes", 'keylen' => 128); |
|
182 |
$item['hash-algorithm'] = "sha256"; |
|
183 |
$item['prf-algorithm'] = "sha256"; |
|
184 |
$item['dhgroup'] = "14"; |
|
185 |
$pconfig['encryption']['item'][] = $item; |
|
186 |
} |
|
187 |
|
|
188 |
if (isset($_REQUEST['dup']) && is_numericint($_REQUEST['dup'])) { |
|
189 |
unset($p1index); |
|
190 |
} |
|
191 |
|
|
192 |
if ($_POST['save']) { |
|
193 |
unset($input_errors); |
|
194 |
$pconfig = $_POST; |
|
195 |
|
|
196 |
for($i = 0; $i < 100; $i++) { |
|
197 |
if (isset($_POST['ealgo_algo'.$i])) { |
|
198 |
$item = array(); |
|
199 |
$item['encryption-algorithm']['name'] = $_POST['ealgo_algo'.$i]; |
|
200 |
$item['encryption-algorithm']['keylen'] = $_POST['ealgo_keylen'.$i]; |
|
201 |
$item['hash-algorithm'] = $_POST['halgo'.$i]; |
|
202 |
$item['prf-algorithm'] = $_POST['prfalgo'.$i]; |
|
203 |
$item['dhgroup'] = $_POST['dhgroup'.$i]; |
|
204 |
$pconfig['encryption']['item'][] = $item; |
|
205 |
} |
|
206 |
} |
|
207 |
|
|
208 |
/* input validation */ |
|
209 |
|
|
210 |
$method = $pconfig['authentication_method']; |
|
211 |
|
|
212 |
// Unset ca and cert if not required to avoid storing in config |
|
213 |
if ($method == "pre_shared_key" || $method == "xauth_psk_server") { |
|
214 |
unset($pconfig['certref']); |
|
215 |
unset($pconfig['pkcs11certref']); |
|
216 |
} |
|
217 |
|
|
218 |
if (!in_array($method, array('cert', 'eap-tls', 'xauth_cert_server', 'pkcs11'))) { |
|
219 |
unset($pconfig['caref']); |
|
220 |
} |
|
221 |
|
|
222 |
// Only require PSK here for normal PSK tunnels (not mobile) or xauth. |
|
223 |
// For certificate methods, require the CA/Cert. |
|
224 |
switch ($method) { |
|
225 |
case 'eap-mschapv2': |
|
226 |
if ($pconfig['iketype'] != 'ikev2') { |
|
227 |
$input_errors[] = gettext("EAP-MSChapv2 can only be used with IKEv2 type VPNs."); |
|
228 |
} |
|
229 |
break; |
|
230 |
case "eap-tls": |
|
231 |
if ($pconfig['iketype'] != 'ikev2') { |
|
232 |
$input_errors[] = gettext("EAP-TLS can only be used with IKEv2 type VPNs."); |
|
233 |
} |
|
234 |
break; |
|
235 |
case "eap-radius": |
|
236 |
if ($pconfig['iketype'] != 'ikev2') { |
|
237 |
$input_errors[] = gettext("EAP-RADIUS can only be used with IKEv2 type VPNs."); |
|
238 |
} |
|
239 |
break; |
|
240 |
case "pre_shared_key": |
|
241 |
// If this is a mobile PSK tunnel the user PSKs go on |
|
242 |
// the PSK tab, not here, so skip the check. |
|
243 |
if ($pconfig['mobile']) { |
|
244 |
break; |
|
245 |
} |
|
246 |
case "xauth_psk_server": |
|
247 |
$reqdfields = explode(" ", "pskey"); |
|
248 |
$reqdfieldsn = array(gettext("Pre-Shared Key")); |
|
249 |
$validate_pskey = true; |
|
250 |
break; |
|
251 |
case "xauth_cert_server": |
|
252 |
case "cert": |
|
253 |
$reqdfields = explode(" ", "caref certref"); |
|
254 |
$reqdfieldsn = array(gettext("Certificate Authority"), gettext("Certificate")); |
|
255 |
break; |
|
256 |
case "pkcs11": |
|
257 |
$reqdfields = explode(" ", "caref pkcs11certref pkcs11pin"); |
|
258 |
$reqdfieldsn = array(gettext("Certificate Authority"), gettext("Token Certificate"), gettext("Token PIN")); |
|
259 |
break; |
|
260 |
default: |
|
261 |
/* Other types do not use this validation mechanism. */ |
|
262 |
} |
|
263 |
|
|
264 |
if (!$pconfig['mobile']) { |
|
265 |
$reqdfields[] = "remotegw"; |
|
266 |
$reqdfieldsn[] = gettext("Remote gateway"); |
|
267 |
} |
|
268 |
|
|
269 |
do_input_validation($pconfig, $reqdfields, $reqdfieldsn, $input_errors); |
|
270 |
|
|
271 |
if (isset($validate_pskey) && isset($pconfig['pskey']) && !preg_match('/^[[:ascii:]]*$/', $pconfig['pskey'])) { |
|
272 |
unset($validate_pskey); |
|
273 |
$input_errors[] = gettext("Pre-Shared Key contains invalid characters."); |
|
274 |
} |
|
275 |
|
|
276 |
if (!empty($pconfig['rekey_time']) && !is_numericint($pconfig['rekey_time'])) { |
|
277 |
$input_errors[] = gettext("Rekey Time must be an integer."); |
|
278 |
} |
|
279 |
if (!empty($pconfig['reauth_time']) && !is_numericint($pconfig['reauth_time'])) { |
|
280 |
$input_errors[] = gettext("Reauth Time must be an integer."); |
|
281 |
} |
|
282 |
if (!empty($pconfig['over_time']) && !is_numericint($pconfig['over_time'])) { |
|
283 |
$input_errors[] = gettext("Over Time must be an integer."); |
|
284 |
} |
|
285 |
|
|
286 |
if (!empty($pconfig['closeaction']) && !array_key_exists($pconfig['closeaction'], $ipsec_closeactions)) { |
|
287 |
$input_errors[] = gettext("Invalid Child SA Close Action."); |
|
288 |
} |
|
289 |
|
|
290 |
if ($pconfig['remotegw']) { |
|
291 |
if (!is_ipaddr($pconfig['remotegw']) && !is_domain($pconfig['remotegw'])) { |
|
292 |
$input_errors[] = gettext("A valid remote gateway address or host name must be specified."); |
|
293 |
} elseif (is_ipaddrv4($pconfig['remotegw']) && ($pconfig['protocol'] == "inet6")) { |
|
294 |
$input_errors[] = gettext("A valid remote gateway IPv4 address must be specified or protocol needs to be changed to IPv6"); |
|
295 |
} elseif (is_ipaddrv6($pconfig['remotegw']) && ($pconfig['protocol'] == "inet")) { |
|
296 |
$input_errors[] = gettext("A valid remote gateway IPv6 address must be specified or protocol needs to be changed to IPv4"); |
|
297 |
} |
|
298 |
} |
|
299 |
|
|
300 |
if ($_POST['ikeport']) { |
|
301 |
if (!is_port($pconfig['ikeport'])) { |
|
302 |
$input_errors[] = gettext("The IKE port number is invalid."); |
|
303 |
} |
|
304 |
} else { |
|
305 |
unset($pconfig['ikeport']); |
|
306 |
} |
|
307 |
|
|
308 |
if ($_POST['nattport']) { |
|
309 |
if (!is_port($pconfig['nattport'])) { |
|
310 |
$input_errors[] = gettext("The NAT-T port number is invalid."); |
|
311 |
} |
|
312 |
} else { |
|
313 |
unset($pconfig['nattport']); |
|
314 |
} |
|
315 |
|
|
316 |
if (isset($pconfig['ikeport']) && isset($pconfig['nattport']) && $pconfig['ikeport'] == $pconfig['nattport']) { |
|
317 |
$input_errors[] = gettext("IKE and NAT-T port numbers must be different."); |
|
318 |
} |
|
319 |
|
|
320 |
if ($pconfig['remotegw'] && is_ipaddr($pconfig['remotegw']) && !isset($pconfig['disabled'])) { |
|
321 |
$t = 0; |
|
322 |
foreach ($a_phase1 as $ph1tmp) { |
|
323 |
if ($p1index != $t) { |
|
324 |
$tremotegw = $pconfig['remotegw']; |
|
325 |
if (($ph1tmp['remote-gateway'] == $tremotegw) && ($ph1tmp['remote-gateway'] != '0.0.0.0') && |
|
326 |
($ph1tmp['remote-gateway'] != '::') && !isset($ph1tmp['disabled']) && |
|
327 |
(!isset($pconfig['gw_duplicates']) || !isset($ph1tmp['gw_duplicates']))) { |
|
328 |
$input_errors[] = sprintf(gettext('The remote gateway "%1$s" is already used by phase1 "%2$s".'), $tremotegw, $ph1tmp['descr']); |
|
329 |
} |
|
330 |
} |
|
331 |
$t++; |
|
332 |
} |
|
333 |
} |
|
334 |
|
|
335 |
if (($pconfig['remotegw'] == '0.0.0.0') || ($pconfig['remotegw'] == '::')) { |
|
336 |
if (!isset($pconfig['responderonly'])) { |
|
337 |
$input_errors[] = gettext('The remote gateway "0.0.0.0" or "::" address can only be used with "Responder Only".'); |
|
338 |
} |
|
339 |
if ($pconfig['peerid_type'] == "peeraddress") { |
|
340 |
$input_errors[] = gettext('The remote gateway "0.0.0.0" or "::" address can not be used with IP address peer identifier.'); |
|
341 |
} |
|
342 |
|
|
343 |
} |
|
344 |
|
|
345 |
if (($pconfig['iketype'] == "ikev1") && is_array($a_phase2) && (count($a_phase2))) { |
|
346 |
foreach ($a_phase2 as $phase2) { |
|
347 |
if ($phase2['ikeid'] == $pconfig['ikeid']) { |
|
348 |
if (($pconfig['protocol'] == "inet") && ($phase2['mode'] == "tunnel6")) { |
|
349 |
$input_errors[] = gettext("There is a Phase 2 using IPv6, cannot use IPv4."); |
|
350 |
break; |
|
351 |
} |
|
352 |
if (($pconfig['protocol'] == "inet6") && ($phase2['mode'] == "tunnel")) { |
|
353 |
$input_errors[] = gettext("There is a Phase 2 using IPv4, cannot use IPv6."); |
|
354 |
break; |
|
355 |
} |
|
356 |
} |
|
357 |
} |
|
358 |
} |
|
359 |
|
|
360 |
/* My identity */ |
|
361 |
|
|
362 |
if ($pconfig['myid_type'] == "myaddress") { |
|
363 |
$pconfig['myid_data'] = ""; |
|
364 |
} |
|
365 |
|
|
366 |
if ($pconfig['myid_type'] == "address" and $pconfig['myid_data'] == "") { |
|
367 |
$input_errors[] = gettext("Please enter an address for 'My Identifier'"); |
|
368 |
} |
|
369 |
|
|
370 |
if ($pconfig['myid_type'] == "keyid tag" and $pconfig['myid_data'] == "") { |
|
371 |
$input_errors[] = gettext("Please enter a keyid tag for 'My Identifier'"); |
|
372 |
} |
|
373 |
|
|
374 |
if ($pconfig['myid_type'] == "fqdn" and $pconfig['myid_data'] == "") { |
|
375 |
$input_errors[] = gettext("Please enter a fully qualified domain name for 'My Identifier'"); |
|
376 |
} |
|
377 |
|
|
378 |
if ($pconfig['myid_type'] == "user_fqdn" and $pconfig['myid_data'] == "") { |
|
379 |
$input_errors[] = gettext("Please enter a user and fully qualified domain name for 'My Identifier'"); |
|
380 |
} |
|
381 |
|
|
382 |
if ($pconfig['myid_type'] == "dyn_dns" and $pconfig['myid_data'] == "") { |
|
383 |
$input_errors[] = gettext("Please enter a dynamic domain name for 'My Identifier'"); |
|
384 |
} |
|
385 |
|
|
386 |
if (($pconfig['myid_type'] == "address") && !is_ipaddr($pconfig['myid_data'])) { |
|
387 |
$input_errors[] = gettext("A valid IP address for 'My identifier' must be specified."); |
|
388 |
} |
|
389 |
|
|
390 |
if (($pconfig['myid_type'] == "fqdn") && !is_domain($pconfig['myid_data'])) { |
|
391 |
$input_errors[] = gettext("A valid domain name for 'My identifier' must be specified."); |
|
392 |
} |
|
393 |
|
|
394 |
if ($pconfig['myid_type'] == "fqdn") { |
|
395 |
if (is_domain($pconfig['myid_data']) == false) { |
|
396 |
$input_errors[] = gettext("A valid FQDN for 'My identifier' must be specified."); |
|
397 |
} |
|
398 |
} |
|
399 |
|
|
400 |
if ($pconfig['myid_type'] == "user_fqdn") { |
|
401 |
$user_fqdn = explode("@", $pconfig['myid_data']); |
|
402 |
if (is_domain($user_fqdn[1]) == false) { |
|
403 |
$input_errors[] = gettext("A valid User FQDN in the form of user@my.domain.com for 'My identifier' must be specified."); |
|
404 |
} |
|
405 |
} |
|
406 |
|
|
407 |
if ($pconfig['myid_type'] == "dyn_dns") { |
|
408 |
if (is_domain($pconfig['myid_data']) == false) { |
|
409 |
$input_errors[] = gettext("A valid Dynamic DNS address for 'My identifier' must be specified."); |
|
410 |
} |
|
411 |
} |
|
412 |
|
|
413 |
/* Peer identity */ |
|
414 |
|
|
415 |
if ($pconfig['myid_type'] == "peeraddress") { |
|
416 |
$pconfig['peerid_data'] = ""; |
|
417 |
} |
|
418 |
|
|
419 |
// Only enforce peer ID if we are not dealing with a pure-psk mobile config. |
|
420 |
if (!(($pconfig['authentication_method'] == "pre_shared_key") && ($pconfig['mobile']))) { |
|
421 |
if ($pconfig['peerid_type'] == "address" and $pconfig['peerid_data'] == "") { |
|
422 |
$input_errors[] = gettext("Please enter an address for 'Peer Identifier'"); |
|
423 |
} |
|
424 |
|
|
425 |
if ($pconfig['peerid_type'] == "keyid tag" and $pconfig['peerid_data'] == "") { |
|
426 |
$input_errors[] = gettext("Please enter a keyid tag for 'Peer Identifier'"); |
|
427 |
} |
|
428 |
|
|
429 |
if ($pconfig['peerid_type'] == "fqdn" and $pconfig['peerid_data'] == "") { |
|
430 |
$input_errors[] = gettext("Please enter a fully qualified domain name for 'Peer Identifier'"); |
|
431 |
} |
|
432 |
|
|
433 |
if ($pconfig['peerid_type'] == "user_fqdn" and $pconfig['peerid_data'] == "") { |
|
434 |
$input_errors[] = gettext("Please enter a user and fully qualified domain name for 'Peer Identifier'"); |
|
435 |
} |
|
436 |
|
|
437 |
if ((($pconfig['peerid_type'] == "address") && !is_ipaddr($pconfig['peerid_data']))) { |
|
438 |
$input_errors[] = gettext("A valid IP address for 'Peer identifier' must be specified."); |
|
439 |
} |
|
440 |
|
|
441 |
if ((($pconfig['peerid_type'] == "fqdn") && !is_domain($pconfig['peerid_data']))) { |
|
442 |
$input_errors[] = gettext("A valid domain name for 'Peer identifier' must be specified."); |
|
443 |
} |
|
444 |
|
|
445 |
if ($pconfig['peerid_type'] == "fqdn") { |
|
446 |
if (is_domain($pconfig['peerid_data']) == false) { |
|
447 |
$input_errors[] = gettext("A valid FQDN for 'Peer identifier' must be specified."); |
|
448 |
} |
|
449 |
} |
|
450 |
|
|
451 |
if ($pconfig['peerid_type'] == "user_fqdn") { |
|
452 |
$user_fqdn = explode("@", $pconfig['peerid_data']); |
|
453 |
if (is_domain($user_fqdn[1]) == false) { |
|
454 |
$input_errors[] = gettext("A valid User FQDN in the form of user@my.domain.com for 'Peer identifier' must be specified."); |
|
455 |
} |
|
456 |
} |
|
457 |
} |
|
458 |
|
|
459 |
if ($pconfig['dpd_enable']) { |
|
460 |
if (!is_numericint($pconfig['dpd_delay'])) { |
|
461 |
$input_errors[] = gettext("A numeric value must be specified for DPD delay."); |
|
462 |
} |
|
463 |
|
|
464 |
if (!is_numericint($pconfig['dpd_maxfail'])) { |
|
465 |
$input_errors[] = gettext("A numeric value must be specified for DPD retries."); |
|
466 |
} |
|
467 |
} |
|
468 |
|
|
469 |
if ($pconfig['tfc_bytes'] && !is_numericint($pconfig['tfc_bytes'])) { |
|
470 |
$input_errors[] = gettext("A numeric value must be specified for TFC bytes."); |
|
471 |
} |
|
472 |
|
|
473 |
if (!empty($pconfig['iketype']) && $pconfig['iketype'] != "ikev1" && $pconfig['iketype'] != "ikev2" && $pconfig['iketype'] != "auto") { |
|
474 |
$input_errors[] = gettext("Valid arguments for IKE type are v1, v2 or auto"); |
|
475 |
} |
|
476 |
|
|
477 |
foreach($pconfig['encryption']['item'] as $p1algo) { |
|
478 |
if (preg_match("/aes\d+gcm/", $p1algo['encryption-algorithm']['name']) && $_POST['iketype'] != "ikev2") { |
|
479 |
$input_errors[] = gettext("Encryption Algorithm AES-GCM can only be used with IKEv2"); |
|
480 |
} |
|
481 |
} |
|
482 |
/* auth backend for mobile eap-radius VPNs should be a RADIUS server */ |
|
483 |
if (($pconfig['authentication_method'] == 'eap-radius') && $pconfig['mobile']) { |
|
484 |
if (!empty($config['ipsec']['client']['user_source'])) { |
|
485 |
$auth_server_list = explode(',', $config['ipsec']['client']['user_source']); |
|
486 |
foreach ($auth_server_list as $auth_server_name) { |
|
487 |
$auth_server = auth_get_authserver($auth_server_name); |
|
488 |
if (!is_array($auth_server) || ($auth_server['type'] != 'radius')) { |
|
489 |
$input_errors[] = gettext("A valid RADIUS server must be selected for user authentication on the Mobile Clients tab in order to set EAP-RADIUS as the authentication method."); |
|
490 |
} |
|
491 |
} |
|
492 |
} |
|
493 |
} |
|
494 |
if (is_array($old_ph1ent) && ipsec_vti($old_ph1ent, false, false) && $pconfig['disabled']) { |
|
495 |
$input_errors[] = gettext("Cannot disable a Phase 1 with a child Phase 2 while the interface is assigned. Remove the interface assignment before disabling this P2."); |
|
496 |
} |
|
497 |
|
|
498 |
if (!empty($pconfig['certref'])) { |
|
499 |
$errchkcert =& lookup_cert($pconfig['certref']); |
|
500 |
if (is_array($errchkcert) && !cert_check_pkey_compatibility($errchkcert['prv'], 'IPsec')) { |
|
501 |
$input_errors[] = gettext("The selected ECDSA certificate does not use a curve compatible with IKEv2"); |
|
502 |
} |
|
503 |
} |
|
504 |
|
|
505 |
if (!$input_errors) { |
|
506 |
$ph1ent['ikeid'] = $pconfig['ikeid']; |
|
507 |
$ph1ent['iketype'] = $pconfig['iketype']; |
|
508 |
if ($pconfig['iketype'] == 'ikev2') { |
|
509 |
unset($ph1ent['mode']); |
|
510 |
} else { |
|
511 |
$ph1ent['mode'] = $pconfig['mode']; |
|
512 |
} |
|
513 |
|
|
514 |
// re-create vtimaps after IKE version switching |
|
515 |
$vtisubnet_spec = ipsec_vti($ph1ent, true); |
|
516 |
if ((($pconfig['iketype'] != $a_phase1[$p1index]['iketype']) || |
|
517 |
(isset($pconfig['splitconn']) != isset($a_phase1[$p1index]['splitconn']))) && |
|
518 |
($vtisubnet_spec || is_array($vtisubnet_spec))) { |
|
519 |
foreach ($a_vtimaps as $id => $vtimap) { |
|
520 |
if ($vtimap['reqid'] == $ph1ent['ikeid']) { |
|
521 |
unset($a_vtimaps[$id]); |
|
522 |
} |
|
523 |
} |
|
524 |
if (($pconfig['iketype'] == 'ikev1') || |
|
525 |
isset($pconfig['splitconn'])) { |
|
526 |
foreach ($vtisubnet_spec as $idx => $vtisub) { |
|
527 |
$a_vtimaps[] = ipsec_create_vtimap( |
|
528 |
$ph1ent['ikeid'], $idx); |
|
529 |
} |
|
530 |
} else { |
|
531 |
$a_vtimaps[] = ipsec_create_vtimap( |
|
532 |
$ph1ent['ikeid'], 0); |
|
533 |
} |
|
534 |
} |
|
535 |
|
|
536 |
$ph1ent['disabled'] = $pconfig['disabled'] ? true : false; |
|
537 |
$ph1ent['interface'] = $pconfig['interface']; |
|
538 |
/* if the remote gateway changed and the interface is not WAN then remove route */ |
|
539 |
/* the ipsec_configure() handles adding the route */ |
|
540 |
if ($pconfig['interface'] <> "wan") { |
|
541 |
if ($old_ph1ent['remote-gateway'] <> $pconfig['remotegw']) { |
|
542 |
route_del($old_ph1ent['remote-gateway']); |
|
543 |
} |
|
544 |
} |
|
545 |
|
|
546 |
if ($pconfig['mobile']) { |
|
547 |
$ph1ent['mobile'] = true; |
|
548 |
} else { |
|
549 |
$ph1ent['remote-gateway'] = $pconfig['remotegw']; |
|
550 |
if ( !empty($pconfig['ikeport']) ) { |
|
551 |
$ph1ent['ikeport'] = $pconfig['ikeport']; |
|
552 |
} else { |
|
553 |
unset($ph1ent['ikeport']); |
|
554 |
} |
|
555 |
if ( !empty($pconfig['nattport']) ) { |
|
556 |
$ph1ent['nattport'] = $pconfig['nattport']; |
|
557 |
} else { |
|
558 |
unset($ph1ent['nattport']); |
|
559 |
} |
|
560 |
} |
|
561 |
|
|
562 |
$ph1ent['protocol'] = $pconfig['protocol']; |
|
563 |
|
|
564 |
$ph1ent['myid_type'] = $pconfig['myid_type']; |
|
565 |
$ph1ent['myid_data'] = $pconfig['myid_data']; |
|
566 |
$ph1ent['peerid_type'] = $pconfig['peerid_type']; |
|
567 |
$ph1ent['peerid_data'] = $pconfig['peerid_data']; |
|
568 |
|
|
569 |
$ph1ent['encryption'] = $pconfig['encryption']; |
|
570 |
$ph1ent['rekey_time'] = $pconfig['rekey_time']; |
|
571 |
$ph1ent['reauth_time'] = $pconfig['reauth_time']; |
|
572 |
$ph1ent['over_time'] = $pconfig['over_time']; |
|
573 |
$ph1ent['pre-shared-key'] = $pconfig['pskey']; |
|
574 |
$ph1ent['private-key'] = base64_encode($pconfig['privatekey']); |
|
575 |
$ph1ent['certref'] = $pconfig['certref']; |
|
576 |
$ph1ent['pkcs11certref'] = $pconfig['pkcs11certref']; |
|
577 |
$ph1ent['pkcs11pin'] = $pconfig['pkcs11pin']; |
|
578 |
$ph1ent['caref'] = $pconfig['caref']; |
|
579 |
$ph1ent['authentication_method'] = $pconfig['authentication_method']; |
|
580 |
$ph1ent['descr'] = $pconfig['descr']; |
|
581 |
$ph1ent['nat_traversal'] = $pconfig['nat_traversal']; |
|
582 |
$ph1ent['mobike'] = $pconfig['mobike']; |
|
583 |
|
|
584 |
if ( isset($pconfig['gw_duplicates'])) { |
|
585 |
$ph1ent['gw_duplicates'] = true; |
|
586 |
} else { |
|
587 |
unset($ph1ent['gw_duplicates']); |
|
588 |
} |
|
589 |
|
|
590 |
$ph1ent['closeaction'] = $pconfig['closeaction']; |
|
591 |
|
|
592 |
if (isset($pconfig['prfselect_enable'])) { |
|
593 |
$ph1ent['prfselect_enable'] = 'yes'; |
|
594 |
} else { |
|
595 |
unset($ph1ent['prfselect_enable']); |
|
596 |
} |
|
597 |
|
|
598 |
if (isset($pconfig['responderonly'])) { |
|
599 |
$ph1ent['responderonly'] = true; |
|
600 |
} else { |
|
601 |
unset($ph1ent['responderonly']); |
|
602 |
} |
|
603 |
|
|
604 |
if (isset($pconfig['dpd_enable'])) { |
|
605 |
$ph1ent['dpd_delay'] = $pconfig['dpd_delay']; |
|
606 |
$ph1ent['dpd_maxfail'] = $pconfig['dpd_maxfail']; |
|
607 |
} |
|
608 |
|
|
609 |
if (isset($pconfig['splitconn'])) { |
|
610 |
$ph1ent['splitconn'] = true; |
|
611 |
} else { |
|
612 |
unset($ph1ent['splitconn']); |
|
613 |
} |
|
614 |
|
|
615 |
if (isset($pconfig['tfc_enable'])) { |
|
616 |
$ph1ent['tfc_enable'] = true; |
|
617 |
} |
|
618 |
|
|
619 |
if (isset($pconfig['tfc_bytes'])) { |
|
620 |
$ph1ent['tfc_bytes'] = $pconfig['tfc_bytes']; |
|
621 |
} |
|
622 |
|
|
623 |
/* generate unique phase1 ikeid */ |
|
624 |
if ($ph1ent['ikeid'] == 0) { |
|
625 |
$ph1ent['ikeid'] = ipsec_ikeid_next(); |
|
626 |
} |
|
627 |
|
|
628 |
if (isset($p1index) && $a_phase1[$p1index]) { |
|
629 |
$a_phase1[$p1index] = $ph1ent; |
|
630 |
} else { |
|
631 |
$a_phase1[] = $ph1ent; |
|
632 |
} |
|
633 |
|
|
634 |
write_config(gettext("Saved IPsec tunnel Phase 1 configuration.")); |
|
635 |
mark_subsystem_dirty('ipsec'); |
|
636 |
|
|
637 |
header("Location: vpn_ipsec.php"); |
|
638 |
exit; |
|
639 |
} |
|
640 |
} |
|
641 |
|
|
642 |
function build_interface_list() { |
|
643 |
$interfaces = get_configured_interface_with_descr(); |
|
644 |
|
|
645 |
$viplist = get_configured_vip_list(); |
|
646 |
foreach ($viplist as $vip => $address) { |
|
647 |
$interfaces[$vip] = $address; |
|
648 |
if (get_vip_descr($address)) { |
|
649 |
$interfaces[$vip] .= " (". get_vip_descr($address) .")"; |
|
650 |
} |
|
651 |
} |
|
652 |
|
|
653 |
$grouplist = return_gateway_groups_array(); |
|
654 |
|
|
655 |
foreach ($grouplist as $name => $group) { |
|
656 |
if ($group[0]['vip'] != "") { |
|
657 |
$vipif = $group[0]['vip']; |
|
658 |
} else { |
|
659 |
$vipif = $group[0]['int']; |
|
660 |
} |
|
661 |
|
|
662 |
$interfaces[$name] = sprintf(gettext("GW Group %s"), $name); |
|
663 |
} |
|
664 |
|
|
665 |
return($interfaces); |
|
666 |
|
|
667 |
} |
|
668 |
|
|
669 |
function build_auth_method_list() { |
|
670 |
global $p1_authentication_methods, $pconfig; |
|
671 |
|
|
672 |
$list = array(); |
|
673 |
|
|
674 |
foreach ($p1_authentication_methods as $method_type => $method_params) { |
|
675 |
if (!$pconfig['mobile'] && $method_params['mobile']) { |
|
676 |
continue; |
|
677 |
} |
|
678 |
|
|
679 |
$list[$method_type] = htmlspecialchars($method_params['name']); |
|
680 |
} |
|
681 |
|
|
682 |
return($list); |
|
683 |
} |
|
684 |
|
|
685 |
function build_myid_list() { |
|
686 |
global $my_identifier_list; |
|
687 |
|
|
688 |
$list = array(); |
|
689 |
|
|
690 |
foreach ($my_identifier_list as $id_type => $id_params) { |
|
691 |
$list[$id_type] = htmlspecialchars($id_params['desc']); |
|
692 |
} |
|
693 |
|
|
694 |
return($list); |
|
695 |
} |
|
696 |
|
|
697 |
function build_peerid_list() { |
|
698 |
global $peer_identifier_list; |
|
699 |
|
|
700 |
$list = array(); |
|
701 |
|
|
702 |
foreach ($peer_identifier_list as $id_type => $id_params) { |
|
703 |
$list[$id_type] = htmlspecialchars($id_params['desc']); |
|
704 |
} |
|
705 |
|
|
706 |
return($list); |
|
707 |
} |
|
708 |
|
|
709 |
function build_pkcs11cert_list() { |
|
710 |
global $config; |
|
711 |
|
|
712 |
$list = array(); |
|
713 |
$p11_cn = array(); |
|
714 |
$p11_id = array(); |
|
715 |
$output = shell_exec('/usr/local/bin/pkcs15-tool -c'); |
|
716 |
|
|
717 |
preg_match_all('/X\.509\ Certificate\ \[(.*)\]/', $output, $p11_cn); |
|
718 |
preg_match_all('/ID\s+: (.*)/', $output, $p11_id); |
|
719 |
|
|
720 |
if (is_array($p11_id)) { |
|
721 |
for ($i = 0; $i < count($p11_id[1]); $i++) { |
|
722 |
$list[$p11_id[1][$i]] = "{$p11_cn[1][$i]} " . "({$p11_id[1][$i]})"; |
|
723 |
} |
|
724 |
} |
|
725 |
return($list); |
|
726 |
} |
|
727 |
|
|
728 |
function build_eal_list() { |
|
729 |
global $p1_ealgos; |
|
730 |
|
|
731 |
$list = array(); |
|
732 |
|
|
733 |
if (is_array($p1_ealgos)) { |
|
734 |
foreach ($p1_ealgos as $algo => $algodata) { |
|
735 |
$list[$algo] = htmlspecialchars($algodata['name']); |
|
736 |
} |
|
737 |
} |
|
738 |
|
|
739 |
return($list); |
|
740 |
} |
|
741 |
|
|
742 |
if ($pconfig['mobile']) { |
|
743 |
$pgtitle = array(gettext("VPN"), gettext("IPsec"), gettext("Mobile Clients"), gettext("Edit Phase 1")); |
|
744 |
$pglinks = array("", "vpn_ipsec.php", "vpn_ipsec_mobile.php", "@self"); |
|
745 |
} else { |
|
746 |
$pgtitle = array(gettext("VPN"), gettext("IPsec"), gettext("Tunnels"), gettext("Edit Phase 1")); |
|
747 |
$pglinks = array("", "vpn_ipsec.php", "vpn_ipsec.php", "@self"); |
|
748 |
} |
|
749 |
|
|
750 |
$shortcut_section = "ipsec"; |
|
751 |
|
|
752 |
include("head.inc"); |
|
753 |
|
|
754 |
if ($input_errors) { |
|
755 |
print_input_errors($input_errors); |
|
756 |
} |
|
757 |
|
|
758 |
$tab_array = array(); |
|
759 |
$tab_array[] = array(gettext("Tunnels"), true, "vpn_ipsec.php"); |
|
760 |
$tab_array[] = array(gettext("Mobile Clients"), false, "vpn_ipsec_mobile.php"); |
|
761 |
$tab_array[] = array(gettext("Pre-Shared Keys"), false, "vpn_ipsec_keys.php"); |
|
762 |
$tab_array[] = array(gettext("Advanced Settings"), false, "vpn_ipsec_settings.php"); |
|
763 |
display_top_tabs($tab_array); |
|
764 |
|
|
765 |
$form = new Form(); |
|
766 |
|
|
767 |
$section = new Form_Section('General Information'); |
|
768 |
|
|
769 |
$section->addInput(new Form_Checkbox( |
|
770 |
'disabled', |
|
771 |
'Disabled', |
|
772 |
'Set this option to disable this phase1 without removing it from the list. ', |
|
773 |
$pconfig['disabled'] |
|
774 |
)); |
|
775 |
|
|
776 |
$section->addInput(new Form_Select( |
|
777 |
'iketype', |
|
778 |
'*Key Exchange version', |
|
779 |
$pconfig['iketype'], |
|
780 |
array("ikev1" => "IKEv1", "ikev2" => "IKEv2", "auto" => gettext("Auto")) |
|
781 |
))->setHelp('Select the Internet Key Exchange protocol version to be used. Auto uses IKEv2 when initiator, and accepts either IKEv1 or IKEv2 as responder.'); |
|
782 |
|
|
783 |
$section->addInput(new Form_Select( |
|
784 |
'protocol', |
|
785 |
'*Internet Protocol', |
|
786 |
$pconfig['protocol'], |
|
787 |
array("inet" => "IPv4", "inet6" => "IPv6", "both" => "Both (Dual Stack)") |
|
788 |
))->setHelp('Select the Internet Protocol family.'); |
|
789 |
|
|
790 |
$section->addInput(new Form_Select( |
|
791 |
'interface', |
|
792 |
'*Interface', |
|
793 |
$pconfig['interface'], |
|
794 |
build_interface_list() |
|
795 |
))->setHelp('Select the interface for the local endpoint of this phase1 entry.'); |
|
796 |
|
|
797 |
if (!$pconfig['mobile']) { |
|
798 |
$group = new Form_Group('*Remote Gateway'); |
|
799 |
|
|
800 |
$group->add(new Form_Input( |
|
801 |
'remotegw', |
|
802 |
'Remote Gateway', |
|
803 |
'text', |
|
804 |
$pconfig['remotegw'] |
|
805 |
))->setHelp('Enter the public IP address or host name of the remote gateway.%1$s%2$s%3$s', |
|
806 |
'<div class="infoblock">', |
|
807 |
sprint_info_box(gettext('Use \'0.0.0.0\' to allow connections from any IPv4 address or \'::\' ' . |
|
808 |
'to allow connections from any IPv6 address.' . '<br/>' . 'Responder Only must be set and ' . |
|
809 |
'Peer IP Address cannot be used for Remote Identifier.'), 'info', false), |
|
810 |
'</div>'); |
|
811 |
$group->add(new Form_Input( |
|
812 |
'ikeport', |
|
813 |
'Remote IKE Port', |
|
814 |
'number', |
|
815 |
$pconfig['ikeport'], |
|
816 |
['min' => 1, 'max' => 65535] |
|
817 |
))->setHelp('UDP port for IKE on the remote gateway. Leave empty for default automatic behavior (500/4500).'); |
|
818 |
$group->add(new Form_Input( |
|
819 |
'nattport', |
|
820 |
'Remote NAT-T Port', |
|
821 |
'number', |
|
822 |
$pconfig['nattport'], |
|
823 |
['min' => 1, 'max' => 65535] |
|
824 |
))->setHelp('UDP port for NAT-T on the remote gateway.%1$s%2$s%3$s', |
|
825 |
'<div class="infoblock">', |
|
826 |
sprint_info_box(gettext('If the IKE port is empty and NAT-T contains a value, the tunnel will use only NAT-T.'), |
|
827 |
'info', false), |
|
828 |
'</div>'); |
|
829 |
$section->add($group); |
|
830 |
} |
|
831 |
|
|
832 |
$section->addInput(new Form_Input( |
Also available in: Unified diff
Outlined Wireguard GUI pages and added it to the VPN menu