Project

General

Profile

Download (53.6 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
	}
93

    
94
	return $convertion;
95
}
96

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

    
101
	if ($g['platform'] == 'jail')
102
		return;
103

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

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

    
116
		/* wait for process to die */
117
		sleep(2);
118

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

    
123
		filter_configure();
124

    
125
		return 0;
126
	}
127

    
128
	$a_phase1 = $config['ipsec']['phase1'];
129
	$a_phase2 = $config['ipsec']['phase2'];
130
	$a_client = $config['ipsec']['client'];
131

    
132
	$certpath = "{$g['varetc_path']}/ipsec/ipsec.d/certs";
133
	$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts";
134
	$keypath = "{$g['varetc_path']}/ipsec/ipsec.d/private";
135

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

    
161
	if (platform_booting())
162
		echo gettext("Configuring IPsec VPN... ");
163

    
164
	/* fastforwarding is not compatible with ipsec tunnels */
165
	set_single_sysctl("net.inet.ip.fastforwarding", "0");
166

    
167
	/* resolve all local, peer addresses and setup pings */
168
	$ipmap = array();
169
	$rgmap = array();
170
	$filterdns_list = array();
171
	$listeniflist = array();
172
	$aggressive_mode_psk = false;
173
	unset($iflist);
174
	$ifacesuse = array();
175
	if (is_array($a_phase1) && count($a_phase1)) {
176

    
177
		$ipsecpinghosts = "";
178
		/* step through each phase1 entry */
179
		foreach ($a_phase1 as $ph1ent) {
180
			if (isset($ph1ent['disabled']))
181
				continue;
182

    
183
			if (strpos($ph1ent['interface'], '_vip')) {
184
				$vpninterface = explode('_vip', $ph1ent['interface']);
185
				$ifacesuse[] = get_real_interface($vpninterface[0]);
186
                        } else {
187
                                $vpninterface = get_failover_interface($ph1ent['interface']);
188
				if (strpos($vpninterface, '_vip')) {
189
					$vpninterface = explode('_vip', $vpninterface);
190
					$ifacesuse[] = get_real_interface($vpninterface[0]);
191
				} elseif (!empty($vpninterface))
192
					$ifacesuse[] = $vpninterface;
193
			}
194
				
195
			if ($ph1ent['mode'] == "aggressive" && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) 
196
				$aggressive_mode_psk = true;
197

    
198
			$ikeid = $ph1ent['ikeid'];
199
			$listeniflist = get_real_interface($a_phase1['interface']);
200

    
201
			$ep = ipsec_get_phase1_src($ph1ent);
202
			if (!is_ipaddr($ep))
203
				continue;
204

    
205
			if(!in_array($ep,$ipmap))
206
				$ipmap[] = $ep;
207

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

    
211
			if (isset ($ph1ent['mobile']))
212
				continue;
213

    
214
			$rg = $ph1ent['remote-gateway'];
215

    
216
			if (!is_ipaddr($rg)) {
217
				$filterdns_list[] = "{$rg}";
218
				add_hostname_to_watch($rg);
219
				if (!platform_booting())
220
					$rg = resolve_retry($rg);
221
				if (!is_ipaddr($rg))
222
					continue;
223
			}
224
			if(array_search($rg, $rgmap)) {
225
				log_error("The remote gateway {$rg} already exists on another phase 1 entry");
226
				continue;
227
			}
228
			$rgmap[$ph1ent['remote-gateway']] = $rg;
229

    
230
			if (is_array($a_phase2)) {
231
				/* step through each phase2 entry */
232
				foreach ($a_phase2 as $ph2ent) {
233
					if (isset($ph2ent['disabled']))
234
						continue;
235

    
236
					if ($ikeid != $ph2ent['ikeid'])
237
						continue;
238

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

    
293
	$accept_unencrypted = "";
294
	if (isset($config['ipsec']['acceptunencryptedmainmode']))
295
		$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
296

    
297
	$stronconf = '';
298
	if (file_exists("{$g['varetc_path']}/ipsec/strongswan.conf"))
299
		$stronconf = file_get_contents("{$g['varetc_path']}/ipsec/strongswan.conf");
300

    
301
	$i_dont_care_about_security_and_use_aggressive_mode_psk = "";
302
	if ($aggressive_mode_psk) {
303
		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.");
304
		if (!empty($stronconf) && strpos($stronconf, 'i_dont_care_about_security_and_use_aggressive_mode_psk') === FALSE)
305
			$restart = true;
306
		$i_dont_care_about_security_and_use_aggressive_mode_psk = "i_dont_care_about_security_and_use_aggressive_mode_psk=yes";
307
	} 
308

    
309
	$unity_enabled = 'yes';
310
	if (isset($config['ipsec']['unityplugin'])) {
311
		$unity_enabled = 'no';
312
		if (file_exists("/usr/local/lib/ipsec/plugins/libstrongswan-unity.so")) {
313
			conf_mount_rw();
314
			mwexec("mv /usr/local/lib/ipsec/plugins/libstrongswan-unity.so /usr/local/lib/ipsec/plugins/libstrongswan-unity.MOVED");
315
			conf_mount_ro();
316
		}
317
	} else if (file_exists("/usr/local/lib/ipsec/plugins/libstrongswan-unity.MOVED")) {
318
		conf_mount_rw();
319
		mwexec("mv /usr/local/lib/ipsec/plugins/libstrongswan-unity.MOVED /usr/local/lib/ipsec/plugins/libstrongswan-unity.so");
320
		conf_mount_ro();
321
	}
322
	
323
	if (isset($config['ipsec']['enableinterfacesuse'])) {
324
		if (!empty($ifacesuse)) {
325
			$ifacesuse = 'interfaces_use = ' . implode(',', array_unique($ifacesuse));
326
		} else {
327
			$ifacesuse = '';
328
		}
329
	} else {
330
		$ifacesuse = '';
331
	}
332

    
333
	unset($stronconf);
334

    
335
	$strongswan = <<<EOD
336

    
337
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten. 
338
starter {
339
load_warning = no
340
}
341

    
342
charon {
343
# number of worker threads in charon
344
threads = 16
345
ikesa_table_size = 32
346
ikesa_table_segments = 4
347
init_limit_half_open = 1000
348
install_routes = no
349
{$i_dont_care_about_security_and_use_aggressive_mode_psk}
350
{$accept_unencrypted}
351
cisco_unity = {$unity_enabled}
352
{$ifacesuse}
353

    
354
# And two loggers using syslog. The subsections define the facility to log
355
# to, currently one of: daemon, auth.
356
syslog {
357
	identifier = charon
358
	# default level to the LOG_DAEMON facility
359
	daemon {
360
	}
361
	# very minimalistic IKE auditing logs to LOG_AUTHPRIV
362
	auth {
363
		default = -1
364
		ike = 1
365
		ike_name = yes
366
	}
367
}
368

    
369
EOD;
370

    
371
	$strongswan .= "\tplugins {\n";
372

    
373
	if (is_array($a_client) && isset($a_client['enable'])) {
374
		$strongswan .= "\t\tattr {\n";
375
		if ($a_client['pool_address'] && $a_client['pool_netbits'])
376
			$strongswan .= "\t\t\tsubnet = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
377

    
378
		$cfgservers = array();
379
		if (!empty($a_client['dns_server1']))
380
			$cfgservers[] = $a_client['dns_server1'];
381
		if (!empty($a_client['dns_server2']))
382
			$cfgservers[] = $a_client['dns_server2'];
383
		if (!empty($a_client['dns_server3']))
384
			$cfgservers[] = $a_client['dns_server3'];
385
		if (!empty($a_client['dns_server4']))
386
			$cfgservers[] = $a_client['dns_server4'];
387

    
388
		if (!empty($cfgservers))
389
			$strongswan .= "\t\t\tdns = " . implode(",", $cfgservers) . "\n";
390
		unset($cfgservers);
391
		$cfgservers = array();
392
		if (!empty($a_client['wins_server1']))
393
			$cfgservers[] = $a_client['wins_server1'];
394
		if (!empty($a_client['wins_server2']))
395
			$cfgservers[] = $a_client['wins_server2'];
396
		if (!empty($cfgservers))
397
			$strongswan .= "\t\t\tnbns = " . implode(",", $cfgservers) . "\n";
398
		unset($cfgservers);
399

    
400
		if (isset($a_client['net_list']) && is_array($a_phase2)) {
401
			$net_list = '';
402
			foreach ($a_phase2 as $ph2ent) {
403
				if (isset($ph2ent['disabled']))
404
					continue;
405

    
406
				if (!isset($ph2ent['mobile']))
407
					continue;
408

    
409
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
410

    
411
				if (!empty($net_list))
412
					$net_list .= ",";
413
				$net_list .= $localid;
414
			}
415

    
416
			if (!empty($net_list)) {
417
				$strongswan .= "\t\t\tsplit-include = {$net_list}\n";
418
				unset($net_list);
419
			}
420
		}
421

    
422
		if (!empty($a_client['dns_domain'])) {
423
			$strongswan .= "\t\t\t# Search domain and default domain\n";
424
			$strongswan .= "\t\t\t28674 = \"{$a_client['dns_domain']}\"\n";
425
			if (empty($a_client['dns_split'])) {
426
				$strongswan .= "\t\t\t28675 = \"{$a_client['dns_domain']}\"";
427
			}
428
			$strongswan .= "\n";
429
		}
430

    
431
		if (!empty($a_client['dns_split'])) {
432
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
433
		}
434

    
435
		if (!empty($a_client['login_banner']))
436
			$strongswan .= "\t\t\t28672 = \"{$a_client['login_banner']}\"\n";
437

    
438
		if (isset($a_client['save_passwd']))
439
			$strongswan .= "\t\t\t28673 = 1\n";
440

    
441
		if ($a_client['pfs_group'])
442
			$strongswan .= "\t\t\t28679 = \"{$a_client['pfs_group']}\"\n";
443
		$strongswan .= "\t\t}\n";
444

    
445
		if ($a_client['user_source'] != "none") {
446
			$strongswan .= "\t\txauth-generic {\n";
447
			$strongswan .= "\t\t\tscript = /etc/inc/ipsec.auth-user.php\n";
448
			$strongswan .= "\t\t\tauthcfg = ";
449
			$firstsed = 0;
450
			$authcfgs = explode(",", $a_client['user_source']);
451
			foreach ($authcfgs as $authcfg) {
452
				if ($firstsed > 0)
453
					$strongswan .= ",";
454
				if ($authcfg == "system")
455
					$authcfg = "Local Database";
456
				$strongswan .= $authcfg;
457
				$firstsed = 1;
458
			}
459
			$strongswan .= "\n";
460
			$strongswan .= "\t\t}\n";
461
		}
462
	}
463

    
464
	$strongswan .= "\t}\n}\n";
465
	@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
466
	unset($strongswan);
467

    
468
	/* generate CA certificates files */
469
	if (is_array($config['ca']) && count($config['ca'])) {
470
		foreach ($config['ca'] as $ca) {
471
			if (!isset($ca['crt'])) {
472
				log_error(sprintf(gettext("Error: Invalid certificate info for %s"), $ca['descr']));
473
				continue;
474
			}
475
			$cert = base64_decode($ca['crt']);
476
			$x509cert = openssl_x509_parse(openssl_x509_read($cert));
477
			if (!is_array($x509cert) || !isset($x509cert['hash'])) {
478
				log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $ca['descr']));
479
				continue;
480
			}
481
			$fname = "{$capath}/{$x509cert['hash']}.0.crt";
482
			if (!@file_put_contents($fname, $cert)) {
483
				log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $ca['descr']));
484
				continue;
485
			}
486
			unset($cert);
487
		}
488
	}
489

    
490
	$pskconf = "";
491

    
492
	if (is_array($a_phase1) && count($a_phase1)) {
493
		foreach ($a_phase1 as $ph1ent) {
494

    
495
			if (isset($ph1ent['disabled']))
496
				continue;
497

    
498
			if (strstr($ph1ent['authentication_method'], 'rsa') ||
499
			    in_array($ph1ent['authentication_method'], array('eap-mschapv2', 'eap-tls'))) {
500
				$certline = '';
501

    
502
				$ikeid = $ph1ent['ikeid'];
503
				$cert = lookup_cert($ph1ent['certref']);
504

    
505
				if (!$cert) {
506
					log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
507
					continue;
508
				}
509

    
510
				@chmod($certpath, 0600);
511

    
512
				$ph1keyfile = "{$keypath}/cert-{$ikeid}.key";
513
				if (!file_put_contents($ph1keyfile, base64_decode($cert['prv']))) {
514
					log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
515
					continue;
516
				}
517
				@chmod($ph1keyfile, 0600);
518

    
519
				$ph1certfile = "{$certpath}/cert-{$ikeid}.crt";
520
				if (!file_put_contents($ph1certfile, base64_decode($cert['crt']))) {
521
					log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name']));
522
					@unlink($ph1keyfile);
523
					continue;
524
				}
525
				@chmod($ph1certfile, 0600);
526

    
527
				/* XXX" Traffic selectors? */
528
				$pskconf .= " : RSA {$ph1keyfile}\n";
529
			} else {
530
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, "local");
531
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, "peer", $rgmap);
532

    
533
				if (empty($peerid_data))
534
					continue;
535

    
536
				$myid = isset($ph1ent['mobile']) ? trim($myid_data) : "%any";
537
				$peerid = ($peerid_data != "allusers") ? trim($peerid_data) : "";
538
				if (!empty($ph1ent['pre-shared-key'])) {
539
					if ($myid_type == 'fqdn' && !empty($myid_data))
540
						$pskconf .= "@{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
541
					else
542
						$pskconf .= "{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
543
				}
544
			}
545
		}
546
	}
547

    
548
	/* Add user PSKs */
549
	if (is_array($config['system']) && is_array($config['system']['user'])) {
550
		foreach ($config['system']['user'] as $user) {
551
			if (!empty($user['ipsecpsk'])) {
552
				$pskconf .= "%any {$user['name']} : PSK 0s" . base64_encode($user['ipsecpsk']) . "\n";
553
			}
554
		}
555
		unset($user);
556
	}
557

    
558
	/* add PSKs for mobile clients */
559
	if (is_array($ipseccfg['mobilekey'])) {
560
		foreach ($ipseccfg['mobilekey'] as $key) {
561
			if ($key['ident'] == "allusers")
562
				$key['ident'] = '%any';
563
			if (empty($key['type']))
564
				$key['type'] = 'PSK';
565
			$pskconf .= "%any {$key['ident']} : {$key['type']} 0s" . base64_encode($key['pre-shared-key']) . "\n";
566
		}
567
		unset($key);
568
	}
569

    
570
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
571
	chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
572
	unset($pskconf);
573

    
574
	$uniqueids = 'yes';
575
	if (!empty($config['ipsec']['uniqueids'])) {
576
		if (in_array($uniqueids, $ipsec_idhandling))
577
			$uniqueids = $config['ipsec']['uniqueids'];
578
	}
579
	$natfilterrules = false;
580
	/* begin ipsec.conf */
581
	$ipsecconf = "";
582
	$enablecompression = false;
583
	if (is_array($a_phase1) && count($a_phase1))  {
584

    
585
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
586
		$ipsecconf .= "config setup\n\tuniqueids = {$uniqueids}\n";
587
		$ipsecconf .= "\tcharondebug=\"" . vpn_ipsec_configure_loglevels(true) . "\"\n";
588

    
589
		foreach ($a_phase1 as $ph1ent) {
590
			if (isset($ph1ent['disabled']))
591
				continue;
592

    
593
			if ($ph1ent['mode'] == "aggressive")
594
				$aggressive = "yes";
595
			else
596
				$aggressive = "no";
597

    
598
			$ep = ipsec_get_phase1_src($ph1ent);
599
			if (!$ep)
600
				continue;
601

    
602
			$ikeid = $ph1ent['ikeid'];
603
			$keyexchange = "ikev1";
604
			$passive = "route";
605
			if (!empty($ph1ent['iketype'])) {
606
				if ($ph1ent['iketype'] == "ikev2") {
607
					$keyexchange = "ikev2";
608
					//$passive = "start";
609
				} else if ($ph1ent['iketype'] == "auto")
610
					$keyexchange = "ike";
611
			}
612

    
613
			if (isset($ph1ent['mobile'])) {
614
				$right_spec = "%any";
615
				$passive = 'add';
616
			} else {
617
				if (isset($ph1ent['responderonly']))
618
					$passive = 'add';
619

    
620
				$right_spec = $ph1ent['remote-gateway'];
621
				if (is_ipaddr($right_spec))
622
					$sourcehost = $right_spec;
623
				else
624
					$sourcehost = $rgmap['remote-gateway'];
625

    
626
				if ($ph1ent['protocol'] == 'inet') {
627
					if (strpos($ph1ent['interface'], '_vip')) {
628
						$vpninterface = explode('_vip', $ph1ent['interface']);
629
						$ifacesuse = get_real_interface($vpninterface[0]);
630
						$vpninterface = $vpninterface[0];
631
					} else {
632
						$ifacesuse = get_failover_interface($ph1ent['interface']);
633
						if (strpos($ifacesuse, '_vip')) {
634
							$vpninterface = explode('_vip', $ifacesuse);
635
							$ifacesuse = get_real_interface($vpninterface[0]);
636
							$vpninterface = $vpninterface[0];
637
						} else {
638
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
639
						}
640
					}
641
					
642
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
643
						$gatewayip = get_interface_gateway($vpninterface);
644
						$interfaceip = get_interface_ip($vpninterface);
645
						$subnet_bits = get_interface_subnet($vpninterface);
646
						$subnet_ip = gen_subnetv4($interfaceip, $subnet_bits);
647
						/* if the remote gateway is in the local subnet, then don't add a route */
648
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
649
							if (is_ipaddrv4($gatewayip)) {
650
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
651
								mwexec("/sbin/route change -host {$sourcehost} {$gatewayip}", true);
652
							}
653
						}
654
					}
655
				} else if ($ph1ent['protocol'] == 'inet6') {
656
					if (strpos($ph1ent['interface'], '_vip')) {
657
						$vpninterface = explode('_vip', $ph1ent['interface']);
658
						$ifacesuse = get_real_interface($vpninterface[0]);
659
						$vpninterface = $vpninterface[0];
660
					} else {
661
						$ifacesuse = get_failover_interface($ph1ent['interface']);
662
						if (strpos($ifacesuse, '_vip')) {
663
							$vpninterface = explode('_vip', $ifacesuse);
664
							$ifacesuse = get_real_interface($vpninterface[0]);
665
							$vpninterface = $vpninterface[0];
666
						} else {
667
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
668
						}
669
					}
670
					
671
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
672
						$gatewayip = get_interface_gateway_v6($vpninterface);
673
						$interfaceip = get_interface_ipv6($vpninterface);
674
						$subnet_bits = get_interface_subnetv6($vpninterface);
675
						$subnet_ip = gen_subnetv6($interfaceip, $subnet_bits);
676
						/* if the remote gateway is in the local subnet, then don't add a route */
677
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
678
							if (is_ipaddrv6($gatewayip)) {
679
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
680
								mwexec("/sbin/route change -inet6 -host {$sourcehost} {$gatewayip}", true);
681
							}
682
						}
683
					}
684
				}
685
			}
686

    
687
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, "local");
688
			if ($myid_type == 'fqdn')
689
				$myid_data = "@{$myid_data}";
690
			list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, "peer", $rgmap);
691
			if ($peerid_type == 'fqdn')
692
				$peerid_data = "@{$peerid_data}";
693

    
694
			/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
695
			$peerid_spec = '';
696
			if (!isset($ph1ent['mobile']))
697
				$peerid_spec = $peerid_data;
698

    
699
			if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
700
				$ealgosp1 = '';
701
				$ealg_id = $ph1ent['encryption-algorithm']['name'];
702
				$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
703
				if ($ealg_kl)
704
					$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
705
				else
706
					$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
707

    
708
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
709
				if (!empty($modp))
710
					$ealgosp1 .= "-{$modp}";
711

    
712
				$ealgosp1 .= "!";
713
			}
714

    
715
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
716
				if ($passive == "route")
717
					$dpdline = "dpdaction = restart";
718
				else
719
					$dpdline = "dpdaction = clear";
720
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
721
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
722
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
723
			} else
724
				$dpdline = "dpdaction = none";
725

    
726
			$ikelifeline = '';
727
			if ($ph1ent['lifetime'])
728
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
729

    
730
			$rightsourceip = NULL;
731
			if (isset($ph1ent['mobile']) && !empty($a_client['pool_address'])) 
732
				$rightsourceip = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
733

    
734
			$authentication = "";
735
			switch ($ph1ent['authentication_method']) {
736
			case 'eap-mschapv2':
737
				if (isset($ph1ent['mobile'])) {
738
					$authentication = "eap_identity=%any\n\t";
739
					$authentication .= "leftauth=pubkey\n\trightauth=eap-mschapv2";
740
					if (!empty($ph1ent['certref']))
741
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
742
				}
743
				break;
744
			case 'eap-tls':
745
				if (isset($ph1ent['mobile'])) {
746
					$authentication = "eap_identity=%identity\n\t";
747
					$authentication .= "leftauth=pubkey\n\trightauth=eap-tls";
748
					if (!empty($ph1ent['certref']))
749
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
750
				} else {
751
					$authentication = "leftauth=eap-tls\n\trightauth=eap-tls";
752
					if (!empty($ph1ent['certref']))
753
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
754
				}
755
				break;
756
			case 'xauth_rsa_server':
757
				$authentication = "leftauth = pubkey\n\trightauth = pubkey";
758
				$authentication .= "\n\trightauth2 = xauth-generic";
759
				if (!empty($ph1ent['certref']))
760
					$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
761
				break;
762
			case 'xauth_psk_server':
763
				$authentication = "leftauth = psk\n\trightauth = psk";
764
				$authentication .= "\n\trightauth2 = xauth-generic";
765
				break;
766
			case 'pre_shared_key':
767
				$authentication = "leftauth = psk\n\trightauth = psk";
768
				break;
769
			case 'rsasig':
770
				$authentication = "leftauth = pubkey\n\trightauth = pubkey";
771
				if (!empty($ph1ent['certref']))
772
					$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
773
				break;
774
			case 'hybrid_rsa_server':
775
				$authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
776
				$authentication .= "\n\trightauth2 = xauth";
777
				if (!empty($ph1ent['certref']))
778
					$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
779
				break;
780
			}
781

    
782
			$left_spec = $ep;
783

    
784
			if (isset($ph1ent['reauth_enable']))
785
				$reauth = "reauth = no";
786
			else
787
				$reauth = "reauth = yes";
788
			if (isset($ph1ent['rekey_enable']))
789
				$rekey = "rekey = no";
790
			else
791
				$rekey = "rekey = yes";
792

    
793
			if ($ph1ent['nat_traversal'] == 'off')
794
				$forceencaps = 'forceencaps = no';
795
			else if ($ph1ent['nat_traversal'] == 'force')
796
				$forceencaps = 'forceencaps = yes';
797
			else
798
				$forceencaps = 'forceencaps = no';
799
				
800
			if ($ph1ent['mobike'] == 'on')
801
				$mobike = 'mobike = yes';
802
			else
803
				$mobike = 'mobike = no';
804

    
805
			$ipseclifetime = 0;
806
			$rightsubnet_spec = array();
807
			$leftsubnet_spec = array();
808
			$reqids = array();
809
			$ealgoAHsp2arr = array();
810
			$ealgoESPsp2arr = array();
811
		if (is_array($a_phase2) && count($a_phase2)) {
812
			foreach ($a_phase2 as $ph2ent) {
813
				if ($ikeid != $ph2ent['ikeid'])
814
					continue;
815

    
816
				if (isset($ph2ent['disabled']))
817
					continue;
818

    
819
				if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
820
					continue;
821

    
822
				if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
823
					$tunneltype = "type = tunnel";
824

    
825
					$localid_type = $ph2ent['localid']['type'];
826
					$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
827

    
828
					/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
829
					if (($localid_type == "none" || $localid_type == "mobile")
830
					    && isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ikeid)==1)) {
831
						$left_spec = '%any';
832
					} else {
833
						if ($localid_type != "address") {
834
							$localid_type = "subnet";
835
						}
836
						// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
837
						if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) {
838
							log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
839
							continue;
840
						}
841
						if (!empty($ph2ent['natlocalid'])) {
842
							$natleftsubnet_data =  ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
843
							if ($ph2ent['natlocalid']['type'] != "address") {
844
								if (is_subnet($natleftsubnet_data))
845
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
846
							} else {
847
								if (is_ipaddr($natleftsubnet_data))
848
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
849
							}
850
							$natfilterrules = true;
851
						}
852
					}
853

    
854
					$leftsubnet_spec[] = $leftsubnet_data;
855

    
856
					if (!isset($ph2ent['mobile'])) {
857
						$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
858
						$rightsubnet_spec[] = $tmpsubnet;
859
					} else if (!empty($a_client['pool_address'])) {
860
						$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
861
					}
862
				} else {
863
					$tunneltype = "type = transport";
864

    
865
					if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
866
					    ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) {
867
						$left_spec = "%any";
868
					} else {
869
						$tmpsubnet = ipsec_get_phase1_src($ph1ent);
870
						$leftsubnet_spec[] = $tmpsubnet;
871
					}
872

    
873
					if (!isset($ph2ent['mobile'])) {
874
						$rightsubnet_spec[] = $right_spec;
875
					}
876
				}
877

    
878
				if (isset($a_client['pfs_group']))
879
					$ph2ent['pfsgroup'] = $a_client['pfs_group'];
880

    
881
				if ($ph2ent['protocol'] == 'esp') {
882
					if (is_array($ph2ent['encryption-algorithm-option'])) {
883
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
884
							$ealg_id = $ealg['name'];
885
							$ealg_kl = $ealg['keylen'];
886

    
887
							if (!empty($ealg_kl) && $ealg_kl == "auto") {
888
								if (empty($p2_ealgos) || !is_array($p2_ealgos))
889
									require("ipsec.inc");
890
								$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
891
								$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
892
								$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
893
								/* XXX: in some cases where include ordering is suspect these variables
894
								 * are somehow 0 and we enter this loop forever and timeout after 900
895
								 * seconds wrecking bootup */
896
								if ($key_hi != 0 and $key_lo !=0 and $key_step !=0) {
897
									for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
898
										if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
899
											foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
900
												$halgo = str_replace('hmac_', '', $halgo);
901
												$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
902
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
903
												if (!empty($modp))
904
													$tmpealgo .= "-{$modp}";
905
												$ealgoESPsp2arr[] = $tmpealgo;
906
											}
907
										} else {
908
											$tmpealgo = "{$ealg_id}{$keylen}";
909
											$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
910
											if (!empty($modp))
911
												$tmpealgo .= "-{$modp}";
912
											$ealgoESPsp2arr[] = $tmpealgo;
913
										}
914
									}
915
								}
916
							} else {
917
								if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
918
									foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
919
										$halgo = str_replace('hmac_', '', $halgo);
920
										$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
921
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
922
										if (!empty($modp))
923
											$tmpealgo .= "-{$modp}";
924
										$ealgoESPsp2arr[] = $tmpealgo;
925
									}
926
								} else {
927
									$tmpealgo = "{$ealg_id}{$ealg_kl}";
928
									$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
929
									if (!empty($modp))
930
										$tmpealgo .= "-{$modp}";
931
									$ealgoESPsp2arr[] = $tmpealgo;
932
								}
933
							}
934
						}
935
					}
936
				} else if ($ph2ent['protocol'] == 'ah') {
937
					if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
938
						$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
939
						foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
940
							$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
941
							if (!empty($modp))
942
								$tmpAHalgo = "-{$modp}";
943
							$ealgoAHsp2arr[] = $tmpAHalgo;
944
						}
945
					}
946
				}
947

    
948
				$reqids[] = $ph2ent['reqid'];
949

    
950
				if (!empty($ph2ent['lifetime'])) {
951
					if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime']))
952
						$ipseclifetime = intval($ph2ent['lifetime']);
953
				}
954

    
955
			}
956
		}
957

    
958
			$ipsecconnect =<<<EOD
959
	fragmentation = yes
960
	keyexchange = {$keyexchange}
961
	{$reauth}
962
	{$forceencaps}
963
	{$mobike}
964
	{$rekey}
965
	installpolicy = yes
966
	{$tunneltype}
967
	{$dpdline}
968
	auto = {$passive}
969
	left = {$left_spec}
970
	right = {$right_spec}
971
	leftid = {$myid_data}
972

    
973
EOD;
974

    
975
			if (isset($config['ipsec']['compression'])) {
976
				$ipsecconnect .= "\tcompress = yes\n";
977
				$enablecompression = true;
978
			}
979
			if (!empty($ikelifeline))
980
				$ipsecconnect .= "\t{$ikelifeline}\n";
981
			if ($ipseclifetime > 0)
982
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
983
			if (!empty($rightsourceip))
984
				$ipsecconnect .= "{$rightsourceip}";
985
			if (!empty($ealgosp1))
986
				$ipsecconnect .= "\t{$ealgosp1}\n";
987
			if (!empty($ealgoAHsp2arr))
988
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
989
			if (!empty($ealgoESPsp2arr))
990
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
991
			if (!empty($authentication))
992
				$ipsecconnect .= "\t{$authentication}\n";
993
			if (!empty($peerid_spec))
994
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
995
			if ($keyexchange == 'ikev1')
996
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
997

    
998
			if (!isset($ph1ent['mobile']) && $keyexchange == 'ikev1') {
999
				if (!empty($rightsubnet_spec)) {
1000
					$ipsecfin = '';
1001
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
1002
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
1003
						if (!empty($reqids[$idx]))
1004
							$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
1005
						$ipsecfin .= $ipsecconnect;
1006
						$ipsecfin .= "\trightsubnet = {$rsubnet}\n";
1007
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n";
1008
					}
1009
				} else
1010
					log_error("No phase2 specifications for tunnel with REQID = {$ikeid}");
1011
			} else {
1012
				$ipsecfin = "\nconn con{$ph1ent['ikeid']}\n";
1013
				if (!empty($reqids[$idx]))
1014
					$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
1015
				$ipsecfin .= $ipsecconnect;
1016
				if (!isset($ph1ent['mobile']) && !empty($rightsubnet_spec)) {
1017
					$tempsubnets = array();
1018
					foreach ($rightsubnet_spec as $rightsubnet)
1019
						$tempsubnets[$rightsubnet] = $rightsubnet;
1020
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "\n";
1021
					unset($tempsubnets, $rightsubnet);
1022
				}
1023
				if (!empty($leftsubnet_spec)) {
1024
					$tempsubnets = array();
1025
					foreach ($leftsubnet_spec as $leftsubnet)
1026
						$tempsubnets[$leftsubnet] = $leftsubnet;
1027
					$ipsecfin .= "\tleftsubnet = " . join(",", $leftsubnet_spec) . "\n";
1028
					unset($tempsubnets, $leftsubnet);
1029
				}
1030
			}
1031
			$ipsecconf .= $ipsecfin;
1032
			unset($ipsecfin);
1033

    
1034
		}
1035
	}
1036

    
1037
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1038
	unset($ipsecconf);
1039
	/* end ipsec.conf */
1040

    
1041
	if ($enablecompression === true)
1042
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1043
	else
1044
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1045

    
1046
	/* mange process */
1047
	if ($restart === true) {
1048
		mwexec("/usr/local/sbin/ipsec restart", false); 
1049
	} else {
1050
		if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
1051
			/* Read secrets */
1052
			mwexec("/usr/local/sbin/ipsec rereadall", false);
1053
			/* Update configuration changes */
1054
			mwexec("/usr/local/sbin/ipsec update", false);
1055
		} else {
1056
			mwexec("/usr/local/sbin/ipsec start", false); 
1057
		}
1058
	}
1059

    
1060
	if ($natfilterrules == true)
1061
		filter_configure();
1062
	/* start filterdns, if necessary */
1063
	if (count($filterdns_list) > 0) {
1064
		$interval = 60;
1065
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
1066
			$interval = $ipseccfg['dns-interval'];
1067

    
1068
		$hostnames = "";
1069
		array_unique($filterdns_list);
1070
		foreach ($filterdns_list as $hostname)
1071
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1072
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1073
		unset($hostnames);
1074

    
1075
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
1076
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1077
		else {
1078
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1079
		}
1080
	} else {
1081
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1082
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1083
	}
1084

    
1085
	if (platform_booting())
1086
		echo "done\n";
1087

    
1088
	return count($filterdns_list);
1089
}
1090

    
1091
/*
1092
 * Forcefully restart IPsec
1093
 * This is required for when dynamic interfaces reload
1094
 * For all other occasions the normal vpn_ipsec_configure()
1095
 * will gracefully reload the settings without restarting
1096
 */
1097
function vpn_ipsec_force_reload($interface = "") {
1098
	global $g, $config;
1099

    
1100
	$ipseccfg = $config['ipsec'];
1101

    
1102
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1103
		$found = false;
1104
		foreach ($ipseccfg['phase1'] as $ipsec) {
1105
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1106
				$found = true;
1107
				break;
1108
			}
1109
		}
1110
		if (!$found) {
1111
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1112
			return;
1113
		}
1114
	}
1115

    
1116
	/* if ipsec is enabled, start up again */
1117
	if (isset($ipseccfg['enable'])) {
1118
		log_error(gettext("Forcefully reloading IPsec"));
1119
		vpn_ipsec_configure();
1120
	}
1121
}
1122

    
1123
/* master setup for vpn (mpd) */
1124
function vpn_setup() {
1125
	global $g;
1126

    
1127
	if ($g['platform'] == 'jail')
1128
		return;
1129

    
1130
	/* start pptpd */
1131
	vpn_pptpd_configure();
1132

    
1133
	/* start pppoe server */
1134
	vpn_pppoes_configure();
1135

    
1136
	/* setup l2tp */
1137
	vpn_l2tp_configure();
1138
}
1139

    
1140
function vpn_netgraph_support() {
1141
	$iflist = get_configured_interface_list();
1142
	foreach ($iflist as $iface) {
1143
		$realif = get_real_interface($iface);
1144
		/* Get support for netgraph(4) from the nic */
1145
		$ifinfo = pfSense_get_interface_addresses($realif);
1146
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
1147
			pfSense_ngctl_attach(".", $realif);
1148
	}
1149
}
1150

    
1151
function vpn_pptpd_configure() {
1152
	global $config, $g;
1153

    
1154
	$syscfg = $config['system'];
1155
	$pptpdcfg = $config['pptpd'];
1156

    
1157
	if (platform_booting()) {
1158
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
1159
			return 0;
1160

    
1161
		if (platform_booting(true))
1162
			echo gettext("Configuring PPTP VPN service... ");
1163
	} else {
1164
		/* kill mpd */
1165
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1166

    
1167
		/* wait for process to die */
1168
		sleep(3);
1169

    
1170
		if (is_process_running("mpd -b")) {
1171
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1172
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
1173
		}
1174

    
1175
		/* remove mpd.conf, if it exists */
1176
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
1177
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
1178
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
1179
	}
1180

    
1181
	if (empty($pptpdcfg['n_pptp_units'])) {
1182
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
1183
		return;
1184
	}
1185

    
1186
	/* make sure pptp-vpn directory exists */
1187
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
1188
		mkdir("{$g['varetc_path']}/pptp-vpn");
1189

    
1190
	switch ($pptpdcfg['mode']) {
1191
		case 'server' :
1192
			/* write mpd.conf */
1193
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1194
			if (!$fd) {
1195
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
1196
				return 1;
1197
			}
1198

    
1199
			$mpdconf = <<<EOD
1200
pptps:
1201

    
1202
EOD;
1203

    
1204
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1205
				$mpdconf .= "	load pt{$i}\n";
1206
			}
1207

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

    
1210
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1211

    
1212
				$mpdconf .= <<<EOD
1213

    
1214
pt{$i}:
1215
	new -i pptpd{$i} pt{$i} pt{$i}
1216
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1217
	load pts
1218

    
1219
EOD;
1220
			}
1221

    
1222
			$mpdconf .=<<<EOD
1223

    
1224
pts:
1225
	set iface disable on-demand
1226
	set iface enable proxy-arp
1227
	set iface enable tcpmssfix
1228
	set iface idle 1800
1229
	set iface up-script /usr/local/sbin/vpn-linkup
1230
	set iface down-script /usr/local/sbin/vpn-linkdown
1231
	set bundle enable multilink
1232
	set bundle enable crypt-reqd
1233
	set link yes acfcomp protocomp
1234
	set link no pap chap
1235
	set link enable chap-msv2
1236
	set link mtu 1460
1237
	set link keep-alive 10 60
1238
	set ipcp yes vjcomp
1239
	set bundle enable compression
1240
	set ccp yes mppc
1241
	set ccp yes mpp-e128
1242
	set ccp yes mpp-stateless
1243

    
1244
EOD;
1245

    
1246
			if (!isset ($pptpdcfg['req128'])) {
1247
				$mpdconf .=<<<EOD
1248
	set ccp yes mpp-e40
1249
	set ccp yes mpp-e56
1250

    
1251
EOD;
1252
			}
1253

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

    
1257
			if (!empty($pptpdcfg['dns1'])) {
1258
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1259
				if (!empty($pptpdcfg['dns2']))
1260
					$mpdconf .= " " . $pptpdcfg['dns2'];
1261
				$mpdconf .= "\n";
1262
			} elseif (isset ($config['dnsmasq']['enable'])) {
1263
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1264
				if ($syscfg['dnsserver'][0])
1265
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1266
				$mpdconf .= "\n";
1267
			} elseif (isset($config['unbound']['enable'])) {
1268
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1269
				if ($syscfg['dnsserver'][0])
1270
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1271
				$mpdconf .= "\n";
1272
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1273
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1274
			}
1275

    
1276
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1277
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1278
				$acctport = $authport + 1;
1279
				$mpdconf .=<<<EOD
1280
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1281

    
1282
EOD;
1283
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1284
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1285
				$acctport = $authport + 1;
1286
				$mpdconf .=<<<EOD
1287
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1288

    
1289
EOD;
1290
			}
1291
			$mpdconf .=<<<EOD
1292
	set radius retries 3
1293
	set radius timeout 10
1294
	set auth enable radius-auth
1295

    
1296
EOD;
1297

    
1298
				if (isset ($pptpdcfg['radius']['accounting'])) {
1299
					$mpdconf .=<<<EOD
1300
	set auth enable radius-acct
1301
	set radius acct-update 300
1302

    
1303
EOD;
1304
				}
1305
			}
1306

    
1307
			fwrite($fd, $mpdconf);
1308
			fclose($fd);
1309
			unset($mpdconf);
1310

    
1311
			/* write mpd.links */
1312
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1313
			if (!$fd) {
1314
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1315
				return 1;
1316
			}
1317

    
1318
			$mpdlinks = "";
1319

    
1320
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1321
				$mpdlinks .=<<<EOD
1322

    
1323
pt{$i}:
1324
	set link type pptp
1325
	set pptp enable incoming
1326
	set pptp disable originate
1327
	set pptp disable windowing
1328

    
1329
EOD;
1330
			}
1331

    
1332
			fwrite($fd, $mpdlinks);
1333
			fclose($fd);
1334
			unset($mpdlinks);
1335

    
1336
			/* write mpd.secret */
1337
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1338
			if (!$fd) {
1339
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1340
				return 1;
1341
			}
1342

    
1343
			$mpdsecret = "";
1344

    
1345
			if (is_array($pptpdcfg['user'])) {
1346
				foreach ($pptpdcfg['user'] as $user) {
1347
					$pass = str_replace('\\', '\\\\', $user['password']);
1348
					$pass = str_replace('"', '\"', $pass);
1349
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1350
				}
1351
			}
1352

    
1353
			fwrite($fd, $mpdsecret);
1354
			fclose($fd);
1355
			unset($mpdsecret);
1356
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1357

    
1358
			vpn_netgraph_support();
1359

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

    
1363
			break;
1364

    
1365
		case 'redir' :
1366
			break;
1367
	}
1368

    
1369
	if (platform_booting())
1370
		echo "done\n";
1371

    
1372
	return 0;
1373
}
1374

    
1375
function vpn_pppoes_configure() {
1376
	global $config;
1377

    
1378
	if (is_array($config['pppoes']['pppoe'])) {
1379
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1380
			vpn_pppoe_configure($pppoe);
1381
	}
1382
}
1383

    
1384
function vpn_pppoe_configure(&$pppoecfg) {
1385
	global $config, $g;
1386

    
1387
	$syscfg = $config['system'];
1388

    
1389
	/* create directory if it does not exist */
1390
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1391
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1392

    
1393
	if (platform_booting()) {
1394
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1395
			return 0;
1396

    
1397
		echo gettext("Configuring PPPoE Server service... ");
1398
	} else {
1399
		/* kill mpd */
1400
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1401

    
1402
		/* wait for process to die */
1403
		sleep(2);
1404

    
1405
	}
1406

    
1407
	switch ($pppoecfg['mode']) {
1408

    
1409
		case 'server' :
1410

    
1411
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1412

    
1413
			if ($pppoecfg['paporchap'] == "chap")
1414
				$paporchap = "set link enable chap";
1415
			else
1416
				$paporchap = "set link enable pap";
1417

    
1418
			/* write mpd.conf */
1419
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1420
			if (!$fd) {
1421
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1422
				return 1;
1423
			}
1424
			$mpdconf = "\n\n";
1425
			$mpdconf .= "poes:\n";
1426

    
1427
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1428
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1429
			}
1430

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

    
1433
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1434

    
1435
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1436
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1437
				} else {
1438
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1439
				}
1440

    
1441
				$mpdconf .=<<<EOD
1442

    
1443
poes{$pppoecfg['pppoeid']}{$i}:
1444
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1445
	{$isssue_ip_type}
1446
	load pppoe_standard
1447

    
1448
EOD;
1449
			}
1450

    
1451
			$mpdconf .=<<<EOD
1452

    
1453
pppoe_standard:
1454
	set bundle no multilink
1455
	set bundle enable compression
1456
	set auth max-logins 1
1457
	set iface up-script /usr/local/sbin/vpn-linkup
1458
	set iface down-script /usr/local/sbin/vpn-linkdown
1459
	set iface idle 0
1460
	set iface disable on-demand
1461
	set iface disable proxy-arp
1462
	set iface enable tcpmssfix
1463
	set iface mtu 1500
1464
	set link no pap chap
1465
	{$paporchap}
1466
	set link keep-alive 60 180
1467
	set ipcp yes vjcomp
1468
	set ipcp no vjcomp
1469
	set link max-redial -1
1470
	set link mtu 1492
1471
	set link mru 1492
1472
	set ccp yes mpp-e40
1473
	set ccp yes mpp-e128
1474
	set ccp yes mpp-stateless
1475
	set link latency 1
1476
	#set ipcp dns 10.10.1.3
1477
	#set bundle accept encryption
1478

    
1479
EOD;
1480

    
1481
			if (!empty($pppoecfg['dns1'])) {
1482
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1483
				if (!empty($pppoecfg['dns2']))
1484
					$mpdconf .= " " . $pppoecfg['dns2'];
1485
				$mpdconf .= "\n";
1486
			} elseif (isset ($config['dnsmasq']['enable'])) {
1487
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1488
				if ($syscfg['dnsserver'][0])
1489
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1490
				$mpdconf .= "\n";
1491
			} elseif (isset ($config['unbound']['enable'])) {
1492
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1493
				if ($syscfg['dnsserver'][0])
1494
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1495
				$mpdconf .= "\n";
1496
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1497
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1498
			}
1499

    
1500
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1501
				$radiusport = "";
1502
				$radiusacctport = "";
1503
				if (isset($pppoecfg['radius']['server']['port']))
1504
					$radiusport = $pppoecfg['radius']['server']['port'];
1505
				if (isset($pppoecfg['radius']['server']['acctport']))
1506
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1507
				$mpdconf .=<<<EOD
1508
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1509
	set radius retries 3
1510
	set radius timeout 10
1511
	set auth enable radius-auth
1512

    
1513
EOD;
1514

    
1515
				if (isset ($pppoecfg['radius']['accounting'])) {
1516
					$mpdconf .=<<<EOD
1517
	set auth enable radius-acct
1518

    
1519
EOD;
1520
				}
1521
			}
1522

    
1523
			fwrite($fd, $mpdconf);
1524
			fclose($fd);
1525
			unset($mpdconf);
1526

    
1527
			/* write mpd.links */
1528
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1529
			if (!$fd) {
1530
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1531
				return 1;
1532
			}
1533

    
1534
			$mpdlinks = "";
1535

    
1536
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1537
				$mpdlinks .=<<<EOD
1538

    
1539
poes{$pppoecfg['pppoeid']}{$i}:
1540
	set phys type pppoe
1541
	set pppoe iface {$pppoe_interface}
1542
	set pppoe service "*"
1543
	set pppoe disable originate
1544
	set pppoe enable incoming
1545

    
1546
EOD;
1547
			}
1548

    
1549
			fwrite($fd, $mpdlinks);
1550
			fclose($fd);
1551
			unset($mpdlinks);
1552

    
1553
			if ($pppoecfg['username']) {
1554
				/* write mpd.secret */
1555
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1556
				if (!$fd) {
1557
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1558
					return 1;
1559
				}
1560

    
1561
				$mpdsecret = "\n\n";
1562

    
1563
				if (!empty($pppoecfg['username'])) {
1564
					$item = explode(" ", $pppoecfg['username']);
1565
					foreach($item as $userdata) {
1566
						$data = explode(":", $userdata);
1567
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1568
					}
1569
				}
1570

    
1571
				fwrite($fd, $mpdsecret);
1572
				fclose($fd);
1573
				unset($mpdsecret);
1574
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1575
			}
1576

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

    
1581
			/* Get support for netgraph(4) from the nic */
1582
			pfSense_ngctl_attach(".", $pppoe_interface);
1583
			/* fire up mpd */
1584
			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");
1585

    
1586
			break;
1587
	}
1588

    
1589
	if (platform_booting())
1590
		echo gettext("done") . "\n";
1591

    
1592
	return 0;
1593
}
1594

    
1595
function vpn_l2tp_configure() {
1596
	global $config, $g;
1597

    
1598
	$syscfg = $config['system'];
1599
	$l2tpcfg = $config['l2tp'];
1600

    
1601
	/* create directory if it does not exist */
1602
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1603
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1604

    
1605
	if (platform_booting()) {
1606
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1607
			return 0;
1608

    
1609
		echo gettext("Configuring l2tp VPN service... ");
1610
	} else {
1611
		/* kill mpd */
1612
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1613

    
1614
		/* wait for process to die */
1615
		sleep(8);
1616

    
1617
	}
1618

    
1619
	/* make sure l2tp-vpn directory exists */
1620
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1621
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1622

    
1623
	switch ($l2tpcfg['mode']) {
1624

    
1625
		case 'server' :
1626
			if ($l2tpcfg['paporchap'] == "chap")
1627
				$paporchap = "set link enable chap";
1628
			else
1629
				$paporchap = "set link enable pap";
1630

    
1631
			/* write mpd.conf */
1632
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1633
			if (!$fd) {
1634
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1635
				return 1;
1636
			}
1637
			$mpdconf = "\n\n";
1638
			$mpdconf .=<<<EOD
1639
l2tps:
1640

    
1641
EOD;
1642

    
1643
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1644
				$mpdconf .= "	load l2tp{$i}\n";
1645
			}
1646

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

    
1649
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1650

    
1651
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1652
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1653
				} else {
1654
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1655
				}
1656

    
1657
				$mpdconf .=<<<EOD
1658

    
1659
l2tp{$i}:
1660
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1661
	{$isssue_ip_type}
1662
	load l2tp_standard
1663

    
1664
EOD;
1665
			}
1666

    
1667
			$mpdconf .=<<<EOD
1668

    
1669
l2tp_standard:
1670
	set bundle disable multilink
1671
	set bundle enable compression
1672
	set bundle yes crypt-reqd
1673
	set ipcp yes vjcomp
1674
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1675
	set ccp yes mppc
1676
	set iface disable on-demand
1677
	set iface enable proxy-arp
1678
	set iface up-script /usr/local/sbin/vpn-linkup
1679
	set iface down-script /usr/local/sbin/vpn-linkdown
1680
	set link yes acfcomp protocomp
1681
	set link no pap chap
1682
	{$paporchap}
1683
	set link keep-alive 10 180
1684

    
1685
EOD;
1686

    
1687
			if (is_ipaddr($l2tpcfg['wins'])) {
1688
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1689
			}
1690
			if (is_ipaddr($l2tpcfg['dns1'])) {
1691
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1692
				if (is_ipaddr($l2tpcfg['dns2']))
1693
					$mpdconf .= " " . $l2tpcfg['dns2'];
1694
				$mpdconf .= "\n";
1695
			} elseif (isset ($config['dnsmasq']['enable'])) {
1696
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1697
				if ($syscfg['dnsserver'][0])
1698
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1699
				$mpdconf .= "\n";
1700
			} elseif (isset ($config['unbound']['enable'])) {
1701
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1702
				if ($syscfg['dnsserver'][0])
1703
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1704
				$mpdconf .= "\n";
1705
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1706
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1707
			}
1708

    
1709
			if (isset ($l2tpcfg['radius']['enable'])) {
1710
				$mpdconf .=<<<EOD
1711
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1712
	set radius retries 3
1713
	set radius timeout 10
1714
	set auth enable radius-auth
1715

    
1716
EOD;
1717

    
1718
				if (isset ($l2tpcfg['radius']['accounting'])) {
1719
					$mpdconf .=<<<EOD
1720
	set auth enable radius-acct
1721

    
1722
EOD;
1723
				}
1724
			}
1725

    
1726
			fwrite($fd, $mpdconf);
1727
			fclose($fd);
1728
			unset($mpdconf);
1729

    
1730
			/* write mpd.links */
1731
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1732
			if (!$fd) {
1733
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1734
				return 1;
1735
			}
1736

    
1737
			$mpdlinks = "";
1738

    
1739
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1740
				$mpdlinks .=<<<EOD
1741

    
1742
l2tp{$i}:
1743
	set link type l2tp
1744
	set l2tp enable incoming
1745
	set l2tp disable originate
1746

    
1747
EOD;
1748
			if (!empty($l2tpcfg['secret']))
1749
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1750
			}
1751

    
1752
			fwrite($fd, $mpdlinks);
1753
			fclose($fd);
1754
			unset($mpdlinks);
1755

    
1756
			/* write mpd.secret */
1757
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1758
			if (!$fd) {
1759
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1760
				return 1;
1761
			}
1762

    
1763
			$mpdsecret = "\n\n";
1764

    
1765
			if (is_array($l2tpcfg['user'])) {
1766
				foreach ($l2tpcfg['user'] as $user)
1767
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1768
			}
1769

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

    
1775
			vpn_netgraph_support();
1776

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

    
1780
			break;
1781

    
1782
		case 'redir' :
1783
			break;
1784
	}
1785

    
1786
	if (platform_booting())
1787
		echo "done\n";
1788

    
1789
	return 0;
1790
}
1791

    
1792
?>
(59-59/68)