Project

General

Profile

Download (55.7 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
	if ($forconfig)
59
		return implode(',', $cfgtext);
60
}
61

    
62
/* include all configuration functions */
63
function vpn_ipsec_convert_to_modp($index)
64
{
65

    
66
	$convertion = "";
67
	switch ($index) {
68
	case '1':
69
		$convertion = "modp768";
70
		break;
71
	case '2':
72
		$convertion = "modp1024";
73
		break;
74
	case '5':
75
		$convertion = "modp1536";
76
		break;
77
	case '14':
78
		$convertion = "modp2048";
79
		break;
80
	case '15':
81
		$convertion = "modp3072";
82
		break;
83
	case '16':      
84
		$convertion = "modp4096";
85
		break;
86
	case '17':
87
		$convertion = "modp6144";
88
		break;
89
	case '18':
90
		$convertion = "modp8192";
91
		break;
92
	case '19':
93
		$convertion = "ecp256";
94
		break;
95
	case '20':
96
		$convertion = "ecp384";
97
		break;
98
	case '21':
99
		$convertion = "ecp512";
100
		break;
101
	}
102

    
103
	return $convertion;
104
}
105

    
106
function vpn_ipsec_configure($restart = false)
107
{
108
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos, $ipsec_idhandling;
109

    
110
	if ($g['platform'] == 'jail')
111
		return;
112

    
113
	/* get the automatic ping_hosts.sh ready */
114
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
115
	touch("{$g['vardb_path']}/ipsecpinghosts");
116
	
117
	/* service may have been enabled, disabled, or otherwise changed in a way requiring rule updates */
118
	filter_configure();
119

    
120
	$syscfg = $config['system'];
121
	$ipseccfg = $config['ipsec'];
122
	if (!isset($ipseccfg['enable'])) {
123
		/* try to stop charon */
124
		mwexec("/usr/local/sbin/ipsec stop");
125
		/* Stop dynamic monitoring */
126
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
127

    
128
		/* wait for process to die */
129
		sleep(2);
130

    
131
		/* disallow IPSEC, it is off */
132
		mwexec("/sbin/ifconfig enc0 down");
133
		set_single_sysctl("net.inet.ip.ipsec_in_use", "0");
134

    
135
		return 0;
136
	}
137

    
138
	$a_phase1 = $config['ipsec']['phase1'];
139
	$a_phase2 = $config['ipsec']['phase2'];
140
	$a_client = $config['ipsec']['client'];
141

    
142
	$certpath = "{$g['varetc_path']}/ipsec/ipsec.d/certs";
143
	$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts";
144
	$keypath = "{$g['varetc_path']}/ipsec/ipsec.d/private";
145

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

    
171
	if (platform_booting())
172
		echo gettext("Configuring IPsec VPN... ");
173

    
174
	/* fastforwarding is not compatible with ipsec tunnels */
175
	set_single_sysctl("net.inet.ip.fastforwarding", "0");
176

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

    
187
		$ipsecpinghosts = "";
188
		/* step through each phase1 entry */
189
		foreach ($a_phase1 as $ph1ent) {
190
			if (isset($ph1ent['disabled']))
191
				continue;
192

    
193
			if (strpos($ph1ent['interface'], '_vip')) {
194
				$vpninterface = explode('_vip', $ph1ent['interface']);
195
				$ifacesuse[] = get_real_interface($vpninterface[0]);
196
                        } else {
197
                                $vpninterface = get_failover_interface($ph1ent['interface']);
198
				if (strpos($vpninterface, '_vip')) {
199
					$vpninterface = explode('_vip', $vpninterface);
200
					$ifacesuse[] = get_real_interface($vpninterface[0]);
201
				} elseif (!empty($vpninterface))
202
					$ifacesuse[] = $vpninterface;
203
			}
204
				
205
			if ($ph1ent['mode'] == "aggressive" && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) 
206
				$aggressive_mode_psk = true;
207

    
208
			$ikeid = $ph1ent['ikeid'];
209
			$listeniflist = get_real_interface($a_phase1['interface']);
210

    
211
			$ep = ipsec_get_phase1_src($ph1ent);
212
			if (!is_ipaddr($ep)) {
213
				log_error("IPsec ERROR: Could not find phase 1 source for connection {$ph1ent['descr']}. Omitting from configuration file.");
214
				continue;
215
			}
216

    
217
			if(!in_array($ep,$ipmap))
218
				$ipmap[] = $ep;
219

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

    
223
			if (isset ($ph1ent['mobile']))
224
				continue;
225

    
226
			$rg = $ph1ent['remote-gateway'];
227

    
228
			if (!is_ipaddr($rg)) {
229
				$filterdns_list[] = "{$rg}";
230
				add_hostname_to_watch($rg);
231
				if (!platform_booting())
232
					$rg = resolve_retry($rg);
233
				if (!is_ipaddr($rg))
234
					continue;
235
			}
236
			if(array_search($rg, $rgmap)) {
237
				log_error("The remote gateway {$rg} already exists on another phase 1 entry");
238
				continue;
239
			}
240
			$rgmap[$ph1ent['remote-gateway']] = $rg;
241

    
242
			if (is_array($a_phase2)) {
243
				/* step through each phase2 entry */
244
				foreach ($a_phase2 as $ph2ent) {
245
					if (isset($ph2ent['disabled']))
246
						continue;
247

    
248
					if ($ikeid != $ph2ent['ikeid'])
249
						continue;
250

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

    
305
	$accept_unencrypted = "";
306
	if (isset($config['ipsec']['acceptunencryptedmainmode']))
307
		$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
308

    
309
	$stronconf = '';
310
	if (file_exists("{$g['varetc_path']}/ipsec/strongswan.conf"))
311
		$stronconf = file_get_contents("{$g['varetc_path']}/ipsec/strongswan.conf");
312

    
313
	$i_dont_care_about_security_and_use_aggressive_mode_psk = "";
314
	if ($aggressive_mode_psk) {
315
		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.");
316
		if (!empty($stronconf) && strpos($stronconf, 'i_dont_care_about_security_and_use_aggressive_mode_psk') === FALSE)
317
			$restart = true;
318
		$i_dont_care_about_security_and_use_aggressive_mode_psk = "i_dont_care_about_security_and_use_aggressive_mode_psk=yes";
319
	} 
320

    
321
	$unity_enabled = 'yes';
322
	if (isset($config['ipsec']['unityplugin'])) {
323
		$unity_enabled = 'no';
324
		if (file_exists("/usr/local/lib/ipsec/plugins/libstrongswan-unity.so")) {
325
			conf_mount_rw();
326
			mwexec("mv /usr/local/lib/ipsec/plugins/libstrongswan-unity.so /usr/local/lib/ipsec/plugins/libstrongswan-unity.MOVED");
327
			conf_mount_ro();
328
		}
329
	} else if (file_exists("/usr/local/lib/ipsec/plugins/libstrongswan-unity.MOVED")) {
330
		conf_mount_rw();
331
		mwexec("mv /usr/local/lib/ipsec/plugins/libstrongswan-unity.MOVED /usr/local/lib/ipsec/plugins/libstrongswan-unity.so");
332
		conf_mount_ro();
333
	}
334

    
335
	$makebeforebreak = '';
336
	if (isset($config['ipsec']['makebeforebreak'])) {
337
		$makebeforebreak = 'make_before_break = yes';
338
	}
339

    
340
	if (isset($config['ipsec']['enableinterfacesuse'])) {
341
		if (!empty($ifacesuse)) {
342
			$ifacesuse = 'interfaces_use = ' . implode(',', array_unique($ifacesuse));
343
		} else {
344
			$ifacesuse = '';
345
		}
346
	} else {
347
		$ifacesuse = '';
348
	}
349

    
350
	unset($stronconf);
351

    
352
	$strongswan = <<<EOD
353

    
354
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten. 
355
starter {
356
load_warning = no
357
}
358

    
359
charon {
360
# number of worker threads in charon
361
threads = 16
362
ikesa_table_size = 32
363
ikesa_table_segments = 4
364
init_limit_half_open = 1000
365
install_routes = no
366
{$i_dont_care_about_security_and_use_aggressive_mode_psk}
367
{$accept_unencrypted}
368
cisco_unity = {$unity_enabled}
369
{$ifacesuse}
370
{$makebeforebreak}
371

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

    
388
EOD;
389

    
390
	$strongswan .= "\tplugins {\n";
391

    
392
	$a_servers = auth_get_authserver_list();
393
	foreach ($a_servers as $id => $pconfig) {
394
		if ($id == $config['ipsec']['client']['user_source'] && $pconfig['type'] == "radius") {
395
			$strongswan .= <<<EOD
396
		eap-radius {
397
			class_group = yes
398
			eap_start = no
399
			servers {
400
				primary {
401
					address = {$pconfig['host']}
402
					secret = {$pconfig['radius_secret']}
403
					auth_port = {$pconfig['radius_auth_port']}
404
					acct_port = {$pconfig['radius_acct_port']}
405
				}
406
			}
407
		}
408

    
409
EOD;
410
			break;
411
		}
412
	}
413

    
414
	if (is_array($a_client) && isset($a_client['enable'])) {
415
		$strongswan .= "\t\tattr {\n";
416
		if ($a_client['pool_address'] && $a_client['pool_netbits'])
417
			$strongswan .= "\t\t\tsubnet = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
418

    
419
		$cfgservers = array();
420
		if (!empty($a_client['dns_server1']))
421
			$cfgservers[] = $a_client['dns_server1'];
422
		if (!empty($a_client['dns_server2']))
423
			$cfgservers[] = $a_client['dns_server2'];
424
		if (!empty($a_client['dns_server3']))
425
			$cfgservers[] = $a_client['dns_server3'];
426
		if (!empty($a_client['dns_server4']))
427
			$cfgservers[] = $a_client['dns_server4'];
428

    
429
		if (!empty($cfgservers))
430
			$strongswan .= "\t\t\tdns = " . implode(",", $cfgservers) . "\n";
431
		unset($cfgservers);
432
		$cfgservers = array();
433
		if (!empty($a_client['wins_server1']))
434
			$cfgservers[] = $a_client['wins_server1'];
435
		if (!empty($a_client['wins_server2']))
436
			$cfgservers[] = $a_client['wins_server2'];
437
		if (!empty($cfgservers))
438
			$strongswan .= "\t\t\tnbns = " . implode(",", $cfgservers) . "\n";
439
		unset($cfgservers);
440

    
441
		if (isset($a_client['net_list']) && is_array($a_phase2)) {
442
			$net_list = '';
443
			foreach ($a_phase2 as $ph2ent) {
444
				if (isset($ph2ent['disabled']))
445
					continue;
446

    
447
				if (!isset($ph2ent['mobile']))
448
					continue;
449

    
450
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
451

    
452
				if (!empty($net_list))
453
					$net_list .= ",";
454
				$net_list .= $localid;
455
			}
456

    
457
			if (!empty($net_list)) {
458
				$strongswan .= "\t\t\tsplit-include = {$net_list}\n";
459
				unset($net_list);
460
			}
461
		}
462

    
463
		if (!empty($a_client['dns_domain'])) {
464
			$strongswan .= "\t\t\t# Search domain and default domain\n";
465
			$strongswan .= "\t\t\t28674 = \"{$a_client['dns_domain']}\"\n";
466
			if (empty($a_client['dns_split'])) {
467
				$strongswan .= "\t\t\t28675 = \"{$a_client['dns_domain']}\"";
468
			}
469
			$strongswan .= "\n";
470
		}
471

    
472
		if (!empty($a_client['dns_split'])) {
473
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
474
		}
475

    
476
		if (!empty($a_client['login_banner']))
477
			$strongswan .= "\t\t\t28672 = \"{$a_client['login_banner']}\"\n";
478

    
479
		if (isset($a_client['save_passwd']))
480
			$strongswan .= "\t\t\t28673 = 1\n";
481

    
482
		if ($a_client['pfs_group'])
483
			$strongswan .= "\t\t\t28679 = \"{$a_client['pfs_group']}\"\n";
484
		$strongswan .= "\t\t}\n";
485

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

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

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

    
531
	$pskconf = "";
532

    
533
	if (is_array($a_phase1) && count($a_phase1)) {
534
		foreach ($a_phase1 as $ph1ent) {
535

    
536
			if (isset($ph1ent['disabled']))
537
				continue;
538

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

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

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

    
551
				@chmod($certpath, 0600);
552

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

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

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

    
574
				if (empty($peerid_data))
575
					continue;
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
	/* Add user PSKs */
590
	if (is_array($config['system']) && is_array($config['system']['user'])) {
591
		foreach ($config['system']['user'] as $user) {
592
			if (!empty($user['ipsecpsk'])) {
593
				$pskconf .= "%any {$user['name']} : PSK 0s" . base64_encode($user['ipsecpsk']) . "\n";
594
			}
595
		}
596
		unset($user);
597
	}
598

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

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

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

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

    
631
		if (!isset($config['ipsec']['noshuntlaninterfaces'])) {
632
			if ($config['interfaces']['lan']) {
633
				$lanip = get_interface_ip("lan");
634
				if (!empty($lanip) && is_ipaddrv4($lanip)) {
635
					$lansn = get_interface_subnet("lan");
636
					$lansa = gen_subnet($lanip, $lansn);
637
					$ipsecconf .= <<<EOD
638

    
639
conn bypasslan
640
	leftsubnet = {$lanip}/32
641
	rightsubnet = {$lansa}/{$lansn}
642
	authby = never
643
	type = passthrough
644
	auto = route
645

    
646
EOD;
647
				}
648
			}
649
		}
650

    
651
		foreach ($a_phase1 as $ph1ent) {
652
			if (isset($ph1ent['disabled']))
653
				continue;
654

    
655
			if ($ph1ent['mode'] == "aggressive")
656
				$aggressive = "yes";
657
			else
658
				$aggressive = "no";
659

    
660
			$ep = ipsec_get_phase1_src($ph1ent);
661
			if (!$ep)
662
				continue;
663

    
664
			$ikeid = $ph1ent['ikeid'];
665
			$keyexchange = "ikev1";
666
			$passive = "route";
667
			if (!empty($ph1ent['iketype'])) {
668
				if ($ph1ent['iketype'] == "ikev2") {
669
					$keyexchange = "ikev2";
670
					//$passive = "start";
671
				} else if ($ph1ent['iketype'] == "auto")
672
					$keyexchange = "ike";
673
			}
674

    
675
			if (isset($ph1ent['mobile'])) {
676
				$right_spec = "%any";
677
				$passive = 'add';
678
			} else {
679
				if (isset($ph1ent['responderonly']))
680
					$passive = 'add';
681

    
682
				$right_spec = $ph1ent['remote-gateway'];
683
				if (is_ipaddr($right_spec))
684
					$sourcehost = $right_spec;
685
				else
686
					$sourcehost = $rgmap['remote-gateway'];
687

    
688
				if ($ph1ent['protocol'] == 'inet') {
689
					if (strpos($ph1ent['interface'], '_vip')) {
690
						$vpninterface = explode('_vip', $ph1ent['interface']);
691
						$ifacesuse = get_real_interface($vpninterface[0]);
692
						$vpninterface = $vpninterface[0];
693
					} else {
694
						$ifacesuse = get_failover_interface($ph1ent['interface']);
695
						if (strpos($ifacesuse, '_vip')) {
696
							$vpninterface = explode('_vip', $ifacesuse);
697
							$ifacesuse = get_real_interface($vpninterface[0]);
698
							$vpninterface = $vpninterface[0];
699
						} else {
700
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
701
						}
702
					}
703
					
704
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
705
						$gatewayip = get_interface_gateway($vpninterface);
706
						$interfaceip = get_interface_ip($vpninterface);
707
						$subnet_bits = get_interface_subnet($vpninterface);
708
						$subnet_ip = gen_subnetv4($interfaceip, $subnet_bits);
709
						/* if the remote gateway is in the local subnet, then don't add a route */
710
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
711
							if (is_ipaddrv4($gatewayip)) {
712
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
713
								mwexec("/sbin/route change -host {$sourcehost} {$gatewayip}", true);
714
							}
715
						}
716
					}
717
				} else if ($ph1ent['protocol'] == 'inet6') {
718
					if (strpos($ph1ent['interface'], '_vip')) {
719
						$vpninterface = explode('_vip', $ph1ent['interface']);
720
						$ifacesuse = get_real_interface($vpninterface[0]);
721
						$vpninterface = $vpninterface[0];
722
					} else {
723
						$ifacesuse = get_failover_interface($ph1ent['interface']);
724
						if (strpos($ifacesuse, '_vip')) {
725
							$vpninterface = explode('_vip', $ifacesuse);
726
							$ifacesuse = get_real_interface($vpninterface[0]);
727
							$vpninterface = $vpninterface[0];
728
						} else {
729
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
730
						}
731
					}
732
					
733
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
734
						$gatewayip = get_interface_gateway_v6($vpninterface);
735
						$interfaceip = get_interface_ipv6($vpninterface);
736
						$subnet_bits = get_interface_subnetv6($vpninterface);
737
						$subnet_ip = gen_subnetv6($interfaceip, $subnet_bits);
738
						/* if the remote gateway is in the local subnet, then don't add a route */
739
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
740
							if (is_ipaddrv6($gatewayip)) {
741
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
742
								mwexec("/sbin/route change -inet6 -host {$sourcehost} {$gatewayip}", true);
743
							}
744
						}
745
					}
746
				}
747
			}
748

    
749
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
750
			if ($myid_type != 'address')
751
				$myid_data = "{$myid_type}:{$myid_data}";
752

    
753
			/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
754
			$peerid_spec = '';
755
			if (!isset($ph1ent['mobile'])) {
756
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
757
				if ($peerid_type != 'address')
758
					$peerid_spec = "{$peerid_type}:{$peerid_data}";
759
				else
760
					$peerid_spec = $peerid_data;
761
			}
762

    
763
			if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
764
				$ealgosp1 = '';
765
				$ealg_id = $ph1ent['encryption-algorithm']['name'];
766
				$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
767
				if ($ealg_kl)
768
					$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
769
				else
770
					$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
771

    
772
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
773
				if (!empty($modp))
774
					$ealgosp1 .= "-{$modp}";
775

    
776
				$ealgosp1 .= "!";
777
			}
778

    
779
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
780
				if ($passive == "route")
781
					$dpdline = "dpdaction = restart";
782
				else
783
					$dpdline = "dpdaction = clear";
784
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
785
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
786
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
787
			} else
788
				$dpdline = "dpdaction = none";
789

    
790
			$ikelifeline = '';
791
			if ($ph1ent['lifetime'])
792
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
793

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

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

    
858
			$left_spec = $ep;
859

    
860
			if (isset($ph1ent['reauth_enable']))
861
				$reauth = "reauth = no";
862
			else
863
				$reauth = "reauth = yes";
864
			if (isset($ph1ent['rekey_enable']))
865
				$rekey = "rekey = no";
866
			else
867
				$rekey = "rekey = yes";
868

    
869
			if ($ph1ent['nat_traversal'] == 'off')
870
				$forceencaps = 'forceencaps = no';
871
			else if ($ph1ent['nat_traversal'] == 'force')
872
				$forceencaps = 'forceencaps = yes';
873
			else
874
				$forceencaps = 'forceencaps = no';
875
				
876
			if ($ph1ent['mobike'] == 'on')
877
				$mobike = 'mobike = yes';
878
			else
879
				$mobike = 'mobike = no';
880

    
881
			$ipseclifetime = 0;
882
			$rightsubnet_spec = array();
883
			$leftsubnet_spec = array();
884
			$reqids = array();
885
			$ealgoAHsp2arr = array();
886
			$ealgoESPsp2arr = array();
887
		if (is_array($a_phase2) && count($a_phase2)) {
888
			foreach ($a_phase2 as $ph2ent) {
889
				if ($ikeid != $ph2ent['ikeid'])
890
					continue;
891

    
892
				if (isset($ph2ent['disabled']))
893
					continue;
894

    
895
				if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
896
					continue;
897

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

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

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

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

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

    
1024
				$reqids[] = $ph2ent['reqid'];
1025

    
1026
				if (!empty($ph2ent['lifetime'])) {
1027
					if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime']))
1028
						$ipseclifetime = intval($ph2ent['lifetime']);
1029
				}
1030

    
1031
			}
1032
		}
1033

    
1034
			$ipsecconnect =<<<EOD
1035
	fragmentation = yes
1036
	keyexchange = {$keyexchange}
1037
	{$reauth}
1038
	{$forceencaps}
1039
	{$mobike}
1040
	{$rekey}
1041
	installpolicy = yes
1042
	{$tunneltype}
1043
	{$dpdline}
1044
	auto = {$passive}
1045
	left = {$left_spec}
1046
	right = {$right_spec}
1047
	leftid = {$myid_data}
1048

    
1049
EOD;
1050

    
1051
			if (isset($config['ipsec']['compression'])) {
1052
				$ipsecconnect .= "\tcompress = yes\n";
1053
				$enablecompression = true;
1054
			}
1055
			if (!empty($ikelifeline))
1056
				$ipsecconnect .= "\t{$ikelifeline}\n";
1057
			if ($ipseclifetime > 0)
1058
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
1059
			if (!empty($rightsourceip))
1060
				$ipsecconnect .= "{$rightsourceip}";
1061
			if (!empty($ealgosp1))
1062
				$ipsecconnect .= "\t{$ealgosp1}\n";
1063
			if (!empty($ealgoAHsp2arr))
1064
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
1065
			if (!empty($ealgoESPsp2arr))
1066
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
1067
			if (!empty($authentication))
1068
				$ipsecconnect .= "\t{$authentication}\n";
1069
			if (!empty($peerid_spec))
1070
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
1071
			if ($keyexchange == 'ikev1')
1072
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
1073

    
1074
			if (!isset($ph1ent['mobile']) && $keyexchange == 'ikev1') {
1075
				if (!empty($rightsubnet_spec)) {
1076
					$ipsecfin = '';
1077
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
1078
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
1079
						if (!empty($reqids[$idx]))
1080
							$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
1081
						$ipsecfin .= $ipsecconnect;
1082
						$ipsecfin .= "\trightsubnet = {$rsubnet}\n";
1083
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n";
1084
					}
1085
				} else
1086
					log_error("No phase2 specifications for tunnel with REQID = {$ikeid}");
1087
			} else {
1088
				$ipsecfin = "\nconn con{$ph1ent['ikeid']}\n";
1089
				if (!empty($reqids[$idx]))
1090
					$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
1091
				$ipsecfin .= $ipsecconnect;
1092
				if (!isset($ph1ent['mobile']) && !empty($rightsubnet_spec)) {
1093
					$tempsubnets = array();
1094
					foreach ($rightsubnet_spec as $rightsubnet)
1095
						$tempsubnets[$rightsubnet] = $rightsubnet;
1096
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "\n";
1097
					unset($tempsubnets, $rightsubnet);
1098
				}
1099
				if (!empty($leftsubnet_spec)) {
1100
					$tempsubnets = array();
1101
					foreach ($leftsubnet_spec as $leftsubnet)
1102
						$tempsubnets[$leftsubnet] = $leftsubnet;
1103
					$ipsecfin .= "\tleftsubnet = " . join(",", $leftsubnet_spec) . "\n";
1104
					unset($tempsubnets, $leftsubnet);
1105
				}
1106
			}
1107
			$ipsecconf .= $ipsecfin;
1108
			unset($ipsecfin);
1109

    
1110
		}
1111
	}
1112

    
1113
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1114
	unset($ipsecconf);
1115
	/* end ipsec.conf */
1116

    
1117
	if ($enablecompression === true)
1118
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1119
	else
1120
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1121

    
1122
	/* mange process */
1123
	if ($restart === true) {
1124
		mwexec("/usr/local/sbin/ipsec restart", false); 
1125
	} else {
1126
		if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
1127
			/* Read secrets */
1128
			mwexec("/usr/local/sbin/ipsec rereadall", false);
1129
			/* Update configuration changes */
1130
			mwexec("/usr/local/sbin/ipsec update", false);
1131
		} else {
1132
			mwexec("/usr/local/sbin/ipsec start", false); 
1133
		}
1134
	}
1135

    
1136
	if ($natfilterrules == true)
1137
		filter_configure();
1138
	/* start filterdns, if necessary */
1139
	if (count($filterdns_list) > 0) {
1140
		$interval = 60;
1141
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
1142
			$interval = $ipseccfg['dns-interval'];
1143

    
1144
		$hostnames = "";
1145
		array_unique($filterdns_list);
1146
		foreach ($filterdns_list as $hostname)
1147
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1148
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1149
		unset($hostnames);
1150

    
1151
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
1152
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1153
		else {
1154
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1155
		}
1156
	} else {
1157
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1158
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1159
	}
1160

    
1161
	if (platform_booting())
1162
		echo "done\n";
1163

    
1164
	return count($filterdns_list);
1165
}
1166

    
1167
/*
1168
 * Forcefully restart IPsec
1169
 * This is required for when dynamic interfaces reload
1170
 * For all other occasions the normal vpn_ipsec_configure()
1171
 * will gracefully reload the settings without restarting
1172
 */
1173
function vpn_ipsec_force_reload($interface = "") {
1174
	global $g, $config;
1175

    
1176
	$ipseccfg = $config['ipsec'];
1177

    
1178
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1179
		$found = false;
1180
		foreach ($ipseccfg['phase1'] as $ipsec) {
1181
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1182
				$found = true;
1183
				break;
1184
			}
1185
		}
1186
		if (!$found) {
1187
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1188
			return;
1189
		}
1190
	}
1191

    
1192
	/* if ipsec is enabled, start up again */
1193
	if (isset($ipseccfg['enable'])) {
1194
		log_error(gettext("Forcefully reloading IPsec"));
1195
		vpn_ipsec_configure();
1196
	}
1197
}
1198

    
1199
/* master setup for vpn (mpd) */
1200
function vpn_setup() {
1201
	global $g;
1202

    
1203
	if ($g['platform'] == 'jail')
1204
		return;
1205

    
1206
	/* start pptpd */
1207
	vpn_pptpd_configure();
1208

    
1209
	/* start pppoe server */
1210
	vpn_pppoes_configure();
1211

    
1212
	/* setup l2tp */
1213
	vpn_l2tp_configure();
1214
}
1215

    
1216
function vpn_netgraph_support() {
1217
	$iflist = get_configured_interface_list();
1218
	foreach ($iflist as $iface) {
1219
		$realif = get_real_interface($iface);
1220
		/* Get support for netgraph(4) from the nic */
1221
		$ifinfo = pfSense_get_interface_addresses($realif);
1222
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
1223
			pfSense_ngctl_attach(".", $realif);
1224
	}
1225
}
1226

    
1227
function vpn_pptpd_configure() {
1228
	global $config, $g;
1229

    
1230
	$syscfg = $config['system'];
1231
	$pptpdcfg = $config['pptpd'];
1232

    
1233
	if (platform_booting()) {
1234
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
1235
			return 0;
1236

    
1237
		if (platform_booting(true))
1238
			echo gettext("Configuring PPTP VPN service... ");
1239
	} else {
1240
		/* kill mpd */
1241
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1242

    
1243
		/* wait for process to die */
1244
		sleep(3);
1245

    
1246
		if (is_process_running("mpd -b")) {
1247
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1248
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
1249
		}
1250

    
1251
		/* remove mpd.conf, if it exists */
1252
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
1253
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
1254
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
1255
	}
1256

    
1257
	if (empty($pptpdcfg['n_pptp_units'])) {
1258
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
1259
		return;
1260
	}
1261

    
1262
	/* make sure pptp-vpn directory exists */
1263
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
1264
		mkdir("{$g['varetc_path']}/pptp-vpn");
1265

    
1266
	switch ($pptpdcfg['mode']) {
1267
		case 'server' :
1268
			/* write mpd.conf */
1269
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1270
			if (!$fd) {
1271
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
1272
				return 1;
1273
			}
1274

    
1275
			$mpdconf = <<<EOD
1276
pptps:
1277

    
1278
EOD;
1279

    
1280
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1281
				$mpdconf .= "	load pt{$i}\n";
1282
			}
1283

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

    
1286
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1287

    
1288
				$mpdconf .= <<<EOD
1289

    
1290
pt{$i}:
1291
	new -i pptpd{$i} pt{$i} pt{$i}
1292
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1293
	load pts
1294

    
1295
EOD;
1296
			}
1297

    
1298
			$mpdconf .=<<<EOD
1299

    
1300
pts:
1301
	set iface disable on-demand
1302
	set iface enable proxy-arp
1303
	set iface enable tcpmssfix
1304
	set iface idle 1800
1305
	set iface up-script /usr/local/sbin/vpn-linkup
1306
	set iface down-script /usr/local/sbin/vpn-linkdown
1307
	set bundle enable multilink
1308
	set bundle enable crypt-reqd
1309
	set link yes acfcomp protocomp
1310
	set link no pap chap
1311
	set link enable chap-msv2
1312
	set link mtu 1460
1313
	set link keep-alive 10 60
1314
	set ipcp yes vjcomp
1315
	set bundle enable compression
1316
	set ccp yes mppc
1317
	set ccp yes mpp-e128
1318
	set ccp yes mpp-stateless
1319

    
1320
EOD;
1321

    
1322
			if (!isset ($pptpdcfg['req128'])) {
1323
				$mpdconf .=<<<EOD
1324
	set ccp yes mpp-e40
1325
	set ccp yes mpp-e56
1326

    
1327
EOD;
1328
			}
1329

    
1330
			if  (isset($pptpdcfg["wins"]) && $pptpdcfg['wins'] != "")
1331
				$mpdconf  .=  "	set ipcp nbns {$pptpdcfg['wins']}\n";
1332

    
1333
			if (!empty($pptpdcfg['dns1'])) {
1334
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1335
				if (!empty($pptpdcfg['dns2']))
1336
					$mpdconf .= " " . $pptpdcfg['dns2'];
1337
				$mpdconf .= "\n";
1338
			} elseif (isset ($config['dnsmasq']['enable'])) {
1339
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1340
				if ($syscfg['dnsserver'][0])
1341
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1342
				$mpdconf .= "\n";
1343
			} elseif (isset($config['unbound']['enable'])) {
1344
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1345
				if ($syscfg['dnsserver'][0])
1346
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1347
				$mpdconf .= "\n";
1348
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1349
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1350
			}
1351

    
1352
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1353
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1354
				$acctport = $authport + 1;
1355
				$mpdconf .=<<<EOD
1356
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1357

    
1358
EOD;
1359
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1360
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1361
				$acctport = $authport + 1;
1362
				$mpdconf .=<<<EOD
1363
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1364

    
1365
EOD;
1366
			}
1367
			$mpdconf .=<<<EOD
1368
	set radius retries 3
1369
	set radius timeout 10
1370
	set auth enable radius-auth
1371

    
1372
EOD;
1373

    
1374
				if (isset ($pptpdcfg['radius']['accounting'])) {
1375
					$mpdconf .=<<<EOD
1376
	set auth enable radius-acct
1377
	set radius acct-update 300
1378

    
1379
EOD;
1380
				}
1381
			}
1382

    
1383
			fwrite($fd, $mpdconf);
1384
			fclose($fd);
1385
			unset($mpdconf);
1386

    
1387
			/* write mpd.links */
1388
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1389
			if (!$fd) {
1390
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1391
				return 1;
1392
			}
1393

    
1394
			$mpdlinks = "";
1395

    
1396
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1397
				$mpdlinks .=<<<EOD
1398

    
1399
pt{$i}:
1400
	set link type pptp
1401
	set pptp enable incoming
1402
	set pptp disable originate
1403
	set pptp disable windowing
1404

    
1405
EOD;
1406
			}
1407

    
1408
			fwrite($fd, $mpdlinks);
1409
			fclose($fd);
1410
			unset($mpdlinks);
1411

    
1412
			/* write mpd.secret */
1413
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1414
			if (!$fd) {
1415
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1416
				return 1;
1417
			}
1418

    
1419
			$mpdsecret = "";
1420

    
1421
			if (is_array($pptpdcfg['user'])) {
1422
				foreach ($pptpdcfg['user'] as $user) {
1423
					$pass = str_replace('\\', '\\\\', $user['password']);
1424
					$pass = str_replace('"', '\"', $pass);
1425
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1426
				}
1427
			}
1428

    
1429
			fwrite($fd, $mpdsecret);
1430
			fclose($fd);
1431
			unset($mpdsecret);
1432
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1433

    
1434
			vpn_netgraph_support();
1435

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

    
1439
			break;
1440

    
1441
		case 'redir' :
1442
			break;
1443
	}
1444

    
1445
	if (platform_booting())
1446
		echo "done\n";
1447

    
1448
	return 0;
1449
}
1450

    
1451
function vpn_pppoes_configure() {
1452
	global $config;
1453

    
1454
	if (is_array($config['pppoes']['pppoe'])) {
1455
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1456
			vpn_pppoe_configure($pppoe);
1457
	}
1458
}
1459

    
1460
function vpn_pppoe_configure(&$pppoecfg) {
1461
	global $config, $g;
1462

    
1463
	$syscfg = $config['system'];
1464

    
1465
	/* create directory if it does not exist */
1466
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1467
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1468

    
1469
	if (platform_booting()) {
1470
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1471
			return 0;
1472

    
1473
		echo gettext("Configuring PPPoE Server service... ");
1474
	} else {
1475
		/* kill mpd */
1476
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1477

    
1478
		/* wait for process to die */
1479
		sleep(2);
1480

    
1481
	}
1482

    
1483
	switch ($pppoecfg['mode']) {
1484

    
1485
		case 'server' :
1486

    
1487
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1488

    
1489
			if ($pppoecfg['paporchap'] == "chap")
1490
				$paporchap = "set link enable chap";
1491
			else
1492
				$paporchap = "set link enable pap";
1493

    
1494
			/* write mpd.conf */
1495
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1496
			if (!$fd) {
1497
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1498
				return 1;
1499
			}
1500
			$mpdconf = "\n\n";
1501
			$mpdconf .= "poes:\n";
1502

    
1503
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1504
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1505
			}
1506

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

    
1509
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1510

    
1511
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1512
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1513
				} else {
1514
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1515
				}
1516

    
1517
				$mpdconf .=<<<EOD
1518

    
1519
poes{$pppoecfg['pppoeid']}{$i}:
1520
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1521
	{$isssue_ip_type}
1522
	load pppoe_standard
1523

    
1524
EOD;
1525
			}
1526

    
1527
			$mpdconf .=<<<EOD
1528

    
1529
pppoe_standard:
1530
	set bundle no multilink
1531
	set bundle enable compression
1532
	set auth max-logins 1
1533
	set iface up-script /usr/local/sbin/vpn-linkup
1534
	set iface down-script /usr/local/sbin/vpn-linkdown
1535
	set iface idle 0
1536
	set iface disable on-demand
1537
	set iface disable proxy-arp
1538
	set iface enable tcpmssfix
1539
	set iface mtu 1500
1540
	set link no pap chap
1541
	{$paporchap}
1542
	set link keep-alive 60 180
1543
	set ipcp yes vjcomp
1544
	set ipcp no vjcomp
1545
	set link max-redial -1
1546
	set link mtu 1492
1547
	set link mru 1492
1548
	set ccp yes mpp-e40
1549
	set ccp yes mpp-e128
1550
	set ccp yes mpp-stateless
1551
	set link latency 1
1552
	#set ipcp dns 10.10.1.3
1553
	#set bundle accept encryption
1554

    
1555
EOD;
1556

    
1557
			if (!empty($pppoecfg['dns1'])) {
1558
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1559
				if (!empty($pppoecfg['dns2']))
1560
					$mpdconf .= " " . $pppoecfg['dns2'];
1561
				$mpdconf .= "\n";
1562
			} elseif (isset ($config['dnsmasq']['enable'])) {
1563
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1564
				if ($syscfg['dnsserver'][0])
1565
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1566
				$mpdconf .= "\n";
1567
			} elseif (isset ($config['unbound']['enable'])) {
1568
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1569
				if ($syscfg['dnsserver'][0])
1570
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1571
				$mpdconf .= "\n";
1572
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1573
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1574
			}
1575

    
1576
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1577
				$radiusport = "";
1578
				$radiusacctport = "";
1579
				if (isset($pppoecfg['radius']['server']['port']))
1580
					$radiusport = $pppoecfg['radius']['server']['port'];
1581
				if (isset($pppoecfg['radius']['server']['acctport']))
1582
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1583
				$mpdconf .=<<<EOD
1584
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1585
	set radius retries 3
1586
	set radius timeout 10
1587
	set auth enable radius-auth
1588

    
1589
EOD;
1590

    
1591
				if (isset ($pppoecfg['radius']['accounting'])) {
1592
					$mpdconf .=<<<EOD
1593
	set auth enable radius-acct
1594

    
1595
EOD;
1596
				}
1597
			}
1598

    
1599
			fwrite($fd, $mpdconf);
1600
			fclose($fd);
1601
			unset($mpdconf);
1602

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

    
1610
			$mpdlinks = "";
1611

    
1612
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1613
				$mpdlinks .=<<<EOD
1614

    
1615
poes{$pppoecfg['pppoeid']}{$i}:
1616
	set phys type pppoe
1617
	set pppoe iface {$pppoe_interface}
1618
	set pppoe service "*"
1619
	set pppoe disable originate
1620
	set pppoe enable incoming
1621

    
1622
EOD;
1623
			}
1624

    
1625
			fwrite($fd, $mpdlinks);
1626
			fclose($fd);
1627
			unset($mpdlinks);
1628

    
1629
			if ($pppoecfg['username']) {
1630
				/* write mpd.secret */
1631
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1632
				if (!$fd) {
1633
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1634
					return 1;
1635
				}
1636

    
1637
				$mpdsecret = "\n\n";
1638

    
1639
				if (!empty($pppoecfg['username'])) {
1640
					$item = explode(" ", $pppoecfg['username']);
1641
					foreach($item as $userdata) {
1642
						$data = explode(":", $userdata);
1643
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1644
					}
1645
				}
1646

    
1647
				fwrite($fd, $mpdsecret);
1648
				fclose($fd);
1649
				unset($mpdsecret);
1650
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1651
			}
1652

    
1653
			/* Check if previous instance is still up */
1654
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid"))
1655
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1656

    
1657
			/* Get support for netgraph(4) from the nic */
1658
			pfSense_ngctl_attach(".", $pppoe_interface);
1659
			/* fire up mpd */
1660
			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");
1661

    
1662
			break;
1663
	}
1664

    
1665
	if (platform_booting())
1666
		echo gettext("done") . "\n";
1667

    
1668
	return 0;
1669
}
1670

    
1671
function vpn_l2tp_configure() {
1672
	global $config, $g;
1673

    
1674
	$syscfg = $config['system'];
1675
	$l2tpcfg = $config['l2tp'];
1676

    
1677
	/* create directory if it does not exist */
1678
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1679
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1680

    
1681
	if (platform_booting()) {
1682
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1683
			return 0;
1684

    
1685
		echo gettext("Configuring l2tp VPN service... ");
1686
	} else {
1687
		/* kill mpd */
1688
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1689

    
1690
		/* wait for process to die */
1691
		sleep(8);
1692

    
1693
	}
1694

    
1695
	/* make sure l2tp-vpn directory exists */
1696
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1697
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1698

    
1699
	switch ($l2tpcfg['mode']) {
1700

    
1701
		case 'server' :
1702
			if ($l2tpcfg['paporchap'] == "chap")
1703
				$paporchap = "set link enable chap";
1704
			else
1705
				$paporchap = "set link enable pap";
1706

    
1707
			/* write mpd.conf */
1708
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1709
			if (!$fd) {
1710
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1711
				return 1;
1712
			}
1713
			$mpdconf = "\n\n";
1714
			$mpdconf .=<<<EOD
1715
l2tps:
1716

    
1717
EOD;
1718

    
1719
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1720
				$mpdconf .= "	load l2tp{$i}\n";
1721
			}
1722

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

    
1725
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1726

    
1727
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1728
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1729
				} else {
1730
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1731
				}
1732

    
1733
				$mpdconf .=<<<EOD
1734

    
1735
l2tp{$i}:
1736
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1737
	{$isssue_ip_type}
1738
	load l2tp_standard
1739

    
1740
EOD;
1741
			}
1742

    
1743
			$mpdconf .=<<<EOD
1744

    
1745
l2tp_standard:
1746
	set bundle disable multilink
1747
	set bundle enable compression
1748
	set bundle yes crypt-reqd
1749
	set ipcp yes vjcomp
1750
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1751
	set ccp yes mppc
1752
	set iface disable on-demand
1753
	set iface enable proxy-arp
1754
	set iface up-script /usr/local/sbin/vpn-linkup
1755
	set iface down-script /usr/local/sbin/vpn-linkdown
1756
	set link yes acfcomp protocomp
1757
	set link no pap chap
1758
	{$paporchap}
1759
	set link keep-alive 10 180
1760

    
1761
EOD;
1762

    
1763
			if (is_ipaddr($l2tpcfg['wins'])) {
1764
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1765
			}
1766
			if (is_ipaddr($l2tpcfg['dns1'])) {
1767
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1768
				if (is_ipaddr($l2tpcfg['dns2']))
1769
					$mpdconf .= " " . $l2tpcfg['dns2'];
1770
				$mpdconf .= "\n";
1771
			} elseif (isset ($config['dnsmasq']['enable'])) {
1772
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1773
				if ($syscfg['dnsserver'][0])
1774
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1775
				$mpdconf .= "\n";
1776
			} elseif (isset ($config['unbound']['enable'])) {
1777
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1778
				if ($syscfg['dnsserver'][0])
1779
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1780
				$mpdconf .= "\n";
1781
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1782
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1783
			}
1784

    
1785
			if (isset ($l2tpcfg['radius']['enable'])) {
1786
				$mpdconf .=<<<EOD
1787
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1788
	set radius retries 3
1789
	set radius timeout 10
1790
	set auth enable radius-auth
1791

    
1792
EOD;
1793

    
1794
				if (isset ($l2tpcfg['radius']['accounting'])) {
1795
					$mpdconf .=<<<EOD
1796
	set auth enable radius-acct
1797

    
1798
EOD;
1799
				}
1800
			}
1801

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

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

    
1813
			$mpdlinks = "";
1814

    
1815
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1816
				$mpdlinks .=<<<EOD
1817

    
1818
l2tp{$i}:
1819
	set link type l2tp
1820
	set l2tp enable incoming
1821
	set l2tp disable originate
1822

    
1823
EOD;
1824
			if (!empty($l2tpcfg['secret']))
1825
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1826
			}
1827

    
1828
			fwrite($fd, $mpdlinks);
1829
			fclose($fd);
1830
			unset($mpdlinks);
1831

    
1832
			/* write mpd.secret */
1833
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1834
			if (!$fd) {
1835
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1836
				return 1;
1837
			}
1838

    
1839
			$mpdsecret = "\n\n";
1840

    
1841
			if (is_array($l2tpcfg['user'])) {
1842
				foreach ($l2tpcfg['user'] as $user)
1843
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1844
			}
1845

    
1846
			fwrite($fd, $mpdsecret);
1847
			fclose($fd);
1848
			unset($mpdsecret);
1849
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1850

    
1851
			vpn_netgraph_support();
1852

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

    
1856
			break;
1857

    
1858
		case 'redir' :
1859
			break;
1860
	}
1861

    
1862
	if (platform_booting())
1863
		echo "done\n";
1864

    
1865
	return 0;
1866
}
1867

    
1868
?>
(58-58/67)