Project

General

Profile

Download (51.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($ipchg = false)
98
{
99
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos;
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
	vpn_ipsec_configure_preferoldsa();
109

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

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

    
121
		/* disallow IPSEC, it is off */
122
		mwexec("/sbin/ifconfig enc0 down");
123
		set_single_sysctl("net.inet.ip.ipsec_in_use", "0");
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 (!empty($vpninterface))
189
					$ifacesuse[] = $vpninterface;
190
			}
191
				
192
			if ($ph1ent['mode'] == "aggressive" && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) 
193
				$aggressive_mode_psk = true;
194

    
195
			$ikeid = $ph1ent['ikeid'];
196
			$listeniflist = get_real_interface($a_phase1['interface']);
197

    
198
			$ep = ipsec_get_phase1_src($ph1ent);
199
			if (!is_ipaddr($ep))
200
				continue;
201

    
202
			if(!in_array($ep,$ipmap))
203
				$ipmap[] = $ep;
204

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

    
208
			if (isset ($ph1ent['mobile']))
209
				continue;
210

    
211
			$rg = $ph1ent['remote-gateway'];
212

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

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

    
233
					if ($ikeid != $ph2ent['ikeid'])
234
						continue;
235

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

    
290
	$accept_unencrypted = "";
291
	if (isset($config['ipsec']['acceptunencryptedmainmode']))
292
		$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
293

    
294
	$i_dont_care_about_security_and_use_aggressive_mode_psk = "";
295
	if ($aggressive_mode_psk) {
296
		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.");
297
		$i_dont_care_about_security_and_use_aggressive_mode_psk = "i_dont_care_about_security_and_use_aggressive_mode_psk=yes";
298
	} 
299

    
300
	$unity_enabled = 'yes';
301
	if (isset($config['ipsec']['unityplugin']))
302
		$unity_enabled = 'no';
303

    
304
	if (!empty($ifacesuse))
305
		$ifacesuse = 'interfaces_use = ' . implode(',', array_unique($ifacesuse));
306
	else
307
		$ifacesuse = '';
308

    
309
	$strongswan = <<<EOD
310

    
311
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten. 
312
starter {
313
load_warning = no
314
}
315

    
316
charon {
317
# number of worker threads in charon
318
threads = 16
319
ikesa_table_size = 32
320
ikesa_table_segments = 4
321
init_limit_half_open = 1000
322
install_routes = no
323
{$i_dont_care_about_security_and_use_aggressive_mode_psk}
324
{$accept_unencrypted}
325
cisco_unity = {$unity_enabled}
326
{$ifacesuse}
327

    
328
# And two loggers using syslog. The subsections define the facility to log
329
# to, currently one of: daemon, auth.
330
syslog {
331
	identifier = charon
332
	# default level to the LOG_DAEMON facility
333
	daemon {
334
	}
335
	# very minimalistic IKE auditing logs to LOG_AUTHPRIV
336
	auth {
337
		default = -1
338
		ike = 1
339
		ike_name = yes
340
	}
341
}
342

    
343
EOD;
344

    
345
	$strongswan .= "\tplugins {\n";
346

    
347
	if (is_array($a_client) && isset($a_client['enable'])) {
348
		$strongswan .= "\t\tattr {\n";
349
		if ($a_client['pool_address'] && $a_client['pool_netbits'])
350
			$strongswan .= "\t\t\tsubnet = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
351

    
352
		$cfgservers = array();
353
		if (!empty($a_client['dns_server1']))
354
			$cfgservers[] = $a_client['dns_server1'];
355
		if (!empty($a_client['dns_server2']))
356
			$cfgservers[] = $a_client['dns_server2'];
357
		if (!empty($a_client['dns_server3']))
358
			$cfgservers[] = $a_client['dns_server3'];
359
		if (!empty($a_client['dns_server4']))
360
			$cfgservers[] = $a_client['dns_server4'];
361

    
362
		if (!empty($cfgservers))
363
			$strongswan .= "\t\t\tdns = " . implode(",", $cfgservers) . "\n";
364
		unset($cfgservers);
365
		$cfgservers = array();
366
		if (!empty($a_client['wins_server1']))
367
			$cfgservers[] = $a_client['wins_server1'];
368
		if (!empty($a_client['wins_server2']))
369
			$cfgservers[] = $a_client['wins_server2'];
370
		if (!empty($cfgservers))
371
			$strongswan .= "\t\t\tnbns = " . implode(",", $cfgservers) . "\n";
372
		unset($cfgservers);
373

    
374
		if (isset($a_client['net_list'])) {
375
			$net_list = '';
376
			foreach ($a_phase2 as $ph2ent) {
377
				if (isset($ph2ent['disabled']))
378
					continue;
379

    
380
				if (!isset($ph2ent['mobile']))
381
					continue;
382

    
383
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
384

    
385
				if (!empty($net_list))
386
					$net_list .= ",";
387
				$net_list .= $localid;
388
			}
389

    
390
			if (!empty($net_list)) {
391
				$strongswan .= "\t\t\tsplit-include = {$net_list}\n";
392
				unset($net_list);
393
			}
394
		}
395

    
396
		if (!empty($a_client['dns_domain'])) {
397
			$strongswan .= "\t\t\t# Search domain and default domain\n";
398
			$strongswan .= "\t\t\t28674 = {$a_client['dns_domain']}\n";
399
			if (empty($a_client['dns_split']))
400
				$strongswan .= "\t\t\t28675 = {$a_client['dns_domain']}";
401
			$strongswan .= "\n";
402
		}
403

    
404
		if (!empty($a_client['dns_split'])) {
405
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
406
		}
407

    
408
		if (!empty($a_client['login_banner']))
409
			$strongswan .= "\t\t\t28672 = {$a_client['login_banner']}\n";
410

    
411
		if (isset($a_client['save_passwd']))
412
			$strongswan .= "\t\t\t28673 = 1\n";
413

    
414
		if ($a_client['pfs_group'])
415
			$strongswan .= "\t\t\t28679 = {$a_client['pfs_group']}\n";
416
		$strongswan .= "\t\t}\n";
417

    
418
		if ($a_client['user_source'] != "none") {
419
			$strongswan .= "\t\txauth-generic {\n";
420
			$strongswan .= "\t\t\tscript = /etc/inc/ipsec.auth-user.php\n";
421
			$strongswan .= "\t\t\tauthcfg = ";
422
			$firstsed = 0;
423
			$authcfgs = explode(",", $a_client['user_source']);
424
			foreach ($authcfgs as $authcfg) {
425
				if ($firstsed > 0)
426
					$strongswan .= ",";
427
				if ($authcfg == "system")
428
					$authcfg = "Local Database";
429
				$strongswan .= $authcfg;
430
				$firstsed = 1;
431
			}
432
			$strongswan .= "\n";
433
			$strongswan .= "\t\t}\n";
434
		}
435
	}
436

    
437
	$strongswan .= "\t}\n}\n";
438
	@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
439
	unset($strongswan);
440

    
441
	/* generate CA certificates files */
442
	if (is_array($config['ca']) && count($config['ca'])) {
443
		foreach ($config['ca'] as $ca) {
444
			if (!isset($ca['crt'])) {
445
				log_error(sprintf(gettext("Error: Invalid certificate info for %s"), $ca['descr']));
446
				continue;
447
			}
448
			$cert = base64_decode($ca['crt']);
449
			$x509cert = openssl_x509_parse(openssl_x509_read($cert));
450
			if (!is_array($x509cert) || !isset($x509cert['hash'])) {
451
				log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $ca['descr']));
452
				continue;
453
			}
454
			$fname = "{$capath}/{$x509cert['hash']}.0.crt";
455
			if (!@file_put_contents($fname, $cert)) {
456
				log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $ca['descr']));
457
				continue;
458
			}
459
			unset($cert);
460
		}
461
	}
462

    
463
	$pskconf = "";
464

    
465
	if (is_array($a_phase1) && count($a_phase1)) {
466
		foreach ($a_phase1 as $ph1ent) {
467

    
468
			if (isset($ph1ent['disabled']))
469
				continue;
470

    
471
			if (strstr($ph1ent['authentication_method'], 'rsa') ||
472
			    in_array($ph1ent['authentication_method'], array('eap-mschapv2', 'eap-tls'))) {
473
				$certline = '';
474

    
475
				$ikeid = $ph1ent['ikeid'];
476
				$cert = lookup_cert($ph1ent['certref']);
477

    
478
				if (!$cert) {
479
					log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
480
					continue;
481
				}
482

    
483
				@chmod($certpath, 0600);
484

    
485
				$ph1keyfile = "{$keypath}/cert-{$ikeid}.key";
486
				if (!file_put_contents($ph1keyfile, base64_decode($cert['prv']))) {
487
					log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
488
					continue;
489
				}
490
				@chmod($ph1keyfile, 0600);
491

    
492
				$ph1certfile = "{$certpath}/cert-{$ikeid}.crt";
493
				if (!file_put_contents($ph1certfile, base64_decode($cert['crt']))) {
494
					log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name']));
495
					@unlink($ph1keyfile);
496
					continue;
497
				}
498
				@chmod($ph1certfile, 0600);
499

    
500
				/* XXX" Traffic selectors? */
501
				$pskconf .= " : RSA {$ph1keyfile}\n";
502
			} else {
503
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, "local");
504
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, "peer", $rgmap);
505

    
506
				if (empty($peerid_data))
507
					continue;
508

    
509
				$myid = isset($ph1ent['mobile']) ? trim($myid_data) : "%any";
510
				$peerid = ($peerid_data != "allusers") ? trim($peerid_data) : "";
511
				if (!empty($ph1ent['pre-shared-key'])) {
512
					if ($myid_type == 'fqdn' && !empty($myid_data))
513
						$pskconf .= "@{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
514
					else
515
						$pskconf .= "{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
516
				}
517
			}
518
		}
519
	}
520

    
521
	/* Add user PSKs */
522
	if (is_array($config['system']) && is_array($config['system']['user'])) {
523
		foreach ($config['system']['user'] as $user) {
524
			if (!empty($user['ipsecpsk'])) {
525
				$pskconf .= "%any {$user['name']} : PSK 0s" . base64_encode($user['ipsecpsk']) . "\n";
526
			}
527
		}
528
		unset($user);
529
	}
530

    
531
	/* add PSKs for mobile clients */
532
	if (is_array($ipseccfg['mobilekey'])) {
533
		foreach ($ipseccfg['mobilekey'] as $key) {
534
			if ($key['ident'] == "allusers")
535
				$key['ident'] = '%any';
536
			if (empty($key['type']))
537
				$key['type'] = 'PSK';
538
			$pskconf .= "%any {$key['ident']} : {$key['type']} 0s" . base64_encode($key['pre-shared-key']) . "\n";
539
		}
540
		unset($key);
541
	}
542

    
543
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
544
	chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
545
	unset($pskconf);
546

    
547
	$natfilterrules = false;
548
	/* begin ipsec.conf */
549
	$ipsecconf = "";
550
	$enablecompression = false;
551
	if (is_array($a_phase1) && count($a_phase1))  {
552

    
553
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
554
		$ipsecconf .= "config setup\n\tuniqueids = yes\n";
555
		$ipsecconf .= "\tcharondebug=\"" . vpn_ipsec_configure_loglevels(true) . "\"\n";
556

    
557
		foreach ($a_phase1 as $ph1ent) {
558
			if (isset($ph1ent['disabled']))
559
				continue;
560

    
561
			if ($ph1ent['mode'] == "aggressive")
562
				$aggressive = "yes";
563
			else
564
				$aggressive = "no";
565

    
566
			$ep = ipsec_get_phase1_src($ph1ent);
567
			if (!$ep)
568
				continue;
569

    
570
			$ikeid = $ph1ent['ikeid'];
571
			$keyexchange = "ikev1";
572
			$passive = "route";
573
			if (!empty($ph1ent['iketype'])) {
574
				if ($ph1ent['iketype'] == "ikev2") {
575
					$keyexchange = "ikev2";
576
					//$passive = "start";
577
				} else if ($ph1ent['iketype'] == "auto")
578
					$keyexchange = "ike";
579
			}
580

    
581
			if (isset($ph1ent['mobile'])) {
582
				$right_spec = "%any";
583
				$passive = 'add';
584
			} else {
585
				$right_spec = $ph1ent['remote-gateway'];
586
				if (is_ipaddr($right_spec))
587
					$sourcehost = $right_spec;
588
				else
589
					$sourcehost = $rgmap['remote-gateway'];
590

    
591
				if ($ph1ent['protocol'] == 'inet') {
592
					if (strpos($ph1ent['interface'], '_vip')) {
593
						$vpninterface = explode('_vip', $ph1ent['interface']);
594
						$ifacesuse = get_real_interface($vpninterface[0]);
595
						$vpninterface = $vpninterface[0];
596
					} else {
597
						$ifacesuse = get_failover_interface($ph1ent['interface']);
598
						$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
599
					}
600
					
601
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
602
						$gatewayip = get_interface_gateway($vpninterface);
603
						$interfaceip = get_interface_ip($vpninterface);
604
						$subnet_bits = get_interface_subnet($vpninterface);
605
						$subnet_ip = gen_subnetv4($interfaceip, $subnet_bits);
606
						/* if the remote gateway is in the local subnet, then don't add a route */
607
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
608
							if (is_ipaddrv4($gatewayip)) {
609
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
610
								mwexec("/sbin/route change -host {$sourcehost} {$gatewayip}", true);
611
							}
612
						}
613
					}
614
				} else if ($ph1ent['protocol'] == 'inet6') {
615
					if (strpos($ph1ent['interface'], '_vip')) {
616
						$vpninterface = explode('_vip', $ph1ent['interface']);
617
						$ifacesuse = get_real_interface($vpninterface[0]);
618
						$vpninterface = $vpninterface[0];
619
					} else {
620
						$ifacesuse = get_failover_interface($ph1ent['interface']);
621
						$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
622
					}
623
					
624
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
625
						$gatewayip = get_interface_gateway_v6($vpninterface);
626
						$interfaceip = get_interface_ipv6($vpninterface);
627
						$subnet_bits = get_interface_subnetv6($vpninterface);
628
						$subnet_ip = gen_subnetv6($interfaceip, $subnet_bits);
629
						/* if the remote gateway is in the local subnet, then don't add a route */
630
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
631
							if (is_ipaddrv6($gatewayip)) {
632
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
633
								mwexec("/sbin/route change -inet6 -host {$sourcehost} {$gatewayip}", true);
634
							}
635
						}
636
					}
637
				}
638
			}
639

    
640
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, "local");
641
			if ($myid_type == 'fqdn')
642
				$myid_data = "@{$myid_data}";
643
			list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, "peer", $rgmap);
644
			if ($peerid_type == 'fqdn')
645
				$peerid_data = "@{$peerid_data}";
646

    
647
			/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
648
			$peerid_spec = '';
649
			if (!isset($ph1ent['mobile']))
650
				$peerid_spec = $peerid_data;
651

    
652
			if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
653
				$ealgosp1 = '';
654
				$ealg_id = $ph1ent['encryption-algorithm']['name'];
655
				$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
656
				if ($ealg_kl)
657
					$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
658
				else
659
					$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
660

    
661
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
662
				if (!empty($modp))
663
					$ealgosp1 .= "-{$modp}";
664

    
665
				$ealgosp1 .= "!";
666
			}
667

    
668
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
669
				if ($passive == "route")
670
					$dpdline = "dpdaction = restart";
671
				else
672
					$dpdline = "dpdaction = clear";
673
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
674
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
675
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
676
			} else
677
				$dpdline = "dpdaction = none";
678

    
679
			$ikelifeline = '';
680
			if ($ph1ent['lifetime'])
681
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
682

    
683
			$rightsourceip = NULL;
684
			if (isset($ph1ent['mobile']) && !empty($a_client['pool_address'])) 
685
				$rightsourceip = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
686

    
687
			$authentication = "";
688
			switch ($ph1ent['authentication_method']) {
689
			case 'eap-mschapv2':
690
				if (isset($ph1ent['mobile'])) {
691
					$authentication = "eap_identity=%any\n\t";
692
					$authentication .= "leftauth=pubkey\n\trightauth=eap-mschapv2";
693
					if (!empty($ph1ent['certref']))
694
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
695
				}
696
				break;
697
			case 'eap-tls':
698
				if (isset($ph1ent['mobile'])) {
699
					$authentication = "eap_identity=%identity\n\t";
700
					$authentication .= "leftauth=pubkey\n\trightauth=eap-tls";
701
					if (!empty($ph1ent['certref']))
702
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
703
				} else {
704
					$authentication = "leftauth=eap-tls\n\trightauth=eap-tls";
705
					if (!empty($ph1ent['certref']))
706
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
707
				}
708
				break;
709
			case 'xauth_rsa_server':
710
				$authentication = "leftauth = pubkey\n\trightauth = pubkey";
711
				$authentication .= "\n\trightauth2 = xauth-generic";
712
				if (!empty($ph1ent['certref']))
713
					$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
714
				break;
715
			case 'xauth_psk_server':
716
				$authentication = "leftauth = psk\n\trightauth = psk";
717
				$authentication .= "\n\trightauth2 = xauth-generic";
718
				break;
719
			case 'pre_shared_key':
720
				$authentication = "leftauth = psk\n\trightauth = psk";
721
				break;
722
			case 'rsasig':
723
				$authentication = "leftauth = pubkey\n\trightauth = pubkey";
724
				if (!empty($ph1ent['certref']))
725
					$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
726
				break;
727
			case 'hybrid_rsa_server':
728
				$authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
729
				$authentication .= "\n\trightauth2 = xauth";
730
				if (!empty($ph1ent['certref']))
731
					$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
732
				break;
733
			}
734

    
735
			$left_spec = $ep;
736

    
737
			if (isset($ph1ent['reauth_enable']))
738
				$reauth = "reauth = no";
739
			else
740
				$reauth = "reauth = yes";
741
			if (isset($ph1ent['rekey_enable']))
742
				$rekey = "rekey = no";
743
			else
744
				$rekey = "rekey = yes";
745

    
746
			if ($ph1ent['nat_traversal'] == 'off')
747
				$forceencaps = 'forceencaps = no';
748
			else if ($ph1ent['nat_traversal'] == 'force')
749
				$forceencaps = 'forceencaps = yes';
750
			else
751
				$forceencaps = 'forceencaps = no';
752

    
753
			$ipseclifetime = 0;
754
			$rightsubnet_spec = array();
755
			$leftsubnet_spec = array();
756
			$reqids = array();
757
			$ealgoAHsp2arr = array();
758
			$ealgoESPsp2arr = array();
759
		if (is_array($a_phase2) && count($a_phase2)) {
760
			foreach ($a_phase2 as $ph2ent) {
761
				if ($ikeid != $ph2ent['ikeid'])
762
					continue;
763

    
764
				if (isset($ph2ent['disabled']))
765
					continue;
766

    
767
				if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
768
					continue;
769

    
770
				if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
771
					$tunneltype = "type = tunnel";
772

    
773
					$localid_type = $ph2ent['localid']['type'];
774
					$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
775

    
776
					/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
777
					if (($localid_type == "none" || $localid_type == "mobile")
778
					    && isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ikeid)==1)) {
779
						$left_spec = '%any';
780
					} else {
781
						if ($localid_type != "address") {
782
							$localid_type = "subnet";
783
						}
784
						// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
785
						if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) {
786
							log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
787
							continue;
788
						}
789
						if (!empty($ph2ent['natlocalid'])) {
790
							$natleftsubnet_data =  ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
791
							if ($ph2ent['natlocalid']['type'] != "address") {
792
								if (is_subnet($natleftsubnet_data))
793
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
794
							} else {
795
								if (is_ipaddr($natleftsubnet_data))
796
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
797
							}
798
							$natfilterrules = true;
799
						}
800
					}
801

    
802
					$leftsubnet_spec[] = $leftsubnet_data;
803

    
804
					if (!isset($ph2ent['mobile'])) {
805
						$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
806
						$rightsubnet_spec[] = $tmpsubnet;
807
					} else if (!empty($a_client['pool_address'])) {
808
						$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
809
					}
810
				} else {
811
					$tunneltype = "type = transport";
812

    
813
					if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
814
					    ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) {
815
						$left_spec = "%any";
816
					} else {
817
						$tmpsubnet = ipsec_get_phase1_src($ph1ent);
818
						$leftsubnet_spec[] = $tmpsubnet;
819
					}
820

    
821
					if (!isset($ph2ent['mobile'])) {
822
						$rightsubnet_spec[] = $right_spec;
823
					}
824
				}
825

    
826
				if (isset($a_client['pfs_group']))
827
					$ph2ent['pfsgroup'] = $a_client['pfs_group'];
828

    
829
				if ($ph2ent['protocol'] == 'esp') {
830
					if (is_array($ph2ent['encryption-algorithm-option'])) {
831
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
832
							$ealg_id = $ealg['name'];
833
							$ealg_kl = $ealg['keylen'];
834

    
835
							if (!empty($ealg_kl) && $ealg_kl == "auto") {
836
								if (empty($p2_ealgos) || !is_array($p2_ealgos))
837
									require("ipsec.inc");
838
								$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
839
								$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
840
								$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
841
								/* XXX: in some cases where include ordering is suspect these variables
842
								 * are somehow 0 and we enter this loop forever and timeout after 900
843
								 * seconds wrecking bootup */
844
								if ($key_hi != 0 and $key_lo !=0 and $key_step !=0) {
845
									for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
846
										if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
847
											foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
848
												$halgo = str_replace('hmac_', '', $halgo);
849
												$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
850
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
851
												if (!empty($modp))
852
													$tmpealgo .= "-{$modp}";
853
												$ealgoESPsp2arr[] = $tmpealgo;
854
											}
855
										} else {
856
											$tmpealgo = "{$ealg_id}{$keylen}";
857
											$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
858
											if (!empty($modp))
859
												$tmpealgo .= "-{$modp}";
860
											$ealgoESPsp2arr[] = $tmpealgo;
861
										}
862
									}
863
								}
864
							} else {
865
								if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
866
									foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
867
										$halgo = str_replace('hmac_', '', $halgo);
868
										$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
869
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
870
										if (!empty($modp))
871
											$tmpealgo .= "-{$modp}";
872
										$ealgoESPsp2arr[] = $tmpealgo;
873
									}
874
								} else {
875
									$tmpealgo = "{$ealg_id}{$ealg_kl}";
876
									$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
877
									if (!empty($modp))
878
										$tmpealgo .= "-{$modp}";
879
									$ealgoESPsp2arr[] = $tmpealgo;
880
								}
881
							}
882
						}
883
					}
884
				} else if ($ph2ent['protocol'] == 'ah') {
885
					if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
886
						$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
887
						foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
888
							$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
889
							if (!empty($modp))
890
								$tmpAHalgo = "-{$modp}";
891
							$ealgoAHsp2arr[] = $tmpAHalgo;
892
						}
893
					}
894
				}
895

    
896
				$reqids[] = $ph2ent['reqid'];
897

    
898
				if (!empty($ph2ent['lifetime'])) {
899
					if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime']))
900
						$ipseclifetime = intval($ph2ent['lifetime']);
901
				}
902

    
903
			}
904
		}
905

    
906
			$ipsecconnect =<<<EOD
907
	fragmentation = yes
908
	keyexchange = {$keyexchange}
909
	{$reauth}
910
	{$forceencaps}
911
	{$rekey}
912
	installpolicy = yes
913
	{$tunneltype}
914
	{$dpdline}
915
	auto = {$passive}
916
	left = {$left_spec}
917
	right = {$right_spec}
918
	leftid = {$myid_data}
919

    
920
EOD;
921

    
922
			if (isset($config['ipsec']['compression'])) {
923
				$ipsecconnect .= "\tcompress = yes\n";
924
				$enablecompression = true;
925
			}
926
			if (!empty($ikelifeline))
927
				$ipsecconnect .= "\t{$ikelifeline}\n";
928
			if ($ipseclifetime > 0)
929
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
930
			if (!empty($rightsourceip))
931
				$ipsecconnect .= "{$rightsourceip}";
932
			if (!empty($ealgosp1))
933
				$ipsecconnect .= "\t{$ealgosp1}\n";
934
			if (!empty($ealgoAHsp2arr))
935
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
936
			if (!empty($ealgoESPsp2arr))
937
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
938
			if (!empty($authentication))
939
				$ipsecconnect .= "\t{$authentication}\n";
940
			if (!empty($peerid_spec))
941
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
942
			if ($keyexchange == 'ikev1')
943
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
944

    
945
			if (!isset($ph1ent['mobile']) && $keyexchange == 'ikev1') {
946
				if (!empty($rightsubnet_spec)) {
947
					$ipsecfin = '';
948
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
949
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
950
						if (!empty($reqids[$idx]))
951
							$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
952
						$ipsecfin .= $ipsecconnect;
953
						$ipsecfin .= "\trightsubnet = {$rsubnet}\n";
954
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n";
955
					}
956
				} else
957
					log_error("No phase2 specifications for tunnel with REQID = {$ikeid}");
958
			} else {
959
				$ipsecfin = "\nconn con{$ph1ent['ikeid']}\n";
960
				if (!empty($reqids[$idx]))
961
					$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
962
				$ipsecfin .= $ipsecconnect;
963
				if (!empty($rightsubnet_spec)) {
964
					$tempsubnets = array();
965
					foreach ($rightsubnet_spec as $rightsubnet)
966
						$tempsubnets[$rightsubnet] = $rightsubnet;
967
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "\n";
968
					unset($tempsubnets, $rightsubnet);
969
				}
970
				if (!empty($leftsubnet_spec)) {
971
					$tempsubnets = array();
972
					foreach ($leftsubnet_spec as $leftsubnet)
973
						$tempsubnets[$leftsubnet] = $leftsubnet;
974
					$ipsecfin .= "\tleftsubnet = " . join(",", $leftsubnet_spec) . "\n";
975
					unset($tempsubnets, $leftsubnet);
976
				}
977
			}
978
			$ipsecconf .= $ipsecfin;
979
			unset($ipsecfin);
980

    
981
		}
982
	}
983

    
984
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
985
	unset($ipsecconf);
986
	/* end ipsec.conf */
987

    
988
	if ($enablecompression === true)
989
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
990
	else
991
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
992

    
993
	/* mange process */
994
	if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
995
		/* Read secrets */
996
		mwexec("/usr/local/sbin/ipsec rereadall", false);
997
		/* Update configuration changes */
998
		mwexec("/usr/local/sbin/ipsec update", false);
999
	} else {
1000
		mwexec("/usr/local/sbin/ipsec start", false); 
1001
	}
1002

    
1003
	if ($natfilterrules == true)
1004
		filter_configure();
1005
	/* start filterdns, if necessary */
1006
	if (count($filterdns_list) > 0) {
1007
		$interval = 60;
1008
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
1009
			$interval = $ipseccfg['dns-interval'];
1010

    
1011
		$hostnames = "";
1012
		array_unique($filterdns_list);
1013
		foreach ($filterdns_list as $hostname)
1014
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1015
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1016
		unset($hostnames);
1017

    
1018
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
1019
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1020
		else {
1021
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1022
		}
1023
	} else {
1024
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1025
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1026
	}
1027

    
1028
	if (platform_booting())
1029
		echo "done\n";
1030

    
1031
	return count($filterdns_list);
1032
}
1033

    
1034
/*
1035
 * Forcefully restart IPsec
1036
 * This is required for when dynamic interfaces reload
1037
 * For all other occasions the normal vpn_ipsec_configure()
1038
 * will gracefully reload the settings without restarting
1039
 */
1040
function vpn_ipsec_force_reload($interface = "") {
1041
	global $g, $config;
1042

    
1043
	$ipseccfg = $config['ipsec'];
1044

    
1045
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1046
		$found = false;
1047
		foreach ($ipseccfg['phase1'] as $ipsec) {
1048
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1049
				$found = true;
1050
				break;
1051
			}
1052
		}
1053
		if (!$found) {
1054
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1055
			return;
1056
		}
1057
	}
1058

    
1059
	/* if ipsec is enabled, start up again */
1060
	if (isset($ipseccfg['enable'])) {
1061
		log_error(gettext("Forcefully reloading IPsec"));
1062
		vpn_ipsec_configure();
1063
	}
1064
}
1065

    
1066
/* master setup for vpn (mpd) */
1067
function vpn_setup() {
1068
	global $g;
1069

    
1070
	if ($g['platform'] == 'jail')
1071
		return;
1072

    
1073
	/* start pptpd */
1074
	vpn_pptpd_configure();
1075

    
1076
	/* start pppoe server */
1077
	vpn_pppoes_configure();
1078

    
1079
	/* setup l2tp */
1080
	vpn_l2tp_configure();
1081
}
1082

    
1083
function vpn_netgraph_support() {
1084
	$iflist = get_configured_interface_list();
1085
	foreach ($iflist as $iface) {
1086
		$realif = get_real_interface($iface);
1087
		/* Get support for netgraph(4) from the nic */
1088
		$ifinfo = pfSense_get_interface_addresses($realif);
1089
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
1090
			pfSense_ngctl_attach(".", $realif);
1091
	}
1092
}
1093

    
1094
function vpn_pptpd_configure() {
1095
	global $config, $g;
1096

    
1097
	$syscfg = $config['system'];
1098
	$pptpdcfg = $config['pptpd'];
1099

    
1100
	if (platform_booting()) {
1101
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
1102
			return 0;
1103

    
1104
		if (platform_booting(true))
1105
			echo gettext("Configuring PPTP VPN service... ");
1106
	} else {
1107
		/* kill mpd */
1108
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1109

    
1110
		/* wait for process to die */
1111
		sleep(3);
1112

    
1113
		if (is_process_running("mpd -b")) {
1114
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1115
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
1116
		}
1117

    
1118
		/* remove mpd.conf, if it exists */
1119
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
1120
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
1121
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
1122
	}
1123

    
1124
	if (empty($pptpdcfg['n_pptp_units'])) {
1125
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
1126
		return;
1127
	}
1128

    
1129
	/* make sure pptp-vpn directory exists */
1130
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
1131
		mkdir("{$g['varetc_path']}/pptp-vpn");
1132

    
1133
	switch ($pptpdcfg['mode']) {
1134
		case 'server' :
1135
			/* write mpd.conf */
1136
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1137
			if (!$fd) {
1138
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
1139
				return 1;
1140
			}
1141

    
1142
			$mpdconf = <<<EOD
1143
pptps:
1144

    
1145
EOD;
1146

    
1147
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1148
				$mpdconf .= "	load pt{$i}\n";
1149
			}
1150

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

    
1153
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1154

    
1155
				$mpdconf .= <<<EOD
1156

    
1157
pt{$i}:
1158
	new -i pptpd{$i} pt{$i} pt{$i}
1159
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1160
	load pts
1161

    
1162
EOD;
1163
			}
1164

    
1165
			$mpdconf .=<<<EOD
1166

    
1167
pts:
1168
	set iface disable on-demand
1169
	set iface enable proxy-arp
1170
	set iface enable tcpmssfix
1171
	set iface idle 1800
1172
	set iface up-script /usr/local/sbin/vpn-linkup
1173
	set iface down-script /usr/local/sbin/vpn-linkdown
1174
	set bundle enable multilink
1175
	set bundle enable crypt-reqd
1176
	set link yes acfcomp protocomp
1177
	set link no pap chap
1178
	set link enable chap-msv2
1179
	set link mtu 1460
1180
	set link keep-alive 10 60
1181
	set ipcp yes vjcomp
1182
	set bundle enable compression
1183
	set ccp yes mppc
1184
	set ccp yes mpp-e128
1185
	set ccp yes mpp-stateless
1186

    
1187
EOD;
1188

    
1189
			if (!isset ($pptpdcfg['req128'])) {
1190
				$mpdconf .=<<<EOD
1191
	set ccp yes mpp-e40
1192
	set ccp yes mpp-e56
1193

    
1194
EOD;
1195
			}
1196

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

    
1200
			if (!empty($pptpdcfg['dns1'])) {
1201
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1202
				if (!empty($pptpdcfg['dns2']))
1203
					$mpdconf .= " " . $pptpdcfg['dns2'];
1204
				$mpdconf .= "\n";
1205
			} elseif (isset ($config['dnsmasq']['enable'])) {
1206
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1207
				if ($syscfg['dnsserver'][0])
1208
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1209
				$mpdconf .= "\n";
1210
			} elseif (isset($config['unbound']['enable'])) {
1211
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1212
				if ($syscfg['dnsserver'][0])
1213
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1214
				$mpdconf .= "\n";
1215
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1216
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1217
			}
1218

    
1219
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1220
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1221
				$acctport = $authport + 1;
1222
				$mpdconf .=<<<EOD
1223
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1224

    
1225
EOD;
1226
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1227
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1228
				$acctport = $authport + 1;
1229
				$mpdconf .=<<<EOD
1230
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1231

    
1232
EOD;
1233
			}
1234
			$mpdconf .=<<<EOD
1235
	set radius retries 3
1236
	set radius timeout 10
1237
	set auth enable radius-auth
1238

    
1239
EOD;
1240

    
1241
				if (isset ($pptpdcfg['radius']['accounting'])) {
1242
					$mpdconf .=<<<EOD
1243
	set auth enable radius-acct
1244
	set radius acct-update 300
1245

    
1246
EOD;
1247
				}
1248
			}
1249

    
1250
			fwrite($fd, $mpdconf);
1251
			fclose($fd);
1252
			unset($mpdconf);
1253

    
1254
			/* write mpd.links */
1255
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1256
			if (!$fd) {
1257
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1258
				return 1;
1259
			}
1260

    
1261
			$mpdlinks = "";
1262

    
1263
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1264
				$mpdlinks .=<<<EOD
1265

    
1266
pt{$i}:
1267
	set link type pptp
1268
	set pptp enable incoming
1269
	set pptp disable originate
1270
	set pptp disable windowing
1271

    
1272
EOD;
1273
			}
1274

    
1275
			fwrite($fd, $mpdlinks);
1276
			fclose($fd);
1277
			unset($mpdlinks);
1278

    
1279
			/* write mpd.secret */
1280
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1281
			if (!$fd) {
1282
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1283
				return 1;
1284
			}
1285

    
1286
			$mpdsecret = "";
1287

    
1288
			if (is_array($pptpdcfg['user'])) {
1289
				foreach ($pptpdcfg['user'] as $user) {
1290
					$pass = str_replace('\\', '\\\\', $user['password']);
1291
					$pass = str_replace('"', '\"', $pass);
1292
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1293
				}
1294
			}
1295

    
1296
			fwrite($fd, $mpdsecret);
1297
			fclose($fd);
1298
			unset($mpdsecret);
1299
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1300

    
1301
			vpn_netgraph_support();
1302

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

    
1306
			break;
1307

    
1308
		case 'redir' :
1309
			break;
1310
	}
1311

    
1312
	if (platform_booting())
1313
		echo "done\n";
1314

    
1315
	return 0;
1316
}
1317

    
1318
function vpn_pppoes_configure() {
1319
	global $config;
1320

    
1321
	if (is_array($config['pppoes']['pppoe'])) {
1322
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1323
			vpn_pppoe_configure($pppoe);
1324
	}
1325
}
1326

    
1327
function vpn_pppoe_configure(&$pppoecfg) {
1328
	global $config, $g;
1329

    
1330
	$syscfg = $config['system'];
1331

    
1332
	/* create directory if it does not exist */
1333
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1334
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1335

    
1336
	if (platform_booting()) {
1337
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1338
			return 0;
1339

    
1340
		echo gettext("Configuring PPPoE Server service... ");
1341
	} else {
1342
		/* kill mpd */
1343
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1344

    
1345
		/* wait for process to die */
1346
		sleep(2);
1347

    
1348
	}
1349

    
1350
	switch ($pppoecfg['mode']) {
1351

    
1352
		case 'server' :
1353

    
1354
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1355

    
1356
			if ($pppoecfg['paporchap'] == "chap")
1357
				$paporchap = "set link enable chap";
1358
			else
1359
				$paporchap = "set link enable pap";
1360

    
1361
			/* write mpd.conf */
1362
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1363
			if (!$fd) {
1364
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1365
				return 1;
1366
			}
1367
			$mpdconf = "\n\n";
1368
			$mpdconf .= "poes:\n";
1369

    
1370
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1371
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1372
			}
1373

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

    
1376
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1377

    
1378
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1379
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1380
				} else {
1381
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1382
				}
1383

    
1384
				$mpdconf .=<<<EOD
1385

    
1386
poes{$pppoecfg['pppoeid']}{$i}:
1387
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1388
	{$isssue_ip_type}
1389
	load pppoe_standard
1390

    
1391
EOD;
1392
			}
1393

    
1394
			$mpdconf .=<<<EOD
1395

    
1396
pppoe_standard:
1397
	set bundle no multilink
1398
	set bundle enable compression
1399
	set auth max-logins 1
1400
	set iface up-script /usr/local/sbin/vpn-linkup
1401
	set iface down-script /usr/local/sbin/vpn-linkdown
1402
	set iface idle 0
1403
	set iface disable on-demand
1404
	set iface disable proxy-arp
1405
	set iface enable tcpmssfix
1406
	set iface mtu 1500
1407
	set link no pap chap
1408
	{$paporchap}
1409
	set link keep-alive 60 180
1410
	set ipcp yes vjcomp
1411
	set ipcp no vjcomp
1412
	set link max-redial -1
1413
	set link mtu 1492
1414
	set link mru 1492
1415
	set ccp yes mpp-e40
1416
	set ccp yes mpp-e128
1417
	set ccp yes mpp-stateless
1418
	set link latency 1
1419
	#set ipcp dns 10.10.1.3
1420
	#set bundle accept encryption
1421

    
1422
EOD;
1423

    
1424
			if (!empty($pppoecfg['dns1'])) {
1425
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1426
				if (!empty($pppoecfg['dns2']))
1427
					$mpdconf .= " " . $pppoecfg['dns2'];
1428
				$mpdconf .= "\n";
1429
			} elseif (isset ($config['dnsmasq']['enable'])) {
1430
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1431
				if ($syscfg['dnsserver'][0])
1432
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1433
				$mpdconf .= "\n";
1434
			} elseif (isset ($config['unbound']['enable'])) {
1435
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1436
				if ($syscfg['dnsserver'][0])
1437
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1438
				$mpdconf .= "\n";
1439
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1440
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1441
			}
1442

    
1443
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1444
				$radiusport = "";
1445
				$radiusacctport = "";
1446
				if (isset($pppoecfg['radius']['server']['port']))
1447
					$radiusport = $pppoecfg['radius']['server']['port'];
1448
				if (isset($pppoecfg['radius']['server']['acctport']))
1449
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1450
				$mpdconf .=<<<EOD
1451
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1452
	set radius retries 3
1453
	set radius timeout 10
1454
	set auth enable radius-auth
1455

    
1456
EOD;
1457

    
1458
				if (isset ($pppoecfg['radius']['accounting'])) {
1459
					$mpdconf .=<<<EOD
1460
	set auth enable radius-acct
1461

    
1462
EOD;
1463
				}
1464
			}
1465

    
1466
			fwrite($fd, $mpdconf);
1467
			fclose($fd);
1468
			unset($mpdconf);
1469

    
1470
			/* write mpd.links */
1471
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1472
			if (!$fd) {
1473
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1474
				return 1;
1475
			}
1476

    
1477
			$mpdlinks = "";
1478

    
1479
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1480
				$mpdlinks .=<<<EOD
1481

    
1482
poes{$pppoecfg['pppoeid']}{$i}:
1483
	set phys type pppoe
1484
	set pppoe iface {$pppoe_interface}
1485
	set pppoe service "*"
1486
	set pppoe disable originate
1487
	set pppoe enable incoming
1488

    
1489
EOD;
1490
			}
1491

    
1492
			fwrite($fd, $mpdlinks);
1493
			fclose($fd);
1494
			unset($mpdlinks);
1495

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

    
1504
				$mpdsecret = "\n\n";
1505

    
1506
				if (!empty($pppoecfg['username'])) {
1507
					$item = explode(" ", $pppoecfg['username']);
1508
					foreach($item as $userdata) {
1509
						$data = explode(":", $userdata);
1510
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1511
					}
1512
				}
1513

    
1514
				fwrite($fd, $mpdsecret);
1515
				fclose($fd);
1516
				unset($mpdsecret);
1517
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1518
			}
1519

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

    
1524
			/* Get support for netgraph(4) from the nic */
1525
			pfSense_ngctl_attach(".", $pppoe_interface);
1526
			/* fire up mpd */
1527
			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");
1528

    
1529
			break;
1530
	}
1531

    
1532
	if (platform_booting())
1533
		echo gettext("done") . "\n";
1534

    
1535
	return 0;
1536
}
1537

    
1538
function vpn_l2tp_configure() {
1539
	global $config, $g;
1540

    
1541
	$syscfg = $config['system'];
1542
	$l2tpcfg = $config['l2tp'];
1543

    
1544
	/* create directory if it does not exist */
1545
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1546
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1547

    
1548
	if (platform_booting()) {
1549
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1550
			return 0;
1551

    
1552
		echo gettext("Configuring l2tp VPN service... ");
1553
	} else {
1554
		/* kill mpd */
1555
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1556

    
1557
		/* wait for process to die */
1558
		sleep(8);
1559

    
1560
	}
1561

    
1562
	/* make sure l2tp-vpn directory exists */
1563
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1564
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1565

    
1566
	switch ($l2tpcfg['mode']) {
1567

    
1568
		case 'server' :
1569
			if ($l2tpcfg['paporchap'] == "chap")
1570
				$paporchap = "set link enable chap";
1571
			else
1572
				$paporchap = "set link enable pap";
1573

    
1574
			/* write mpd.conf */
1575
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1576
			if (!$fd) {
1577
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1578
				return 1;
1579
			}
1580
			$mpdconf = "\n\n";
1581
			$mpdconf .=<<<EOD
1582
l2tps:
1583

    
1584
EOD;
1585

    
1586
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1587
				$mpdconf .= "	load l2tp{$i}\n";
1588
			}
1589

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

    
1592
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1593

    
1594
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1595
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1596
				} else {
1597
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1598
				}
1599

    
1600
				$mpdconf .=<<<EOD
1601

    
1602
l2tp{$i}:
1603
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1604
	{$isssue_ip_type}
1605
	load l2tp_standard
1606

    
1607
EOD;
1608
			}
1609

    
1610
			$mpdconf .=<<<EOD
1611

    
1612
l2tp_standard:
1613
	set bundle disable multilink
1614
	set bundle enable compression
1615
	set bundle yes crypt-reqd
1616
	set ipcp yes vjcomp
1617
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1618
	set ccp yes mppc
1619
	set iface disable on-demand
1620
	set iface enable proxy-arp
1621
	set iface up-script /usr/local/sbin/vpn-linkup
1622
	set iface down-script /usr/local/sbin/vpn-linkdown
1623
	set link yes acfcomp protocomp
1624
	set link no pap chap
1625
	set link enable chap
1626
	set link keep-alive 10 180
1627

    
1628
EOD;
1629

    
1630
			if (is_ipaddr($l2tpcfg['wins'])) {
1631
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1632
			}
1633
			if (is_ipaddr($l2tpcfg['dns1'])) {
1634
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1635
				if (is_ipaddr($l2tpcfg['dns2']))
1636
					$mpdconf .= " " . $l2tpcfg['dns2'];
1637
				$mpdconf .= "\n";
1638
			} elseif (isset ($config['dnsmasq']['enable'])) {
1639
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1640
				if ($syscfg['dnsserver'][0])
1641
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1642
				$mpdconf .= "\n";
1643
			} elseif (isset ($config['unbound']['enable'])) {
1644
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1645
				if ($syscfg['dnsserver'][0])
1646
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1647
				$mpdconf .= "\n";
1648
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1649
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1650
			}
1651

    
1652
			if (isset ($l2tpcfg['radius']['enable'])) {
1653
				$mpdconf .=<<<EOD
1654
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1655
	set radius retries 3
1656
	set radius timeout 10
1657
	set auth enable radius-auth
1658

    
1659
EOD;
1660

    
1661
				if (isset ($l2tpcfg['radius']['accounting'])) {
1662
					$mpdconf .=<<<EOD
1663
	set auth enable radius-acct
1664

    
1665
EOD;
1666
				}
1667
			}
1668

    
1669
			fwrite($fd, $mpdconf);
1670
			fclose($fd);
1671
			unset($mpdconf);
1672

    
1673
			/* write mpd.links */
1674
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1675
			if (!$fd) {
1676
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1677
				return 1;
1678
			}
1679

    
1680
			$mpdlinks = "";
1681

    
1682
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1683
				$mpdlinks .=<<<EOD
1684

    
1685
l2tp{$i}:
1686
	set link type l2tp
1687
	set l2tp enable incoming
1688
	set l2tp disable originate
1689

    
1690
EOD;
1691
			if (!empty($l2tpcfg['secret']))
1692
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1693
			}
1694

    
1695
			fwrite($fd, $mpdlinks);
1696
			fclose($fd);
1697
			unset($mpdlinks);
1698

    
1699
			/* write mpd.secret */
1700
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1701
			if (!$fd) {
1702
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1703
				return 1;
1704
			}
1705

    
1706
			$mpdsecret = "\n\n";
1707

    
1708
			if (is_array($l2tpcfg['user'])) {
1709
				foreach ($l2tpcfg['user'] as $user)
1710
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1711
			}
1712

    
1713
			fwrite($fd, $mpdsecret);
1714
			fclose($fd);
1715
			unset($mpdsecret);
1716
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1717

    
1718
			vpn_netgraph_support();
1719

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

    
1723
			break;
1724

    
1725
		case 'redir' :
1726
			break;
1727
	}
1728

    
1729
	if (platform_booting())
1730
		echo "done\n";
1731

    
1732
	return 0;
1733
}
1734

    
1735
function vpn_ipsec_configure_preferoldsa() {
1736
	global $config;
1737
	if(isset($config['ipsec']['preferoldsa']))
1738
		set_single_sysctl("net.key.preferred_oldsa", "-30");
1739
	else
1740
		set_single_sysctl("net.key.preferred_oldsa", "0");
1741
}
1742

    
1743
?>
(59-59/68)