Project

General

Profile

Download (58 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	vpn.inc
4

    
5
	part of pfSense (https://www.pfsense.org)
6
	Copyright (C) 2008 Shrew Soft Inc
7
	Copyright (c) 2004-2016 Electric Sheep Fencing, LLC.
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
	Redistribution and use in source and binary forms, with or without
15
	modification, are permitted provided that the following conditions are met:
16

    
17
	1. Redistributions of source code must retain the above copyright notice,
18
	   this list of conditions and the following disclaimer.
19

    
20
	2. Redistributions in binary form must reproduce the above copyright
21
	   notice, this list of conditions and the following disclaimer in
22
	   the documentation and/or other materials provided with the
23
	   distribution.
24

    
25
	3. All advertising materials mentioning features or use of this software
26
	   must display the following acknowledgment:
27
	   "This product includes software developed by the pfSense Project
28
	   for use in the pfSense® software distribution. (http://www.pfsense.org/).
29

    
30
	4. The names "pfSense" and "pfSense Project" must not be used to
31
	   endorse or promote products derived from this software without
32
	   prior written permission. For written permission, please contact
33
	   coreteam@pfsense.org.
34

    
35
	5. Products derived from this software may not be called "pfSense"
36
	   nor may "pfSense" appear in their names without prior written
37
	   permission of the Electric Sheep Fencing, LLC.
38

    
39
	6. Redistributions of any form whatsoever must retain the following
40
	   acknowledgment:
41

    
42
	"This product includes software developed by the pfSense Project
43
	for use in the pfSense software distribution (http://www.pfsense.org/).
44

    
45
	THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
46
	EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47
	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
48
	PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
49
	ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50
	SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
51
	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52
	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53
	HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
54
	STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
55
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
56
	OF THE POSSIBILITY OF SUCH DAMAGE.
57
*/
58

    
59
require_once("ipsec.inc");
60
require_once("filter.inc");
61

    
62
function vpn_update_daemon_loglevel($category, $level) {
63
	global $ipsec_log_cats, $ipsec_log_sevs;
64

    
65
	if (in_array($category, array_keys($ipsec_log_cats), true) && in_array(intval($level), array_keys($ipsec_log_sevs), true)) {
66

    
67
		/* if you're setting to -1, need to add "--" to args */
68
		$argterm = "";
69
		if ($level == "-1") {
70
			$argterm = "--";
71
		}
72

    
73
		mwexec("/usr/local/sbin/ipsec stroke loglevel {$category} {$argterm} {$level}");
74
	}
75
}
76

    
77
function vpn_logging_cfgtxt() {
78
	global $config, $ipsec_log_cats, $ipsec_log_sevs;
79

    
80
	$cfgtext = array();
81
	foreach (array_keys($ipsec_log_cats) as $cat) {
82
		if (is_numeric($config['ipsec']['logging'][$cat]) &&
83
		    in_array(intval($config['ipsec']['logging'][$cat]), array_keys($ipsec_log_sevs), true)) {
84
			$cfgtext[] = "${cat} = {$config['ipsec']['logging'][$cat]}";
85
		}
86
	}
87

    
88
	return $cfgtext;
89
}
90

    
91
/* include all configuration functions */
92
function vpn_ipsec_convert_to_modp($index) {
93

    
94
	$conversion = "";
95
	switch ($index) {
96
		case '1':
97
			$conversion = "modp768";
98
			break;
99
		case '2':
100
			$conversion = "modp1024";
101
			break;
102
		case '5':
103
			$conversion = "modp1536";
104
			break;
105
		case '14':
106
			$conversion = "modp2048";
107
			break;
108
		case '15':
109
			$conversion = "modp3072";
110
			break;
111
		case '16':
112
			$conversion = "modp4096";
113
			break;
114
		case '17':
115
			$conversion = "modp6144";
116
			break;
117
		case '18':
118
			$conversion = "modp8192";
119
			break;
120
		case '19':
121
			$conversion = "ecp256";
122
			break;
123
		case '20':
124
			$conversion = "ecp384";
125
			break;
126
		case '21':
127
			$conversion = "ecp521";
128
			break;
129
		case '22':
130
			$conversion = "modp1024s160";
131
			break;
132
		case '23':
133
			$conversion = "modp2048s224";
134
			break;
135
		case '24':
136
			$conversion = "modp2048s256";
137
			break;
138
		case '28':
139
			$conversion = "ecp256bp";
140
			break;
141
		case '29':
142
			$conversion = "ecp384bp";
143
			break;
144
		case '30':
145
			$conversion = "ecp512bp";
146
			break;
147
	}
148

    
149
	return $conversion;
150
}
151

    
152
function vpn_ipsec_configure($restart = false) {
153
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos, $ipsec_idhandling;
154

    
155
	/* get the automatic ping_hosts.sh ready */
156
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
157
	touch("{$g['vardb_path']}/ipsecpinghosts");
158
	$ipsecpinghostsactive = false;
159

    
160
	/* service may have been enabled, disabled, or otherwise changed in a way requiring rule updates */
161
	filter_configure();
162

    
163
	$syscfg = $config['system'];
164
	$ipseccfg = $config['ipsec'];
165
	if (!ipsec_enabled()) {
166
		/* try to stop charon */
167
		mwexec("/usr/local/sbin/ipsec stop");
168
		/* Stop dynamic monitoring */
169
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
170

    
171
		/* wait for process to die */
172
		sleep(2);
173

    
174
		/* IPSEC is off, shutdown enc interface.*/
175
		mwexec("/sbin/ifconfig enc0 down");
176

    
177
		return 0;
178
	}
179

    
180
	$a_phase1 = $config['ipsec']['phase1'];
181
	$a_phase2 = $config['ipsec']['phase2'];
182
	$a_client = $config['ipsec']['client'];
183

    
184
	$certpath = "{$g['varetc_path']}/ipsec/ipsec.d/certs";
185
	$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts";
186
	$keypath = "{$g['varetc_path']}/ipsec/ipsec.d/private";
187
	$crlpath = "{$g['varetc_path']}/ipsec/ipsec.d/crls";
188

    
189
	mwexec("/sbin/ifconfig enc0 up");
190
	if (php_uname('m') != "amd64") {
191
		set_single_sysctl("net.inet.ipsec.directdispatch", "0");
192
	}
193

    
194
	/* needed for config files */
195
	if (!is_dir("{$g['varetc_path']}/ipsec")) {
196
		mkdir("{$g['varetc_path']}/ipsec");
197
	}
198
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d")) {
199
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d");
200
	}
201
	// delete these paths first to ensure old CAs, certs and CRLs aren't left behind. redmine #5238
202
	rmdir_recursive($capath);
203
	rmdir_recursive($keypath);
204
	rmdir_recursive($crlpath);
205
	rmdir_recursive($certpath);
206
	if (!is_dir($capath)) {
207
		mkdir($capath);
208
	}
209
	if (!is_dir($keypath)) {
210
		mkdir($keypath);
211
	}
212
	if (!is_dir($crlpath)) {
213
		mkdir($crlpath);
214
	}
215
	if (!is_dir($certpath)) {
216
		mkdir($certpath);
217
	}
218
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts")) {
219
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts");
220
	}
221
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/acerts")) {
222
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/acerts");
223
	}
224
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts")) {
225
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts");
226
	}
227
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/reqs")) {
228
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/reqs");
229
	}
230

    
231
	if (!file_exists("/usr/local/etc/ipsec.d") ||
232
	    !is_link("/usr/local/etc/ipsec.d")) {
233
		conf_mount_rw();
234
		if (file_exists("/usr/local/etc/ipsec.d")) {
235
			rmdir_recursive("/usr/local/etc/ipsec.d");
236
		}
237
		@symlink("{$g['varetc_path']}/ipsec/ipsec.d",
238
		    "/usr/local/etc/ipsec.d");
239
		conf_mount_ro();
240
	}
241
	if (!file_exists("{$g['varetc_path']}/etc/strongswan.d") ||
242
	    !is_link("{$g['varetc_path']}/etc/strongswan.d")) {
243
		conf_mount_rw();
244
		if (is_link("{$g['varetc_path']}/etc/strongswan.d")) {
245
			@unlink("{$g['varetc_path']}/etc/strongswan.d");
246
		} else {
247
			rmdir_recursive("{$g['varetc_path']}/etc/strongswan.d");
248
		}
249
		@symlink("/usr/local/etc/strongswan.d",
250
		    "{$g['varetc_path']}/ipsec/strongswan.d");
251
		conf_mount_ro();
252
	}
253
	if (!file_exists("/usr/local/etc/strongswan.conf") ||
254
	    !is_link("/usr/local/etc/strongswan.conf")) {
255
		conf_mount_rw();
256
		@unlink("/usr/local/etc/strongswan.conf");
257
		@symlink("{$g['varetc_path']}/ipsec/strongswan.conf",
258
		    "/usr/local/etc/strongswan.conf");
259
		conf_mount_ro();
260
	}
261
	if (!file_exists("/usr/local/etc/ipsec.conf") ||
262
	    !is_link("/usr/local/etc/ipsec.conf")) {
263
		conf_mount_rw();
264
		@unlink("/usr/local/etc/ipsec.conf");
265
		@symlink("{$g['varetc_path']}/ipsec/ipsec.conf",
266
		    "/usr/local/etc/ipsec.conf");
267
		conf_mount_ro();
268
	}
269

    
270
	if (platform_booting()) {
271
		echo gettext("Configuring IPsec VPN... ");
272
	}
273

    
274
	/* resolve all local, peer addresses and setup pings */
275
	$ipmap = array();
276
	$rgmap = array();
277
	$filterdns_list = array();
278
	$aggressive_mode_psk = false;
279
	unset($iflist);
280
	$ifacesuse = array();
281
	$mobile_ipsec_auth = "";
282
	if (is_array($a_phase1) && count($a_phase1)) {
283

    
284
		$ipsecpinghosts = "";
285
		/* step through each phase1 entry */
286
		foreach ($a_phase1 as $ph1ent) {
287
			if (isset($ph1ent['disabled'])) {
288
				continue;
289
			}
290

    
291
			if (substr($ph1ent['interface'], 0, 4) == "_vip") {
292
				$vpninterface = get_configured_vip_interface($ph1ent['interface']);
293
				$ifacesuse[] = get_real_interface($vpninterface);
294
			} else {
295
				$vpninterface = get_failover_interface($ph1ent['interface']);
296
				if (substr($vpninterface, 0, 4) == "_vip") {
297
					$vpninterface = get_configured_vip_interface($vpninterface);
298
					$ifacesuse[] = get_real_interface($vpninterface);
299
				} elseif (!empty($vpninterface)) {
300
					$ifacesuse[] = $vpninterface;
301
				}
302
			}
303

    
304
			if ($ph1ent['mode'] == "aggressive" && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
305
				$aggressive_mode_psk = true;
306
			}
307

    
308
			$ikeid = $ph1ent['ikeid'];
309

    
310
			$ep = ipsec_get_phase1_src($ph1ent);
311
			if (!is_ipaddr($ep)) {
312
				log_error(sprintf(gettext("IPsec ERROR: Could not find phase 1 source for connection %s. Omitting from configuration file."), $ph1ent['descr']));
313
				continue;
314
			}
315

    
316
			if (!in_array($ep, $ipmap)) {
317
				$ipmap[] = $ep;
318
			}
319

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

    
323
			if (isset ($ph1ent['mobile'])) {
324
				$mobile_ipsec_auth = $ph1ent['authentication_method'];
325
				continue;
326
			}
327

    
328
			$rg = $ph1ent['remote-gateway'];
329

    
330
			if (!is_ipaddr($rg)) {
331
				$filterdns_list[] = "{$rg}";
332
				add_hostname_to_watch($rg);
333
				if (!platform_booting()) {
334
					$rg = resolve_retry($rg);
335
				}
336
				if (!is_ipaddr($rg)) {
337
					continue;
338
				}
339
			}
340
			if (array_search($rg, $rgmap)) {
341
				log_error(sprintf(gettext("The remote gateway %s already exists on another phase 1 entry"), $rg));
342
				continue;
343
			}
344
			$rgmap[$ph1ent['remote-gateway']] = $rg;
345

    
346
			if (is_array($a_phase2)) {
347
				/* step through each phase2 entry */
348
				foreach ($a_phase2 as $ph2ent) {
349
					if (isset($ph2ent['disabled'])) {
350
						continue;
351
					}
352

    
353
					if ($ikeid != $ph2ent['ikeid']) {
354
						continue;
355
					}
356

    
357
					/* add an ipsec pinghosts entry */
358
					if ($ph2ent['pinghost']) {
359
						if (!is_array($iflist)) {
360
							$iflist = get_configured_interface_list();
361
						}
362
						$srcip = null;
363
						$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
364
						if (is_ipaddrv6($ph2ent['pinghost'])) {
365
							foreach ($iflist as $ifent => $ifname) {
366
								$interface_ip = get_interface_ipv6($ifent);
367
								if (!is_ipaddrv6($interface_ip)) {
368
									continue;
369
								}
370
								if (ip_in_subnet($interface_ip, $local_subnet)) {
371
									$srcip = $interface_ip;
372
									break;
373
								}
374
							}
375
						} else {
376
							foreach ($iflist as $ifent => $ifname) {
377
								$interface_ip = get_interface_ip($ifent);
378
								if (!is_ipaddrv4($interface_ip)) {
379
									continue;
380
								}
381
								if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) {
382
									$srcip = $interface_ip;
383
									break;
384
								}
385
							}
386
						}
387
						/* if no valid src IP was found in configured interfaces, try the vips */
388
						if (is_null($srcip)) {
389
							$viplist = get_configured_vip_list();
390
							foreach ($viplist as $vip => $address) {
391
								if (ip_in_subnet($address, $local_subnet)) {
392
									$srcip = $address;
393
									break;
394
								}
395
							}
396
						}
397
						$dstip = $ph2ent['pinghost'];
398
						if (is_ipaddrv6($dstip)) {
399
							$family = "inet6";
400
						} else {
401
							$family = "inet";
402
						}
403
						if (is_ipaddr($srcip)) {
404
							$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
405
							$ipsecpinghostsactive = true;
406
						}
407
					}
408
				}
409
			}
410
		}
411
		@file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
412
		unset($ipsecpinghosts);
413
	}
414
	unset($iflist);
415

    
416
	$accept_unencrypted = "";
417
	if (isset($config['ipsec']['acceptunencryptedmainmode'])) {
418
		$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
419
	}
420

    
421
	$stronconf = '';
422
	if (file_exists("{$g['varetc_path']}/ipsec/strongswan.conf")) {
423
		$stronconf = file_get_contents("{$g['varetc_path']}/ipsec/strongswan.conf");
424
	}
425

    
426
	$i_dont_care_about_security_and_use_aggressive_mode_psk = "";
427
	if ($aggressive_mode_psk) {
428
		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.");
429
		if (!empty($stronconf) && strpos($stronconf, 'i_dont_care_about_security_and_use_aggressive_mode_psk') === FALSE) {
430
			$restart = true;
431
		}
432
		$i_dont_care_about_security_and_use_aggressive_mode_psk = "i_dont_care_about_security_and_use_aggressive_mode_psk=yes";
433
	}
434

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

    
437
	$makebeforebreak = '';
438
	if (isset($config['ipsec']['makebeforebreak'])) {
439
		$makebeforebreak = 'make_before_break = yes';
440
	}
441

    
442
	if (isset($config['ipsec']['enableinterfacesuse'])) {
443
		if (!empty($ifacesuse)) {
444
			$ifacesuse = 'interfaces_use = ' . implode(',', array_unique($ifacesuse));
445
		} else {
446
			$ifacesuse = '';
447
		}
448
	} else {
449
		$ifacesuse = '';
450
	}
451

    
452
	unset($stronconf);
453

    
454
	$strongswanlog = "";
455
	$ipsecloglevels = vpn_logging_cfgtxt();
456
	if (is_array($ipsecloglevels)) {
457
		foreach ($ipsecloglevels as $loglevel) {
458
			$strongswanlog .= "\t\t\t" . $loglevel . "\n";
459
		}
460
	}
461
	$strongswan = <<<EOD
462

    
463
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten.
464
starter {
465
	load_warning = no
466
	config_file = {$g['varetc_path']}/ipsec/ipsec.conf
467
}
468

    
469
charon {
470
# number of worker threads in charon
471
	threads = 16
472
	ikesa_table_size = 32
473
	ikesa_table_segments = 4
474
	init_limit_half_open = 1000
475
	install_routes = no
476
	load_modular = yes
477
	{$i_dont_care_about_security_and_use_aggressive_mode_psk}
478
	{$accept_unencrypted}
479
	cisco_unity = {$unity_enabled}
480
	{$ifacesuse}
481
	{$makebeforebreak}
482

    
483
	syslog {
484
		identifier = charon
485
		# log everything under daemon since it ends up in the same place regardless with our syslog.conf
486
		daemon {
487
			ike_name = yes
488
{$strongswanlog}
489
		}
490
		# disable logging under auth so logs aren't duplicated
491
		auth {
492
			default = -1
493
		}
494
	}
495

    
496
	plugins {
497
		# Load defaults
498
		include {$g['varetc_path']}/ipsec/strongswan.d/charon/*.conf
499

    
500
		stroke {
501
			secrets_file = {$g['varetc_path']}/ipsec/ipsec.secrets
502
		}
503

    
504
		unity {
505
			load = {$unity_enabled}
506
		}
507

    
508
EOD;
509

    
510
	/* Find RADIUS servers designated for Mobile IPsec user auth */
511
	$radius_server_txt = "";
512
	$user_sources = explode(',', $config['ipsec']['client']['user_source']);
513
	foreach ($user_sources as $user_source) {
514
		$auth_server = auth_get_authserver($user_source);
515
		$nice_user_source = strtolower(preg_replace('/\s+/', '_', $user_source));
516
		if ($auth_server && $auth_server['type'] === 'radius') {
517
			$radius_server_txt .= <<<EOD
518
				{$nice_user_source} {
519
					address = {$auth_server['host']}
520
					secret = "{$auth_server['radius_secret']}"
521
					auth_port = {$auth_server['radius_auth_port']}
522
					acct_port = {$auth_server['radius_acct_port']}
523
				}
524

    
525
EOD;
526
		}
527
	}
528

    
529
	/* write an eap-radius config section if appropriate */
530
	if (strlen($radius_server_txt) && ($mobile_ipsec_auth === "eap-radius")) {
531
		$strongswan .= <<<EOD
532
		eap-radius {
533
			class_group = yes
534
			eap_start = no
535
			servers {
536
{$radius_server_txt}
537
			}
538
		}
539

    
540
EOD;
541
	}
542

    
543
	if (is_array($a_client) && isset($a_client['enable'])) {
544
		$strongswan .= "\t\tattr {\n";
545

    
546
		$cfgservers = array();
547
		if (!empty($a_client['dns_server1'])) {
548
			$cfgservers[] = $a_client['dns_server1'];
549
		}
550
		if (!empty($a_client['dns_server2'])) {
551
			$cfgservers[] = $a_client['dns_server2'];
552
		}
553
		if (!empty($a_client['dns_server3'])) {
554
			$cfgservers[] = $a_client['dns_server3'];
555
		}
556
		if (!empty($a_client['dns_server4'])) {
557
			$cfgservers[] = $a_client['dns_server4'];
558
		}
559

    
560
		if (!empty($cfgservers)) {
561
			$strongswan .= "\t\t\tdns = " . implode(",", $cfgservers) . "\n";
562
		}
563
		unset($cfgservers);
564
		$cfgservers = array();
565
		if (!empty($a_client['wins_server1'])) {
566
			$cfgservers[] = $a_client['wins_server1'];
567
		}
568
		if (!empty($a_client['wins_server2'])) {
569
			$cfgservers[] = $a_client['wins_server2'];
570
		}
571
		if (!empty($cfgservers)) {
572
			$strongswan .= "\t\t\tnbns = " . implode(",", $cfgservers) . "\n";
573
		}
574
		unset($cfgservers);
575

    
576
		if (isset($a_client['net_list']) && is_array($a_phase2)) {
577
			$net_list = '';
578
			foreach ($a_phase2 as $ph2ent) {
579
				if (isset($ph2ent['disabled'])) {
580
					continue;
581
				}
582

    
583
				if (!isset($ph2ent['mobile'])) {
584
					continue;
585
				}
586

    
587
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
588

    
589
				if (!empty($net_list)) {
590
					$net_list .= ",";
591
				}
592
				$net_list .= $localid;
593
			}
594

    
595
			if (!empty($net_list)) {
596
				$strongswan .= "\t\t\tsubnet = {$net_list}\n";
597
				$strongswan .= "\t\t\tsplit-include = {$net_list}\n";
598
				unset($net_list);
599
			}
600
		}
601

    
602
		if (!empty($a_client['dns_domain'])) {
603
			$strongswan .= "\t\t\t# Search domain and default domain\n";
604
			$strongswan .= "\t\t\t28674 = \"{$a_client['dns_domain']}\"\n";
605
			if (empty($a_client['dns_split'])) {
606
				$strongswan .= "\t\t\t28675 = \"{$a_client['dns_domain']}\"";
607
			}
608
			$strongswan .= "\n";
609
		}
610

    
611
		if (!empty($a_client['dns_split'])) {
612
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
613
		}
614

    
615
		if (!empty($a_client['login_banner'])) {
616
			$strongswan .= "\t\t\t28672 = \"{$a_client['login_banner']}\"\n";
617
		}
618

    
619
		if (isset($a_client['save_passwd'])) {
620
			$strongswan .= "\t\t\t28673 = 1\n";
621
		}
622

    
623
		if ($a_client['pfs_group']) {
624
			$strongswan .= "\t\t\t28679 = \"{$a_client['pfs_group']}\"\n";
625
		}
626
		$strongswan .= "\t\t}\n";
627

    
628
		if ($a_client['user_source'] != "none") {
629
			$strongswan .= "\t\txauth-generic {\n";
630
			$strongswan .= "\t\t\tscript = /etc/inc/ipsec.auth-user.php\n";
631
			$strongswan .= "\t\t\tauthcfg = ";
632
			$firstsed = 0;
633
			$authcfgs = explode(",", $a_client['user_source']);
634
			foreach ($authcfgs as $authcfg) {
635
				if ($firstsed > 0) {
636
					$strongswan .= ",";
637
				}
638
				if ($authcfg == "system") {
639
					$authcfg = "Local Database";
640
				}
641
				$strongswan .= $authcfg;
642
				$firstsed = 1;
643
			}
644
			$strongswan .= "\n";
645
			$strongswan .= "\t\t}\n";
646
		}
647
	}
648

    
649
	$strongswan .= "\n\t}\n}\n";
650
	@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
651
	unset($strongswan);
652

    
653
	/* write out CRL files */
654
	if (is_array($config['crl']) && count($config['crl'])) {
655
		foreach ($config['crl'] as $crl) {
656
			if (!isset($crl['text'])) {
657
				log_error(sprintf(gettext("Warning: Missing CRL data for %s"), $crl['descr']));
658
				continue;
659
			}
660
			$fpath = "{$crlpath}/{$crl['refid']}.crl";
661
			if (!@file_put_contents($fpath, base64_decode($crl['text']))) {
662
				log_error(sprintf(gettext("Error: Cannot write IPsec CRL file for %s"), $crl['descr']));
663
				continue;
664
			}
665
		}
666
	}
667

    
668
	$pskconf = "";
669

    
670
	$vpncas = array();
671
	if (is_array($a_phase1) && count($a_phase1)) {
672
		foreach ($a_phase1 as $ph1ent) {
673

    
674
			if (isset($ph1ent['disabled'])) {
675
				continue;
676
			}
677

    
678
			if (strstr($ph1ent['authentication_method'], 'rsa') ||
679
			    in_array($ph1ent['authentication_method'], array('eap-mschapv2', 'eap-tls', 'eap-radius'))) {
680
				$certline = '';
681

    
682
				$ikeid = $ph1ent['ikeid'];
683
				$cert = lookup_cert($ph1ent['certref']);
684

    
685
				if (!$cert) {
686
					log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
687
					continue;
688
				}
689

    
690
				/* add signing CA cert chain of server cert
691
				 * to the list of CAs to write
692
				 */
693
				$cachain = ca_chain_array($cert);
694
				if ($cachain && is_array($cachain)) {
695
					foreach ($cachain as $cacrt) {
696
						$vpncas[$cacrt['refid']] = $cacrt;
697
					}
698
				}
699

    
700
				@chmod($certpath, 0600);
701

    
702
				$ph1keyfile = "{$keypath}/cert-{$ikeid}.key";
703
				if (!file_put_contents($ph1keyfile, base64_decode($cert['prv']))) {
704
					log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
705
					continue;
706
				}
707
				@chmod($ph1keyfile, 0600);
708

    
709
				$ph1certfile = "{$certpath}/cert-{$ikeid}.crt";
710
				if (!file_put_contents($ph1certfile, base64_decode($cert['crt']))) {
711
					log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name']));
712
					@unlink($ph1keyfile);
713
					continue;
714
				}
715
				@chmod($ph1certfile, 0600);
716

    
717
				/* XXX" Traffic selectors? */
718
				$pskconf .= " : RSA {$ph1keyfile}\n";
719
			} else {
720
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
721
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
722

    
723
				$myid = trim($myid_data);
724

    
725
				if (empty($peerid_data)) {
726
					continue;
727
				}
728

    
729
				if ($myid_type == 'fqdn' && !empty($myid)) {
730
					$myid = "@{$myid}";
731
				}
732

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

    
735
				$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
736

    
737
				if ($peerid_type == 'fqdn' && !empty($peerid)) {
738
					$peerid = "@{$peerid}";
739
				}
740

    
741
				if (!empty($ph1ent['pre-shared-key'])) {
742
					$pskconf .= "{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
743
					if (isset($ph1ent['mobile'])) {
744
						$pskconf .= " : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
745
					}
746
				}
747
			}
748

    
749
			/* if the client authenticates with a cert add the
750
			 * client cert CA chain to the list of CAs to write
751
			 */
752
			if (in_array($ph1ent['authentication_method'],
753
			array('rsasig', 'eap-tls', 'xauth_rsa_server'))) {
754

    
755
				if (!empty($ph1ent['caref']) && !array_key_exists($ph1ent['caref'], $vpncas)) {
756
					$thisca = lookup_ca($ph1ent['caref']);
757
					$vpncas[$ph1ent['caref']] = $thisca;
758

    
759
					/* follow chain up to root */
760
					$cachain = ca_chain_array($thisca);
761
					if ($cachain and is_array($cachain)) {
762
						foreach ($cachain as $cacrt) {
763
							$vpncas[$cacrt['refid']] = $cacrt;
764
						}
765
					}
766
				}
767
			}
768
		}
769
	}
770

    
771
	/* write the required CAs */
772
	foreach ($vpncas as $carefid => $cadata) {
773
		$cacrt = base64_decode($cadata['crt']);
774
		$cacrtattrs = openssl_x509_parse($cacrt);
775
		if (!is_array($cacrtattrs) || !isset($cacrtattrs['hash'])) {
776
			log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $cadata['descr']));
777
			continue;
778
		}
779
		$cafilename = "{$capath}/{$cacrtattrs['hash']}.0.crt";
780
		if (!@file_put_contents($cafilename, $cacrt)) {
781
				log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $cadata['descr']));
782
				continue;
783
		}
784
	}
785

    
786
	/* Add user PSKs */
787
	if (is_array($config['system']) && is_array($config['system']['user'])) {
788
		foreach ($config['system']['user'] as $user) {
789
			if (!empty($user['ipsecpsk'])) {
790
				$pskconf .= "{$myid} {$user['name']} : PSK 0s" . base64_encode($user['ipsecpsk']) . "\n";
791
			}
792
		}
793
		unset($user);
794
	}
795

    
796
	/* add PSKs for mobile clients */
797
	if (is_array($ipseccfg['mobilekey'])) {
798
		foreach ($ipseccfg['mobilekey'] as $key) {
799
			if ($key['ident'] == "allusers") {
800
				$key['ident'] = '%any';
801
			}
802
			if ($key['ident'] == "any") {
803
				$key['ident'] = '%any';
804
			}
805
			if (empty($key['type'])) {
806
				$key['type'] = 'PSK';
807
			}
808
			$pskconf .= "{$myid} {$key['ident']} : {$key['type']} 0s" . base64_encode($key['pre-shared-key']) . "\n";
809
		}
810
		unset($key);
811
	}
812

    
813
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
814
	chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
815
	unset($pskconf);
816

    
817
	$uniqueids = 'yes';
818
	if (!empty($config['ipsec']['uniqueids'])) {
819
		if (array_key_exists($config['ipsec']['uniqueids'], $ipsec_idhandling)) {
820
			$uniqueids = $config['ipsec']['uniqueids'];
821
		}
822
	}
823
	$natfilterrules = false;
824
	/* begin ipsec.conf */
825
	$ipsecconf = "";
826
	$enablecompression = false;
827
	if (is_array($a_phase1) && count($a_phase1)) {
828

    
829
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
830
		$ipsecconf .= "config setup\n\tuniqueids = {$uniqueids}\n";
831

    
832
		if (isset($config['ipsec']['strictcrlpolicy'])) {
833
			$ipsecconf .= "\tstrictcrlpolicy = yes \n";
834
		}
835

    
836
		if (!isset($config['ipsec']['noshuntlaninterfaces'])) {
837
			if ($config['interfaces']['lan']) {
838
				$lanip = get_interface_ip("lan");
839
				if (!empty($lanip) && is_ipaddrv4($lanip)) {
840
					$lansn = get_interface_subnet("lan");
841
					$lansa = gen_subnet($lanip, $lansn);
842
					$ipsecconf .= <<<EOD
843

    
844
conn bypasslan
845
	leftsubnet = {$lansa}/{$lansn}
846
	rightsubnet = {$lansa}/{$lansn}
847
	authby = never
848
	type = passthrough
849
	auto = route
850

    
851
EOD;
852
				}
853
			}
854
		}
855

    
856
		foreach ($a_phase1 as $ph1ent) {
857
			if (isset($ph1ent['disabled'])) {
858
				continue;
859
			}
860

    
861
			if ($ph1ent['mode'] == "aggressive") {
862
				$aggressive = "yes";
863
			} else {
864
				$aggressive = "no";
865
			}
866

    
867
			$ep = ipsec_get_phase1_src($ph1ent);
868
			if (!$ep) {
869
				continue;
870
			}
871

    
872
			$ikeid = $ph1ent['ikeid'];
873
			$keyexchange = "ikev1";
874
			$passive = "route";
875
			if (!empty($ph1ent['iketype'])) {
876
				if ($ph1ent['iketype'] == "ikev2") {
877
					$keyexchange = "ikev2";
878
				} elseif ($ph1ent['iketype'] == "auto") {
879
					$keyexchange = "ike";
880
				}
881
			}
882

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

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

    
898
				if ($ph1ent['protocol'] == 'inet') {
899
					if (substr($ph1ent['interface'], 0, 4) == "_vip") {
900
						$vpninterface = get_configured_vip_interface($ph1ent['interface']);
901
						$ifacesuse = get_real_interface($vpninterface);
902
					} else {
903
						$ifacesuse = get_failover_interface($ph1ent['interface']);
904
						if (substr($ifacesuse, 0, 4) == "_vip") {
905
							$vpninterface = get_configured_vip_interface($ifacesuse);
906
							$ifacesuse = get_real_interface($vpninterface);
907
						} else {
908
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
909
						}
910
					}
911

    
912
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
913
						$gatewayip = get_interface_gateway($vpninterface);
914
						$interfaceip = get_interface_ip($vpninterface);
915
						$subnet_bits = get_interface_subnet($vpninterface);
916
						$subnet_ip = gen_subnetv4($interfaceip, $subnet_bits);
917
						/* if the remote gateway is in the local subnet, then don't add a route */
918
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
919
							if (is_ipaddrv4($gatewayip)) {
920
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
921
								mwexec("/sbin/route change -host {$sourcehost} {$gatewayip}", true);
922
							}
923
						}
924
					}
925
				} else if ($ph1ent['protocol'] == 'inet6') {
926
					if (substr($ph1ent['interface'], 0, 4) == "_vip") {
927
						$vpninterface = get_configured_vip_interface($ph1ent['interface']);
928
						$ifacesuse = get_real_interface($vpninterface);
929
					} else {
930
						$ifacesuse = get_failover_interface($ph1ent['interface']);
931
						if (substr($ifacesuse, 0, 4) == "_vip") {
932
							$vpninterface = get_configured_vip_interface($ifacesuse);
933
							$ifacesuse = get_real_interface($vpninterface);
934
						} else {
935
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
936
						}
937
					}
938

    
939
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
940
						$gatewayip = get_interface_gateway_v6($vpninterface);
941
						$interfaceip = get_interface_ipv6($vpninterface);
942
						$subnet_bits = get_interface_subnetv6($vpninterface);
943
						$subnet_ip = gen_subnetv6($interfaceip, $subnet_bits);
944
						/* if the remote gateway is in the local subnet, then don't add a route */
945
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
946
							if (is_ipaddrv6($gatewayip)) {
947
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
948
								mwexec("/sbin/route change -inet6 -host {$sourcehost} {$gatewayip}", true);
949
							}
950
						}
951
					}
952
				}
953
			}
954

    
955
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
956
			if ($myid_type != 'address' && $myid_type != 'keyid' && $myid_type != 'asn1dn') {
957
				$myid_data = "{$myid_type}:{$myid_data}";
958
			} elseif ($myid_type == "asn1dn" && !empty($myid_data)) {
959
				if ($myid_data[0] == '#') {
960
				/* asn1dn needs double quotes */
961
					$myid_data = "\"{$myid_type}:{$myid_data}\"";
962
				} else {
963
					$myid_data = "\"{$myid_data}\"";
964
				}
965
			}
966
			$leftid = '';
967
			if (!empty($myid_data)) {
968
				$leftid = "leftid = {$myid_data}";
969
			}
970

    
971
			$peerid_spec = '';
972
			if (isset($ph1ent['mobile']) && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
973
				// Only specify peer ID if we are not dealing with mobile PSK
974
			} else {
975
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
976
				if ($peerid_type == 'any') {
977
					$peerid_spec = '';
978
				} elseif ($peerid_type != 'address' && $peerid_type != 'keyid' && $peerid_type != 'asn1dn') {
979
					$peerid_spec = "{$peerid_type}:{$peerid_data}";
980
				} elseif ($peerid_type == "asn1dn") {
981
					/* asn1dn needs double quotes */
982
					if ($peerid_data[0] == '#') {
983
						$peerid_spec = "\"{$peerid_type}:{$peerid_data}\"";
984
					} elseif (!empty($peerid_data)) {
985
						$peerid_spec = "\"{$peerid_data}\"";
986
					}
987
				} else {
988
					$peerid_spec = $peerid_data;
989
				}
990
			}
991

    
992
			if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
993
				$ealgosp1 = '';
994
				$ealg_id = $ph1ent['encryption-algorithm']['name'];
995
				$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
996
				if ($ealg_kl) {
997
					$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
998
				} else {
999
					$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
1000
				}
1001

    
1002
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
1003
				if (!empty($modp)) {
1004
					$ealgosp1 .= "-{$modp}";
1005
				}
1006

    
1007
				$ealgosp1 .= "!";
1008
			}
1009

    
1010
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
1011
				if ($passive == "route") {
1012
					$dpdline = "dpdaction = restart";
1013
				} else {
1014
					$dpdline = "dpdaction = clear";
1015
				}
1016
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
1017
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
1018
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
1019
			} else {
1020
				$dpdline = "dpdaction = none";
1021
			}
1022

    
1023
			$ikelifeline = '';
1024
			if ($ph1ent['lifetime']) {
1025
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
1026
			}
1027

    
1028
			$rightsourceip = NULL;
1029
			if (isset($ph1ent['mobile'])) {
1030
				$rightsourceips = array();
1031
				if (!empty($a_client['pool_address'])) {
1032
					$rightsourceips[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1033
				}
1034
				if (!empty($a_client['pool_address_v6'])) {
1035
					$rightsourceips[] = "{$a_client['pool_address_v6']}/{$a_client['pool_netbits_v6']}";
1036
				}
1037
				if ($ph1ent['authentication_method'] == "eap-radius" && !count($rightsourceips)) {
1038
					$rightsourceips[] = "%radius";
1039
				}
1040
				if (count($rightsourceips)) {
1041
					$rightsourceip = "\trightsourceip = " . implode(',', $rightsourceips) . "\n";
1042
				}
1043
			}
1044

    
1045
			if (!empty($ph1ent['caref'])) {
1046
				$ca = lookup_ca($ph1ent['caref']);
1047
				if ($ca) {
1048
					$casubarr = cert_get_subject_array($ca['crt']);
1049
					$casub = "";
1050
					foreach ($casubarr as $casubfield) {
1051
						if (empty($casub)) {
1052
							$casub = "/";
1053
						}
1054
						$casub .= "{$casubfield['a']}={$casubfield['v']}/";
1055
					}
1056

    
1057
				}
1058
			}
1059

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

    
1141
			$left_spec = $ep;
1142

    
1143
			if (isset($ph1ent['reauth_enable'])) {
1144
				$reauth = "reauth = no";
1145
			} else {
1146
				$reauth = "reauth = yes";
1147
			}
1148
			if (isset($ph1ent['rekey_enable'])) {
1149
				$rekey = "rekey = no";
1150
			} else {
1151
				$rekey = "rekey = yes";
1152
			}
1153

    
1154
			if ($ph1ent['nat_traversal'] == 'off') {
1155
				$forceencaps = 'forceencaps = no';
1156
			} else if ($ph1ent['nat_traversal'] == 'force') {
1157
				$forceencaps = 'forceencaps = yes';
1158
			} else {
1159
				$forceencaps = 'forceencaps = no';
1160
			}
1161

    
1162
			if ($ph1ent['mobike'] == 'on') {
1163
				$mobike = 'mobike = yes';
1164
			} else {
1165
				$mobike = 'mobike = no';
1166
			}
1167

    
1168
			if (isset($ph1ent['tfc_enable'])) {
1169
				if (isset($ph1ent['tfc_bytes']) && is_numericint($ph1ent['tfc_bytes'])) {
1170
					$tfc = "tfc = {$ph1ent['tfc_bytes']}";
1171
				} else {
1172
					$tfc = "tfc = %mtu";
1173
				}
1174
			}
1175

    
1176
			$ipseclifetime = 0;
1177
			$rightsubnet_spec = array();
1178
			$leftsubnet_spec = array();
1179
			$reqids = array();
1180
			$ealgoAHsp2arr = array();
1181
			$ealgoESPsp2arr = array();
1182
		if (is_array($a_phase2) && count($a_phase2)) {
1183
			foreach ($a_phase2 as $ph2ent) {
1184
				if ($ikeid != $ph2ent['ikeid']) {
1185
					continue;
1186
				}
1187

    
1188
				if (isset($ph2ent['disabled'])) {
1189
					continue;
1190
				}
1191

    
1192
				if (isset($ph2ent['mobile']) && !isset($a_client['enable'])) {
1193
					continue;
1194
				}
1195

    
1196
				if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
1197
					$tunneltype = "type = tunnel";
1198

    
1199
					$localid_type = $ph2ent['localid']['type'];
1200
					$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
1201

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

    
1230
					$leftsubnet_spec[] = $leftsubnet_data;
1231

    
1232
					if (!isset($ph2ent['mobile'])) {
1233
						$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
1234
						$rightsubnet_spec[] = $tmpsubnet;
1235
					} else if (!empty($a_client['pool_address'])) {
1236
						$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1237
					}
1238
				} else {
1239
					$tunneltype = "type = transport";
1240

    
1241
					if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
1242
					     ($ph1ent['authentication_method'] == "pre_shared_key")) &&
1243
					    isset($ph1ent['mobile'])) {
1244
						$left_spec = "%any";
1245
					} else {
1246
						$tmpsubnet = ipsec_get_phase1_src($ph1ent);
1247
						$leftsubnet_spec[] = $tmpsubnet;
1248
					}
1249

    
1250
					if (!isset($ph2ent['mobile'])) {
1251
						$rightsubnet_spec[] = $right_spec;
1252
					}
1253
				}
1254

    
1255
				if (isset($a_client['pfs_group']) && isset($ph2ent['mobile'])) {
1256
					$ph2ent['pfsgroup'] = $a_client['pfs_group'];
1257
				}
1258

    
1259
				if ($ph2ent['protocol'] == 'esp') {
1260
					if (is_array($ph2ent['encryption-algorithm-option'])) {
1261
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
1262
							$ealg_id = $ealg['name'];
1263
							$ealg_kl = $ealg['keylen'];
1264

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

    
1332
				$reqids[] = $ph2ent['reqid'];
1333

    
1334
				if (!empty($ph2ent['lifetime'])) {
1335
					if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) {
1336
						$ipseclifetime = intval($ph2ent['lifetime']);
1337
					}
1338
				}
1339

    
1340
			}
1341
		}
1342

    
1343
			$ipsecconnect =<<<EOD
1344
	fragmentation = yes
1345
	keyexchange = {$keyexchange}
1346
	{$reauth}
1347
	{$forceencaps}
1348
	{$mobike}
1349
	{$tfc}
1350
	{$rekey}
1351
	installpolicy = yes
1352
	{$tunneltype}
1353
	{$dpdline}
1354
	auto = {$passive}
1355
	left = {$left_spec}
1356
	right = {$right_spec}
1357
	{$leftid}
1358

    
1359
EOD;
1360

    
1361
			if (isset($config['ipsec']['compression'])) {
1362
				$ipsecconnect .= "\tcompress = yes\n";
1363
				$enablecompression = true;
1364
			}
1365
			if (!empty($ikelifeline)) {
1366
				$ipsecconnect .= "\t{$ikelifeline}\n";
1367
			}
1368
			if ($ipseclifetime > 0) {
1369
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
1370
			}
1371
			if (!empty($rightsourceip)) {
1372
				$ipsecconnect .= "{$rightsourceip}";
1373
			}
1374
			if (!empty($ealgosp1)) {
1375
				$ipsecconnect .= "\t{$ealgosp1}\n";
1376
			}
1377
			if (!empty($ealgoAHsp2arr)) {
1378
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
1379
			}
1380
			if (!empty($ealgoESPsp2arr)) {
1381
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
1382
			}
1383
			if (!empty($authentication)) {
1384
				$ipsecconnect .= "\t{$authentication}\n";
1385
			}
1386
			if (!empty($peerid_spec)) {
1387
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
1388
			}
1389
			if ($keyexchange == 'ikev1') {
1390
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
1391
			}
1392

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

    
1436
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1437
	unset($ipsecconf);
1438
	/* end ipsec.conf */
1439

    
1440
	if ($enablecompression === true) {
1441
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1442
	} else {
1443
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1444
	}
1445

    
1446
	/* manage process */
1447
	if ($restart === true) {
1448
		mwexec("/usr/local/sbin/ipsec restart", false);
1449
	} else {
1450
		if (isvalidpid("{$g['varrun_path']}/starter.charon.pid")) {
1451
			/* Update configuration changes */
1452
			/* Read secrets */
1453
			mwexec("/usr/local/sbin/ipsec rereadall", false);
1454
			mwexec("/usr/local/sbin/ipsec reload", false);
1455
		} else {
1456
			mwexec("/usr/local/sbin/ipsec start", false);
1457
		}
1458
	}
1459

    
1460
	// run ping_hosts.sh once if it's enabled to avoid wait for minicron
1461
	if ($ipsecpinghostsactive == true) {
1462
		mwexec_bg("/usr/local/bin/ping_hosts.sh");
1463
	}
1464

    
1465
	if ($natfilterrules == true) {
1466
		filter_configure();
1467
	}
1468
	/* start filterdns, if necessary */
1469
	if (count($filterdns_list) > 0) {
1470
		$interval = 60;
1471
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) {
1472
			$interval = $ipseccfg['dns-interval'];
1473
		}
1474

    
1475
		$hostnames = "";
1476
		array_unique($filterdns_list);
1477
		foreach ($filterdns_list as $hostname) {
1478
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1479
		}
1480
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1481
		unset($hostnames);
1482

    
1483
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid")) {
1484
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1485
		} else {
1486
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1487
		}
1488
	} else {
1489
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1490
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1491
	}
1492

    
1493
	if (platform_booting()) {
1494
		echo "done\n";
1495
	}
1496

    
1497
	return count($filterdns_list);
1498
}
1499

    
1500
/*
1501
 * Forcefully restart IPsec
1502
 * This is required for when dynamic interfaces reload
1503
 * For all other occasions the normal vpn_ipsec_configure()
1504
 * will gracefully reload the settings without restarting
1505
 */
1506
function vpn_ipsec_force_reload($interface = "") {
1507
	global $g, $config;
1508

    
1509
	if (!ipsec_enabled()) {
1510
		return;
1511
	}
1512

    
1513
	$ipseccfg = $config['ipsec'];
1514

    
1515
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1516
		$found = false;
1517
		foreach ($ipseccfg['phase1'] as $ipsec) {
1518
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1519
				$found = true;
1520
				break;
1521
			}
1522
		}
1523
		if (!$found) {
1524
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1525
			return;
1526
		}
1527
	}
1528

    
1529
	/* If we get this far then we need to take action. */
1530
	log_error(gettext("Forcefully reloading IPsec"));
1531
	vpn_ipsec_configure();
1532
}
1533

    
1534
/* master setup for vpn (mpd) */
1535
function vpn_setup() {
1536
	/* start pppoe server */
1537
	vpn_pppoes_configure();
1538

    
1539
	/* setup l2tp */
1540
	vpn_l2tp_configure();
1541
}
1542

    
1543
function vpn_netgraph_support() {
1544
	$iflist = get_configured_interface_list();
1545
	foreach ($iflist as $iface) {
1546
		$realif = get_real_interface($iface);
1547
		/* Get support for netgraph(4) from the nic */
1548
		$ifinfo = pfSense_get_interface_addresses($realif);
1549
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) {
1550
			pfSense_ngctl_attach(".", $realif);
1551
		}
1552
	}
1553
}
1554

    
1555
function vpn_pppoes_configure() {
1556
	global $config;
1557

    
1558
	if (is_array($config['pppoes']['pppoe'])) {
1559
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
1560
			vpn_pppoe_configure($pppoe);
1561
		}
1562
	}
1563
}
1564

    
1565
function vpn_pppoe_configure(&$pppoecfg) {
1566
	global $config, $g;
1567

    
1568
	$syscfg = $config['system'];
1569

    
1570
	/* create directory if it does not exist */
1571
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
1572
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1573
	}
1574

    
1575
	if (platform_booting()) {
1576
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
1577
			return 0;
1578
		}
1579

    
1580
		echo gettext("Configuring PPPoE Server service... ");
1581
	} else {
1582
		/* kill mpd */
1583
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1584

    
1585
		/* wait for process to die */
1586
		sleep(2);
1587

    
1588
	}
1589

    
1590
	switch ($pppoecfg['mode']) {
1591

    
1592
		case 'server':
1593

    
1594
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1595

    
1596
			if ($pppoecfg['paporchap'] == "chap") {
1597
				$paporchap = "set link enable chap";
1598
			} else {
1599
				$paporchap = "set link enable pap";
1600
			}
1601

    
1602
			/* write mpd.conf */
1603
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1604
			if (!$fd) {
1605
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1606
				return 1;
1607
			}
1608
			$mpdconf = "\n\n";
1609
			$mpdconf .= "poes:\n";
1610

    
1611
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1612
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1613
			}
1614

    
1615
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1616

    
1617
				$clientip = ip_after($pppoecfg['remoteip'], $i);
1618

    
1619
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1620
					$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1621
				} else {
1622
					$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1623
				}
1624

    
1625
				$mpdconf .=<<<EOD
1626

    
1627
poes{$pppoecfg['pppoeid']}{$i}:
1628
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1629
	{$issue_ip_type}
1630
	load pppoe_standard
1631

    
1632
EOD;
1633
			}
1634
			if (is_numeric($pppoecfg['n_pppoe_maxlogin']) && ($pppoecfg['n_pppoe_maxlogin'] > 0)) {
1635
				$pppoemaxlogins = $pppoecfg['n_pppoe_maxlogin'];
1636
			} else {
1637
				$pppoemaxlogins = 1;
1638
			}
1639

    
1640
			$mpdconf .=<<<EOD
1641

    
1642
pppoe_standard:
1643
	set bundle no multilink
1644
	set bundle enable compression
1645
	set auth max-logins {$pppoemaxlogins}
1646
	set iface up-script /usr/local/sbin/vpn-linkup
1647
	set iface down-script /usr/local/sbin/vpn-linkdown
1648
	set iface idle 0
1649
	set iface disable on-demand
1650
	set iface disable proxy-arp
1651
	set iface enable tcpmssfix
1652
	set iface mtu 1500
1653
	set link no pap chap
1654
	{$paporchap}
1655
	set link keep-alive 60 180
1656
	set ipcp yes vjcomp
1657
	set ipcp no vjcomp
1658
	set link max-redial -1
1659
	set link mtu 1492
1660
	set link mru 1492
1661
	set ccp yes mpp-e40
1662
	set ccp yes mpp-e128
1663
	set ccp yes mpp-stateless
1664
	set link latency 1
1665
	#set ipcp dns 10.10.1.3
1666
	#set bundle accept encryption
1667

    
1668
EOD;
1669

    
1670
			if (!empty($pppoecfg['dns1'])) {
1671
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1672
				if (!empty($pppoecfg['dns2'])) {
1673
					$mpdconf .= " " . $pppoecfg['dns2'];
1674
				}
1675
				$mpdconf .= "\n";
1676
			} elseif (isset ($config['dnsmasq']['enable'])) {
1677
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1678
				if ($syscfg['dnsserver'][0]) {
1679
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1680
				}
1681
				$mpdconf .= "\n";
1682
			} elseif (isset ($config['unbound']['enable'])) {
1683
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1684
				if ($syscfg['dnsserver'][0]) {
1685
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1686
				}
1687
				$mpdconf .= "\n";
1688
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1689
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1690
			}
1691

    
1692
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1693
				$radiusport = "";
1694
				$radiusacctport = "";
1695
				if (isset($pppoecfg['radius']['server']['port'])) {
1696
					$radiusport = $pppoecfg['radius']['server']['port'];
1697
				}
1698
				if (isset($pppoecfg['radius']['server']['acctport'])) {
1699
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1700
				}
1701
				$mpdconf .=<<<EOD
1702
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1703
	set radius retries 3
1704
	set radius timeout 10
1705
	set auth enable radius-auth
1706

    
1707
EOD;
1708

    
1709
				if (isset ($pppoecfg['radius']['accounting'])) {
1710
					$mpdconf .=<<<EOD
1711
	set auth enable radius-acct
1712

    
1713
EOD;
1714
				}
1715
				if (isset($pppoecfg['radius']['nasip'])) {
1716
					$mpdconf .= "\tset radius me {$pppoecfg['radius']['nasip']}\n";
1717
				}
1718
			}
1719

    
1720
			fwrite($fd, $mpdconf);
1721
			fclose($fd);
1722
			unset($mpdconf);
1723

    
1724
			/* write mpd.links */
1725
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1726
			if (!$fd) {
1727
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1728
				return 1;
1729
			}
1730

    
1731
			$mpdlinks = "";
1732

    
1733
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1734
				$mpdlinks .=<<<EOD
1735

    
1736
poes{$pppoecfg['pppoeid']}{$i}:
1737
	set phys type pppoe
1738
	set pppoe iface {$pppoe_interface}
1739
	set pppoe service "*"
1740
	set pppoe disable originate
1741
	set pppoe enable incoming
1742

    
1743
EOD;
1744
			}
1745

    
1746
			fwrite($fd, $mpdlinks);
1747
			fclose($fd);
1748
			unset($mpdlinks);
1749

    
1750
			if ($pppoecfg['username']) {
1751
				/* write mpd.secret */
1752
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1753
				if (!$fd) {
1754
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1755
					return 1;
1756
				}
1757

    
1758
				$mpdsecret = "\n\n";
1759

    
1760
				if (!empty($pppoecfg['username'])) {
1761
					$item = explode(" ", $pppoecfg['username']);
1762
					foreach ($item as $userdata) {
1763
						$data = explode(":", $userdata);
1764
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1765
					}
1766
				}
1767

    
1768
				fwrite($fd, $mpdsecret);
1769
				fclose($fd);
1770
				unset($mpdsecret);
1771
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1772
			}
1773

    
1774
			/* Check if previous instance is still up */
1775
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
1776
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1777
			}
1778

    
1779
			/* Get support for netgraph(4) from the nic */
1780
			pfSense_ngctl_attach(".", $pppoe_interface);
1781
			/* fire up mpd */
1782
			mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn -p {$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid -s poes poes");
1783

    
1784
			break;
1785
	}
1786

    
1787
	if (platform_booting()) {
1788
		echo gettext("done") . "\n";
1789
	}
1790

    
1791
	return 0;
1792
}
1793

    
1794
function vpn_l2tp_configure() {
1795
	global $config, $g;
1796

    
1797
	$syscfg = $config['system'];
1798
	$l2tpcfg = $config['l2tp'];
1799

    
1800
	/* create directory if it does not exist */
1801
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
1802
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1803
	}
1804

    
1805
	if (platform_booting()) {
1806
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
1807
			return 0;
1808
		}
1809

    
1810
		echo gettext("Configuring l2tp VPN service... ");
1811
	} else {
1812
		/* kill mpd */
1813
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1814

    
1815
		/* wait for process to die */
1816
		sleep(8);
1817

    
1818
	}
1819

    
1820
	/* make sure l2tp-vpn directory exists */
1821
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
1822
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1823
	}
1824

    
1825
	switch ($l2tpcfg['mode']) {
1826

    
1827
		case 'server':
1828
			$l2tp_listen="";
1829
			$ipaddr = get_interface_ip(get_failover_interface($l2tpcfg['interface']));
1830
			if (is_ipaddrv4($ipaddr)) {
1831
				$l2tp_listen="set l2tp self $ipaddr";
1832
			}
1833

    
1834
			switch ($l2tpcfg['paporchap']) {
1835
				case 'chap':
1836
					$paporchap = "set link enable chap";
1837
					break;
1838
				case 'chap-msv2':
1839
					$paporchap = "set link enable chap-msv2";
1840
					break;
1841
				default:
1842
					$paporchap = "set link enable pap";
1843
					break;
1844
			}
1845

    
1846
			/* write mpd.conf */
1847
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1848
			if (!$fd) {
1849
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1850
				return 1;
1851
			}
1852
			$mpdconf = "\n\n";
1853
			$mpdconf .=<<<EOD
1854
l2tps:
1855

    
1856
EOD;
1857

    
1858
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1859
				$mpdconf .= "	load l2tp{$i}\n";
1860
			}
1861

    
1862
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1863

    
1864
				$clientip = ip_after($l2tpcfg['remoteip'], $i);
1865

    
1866
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1867
					$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1868
				} else {
1869
					$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1870
				}
1871

    
1872
				$mpdconf .=<<<EOD
1873

    
1874
l2tp{$i}:
1875
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1876
	{$issue_ip_type}
1877
	load l2tp_standard
1878

    
1879
EOD;
1880
			}
1881

    
1882
			$mpdconf .=<<<EOD
1883

    
1884
l2tp_standard:
1885
	set bundle disable multilink
1886
	set bundle enable compression
1887
	set bundle yes crypt-reqd
1888
	set ipcp yes vjcomp
1889
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1890
	set ccp yes mppc
1891
	set iface disable on-demand
1892
	set iface enable proxy-arp
1893
	set iface up-script /usr/local/sbin/vpn-linkup
1894
	set iface down-script /usr/local/sbin/vpn-linkdown
1895
	set link yes acfcomp protocomp
1896
	set link no pap chap
1897
	{$paporchap}
1898
	{$l2tp_listen}
1899
	set link keep-alive 10 180
1900

    
1901
EOD;
1902

    
1903
			if (is_ipaddr($l2tpcfg['wins'])) {
1904
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1905
			}
1906
			if (is_ipaddr($l2tpcfg['dns1'])) {
1907
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1908
				if (is_ipaddr($l2tpcfg['dns2'])) {
1909
					$mpdconf .= " " . $l2tpcfg['dns2'];
1910
				}
1911
				$mpdconf .= "\n";
1912
			} elseif (isset ($config['dnsmasq']['enable'])) {
1913
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1914
				if ($syscfg['dnsserver'][0]) {
1915
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1916
				}
1917
				$mpdconf .= "\n";
1918
			} elseif (isset ($config['unbound']['enable'])) {
1919
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1920
				if ($syscfg['dnsserver'][0]) {
1921
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1922
				}
1923
				$mpdconf .= "\n";
1924
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1925
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1926
			}
1927

    
1928
			if (isset ($l2tpcfg['radius']['enable'])) {
1929
				$mpdconf .=<<<EOD
1930
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1931
	set radius retries 3
1932
	set radius timeout 10
1933
	set auth enable radius-auth
1934

    
1935
EOD;
1936

    
1937
				if (isset ($l2tpcfg['radius']['accounting'])) {
1938
					$mpdconf .=<<<EOD
1939
	set auth enable radius-acct
1940

    
1941
EOD;
1942
				}
1943
			}
1944

    
1945
			fwrite($fd, $mpdconf);
1946
			fclose($fd);
1947
			unset($mpdconf);
1948

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

    
1956
			$mpdlinks = "";
1957

    
1958
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1959
				$mpdlinks .=<<<EOD
1960

    
1961
l2tp{$i}:
1962
	set link type l2tp
1963
	set l2tp enable incoming
1964
	set l2tp disable originate
1965

    
1966
EOD;
1967
				if (!empty($l2tpcfg['secret'])) {
1968
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1969
				}
1970
			}
1971

    
1972
			fwrite($fd, $mpdlinks);
1973
			fclose($fd);
1974
			unset($mpdlinks);
1975

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

    
1983
			$mpdsecret = "\n\n";
1984

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

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

    
1996
			vpn_netgraph_support();
1997

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

    
2001
			break;
2002

    
2003
		case 'redir':
2004
			break;
2005
	}
2006

    
2007
	if (platform_booting()) {
2008
		echo "done\n";
2009
	}
2010

    
2011
	return 0;
2012
}
2013

    
2014
?>
(57-57/65)