Project

General

Profile

Download (49.7 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	/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
		/* resolve all local, peer addresses and setup pings */
130
		$ipmap = array();
131
		$rgmap = array();
132
		$filterdns_list = array();
133
		if (is_array($a_phase1) && count($a_phase1)) {
134

    
135
			$ipsecpinghosts = "";
136
			/* step through each phase1 entry */
137
			foreach ($a_phase1 as $ph1ent) {
138
				if (isset($ph1ent['disabled']))
139
					continue;
140

    
141
				$ep = ipsec_get_phase1_src($ph1ent);
142
				if (!$ep)
143
					continue;
144

    
145
				if(!in_array($ep,$ipmap))
146
					$ipmap[] = $ep;
147

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

    
151
				if (isset ($ph1ent['mobile']))
152
					continue;
153

    
154
				$rg = $ph1ent['remote-gateway'];
155

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

    
170
				/* step through each phase2 entry */
171
				if (is_array($a_phase2)) {
172
					foreach ($a_phase2 as $ph2ent) {
173

    
174
						$ikeid = $ph2ent['ikeid'];
175

    
176
						if (isset($ph2ent['disabled']))
177
							continue;
178

    
179
						if ($ikeid != $ph1ent['ikeid'])
180
							continue;
181

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

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

    
235
		$pskconf = "";
236

    
237
		if (is_array($a_phase1) && count($a_phase1)) {
238
			foreach ($a_phase1 as $ph1ent) {
239

    
240
				if (isset($ph1ent['disabled']))
241
					continue;
242

    
243
				if (strstr($ph1ent['authentication_method'],'rsa'))
244
					continue;
245

    
246
				$peerid_type = $ph1ent['peerid_type'];
247

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

    
254
					case "address";
255
						$peerid_data = $ph1ent['peerid_data'];
256
						break;
257

    
258
					case "fqdn";
259
					case "keyid tag";
260
					case "user_fqdn";
261
						$peerid_data = $ph1ent['peerid_data'];
262
						break;
263
				}
264

    
265
				if (!empty($peerid_data) && !empty($ph1ent['pre-shared-key']))
266
					$pskconf .= trim($peerid_data) . "\t" . trim($ph1ent['pre-shared-key']) . "\n";
267
			}
268
		}
269

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

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

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

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

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

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

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

    
317
				$racoonconf .= "\nmode_cfg\n";
318
				$racoonconf .= "{\n";
319

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

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

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

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

    
337
				if (isset($a_client['net_list'])) {
338

    
339
					$net_list = '';
340

    
341
					foreach ($a_phase2 as $ph2ent) {
342

    
343
						if (isset($ph2ent['disabled']))
344
							continue;
345

    
346
						if (!isset($ph2ent['mobile']))
347
							continue;
348

    
349
						$localid = ipsec_idinfo_to_cidr($ph2ent['localid'],true);
350

    
351
						if ($net_list)
352
							$net_list .= ", ";
353
						$net_list .= $localid;
354
					}
355

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

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

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

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

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

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

    
390
					fwrite($fd1, $a_client['login_banner']);
391
					fclose($fd1);
392

    
393
					$racoonconf .= "\tbanner \"{$fn}\";\n";
394
				}
395

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

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

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

    
408
					if (isset($ph1ent['disabled']))
409
						continue;
410

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

    
414
					$ikeid = $ph1ent['ikeid'];
415

    
416
					$ep = ipsec_get_phase1_src($ph1ent);
417
					if (!$ep)
418
						continue;
419

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

    
426
					$myid_type = $ph1ent['myid_type'];
427

    
428
					switch ($myid_type) {
429

    
430
						case "myaddress":
431
							$myid_type = "address";
432
							$myid_data = $ep;
433
							break;
434

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

    
440
						case "address";
441
							$myid_data = $ph1ent['myid_data'];
442
							break;
443

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

    
454
					$peerid_type = $ph1ent['peerid_type'];
455

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

    
462
						case "address";
463
							$peerid_data = $ph1ent['peerid_data'];
464
							break;
465

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

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

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

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

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

    
509
					$certline = '';
510

    
511
					if (strstr($authmethod,'rsa')) {
512

    
513
						$cert = lookup_cert($ph1ent['certref']);
514

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

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

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

    
530
						chmod($certpath, 0600);
531

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

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

    
541
						chmod($keypath, 0600);
542

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

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

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

    
558
						$certline = "certificate_type x509 \"".basename($certpath)."\" \"".basename($keypath)."\";";
559

    
560
					}
561

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

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

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

    
579
					/* add remote section to configuration */
580

    
581
					$racoonconf .=<<<EOD
582

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

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

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

    
620
				/* begin sainfo */
621
				foreach ($a_phase2 as $ph2ent) {
622

    
623
					$ikeid = $ph2ent['ikeid'];
624

    
625
					if( !ipsec_lookup_phase1($ph2ent,$ph1ent))
626
						continue;
627

    
628
					if (isset($ph1ent['disabled']))
629
						continue;
630

    
631
					if (isset($ph2ent['disabled']))
632
						continue;
633

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

    
637
					if ($ph2ent['mode'] == 'tunnel') {
638

    
639
						$localid_type = $ph2ent['localid']['type'];
640
						$localid_data = ipsec_idinfo_to_cidr($ph2ent['localid']);
641
						/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
642
						if (($localid_type == "none") ||
643
							(($ph1ent['authentication_method'] == "xauth_psk_server") ||
644
							($ph1ent['authentication_method'] == "pre_shared_key"))
645
							&& isset($ph1ent['mobile'])
646
							&& (ipsec_get_number_of_phase2($ikeid)==1))
647
							$localid_spec = " ";
648
						else {
649
							if ($localid_type != "address") {
650
								$localid_type = "subnet";
651
							}
652
							// Don't let an empty subnet into racoon.conf, it can cause parse errors. Ticket #2201.
653
							if (!is_subnet($localid_data)) {
654
								log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
655
								continue;
656
							}
657
							$localid_spec = $localid_type." ".$localid_data." any";
658
						}
659

    
660
						if (!isset($ph2ent['mobile'])) {
661
							$remoteid_type = $ph2ent['remoteid']['type'];
662
							if ($remoteid_type != "address")
663
								$remoteid_type = "subnet";
664

    
665
							$remoteid_data = ipsec_idinfo_to_cidr($ph2ent['remoteid']);
666
							$remoteid_spec = $remoteid_type." ".$remoteid_data." any";
667
						} else
668
							$remoteid_spec = "anonymous";
669

    
670
					} else {
671
						$rgip = $rgmap[$ph1ent['remote-gateway']];
672

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

    
690
					if($ph2ent['protocol'] == 'esp') {
691

    
692
						$ealgos = '';
693

    
694
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
695

    
696
							$ealg_id = $ealg['name'];
697
							$ealg_kl = $ealg['keylen'];
698

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

    
734
						$ealgosline = "encryption_algorithm {$ealgos};";
735

    
736
					} else {
737

    
738
						$ealgosline = "encryption_algorithm null_enc;";
739
					}
740

    
741
					$halgos = join(",", $ph2ent['hash-algorithm-option']);
742
					$halgosline = "authentication_algorithm {$halgos};";
743

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

    
753
					$lifeline = '';
754
					if ($ph2ent['lifetime'])
755
						$lifeline = "lifetime time {$ph2ent['lifetime']} secs;";
756

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

    
771
EOD;
772
				}
773
				/* end sainfo */
774
			}
775
			/* end sainfo sections */
776

    
777
			fwrite($fd, $racoonconf);
778
			fclose($fd);
779
		}
780
		/* end racoon.conf */
781

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

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

    
803
			foreach ($a_phase2 as $ph2ent) {
804

    
805
				if( !ipsec_lookup_phase1($ph2ent,$ph1ent))
806
					continue;
807

    
808
				if (isset($ph1ent['mobile']))
809
					continue;
810

    
811
				if (isset($ph1ent['disabled']))
812
					continue;
813

    
814
				if (isset($ph2ent['disabled']))
815
					continue;
816

    
817
				$ep = ipsec_get_phase1_src($ph1ent);
818
				if (!$ep)
819
					continue;
820

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

    
825
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'],true);
826
				$remoteid = ipsec_idinfo_to_cidr($ph2ent['remoteid'],true);
827

    
828
				// Error will be logged above, no need to log this twice. #2201
829
				if (!is_subnet($localid))
830
					continue;
831

    
832
				if($ph2ent['mode'] == "tunnel") {
833

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

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

    
840
				} else {
841

    
842
					$localid_data = ipsec_get_phase1_src($ph1ent);
843
					$remoteid_data = $rgmap[$ph1ent['remote-gateway']];
844

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

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

    
851
				}
852

    
853
				/* static route needed? */
854
				if (preg_match("/^carp|^vip/i", $ph1ent['interface']))
855
					$parentinterface = link_carp_interface_to_parent($ph1ent['interface']);
856
				else
857
					$parentinterface = $ph1ent['interface'];
858

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

    
880
		}
881
		fwrite($fd, $spdconf);
882
		fclose($fd);
883

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

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

    
914
			$hostnames = "";
915
			array_unique($filterdns_list);
916
			foreach ($filterdns_list as $hostname)
917
				$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
918
			file_put_contents("{$g['varetc_path']}/filterdns-ipsec.hosts", $hostnames);
919

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

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

    
931
	return 0;
932
}
933

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

    
943
	$ipseccfg = $config['ipsec'];
944

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

    
949
	/* wait for process to die */
950
	sleep(4);
951

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

    
955
	/* wait for flushing to finish */
956
	sleep(1);
957

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

    
964
}
965

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

    
971
	/* start pppoe server */
972
	vpn_pppoes_configure();
973

    
974
	/* setup l2tp */
975
	vpn_l2tp_configure();
976
}
977

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

    
989
function vpn_pptpd_configure() {
990
	global $config, $g;
991

    
992
	$syscfg = $config['system'];
993
	$pptpdcfg = $config['pptpd'];
994

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

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

    
1004
		/* wait for process to die */
1005
		sleep(3);
1006

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

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

    
1018
	if (empty($pptpdcfg['n_pptp_units'])) {
1019
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
1020
		return; 
1021
	}
1022

    
1023
	/* make sure pptp-vpn directory exists */
1024
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
1025
		mkdir("{$g['varetc_path']}/pptp-vpn");
1026

    
1027
	switch ($pptpdcfg['mode']) {
1028
		case 'server' :
1029
			/* write mpd.conf */
1030
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1031
			if (!$fd) {
1032
				printf("Error: cannot open mpd.conf in vpn_pptpd_configure().\n");
1033
				return 1;
1034
			}
1035

    
1036
			$mpdconf = <<<EOD
1037
pptps:
1038

    
1039
EOD;
1040

    
1041
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1042
				$mpdconf .= "	load pt{$i}\n";
1043
			}
1044

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

    
1047
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1048

    
1049
				$mpdconf .= <<<EOD
1050

    
1051
pt{$i}:
1052
	new -i pptpd{$i} pt{$i} pt{$i}
1053
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1054
	load pts
1055

    
1056
EOD;
1057
			}
1058

    
1059
			$mpdconf .=<<<EOD
1060

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

    
1081
EOD;
1082

    
1083
			if (!isset ($pptpdcfg['req128'])) {
1084
				$mpdconf .=<<<EOD
1085
	set ccp yes mpp-e40
1086
	set ccp yes mpp-e56
1087

    
1088
EOD;
1089
			}
1090

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

    
1094
			if (!empty($pptpdcfg['dns1'])) {
1095
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1096
				if (!empty($pptpdcfg['dns2']))
1097
					$mpdconf .= " " . $pptpdcfg['dns2'];
1098
				$mpdconf .= "\n";
1099
			} elseif (isset ($config['dnsmasq']['enable'])) {
1100
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1101
				if ($syscfg['dnsserver'][0])
1102
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1103
				$mpdconf .= "\n";
1104
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1105
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1106
			}
1107

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

    
1114
EOD;
1115
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1116
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1117
				$acctport = $authport + 1;
1118
				$mpdconf .=<<<EOD
1119
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1120

    
1121
EOD;
1122
			}
1123
			$mpdconf .=<<<EOD
1124
	set radius retries 3
1125
	set radius timeout 10
1126
	set auth enable radius-auth
1127

    
1128
EOD;
1129

    
1130
				if (isset ($pptpdcfg['radius']['accounting'])) {
1131
					$mpdconf .=<<<EOD
1132
	set auth enable radius-acct
1133
	set radius acct-update 300
1134

    
1135
EOD;
1136
				}
1137
			}
1138

    
1139
			fwrite($fd, $mpdconf);
1140
			fclose($fd);
1141

    
1142
			/* write mpd.links */
1143
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1144
			if (!$fd) {
1145
				printf("Error: cannot open mpd.links in vpn_pptpd_configure().\n");
1146
				return 1;
1147
			}
1148

    
1149
			$mpdlinks = "";
1150

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

    
1154
pt{$i}:
1155
	set link type pptp
1156
	set pptp enable incoming
1157
	set pptp disable originate
1158
	set pptp disable windowing
1159

    
1160
EOD;
1161
			}
1162

    
1163
			fwrite($fd, $mpdlinks);
1164
			fclose($fd);
1165

    
1166
			/* write mpd.secret */
1167
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1168
			if (!$fd) {
1169
				printf("Error: cannot open mpd.secret in vpn_pptpd_configure().\n");
1170
				return 1;
1171
			}
1172

    
1173
			$mpdsecret = "";
1174

    
1175
			if (is_array($pptpdcfg['user'])) {
1176
				foreach ($pptpdcfg['user'] as $user) {
1177
					$pass = str_replace('\\', '\\\\', $user['password']);
1178
					$pass = str_replace('"', '\"', $pass);
1179
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1180
				}
1181
			}
1182

    
1183
			fwrite($fd, $mpdsecret);
1184
			fclose($fd);
1185
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1186

    
1187
			vpn_netgraph_support();
1188

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

    
1192
			break;
1193

    
1194
		case 'redir' :
1195
			break;
1196
	}
1197

    
1198
	if ($g['booting'])
1199
		echo "done\n";
1200

    
1201
	return 0;
1202
}
1203

    
1204
function vpn_pppoes_configure() {
1205
	global $config;
1206

    
1207
	if (is_array($config['pppoes']['pppoe'])) {
1208
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1209
			vpn_pppoe_configure($pppoe);
1210
	}
1211
}
1212

    
1213
function vpn_pppoe_configure(&$pppoecfg) {
1214
	global $config, $g;
1215

    
1216
	$syscfg = $config['system'];
1217

    
1218
	/* create directory if it does not exist */
1219
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1220
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1221

    
1222
	if ($g['booting']) {
1223
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1224
			return 0;
1225

    
1226
		echo "Configuring PPPoE VPN service... ";
1227
	} else {
1228
		/* kill mpd */
1229
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1230

    
1231
		/* wait for process to die */
1232
		sleep(2);
1233

    
1234
	}
1235

    
1236
	switch ($pppoecfg['mode']) {
1237

    
1238
		case 'server' :
1239

    
1240
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1241

    
1242
			if ($pppoecfg['paporchap'] == "chap")
1243
				$paporchap = "set link enable chap";
1244
			else
1245
				$paporchap = "set link enable pap";
1246

    
1247
			/* write mpd.conf */
1248
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1249
			if (!$fd) {
1250
				printf("Error: cannot open mpd.conf in vpn_pppoe_configure().\n");
1251
				return 1;
1252
			}
1253
			$mpdconf = "\n\n";
1254
			$mpdconf .= "poes:\n";
1255

    
1256
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1257
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1258
			}
1259

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

    
1262
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1263

    
1264
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1265
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1266
				} else {
1267
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1268
				}
1269

    
1270
				$mpdconf .=<<<EOD
1271

    
1272
poes{$pppoecfg['pppoeid']}{$i}:
1273
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1274
	{$isssue_ip_type}
1275
	load pppoe_standard
1276

    
1277
EOD;
1278
			}
1279

    
1280
			$mpdconf .=<<<EOD
1281

    
1282
pppoe_standard:
1283
	set bundle no multilink
1284
	set bundle enable compression
1285
	set auth max-logins 1
1286
	set iface up-script /usr/local/sbin/vpn-linkup
1287
	set iface down-script /usr/local/sbin/vpn-linkdown
1288
	set iface idle 0
1289
	set iface disable on-demand
1290
	set iface disable proxy-arp
1291
	set iface enable tcpmssfix
1292
	set iface mtu 1500
1293
	set link no pap chap
1294
	{$paporchap}
1295
	set link keep-alive 60 180
1296
	set ipcp yes vjcomp
1297
	set ipcp no vjcomp
1298
	set link max-redial -1
1299
	set link mtu 1492
1300
	set link mru 1492
1301
	set ccp yes mpp-e40
1302
	set ccp yes mpp-e128
1303
	set ccp yes mpp-stateless
1304
	set link latency 1
1305
	#set ipcp dns 10.10.1.3
1306
	#set bundle accept encryption
1307

    
1308
EOD;
1309

    
1310
			if (!empty($pppoecfg['dns1'])) {
1311
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1312
				if (!empty($pppoecfg['dns2']))
1313
					$mpdconf .= " " . $pppoecfg['dns2'];
1314
				$mpdconf .= "\n";
1315
			} elseif (isset ($config['dnsmasq']['enable'])) {
1316
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1317
				if ($syscfg['dnsserver'][0])
1318
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1319
				$mpdconf .= "\n";
1320
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1321
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1322
			}
1323

    
1324
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1325
				$radiusport = "";
1326
				$radiusacctport = "";
1327
				if (isset($pppoecfg['radius']['server']['port']))
1328
					$radiusport = $pppoecfg['radius']['server']['port'];
1329
				if (isset($pppoecfg['radius']['server']['acctport']))
1330
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1331
				$mpdconf .=<<<EOD
1332
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1333
	set radius retries 3
1334
	set radius timeout 10
1335
	set auth enable radius-auth
1336

    
1337
EOD;
1338

    
1339
				if (isset ($pppoecfg['radius']['accounting'])) {
1340
					$mpdconf .=<<<EOD
1341
	set auth enable radius-acct
1342

    
1343
EOD;
1344
				}
1345
			}
1346

    
1347
			fwrite($fd, $mpdconf);
1348
			fclose($fd);
1349

    
1350
			/* write mpd.links */
1351
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1352
			if (!$fd) {
1353
				printf("Error: cannot open mpd.links in vpn_pppoe_configure().\n");
1354
				return 1;
1355
			}
1356

    
1357
			$mpdlinks = "";
1358

    
1359
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1360
				$mpdlinks .=<<<EOD
1361
			
1362
poes{$pppoecfg['pppoeid']}{$i}:
1363
	set phys type pppoe
1364
        set pppoe iface {$pppoe_interface}
1365
        set pppoe service "*"
1366
        set pppoe disable originate
1367
        set pppoe enable incoming
1368

    
1369
EOD;
1370
			}
1371

    
1372
			fwrite($fd, $mpdlinks);
1373
			fclose($fd);
1374

    
1375
			if ($pppoecfg['username']) {
1376
				/* write mpd.secret */
1377
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1378
				if (!$fd) {
1379
					printf("Error: cannot open mpd.secret in vpn_pppoe_configure().\n");
1380
					return 1;
1381
				}
1382

    
1383
				$mpdsecret = "\n\n";
1384

    
1385
				if (!empty($pppoecfg['username'])) {
1386
					$item = explode(" ", $pppoecfg['username']);
1387
					foreach($item as $userdata) {
1388
						$data = explode(":", $userdata);
1389
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1390
					}
1391
				}
1392

    
1393
				fwrite($fd, $mpdsecret);
1394
				fclose($fd);
1395
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1396
			}
1397

    
1398
			/* Get support for netgraph(4) from the nic */
1399
			pfSense_ngctl_attach(".", $pppoe_interface);
1400
			/* fire up mpd */
1401
			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");
1402

    
1403
			break;
1404
	}
1405

    
1406
	if ($g['booting'])
1407
		echo "done\n";
1408

    
1409
	return 0;
1410
}
1411

    
1412
function vpn_l2tp_configure() {
1413
	global $config, $g;
1414

    
1415
	$syscfg = $config['system'];
1416
	$l2tpcfg = $config['l2tp'];
1417

    
1418
	/* create directory if it does not exist */
1419
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1420
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1421

    
1422
	if ($g['booting']) {
1423
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1424
			return 0;
1425

    
1426
		echo "Configuring l2tp VPN service... ";
1427
	} else {
1428
		/* kill mpd */
1429
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1430

    
1431
		/* wait for process to die */
1432
		sleep(8);
1433

    
1434
	}
1435

    
1436
	/* make sure l2tp-vpn directory exists */
1437
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1438
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1439

    
1440
	switch ($l2tpcfg['mode']) {
1441

    
1442
		case 'server' :
1443
			if ($l2tpcfg['paporchap'] == "chap")
1444
				$paporchap = "set link enable chap";
1445
			else
1446
				$paporchap = "set link enable pap";
1447

    
1448
			/* write mpd.conf */
1449
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1450
			if (!$fd) {
1451
				printf("Error: cannot open mpd.conf in vpn_l2tp_configure().\n");
1452
				return 1;
1453
			}
1454
			$mpdconf = "\n\n";
1455
			$mpdconf .=<<<EOD
1456
l2tps:
1457

    
1458
EOD;
1459

    
1460
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1461
				$mpdconf .= "	load l2tp{$i}\n";
1462
			}
1463

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

    
1466
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1467

    
1468
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1469
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1470
				} else {
1471
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1472
				}
1473

    
1474
				$mpdconf .=<<<EOD
1475

    
1476
l2tp{$i}:
1477
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1478
	{$isssue_ip_type}
1479
	load l2tp_standard
1480

    
1481
EOD;
1482
			}
1483

    
1484
			$mpdconf .=<<<EOD
1485

    
1486
l2tp_standard:
1487
        set bundle disable multilink
1488
        set bundle enable compression
1489
        set bundle yes crypt-reqd
1490
        set ipcp yes vjcomp
1491
        # set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1492
        set ccp yes mppc
1493
        set iface disable on-demand
1494
        set iface enable proxy-arp
1495
	set iface up-script /usr/local/sbin/vpn-linkup
1496
	set iface down-script /usr/local/sbin/vpn-linkdown
1497
        set link yes acfcomp protocomp
1498
        set link no pap chap
1499
        set link enable chap
1500
        set link keep-alive 10 180
1501

    
1502
EOD;
1503

    
1504
			if (is_ipaddr($l2tpcfg['wins'])) {
1505
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1506
			}
1507
			if (is_ipaddr($l2tpcfg['dns1'])) {
1508
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1509
				if (is_ipaddr($l2tpcfg['dns2']))
1510
					$mpdconf .= " " . $l2tpcfg['dns2'];
1511
				$mpdconf .= "\n";
1512
			} elseif (isset ($config['dnsmasq']['enable'])) {
1513
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1514
				if ($syscfg['dnsserver'][0])
1515
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1516
				$mpdconf .= "\n";
1517
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1518
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1519
			}
1520

    
1521
			if (isset ($l2tpcfg['radius']['enable'])) {
1522
				$mpdconf .=<<<EOD
1523
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1524
	set radius retries 3
1525
	set radius timeout 10
1526
	set auth enable radius-auth
1527

    
1528
EOD;
1529

    
1530
				if (isset ($l2tpcfg['radius']['accounting'])) {
1531
					$mpdconf .=<<<EOD
1532
	set auth enable radius-acct
1533

    
1534
EOD;
1535
				}
1536
			}
1537

    
1538
			fwrite($fd, $mpdconf);
1539
			fclose($fd);
1540

    
1541
			/* write mpd.links */
1542
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1543
			if (!$fd) {
1544
				printf("Error: cannot open mpd.links in vpn_l2tp_configure().\n");
1545
				return 1;
1546
			}
1547

    
1548
			$mpdlinks = "";
1549

    
1550
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1551
				$mpdlinks .=<<<EOD
1552

    
1553
l2tp{$i}:
1554
	set link type l2tp
1555
        set l2tp enable incoming
1556
        set l2tp disable originate
1557

    
1558
EOD;
1559
			if (!empty($l2tpcfg['secret']))
1560
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1561
			}
1562

    
1563
			fwrite($fd, $mpdlinks);
1564
			fclose($fd);
1565

    
1566
			/* write mpd.secret */
1567
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1568
			if (!$fd) {
1569
				printf("Error: cannot open mpd.secret in vpn_l2tp_configure().\n");
1570
				return 1;
1571
			}
1572

    
1573
			$mpdsecret = "\n\n";
1574

    
1575
			if (is_array($l2tpcfg['user'])) {
1576
				foreach ($l2tpcfg['user'] as $user)
1577
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1578
			}
1579

    
1580
			fwrite($fd, $mpdsecret);
1581
			fclose($fd);
1582
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1583

    
1584
			vpn_netgraph_support();
1585

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

    
1589
			break;
1590

    
1591
		case 'redir' :
1592
			break;
1593
	}
1594

    
1595
	if ($g['booting'])
1596
		echo "done\n";
1597

    
1598
	return 0;
1599
}
1600

    
1601
/* Walk the tunnels for hostname endpoints. If the hostnames 
1602
 * resolve to a different IP now compared to the DNS cache
1603
 * we reload the policies if the endpoint has changed */
1604
function vpn_ipsec_refresh_policies() {
1605
	global $config;
1606
	global $g;
1607

    
1608
	$ipseccfg = $config['ipsec'];
1609
	$a_phase1 = $config['ipsec']['phase1'];
1610
	$a_phase2 = $config['ipsec']['phase2'];
1611

    
1612
	if (isset($ipseccfg['disable'])) {
1613
		return true;
1614
	}
1615

    
1616
	/* Walk the Ipsec tunnel array */
1617
	if (!is_array($a_phase1) || (!count($a_phase1))) {
1618
		return;
1619
	}
1620

    
1621
	foreach ($a_phase1 as $phase1) {
1622
		if (isset($phase1['disabled'])) {
1623
			continue;
1624
		}
1625
		if (is_ipaddr($phase1['remote-gateway'])) {
1626
			continue;
1627
		}
1628
		if (!is_ipaddr($phase1['remote-gateway'])) {
1629
			$dnscache = compare_hostname_to_dnscache($phase1['remote-gateway']);
1630
			$dnscache = trim($dnscache);
1631
			/* we should have the old IP addresses in the dnscache now */
1632
			if($dnscache <> "") {
1633
				$oldphase1 = $phase1;
1634
				$oldphase1['remote-gateway'] = trim($dnscache);
1635
				/* now we need to find all tunnels for this host */
1636
				if (!is_array($a_phase2) || (!count($a_phase2))) {
1637
					continue;
1638
				}
1639
				foreach ($a_phase2 as $phase2) {
1640
					if($phase2['ikeid'] == $phase1['ikeid']) {
1641
						reload_tunnel_spd_policy ($phase1, $phase2, $oldphase1, $oldphase2);
1642
					}
1643
				}
1644
			}
1645
		}
1646
	}
1647

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

    
1669
/* reloads the tunnel configuration for a tunnel item
1670
 * Will remove and add SPD polices */
1671
function reload_tunnel_spd_policy($phase1, $phase2, $old_phase1, $old_phase2) {
1672
	global $config;
1673
	global $g;
1674

    
1675
	/* if we are not passed a old tunnel array we create one */
1676
	if(empty($old_phase1)) {
1677
		$old_phase1 = $phase1;
1678
	}
1679
	if(empty($old_phase2)) {
1680
		$old_phase2 = $phase2;
1681
	}
1682

    
1683
	$sad_arr = ipsec_dump_sad();
1684

    
1685
	$ep = ipsec_get_phase1_src($phase1);
1686
	$local_subnet = ipsec_idinfo_to_cidr($phase2['localid']);
1687
	$remote_subnet = ipsec_idinfo_to_cidr($phase2['remoteid']);
1688

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

    
1692
	$old_ep = ipsec_get_phase1_src($old_phase1);
1693
	$old_local_subnet = ipsec_idinfo_to_cidr($old_phase2['localid']);
1694
	$old_remote_subnet = ipsec_idinfo_to_cidr($old_phase2['remoteid']);
1695

    
1696
	/* see if this tunnel has a hostname for the remote-gateway, and if so,
1697
	 * try to resolve it now and add it to the list for filterdns */
1698
	$rgip = "";
1699
	if (!is_ipaddr($phase1['remote-gateway'])) {
1700
		if(! $g['booting']) {
1701
			$rgip = resolve_retry($phase1['remote-gateway']);
1702
			add_hostname_to_watch($phase1['remote-gateway']);
1703
		} else {
1704
			add_hostname_to_watch($phase1['remote-gateway']);
1705
		}
1706
		if (!is_ipaddr($rgip)) {
1707
			log_error("Could not determine VPN endpoint for '{$phase1['descr']}'");
1708
			return false;
1709
		}
1710
	} else {
1711
		$rgip = $phase1['remote-gateway'];
1712
	}
1713
	if (!$ep) {
1714
		log_error("Could not determine VPN endpoint for '{$phase1['descr']}'");
1715
		return false;
1716
	}
1717

    
1718
	if((!is_ipaddr($old_ep)) || (! is_ipaddr($ep))) {
1719
		log_error("IPSEC: ERROR: One of the endpoints is not a IP address. Old EP '{$old_ep}' new EP '{$ep}'");
1720
	}
1721
	if((! is_ipaddr($rgip)) || (! is_ipaddr($old_gw))) {
1722
		log_error("IPSEC: ERROR: One of the remote endpoints is not a IP address. Old RG '{$old_gw}' new RG '{$rgip}'");
1723
	}
1724

    
1725
	$spdconf = "";
1726
	/* Delete old SPD policies if there are changes between the old and new */
1727
	if(($phase1 != $old_phase1) || ($phase2 != $old_phase2)) {
1728
		$spdconf .= "spddelete {$old_local_subnet} " .
1729
			"{$old_remote_subnet} any -P out ipsec " .
1730
			"{$old_phase2['protocol']}/tunnel/{$old_ep}-" .
1731
			"{$old_gw}/unique;\n";
1732
		$spdconf .= "spddelete {$old_remote_subnet} " .
1733
			"{$old_local_subnet} any -P in ipsec " .
1734
			"{$old_phase2['protocol']}/tunnel/{$old_gw}-" .
1735
			"{$old_ep}/unique;\n";
1736

    
1737
		/* zap any existing SA entries */
1738
		foreach($sad_arr as $sad) {
1739
			if(($sad['dst'] == $old_ep) && ($sad['src'] == $old_gw)) {
1740
				$spdconf .= "delete {$old_ep} {$old_gw} {$old_phase2['protocol']} 0x{$sad['spi']};\n";
1741
			}
1742
			if(($sad['src'] == $oldep) && ($sad['dst'] == $old_gw)) {
1743
				$spdconf .= "delete {$old_gw} {$old_ep} {$old_phase2['protocol']} 0x{$sad['spi']};\n";
1744
			}
1745
		}
1746
	}
1747

    
1748
	/* Create new SPD entries for the new configuration */
1749
	/* zap any existing SA entries beforehand */
1750
	foreach($sad_arr as $sad) {
1751
		if(($sad['dst'] == $ep) && ($sad['src'] == $rgip)) {
1752
			$spdconf .= "delete {$rgip} {$ep} {$phase2['protocol']} 0x{$sad['spi']};\n";
1753
		}
1754
		if(($sad['src'] == $ep) && ($sad['dst'] == $rgip)) {
1755
			$spdconf .= "delete {$ep} {$rgip} {$phase2['protocol']} 0x{$sad['spi']};\n";
1756
		}
1757
	}
1758
	/* add new SPD policies to replace them */
1759
	$spdconf .= "spdadd {$local_subnet} " .
1760
		"{$remote_subnet} any -P out ipsec " .
1761
		"{$phase2['protocol']}/tunnel/{$ep}-" .
1762
		"{$rgip}/unique;\n";
1763
	$spdconf .= "spdadd {$remote_subnet} " .
1764
		"{$local_subnet} any -P in ipsec " .
1765
		"{$phase2['protocol']}/tunnel/{$rgip}-" .
1766
		"{$ep}/unique;\n";
1767

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

    
1770
	$now = time();
1771
	$spdfile = tempnam("{$g['tmp_path']}", "spd.conf.reload.{$now}.");
1772
	/* generate temporary spd.conf */
1773
	file_put_contents($spdfile, $spdconf);
1774
	return true;
1775
}
1776

    
1777
function vpn_ipsec_configure_preferoldsa() {
1778
	global $config;
1779
	if(isset($config['ipsec']['preferoldsa']))
1780
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
1781
	else
1782
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
1783
}
1784

    
1785
?>
(53-53/62)