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
			sleep(1);
920
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/filterdns-ipsec.hosts -d 1");
921
		}
922
	
923
		vpn_ipsec_failover_configure();
924

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

    
929
	return 0;
930
}
931

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

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

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

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

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

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

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

    
962
}
963

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1032
EOD;
1033

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

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

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

    
1042
				$mpdconf .= <<<EOD
1043

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

    
1049
EOD;
1050
			}
1051

    
1052
			$mpdconf .=<<<EOD
1053

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

    
1074
EOD;
1075

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

    
1081
EOD;
1082
			}
1083

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

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

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

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

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

    
1121
EOD;
1122

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

    
1128
EOD;
1129
				}
1130
			}
1131

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

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

    
1142
			$mpdlinks = "";
1143

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

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

    
1153
EOD;
1154
			}
1155

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

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

    
1166
			$mpdsecret = "";
1167

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

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

    
1177
			vpn_netgraph_support();
1178

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

    
1182
			break;
1183

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

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

    
1191
	return 0;
1192
}
1193

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

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

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

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

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

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

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

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

    
1224
	}
1225

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

    
1228
		case 'server' :
1229

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

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

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

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

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

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

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

    
1260
				$mpdconf .=<<<EOD
1261

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

    
1267
EOD;
1268
			}
1269

    
1270
			$mpdconf .=<<<EOD
1271

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

    
1298
EOD;
1299

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

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

    
1327
EOD;
1328

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

    
1333
EOD;
1334
				}
1335
			}
1336

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

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

    
1347
			$mpdlinks = "";
1348

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

    
1359
EOD;
1360
			}
1361

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

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

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

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

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

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

    
1393
			break;
1394
	}
1395

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

    
1399
	return 0;
1400
}
1401

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

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

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

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

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

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

    
1424
	}
1425

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

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

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

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

    
1448
EOD;
1449

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

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

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

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

    
1464
				$mpdconf .=<<<EOD
1465

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

    
1471
EOD;
1472
			}
1473

    
1474
			$mpdconf .=<<<EOD
1475

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

    
1492
EOD;
1493

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

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

    
1518
EOD;
1519

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

    
1524
EOD;
1525
				}
1526
			}
1527

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

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

    
1538
			$mpdlinks = "";
1539

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

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

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

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

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

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

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

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

    
1574
			vpn_netgraph_support();
1575

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

    
1579
			break;
1580

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

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

    
1588
	return 0;
1589
}
1590

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

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

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

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

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

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

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

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

    
1673
	$sad_arr = ipsec_dump_sad();
1674

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

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

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

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

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

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

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

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

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

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

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

    
1775
?>
(52-52/61)