Project

General

Profile

Download (60 KB) Statistics
| Branch: | Tag: | Revision:
1 5b237745 Scott Ullrich
<?php
2
/*
3 ac24dc24 Renato Botelho
 * vpn.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6 4a762cf0 Steve Beaver
 * Copyright (c) 2004-2019 Rubicon Communications, LLC (Netgate)
7 c5d81585 Renato Botelho
 * Copyright (c) 2008 Shrew Soft Inc
8 ac24dc24 Renato Botelho
 * All rights reserved.
9
 *
10
 * originally part of m0n0wall (http://m0n0.ch/wall)
11 c5d81585 Renato Botelho
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
12 ac24dc24 Renato Botelho
 * All rights reserved.
13
 *
14 b12ea3fb Renato Botelho
 * Licensed under the Apache License, Version 2.0 (the "License");
15
 * you may not use this file except in compliance with the License.
16
 * You may obtain a copy of the License at
17 ac24dc24 Renato Botelho
 *
18 b12ea3fb Renato Botelho
 * http://www.apache.org/licenses/LICENSE-2.0
19 ac24dc24 Renato Botelho
 *
20 b12ea3fb Renato Botelho
 * Unless required by applicable law or agreed to in writing, software
21
 * distributed under the License is distributed on an "AS IS" BASIS,
22
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23
 * See the License for the specific language governing permissions and
24
 * limitations under the License.
25 ac24dc24 Renato Botelho
 */
26 8f67a8e1 Scott Ullrich
27 50813d24 jim-p
require_once("ipsec.inc");
28 0dea741f Chris Buechler
require_once("filter.inc");
29 87a898b1 Chris Buechler
require_once("auth.inc");
30 50813d24 jim-p
31 c53e411f Matt Smith
function vpn_update_daemon_loglevel($category, $level) {
32
	global $ipsec_log_cats, $ipsec_log_sevs;
33 c6efc8fd Ermal
34 c53e411f Matt Smith
	if (in_array($category, array_keys($ipsec_log_cats), true) && in_array(intval($level), array_keys($ipsec_log_sevs), true)) {
35
36
		/* if you're setting to -1, need to add "--" to args */
37
		$argterm = "";
38
		if ($level == "-1") {
39
			$argterm = "--";
40 79262830 Phil Davis
		}
41 c53e411f Matt Smith
42
		mwexec("/usr/local/sbin/ipsec stroke loglevel {$category} {$argterm} {$level}");
43 c6efc8fd Ermal
	}
44 c53e411f Matt Smith
}
45
46
function vpn_logging_cfgtxt() {
47
	global $config, $ipsec_log_cats, $ipsec_log_sevs;
48
49
	$cfgtext = array();
50 e470f721 jim-p
	$log_levels = ipsec_get_loglevels();
51 c53e411f Matt Smith
	foreach (array_keys($ipsec_log_cats) as $cat) {
52 e470f721 jim-p
		if (is_numeric($log_levels[$cat]) &&
53
		    in_array(intval($log_levels[$cat]), array_keys($ipsec_log_sevs), true)) {
54
			$cfgtext[] = "${cat} = {$log_levels[$cat]}";
55 c53e411f Matt Smith
		}
56 79262830 Phil Davis
	}
57 c53e411f Matt Smith
58
	return $cfgtext;
59 c6efc8fd Ermal
}
60
61 5b237745 Scott Ullrich
/* include all configuration functions */
62 086cf944 Phil Davis
function vpn_ipsec_convert_to_modp($index) {
63 8f67a8e1 Scott Ullrich
64 51a14c58 Phil Davis
	$conversion = "";
65 496acde1 Ermal
	switch ($index) {
66 79262830 Phil Davis
		case '1':
67 51a14c58 Phil Davis
			$conversion = "modp768";
68 79262830 Phil Davis
			break;
69
		case '2':
70 51a14c58 Phil Davis
			$conversion = "modp1024";
71 79262830 Phil Davis
			break;
72
		case '5':
73 51a14c58 Phil Davis
			$conversion = "modp1536";
74 79262830 Phil Davis
			break;
75
		case '14':
76 51a14c58 Phil Davis
			$conversion = "modp2048";
77 79262830 Phil Davis
			break;
78
		case '15':
79 51a14c58 Phil Davis
			$conversion = "modp3072";
80 79262830 Phil Davis
			break;
81
		case '16':
82 51a14c58 Phil Davis
			$conversion = "modp4096";
83 79262830 Phil Davis
			break;
84
		case '17':
85 51a14c58 Phil Davis
			$conversion = "modp6144";
86 79262830 Phil Davis
			break;
87
		case '18':
88 51a14c58 Phil Davis
			$conversion = "modp8192";
89 79262830 Phil Davis
			break;
90 7a747654 Ermal LUÇI
		case '19':
91 51a14c58 Phil Davis
			$conversion = "ecp256";
92 7a747654 Ermal LUÇI
			break;
93
		case '20':
94 51a14c58 Phil Davis
			$conversion = "ecp384";
95 7a747654 Ermal LUÇI
			break;
96
		case '21':
97 51a14c58 Phil Davis
			$conversion = "ecp521";
98 7a747654 Ermal LUÇI
			break;
99 9f52ee2c Michael Newton
		case '22':
100 51a14c58 Phil Davis
			$conversion = "modp1024s160";
101 9f52ee2c Michael Newton
			break;
102
		case '23':
103 51a14c58 Phil Davis
			$conversion = "modp2048s224";
104 9f52ee2c Michael Newton
			break;
105
		case '24':
106 51a14c58 Phil Davis
			$conversion = "modp2048s256";
107 9f52ee2c Michael Newton
			break;
108 0d102fcd Bruno Thomsen
		case '28':
109 51a14c58 Phil Davis
			$conversion = "ecp256bp";
110 0d102fcd Bruno Thomsen
			break;
111
		case '29':
112 51a14c58 Phil Davis
			$conversion = "ecp384bp";
113 0d102fcd Bruno Thomsen
			break;
114
		case '30':
115 51a14c58 Phil Davis
			$conversion = "ecp512bp";
116 7a747654 Ermal LUÇI
			break;
117 920af30f Ermal Lu?i
	}
118 496acde1 Ermal
119 51a14c58 Phil Davis
	return $conversion;
120 600dd4e0 Scott Ullrich
}
121 8f67a8e1 Scott Ullrich
122 086cf944 Phil Davis
function vpn_ipsec_configure($restart = false) {
123 34ba4e5d Chris Buechler
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos, $ipsec_idhandling;
124 17da6c79 Scott Ullrich
125 c520e3e3 Chris Buechler
	$ipsecstartlock = lock('ipsec', LOCK_EX);
126
127 f41c9fd5 Ermal Lu?i
	/* get the automatic ping_hosts.sh ready */
128 cdd5b2ce Ermal Lu?i
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
129
	touch("{$g['vardb_path']}/ipsecpinghosts");
130 d315b341 Chris Buechler
	$ipsecpinghostsactive = false;
131 086cf944 Phil Davis
132 0545a75e Chris Buechler
	/* service may have been enabled, disabled, or otherwise changed in a way requiring rule updates */
133
	filter_configure();
134 c1f5a46b Scott Ullrich
135 8f67a8e1 Scott Ullrich
	$syscfg = $config['system'];
136 5b237745 Scott Ullrich
	$ipseccfg = $config['ipsec'];
137 91244542 jim-p
138
	/* Configure asynchronous crypto. See https://redmine.pfsense.org/issues/8772 */
139 23b2c59e Steve Beaver
	set_sysctl(array('net.inet.ipsec.async_crypto' => (int) (isset($ipseccfg['async_crypto']) && ($ipseccfg['async_crypto'] == "enabled"))));
140 91244542 jim-p
141 1a2de6d6 Luiz Otavio O Souza
	if (!ipsec_enabled()) {
142 6c576b27 Ermal
		/* try to stop charon */
143
		mwexec("/usr/local/sbin/ipsec stop");
144 52c9f9fa Ermal
		/* Stop dynamic monitoring */
145 f8c10a18 Ermal
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
146 98c02cac Ermal
147 6c576b27 Ermal
		/* wait for process to die */
148 8f67a8e1 Scott Ullrich
		sleep(2);
149
150 ce0dbd72 Matt Smith
		/* IPSEC is off, shutdown enc interface.*/
151 52c9f9fa Ermal
		mwexec("/sbin/ifconfig enc0 down");
152 2f1e0311 Seth Mos
153 c520e3e3 Chris Buechler
		unlock($ipsecstartlock);
154 6a781df6 Ermal
		return 0;
155 7a683b46 Ermal LUÇI
	}
156 8f67a8e1 Scott Ullrich
157 d8cb5ff3 Ermal LUÇI
	$a_phase1 = $config['ipsec']['phase1'];
158
	$a_phase2 = $config['ipsec']['phase2'];
159
	$a_client = $config['ipsec']['client'];
160
161 7a683b46 Ermal LUÇI
	$certpath = "{$g['varetc_path']}/ipsec/ipsec.d/certs";
162
	$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts";
163
	$keypath = "{$g['varetc_path']}/ipsec/ipsec.d/private";
164 14ec7c4b Chris Buechler
	$crlpath = "{$g['varetc_path']}/ipsec/ipsec.d/crls";
165 7a683b46 Ermal LUÇI
166
	mwexec("/sbin/ifconfig enc0 up");
167 2c3ac0b3 jim-p
	$ipsec_vti_cleanup_ifs = array();
168 05591613 Ermal LUÇI
169 7a683b46 Ermal LUÇI
	/* needed for config files */
170 b5a4633f jim-p
	safe_mkdir("{$g['varetc_path']}/ipsec");
171
	safe_mkdir("{$g['varetc_path']}/ipsec/ipsec.d");
172
173 96d5ca11 Chris Buechler
	// delete these paths first to ensure old CAs, certs and CRLs aren't left behind. redmine #5238
174
	rmdir_recursive($capath);
175
	rmdir_recursive($keypath);
176
	rmdir_recursive($crlpath);
177
	rmdir_recursive($certpath);
178 b5a4633f jim-p
179
	safe_mkdir($capath);
180
	safe_mkdir($keypath);
181
	safe_mkdir($crlpath);
182
	safe_mkdir($certpath);
183
	safe_mkdir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts");
184
	safe_mkdir("{$g['varetc_path']}/ipsec/ipsec.d/acerts");
185
	safe_mkdir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts");
186
	safe_mkdir("{$g['varetc_path']}/ipsec/ipsec.d/reqs");
187 79262830 Phil Davis
188 680e4db5 Renato Botelho
	if (!file_exists("/usr/local/etc/ipsec.d") ||
189 03c4effd Renato Botelho
	    !is_link("/usr/local/etc/ipsec.d")) {
190 680e4db5 Renato Botelho
		if (file_exists("/usr/local/etc/ipsec.d")) {
191
			rmdir_recursive("/usr/local/etc/ipsec.d");
192
		}
193 03c4effd Renato Botelho
		@symlink("{$g['varetc_path']}/ipsec/ipsec.d",
194
		    "/usr/local/etc/ipsec.d");
195
	}
196 a095a1e5 Renato Botelho
	if (!file_exists("{$g['varetc_path']}/etc/strongswan.d") ||
197 65ed01c5 Renato Botelho
	    !is_link("{$g['varetc_path']}/etc/strongswan.d")) {
198 a095a1e5 Renato Botelho
		if (is_link("{$g['varetc_path']}/etc/strongswan.d")) {
199
			@unlink("{$g['varetc_path']}/etc/strongswan.d");
200
		} else {
201
			rmdir_recursive("{$g['varetc_path']}/etc/strongswan.d");
202
		}
203 65ed01c5 Renato Botelho
		@symlink("/usr/local/etc/strongswan.d",
204
		    "{$g['varetc_path']}/ipsec/strongswan.d");
205 03c4effd Renato Botelho
	}
206 b0e51046 Renato Botelho
	if (!file_exists("/usr/local/etc/strongswan.conf") ||
207 03c4effd Renato Botelho
	    !is_link("/usr/local/etc/strongswan.conf")) {
208
		@unlink("/usr/local/etc/strongswan.conf");
209
		@symlink("{$g['varetc_path']}/ipsec/strongswan.conf",
210
		    "/usr/local/etc/strongswan.conf");
211
	}
212 b0e51046 Renato Botelho
	if (!file_exists("/usr/local/etc/ipsec.conf") ||
213 03c4effd Renato Botelho
	    !is_link("/usr/local/etc/ipsec.conf")) {
214
		@unlink("/usr/local/etc/ipsec.conf");
215
		@symlink("{$g['varetc_path']}/ipsec/ipsec.conf",
216
		    "/usr/local/etc/ipsec.conf");
217
	}
218 e3afacbb Chris Buechler
219 79262830 Phil Davis
	if (platform_booting()) {
220 7a683b46 Ermal LUÇI
		echo gettext("Configuring IPsec VPN... ");
221 79262830 Phil Davis
	}
222 496acde1 Ermal
223 7a683b46 Ermal LUÇI
	/* resolve all local, peer addresses and setup pings */
224
	$ipmap = array();
225
	$rgmap = array();
226
	$filterdns_list = array();
227
	$aggressive_mode_psk = false;
228
	unset($iflist);
229 778d2ea9 Ermal LUÇI
	$ifacesuse = array();
230 6684d594 Matt Smith
	$mobile_ipsec_auth = "";
231 7a683b46 Ermal LUÇI
	if (is_array($a_phase1) && count($a_phase1)) {
232 8f67a8e1 Scott Ullrich
233 07ca0162 Stephen Jones
		$ipsecpinghosts = array();
234 7a683b46 Ermal LUÇI
		/* step through each phase1 entry */
235
		foreach ($a_phase1 as $ph1ent) {
236 79262830 Phil Davis
			if (isset($ph1ent['disabled'])) {
237 7a683b46 Ermal LUÇI
				continue;
238 79262830 Phil Davis
			}
239 8f67a8e1 Scott Ullrich
240 2a5960b0 Luiz Otavio O Souza
			if (substr($ph1ent['interface'], 0, 4) == "_vip") {
241
				$vpninterface = get_configured_vip_interface($ph1ent['interface']);
242
				$ifacesuse[] = get_real_interface($vpninterface);
243 79262830 Phil Davis
			} else {
244
				$vpninterface = get_failover_interface($ph1ent['interface']);
245 2a5960b0 Luiz Otavio O Souza
				if (substr($vpninterface, 0, 4) == "_vip") {
246
					$vpninterface = get_configured_vip_interface($vpninterface);
247
					$ifacesuse[] = get_real_interface($vpninterface);
248 79262830 Phil Davis
				} elseif (!empty($vpninterface)) {
249 121cde47 Ermal LUÇI
					$ifacesuse[] = $vpninterface;
250 79262830 Phil Davis
				}
251 121cde47 Ermal LUÇI
			}
252 79262830 Phil Davis
253
			if ($ph1ent['mode'] == "aggressive" && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
254 7a683b46 Ermal LUÇI
				$aggressive_mode_psk = true;
255 79262830 Phil Davis
			}
256 3462a529 Matthew Grooms
257 7a683b46 Ermal LUÇI
			$ikeid = $ph1ent['ikeid'];
258 979cd6db Scott Ullrich
259 7a683b46 Ermal LUÇI
			$ep = ipsec_get_phase1_src($ph1ent);
260 d1f69741 jim-p
			/* When automatically guessing, use the first address. */
261
			$ep  = explode(',', $ep);
262
			$ep  = $ep[0];
263 79262830 Phil Davis
			if (!is_ipaddr($ep)) {
264 51a14c58 Phil Davis
				log_error(sprintf(gettext("IPsec ERROR: Could not find phase 1 source for connection %s. Omitting from configuration file."), $ph1ent['descr']));
265 7a683b46 Ermal LUÇI
				continue;
266 79262830 Phil Davis
			}
267 7a683b46 Ermal LUÇI
268 086cf944 Phil Davis
			if (!in_array($ep, $ipmap)) {
269 7a683b46 Ermal LUÇI
				$ipmap[] = $ep;
270 79262830 Phil Davis
			}
271 7a683b46 Ermal LUÇI
272
			/* see if this tunnel has a hostname for the remote-gateway. If so,
273
			   try to resolve it now and add it to the list for filterdns */
274
275 79262830 Phil Davis
			if (isset ($ph1ent['mobile'])) {
276 6684d594 Matt Smith
				$mobile_ipsec_auth = $ph1ent['authentication_method'];
277 7a683b46 Ermal LUÇI
				continue;
278 79262830 Phil Davis
			}
279 7a683b46 Ermal LUÇI
280
			$rg = $ph1ent['remote-gateway'];
281
282
			if (!is_ipaddr($rg)) {
283
				$filterdns_list[] = "{$rg}";
284
				add_hostname_to_watch($rg);
285 79262830 Phil Davis
				if (!platform_booting()) {
286 7a683b46 Ermal LUÇI
					$rg = resolve_retry($rg);
287 79262830 Phil Davis
				}
288
				if (!is_ipaddr($rg)) {
289 829fa12e smos
					continue;
290 79262830 Phil Davis
				}
291 7a683b46 Ermal LUÇI
			}
292 79262830 Phil Davis
			if (array_search($rg, $rgmap)) {
293 51a14c58 Phil Davis
				log_error(sprintf(gettext("The remote gateway %s already exists on another phase 1 entry"), $rg));
294 7a683b46 Ermal LUÇI
				continue;
295
			}
296
			$rgmap[$ph1ent['remote-gateway']] = $rg;
297 8f67a8e1 Scott Ullrich
298 65767828 jim-p
			$is_vti = false;
299 7a683b46 Ermal LUÇI
			if (is_array($a_phase2)) {
300
				/* step through each phase2 entry */
301
				foreach ($a_phase2 as $ph2ent) {
302 65767828 jim-p
					if ($ph2ent['mode'] == 'vti') {
303
						$is_vti = true;
304
					}
305 79262830 Phil Davis
					if (isset($ph2ent['disabled'])) {
306 7a683b46 Ermal LUÇI
						continue;
307 79262830 Phil Davis
					}
308 a11df336 jim-p
309 79262830 Phil Davis
					if ($ikeid != $ph2ent['ikeid']) {
310 7a683b46 Ermal LUÇI
						continue;
311 79262830 Phil Davis
					}
312 a11df336 jim-p
313 7a683b46 Ermal LUÇI
					/* add an ipsec pinghosts entry */
314
					if ($ph2ent['pinghost']) {
315 79262830 Phil Davis
						if (!is_array($iflist)) {
316 7a683b46 Ermal LUÇI
							$iflist = get_configured_interface_list();
317 79262830 Phil Davis
						}
318 7a683b46 Ermal LUÇI
						$srcip = null;
319
						$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
320 79262830 Phil Davis
						if (is_ipaddrv6($ph2ent['pinghost'])) {
321 7a683b46 Ermal LUÇI
							foreach ($iflist as $ifent => $ifname) {
322
								$interface_ip = get_interface_ipv6($ifent);
323 79262830 Phil Davis
								if (!is_ipaddrv6($interface_ip)) {
324 7a683b46 Ermal LUÇI
									continue;
325 79262830 Phil Davis
								}
326 7a683b46 Ermal LUÇI
								if (ip_in_subnet($interface_ip, $local_subnet)) {
327
									$srcip = $interface_ip;
328
									break;
329 fb17f629 Seth Mos
								}
330 a11df336 jim-p
							}
331 7a683b46 Ermal LUÇI
						} else {
332
							foreach ($iflist as $ifent => $ifname) {
333
								$interface_ip = get_interface_ip($ifent);
334 79262830 Phil Davis
								if (!is_ipaddrv4($interface_ip)) {
335 7a683b46 Ermal LUÇI
									continue;
336 79262830 Phil Davis
								}
337 7a683b46 Ermal LUÇI
								if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) {
338
									$srcip = $interface_ip;
339
									break;
340 dc63467f Matt Smith
								}
341
							}
342 7a683b46 Ermal LUÇI
						}
343
						/* if no valid src IP was found in configured interfaces, try the vips */
344
						if (is_null($srcip)) {
345 2a5960b0 Luiz Otavio O Souza
							$viplist = get_configured_vip_list();
346
							foreach ($viplist as $vip => $address) {
347
								if (ip_in_subnet($address, $local_subnet)) {
348
									$srcip = $address;
349 7a683b46 Ermal LUÇI
									break;
350
								}
351 741077bc Ermal Lu?i
							}
352 87e07f52 mgrooms
						}
353 7a683b46 Ermal LUÇI
						$dstip = $ph2ent['pinghost'];
354 79262830 Phil Davis
						if (is_ipaddrv6($dstip)) {
355 7a683b46 Ermal LUÇI
							$family = "inet6";
356
						} else {
357
							$family = "inet";
358
						}
359 79262830 Phil Davis
						if (is_ipaddr($srcip)) {
360 7a683b46 Ermal LUÇI
							$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
361 d315b341 Chris Buechler
							$ipsecpinghostsactive = true;
362 79262830 Phil Davis
						}
363 17da6c79 Scott Ullrich
					}
364 a93e56c5 Matthew Grooms
				}
365
			}
366 65767828 jim-p
			if ($is_vti) {
367
				interface_ipsec_vti_configure($ph1ent);
368
			}
369 a93e56c5 Matthew Grooms
		}
370 7a683b46 Ermal LUÇI
		@file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
371
		unset($ipsecpinghosts);
372
	}
373
	unset($iflist);
374 74e45438 jim-p
	/* Build a list of all IPsec interfaces configured on the firewall at the OS level */
375
	foreach (get_interface_arr() as $thisif) {
376
		if (substr($thisif, 0, 5) == "ipsec") {
377
			$ipsec_vti_cleanup_ifs[] = $thisif;
378
		}
379
	}
380 496acde1 Ermal
381 7a683b46 Ermal LUÇI
	$accept_unencrypted = "";
382 79262830 Phil Davis
	if (isset($config['ipsec']['acceptunencryptedmainmode'])) {
383 7a683b46 Ermal LUÇI
		$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
384 79262830 Phil Davis
	}
385 737b18f2 Ermal
386 420fce04 Ermal LUÇI
	$stronconf = '';
387 79262830 Phil Davis
	if (file_exists("{$g['varetc_path']}/ipsec/strongswan.conf")) {
388 420fce04 Ermal LUÇI
		$stronconf = file_get_contents("{$g['varetc_path']}/ipsec/strongswan.conf");
389 79262830 Phil Davis
	}
390 420fce04 Ermal LUÇI
391 7a683b46 Ermal LUÇI
	$i_dont_care_about_security_and_use_aggressive_mode_psk = "";
392
	if ($aggressive_mode_psk) {
393
		log_error("WARNING: Setting i_dont_care_about_security_and_use_aggressive_mode_psk option because a phase 1 is configured using aggressive mode with pre-shared keys. This is not a secure configuration.");
394 79262830 Phil Davis
		if (!empty($stronconf) && strpos($stronconf, 'i_dont_care_about_security_and_use_aggressive_mode_psk') === FALSE) {
395 420fce04 Ermal LUÇI
			$restart = true;
396 79262830 Phil Davis
		}
397 7a683b46 Ermal LUÇI
		$i_dont_care_about_security_and_use_aggressive_mode_psk = "i_dont_care_about_security_and_use_aggressive_mode_psk=yes";
398 79262830 Phil Davis
	}
399 4a076e36 Ermal LUÇI
400 d9a17eaf Chris Buechler
	$unity_enabled = isset($config['ipsec']['unityplugin']) ? 'yes' : 'no';
401 4a076e36 Ermal LUÇI
402 0608bd3c Ermal LUÇI
	$makebeforebreak = '';
403
	if (isset($config['ipsec']['makebeforebreak'])) {
404
		$makebeforebreak = 'make_before_break = yes';
405
	}
406
407 24acc8f4 Chris Buechler
	if (isset($config['ipsec']['enableinterfacesuse'])) {
408
		if (!empty($ifacesuse)) {
409
			$ifacesuse = 'interfaces_use = ' . implode(',', array_unique($ifacesuse));
410
		} else {
411
			$ifacesuse = '';
412
		}
413 79262830 Phil Davis
	} else {
414 778d2ea9 Ermal LUÇI
		$ifacesuse = '';
415 79262830 Phil Davis
	}
416 778d2ea9 Ermal LUÇI
417 1c4540dc Ermal LUÇI
	unset($stronconf);
418 420fce04 Ermal LUÇI
419 31630f47 Chris Buechler
	$strongswanlog = "";
420 c53e411f Matt Smith
	$ipsecloglevels = vpn_logging_cfgtxt();
421 31630f47 Chris Buechler
	if (is_array($ipsecloglevels)) {
422
		foreach ($ipsecloglevels as $loglevel) {
423 62fb5808 Renato Botelho
			$strongswanlog .= "\t\t\t" . $loglevel . "\n";
424 31630f47 Chris Buechler
		}
425
	}
426 7a683b46 Ermal LUÇI
	$strongswan = <<<EOD
427 496acde1 Ermal
428 79262830 Phil Davis
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten.
429 496acde1 Ermal
starter {
430 03c4effd Renato Botelho
	load_warning = no
431
	config_file = {$g['varetc_path']}/ipsec/ipsec.conf
432 496acde1 Ermal
}
433
434
charon {
435 7a683b46 Ermal LUÇI
# number of worker threads in charon
436 62fb5808 Renato Botelho
	threads = 16
437
	ikesa_table_size = 32
438
	ikesa_table_segments = 4
439
	init_limit_half_open = 1000
440
	install_routes = no
441 2a44b0eb Renato Botelho
	load_modular = yes
442 4225416f Chris Buechler
	ignore_acquire_ts = yes
443 62fb5808 Renato Botelho
	{$i_dont_care_about_security_and_use_aggressive_mode_psk}
444
	{$accept_unencrypted}
445
	cisco_unity = {$unity_enabled}
446
	{$ifacesuse}
447
	{$makebeforebreak}
448
449
	syslog {
450
		identifier = charon
451
		# log everything under daemon since it ends up in the same place regardless with our syslog.conf
452
		daemon {
453
			ike_name = yes
454 31630f47 Chris Buechler
{$strongswanlog}
455 62fb5808 Renato Botelho
		}
456
		# disable logging under auth so logs aren't duplicated
457
		auth {
458
			default = -1
459
		}
460 7335fa53 Ermal
	}
461 c6efc8fd Ermal
462 03c4effd Renato Botelho
	plugins {
463 2a44b0eb Renato Botelho
		# Load defaults
464
		include {$g['varetc_path']}/ipsec/strongswan.d/charon/*.conf
465
466 03c4effd Renato Botelho
		stroke {
467
			secrets_file = {$g['varetc_path']}/ipsec/ipsec.secrets
468
		}
469 496acde1 Ermal
470 2a44b0eb Renato Botelho
		unity {
471
			load = {$unity_enabled}
472
		}
473
474 03c4effd Renato Botelho
EOD;
475 7a683b46 Ermal LUÇI
476 6684d594 Matt Smith
	/* Find RADIUS servers designated for Mobile IPsec user auth */
477
	$radius_server_txt = "";
478
	$user_sources = explode(',', $config['ipsec']['client']['user_source']);
479
	foreach ($user_sources as $user_source) {
480
		$auth_server = auth_get_authserver($user_source);
481 5a78cccc jim-p
		$nice_user_source = strtolower(preg_replace('/[\s\.]+/', '_', $user_source));
482 6684d594 Matt Smith
		if ($auth_server && $auth_server['type'] === 'radius') {
483
			$radius_server_txt .= <<<EOD
484
				{$nice_user_source} {
485
					address = {$auth_server['host']}
486 53e8d0a3 Jose Luis Duran
					secret = "{$auth_server['radius_secret']}"
487 6684d594 Matt Smith
					auth_port = {$auth_server['radius_auth_port']}
488
					acct_port = {$auth_server['radius_acct_port']}
489
				}
490
491
EOD;
492
		}
493
	}
494
495 1e0442e0 hamnur
	/* Activate RADIUS accounting if it was selected on the auth server view */
496
	$radius_accounting = "";
497
	if($auth_server && isset($auth_server['radius_acct_port'])){
498
		$radius_accounting = 'accounting = yes';
499
	}
500
501 6684d594 Matt Smith
	/* write an eap-radius config section if appropriate */
502
	if (strlen($radius_server_txt) && ($mobile_ipsec_auth === "eap-radius")) {
503
		$strongswan .= <<<EOD
504
		eap-radius {
505
			class_group = yes
506
			eap_start = no
507 1e0442e0 hamnur
			{$radius_accounting}
508 6684d594 Matt Smith
			servers {
509
{$radius_server_txt}
510
			}
511
		}
512
513
EOD;
514
	}
515
516 7a683b46 Ermal LUÇI
	if (is_array($a_client) && isset($a_client['enable'])) {
517
		$strongswan .= "\t\tattr {\n";
518 59a5679c Christian
		
519 7a683b46 Ermal LUÇI
		$cfgservers = array();
520 79262830 Phil Davis
		if (!empty($a_client['wins_server1'])) {
521 7a683b46 Ermal LUÇI
			$cfgservers[] = $a_client['wins_server1'];
522 79262830 Phil Davis
		}
523
		if (!empty($a_client['wins_server2'])) {
524 7a683b46 Ermal LUÇI
			$cfgservers[] = $a_client['wins_server2'];
525 79262830 Phil Davis
		}
526
		if (!empty($cfgservers)) {
527 7a683b46 Ermal LUÇI
			$strongswan .= "\t\t\tnbns = " . implode(",", $cfgservers) . "\n";
528 79262830 Phil Davis
		}
529 7a683b46 Ermal LUÇI
		unset($cfgservers);
530
531 588d3cf6 Renato Botelho
		if (isset($a_client['net_list']) && is_array($a_phase2)) {
532 7a683b46 Ermal LUÇI
			$net_list = '';
533
			foreach ($a_phase2 as $ph2ent) {
534 79262830 Phil Davis
				if (isset($ph2ent['disabled'])) {
535 7a683b46 Ermal LUÇI
					continue;
536 79262830 Phil Davis
				}
537 496acde1 Ermal
538 79262830 Phil Davis
				if (!isset($ph2ent['mobile'])) {
539 7a683b46 Ermal LUÇI
					continue;
540 79262830 Phil Davis
				}
541 496acde1 Ermal
542 7a683b46 Ermal LUÇI
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
543 496acde1 Ermal
544 79262830 Phil Davis
				if (!empty($net_list)) {
545 7a683b46 Ermal LUÇI
					$net_list .= ",";
546 79262830 Phil Davis
				}
547 7a683b46 Ermal LUÇI
				$net_list .= $localid;
548 496acde1 Ermal
			}
549
550 7a683b46 Ermal LUÇI
			if (!empty($net_list)) {
551 41f7b662 Matt Smith
				$strongswan .= "\t\t\tsubnet = {$net_list}\n";
552 7a683b46 Ermal LUÇI
				$strongswan .= "\t\t\tsplit-include = {$net_list}\n";
553
				unset($net_list);
554 496acde1 Ermal
			}
555 7a683b46 Ermal LUÇI
		}
556 496acde1 Ermal
557 7a683b46 Ermal LUÇI
		if (!empty($a_client['dns_domain'])) {
558
			$strongswan .= "\t\t\t# Search domain and default domain\n";
559 d17ad7f5 Ermal LUÇI
			$strongswan .= "\t\t\t28674 = \"{$a_client['dns_domain']}\"\n";
560 e1c4a5ff Ermal LUÇI
			if (empty($a_client['dns_split'])) {
561 d17ad7f5 Ermal LUÇI
				$strongswan .= "\t\t\t28675 = \"{$a_client['dns_domain']}\"";
562 e1c4a5ff Ermal LUÇI
			}
563 7a683b46 Ermal LUÇI
			$strongswan .= "\n";
564
		}
565 496acde1 Ermal
566 7a683b46 Ermal LUÇI
		if (!empty($a_client['dns_split'])) {
567 883096d8 Ermal LUÇI
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
568 7a683b46 Ermal LUÇI
		}
569 496acde1 Ermal
570 79262830 Phil Davis
		if (!empty($a_client['login_banner'])) {
571 d17ad7f5 Ermal LUÇI
			$strongswan .= "\t\t\t28672 = \"{$a_client['login_banner']}\"\n";
572 79262830 Phil Davis
		}
573 7a683b46 Ermal LUÇI
574 79262830 Phil Davis
		if (isset($a_client['save_passwd'])) {
575 7a683b46 Ermal LUÇI
			$strongswan .= "\t\t\t28673 = 1\n";
576 79262830 Phil Davis
		}
577 7a683b46 Ermal LUÇI
578 79262830 Phil Davis
		if ($a_client['pfs_group']) {
579 d17ad7f5 Ermal LUÇI
			$strongswan .= "\t\t\t28679 = \"{$a_client['pfs_group']}\"\n";
580 79262830 Phil Davis
		}
581 7a683b46 Ermal LUÇI
		$strongswan .= "\t\t}\n";
582
583
		if ($a_client['user_source'] != "none") {
584
			$strongswan .= "\t\txauth-generic {\n";
585
			$strongswan .= "\t\t\tscript = /etc/inc/ipsec.auth-user.php\n";
586
			$strongswan .= "\t\t\tauthcfg = ";
587
			$firstsed = 0;
588
			$authcfgs = explode(",", $a_client['user_source']);
589
			foreach ($authcfgs as $authcfg) {
590 79262830 Phil Davis
				if ($firstsed > 0) {
591 7a683b46 Ermal LUÇI
					$strongswan .= ",";
592 79262830 Phil Davis
				}
593
				if ($authcfg == "system") {
594 7a683b46 Ermal LUÇI
					$authcfg = "Local Database";
595 79262830 Phil Davis
				}
596 7a683b46 Ermal LUÇI
				$strongswan .= $authcfg;
597
				$firstsed = 1;
598 91287d1f Ermal
			}
599 7a683b46 Ermal LUÇI
			$strongswan .= "\n";
600
			$strongswan .= "\t\t}\n";
601 496acde1 Ermal
		}
602 7a683b46 Ermal LUÇI
	}
603 496acde1 Ermal
604 de985aea Renato Botelho
	$strongswan .= "\n\t}\n}\n";
605 7a683b46 Ermal LUÇI
	@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
606
	unset($strongswan);
607 8f67a8e1 Scott Ullrich
608 14ec7c4b Chris Buechler
	/* write out CRL files */
609
	if (is_array($config['crl']) && count($config['crl'])) {
610
		foreach ($config['crl'] as $crl) {
611
			if (!isset($crl['text'])) {
612 905205a2 Chris Buechler
				log_error(sprintf(gettext("Warning: Missing CRL data for %s"), $crl['descr']));
613 14ec7c4b Chris Buechler
				continue;
614
			}
615
			$fpath = "{$crlpath}/{$crl['refid']}.crl";
616
			if (!@file_put_contents($fpath, base64_decode($crl['text']))) {
617
				log_error(sprintf(gettext("Error: Cannot write IPsec CRL file for %s"), $crl['descr']));
618
				continue;
619
			}
620
		}
621
	}
622 09628a07 Renato Botelho
623 7a683b46 Ermal LUÇI
	$pskconf = "";
624 037b51b3 Seth Mos
625 9d8f66b9 Matt Smith
	$vpncas = array();
626 7a683b46 Ermal LUÇI
	if (is_array($a_phase1) && count($a_phase1)) {
627
		foreach ($a_phase1 as $ph1ent) {
628 a93e56c5 Matthew Grooms
629 79262830 Phil Davis
			if (isset($ph1ent['disabled'])) {
630 7a683b46 Ermal LUÇI
				continue;
631 79262830 Phil Davis
			}
632 a93e56c5 Matthew Grooms
633 07d0d1b2 Ermal LUÇI
			if (strstr($ph1ent['authentication_method'], 'rsa') ||
634 cb377516 Ingo Bauersachs
			    in_array($ph1ent['authentication_method'], array('eap-mschapv2', 'eap-tls', 'eap-radius'))) {
635 7a683b46 Ermal LUÇI
				$certline = '';
636 a93e56c5 Matthew Grooms
637 7a683b46 Ermal LUÇI
				$ikeid = $ph1ent['ikeid'];
638
				$cert = lookup_cert($ph1ent['certref']);
639 496acde1 Ermal
640 7a683b46 Ermal LUÇI
				if (!$cert) {
641
					log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
642
					continue;
643
				}
644 496acde1 Ermal
645 9d8f66b9 Matt Smith
				/* add signing CA cert chain of server cert
646
				 * to the list of CAs to write
647
				 */
648
				$cachain = ca_chain_array($cert);
649
				if ($cachain && is_array($cachain)) {
650
					foreach ($cachain as $cacrt) {
651
						$vpncas[$cacrt['refid']] = $cacrt;
652
					}
653
				}
654
655 7a683b46 Ermal LUÇI
				@chmod($certpath, 0600);
656 496acde1 Ermal
657 7a683b46 Ermal LUÇI
				$ph1keyfile = "{$keypath}/cert-{$ikeid}.key";
658
				if (!file_put_contents($ph1keyfile, base64_decode($cert['prv']))) {
659
					log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
660
					continue;
661
				}
662
				@chmod($ph1keyfile, 0600);
663 496acde1 Ermal
664 7a683b46 Ermal LUÇI
				$ph1certfile = "{$certpath}/cert-{$ikeid}.crt";
665
				if (!file_put_contents($ph1certfile, base64_decode($cert['crt']))) {
666
					log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name']));
667
					@unlink($ph1keyfile);
668
					continue;
669
				}
670
				@chmod($ph1certfile, 0600);
671 fa4e059e Ermal
672 7a683b46 Ermal LUÇI
				/* XXX" Traffic selectors? */
673
				$pskconf .= " : RSA {$ph1keyfile}\n";
674
			} else {
675 5324ea38 Ermal LUÇI
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
676
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
677 6990ad35 Phil Davis
678 d812e83e Chris Buechler
				$myid = trim($myid_data);
679 496acde1 Ermal
680 79262830 Phil Davis
				if (empty($peerid_data)) {
681 7a683b46 Ermal LUÇI
					continue;
682 79262830 Phil Davis
				}
683 496acde1 Ermal
684 019ee2bc Renato Botelho
				if ($myid_type == 'fqdn' && !empty($myid)) {
685
					$myid = "@{$myid}";
686
				}
687 6990ad35 Phil Davis
688 d44e7dc0 Chris Buechler
				$myid = isset($ph1ent['mobile']) ? trim($myid_data) : "%any";
689 019ee2bc Renato Botelho
690 5324ea38 Ermal LUÇI
				$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
691 019ee2bc Renato Botelho
692
				if ($peerid_type == 'fqdn' && !empty($peerid)) {
693
					$peerid = "@{$peerid}";
694
				}
695
696 13403bd1 Ermal LUÇI
				if (!empty($ph1ent['pre-shared-key'])) {
697 019ee2bc Renato Botelho
					$pskconf .= "{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
698 41d968bd Chris Buechler
					if (isset($ph1ent['mobile'])) {
699 af7c0311 jim-p
						$pskconf .= "{$myid} %any : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
700 41d968bd Chris Buechler
						$pskconf .= " : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
701
					}
702 13403bd1 Ermal LUÇI
				}
703 5b237745 Scott Ullrich
			}
704 9d8f66b9 Matt Smith
705
			/* if the client authenticates with a cert add the
706
			 * client cert CA chain to the list of CAs to write
707
			 */
708
			if (in_array($ph1ent['authentication_method'],
709
			array('rsasig', 'eap-tls', 'xauth_rsa_server'))) {
710
711
				if (!empty($ph1ent['caref']) && !array_key_exists($ph1ent['caref'], $vpncas)) {
712
					$thisca = lookup_ca($ph1ent['caref']);
713
					$vpncas[$ph1ent['caref']] = $thisca;
714
715
					/* follow chain up to root */
716
					$cachain = ca_chain_array($thisca);
717
					if ($cachain and is_array($cachain)) {
718
						foreach ($cachain as $cacrt) {
719
							$vpncas[$cacrt['refid']] = $cacrt;
720
						}
721
					}
722
				}
723
			}
724
		}
725
	}
726
727
	/* write the required CAs */
728
	foreach ($vpncas as $carefid => $cadata) {
729
		$cacrt = base64_decode($cadata['crt']);
730
		$cacrtattrs = openssl_x509_parse($cacrt);
731
		if (!is_array($cacrtattrs) || !isset($cacrtattrs['hash'])) {
732
			log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $cadata['descr']));
733
			continue;
734
		}
735
		$cafilename = "{$capath}/{$cacrtattrs['hash']}.0.crt";
736
		if (!@file_put_contents($cafilename, $cacrt)) {
737
				log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $cadata['descr']));
738
				continue;
739 a93e56c5 Matthew Grooms
		}
740 7a683b46 Ermal LUÇI
	}
741 a93e56c5 Matthew Grooms
742 7a683b46 Ermal LUÇI
	/* Add user PSKs */
743
	if (is_array($config['system']) && is_array($config['system']['user'])) {
744
		foreach ($config['system']['user'] as $user) {
745
			if (!empty($user['ipsecpsk'])) {
746 62102a8b Chris Buechler
				$pskconf .= "{$myid} {$user['name']} : PSK 0s" . base64_encode($user['ipsecpsk']) . "\n";
747 4ed2dde7 jim-p
			}
748
		}
749 7a683b46 Ermal LUÇI
		unset($user);
750
	}
751 4ed2dde7 jim-p
752 7a683b46 Ermal LUÇI
	/* add PSKs for mobile clients */
753
	if (is_array($ipseccfg['mobilekey'])) {
754
		foreach ($ipseccfg['mobilekey'] as $key) {
755 79262830 Phil Davis
			if ($key['ident'] == "allusers") {
756 7f69cbe7 Ermal LUÇI
				$key['ident'] = '%any';
757 79262830 Phil Davis
			}
758 a83fce46 Chris Buechler
			if ($key['ident'] == "any") {
759
				$key['ident'] = '%any';
760
			}
761 79262830 Phil Davis
			if (empty($key['type'])) {
762 10e2acb5 Ermal LUÇI
				$key['type'] = 'PSK';
763 79262830 Phil Davis
			}
764 b3b9c811 Chris Buechler
			$pskconf .= " {$key['ident']} : {$key['type']} 0s" . base64_encode($key['pre-shared-key']) . "\n";
765 2ef1b601 jim-p
		}
766 7a683b46 Ermal LUÇI
		unset($key);
767
	}
768 2ef1b601 jim-p
769 7a683b46 Ermal LUÇI
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
770
	chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
771
	unset($pskconf);
772 09628a07 Renato Botelho
773 86e1846f Ermal LUÇI
	$uniqueids = 'yes';
774
	if (!empty($config['ipsec']['uniqueids'])) {
775 086cf944 Phil Davis
		if (array_key_exists($config['ipsec']['uniqueids'], $ipsec_idhandling)) {
776 86e1846f Ermal LUÇI
			$uniqueids = $config['ipsec']['uniqueids'];
777 086cf944 Phil Davis
		}
778 86e1846f Ermal LUÇI
	}
779 7a683b46 Ermal LUÇI
	$natfilterrules = false;
780
	/* begin ipsec.conf */
781
	$ipsecconf = "";
782 40cc36d1 Ermal LUÇI
	$enablecompression = false;
783 6c07db48 Phil Davis
	if (is_array($a_phase1) && count($a_phase1)) {
784 17da6c79 Scott Ullrich
785 7a683b46 Ermal LUÇI
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
786 86e1846f Ermal LUÇI
		$ipsecconf .= "config setup\n\tuniqueids = {$uniqueids}\n";
787 6990ad35 Phil Davis
788 df4de32d Chris Buechler
		if (isset($config['ipsec']['strictcrlpolicy'])) {
789
			$ipsecconf .= "\tstrictcrlpolicy = yes \n";
790
		}
791 4178a1dd jim-p
792 0a9e6c85 Chris Buechler
		if (!isset($config['ipsec']['noshuntlaninterfaces'])) {
793 1dc6392b jim-p
			$bypassnets = array();
794 0887e836 Ermal LUÇI
			if ($config['interfaces']['lan']) {
795
				$lanip = get_interface_ip("lan");
796
				if (!empty($lanip) && is_ipaddrv4($lanip)) {
797
					$lansn = get_interface_subnet("lan");
798 1dc6392b jim-p
					$lansa = gen_subnetv4($lanip, $lansn);
799 fbdf0a08 jim-p
					if (!empty($lansa) && !empty($lansn)) {
800 1dc6392b jim-p
						$bypassnets[] = "{$lansa}/{$lansn}";
801
					}
802
				}
803
				$lanip6 = get_interface_ipv6("lan");
804
				if (!empty($lanip6) && is_ipaddrv6($lanip6)) {
805
					$lansn6 = get_interface_subnetv6("lan");
806
					$lansa6 = gen_subnetv6($lanip6, $lansn6);
807
					if (!empty($lansa6) && !empty($lansn6)) {
808
						$bypassnets[] = "{$lansa6}/{$lansn6}";
809
					}
810
				}
811
			}
812
			if (!empty($bypassnets)) {
813
				$bypass = implode(',', $bypassnets);
814
				$ipsecconf .= <<<EOD
815 755b75c7 Ermal LUÇI
816 0887e836 Ermal LUÇI
conn bypasslan
817 1dc6392b jim-p
	leftsubnet = {$bypass}
818
	rightsubnet = {$bypass}
819 0a9e6c85 Chris Buechler
	authby = never
820
	type = passthrough
821
	auto = route
822 0887e836 Ermal LUÇI
823
EOD;
824
			}
825
		}
826
827 7a683b46 Ermal LUÇI
		foreach ($a_phase1 as $ph1ent) {
828 79262830 Phil Davis
			if (isset($ph1ent['disabled'])) {
829 7a683b46 Ermal LUÇI
				continue;
830 79262830 Phil Davis
			}
831 96267107 Ermal
832 79262830 Phil Davis
			if ($ph1ent['mode'] == "aggressive") {
833 7a683b46 Ermal LUÇI
				$aggressive = "yes";
834 79262830 Phil Davis
			} else {
835 7a683b46 Ermal LUÇI
				$aggressive = "no";
836 79262830 Phil Davis
			}
837 7a683b46 Ermal LUÇI
838
			$ep = ipsec_get_phase1_src($ph1ent);
839 79262830 Phil Davis
			if (!$ep) {
840 7a683b46 Ermal LUÇI
				continue;
841 79262830 Phil Davis
			}
842 7a683b46 Ermal LUÇI
843
			$ikeid = $ph1ent['ikeid'];
844
			$keyexchange = "ikev1";
845
			$passive = "route";
846
			if (!empty($ph1ent['iketype'])) {
847
				if ($ph1ent['iketype'] == "ikev2") {
848
					$keyexchange = "ikev2";
849 f15f4c17 Chris Buechler
				} elseif ($ph1ent['iketype'] == "auto") {
850
					$keyexchange = "ike";
851 6990ad35 Phil Davis
				}
852 7a683b46 Ermal LUÇI
			}
853 0b5fc1d1 Ermal
854 7a683b46 Ermal LUÇI
			if (isset($ph1ent['mobile'])) {
855
				$right_spec = "%any";
856
				$passive = 'add';
857 95783403 Ermal LUÇI
			} else {
858 79262830 Phil Davis
				if (isset($ph1ent['responderonly'])) {
859 87808568 Ermal LUÇI
					$passive = 'add';
860 79262830 Phil Davis
				}
861 87808568 Ermal LUÇI
862 7a683b46 Ermal LUÇI
				$right_spec = $ph1ent['remote-gateway'];
863 79262830 Phil Davis
				if (is_ipaddr($right_spec)) {
864 7f9844c2 Ermal LUÇI
					$sourcehost = $right_spec;
865 79262830 Phil Davis
				} else {
866 ba969e67 Luiz Souza
					$sourcehost = $rgmap[$right_spec];
867 79262830 Phil Davis
				}
868 7f9844c2 Ermal LUÇI
869 ee908e93 PiBa-NL
				if (substr($ph1ent['interface'], 0, 4) == "_vip") {
870
					$vpninterface = get_configured_vip_interface($ph1ent['interface']);
871
					if (substr($vpninterface, 0, 4) == "_vip") {
872
						// vips are nested if its a ipalias with a carp parent
873
						$vpninterface = get_configured_vip_interface($vpninterface);
874
					}
875
					$ifacesuse = get_real_interface($vpninterface);
876
				} else {
877
					$ifacesuse = get_failover_interface($ph1ent['interface']);
878
					if (substr($ifacesuse, 0, 4) == "_vip") {
879
						$vpninterface = get_configured_vip_interface($ifacesuse);
880 2a5960b0 Luiz Otavio O Souza
						$ifacesuse = get_real_interface($vpninterface);
881 95783403 Ermal LUÇI
					} else {
882 ee908e93 PiBa-NL
						$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
883 95783403 Ermal LUÇI
					}
884 ee908e93 PiBa-NL
				}
885
				if ($ph1ent['protocol'] == 'inet') {
886 52b25e81 Ermal LUÇI
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
887 b61930dc Ermal LUÇI
						$gatewayip = get_interface_gateway($vpninterface);
888
						$interfaceip = get_interface_ip($vpninterface);
889
						$subnet_bits = get_interface_subnet($vpninterface);
890 95783403 Ermal LUÇI
						$subnet_ip = gen_subnetv4($interfaceip, $subnet_bits);
891
						/* if the remote gateway is in the local subnet, then don't add a route */
892 ba969e67 Luiz Souza
						if (is_ipaddrv4($sourcehost) &&
893
						    !ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
894 95783403 Ermal LUÇI
							if (is_ipaddrv4($gatewayip)) {
895 1e453232 Ermal LUÇI
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
896 94bd7fb3 Renato Botelho
								route_add_or_change("-host {$sourcehost} {$gatewayip}");
897 95783403 Ermal LUÇI
							}
898
						}
899
					}
900 c7d44786 Ermal LUÇI
				} else if ($ph1ent['protocol'] == 'inet6') {
901 ee908e93 PiBa-NL
					if (!empty($ifacesuse) && interface_has_gatewayv6($vpninterface)) {
902 b61930dc Ermal LUÇI
						$gatewayip = get_interface_gateway_v6($vpninterface);
903
						$interfaceip = get_interface_ipv6($vpninterface);
904
						$subnet_bits = get_interface_subnetv6($vpninterface);
905 95783403 Ermal LUÇI
						$subnet_ip = gen_subnetv6($interfaceip, $subnet_bits);
906
						/* if the remote gateway is in the local subnet, then don't add a route */
907 ba969e67 Luiz Souza
						if (is_ipaddrv6($sourcehost) &&
908
						    !ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
909 95783403 Ermal LUÇI
							if (is_ipaddrv6($gatewayip)) {
910 1e453232 Ermal LUÇI
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
911 94bd7fb3 Renato Botelho
								route_add_or_change("-inet6 -host {$sourcehost} {$gatewayip}");
912 95783403 Ermal LUÇI
							}
913
						}
914
					}
915
				}
916
			}
917 7a683b46 Ermal LUÇI
918 5324ea38 Ermal LUÇI
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
919 d9d237af Renato Botelho
			if ($myid_type != 'address' && $myid_type != 'keyid' && $myid_type != 'asn1dn') {
920 5324ea38 Ermal LUÇI
				$myid_data = "{$myid_type}:{$myid_data}";
921 d9d237af Renato Botelho
			} elseif ($myid_type == "asn1dn" && !empty($myid_data)) {
922
				if ($myid_data[0] == '#') {
923 d5dd538d Renato Botelho
				/* asn1dn needs double quotes */
924 d9d237af Renato Botelho
					$myid_data = "\"{$myid_type}:{$myid_data}\"";
925
				} else {
926
					$myid_data = "\"{$myid_data}\"";
927 d5dd538d Renato Botelho
				}
928 79262830 Phil Davis
			}
929 d9d237af Renato Botelho
			$leftid = '';
930
			if (!empty($myid_data)) {
931
				$leftid = "leftid = {$myid_data}";
932
			}
933 7a683b46 Ermal LUÇI
934
			$peerid_spec = '';
935 021a97b5 Chris Buechler
			if (isset($ph1ent['mobile']) && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
936
				// Only specify peer ID if we are not dealing with mobile PSK
937
			} else {
938 5324ea38 Ermal LUÇI
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
939 b0994811 Chris Buechler
				if ($peerid_type == 'any') {
940
					$peerid_spec = '';
941
				} elseif ($peerid_type != 'address' && $peerid_type != 'keyid' && $peerid_type != 'asn1dn') {
942 5324ea38 Ermal LUÇI
					$peerid_spec = "{$peerid_type}:{$peerid_data}";
943 d9d237af Renato Botelho
				} elseif ($peerid_type == "asn1dn") {
944 d5dd538d Renato Botelho
					/* asn1dn needs double quotes */
945 d9d237af Renato Botelho
					if ($peerid_data[0] == '#') {
946
						$peerid_spec = "\"{$peerid_type}:{$peerid_data}\"";
947
					} elseif (!empty($peerid_data)) {
948
						$peerid_spec = "\"{$peerid_data}\"";
949 d5dd538d Renato Botelho
					}
950 79262830 Phil Davis
				} else {
951 5324ea38 Ermal LUÇI
					$peerid_spec = $peerid_data;
952 79262830 Phil Davis
				}
953 5324ea38 Ermal LUÇI
			}
954 7a683b46 Ermal LUÇI
955 22dbacd0 PiBa-NL
			$ealgosp1 = '';
956
			if (is_array($ph1ent['encryption']['item'])) {
957
				$ciphers = "";
958
				foreach($ph1ent['encryption']['item'] as $p1enc) {
959
					if (!is_array($p1enc['encryption-algorithm']) ||
960
							empty($p1enc['encryption-algorithm']['name']) ||
961
							empty($p1enc['hash-algorithm'])) {
962
						continue;
963
					}
964
					$ciphers .= ",";
965
					$ciphers .= $p1enc['encryption-algorithm']['name'];
966
					$ealg_kl = $p1enc['encryption-algorithm']['keylen'];
967
					if ($ealg_kl) {
968
						$ciphers .= "{$ealg_kl}";
969
					}
970
					$ciphers .= "-{$p1enc['hash-algorithm']}";
971 0b5fc1d1 Ermal
972 22dbacd0 PiBa-NL
					$modp = vpn_ipsec_convert_to_modp($p1enc['dhgroup']);
973
					if (!empty($modp)) {
974
						$ciphers .= "-{$modp}";
975
					}
976 79262830 Phil Davis
				}
977 22dbacd0 PiBa-NL
				$ciphers = substr($ciphers, 1);
978
				$ealgosp1 = "ike = {$ciphers}!";
979 7a683b46 Ermal LUÇI
			}
980 c52719a8 Scott Ullrich
981 7a683b46 Ermal LUÇI
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
982 79262830 Phil Davis
				if ($passive == "route") {
983 7a683b46 Ermal LUÇI
					$dpdline = "dpdaction = restart";
984 79262830 Phil Davis
				} else {
985 7a683b46 Ermal LUÇI
					$dpdline = "dpdaction = clear";
986 79262830 Phil Davis
				}
987 7a683b46 Ermal LUÇI
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
988
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
989
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
990 79262830 Phil Davis
			} else {
991 7a683b46 Ermal LUÇI
				$dpdline = "dpdaction = none";
992 79262830 Phil Davis
			}
993 7a683b46 Ermal LUÇI
994
			$ikelifeline = '';
995 79262830 Phil Davis
			if ($ph1ent['lifetime']) {
996 7a683b46 Ermal LUÇI
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
997 79262830 Phil Davis
			}
998 7a683b46 Ermal LUÇI
999
			$rightsourceip = NULL;
1000 59a5679c Christian
			$rightdnsserver = NULL;
1001 86330e2b jim-p
			if (isset($ph1ent['mobile'])) {
1002 446db735 Matt Smith
				$rightsourceips = array();
1003 86330e2b jim-p
				if (!empty($a_client['pool_address'])) {
1004 446db735 Matt Smith
					$rightsourceips[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1005
				}
1006
				if (!empty($a_client['pool_address_v6'])) {
1007
					$rightsourceips[] = "{$a_client['pool_address_v6']}/{$a_client['pool_netbits_v6']}";
1008
				}
1009
				if ($ph1ent['authentication_method'] == "eap-radius" && !count($rightsourceips)) {
1010
					$rightsourceips[] = "%radius";
1011
				}
1012
				if (count($rightsourceips)) {
1013
					$rightsourceip = "\trightsourceip = " . implode(',', $rightsourceips) . "\n";
1014 86330e2b jim-p
				}
1015 59a5679c Christian
1016
				$rightdnsservers = array();
1017
				if (!empty($a_client['dns_server1'])) {
1018
					$rightdnsservers[] = $a_client['dns_server1'];
1019
				}
1020
				if (!empty($a_client['dns_server2'])) {
1021
					$rightdnsservers[] = $a_client['dns_server2'];
1022
				}
1023
				if (!empty($a_client['dns_server3'])) {
1024
					$rightdnsservers[] = $a_client['dns_server3'];
1025
				}
1026
				if (!empty($a_client['dns_server4'])) {
1027
					$rightdnsservers[] = $a_client['dns_server4'];
1028
				}
1029
				
1030
				if (count($rightdnsservers)) {
1031
					$rightdnsserver = "\trightdns = " . implode(',', $rightdnsservers) . "\n";
1032
				}
1033 79262830 Phil Davis
			}
1034 7a683b46 Ermal LUÇI
1035 7a7e1ba9 Matt Smith
			if (!empty($ph1ent['caref'])) {
1036
				$ca = lookup_ca($ph1ent['caref']);
1037
				if ($ca) {
1038
					$casubarr = cert_get_subject_array($ca['crt']);
1039
					$casub = "";
1040
					foreach ($casubarr as $casubfield) {
1041
						if (empty($casub)) {
1042
							$casub = "/";
1043
						}
1044 7e37da2e jim-p
						/* The subfield value could be an array. To avoid duplicating code,
1045
						 * always make it an array then iterate.
1046
						 * See https://redmine.pfsense.org/issues/7929
1047
						 */
1048
						if (!is_array($casubfield['v'])) {
1049
							$casubfield['v'] = array($casubfield['v']);
1050
						}
1051
						foreach ($casubfield['v'] as $casubval) {
1052
							$casub .= "{$casubfield['a']}={$casubval}/";
1053
						}
1054 7a7e1ba9 Matt Smith
					}
1055
1056
				}
1057
			}
1058
1059 7a683b46 Ermal LUÇI
			$authentication = "";
1060
			switch ($ph1ent['authentication_method']) {
1061 79262830 Phil Davis
				case 'eap-mschapv2':
1062
					if (isset($ph1ent['mobile'])) {
1063
						$authentication = "eap_identity=%any\n\t";
1064
						$authentication .= "leftauth=pubkey\n\trightauth=eap-mschapv2";
1065
						if (!empty($ph1ent['certref'])) {
1066
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1067 ce0dbd72 Matt Smith
							$authentication .= "\n\tleftsendcert=always";
1068 79262830 Phil Davis
						}
1069
					}
1070
					break;
1071
				case 'eap-tls':
1072
					if (isset($ph1ent['mobile'])) {
1073
						$authentication = "eap_identity=%identity\n\t";
1074
						$authentication .= "leftauth=pubkey\n\trightauth=eap-tls";
1075
						if (!empty($ph1ent['certref'])) {
1076
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1077 ce0dbd72 Matt Smith
							$authentication .= "\n\tleftsendcert=always";
1078 79262830 Phil Davis
						}
1079
					} else {
1080
						$authentication = "leftauth=eap-tls\n\trightauth=eap-tls";
1081
						if (!empty($ph1ent['certref'])) {
1082
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1083 ce0dbd72 Matt Smith
							$authentication .= "\n\tleftsendcert=always";
1084 79262830 Phil Davis
						}
1085 cb377516 Ingo Bauersachs
					}
1086 7a7e1ba9 Matt Smith
					if (isset($casub)) {
1087
						$authentication .= "\n\trightca=\"$casub\"";
1088
					}
1089 cb377516 Ingo Bauersachs
					break;
1090
				case 'eap-radius':
1091
					if (isset($ph1ent['mobile'])) {
1092
						$authentication = "eap_identity=%identity\n\t";
1093
						$authentication .= "leftauth=pubkey\n\trightauth=eap-radius";
1094 086cf944 Phil Davis
						if (!empty($ph1ent['certref'])) {
1095 cb377516 Ingo Bauersachs
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1096 ce0dbd72 Matt Smith
							$authentication .= "\n\tleftsendcert=always";
1097 086cf944 Phil Davis
						}
1098 cb377516 Ingo Bauersachs
					} else {
1099
						$authentication = "leftauth=eap-radius\n\trightauth=eap-radius";
1100
						if (!empty($ph1ent['certref'])) {
1101
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1102 ce0dbd72 Matt Smith
							$authentication .= "\n\tleftsendcert=always";
1103 cb377516 Ingo Bauersachs
						}
1104 79262830 Phil Davis
					}
1105
					break;
1106
				case 'xauth_rsa_server':
1107
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
1108
					$authentication .= "\n\trightauth2 = xauth-generic";
1109
					if (!empty($ph1ent['certref'])) {
1110 10e2acb5 Ermal LUÇI
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1111 7951cab4 Chris Buechler
						$authentication .= "\n\tleftsendcert=always";
1112 79262830 Phil Davis
					}
1113 7a7e1ba9 Matt Smith
					if (isset($casub)) {
1114
						$authentication .= "\n\trightca=\"$casub\"";
1115
					}
1116 79262830 Phil Davis
					break;
1117
				case 'xauth_psk_server':
1118
					$authentication = "leftauth = psk\n\trightauth = psk";
1119
					$authentication .= "\n\trightauth2 = xauth-generic";
1120
					break;
1121
				case 'pre_shared_key':
1122
					$authentication = "leftauth = psk\n\trightauth = psk";
1123
					break;
1124
				case 'rsasig':
1125
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
1126
					if (!empty($ph1ent['certref'])) {
1127 54ab1bdc Ermal LUÇI
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1128 7951cab4 Chris Buechler
						$authentication .= "\n\tleftsendcert=always";
1129 79262830 Phil Davis
					}
1130 7a7e1ba9 Matt Smith
					if (isset($casub)) {
1131
						$authentication .= "\n\trightca=\"$casub\"";
1132
					}
1133 79262830 Phil Davis
					break;
1134
				case 'hybrid_rsa_server':
1135 7b1e6c3a Matt Smith
					$authentication = "leftauth = pubkey\n\trightauth = xauth-generic";
1136 79262830 Phil Davis
					if (!empty($ph1ent['certref'])) {
1137 54ab1bdc Ermal LUÇI
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1138 7951cab4 Chris Buechler
						$authentication .= "\n\tleftsendcert=always";
1139 79262830 Phil Davis
					}
1140
					break;
1141 7a683b46 Ermal LUÇI
			}
1142 b4ad5b1c Ermal
1143 7a683b46 Ermal LUÇI
			$left_spec = $ep;
1144 c52719a8 Scott Ullrich
1145 79262830 Phil Davis
			if (isset($ph1ent['reauth_enable'])) {
1146 7a683b46 Ermal LUÇI
				$reauth = "reauth = no";
1147 79262830 Phil Davis
			} else {
1148 7a683b46 Ermal LUÇI
				$reauth = "reauth = yes";
1149 79262830 Phil Davis
			}
1150 e18ddb38 hamnur
1151 376e6f67 hamnur
			if (isset($ph1ent['rekey_enable'])) {
1152 e18ddb38 hamnur
				$rekeyline = "rekey = no";
1153 376e6f67 hamnur
			} else {
1154
				$rekeyline = "rekey = yes";
1155
				if(!empty($ph1ent['margintime'])){
1156
					$rekeyline .= "\n\tmargintime = {$ph1ent['margintime']}s";
1157
				}
1158 79262830 Phil Davis
			}
1159 16c02722 Ermal
1160 79262830 Phil Davis
			if ($ph1ent['nat_traversal'] == 'off') {
1161 7a683b46 Ermal LUÇI
				$forceencaps = 'forceencaps = no';
1162 79262830 Phil Davis
			} else if ($ph1ent['nat_traversal'] == 'force') {
1163 7a683b46 Ermal LUÇI
				$forceencaps = 'forceencaps = yes';
1164 79262830 Phil Davis
			} else {
1165 7a683b46 Ermal LUÇI
				$forceencaps = 'forceencaps = no';
1166 79262830 Phil Davis
			}
1167
1168
			if ($ph1ent['mobike'] == 'on') {
1169 065e78b3 Chris Buechler
				$mobike = 'mobike = yes';
1170 79262830 Phil Davis
			} else {
1171 065e78b3 Chris Buechler
				$mobike = 'mobike = no';
1172 79262830 Phil Davis
			}
1173 7a683b46 Ermal LUÇI
1174 54c36056 Chris Buechler
			if (isset($ph1ent['tfc_enable'])) {
1175
				if (isset($ph1ent['tfc_bytes']) && is_numericint($ph1ent['tfc_bytes'])) {
1176
					$tfc = "tfc = {$ph1ent['tfc_bytes']}";
1177
				} else {
1178
					$tfc = "tfc = %mtu";
1179
				}
1180
			}
1181
1182 7a683b46 Ermal LUÇI
			$ipseclifetime = 0;
1183
			$rightsubnet_spec = array();
1184
			$leftsubnet_spec = array();
1185 1fe208ec Ermal LUÇI
			$reqids = array();
1186 50c4282d jim-p
			$vtireq = array();
1187 7a683b46 Ermal LUÇI
			$ealgoAHsp2arr = array();
1188
			$ealgoESPsp2arr = array();
1189 1e678c38 Renato Botelho
			if (is_array($a_phase2) && count($a_phase2)) {
1190
				foreach ($a_phase2 as $ph2ent) {
1191
					if ($ikeid != $ph2ent['ikeid']) {
1192
						continue;
1193
					}
1194 c52719a8 Scott Ullrich
1195 1e678c38 Renato Botelho
					if (isset($ph2ent['disabled'])) {
1196
						continue;
1197
					}
1198 6586b30f Ermal
1199 1e678c38 Renato Botelho
					if (isset($ph2ent['mobile']) && !isset($a_client['enable'])) {
1200
						continue;
1201
					}
1202 96ef83a7 jim-p
1203 1e678c38 Renato Botelho
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
1204
						$tunneltype = "type = tunnel";
1205 50c4282d jim-p
						$installpolicy = "installpolicy = yes";
1206 c52719a8 Scott Ullrich
1207 1e678c38 Renato Botelho
						$localid_type = $ph2ent['localid']['type'];
1208
						$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
1209 d8cb5ff3 Ermal LUÇI
1210 1e678c38 Renato Botelho
						/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
1211
						if (($localid_type == "none" || $localid_type == "mobile") &&
1212
						    isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ikeid) == 1)) {
1213
							$left_spec = '%any';
1214
						} else {
1215
							if ($localid_type != "address") {
1216
								$localid_type = "subnet";
1217
							}
1218
							// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
1219
							if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) {
1220
								log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
1221
								continue;
1222
							}
1223
							if (!empty($ph2ent['natlocalid'])) {
1224
								$natleftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
1225
								if ($ph2ent['natlocalid']['type'] != "address") {
1226
									if (is_subnet($natleftsubnet_data)) {
1227
										$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
1228
									}
1229
								} else {
1230
									if (is_ipaddr($natleftsubnet_data)) {
1231
										$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
1232
									}
1233 79262830 Phil Davis
								}
1234 1e678c38 Renato Botelho
								$natfilterrules = true;
1235 3c107b76 Ermal
							}
1236 20699f3f jim-p
						}
1237 3462a529 Matthew Grooms
1238 1e678c38 Renato Botelho
						$leftsubnet_spec[] = $leftsubnet_data;
1239 0b5fc1d1 Ermal
1240 1e678c38 Renato Botelho
						if (!isset($ph2ent['mobile'])) {
1241
							$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
1242
							$rightsubnet_spec[] = $tmpsubnet;
1243
						} else if (!empty($a_client['pool_address'])) {
1244
							$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1245
						}
1246 50c4282d jim-p
					} elseif ($ph2ent['mode'] == 'vti') {
1247
						$tunneltype = "";
1248
						$installpolicy = "installpolicy = no";
1249
						$passive = 'start';
1250
1251
						$localid_type = $ph2ent['localid']['type'];
1252
						$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
1253
						$leftsubnet_spec[] = $leftsubnet_data;
1254
1255
						$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
1256
						$rightsubnet_spec[] = $tmpsubnet;
1257
						$vtireq[] = $ph2ent['reqid'];
1258 7a683b46 Ermal LUÇI
					} else {
1259 1e678c38 Renato Botelho
						$tunneltype = "type = transport";
1260 50c4282d jim-p
						$installpolicy = "installpolicy = yes";
1261 1e678c38 Renato Botelho
1262
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
1263
						    ($ph1ent['authentication_method'] == "pre_shared_key")) &&
1264
						    isset($ph1ent['mobile'])) {
1265
							$left_spec = "%any";
1266
						} else {
1267
							$tmpsubnet = ipsec_get_phase1_src($ph1ent);
1268
							$leftsubnet_spec[] = $tmpsubnet;
1269
						}
1270 0b5fc1d1 Ermal
1271 1e678c38 Renato Botelho
						if (!isset($ph2ent['mobile'])) {
1272
							$rightsubnet_spec[] = $right_spec;
1273
						}
1274 3462a529 Matthew Grooms
					}
1275 c52719a8 Scott Ullrich
1276 1e678c38 Renato Botelho
					if (isset($a_client['pfs_group']) && isset($ph2ent['mobile'])) {
1277
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
1278
					}
1279 7a683b46 Ermal LUÇI
1280 1e678c38 Renato Botelho
					if ($ph2ent['protocol'] == 'esp') {
1281
						if (is_array($ph2ent['encryption-algorithm-option'])) {
1282
							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
1283
								$ealg_id = $ealg['name'];
1284
								$ealg_kl = $ealg['keylen'];
1285 7a683b46 Ermal LUÇI
1286 1e678c38 Renato Botelho
								if (!empty($ealg_kl) && $ealg_kl == "auto") {
1287
									if (empty($p2_ealgos) || !is_array($p2_ealgos)) {
1288 c81ef6e2 Phil Davis
										require_once("ipsec.inc");
1289 1e678c38 Renato Botelho
									}
1290
									$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
1291
									$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
1292
									$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
1293
									/* XXX: in some cases where include ordering is suspect these variables
1294
									 * are somehow 0 and we enter this loop forever and timeout after 900
1295
									 * seconds wrecking bootup */
1296
									if ($key_hi != 0 and $key_lo != 0 and $key_step != 0) {
1297
										for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
1298
											if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1299
												foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1300
													$halgo = str_replace('hmac_', '', $halgo);
1301
													$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
1302
													$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1303
													if (!empty($modp)) {
1304
														$tmpealgo .= "-{$modp}";
1305
													}
1306
													$ealgoESPsp2arr[] = $tmpealgo;
1307
												}
1308
											} else {
1309
												$tmpealgo = "{$ealg_id}{$keylen}";
1310 496acde1 Ermal
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1311 79262830 Phil Davis
												if (!empty($modp)) {
1312 496acde1 Ermal
													$tmpealgo .= "-{$modp}";
1313 79262830 Phil Davis
												}
1314 0b5fc1d1 Ermal
												$ealgoESPsp2arr[] = $tmpealgo;
1315 496acde1 Ermal
											}
1316 1e678c38 Renato Botelho
										}
1317
									}
1318
								} else {
1319
									if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1320
										foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1321
											$halgo = str_replace('hmac_', '', $halgo);
1322
											$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
1323 c650b2f7 Ermal
											$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1324 79262830 Phil Davis
											if (!empty($modp)) {
1325 c650b2f7 Ermal
												$tmpealgo .= "-{$modp}";
1326 79262830 Phil Davis
											}
1327 c650b2f7 Ermal
											$ealgoESPsp2arr[] = $tmpealgo;
1328
										}
1329 1e678c38 Renato Botelho
									} else {
1330
										$tmpealgo = "{$ealg_id}{$ealg_kl}";
1331 496acde1 Ermal
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1332 79262830 Phil Davis
										if (!empty($modp)) {
1333 496acde1 Ermal
											$tmpealgo .= "-{$modp}";
1334 79262830 Phil Davis
										}
1335 0b5fc1d1 Ermal
										$ealgoESPsp2arr[] = $tmpealgo;
1336 496acde1 Ermal
									}
1337 a93e56c5 Matthew Grooms
								}
1338 979cd6db Scott Ullrich
							}
1339 496acde1 Ermal
						}
1340 1e678c38 Renato Botelho
					} else if ($ph2ent['protocol'] == 'ah') {
1341
						if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1342
							$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1343
							foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
1344
								$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
1345
								if (!empty($modp)) {
1346
									$tmpAHalgo = "-{$modp}";
1347
								}
1348
								$ealgoAHsp2arr[] = $tmpAHalgo;
1349 79262830 Phil Davis
							}
1350 a93e56c5 Matthew Grooms
						}
1351 a63f7d55 Scott Ullrich
					}
1352 c52719a8 Scott Ullrich
1353 1e678c38 Renato Botelho
					$reqids[] = $ph2ent['reqid'];
1354 e8f7e051 jim-p
					if ($ph2ent['mode'] != 'vti') {
1355
						$vtireq[] = null;
1356
					}
1357 4b96b367 mgrooms
1358 1e678c38 Renato Botelho
					if (!empty($ph2ent['lifetime'])) {
1359
						if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) {
1360
							$ipseclifetime = intval($ph2ent['lifetime']);
1361
						}
1362 79262830 Phil Davis
					}
1363 7a683b46 Ermal LUÇI
1364 1e678c38 Renato Botelho
				}
1365 0b5fc1d1 Ermal
			}
1366 496acde1 Ermal
1367 d8cb5ff3 Ermal LUÇI
			$ipsecconnect =<<<EOD
1368 0b7f174c Ermal LUÇI
	fragmentation = yes
1369
	keyexchange = {$keyexchange}
1370
	{$reauth}
1371
	{$forceencaps}
1372 065e78b3 Chris Buechler
	{$mobike}
1373 54c36056 Chris Buechler
	{$tfc}
1374 e18ddb38 hamnur
	{$rekeyline}
1375 50c4282d jim-p
	{$installpolicy}
1376 0b7f174c Ermal LUÇI
	{$tunneltype}
1377
	{$dpdline}
1378
	auto = {$passive}
1379
	left = {$left_spec}
1380
	right = {$right_spec}
1381 d9d237af Renato Botelho
	{$leftid}
1382 5b237745 Scott Ullrich
1383
EOD;
1384 4b96b367 mgrooms
1385 c7759e4e Chris Buechler
			/* Disable ipcomp for now. redmine #6167
1386 e57a3e40 Chris Buechler
			if (isset($config['ipsec']['compression'])) {
1387 2a691e34 Chris Buechler
				$ipsecconnect .= "\tcompress = yes\n";
1388 40cc36d1 Ermal LUÇI
				$enablecompression = true;
1389 c7759e4e Chris Buechler
			} */
1390 79262830 Phil Davis
			if (!empty($ikelifeline)) {
1391 d8cb5ff3 Ermal LUÇI
				$ipsecconnect .= "\t{$ikelifeline}\n";
1392 79262830 Phil Davis
			}
1393
			if ($ipseclifetime > 0) {
1394 d8cb5ff3 Ermal LUÇI
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
1395 79262830 Phil Davis
			}
1396
			if (!empty($rightsourceip)) {
1397 d8cb5ff3 Ermal LUÇI
				$ipsecconnect .= "{$rightsourceip}";
1398 79262830 Phil Davis
			}
1399 59a5679c Christian
			if (!empty($rightdnsserver)) {
1400
				$ipsecconnect .= "{$rightdnsserver}";
1401
			}
1402 79262830 Phil Davis
			if (!empty($ealgosp1)) {
1403 d8cb5ff3 Ermal LUÇI
				$ipsecconnect .= "\t{$ealgosp1}\n";
1404 79262830 Phil Davis
			}
1405
			if (!empty($ealgoAHsp2arr)) {
1406 d8cb5ff3 Ermal LUÇI
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
1407 79262830 Phil Davis
			}
1408
			if (!empty($ealgoESPsp2arr)) {
1409 d8cb5ff3 Ermal LUÇI
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
1410 79262830 Phil Davis
			}
1411
			if (!empty($authentication)) {
1412 d8cb5ff3 Ermal LUÇI
				$ipsecconnect .= "\t{$authentication}\n";
1413 79262830 Phil Davis
			}
1414
			if (!empty($peerid_spec)) {
1415 d8cb5ff3 Ermal LUÇI
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
1416 79262830 Phil Davis
			}
1417 03de0c24 Chris Buechler
			if ($keyexchange != 'ikev2') {
1418 d8cb5ff3 Ermal LUÇI
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
1419 79262830 Phil Davis
			}
1420 d8cb5ff3 Ermal LUÇI
1421 9d51fcde Chris Buechler
			if (!isset($ph1ent['mobile']) && ($keyexchange == 'ikev1' || isset($ph1ent['splitconn']))) {
1422 d8cb5ff3 Ermal LUÇI
				if (!empty($rightsubnet_spec)) {
1423
					$ipsecfin = '';
1424
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
1425
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
1426 b27fdc8b Ermal LUÇI
						//if (!empty($reqids[$idx])) {
1427
						//	$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
1428 d55e91c1 Chris Buechler
						//}
1429 17dfb092 jim-p
						$rightadd = "";
1430
						$leftadd = "";
1431 50c4282d jim-p
						if (!empty($vtireq[$idx])) {
1432 235c051f jim-p
							$ipsecfin .= "\treqid = {$ph1ent['ikeid']}00{$idx}\n";
1433 2c3ac0b3 jim-p
							/* This interface will be a valid IPsec interface, so remove it from the cleanup list. */
1434
							$ipsec_vti_cleanup_ifs = array_diff($ipsec_vti_cleanup_ifs, array("ipsec{$ph1ent['ikeid']}00{$idx}"));
1435 17dfb092 jim-p
							$rightadd = ",0.0.0.0/0";
1436
							$leftadd = ",0.0.0.0/0";
1437 50c4282d jim-p
						}
1438 d8cb5ff3 Ermal LUÇI
						$ipsecfin .= $ipsecconnect;
1439 17dfb092 jim-p
						$ipsecfin .= "\trightsubnet = {$rsubnet}{$rightadd}\n";
1440
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "{$leftadd}\n";
1441 d8cb5ff3 Ermal LUÇI
					}
1442 79262830 Phil Davis
				} else {
1443 51a14c58 Phil Davis
					log_error(sprintf(gettext("No phase2 specifications for tunnel with REQID = %s"), $ikeid));
1444 79262830 Phil Davis
				}
1445 d8cb5ff3 Ermal LUÇI
			} else {
1446 d2a8a7e7 Christian
				if (isset($ph1ent['mobile'])) {
1447
					$ipsecfin = "\nconn con-mobile\n";
1448
				}
1449
				else {
1450 d4b43c48 jim-p
					$ipsecfin = "\nconn con{$ph1ent['ikeid']}000\n";
1451 d2a8a7e7 Christian
				}
1452 b27fdc8b Ermal LUÇI
				//if (!empty($reqids[$idx])) {
1453
				//	$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
1454 d55e91c1 Chris Buechler
				//}
1455 17dfb092 jim-p
				$rightadd = "";
1456
				$leftadd = "";
1457 2c3ac0b3 jim-p
				if (!empty($vtireq[0])) {
1458 235c051f jim-p
					$ipsecfin .= "\treqid = {$ph1ent['ikeid']}000\n";
1459 2c3ac0b3 jim-p
					/* This interface will be a valid IPsec interface, so remove it from the cleanup list. */
1460
					$ipsec_vti_cleanup_ifs = array_diff($ipsec_vti_cleanup_ifs, array("ipsec{$ph1ent['ikeid']}000"));
1461 17dfb092 jim-p
					$rightadd = ",0.0.0.0/0";
1462
					$leftadd = ",0.0.0.0/0";
1463 50c4282d jim-p
				}
1464 d8cb5ff3 Ermal LUÇI
				$ipsecfin .= $ipsecconnect;
1465 bfcb1e4a Ermal LUÇI
				if (!isset($ph1ent['mobile']) && !empty($rightsubnet_spec)) {
1466 d8cb5ff3 Ermal LUÇI
					$tempsubnets = array();
1467 79262830 Phil Davis
					foreach ($rightsubnet_spec as $rightsubnet) {
1468 d8cb5ff3 Ermal LUÇI
						$tempsubnets[$rightsubnet] = $rightsubnet;
1469 79262830 Phil Davis
					}
1470 17dfb092 jim-p
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "{$rightadd}\n";
1471 d8cb5ff3 Ermal LUÇI
					unset($tempsubnets, $rightsubnet);
1472
				}
1473
				if (!empty($leftsubnet_spec)) {
1474
					$tempsubnets = array();
1475 79262830 Phil Davis
					foreach ($leftsubnet_spec as $leftsubnet) {
1476 d8cb5ff3 Ermal LUÇI
						$tempsubnets[$leftsubnet] = $leftsubnet;
1477 79262830 Phil Davis
					}
1478 17dfb092 jim-p
					$ipsecfin .= "\tleftsubnet = " . join(",", $tempsubnets) . "{$leftadd}\n";
1479 d8cb5ff3 Ermal LUÇI
					unset($tempsubnets, $leftsubnet);
1480
				}
1481
			}
1482
			$ipsecconf .= $ipsecfin;
1483
			unset($ipsecfin);
1484 a93e56c5 Matthew Grooms
		}
1485 496acde1 Ermal
	}
1486 7a683b46 Ermal LUÇI
1487 6e14487b Christian
	$a_mobilekey = $config['ipsec']['mobilekey'];
1488
1489
	if (is_array($a_phase1) && count($a_phase1)) {
1490
		foreach ($a_phase1 as $ph1ent) {
1491
			if (!isset($ph1ent['mobile'])) {
1492
				continue;
1493
			}
1494
			if (isset($ph1ent['disabled'])) {
1495
				continue;
1496
			}
1497
1498
			if (is_array($a_mobilekey) && count($a_mobilekey)) {
1499
				$ipsecfin = '';
1500
				$mobilekey_counter = 1;
1501
				foreach ($a_mobilekey as $mkent) {
1502
					if ($mkent['type'] != "EAP") {
1503
						continue;
1504
					}
1505
1506 8e461d38 Christian
					if (!isset($mkent['ident_type']) || !isset($mkent['pool_address']) || !isset($mkent['pool_netbits'])) {
1507
						continue;
1508
					}
1509
1510 bbc752e1 Christian
					if (strlen($mkent['pool_address']) < 1 || !is_ipaddr($mkent['pool_address'])) {
1511 6e14487b Christian
						continue;
1512
					}
1513 b950e991 jim-p
					$clientid = ($mkent['ident_type'] == "none") ? "\"{$mkent['ident']}\"" : "{$mkent['ident_type']}:{$mkent['ident']}";
1514
					$clienteapid = ($ph1ent['authentication_method'] == "eap-mschapv2") ? $clientid : '%identity';
1515 6e14487b Christian
					$ipsecfin .= "\nconn mobile-{$mobilekey_counter}\n";
1516
					$ipsecfin .= "\talso = con-mobile\n";
1517 b950e991 jim-p
					$ipsecfin .= "\teap_identity = {$clienteapid}\n";
1518 6e14487b Christian
					$ipsecfin .= "\trightsourceip = {$mkent['pool_address']}/{$mkent['pool_netbits']}\n";
1519 8e461d38 Christian
1520 bbc752e1 Christian
					if (isset($mkent['dns_address']) && strlen($mkent['dns_address']) > 0 && is_ipaddr($mkent['dns_address'])) {
1521
						$ipsecfin .= "\trightdns = {$mkent['dns_address']}\n";
1522
					}
1523
1524 b950e991 jim-p
					$ipsecfin .= "\trightid = {$clientid}\n";
1525 6e14487b Christian
1526
					// optional: define left|rightid more granular
1527
					// supported: ipv4, ipv6, rfc822, email, userfqdn, fqdn, dns, asn1dn, asn1gn, keyid
1528
					// example: $ipsecfin = "\trightid = email:your@email.address\n";
1529
1530
					// note: comma seperated list for access restriction, regardless of firewall rules
1531
					// example: $ipsecfin = "\tleftsubnet = 1.1.1.1/32,1.1.1.2/32,2.2.2.0/24\n";
1532
1533
					$mobilekey_counter++;
1534
				}
1535
				$ipsecconf .= $ipsecfin;
1536
				unset($ipsecfin);
1537
				unset($mobilekey_counter);
1538
			}
1539
		}
1540
	}
1541
1542 496acde1 Ermal
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1543
	unset($ipsecconf);
1544 6c576b27 Ermal
	/* end ipsec.conf */
1545 496acde1 Ermal
1546 2c3ac0b3 jim-p
	foreach ($ipsec_vti_cleanup_ifs as $cleanif) {
1547
		if (does_interface_exist($cleanif)) {
1548
			mwexec("/sbin/ifconfig " . escapeshellarg($cleanif) . " destroy", false);
1549
		}
1550
	}
1551
1552 79262830 Phil Davis
	if ($enablecompression === true) {
1553 40cc36d1 Ermal LUÇI
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1554 79262830 Phil Davis
	} else {
1555 40cc36d1 Ermal LUÇI
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1556 79262830 Phil Davis
	}
1557 40cc36d1 Ermal LUÇI
1558 79262830 Phil Davis
	/* manage process */
1559 420fce04 Ermal LUÇI
	if ($restart === true) {
1560 bc771514 Renato Botelho
		mwexec("/usr/local/sbin/ipsec restart", false);
1561 496acde1 Ermal
	} else {
1562 7370c469 Ermal LUÇI
		if (isvalidpid("{$g['varrun_path']}/starter.charon.pid")) {
1563 420fce04 Ermal LUÇI
			/* Update configuration changes */
1564 7370c469 Ermal LUÇI
			/* Read secrets */
1565 9edeadc5 Renato Botelho
			mwexec("/usr/local/sbin/ipsec rereadall", false);
1566 96072f52 Renato Botelho
			mwexec("/usr/local/sbin/ipsec reload", false);
1567 420fce04 Ermal LUÇI
		} else {
1568 bc771514 Renato Botelho
			mwexec("/usr/local/sbin/ipsec start", false);
1569 420fce04 Ermal LUÇI
		}
1570 496acde1 Ermal
	}
1571 9abaa8f7 Ermal
1572 d315b341 Chris Buechler
	// run ping_hosts.sh once if it's enabled to avoid wait for minicron
1573
	if ($ipsecpinghostsactive == true) {
1574
		mwexec_bg("/usr/local/bin/ping_hosts.sh");
1575
	}
1576
1577 79262830 Phil Davis
	if ($natfilterrules == true) {
1578 496acde1 Ermal
		filter_configure();
1579 79262830 Phil Davis
	}
1580 496acde1 Ermal
	/* start filterdns, if necessary */
1581
	if (count($filterdns_list) > 0) {
1582
		$interval = 60;
1583 79262830 Phil Davis
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) {
1584 496acde1 Ermal
			$interval = $ipseccfg['dns-interval'];
1585 79262830 Phil Davis
		}
1586 496acde1 Ermal
1587
		$hostnames = "";
1588
		array_unique($filterdns_list);
1589 79262830 Phil Davis
		foreach ($filterdns_list as $hostname) {
1590 496acde1 Ermal
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1591 79262830 Phil Davis
		}
1592 496acde1 Ermal
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1593
		unset($hostnames);
1594
1595 79262830 Phil Davis
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid")) {
1596 496acde1 Ermal
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1597 79262830 Phil Davis
		} else {
1598 496acde1 Ermal
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1599 5b237745 Scott Ullrich
		}
1600 496acde1 Ermal
	} else {
1601
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1602
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1603
	}
1604 09628a07 Renato Botelho
1605 79262830 Phil Davis
	if (platform_booting()) {
1606 496acde1 Ermal
		echo "done\n";
1607 79262830 Phil Davis
	}
1608 8f67a8e1 Scott Ullrich
1609 c520e3e3 Chris Buechler
	unlock($ipsecstartlock);
1610 496acde1 Ermal
	return count($filterdns_list);
1611 5b237745 Scott Ullrich
}
1612
1613 09628a07 Renato Botelho
/*
1614 52c9f9fa Ermal
 * Forcefully restart IPsec
1615 67ee1ec5 Ermal Luçi
 * This is required for when dynamic interfaces reload
1616
 * For all other occasions the normal vpn_ipsec_configure()
1617
 * will gracefully reload the settings without restarting
1618
 */
1619 aa752473 Renato Botelho
function vpn_ipsec_force_reload($interface = "") {
1620
	global $g, $config;
1621 67ee1ec5 Ermal Luçi
1622 1ee4cd19 Phil Davis
	if (!ipsec_enabled()) {
1623
		return;
1624
	}
1625
1626 67ee1ec5 Ermal Luçi
	$ipseccfg = $config['ipsec'];
1627
1628 aa752473 Renato Botelho
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1629
		$found = false;
1630
		foreach ($ipseccfg['phase1'] as $ipsec) {
1631
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1632
				$found = true;
1633
				break;
1634
			}
1635
		}
1636
		if (!$found) {
1637 8b4abd59 Ermal
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1638 aa752473 Renato Botelho
			return;
1639
		}
1640
	}
1641
1642 1ee4cd19 Phil Davis
	/* If we get this far then we need to take action. */
1643
	log_error(gettext("Forcefully reloading IPsec"));
1644
	vpn_ipsec_configure();
1645 67ee1ec5 Ermal Luçi
}
1646
1647
/* master setup for vpn (mpd) */
1648
function vpn_setup() {
1649
	/* start pppoe server */
1650 0e642c78 Ermal
	vpn_pppoes_configure();
1651 67ee1ec5 Ermal Luçi
1652
	/* setup l2tp */
1653
	vpn_l2tp_configure();
1654
}
1655
1656 67b057a9 Ermal
function vpn_netgraph_support() {
1657
	$iflist = get_configured_interface_list();
1658
	foreach ($iflist as $iface) {
1659
		$realif = get_real_interface($iface);
1660
		/* Get support for netgraph(4) from the nic */
1661 c513c309 Ermal
		$ifinfo = pfSense_get_interface_addresses($realif);
1662 79262830 Phil Davis
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) {
1663 09628a07 Renato Botelho
			pfSense_ngctl_attach(".", $realif);
1664 79262830 Phil Davis
		}
1665 67b057a9 Ermal
	}
1666
}
1667
1668 0e642c78 Ermal
function vpn_pppoes_configure() {
1669
	global $config;
1670
1671
	if (is_array($config['pppoes']['pppoe'])) {
1672 79262830 Phil Davis
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
1673 0e642c78 Ermal
			vpn_pppoe_configure($pppoe);
1674 79262830 Phil Davis
		}
1675 0e642c78 Ermal
	}
1676
}
1677
1678
function vpn_pppoe_configure(&$pppoecfg) {
1679 06e69b03 Scott Ullrich
	global $config, $g;
1680
1681
	$syscfg = $config['system'];
1682
1683 48918ed5 Scott Ullrich
	/* create directory if it does not exist */
1684 79262830 Phil Davis
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
1685 0e642c78 Ermal
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1686 79262830 Phil Davis
	}
1687 c52719a8 Scott Ullrich
1688 285ef132 Ermal LUÇI
	if (platform_booting()) {
1689 79262830 Phil Davis
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
1690 06e69b03 Scott Ullrich
			return 0;
1691 79262830 Phil Davis
		}
1692 06e69b03 Scott Ullrich
1693 d3d23754 Chris Buechler
		echo gettext("Configuring PPPoE Server service... ");
1694 979cd6db Scott Ullrich
	} else {
1695
		/* kill mpd */
1696 0e642c78 Ermal
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1697 979cd6db Scott Ullrich
1698
		/* wait for process to die */
1699
		sleep(2);
1700
1701 06e69b03 Scott Ullrich
	}
1702
1703
	switch ($pppoecfg['mode']) {
1704
1705 79262830 Phil Davis
		case 'server':
1706 06e69b03 Scott Ullrich
1707 0e642c78 Ermal
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1708 0301deff Scott Ullrich
1709 79262830 Phil Davis
			if ($pppoecfg['paporchap'] == "chap") {
1710 979cd6db Scott Ullrich
				$paporchap = "set link enable chap";
1711 79262830 Phil Davis
			} else {
1712 979cd6db Scott Ullrich
				$paporchap = "set link enable pap";
1713 79262830 Phil Davis
			}
1714 979cd6db Scott Ullrich
1715 06e69b03 Scott Ullrich
			/* write mpd.conf */
1716 0e642c78 Ermal
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1717 06e69b03 Scott Ullrich
			if (!$fd) {
1718 89ceb4ba Renato Botelho
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1719 06e69b03 Scott Ullrich
				return 1;
1720
			}
1721
1722 2c0a3677 Renato Botelho
			$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 ";
1723
			if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1724
				$issue_ip_type .= "0.0.0.0/0";
1725
			} else {
1726
				$issue_ip_type .= "ippool p0";
1727 06e69b03 Scott Ullrich
			}
1728
1729 2c0a3677 Renato Botelho
			$ippool_p0 = ip_after($pppoecfg['remoteip'], $pppoecfg['n_pppoe_units'] - 1);
1730 06e69b03 Scott Ullrich
1731 fa6e6196 jim-p
			if (is_numeric($pppoecfg['n_pppoe_maxlogin']) && ($pppoecfg['n_pppoe_maxlogin'] > 0)) {
1732
				$pppoemaxlogins = $pppoecfg['n_pppoe_maxlogin'];
1733
			} else {
1734 6801de75 jim-p
				$pppoemaxlogins = 1;
1735 fa6e6196 jim-p
			}
1736 06e69b03 Scott Ullrich
1737 2c0a3677 Renato Botelho
			$ipcp_dns = '';
1738
			if (!empty($pppoecfg['dns1'])) {
1739
				$ipcp_dns = "set ipcp dns " . $pppoecfg['dns1'];
1740
				if (!empty($pppoecfg['dns2'])) {
1741
					$ipcp_dns .= " " . $pppoecfg['dns2'];
1742
				}
1743
			} elseif (isset($config['dnsmasq']['enable']) ||
1744
			    isset ($config['unbound']['enable'])) {
1745
				$ipcp_dns = "set ipcp dns " . get_interface_ip("lan");
1746
				if ($syscfg['dnsserver'][0]) {
1747
					$ipcp_dns .= " " . $syscfg['dnsserver'][0];
1748
				}
1749
			} elseif (is_array($syscfg['dnsserver']) &&
1750
			    ($syscfg['dnsserver'][0])) {
1751
				$ipcp_dns = "set ipcp dns " . join(" ", $syscfg['dnsserver']);
1752
			}
1753
1754
			$mpdconf = <<<EOD
1755
startup:
1756 06e69b03 Scott Ullrich
1757 2c0a3677 Renato Botelho
poes:
1758
	set ippool add p0 {$pppoecfg['remoteip']} {$ippool_p0}
1759
1760
	create bundle template poes_b
1761 979cd6db Scott Ullrich
	set bundle enable compression
1762 2c0a3677 Renato Botelho
1763
	set ccp yes mppc
1764
	set mppc yes e40
1765
	set mppc yes e128
1766
	set mppc yes stateless
1767
1768 e4191be8 Renato Botelho
	set iface group pppoe
1769 902a31e3 jim-p
	set iface up-script /usr/local/sbin/vpn-linkup-poes
1770
	set iface down-script /usr/local/sbin/vpn-linkdown-poes
1771 979cd6db Scott Ullrich
	set iface idle 0
1772 06e69b03 Scott Ullrich
	set iface disable on-demand
1773
	set iface disable proxy-arp
1774
	set iface enable tcpmssfix
1775 979cd6db Scott Ullrich
	set iface mtu 1500
1776 2c0a3677 Renato Botelho
1777
	set ipcp no vjcomp
1778
	{$issue_ip_type}
1779
	{$ipcp_dns}
1780
1781
	create link template poes_l pppoe
1782
	set link action bundle poes_b
1783
1784
	set auth max-logins {$pppoemaxlogins}
1785
1786
	set pppoe iface {$pppoe_interface}
1787
1788
	set link no multilink
1789 06e69b03 Scott Ullrich
	set link no pap chap
1790 979cd6db Scott Ullrich
	{$paporchap}
1791
	set link keep-alive 60 180
1792
	set link max-redial -1
1793
	set link mru 1492
1794
	set link latency 1
1795 2c0a3677 Renato Botelho
	set link enable incoming
1796 06e69b03 Scott Ullrich
1797 c8c416db Scott Ullrich
EOD;
1798
1799 37d7de2d jim-p
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1800 c3583058 Ermal
				$radiusport = "";
1801
				$radiusacctport = "";
1802 79262830 Phil Davis
				if (isset($pppoecfg['radius']['server']['port'])) {
1803 c3583058 Ermal
					$radiusport = $pppoecfg['radius']['server']['port'];
1804 79262830 Phil Davis
				}
1805
				if (isset($pppoecfg['radius']['server']['acctport'])) {
1806 c3583058 Ermal
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1807 79262830 Phil Davis
				}
1808 979cd6db Scott Ullrich
				$mpdconf .=<<<EOD
1809 b0943409 Ermal
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1810 06e69b03 Scott Ullrich
	set radius retries 3
1811 979cd6db Scott Ullrich
	set radius timeout 10
1812 0af9dba4 Ermal Lu?i
	set auth enable radius-auth
1813 06e69b03 Scott Ullrich
1814
EOD;
1815
1816 979cd6db Scott Ullrich
				if (isset ($pppoecfg['radius']['accounting'])) {
1817
					$mpdconf .=<<<EOD
1818 0af9dba4 Ermal Lu?i
	set auth enable radius-acct
1819 07cae4b2 Scott Ullrich
1820 06e69b03 Scott Ullrich
EOD;
1821
				}
1822 2c0a3677 Renato Botelho
				if (!empty($pppoecfg['radius']['nasip'])) {
1823 f362c73b Chris Buechler
					$mpdconf .= "\tset radius me {$pppoecfg['radius']['nasip']}\n";
1824
				}
1825 06e69b03 Scott Ullrich
			}
1826
1827
			fwrite($fd, $mpdconf);
1828
			fclose($fd);
1829 a49784a2 Ermal
			unset($mpdconf);
1830 06e69b03 Scott Ullrich
1831 0e642c78 Ermal
			if ($pppoecfg['username']) {
1832
				/* write mpd.secret */
1833
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1834
				if (!$fd) {
1835 8c04b1ae Renato Botelho
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1836 0e642c78 Ermal
					return 1;
1837
				}
1838 06e69b03 Scott Ullrich
1839 0e642c78 Ermal
				$mpdsecret = "\n\n";
1840 06e69b03 Scott Ullrich
1841 0e642c78 Ermal
				if (!empty($pppoecfg['username'])) {
1842
					$item = explode(" ", $pppoecfg['username']);
1843 79262830 Phil Davis
					foreach ($item as $userdata) {
1844 0e642c78 Ermal
						$data = explode(":", $userdata);
1845 90388e48 Ermal
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1846 0e642c78 Ermal
					}
1847
				}
1848 06e69b03 Scott Ullrich
1849 0e642c78 Ermal
				fwrite($fd, $mpdsecret);
1850
				fclose($fd);
1851 a49784a2 Ermal
				unset($mpdsecret);
1852 0e642c78 Ermal
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1853
			}
1854 979cd6db Scott Ullrich
1855 062676f8 Ermal
			/* Check if previous instance is still up */
1856 79262830 Phil Davis
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
1857 062676f8 Ermal
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1858 79262830 Phil Davis
			}
1859 062676f8 Ermal
1860 67b057a9 Ermal
			/* Get support for netgraph(4) from the nic */
1861
			pfSense_ngctl_attach(".", $pppoe_interface);
1862 979cd6db Scott Ullrich
			/* fire up mpd */
1863 2c0a3677 Renato Botelho
			mwexec("/usr/local/sbin/mpd5 -b -d {$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn -p {$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid -s poes poes");
1864 979cd6db Scott Ullrich
1865
			break;
1866
	}
1867
1868 79262830 Phil Davis
	if (platform_booting()) {
1869 561130e4 Carlos Eduardo Ramos
		echo gettext("done") . "\n";
1870 79262830 Phil Davis
	}
1871 979cd6db Scott Ullrich
1872
	return 0;
1873
}
1874
1875
function vpn_l2tp_configure() {
1876
	global $config, $g;
1877
1878
	$syscfg = $config['system'];
1879
	$l2tpcfg = $config['l2tp'];
1880
1881
	/* create directory if it does not exist */
1882 79262830 Phil Davis
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
1883 67ee1ec5 Ermal Luçi
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1884 79262830 Phil Davis
	}
1885 979cd6db Scott Ullrich
1886 285ef132 Ermal LUÇI
	if (platform_booting()) {
1887 79262830 Phil Davis
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
1888 979cd6db Scott Ullrich
			return 0;
1889 79262830 Phil Davis
		}
1890 979cd6db Scott Ullrich
1891 89ceb4ba Renato Botelho
		echo gettext("Configuring l2tp VPN service... ");
1892 979cd6db Scott Ullrich
	} else {
1893
		/* kill mpd */
1894 67ee1ec5 Ermal Luçi
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1895 979cd6db Scott Ullrich
1896
		/* wait for process to die */
1897 01c41d40 Ermal Lu?i
		sleep(8);
1898 979cd6db Scott Ullrich
1899
	}
1900
1901 67ee1ec5 Ermal Luçi
	/* make sure l2tp-vpn directory exists */
1902 79262830 Phil Davis
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
1903 67ee1ec5 Ermal Luçi
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1904 79262830 Phil Davis
	}
1905 979cd6db Scott Ullrich
1906
	switch ($l2tpcfg['mode']) {
1907
1908 79262830 Phil Davis
		case 'server':
1909 adc70099 Renato Botelho
			$l2tp_listen="";
1910
			$ipaddr = get_interface_ip(get_failover_interface($l2tpcfg['interface']));
1911
			if (is_ipaddrv4($ipaddr)) {
1912
				$l2tp_listen="set l2tp self $ipaddr";
1913
			}
1914 c4f22962 TarasSavchuk
1915 3fac0afc Jose Luis Duran
			switch ($l2tpcfg['paporchap']) {
1916
				case 'chap':
1917
					$paporchap = "set link enable chap";
1918
					break;
1919
				case 'chap-msv2':
1920
					$paporchap = "set link enable chap-msv2";
1921
					break;
1922
				default:
1923
					$paporchap = "set link enable pap";
1924
					break;
1925 79262830 Phil Davis
			}
1926 979cd6db Scott Ullrich
1927
			/* write mpd.conf */
1928 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1929 979cd6db Scott Ullrich
			if (!$fd) {
1930 89ceb4ba Renato Botelho
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1931 979cd6db Scott Ullrich
				return 1;
1932
			}
1933
1934 8d50c07c Renato Botelho
			$ippool_p0 = ip_after($l2tpcfg['remoteip'], $l2tpcfg['n_l2tp_units'] - 1);
1935 979cd6db Scott Ullrich
1936 8d50c07c Renato Botelho
			$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 ";
1937
			if (isset($l2tpcfg['radius']['radiusissueips']) && isset($l2tpcfg['radius']['server']['enable'])) {
1938
				$issue_ip_type .= "0.0.0.0/0";
1939
			} else {
1940
				$issue_ip_type .= "ippool p0";
1941 979cd6db Scott Ullrich
			}
1942
1943 8d50c07c Renato Botelho
			$ipcp_dns = '';
1944
			if (is_ipaddr($l2tpcfg['dns1'])) {
1945
				$ipcp_dns = "set ipcp dns " . $l2tpcfg['dns1'];
1946
				if (is_ipaddr($l2tpcfg['dns2'])) {
1947
					$ipcp_dns .= " " . $l2tpcfg['dns2'];
1948 979cd6db Scott Ullrich
				}
1949 8d50c07c Renato Botelho
			} elseif (isset ($config['dnsmasq']['enable']) ||
1950
			    isset ($config['unbound']['enable'])) {
1951
				$ipcp_dns = "set ipcp dns " . get_interface_ip("lan");
1952
				if ($syscfg['dnsserver'][0]) {
1953
					$ipcp_dns .= " " . $syscfg['dnsserver'][0];
1954
				}
1955
			} elseif (is_array($syscfg['dnsserver']) &&
1956
			    ($syscfg['dnsserver'][0])) {
1957
				$ipcp_dns = "set ipcp dns " . join(" ", $syscfg['dnsserver']);
1958
			}
1959 979cd6db Scott Ullrich
1960 8d50c07c Renato Botelho
			$mpdconf =<<<EOD
1961 979cd6db Scott Ullrich
1962 8d50c07c Renato Botelho
startup:
1963 979cd6db Scott Ullrich
1964 8d50c07c Renato Botelho
l2tps:
1965
	set ippool add p0 {$l2tpcfg['remoteip']} {$ippool_p0}
1966 979cd6db Scott Ullrich
1967 8d50c07c Renato Botelho
	create bundle template l2tp_b
1968 09628a07 Renato Botelho
	set bundle enable compression
1969
	set bundle yes crypt-reqd
1970 8d50c07c Renato Botelho
1971 09628a07 Renato Botelho
	set ccp yes mppc
1972 8d50c07c Renato Botelho
1973 902a31e3 jim-p
	set iface name l2tp
1974 8d50c07c Renato Botelho
	set iface group l2tp
1975 902a31e3 jim-p
	set iface up-script /usr/local/sbin/vpn-linkup-l2tp
1976
	set iface down-script /usr/local/sbin/vpn-linkdown-l2tp
1977 8d50c07c Renato Botelho
	set iface disable on-demand
1978
	set iface enable proxy-arp
1979
1980
	set ipcp yes vjcomp
1981
	{$issue_ip_type}
1982
	{$ipcp_dns}
1983
1984
	create link template l2tp_l l2tp
1985
	set link action bundle l2tp_b
1986
1987 09628a07 Renato Botelho
	set link yes acfcomp protocomp
1988 8d50c07c Renato Botelho
	set link enable multilink
1989
	set link no pap chap chap-msv2
1990 d06f9ebe Sebastian Öhman
	{$paporchap}
1991 adc70099 Renato Botelho
	{$l2tp_listen}
1992 09628a07 Renato Botelho
	set link keep-alive 10 180
1993 8d50c07c Renato Botelho
	set link enable incoming
1994 979cd6db Scott Ullrich
1995
EOD;
1996
1997
1998
			if (isset ($l2tpcfg['radius']['enable'])) {
1999
				$mpdconf .=<<<EOD
2000
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
2001
	set radius retries 3
2002
	set radius timeout 10
2003 5de4b046 jim-p
	set auth disable internal
2004 0af9dba4 Ermal Lu?i
	set auth enable radius-auth
2005 979cd6db Scott Ullrich
2006
EOD;
2007
2008
				if (isset ($l2tpcfg['radius']['accounting'])) {
2009
					$mpdconf .=<<<EOD
2010 0af9dba4 Ermal Lu?i
	set auth enable radius-acct
2011 979cd6db Scott Ullrich
2012
EOD;
2013
				}
2014
			}
2015
2016
			fwrite($fd, $mpdconf);
2017
			fclose($fd);
2018 a49784a2 Ermal
			unset($mpdconf);
2019 979cd6db Scott Ullrich
2020
			/* write mpd.secret */
2021 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
2022 979cd6db Scott Ullrich
			if (!$fd) {
2023 89ceb4ba Renato Botelho
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
2024 979cd6db Scott Ullrich
				return 1;
2025
			}
2026
2027
			$mpdsecret = "\n\n";
2028
2029
			if (is_array($l2tpcfg['user'])) {
2030 79262830 Phil Davis
				foreach ($l2tpcfg['user'] as $user) {
2031 979cd6db Scott Ullrich
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
2032 79262830 Phil Davis
				}
2033 979cd6db Scott Ullrich
			}
2034
2035
			fwrite($fd, $mpdsecret);
2036
			fclose($fd);
2037 a49784a2 Ermal
			unset($mpdsecret);
2038 67ee1ec5 Ermal Luçi
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
2039 06e69b03 Scott Ullrich
2040 67b057a9 Ermal
			vpn_netgraph_support();
2041
2042 06e69b03 Scott Ullrich
			/* fire up mpd */
2043 8d50c07c Renato Botelho
			mwexec("/usr/local/sbin/mpd5 -b -d {$g['varetc_path']}/l2tp-vpn -p {$g['varrun_path']}/l2tp-vpn.pid -s l2tps l2tps");
2044 06e69b03 Scott Ullrich
2045
			break;
2046
2047 79262830 Phil Davis
		case 'redir':
2048 06e69b03 Scott Ullrich
			break;
2049
	}
2050
2051 79262830 Phil Davis
	if (platform_booting()) {
2052 06e69b03 Scott Ullrich
		echo "done\n";
2053 79262830 Phil Davis
	}
2054 06e69b03 Scott Ullrich
2055
	return 0;
2056
}
2057 630cfa6c Scott Ullrich
2058 79262830 Phil Davis
?>