Project

General

Profile

Download (49 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:	/usr/bin/killall	/usr/local/sbin/sasyncd	/sbin/ifconfig	/sbin/sysctl
38
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/setkey	/usr/bin/netstat	/sbin/route	/bin/mkdir
39
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/racoonctl	/usr/local/sbin/racoon
40
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/filterdns	/usr/local/sbin/mpd4	
41
	pfSense_MODULE:	vpn
42
*/
43

    
44
/* include all configuration functions */
45

    
46
function vpn_ipsec_failover_configure() {
47
	global $config, $g;
48

    
49

    
50
	if (is_array($config['installedpackages']['sasyncd'])) {
51
		$sasyncd_text = "";
52
		foreach ($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
53
			$enabled = isset ($sasyncd['enable']);
54
			if (!$enabled)
55
				return;
56
			if ($sasyncd['peerip'] <> "")
57
				$sasyncd_text .= "peer {$sasyncd['peerip']}\n";
58
			if ($sasyncd['interface'])
59
				$sasyncd_text .= "carp interface {$sasyncd['interface']}\n";
60
			if ($sasyncd['sharedkey'] <> "")
61
				$sasyncd_text .= "sharedkey {$sasyncd['sharedkey']}\n";
62
			if ($sasyncd['mode'] <> "")
63
				$sasyncd_text .= "mode {$sasyncd['mode']}\n";
64
			if ($sasyncd['listenon'] <> "")
65
				$sasyncd_text .= "listen on {$sasyncd['listenon']}\n";
66
			if ($sasyncd['flushmodesync'] <> "")
67
				$sasyncd_text .= "flushmode sync {$sasyncd['flushmodesync']}\n";
68
		}
69

    
70
		file_put_contents("{$g['varetc_path']}/sasyncd.conf", $sasyncd_text);
71
		chmod("{$g['varetc_path']}/sasyncd.conf", 0600);
72

    
73
		if(is_process_running("sasyncd"))
74
			mwexec("killall sasyncd", true);
75

    
76
		/* launch sasyncd, oh wise one */
77
		mwexec_bg("/usr/local/sbin/sasyncd -d -v -v -v");
78
	}
79
}
80

    
81
function vpn_ipsec_configure($ipchg = false)
82
{
83
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos;
84

    
85
	/* get the automatic ping_hosts.sh ready */
86
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
87
	touch("{$g['vardb_path']}/ipsecpinghosts");
88

    
89
	vpn_ipsec_configure_preferoldsa();
90

    
91
	$syscfg = $config['system'];
92
	$ipseccfg = $config['ipsec'];
93
	$a_phase1 = $config['ipsec']['phase1'];
94
	$a_phase2 = $config['ipsec']['phase2'];
95
	$a_client = $config['ipsec']['client'];
96

    
97
	if (!isset($ipseccfg['enable'])) {
98
		mwexec("/sbin/ifconfig enc0 down");
99

    
100
		/* send a SIGKILL to be sure */
101
		sigkillbypid("{$g['varrun_path']}/racoon.pid", "KILL");
102

    
103
		/* kill racoon */
104
		if(is_process_running("racoon"))
105
			mwexec("/usr/bin/killall racoon", true);
106
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
107

    
108
		/* wait for racoon process to die */
109
		sleep(2);
110

    
111
		/* flush SPD and SAD */
112
		mwexec("/usr/local/sbin/setkey -F");
113
		mwexec("/usr/local/sbin/setkey -FP");
114

    
115
		/* disallow IPSEC, it is off */
116
		exec("/sbin/sysctl net.inet.ip.ipsec_in_use=0");
117

    
118
		return true;
119
	} else {
120
		mwexec("/sbin/ifconfig enc0 up");
121
		mwexec("/sbin/sysctl net.inet.ip.ipsec_in_use=1");
122

    
123
		if ($g['booting'])
124
			echo "Configuring IPsec VPN... ";
125

    
126
		/* fastforwarding is not compatible with ipsec tunnels */
127
		mwexec("/sbin/sysctl net.inet.ip.fastforwarding=0");
128

    
129
		/* this loads a route table which is used to determine if a route needs to be removed. */
130
		exec("/usr/bin/netstat -rnf inet", $route_arr, $retval);
131
		$route_str = implode("\n", $route_arr);
132

    
133
		/* resolve all local, peer addresses and setup pings */
134
		$ipmap = array();
135
		$rgmap = array();
136
		$filterdns_list = array();
137
		if (is_array($a_phase1) && count($a_phase1)) {
138

    
139
			$ipsecpinghosts = "";
140
			/* step through each phase1 entry */
141
			foreach ($a_phase1 as $ph1ent) {
142
				if (isset($ph1ent['disabled']))
143
					continue;
144

    
145
				$ep = ipsec_get_phase1_src($ph1ent);
146
				if (!$ep)
147
					continue;
148

    
149
				if(!in_array($ep,$ipmap))
150
					$ipmap[] = $ep;
151

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

    
155
				if (isset ($ph1ent['mobile']))
156
					continue;
157

    
158
				$rg = $ph1ent['remote-gateway'];
159

    
160
				if (!is_ipaddr($rg)) {
161
					$filterdns_list[] = "{$rg}";
162
					add_hostname_to_watch($rg);
163
					if(! $g['booting'])
164
						$rg = resolve_retry($rg);
165
					if (!is_ipaddr($rg))
166
						continue;
167
				}
168
				if(array_search($rg, $rgmap)) {
169
					log_error("The remote gateway {$rg} already exists on another phase 1 entry");
170
					continue;
171
				}
172
				$rgmap[$ph1ent['remote-gateway']] = $rg;
173

    
174
				/* step through each phase2 entry */
175
				foreach ($a_phase2 as $ph2ent) {
176

    
177
					$ikeid = $ph2ent['ikeid'];
178

    
179
					if (isset($ph2ent['disabled']))
180
						continue;
181

    
182
					if ($ikeid != $ph1ent['ikeid'])
183
						continue;
184

    
185
					/* add an ipsec pinghosts entry */
186
					if ($ph2ent['pinghost']) {
187
						$iflist = get_configured_interface_list();
188
						foreach ($iflist as $ifent => $ifname) {
189
							$interface_ip = get_interface_ip($ifent);
190
							$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true);
191
							if (ip_in_subnet($interface_ip, $local_subnet)) {
192
								$srcip = $interface_ip;
193
								break;
194
							}
195
						}
196
						$dstip = $ph2ent['pinghost'];
197
						if (is_ipaddr($srcip))
198
							$ipsecpinghosts .= "{$srcip}|{$dstip}|3\n";
199
					}
200
				}
201
				$pfd = fopen("{$g['vardb_path']}/ipsecpinghosts", "w");
202
				if ($pfd) {
203
					fwrite($pfd, $ipsecpinghosts);
204
					fclose($pfd);
205
				}
206
				
207
			}
208
		}
209

    
210
		/* generate CA certificates files */
211
		if (is_array($config['ca']) && count($config['ca'])) {
212
			foreach ($config['ca'] as $ca) {
213
				if (!isset($ca['crt'])) {
214
					log_error("Error: Invalid certificate info for {$ca['descr']}");
215
					continue;
216
				}
217
				$cert = base64_decode($ca['crt']);
218
				$x509cert = openssl_x509_parse(openssl_x509_read($cert));
219
				if (!is_array($x509cert) || !isset($x509cert['hash'])) {
220
					log_error("Error: Invalid certificate hash info for {$ca['descr']}");
221
					continue;
222
				}
223
				$fname = $g['varetc_path']."/".$x509cert['hash'].".0";
224
				if (!file_put_contents($fname, $cert)) {
225
					log_error("Error: Cannot write IPsec CA file for {$ca['descr']}");
226
					continue;
227
				}
228
			}
229
		}
230
		
231
		/* generate psk.txt */
232
		$fd = fopen("{$g['varetc_path']}/psk.txt", "w");
233
		if (!$fd) {
234
			printf("Error: cannot open psk.txt in vpn_ipsec_configure().\n");
235
			return 1;
236
		}
237

    
238
		$pskconf = "";
239

    
240
		if (is_array($a_phase1) && count($a_phase1)) {
241
			foreach ($a_phase1 as $ph1ent) {
242

    
243
				if (isset($ph1ent['disabled']))
244
					continue;
245

    
246
				if (strstr($ph1ent['authentication_method'],'rsa'))
247
					continue;
248

    
249
				$peerid_type = $ph1ent['peerid_type'];
250

    
251
				switch ($peerid_type) {
252
					case "peeraddress":
253
						$peerid_type = "address";
254
						$peerid_data = $rgmap[$ph1ent['remote-gateway']];
255
						break;
256

    
257
					case "address";
258
						$peerid_data = $ph1ent['peerid_data'];
259
						break;
260

    
261
					case "fqdn";
262
					case "keyid tag";
263
					case "user_fqdn";
264
						$peerid_data = $ph1ent['peerid_data'];
265
						break;
266
				}
267

    
268
				$pskconf .= "{$peerid_data}\t{$ph1ent['pre-shared-key']}\n";
269
			}
270
		}
271

    
272
		/* Add user PSKs */
273
		foreach ($config['system']['user'] as $user) {
274
			if (!empty($user['ipsecpsk'])) {
275
				$pskconf .= "{$user['name']}\t{$user['ipsecpsk']}\n";
276
			}
277
		}
278

    
279
		/* add PSKs for mobile clients */
280
		if (is_array($ipseccfg['mobilekey'])) {
281
			foreach ($ipseccfg['mobilekey'] as $key) {
282
				$pskconf .= "{$key['ident']}\t{$key['pre-shared-key']}\n";
283
			}
284
		}
285

    
286
		fwrite($fd, $pskconf);
287
		fclose($fd);
288
		chmod("{$g['varetc_path']}/psk.txt", 0600);
289
			
290
		/* begin racoon.conf */
291
		if ((is_array($a_phase1) && count($a_phase1)) ||
292
			(is_array($a_phase2) && count($a_phase2))) {
293

    
294
			$fd = fopen("{$g['varetc_path']}/racoon.conf", "w");
295
			if (!$fd) {
296
				printf("Error: cannot open racoon.conf in vpn_ipsec_configure().\n");
297
				return 1;
298
			}
299

    
300
			$racoonconf = "# This file is automatically generated. Do not edit\n";			
301
			$racoonconf .= "path pre_shared_key \"{$g['varetc_path']}/psk.txt\";\n\n";
302
			$racoonconf .= "path certificate  \"{$g['varetc_path']}\";\n\n";
303

    
304
			/* begin listen section */
305
			if (count($ipmap)) {
306
				$racoonconf .= "\nlisten\n";
307
				$racoonconf .= "{\n";
308
				$racoonconf .= "	adminsock \"/var/db/racoon/racoon.sock\" \"root\" \"wheel\" 0660;\n";
309
				foreach ($ipmap as $addr) {
310
					$racoonconf .= "\tisakmp {$addr} [500];\n";
311
					$racoonconf .= "\tisakmp_natt {$addr} [4500];\n";
312
				}
313
				$racoonconf .= "}\n\n";
314
			}
315

    
316
			/* begin mode_cfg section */
317
			if (is_array($a_client) && isset($a_client['enable'])) {
318

    
319
				$racoonconf .= "\nmode_cfg\n";
320
				$racoonconf .= "{\n";
321

    
322
				if ($a_client['user_source'])
323
					$racoonconf .= "\tauth_source {$a_client['user_source']};\n";
324
				if ($a_client['group_source'])
325
					$racoonconf .= "\tgroup_source {$a_client['group_source']};\n";
326

    
327
				if ($a_client['pool_address'] && $a_client['pool_netbits']) {
328
					$pool_address = $a_client['pool_address'];
329
					$pool_netmask = gen_subnet_mask($a_client['pool_netbits']);
330

    
331
					$pool_address = long2ip32(ip2long($pool_address)+1);
332
					$pool_size = (~ip2long($pool_netmask) & 0xFFFFFFFF) - 2;
333

    
334
					$racoonconf .= "\tpool_size {$pool_size};\n";
335
					$racoonconf .= "\tnetwork4 {$pool_address};\n";
336
					$racoonconf .= "\tnetmask4 {$pool_netmask};\n";
337
				}
338

    
339
				if (isset($a_client['net_list'])) {
340

    
341
					$net_list = '';
342

    
343
					foreach ($a_phase2 as $ph2ent) {
344

    
345
						if (isset($ph2ent['disabled']))
346
							continue;
347

    
348
						if (!isset($ph2ent['mobile']))
349
							continue;
350

    
351
						$localid = ipsec_idinfo_to_cidr($ph2ent['localid'],true);
352

    
353
						if ($net_list)
354
							$net_list .= ", ";
355
						$net_list .= $localid;
356
					}
357

    
358
					if ($net_list)
359
						$racoonconf .= "\tsplit_network include {$net_list};\n";
360
				}
361

    
362
				if ($a_client['dns_server1'])
363
					$racoonconf .= "\tdns4 {$a_client['dns_server1']};\n";
364
				if ($a_client['dns_server2'])
365
					$racoonconf .= "\tdns4 {$a_client['dns_server2']};\n";
366
				if ($a_client['dns_server3'])
367
					$racoonconf .= "\tdns4 {$a_client['dns_server3']};\n";
368
				if ($a_client['dns_server4'])
369
					$racoonconf .= "\tdns4 {$a_client['dns_server4']};\n";
370

    
371
				if ($a_client['wins_server1'])
372
					$racoonconf .= "\twins4 {$a_client['wins_server1']};\n";
373
				if ($a_client['wins_server2'])
374
					$racoonconf .= "\twins4 {$a_client['wins_server2']};\n";
375

    
376
				if ($a_client['dns_domain']) {
377
					$racoonconf .= "\tdefault_domain \"{$a_client['dns_domain']}\";\n";
378
					$racoonconf .= "\tsplit_dns \"{$a_client['dns_domain']}\";\n";
379
				}
380

    
381
				if ($a_client['pfs_group'])
382
					$racoonconf .= "\tpfs_group {$a_client['pfs_group']};\n";
383

    
384
				if ($a_client['login_banner']) {
385
					$fn = "{$g['varetc_path']}/racoon.motd";
386
					$fd1 = fopen($fn, "w");
387
					if (!$fd1) {
388
						printf("Error: cannot open server{$fn} in vpn.\n");
389
						return 1;
390
					}
391

    
392
					fwrite($fd1, $a_client['login_banner']);
393
					fclose($fd1);
394

    
395
					$racoonconf .= "\tbanner \"{$fn}\";\n";
396
				}
397

    
398
				if (isset($a_client['save_passwd']))
399
					$racoonconf .= "\tsave_passwd on;\n";
400

    
401
				$racoonconf .= "}\n\n";
402
			}
403
			/* end mode_cfg section */
404

    
405
			/* begin remote sections */
406
			if (is_array($a_phase1) && count($a_phase1)) {
407
				/* begin remote */
408
				foreach ($a_phase1 as $ph1ent) {
409

    
410
					if (isset($ph1ent['disabled']))
411
						continue;
412

    
413
					if (isset($ph1ent['mobile']) && !isset($a_client['enable']))
414
						continue;
415

    
416
					$ikeid = $ph1ent['ikeid'];
417

    
418
					$ep = ipsec_get_phase1_src($ph1ent);
419
					if (!$ep)
420
						continue;
421

    
422
					if (!isset($ph1ent['mobile'])) {
423
						$rgip = $rgmap[$ph1ent['remote-gateway']];
424
						if (!$rgip)
425
							continue;
426
					}
427

    
428
					$myid_type = $ph1ent['myid_type'];
429

    
430
					switch ($myid_type) {
431

    
432
						case "myaddress":
433
							$myid_type = "address";
434
							$myid_data = $ep;
435
							break;
436

    
437
						case "dyn_dns":
438
							$myid_type = "address";
439
							$myid_data = gethostbyname($ph1ent['myid_data']);
440
							break;
441

    
442
						case "address";
443
							$myid_data = $ph1ent['myid_data'];
444
							break;
445

    
446
						case "fqdn";
447
						case "keyid tag";
448
						case "user_fqdn";
449
						case "asn1dn";
450
							$myid_data = $ph1ent['myid_data'];
451
							if( $myid_data )
452
								$myid_data = "\"".$myid_data."\"";
453
							break;
454
					}
455

    
456
					$peerid_type = $ph1ent['peerid_type'];
457

    
458
					switch ($peerid_type) {
459
						case "peeraddress":
460
							$peerid_type = "address";
461
							$peerid_data = $rgip;
462
							break;
463

    
464
						case "address";
465
							$peerid_data = $ph1ent['peerid_data'];
466
							break;
467

    
468
						case "fqdn";
469
						case "keyid tag";
470
						case "user_fqdn";
471
						case "asn1dn";
472
							$peerid_data = $ph1ent['peerid_data'];
473
							if( $peerid_data )
474
								$peerid_data = "\"".$peerid_data."\"";
475
							break;
476
					}
477

    
478
					$natt = "off";
479
					if (isset($ph1ent['nat_traversal']))
480
						$natt = $ph1ent['nat_traversal'];
481

    
482
					$init = "on";
483
					$genp = "off";
484
					$pcheck = !empty($ph1ent['proposal_check']) ? $ph1ent['proposal_check'] : $pcheck = "claim";
485
					$passive = "";
486
					if (isset($ph1ent['mobile'])) {
487
						$rgip = "anonymous";
488
						/* Mimic 1.2.3's behavior for pure-psk mobile tunnels */
489
						if ($ph1ent['authentication_method'] == "pre_shared_key") {
490
							$passive = "passive on;";
491
							$pcheck = !empty($ph1ent['proposal_check']) ? $ph1ent['proposal_check'] : $pcheck = "obey";
492
							$genp = "on";
493
						} else {
494
							$init = "off";
495
							$genp = "unique";
496
						}
497
					}
498

    
499
					$dpdline1 = '';
500
					$dpdline2 = '';
501
					if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
502
						$dpdline1 = "dpd_delay = {$ph1ent['dpd_delay']};";
503
						$dpdline2 = "dpd_maxfail = {$ph1ent['dpd_maxfail']};";
504
					}
505

    
506
					if (isset ($ph1ent['authentication_method']))
507
						$authmethod = $ph1ent['authentication_method'];
508
					else
509
						$authmethod = 'pre_shared_key';
510

    
511
					$certline = '';
512

    
513
					if (strstr($authmethod,'rsa')) {
514

    
515
						$cert = lookup_cert($ph1ent['certref']);
516

    
517
						if (!$cert)
518
						{
519
							log_error("Error: Invalid phase1 certificate reference for {$ph1ent['name']}");
520
							continue;
521
						}
522

    
523
						$certfile = "cert-".$ikeid.".crt";
524
						$certpath = $g['varetc_path']."/".$certfile;
525

    
526
						if (!file_put_contents($certpath, base64_decode($cert['crt'])))
527
						{
528
							log_error("Error: Cannot write phase1 certificate file for {$ph1ent['name']}");
529
							continue;
530
						}
531

    
532
						chmod($certpath, 0600);
533

    
534
						$keyfile = "cert-".$ikeid.".key";
535
						$keypath = $g['varetc_path']."/".$keyfile;
536

    
537
						if (!file_put_contents($keypath, base64_decode($cert['prv'])))
538
						{
539
							log_error("Error: Cannot write phase1 key file for {$ph1ent['name']}");
540
							continue;
541
						}
542

    
543
						chmod($keypath, 0600);
544

    
545
						$ca = lookup_ca($ph1ent['caref']);
546
						if ($ca) {
547
							$cafile = "ca-".$ikeid.".crt";
548
							$capath = $g['varetc_path']."/".$cafile;
549

    
550
							if (!file_put_contents($capath, base64_decode($ca['crt'])))
551
							{
552
								log_error("Error: Cannot write phase1 CA certificate file for {$ph1ent['name']}");
553
								continue;
554
							}
555

    
556
							chmod($capath, 0600);
557
							$caline = "ca_type x509 \"".basename($capath)."\";";
558
						}
559

    
560
						$certline = "certificate_type x509 \"".basename($certpath)."\" \"".basename($keypath)."\";";
561

    
562
					}
563

    
564
					$ealgos = '';
565
					$ealg_id = $ph1ent['encryption-algorithm']['name'];
566
					$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
567
					if ($ealg_kl)
568
						$ealgos = $ealgos.$ealg_id." ".$ealg_kl;
569
					else
570
						$ealgos = $ealgos.$ealg_id;
571

    
572
					$lifeline = '';
573
					if ($ph1ent['lifetime'])
574
						$lifeline = "lifetime time {$ph1ent['lifetime']} secs;";
575

    
576
					/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
577
					if (!(($ph1ent['authentication_method'] == "pre_shared_key") && isset($ph1ent['mobile']))) {
578
						$peerid_spec = "peers_identifier {$peerid_type} {$peerid_data};";
579
					}
580

    
581
					/* add remote section to configuration */
582

    
583
					$racoonconf .=<<<EOD
584

    
585
remote {$rgip}
586
{
587
	ph1id {$ikeid};
588
	exchange_mode {$ph1ent['mode']};
589
	my_identifier {$myid_type} {$myid_data};
590
	{$peerid_spec}
591
	ike_frag on;
592
	generate_policy = {$genp};
593
	initial_contact = {$init};
594
	nat_traversal = {$natt};
595
	{$certline}
596
	{$caline}
597
	{$dpdline1}
598
	{$dpdline2}
599
	support_proxy on;
600
	proposal_check {$pcheck};
601
	{$passive}
602

    
603
	proposal
604
	{
605
		authentication_method {$authmethod};
606
		encryption_algorithm ${ealgos};
607
		hash_algorithm {$ph1ent['hash-algorithm']};
608
		dh_group {$ph1ent['dhgroup']};
609
		${lifeline}
610
	}
611
}
612

    
613
EOD;
614
				}
615
				/* end remote */
616
			}
617
			/* end remote sections */
618
		
619
			/* begin sainfo sections */
620
			if (is_array($a_phase2) && count($a_phase2)) {
621

    
622
				/* begin sainfo */
623
				foreach ($a_phase2 as $ph2ent) {
624

    
625
					$ikeid = $ph2ent['ikeid'];
626

    
627
					if( !ipsec_lookup_phase1($ph2ent,$ph1ent))
628
						continue;
629

    
630
					if (isset($ph1ent['disabled']))
631
						continue;
632

    
633
					if (isset($ph2ent['disabled']))
634
						continue;
635

    
636
					if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
637
						continue;
638

    
639
					if ($ph2ent['mode'] == 'tunnel') {
640

    
641
						$localid_type = $ph2ent['localid']['type'];
642
						$localid_data = ipsec_idinfo_to_cidr($ph2ent['localid']);
643
						/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
644
						if (($localid_type == "none") ||
645
							(($ph1ent['authentication_method'] == "xauth_psk_server") ||
646
							($ph1ent['authentication_method'] == "pre_shared_key"))
647
							&& isset($ph1ent['mobile'])
648
							&& (ipsec_get_number_of_phase2($ikeid)==1))
649
							$localid_spec = " ";
650
						else {
651
							if ($localid_type != "address") {
652
								$localid_type = "subnet";
653
							}
654
							$localid_spec = $localid_type." ".$localid_data." any";
655
						}
656

    
657
						if (!isset($ph2ent['mobile'])) {
658
							$remoteid_type = $ph2ent['remoteid']['type'];
659
							if ($remoteid_type != "address")
660
								$remoteid_type = "subnet";
661

    
662
							$remoteid_data = ipsec_idinfo_to_cidr($ph2ent['remoteid']);
663
							$remoteid_spec = $remoteid_type." ".$remoteid_data." any";
664
						} else
665
							$remoteid_spec = "anonymous";
666

    
667
					} else {
668
						$rgip = $rgmap[$ph1ent['remote-gateway']];
669

    
670
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
671
							($ph1ent['authentication_method'] == "pre_shared_key"))
672
							&& isset($ph1ent['mobile']))
673
							$localid_spec = " ";
674
						else {
675
							$localid_data = ipsec_get_phase1_src($ph1ent);
676
							if($ph2ent['mode'] == 'transport') { $localid_data="$localid_data any"; }
677
							$localid_spec = "address {$localid_data}";
678
						}
679
						if (!isset($ph2ent['mobile'])) {
680
							$remoteid_data = $rgmap[$ph1ent['remote-gateway']];
681
							if($ph2ent['mode'] == 'transport') { $remoteid_data="$remoteid_data any"; }
682
							$remoteid_spec = "address {$remoteid_data}";
683
						} else
684
							$remoteid_spec = "anonymous";
685
					}
686

    
687
					if($ph2ent['protocol'] == 'esp') {
688

    
689
						$ealgos = '';
690

    
691
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
692

    
693
							$ealg_id = $ealg['name'];
694
							$ealg_kl = $ealg['keylen'];
695

    
696
							if ($ealg_kl) {
697
								if( $ealg_kl == "auto" ) {
698
									/*   This seems to be required on my system and was not reproducable
699
									 *   on other systems.   For some reason $p2_ealgos is not defined
700
									 *   and needs to be read back in!?  -sullrich Aug 26, 2009 
701
									 */
702
									if(!$p2_ealgos)
703
										require("ipsec.inc");
704
									$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
705
									$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
706
									$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
707
									/* in some cases where include ordering is suspect these variables
708
									   are somehow 0 and we enter this loop forever and timeout after 900
709
									   seconds wrecking bootup */
710
									if($key_hi != 0 and $key_lo !=0 and $key_step !=0) {
711
										for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
712
//											Uncomment the next line if you want to test the comment 5 lines up.											
713
//											echo "$keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step \n";
714
											if ($ealgos)
715
												$ealgos = $ealgos.", ";
716
											$ealgos = $ealgos.$ealg_id." ".$keylen;
717
										}
718
									}
719
								} else {
720
									if ($ealgos)
721
										$ealgos = $ealgos.", ";
722
									$ealgos = $ealgos.$ealg_id." ".$ealg_kl;
723
								}
724
							} else {
725
								if ($ealgos)
726
									$ealgos = $ealgos.", ";
727
								$ealgos = $ealgos.$ealg_id;
728
							}
729
						}
730

    
731
						$ealgosline = "encryption_algorithm {$ealgos};";
732

    
733
					} else {
734

    
735
						$ealgosline = "encryption_algorithm null_enc;";
736
					}
737

    
738
					$halgos = join(",", $ph2ent['hash-algorithm-option']);
739
					$halgosline = "authentication_algorithm {$halgos};";
740

    
741
					$pfsline = '';
742
					if ($ph2ent['pfsgroup'])
743
						$pfsline = "pfs_group {$ph2ent['pfsgroup']};";
744
					if (isset($a_client['pfs_group'])) {
745
						$pfsline = '';
746
						if ($a_client['pfs_group'])
747
							$pfsline = "pfs_group {$a_client['pfs_group']};";
748
					}
749

    
750
					$lifeline = '';
751
					if ($ph2ent['lifetime'])
752
						$lifeline = "lifetime time {$ph2ent['lifetime']} secs;";
753

    
754
					/* add sainfo section to configuration */
755
					
756
					$racoonconf .=<<<EOD
757
					
758
sainfo {$localid_spec} {$remoteid_spec}
759
{
760
	remoteid {$ikeid};
761
	{$ealgosline}
762
	{$halgosline}
763
	{$pfsline}
764
	{$lifeline}
765
	compression_algorithm deflate;
766
}
767

    
768
EOD;
769
				}
770
				/* end sainfo */
771
			}
772
			/* end sainfo sections */
773

    
774
			fwrite($fd, $racoonconf);
775
			fclose($fd);
776
		}
777
		/* end racoon.conf */
778

    
779
		/* generate IPsec policies */
780
		if (is_array($a_phase2) && count($a_phase2)) {
781
			/* generate spd.conf */
782
			$fd = fopen("{$g['varetc_path']}/spd.conf", "w");
783
			if (!$fd) {
784
				printf("Error: cannot open spd.conf in vpn_ipsec_configure().\n");
785
				return 1;
786
			}
787

    
788
			$spdconf = "";
789

    
790
			/* Try to prevent people from locking themselves out of webgui. Just in case. */
791
			if ($config['interfaces']['lan']) {
792
				$lanip = get_interface_ip("lan");
793
				if (!empty($lanip) && is_ipaddr($lanip)) {
794
					$lansn = get_interface_subnet("lan");
795
					$lansa = gen_subnet($lanip, $lansn);
796
					$spdconf .= "spdadd {$lanip}/32 {$lansa}/{$lansn} any -P out none;\n";
797
					$spdconf .= "spdadd {$lansa}/{$lansn} {$lanip}/32 any -P in none;\n";
798
				}
799
			}
800

    
801
			foreach ($a_phase2 as $ph2ent) {
802

    
803
				if( !ipsec_lookup_phase1($ph2ent,$ph1ent))
804
					continue;
805

    
806
				if (isset($ph1ent['mobile']))
807
					continue;
808

    
809
				if (isset($ph1ent['disabled']))
810
					continue;
811

    
812
				if (isset($ph2ent['disabled']))
813
					continue;
814

    
815
				$ep = ipsec_get_phase1_src($ph1ent);
816
				if (!$ep)
817
					continue;
818

    
819
				$rgip = $rgmap[$ph1ent['remote-gateway']];
820
				if(!is_ipaddr($rgip))
821
					continue;
822

    
823
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'],true);
824
				$remoteid = ipsec_idinfo_to_cidr($ph2ent['remoteid'],true);
825

    
826
				if($ph2ent['mode'] == "tunnel") {
827

    
828
					$spdconf .= "spdadd {$localid} {$remoteid} any -P out ipsec " .
829
						"{$ph2ent['protocol']}/tunnel/{$ep}-{$rgip}/unique;\n";
830

    
831
					$spdconf .= "spdadd {$remoteid} {$localid} any -P in ipsec " .
832
						"{$ph2ent['protocol']}/tunnel/{$rgip}-{$ep}/unique;\n";
833

    
834
				} else {
835

    
836
					$localid_data = ipsec_get_phase1_src($ph1ent);
837
					$remoteid_data = $rgmap[$ph1ent['remote-gateway']];
838

    
839
					$spdconf .= "spdadd {$localid_data} {$remoteid_data} any -P out ipsec " .
840
						"{$ph2ent['protocol']}/transport//require;\n";
841

    
842
					$spdconf .= "spdadd {$remoteid_data} {$localid_data} any -P in ipsec " .
843
						"{$ph2ent['protocol']}/transport//require;\n";
844

    
845
				}
846

    
847
				/* static route needed? */
848
				if (preg_match("/^carp|^vip/i", $ph1ent['interface']))
849
					$parentinterface = link_carp_interface_to_parent($ph1ent['interface']);
850
				else
851
					$parentinterface = $ph1ent['interface'];
852

    
853
				if (($parentinterface <> "wan") && (is_ipaddr($rgip))) {
854
					/* add endpoint routes to correct gateway on interface */
855
					if (interface_has_gateway($parentinterface)) {
856
						$gatewayip = get_interface_gateway("$parentinterface");
857
						$interfaceip = get_interface_ip($parentinterface);
858
						$subnet_bits = get_interface_subnet($parentinterface);
859
						$subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
860
						/* if the remote gateway is in the local subnet, then don't add a route */
861
						if (! ip_in_subnet($rgip, "{$subnet_ip}/{$subnet_bits}")) {
862
							if(is_ipaddr($gatewayip)) {
863
								/* FIXME: does adding route-to and reply-to on the in/outbound
864
								 * rules fix this? smos@ 13-01-2009 */
865
								log_error("IPSEC interface is not WAN but {$parentinterface}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
866
								mwexec("/sbin/route delete -host {$rgip}");
867
								mwexec("/sbin/route add -host {$rgip} {$gatewayip}");
868
							}
869
						}
870
					}
871
				} elseif(is_ipaddr($rgip)) {
872
					if(stristr($route_str, "{$rgip}")) {
873
						mwexec("/sbin/route delete -host {$rgip}", true);
874
					}
875
				}
876
			}
877

    
878
			fwrite($fd, $spdconf);
879
			fclose($fd);
880
		}
881

    
882
		/* needed for racoonctl admin socket */
883
		if (!is_dir("/var/db/racoon"))
884
			mkdir("/var/db/racoon/");
885
		
886
		/* mange racoon process */
887
		if (is_process_running("racoon")) {
888
			sleep("0.1");
889
			mwexec("/usr/local/sbin/racoonctl -s /var/db/racoon/racoon.sock reload-config", false);
890
			/* load SPD without flushing to be safe on config additions or changes. */
891
			mwexec("/usr/local/sbin/setkey -f {$g['varetc_path']}/spd.conf", false);
892
		} else {
893
			/* flush SA + SPD entries */
894
			mwexec("/usr/local/sbin/setkey -FP", false);
895
 			sleep("0.1");
896
			mwexec("/usr/local/sbin/setkey -F", false);
897
 			sleep("0.1");
898
 			/* start racoon */
899
			$ipsecdebug = isset($config['ipsec']['racoondebug']) ? "-d -v" : "";
900
			mwexec("/usr/local/sbin/racoon {$ipsecdebug} -f {$g['varetc_path']}/racoon.conf", false);
901
 			sleep("0.1");
902
 			/* load SPD */
903
			mwexec("/usr/local/sbin/setkey -f {$g['varetc_path']}/spd.conf", false);
904

    
905
		}
906
		/* start filterdns, if necessary */
907
		if (count($filterdns_list) > 0) {
908
			$interval = 60;
909
			if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
910
				$interval = $ipseccfg['dns-interval'];
911

    
912
			$hostnames = "";
913
			array_unique($filterdns_list);
914
			foreach ($filterdns_list as $hostname)
915
				$hostnames .= "cmd {$hostname} '/etc/rc.newipsecdns'\n";
916
			file_put_contents("{$g['varetc_path']}/filterdns-ipsec.hosts", $hostnames);
917

    
918
			killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
919
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/filterdns-ipsec.hosts -d 1");
920
		}
921
	
922
		vpn_ipsec_failover_configure();
923

    
924
		if ($g['booting'])
925
			echo "done\n";
926
	}
927

    
928
	return 0;
929
}
930

    
931
/* Forcefully restart IPsec
932
 * This is required for when dynamic interfaces reload
933
 * For all other occasions the normal vpn_ipsec_configure()
934
 * will gracefully reload the settings without restarting
935
 */
936
function vpn_ipsec_force_reload() {
937
	global $config;
938
	global $g;
939

    
940
	$ipseccfg = $config['ipsec'];
941

    
942
	/* kill racoon */
943
	if(is_process_running("racoon"))
944
		mwexec("/usr/bin/killall racoon", true);
945

    
946
	/* wait for process to die */
947
	sleep(4);
948

    
949
	/* send a SIGKILL to be sure */
950
	sigkillbypid("{$g['varrun_path']}/racoon.pid", "KILL");
951

    
952
	/* wait for flushing to finish */
953
	sleep(1);
954

    
955
	/* if ipsec is enabled, start up again */
956
	if (isset($ipseccfg['enable'])) {
957
		log_error("Forcefully reloading IPsec racoon daemon");
958
		vpn_ipsec_configure();
959
	}
960

    
961
}
962

    
963
/* master setup for vpn (mpd) */
964
function vpn_setup() {
965
	/* start pptpd */
966
	vpn_pptpd_configure();
967

    
968
	/* start pppoe server */
969
	vpn_pppoes_configure();
970

    
971
	/* setup l2tp */
972
	vpn_l2tp_configure();
973
}
974

    
975
function vpn_netgraph_support() {
976
	$iflist = get_configured_interface_list();
977
	foreach ($iflist as $iface) {
978
		$realif = get_real_interface($iface);
979
		/* Get support for netgraph(4) from the nic */
980
		$ifinfo = pfSense_get_interface_addresses($realif);
981
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
982
                	pfSense_ngctl_attach(".", $realif);
983
	}
984
}
985

    
986
function vpn_pptpd_configure() {
987
	global $config, $g;
988

    
989
	$syscfg = $config['system'];
990
	$pptpdcfg = $config['pptpd'];
991

    
992
	if ($g['booting']) {
993
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
994
			return 0;
995

    
996
		echo "Configuring PPTP VPN service... ";
997
	} else {
998
		/* kill mpd */
999
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1000

    
1001
		/* wait for process to die */
1002
		sleep(3);
1003

    
1004
		if (is_process_running("mpd -b")) {
1005
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1006
			log_error("Could not kill mpd within 3 seconds.   Trying again.");
1007
		}
1008

    
1009
		/* remove mpd.conf, if it exists */
1010
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
1011
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
1012
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
1013
	}
1014

    
1015
	/* make sure pptp-vpn directory exists */
1016
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
1017
		mkdir("{$g['varetc_path']}/pptp-vpn");
1018

    
1019
	switch ($pptpdcfg['mode']) {
1020
		case 'server' :
1021
			/* write mpd.conf */
1022
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1023
			if (!$fd) {
1024
				printf("Error: cannot open mpd.conf in vpn_pptpd_configure().\n");
1025
				return 1;
1026
			}
1027

    
1028
			$mpdconf = <<<EOD
1029
pptps:
1030

    
1031
EOD;
1032

    
1033
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1034
				$mpdconf .= "	load pt{$i}\n";
1035
			}
1036

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

    
1039
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1040

    
1041
				$mpdconf .= <<<EOD
1042

    
1043
pt{$i}:
1044
	new -i pptpd{$i} pt{$i} pt{$i}
1045
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1046
	load pts
1047

    
1048
EOD;
1049
			}
1050

    
1051
			$mpdconf .=<<<EOD
1052

    
1053
pts:
1054
	set iface disable on-demand
1055
	set iface enable proxy-arp
1056
	set iface enable tcpmssfix
1057
	set iface idle 1800
1058
	set iface up-script /usr/local/sbin/vpn-linkup
1059
	set iface down-script /usr/local/sbin/vpn-linkdown
1060
	set bundle enable multilink
1061
	set bundle enable crypt-reqd
1062
	set link yes acfcomp protocomp
1063
	set link no pap chap
1064
	set link enable chap-msv2
1065
	set link mtu 1460
1066
	set link keep-alive 10 60
1067
	set ipcp yes vjcomp
1068
	set bundle enable compression
1069
	set ccp yes mppc
1070
	set ccp yes mpp-e128
1071
	set ccp yes mpp-stateless
1072

    
1073
EOD;
1074

    
1075
			if (!isset ($pptpdcfg['req128'])) {
1076
				$mpdconf .=<<<EOD
1077
	set ccp yes mpp-e40
1078
	set ccp yes mpp-e56
1079

    
1080
EOD;
1081
			}
1082

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

    
1086
			if (!empty($pptpdcfg['dns1'])) {
1087
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1088
				if (!empty($pptpdcfg['dns2']))
1089
					$mpdconf .= " " . $pptpdcfg['dns2'];
1090
				$mpdconf .= "\n";
1091
			} elseif (isset ($config['dnsmasq']['enable'])) {
1092
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1093
				if ($syscfg['dnsserver'][0])
1094
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1095
				$mpdconf .= "\n";
1096
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1097
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1098
			}
1099

    
1100
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1101
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1102
				$acctport = $authport + 1;
1103
				$mpdconf .=<<<EOD
1104
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1105

    
1106
EOD;
1107
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1108
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1109
				$acctport = $authport + 1;
1110
				$mpdconf .=<<<EOD
1111
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret']}" {$authport} {$acctport}
1112

    
1113
EOD;
1114
			}
1115
			$mpdconf .=<<<EOD
1116
	set radius retries 3
1117
	set radius timeout 10
1118
	set auth enable radius-auth
1119

    
1120
EOD;
1121

    
1122
				if (isset ($pptpdcfg['radius']['accounting'])) {
1123
					$mpdconf .=<<<EOD
1124
	set auth enable radius-acct
1125
	set radius acct-update 300
1126

    
1127
EOD;
1128
				}
1129
			}
1130

    
1131
			fwrite($fd, $mpdconf);
1132
			fclose($fd);
1133

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

    
1141
			$mpdlinks = "";
1142

    
1143
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1144
				$mpdlinks .=<<<EOD
1145

    
1146
pt{$i}:
1147
	set link type pptp
1148
	set pptp enable incoming
1149
	set pptp disable originate
1150
	set pptp disable windowing
1151

    
1152
EOD;
1153
			}
1154

    
1155
			fwrite($fd, $mpdlinks);
1156
			fclose($fd);
1157

    
1158
			/* write mpd.secret */
1159
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1160
			if (!$fd) {
1161
				printf("Error: cannot open mpd.secret in vpn_pptpd_configure().\n");
1162
				return 1;
1163
			}
1164

    
1165
			$mpdsecret = "";
1166

    
1167
			if (is_array($pptpdcfg['user'])) {
1168
				foreach ($pptpdcfg['user'] as $user)
1169
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1170
			}
1171

    
1172
			fwrite($fd, $mpdsecret);
1173
			fclose($fd);
1174
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1175

    
1176
			vpn_netgraph_support();
1177

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

    
1181
			break;
1182

    
1183
		case 'redir' :
1184
			break;
1185
	}
1186

    
1187
	if ($g['booting'])
1188
		echo "done\n";
1189

    
1190
	return 0;
1191
}
1192

    
1193
function vpn_pppoes_configure() {
1194
	global $config;
1195

    
1196
	if (is_array($config['pppoes']['pppoe'])) {
1197
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1198
			vpn_pppoe_configure($pppoe);
1199
	}
1200
}
1201

    
1202
function vpn_pppoe_configure(&$pppoecfg) {
1203
	global $config, $g;
1204

    
1205
	$syscfg = $config['system'];
1206

    
1207
	/* create directory if it does not exist */
1208
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1209
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1210

    
1211
	if ($g['booting']) {
1212
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1213
			return 0;
1214

    
1215
		echo "Configuring PPPoE VPN service... ";
1216
	} else {
1217
		/* kill mpd */
1218
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1219

    
1220
		/* wait for process to die */
1221
		sleep(2);
1222

    
1223
	}
1224

    
1225
	switch ($pppoecfg['mode']) {
1226

    
1227
		case 'server' :
1228

    
1229
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1230

    
1231
			if ($pppoecfg['paporchap'] == "chap")
1232
				$paporchap = "set link enable chap";
1233
			else
1234
				$paporchap = "set link enable pap";
1235

    
1236
			/* write mpd.conf */
1237
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1238
			if (!$fd) {
1239
				printf("Error: cannot open mpd.conf in vpn_pppoe_configure().\n");
1240
				return 1;
1241
			}
1242
			$mpdconf = "\n\n";
1243
			$mpdconf .= "poes:\n";
1244

    
1245
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1246
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1247
			}
1248

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

    
1251
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1252

    
1253
				if (isset ($pppoecfg['radius']['radiusissueips']) && isset ($pppoecfg['radius']['server']['enable'])) {
1254
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1255
				} else {
1256
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1257
				}
1258

    
1259
				$mpdconf .=<<<EOD
1260

    
1261
poes{$pppoecfg['pppoeid']}{$i}:
1262
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1263
	{$isssue_ip_type}
1264
	load pppoe_standard
1265

    
1266
EOD;
1267
			}
1268

    
1269
			$mpdconf .=<<<EOD
1270

    
1271
pppoe_standard:
1272
	set bundle no multilink
1273
	set bundle enable compression
1274
	set auth max-logins 1
1275
	set iface up-script /usr/local/sbin/vpn-linkup
1276
	set iface down-script /usr/local/sbin/vpn-linkdown
1277
	set iface idle 0
1278
	set iface disable on-demand
1279
	set iface disable proxy-arp
1280
	set iface enable tcpmssfix
1281
	set iface mtu 1500
1282
	set link no pap chap
1283
	{$paporchap}
1284
	set link keep-alive 60 180
1285
	set ipcp yes vjcomp
1286
	set ipcp no vjcomp
1287
	set link max-redial -1
1288
	set link mtu 1492
1289
	set link mru 1492
1290
	set ccp yes mpp-e40
1291
	set ccp yes mpp-e128
1292
	set ccp yes mpp-stateless
1293
	set link latency 1
1294
	#set ipcp dns 10.10.1.3
1295
	#set bundle accept encryption
1296

    
1297
EOD;
1298

    
1299
			if (!empty($pppoecfg['dns1'])) {
1300
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1301
				if (!empty($pppoecfg['dns2']))
1302
					$mpdconf .= " " . $pppoecfg['dns2'];
1303
				$mpdconf .= "\n";
1304
			} elseif (isset ($config['dnsmasq']['enable'])) {
1305
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1306
				if ($syscfg['dnsserver'][0])
1307
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1308
				$mpdconf .= "\n";
1309
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1310
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1311
			}
1312

    
1313
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1314
				$radiusport = "";
1315
				$radiusacctport = "";
1316
				if (isset($pppoecfg['radius']['server']['port']))
1317
					$radiusport = $pppoecfg['radius']['server']['port'];
1318
				if (isset($pppoecfg['radius']['server']['acctport']))
1319
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1320
				$mpdconf .=<<<EOD
1321
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']} {$radiusport} {$radiusacctport}" 
1322
	set radius retries 3
1323
	set radius timeout 10
1324
	set auth enable radius-auth
1325

    
1326
EOD;
1327

    
1328
				if (isset ($pppoecfg['radius']['accounting'])) {
1329
					$mpdconf .=<<<EOD
1330
	set auth enable radius-acct
1331

    
1332
EOD;
1333
				}
1334
			}
1335

    
1336
			fwrite($fd, $mpdconf);
1337
			fclose($fd);
1338

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

    
1346
			$mpdlinks = "";
1347

    
1348
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1349
				$mpdlinks .=<<<EOD
1350
			
1351
poes{$pppoecfg['pppoeid']}{$i}:
1352
	set phys type pppoe
1353
        set pppoe iface {$pppoe_interface}
1354
        set pppoe service "*"
1355
        set pppoe disable originate
1356
        set pppoe enable incoming
1357

    
1358
EOD;
1359
			}
1360

    
1361
			fwrite($fd, $mpdlinks);
1362
			fclose($fd);
1363

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

    
1372
				$mpdsecret = "\n\n";
1373

    
1374
				if (!empty($pppoecfg['username'])) {
1375
					$item = explode(" ", $pppoecfg['username']);
1376
					foreach($item as $userdata) {
1377
						$data = explode(":", $userdata);
1378
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1379
					}
1380
				}
1381

    
1382
				fwrite($fd, $mpdsecret);
1383
				fclose($fd);
1384
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1385
			}
1386

    
1387
			/* Get support for netgraph(4) from the nic */
1388
			pfSense_ngctl_attach(".", $pppoe_interface);
1389
			/* fire up mpd */
1390
			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");
1391

    
1392
			break;
1393
	}
1394

    
1395
	if ($g['booting'])
1396
		echo "done\n";
1397

    
1398
	return 0;
1399
}
1400

    
1401
function vpn_l2tp_configure() {
1402
	global $config, $g;
1403

    
1404
	$syscfg = $config['system'];
1405
	$l2tpcfg = $config['l2tp'];
1406

    
1407
	/* create directory if it does not exist */
1408
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1409
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1410

    
1411
	if ($g['booting']) {
1412
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1413
			return 0;
1414

    
1415
		echo "Configuring l2tp VPN service... ";
1416
	} else {
1417
		/* kill mpd */
1418
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1419

    
1420
		/* wait for process to die */
1421
		sleep(8);
1422

    
1423
	}
1424

    
1425
	/* make sure l2tp-vpn directory exists */
1426
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1427
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1428

    
1429
	switch ($l2tpcfg['mode']) {
1430

    
1431
		case 'server' :
1432
			if ($l2tpcfg['paporchap'] == "chap")
1433
				$paporchap = "set link enable chap";
1434
			else
1435
				$paporchap = "set link enable pap";
1436

    
1437
			/* write mpd.conf */
1438
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1439
			if (!$fd) {
1440
				printf("Error: cannot open mpd.conf in vpn_l2tp_configure().\n");
1441
				return 1;
1442
			}
1443
			$mpdconf = "\n\n";
1444
			$mpdconf .=<<<EOD
1445
l2tps:
1446

    
1447
EOD;
1448

    
1449
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1450
				$mpdconf .= "	load l2tp{$i}\n";
1451
			}
1452

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

    
1455
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1456

    
1457
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1458
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1459
				} else {
1460
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1461
				}
1462

    
1463
				$mpdconf .=<<<EOD
1464

    
1465
l2tp{$i}:
1466
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1467
	{$isssue_ip_type}
1468
	load l2tp_standard
1469

    
1470
EOD;
1471
			}
1472

    
1473
			$mpdconf .=<<<EOD
1474

    
1475
l2tp_standard:
1476
        set bundle disable multilink
1477
        set bundle enable compression
1478
        set bundle yes crypt-reqd
1479
        set ipcp yes vjcomp
1480
        # set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1481
        set ccp yes mppc
1482
        set iface disable on-demand
1483
        set iface enable proxy-arp
1484
	set iface up-script /usr/local/sbin/vpn-linkup
1485
	set iface down-script /usr/local/sbin/vpn-linkdown
1486
        set link yes acfcomp protocomp
1487
        set link no pap chap
1488
        set link enable chap
1489
        set link keep-alive 10 180
1490

    
1491
EOD;
1492

    
1493
			if (is_ipaddr($l2tpcfg['wins'])) {
1494
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1495
			}
1496
			if (is_ipaddr($l2tpcfg['dns1'])) {
1497
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1498
				if (is_ipaddr($l2tpcfg['dns2']))
1499
					$mpdconf .= " " . $l2tpcfg['dns2'];
1500
				$mpdconf .= "\n";
1501
			} elseif (isset ($config['dnsmasq']['enable'])) {
1502
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1503
				if ($syscfg['dnsserver'][0])
1504
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1505
				$mpdconf .= "\n";
1506
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1507
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1508
			}
1509

    
1510
			if (isset ($l2tpcfg['radius']['enable'])) {
1511
				$mpdconf .=<<<EOD
1512
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1513
	set radius retries 3
1514
	set radius timeout 10
1515
	set auth enable radius-auth
1516

    
1517
EOD;
1518

    
1519
				if (isset ($l2tpcfg['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

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

    
1537
			$mpdlinks = "";
1538

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

    
1542
l2tp{$i}:
1543
	set link type l2tp
1544
        set l2tp enable incoming
1545
        set l2tp disable originate
1546

    
1547
EOD;
1548
			if (!empty($l2tpcfg['secret']))
1549
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1550
			}
1551

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

    
1555
			/* write mpd.secret */
1556
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1557
			if (!$fd) {
1558
				printf("Error: cannot open mpd.secret in vpn_l2tp_configure().\n");
1559
				return 1;
1560
			}
1561

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

    
1564
			if (is_array($l2tpcfg['user'])) {
1565
				foreach ($l2tpcfg['user'] as $user)
1566
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1567
			}
1568

    
1569
			fwrite($fd, $mpdsecret);
1570
			fclose($fd);
1571
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1572

    
1573
			vpn_netgraph_support();
1574

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

    
1578
			break;
1579

    
1580
		case 'redir' :
1581
			break;
1582
	}
1583

    
1584
	if ($g['booting'])
1585
		echo "done\n";
1586

    
1587
	return 0;
1588
}
1589

    
1590
/* Walk the tunnels for hostname endpoints. If the hostnames 
1591
 * resolve to a different IP now compared to the DNS cache
1592
 * we reload the policies if the endpoint has changed */
1593
function vpn_ipsec_refresh_policies() {
1594
	global $config;
1595
	global $g;
1596

    
1597
	$ipseccfg = $config['ipsec'];
1598
	$a_phase1 = $config['ipsec']['phase1'];
1599
	$a_phase2 = $config['ipsec']['phase2'];
1600

    
1601
	if (isset($ipseccfg['disable'])) {
1602
		return true;
1603
	}
1604

    
1605
	/* Walk the Ipsec tunnel array */
1606
	if (!is_array($a_phase1) || (!count($a_phase1))) {
1607
		return;
1608
	}
1609

    
1610
	foreach ($a_phase1 as $phase1) {
1611
		if (isset($phase1['disabled'])) {
1612
			continue;
1613
		}
1614
		if (is_ipaddr($phase1['remote-gateway'])) {
1615
			continue;
1616
		}
1617
		if (!is_ipaddr($phase1['remote-gateway'])) {
1618
			$dnscache = compare_hostname_to_dnscache($phase1['remote-gateway']);
1619
			$dnscache = trim($dnscache);
1620
			/* we should have the old IP addresses in the dnscache now */
1621
			if($dnscache <> "") {
1622
				$oldphase1 = $phase1;
1623
				$oldphase1['remote-gateway'] = trim($dnscache);
1624
				/* now we need to find all tunnels for this host */
1625
				if (!is_array($a_phase2) || (!count($a_phase2))) {
1626
					continue;
1627
				}
1628
				foreach ($a_phase2 as $phase2) {
1629
					if($phase2['ikeid'] == $phase1['ikeid']) {
1630
						reload_tunnel_spd_policy ($phase1, $phase2, $oldphase1, $oldphase2);
1631
					}
1632
				}
1633
			}
1634
		}
1635
	}
1636

    
1637
	/* process all generated spd.conf files from tmp which are left behind
1638
	 * behind by either changes of dynamic tunnels or manual edits
1639
	 * scandir() is only available in PHP5 */
1640
	$tmpfiles = array();
1641
	$dh  = opendir($g['tmp_path']);
1642
	while (false !== ($filename = readdir($dh))) {
1643
		if(preg_match("/^spd.conf.reload./", $filename)) {
1644
			$tmpfiles[] = $filename;
1645
		}
1646
	}
1647
	sort($tmpfiles);
1648
	foreach($tmpfiles as $tmpfile) {
1649
		$ret = mwexec("/usr/local/sbin/setkey -f {$g['tmp_path']}/{$tmpfile} 2>&1", false);
1650
		if($ret == 0) {
1651
			unlink_if_exists("{$g['tmp_path']}/{$tmpfile}");
1652
		} else {
1653
			rename("{$g['tmp_path']}/{$tmpfile}", ("{$g['tmp_path']}/failed.{$tmpfile}"));
1654
		}
1655
	}
1656
}
1657

    
1658
/* reloads the tunnel configuration for a tunnel item
1659
 * Will remove and add SPD polices */
1660
function reload_tunnel_spd_policy($phase1, $phase2, $old_phase1, $old_phase2) {
1661
	global $config;
1662
	global $g;
1663

    
1664
	/* if we are not passed a old tunnel array we create one */
1665
	if(empty($old_phase1)) {
1666
		$old_phase1 = $phase1;
1667
	}
1668
	if(empty($old_phase2)) {
1669
		$old_phase2 = $phase2;
1670
	}
1671

    
1672
	$sad_arr = ipsec_dump_sad();
1673

    
1674
	$ep = ipsec_get_phase1_src($phase1);
1675
	$local_subnet = ipsec_idinfo_to_cidr($phase2['localid']);
1676
	$remote_subnet = ipsec_idinfo_to_cidr($phase2['remoteid']);
1677

    
1678
	/* make sure we pass the oldtunnel array with a IP for the remote gw */
1679
	$old_gw = trim($old_phase1['remote-gateway']);
1680

    
1681
	$old_ep = ipsec_get_phase1_src($old_phase1);
1682
	$old_local_subnet = ipsec_idinfo_to_cidr($old_phase2['localid']);
1683
	$old_remote_subnet = ipsec_idinfo_to_cidr($old_phase2['remoteid']);
1684

    
1685
	/* see if this tunnel has a hostname for the remote-gateway, and if so,
1686
	 * try to resolve it now and add it to the list for filterdns */
1687
	$rgip = "";
1688
	if (!is_ipaddr($phase1['remote-gateway'])) {
1689
		if(! $g['booting']) {
1690
			$rgip = resolve_retry($phase1['remote-gateway']);
1691
			add_hostname_to_watch($phase1['remote-gateway']);
1692
		} else {
1693
			add_hostname_to_watch($phase1['remote-gateway']);
1694
		}
1695
		if (!is_ipaddr($rgip)) {
1696
			log_error("Could not determine VPN endpoint for '{$phase1['descr']}'");
1697
			return false;
1698
		}
1699
	} else {
1700
		$rgip = $phase1['remote-gateway'];
1701
	}
1702
	if (!$ep) {
1703
		log_error("Could not determine VPN endpoint for '{$phase1['descr']}'");
1704
		return false;
1705
	}
1706

    
1707
	if((!is_ipaddr($old_ep)) || (! is_ipaddr($ep))) {
1708
		log_error("IPSEC: ERROR: One of the endpoints is not a IP address. Old EP '{$old_ep}' new EP '{$ep}'");
1709
	}
1710
	if((! is_ipaddr($rgip)) || (! is_ipaddr($old_gw))) {
1711
		log_error("IPSEC: ERROR: One of the remote endpoints is not a IP address. Old RG '{$old_gw}' new RG '{$rgip}'");
1712
	}
1713

    
1714
	$spdconf = "";
1715
	/* Delete old SPD policies if there are changes between the old and new */
1716
	if(($phase1 != $old_phase1) || ($phase2 != $old_phase2)) {
1717
		$spdconf .= "spddelete {$old_local_subnet} " .
1718
			"{$old_remote_subnet} any -P out ipsec " .
1719
			"{$old_phase2['protocol']}/tunnel/{$old_ep}-" .
1720
			"{$old_gw}/unique;\n";
1721
		$spdconf .= "spddelete {$old_remote_subnet} " .
1722
			"{$old_local_subnet} any -P in ipsec " .
1723
			"{$old_phase2['protocol']}/tunnel/{$old_gw}-" .
1724
			"{$old_ep}/unique;\n";
1725

    
1726
		/* zap any existing SA entries */
1727
		foreach($sad_arr as $sad) {
1728
			if(($sad['dst'] == $old_ep) && ($sad['src'] == $old_gw)) {
1729
				$spdconf .= "delete {$old_ep} {$old_gw} {$old_phase2['protocol']} 0x{$sad['spi']};\n";
1730
			}
1731
			if(($sad['src'] == $oldep) && ($sad['dst'] == $old_gw)) {
1732
				$spdconf .= "delete {$old_gw} {$old_ep} {$old_phase2['protocol']} 0x{$sad['spi']};\n";
1733
			}
1734
		}
1735
	}
1736

    
1737
	/* Create new SPD entries for the new configuration */
1738
	/* zap any existing SA entries beforehand */
1739
	foreach($sad_arr as $sad) {
1740
		if(($sad['dst'] == $ep) && ($sad['src'] == $rgip)) {
1741
			$spdconf .= "delete {$rgip} {$ep} {$phase2['protocol']} 0x{$sad['spi']};\n";
1742
		}
1743
		if(($sad['src'] == $ep) && ($sad['dst'] == $rgip)) {
1744
			$spdconf .= "delete {$ep} {$rgip} {$phase2['protocol']} 0x{$sad['spi']};\n";
1745
		}
1746
	}
1747
	/* add new SPD policies to replace them */
1748
	$spdconf .= "spdadd {$local_subnet} " .
1749
		"{$remote_subnet} any -P out ipsec " .
1750
		"{$phase2['protocol']}/tunnel/{$ep}-" .
1751
		"{$rgip}/unique;\n";
1752
	$spdconf .= "spdadd {$remote_subnet} " .
1753
		"{$local_subnet} any -P in ipsec " .
1754
		"{$phase2['protocol']}/tunnel/{$rgip}-" .
1755
		"{$ep}/unique;\n";
1756

    
1757
	log_error("Reloading IPsec tunnel '{$phase1['descr']}'. Previous IP '{$old_gw}', current IP '{$rgip}'. Reloading policy");
1758

    
1759
	$now = time();
1760
	$spdfile = tempnam("{$g['tmp_path']}", "spd.conf.reload.{$now}.");
1761
	/* generate temporary spd.conf */
1762
	file_put_contents($spdfile, $spdconf);
1763
	return true;
1764
}
1765

    
1766
function vpn_ipsec_configure_preferoldsa() {
1767
	global $config;
1768
	if(isset($config['ipsec']['preferoldsa']))
1769
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
1770
	else
1771
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
1772
}
1773

    
1774
?>
(52-52/61)