Project

General

Profile

Download (58.5 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
			$vtireq = array();
1186
			$ealgoAHsp2arr = array();
1187
			$ealgoESPsp2arr = array();
1188
			if (is_array($a_phase2) && count($a_phase2)) {
1189
				foreach ($a_phase2 as $ph2ent) {
1190
					if ($ikeid != $ph2ent['ikeid']) {
1191
						continue;
1192
					}
1193

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

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

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

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

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

    
1237
						$leftsubnet_spec[] = $leftsubnet_data;
1238

    
1239
						if (!isset($ph2ent['mobile'])) {
1240
							$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
1241
							$rightsubnet_spec[] = $tmpsubnet;
1242
						} else if (!empty($a_client['pool_address'])) {
1243
							$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1244
						}
1245
					} elseif ($ph2ent['mode'] == 'vti') {
1246
						$tunneltype = "";
1247
						$installpolicy = "installpolicy = no";
1248
						$passive = 'start';
1249

    
1250
						$localid_type = $ph2ent['localid']['type'];
1251
						$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
1252
						$leftsubnet_spec[] = $leftsubnet_data;
1253

    
1254
						$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
1255
						$rightsubnet_spec[] = $tmpsubnet;
1256
						$vtireq[] = $ph2ent['reqid'];
1257
					} else {
1258
						$tunneltype = "type = transport";
1259
						$installpolicy = "installpolicy = yes";
1260

    
1261
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
1262
						    ($ph1ent['authentication_method'] == "pre_shared_key")) &&
1263
						    isset($ph1ent['mobile'])) {
1264
							$left_spec = "%any";
1265
						} else {
1266
							$tmpsubnet = ipsec_get_phase1_src($ph1ent);
1267
							$leftsubnet_spec[] = $tmpsubnet;
1268
						}
1269

    
1270
						if (!isset($ph2ent['mobile'])) {
1271
							$rightsubnet_spec[] = $right_spec;
1272
						}
1273
					}
1274

    
1275
					if (isset($a_client['pfs_group']) && isset($ph2ent['mobile'])) {
1276
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
1277
					}
1278

    
1279
					if ($ph2ent['protocol'] == 'esp') {
1280
						if (is_array($ph2ent['encryption-algorithm-option'])) {
1281
							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
1282
								$ealg_id = $ealg['name'];
1283
								$ealg_kl = $ealg['keylen'];
1284

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

    
1352
					$reqids[] = $ph2ent['reqid'];
1353

    
1354
					if (!empty($ph2ent['lifetime'])) {
1355
						if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) {
1356
							$ipseclifetime = intval($ph2ent['lifetime']);
1357
						}
1358
					}
1359

    
1360
				}
1361
			}
1362

    
1363
			$ipsecconnect =<<<EOD
1364
	fragmentation = yes
1365
	keyexchange = {$keyexchange}
1366
	{$reauth}
1367
	{$forceencaps}
1368
	{$mobike}
1369
	{$tfc}
1370
	{$rekeyline}
1371
	{$installpolicy}
1372
	{$tunneltype}
1373
	{$dpdline}
1374
	auto = {$passive}
1375
	left = {$left_spec}
1376
	right = {$right_spec}
1377
	{$leftid}
1378

    
1379
EOD;
1380

    
1381
			/* Disable ipcomp for now. redmine #6167
1382
			if (isset($config['ipsec']['compression'])) {
1383
				$ipsecconnect .= "\tcompress = yes\n";
1384
				$enablecompression = true;
1385
			} */
1386
			if (!empty($ikelifeline)) {
1387
				$ipsecconnect .= "\t{$ikelifeline}\n";
1388
			}
1389
			if ($ipseclifetime > 0) {
1390
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
1391
			}
1392
			if (!empty($rightsourceip)) {
1393
				$ipsecconnect .= "{$rightsourceip}";
1394
			}
1395
			if (!empty($ealgosp1)) {
1396
				$ipsecconnect .= "\t{$ealgosp1}\n";
1397
			}
1398
			if (!empty($ealgoAHsp2arr)) {
1399
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
1400
			}
1401
			if (!empty($ealgoESPsp2arr)) {
1402
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
1403
			}
1404
			if (!empty($authentication)) {
1405
				$ipsecconnect .= "\t{$authentication}\n";
1406
			}
1407
			if (!empty($peerid_spec)) {
1408
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
1409
			}
1410
			if ($keyexchange != 'ikev2') {
1411
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
1412
			}
1413

    
1414
			if (!isset($ph1ent['mobile']) && ($keyexchange == 'ikev1' || isset($ph1ent['splitconn']))) {
1415
				if (!empty($rightsubnet_spec)) {
1416
					$ipsecfin = '';
1417
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
1418
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
1419
						//if (!empty($reqids[$idx])) {
1420
						//	$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
1421
						//}
1422
						if (!empty($vtireq[$idx])) {
1423
							$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
1424
						}
1425
						$ipsecfin .= $ipsecconnect;
1426
						$ipsecfin .= "\trightsubnet = {$rsubnet}\n";
1427
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n";
1428
					}
1429
				} else {
1430
					log_error(sprintf(gettext("No phase2 specifications for tunnel with REQID = %s"), $ikeid));
1431
				}
1432
			} else {
1433
				if (isset($ph1ent['mobile'])) {
1434
					$ipsecfin = "\nconn con-mobile\n";
1435
				}
1436
				else {
1437
					$ipsecfin = "\nconn con{$ph1ent['ikeid']}\n";
1438
				}
1439
				//if (!empty($reqids[$idx])) {
1440
				//	$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
1441
				//}
1442
				if (!empty($vtireq[$idx])) {
1443
					$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
1444
				}
1445
				$ipsecfin .= $ipsecconnect;
1446
				if (!isset($ph1ent['mobile']) && !empty($rightsubnet_spec)) {
1447
					$tempsubnets = array();
1448
					foreach ($rightsubnet_spec as $rightsubnet) {
1449
						$tempsubnets[$rightsubnet] = $rightsubnet;
1450
					}
1451
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "\n";
1452
					unset($tempsubnets, $rightsubnet);
1453
				}
1454
				if (!empty($leftsubnet_spec)) {
1455
					$tempsubnets = array();
1456
					foreach ($leftsubnet_spec as $leftsubnet) {
1457
						$tempsubnets[$leftsubnet] = $leftsubnet;
1458
					}
1459
					$ipsecfin .= "\tleftsubnet = " . join(",", $tempsubnets) . "\n";
1460
					unset($tempsubnets, $leftsubnet);
1461
				}
1462
			}
1463
			$ipsecconf .= $ipsecfin;
1464
			unset($ipsecfin);
1465
		}
1466
	}
1467

    
1468
	$a_mobilekey = $config['ipsec']['mobilekey'];
1469

    
1470
	if (is_array($a_phase1) && count($a_phase1)) {
1471
		foreach ($a_phase1 as $ph1ent) {
1472
			if (!isset($ph1ent['mobile'])) {
1473
				continue;
1474
			}
1475
			if (isset($ph1ent['disabled'])) {
1476
				continue;
1477
			}
1478

    
1479
			if (is_array($a_mobilekey) && count($a_mobilekey)) {
1480
				$ipsecfin = '';
1481
				$mobilekey_counter = 1;
1482
				foreach ($a_mobilekey as $mkent) {
1483
					if ($mkent['type'] != "EAP") {
1484
						continue;
1485
					}
1486

    
1487
					if (!isset($mkent['ident_type']) || !isset($mkent['pool_address']) || !isset($mkent['pool_netbits'])) {
1488
						continue;
1489
					}
1490

    
1491
					if (strlen($mkent['pool_address'] < 1) || !is_ipaddr($mkent['pool_address'])) {
1492
						continue;
1493
					}
1494

    
1495
					$ipsecfin .= "\nconn mobile-{$mobilekey_counter}\n";
1496
					$ipsecfin .= "\talso = con-mobile\n";
1497
					$ipsecfin .= "\teap_identity = %identity\n";
1498
					$ipsecfin .= "\trightsourceip = {$mkent['pool_address']}/{$mkent['pool_netbits']}\n";
1499

    
1500
					if ($mkent['ident_type'] == "none") {
1501
						$ipsecfin .= "\trightid = \"{$mkent['ident']}\"\n";
1502
					}
1503
					else {
1504
						$ipsecfin .= "\trightid = {$mkent['ident_type']}:{$mkent['ident']}\n";
1505
					}
1506

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

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

    
1514
					$mobilekey_counter++;
1515
				}
1516
				$ipsecconf .= $ipsecfin;
1517
				unset($ipsecfin);
1518
				unset($mobilekey_counter);
1519
			}
1520
		}
1521
	}
1522

    
1523
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1524
	unset($ipsecconf);
1525
	/* end ipsec.conf */
1526

    
1527
	if ($enablecompression === true) {
1528
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1529
	} else {
1530
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1531
	}
1532

    
1533
	/* manage process */
1534
	if ($restart === true) {
1535
		mwexec("/usr/local/sbin/ipsec restart", false);
1536
	} else {
1537
		if (isvalidpid("{$g['varrun_path']}/starter.charon.pid")) {
1538
			/* Update configuration changes */
1539
			/* Read secrets */
1540
			mwexec("/usr/local/sbin/ipsec rereadall", false);
1541
			mwexec("/usr/local/sbin/ipsec reload", false);
1542
		} else {
1543
			mwexec("/usr/local/sbin/ipsec start", false);
1544
		}
1545
	}
1546

    
1547
	// run ping_hosts.sh once if it's enabled to avoid wait for minicron
1548
	if ($ipsecpinghostsactive == true) {
1549
		mwexec_bg("/usr/local/bin/ping_hosts.sh");
1550
	}
1551

    
1552
	if ($natfilterrules == true) {
1553
		filter_configure();
1554
	}
1555
	/* start filterdns, if necessary */
1556
	if (count($filterdns_list) > 0) {
1557
		$interval = 60;
1558
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) {
1559
			$interval = $ipseccfg['dns-interval'];
1560
		}
1561

    
1562
		$hostnames = "";
1563
		array_unique($filterdns_list);
1564
		foreach ($filterdns_list as $hostname) {
1565
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1566
		}
1567
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1568
		unset($hostnames);
1569

    
1570
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid")) {
1571
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1572
		} else {
1573
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1574
		}
1575
	} else {
1576
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1577
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1578
	}
1579

    
1580
	if (platform_booting()) {
1581
		echo "done\n";
1582
	}
1583

    
1584
	unlock($ipsecstartlock);
1585
	return count($filterdns_list);
1586
}
1587

    
1588
/*
1589
 * Forcefully restart IPsec
1590
 * This is required for when dynamic interfaces reload
1591
 * For all other occasions the normal vpn_ipsec_configure()
1592
 * will gracefully reload the settings without restarting
1593
 */
1594
function vpn_ipsec_force_reload($interface = "") {
1595
	global $g, $config;
1596

    
1597
	if (!ipsec_enabled()) {
1598
		return;
1599
	}
1600

    
1601
	$ipseccfg = $config['ipsec'];
1602

    
1603
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1604
		$found = false;
1605
		foreach ($ipseccfg['phase1'] as $ipsec) {
1606
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1607
				$found = true;
1608
				break;
1609
			}
1610
		}
1611
		if (!$found) {
1612
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1613
			return;
1614
		}
1615
	}
1616

    
1617
	/* If we get this far then we need to take action. */
1618
	log_error(gettext("Forcefully reloading IPsec"));
1619
	vpn_ipsec_configure();
1620
}
1621

    
1622
/* master setup for vpn (mpd) */
1623
function vpn_setup() {
1624
	/* start pppoe server */
1625
	vpn_pppoes_configure();
1626

    
1627
	/* setup l2tp */
1628
	vpn_l2tp_configure();
1629
}
1630

    
1631
function vpn_netgraph_support() {
1632
	$iflist = get_configured_interface_list();
1633
	foreach ($iflist as $iface) {
1634
		$realif = get_real_interface($iface);
1635
		/* Get support for netgraph(4) from the nic */
1636
		$ifinfo = pfSense_get_interface_addresses($realif);
1637
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) {
1638
			pfSense_ngctl_attach(".", $realif);
1639
		}
1640
	}
1641
}
1642

    
1643
function vpn_pppoes_configure() {
1644
	global $config;
1645

    
1646
	if (is_array($config['pppoes']['pppoe'])) {
1647
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
1648
			vpn_pppoe_configure($pppoe);
1649
		}
1650
	}
1651
}
1652

    
1653
function vpn_pppoe_configure(&$pppoecfg) {
1654
	global $config, $g;
1655

    
1656
	$syscfg = $config['system'];
1657

    
1658
	/* create directory if it does not exist */
1659
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
1660
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1661
	}
1662

    
1663
	if (platform_booting()) {
1664
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
1665
			return 0;
1666
		}
1667

    
1668
		echo gettext("Configuring PPPoE Server service... ");
1669
	} else {
1670
		/* kill mpd */
1671
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1672

    
1673
		/* wait for process to die */
1674
		sleep(2);
1675

    
1676
	}
1677

    
1678
	switch ($pppoecfg['mode']) {
1679

    
1680
		case 'server':
1681

    
1682
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1683

    
1684
			if ($pppoecfg['paporchap'] == "chap") {
1685
				$paporchap = "set link enable chap";
1686
			} else {
1687
				$paporchap = "set link enable pap";
1688
			}
1689

    
1690
			/* write mpd.conf */
1691
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1692
			if (!$fd) {
1693
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1694
				return 1;
1695
			}
1696

    
1697
			$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 ";
1698
			if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1699
				$issue_ip_type .= "0.0.0.0/0";
1700
			} else {
1701
				$issue_ip_type .= "ippool p0";
1702
			}
1703

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

    
1706
			if (is_numeric($pppoecfg['n_pppoe_maxlogin']) && ($pppoecfg['n_pppoe_maxlogin'] > 0)) {
1707
				$pppoemaxlogins = $pppoecfg['n_pppoe_maxlogin'];
1708
			} else {
1709
				$pppoemaxlogins = 1;
1710
			}
1711

    
1712
			$ipcp_dns = '';
1713
			if (!empty($pppoecfg['dns1'])) {
1714
				$ipcp_dns = "set ipcp dns " . $pppoecfg['dns1'];
1715
				if (!empty($pppoecfg['dns2'])) {
1716
					$ipcp_dns .= " " . $pppoecfg['dns2'];
1717
				}
1718
			} elseif (isset($config['dnsmasq']['enable']) ||
1719
			    isset ($config['unbound']['enable'])) {
1720
				$ipcp_dns = "set ipcp dns " . get_interface_ip("lan");
1721
				if ($syscfg['dnsserver'][0]) {
1722
					$ipcp_dns .= " " . $syscfg['dnsserver'][0];
1723
				}
1724
			} elseif (is_array($syscfg['dnsserver']) &&
1725
			    ($syscfg['dnsserver'][0])) {
1726
				$ipcp_dns = "set ipcp dns " . join(" ", $syscfg['dnsserver']);
1727
			}
1728

    
1729
			$mpdconf = <<<EOD
1730
startup:
1731

    
1732
poes:
1733
	set ippool add p0 {$pppoecfg['remoteip']} {$ippool_p0}
1734

    
1735
	create bundle template poes_b
1736
	set bundle enable compression
1737

    
1738
	set ccp yes mppc
1739
	set mppc yes e40
1740
	set mppc yes e128
1741
	set mppc yes stateless
1742

    
1743
	set iface group pppoe
1744
	set iface up-script /usr/local/sbin/vpn-linkup-poes
1745
	set iface down-script /usr/local/sbin/vpn-linkdown-poes
1746
	set iface idle 0
1747
	set iface disable on-demand
1748
	set iface disable proxy-arp
1749
	set iface enable tcpmssfix
1750
	set iface mtu 1500
1751

    
1752
	set ipcp no vjcomp
1753
	{$issue_ip_type}
1754
	{$ipcp_dns}
1755

    
1756
	create link template poes_l pppoe
1757
	set link action bundle poes_b
1758

    
1759
	set auth max-logins {$pppoemaxlogins}
1760

    
1761
	set pppoe iface {$pppoe_interface}
1762

    
1763
	set link no multilink
1764
	set link no pap chap
1765
	{$paporchap}
1766
	set link keep-alive 60 180
1767
	set link max-redial -1
1768
	set link mru 1492
1769
	set link latency 1
1770
	set link enable incoming
1771

    
1772
EOD;
1773

    
1774
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1775
				$radiusport = "";
1776
				$radiusacctport = "";
1777
				if (isset($pppoecfg['radius']['server']['port'])) {
1778
					$radiusport = $pppoecfg['radius']['server']['port'];
1779
				}
1780
				if (isset($pppoecfg['radius']['server']['acctport'])) {
1781
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1782
				}
1783
				$mpdconf .=<<<EOD
1784
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1785
	set radius retries 3
1786
	set radius timeout 10
1787
	set auth enable radius-auth
1788

    
1789
EOD;
1790

    
1791
				if (isset ($pppoecfg['radius']['accounting'])) {
1792
					$mpdconf .=<<<EOD
1793
	set auth enable radius-acct
1794

    
1795
EOD;
1796
				}
1797
				if (!empty($pppoecfg['radius']['nasip'])) {
1798
					$mpdconf .= "\tset radius me {$pppoecfg['radius']['nasip']}\n";
1799
				}
1800
			}
1801

    
1802
			fwrite($fd, $mpdconf);
1803
			fclose($fd);
1804
			unset($mpdconf);
1805

    
1806
			if ($pppoecfg['username']) {
1807
				/* write mpd.secret */
1808
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1809
				if (!$fd) {
1810
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1811
					return 1;
1812
				}
1813

    
1814
				$mpdsecret = "\n\n";
1815

    
1816
				if (!empty($pppoecfg['username'])) {
1817
					$item = explode(" ", $pppoecfg['username']);
1818
					foreach ($item as $userdata) {
1819
						$data = explode(":", $userdata);
1820
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1821
					}
1822
				}
1823

    
1824
				fwrite($fd, $mpdsecret);
1825
				fclose($fd);
1826
				unset($mpdsecret);
1827
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1828
			}
1829

    
1830
			/* Check if previous instance is still up */
1831
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
1832
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1833
			}
1834

    
1835
			/* Get support for netgraph(4) from the nic */
1836
			pfSense_ngctl_attach(".", $pppoe_interface);
1837
			/* fire up mpd */
1838
			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");
1839

    
1840
			break;
1841
	}
1842

    
1843
	if (platform_booting()) {
1844
		echo gettext("done") . "\n";
1845
	}
1846

    
1847
	return 0;
1848
}
1849

    
1850
function vpn_l2tp_configure() {
1851
	global $config, $g;
1852

    
1853
	$syscfg = $config['system'];
1854
	$l2tpcfg = $config['l2tp'];
1855

    
1856
	/* create directory if it does not exist */
1857
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
1858
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1859
	}
1860

    
1861
	if (platform_booting()) {
1862
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
1863
			return 0;
1864
		}
1865

    
1866
		echo gettext("Configuring l2tp VPN service... ");
1867
	} else {
1868
		/* kill mpd */
1869
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1870

    
1871
		/* wait for process to die */
1872
		sleep(8);
1873

    
1874
	}
1875

    
1876
	/* make sure l2tp-vpn directory exists */
1877
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
1878
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1879
	}
1880

    
1881
	switch ($l2tpcfg['mode']) {
1882

    
1883
		case 'server':
1884
			$l2tp_listen="";
1885
			$ipaddr = get_interface_ip(get_failover_interface($l2tpcfg['interface']));
1886
			if (is_ipaddrv4($ipaddr)) {
1887
				$l2tp_listen="set l2tp self $ipaddr";
1888
			}
1889

    
1890
			switch ($l2tpcfg['paporchap']) {
1891
				case 'chap':
1892
					$paporchap = "set link enable chap";
1893
					break;
1894
				case 'chap-msv2':
1895
					$paporchap = "set link enable chap-msv2";
1896
					break;
1897
				default:
1898
					$paporchap = "set link enable pap";
1899
					break;
1900
			}
1901

    
1902
			/* write mpd.conf */
1903
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1904
			if (!$fd) {
1905
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1906
				return 1;
1907
			}
1908

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

    
1911
			$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 ";
1912
			if (isset($l2tpcfg['radius']['radiusissueips']) && isset($l2tpcfg['radius']['server']['enable'])) {
1913
				$issue_ip_type .= "0.0.0.0/0";
1914
			} else {
1915
				$issue_ip_type .= "ippool p0";
1916
			}
1917

    
1918
			$ipcp_dns = '';
1919
			if (is_ipaddr($l2tpcfg['dns1'])) {
1920
				$ipcp_dns = "set ipcp dns " . $l2tpcfg['dns1'];
1921
				if (is_ipaddr($l2tpcfg['dns2'])) {
1922
					$ipcp_dns .= " " . $l2tpcfg['dns2'];
1923
				}
1924
			} elseif (isset ($config['dnsmasq']['enable']) ||
1925
			    isset ($config['unbound']['enable'])) {
1926
				$ipcp_dns = "set ipcp dns " . get_interface_ip("lan");
1927
				if ($syscfg['dnsserver'][0]) {
1928
					$ipcp_dns .= " " . $syscfg['dnsserver'][0];
1929
				}
1930
			} elseif (is_array($syscfg['dnsserver']) &&
1931
			    ($syscfg['dnsserver'][0])) {
1932
				$ipcp_dns = "set ipcp dns " . join(" ", $syscfg['dnsserver']);
1933
			}
1934

    
1935
			$mpdconf =<<<EOD
1936

    
1937
startup:
1938

    
1939
l2tps:
1940
	set ippool add p0 {$l2tpcfg['remoteip']} {$ippool_p0}
1941

    
1942
	create bundle template l2tp_b
1943
	set bundle enable compression
1944
	set bundle yes crypt-reqd
1945

    
1946
	set ccp yes mppc
1947

    
1948
	set iface name l2tp
1949
	set iface group l2tp
1950
	set iface up-script /usr/local/sbin/vpn-linkup-l2tp
1951
	set iface down-script /usr/local/sbin/vpn-linkdown-l2tp
1952
	set iface disable on-demand
1953
	set iface enable proxy-arp
1954

    
1955
	set ipcp yes vjcomp
1956
	{$issue_ip_type}
1957
	{$ipcp_dns}
1958

    
1959
	create link template l2tp_l l2tp
1960
	set link action bundle l2tp_b
1961

    
1962
	set link yes acfcomp protocomp
1963
	set link enable multilink
1964
	set link no pap chap chap-msv2
1965
	{$paporchap}
1966
	{$l2tp_listen}
1967
	set link keep-alive 10 180
1968
	set link enable incoming
1969

    
1970
EOD;
1971

    
1972

    
1973
			if (isset ($l2tpcfg['radius']['enable'])) {
1974
				$mpdconf .=<<<EOD
1975
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1976
	set radius retries 3
1977
	set radius timeout 10
1978
	set auth disable internal
1979
	set auth enable radius-auth
1980

    
1981
EOD;
1982

    
1983
				if (isset ($l2tpcfg['radius']['accounting'])) {
1984
					$mpdconf .=<<<EOD
1985
	set auth enable radius-acct
1986

    
1987
EOD;
1988
				}
1989
			}
1990

    
1991
			fwrite($fd, $mpdconf);
1992
			fclose($fd);
1993
			unset($mpdconf);
1994

    
1995
			/* write mpd.secret */
1996
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1997
			if (!$fd) {
1998
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1999
				return 1;
2000
			}
2001

    
2002
			$mpdsecret = "\n\n";
2003

    
2004
			if (is_array($l2tpcfg['user'])) {
2005
				foreach ($l2tpcfg['user'] as $user) {
2006
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
2007
				}
2008
			}
2009

    
2010
			fwrite($fd, $mpdsecret);
2011
			fclose($fd);
2012
			unset($mpdsecret);
2013
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
2014

    
2015
			vpn_netgraph_support();
2016

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

    
2020
			break;
2021

    
2022
		case 'redir':
2023
			break;
2024
	}
2025

    
2026
	if (platform_booting()) {
2027
		echo "done\n";
2028
	}
2029

    
2030
	return 0;
2031
}
2032

    
2033
?>
(54-54/60)