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
		ike_name = yes
363
	}
364
	# very minimalistic IKE auditing logs to LOG_AUTHPRIV
365
	auth {
366
		default = -1
367
		ike = 1
368
		ike_name = yes
369
	}
370
}
371

    
372
EOD;
373

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
493
	$pskconf = "";
494

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

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

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

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

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

    
513
				@chmod($certpath, 0600);
514

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
786
			$left_spec = $ep;
787

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

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

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

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

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

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

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

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

    
858
					$leftsubnet_spec[] = $leftsubnet_data;
859

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

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

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

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

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

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

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

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

    
959
			}
960
		}
961

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

    
977
EOD;
978

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

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

    
1038
		}
1039
	}
1040

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

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

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

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

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

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

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

    
1092
	return count($filterdns_list);
1093
}
1094

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1206
EOD;
1207

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

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

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

    
1216
				$mpdconf .= <<<EOD
1217

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

    
1223
EOD;
1224
			}
1225

    
1226
			$mpdconf .=<<<EOD
1227

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

    
1248
EOD;
1249

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

    
1255
EOD;
1256
			}
1257

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

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

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

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

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

    
1300
EOD;
1301

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

    
1307
EOD;
1308
				}
1309
			}
1310

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

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

    
1322
			$mpdlinks = "";
1323

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

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

    
1333
EOD;
1334
			}
1335

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

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

    
1347
			$mpdsecret = "";
1348

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

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

    
1362
			vpn_netgraph_support();
1363

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

    
1367
			break;
1368

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

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

    
1376
	return 0;
1377
}
1378

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

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

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

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

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

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

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

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

    
1409
	}
1410

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

    
1413
		case 'server' :
1414

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

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

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

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

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

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

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

    
1445
				$mpdconf .=<<<EOD
1446

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

    
1452
EOD;
1453
			}
1454

    
1455
			$mpdconf .=<<<EOD
1456

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

    
1483
EOD;
1484

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

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

    
1517
EOD;
1518

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

    
1523
EOD;
1524
				}
1525
			}
1526

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

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

    
1538
			$mpdlinks = "";
1539

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

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

    
1550
EOD;
1551
			}
1552

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

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

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

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

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

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

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

    
1590
			break;
1591
	}
1592

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

    
1596
	return 0;
1597
}
1598

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

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

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

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

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

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

    
1621
	}
1622

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

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

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

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

    
1645
EOD;
1646

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

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

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

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

    
1661
				$mpdconf .=<<<EOD
1662

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

    
1668
EOD;
1669
			}
1670

    
1671
			$mpdconf .=<<<EOD
1672

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

    
1689
EOD;
1690

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

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

    
1720
EOD;
1721

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

    
1726
EOD;
1727
				}
1728
			}
1729

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

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

    
1741
			$mpdlinks = "";
1742

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

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

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

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

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

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

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

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

    
1779
			vpn_netgraph_support();
1780

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

    
1784
			break;
1785

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

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

    
1793
	return 0;
1794
}
1795

    
1796
?>
(59-59/68)