Project

General

Profile

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

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

    
149
	return $convertion;
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
	$listeniflist = array();
279
	$aggressive_mode_psk = false;
280
	unset($iflist);
281
	$ifacesuse = array();
282
	$mobile_ipsec_auth = "";
283
	if (is_array($a_phase1) && count($a_phase1)) {
284

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

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

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

    
309
			$ikeid = $ph1ent['ikeid'];
310
			$listeniflist = get_real_interface($a_phase1['interface']);
311

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

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

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

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

    
330
			$rg = $ph1ent['remote-gateway'];
331

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

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

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

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

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

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

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

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

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

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

    
454
	unset($stronconf);
455

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

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

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

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

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

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

    
506
		unity {
507
			load = {$unity_enabled}
508
		}
509

    
510
EOD;
511

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

    
527
EOD;
528
		}
529
	}
530

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

    
542
EOD;
543
	}
544

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

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

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

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

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

    
589
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
590

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

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

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

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

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

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

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

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

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

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

    
670
	$pskconf = "";
671

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

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

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

    
684
				$ikeid = $ph1ent['ikeid'];
685
				$cert = lookup_cert($ph1ent['certref']);
686

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

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

    
702
				@chmod($certpath, 0600);
703

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

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

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

    
725
				$myid = trim($myid_data);
726

    
727
				if (empty($peerid_data)) {
728
					continue;
729
				}
730

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

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

    
737
				$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
738

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
853
EOD;
854
				}
855
			}
856
		}
857

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

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

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

    
874
			$ikeid = $ph1ent['ikeid'];
875
			$keyexchange = "ikev1";
876
			$passive = "route";
877
			if (!empty($ph1ent['iketype'])) {
878
				if ($ph1ent['iketype'] == "ikev2") {
879
					$keyexchange = "ikev2";
880
					//$passive = "start";
881
				}
882
			}
883

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

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

    
899
				if ($ph1ent['protocol'] == 'inet') {
900
					if (strpos($ph1ent['interface'], '_vip')) {
901
						$vpninterface = explode('_vip', $ph1ent['interface']);
902
						$ifacesuse = get_real_interface($vpninterface[0]);
903
						$vpninterface = $vpninterface[0];
904
					} else {
905
						$ifacesuse = get_failover_interface($ph1ent['interface']);
906
						if (strpos($ifacesuse, '_vip')) {
907
							$vpninterface = explode('_vip', $ifacesuse);
908
							$ifacesuse = get_real_interface($vpninterface[0]);
909
							$vpninterface = $vpninterface[0];
910
						} else {
911
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
912
						}
913
					}
914

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

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

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

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

    
997
			if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
998
				$ealgosp1 = '';
999
				$ealg_id = $ph1ent['encryption-algorithm']['name'];
1000
				$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
1001
				if ($ealg_kl) {
1002
					$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
1003
				} else {
1004
					$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
1005
				}
1006

    
1007
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
1008
				if (!empty($modp)) {
1009
					$ealgosp1 .= "-{$modp}";
1010
				}
1011

    
1012
				$ealgosp1 .= "!";
1013
			}
1014

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

    
1028
			$ikelifeline = '';
1029
			if ($ph1ent['lifetime']) {
1030
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
1031
			}
1032

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

    
1050
			if (!empty($ph1ent['caref'])) {
1051
				$ca = lookup_ca($ph1ent['caref']);
1052
				if ($ca) {
1053
					$casubarr = cert_get_subject_array($ca['crt']);
1054
					$casub = "";
1055
					foreach ($casubarr as $casubfield) {
1056
						if (empty($casub)) {
1057
							$casub = "/";
1058
						}
1059
						$casub .= "{$casubfield['a']}={$casubfield['v']}/";
1060
					}
1061

    
1062
				}
1063
			}
1064

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

    
1146
			$left_spec = $ep;
1147

    
1148
			if (isset($ph1ent['reauth_enable'])) {
1149
				$reauth = "reauth = no";
1150
			} else {
1151
				$reauth = "reauth = yes";
1152
			}
1153
			if (isset($ph1ent['rekey_enable'])) {
1154
				$rekey = "rekey = no";
1155
			} else {
1156
				$rekey = "rekey = yes";
1157
			}
1158

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

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

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

    
1185
				if (isset($ph2ent['disabled'])) {
1186
					continue;
1187
				}
1188

    
1189
				if (isset($ph2ent['mobile']) && !isset($a_client['enable'])) {
1190
					continue;
1191
				}
1192

    
1193
				if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
1194
					$tunneltype = "type = tunnel";
1195

    
1196
					$localid_type = $ph2ent['localid']['type'];
1197
					$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
1198

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

    
1227
					$leftsubnet_spec[] = $leftsubnet_data;
1228

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

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

    
1247
					if (!isset($ph2ent['mobile'])) {
1248
						$rightsubnet_spec[] = $right_spec;
1249
					}
1250
				}
1251

    
1252
				if (isset($a_client['pfs_group']) && isset($ph2ent['mobile'])) {
1253
					$ph2ent['pfsgroup'] = $a_client['pfs_group'];
1254
				}
1255

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

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

    
1329
				$reqids[] = $ph2ent['reqid'];
1330

    
1331
				if (!empty($ph2ent['lifetime'])) {
1332
					if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) {
1333
						$ipseclifetime = intval($ph2ent['lifetime']);
1334
					}
1335
				}
1336

    
1337
			}
1338
		}
1339

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

    
1355
EOD;
1356

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

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

    
1432
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1433
	unset($ipsecconf);
1434
	/* end ipsec.conf */
1435

    
1436
	if ($enablecompression === true) {
1437
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1438
	} else {
1439
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1440
	}
1441

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

    
1456
	// run ping_hosts.sh once if it's enabled to avoid wait for minicron
1457
	if ($ipsecpinghostsactive == true) {
1458
		mwexec_bg("/usr/local/bin/ping_hosts.sh");
1459
	}
1460

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

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

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

    
1489
	if (platform_booting()) {
1490
		echo "done\n";
1491
	}
1492

    
1493
	return count($filterdns_list);
1494
}
1495

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

    
1505
	if (!ipsec_enabled()) {
1506
		return;
1507
	}
1508

    
1509
	$ipseccfg = $config['ipsec'];
1510

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

    
1525
	/* If we get this far then we need to take action. */
1526
	log_error(gettext("Forcefully reloading IPsec"));
1527
	vpn_ipsec_configure();
1528
}
1529

    
1530
/* master setup for vpn (mpd) */
1531
function vpn_setup() {
1532
	/* start pppoe server */
1533
	vpn_pppoes_configure();
1534

    
1535
	/* setup l2tp */
1536
	vpn_l2tp_configure();
1537
}
1538

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

    
1551
function vpn_pppoes_configure() {
1552
	global $config;
1553

    
1554
	if (is_array($config['pppoes']['pppoe'])) {
1555
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
1556
			vpn_pppoe_configure($pppoe);
1557
		}
1558
	}
1559
}
1560

    
1561
function vpn_pppoe_configure(&$pppoecfg) {
1562
	global $config, $g;
1563

    
1564
	$syscfg = $config['system'];
1565

    
1566
	/* create directory if it does not exist */
1567
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
1568
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1569
	}
1570

    
1571
	if (platform_booting()) {
1572
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
1573
			return 0;
1574
		}
1575

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

    
1581
		/* wait for process to die */
1582
		sleep(2);
1583

    
1584
	}
1585

    
1586
	switch ($pppoecfg['mode']) {
1587

    
1588
		case 'server':
1589

    
1590
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1591

    
1592
			if ($pppoecfg['paporchap'] == "chap") {
1593
				$paporchap = "set link enable chap";
1594
			} else {
1595
				$paporchap = "set link enable pap";
1596
			}
1597

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

    
1607
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1608
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1609
			}
1610

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

    
1613
				$clientip = ip_after($pppoecfg['remoteip'], $i);
1614

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

    
1621
				$mpdconf .=<<<EOD
1622

    
1623
poes{$pppoecfg['pppoeid']}{$i}:
1624
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1625
	{$issue_ip_type}
1626
	load pppoe_standard
1627

    
1628
EOD;
1629
			}
1630
			if (is_numeric($pppoecfg['n_pppoe_maxlogin']) && ($pppoecfg['n_pppoe_maxlogin'] > 0)) {
1631
				$pppoemaxlogins = $pppoecfg['n_pppoe_maxlogin'];
1632
			} else {
1633
				$pppoemaxlogins = 1;
1634
			}
1635

    
1636
			$mpdconf .=<<<EOD
1637

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

    
1664
EOD;
1665

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

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

    
1703
EOD;
1704

    
1705
				if (isset ($pppoecfg['radius']['accounting'])) {
1706
					$mpdconf .=<<<EOD
1707
	set auth enable radius-acct
1708

    
1709
EOD;
1710
				}
1711
			}
1712

    
1713
			fwrite($fd, $mpdconf);
1714
			fclose($fd);
1715
			unset($mpdconf);
1716

    
1717
			/* write mpd.links */
1718
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1719
			if (!$fd) {
1720
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1721
				return 1;
1722
			}
1723

    
1724
			$mpdlinks = "";
1725

    
1726
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1727
				$mpdlinks .=<<<EOD
1728

    
1729
poes{$pppoecfg['pppoeid']}{$i}:
1730
	set phys type pppoe
1731
	set pppoe iface {$pppoe_interface}
1732
	set pppoe service "*"
1733
	set pppoe disable originate
1734
	set pppoe enable incoming
1735

    
1736
EOD;
1737
			}
1738

    
1739
			fwrite($fd, $mpdlinks);
1740
			fclose($fd);
1741
			unset($mpdlinks);
1742

    
1743
			if ($pppoecfg['username']) {
1744
				/* write mpd.secret */
1745
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1746
				if (!$fd) {
1747
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1748
					return 1;
1749
				}
1750

    
1751
				$mpdsecret = "\n\n";
1752

    
1753
				if (!empty($pppoecfg['username'])) {
1754
					$item = explode(" ", $pppoecfg['username']);
1755
					foreach ($item as $userdata) {
1756
						$data = explode(":", $userdata);
1757
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1758
					}
1759
				}
1760

    
1761
				fwrite($fd, $mpdsecret);
1762
				fclose($fd);
1763
				unset($mpdsecret);
1764
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1765
			}
1766

    
1767
			/* Check if previous instance is still up */
1768
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
1769
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1770
			}
1771

    
1772
			/* Get support for netgraph(4) from the nic */
1773
			pfSense_ngctl_attach(".", $pppoe_interface);
1774
			/* fire up mpd */
1775
			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");
1776

    
1777
			break;
1778
	}
1779

    
1780
	if (platform_booting()) {
1781
		echo gettext("done") . "\n";
1782
	}
1783

    
1784
	return 0;
1785
}
1786

    
1787
function vpn_l2tp_configure() {
1788
	global $config, $g;
1789

    
1790
	$syscfg = $config['system'];
1791
	$l2tpcfg = $config['l2tp'];
1792

    
1793
	/* create directory if it does not exist */
1794
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
1795
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1796
	}
1797

    
1798
	if (platform_booting()) {
1799
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
1800
			return 0;
1801
		}
1802

    
1803
		echo gettext("Configuring l2tp VPN service... ");
1804
	} else {
1805
		/* kill mpd */
1806
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1807

    
1808
		/* wait for process to die */
1809
		sleep(8);
1810

    
1811
	}
1812

    
1813
	/* make sure l2tp-vpn directory exists */
1814
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
1815
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1816
	}
1817

    
1818
	switch ($l2tpcfg['mode']) {
1819

    
1820
		case 'server':
1821
			$l2tp_listen="";
1822
			$ipaddr = get_interface_ip(get_failover_interface($l2tpcfg['interface']));
1823
			if (is_ipaddrv4($ipaddr)) {
1824
				$l2tp_listen="set l2tp self $ipaddr";
1825
			}
1826

    
1827
			switch ($l2tpcfg['paporchap']) {
1828
				case 'chap':
1829
					$paporchap = "set link enable chap";
1830
					break;
1831
				case 'chap-msv2':
1832
					$paporchap = "set link enable chap-msv2";
1833
					break;
1834
				default:
1835
					$paporchap = "set link enable pap";
1836
					break;
1837
			}
1838

    
1839
			/* write mpd.conf */
1840
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1841
			if (!$fd) {
1842
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1843
				return 1;
1844
			}
1845
			$mpdconf = "\n\n";
1846
			$mpdconf .=<<<EOD
1847
l2tps:
1848

    
1849
EOD;
1850

    
1851
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1852
				$mpdconf .= "	load l2tp{$i}\n";
1853
			}
1854

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

    
1857
				$clientip = ip_after($l2tpcfg['remoteip'], $i);
1858

    
1859
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1860
					$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1861
				} else {
1862
					$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1863
				}
1864

    
1865
				$mpdconf .=<<<EOD
1866

    
1867
l2tp{$i}:
1868
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1869
	{$issue_ip_type}
1870
	load l2tp_standard
1871

    
1872
EOD;
1873
			}
1874

    
1875
			$mpdconf .=<<<EOD
1876

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

    
1894
EOD;
1895

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

    
1921
			if (isset ($l2tpcfg['radius']['enable'])) {
1922
				$mpdconf .=<<<EOD
1923
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1924
	set radius retries 3
1925
	set radius timeout 10
1926
	set auth enable radius-auth
1927

    
1928
EOD;
1929

    
1930
				if (isset ($l2tpcfg['radius']['accounting'])) {
1931
					$mpdconf .=<<<EOD
1932
	set auth enable radius-acct
1933

    
1934
EOD;
1935
				}
1936
			}
1937

    
1938
			fwrite($fd, $mpdconf);
1939
			fclose($fd);
1940
			unset($mpdconf);
1941

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

    
1949
			$mpdlinks = "";
1950

    
1951
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1952
				$mpdlinks .=<<<EOD
1953

    
1954
l2tp{$i}:
1955
	set link type l2tp
1956
	set l2tp enable incoming
1957
	set l2tp disable originate
1958

    
1959
EOD;
1960
				if (!empty($l2tpcfg['secret'])) {
1961
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1962
				}
1963
			}
1964

    
1965
			fwrite($fd, $mpdlinks);
1966
			fclose($fd);
1967
			unset($mpdlinks);
1968

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

    
1976
			$mpdsecret = "\n\n";
1977

    
1978
			if (is_array($l2tpcfg['user'])) {
1979
				foreach ($l2tpcfg['user'] as $user) {
1980
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1981
				}
1982
			}
1983

    
1984
			fwrite($fd, $mpdsecret);
1985
			fclose($fd);
1986
			unset($mpdsecret);
1987
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1988

    
1989
			vpn_netgraph_support();
1990

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

    
1994
			break;
1995

    
1996
		case 'redir':
1997
			break;
1998
	}
1999

    
2000
	if (platform_booting()) {
2001
		echo "done\n";
2002
	}
2003

    
2004
	return 0;
2005
}
2006

    
2007
?>
(57-57/65)