Project

General

Profile

Download (54.2 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2

    
3
/*
4
	vpn.inc
5
	Copyright (C) 2004 Scott Ullrich
6
	Copyright (C) 2008 Shrew Soft Inc
7
	Copyright (C) 2008 Ermal Lu�i
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 the
22
	   documentation and/or other materials provided with the distribution.
23

    
24
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
25
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
26
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
28
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33
	POSSIBILITY OF SUCH DAMAGE.
34
*/
35

    
36
/*
37
	pfSense_BUILDER_BINARIES:	/sbin/ifconfig
38
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/ipsec	/usr/local/libexec/ipsec/charon /usr/local/libexec/ipsec/starter
39
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/filterdns	/usr/local/sbin/mpd4
40
	pfSense_MODULE:	vpn
41
*/
42

    
43
require_once("ipsec.inc");
44

    
45
function vpn_ipsec_configure_loglevels($forconfig = false)
46
{
47
	global $config, $ipsec_loglevels;
48

    
49
	$cfgtext = array();
50
	foreach ($ipsec_loglevels as $lkey => $ldescr) {
51
		if (!isset($config['ipsec']["ipsec_{$lkey}"]) && !$forconfig) {
52
			mwexec("/usr/local/sbin/ipsec stroke loglevel {$lkey} -- -1", false);
53
		} else if (is_numeric($config['ipsec']["ipsec_{$lkey}"]) &&
54
		    intval($config['ipsec']["ipsec_{$lkey}"]) >= 0 && intval($config['ipsec']["ipsec_{$lkey}"]) <= 5) {
55
			$forconfig ? $cfgtext[] = "${lkey} " . (intval($config['ipsec']["ipsec_{$lkey}"]) - 1) :
56
				mwexec("/usr/local/sbin/ipsec stroke loglevel {$lkey} " . (intval($config['ipsec']["ipsec_{$lkey}"]) - 1) , false);
57
		}
58
	}
59
	if ($forconfig) {
60
		return implode(',', $cfgtext);
61
	}
62
}
63

    
64
/* include all configuration functions */
65
function vpn_ipsec_convert_to_modp($index)
66
{
67

    
68
	$convertion = "";
69
	switch ($index) {
70
		case '1':
71
			$convertion = "modp768";
72
			break;
73
		case '2':
74
			$convertion = "modp1024";
75
			break;
76
		case '5':
77
			$convertion = "modp1536";
78
			break;
79
		case '14':
80
			$convertion = "modp2048";
81
			break;
82
		case '15':
83
			$convertion = "modp3072";
84
			break;
85
		case '16':
86
			$convertion = "modp4096";
87
			break;
88
		case '17':
89
			$convertion = "modp6144";
90
			break;
91
		case '18':
92
			$convertion = "modp8192";
93
			break;
94
	}
95

    
96
	return $convertion;
97
}
98

    
99
function vpn_ipsec_configure($restart = false)
100
{
101
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos;
102

    
103
	if ($g['platform'] == 'jail') {
104
		return;
105
	}
106

    
107
	/* get the automatic ping_hosts.sh ready */
108
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
109
	touch("{$g['vardb_path']}/ipsecpinghosts");
110

    
111
	$syscfg = $config['system'];
112
	$ipseccfg = $config['ipsec'];
113
	if (!isset($ipseccfg['enable'])) {
114
		/* try to stop charon */
115
		mwexec("/usr/local/sbin/ipsec stop");
116
		/* Stop dynamic monitoring */
117
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
118

    
119
		/* wait for process to die */
120
		sleep(2);
121

    
122
		/* disallow IPSEC, it is off */
123
		mwexec("/sbin/ifconfig enc0 down");
124
		set_single_sysctl("net.inet.ip.ipsec_in_use", "0");
125

    
126
		filter_configure();
127

    
128
		return 0;
129
	}
130

    
131
	$a_phase1 = $config['ipsec']['phase1'];
132
	$a_phase2 = $config['ipsec']['phase2'];
133
	$a_client = $config['ipsec']['client'];
134

    
135
	$certpath = "{$g['varetc_path']}/ipsec/ipsec.d/certs";
136
	$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts";
137
	$keypath = "{$g['varetc_path']}/ipsec/ipsec.d/private";
138

    
139
	mwexec("/sbin/ifconfig enc0 up");
140
	set_single_sysctl("net.inet.ip.ipsec_in_use", "1");
141
	/* needed for config files */
142
	if (!is_dir("{$g['varetc_path']}/ipsec")) {
143
		mkdir("{$g['varetc_path']}/ipsec");
144
	}
145
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d")) {
146
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d");
147
	}
148
	if (!is_dir($capath)) {
149
		mkdir($capath);
150
	}
151
	if (!is_dir($keypath)) {
152
		mkdir($keypath);
153
	}
154
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/crls")) {
155
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/crls");
156
	}
157
	if (!is_dir($certpath)) {
158
		mkdir($certpath);
159
	}
160
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts")) {
161
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts");
162
	}
163
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/acerts")) {
164
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/acerts");
165
	}
166
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts")) {
167
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts");
168
	}
169
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/reqs")) {
170
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/reqs");
171
	}
172

    
173

    
174
	if (platform_booting()) {
175
		echo gettext("Configuring IPsec VPN... ");
176
	}
177

    
178
	/* fastforwarding is not compatible with ipsec tunnels */
179
	set_single_sysctl("net.inet.ip.fastforwarding", "0");
180

    
181
	/* resolve all local, peer addresses and setup pings */
182
	$ipmap = array();
183
	$rgmap = array();
184
	$filterdns_list = array();
185
	$listeniflist = array();
186
	$aggressive_mode_psk = false;
187
	unset($iflist);
188
	$ifacesuse = array();
189
	if (is_array($a_phase1) && count($a_phase1)) {
190

    
191
		$ipsecpinghosts = "";
192
		/* step through each phase1 entry */
193
		foreach ($a_phase1 as $ph1ent) {
194
			if (isset($ph1ent['disabled'])) {
195
				continue;
196
			}
197

    
198
			if (strpos($ph1ent['interface'], '_vip')) {
199
				$vpninterface = explode('_vip', $ph1ent['interface']);
200
				$ifacesuse[] = get_real_interface($vpninterface[0]);
201
			} else {
202
				$vpninterface = get_failover_interface($ph1ent['interface']);
203
				if (strpos($vpninterface, '_vip')) {
204
					$vpninterface = explode('_vip', $vpninterface);
205
					$ifacesuse[] = get_real_interface($vpninterface[0]);
206
				} elseif (!empty($vpninterface)) {
207
					$ifacesuse[] = $vpninterface;
208
				}
209
			}
210

    
211
			if ($ph1ent['mode'] == "aggressive" && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
212
				$aggressive_mode_psk = true;
213
			}
214

    
215
			$ikeid = $ph1ent['ikeid'];
216
			$listeniflist = get_real_interface($a_phase1['interface']);
217

    
218
			$ep = ipsec_get_phase1_src($ph1ent);
219
			if (!is_ipaddr($ep)) {
220
				continue;
221
			}
222

    
223
			if (!in_array($ep,$ipmap)) {
224
				$ipmap[] = $ep;
225
			}
226

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

    
230
			if (isset ($ph1ent['mobile'])) {
231
				continue;
232
			}
233

    
234
			$rg = $ph1ent['remote-gateway'];
235

    
236
			if (!is_ipaddr($rg)) {
237
				$filterdns_list[] = "{$rg}";
238
				add_hostname_to_watch($rg);
239
				if (!platform_booting()) {
240
					$rg = resolve_retry($rg);
241
				}
242
				if (!is_ipaddr($rg)) {
243
					continue;
244
				}
245
			}
246
			if (array_search($rg, $rgmap)) {
247
				log_error("The remote gateway {$rg} already exists on another phase 1 entry");
248
				continue;
249
			}
250
			$rgmap[$ph1ent['remote-gateway']] = $rg;
251

    
252
			if (is_array($a_phase2)) {
253
				/* step through each phase2 entry */
254
				foreach ($a_phase2 as $ph2ent) {
255
					if (isset($ph2ent['disabled'])) {
256
						continue;
257
					}
258

    
259
					if ($ikeid != $ph2ent['ikeid']) {
260
						continue;
261
					}
262

    
263
					/* add an ipsec pinghosts entry */
264
					if ($ph2ent['pinghost']) {
265
						if (!is_array($iflist)) {
266
							$iflist = get_configured_interface_list();
267
						}
268
						$srcip = null;
269
						$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
270
						if (is_ipaddrv6($ph2ent['pinghost'])) {
271
							foreach ($iflist as $ifent => $ifname) {
272
								$interface_ip = get_interface_ipv6($ifent);
273
								if (!is_ipaddrv6($interface_ip)) {
274
									continue;
275
								}
276
								if (ip_in_subnet($interface_ip, $local_subnet)) {
277
									$srcip = $interface_ip;
278
									break;
279
								}
280
							}
281
						} else {
282
							foreach ($iflist as $ifent => $ifname) {
283
								$interface_ip = get_interface_ip($ifent);
284
								if (!is_ipaddrv4($interface_ip)) {
285
									continue;
286
								}
287
								if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) {
288
									$srcip = $interface_ip;
289
									break;
290
								}
291
							}
292
						}
293
						/* if no valid src IP was found in configured interfaces, try the vips */
294
						if (is_null($srcip)) {
295
							$viplist = get_configured_vips_list();
296
							foreach ($viplist as $vip) {
297
								if (ip_in_subnet($vip['ipaddr'], $local_subnet)) {
298
									$srcip = $vip['ipaddr'];
299
									break;
300
								}
301
							}
302
						}
303
						$dstip = $ph2ent['pinghost'];
304
						if (is_ipaddrv6($dstip)) {
305
							$family = "inet6";
306
						} else {
307
							$family = "inet";
308
						}
309
						if (is_ipaddr($srcip)) {
310
							$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
311
						}
312
					}
313
				}
314
			}
315
		}
316
		@file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
317
		unset($ipsecpinghosts);
318
	}
319
	unset($iflist);
320

    
321
	$accept_unencrypted = "";
322
	if (isset($config['ipsec']['acceptunencryptedmainmode'])) {
323
		$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
324
	}
325

    
326
	$stronconf = '';
327
	if (file_exists("{$g['varetc_path']}/ipsec/strongswan.conf")) {
328
		$stronconf = file_get_contents("{$g['varetc_path']}/ipsec/strongswan.conf");
329
	}
330

    
331
	$i_dont_care_about_security_and_use_aggressive_mode_psk = "";
332
	if ($aggressive_mode_psk) {
333
		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.");
334
		if (!empty($stronconf) && strpos($stronconf, 'i_dont_care_about_security_and_use_aggressive_mode_psk') === FALSE) {
335
			$restart = true;
336
		}
337
		$i_dont_care_about_security_and_use_aggressive_mode_psk = "i_dont_care_about_security_and_use_aggressive_mode_psk=yes";
338
	}
339

    
340
	$unity_enabled = 'yes';
341
	if (isset($config['ipsec']['unityplugin'])) {
342
		$unity_enabled = 'no';
343
	}
344

    
345
	if (isset($config['ipsec']['enableinterfacesuse'])) {
346
		if (!empty($ifacesuse)) {
347
			$ifacesuse = 'interfaces_use = ' . implode(',', array_unique($ifacesuse));
348
		} else {
349
			$ifacesuse = '';
350
		}
351
	} else {
352
		$ifacesuse = '';
353
	}
354

    
355
	unset($stronconf);
356

    
357
	$strongswan = <<<EOD
358

    
359
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten.
360
starter {
361
load_warning = no
362
}
363

    
364
charon {
365
# number of worker threads in charon
366
threads = 16
367
ikesa_table_size = 32
368
ikesa_table_segments = 4
369
init_limit_half_open = 1000
370
install_routes = no
371
{$i_dont_care_about_security_and_use_aggressive_mode_psk}
372
{$accept_unencrypted}
373
cisco_unity = {$unity_enabled}
374
{$ifacesuse}
375

    
376
# And two loggers using syslog. The subsections define the facility to log
377
# to, currently one of: daemon, auth.
378
syslog {
379
	identifier = charon
380
	# default level to the LOG_DAEMON facility
381
	daemon {
382
	}
383
	# very minimalistic IKE auditing logs to LOG_AUTHPRIV
384
	auth {
385
		default = -1
386
		ike = 1
387
		ike_name = yes
388
	}
389
}
390

    
391
EOD;
392

    
393
	$strongswan .= "\tplugins {\n";
394

    
395
	if (is_array($a_client) && isset($a_client['enable'])) {
396
		$strongswan .= "\t\tattr {\n";
397
		if ($a_client['pool_address'] && $a_client['pool_netbits']) {
398
			$strongswan .= "\t\t\tsubnet = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
399
		}
400

    
401
		$cfgservers = array();
402
		if (!empty($a_client['dns_server1'])) {
403
			$cfgservers[] = $a_client['dns_server1'];
404
		}
405
		if (!empty($a_client['dns_server2'])) {
406
			$cfgservers[] = $a_client['dns_server2'];
407
		}
408
		if (!empty($a_client['dns_server3'])) {
409
			$cfgservers[] = $a_client['dns_server3'];
410
		}
411
		if (!empty($a_client['dns_server4'])) {
412
			$cfgservers[] = $a_client['dns_server4'];
413
		}
414

    
415
		if (!empty($cfgservers)) {
416
			$strongswan .= "\t\t\tdns = " . implode(",", $cfgservers) . "\n";
417
		}
418
		unset($cfgservers);
419
		$cfgservers = array();
420
		if (!empty($a_client['wins_server1'])) {
421
			$cfgservers[] = $a_client['wins_server1'];
422
		}
423
		if (!empty($a_client['wins_server2'])) {
424
			$cfgservers[] = $a_client['wins_server2'];
425
		}
426
		if (!empty($cfgservers)) {
427
			$strongswan .= "\t\t\tnbns = " . implode(",", $cfgservers) . "\n";
428
		}
429
		unset($cfgservers);
430

    
431
		if (isset($a_client['net_list']) && is_array($a_phase2)) {
432
			$net_list = '';
433
			foreach ($a_phase2 as $ph2ent) {
434
				if (isset($ph2ent['disabled'])) {
435
					continue;
436
				}
437

    
438
				if (!isset($ph2ent['mobile'])) {
439
					continue;
440
				}
441

    
442
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
443

    
444
				if (!empty($net_list)) {
445
					$net_list .= ",";
446
				}
447
				$net_list .= $localid;
448
			}
449

    
450
			if (!empty($net_list)) {
451
				$strongswan .= "\t\t\tsplit-include = {$net_list}\n";
452
				unset($net_list);
453
			}
454
		}
455

    
456
		if (!empty($a_client['dns_domain'])) {
457
			$strongswan .= "\t\t\t# Search domain and default domain\n";
458
			$strongswan .= "\t\t\t28674 = \"{$a_client['dns_domain']}\"\n";
459
			if (empty($a_client['dns_split'])) {
460
				$strongswan .= "\t\t\t28675 = \"{$a_client['dns_domain']}\"";
461
			}
462
			$strongswan .= "\n";
463
		}
464

    
465
		if (!empty($a_client['dns_split'])) {
466
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
467
		}
468

    
469
		if (!empty($a_client['login_banner'])) {
470
			$strongswan .= "\t\t\t28672 = \"{$a_client['login_banner']}\"\n";
471
		}
472

    
473
		if (isset($a_client['save_passwd'])) {
474
			$strongswan .= "\t\t\t28673 = 1\n";
475
		}
476

    
477
		if ($a_client['pfs_group']) {
478
			$strongswan .= "\t\t\t28679 = \"{$a_client['pfs_group']}\"\n";
479
		}
480
		$strongswan .= "\t\t}\n";
481

    
482
		if ($a_client['user_source'] != "none") {
483
			$strongswan .= "\t\txauth-generic {\n";
484
			$strongswan .= "\t\t\tscript = /etc/inc/ipsec.auth-user.php\n";
485
			$strongswan .= "\t\t\tauthcfg = ";
486
			$firstsed = 0;
487
			$authcfgs = explode(",", $a_client['user_source']);
488
			foreach ($authcfgs as $authcfg) {
489
				if ($firstsed > 0) {
490
					$strongswan .= ",";
491
				}
492
				if ($authcfg == "system") {
493
					$authcfg = "Local Database";
494
				}
495
				$strongswan .= $authcfg;
496
				$firstsed = 1;
497
			}
498
			$strongswan .= "\n";
499
			$strongswan .= "\t\t}\n";
500
		}
501
	}
502

    
503
	$strongswan .= "\t}\n}\n";
504
	@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
505
	unset($strongswan);
506

    
507
	/* generate CA certificates files */
508
	if (is_array($config['ca']) && count($config['ca'])) {
509
		foreach ($config['ca'] as $ca) {
510
			if (!isset($ca['crt'])) {
511
				log_error(sprintf(gettext("Error: Invalid certificate info for %s"), $ca['descr']));
512
				continue;
513
			}
514
			$cert = base64_decode($ca['crt']);
515
			$x509cert = openssl_x509_parse(openssl_x509_read($cert));
516
			if (!is_array($x509cert) || !isset($x509cert['hash'])) {
517
				log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $ca['descr']));
518
				continue;
519
			}
520
			$fname = "{$capath}/{$x509cert['hash']}.0.crt";
521
			if (!@file_put_contents($fname, $cert)) {
522
				log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $ca['descr']));
523
				continue;
524
			}
525
			unset($cert);
526
		}
527
	}
528

    
529
	$pskconf = "";
530

    
531
	if (is_array($a_phase1) && count($a_phase1)) {
532
		foreach ($a_phase1 as $ph1ent) {
533

    
534
			if (isset($ph1ent['disabled'])) {
535
				continue;
536
			}
537

    
538
			if (strstr($ph1ent['authentication_method'], 'rsa') ||
539
			    in_array($ph1ent['authentication_method'], array('eap-mschapv2', 'eap-tls'))) {
540
				$certline = '';
541

    
542
				$ikeid = $ph1ent['ikeid'];
543
				$cert = lookup_cert($ph1ent['certref']);
544

    
545
				if (!$cert) {
546
					log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
547
					continue;
548
				}
549

    
550
				@chmod($certpath, 0600);
551

    
552
				$ph1keyfile = "{$keypath}/cert-{$ikeid}.key";
553
				if (!file_put_contents($ph1keyfile, base64_decode($cert['prv']))) {
554
					log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
555
					continue;
556
				}
557
				@chmod($ph1keyfile, 0600);
558

    
559
				$ph1certfile = "{$certpath}/cert-{$ikeid}.crt";
560
				if (!file_put_contents($ph1certfile, base64_decode($cert['crt']))) {
561
					log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name']));
562
					@unlink($ph1keyfile);
563
					continue;
564
				}
565
				@chmod($ph1certfile, 0600);
566

    
567
				/* XXX" Traffic selectors? */
568
				$pskconf .= " : RSA {$ph1keyfile}\n";
569
			} else {
570
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
571
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
572

    
573
				if (empty($peerid_data)) {
574
					continue;
575
				}
576

    
577
				$myid = isset($ph1ent['mobile']) ? trim($myid_data) : "%any";
578
				$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
579
				if (!empty($ph1ent['pre-shared-key'])) {
580
					if ($myid_type == 'fqdn' && !empty($myid_data)) {
581
						$pskconf .= "@{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
582
					} else {
583
						$pskconf .= "{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
584
					}
585
				}
586
			}
587
		}
588
	}
589

    
590
	/* Add user PSKs */
591
	if (is_array($config['system']) && is_array($config['system']['user'])) {
592
		foreach ($config['system']['user'] as $user) {
593
			if (!empty($user['ipsecpsk'])) {
594
				$pskconf .= "%any {$user['name']} : PSK 0s" . base64_encode($user['ipsecpsk']) . "\n";
595
			}
596
		}
597
		unset($user);
598
	}
599

    
600
	/* add PSKs for mobile clients */
601
	if (is_array($ipseccfg['mobilekey'])) {
602
		foreach ($ipseccfg['mobilekey'] as $key) {
603
			if ($key['ident'] == "allusers") {
604
				$key['ident'] = '%any';
605
			}
606
			if (empty($key['type'])) {
607
				$key['type'] = 'PSK';
608
			}
609
			$pskconf .= "%any {$key['ident']} : {$key['type']} 0s" . base64_encode($key['pre-shared-key']) . "\n";
610
		}
611
		unset($key);
612
	}
613

    
614
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
615
	chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
616
	unset($pskconf);
617

    
618
	$uniqueids = 'yes';
619
	if (!empty($config['ipsec']['uniqueids'])) {
620
		if (in_array($uniqueids, $ipsec_idhandling)) {
621
			$uniqueids = $config['ipsec']['uniqueids'];
622
		}
623
	}
624
	$natfilterrules = false;
625
	/* begin ipsec.conf */
626
	$ipsecconf = "";
627
	$enablecompression = false;
628
	if (is_array($a_phase1) && count($a_phase1))  {
629

    
630
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
631
		$ipsecconf .= "config setup\n\tuniqueids = {$uniqueids}\n";
632
		$ipsecconf .= "\tcharondebug=\"" . vpn_ipsec_configure_loglevels(true) . "\"\n";
633

    
634
		foreach ($a_phase1 as $ph1ent) {
635
			if (isset($ph1ent['disabled'])) {
636
				continue;
637
			}
638

    
639
			if ($ph1ent['mode'] == "aggressive") {
640
				$aggressive = "yes";
641
			} else {
642
				$aggressive = "no";
643
			}
644

    
645
			$ep = ipsec_get_phase1_src($ph1ent);
646
			if (!$ep) {
647
				continue;
648
			}
649

    
650
			$ikeid = $ph1ent['ikeid'];
651
			$keyexchange = "ikev1";
652
			$passive = "route";
653
			if (!empty($ph1ent['iketype'])) {
654
				if ($ph1ent['iketype'] == "ikev2") {
655
					$keyexchange = "ikev2";
656
					//$passive = "start";
657
				} else if ($ph1ent['iketype'] == "auto") {
658
					$keyexchange = "ike";
659
				}
660
			}
661

    
662
			if (isset($ph1ent['mobile'])) {
663
				$right_spec = "%any";
664
				$passive = 'add';
665
			} else {
666
				if (isset($ph1ent['responderonly'])) {
667
					$passive = 'add';
668
				}
669

    
670
				$right_spec = $ph1ent['remote-gateway'];
671
				if (is_ipaddr($right_spec)) {
672
					$sourcehost = $right_spec;
673
				} else {
674
					$sourcehost = $rgmap['remote-gateway'];
675
				}
676

    
677
				if ($ph1ent['protocol'] == 'inet') {
678
					if (strpos($ph1ent['interface'], '_vip')) {
679
						$vpninterface = explode('_vip', $ph1ent['interface']);
680
						$ifacesuse = get_real_interface($vpninterface[0]);
681
						$vpninterface = $vpninterface[0];
682
					} else {
683
						$ifacesuse = get_failover_interface($ph1ent['interface']);
684
						if (strpos($ifacesuse, '_vip')) {
685
							$vpninterface = explode('_vip', $ifacesuse);
686
							$ifacesuse = get_real_interface($vpninterface[0]);
687
							$vpninterface = $vpninterface[0];
688
						} else {
689
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
690
						}
691
					}
692

    
693
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
694
						$gatewayip = get_interface_gateway($vpninterface);
695
						$interfaceip = get_interface_ip($vpninterface);
696
						$subnet_bits = get_interface_subnet($vpninterface);
697
						$subnet_ip = gen_subnetv4($interfaceip, $subnet_bits);
698
						/* if the remote gateway is in the local subnet, then don't add a route */
699
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
700
							if (is_ipaddrv4($gatewayip)) {
701
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
702
								mwexec("/sbin/route change -host {$sourcehost} {$gatewayip}", true);
703
							}
704
						}
705
					}
706
				} else if ($ph1ent['protocol'] == 'inet6') {
707
					if (strpos($ph1ent['interface'], '_vip')) {
708
						$vpninterface = explode('_vip', $ph1ent['interface']);
709
						$ifacesuse = get_real_interface($vpninterface[0]);
710
						$vpninterface = $vpninterface[0];
711
					} else {
712
						$ifacesuse = get_failover_interface($ph1ent['interface']);
713
						if (strpos($ifacesuse, '_vip')) {
714
							$vpninterface = explode('_vip', $ifacesuse);
715
							$ifacesuse = get_real_interface($vpninterface[0]);
716
							$vpninterface = $vpninterface[0];
717
						} else {
718
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
719
						}
720
					}
721

    
722
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
723
						$gatewayip = get_interface_gateway_v6($vpninterface);
724
						$interfaceip = get_interface_ipv6($vpninterface);
725
						$subnet_bits = get_interface_subnetv6($vpninterface);
726
						$subnet_ip = gen_subnetv6($interfaceip, $subnet_bits);
727
						/* if the remote gateway is in the local subnet, then don't add a route */
728
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
729
							if (is_ipaddrv6($gatewayip)) {
730
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
731
								mwexec("/sbin/route change -inet6 -host {$sourcehost} {$gatewayip}", true);
732
							}
733
						}
734
					}
735
				}
736
			}
737

    
738
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
739
			if ($myid_type != 'address') {
740
				$myid_data = "{$myid_type}:{$myid_data}";
741
			}
742

    
743
			/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
744
			$peerid_spec = '';
745
			if (!isset($ph1ent['mobile'])) {
746
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
747
				if ($peerid_type != 'address') {
748
					$peerid_spec = "{$peerid_type}:{$peerid_data}";
749
				} else {
750
					$peerid_spec = $peerid_data;
751
				}
752
			}
753

    
754
			if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
755
				$ealgosp1 = '';
756
				$ealg_id = $ph1ent['encryption-algorithm']['name'];
757
				$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
758
				if ($ealg_kl) {
759
					$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
760
				} else {
761
					$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
762
				}
763

    
764
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
765
				if (!empty($modp)) {
766
					$ealgosp1 .= "-{$modp}";
767
				}
768

    
769
				$ealgosp1 .= "!";
770
			}
771

    
772
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
773
				if ($passive == "route") {
774
					$dpdline = "dpdaction = restart";
775
				} else {
776
					$dpdline = "dpdaction = clear";
777
				}
778
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
779
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
780
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
781
			} else {
782
				$dpdline = "dpdaction = none";
783
			}
784

    
785
			$ikelifeline = '';
786
			if ($ph1ent['lifetime']) {
787
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
788
			}
789

    
790
			$rightsourceip = NULL;
791
			if (isset($ph1ent['mobile']) && !empty($a_client['pool_address'])) {
792
				$rightsourceip = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
793
			}
794

    
795
			$authentication = "";
796
			switch ($ph1ent['authentication_method']) {
797
				case 'eap-mschapv2':
798
					if (isset($ph1ent['mobile'])) {
799
						$authentication = "eap_identity=%any\n\t";
800
						$authentication .= "leftauth=pubkey\n\trightauth=eap-mschapv2";
801
						if (!empty($ph1ent['certref'])) {
802
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
803
						}
804
					}
805
					break;
806
				case 'eap-tls':
807
					if (isset($ph1ent['mobile'])) {
808
						$authentication = "eap_identity=%identity\n\t";
809
						$authentication .= "leftauth=pubkey\n\trightauth=eap-tls";
810
						if (!empty($ph1ent['certref'])) {
811
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
812
						}
813
					} else {
814
						$authentication = "leftauth=eap-tls\n\trightauth=eap-tls";
815
						if (!empty($ph1ent['certref'])) {
816
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
817
						}
818
					}
819
					break;
820
				case 'xauth_rsa_server':
821
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
822
					$authentication .= "\n\trightauth2 = xauth-generic";
823
					if (!empty($ph1ent['certref'])) {
824
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
825
					}
826
					break;
827
				case 'xauth_psk_server':
828
					$authentication = "leftauth = psk\n\trightauth = psk";
829
					$authentication .= "\n\trightauth2 = xauth-generic";
830
					break;
831
				case 'pre_shared_key':
832
					$authentication = "leftauth = psk\n\trightauth = psk";
833
					break;
834
				case 'rsasig':
835
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
836
					if (!empty($ph1ent['certref'])) {
837
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
838
					}
839
					break;
840
				case 'hybrid_rsa_server':
841
					$authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
842
					$authentication .= "\n\trightauth2 = xauth";
843
					if (!empty($ph1ent['certref'])) {
844
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
845
					}
846
					break;
847
			}
848

    
849
			$left_spec = $ep;
850

    
851
			if (isset($ph1ent['reauth_enable'])) {
852
				$reauth = "reauth = no";
853
			} else {
854
				$reauth = "reauth = yes";
855
			}
856
			if (isset($ph1ent['rekey_enable'])) {
857
				$rekey = "rekey = no";
858
			} else {
859
				$rekey = "rekey = yes";
860
			}
861

    
862
			if ($ph1ent['nat_traversal'] == 'off') {
863
				$forceencaps = 'forceencaps = no';
864
			} else if ($ph1ent['nat_traversal'] == 'force') {
865
				$forceencaps = 'forceencaps = yes';
866
			} else {
867
				$forceencaps = 'forceencaps = no';
868
			}
869

    
870
			if ($ph1ent['mobike'] == 'on') {
871
				$mobike = 'mobike = yes';
872
			} else {
873
				$mobike = 'mobike = no';
874
			}
875

    
876
			$ipseclifetime = 0;
877
			$rightsubnet_spec = array();
878
			$leftsubnet_spec = array();
879
			$reqids = array();
880
			$ealgoAHsp2arr = array();
881
			$ealgoESPsp2arr = array();
882
		if (is_array($a_phase2) && count($a_phase2)) {
883
			foreach ($a_phase2 as $ph2ent) {
884
				if ($ikeid != $ph2ent['ikeid']) {
885
					continue;
886
				}
887

    
888
				if (isset($ph2ent['disabled'])) {
889
					continue;
890
				}
891

    
892
				if (isset($ph2ent['mobile']) && !isset($a_client['enable'])) {
893
					continue;
894
				}
895

    
896
				if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
897
					$tunneltype = "type = tunnel";
898

    
899
					$localid_type = $ph2ent['localid']['type'];
900
					$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
901

    
902
					/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
903
					if (($localid_type == "none" || $localid_type == "mobile") &&
904
					    isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ikeid)==1)) {
905
						$left_spec = '%any';
906
					} else {
907
						if ($localid_type != "address") {
908
							$localid_type = "subnet";
909
						}
910
						// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
911
						if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) {
912
							log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
913
							continue;
914
						}
915
						if (!empty($ph2ent['natlocalid'])) {
916
							$natleftsubnet_data =  ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
917
							if ($ph2ent['natlocalid']['type'] != "address") {
918
								if (is_subnet($natleftsubnet_data)) {
919
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
920
								}
921
							} else {
922
								if (is_ipaddr($natleftsubnet_data)) {
923
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
924
								}
925
							}
926
							$natfilterrules = true;
927
						}
928
					}
929

    
930
					$leftsubnet_spec[] = $leftsubnet_data;
931

    
932
					if (!isset($ph2ent['mobile'])) {
933
						$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
934
						$rightsubnet_spec[] = $tmpsubnet;
935
					} else if (!empty($a_client['pool_address'])) {
936
						$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
937
					}
938
				} else {
939
					$tunneltype = "type = transport";
940

    
941
					if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
942
					    ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) {
943
						$left_spec = "%any";
944
					} else {
945
						$tmpsubnet = ipsec_get_phase1_src($ph1ent);
946
						$leftsubnet_spec[] = $tmpsubnet;
947
					}
948

    
949
					if (!isset($ph2ent['mobile'])) {
950
						$rightsubnet_spec[] = $right_spec;
951
					}
952
				}
953

    
954
				if (isset($a_client['pfs_group'])) {
955
					$ph2ent['pfsgroup'] = $a_client['pfs_group'];
956
				}
957

    
958
				if ($ph2ent['protocol'] == 'esp') {
959
					if (is_array($ph2ent['encryption-algorithm-option'])) {
960
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
961
							$ealg_id = $ealg['name'];
962
							$ealg_kl = $ealg['keylen'];
963

    
964
							if (!empty($ealg_kl) && $ealg_kl == "auto") {
965
								if (empty($p2_ealgos) || !is_array($p2_ealgos)) {
966
									require("ipsec.inc");
967
								}
968
								$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
969
								$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
970
								$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
971
								/* XXX: in some cases where include ordering is suspect these variables
972
								 * are somehow 0 and we enter this loop forever and timeout after 900
973
								 * seconds wrecking bootup */
974
								if ($key_hi != 0 and $key_lo !=0 and $key_step !=0) {
975
									for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
976
										if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
977
											foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
978
												$halgo = str_replace('hmac_', '', $halgo);
979
												$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
980
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
981
												if (!empty($modp)) {
982
													$tmpealgo .= "-{$modp}";
983
												}
984
												$ealgoESPsp2arr[] = $tmpealgo;
985
											}
986
										} else {
987
											$tmpealgo = "{$ealg_id}{$keylen}";
988
											$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
989
											if (!empty($modp)) {
990
												$tmpealgo .= "-{$modp}";
991
											}
992
											$ealgoESPsp2arr[] = $tmpealgo;
993
										}
994
									}
995
								}
996
							} else {
997
								if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
998
									foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
999
										$halgo = str_replace('hmac_', '', $halgo);
1000
										$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
1001
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1002
										if (!empty($modp)) {
1003
											$tmpealgo .= "-{$modp}";
1004
										}
1005
										$ealgoESPsp2arr[] = $tmpealgo;
1006
									}
1007
								} else {
1008
									$tmpealgo = "{$ealg_id}{$ealg_kl}";
1009
									$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1010
									if (!empty($modp)) {
1011
										$tmpealgo .= "-{$modp}";
1012
									}
1013
									$ealgoESPsp2arr[] = $tmpealgo;
1014
								}
1015
							}
1016
						}
1017
					}
1018
				} else if ($ph2ent['protocol'] == 'ah') {
1019
					if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1020
						$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1021
						foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
1022
							$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
1023
							if (!empty($modp)) {
1024
								$tmpAHalgo = "-{$modp}";
1025
							}
1026
							$ealgoAHsp2arr[] = $tmpAHalgo;
1027
						}
1028
					}
1029
				}
1030

    
1031
				$reqids[] = $ph2ent['reqid'];
1032

    
1033
				if (!empty($ph2ent['lifetime'])) {
1034
					if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) {
1035
						$ipseclifetime = intval($ph2ent['lifetime']);
1036
					}
1037
				}
1038

    
1039
			}
1040
		}
1041

    
1042
			$ipsecconnect =<<<EOD
1043
	fragmentation = yes
1044
	keyexchange = {$keyexchange}
1045
	{$reauth}
1046
	{$forceencaps}
1047
	{$mobike}
1048
	{$rekey}
1049
	installpolicy = yes
1050
	{$tunneltype}
1051
	{$dpdline}
1052
	auto = {$passive}
1053
	left = {$left_spec}
1054
	right = {$right_spec}
1055
	leftid = {$myid_data}
1056

    
1057
EOD;
1058

    
1059
			if (isset($config['ipsec']['compression'])) {
1060
				$ipsecconnect .= "\tcompress = yes\n";
1061
				$enablecompression = true;
1062
			}
1063
			if (!empty($ikelifeline)) {
1064
				$ipsecconnect .= "\t{$ikelifeline}\n";
1065
			}
1066
			if ($ipseclifetime > 0) {
1067
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
1068
			}
1069
			if (!empty($rightsourceip)) {
1070
				$ipsecconnect .= "{$rightsourceip}";
1071
			}
1072
			if (!empty($ealgosp1)) {
1073
				$ipsecconnect .= "\t{$ealgosp1}\n";
1074
			}
1075
			if (!empty($ealgoAHsp2arr)) {
1076
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
1077
			}
1078
			if (!empty($ealgoESPsp2arr)) {
1079
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
1080
			}
1081
			if (!empty($authentication)) {
1082
				$ipsecconnect .= "\t{$authentication}\n";
1083
			}
1084
			if (!empty($peerid_spec)) {
1085
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
1086
			}
1087
			if ($keyexchange == 'ikev1') {
1088
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
1089
			}
1090

    
1091
			if (!isset($ph1ent['mobile']) && $keyexchange == 'ikev1') {
1092
				if (!empty($rightsubnet_spec)) {
1093
					$ipsecfin = '';
1094
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
1095
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
1096
						if (!empty($reqids[$idx])) {
1097
							$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
1098
						}
1099
						$ipsecfin .= $ipsecconnect;
1100
						$ipsecfin .= "\trightsubnet = {$rsubnet}\n";
1101
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n";
1102
					}
1103
				} else {
1104
					log_error("No phase2 specifications for tunnel with REQID = {$ikeid}");
1105
				}
1106
			} else {
1107
				$ipsecfin = "\nconn con{$ph1ent['ikeid']}\n";
1108
				if (!empty($reqids[$idx])) {
1109
					$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
1110
				}
1111
				$ipsecfin .= $ipsecconnect;
1112
				if (!isset($ph1ent['mobile']) && !empty($rightsubnet_spec)) {
1113
					$tempsubnets = array();
1114
					foreach ($rightsubnet_spec as $rightsubnet) {
1115
						$tempsubnets[$rightsubnet] = $rightsubnet;
1116
					}
1117
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "\n";
1118
					unset($tempsubnets, $rightsubnet);
1119
				}
1120
				if (!empty($leftsubnet_spec)) {
1121
					$tempsubnets = array();
1122
					foreach ($leftsubnet_spec as $leftsubnet) {
1123
						$tempsubnets[$leftsubnet] = $leftsubnet;
1124
					}
1125
					$ipsecfin .= "\tleftsubnet = " . join(",", $leftsubnet_spec) . "\n";
1126
					unset($tempsubnets, $leftsubnet);
1127
				}
1128
			}
1129
			$ipsecconf .= $ipsecfin;
1130
			unset($ipsecfin);
1131
		}
1132
	}
1133

    
1134
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1135
	unset($ipsecconf);
1136
	/* end ipsec.conf */
1137

    
1138
	if ($enablecompression === true) {
1139
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1140
	} else {
1141
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1142
	}
1143

    
1144
	/* manage process */
1145
	if ($restart === true) {
1146
		mwexec("/usr/local/sbin/ipsec restart", false);
1147
	} else {
1148
		if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
1149
			/* Read secrets */
1150
			mwexec("/usr/local/sbin/ipsec rereadall", false);
1151
			/* Update configuration changes */
1152
			mwexec("/usr/local/sbin/ipsec update", false);
1153
		} else {
1154
			mwexec("/usr/local/sbin/ipsec start", false);
1155
		}
1156
	}
1157

    
1158
	if ($natfilterrules == true) {
1159
		filter_configure();
1160
	}
1161
	/* start filterdns, if necessary */
1162
	if (count($filterdns_list) > 0) {
1163
		$interval = 60;
1164
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) {
1165
			$interval = $ipseccfg['dns-interval'];
1166
		}
1167

    
1168
		$hostnames = "";
1169
		array_unique($filterdns_list);
1170
		foreach ($filterdns_list as $hostname) {
1171
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1172
		}
1173
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1174
		unset($hostnames);
1175

    
1176
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid")) {
1177
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1178
		} else {
1179
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1180
		}
1181
	} else {
1182
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1183
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1184
	}
1185

    
1186
	if (platform_booting()) {
1187
		echo "done\n";
1188
	}
1189

    
1190
	return count($filterdns_list);
1191
}
1192

    
1193
/*
1194
 * Forcefully restart IPsec
1195
 * This is required for when dynamic interfaces reload
1196
 * For all other occasions the normal vpn_ipsec_configure()
1197
 * will gracefully reload the settings without restarting
1198
 */
1199
function vpn_ipsec_force_reload($interface = "") {
1200
	global $g, $config;
1201

    
1202
	$ipseccfg = $config['ipsec'];
1203

    
1204
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1205
		$found = false;
1206
		foreach ($ipseccfg['phase1'] as $ipsec) {
1207
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1208
				$found = true;
1209
				break;
1210
			}
1211
		}
1212
		if (!$found) {
1213
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1214
			return;
1215
		}
1216
	}
1217

    
1218
	/* if ipsec is enabled, start up again */
1219
	if (isset($ipseccfg['enable'])) {
1220
		log_error(gettext("Forcefully reloading IPsec"));
1221
		vpn_ipsec_configure();
1222
	}
1223
}
1224

    
1225
/* master setup for vpn (mpd) */
1226
function vpn_setup() {
1227
	global $g;
1228

    
1229
	if ($g['platform'] == 'jail') {
1230
		return;
1231
	}
1232

    
1233
	/* start pptpd */
1234
	vpn_pptpd_configure();
1235

    
1236
	/* start pppoe server */
1237
	vpn_pppoes_configure();
1238

    
1239
	/* setup l2tp */
1240
	vpn_l2tp_configure();
1241
}
1242

    
1243
function vpn_netgraph_support() {
1244
	$iflist = get_configured_interface_list();
1245
	foreach ($iflist as $iface) {
1246
		$realif = get_real_interface($iface);
1247
		/* Get support for netgraph(4) from the nic */
1248
		$ifinfo = pfSense_get_interface_addresses($realif);
1249
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) {
1250
			pfSense_ngctl_attach(".", $realif);
1251
		}
1252
	}
1253
}
1254

    
1255
function vpn_pptpd_configure() {
1256
	global $config, $g;
1257

    
1258
	$syscfg = $config['system'];
1259
	$pptpdcfg = $config['pptpd'];
1260

    
1261
	if (platform_booting()) {
1262
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off")) {
1263
			return 0;
1264
		}
1265

    
1266
		if (platform_booting(true)) {
1267
			echo gettext("Configuring PPTP VPN service... ");
1268
		}
1269
	} else {
1270
		/* kill mpd */
1271
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1272

    
1273
		/* wait for process to die */
1274
		sleep(3);
1275

    
1276
		if (is_process_running("mpd -b")) {
1277
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1278
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
1279
		}
1280

    
1281
		/* remove mpd.conf, if it exists */
1282
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
1283
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
1284
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
1285
	}
1286

    
1287
	if (empty($pptpdcfg['n_pptp_units'])) {
1288
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
1289
		return;
1290
	}
1291

    
1292
	/* make sure pptp-vpn directory exists */
1293
	if (!file_exists("{$g['varetc_path']}/pptp-vpn")) {
1294
		mkdir("{$g['varetc_path']}/pptp-vpn");
1295
	}
1296

    
1297
	switch ($pptpdcfg['mode']) {
1298
		case 'server':
1299
			/* write mpd.conf */
1300
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1301
			if (!$fd) {
1302
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
1303
				return 1;
1304
			}
1305

    
1306
			$mpdconf = <<<EOD
1307
pptps:
1308

    
1309
EOD;
1310

    
1311
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1312
				$mpdconf .= "	load pt{$i}\n";
1313
			}
1314

    
1315
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1316

    
1317
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1318

    
1319
				$mpdconf .= <<<EOD
1320

    
1321
pt{$i}:
1322
	new -i pptpd{$i} pt{$i} pt{$i}
1323
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1324
	load pts
1325

    
1326
EOD;
1327
			}
1328

    
1329
			$mpdconf .=<<<EOD
1330

    
1331
pts:
1332
	set iface disable on-demand
1333
	set iface enable proxy-arp
1334
	set iface enable tcpmssfix
1335
	set iface idle 1800
1336
	set iface up-script /usr/local/sbin/vpn-linkup
1337
	set iface down-script /usr/local/sbin/vpn-linkdown
1338
	set bundle enable multilink
1339
	set bundle enable crypt-reqd
1340
	set link yes acfcomp protocomp
1341
	set link no pap chap
1342
	set link enable chap-msv2
1343
	set link mtu 1460
1344
	set link keep-alive 10 60
1345
	set ipcp yes vjcomp
1346
	set bundle enable compression
1347
	set ccp yes mppc
1348
	set ccp yes mpp-e128
1349
	set ccp yes mpp-stateless
1350

    
1351
EOD;
1352

    
1353
			if (!isset ($pptpdcfg['req128'])) {
1354
				$mpdconf .=<<<EOD
1355
	set ccp yes mpp-e40
1356
	set ccp yes mpp-e56
1357

    
1358
EOD;
1359
			}
1360

    
1361
			if  (isset($pptpdcfg["wins"]) && $pptpdcfg['wins'] != "") {
1362
				$mpdconf  .=  "	set ipcp nbns {$pptpdcfg['wins']}\n";
1363
			}
1364

    
1365
			if (!empty($pptpdcfg['dns1'])) {
1366
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1367
				if (!empty($pptpdcfg['dns2'])) {
1368
					$mpdconf .= " " . $pptpdcfg['dns2'];
1369
				}
1370
				$mpdconf .= "\n";
1371
			} elseif (isset ($config['dnsmasq']['enable'])) {
1372
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1373
				if ($syscfg['dnsserver'][0]) {
1374
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1375
				}
1376
				$mpdconf .= "\n";
1377
			} elseif (isset($config['unbound']['enable'])) {
1378
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1379
				if ($syscfg['dnsserver'][0]) {
1380
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1381
				}
1382
				$mpdconf .= "\n";
1383
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1384
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1385
			}
1386

    
1387
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1388
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1389
				$acctport = $authport + 1;
1390
				$mpdconf .=<<<EOD
1391
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1392

    
1393
EOD;
1394
				if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1395
					$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1396
					$acctport = $authport + 1;
1397
					$mpdconf .=<<<EOD
1398
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1399

    
1400
EOD;
1401
				}
1402
				$mpdconf .=<<<EOD
1403
	set radius retries 3
1404
	set radius timeout 10
1405
	set auth enable radius-auth
1406

    
1407
EOD;
1408

    
1409
				if (isset ($pptpdcfg['radius']['accounting'])) {
1410
					$mpdconf .=<<<EOD
1411
	set auth enable radius-acct
1412
	set radius acct-update 300
1413

    
1414
EOD;
1415
				}
1416
			}
1417

    
1418
			fwrite($fd, $mpdconf);
1419
			fclose($fd);
1420
			unset($mpdconf);
1421

    
1422
			/* write mpd.links */
1423
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1424
			if (!$fd) {
1425
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1426
				return 1;
1427
			}
1428

    
1429
			$mpdlinks = "";
1430

    
1431
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1432
				$mpdlinks .=<<<EOD
1433

    
1434
pt{$i}:
1435
	set link type pptp
1436
	set pptp enable incoming
1437
	set pptp disable originate
1438
	set pptp disable windowing
1439

    
1440
EOD;
1441
			}
1442

    
1443
			fwrite($fd, $mpdlinks);
1444
			fclose($fd);
1445
			unset($mpdlinks);
1446

    
1447
			/* write mpd.secret */
1448
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1449
			if (!$fd) {
1450
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1451
				return 1;
1452
			}
1453

    
1454
			$mpdsecret = "";
1455

    
1456
			if (is_array($pptpdcfg['user'])) {
1457
				foreach ($pptpdcfg['user'] as $user) {
1458
					$pass = str_replace('\\', '\\\\', $user['password']);
1459
					$pass = str_replace('"', '\"', $pass);
1460
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1461
				}
1462
			}
1463

    
1464
			fwrite($fd, $mpdsecret);
1465
			fclose($fd);
1466
			unset($mpdsecret);
1467
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1468

    
1469
			vpn_netgraph_support();
1470

    
1471
			/* fire up mpd */
1472
			mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']}/pptp-vpn -p {$g['varrun_path']}/pptp-vpn.pid -s pptps pptps");
1473

    
1474
			break;
1475

    
1476
		case 'redir':
1477
			break;
1478
	}
1479

    
1480
	if (platform_booting()) {
1481
		echo "done\n";
1482
	}
1483

    
1484
	return 0;
1485
}
1486

    
1487
function vpn_pppoes_configure() {
1488
	global $config;
1489

    
1490
	if (is_array($config['pppoes']['pppoe'])) {
1491
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
1492
			vpn_pppoe_configure($pppoe);
1493
		}
1494
	}
1495
}
1496

    
1497
function vpn_pppoe_configure(&$pppoecfg) {
1498
	global $config, $g;
1499

    
1500
	$syscfg = $config['system'];
1501

    
1502
	/* create directory if it does not exist */
1503
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
1504
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1505
	}
1506

    
1507
	if (platform_booting()) {
1508
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
1509
			return 0;
1510
		}
1511

    
1512
		echo gettext("Configuring PPPoE Server service... ");
1513
	} else {
1514
		/* kill mpd */
1515
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1516

    
1517
		/* wait for process to die */
1518
		sleep(2);
1519

    
1520
	}
1521

    
1522
	switch ($pppoecfg['mode']) {
1523

    
1524
		case 'server':
1525

    
1526
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1527

    
1528
			if ($pppoecfg['paporchap'] == "chap") {
1529
				$paporchap = "set link enable chap";
1530
			} else {
1531
				$paporchap = "set link enable pap";
1532
			}
1533

    
1534
			/* write mpd.conf */
1535
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1536
			if (!$fd) {
1537
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1538
				return 1;
1539
			}
1540
			$mpdconf = "\n\n";
1541
			$mpdconf .= "poes:\n";
1542

    
1543
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1544
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1545
			}
1546

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

    
1549
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1550

    
1551
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1552
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1553
				} else {
1554
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1555
				}
1556

    
1557
				$mpdconf .=<<<EOD
1558

    
1559
poes{$pppoecfg['pppoeid']}{$i}:
1560
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1561
	{$isssue_ip_type}
1562
	load pppoe_standard
1563

    
1564
EOD;
1565
			}
1566

    
1567
			$mpdconf .=<<<EOD
1568

    
1569
pppoe_standard:
1570
	set bundle no multilink
1571
	set bundle enable compression
1572
	set auth max-logins 1
1573
	set iface up-script /usr/local/sbin/vpn-linkup
1574
	set iface down-script /usr/local/sbin/vpn-linkdown
1575
	set iface idle 0
1576
	set iface disable on-demand
1577
	set iface disable proxy-arp
1578
	set iface enable tcpmssfix
1579
	set iface mtu 1500
1580
	set link no pap chap
1581
	{$paporchap}
1582
	set link keep-alive 60 180
1583
	set ipcp yes vjcomp
1584
	set ipcp no vjcomp
1585
	set link max-redial -1
1586
	set link mtu 1492
1587
	set link mru 1492
1588
	set ccp yes mpp-e40
1589
	set ccp yes mpp-e128
1590
	set ccp yes mpp-stateless
1591
	set link latency 1
1592
	#set ipcp dns 10.10.1.3
1593
	#set bundle accept encryption
1594

    
1595
EOD;
1596

    
1597
			if (!empty($pppoecfg['dns1'])) {
1598
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1599
				if (!empty($pppoecfg['dns2'])) {
1600
					$mpdconf .= " " . $pppoecfg['dns2'];
1601
				}
1602
				$mpdconf .= "\n";
1603
			} elseif (isset ($config['dnsmasq']['enable'])) {
1604
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1605
				if ($syscfg['dnsserver'][0]) {
1606
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1607
				}
1608
				$mpdconf .= "\n";
1609
			} elseif (isset ($config['unbound']['enable'])) {
1610
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1611
				if ($syscfg['dnsserver'][0]) {
1612
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1613
				}
1614
				$mpdconf .= "\n";
1615
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1616
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1617
			}
1618

    
1619
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1620
				$radiusport = "";
1621
				$radiusacctport = "";
1622
				if (isset($pppoecfg['radius']['server']['port'])) {
1623
					$radiusport = $pppoecfg['radius']['server']['port'];
1624
				}
1625
				if (isset($pppoecfg['radius']['server']['acctport'])) {
1626
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1627
				}
1628
				$mpdconf .=<<<EOD
1629
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1630
	set radius retries 3
1631
	set radius timeout 10
1632
	set auth enable radius-auth
1633

    
1634
EOD;
1635

    
1636
				if (isset ($pppoecfg['radius']['accounting'])) {
1637
					$mpdconf .=<<<EOD
1638
	set auth enable radius-acct
1639

    
1640
EOD;
1641
				}
1642
			}
1643

    
1644
			fwrite($fd, $mpdconf);
1645
			fclose($fd);
1646
			unset($mpdconf);
1647

    
1648
			/* write mpd.links */
1649
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1650
			if (!$fd) {
1651
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1652
				return 1;
1653
			}
1654

    
1655
			$mpdlinks = "";
1656

    
1657
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1658
				$mpdlinks .=<<<EOD
1659

    
1660
poes{$pppoecfg['pppoeid']}{$i}:
1661
	set phys type pppoe
1662
	set pppoe iface {$pppoe_interface}
1663
	set pppoe service "*"
1664
	set pppoe disable originate
1665
	set pppoe enable incoming
1666

    
1667
EOD;
1668
			}
1669

    
1670
			fwrite($fd, $mpdlinks);
1671
			fclose($fd);
1672
			unset($mpdlinks);
1673

    
1674
			if ($pppoecfg['username']) {
1675
				/* write mpd.secret */
1676
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1677
				if (!$fd) {
1678
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1679
					return 1;
1680
				}
1681

    
1682
				$mpdsecret = "\n\n";
1683

    
1684
				if (!empty($pppoecfg['username'])) {
1685
					$item = explode(" ", $pppoecfg['username']);
1686
					foreach ($item as $userdata) {
1687
						$data = explode(":", $userdata);
1688
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1689
					}
1690
				}
1691

    
1692
				fwrite($fd, $mpdsecret);
1693
				fclose($fd);
1694
				unset($mpdsecret);
1695
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1696
			}
1697

    
1698
			/* Check if previous instance is still up */
1699
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
1700
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1701
			}
1702

    
1703
			/* Get support for netgraph(4) from the nic */
1704
			pfSense_ngctl_attach(".", $pppoe_interface);
1705
			/* fire up mpd */
1706
			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");
1707

    
1708
			break;
1709
	}
1710

    
1711
	if (platform_booting()) {
1712
		echo gettext("done") . "\n";
1713
	}
1714

    
1715
	return 0;
1716
}
1717

    
1718
function vpn_l2tp_configure() {
1719
	global $config, $g;
1720

    
1721
	$syscfg = $config['system'];
1722
	$l2tpcfg = $config['l2tp'];
1723

    
1724
	/* create directory if it does not exist */
1725
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
1726
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1727
	}
1728

    
1729
	if (platform_booting()) {
1730
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
1731
			return 0;
1732
		}
1733

    
1734
		echo gettext("Configuring l2tp VPN service... ");
1735
	} else {
1736
		/* kill mpd */
1737
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1738

    
1739
		/* wait for process to die */
1740
		sleep(8);
1741

    
1742
	}
1743

    
1744
	/* make sure l2tp-vpn directory exists */
1745
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
1746
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1747
	}
1748

    
1749
	switch ($l2tpcfg['mode']) {
1750

    
1751
		case 'server':
1752
			if ($l2tpcfg['paporchap'] == "chap") {
1753
				$paporchap = "set link enable chap";
1754
			} else {
1755
				$paporchap = "set link enable pap";
1756
			}
1757

    
1758
			/* write mpd.conf */
1759
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1760
			if (!$fd) {
1761
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1762
				return 1;
1763
			}
1764
			$mpdconf = "\n\n";
1765
			$mpdconf .=<<<EOD
1766
l2tps:
1767

    
1768
EOD;
1769

    
1770
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1771
				$mpdconf .= "	load l2tp{$i}\n";
1772
			}
1773

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

    
1776
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1777

    
1778
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1779
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1780
				} else {
1781
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1782
				}
1783

    
1784
				$mpdconf .=<<<EOD
1785

    
1786
l2tp{$i}:
1787
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1788
	{$isssue_ip_type}
1789
	load l2tp_standard
1790

    
1791
EOD;
1792
			}
1793

    
1794
			$mpdconf .=<<<EOD
1795

    
1796
l2tp_standard:
1797
	set bundle disable multilink
1798
	set bundle enable compression
1799
	set bundle yes crypt-reqd
1800
	set ipcp yes vjcomp
1801
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1802
	set ccp yes mppc
1803
	set iface disable on-demand
1804
	set iface enable proxy-arp
1805
	set iface up-script /usr/local/sbin/vpn-linkup
1806
	set iface down-script /usr/local/sbin/vpn-linkdown
1807
	set link yes acfcomp protocomp
1808
	set link no pap chap
1809
	{$paporchap}
1810
	set link keep-alive 10 180
1811

    
1812
EOD;
1813

    
1814
			if (is_ipaddr($l2tpcfg['wins'])) {
1815
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1816
			}
1817
			if (is_ipaddr($l2tpcfg['dns1'])) {
1818
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1819
				if (is_ipaddr($l2tpcfg['dns2'])) {
1820
					$mpdconf .= " " . $l2tpcfg['dns2'];
1821
				}
1822
				$mpdconf .= "\n";
1823
			} elseif (isset ($config['dnsmasq']['enable'])) {
1824
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1825
				if ($syscfg['dnsserver'][0]) {
1826
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1827
				}
1828
				$mpdconf .= "\n";
1829
			} elseif (isset ($config['unbound']['enable'])) {
1830
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1831
				if ($syscfg['dnsserver'][0]) {
1832
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1833
				}
1834
				$mpdconf .= "\n";
1835
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1836
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1837
			}
1838

    
1839
			if (isset ($l2tpcfg['radius']['enable'])) {
1840
				$mpdconf .=<<<EOD
1841
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1842
	set radius retries 3
1843
	set radius timeout 10
1844
	set auth enable radius-auth
1845

    
1846
EOD;
1847

    
1848
				if (isset ($l2tpcfg['radius']['accounting'])) {
1849
					$mpdconf .=<<<EOD
1850
	set auth enable radius-acct
1851

    
1852
EOD;
1853
				}
1854
			}
1855

    
1856
			fwrite($fd, $mpdconf);
1857
			fclose($fd);
1858
			unset($mpdconf);
1859

    
1860
			/* write mpd.links */
1861
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1862
			if (!$fd) {
1863
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1864
				return 1;
1865
			}
1866

    
1867
			$mpdlinks = "";
1868

    
1869
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1870
				$mpdlinks .=<<<EOD
1871

    
1872
l2tp{$i}:
1873
	set link type l2tp
1874
	set l2tp enable incoming
1875
	set l2tp disable originate
1876

    
1877
EOD;
1878
				if (!empty($l2tpcfg['secret'])) {
1879
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1880
				}
1881
			}
1882

    
1883
			fwrite($fd, $mpdlinks);
1884
			fclose($fd);
1885
			unset($mpdlinks);
1886

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

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

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

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

    
1907
			vpn_netgraph_support();
1908

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

    
1912
			break;
1913

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

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

    
1922
	return 0;
1923
}
1924

    
1925
?>
(59-59/68)