Project

General

Profile

Download (57.7 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * vpn.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2018 Rubicon Communications, LLC (Netgate)
7
 * Copyright (c) 2008 Shrew Soft Inc
8
 * All rights reserved.
9
 *
10
 * originally part of m0n0wall (http://m0n0.ch/wall)
11
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
12
 * All rights reserved.
13
 *
14
 * 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
 *
18
 * http://www.apache.org/licenses/LICENSE-2.0
19
 *
20
 * 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
 */
26

    
27
require_once("ipsec.inc");
28
require_once("filter.inc");
29
require_once("auth.inc");
30

    
31
function vpn_update_daemon_loglevel($category, $level) {
32
	global $ipsec_log_cats, $ipsec_log_sevs;
33

    
34
	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
		}
41

    
42
		mwexec("/usr/local/sbin/ipsec stroke loglevel {$category} {$argterm} {$level}");
43
	}
44
}
45

    
46
function vpn_logging_cfgtxt() {
47
	global $config, $ipsec_log_cats, $ipsec_log_sevs;
48

    
49
	$cfgtext = array();
50
	$log_levels = ipsec_get_loglevels();
51
	foreach (array_keys($ipsec_log_cats) as $cat) {
52
		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
		}
56
	}
57

    
58
	return $cfgtext;
59
}
60

    
61
/* include all configuration functions */
62
function vpn_ipsec_convert_to_modp($index) {
63

    
64
	$conversion = "";
65
	switch ($index) {
66
		case '1':
67
			$conversion = "modp768";
68
			break;
69
		case '2':
70
			$conversion = "modp1024";
71
			break;
72
		case '5':
73
			$conversion = "modp1536";
74
			break;
75
		case '14':
76
			$conversion = "modp2048";
77
			break;
78
		case '15':
79
			$conversion = "modp3072";
80
			break;
81
		case '16':
82
			$conversion = "modp4096";
83
			break;
84
		case '17':
85
			$conversion = "modp6144";
86
			break;
87
		case '18':
88
			$conversion = "modp8192";
89
			break;
90
		case '19':
91
			$conversion = "ecp256";
92
			break;
93
		case '20':
94
			$conversion = "ecp384";
95
			break;
96
		case '21':
97
			$conversion = "ecp521";
98
			break;
99
		case '22':
100
			$conversion = "modp1024s160";
101
			break;
102
		case '23':
103
			$conversion = "modp2048s224";
104
			break;
105
		case '24':
106
			$conversion = "modp2048s256";
107
			break;
108
		case '28':
109
			$conversion = "ecp256bp";
110
			break;
111
		case '29':
112
			$conversion = "ecp384bp";
113
			break;
114
		case '30':
115
			$conversion = "ecp512bp";
116
			break;
117
	}
118

    
119
	return $conversion;
120
}
121

    
122
function vpn_ipsec_configure($restart = false) {
123
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos, $ipsec_idhandling;
124

    
125
	$ipsecstartlock = lock('ipsec', LOCK_EX);
126

    
127
	/* get the automatic ping_hosts.sh ready */
128
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
129
	touch("{$g['vardb_path']}/ipsecpinghosts");
130
	$ipsecpinghostsactive = false;
131

    
132
	/* service may have been enabled, disabled, or otherwise changed in a way requiring rule updates */
133
	filter_configure();
134

    
135
	$syscfg = $config['system'];
136
	$ipseccfg = $config['ipsec'];
137
	if (!ipsec_enabled()) {
138
		/* try to stop charon */
139
		mwexec("/usr/local/sbin/ipsec stop");
140
		/* Stop dynamic monitoring */
141
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
142

    
143
		/* wait for process to die */
144
		sleep(2);
145

    
146
		/* IPSEC is off, shutdown enc interface.*/
147
		mwexec("/sbin/ifconfig enc0 down");
148

    
149
		unlock($ipsecstartlock);
150
		return 0;
151
	}
152

    
153
	$a_phase1 = $config['ipsec']['phase1'];
154
	$a_phase2 = $config['ipsec']['phase2'];
155
	$a_client = $config['ipsec']['client'];
156

    
157
	$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
	$crlpath = "{$g['varetc_path']}/ipsec/ipsec.d/crls";
161

    
162
	mwexec("/sbin/ifconfig enc0 up");
163

    
164
	/* needed for config files */
165
	if (!is_dir("{$g['varetc_path']}/ipsec")) {
166
		mkdir("{$g['varetc_path']}/ipsec");
167
	}
168
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d")) {
169
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d");
170
	}
171
	// 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
	if (!is_dir($capath)) {
177
		mkdir($capath);
178
	}
179
	if (!is_dir($keypath)) {
180
		mkdir($keypath);
181
	}
182
	if (!is_dir($crlpath)) {
183
		mkdir($crlpath);
184
	}
185
	if (!is_dir($certpath)) {
186
		mkdir($certpath);
187
	}
188
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts")) {
189
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts");
190
	}
191
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/acerts")) {
192
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/acerts");
193
	}
194
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts")) {
195
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts");
196
	}
197
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/reqs")) {
198
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/reqs");
199
	}
200

    
201
	if (!file_exists("/usr/local/etc/ipsec.d") ||
202
	    !is_link("/usr/local/etc/ipsec.d")) {
203
		if (file_exists("/usr/local/etc/ipsec.d")) {
204
			rmdir_recursive("/usr/local/etc/ipsec.d");
205
		}
206
		@symlink("{$g['varetc_path']}/ipsec/ipsec.d",
207
		    "/usr/local/etc/ipsec.d");
208
	}
209
	if (!file_exists("{$g['varetc_path']}/etc/strongswan.d") ||
210
	    !is_link("{$g['varetc_path']}/etc/strongswan.d")) {
211
		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
		@symlink("/usr/local/etc/strongswan.d",
217
		    "{$g['varetc_path']}/ipsec/strongswan.d");
218
	}
219
	if (!file_exists("/usr/local/etc/strongswan.conf") ||
220
	    !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
	if (!file_exists("/usr/local/etc/ipsec.conf") ||
226
	    !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

    
232
	if (platform_booting()) {
233
		echo gettext("Configuring IPsec VPN... ");
234
	}
235

    
236
	/* 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
	$ifacesuse = array();
243
	$mobile_ipsec_auth = "";
244
	if (is_array($a_phase1) && count($a_phase1)) {
245

    
246
		$ipsecpinghosts = "";
247
		/* step through each phase1 entry */
248
		foreach ($a_phase1 as $ph1ent) {
249
			if (isset($ph1ent['disabled'])) {
250
				continue;
251
			}
252

    
253
			if (substr($ph1ent['interface'], 0, 4) == "_vip") {
254
				$vpninterface = get_configured_vip_interface($ph1ent['interface']);
255
				$ifacesuse[] = get_real_interface($vpninterface);
256
			} else {
257
				$vpninterface = get_failover_interface($ph1ent['interface']);
258
				if (substr($vpninterface, 0, 4) == "_vip") {
259
					$vpninterface = get_configured_vip_interface($vpninterface);
260
					$ifacesuse[] = get_real_interface($vpninterface);
261
				} elseif (!empty($vpninterface)) {
262
					$ifacesuse[] = $vpninterface;
263
				}
264
			}
265

    
266
			if ($ph1ent['mode'] == "aggressive" && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
267
				$aggressive_mode_psk = true;
268
			}
269

    
270
			$ikeid = $ph1ent['ikeid'];
271

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

    
281
			if (!in_array($ep, $ipmap)) {
282
				$ipmap[] = $ep;
283
			}
284

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

    
288
			if (isset ($ph1ent['mobile'])) {
289
				$mobile_ipsec_auth = $ph1ent['authentication_method'];
290
				continue;
291
			}
292

    
293
			$rg = $ph1ent['remote-gateway'];
294

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

    
311
			if (is_array($a_phase2)) {
312
				/* step through each phase2 entry */
313
				foreach ($a_phase2 as $ph2ent) {
314
					if (isset($ph2ent['disabled'])) {
315
						continue;
316
					}
317

    
318
					if ($ikeid != $ph2ent['ikeid']) {
319
						continue;
320
					}
321

    
322
					/* add an ipsec pinghosts entry */
323
					if ($ph2ent['pinghost']) {
324
						if (!is_array($iflist)) {
325
							$iflist = get_configured_interface_list();
326
						}
327
						$srcip = null;
328
						$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
329
						if (is_ipaddrv6($ph2ent['pinghost'])) {
330
							foreach ($iflist as $ifent => $ifname) {
331
								$interface_ip = get_interface_ipv6($ifent);
332
								if (!is_ipaddrv6($interface_ip)) {
333
									continue;
334
								}
335
								if (ip_in_subnet($interface_ip, $local_subnet)) {
336
									$srcip = $interface_ip;
337
									break;
338
								}
339
							}
340
						} else {
341
							foreach ($iflist as $ifent => $ifname) {
342
								$interface_ip = get_interface_ip($ifent);
343
								if (!is_ipaddrv4($interface_ip)) {
344
									continue;
345
								}
346
								if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) {
347
									$srcip = $interface_ip;
348
									break;
349
								}
350
							}
351
						}
352
						/* if no valid src IP was found in configured interfaces, try the vips */
353
						if (is_null($srcip)) {
354
							$viplist = get_configured_vip_list();
355
							foreach ($viplist as $vip => $address) {
356
								if (ip_in_subnet($address, $local_subnet)) {
357
									$srcip = $address;
358
									break;
359
								}
360
							}
361
						}
362
						$dstip = $ph2ent['pinghost'];
363
						if (is_ipaddrv6($dstip)) {
364
							$family = "inet6";
365
						} else {
366
							$family = "inet";
367
						}
368
						if (is_ipaddr($srcip)) {
369
							$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
370
							$ipsecpinghostsactive = true;
371
						}
372
					}
373
				}
374
			}
375
		}
376
		@file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
377
		unset($ipsecpinghosts);
378
	}
379
	unset($iflist);
380

    
381
	$accept_unencrypted = "";
382
	if (isset($config['ipsec']['acceptunencryptedmainmode'])) {
383
		$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
384
	}
385

    
386
	$stronconf = '';
387
	if (file_exists("{$g['varetc_path']}/ipsec/strongswan.conf")) {
388
		$stronconf = file_get_contents("{$g['varetc_path']}/ipsec/strongswan.conf");
389
	}
390

    
391
	$i_dont_care_about_security_and_use_aggressive_mode_psk = "";
392
	if ($aggressive_mode_psk) {
393
		log_error("WARNING: Setting i_dont_care_about_security_and_use_aggressive_mode_psk option because a phase 1 is configured using aggressive mode with pre-shared keys. This is not a secure configuration.");
394
		if (!empty($stronconf) && strpos($stronconf, 'i_dont_care_about_security_and_use_aggressive_mode_psk') === FALSE) {
395
			$restart = true;
396
		}
397
		$i_dont_care_about_security_and_use_aggressive_mode_psk = "i_dont_care_about_security_and_use_aggressive_mode_psk=yes";
398
	}
399

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

    
402
	$makebeforebreak = '';
403
	if (isset($config['ipsec']['makebeforebreak'])) {
404
		$makebeforebreak = 'make_before_break = yes';
405
	}
406

    
407
	if (isset($config['ipsec']['enableinterfacesuse'])) {
408
		if (!empty($ifacesuse)) {
409
			$ifacesuse = 'interfaces_use = ' . implode(',', array_unique($ifacesuse));
410
		} else {
411
			$ifacesuse = '';
412
		}
413
	} else {
414
		$ifacesuse = '';
415
	}
416

    
417
	unset($stronconf);
418

    
419
	$strongswanlog = "";
420
	$ipsecloglevels = vpn_logging_cfgtxt();
421
	if (is_array($ipsecloglevels)) {
422
		foreach ($ipsecloglevels as $loglevel) {
423
			$strongswanlog .= "\t\t\t" . $loglevel . "\n";
424
		}
425
	}
426
	$strongswan = <<<EOD
427

    
428
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten.
429
starter {
430
	load_warning = no
431
	config_file = {$g['varetc_path']}/ipsec/ipsec.conf
432
}
433

    
434
charon {
435
# number of worker threads in charon
436
	threads = 16
437
	ikesa_table_size = 32
438
	ikesa_table_segments = 4
439
	init_limit_half_open = 1000
440
	install_routes = no
441
	load_modular = yes
442
	ignore_acquire_ts = yes
443
	{$i_dont_care_about_security_and_use_aggressive_mode_psk}
444
	{$accept_unencrypted}
445
	cisco_unity = {$unity_enabled}
446
	{$ifacesuse}
447
	{$makebeforebreak}
448

    
449
	syslog {
450
		identifier = charon
451
		# log everything under daemon since it ends up in the same place regardless with our syslog.conf
452
		daemon {
453
			ike_name = yes
454
{$strongswanlog}
455
		}
456
		# disable logging under auth so logs aren't duplicated
457
		auth {
458
			default = -1
459
		}
460
	}
461

    
462
	plugins {
463
		# Load defaults
464
		include {$g['varetc_path']}/ipsec/strongswan.d/charon/*.conf
465

    
466
		stroke {
467
			secrets_file = {$g['varetc_path']}/ipsec/ipsec.secrets
468
		}
469

    
470
		unity {
471
			load = {$unity_enabled}
472
		}
473

    
474
EOD;
475

    
476
	/* Find RADIUS servers designated for Mobile IPsec user auth */
477
	$radius_server_txt = "";
478
	$user_sources = explode(',', $config['ipsec']['client']['user_source']);
479
	foreach ($user_sources as $user_source) {
480
		$auth_server = auth_get_authserver($user_source);
481
		$nice_user_source = strtolower(preg_replace('/\s+/', '_', $user_source));
482
		if ($auth_server && $auth_server['type'] === 'radius') {
483
			$radius_server_txt .= <<<EOD
484
				{$nice_user_source} {
485
					address = {$auth_server['host']}
486
					secret = "{$auth_server['radius_secret']}"
487
					auth_port = {$auth_server['radius_auth_port']}
488
					acct_port = {$auth_server['radius_acct_port']}
489
				}
490

    
491
EOD;
492
		}
493
	}
494

    
495
	/* Activate RADIUS accounting if it was selected on the auth server view */
496
	$radius_accounting = "";
497
	if($auth_server && isset($auth_server['radius_acct_port'])){
498
		$radius_accounting = 'accounting = yes';
499
	}
500

    
501
	/* write an eap-radius config section if appropriate */
502
	if (strlen($radius_server_txt) && ($mobile_ipsec_auth === "eap-radius")) {
503
		$strongswan .= <<<EOD
504
		eap-radius {
505
			class_group = yes
506
			eap_start = no
507
			{$radius_accounting}
508
			servers {
509
{$radius_server_txt}
510
			}
511
		}
512

    
513
EOD;
514
	}
515

    
516
	if (is_array($a_client) && isset($a_client['enable'])) {
517
		$strongswan .= "\t\tattr {\n";
518

    
519
		$cfgservers = array();
520
		if (!empty($a_client['dns_server1'])) {
521
			$cfgservers[] = $a_client['dns_server1'];
522
		}
523
		if (!empty($a_client['dns_server2'])) {
524
			$cfgservers[] = $a_client['dns_server2'];
525
		}
526
		if (!empty($a_client['dns_server3'])) {
527
			$cfgservers[] = $a_client['dns_server3'];
528
		}
529
		if (!empty($a_client['dns_server4'])) {
530
			$cfgservers[] = $a_client['dns_server4'];
531
		}
532

    
533
		if (!empty($cfgservers)) {
534
			$strongswan .= "\t\t\tdns = " . implode(",", $cfgservers) . "\n";
535
		}
536
		unset($cfgservers);
537
		$cfgservers = array();
538
		if (!empty($a_client['wins_server1'])) {
539
			$cfgservers[] = $a_client['wins_server1'];
540
		}
541
		if (!empty($a_client['wins_server2'])) {
542
			$cfgservers[] = $a_client['wins_server2'];
543
		}
544
		if (!empty($cfgservers)) {
545
			$strongswan .= "\t\t\tnbns = " . implode(",", $cfgservers) . "\n";
546
		}
547
		unset($cfgservers);
548

    
549
		if (isset($a_client['net_list']) && is_array($a_phase2)) {
550
			$net_list = '';
551
			foreach ($a_phase2 as $ph2ent) {
552
				if (isset($ph2ent['disabled'])) {
553
					continue;
554
				}
555

    
556
				if (!isset($ph2ent['mobile'])) {
557
					continue;
558
				}
559

    
560
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
561

    
562
				if (!empty($net_list)) {
563
					$net_list .= ",";
564
				}
565
				$net_list .= $localid;
566
			}
567

    
568
			if (!empty($net_list)) {
569
				$strongswan .= "\t\t\tsubnet = {$net_list}\n";
570
				$strongswan .= "\t\t\tsplit-include = {$net_list}\n";
571
				unset($net_list);
572
			}
573
		}
574

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

    
584
		if (!empty($a_client['dns_split'])) {
585
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
586
		}
587

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

    
592
		if (isset($a_client['save_passwd'])) {
593
			$strongswan .= "\t\t\t28673 = 1\n";
594
		}
595

    
596
		if ($a_client['pfs_group']) {
597
			$strongswan .= "\t\t\t28679 = \"{$a_client['pfs_group']}\"\n";
598
		}
599
		$strongswan .= "\t\t}\n";
600

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

    
622
	$strongswan .= "\n\t}\n}\n";
623
	@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
624
	unset($strongswan);
625

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

    
641
	$pskconf = "";
642

    
643
	$vpncas = array();
644
	if (is_array($a_phase1) && count($a_phase1)) {
645
		foreach ($a_phase1 as $ph1ent) {
646

    
647
			if (isset($ph1ent['disabled'])) {
648
				continue;
649
			}
650

    
651
			if (strstr($ph1ent['authentication_method'], 'rsa') ||
652
			    in_array($ph1ent['authentication_method'], array('eap-mschapv2', 'eap-tls', 'eap-radius'))) {
653
				$certline = '';
654

    
655
				$ikeid = $ph1ent['ikeid'];
656
				$cert = lookup_cert($ph1ent['certref']);
657

    
658
				if (!$cert) {
659
					log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
660
					continue;
661
				}
662

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

    
673
				@chmod($certpath, 0600);
674

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

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

    
690
				/* XXX" Traffic selectors? */
691
				$pskconf .= " : RSA {$ph1keyfile}\n";
692
			} else {
693
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
694
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
695

    
696
				$myid = trim($myid_data);
697

    
698
				if (empty($peerid_data)) {
699
					continue;
700
				}
701

    
702
				if ($myid_type == 'fqdn' && !empty($myid)) {
703
					$myid = "@{$myid}";
704
				}
705

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

    
708
				$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
709

    
710
				if ($peerid_type == 'fqdn' && !empty($peerid)) {
711
					$peerid = "@{$peerid}";
712
				}
713

    
714
				if (!empty($ph1ent['pre-shared-key'])) {
715
					$pskconf .= "{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
716
					if (isset($ph1ent['mobile'])) {
717
						$pskconf .= "{$myid} %any : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
718
						$pskconf .= " : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
719
					}
720
				}
721
			}
722

    
723
			/* if the client authenticates with a cert add the
724
			 * client cert CA chain to the list of CAs to write
725
			 */
726
			if (in_array($ph1ent['authentication_method'],
727
			array('rsasig', 'eap-tls', 'xauth_rsa_server'))) {
728

    
729
				if (!empty($ph1ent['caref']) && !array_key_exists($ph1ent['caref'], $vpncas)) {
730
					$thisca = lookup_ca($ph1ent['caref']);
731
					$vpncas[$ph1ent['caref']] = $thisca;
732

    
733
					/* follow chain up to root */
734
					$cachain = ca_chain_array($thisca);
735
					if ($cachain and is_array($cachain)) {
736
						foreach ($cachain as $cacrt) {
737
							$vpncas[$cacrt['refid']] = $cacrt;
738
						}
739
					}
740
				}
741
			}
742
		}
743
	}
744

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

    
760
	/* Add user PSKs */
761
	if (is_array($config['system']) && is_array($config['system']['user'])) {
762
		foreach ($config['system']['user'] as $user) {
763
			if (!empty($user['ipsecpsk'])) {
764
				$pskconf .= "{$myid} {$user['name']} : PSK 0s" . base64_encode($user['ipsecpsk']) . "\n";
765
			}
766
		}
767
		unset($user);
768
	}
769

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

    
787
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
788
	chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
789
	unset($pskconf);
790

    
791
	$uniqueids = 'yes';
792
	if (!empty($config['ipsec']['uniqueids'])) {
793
		if (array_key_exists($config['ipsec']['uniqueids'], $ipsec_idhandling)) {
794
			$uniqueids = $config['ipsec']['uniqueids'];
795
		}
796
	}
797
	$natfilterrules = false;
798
	/* begin ipsec.conf */
799
	$ipsecconf = "";
800
	$enablecompression = false;
801
	if (is_array($a_phase1) && count($a_phase1)) {
802

    
803
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
804
		$ipsecconf .= "config setup\n\tuniqueids = {$uniqueids}\n";
805

    
806
		if (isset($config['ipsec']['strictcrlpolicy'])) {
807
			$ipsecconf .= "\tstrictcrlpolicy = yes \n";
808
		}
809

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

    
834
conn bypasslan
835
	leftsubnet = {$bypass}
836
	rightsubnet = {$bypass}
837
	authby = never
838
	type = passthrough
839
	auto = route
840

    
841
EOD;
842
			}
843
		}
844

    
845
		foreach ($a_phase1 as $ph1ent) {
846
			if (isset($ph1ent['disabled'])) {
847
				continue;
848
			}
849

    
850
			if ($ph1ent['mode'] == "aggressive") {
851
				$aggressive = "yes";
852
			} else {
853
				$aggressive = "no";
854
			}
855

    
856
			$ep = ipsec_get_phase1_src($ph1ent);
857
			if (!$ep) {
858
				continue;
859
			}
860

    
861
			$ikeid = $ph1ent['ikeid'];
862
			$keyexchange = "ikev1";
863
			$passive = "route";
864
			if (!empty($ph1ent['iketype'])) {
865
				if ($ph1ent['iketype'] == "ikev2") {
866
					$keyexchange = "ikev2";
867
				} elseif ($ph1ent['iketype'] == "auto") {
868
					$keyexchange = "ike";
869
				}
870
			}
871

    
872
			if (isset($ph1ent['mobile'])) {
873
				$right_spec = "%any";
874
				$passive = 'add';
875
			} else {
876
				if (isset($ph1ent['responderonly'])) {
877
					$passive = 'add';
878
				}
879

    
880
				$right_spec = $ph1ent['remote-gateway'];
881
				if (is_ipaddr($right_spec)) {
882
					$sourcehost = $right_spec;
883
				} else {
884
					$sourcehost = $rgmap[$right_spec];
885
				}
886

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

    
936
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
937
			if ($myid_type != 'address' && $myid_type != 'keyid' && $myid_type != 'asn1dn') {
938
				$myid_data = "{$myid_type}:{$myid_data}";
939
			} elseif ($myid_type == "asn1dn" && !empty($myid_data)) {
940
				if ($myid_data[0] == '#') {
941
				/* asn1dn needs double quotes */
942
					$myid_data = "\"{$myid_type}:{$myid_data}\"";
943
				} else {
944
					$myid_data = "\"{$myid_data}\"";
945
				}
946
			}
947
			$leftid = '';
948
			if (!empty($myid_data)) {
949
				$leftid = "leftid = {$myid_data}";
950
			}
951

    
952
			$peerid_spec = '';
953
			if (isset($ph1ent['mobile']) && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
954
				// Only specify peer ID if we are not dealing with mobile PSK
955
			} else {
956
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
957
				if ($peerid_type == 'any') {
958
					$peerid_spec = '';
959
				} elseif ($peerid_type != 'address' && $peerid_type != 'keyid' && $peerid_type != 'asn1dn') {
960
					$peerid_spec = "{$peerid_type}:{$peerid_data}";
961
				} elseif ($peerid_type == "asn1dn") {
962
					/* asn1dn needs double quotes */
963
					if ($peerid_data[0] == '#') {
964
						$peerid_spec = "\"{$peerid_type}:{$peerid_data}\"";
965
					} elseif (!empty($peerid_data)) {
966
						$peerid_spec = "\"{$peerid_data}\"";
967
					}
968
				} else {
969
					$peerid_spec = $peerid_data;
970
				}
971
			}
972

    
973
			$ealgosp1 = '';
974
			if (is_array($ph1ent['encryption']['item'])) {
975
				$ciphers = "";
976
				foreach($ph1ent['encryption']['item'] as $p1enc) {
977
					if (!is_array($p1enc['encryption-algorithm']) ||
978
							empty($p1enc['encryption-algorithm']['name']) ||
979
							empty($p1enc['hash-algorithm'])) {
980
						continue;
981
					}
982
					$ciphers .= ",";
983
					$ciphers .= $p1enc['encryption-algorithm']['name'];
984
					$ealg_kl = $p1enc['encryption-algorithm']['keylen'];
985
					if ($ealg_kl) {
986
						$ciphers .= "{$ealg_kl}";
987
					}
988
					$ciphers .= "-{$p1enc['hash-algorithm']}";
989

    
990
					$modp = vpn_ipsec_convert_to_modp($p1enc['dhgroup']);
991
					if (!empty($modp)) {
992
						$ciphers .= "-{$modp}";
993
					}
994
				}
995
				$ciphers = substr($ciphers, 1);
996
				$ealgosp1 = "ike = {$ciphers}!";
997
			}
998

    
999
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
1000
				if ($passive == "route") {
1001
					$dpdline = "dpdaction = restart";
1002
				} else {
1003
					$dpdline = "dpdaction = clear";
1004
				}
1005
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
1006
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
1007
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
1008
			} else {
1009
				$dpdline = "dpdaction = none";
1010
			}
1011

    
1012
			$ikelifeline = '';
1013
			if ($ph1ent['lifetime']) {
1014
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
1015
			}
1016

    
1017
			$rightsourceip = NULL;
1018
			if (isset($ph1ent['mobile'])) {
1019
				$rightsourceips = array();
1020
				if (!empty($a_client['pool_address'])) {
1021
					$rightsourceips[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1022
				}
1023
				if (!empty($a_client['pool_address_v6'])) {
1024
					$rightsourceips[] = "{$a_client['pool_address_v6']}/{$a_client['pool_netbits_v6']}";
1025
				}
1026
				if ($ph1ent['authentication_method'] == "eap-radius" && !count($rightsourceips)) {
1027
					$rightsourceips[] = "%radius";
1028
				}
1029
				if (count($rightsourceips)) {
1030
					$rightsourceip = "\trightsourceip = " . implode(',', $rightsourceips) . "\n";
1031
				}
1032
			}
1033

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

    
1055
				}
1056
			}
1057

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

    
1142
			$left_spec = $ep;
1143

    
1144
			if (isset($ph1ent['reauth_enable'])) {
1145
				$reauth = "reauth = no";
1146
			} else {
1147
				$reauth = "reauth = yes";
1148
			}
1149

    
1150
			if (isset($ph1ent['rekey_enable'])) {
1151
				$rekeyline = "rekey = no";
1152
			} else {
1153
				$rekeyline = "rekey = yes";
1154
				if(!empty($ph1ent['margintime'])){
1155
					$rekeyline .= "\n\tmargintime = {$ph1ent['margintime']}s";
1156
				}
1157
			}
1158

    
1159
			if ($ph1ent['nat_traversal'] == 'off') {
1160
				$forceencaps = 'forceencaps = no';
1161
			} else if ($ph1ent['nat_traversal'] == 'force') {
1162
				$forceencaps = 'forceencaps = yes';
1163
			} else {
1164
				$forceencaps = 'forceencaps = no';
1165
			}
1166

    
1167
			if ($ph1ent['mobike'] == 'on') {
1168
				$mobike = 'mobike = yes';
1169
			} else {
1170
				$mobike = 'mobike = no';
1171
			}
1172

    
1173
			if (isset($ph1ent['tfc_enable'])) {
1174
				if (isset($ph1ent['tfc_bytes']) && is_numericint($ph1ent['tfc_bytes'])) {
1175
					$tfc = "tfc = {$ph1ent['tfc_bytes']}";
1176
				} else {
1177
					$tfc = "tfc = %mtu";
1178
				}
1179
			}
1180

    
1181
			$ipseclifetime = 0;
1182
			$rightsubnet_spec = array();
1183
			$leftsubnet_spec = array();
1184
			$reqids = array();
1185
			$ealgoAHsp2arr = array();
1186
			$ealgoESPsp2arr = array();
1187
			if (is_array($a_phase2) && count($a_phase2)) {
1188
				foreach ($a_phase2 as $ph2ent) {
1189
					if ($ikeid != $ph2ent['ikeid']) {
1190
						continue;
1191
					}
1192

    
1193
					if (isset($ph2ent['disabled'])) {
1194
						continue;
1195
					}
1196

    
1197
					if (isset($ph2ent['mobile']) && !isset($a_client['enable'])) {
1198
						continue;
1199
					}
1200

    
1201
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
1202
						$tunneltype = "type = tunnel";
1203

    
1204
						$localid_type = $ph2ent['localid']['type'];
1205
						$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
1206

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

    
1235
						$leftsubnet_spec[] = $leftsubnet_data;
1236

    
1237
						if (!isset($ph2ent['mobile'])) {
1238
							$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
1239
							$rightsubnet_spec[] = $tmpsubnet;
1240
						} else if (!empty($a_client['pool_address'])) {
1241
							$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1242
						}
1243
					} else {
1244
						$tunneltype = "type = transport";
1245

    
1246
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
1247
						    ($ph1ent['authentication_method'] == "pre_shared_key")) &&
1248
						    isset($ph1ent['mobile'])) {
1249
							$left_spec = "%any";
1250
						} else {
1251
							$tmpsubnet = ipsec_get_phase1_src($ph1ent);
1252
							$leftsubnet_spec[] = $tmpsubnet;
1253
						}
1254

    
1255
						if (!isset($ph2ent['mobile'])) {
1256
							$rightsubnet_spec[] = $right_spec;
1257
						}
1258
					}
1259

    
1260
					if (isset($a_client['pfs_group']) && isset($ph2ent['mobile'])) {
1261
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
1262
					}
1263

    
1264
					if ($ph2ent['protocol'] == 'esp') {
1265
						if (is_array($ph2ent['encryption-algorithm-option'])) {
1266
							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
1267
								$ealg_id = $ealg['name'];
1268
								$ealg_kl = $ealg['keylen'];
1269

    
1270
								if (!empty($ealg_kl) && $ealg_kl == "auto") {
1271
									if (empty($p2_ealgos) || !is_array($p2_ealgos)) {
1272
										require_once("ipsec.inc");
1273
									}
1274
									$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
1275
									$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
1276
									$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
1277
									/* XXX: in some cases where include ordering is suspect these variables
1278
									 * are somehow 0 and we enter this loop forever and timeout after 900
1279
									 * seconds wrecking bootup */
1280
									if ($key_hi != 0 and $key_lo != 0 and $key_step != 0) {
1281
										for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
1282
											if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1283
												foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1284
													$halgo = str_replace('hmac_', '', $halgo);
1285
													$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
1286
													$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1287
													if (!empty($modp)) {
1288
														$tmpealgo .= "-{$modp}";
1289
													}
1290
													$ealgoESPsp2arr[] = $tmpealgo;
1291
												}
1292
											} else {
1293
												$tmpealgo = "{$ealg_id}{$keylen}";
1294
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1295
												if (!empty($modp)) {
1296
													$tmpealgo .= "-{$modp}";
1297
												}
1298
												$ealgoESPsp2arr[] = $tmpealgo;
1299
											}
1300
										}
1301
									}
1302
								} else {
1303
									if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1304
										foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1305
											$halgo = str_replace('hmac_', '', $halgo);
1306
											$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
1307
											$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1308
											if (!empty($modp)) {
1309
												$tmpealgo .= "-{$modp}";
1310
											}
1311
											$ealgoESPsp2arr[] = $tmpealgo;
1312
										}
1313
									} else {
1314
										$tmpealgo = "{$ealg_id}{$ealg_kl}";
1315
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1316
										if (!empty($modp)) {
1317
											$tmpealgo .= "-{$modp}";
1318
										}
1319
										$ealgoESPsp2arr[] = $tmpealgo;
1320
									}
1321
								}
1322
							}
1323
						}
1324
					} else if ($ph2ent['protocol'] == 'ah') {
1325
						if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1326
							$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1327
							foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
1328
								$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
1329
								if (!empty($modp)) {
1330
									$tmpAHalgo = "-{$modp}";
1331
								}
1332
								$ealgoAHsp2arr[] = $tmpAHalgo;
1333
							}
1334
						}
1335
					}
1336

    
1337
					$reqids[] = $ph2ent['reqid'];
1338

    
1339
					if (!empty($ph2ent['lifetime'])) {
1340
						if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) {
1341
							$ipseclifetime = intval($ph2ent['lifetime']);
1342
						}
1343
					}
1344

    
1345
				}
1346
			}
1347

    
1348
			$ipsecconnect =<<<EOD
1349
	fragmentation = yes
1350
	keyexchange = {$keyexchange}
1351
	{$reauth}
1352
	{$forceencaps}
1353
	{$mobike}
1354
	{$tfc}
1355
	{$rekeyline}
1356
	installpolicy = yes
1357
	{$tunneltype}
1358
	{$dpdline}
1359
	auto = {$passive}
1360
	left = {$left_spec}
1361
	right = {$right_spec}
1362
	{$leftid}
1363

    
1364
EOD;
1365

    
1366
			/* Disable ipcomp for now. redmine #6167
1367
			if (isset($config['ipsec']['compression'])) {
1368
				$ipsecconnect .= "\tcompress = yes\n";
1369
				$enablecompression = true;
1370
			} */
1371
			if (!empty($ikelifeline)) {
1372
				$ipsecconnect .= "\t{$ikelifeline}\n";
1373
			}
1374
			if ($ipseclifetime > 0) {
1375
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
1376
			}
1377
			if (!empty($rightsourceip)) {
1378
				$ipsecconnect .= "{$rightsourceip}";
1379
			}
1380
			if (!empty($ealgosp1)) {
1381
				$ipsecconnect .= "\t{$ealgosp1}\n";
1382
			}
1383
			if (!empty($ealgoAHsp2arr)) {
1384
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
1385
			}
1386
			if (!empty($ealgoESPsp2arr)) {
1387
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
1388
			}
1389
			if (!empty($authentication)) {
1390
				$ipsecconnect .= "\t{$authentication}\n";
1391
			}
1392
			if (!empty($peerid_spec)) {
1393
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
1394
			}
1395
			if ($keyexchange != 'ikev2') {
1396
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
1397
			}
1398

    
1399
			if (!isset($ph1ent['mobile']) && ($keyexchange == 'ikev1' || isset($ph1ent['splitconn']))) {
1400
				if (!empty($rightsubnet_spec)) {
1401
					$ipsecfin = '';
1402
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
1403
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
1404
						//if (!empty($reqids[$idx])) {
1405
						//	$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
1406
						//}
1407
						$ipsecfin .= $ipsecconnect;
1408
						$ipsecfin .= "\trightsubnet = {$rsubnet}\n";
1409
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n";
1410
					}
1411
				} else {
1412
					log_error(sprintf(gettext("No phase2 specifications for tunnel with REQID = %s"), $ikeid));
1413
				}
1414
			} else {
1415
				if (isset($ph1ent['mobile'])) {
1416
					$ipsecfin = "\nconn con-mobile\n";
1417
				}
1418
				else {
1419
					$ipsecfin = "\nconn con{$ph1ent['ikeid']}\n";
1420
				}
1421
				//if (!empty($reqids[$idx])) {
1422
				//	$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
1423
				//}
1424
				$ipsecfin .= $ipsecconnect;
1425
				if (!isset($ph1ent['mobile']) && !empty($rightsubnet_spec)) {
1426
					$tempsubnets = array();
1427
					foreach ($rightsubnet_spec as $rightsubnet) {
1428
						$tempsubnets[$rightsubnet] = $rightsubnet;
1429
					}
1430
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "\n";
1431
					unset($tempsubnets, $rightsubnet);
1432
				}
1433
				if (!empty($leftsubnet_spec)) {
1434
					$tempsubnets = array();
1435
					foreach ($leftsubnet_spec as $leftsubnet) {
1436
						$tempsubnets[$leftsubnet] = $leftsubnet;
1437
					}
1438
					$ipsecfin .= "\tleftsubnet = " . join(",", $tempsubnets) . "\n";
1439
					unset($tempsubnets, $leftsubnet);
1440
				}
1441
			}
1442
			$ipsecconf .= $ipsecfin;
1443
			unset($ipsecfin);
1444
		}
1445
	}
1446

    
1447
	$a_mobilekey = $config['ipsec']['mobilekey'];
1448

    
1449
	if (is_array($a_phase1) && count($a_phase1)) {
1450
		foreach ($a_phase1 as $ph1ent) {
1451
			if (!isset($ph1ent['mobile'])) {
1452
				continue;
1453
			}
1454
			if (isset($ph1ent['disabled'])) {
1455
				continue;
1456
			}
1457

    
1458
			if (is_array($a_mobilekey) && count($a_mobilekey)) {
1459
				$ipsecfin = '';
1460
				$mobilekey_counter = 1;
1461
				foreach ($a_mobilekey as $mkent) {
1462
					if ($mkent['type'] != "EAP") {
1463
						continue;
1464
					}
1465

    
1466
					if (!isset($mkent['ident_type']) || !isset($mkent['pool_address']) || !isset($mkent['pool_netbits'])) {
1467
						continue;
1468
					}
1469

    
1470
					if (strlen($mkent['pool_address'] < 1) || !is_ipaddr($mkent['pool_address'])) {
1471
						continue;
1472
					}
1473

    
1474
					$ipsecfin .= "\nconn mobile-{$mobilekey_counter}\n";
1475
					$ipsecfin .= "\talso = con-mobile\n";
1476
					$ipsecfin .= "\teap_identity = %identity\n";
1477
					$ipsecfin .= "\trightsourceip = {$mkent['pool_address']}/{$mkent['pool_netbits']}\n";
1478

    
1479
					if ($mkent['ident_type'] == "none") {
1480
						$ipsecfin .= "\trightid = \"{$mkent['ident']}\"\n";
1481
					}
1482
					else {
1483
						$ipsecfin .= "\trightid = {$mkent['ident_type']}:{$mkent['ident']}\n";
1484
					}
1485

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

    
1490
					// note: comma seperated list for access restriction, regardless of firewall rules
1491
					// example: $ipsecfin = "\tleftsubnet = 1.1.1.1/32,1.1.1.2/32,2.2.2.0/24\n";
1492

    
1493
					$mobilekey_counter++;
1494
				}
1495
				$ipsecconf .= $ipsecfin;
1496
				unset($ipsecfin);
1497
				unset($mobilekey_counter);
1498
			}
1499
		}
1500
	}
1501

    
1502
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1503
	unset($ipsecconf);
1504
	/* end ipsec.conf */
1505

    
1506
	if ($enablecompression === true) {
1507
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1508
	} else {
1509
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1510
	}
1511

    
1512
	/* manage process */
1513
	if ($restart === true) {
1514
		mwexec("/usr/local/sbin/ipsec restart", false);
1515
	} else {
1516
		if (isvalidpid("{$g['varrun_path']}/starter.charon.pid")) {
1517
			/* Update configuration changes */
1518
			/* Read secrets */
1519
			mwexec("/usr/local/sbin/ipsec rereadall", false);
1520
			mwexec("/usr/local/sbin/ipsec reload", false);
1521
		} else {
1522
			mwexec("/usr/local/sbin/ipsec start", false);
1523
		}
1524
	}
1525

    
1526
	// run ping_hosts.sh once if it's enabled to avoid wait for minicron
1527
	if ($ipsecpinghostsactive == true) {
1528
		mwexec_bg("/usr/local/bin/ping_hosts.sh");
1529
	}
1530

    
1531
	if ($natfilterrules == true) {
1532
		filter_configure();
1533
	}
1534
	/* start filterdns, if necessary */
1535
	if (count($filterdns_list) > 0) {
1536
		$interval = 60;
1537
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) {
1538
			$interval = $ipseccfg['dns-interval'];
1539
		}
1540

    
1541
		$hostnames = "";
1542
		array_unique($filterdns_list);
1543
		foreach ($filterdns_list as $hostname) {
1544
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1545
		}
1546
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1547
		unset($hostnames);
1548

    
1549
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid")) {
1550
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1551
		} else {
1552
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1553
		}
1554
	} else {
1555
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1556
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1557
	}
1558

    
1559
	if (platform_booting()) {
1560
		echo "done\n";
1561
	}
1562

    
1563
	unlock($ipsecstartlock);
1564
	return count($filterdns_list);
1565
}
1566

    
1567
/*
1568
 * Forcefully restart IPsec
1569
 * This is required for when dynamic interfaces reload
1570
 * For all other occasions the normal vpn_ipsec_configure()
1571
 * will gracefully reload the settings without restarting
1572
 */
1573
function vpn_ipsec_force_reload($interface = "") {
1574
	global $g, $config;
1575

    
1576
	if (!ipsec_enabled()) {
1577
		return;
1578
	}
1579

    
1580
	$ipseccfg = $config['ipsec'];
1581

    
1582
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1583
		$found = false;
1584
		foreach ($ipseccfg['phase1'] as $ipsec) {
1585
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1586
				$found = true;
1587
				break;
1588
			}
1589
		}
1590
		if (!$found) {
1591
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1592
			return;
1593
		}
1594
	}
1595

    
1596
	/* If we get this far then we need to take action. */
1597
	log_error(gettext("Forcefully reloading IPsec"));
1598
	vpn_ipsec_configure();
1599
}
1600

    
1601
/* master setup for vpn (mpd) */
1602
function vpn_setup() {
1603
	/* start pppoe server */
1604
	vpn_pppoes_configure();
1605

    
1606
	/* setup l2tp */
1607
	vpn_l2tp_configure();
1608
}
1609

    
1610
function vpn_netgraph_support() {
1611
	$iflist = get_configured_interface_list();
1612
	foreach ($iflist as $iface) {
1613
		$realif = get_real_interface($iface);
1614
		/* Get support for netgraph(4) from the nic */
1615
		$ifinfo = pfSense_get_interface_addresses($realif);
1616
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) {
1617
			pfSense_ngctl_attach(".", $realif);
1618
		}
1619
	}
1620
}
1621

    
1622
function vpn_pppoes_configure() {
1623
	global $config;
1624

    
1625
	if (is_array($config['pppoes']['pppoe'])) {
1626
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
1627
			vpn_pppoe_configure($pppoe);
1628
		}
1629
	}
1630
}
1631

    
1632
function vpn_pppoe_configure(&$pppoecfg) {
1633
	global $config, $g;
1634

    
1635
	$syscfg = $config['system'];
1636

    
1637
	/* create directory if it does not exist */
1638
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
1639
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1640
	}
1641

    
1642
	if (platform_booting()) {
1643
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
1644
			return 0;
1645
		}
1646

    
1647
		echo gettext("Configuring PPPoE Server service... ");
1648
	} else {
1649
		/* kill mpd */
1650
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1651

    
1652
		/* wait for process to die */
1653
		sleep(2);
1654

    
1655
	}
1656

    
1657
	switch ($pppoecfg['mode']) {
1658

    
1659
		case 'server':
1660

    
1661
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1662

    
1663
			if ($pppoecfg['paporchap'] == "chap") {
1664
				$paporchap = "set link enable chap";
1665
			} else {
1666
				$paporchap = "set link enable pap";
1667
			}
1668

    
1669
			/* write mpd.conf */
1670
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1671
			if (!$fd) {
1672
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1673
				return 1;
1674
			}
1675

    
1676
			$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 ";
1677
			if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1678
				$issue_ip_type .= "0.0.0.0/0";
1679
			} else {
1680
				$issue_ip_type .= "ippool p0";
1681
			}
1682

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

    
1685
			if (is_numeric($pppoecfg['n_pppoe_maxlogin']) && ($pppoecfg['n_pppoe_maxlogin'] > 0)) {
1686
				$pppoemaxlogins = $pppoecfg['n_pppoe_maxlogin'];
1687
			} else {
1688
				$pppoemaxlogins = 1;
1689
			}
1690

    
1691
			$ipcp_dns = '';
1692
			if (!empty($pppoecfg['dns1'])) {
1693
				$ipcp_dns = "set ipcp dns " . $pppoecfg['dns1'];
1694
				if (!empty($pppoecfg['dns2'])) {
1695
					$ipcp_dns .= " " . $pppoecfg['dns2'];
1696
				}
1697
			} elseif (isset($config['dnsmasq']['enable']) ||
1698
			    isset ($config['unbound']['enable'])) {
1699
				$ipcp_dns = "set ipcp dns " . get_interface_ip("lan");
1700
				if ($syscfg['dnsserver'][0]) {
1701
					$ipcp_dns .= " " . $syscfg['dnsserver'][0];
1702
				}
1703
			} elseif (is_array($syscfg['dnsserver']) &&
1704
			    ($syscfg['dnsserver'][0])) {
1705
				$ipcp_dns = "set ipcp dns " . join(" ", $syscfg['dnsserver']);
1706
			}
1707

    
1708
			$mpdconf = <<<EOD
1709
startup:
1710

    
1711
poes:
1712
	set ippool add p0 {$pppoecfg['remoteip']} {$ippool_p0}
1713

    
1714
	create bundle template poes_b
1715
	set bundle enable compression
1716

    
1717
	set ccp yes mppc
1718
	set mppc yes e40
1719
	set mppc yes e128
1720
	set mppc yes stateless
1721

    
1722
	set iface group pppoe
1723
	set iface up-script /usr/local/sbin/vpn-linkup-poes
1724
	set iface down-script /usr/local/sbin/vpn-linkdown-poes
1725
	set iface idle 0
1726
	set iface disable on-demand
1727
	set iface disable proxy-arp
1728
	set iface enable tcpmssfix
1729
	set iface mtu 1500
1730

    
1731
	set ipcp no vjcomp
1732
	{$issue_ip_type}
1733
	{$ipcp_dns}
1734

    
1735
	create link template poes_l pppoe
1736
	set link action bundle poes_b
1737

    
1738
	set auth max-logins {$pppoemaxlogins}
1739

    
1740
	set pppoe iface {$pppoe_interface}
1741

    
1742
	set link no multilink
1743
	set link no pap chap
1744
	{$paporchap}
1745
	set link keep-alive 60 180
1746
	set link max-redial -1
1747
	set link mru 1492
1748
	set link latency 1
1749
	set link enable incoming
1750

    
1751
EOD;
1752

    
1753
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1754
				$radiusport = "";
1755
				$radiusacctport = "";
1756
				if (isset($pppoecfg['radius']['server']['port'])) {
1757
					$radiusport = $pppoecfg['radius']['server']['port'];
1758
				}
1759
				if (isset($pppoecfg['radius']['server']['acctport'])) {
1760
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1761
				}
1762
				$mpdconf .=<<<EOD
1763
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1764
	set radius retries 3
1765
	set radius timeout 10
1766
	set auth enable radius-auth
1767

    
1768
EOD;
1769

    
1770
				if (isset ($pppoecfg['radius']['accounting'])) {
1771
					$mpdconf .=<<<EOD
1772
	set auth enable radius-acct
1773

    
1774
EOD;
1775
				}
1776
				if (!empty($pppoecfg['radius']['nasip'])) {
1777
					$mpdconf .= "\tset radius me {$pppoecfg['radius']['nasip']}\n";
1778
				}
1779
			}
1780

    
1781
			fwrite($fd, $mpdconf);
1782
			fclose($fd);
1783
			unset($mpdconf);
1784

    
1785
			if ($pppoecfg['username']) {
1786
				/* write mpd.secret */
1787
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1788
				if (!$fd) {
1789
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1790
					return 1;
1791
				}
1792

    
1793
				$mpdsecret = "\n\n";
1794

    
1795
				if (!empty($pppoecfg['username'])) {
1796
					$item = explode(" ", $pppoecfg['username']);
1797
					foreach ($item as $userdata) {
1798
						$data = explode(":", $userdata);
1799
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1800
					}
1801
				}
1802

    
1803
				fwrite($fd, $mpdsecret);
1804
				fclose($fd);
1805
				unset($mpdsecret);
1806
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1807
			}
1808

    
1809
			/* Check if previous instance is still up */
1810
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
1811
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1812
			}
1813

    
1814
			/* Get support for netgraph(4) from the nic */
1815
			pfSense_ngctl_attach(".", $pppoe_interface);
1816
			/* fire up mpd */
1817
			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");
1818

    
1819
			break;
1820
	}
1821

    
1822
	if (platform_booting()) {
1823
		echo gettext("done") . "\n";
1824
	}
1825

    
1826
	return 0;
1827
}
1828

    
1829
function vpn_l2tp_configure() {
1830
	global $config, $g;
1831

    
1832
	$syscfg = $config['system'];
1833
	$l2tpcfg = $config['l2tp'];
1834

    
1835
	/* create directory if it does not exist */
1836
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
1837
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1838
	}
1839

    
1840
	if (platform_booting()) {
1841
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
1842
			return 0;
1843
		}
1844

    
1845
		echo gettext("Configuring l2tp VPN service... ");
1846
	} else {
1847
		/* kill mpd */
1848
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1849

    
1850
		/* wait for process to die */
1851
		sleep(8);
1852

    
1853
	}
1854

    
1855
	/* make sure l2tp-vpn directory exists */
1856
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
1857
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1858
	}
1859

    
1860
	switch ($l2tpcfg['mode']) {
1861

    
1862
		case 'server':
1863
			$l2tp_listen="";
1864
			$ipaddr = get_interface_ip(get_failover_interface($l2tpcfg['interface']));
1865
			if (is_ipaddrv4($ipaddr)) {
1866
				$l2tp_listen="set l2tp self $ipaddr";
1867
			}
1868

    
1869
			switch ($l2tpcfg['paporchap']) {
1870
				case 'chap':
1871
					$paporchap = "set link enable chap";
1872
					break;
1873
				case 'chap-msv2':
1874
					$paporchap = "set link enable chap-msv2";
1875
					break;
1876
				default:
1877
					$paporchap = "set link enable pap";
1878
					break;
1879
			}
1880

    
1881
			/* write mpd.conf */
1882
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1883
			if (!$fd) {
1884
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1885
				return 1;
1886
			}
1887

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

    
1890
			$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 ";
1891
			if (isset($l2tpcfg['radius']['radiusissueips']) && isset($l2tpcfg['radius']['server']['enable'])) {
1892
				$issue_ip_type .= "0.0.0.0/0";
1893
			} else {
1894
				$issue_ip_type .= "ippool p0";
1895
			}
1896

    
1897
			$ipcp_dns = '';
1898
			if (is_ipaddr($l2tpcfg['dns1'])) {
1899
				$ipcp_dns = "set ipcp dns " . $l2tpcfg['dns1'];
1900
				if (is_ipaddr($l2tpcfg['dns2'])) {
1901
					$ipcp_dns .= " " . $l2tpcfg['dns2'];
1902
				}
1903
			} elseif (isset ($config['dnsmasq']['enable']) ||
1904
			    isset ($config['unbound']['enable'])) {
1905
				$ipcp_dns = "set ipcp dns " . get_interface_ip("lan");
1906
				if ($syscfg['dnsserver'][0]) {
1907
					$ipcp_dns .= " " . $syscfg['dnsserver'][0];
1908
				}
1909
			} elseif (is_array($syscfg['dnsserver']) &&
1910
			    ($syscfg['dnsserver'][0])) {
1911
				$ipcp_dns = "set ipcp dns " . join(" ", $syscfg['dnsserver']);
1912
			}
1913

    
1914
			$mpdconf =<<<EOD
1915

    
1916
startup:
1917

    
1918
l2tps:
1919
	set ippool add p0 {$l2tpcfg['remoteip']} {$ippool_p0}
1920

    
1921
	create bundle template l2tp_b
1922
	set bundle enable compression
1923
	set bundle yes crypt-reqd
1924

    
1925
	set ccp yes mppc
1926

    
1927
	set iface name l2tp
1928
	set iface group l2tp
1929
	set iface up-script /usr/local/sbin/vpn-linkup-l2tp
1930
	set iface down-script /usr/local/sbin/vpn-linkdown-l2tp
1931
	set iface disable on-demand
1932
	set iface enable proxy-arp
1933

    
1934
	set ipcp yes vjcomp
1935
	{$issue_ip_type}
1936
	{$ipcp_dns}
1937

    
1938
	create link template l2tp_l l2tp
1939
	set link action bundle l2tp_b
1940

    
1941
	set link yes acfcomp protocomp
1942
	set link enable multilink
1943
	set link no pap chap chap-msv2
1944
	{$paporchap}
1945
	{$l2tp_listen}
1946
	set link keep-alive 10 180
1947
	set link enable incoming
1948

    
1949
EOD;
1950

    
1951

    
1952
			if (isset ($l2tpcfg['radius']['enable'])) {
1953
				$mpdconf .=<<<EOD
1954
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1955
	set radius retries 3
1956
	set radius timeout 10
1957
	set auth disable internal
1958
	set auth enable radius-auth
1959

    
1960
EOD;
1961

    
1962
				if (isset ($l2tpcfg['radius']['accounting'])) {
1963
					$mpdconf .=<<<EOD
1964
	set auth enable radius-acct
1965

    
1966
EOD;
1967
				}
1968
			}
1969

    
1970
			fwrite($fd, $mpdconf);
1971
			fclose($fd);
1972
			unset($mpdconf);
1973

    
1974
			/* write mpd.secret */
1975
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1976
			if (!$fd) {
1977
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1978
				return 1;
1979
			}
1980

    
1981
			$mpdsecret = "\n\n";
1982

    
1983
			if (is_array($l2tpcfg['user'])) {
1984
				foreach ($l2tpcfg['user'] as $user) {
1985
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1986
				}
1987
			}
1988

    
1989
			fwrite($fd, $mpdsecret);
1990
			fclose($fd);
1991
			unset($mpdsecret);
1992
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1993

    
1994
			vpn_netgraph_support();
1995

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

    
1999
			break;
2000

    
2001
		case 'redir':
2002
			break;
2003
	}
2004

    
2005
	if (platform_booting()) {
2006
		echo "done\n";
2007
	}
2008

    
2009
	return 0;
2010
}
2011

    
2012
?>
(54-54/60)