Project

General

Profile

Download (55.1 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * vpn.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2016 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
			if (!is_ipaddr($ep)) {
274
				log_error(sprintf(gettext("IPsec ERROR: Could not find phase 1 source for connection %s. Omitting from configuration file."), $ph1ent['descr']));
275
				continue;
276
			}
277

    
278
			if (!in_array($ep, $ipmap)) {
279
				$ipmap[] = $ep;
280
			}
281

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

    
285
			if (isset ($ph1ent['mobile'])) {
286
				$mobile_ipsec_auth = $ph1ent['authentication_method'];
287
				continue;
288
			}
289

    
290
			$rg = $ph1ent['remote-gateway'];
291

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

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

    
315
					if ($ikeid != $ph2ent['ikeid']) {
316
						continue;
317
					}
318

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

    
378
	$accept_unencrypted = "";
379
	if (isset($config['ipsec']['acceptunencryptedmainmode'])) {
380
		$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
381
	}
382

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

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

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

    
399
	$makebeforebreak = '';
400
	if (isset($config['ipsec']['makebeforebreak'])) {
401
		$makebeforebreak = 'make_before_break = yes';
402
	}
403

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

    
414
	unset($stronconf);
415

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

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

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

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

    
459
	plugins {
460
		# Load defaults
461
		include {$g['varetc_path']}/ipsec/strongswan.d/charon/*.conf
462

    
463
		stroke {
464
			secrets_file = {$g['varetc_path']}/ipsec/ipsec.secrets
465
		}
466

    
467
		unity {
468
			load = {$unity_enabled}
469
		}
470

    
471
EOD;
472

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

    
488
EOD;
489
		}
490
	}
491

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

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

    
510
EOD;
511
	}
512

    
513
	if (is_array($a_client) && isset($a_client['enable'])) {
514
		$strongswan .= "\t\tattr {\n";
515

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

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

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

    
553
				if (!isset($ph2ent['mobile'])) {
554
					continue;
555
				}
556

    
557
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
558

    
559
				if (!empty($net_list)) {
560
					$net_list .= ",";
561
				}
562
				$net_list .= $localid;
563
			}
564

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

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

    
581
		if (!empty($a_client['dns_split'])) {
582
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
583
		}
584

    
585
		if (!empty($a_client['login_banner'])) {
586
			$strongswan .= "\t\t\t28672 = \"{$a_client['login_banner']}\"\n";
587
		}
588

    
589
		if (isset($a_client['save_passwd'])) {
590
			$strongswan .= "\t\t\t28673 = 1\n";
591
		}
592

    
593
		if ($a_client['pfs_group']) {
594
			$strongswan .= "\t\t\t28679 = \"{$a_client['pfs_group']}\"\n";
595
		}
596
		$strongswan .= "\t\t}\n";
597

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

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

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

    
638
	$pskconf = "";
639

    
640
	$vpncas = array();
641
	if (is_array($a_phase1) && count($a_phase1)) {
642
		foreach ($a_phase1 as $ph1ent) {
643

    
644
			if (isset($ph1ent['disabled'])) {
645
				continue;
646
			}
647

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

    
652
				$ikeid = $ph1ent['ikeid'];
653
				$cert = lookup_cert($ph1ent['certref']);
654

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

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

    
670
				@chmod($certpath, 0600);
671

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

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

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

    
693
				$myid = trim($myid_data);
694

    
695
				if (empty($peerid_data)) {
696
					continue;
697
				}
698

    
699
				if ($myid_type == 'fqdn' && !empty($myid)) {
700
					$myid = "@{$myid}";
701
				}
702

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

    
705
				$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
706

    
707
				if ($peerid_type == 'fqdn' && !empty($peerid)) {
708
					$peerid = "@{$peerid}";
709
				}
710

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

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

    
725
				if (!empty($ph1ent['caref']) && !array_key_exists($ph1ent['caref'], $vpncas)) {
726
					$thisca = lookup_ca($ph1ent['caref']);
727
					$vpncas[$ph1ent['caref']] = $thisca;
728

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

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

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

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

    
783
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
784
	chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
785
	unset($pskconf);
786

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

    
799
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
800
		$ipsecconf .= "config setup\n\tuniqueids = {$uniqueids}\n";
801

    
802
		if (isset($config['ipsec']['strictcrlpolicy'])) {
803
			$ipsecconf .= "\tstrictcrlpolicy = yes \n";
804
		}
805

    
806
		if (!isset($config['ipsec']['noshuntlaninterfaces'])) {
807
			if ($config['interfaces']['lan']) {
808
				$lanip = get_interface_ip("lan");
809
				if (!empty($lanip) && is_ipaddrv4($lanip)) {
810
					$lansn = get_interface_subnet("lan");
811
					$lansa = gen_subnet($lanip, $lansn);
812
					$ipsecconf .= <<<EOD
813

    
814
conn bypasslan
815
	leftsubnet = {$lansa}/{$lansn}
816
	rightsubnet = {$lansa}/{$lansn}
817
	authby = never
818
	type = passthrough
819
	auto = route
820

    
821
EOD;
822
				}
823
			}
824
		}
825

    
826
		foreach ($a_phase1 as $ph1ent) {
827
			if (isset($ph1ent['disabled'])) {
828
				continue;
829
			}
830

    
831
			if ($ph1ent['mode'] == "aggressive") {
832
				$aggressive = "yes";
833
			} else {
834
				$aggressive = "no";
835
			}
836

    
837
			$ep = ipsec_get_phase1_src($ph1ent);
838
			if (!$ep) {
839
				continue;
840
			}
841

    
842
			$ikeid = $ph1ent['ikeid'];
843
			$keyexchange = "ikev1";
844
			$passive = "route";
845
			if (!empty($ph1ent['iketype'])) {
846
				if ($ph1ent['iketype'] == "ikev2") {
847
					$keyexchange = "ikev2";
848
				} elseif ($ph1ent['iketype'] == "auto") {
849
					$keyexchange = "ike";
850
				}
851
			}
852

    
853
			if (isset($ph1ent['mobile'])) {
854
				$right_spec = "%any";
855
				$passive = 'add';
856
			} else {
857
				if (isset($ph1ent['responderonly'])) {
858
					$passive = 'add';
859
				}
860

    
861
				$right_spec = $ph1ent['remote-gateway'];
862
				if (is_ipaddr($right_spec)) {
863
					$sourcehost = $right_spec;
864
				} else {
865
					$sourcehost = $rgmap[$right_spec];
866
				}
867

    
868
				if (substr($ph1ent['interface'], 0, 4) == "_vip") {
869
					$vpninterface = get_configured_vip_interface($ph1ent['interface']);
870
					if (substr($vpninterface, 0, 4) == "_vip") {
871
						// vips are nested if its a ipalias with a carp parent
872
						$vpninterface = get_configured_vip_interface($vpninterface);
873
					}
874
					$ifacesuse = get_real_interface($vpninterface);
875
				} else {
876
					$ifacesuse = get_failover_interface($ph1ent['interface']);
877
					if (substr($ifacesuse, 0, 4) == "_vip") {
878
						$vpninterface = get_configured_vip_interface($ifacesuse);
879
						$ifacesuse = get_real_interface($vpninterface);
880
					} else {
881
						$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
882
					}
883
				}
884
				if ($ph1ent['protocol'] == 'inet') {
885
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
886
						$gatewayip = get_interface_gateway($vpninterface);
887
						$interfaceip = get_interface_ip($vpninterface);
888
						$subnet_bits = get_interface_subnet($vpninterface);
889
						$subnet_ip = gen_subnetv4($interfaceip, $subnet_bits);
890
						/* if the remote gateway is in the local subnet, then don't add a route */
891
						if (is_ipaddrv4($sourcehost) &&
892
						    !ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
893
							if (is_ipaddrv4($gatewayip)) {
894
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
895
								route_add_or_change("-host {$sourcehost} {$gatewayip}");
896
							}
897
						}
898
					}
899
				} else if ($ph1ent['protocol'] == 'inet6') {
900
					if (!empty($ifacesuse) && interface_has_gatewayv6($vpninterface)) {
901
						$gatewayip = get_interface_gateway_v6($vpninterface);
902
						$interfaceip = get_interface_ipv6($vpninterface);
903
						$subnet_bits = get_interface_subnetv6($vpninterface);
904
						$subnet_ip = gen_subnetv6($interfaceip, $subnet_bits);
905
						/* if the remote gateway is in the local subnet, then don't add a route */
906
						if (is_ipaddrv6($sourcehost) &&
907
						    !ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
908
							if (is_ipaddrv6($gatewayip)) {
909
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
910
								route_add_or_change("-inet6 -host {$sourcehost} {$gatewayip}");
911
							}
912
						}
913
					}
914
				}
915
			}
916

    
917
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
918
			if ($myid_type != 'address' && $myid_type != 'keyid' && $myid_type != 'asn1dn') {
919
				$myid_data = "{$myid_type}:{$myid_data}";
920
			} elseif ($myid_type == "asn1dn" && !empty($myid_data)) {
921
				if ($myid_data[0] == '#') {
922
				/* asn1dn needs double quotes */
923
					$myid_data = "\"{$myid_type}:{$myid_data}\"";
924
				} else {
925
					$myid_data = "\"{$myid_data}\"";
926
				}
927
			}
928
			$leftid = '';
929
			if (!empty($myid_data)) {
930
				$leftid = "leftid = {$myid_data}";
931
			}
932

    
933
			$peerid_spec = '';
934
			if (isset($ph1ent['mobile']) && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
935
				// Only specify peer ID if we are not dealing with mobile PSK
936
			} else {
937
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
938
				if ($peerid_type == 'any') {
939
					$peerid_spec = '';
940
				} elseif ($peerid_type != 'address' && $peerid_type != 'keyid' && $peerid_type != 'asn1dn') {
941
					$peerid_spec = "{$peerid_type}:{$peerid_data}";
942
				} elseif ($peerid_type == "asn1dn") {
943
					/* asn1dn needs double quotes */
944
					if ($peerid_data[0] == '#') {
945
						$peerid_spec = "\"{$peerid_type}:{$peerid_data}\"";
946
					} elseif (!empty($peerid_data)) {
947
						$peerid_spec = "\"{$peerid_data}\"";
948
					}
949
				} else {
950
					$peerid_spec = $peerid_data;
951
				}
952
			}
953

    
954
			if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
955
				$ealgosp1 = '';
956
				$ealg_id = $ph1ent['encryption-algorithm']['name'];
957
				$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
958
				if ($ealg_kl) {
959
					$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
960
				} else {
961
					$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
962
				}
963

    
964
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
965
				if (!empty($modp)) {
966
					$ealgosp1 .= "-{$modp}";
967
				}
968

    
969
				$ealgosp1 .= "!";
970
			}
971

    
972
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
973
				if ($passive == "route") {
974
					$dpdline = "dpdaction = restart";
975
				} else {
976
					$dpdline = "dpdaction = clear";
977
				}
978
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
979
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
980
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
981
			} else {
982
				$dpdline = "dpdaction = none";
983
			}
984

    
985
			$ikelifeline = '';
986
			if ($ph1ent['lifetime']) {
987
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
988
			}
989

    
990
			$rightsourceip = NULL;
991
			if (isset($ph1ent['mobile'])) {
992
				$rightsourceips = array();
993
				if (!empty($a_client['pool_address'])) {
994
					$rightsourceips[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
995
				}
996
				if (!empty($a_client['pool_address_v6'])) {
997
					$rightsourceips[] = "{$a_client['pool_address_v6']}/{$a_client['pool_netbits_v6']}";
998
				}
999
				if ($ph1ent['authentication_method'] == "eap-radius" && !count($rightsourceips)) {
1000
					$rightsourceips[] = "%radius";
1001
				}
1002
				if (count($rightsourceips)) {
1003
					$rightsourceip = "\trightsourceip = " . implode(',', $rightsourceips) . "\n";
1004
				}
1005
			}
1006

    
1007
			if (!empty($ph1ent['caref'])) {
1008
				$ca = lookup_ca($ph1ent['caref']);
1009
				if ($ca) {
1010
					$casubarr = cert_get_subject_array($ca['crt']);
1011
					$casub = "";
1012
					foreach ($casubarr as $casubfield) {
1013
						if (empty($casub)) {
1014
							$casub = "/";
1015
						}
1016
						/* The subfield value could be an array. To avoid duplicating code,
1017
						 * always make it an array then iterate.
1018
						 * See https://redmine.pfsense.org/issues/7929
1019
						 */
1020
						if (!is_array($casubfield['v'])) {
1021
							$casubfield['v'] = array($casubfield['v']);
1022
						}
1023
						foreach ($casubfield['v'] as $casubval) {
1024
							$casub .= "{$casubfield['a']}={$casubval}/";
1025
						}
1026
					}
1027

    
1028
				}
1029
			}
1030

    
1031
			$authentication = "";
1032
			switch ($ph1ent['authentication_method']) {
1033
				case 'eap-mschapv2':
1034
					if (isset($ph1ent['mobile'])) {
1035
						$authentication = "eap_identity=%any\n\t";
1036
						$authentication .= "leftauth=pubkey\n\trightauth=eap-mschapv2";
1037
						if (!empty($ph1ent['certref'])) {
1038
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1039
							$authentication .= "\n\tleftsendcert=always";
1040
						}
1041
					}
1042
					break;
1043
				case 'eap-tls':
1044
					if (isset($ph1ent['mobile'])) {
1045
						$authentication = "eap_identity=%identity\n\t";
1046
						$authentication .= "leftauth=pubkey\n\trightauth=eap-tls";
1047
						if (!empty($ph1ent['certref'])) {
1048
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1049
							$authentication .= "\n\tleftsendcert=always";
1050
						}
1051
					} else {
1052
						$authentication = "leftauth=eap-tls\n\trightauth=eap-tls";
1053
						if (!empty($ph1ent['certref'])) {
1054
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1055
							$authentication .= "\n\tleftsendcert=always";
1056
						}
1057
					}
1058
					if (isset($casub)) {
1059
						$authentication .= "\n\trightca=\"$casub\"";
1060
					}
1061
					break;
1062
				case 'eap-radius':
1063
					if (isset($ph1ent['mobile'])) {
1064
						$authentication = "eap_identity=%identity\n\t";
1065
						$authentication .= "leftauth=pubkey\n\trightauth=eap-radius";
1066
						if (!empty($ph1ent['certref'])) {
1067
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1068
							$authentication .= "\n\tleftsendcert=always";
1069
						}
1070
					} else {
1071
						$authentication = "leftauth=eap-radius\n\trightauth=eap-radius";
1072
						if (!empty($ph1ent['certref'])) {
1073
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1074
							$authentication .= "\n\tleftsendcert=always";
1075
						}
1076
					}
1077
					break;
1078
				case 'xauth_rsa_server':
1079
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
1080
					$authentication .= "\n\trightauth2 = xauth-generic";
1081
					if (!empty($ph1ent['certref'])) {
1082
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1083
						$authentication .= "\n\tleftsendcert=always";
1084
					}
1085
					if (isset($casub)) {
1086
						$authentication .= "\n\trightca=\"$casub\"";
1087
					}
1088
					break;
1089
				case 'xauth_psk_server':
1090
					$authentication = "leftauth = psk\n\trightauth = psk";
1091
					$authentication .= "\n\trightauth2 = xauth-generic";
1092
					break;
1093
				case 'pre_shared_key':
1094
					$authentication = "leftauth = psk\n\trightauth = psk";
1095
					break;
1096
				case 'rsasig':
1097
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
1098
					if (!empty($ph1ent['certref'])) {
1099
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1100
						$authentication .= "\n\tleftsendcert=always";
1101
					}
1102
					if (isset($casub)) {
1103
						$authentication .= "\n\trightca=\"$casub\"";
1104
					}
1105
					break;
1106
				case 'hybrid_rsa_server':
1107
					$authentication = "leftauth = pubkey\n\trightauth = xauth-generic";
1108
					if (!empty($ph1ent['certref'])) {
1109
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1110
						$authentication .= "\n\tleftsendcert=always";
1111
					}
1112
					break;
1113
			}
1114

    
1115
			$left_spec = $ep;
1116

    
1117
			if (isset($ph1ent['reauth_enable'])) {
1118
				$reauth = "reauth = no";
1119
			} else {
1120
				$reauth = "reauth = yes";
1121
			}
1122

    
1123
			if (isset($ph1ent['rekey_enable'])) {
1124
				$rekeyline = "rekey = no";
1125
			} else {
1126
				$rekeyline = "rekey = yes";
1127
				if(!empty($ph1ent['margintime'])){
1128
					$rekeyline .= "\n\tmargintime = {$ph1ent['margintime']}s";
1129
				}
1130
			}
1131

    
1132
			if ($ph1ent['nat_traversal'] == 'off') {
1133
				$forceencaps = 'forceencaps = no';
1134
			} else if ($ph1ent['nat_traversal'] == 'force') {
1135
				$forceencaps = 'forceencaps = yes';
1136
			} else {
1137
				$forceencaps = 'forceencaps = no';
1138
			}
1139

    
1140
			if ($ph1ent['mobike'] == 'on') {
1141
				$mobike = 'mobike = yes';
1142
			} else {
1143
				$mobike = 'mobike = no';
1144
			}
1145

    
1146
			if (isset($ph1ent['tfc_enable'])) {
1147
				if (isset($ph1ent['tfc_bytes']) && is_numericint($ph1ent['tfc_bytes'])) {
1148
					$tfc = "tfc = {$ph1ent['tfc_bytes']}";
1149
				} else {
1150
					$tfc = "tfc = %mtu";
1151
				}
1152
			}
1153

    
1154
			$ipseclifetime = 0;
1155
			$rightsubnet_spec = array();
1156
			$leftsubnet_spec = array();
1157
			$reqids = array();
1158
			$ealgoAHsp2arr = array();
1159
			$ealgoESPsp2arr = array();
1160
			if (is_array($a_phase2) && count($a_phase2)) {
1161
				foreach ($a_phase2 as $ph2ent) {
1162
					if ($ikeid != $ph2ent['ikeid']) {
1163
						continue;
1164
					}
1165

    
1166
					if (isset($ph2ent['disabled'])) {
1167
						continue;
1168
					}
1169

    
1170
					if (isset($ph2ent['mobile']) && !isset($a_client['enable'])) {
1171
						continue;
1172
					}
1173

    
1174
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
1175
						$tunneltype = "type = tunnel";
1176

    
1177
						$localid_type = $ph2ent['localid']['type'];
1178
						$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
1179

    
1180
						/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
1181
						if (($localid_type == "none" || $localid_type == "mobile") &&
1182
						    isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ikeid) == 1)) {
1183
							$left_spec = '%any';
1184
						} else {
1185
							if ($localid_type != "address") {
1186
								$localid_type = "subnet";
1187
							}
1188
							// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
1189
							if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) {
1190
								log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
1191
								continue;
1192
							}
1193
							if (!empty($ph2ent['natlocalid'])) {
1194
								$natleftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
1195
								if ($ph2ent['natlocalid']['type'] != "address") {
1196
									if (is_subnet($natleftsubnet_data)) {
1197
										$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
1198
									}
1199
								} else {
1200
									if (is_ipaddr($natleftsubnet_data)) {
1201
										$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
1202
									}
1203
								}
1204
								$natfilterrules = true;
1205
							}
1206
						}
1207

    
1208
						$leftsubnet_spec[] = $leftsubnet_data;
1209

    
1210
						if (!isset($ph2ent['mobile'])) {
1211
							$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
1212
							$rightsubnet_spec[] = $tmpsubnet;
1213
						} else if (!empty($a_client['pool_address'])) {
1214
							$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1215
						}
1216
					} else {
1217
						$tunneltype = "type = transport";
1218

    
1219
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
1220
						    ($ph1ent['authentication_method'] == "pre_shared_key")) &&
1221
						    isset($ph1ent['mobile'])) {
1222
							$left_spec = "%any";
1223
						} else {
1224
							$tmpsubnet = ipsec_get_phase1_src($ph1ent);
1225
							$leftsubnet_spec[] = $tmpsubnet;
1226
						}
1227

    
1228
						if (!isset($ph2ent['mobile'])) {
1229
							$rightsubnet_spec[] = $right_spec;
1230
						}
1231
					}
1232

    
1233
					if (isset($a_client['pfs_group']) && isset($ph2ent['mobile'])) {
1234
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
1235
					}
1236

    
1237
					if ($ph2ent['protocol'] == 'esp') {
1238
						if (is_array($ph2ent['encryption-algorithm-option'])) {
1239
							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
1240
								$ealg_id = $ealg['name'];
1241
								$ealg_kl = $ealg['keylen'];
1242

    
1243
								if (!empty($ealg_kl) && $ealg_kl == "auto") {
1244
									if (empty($p2_ealgos) || !is_array($p2_ealgos)) {
1245
										require_once("ipsec.inc");
1246
									}
1247
									$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
1248
									$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
1249
									$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
1250
									/* XXX: in some cases where include ordering is suspect these variables
1251
									 * are somehow 0 and we enter this loop forever and timeout after 900
1252
									 * seconds wrecking bootup */
1253
									if ($key_hi != 0 and $key_lo != 0 and $key_step != 0) {
1254
										for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
1255
											if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1256
												foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1257
													$halgo = str_replace('hmac_', '', $halgo);
1258
													$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
1259
													$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1260
													if (!empty($modp)) {
1261
														$tmpealgo .= "-{$modp}";
1262
													}
1263
													$ealgoESPsp2arr[] = $tmpealgo;
1264
												}
1265
											} else {
1266
												$tmpealgo = "{$ealg_id}{$keylen}";
1267
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1268
												if (!empty($modp)) {
1269
													$tmpealgo .= "-{$modp}";
1270
												}
1271
												$ealgoESPsp2arr[] = $tmpealgo;
1272
											}
1273
										}
1274
									}
1275
								} else {
1276
									if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1277
										foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1278
											$halgo = str_replace('hmac_', '', $halgo);
1279
											$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
1280
											$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1281
											if (!empty($modp)) {
1282
												$tmpealgo .= "-{$modp}";
1283
											}
1284
											$ealgoESPsp2arr[] = $tmpealgo;
1285
										}
1286
									} else {
1287
										$tmpealgo = "{$ealg_id}{$ealg_kl}";
1288
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1289
										if (!empty($modp)) {
1290
											$tmpealgo .= "-{$modp}";
1291
										}
1292
										$ealgoESPsp2arr[] = $tmpealgo;
1293
									}
1294
								}
1295
							}
1296
						}
1297
					} else if ($ph2ent['protocol'] == 'ah') {
1298
						if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1299
							$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1300
							foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
1301
								$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
1302
								if (!empty($modp)) {
1303
									$tmpAHalgo = "-{$modp}";
1304
								}
1305
								$ealgoAHsp2arr[] = $tmpAHalgo;
1306
							}
1307
						}
1308
					}
1309

    
1310
					$reqids[] = $ph2ent['reqid'];
1311

    
1312
					if (!empty($ph2ent['lifetime'])) {
1313
						if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) {
1314
							$ipseclifetime = intval($ph2ent['lifetime']);
1315
						}
1316
					}
1317

    
1318
				}
1319
			}
1320

    
1321
			$ipsecconnect =<<<EOD
1322
	fragmentation = yes
1323
	keyexchange = {$keyexchange}
1324
	{$reauth}
1325
	{$forceencaps}
1326
	{$mobike}
1327
	{$tfc}
1328
	{$rekeyline}
1329
	installpolicy = yes
1330
	{$tunneltype}
1331
	{$dpdline}
1332
	auto = {$passive}
1333
	left = {$left_spec}
1334
	right = {$right_spec}
1335
	{$leftid}
1336

    
1337
EOD;
1338

    
1339
			/* Disable ipcomp for now. redmine #6167
1340
			if (isset($config['ipsec']['compression'])) {
1341
				$ipsecconnect .= "\tcompress = yes\n";
1342
				$enablecompression = true;
1343
			} */
1344
			if (!empty($ikelifeline)) {
1345
				$ipsecconnect .= "\t{$ikelifeline}\n";
1346
			}
1347
			if ($ipseclifetime > 0) {
1348
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
1349
			}
1350
			if (!empty($rightsourceip)) {
1351
				$ipsecconnect .= "{$rightsourceip}";
1352
			}
1353
			if (!empty($ealgosp1)) {
1354
				$ipsecconnect .= "\t{$ealgosp1}\n";
1355
			}
1356
			if (!empty($ealgoAHsp2arr)) {
1357
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
1358
			}
1359
			if (!empty($ealgoESPsp2arr)) {
1360
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
1361
			}
1362
			if (!empty($authentication)) {
1363
				$ipsecconnect .= "\t{$authentication}\n";
1364
			}
1365
			if (!empty($peerid_spec)) {
1366
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
1367
			}
1368
			if ($keyexchange != 'ikev2') {
1369
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
1370
			}
1371

    
1372
			if (!isset($ph1ent['mobile']) && ($keyexchange == 'ikev1' || isset($ph1ent['splitconn']))) {
1373
				if (!empty($rightsubnet_spec)) {
1374
					$ipsecfin = '';
1375
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
1376
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
1377
						//if (!empty($reqids[$idx])) {
1378
						//	$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
1379
						//}
1380
						$ipsecfin .= $ipsecconnect;
1381
						$ipsecfin .= "\trightsubnet = {$rsubnet}\n";
1382
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n";
1383
					}
1384
				} else {
1385
					log_error(sprintf(gettext("No phase2 specifications for tunnel with REQID = %s"), $ikeid));
1386
				}
1387
			} else {
1388
				$ipsecfin = "\nconn con{$ph1ent['ikeid']}\n";
1389
				//if (!empty($reqids[$idx])) {
1390
				//	$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
1391
				//}
1392
				$ipsecfin .= $ipsecconnect;
1393
				if (!isset($ph1ent['mobile']) && !empty($rightsubnet_spec)) {
1394
					$tempsubnets = array();
1395
					foreach ($rightsubnet_spec as $rightsubnet) {
1396
						$tempsubnets[$rightsubnet] = $rightsubnet;
1397
					}
1398
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "\n";
1399
					unset($tempsubnets, $rightsubnet);
1400
				}
1401
				if (!empty($leftsubnet_spec)) {
1402
					$tempsubnets = array();
1403
					foreach ($leftsubnet_spec as $leftsubnet) {
1404
						$tempsubnets[$leftsubnet] = $leftsubnet;
1405
					}
1406
					$ipsecfin .= "\tleftsubnet = " . join(",", $tempsubnets) . "\n";
1407
					unset($tempsubnets, $leftsubnet);
1408
				}
1409
			}
1410
			$ipsecconf .= $ipsecfin;
1411
			unset($ipsecfin);
1412
		}
1413
	}
1414

    
1415
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1416
	unset($ipsecconf);
1417
	/* end ipsec.conf */
1418

    
1419
	if ($enablecompression === true) {
1420
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1421
	} else {
1422
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1423
	}
1424

    
1425
	/* manage process */
1426
	if ($restart === true) {
1427
		mwexec("/usr/local/sbin/ipsec restart", false);
1428
	} else {
1429
		if (isvalidpid("{$g['varrun_path']}/starter.charon.pid")) {
1430
			/* Update configuration changes */
1431
			/* Read secrets */
1432
			mwexec("/usr/local/sbin/ipsec rereadall", false);
1433
			mwexec("/usr/local/sbin/ipsec reload", false);
1434
		} else {
1435
			mwexec("/usr/local/sbin/ipsec start", false);
1436
		}
1437
	}
1438

    
1439
	// run ping_hosts.sh once if it's enabled to avoid wait for minicron
1440
	if ($ipsecpinghostsactive == true) {
1441
		mwexec_bg("/usr/local/bin/ping_hosts.sh");
1442
	}
1443

    
1444
	if ($natfilterrules == true) {
1445
		filter_configure();
1446
	}
1447
	/* start filterdns, if necessary */
1448
	if (count($filterdns_list) > 0) {
1449
		$interval = 60;
1450
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) {
1451
			$interval = $ipseccfg['dns-interval'];
1452
		}
1453

    
1454
		$hostnames = "";
1455
		array_unique($filterdns_list);
1456
		foreach ($filterdns_list as $hostname) {
1457
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1458
		}
1459
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1460
		unset($hostnames);
1461

    
1462
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid")) {
1463
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1464
		} else {
1465
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1466
		}
1467
	} else {
1468
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1469
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1470
	}
1471

    
1472
	if (platform_booting()) {
1473
		echo "done\n";
1474
	}
1475

    
1476
	unlock($ipsecstartlock);
1477
	return count($filterdns_list);
1478
}
1479

    
1480
/*
1481
 * Forcefully restart IPsec
1482
 * This is required for when dynamic interfaces reload
1483
 * For all other occasions the normal vpn_ipsec_configure()
1484
 * will gracefully reload the settings without restarting
1485
 */
1486
function vpn_ipsec_force_reload($interface = "") {
1487
	global $g, $config;
1488

    
1489
	if (!ipsec_enabled()) {
1490
		return;
1491
	}
1492

    
1493
	$ipseccfg = $config['ipsec'];
1494

    
1495
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1496
		$found = false;
1497
		foreach ($ipseccfg['phase1'] as $ipsec) {
1498
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1499
				$found = true;
1500
				break;
1501
			}
1502
		}
1503
		if (!$found) {
1504
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1505
			return;
1506
		}
1507
	}
1508

    
1509
	/* If we get this far then we need to take action. */
1510
	log_error(gettext("Forcefully reloading IPsec"));
1511
	vpn_ipsec_configure();
1512
}
1513

    
1514
/* master setup for vpn (mpd) */
1515
function vpn_setup() {
1516
	/* start pppoe server */
1517
	vpn_pppoes_configure();
1518

    
1519
	/* setup l2tp */
1520
	vpn_l2tp_configure();
1521
}
1522

    
1523
function vpn_netgraph_support() {
1524
	$iflist = get_configured_interface_list();
1525
	foreach ($iflist as $iface) {
1526
		$realif = get_real_interface($iface);
1527
		/* Get support for netgraph(4) from the nic */
1528
		$ifinfo = pfSense_get_interface_addresses($realif);
1529
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) {
1530
			pfSense_ngctl_attach(".", $realif);
1531
		}
1532
	}
1533
}
1534

    
1535
function vpn_pppoes_configure() {
1536
	global $config;
1537

    
1538
	if (is_array($config['pppoes']['pppoe'])) {
1539
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
1540
			vpn_pppoe_configure($pppoe);
1541
		}
1542
	}
1543
}
1544

    
1545
function vpn_pppoe_configure(&$pppoecfg) {
1546
	global $config, $g;
1547

    
1548
	$syscfg = $config['system'];
1549

    
1550
	/* create directory if it does not exist */
1551
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
1552
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1553
	}
1554

    
1555
	if (platform_booting()) {
1556
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
1557
			return 0;
1558
		}
1559

    
1560
		echo gettext("Configuring PPPoE Server service... ");
1561
	} else {
1562
		/* kill mpd */
1563
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1564

    
1565
		/* wait for process to die */
1566
		sleep(2);
1567

    
1568
	}
1569

    
1570
	switch ($pppoecfg['mode']) {
1571

    
1572
		case 'server':
1573

    
1574
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1575

    
1576
			if ($pppoecfg['paporchap'] == "chap") {
1577
				$paporchap = "set link enable chap";
1578
			} else {
1579
				$paporchap = "set link enable pap";
1580
			}
1581

    
1582
			/* write mpd.conf */
1583
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1584
			if (!$fd) {
1585
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1586
				return 1;
1587
			}
1588

    
1589
			$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 ";
1590
			if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1591
				$issue_ip_type .= "0.0.0.0/0";
1592
			} else {
1593
				$issue_ip_type .= "ippool p0";
1594
			}
1595

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

    
1598
			if (is_numeric($pppoecfg['n_pppoe_maxlogin']) && ($pppoecfg['n_pppoe_maxlogin'] > 0)) {
1599
				$pppoemaxlogins = $pppoecfg['n_pppoe_maxlogin'];
1600
			} else {
1601
				$pppoemaxlogins = 1;
1602
			}
1603

    
1604
			$ipcp_dns = '';
1605
			if (!empty($pppoecfg['dns1'])) {
1606
				$ipcp_dns = "set ipcp dns " . $pppoecfg['dns1'];
1607
				if (!empty($pppoecfg['dns2'])) {
1608
					$ipcp_dns .= " " . $pppoecfg['dns2'];
1609
				}
1610
			} elseif (isset($config['dnsmasq']['enable']) ||
1611
			    isset ($config['unbound']['enable'])) {
1612
				$ipcp_dns = "set ipcp dns " . get_interface_ip("lan");
1613
				if ($syscfg['dnsserver'][0]) {
1614
					$ipcp_dns .= " " . $syscfg['dnsserver'][0];
1615
				}
1616
			} elseif (is_array($syscfg['dnsserver']) &&
1617
			    ($syscfg['dnsserver'][0])) {
1618
				$ipcp_dns = "set ipcp dns " . join(" ", $syscfg['dnsserver']);
1619
			}
1620

    
1621
			$mpdconf = <<<EOD
1622
startup:
1623

    
1624
poes:
1625
	set ippool add p0 {$pppoecfg['remoteip']} {$ippool_p0}
1626

    
1627
	create bundle template poes_b
1628
	set bundle enable compression
1629

    
1630
	set ccp yes mppc
1631
	set mppc yes e40
1632
	set mppc yes e128
1633
	set mppc yes stateless
1634

    
1635
	set iface group pppoe
1636
	set iface up-script /usr/local/sbin/vpn-linkup
1637
	set iface down-script /usr/local/sbin/vpn-linkdown
1638
	set iface idle 0
1639
	set iface disable on-demand
1640
	set iface disable proxy-arp
1641
	set iface enable tcpmssfix
1642
	set iface mtu 1500
1643

    
1644
	set ipcp no vjcomp
1645
	{$issue_ip_type}
1646
	{$ipcp_dns}
1647

    
1648
	create link template poes_l pppoe
1649
	set link action bundle poes_b
1650

    
1651
	set auth max-logins {$pppoemaxlogins}
1652

    
1653
	set pppoe iface {$pppoe_interface}
1654

    
1655
	set link no multilink
1656
	set link no pap chap
1657
	{$paporchap}
1658
	set link keep-alive 60 180
1659
	set link max-redial -1
1660
	set link mru 1492
1661
	set link latency 1
1662
	set link enable incoming
1663

    
1664
EOD;
1665

    
1666
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1667
				$radiusport = "";
1668
				$radiusacctport = "";
1669
				if (isset($pppoecfg['radius']['server']['port'])) {
1670
					$radiusport = $pppoecfg['radius']['server']['port'];
1671
				}
1672
				if (isset($pppoecfg['radius']['server']['acctport'])) {
1673
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1674
				}
1675
				$mpdconf .=<<<EOD
1676
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1677
	set radius retries 3
1678
	set radius timeout 10
1679
	set auth enable radius-auth
1680

    
1681
EOD;
1682

    
1683
				if (isset ($pppoecfg['radius']['accounting'])) {
1684
					$mpdconf .=<<<EOD
1685
	set auth enable radius-acct
1686

    
1687
EOD;
1688
				}
1689
				if (!empty($pppoecfg['radius']['nasip'])) {
1690
					$mpdconf .= "\tset radius me {$pppoecfg['radius']['nasip']}\n";
1691
				}
1692
			}
1693

    
1694
			fwrite($fd, $mpdconf);
1695
			fclose($fd);
1696
			unset($mpdconf);
1697

    
1698
			if ($pppoecfg['username']) {
1699
				/* write mpd.secret */
1700
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1701
				if (!$fd) {
1702
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1703
					return 1;
1704
				}
1705

    
1706
				$mpdsecret = "\n\n";
1707

    
1708
				if (!empty($pppoecfg['username'])) {
1709
					$item = explode(" ", $pppoecfg['username']);
1710
					foreach ($item as $userdata) {
1711
						$data = explode(":", $userdata);
1712
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1713
					}
1714
				}
1715

    
1716
				fwrite($fd, $mpdsecret);
1717
				fclose($fd);
1718
				unset($mpdsecret);
1719
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1720
			}
1721

    
1722
			/* Check if previous instance is still up */
1723
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
1724
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1725
			}
1726

    
1727
			/* Get support for netgraph(4) from the nic */
1728
			pfSense_ngctl_attach(".", $pppoe_interface);
1729
			/* fire up mpd */
1730
			mwexec("/usr/local/sbin/mpd5 -b -d {$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn -p {$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid -s poes poes");
1731

    
1732
			break;
1733
	}
1734

    
1735
	if (platform_booting()) {
1736
		echo gettext("done") . "\n";
1737
	}
1738

    
1739
	return 0;
1740
}
1741

    
1742
function vpn_l2tp_configure() {
1743
	global $config, $g;
1744

    
1745
	$syscfg = $config['system'];
1746
	$l2tpcfg = $config['l2tp'];
1747

    
1748
	/* create directory if it does not exist */
1749
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
1750
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1751
	}
1752

    
1753
	if (platform_booting()) {
1754
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
1755
			return 0;
1756
		}
1757

    
1758
		echo gettext("Configuring l2tp VPN service... ");
1759
	} else {
1760
		/* kill mpd */
1761
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1762

    
1763
		/* wait for process to die */
1764
		sleep(8);
1765

    
1766
	}
1767

    
1768
	/* make sure l2tp-vpn directory exists */
1769
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
1770
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1771
	}
1772

    
1773
	switch ($l2tpcfg['mode']) {
1774

    
1775
		case 'server':
1776
			$l2tp_listen="";
1777
			$ipaddr = get_interface_ip(get_failover_interface($l2tpcfg['interface']));
1778
			if (is_ipaddrv4($ipaddr)) {
1779
				$l2tp_listen="set l2tp self $ipaddr";
1780
			}
1781

    
1782
			switch ($l2tpcfg['paporchap']) {
1783
				case 'chap':
1784
					$paporchap = "set link enable chap";
1785
					break;
1786
				case 'chap-msv2':
1787
					$paporchap = "set link enable chap-msv2";
1788
					break;
1789
				default:
1790
					$paporchap = "set link enable pap";
1791
					break;
1792
			}
1793

    
1794
			/* write mpd.conf */
1795
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1796
			if (!$fd) {
1797
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1798
				return 1;
1799
			}
1800

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

    
1803
			$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 ";
1804
			if (isset($l2tpcfg['radius']['radiusissueips']) && isset($l2tpcfg['radius']['server']['enable'])) {
1805
				$issue_ip_type .= "0.0.0.0/0";
1806
			} else {
1807
				$issue_ip_type .= "ippool p0";
1808
			}
1809

    
1810
			$ipcp_dns = '';
1811
			if (is_ipaddr($l2tpcfg['dns1'])) {
1812
				$ipcp_dns = "set ipcp dns " . $l2tpcfg['dns1'];
1813
				if (is_ipaddr($l2tpcfg['dns2'])) {
1814
					$ipcp_dns .= " " . $l2tpcfg['dns2'];
1815
				}
1816
			} elseif (isset ($config['dnsmasq']['enable']) ||
1817
			    isset ($config['unbound']['enable'])) {
1818
				$ipcp_dns = "set ipcp dns " . get_interface_ip("lan");
1819
				if ($syscfg['dnsserver'][0]) {
1820
					$ipcp_dns .= " " . $syscfg['dnsserver'][0];
1821
				}
1822
			} elseif (is_array($syscfg['dnsserver']) &&
1823
			    ($syscfg['dnsserver'][0])) {
1824
				$ipcp_dns = "set ipcp dns " . join(" ", $syscfg['dnsserver']);
1825
			}
1826

    
1827
			$mpdconf =<<<EOD
1828

    
1829
startup:
1830

    
1831
l2tps:
1832
	set ippool add p0 {$l2tpcfg['remoteip']} {$ippool_p0}
1833

    
1834
	create bundle template l2tp_b
1835
	set bundle enable compression
1836
	set bundle yes crypt-reqd
1837

    
1838
	set ccp yes mppc
1839

    
1840
	set iface group l2tp
1841
	set iface up-script /usr/local/sbin/vpn-linkup
1842
	set iface down-script /usr/local/sbin/vpn-linkdown
1843
	set iface disable on-demand
1844
	set iface enable proxy-arp
1845

    
1846
	set ipcp yes vjcomp
1847
	{$issue_ip_type}
1848
	{$ipcp_dns}
1849

    
1850
	create link template l2tp_l l2tp
1851
	set link action bundle l2tp_b
1852

    
1853
	set link yes acfcomp protocomp
1854
	set link enable multilink
1855
	set link no pap chap chap-msv2
1856
	{$paporchap}
1857
	{$l2tp_listen}
1858
	set link keep-alive 10 180
1859
	set link enable incoming
1860

    
1861
EOD;
1862

    
1863

    
1864
			if (isset ($l2tpcfg['radius']['enable'])) {
1865
				$mpdconf .=<<<EOD
1866
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1867
	set radius retries 3
1868
	set radius timeout 10
1869
	set auth disable internal
1870
	set auth enable radius-auth
1871

    
1872
EOD;
1873

    
1874
				if (isset ($l2tpcfg['radius']['accounting'])) {
1875
					$mpdconf .=<<<EOD
1876
	set auth enable radius-acct
1877

    
1878
EOD;
1879
				}
1880
			}
1881

    
1882
			fwrite($fd, $mpdconf);
1883
			fclose($fd);
1884
			unset($mpdconf);
1885

    
1886
			/* write mpd.secret */
1887
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1888
			if (!$fd) {
1889
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1890
				return 1;
1891
			}
1892

    
1893
			$mpdsecret = "\n\n";
1894

    
1895
			if (is_array($l2tpcfg['user'])) {
1896
				foreach ($l2tpcfg['user'] as $user) {
1897
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1898
				}
1899
			}
1900

    
1901
			fwrite($fd, $mpdsecret);
1902
			fclose($fd);
1903
			unset($mpdsecret);
1904
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1905

    
1906
			vpn_netgraph_support();
1907

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

    
1911
			break;
1912

    
1913
		case 'redir':
1914
			break;
1915
	}
1916

    
1917
	if (platform_booting()) {
1918
		echo "done\n";
1919
	}
1920

    
1921
	return 0;
1922
}
1923

    
1924
?>
(48-48/54)