Project

General

Profile

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