Project

General

Profile

Download (50.3 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
			/* step through each phase1 entry */
140
			foreach ($a_phase1 as $ph1ent) {
141
				if (isset($ph1ent['disabled']))
142
					continue;
143

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

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

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

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

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

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

    
173
				/* step through each phase2 entry */
174
				$ipsecpinghosts = "";
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
							if(is_ipaddrv6($ph1ent['src'])) {
190
								$interface_ip = get_interface_ipv6($ifent);
191
								$local_subnetv6 = ipsec_idinfo_to_cidr($ph2ent['localid'], true);
192
								if (ip_in_subnetv6($interface_ip, $local_subnet)) {
193
									$srcip = $interface_ip;
194
									break;
195
								}
196
							} else {
197
								$interface_ip = get_interface_ip($ifent);
198
								$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true);
199
								if (ip_in_subnet($interface_ip, $local_subnet)) {
200
									$srcip = $interface_ip;
201
									break;
202
								}
203
							}
204
						}
205
						$dstip = $ph2ent['pinghost'];
206
						if(is_ipaddrv6($srcip)) {
207
							$family = "inet6";
208
						} else {
209
							$family = "inet";
210
						}
211
						if (is_ipaddr($srcip))
212
							$ipsecpinghosts .= "{$srcip}|{$dstip}|3|{$family}\n";
213
					}
214
				}
215
				$pfd = fopen("{$g['vardb_path']}/ipsecpinghosts", "w");
216
				if ($pfd) {
217
					fwrite($pfd, $ipsecpinghosts);
218
					fclose($pfd);
219
				}
220
				
221
			}
222
		}
223

    
224
		/* generate CA certificates files */
225
		if (is_array($config['ca']) && count($config['ca'])) {
226
			foreach ($config['ca'] as $ca) {
227
				if (!isset($ca['crt'])) {
228
					log_error("Error: Invalid certificate info for {$ca['descr']}");
229
					continue;
230
				}
231
				$cert = base64_decode($ca['crt']);
232
				$x509cert = openssl_x509_parse(openssl_x509_read($cert));
233
				if (!is_array($x509cert) || !isset($x509cert['hash'])) {
234
					log_error("Error: Invalid certificate hash info for {$ca['descr']}");
235
					continue;
236
				}
237
				$fname = $g['varetc_path']."/".$x509cert['hash'].".0";
238
				if (!file_put_contents($fname, $cert)) {
239
					log_error("Error: Cannot write IPsec CA file for {$ca['descr']}");
240
					continue;
241
				}
242
			}
243
		}
244
		
245
		/* generate psk.txt */
246
		$fd = fopen("{$g['varetc_path']}/psk.txt", "w");
247
		if (!$fd) {
248
			printf("Error: cannot open psk.txt in vpn_ipsec_configure().\n");
249
			return 1;
250
		}
251

    
252
		$pskconf = "";
253

    
254
		if (is_array($a_phase1) && count($a_phase1)) {
255
			foreach ($a_phase1 as $ph1ent) {
256

    
257
				if (isset($ph1ent['disabled']))
258
					continue;
259

    
260
				if (strstr($ph1ent['authentication_method'],'rsa'))
261
					continue;
262

    
263
				$peerid_type = $ph1ent['peerid_type'];
264

    
265
				switch ($peerid_type) {
266
					case "peeraddress":
267
						$peerid_type = "address";
268
						$peerid_data = $rgmap[$ph1ent['remote-gateway']];
269
						break;
270

    
271
					case "address";
272
						$peerid_data = $ph1ent['peerid_data'];
273
						break;
274

    
275
					case "fqdn";
276
					case "keyid tag";
277
					case "user_fqdn";
278
						$peerid_data = $ph1ent['peerid_data'];
279
						break;
280
				}
281

    
282
				$pskconf .= "{$peerid_data}\t{$ph1ent['pre-shared-key']}\n";
283
			}
284
		}
285

    
286
		/* Add user PSKs */
287
		foreach ($config['system']['user'] as $user) {
288
			if (!empty($user['ipsecpsk'])) {
289
				$pskconf .= "{$user['name']}\t{$user['ipsecpsk']}\n";
290
			}
291
		}
292

    
293
		/* add PSKs for mobile clients */
294
		if (is_array($ipseccfg['mobilekey'])) {
295
			foreach ($ipseccfg['mobilekey'] as $key) {
296
				$pskconf .= "{$key['ident']}\t{$key['pre-shared-key']}\n";
297
			}
298
		}
299

    
300
		fwrite($fd, $pskconf);
301
		fclose($fd);
302
		chmod("{$g['varetc_path']}/psk.txt", 0600);
303
			
304
		/* begin racoon.conf */
305
		if ((is_array($a_phase1) && count($a_phase1)) ||
306
			(is_array($a_phase2) && count($a_phase2))) {
307

    
308
			$fd = fopen("{$g['varetc_path']}/racoon.conf", "w");
309
			if (!$fd) {
310
				printf("Error: cannot open racoon.conf in vpn_ipsec_configure().\n");
311
				return 1;
312
			}
313

    
314
			$racoonconf = "# This file is automatically generated. Do not edit\n";			
315
			$racoonconf .= "path pre_shared_key \"{$g['varetc_path']}/psk.txt\";\n\n";
316
			$racoonconf .= "path certificate  \"{$g['varetc_path']}\";\n\n";
317

    
318
			/* begin listen section */
319
			if (count($ipmap)) {
320
				$racoonconf .= "\nlisten\n";
321
				$racoonconf .= "{\n";
322
				$racoonconf .= "	adminsock \"/var/db/racoon/racoon.sock\" \"root\" \"wheel\" 0660;\n";
323
				foreach ($ipmap as $addr) {
324
					$racoonconf .= "\tisakmp {$addr} [500];\n";
325
					$racoonconf .= "\tisakmp_natt {$addr} [4500];\n";
326
				}
327
				$racoonconf .= "}\n\n";
328
			}
329

    
330
			/* begin mode_cfg section */
331
			if (is_array($a_client) && isset($a_client['enable'])) {
332

    
333
				$racoonconf .= "\nmode_cfg\n";
334
				$racoonconf .= "{\n";
335

    
336
				if ($a_client['user_source'])
337
					$racoonconf .= "\tauth_source {$a_client['user_source']};\n";
338
				if ($a_client['group_source'])
339
					$racoonconf .= "\tgroup_source {$a_client['group_source']};\n";
340

    
341
				if ($a_client['pool_address'] && $a_client['pool_netbits']) {
342
					$pool_address = $a_client['pool_address'];
343
					$pool_netmask = gen_subnet_mask($a_client['pool_netbits']);
344

    
345
					$pool_address = long2ip32(ip2long($pool_address)+1);
346
					$pool_size = (~ip2long($pool_netmask) & 0xFFFFFFFF) - 2;
347

    
348
					$racoonconf .= "\tpool_size {$pool_size};\n";
349
					$racoonconf .= "\tnetwork4 {$pool_address};\n";
350
					$racoonconf .= "\tnetmask4 {$pool_netmask};\n";
351
				}
352

    
353
				if (isset($a_client['net_list'])) {
354

    
355
					$net_list = '';
356

    
357
					foreach ($a_phase2 as $ph2ent) {
358

    
359
						if (isset($ph2ent['disabled']))
360
							continue;
361

    
362
						if (!isset($ph2ent['mobile']))
363
							continue;
364

    
365
						$localid = ipsec_idinfo_to_cidr($ph2ent['localid'],true);
366

    
367
						if ($net_list)
368
							$net_list .= ", ";
369
						$net_list .= $localid;
370
					}
371

    
372
					if ($net_list)
373
						$racoonconf .= "\tsplit_network include {$net_list};\n";
374
				}
375

    
376
				if ($a_client['dns_server1'])
377
					$racoonconf .= "\tdns4 {$a_client['dns_server1']};\n";
378
				if ($a_client['dns_server2'])
379
					$racoonconf .= "\tdns4 {$a_client['dns_server2']};\n";
380
				if ($a_client['dns_server3'])
381
					$racoonconf .= "\tdns4 {$a_client['dns_server3']};\n";
382
				if ($a_client['dns_server4'])
383
					$racoonconf .= "\tdns4 {$a_client['dns_server4']};\n";
384

    
385
				if ($a_client['wins_server1'])
386
					$racoonconf .= "\twins4 {$a_client['wins_server1']};\n";
387
				if ($a_client['wins_server2'])
388
					$racoonconf .= "\twins4 {$a_client['wins_server2']};\n";
389

    
390
				if ($a_client['dns_domain']) {
391
					$racoonconf .= "\tdefault_domain \"{$a_client['dns_domain']}\";\n";
392
					$racoonconf .= "\tsplit_dns \"{$a_client['dns_domain']}\";\n";
393
				}
394

    
395
				if ($a_client['pfs_group'])
396
					$racoonconf .= "\tpfs_group {$a_client['pfs_group']};\n";
397

    
398
				if ($a_client['login_banner']) {
399
					$fn = "{$g['varetc_path']}/racoon.motd";
400
					$fd1 = fopen($fn, "w");
401
					if (!$fd1) {
402
						printf("Error: cannot open server{$fn} in vpn.\n");
403
						return 1;
404
					}
405

    
406
					fwrite($fd1, $a_client['login_banner']);
407
					fclose($fd1);
408

    
409
					$racoonconf .= "\tbanner \"{$fn}\";\n";
410
				}
411

    
412
				if (isset($a_client['save_passwd']))
413
					$racoonconf .= "\tsave_passwd on;\n";
414

    
415
				$racoonconf .= "}\n\n";
416
			}
417
			/* end mode_cfg section */
418

    
419
			/* begin remote sections */
420
			if (is_array($a_phase1) && count($a_phase1)) {
421
				/* begin remote */
422
				foreach ($a_phase1 as $ph1ent) {
423

    
424
					if (isset($ph1ent['disabled']))
425
						continue;
426

    
427
					if (isset($ph1ent['mobile']) && !isset($a_client['enable']))
428
						continue;
429

    
430
					$ikeid = $ph1ent['ikeid'];
431

    
432
					$ep = ipsec_get_phase1_src($ph1ent);
433
					if (!$ep)
434
						continue;
435

    
436
					if (!isset($ph1ent['mobile'])) {
437
						$rgip = $rgmap[$ph1ent['remote-gateway']];
438
						if (!$rgip)
439
							continue;
440
					}
441

    
442
					$myid_type = $ph1ent['myid_type'];
443

    
444
					switch ($myid_type) {
445

    
446
						case "myaddress":
447
							$myid_type = "address";
448
							$myid_data = $ep;
449
							break;
450

    
451
						case "dyn_dns":
452
							$myid_type = "address";
453
							$myid_data = resolve_retry($ph1ent['myid_data']);
454
							break;
455

    
456
						case "address";
457
							$myid_data = $ph1ent['myid_data'];
458
							break;
459

    
460
						case "fqdn";
461
						case "keyid tag";
462
						case "user_fqdn";
463
						case "asn1dn";
464
							$myid_data = $ph1ent['myid_data'];
465
							if( $myid_data )
466
								$myid_data = "\"".$myid_data."\"";
467
							break;
468
					}
469

    
470
					$peerid_type = $ph1ent['peerid_type'];
471

    
472
					switch ($peerid_type) {
473
						case "peeraddress":
474
							$peerid_type = "address";
475
							$peerid_data = $rgip;
476
							break;
477

    
478
						case "address";
479
							$peerid_data = $ph1ent['peerid_data'];
480
							break;
481

    
482
						case "fqdn";
483
						case "keyid tag";
484
						case "user_fqdn";
485
						case "asn1dn";
486
							$peerid_data = $ph1ent['peerid_data'];
487
							if( $peerid_data )
488
								$peerid_data = "\"".$peerid_data."\"";
489
							break;
490
					}
491

    
492
					$natt = "off";
493
					if (isset($ph1ent['nat_traversal']))
494
						$natt = $ph1ent['nat_traversal'];
495

    
496
					$init = "on";
497
					$genp = "off";
498
					$pcheck = !empty($ph1ent['proposal_check']) ? $ph1ent['proposal_check'] : $pcheck = "claim";
499
					$passive = "";
500
					if (isset($ph1ent['mobile'])) {
501
						$rgip = "anonymous";
502
						/* Mimic 1.2.3's behavior for pure-psk mobile tunnels */
503
						if ($ph1ent['authentication_method'] == "pre_shared_key") {
504
							$passive = "passive on;";
505
							$pcheck = !empty($ph1ent['proposal_check']) ? $ph1ent['proposal_check'] : $pcheck = "obey";
506
							$genp = "on";
507
						} else {
508
							$init = "off";
509
							$genp = "unique";
510
						}
511
					}
512

    
513
					$dpdline1 = '';
514
					$dpdline2 = '';
515
					if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
516
						$dpdline1 = "dpd_delay = {$ph1ent['dpd_delay']};";
517
						$dpdline2 = "dpd_maxfail = {$ph1ent['dpd_maxfail']};";
518
					}
519

    
520
					if (isset ($ph1ent['authentication_method']))
521
						$authmethod = $ph1ent['authentication_method'];
522
					else
523
						$authmethod = 'pre_shared_key';
524

    
525
					$certline = '';
526

    
527
					if (strstr($authmethod,'rsa')) {
528

    
529
						$cert = lookup_cert($ph1ent['certref']);
530

    
531
						if (!$cert)
532
						{
533
							log_error("Error: Invalid phase1 certificate reference for {$ph1ent['name']}");
534
							continue;
535
						}
536

    
537
						$certfile = "cert-".$ikeid.".crt";
538
						$certpath = $g['varetc_path']."/".$certfile;
539

    
540
						if (!file_put_contents($certpath, base64_decode($cert['crt'])))
541
						{
542
							log_error("Error: Cannot write phase1 certificate file for {$ph1ent['name']}");
543
							continue;
544
						}
545

    
546
						chmod($certpath, 0600);
547

    
548
						$keyfile = "cert-".$ikeid.".key";
549
						$keypath = $g['varetc_path']."/".$keyfile;
550

    
551
						if (!file_put_contents($keypath, base64_decode($cert['prv'])))
552
						{
553
							log_error("Error: Cannot write phase1 key file for {$ph1ent['name']}");
554
							continue;
555
						}
556

    
557
						chmod($keypath, 0600);
558

    
559
						$ca = lookup_ca($ph1ent['caref']);
560
						if ($ca) {
561
							$cafile = "ca-".$ikeid.".crt";
562
							$capath = $g['varetc_path']."/".$cafile;
563

    
564
							if (!file_put_contents($capath, base64_decode($ca['crt'])))
565
							{
566
								log_error("Error: Cannot write phase1 CA certificate file for {$ph1ent['name']}");
567
								continue;
568
							}
569

    
570
							chmod($capath, 0600);
571
							$caline = "ca_type x509 \"".basename($capath)."\";";
572
						}
573

    
574
						$certline = "certificate_type x509 \"".basename($certpath)."\" \"".basename($keypath)."\";";
575

    
576
					}
577

    
578
					$ealgos = '';
579
					$ealg_id = $ph1ent['encryption-algorithm']['name'];
580
					$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
581
					if ($ealg_kl)
582
						$ealgos = $ealgos.$ealg_id." ".$ealg_kl;
583
					else
584
						$ealgos = $ealgos.$ealg_id;
585

    
586
					$lifeline = '';
587
					if ($ph1ent['lifetime'])
588
						$lifeline = "lifetime time {$ph1ent['lifetime']} secs;";
589

    
590
					/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
591
					if (!(($ph1ent['authentication_method'] == "pre_shared_key") && isset($ph1ent['mobile']))) {
592
						$peerid_spec = "peers_identifier {$peerid_type} {$peerid_data};";
593
					}
594

    
595
					/* add remote section to configuration */
596

    
597
					$racoonconf .=<<<EOD
598

    
599
remote {$rgip}
600
{
601
	ph1id {$ikeid};
602
	exchange_mode {$ph1ent['mode']};
603
	my_identifier {$myid_type} {$myid_data};
604
	{$peerid_spec}
605
	ike_frag on;
606
	generate_policy = {$genp};
607
	initial_contact = {$init};
608
	nat_traversal = {$natt};
609
	{$certline}
610
	{$caline}
611
	{$dpdline1}
612
	{$dpdline2}
613
	support_proxy on;
614
	proposal_check {$pcheck};
615
	{$passive}
616

    
617
	proposal
618
	{
619
		authentication_method {$authmethod};
620
		encryption_algorithm ${ealgos};
621
		hash_algorithm {$ph1ent['hash-algorithm']};
622
		dh_group {$ph1ent['dhgroup']};
623
		${lifeline}
624
	}
625
}
626

    
627
EOD;
628
				}
629
				/* end remote */
630
			}
631
			/* end remote sections */
632
		
633
			/* begin sainfo sections */
634
			if (is_array($a_phase2) && count($a_phase2)) {
635

    
636
				/* begin sainfo */
637
				foreach ($a_phase2 as $ph2ent) {
638

    
639
					$ikeid = $ph2ent['ikeid'];
640

    
641
					if( !ipsec_lookup_phase1($ph2ent,$ph1ent))
642
						continue;
643

    
644
					if (isset($ph1ent['disabled']))
645
						continue;
646

    
647
					if (isset($ph2ent['disabled']))
648
						continue;
649

    
650
					if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
651
						continue;
652

    
653
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
654

    
655
						$localid_type = $ph2ent['localid']['type'];
656
						$ph2ent['localid']['mode'] = $ph2ent['mode'];
657
						$localid_data = ipsec_idinfo_to_cidr($ph2ent['localid']);
658
						/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
659
						if (($localid_type == "none") ||
660
							(($ph1ent['authentication_method'] == "xauth_psk_server") ||
661
							($ph1ent['authentication_method'] == "pre_shared_key"))
662
							&& isset($ph1ent['mobile'])
663
							&& (ipsec_get_number_of_phase2($ikeid)==1))
664
							$localid_spec = " ";
665
						else {
666
							if ($localid_type != "address") {
667
								$localid_type = "subnet";
668
							}
669
							$localid_spec = $localid_type." ".$localid_data." any";
670
						}
671

    
672
						if (!isset($ph2ent['mobile'])) {
673
							$remoteid_type = $ph2ent['remoteid']['type'];
674
							if ($remoteid_type != "address")
675
								$remoteid_type = "subnet";
676

    
677
							$remoteid_data = ipsec_idinfo_to_cidr($ph2ent['remoteid']);
678
							$remoteid_spec = $remoteid_type." ".$remoteid_data." any";
679
						} else
680
							$remoteid_spec = "anonymous";
681

    
682
					} else {
683
						$rgip = $rgmap[$ph1ent['remote-gateway']];
684

    
685
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
686
							($ph1ent['authentication_method'] == "pre_shared_key"))
687
							&& isset($ph1ent['mobile']))
688
							$localid_spec = " ";
689
						else {
690
							$localid_data = ipsec_get_phase1_src($ph1ent);
691
							if($ph2ent['mode'] == 'transport') { $localid_data="$localid_data any"; }
692
							$localid_spec = "address {$localid_data}";
693
						}
694
						if (!isset($ph2ent['mobile'])) {
695
							$remoteid_data = $rgmap[$ph1ent['remote-gateway']];
696
							if($ph2ent['mode'] == 'transport') { $remoteid_data="$remoteid_data any"; }
697
							$remoteid_spec = "address {$remoteid_data}";
698
						} else
699
							$remoteid_spec = "anonymous";
700
					}
701

    
702
					if($ph2ent['protocol'] == 'esp') {
703

    
704
						$ealgos = '';
705

    
706
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
707

    
708
							$ealg_id = $ealg['name'];
709
							$ealg_kl = $ealg['keylen'];
710

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

    
746
						$ealgosline = "encryption_algorithm {$ealgos};";
747

    
748
					} else {
749

    
750
						$ealgosline = "encryption_algorithm null_enc;";
751
					}
752

    
753
					$halgos = join(",", $ph2ent['hash-algorithm-option']);
754
					$halgosline = "authentication_algorithm {$halgos};";
755

    
756
					$pfsline = '';
757
					if ($ph2ent['pfsgroup'])
758
						$pfsline = "pfs_group {$ph2ent['pfsgroup']};";
759
					if (isset($a_client['pfs_group'])) {
760
						$pfsline = '';
761
						if ($a_client['pfs_group'])
762
							$pfsline = "pfs_group {$a_client['pfs_group']};";
763
					}
764

    
765
					$lifeline = '';
766
					if ($ph2ent['lifetime'])
767
						$lifeline = "lifetime time {$ph2ent['lifetime']} secs;";
768

    
769
					/* add sainfo section to configuration */
770
					
771
					$racoonconf .=<<<EOD
772
					
773
sainfo {$localid_spec} {$remoteid_spec}
774
{
775
	remoteid {$ikeid};
776
	{$ealgosline}
777
	{$halgosline}
778
	{$pfsline}
779
	{$lifeline}
780
	compression_algorithm deflate;
781
}
782

    
783
EOD;
784
				}
785
				/* end sainfo */
786
			}
787
			/* end sainfo sections */
788

    
789
			fwrite($fd, $racoonconf);
790
			fclose($fd);
791
		}
792
		/* end racoon.conf */
793

    
794
		/* generate IPsec policies */
795
		if (is_array($a_phase2) && count($a_phase2)) {
796
			/* generate spd.conf */
797
			$fd = fopen("{$g['varetc_path']}/spd.conf", "w");
798
			if (!$fd) {
799
				printf("Error: cannot open spd.conf in vpn_ipsec_configure().\n");
800
				return 1;
801
			}
802

    
803
			$spdconf = "";
804

    
805
			/* Try to prevent people from locking themselves out of webgui. Just in case. */
806
			if ($config['interfaces']['lan']) {
807
				$lanip = get_interface_ip("lan");
808
				if (!empty($lanip) && is_ipaddrv4($lanip)) {
809
					$lansn = get_interface_subnet("lan");
810
					$lansa = gen_subnet($lanip, $lansn);
811
					$spdconf .= "spdadd -4 {$lanip}/32 {$lansa}/{$lansn} any -P out none;\n";
812
					$spdconf .= "spdadd -4 {$lansa}/{$lansn} {$lanip}/32 any -P in none;\n";
813
				}
814
				$lanipv6 = get_interface_ipv6("lan");
815
				if (!empty($lanipv6) && is_ipaddrv6($lanipv6)) {
816
					$lansnv6 = get_interface_subnetv6("lan");
817
					$lansav6 = gen_subnetv6($lanipv6, $lansnv6);
818
					$spdconf .= "spdadd -6 {$lanipv6}/128 {$lansav6}/{$lansnv6} any -P out none;\n";
819
					$spdconf .= "spdadd -6 {$lansav6}/{$lansnv6} {$lanipv6}/128 any -P in none;\n";
820
				}
821
			}
822

    
823
			foreach ($a_phase2 as $ph2ent) {
824

    
825
				if( !ipsec_lookup_phase1($ph2ent,$ph1ent))
826
					continue;
827

    
828
				if (isset($ph1ent['mobile']))
829
					continue;
830

    
831
				if (isset($ph1ent['disabled']))
832
					continue;
833

    
834
				if (isset($ph2ent['disabled']))
835
					continue;
836

    
837
				$ep = ipsec_get_phase1_src($ph1ent);
838
				if (!$ep)
839
					continue;
840

    
841
				$rgip = $rgmap[$ph1ent['remote-gateway']];
842
				if(!is_ipaddr($rgip))
843
					continue;
844

    
845
				$ph2ent['localid']['mode'] = $ph2ent['mode'];
846
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'],true);
847
				$remoteid = ipsec_idinfo_to_cidr($ph2ent['remoteid'],true);
848

    
849
				if(($ph2ent['mode'] == "tunnel") or ($ph2ent['mode'] == 'tunnel6')) {
850
					if($ph2ent['mode'] == "tunnel6")
851
						$family = "-6";
852
					else
853
						$family = "-4";
854

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

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

    
861
				} else {
862

    
863
					$localid_data = ipsec_get_phase1_src($ph1ent);
864
					$remoteid_data = $rgmap[$ph1ent['remote-gateway']];
865

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

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

    
872
				}
873

    
874
				/* static route needed? */
875
				if (preg_match("/^carp|^vip/i", $ph1ent['interface']))
876
					$parentinterface = link_carp_interface_to_parent($ph1ent['interface']);
877
				else
878
					$parentinterface = $ph1ent['interface'];
879

    
880
				if (($parentinterface <> "wan") && (is_ipaddr($rgip))) {
881
					/* add endpoint routes to correct gateway on interface */
882
					if (interface_has_gateway($parentinterface)) {
883
						$gatewayip = get_interface_gateway("$parentinterface");
884
						$interfaceip = get_interface_ip($parentinterface);
885
						$subnet_bits = get_interface_subnet($parentinterface);
886
						$subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
887
						/* if the remote gateway is in the local subnet, then don't add a route */
888
						if (! ip_in_subnet($rgip, "{$subnet_ip}/{$subnet_bits}")) {
889
							if(is_ipaddr($gatewayip)) {
890
								/* FIXME: does adding route-to and reply-to on the in/outbound
891
								 * rules fix this? smos@ 13-01-2009 */
892
								log_error("IPSEC interface is not WAN but {$parentinterface}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
893
								mwexec("/sbin/route delete -host {$rgip}");
894
								mwexec("/sbin/route add -host {$rgip} {$gatewayip}");
895
							}
896
						}
897
					}
898
				} elseif(is_ipaddr($rgip)) {
899
					if(stristr($route_str, "{$rgip}")) {
900
						mwexec("/sbin/route delete -host {$rgip}", true);
901
					}
902
				}
903
			}
904

    
905
			fwrite($fd, $spdconf);
906
			fclose($fd);
907
		}
908

    
909
		/* needed for racoonctl admin socket */
910
		if (!is_dir("/var/db/racoon"))
911
			mkdir("/var/db/racoon/");
912
		
913
		/* mange racoon process */
914
		if (is_process_running("racoon")) {
915
			sleep("0.1");
916
			mwexec("/usr/local/sbin/racoonctl -s /var/db/racoon/racoon.sock reload-config", false);
917
			/* load SPD without flushing to be safe on config additions or changes. */
918
			mwexec("/usr/local/sbin/setkey -f {$g['varetc_path']}/spd.conf", false);
919
		} else {
920
			/* flush SA + SPD entries */
921
			mwexec("/usr/local/sbin/setkey -FP", false);
922
 			sleep("0.1");
923
			mwexec("/usr/local/sbin/setkey -F", false);
924
 			sleep("0.1");
925
 			/* start racoon */
926
			mwexec("/usr/local/sbin/racoon -f {$g['varetc_path']}/racoon.conf", false);
927
 			sleep("0.1");
928
 			/* load SPD */
929
			mwexec("/usr/local/sbin/setkey -f {$g['varetc_path']}/spd.conf", false);
930

    
931
		}
932
		/* start filterdns, if necessary */
933
		if (count($filterdns_list) > 0) {
934
			$interval = 60;
935
			if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
936
				$interval = $ipseccfg['dns-interval'];
937

    
938
			$hostnames = "";
939
			array_unique($filterdns_list);
940
			foreach ($filterdns_list as $hostname)
941
				$hostnames .= "cmd {$hostname} '/etc/rc.newipsecdns'\n";
942
			file_put_contents("{$g['varetc_path']}/filterdns-ipsec.hosts", $hostnames);
943

    
944
			killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
945
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/filterdns-ipsec.hosts -d 1");
946
		}
947
	
948
		vpn_ipsec_failover_configure();
949

    
950
		if ($g['booting'])
951
			echo "done\n";
952
	}
953

    
954
	return 0;
955
}
956

    
957
/* Forcefully restart IPsec
958
 * This is required for when dynamic interfaces reload
959
 * For all other occasions the normal vpn_ipsec_configure()
960
 * will gracefully reload the settings without restarting
961
 */
962
function vpn_ipsec_force_reload() {
963
	global $config;
964
	global $g;
965

    
966
	$ipseccfg = $config['ipsec'];
967

    
968
	/* kill racoon */
969
	if(is_process_running("racoon"))
970
		mwexec("/usr/bin/killall racoon", true);
971

    
972
	/* wait for process to die */
973
	sleep(4);
974

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

    
978
	/* wait for flushing to finish */
979
	sleep(1);
980

    
981
	/* if ipsec is enabled, start up again */
982
	if (isset($ipseccfg['enable'])) {
983
		log_error("Forcefully reloading IPsec racoon daemon");
984
		vpn_ipsec_configure();
985
	}
986

    
987
}
988

    
989
/* master setup for vpn (mpd) */
990
function vpn_setup() {
991
	/* start pptpd */
992
	vpn_pptpd_configure();
993

    
994
	/* start pppoe server */
995
	vpn_pppoes_configure();
996

    
997
	/* setup l2tp */
998
	vpn_l2tp_configure();
999
}
1000

    
1001
function vpn_netgraph_support() {
1002
	$iflist = get_configured_interface_list();
1003
	foreach ($iflist as $iface) {
1004
		$realif = get_real_interface($iface);
1005
		/* Get support for netgraph(4) from the nic */
1006
		$ifinfo = pfSense_get_interface_addresses($realif);
1007
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
1008
                	pfSense_ngctl_attach(".", $realif);
1009
	}
1010
}
1011

    
1012
function vpn_pptpd_configure() {
1013
	global $config, $g;
1014

    
1015
	$syscfg = $config['system'];
1016
	$pptpdcfg = $config['pptpd'];
1017

    
1018
	if ($g['booting']) {
1019
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
1020
			return 0;
1021

    
1022
		echo "Configuring PPTP VPN service... ";
1023
	} else {
1024
		/* kill mpd */
1025
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1026

    
1027
		/* wait for process to die */
1028
		sleep(3);
1029

    
1030
		if (is_process_running("mpd -b")) {
1031
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1032
			log_error("Could not kill mpd within 3 seconds.   Trying again.");
1033
		}
1034

    
1035
		/* remove mpd.conf, if it exists */
1036
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
1037
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
1038
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
1039
	}
1040

    
1041
	/* make sure pptp-vpn directory exists */
1042
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
1043
		mkdir("{$g['varetc_path']}/pptp-vpn");
1044

    
1045
	switch ($pptpdcfg['mode']) {
1046
		case 'server' :
1047
			/* write mpd.conf */
1048
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1049
			if (!$fd) {
1050
				printf("Error: cannot open mpd.conf in vpn_pptpd_configure().\n");
1051
				return 1;
1052
			}
1053

    
1054
			$mpdconf = <<<EOD
1055
pptps:
1056

    
1057
EOD;
1058

    
1059
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1060
				$mpdconf .= "	load pt{$i}\n";
1061
			}
1062

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

    
1065
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1066

    
1067
				$mpdconf .= <<<EOD
1068

    
1069
pt{$i}:
1070
	new -i pptpd{$i} pt{$i} pt{$i}
1071
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1072
	load pts
1073

    
1074
EOD;
1075
			}
1076

    
1077
			$mpdconf .=<<<EOD
1078

    
1079
pts:
1080
	set iface disable on-demand
1081
	set iface enable proxy-arp
1082
	set iface enable tcpmssfix
1083
	set iface idle 1800
1084
	set iface up-script /usr/local/sbin/vpn-linkup
1085
	set iface down-script /usr/local/sbin/vpn-linkdown
1086
	set bundle enable multilink
1087
	set bundle enable crypt-reqd
1088
	set link yes acfcomp protocomp
1089
	set link no pap chap
1090
	set link enable chap-msv2
1091
	set link mtu 1460
1092
	set link keep-alive 10 60
1093
	set ipcp yes vjcomp
1094
	set bundle enable compression
1095
	set ccp yes mppc
1096
	set ccp yes mpp-e128
1097
	set ccp yes mpp-stateless
1098

    
1099
EOD;
1100

    
1101
			if (!isset ($pptpdcfg['req128'])) {
1102
				$mpdconf .=<<<EOD
1103
	set ccp yes mpp-e40
1104
	set ccp yes mpp-e56
1105

    
1106
EOD;
1107
			}
1108

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

    
1112
			if (!empty($pptpdcfg['dns1'])) {
1113
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1114
				if (!empty($pptpdcfg['dns2']))
1115
					$mpdconf .= " " . $pptpdcfg['dns2'];
1116
				$mpdconf .= "\n";
1117
			} elseif (isset ($config['dnsmasq']['enable'])) {
1118
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1119
				if ($syscfg['dnsserver'][0])
1120
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1121
				$mpdconf .= "\n";
1122
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1123
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1124
			}
1125

    
1126
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1127
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1128
				$acctport = $authport + 1;
1129
				$mpdconf .=<<<EOD
1130
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1131

    
1132
EOD;
1133
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1134
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1135
				$acctport = $authport + 1;
1136
				$mpdconf .=<<<EOD
1137
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret']}" {$authport} {$acctport}
1138

    
1139
EOD;
1140
			}
1141
			$mpdconf .=<<<EOD
1142
	set radius retries 3
1143
	set radius timeout 10
1144
	set auth enable radius-auth
1145

    
1146
EOD;
1147

    
1148
				if (isset ($pptpdcfg['radius']['accounting'])) {
1149
					$mpdconf .=<<<EOD
1150
	set auth enable radius-acct
1151
	set radius acct-update 300
1152

    
1153
EOD;
1154
				}
1155
			}
1156

    
1157
			fwrite($fd, $mpdconf);
1158
			fclose($fd);
1159

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

    
1167
			$mpdlinks = "";
1168

    
1169
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1170
				$mpdlinks .=<<<EOD
1171

    
1172
pt{$i}:
1173
	set link type pptp
1174
	set pptp enable incoming
1175
	set pptp disable originate
1176
	set pptp disable windowing
1177

    
1178
EOD;
1179
			}
1180

    
1181
			fwrite($fd, $mpdlinks);
1182
			fclose($fd);
1183

    
1184
			/* write mpd.secret */
1185
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1186
			if (!$fd) {
1187
				printf("Error: cannot open mpd.secret in vpn_pptpd_configure().\n");
1188
				return 1;
1189
			}
1190

    
1191
			$mpdsecret = "";
1192

    
1193
			if (is_array($pptpdcfg['user'])) {
1194
				foreach ($pptpdcfg['user'] as $user)
1195
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1196
			}
1197

    
1198
			fwrite($fd, $mpdsecret);
1199
			fclose($fd);
1200
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1201

    
1202
			vpn_netgraph_support();
1203

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

    
1207
			break;
1208

    
1209
		case 'redir' :
1210
			break;
1211
	}
1212

    
1213
	if ($g['booting'])
1214
		echo "done\n";
1215

    
1216
	return 0;
1217
}
1218

    
1219
function vpn_pppoes_configure() {
1220
	global $config;
1221

    
1222
	if (is_array($config['pppoes']['pppoe'])) {
1223
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1224
			vpn_pppoe_configure($pppoe);
1225
	}
1226
}
1227

    
1228
function vpn_pppoe_configure(&$pppoecfg) {
1229
	global $config, $g;
1230

    
1231
	$syscfg = $config['system'];
1232

    
1233
	/* create directory if it does not exist */
1234
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1235
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1236

    
1237
	if ($g['booting']) {
1238
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1239
			return 0;
1240

    
1241
		echo "Configuring PPPoE VPN service... ";
1242
	} else {
1243
		/* kill mpd */
1244
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1245

    
1246
		/* wait for process to die */
1247
		sleep(2);
1248

    
1249
	}
1250

    
1251
	switch ($pppoecfg['mode']) {
1252

    
1253
		case 'server' :
1254

    
1255
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1256

    
1257
			if ($pppoecfg['paporchap'] == "chap")
1258
				$paporchap = "set link enable chap";
1259
			else
1260
				$paporchap = "set link enable pap";
1261

    
1262
			/* write mpd.conf */
1263
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1264
			if (!$fd) {
1265
				printf("Error: cannot open mpd.conf in vpn_pppoe_configure().\n");
1266
				return 1;
1267
			}
1268
			$mpdconf = "\n\n";
1269
			$mpdconf .= "poes:\n";
1270

    
1271
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1272
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1273
			}
1274

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

    
1277
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1278

    
1279
				if (isset ($pppoecfg['radius']['radiusissueips']) && isset ($pppoecfg['radius']['server']['enable'])) {
1280
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1281
				} else {
1282
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1283
				}
1284

    
1285
				$mpdconf .=<<<EOD
1286

    
1287
poes{$pppoecfg['pppoeid']}{$i}:
1288
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1289
	{$isssue_ip_type}
1290
	load pppoe_standard
1291

    
1292
EOD;
1293
			}
1294

    
1295
			$mpdconf .=<<<EOD
1296

    
1297
pppoe_standard:
1298
	set bundle no multilink
1299
	set bundle enable compression
1300
	set auth max-logins 1
1301
	set iface up-script /usr/local/sbin/vpn-linkup
1302
	set iface down-script /usr/local/sbin/vpn-linkdown
1303
	set iface idle 0
1304
	set iface disable on-demand
1305
	set iface disable proxy-arp
1306
	set iface enable tcpmssfix
1307
	set iface mtu 1500
1308
	set link no pap chap
1309
	{$paporchap}
1310
	set link keep-alive 60 180
1311
	set ipcp yes vjcomp
1312
	set ipcp no vjcomp
1313
	set link max-redial -1
1314
	set link mtu 1492
1315
	set link mru 1492
1316
	set ccp yes mpp-e40
1317
	set ccp yes mpp-e128
1318
	set ccp yes mpp-stateless
1319
	set link latency 1
1320
	#set ipcp dns 10.10.1.3
1321
	#set bundle accept encryption
1322

    
1323
EOD;
1324

    
1325
			if (!empty($pppoecfg['dns1'])) {
1326
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1327
				if (!empty($pppoecfg['dns2']))
1328
					$mpdconf .= " " . $pppoecfg['dns2'];
1329
				$mpdconf .= "\n";
1330
			} elseif (isset ($config['dnsmasq']['enable'])) {
1331
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1332
				if ($syscfg['dnsserver'][0])
1333
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1334
				$mpdconf .= "\n";
1335
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1336
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1337
			}
1338

    
1339
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1340
				$radiusport = "";
1341
				$radiusacctport = "";
1342
				if (isset($pppoecfg['radius']['server']['port']))
1343
					$radiusport = $pppoecfg['radius']['server']['port'];
1344
				if (isset($pppoecfg['radius']['server']['acctport']))
1345
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1346
				$mpdconf .=<<<EOD
1347
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']} {$radiusport} {$radiusacctport}" 
1348
	set radius retries 3
1349
	set radius timeout 10
1350
	set auth enable radius-auth
1351

    
1352
EOD;
1353

    
1354
				if (isset ($pppoecfg['radius']['accounting'])) {
1355
					$mpdconf .=<<<EOD
1356
	set auth enable radius-acct
1357

    
1358
EOD;
1359
				}
1360
			}
1361

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

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

    
1372
			$mpdlinks = "";
1373

    
1374
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1375
				$mpdlinks .=<<<EOD
1376
			
1377
poes{$pppoecfg['pppoeid']}{$i}:
1378
	set phys type pppoe
1379
        set pppoe iface {$pppoe_interface}
1380
        set pppoe service "*"
1381
        set pppoe disable originate
1382
        set pppoe enable incoming
1383

    
1384
EOD;
1385
			}
1386

    
1387
			fwrite($fd, $mpdlinks);
1388
			fclose($fd);
1389

    
1390
			if ($pppoecfg['username']) {
1391
				/* write mpd.secret */
1392
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1393
				if (!$fd) {
1394
					printf("Error: cannot open mpd.secret in vpn_pppoe_configure().\n");
1395
					return 1;
1396
				}
1397

    
1398
				$mpdsecret = "\n\n";
1399

    
1400
				if (!empty($pppoecfg['username'])) {
1401
					$item = explode(" ", $pppoecfg['username']);
1402
					foreach($item as $userdata) {
1403
						$data = explode(":", $userdata);
1404
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1405
					}
1406
				}
1407

    
1408
				fwrite($fd, $mpdsecret);
1409
				fclose($fd);
1410
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1411
			}
1412

    
1413
			/* Get support for netgraph(4) from the nic */
1414
			pfSense_ngctl_attach(".", $pppoe_interface);
1415
			/* fire up mpd */
1416
			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");
1417

    
1418
			break;
1419
	}
1420

    
1421
	if ($g['booting'])
1422
		echo "done\n";
1423

    
1424
	return 0;
1425
}
1426

    
1427
function vpn_l2tp_configure() {
1428
	global $config, $g;
1429

    
1430
	$syscfg = $config['system'];
1431
	$l2tpcfg = $config['l2tp'];
1432

    
1433
	/* create directory if it does not exist */
1434
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1435
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1436

    
1437
	if ($g['booting']) {
1438
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1439
			return 0;
1440

    
1441
		echo "Configuring l2tp VPN service... ";
1442
	} else {
1443
		/* kill mpd */
1444
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1445

    
1446
		/* wait for process to die */
1447
		sleep(8);
1448

    
1449
	}
1450

    
1451
	/* make sure l2tp-vpn directory exists */
1452
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1453
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1454

    
1455
	switch ($l2tpcfg['mode']) {
1456

    
1457
		case 'server' :
1458
			if ($l2tpcfg['paporchap'] == "chap")
1459
				$paporchap = "set link enable chap";
1460
			else
1461
				$paporchap = "set link enable pap";
1462

    
1463
			/* write mpd.conf */
1464
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1465
			if (!$fd) {
1466
				printf("Error: cannot open mpd.conf in vpn_l2tp_configure().\n");
1467
				return 1;
1468
			}
1469
			$mpdconf = "\n\n";
1470
			$mpdconf .=<<<EOD
1471
l2tps:
1472

    
1473
EOD;
1474

    
1475
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1476
				$mpdconf .= "	load l2tp{$i}\n";
1477
			}
1478

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

    
1481
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1482

    
1483
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1484
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1485
				} else {
1486
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1487
				}
1488

    
1489
				$mpdconf .=<<<EOD
1490

    
1491
l2tp{$i}:
1492
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1493
	{$isssue_ip_type}
1494
	load l2tp_standard
1495

    
1496
EOD;
1497
			}
1498

    
1499
			$mpdconf .=<<<EOD
1500

    
1501
l2tp_standard:
1502
        set bundle disable multilink
1503
        set bundle enable compression
1504
        set bundle yes crypt-reqd
1505
        set ipcp yes vjcomp
1506
        # set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1507
        set ccp yes mppc
1508
        set iface disable on-demand
1509
        set iface enable proxy-arp
1510
	set iface up-script /usr/local/sbin/vpn-linkup
1511
	set iface down-script /usr/local/sbin/vpn-linkdown
1512
        set link yes acfcomp protocomp
1513
        set link no pap chap
1514
        set link enable chap
1515
        set link keep-alive 10 180
1516

    
1517
EOD;
1518

    
1519
			if (!empty($l2tpcfg['dns1'])) {
1520
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1521
				if (!empty($l2tpcfg['dns2']))
1522
					$mpdconf .= " " . $l2tpcfg['dns2'];
1523
				$mpdconf .= "\n";
1524
			} elseif (isset ($config['dnsmasq']['enable'])) {
1525
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1526
				if ($syscfg['dnsserver'][0])
1527
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1528
				$mpdconf .= "\n";
1529
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1530
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1531
			}
1532

    
1533
			if (isset ($l2tpcfg['radius']['enable'])) {
1534
				$mpdconf .=<<<EOD
1535
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1536
	set radius retries 3
1537
	set radius timeout 10
1538
	set auth enable radius-auth
1539

    
1540
EOD;
1541

    
1542
				if (isset ($l2tpcfg['radius']['accounting'])) {
1543
					$mpdconf .=<<<EOD
1544
	set auth enable radius-acct
1545

    
1546
EOD;
1547
				}
1548
			}
1549

    
1550
			fwrite($fd, $mpdconf);
1551
			fclose($fd);
1552

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

    
1560
			$mpdlinks = "";
1561

    
1562
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1563
				$mpdlinks .=<<<EOD
1564

    
1565
l2tp{$i}:
1566
	set link type l2tp
1567
        set l2tp enable incoming
1568
        set l2tp disable originate
1569

    
1570
EOD;
1571
			if (!empty($l2tpcfg['secret']))
1572
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1573
			}
1574

    
1575
			fwrite($fd, $mpdlinks);
1576
			fclose($fd);
1577

    
1578
			/* write mpd.secret */
1579
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1580
			if (!$fd) {
1581
				printf("Error: cannot open mpd.secret in vpn_l2tp_configure().\n");
1582
				return 1;
1583
			}
1584

    
1585
			$mpdsecret = "\n\n";
1586

    
1587
			if (is_array($l2tpcfg['user'])) {
1588
				foreach ($l2tpcfg['user'] as $user)
1589
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1590
			}
1591

    
1592
			fwrite($fd, $mpdsecret);
1593
			fclose($fd);
1594
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1595

    
1596
			vpn_netgraph_support();
1597

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

    
1601
			break;
1602

    
1603
		case 'redir' :
1604
			break;
1605
	}
1606

    
1607
	if ($g['booting'])
1608
		echo "done\n";
1609

    
1610
	return 0;
1611
}
1612

    
1613
/* Walk the tunnels for hostname endpoints. If the hostnames 
1614
 * resolve to a different IP now compared to the DNS cache
1615
 * we reload the policies if the endpoint has changed */
1616
function vpn_ipsec_refresh_policies() {
1617
	global $config;
1618
	global $g;
1619

    
1620
	$ipseccfg = $config['ipsec'];
1621
	$a_phase1 = $config['ipsec']['phase1'];
1622
	$a_phase2 = $config['ipsec']['phase2'];
1623

    
1624
	if (isset($ipseccfg['disable'])) {
1625
		return true;
1626
	}
1627

    
1628
	/* Walk the Ipsec tunnel array */
1629
	if (!is_array($a_phase1) || (!count($a_phase1))) {
1630
		return;
1631
	}
1632

    
1633
	foreach ($a_phase1 as $phase1) {
1634
		if (isset($phase1['disabled'])) {
1635
			continue;
1636
		}
1637
		if (is_ipaddr($phase1['remote-gateway'])) {
1638
			continue;
1639
		}
1640
		if (!is_ipaddr($phase1['remote-gateway'])) {
1641
			$dnscache = compare_hostname_to_dnscache($phase1['remote-gateway']);
1642
			$dnscache = trim($dnscache);
1643
			/* we should have the old IP addresses in the dnscache now */
1644
			if($dnscache <> "") {
1645
				$oldphase1 = $phase1;
1646
				$oldphase1['remote-gateway'] = trim($dnscache);
1647
				/* now we need to find all tunnels for this host */
1648
				if (!is_array($a_phase2) || (!count($a_phase2))) {
1649
					continue;
1650
				}
1651
				foreach ($a_phase2 as $phase2) {
1652
					if($phase2['ikeid'] == $phase1['ikeid']) {
1653
						reload_tunnel_spd_policy ($phase1, $phase2, $oldphase1, $oldphase2);
1654
					}
1655
				}
1656
			}
1657
		}
1658
	}
1659

    
1660
	/* process all generated spd.conf files from tmp which are left behind
1661
	 * behind by either changes of dynamic tunnels or manual edits
1662
	 * scandir() is only available in PHP5 */
1663
	$tmpfiles = array();
1664
	$dh  = opendir($g['tmp_path']);
1665
	while (false !== ($filename = readdir($dh))) {
1666
		if(preg_match("/^spd.conf.reload./", $filename)) {
1667
			$tmpfiles[] = $filename;
1668
		}
1669
	}
1670
	sort($tmpfiles);
1671
	foreach($tmpfiles as $tmpfile) {
1672
		$ret = mwexec("/usr/local/sbin/setkey -f {$g['tmp_path']}/{$tmpfile} 2>&1", false);
1673
		if($ret == 0) {
1674
			unlink_if_exists("{$g['tmp_path']}/{$tmpfile}");
1675
		} else {
1676
			rename("{$g['tmp_path']}/{$tmpfile}", ("{$g['tmp_path']}/failed.{$tmpfile}"));
1677
		}
1678
	}
1679
}
1680

    
1681
/* reloads the tunnel configuration for a tunnel item
1682
 * Will remove and add SPD polices */
1683
function reload_tunnel_spd_policy($phase1, $phase2, $old_phase1, $old_phase2) {
1684
	global $config;
1685
	global $g;
1686

    
1687
	/* if we are not passed a old tunnel array we create one */
1688
	if(empty($old_phase1)) {
1689
		$old_phase1 = $phase1;
1690
	}
1691
	if(empty($old_phase2)) {
1692
		$old_phase2 = $phase2;
1693
	}
1694

    
1695
	$sad_arr = ipsec_dump_sad();
1696

    
1697
	$ep = ipsec_get_phase1_src($phase1);
1698
	$phase2['localid']['mode'] = $phase2['mode'];
1699
	echo "phase2 mode {$phase2['mode']}\n";
1700
	$local_subnet = ipsec_idinfo_to_cidr($phase2['localid']);
1701
	$remote_subnet = ipsec_idinfo_to_cidr($phase2['remoteid']);
1702

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

    
1706
	$old_ep = ipsec_get_phase1_src($old_phase1);
1707
	$old_phase2['localid']['mode'] = $old_phase2['mode'];
1708
	echo "old_phase2 mode {$old_phase2['mode']}\n";
1709
	$old_local_subnet = ipsec_idinfo_to_cidr($old_phase2['localid']);
1710
	$old_remote_subnet = ipsec_idinfo_to_cidr($old_phase2['remoteid']);
1711

    
1712
	/* see if this tunnel has a hostname for the remote-gateway, and if so,
1713
	 * try to resolve it now and add it to the list for filterdns */
1714
	$rgip = "";
1715
	if (!is_ipaddr($phase1['remote-gateway'])) {
1716
		if(! $g['booting']) {
1717
			$rgip = resolve_retry($phase1['remote-gateway']);
1718
			add_hostname_to_watch($phase1['remote-gateway']);
1719
		} else {
1720
			add_hostname_to_watch($phase1['remote-gateway']);
1721
		}
1722
		if (!is_ipaddr($rgip)) {
1723
			log_error("Could not determine VPN endpoint for '{$phase1['descr']}'");
1724
			return false;
1725
		}
1726
	} else {
1727
		$rgip = $phase1['remote-gateway'];
1728
	}
1729
	if (!$ep) {
1730
		log_error("Could not determine VPN endpoint for '{$phase1['descr']}'");
1731
		return false;
1732
	}
1733

    
1734
	if((!is_ipaddr($old_ep)) || (! is_ipaddr($ep))) {
1735
		log_error("IPSEC: ERROR: One of the endpoints is not a IP address. Old EP '{$old_ep}' new EP '{$ep}'");
1736
	}
1737
	if((! is_ipaddr($rgip)) || (! is_ipaddr($old_gw))) {
1738
		log_error("IPSEC: ERROR: One of the remote endpoints is not a IP address. Old RG '{$old_gw}' new RG '{$rgip}'");
1739
	}
1740

    
1741
	$spdconf = "";
1742
	/* Delete old SPD policies if there are changes between the old and new */
1743
	if(($phase1 != $old_phase1) || ($phase2 != $old_phase2)) {
1744
		if($old_phase2['mode'] == "tunnel6")
1745
			$family = "-6";
1746
		else
1747
			$family = "-4";
1748

    
1749
		$spdconf .= "spddelete {$family} {$old_local_subnet} " .
1750
			"{$old_remote_subnet} any -P out ipsec " .
1751
			"{$old_phase2['protocol']}/tunnel/{$old_ep}-" .
1752
			"{$old_gw}/unique;\n";
1753
		$spdconf .= "spddelete {$family} {$old_remote_subnet} " .
1754
			"{$old_local_subnet} any -P in ipsec " .
1755
			"{$old_phase2['protocol']}/tunnel/{$old_gw}-" .
1756
			"{$old_ep}/unique;\n";
1757

    
1758
		/* zap any existing SA entries */
1759
		foreach($sad_arr as $sad) {
1760
			if(($sad['dst'] == $old_ep) && ($sad['src'] == $old_gw)) {
1761
				$spdconf .= "delete {$family} {$old_ep} {$old_gw} {$old_phase2['protocol']} 0x{$sad['spi']};\n";
1762
			}
1763
			if(($sad['src'] == $oldep) && ($sad['dst'] == $old_gw)) {
1764
				$spdconf .= "delete {$family} {$old_gw} {$old_ep} {$old_phase2['protocol']} 0x{$sad['spi']};\n";
1765
			}
1766
		}
1767
	}
1768

    
1769
	if($phase2['mode'] == "tunnel6")
1770
		$family = "-6";
1771
	else
1772
		$family = "-4";
1773

    
1774
	/* Create new SPD entries for the new configuration */
1775
	/* zap any existing SA entries beforehand */
1776
	foreach($sad_arr as $sad) {
1777
		if(($sad['dst'] == $ep) && ($sad['src'] == $rgip)) {
1778
			$spdconf .= "delete {$family} {$rgip} {$ep} {$phase2['protocol']} 0x{$sad['spi']};\n";
1779
		}
1780
		if(($sad['src'] == $ep) && ($sad['dst'] == $rgip)) {
1781
			$spdconf .= "delete {$family} {$ep} {$rgip} {$phase2['protocol']} 0x{$sad['spi']};\n";
1782
		}
1783
	}
1784
	/* add new SPD policies to replace them */
1785
	$spdconf .= "spdadd {$family} {$local_subnet} " .
1786
		"{$remote_subnet} any -P out ipsec " .
1787
		"{$phase2['protocol']}/tunnel/{$ep}-" .
1788
		"{$rgip}/unique;\n";
1789
	$spdconf .= "spdadd {$family} {$remote_subnet} " .
1790
		"{$local_subnet} any -P in ipsec " .
1791
		"{$phase2['protocol']}/tunnel/{$rgip}-" .
1792
		"{$ep}/unique;\n";
1793

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

    
1796
	$now = time();
1797
	$spdfile = tempnam("{$g['tmp_path']}", "spd.conf.reload.{$now}.");
1798
	/* generate temporary spd.conf */
1799
	file_put_contents($spdfile, $spdconf);
1800
	return true;
1801
}
1802

    
1803
function vpn_ipsec_configure_preferoldsa() {
1804
	global $config;
1805
	if(isset($config['ipsec']['preferoldsa']))
1806
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
1807
	else
1808
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
1809
}
1810

    
1811
?>
(52-52/61)