Project

General

Profile

Download (53.8 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
				log_error("IPsec ERROR: Could not find phase 1 source for connection {$ph1ent['descr']}. Omitting from configuration file.");
204
				continue;
205
			}
206

    
207
			if(!in_array($ep,$ipmap))
208
				$ipmap[] = $ep;
209

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

    
213
			if (isset ($ph1ent['mobile']))
214
				continue;
215

    
216
			$rg = $ph1ent['remote-gateway'];
217

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

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

    
238
					if ($ikeid != $ph2ent['ikeid'])
239
						continue;
240

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

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

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

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

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

    
335
	unset($stronconf);
336

    
337
	$strongswan = <<<EOD
338

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

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

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

    
371
EOD;
372

    
373
	$strongswan .= "\tplugins {\n";
374

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

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

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

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

    
408
				if (!isset($ph2ent['mobile']))
409
					continue;
410

    
411
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
412

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

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

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

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

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

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

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

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

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

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

    
492
	$pskconf = "";
493

    
494
	if (is_array($a_phase1) && count($a_phase1)) {
495
		foreach ($a_phase1 as $ph1ent) {
496

    
497
			if (isset($ph1ent['disabled']))
498
				continue;
499

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

    
504
				$ikeid = $ph1ent['ikeid'];
505
				$cert = lookup_cert($ph1ent['certref']);
506

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

    
512
				@chmod($certpath, 0600);
513

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

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

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

    
535
				if (empty($peerid_data))
536
					continue;
537

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

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

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

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

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

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

    
592
		foreach ($a_phase1 as $ph1ent) {
593
			if (isset($ph1ent['disabled']))
594
				continue;
595

    
596
			if ($ph1ent['mode'] == "aggressive")
597
				$aggressive = "yes";
598
			else
599
				$aggressive = "no";
600

    
601
			$ep = ipsec_get_phase1_src($ph1ent);
602
			if (!$ep)
603
				continue;
604

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

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

    
623
				$right_spec = $ph1ent['remote-gateway'];
624
				if (is_ipaddr($right_spec))
625
					$sourcehost = $right_spec;
626
				else
627
					$sourcehost = $rgmap['remote-gateway'];
628

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

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

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

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

    
711
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
712
				if (!empty($modp))
713
					$ealgosp1 .= "-{$modp}";
714

    
715
				$ealgosp1 .= "!";
716
			}
717

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

    
729
			$ikelifeline = '';
730
			if ($ph1ent['lifetime'])
731
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
732

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

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

    
785
			$left_spec = $ep;
786

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

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

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

    
819
				if (isset($ph2ent['disabled']))
820
					continue;
821

    
822
				if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
823
					continue;
824

    
825
				if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
826
					$tunneltype = "type = tunnel";
827

    
828
					$localid_type = $ph2ent['localid']['type'];
829
					$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
830

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

    
857
					$leftsubnet_spec[] = $leftsubnet_data;
858

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

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

    
876
					if (!isset($ph2ent['mobile'])) {
877
						$rightsubnet_spec[] = $right_spec;
878
					}
879
				}
880

    
881
				if (isset($a_client['pfs_group']))
882
					$ph2ent['pfsgroup'] = $a_client['pfs_group'];
883

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

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

    
951
				$reqids[] = $ph2ent['reqid'];
952

    
953
				if (!empty($ph2ent['lifetime'])) {
954
					if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime']))
955
						$ipseclifetime = intval($ph2ent['lifetime']);
956
				}
957

    
958
			}
959
		}
960

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

    
976
EOD;
977

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

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

    
1037
		}
1038
	}
1039

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

    
1044
	if ($enablecompression === true)
1045
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1046
	else
1047
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1048

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

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

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

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

    
1088
	if (platform_booting())
1089
		echo "done\n";
1090

    
1091
	return count($filterdns_list);
1092
}
1093

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

    
1103
	$ipseccfg = $config['ipsec'];
1104

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

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

    
1126
/* master setup for vpn (mpd) */
1127
function vpn_setup() {
1128
	global $g;
1129

    
1130
	if ($g['platform'] == 'jail')
1131
		return;
1132

    
1133
	/* start pptpd */
1134
	vpn_pptpd_configure();
1135

    
1136
	/* start pppoe server */
1137
	vpn_pppoes_configure();
1138

    
1139
	/* setup l2tp */
1140
	vpn_l2tp_configure();
1141
}
1142

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

    
1154
function vpn_pptpd_configure() {
1155
	global $config, $g;
1156

    
1157
	$syscfg = $config['system'];
1158
	$pptpdcfg = $config['pptpd'];
1159

    
1160
	if (platform_booting()) {
1161
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
1162
			return 0;
1163

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

    
1170
		/* wait for process to die */
1171
		sleep(3);
1172

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

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

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

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

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

    
1202
			$mpdconf = <<<EOD
1203
pptps:
1204

    
1205
EOD;
1206

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

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

    
1213
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1214

    
1215
				$mpdconf .= <<<EOD
1216

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

    
1222
EOD;
1223
			}
1224

    
1225
			$mpdconf .=<<<EOD
1226

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

    
1247
EOD;
1248

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

    
1254
EOD;
1255
			}
1256

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

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

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

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

    
1292
EOD;
1293
			}
1294
			$mpdconf .=<<<EOD
1295
	set radius retries 3
1296
	set radius timeout 10
1297
	set auth enable radius-auth
1298

    
1299
EOD;
1300

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

    
1306
EOD;
1307
				}
1308
			}
1309

    
1310
			fwrite($fd, $mpdconf);
1311
			fclose($fd);
1312
			unset($mpdconf);
1313

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

    
1321
			$mpdlinks = "";
1322

    
1323
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1324
				$mpdlinks .=<<<EOD
1325

    
1326
pt{$i}:
1327
	set link type pptp
1328
	set pptp enable incoming
1329
	set pptp disable originate
1330
	set pptp disable windowing
1331

    
1332
EOD;
1333
			}
1334

    
1335
			fwrite($fd, $mpdlinks);
1336
			fclose($fd);
1337
			unset($mpdlinks);
1338

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

    
1346
			$mpdsecret = "";
1347

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

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

    
1361
			vpn_netgraph_support();
1362

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

    
1366
			break;
1367

    
1368
		case 'redir' :
1369
			break;
1370
	}
1371

    
1372
	if (platform_booting())
1373
		echo "done\n";
1374

    
1375
	return 0;
1376
}
1377

    
1378
function vpn_pppoes_configure() {
1379
	global $config;
1380

    
1381
	if (is_array($config['pppoes']['pppoe'])) {
1382
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1383
			vpn_pppoe_configure($pppoe);
1384
	}
1385
}
1386

    
1387
function vpn_pppoe_configure(&$pppoecfg) {
1388
	global $config, $g;
1389

    
1390
	$syscfg = $config['system'];
1391

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

    
1396
	if (platform_booting()) {
1397
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1398
			return 0;
1399

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

    
1405
		/* wait for process to die */
1406
		sleep(2);
1407

    
1408
	}
1409

    
1410
	switch ($pppoecfg['mode']) {
1411

    
1412
		case 'server' :
1413

    
1414
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1415

    
1416
			if ($pppoecfg['paporchap'] == "chap")
1417
				$paporchap = "set link enable chap";
1418
			else
1419
				$paporchap = "set link enable pap";
1420

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

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

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

    
1436
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1437

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

    
1444
				$mpdconf .=<<<EOD
1445

    
1446
poes{$pppoecfg['pppoeid']}{$i}:
1447
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1448
	{$isssue_ip_type}
1449
	load pppoe_standard
1450

    
1451
EOD;
1452
			}
1453

    
1454
			$mpdconf .=<<<EOD
1455

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

    
1482
EOD;
1483

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

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

    
1516
EOD;
1517

    
1518
				if (isset ($pppoecfg['radius']['accounting'])) {
1519
					$mpdconf .=<<<EOD
1520
	set auth enable radius-acct
1521

    
1522
EOD;
1523
				}
1524
			}
1525

    
1526
			fwrite($fd, $mpdconf);
1527
			fclose($fd);
1528
			unset($mpdconf);
1529

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

    
1537
			$mpdlinks = "";
1538

    
1539
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1540
				$mpdlinks .=<<<EOD
1541

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

    
1549
EOD;
1550
			}
1551

    
1552
			fwrite($fd, $mpdlinks);
1553
			fclose($fd);
1554
			unset($mpdlinks);
1555

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

    
1564
				$mpdsecret = "\n\n";
1565

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

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

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

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

    
1589
			break;
1590
	}
1591

    
1592
	if (platform_booting())
1593
		echo gettext("done") . "\n";
1594

    
1595
	return 0;
1596
}
1597

    
1598
function vpn_l2tp_configure() {
1599
	global $config, $g;
1600

    
1601
	$syscfg = $config['system'];
1602
	$l2tpcfg = $config['l2tp'];
1603

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

    
1608
	if (platform_booting()) {
1609
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1610
			return 0;
1611

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

    
1617
		/* wait for process to die */
1618
		sleep(8);
1619

    
1620
	}
1621

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

    
1626
	switch ($l2tpcfg['mode']) {
1627

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

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

    
1644
EOD;
1645

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

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

    
1652
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1653

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

    
1660
				$mpdconf .=<<<EOD
1661

    
1662
l2tp{$i}:
1663
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1664
	{$isssue_ip_type}
1665
	load l2tp_standard
1666

    
1667
EOD;
1668
			}
1669

    
1670
			$mpdconf .=<<<EOD
1671

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

    
1688
EOD;
1689

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

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

    
1719
EOD;
1720

    
1721
				if (isset ($l2tpcfg['radius']['accounting'])) {
1722
					$mpdconf .=<<<EOD
1723
	set auth enable radius-acct
1724

    
1725
EOD;
1726
				}
1727
			}
1728

    
1729
			fwrite($fd, $mpdconf);
1730
			fclose($fd);
1731
			unset($mpdconf);
1732

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

    
1740
			$mpdlinks = "";
1741

    
1742
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1743
				$mpdlinks .=<<<EOD
1744

    
1745
l2tp{$i}:
1746
	set link type l2tp
1747
	set l2tp enable incoming
1748
	set l2tp disable originate
1749

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

    
1755
			fwrite($fd, $mpdlinks);
1756
			fclose($fd);
1757
			unset($mpdlinks);
1758

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

    
1766
			$mpdsecret = "\n\n";
1767

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

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

    
1778
			vpn_netgraph_support();
1779

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

    
1783
			break;
1784

    
1785
		case 'redir' :
1786
			break;
1787
	}
1788

    
1789
	if (platform_booting())
1790
		echo "done\n";
1791

    
1792
	return 0;
1793
}
1794

    
1795
?>
(59-59/68)