Project

General

Profile

Download (60.1 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * vpn.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8
 * Copyright (c) 2014-2019 Rubicon Communications, LLC (Netgate)
9
 * Copyright (c) 2008 Shrew Soft Inc
10
 * All rights reserved.
11
 *
12
 * originally part of m0n0wall (http://m0n0.ch/wall)
13
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
14
 * All rights reserved.
15
 *
16
 * Licensed under the Apache License, Version 2.0 (the "License");
17
 * you may not use this file except in compliance with the License.
18
 * You may obtain a copy of the License at
19
 *
20
 * http://www.apache.org/licenses/LICENSE-2.0
21
 *
22
 * Unless required by applicable law or agreed to in writing, software
23
 * distributed under the License is distributed on an "AS IS" BASIS,
24
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25
 * See the License for the specific language governing permissions and
26
 * limitations under the License.
27
 */
28

    
29
require_once("ipsec.inc");
30
require_once("filter.inc");
31
require_once("auth.inc");
32
require_once("certs.inc");
33

    
34
function vpn_update_daemon_loglevel($category, $level) {
35
	global $ipsec_log_cats, $ipsec_log_sevs;
36

    
37
	if (in_array($category, array_keys($ipsec_log_cats), true) && in_array(intval($level), array_keys($ipsec_log_sevs), true)) {
38

    
39
		/* if you're setting to -1, need to add "--" to args */
40
		$argterm = "";
41
		if ($level == "-1") {
42
			$argterm = "--";
43
		}
44

    
45
		mwexec("/usr/local/sbin/ipsec stroke loglevel {$category} {$argterm} {$level}");
46
	}
47
}
48

    
49
function vpn_logging_cfgtxt() {
50
	global $config, $ipsec_log_cats, $ipsec_log_sevs;
51

    
52
	$cfgtext = array();
53
	$log_levels = ipsec_get_loglevels();
54
	foreach (array_keys($ipsec_log_cats) as $cat) {
55
		if (is_numeric($log_levels[$cat]) &&
56
		    in_array(intval($log_levels[$cat]), array_keys($ipsec_log_sevs), true)) {
57
			$cfgtext[] = "${cat} = {$log_levels[$cat]}";
58
		}
59
	}
60

    
61
	return $cfgtext;
62
}
63

    
64
/* include all configuration functions */
65
function vpn_ipsec_convert_to_modp($index) {
66

    
67
	$conversion = "";
68
	switch ($index) {
69
		case '1':
70
			$conversion = "modp768";
71
			break;
72
		case '2':
73
			$conversion = "modp1024";
74
			break;
75
		case '5':
76
			$conversion = "modp1536";
77
			break;
78
		case '14':
79
			$conversion = "modp2048";
80
			break;
81
		case '15':
82
			$conversion = "modp3072";
83
			break;
84
		case '16':
85
			$conversion = "modp4096";
86
			break;
87
		case '17':
88
			$conversion = "modp6144";
89
			break;
90
		case '18':
91
			$conversion = "modp8192";
92
			break;
93
		case '19':
94
			$conversion = "ecp256";
95
			break;
96
		case '20':
97
			$conversion = "ecp384";
98
			break;
99
		case '21':
100
			$conversion = "ecp521";
101
			break;
102
		case '22':
103
			$conversion = "modp1024s160";
104
			break;
105
		case '23':
106
			$conversion = "modp2048s224";
107
			break;
108
		case '24':
109
			$conversion = "modp2048s256";
110
			break;
111
		case '25':
112
			$conversion = "ecp192";
113
			break;
114
		case '26':
115
			$conversion = "ecp224";
116
			break;
117
		case '27':
118
			$conversion = "ecp224bp";
119
			break;
120
		case '28':
121
			$conversion = "ecp256bp";
122
			break;
123
		case '29':
124
			$conversion = "ecp384bp";
125
			break;
126
		case '30':
127
			$conversion = "ecp512bp";
128
			break;
129
		case '31':
130
			$conversion = "curve25519";
131
			break;
132
		case '32':
133
			$conversion = "curve448";
134
			break;
135
	}
136

    
137
	return $conversion;
138
}
139

    
140
function vpn_ipsec_configure($restart = false) {
141
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos, $ipsec_idhandling;
142

    
143
	$ipsecstartlock = lock('ipsec', LOCK_EX);
144

    
145
	/* get the automatic ping_hosts.sh ready */
146
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
147
	touch("{$g['vardb_path']}/ipsecpinghosts");
148
	$ipsecpinghostsactive = false;
149

    
150
	/* service may have been enabled, disabled, or otherwise changed in a way requiring rule updates */
151
	filter_configure();
152

    
153
	$syscfg = $config['system'];
154
	$ipseccfg = $config['ipsec'];
155

    
156
	/* Configure asynchronous crypto. See https://redmine.pfsense.org/issues/8772 */
157
	set_sysctl(array('net.inet.ipsec.async_crypto' => (int) (isset($ipseccfg['async_crypto']) && ($ipseccfg['async_crypto'] == "enabled"))));
158

    
159
	if (!ipsec_enabled()) {
160
		/* try to stop charon */
161
		mwexec("/usr/local/sbin/ipsec stop");
162
		/* Stop dynamic monitoring */
163
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
164

    
165
		/* wait for process to die */
166
		sleep(2);
167

    
168
		/* IPSEC is off, shutdown enc interface.*/
169
		mwexec("/sbin/ifconfig enc0 down");
170

    
171
		unlock($ipsecstartlock);
172
		return 0;
173
	}
174

    
175
	$a_phase1 = $config['ipsec']['phase1'];
176
	$a_phase2 = $config['ipsec']['phase2'];
177
	$a_client = $config['ipsec']['client'];
178

    
179
	$certpath = "{$g['varetc_path']}/ipsec/ipsec.d/certs";
180
	$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts";
181
	$keypath = "{$g['varetc_path']}/ipsec/ipsec.d/private";
182
	$crlpath = "{$g['varetc_path']}/ipsec/ipsec.d/crls";
183

    
184
	mwexec("/sbin/ifconfig enc0 up");
185
	$ipsec_vti_cleanup_ifs = array();
186

    
187
	/* needed for config files */
188
	safe_mkdir("{$g['varetc_path']}/ipsec");
189
	safe_mkdir("{$g['varetc_path']}/ipsec/ipsec.d");
190

    
191
	// delete these paths first to ensure old CAs, certs and CRLs aren't left behind. redmine #5238
192
	rmdir_recursive($capath);
193
	rmdir_recursive($keypath);
194
	rmdir_recursive($crlpath);
195
	rmdir_recursive($certpath);
196

    
197
	safe_mkdir($capath);
198
	safe_mkdir($keypath);
199
	safe_mkdir($crlpath);
200
	safe_mkdir($certpath);
201
	safe_mkdir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts");
202
	safe_mkdir("{$g['varetc_path']}/ipsec/ipsec.d/acerts");
203
	safe_mkdir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts");
204
	safe_mkdir("{$g['varetc_path']}/ipsec/ipsec.d/reqs");
205

    
206
	if (!file_exists("/usr/local/etc/ipsec.d") ||
207
	    !is_link("/usr/local/etc/ipsec.d")) {
208
		if (file_exists("/usr/local/etc/ipsec.d")) {
209
			rmdir_recursive("/usr/local/etc/ipsec.d");
210
		}
211
		@symlink("{$g['varetc_path']}/ipsec/ipsec.d",
212
		    "/usr/local/etc/ipsec.d");
213
	}
214
	if (!file_exists("{$g['varetc_path']}/etc/strongswan.d") ||
215
	    !is_link("{$g['varetc_path']}/etc/strongswan.d")) {
216
		if (is_link("{$g['varetc_path']}/etc/strongswan.d")) {
217
			@unlink("{$g['varetc_path']}/etc/strongswan.d");
218
		} else {
219
			rmdir_recursive("{$g['varetc_path']}/etc/strongswan.d");
220
		}
221
		@symlink("/usr/local/etc/strongswan.d",
222
		    "{$g['varetc_path']}/ipsec/strongswan.d");
223
	}
224
	if (!file_exists("/usr/local/etc/strongswan.conf") ||
225
	    !is_link("/usr/local/etc/strongswan.conf")) {
226
		@unlink("/usr/local/etc/strongswan.conf");
227
		@symlink("{$g['varetc_path']}/ipsec/strongswan.conf",
228
		    "/usr/local/etc/strongswan.conf");
229
	}
230
	if (!file_exists("/usr/local/etc/ipsec.conf") ||
231
	    !is_link("/usr/local/etc/ipsec.conf")) {
232
		@unlink("/usr/local/etc/ipsec.conf");
233
		@symlink("{$g['varetc_path']}/ipsec/ipsec.conf",
234
		    "/usr/local/etc/ipsec.conf");
235
	}
236

    
237
	if (platform_booting()) {
238
		echo gettext("Configuring IPsec VPN... ");
239
	}
240

    
241
	/* resolve all local, peer addresses and setup pings */
242
	$ipmap = array();
243
	$rgmap = array();
244
	$filterdns_list = array();
245
	$aggressive_mode_psk = false;
246
	unset($iflist);
247
	$ifacesuse = array();
248
	$mobile_ipsec_auth = "";
249
	if (is_array($a_phase1) && count($a_phase1)) {
250

    
251
		$ipsecpinghosts = array();
252
		/* step through each phase1 entry */
253
		foreach ($a_phase1 as $ph1ent) {
254
			if (isset($ph1ent['disabled'])) {
255
				continue;
256
			}
257

    
258
			if (substr($ph1ent['interface'], 0, 4) == "_vip") {
259
				$vpninterface = get_configured_vip_interface($ph1ent['interface']);
260
				$ifacesuse[] = get_real_interface($vpninterface);
261
			} else {
262
				$vpninterface = get_failover_interface($ph1ent['interface']);
263
				if (substr($vpninterface, 0, 4) == "_vip") {
264
					$vpninterface = get_configured_vip_interface($vpninterface);
265
					$ifacesuse[] = get_real_interface($vpninterface);
266
				} elseif (!empty($vpninterface)) {
267
					$ifacesuse[] = $vpninterface;
268
				}
269
			}
270

    
271
			if ($ph1ent['mode'] == "aggressive" && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
272
				$aggressive_mode_psk = true;
273
			}
274

    
275
			$ikeid = $ph1ent['ikeid'];
276

    
277
			$ep = ipsec_get_phase1_src($ph1ent);
278
			/* When automatically guessing, use the first address. */
279
			$ep  = explode(',', $ep);
280
			$ep  = $ep[0];
281
			if (!is_ipaddr($ep)) {
282
				log_error(sprintf(gettext("IPsec ERROR: Could not find phase 1 source for connection %s. Omitting from configuration file."), $ph1ent['descr']));
283
				continue;
284
			}
285

    
286
			if (!in_array($ep, $ipmap)) {
287
				$ipmap[] = $ep;
288
			}
289

    
290
			/* see if this tunnel has a hostname for the remote-gateway. If so,
291
			   try to resolve it now and add it to the list for filterdns */
292

    
293
			if (isset ($ph1ent['mobile'])) {
294
				$mobile_ipsec_auth = $ph1ent['authentication_method'];
295
				continue;
296
			}
297

    
298
			$rg = $ph1ent['remote-gateway'];
299

    
300
			if (!is_ipaddr($rg)) {
301
				$filterdns_list[] = "{$rg}";
302
				add_hostname_to_watch($rg);
303
				if (!platform_booting()) {
304
					$rg = resolve_retry($rg);
305
				}
306
				if (!is_ipaddr($rg)) {
307
					continue;
308
				}
309
			}
310
			if (array_search($rg, $rgmap)) {
311
				log_error(sprintf(gettext("The remote gateway %s already exists on another phase 1 entry"), $rg));
312
				continue;
313
			}
314
			$rgmap[$ph1ent['remote-gateway']] = $rg;
315

    
316
			$is_vti = false;
317
			if (is_array($a_phase2)) {
318
				/* step through each phase2 entry */
319
				foreach ($a_phase2 as $ph2ent) {
320
					if ($ph2ent['mode'] == 'vti') {
321
						$is_vti = true;
322
					}
323
					if (isset($ph2ent['disabled'])) {
324
						continue;
325
					}
326

    
327
					if ($ikeid != $ph2ent['ikeid']) {
328
						continue;
329
					}
330

    
331
					/* add an ipsec pinghosts entry */
332
					if ($ph2ent['pinghost']) {
333
						if (!is_array($iflist)) {
334
							$iflist = get_configured_interface_list();
335
						}
336
						$srcip = null;
337
						$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
338
						if (is_ipaddrv6($ph2ent['pinghost'])) {
339
							foreach ($iflist as $ifent => $ifname) {
340
								$interface_ip = get_interface_ipv6($ifent);
341
								if (!is_ipaddrv6($interface_ip)) {
342
									continue;
343
								}
344
								if (ip_in_subnet($interface_ip, $local_subnet)) {
345
									$srcip = $interface_ip;
346
									break;
347
								}
348
							}
349
						} else {
350
							foreach ($iflist as $ifent => $ifname) {
351
								$interface_ip = get_interface_ip($ifent);
352
								if (!is_ipaddrv4($interface_ip)) {
353
									continue;
354
								}
355
								if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) {
356
									$srcip = $interface_ip;
357
									break;
358
								}
359
							}
360
						}
361
						/* if no valid src IP was found in configured interfaces, try the vips */
362
						if (is_null($srcip)) {
363
							$viplist = get_configured_vip_list();
364
							foreach ($viplist as $vip => $address) {
365
								if (ip_in_subnet($address, $local_subnet)) {
366
									$srcip = $address;
367
									break;
368
								}
369
							}
370
						}
371
						$dstip = $ph2ent['pinghost'];
372
						if (is_ipaddrv6($dstip)) {
373
							$family = "inet6";
374
						} else {
375
							$family = "inet";
376
						}
377
						if (is_ipaddr($srcip)) {
378
							$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
379
							$ipsecpinghostsactive = true;
380
						}
381
					}
382
				}
383
			}
384
			if ($is_vti) {
385
				interface_ipsec_vti_configure($ph1ent);
386
			}
387
		}
388
		@file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
389
		unset($ipsecpinghosts);
390
	}
391
	unset($iflist);
392
	/* Build a list of all IPsec interfaces configured on the firewall at the OS level */
393
	foreach (get_interface_arr() as $thisif) {
394
		if (substr($thisif, 0, 5) == "ipsec") {
395
			$ipsec_vti_cleanup_ifs[] = $thisif;
396
		}
397
	}
398

    
399
	$accept_unencrypted = "";
400
	if (isset($config['ipsec']['acceptunencryptedmainmode'])) {
401
		$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
402
	}
403

    
404
	$stronconf = '';
405
	if (file_exists("{$g['varetc_path']}/ipsec/strongswan.conf")) {
406
		$stronconf = file_get_contents("{$g['varetc_path']}/ipsec/strongswan.conf");
407
	}
408

    
409
	$i_dont_care_about_security_and_use_aggressive_mode_psk = "";
410
	if ($aggressive_mode_psk) {
411
		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.");
412
		if (!empty($stronconf) && strpos($stronconf, 'i_dont_care_about_security_and_use_aggressive_mode_psk') === FALSE) {
413
			$restart = true;
414
		}
415
		$i_dont_care_about_security_and_use_aggressive_mode_psk = "i_dont_care_about_security_and_use_aggressive_mode_psk=yes";
416
	}
417

    
418
	$unity_enabled = isset($config['ipsec']['unityplugin']) ? 'yes' : 'no';
419

    
420
	$makebeforebreak = '';
421
	if (isset($config['ipsec']['makebeforebreak'])) {
422
		$makebeforebreak = 'make_before_break = yes';
423
	}
424

    
425
	if (isset($config['ipsec']['enableinterfacesuse'])) {
426
		if (!empty($ifacesuse)) {
427
			$ifacesuse = 'interfaces_use = ' . implode(',', array_unique($ifacesuse));
428
		} else {
429
			$ifacesuse = '';
430
		}
431
	} else {
432
		$ifacesuse = '';
433
	}
434

    
435
	unset($stronconf);
436

    
437
	$strongswanlog = "";
438
	$ipsecloglevels = vpn_logging_cfgtxt();
439
	if (is_array($ipsecloglevels)) {
440
		foreach ($ipsecloglevels as $loglevel) {
441
			$strongswanlog .= "\t\t\t" . $loglevel . "\n";
442
		}
443
	}
444
	$strongswan = <<<EOD
445

    
446
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten.
447
starter {
448
	load_warning = no
449
	config_file = {$g['varetc_path']}/ipsec/ipsec.conf
450
}
451

    
452
charon {
453
# number of worker threads in charon
454
	threads = 16
455
	ikesa_table_size = 32
456
	ikesa_table_segments = 4
457
	init_limit_half_open = 1000
458
	install_routes = no
459
	load_modular = yes
460
	ignore_acquire_ts = yes
461
	{$i_dont_care_about_security_and_use_aggressive_mode_psk}
462
	{$accept_unencrypted}
463
	cisco_unity = {$unity_enabled}
464
	{$ifacesuse}
465
	{$makebeforebreak}
466

    
467
	syslog {
468
		identifier = charon
469
		# log everything under daemon since it ends up in the same place regardless with our syslog.conf
470
		daemon {
471
			ike_name = yes
472
{$strongswanlog}
473
		}
474
		# disable logging under auth so logs aren't duplicated
475
		auth {
476
			default = -1
477
		}
478
	}
479

    
480
	plugins {
481
		# Load defaults
482
		include {$g['varetc_path']}/ipsec/strongswan.d/charon/*.conf
483

    
484
		stroke {
485
			secrets_file = {$g['varetc_path']}/ipsec/ipsec.secrets
486
		}
487

    
488
		unity {
489
			load = {$unity_enabled}
490
		}
491

    
492
		curve25519 {
493
			load = yes
494
		}
495

    
496
EOD;
497

    
498
	/* Find RADIUS servers designated for Mobile IPsec user auth */
499
	$radius_server_txt = "";
500
	$user_sources = explode(',', $config['ipsec']['client']['user_source']);
501
	foreach ($user_sources as $user_source) {
502
		$auth_server = auth_get_authserver($user_source);
503
		$nice_user_source = strtolower(preg_replace('/[\s\.]+/', '_', $user_source));
504
		if ($auth_server && $auth_server['type'] === 'radius') {
505
			$radius_server_txt .= <<<EOD
506
				{$nice_user_source} {
507
					address = {$auth_server['host']}
508
					secret = "{$auth_server['radius_secret']}"
509
					auth_port = {$auth_server['radius_auth_port']}
510
					acct_port = {$auth_server['radius_acct_port']}
511
				}
512

    
513
EOD;
514
		}
515
	}
516

    
517
	/* Activate RADIUS accounting if it was selected on the auth server view */
518
	$radius_accounting = "";
519
	if($auth_server && isset($auth_server['radius_acct_port'])){
520
		$radius_accounting = 'accounting = yes';
521
	}
522

    
523
	/* write an eap-radius config section if appropriate */
524
	if (strlen($radius_server_txt) && ($mobile_ipsec_auth === "eap-radius")) {
525
		$strongswan .= <<<EOD
526
		eap-radius {
527
			class_group = yes
528
			eap_start = no
529
			{$radius_accounting}
530
			servers {
531
{$radius_server_txt}
532
			}
533
		}
534

    
535
EOD;
536
	}
537

    
538
	if (is_array($a_client) && isset($a_client['enable'])) {
539
		$strongswan .= "\t\tattr {\n";
540

    
541
		$cfgservers = array();
542
		if (!empty($a_client['wins_server1'])) {
543
			$cfgservers[] = $a_client['wins_server1'];
544
		}
545
		if (!empty($a_client['wins_server2'])) {
546
			$cfgservers[] = $a_client['wins_server2'];
547
		}
548
		if (!empty($cfgservers)) {
549
			$strongswan .= "\t\t\tnbns = " . implode(",", $cfgservers) . "\n";
550
		}
551
		unset($cfgservers);
552

    
553
		if (isset($a_client['net_list']) && is_array($a_phase2)) {
554
			$net_list = '';
555
			foreach ($a_phase2 as $ph2ent) {
556
				if (isset($ph2ent['disabled'])) {
557
					continue;
558
				}
559

    
560
				if (!isset($ph2ent['mobile'])) {
561
					continue;
562
				}
563

    
564
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
565

    
566
				if (!empty($net_list)) {
567
					$net_list .= ",";
568
				}
569
				$net_list .= $localid;
570
			}
571

    
572
			if (!empty($net_list)) {
573
				$strongswan .= "\t\t\tsubnet = {$net_list}\n";
574
				$strongswan .= "\t\t\tsplit-include = {$net_list}\n";
575
				unset($net_list);
576
			}
577
		}
578

    
579
		if (!empty($a_client['dns_domain'])) {
580
			$strongswan .= "\t\t\t# Search domain and default domain\n";
581
			$strongswan .= "\t\t\t28674 = \"{$a_client['dns_domain']}\"\n";
582
			if (empty($a_client['dns_split'])) {
583
				$strongswan .= "\t\t\t28675 = \"{$a_client['dns_domain']}\"";
584
			}
585
			$strongswan .= "\n";
586
		}
587

    
588
		if (!empty($a_client['dns_split'])) {
589
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
590
		}
591

    
592
		if (!empty($a_client['login_banner'])) {
593
			$strongswan .= "\t\t\t28672 = \"{$a_client['login_banner']}\"\n";
594
		}
595

    
596
		if (isset($a_client['save_passwd'])) {
597
			$strongswan .= "\t\t\t28673 = 1\n";
598
		}
599

    
600
		if ($a_client['pfs_group']) {
601
			$strongswan .= "\t\t\t28679 = \"{$a_client['pfs_group']}\"\n";
602
		}
603
		$strongswan .= "\t\t}\n";
604

    
605
		if ($a_client['user_source'] != "none") {
606
			$strongswan .= "\t\txauth-generic {\n";
607
			$strongswan .= "\t\t\tscript = /etc/inc/ipsec.auth-user.php\n";
608
			$strongswan .= "\t\t\tauthcfg = ";
609
			$firstsed = 0;
610
			$authcfgs = explode(",", $a_client['user_source']);
611
			foreach ($authcfgs as $authcfg) {
612
				if ($firstsed > 0) {
613
					$strongswan .= ",";
614
				}
615
				if ($authcfg == "system") {
616
					$authcfg = "Local Database";
617
				}
618
				$strongswan .= $authcfg;
619
				$firstsed = 1;
620
			}
621
			$strongswan .= "\n";
622
			$strongswan .= "\t\t}\n";
623
		}
624
	}
625

    
626
	$strongswan .= "\n\t}\n}\n";
627
	@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
628
	unset($strongswan);
629

    
630
	/* write out CRL files */
631
	if (is_array($config['crl']) && count($config['crl'])) {
632
		foreach ($config['crl'] as $crl) {
633
			if (!isset($crl['text'])) {
634
				log_error(sprintf(gettext("Warning: Missing CRL data for %s"), $crl['descr']));
635
				continue;
636
			}
637
			$fpath = "{$crlpath}/{$crl['refid']}.crl";
638
			if (!@file_put_contents($fpath, base64_decode($crl['text']))) {
639
				log_error(sprintf(gettext("Error: Cannot write IPsec CRL file for %s"), $crl['descr']));
640
				continue;
641
			}
642
		}
643
	}
644

    
645
	$pskconf = "";
646

    
647
	$vpncas = array();
648
	if (is_array($a_phase1) && count($a_phase1)) {
649
		foreach ($a_phase1 as $ph1ent) {
650

    
651
			if (isset($ph1ent['disabled'])) {
652
				continue;
653
			}
654

    
655
			if (strstr($ph1ent['authentication_method'], 'cert') ||
656
			    in_array($ph1ent['authentication_method'], array('eap-mschapv2', 'eap-tls', 'eap-radius'))) {
657
				$certline = '';
658

    
659
				$ikeid = $ph1ent['ikeid'];
660
				$cert = lookup_cert($ph1ent['certref']);
661

    
662
				if (!$cert) {
663
					log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
664
					continue;
665
				}
666

    
667
				/* add signing CA cert chain of server cert
668
				 * to the list of CAs to write
669
				 */
670
				$cachain = ca_chain_array($cert);
671
				if ($cachain && is_array($cachain)) {
672
					foreach ($cachain as $cacrt) {
673
						$vpncas[$cacrt['refid']] = $cacrt;
674
					}
675
				}
676

    
677
				@chmod($certpath, 0600);
678

    
679
				$ph1keyfile = "{$keypath}/cert-{$ikeid}.key";
680
				if (!file_put_contents($ph1keyfile, base64_decode($cert['prv']))) {
681
					log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
682
					continue;
683
				}
684
				@chmod($ph1keyfile, 0600);
685

    
686
				$ph1certfile = "{$certpath}/cert-{$ikeid}.crt";
687
				if (!file_put_contents($ph1certfile, base64_decode($cert['crt']))) {
688
					log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name']));
689
					@unlink($ph1keyfile);
690
					continue;
691
				}
692
				@chmod($ph1certfile, 0600);
693

    
694
				/* XXX" Traffic selectors? */
695
				$pskconf .= " : ";
696
				$pskconf .= (cert_get_pkey_curve($cert['prv']) === false) ? "RSA" : "ECDSA";
697
				$pskconf .= " {$ph1keyfile}\n";
698
			} else {
699
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
700
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
701

    
702
				$myid = trim($myid_data);
703

    
704
				if (empty($peerid_data)) {
705
					continue;
706
				}
707

    
708
				if ($myid_type == 'fqdn' && !empty($myid)) {
709
					$myid = "@{$myid}";
710
				}
711

    
712
				$myid = isset($ph1ent['mobile']) ? trim($myid_data) : "%any";
713

    
714
				$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
715

    
716
				if ($peerid_type == 'fqdn' && !empty($peerid)) {
717
					$peerid = "@{$peerid}";
718
				}
719

    
720
				if (!empty($ph1ent['pre-shared-key'])) {
721
					$pskconf .= "{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
722
					if (isset($ph1ent['mobile'])) {
723
						$pskconf .= "{$myid} %any : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
724
						$pskconf .= " : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
725
					}
726
				}
727
			}
728

    
729
			/* if the client authenticates with a cert add the
730
			 * client cert CA chain to the list of CAs to write
731
			 */
732
			if (in_array($ph1ent['authentication_method'],
733
			array('cert', 'eap-tls', 'xauth_cert_server'))) {
734

    
735
				if (!empty($ph1ent['caref']) && !array_key_exists($ph1ent['caref'], $vpncas)) {
736
					$thisca = lookup_ca($ph1ent['caref']);
737
					$vpncas[$ph1ent['caref']] = $thisca;
738

    
739
					/* follow chain up to root */
740
					$cachain = ca_chain_array($thisca);
741
					if ($cachain and is_array($cachain)) {
742
						foreach ($cachain as $cacrt) {
743
							$vpncas[$cacrt['refid']] = $cacrt;
744
						}
745
					}
746
				}
747
			}
748
		}
749
	}
750

    
751
	/* write the required CAs */
752
	foreach ($vpncas as $carefid => $cadata) {
753
		$cacrt = base64_decode($cadata['crt']);
754
		$cacrtattrs = openssl_x509_parse($cacrt);
755
		if (!is_array($cacrtattrs) || !isset($cacrtattrs['hash'])) {
756
			log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $cadata['descr']));
757
			continue;
758
		}
759
		$cafilename = "{$capath}/{$cacrtattrs['hash']}.0.crt";
760
		if (!@file_put_contents($cafilename, $cacrt)) {
761
				log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $cadata['descr']));
762
				continue;
763
		}
764
	}
765

    
766
	/* Add user PSKs */
767
	if (is_array($config['system']) && is_array($config['system']['user'])) {
768
		foreach ($config['system']['user'] as $user) {
769
			if (!empty($user['ipsecpsk'])) {
770
				$pskconf .= "{$myid} {$user['name']} : PSK 0s" . base64_encode($user['ipsecpsk']) . "\n";
771
			}
772
		}
773
		unset($user);
774
	}
775

    
776
	/* add PSKs for mobile clients */
777
	if (is_array($ipseccfg['mobilekey'])) {
778
		foreach ($ipseccfg['mobilekey'] as $key) {
779
			if ($key['ident'] == "allusers") {
780
				$key['ident'] = '%any';
781
			}
782
			if ($key['ident'] == "any") {
783
				$key['ident'] = '%any';
784
			}
785
			if (empty($key['type'])) {
786
				$key['type'] = 'PSK';
787
			}
788
			$pskconf .= " {$key['ident']} : {$key['type']} 0s" . base64_encode($key['pre-shared-key']) . "\n";
789
		}
790
		unset($key);
791
	}
792

    
793
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
794
	chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
795
	unset($pskconf);
796

    
797
	$uniqueids = 'yes';
798
	if (!empty($config['ipsec']['uniqueids'])) {
799
		if (array_key_exists($config['ipsec']['uniqueids'], $ipsec_idhandling)) {
800
			$uniqueids = $config['ipsec']['uniqueids'];
801
		}
802
	}
803
	$natfilterrules = false;
804
	/* begin ipsec.conf */
805
	$ipsecconf = "";
806
	$enablecompression = false;
807
	if (is_array($a_phase1) && count($a_phase1)) {
808

    
809
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
810
		$ipsecconf .= "config setup\n\tuniqueids = {$uniqueids}\n";
811

    
812
		if (isset($config['ipsec']['strictcrlpolicy'])) {
813
			$ipsecconf .= "\tstrictcrlpolicy = yes \n";
814
		}
815

    
816
		if (!isset($config['ipsec']['noshuntlaninterfaces'])) {
817
			$bypassnets = array();
818
			if ($config['interfaces']['lan']) {
819
				$lanip = get_interface_ip("lan");
820
				if (!empty($lanip) && is_ipaddrv4($lanip)) {
821
					$lansn = get_interface_subnet("lan");
822
					$lansa = gen_subnetv4($lanip, $lansn);
823
					if (!empty($lansa) && !empty($lansn)) {
824
						$bypassnets[] = "{$lansa}/{$lansn}";
825
					}
826
				}
827
				$lanip6 = get_interface_ipv6("lan");
828
				if (!empty($lanip6) && is_ipaddrv6($lanip6)) {
829
					$lansn6 = get_interface_subnetv6("lan");
830
					$lansa6 = gen_subnetv6($lanip6, $lansn6);
831
					if (!empty($lansa6) && !empty($lansn6)) {
832
						$bypassnets[] = "{$lansa6}/{$lansn6}";
833
					}
834
				}
835
			}
836
			if (!empty($bypassnets)) {
837
				$bypass = implode(',', $bypassnets);
838
				$ipsecconf .= <<<EOD
839

    
840
conn bypasslan
841
	leftsubnet = {$bypass}
842
	rightsubnet = {$bypass}
843
	authby = never
844
	type = passthrough
845
	auto = route
846

    
847
EOD;
848
			}
849
		}
850

    
851
		foreach ($a_phase1 as $ph1ent) {
852
			if (isset($ph1ent['disabled'])) {
853
				continue;
854
			}
855

    
856
			if ($ph1ent['mode'] == "aggressive") {
857
				$aggressive = "yes";
858
			} else {
859
				$aggressive = "no";
860
			}
861

    
862
			$ep = ipsec_get_phase1_src($ph1ent);
863
			if (!$ep) {
864
				continue;
865
			}
866

    
867
			$ikeid = $ph1ent['ikeid'];
868
			$keyexchange = "ikev1";
869
			$passive = "route";
870

    
871
			$closeaction = "";
872
			if (!empty($ph1ent['closeaction'])) {
873
				$closeaction = "closeaction = {$ph1ent['closeaction']}";
874
			}
875

    
876
			if (!empty($ph1ent['iketype'])) {
877
				if ($ph1ent['iketype'] == "ikev2") {
878
					$keyexchange = "ikev2";
879
				} elseif ($ph1ent['iketype'] == "auto") {
880
					$keyexchange = "ike";
881
				}
882
			}
883

    
884
			if (isset($ph1ent['mobile'])) {
885
				$right_spec = "%any";
886
				$passive = 'add';
887
			} else {
888
				if (isset($ph1ent['responderonly'])) {
889
					$passive = 'add';
890
				}
891

    
892
				$right_spec = $ph1ent['remote-gateway'];
893
				if (is_ipaddr($right_spec)) {
894
					$sourcehost = $right_spec;
895
				} else {
896
					$sourcehost = $rgmap[$right_spec];
897
				}
898

    
899
				if (substr($ph1ent['interface'], 0, 4) == "_vip") {
900
					$vpninterface = get_configured_vip_interface($ph1ent['interface']);
901
					if (substr($vpninterface, 0, 4) == "_vip") {
902
						// vips are nested if its a ipalias with a carp parent
903
						$vpninterface = get_configured_vip_interface($vpninterface);
904
					}
905
					$ifacesuse = get_real_interface($vpninterface);
906
				} else {
907
					$ifacesuse = get_failover_interface($ph1ent['interface']);
908
					if (substr($ifacesuse, 0, 4) == "_vip") {
909
						$vpninterface = get_configured_vip_interface($ifacesuse);
910
						$ifacesuse = get_real_interface($vpninterface);
911
					} else {
912
						$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
913
					}
914
				}
915
				if ($ph1ent['protocol'] == 'inet') {
916
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
917
						$gatewayip = get_interface_gateway($vpninterface);
918
						$interfaceip = get_interface_ip($vpninterface);
919
						$subnet_bits = get_interface_subnet($vpninterface);
920
						$subnet_ip = gen_subnetv4($interfaceip, $subnet_bits);
921
						/* if the remote gateway is in the local subnet, then don't add a route */
922
						if (is_ipaddrv4($sourcehost) &&
923
						    !ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
924
							if (is_ipaddrv4($gatewayip)) {
925
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
926
								route_add_or_change("-host {$sourcehost} {$gatewayip}");
927
							}
928
						}
929
					}
930
				} else if ($ph1ent['protocol'] == 'inet6') {
931
					if (!empty($ifacesuse) && interface_has_gatewayv6($vpninterface)) {
932
						$gatewayip = get_interface_gateway_v6($vpninterface);
933
						$interfaceip = get_interface_ipv6($vpninterface);
934
						$subnet_bits = get_interface_subnetv6($vpninterface);
935
						$subnet_ip = gen_subnetv6($interfaceip, $subnet_bits);
936
						/* if the remote gateway is in the local subnet, then don't add a route */
937
						if (is_ipaddrv6($sourcehost) &&
938
						    !ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
939
							if (is_ipaddrv6($gatewayip)) {
940
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
941
								route_add_or_change("-inet6 -host {$sourcehost} {$gatewayip}");
942
							}
943
						}
944
					}
945
				}
946
			}
947

    
948
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
949
			$leftid = ipsec_fixup_id($myid_type, $myid_data);
950
			if (!empty($leftid)) {
951
				$leftid = "leftid = {$leftid}";
952
			}
953

    
954
			$peerid_spec = '';
955
			if (isset($ph1ent['mobile']) && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
956
				// Only specify peer ID if we are not dealing with mobile PSK
957
			} else {
958
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
959
				$peerid_spec = ipsec_fixup_id($peerid_type, $peerid_data);
960
			}
961

    
962
			$ealgosp1 = '';
963
			if (is_array($ph1ent['encryption']['item'])) {
964
				$ciphers = "";
965
				foreach($ph1ent['encryption']['item'] as $p1enc) {
966
					if (!is_array($p1enc['encryption-algorithm']) ||
967
							empty($p1enc['encryption-algorithm']['name']) ||
968
							empty($p1enc['hash-algorithm'])) {
969
						continue;
970
					}
971
					$ciphers .= ",";
972
					$ciphers .= $p1enc['encryption-algorithm']['name'];
973
					$ealg_kl = $p1enc['encryption-algorithm']['keylen'];
974
					if ($ealg_kl) {
975
						$ciphers .= "{$ealg_kl}";
976
					}
977
					$ciphers .= "-{$p1enc['hash-algorithm']}";
978

    
979
					$modp = vpn_ipsec_convert_to_modp($p1enc['dhgroup']);
980
					if (!empty($modp)) {
981
						$ciphers .= "-{$modp}";
982
					}
983
				}
984
				$ciphers = substr($ciphers, 1);
985
				$ealgosp1 = "ike = {$ciphers}!";
986
			}
987

    
988
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
989
				if ($passive == "route") {
990
					$dpdline = "dpdaction = restart";
991
				} else {
992
					$dpdline = "dpdaction = clear";
993
				}
994
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
995
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
996
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
997
			} else {
998
				$dpdline = "dpdaction = none";
999
			}
1000

    
1001
			$ikelifeline = '';
1002
			if ($ph1ent['lifetime']) {
1003
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
1004
			}
1005

    
1006
			$rightsourceip = NULL;
1007
			$rightdnsserver = NULL;
1008
			if (isset($ph1ent['mobile'])) {
1009
				$rightsourceips = array();
1010
				if (!empty($a_client['pool_address'])) {
1011
					$rightsourceips[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1012
				}
1013
				if (!empty($a_client['pool_address_v6'])) {
1014
					$rightsourceips[] = "{$a_client['pool_address_v6']}/{$a_client['pool_netbits_v6']}";
1015
				}
1016
				if ($ph1ent['authentication_method'] == "eap-radius" && !count($rightsourceips)) {
1017
					$rightsourceips[] = "%radius";
1018
				}
1019
				if (count($rightsourceips)) {
1020
					$rightsourceip = "\trightsourceip = " . implode(',', $rightsourceips) . "\n";
1021
				}
1022

    
1023
				$rightdnsservers = array();
1024
				if (!empty($a_client['dns_server1'])) {
1025
					$rightdnsservers[] = $a_client['dns_server1'];
1026
				}
1027
				if (!empty($a_client['dns_server2'])) {
1028
					$rightdnsservers[] = $a_client['dns_server2'];
1029
				}
1030
				if (!empty($a_client['dns_server3'])) {
1031
					$rightdnsservers[] = $a_client['dns_server3'];
1032
				}
1033
				if (!empty($a_client['dns_server4'])) {
1034
					$rightdnsservers[] = $a_client['dns_server4'];
1035
				}
1036

    
1037
				if (count($rightdnsservers)) {
1038
					$rightdnsserver = "\trightdns = " . implode(',', $rightdnsservers) . "\n";
1039
				}
1040
			}
1041

    
1042
			if (!empty($ph1ent['caref'])) {
1043
				$ca = lookup_ca($ph1ent['caref']);
1044
				if ($ca) {
1045
					$casubarr = cert_get_subject_array($ca['crt']);
1046
					$casub = "";
1047
					foreach ($casubarr as $casubfield) {
1048
						if (empty($casub)) {
1049
							$casub = "/";
1050
						}
1051
						/* The subfield value could be an array. To avoid duplicating code,
1052
						 * always make it an array then iterate.
1053
						 * See https://redmine.pfsense.org/issues/7929
1054
						 */
1055
						if (!is_array($casubfield['v'])) {
1056
							$casubfield['v'] = array($casubfield['v']);
1057
						}
1058
						foreach ($casubfield['v'] as $casubval) {
1059
							$casub .= "{$casubfield['a']}={$casubval}/";
1060
						}
1061
					}
1062

    
1063
				}
1064
			}
1065

    
1066
			$authentication = "";
1067
			switch ($ph1ent['authentication_method']) {
1068
				case 'eap-mschapv2':
1069
					if (isset($ph1ent['mobile'])) {
1070
						$authentication = "eap_identity=%any\n\t";
1071
						$authentication .= "leftauth=pubkey\n\trightauth=eap-mschapv2";
1072
						if (!empty($ph1ent['certref'])) {
1073
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1074
							$authentication .= "\n\tleftsendcert=always";
1075
						}
1076
					}
1077
					break;
1078
				case 'eap-tls':
1079
					if (isset($ph1ent['mobile'])) {
1080
						$authentication = "eap_identity=%identity\n\t";
1081
						$authentication .= "leftauth=pubkey\n\trightauth=eap-tls";
1082
						if (!empty($ph1ent['certref'])) {
1083
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1084
							$authentication .= "\n\tleftsendcert=always";
1085
						}
1086
					} else {
1087
						$authentication = "leftauth=eap-tls\n\trightauth=eap-tls";
1088
						if (!empty($ph1ent['certref'])) {
1089
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1090
							$authentication .= "\n\tleftsendcert=always";
1091
						}
1092
					}
1093
					if (isset($casub)) {
1094
						$authentication .= "\n\trightca=\"$casub\"";
1095
					}
1096
					break;
1097
				case 'eap-radius':
1098
					if (isset($ph1ent['mobile'])) {
1099
						$authentication = "eap_identity=%identity\n\t";
1100
						$authentication .= "leftauth=pubkey\n\trightauth=eap-radius";
1101
						if (!empty($ph1ent['certref'])) {
1102
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1103
							$authentication .= "\n\tleftsendcert=always";
1104
						}
1105
					} else {
1106
						$authentication = "leftauth=eap-radius\n\trightauth=eap-radius";
1107
						if (!empty($ph1ent['certref'])) {
1108
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1109
							$authentication .= "\n\tleftsendcert=always";
1110
						}
1111
					}
1112
					break;
1113
				case 'xauth_cert_server':
1114
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
1115
					$authentication .= "\n\trightauth2 = xauth-generic";
1116
					if (!empty($ph1ent['certref'])) {
1117
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1118
						$authentication .= "\n\tleftsendcert=always";
1119
					}
1120
					if (isset($casub)) {
1121
						$authentication .= "\n\trightca=\"$casub\"";
1122
					}
1123
					break;
1124
				case 'xauth_psk_server':
1125
					$authentication = "leftauth = psk\n\trightauth = psk";
1126
					$authentication .= "\n\trightauth2 = xauth-generic";
1127
					break;
1128
				case 'pre_shared_key':
1129
					$authentication = "leftauth = psk\n\trightauth = psk";
1130
					break;
1131
				case 'cert':
1132
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
1133
					if (!empty($ph1ent['certref'])) {
1134
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1135
						$authentication .= "\n\tleftsendcert=always";
1136
					}
1137
					if (isset($casub)) {
1138
						$authentication .= "\n\trightca=\"$casub\"";
1139
					}
1140
					break;
1141
				case 'hybrid_cert_server':
1142
					$authentication = "leftauth = pubkey\n\trightauth = xauth-generic";
1143
					if (!empty($ph1ent['certref'])) {
1144
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1145
						$authentication .= "\n\tleftsendcert=always";
1146
					}
1147
					break;
1148
			}
1149

    
1150
			$left_spec = $ep;
1151

    
1152
			if (isset($ph1ent['reauth_enable'])) {
1153
				$reauth = "reauth = no";
1154
			} else {
1155
				$reauth = "reauth = yes";
1156
			}
1157

    
1158
			if (isset($ph1ent['rekey_enable'])) {
1159
				$rekeyline = "rekey = no";
1160
			} else {
1161
				$rekeyline = "rekey = yes";
1162
				if(!empty($ph1ent['margintime'])){
1163
					$rekeyline .= "\n\tmargintime = {$ph1ent['margintime']}s";
1164
				}
1165
			}
1166

    
1167
			if ($ph1ent['nat_traversal'] == 'off') {
1168
				$forceencaps = 'forceencaps = no';
1169
			} else if ($ph1ent['nat_traversal'] == 'force') {
1170
				$forceencaps = 'forceencaps = yes';
1171
			} else {
1172
				$forceencaps = 'forceencaps = no';
1173
			}
1174

    
1175
			if ($ph1ent['mobike'] == 'on') {
1176
				$mobike = 'mobike = yes';
1177
			} else {
1178
				$mobike = 'mobike = no';
1179
			}
1180

    
1181
			if (isset($ph1ent['tfc_enable'])) {
1182
				if (isset($ph1ent['tfc_bytes']) && is_numericint($ph1ent['tfc_bytes'])) {
1183
					$tfc = "tfc = {$ph1ent['tfc_bytes']}";
1184
				} else {
1185
					$tfc = "tfc = %mtu";
1186
				}
1187
			}
1188

    
1189
			$ipseclifetime = 0;
1190
			$rightsubnet_spec = array();
1191
			$leftsubnet_spec = array();
1192
			$reqids = array();
1193
			$vtireq = array();
1194
			$ealgoAHsp2arr = array();
1195
			$ealgoESPsp2arr = array();
1196
			if (is_array($a_phase2) && count($a_phase2)) {
1197
				foreach ($a_phase2 as $ph2ent) {
1198
					if ($ikeid != $ph2ent['ikeid']) {
1199
						continue;
1200
					}
1201

    
1202
					if (isset($ph2ent['disabled'])) {
1203
						continue;
1204
					}
1205

    
1206
					if (isset($ph2ent['mobile']) && !isset($a_client['enable'])) {
1207
						continue;
1208
					}
1209

    
1210
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
1211
						$tunneltype = "type = tunnel";
1212
						$installpolicy = "installpolicy = yes";
1213

    
1214
						$localid_type = $ph2ent['localid']['type'];
1215
						$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
1216

    
1217
						/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
1218
						if (($localid_type == "none" || $localid_type == "mobile") &&
1219
						    isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ikeid) == 1)) {
1220
							$left_spec = '%any';
1221
						} else {
1222
							if ($localid_type != "address") {
1223
								$localid_type = "subnet";
1224
							}
1225
							// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
1226
							if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) {
1227
								log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
1228
								continue;
1229
							}
1230
							if (!empty($ph2ent['natlocalid'])) {
1231
								$natleftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
1232
								if ($ph2ent['natlocalid']['type'] != "address") {
1233
									if (is_subnet($natleftsubnet_data)) {
1234
										$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
1235
									}
1236
								} else {
1237
									if (is_ipaddr($natleftsubnet_data)) {
1238
										$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
1239
									}
1240
								}
1241
								$natfilterrules = true;
1242
							}
1243
						}
1244

    
1245
						$leftsubnet_spec[] = $leftsubnet_data;
1246

    
1247
						if (!isset($ph2ent['mobile'])) {
1248
							$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
1249
							$rightsubnet_spec[] = $tmpsubnet;
1250
						} else if (!empty($a_client['pool_address'])) {
1251
							$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1252
						}
1253
					} elseif ($ph2ent['mode'] == 'vti') {
1254
						$tunneltype = "";
1255
						$installpolicy = "installpolicy = no";
1256
						$passive = 'start';
1257

    
1258
						$localid_type = $ph2ent['localid']['type'];
1259
						$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
1260
						$leftsubnet_spec[] = $leftsubnet_data;
1261

    
1262
						$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
1263
						$rightsubnet_spec[] = $tmpsubnet;
1264
						$vtireq[] = $ph2ent['reqid'];
1265
					} else {
1266
						$tunneltype = "type = transport";
1267
						$installpolicy = "installpolicy = yes";
1268

    
1269
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
1270
						    ($ph1ent['authentication_method'] == "pre_shared_key")) &&
1271
						    isset($ph1ent['mobile'])) {
1272
							$left_spec = "%any";
1273
						} else {
1274
							$tmpsubnet = ipsec_get_phase1_src($ph1ent);
1275
							$leftsubnet_spec[] = $tmpsubnet;
1276
						}
1277

    
1278
						if (!isset($ph2ent['mobile'])) {
1279
							$rightsubnet_spec[] = $right_spec;
1280
						}
1281
					}
1282

    
1283
					if (isset($a_client['pfs_group']) && isset($ph2ent['mobile'])) {
1284
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
1285
					}
1286

    
1287
					if ($ph2ent['protocol'] == 'esp') {
1288
						if (is_array($ph2ent['encryption-algorithm-option'])) {
1289
							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
1290
								$ealg_id = $ealg['name'];
1291
								$ealg_kl = $ealg['keylen'];
1292

    
1293
								if (!empty($ealg_kl) && $ealg_kl == "auto") {
1294
									if (empty($p2_ealgos) || !is_array($p2_ealgos)) {
1295
										require_once("ipsec.inc");
1296
									}
1297
									$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
1298
									$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
1299
									$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
1300
									/* XXX: in some cases where include ordering is suspect these variables
1301
									 * are somehow 0 and we enter this loop forever and timeout after 900
1302
									 * seconds wrecking bootup */
1303
									if ($key_hi != 0 and $key_lo != 0 and $key_step != 0) {
1304
										for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
1305
											if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1306
												foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1307
													$halgo = str_replace('hmac_', '', $halgo);
1308
													$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
1309
													$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1310
													if (!empty($modp)) {
1311
														$tmpealgo .= "-{$modp}";
1312
													}
1313
													if (!in_array($tmpealgo, $ealgoESPsp2arr)) {
1314
														$ealgoESPsp2arr[] = $tmpealgo;
1315
													}
1316
												}
1317
											} else {
1318
												$tmpealgo = "{$ealg_id}{$keylen}";
1319
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1320
												if (!empty($modp)) {
1321
													$tmpealgo .= "-{$modp}";
1322
												}
1323
												if (!in_array($tmpealgo, $ealgoESPsp2arr)) {
1324
													$ealgoESPsp2arr[] = $tmpealgo;
1325
												}
1326
											}
1327
										}
1328
									}
1329
								} else {
1330
									if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1331
										foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1332
											$halgo = str_replace('hmac_', '', $halgo);
1333
											$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
1334
											$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1335
											if (!empty($modp)) {
1336
												$tmpealgo .= "-{$modp}";
1337
											}
1338
											if (!in_array($tmpealgo, $ealgoESPsp2arr)) {
1339
												$ealgoESPsp2arr[] = $tmpealgo;
1340
											}
1341
										}
1342
									} else {
1343
										$tmpealgo = "{$ealg_id}{$ealg_kl}";
1344
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1345
										if (!empty($modp)) {
1346
											$tmpealgo .= "-{$modp}";
1347
										}
1348
										if (!in_array($tmpealgo, $ealgoESPsp2arr)) {
1349
											$ealgoESPsp2arr[] = $tmpealgo;
1350
										}
1351
									}
1352
								}
1353
							}
1354
						}
1355
					} else if ($ph2ent['protocol'] == 'ah') {
1356
						if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1357
							$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1358
							foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
1359
								$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
1360
								if (!empty($modp)) {
1361
									$tmpAHalgo = "-{$modp}";
1362
								}
1363
								if (!in_array($tmpAHalgo, $ealgoAHsp2arr)) {
1364
									$ealgoAHsp2arr[] = $tmpAHalgo;
1365
								}
1366
							}
1367
						}
1368
					}
1369

    
1370
					$reqids[] = $ph2ent['reqid'];
1371
					if ($ph2ent['mode'] != 'vti') {
1372
						$vtireq[] = null;
1373
					}
1374

    
1375
					if (!empty($ph2ent['lifetime'])) {
1376
						if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) {
1377
							$ipseclifetime = intval($ph2ent['lifetime']);
1378
						}
1379
					}
1380

    
1381
				}
1382
			}
1383

    
1384
			$ipsecconnect =<<<EOD
1385
	fragmentation = yes
1386
	keyexchange = {$keyexchange}
1387
	{$reauth}
1388
	{$forceencaps}
1389
	{$mobike}
1390
	{$tfc}
1391
	{$rekeyline}
1392
	{$installpolicy}
1393
	{$tunneltype}
1394
	{$dpdline}
1395
	{$closeaction}
1396
	auto = {$passive}
1397
	left = {$left_spec}
1398
	right = {$right_spec}
1399
	{$leftid}
1400

    
1401
EOD;
1402

    
1403
			/* Disable ipcomp for now. redmine #6167
1404
			if (isset($config['ipsec']['compression'])) {
1405
				$ipsecconnect .= "\tcompress = yes\n";
1406
				$enablecompression = true;
1407
			} */
1408
			if (!empty($ikelifeline)) {
1409
				$ipsecconnect .= "\t{$ikelifeline}\n";
1410
			}
1411
			if ($ipseclifetime > 0) {
1412
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
1413
			}
1414
			if (!empty($rightsourceip)) {
1415
				$ipsecconnect .= "{$rightsourceip}";
1416
			}
1417
			if (!empty($rightdnsserver)) {
1418
				$ipsecconnect .= "{$rightdnsserver}";
1419
			}
1420
			if (!empty($ealgosp1)) {
1421
				$ipsecconnect .= "\t{$ealgosp1}\n";
1422
			}
1423
			if (!empty($ealgoAHsp2arr)) {
1424
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
1425
			}
1426
			if (!empty($ealgoESPsp2arr)) {
1427
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
1428
			}
1429
			if (!empty($authentication)) {
1430
				$ipsecconnect .= "\t{$authentication}\n";
1431
			}
1432
			if (!empty($peerid_spec)) {
1433
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
1434
			}
1435
			if ($keyexchange != 'ikev2') {
1436
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
1437
			}
1438

    
1439
			if (!isset($ph1ent['mobile']) && ($keyexchange == 'ikev1' || isset($ph1ent['splitconn']))) {
1440
				if (!empty($rightsubnet_spec)) {
1441
					$ipsecfin = '';
1442
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
1443
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
1444
						//if (!empty($reqids[$idx])) {
1445
						//	$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
1446
						//}
1447
						$rightadd = "";
1448
						$leftadd = "";
1449
						if (!empty($vtireq[$idx])) {
1450
							$ipsecfin .= "\treqid = {$ph1ent['ikeid']}00{$idx}\n";
1451
							/* This interface will be a valid IPsec interface, so remove it from the cleanup list. */
1452
							$ipsec_vti_cleanup_ifs = array_diff($ipsec_vti_cleanup_ifs, array("ipsec{$ph1ent['ikeid']}00{$idx}"));
1453
							$rightadd = ",0.0.0.0/0";
1454
							$leftadd = ",0.0.0.0/0";
1455
						}
1456
						$ipsecfin .= $ipsecconnect;
1457
						$ipsecfin .= "\trightsubnet = {$rsubnet}{$rightadd}\n";
1458
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "{$leftadd}\n";
1459
					}
1460
				} else {
1461
					log_error(sprintf(gettext("No phase2 specifications for tunnel with REQID = %s"), $ikeid));
1462
				}
1463
			} else {
1464
				if (isset($ph1ent['mobile'])) {
1465
					$ipsecfin = "\nconn con-mobile\n";
1466
				}
1467
				else {
1468
					$ipsecfin = "\nconn con{$ph1ent['ikeid']}000\n";
1469
				}
1470
				//if (!empty($reqids[$idx])) {
1471
				//	$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
1472
				//}
1473
				$rightadd = "";
1474
				$leftadd = "";
1475
				if (!empty($vtireq[0])) {
1476
					$ipsecfin .= "\treqid = {$ph1ent['ikeid']}000\n";
1477
					/* This interface will be a valid IPsec interface, so remove it from the cleanup list. */
1478
					$ipsec_vti_cleanup_ifs = array_diff($ipsec_vti_cleanup_ifs, array("ipsec{$ph1ent['ikeid']}000"));
1479
					$rightadd = ",0.0.0.0/0";
1480
					$leftadd = ",0.0.0.0/0";
1481
				}
1482
				$ipsecfin .= $ipsecconnect;
1483
				if (!isset($ph1ent['mobile']) && !empty($rightsubnet_spec)) {
1484
					$tempsubnets = array();
1485
					foreach ($rightsubnet_spec as $rightsubnet) {
1486
						$tempsubnets[$rightsubnet] = $rightsubnet;
1487
					}
1488
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "{$rightadd}\n";
1489
					unset($tempsubnets, $rightsubnet);
1490
				}
1491
				if (!empty($leftsubnet_spec)) {
1492
					$tempsubnets = array();
1493
					foreach ($leftsubnet_spec as $leftsubnet) {
1494
						$tempsubnets[$leftsubnet] = $leftsubnet;
1495
					}
1496
					$ipsecfin .= "\tleftsubnet = " . join(",", $tempsubnets) . "{$leftadd}\n";
1497
					unset($tempsubnets, $leftsubnet);
1498
				}
1499
			}
1500
			$ipsecconf .= $ipsecfin;
1501
			unset($ipsecfin);
1502
		}
1503
	}
1504

    
1505
	$a_mobilekey = $config['ipsec']['mobilekey'];
1506

    
1507
	if (is_array($a_phase1) && count($a_phase1)) {
1508
		foreach ($a_phase1 as $ph1ent) {
1509
			if (!isset($ph1ent['mobile'])) {
1510
				continue;
1511
			}
1512
			if (isset($ph1ent['disabled'])) {
1513
				continue;
1514
			}
1515

    
1516
			if (is_array($a_mobilekey) && count($a_mobilekey)) {
1517
				$ipsecfin = '';
1518
				$mobilekey_counter = 1;
1519
				foreach ($a_mobilekey as $mkent) {
1520
					if ($mkent['type'] != "EAP") {
1521
						continue;
1522
					}
1523

    
1524
					if (!isset($mkent['ident_type']) || !isset($mkent['pool_address']) || !isset($mkent['pool_netbits'])) {
1525
						continue;
1526
					}
1527

    
1528
					if (strlen($mkent['pool_address']) < 1 || !is_ipaddr($mkent['pool_address'])) {
1529
						continue;
1530
					}
1531
					$clientid = ($mkent['ident_type'] == "none") ? "\"{$mkent['ident']}\"" : "{$mkent['ident_type']}:{$mkent['ident']}";
1532
					$clienteapid = ($ph1ent['authentication_method'] == "eap-mschapv2") ? $clientid : '%identity';
1533
					$ipsecfin .= "\nconn mobile-{$mobilekey_counter}\n";
1534
					$ipsecfin .= "\talso = con-mobile\n";
1535
					$ipsecfin .= "\teap_identity = {$clienteapid}\n";
1536
					$ipsecfin .= "\trightsourceip = {$mkent['pool_address']}/{$mkent['pool_netbits']}\n";
1537

    
1538
					if (isset($mkent['dns_address']) && strlen($mkent['dns_address']) > 0 && is_ipaddr($mkent['dns_address'])) {
1539
						$ipsecfin .= "\trightdns = {$mkent['dns_address']}\n";
1540
					}
1541

    
1542
					$ipsecfin .= "\trightid = {$clientid}\n";
1543

    
1544
					// optional: define left|rightid more granular
1545
					// supported: ipv4, ipv6, rfc822, email, userfqdn, fqdn, dns, asn1dn, asn1gn, keyid
1546
					// example: $ipsecfin = "\trightid = email:your@email.address\n";
1547

    
1548
					// note: comma separated list for access restriction, regardless of firewall rules
1549
					// example: $ipsecfin = "\tleftsubnet = 1.1.1.1/32,1.1.1.2/32,2.2.2.0/24\n";
1550

    
1551
					$mobilekey_counter++;
1552
				}
1553
				$ipsecconf .= $ipsecfin;
1554
				unset($ipsecfin);
1555
				unset($mobilekey_counter);
1556
			}
1557
		}
1558
	}
1559

    
1560
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1561
	unset($ipsecconf);
1562
	/* end ipsec.conf */
1563

    
1564
	foreach ($ipsec_vti_cleanup_ifs as $cleanif) {
1565
		if (does_interface_exist($cleanif)) {
1566
			mwexec("/sbin/ifconfig " . escapeshellarg($cleanif) . " destroy", false);
1567
		}
1568
	}
1569

    
1570
	if ($enablecompression === true) {
1571
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1572
	} else {
1573
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1574
	}
1575

    
1576
	/* manage process */
1577
	if ($restart === true) {
1578
		mwexec("/usr/local/sbin/ipsec restart", false);
1579
	} else {
1580
		if (isvalidpid("{$g['varrun_path']}/starter.charon.pid")) {
1581
			/* Update configuration changes */
1582
			/* Read secrets */
1583
			mwexec("/usr/local/sbin/ipsec rereadall", false);
1584
			mwexec("/usr/local/sbin/ipsec reload", false);
1585
		} else {
1586
			mwexec("/usr/local/sbin/ipsec start", false);
1587
		}
1588
	}
1589

    
1590
	// run ping_hosts.sh once if it's enabled to avoid wait for minicron
1591
	if ($ipsecpinghostsactive == true) {
1592
		mwexec_bg("/usr/local/bin/ping_hosts.sh");
1593
	}
1594

    
1595
	if ($natfilterrules == true) {
1596
		filter_configure();
1597
	}
1598
	/* start filterdns, if necessary */
1599
	if (count($filterdns_list) > 0) {
1600
		$interval = 60;
1601
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) {
1602
			$interval = $ipseccfg['dns-interval'];
1603
		}
1604

    
1605
		$hostnames = "";
1606
		array_unique($filterdns_list);
1607
		foreach ($filterdns_list as $hostname) {
1608
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1609
		}
1610
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1611
		unset($hostnames);
1612

    
1613
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid")) {
1614
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1615
		} else {
1616
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1617
		}
1618
	} else {
1619
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1620
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1621
	}
1622

    
1623
	if (platform_booting()) {
1624
		echo "done\n";
1625
	}
1626

    
1627
	unlock($ipsecstartlock);
1628
	return count($filterdns_list);
1629
}
1630

    
1631
/*
1632
 * Forcefully restart IPsec
1633
 * This is required for when dynamic interfaces reload
1634
 * For all other occasions the normal vpn_ipsec_configure()
1635
 * will gracefully reload the settings without restarting
1636
 */
1637
function vpn_ipsec_force_reload($interface = "") {
1638
	global $g, $config;
1639

    
1640
	if (!ipsec_enabled()) {
1641
		return;
1642
	}
1643

    
1644
	$ipseccfg = $config['ipsec'];
1645

    
1646
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1647
		$found = false;
1648
		foreach ($ipseccfg['phase1'] as $ipsec) {
1649
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1650
				$found = true;
1651
				break;
1652
			}
1653
		}
1654
		if (!$found) {
1655
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1656
			return;
1657
		}
1658
	}
1659

    
1660
	/* If we get this far then we need to take action. */
1661
	log_error(gettext("Forcefully reloading IPsec"));
1662
	vpn_ipsec_configure();
1663
}
1664

    
1665
/* master setup for vpn (mpd) */
1666
function vpn_setup() {
1667
	/* start pppoe server */
1668
	vpn_pppoes_configure();
1669

    
1670
	/* setup l2tp */
1671
	vpn_l2tp_configure();
1672
}
1673

    
1674
function vpn_netgraph_support() {
1675
	$iflist = get_configured_interface_list();
1676
	foreach ($iflist as $iface) {
1677
		$realif = get_real_interface($iface);
1678
		/* Get support for netgraph(4) from the nic */
1679
		$ifinfo = pfSense_get_interface_addresses($realif);
1680
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) {
1681
			pfSense_ngctl_attach(".", $realif);
1682
		}
1683
	}
1684
}
1685

    
1686
function vpn_pppoes_configure() {
1687
	global $config;
1688

    
1689
	if (is_array($config['pppoes']['pppoe'])) {
1690
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
1691
			vpn_pppoe_configure($pppoe);
1692
		}
1693
	}
1694
}
1695

    
1696
function vpn_pppoe_configure(&$pppoecfg) {
1697
	global $config, $g;
1698

    
1699
	$syscfg = $config['system'];
1700

    
1701
	/* create directory if it does not exist */
1702
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
1703
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1704
	}
1705

    
1706
	if (platform_booting()) {
1707
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
1708
			return 0;
1709
		}
1710

    
1711
		echo gettext("Configuring PPPoE Server service... ");
1712
	} else {
1713
		/* kill mpd */
1714
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1715

    
1716
		/* wait for process to die */
1717
		sleep(2);
1718

    
1719
	}
1720

    
1721
	switch ($pppoecfg['mode']) {
1722

    
1723
		case 'server':
1724

    
1725
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1726

    
1727
			if ($pppoecfg['paporchap'] == "chap") {
1728
				$paporchap = "set link enable chap";
1729
			} else {
1730
				$paporchap = "set link enable pap";
1731
			}
1732

    
1733
			/* write mpd.conf */
1734
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1735
			if (!$fd) {
1736
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1737
				return 1;
1738
			}
1739

    
1740
			$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 ";
1741
			if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1742
				$issue_ip_type .= "0.0.0.0/0";
1743
			} else {
1744
				$issue_ip_type .= "ippool p0";
1745
			}
1746

    
1747
			$ippool_p0 = ip_after($pppoecfg['remoteip'], $pppoecfg['n_pppoe_units'] - 1);
1748

    
1749
			if (is_numeric($pppoecfg['n_pppoe_maxlogin']) && ($pppoecfg['n_pppoe_maxlogin'] > 0)) {
1750
				$pppoemaxlogins = $pppoecfg['n_pppoe_maxlogin'];
1751
			} else {
1752
				$pppoemaxlogins = 1;
1753
			}
1754

    
1755
			$ipcp_dns = '';
1756
			if (!empty($pppoecfg['dns1'])) {
1757
				$ipcp_dns = "set ipcp dns " . $pppoecfg['dns1'];
1758
				if (!empty($pppoecfg['dns2'])) {
1759
					$ipcp_dns .= " " . $pppoecfg['dns2'];
1760
				}
1761
			} elseif (isset($config['dnsmasq']['enable']) ||
1762
			    isset ($config['unbound']['enable'])) {
1763
				$ipcp_dns = "set ipcp dns " . get_interface_ip("lan");
1764
				if ($syscfg['dnsserver'][0]) {
1765
					$ipcp_dns .= " " . $syscfg['dnsserver'][0];
1766
				}
1767
			} elseif (is_array($syscfg['dnsserver']) &&
1768
			    ($syscfg['dnsserver'][0])) {
1769
				$ipcp_dns = "set ipcp dns " . join(" ", $syscfg['dnsserver']);
1770
			}
1771

    
1772
			$mpdconf = <<<EOD
1773
startup:
1774

    
1775
poes:
1776
	set ippool add p0 {$pppoecfg['remoteip']} {$ippool_p0}
1777

    
1778
	create bundle template poes_b
1779
	set bundle enable compression
1780

    
1781
	set ccp yes mppc
1782
	set mppc yes e40
1783
	set mppc yes e128
1784
	set mppc yes stateless
1785

    
1786
	set iface group pppoe
1787
	set iface up-script /usr/local/sbin/vpn-linkup-poes
1788
	set iface down-script /usr/local/sbin/vpn-linkdown-poes
1789
	set iface idle 0
1790
	set iface disable on-demand
1791
	set iface disable proxy-arp
1792
	set iface enable tcpmssfix
1793
	set iface mtu 1500
1794

    
1795
	set ipcp no vjcomp
1796
	{$issue_ip_type}
1797
	{$ipcp_dns}
1798

    
1799
	create link template poes_l pppoe
1800
	set link action bundle poes_b
1801

    
1802
	set auth max-logins {$pppoemaxlogins}
1803

    
1804
	set pppoe iface {$pppoe_interface}
1805

    
1806
	set link no multilink
1807
	set link no pap chap
1808
	{$paporchap}
1809
	set link keep-alive 60 180
1810
	set link max-redial -1
1811
	set link mru 1492
1812
	set link latency 1
1813
	set link enable incoming
1814

    
1815
EOD;
1816

    
1817
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1818
				$radiusport = "";
1819
				$radiusacctport = "";
1820
				if (isset($pppoecfg['radius']['server']['port'])) {
1821
					$radiusport = $pppoecfg['radius']['server']['port'];
1822
				}
1823
				if (isset($pppoecfg['radius']['server']['acctport'])) {
1824
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1825
				}
1826
				$mpdconf .=<<<EOD
1827
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1828
	set radius retries 3
1829
	set radius timeout 10
1830
	set auth enable radius-auth
1831

    
1832
EOD;
1833

    
1834
				if (isset ($pppoecfg['radius']['accounting'])) {
1835
					$mpdconf .=<<<EOD
1836
	set auth enable radius-acct
1837

    
1838
EOD;
1839
				}
1840
				if (!empty($pppoecfg['radius']['nasip'])) {
1841
					$mpdconf .= "\tset radius me {$pppoecfg['radius']['nasip']}\n";
1842
				}
1843
			}
1844

    
1845
			fwrite($fd, $mpdconf);
1846
			fclose($fd);
1847
			unset($mpdconf);
1848

    
1849
			if ($pppoecfg['username']) {
1850
				/* write mpd.secret */
1851
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1852
				if (!$fd) {
1853
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1854
					return 1;
1855
				}
1856

    
1857
				$mpdsecret = "\n\n";
1858

    
1859
				if (!empty($pppoecfg['username'])) {
1860
					$item = explode(" ", $pppoecfg['username']);
1861
					foreach ($item as $userdata) {
1862
						$data = explode(":", $userdata);
1863
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1864
					}
1865
				}
1866

    
1867
				fwrite($fd, $mpdsecret);
1868
				fclose($fd);
1869
				unset($mpdsecret);
1870
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1871
			}
1872

    
1873
			/* Check if previous instance is still up */
1874
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
1875
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1876
			}
1877

    
1878
			/* Get support for netgraph(4) from the nic */
1879
			pfSense_ngctl_attach(".", $pppoe_interface);
1880
			/* fire up mpd */
1881
			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");
1882

    
1883
			break;
1884
	}
1885

    
1886
	if (platform_booting()) {
1887
		echo gettext("done") . "\n";
1888
	}
1889

    
1890
	return 0;
1891
}
1892

    
1893
function vpn_l2tp_configure() {
1894
	global $config, $g;
1895

    
1896
	$syscfg = $config['system'];
1897
	$l2tpcfg = $config['l2tp'];
1898

    
1899
	/* create directory if it does not exist */
1900
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
1901
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1902
	}
1903

    
1904
	if (platform_booting()) {
1905
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
1906
			return 0;
1907
		}
1908

    
1909
		echo gettext("Configuring l2tp VPN service... ");
1910
	} else {
1911
		/* kill mpd */
1912
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1913

    
1914
		/* wait for process to die */
1915
		sleep(8);
1916

    
1917
	}
1918

    
1919
	/* make sure l2tp-vpn directory exists */
1920
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
1921
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1922
	}
1923

    
1924
	switch ($l2tpcfg['mode']) {
1925

    
1926
		case 'server':
1927
			$l2tp_listen="";
1928
			$ipaddr = get_interface_ip(get_failover_interface($l2tpcfg['interface']));
1929
			if (is_ipaddrv4($ipaddr)) {
1930
				$l2tp_listen="set l2tp self $ipaddr";
1931
			}
1932

    
1933
			switch ($l2tpcfg['paporchap']) {
1934
				case 'chap':
1935
					$paporchap = "set link enable chap";
1936
					break;
1937
				case 'chap-msv2':
1938
					$paporchap = "set link enable chap-msv2";
1939
					break;
1940
				default:
1941
					$paporchap = "set link enable pap";
1942
					break;
1943
			}
1944

    
1945
			/* write mpd.conf */
1946
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1947
			if (!$fd) {
1948
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1949
				return 1;
1950
			}
1951

    
1952
			$ippool_p0 = ip_after($l2tpcfg['remoteip'], $l2tpcfg['n_l2tp_units'] - 1);
1953

    
1954
			$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 ";
1955
			if (isset($l2tpcfg['radius']['radiusissueips']) && isset($l2tpcfg['radius']['server']['enable'])) {
1956
				$issue_ip_type .= "0.0.0.0/0";
1957
			} else {
1958
				$issue_ip_type .= "ippool p0";
1959
			}
1960

    
1961
			$ipcp_dns = '';
1962
			if (is_ipaddr($l2tpcfg['dns1'])) {
1963
				$ipcp_dns = "set ipcp dns " . $l2tpcfg['dns1'];
1964
				if (is_ipaddr($l2tpcfg['dns2'])) {
1965
					$ipcp_dns .= " " . $l2tpcfg['dns2'];
1966
				}
1967
			} elseif (isset ($config['dnsmasq']['enable']) ||
1968
			    isset ($config['unbound']['enable'])) {
1969
				$ipcp_dns = "set ipcp dns " . get_interface_ip("lan");
1970
				if ($syscfg['dnsserver'][0]) {
1971
					$ipcp_dns .= " " . $syscfg['dnsserver'][0];
1972
				}
1973
			} elseif (is_array($syscfg['dnsserver']) &&
1974
			    ($syscfg['dnsserver'][0])) {
1975
				$ipcp_dns = "set ipcp dns " . join(" ", $syscfg['dnsserver']);
1976
			}
1977

    
1978
			$mpdconf =<<<EOD
1979

    
1980
startup:
1981

    
1982
l2tps:
1983
	set ippool add p0 {$l2tpcfg['remoteip']} {$ippool_p0}
1984

    
1985
	create bundle template l2tp_b
1986
	set bundle enable compression
1987
	set bundle yes crypt-reqd
1988

    
1989
	set ccp yes mppc
1990

    
1991
	set iface name l2tp
1992
	set iface group l2tp
1993
	set iface up-script /usr/local/sbin/vpn-linkup-l2tp
1994
	set iface down-script /usr/local/sbin/vpn-linkdown-l2tp
1995
	set iface disable on-demand
1996
	set iface enable proxy-arp
1997

    
1998
	set ipcp yes vjcomp
1999
	{$issue_ip_type}
2000
	{$ipcp_dns}
2001

    
2002
	create link template l2tp_l l2tp
2003
	set link action bundle l2tp_b
2004

    
2005
	set link yes acfcomp protocomp
2006
	set link enable multilink
2007
	set link no pap chap chap-msv2
2008
	{$paporchap}
2009
	{$l2tp_listen}
2010
	set link keep-alive 10 180
2011
	set link enable incoming
2012

    
2013
EOD;
2014

    
2015

    
2016
			if (isset ($l2tpcfg['radius']['enable'])) {
2017
				$mpdconf .=<<<EOD
2018
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
2019
	set radius retries 3
2020
	set radius timeout 10
2021
	set auth disable internal
2022
	set auth enable radius-auth
2023

    
2024
EOD;
2025

    
2026
				if (isset ($l2tpcfg['radius']['accounting'])) {
2027
					$mpdconf .=<<<EOD
2028
	set auth enable radius-acct
2029

    
2030
EOD;
2031
				}
2032
			}
2033

    
2034
			fwrite($fd, $mpdconf);
2035
			fclose($fd);
2036
			unset($mpdconf);
2037

    
2038
			/* write mpd.secret */
2039
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
2040
			if (!$fd) {
2041
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
2042
				return 1;
2043
			}
2044

    
2045
			$mpdsecret = "\n\n";
2046

    
2047
			if (is_array($l2tpcfg['user'])) {
2048
				foreach ($l2tpcfg['user'] as $user) {
2049
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
2050
				}
2051
			}
2052

    
2053
			fwrite($fd, $mpdsecret);
2054
			fclose($fd);
2055
			unset($mpdsecret);
2056
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
2057

    
2058
			vpn_netgraph_support();
2059

    
2060
			/* fire up mpd */
2061
			mwexec("/usr/local/sbin/mpd5 -b -d {$g['varetc_path']}/l2tp-vpn -p {$g['varrun_path']}/l2tp-vpn.pid -s l2tps l2tps");
2062

    
2063
			break;
2064

    
2065
		case 'redir':
2066
			break;
2067
	}
2068

    
2069
	if (platform_booting()) {
2070
		echo "done\n";
2071
	}
2072

    
2073
	return 0;
2074
}
2075

    
2076
?>
(55-55/60)