Project

General

Profile

Download (52.6 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 gettext("Configuring IPsec VPN... ");
125

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
186
					$ph2ent['localid']['mode'] = $ph2ent['mode'];
187
					/* add an ipsec pinghosts entry */
188
					if ($ph2ent['pinghost']) {
189
						$iflist = get_configured_interface_list();
190
						foreach ($iflist as $ifent => $ifname) {
191
							if(is_ipaddrv6($ph2ent['pinghost'])) {
192
								$interface_ip = get_interface_ipv6($ifent);
193
								if(!is_ipaddrv6($interface_ip))
194
									continue;
195
								$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true);
196
								if (ip_in_subnet($interface_ip, $local_subnet)) {
197
									$srcip = $interface_ip;
198
									break;
199
								}
200
							} else {
201
								$interface_ip = get_interface_ip($ifent);
202
								if(!is_ipaddrv4($interface_ip))
203
									continue;
204
								$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true);
205
								if (ip_in_subnet($interface_ip, $local_subnet)) {
206
									$srcip = $interface_ip;
207
									break;
208
								}
209
							}
210
						}
211
						$dstip = $ph2ent['pinghost'];
212
						if(is_ipaddrv6($dstip)) {
213
							$family = "inet6";
214
						} else {
215
							$family = "inet";
216
						}
217
						if (is_ipaddr($srcip))
218
							$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
219

    
220
					}
221
				}
222
				file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
223
				
224
			}
225
		}
226

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

    
255
		$pskconf = "";
256

    
257
		if (is_array($a_phase1) && count($a_phase1)) {
258
			foreach ($a_phase1 as $ph1ent) {
259

    
260
				if (isset($ph1ent['disabled']))
261
					continue;
262

    
263
				if (strstr($ph1ent['authentication_method'],'rsa'))
264
					continue;
265

    
266
				$peerid_type = $ph1ent['peerid_type'];
267

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

    
274
					case "address";
275
						$peerid_data = $ph1ent['peerid_data'];
276
						break;
277

    
278
					case "fqdn";
279
					case "keyid tag";
280
					case "user_fqdn";
281
						$peerid_data = $ph1ent['peerid_data'];
282
						break;
283
				}
284

    
285
				if (!empty($peerid_data) && !empty($ph1ent['pre-shared-key']))
286
					$pskconf .= trim($peerid_data) . "\t" . trim($ph1ent['pre-shared-key']) . "\n";
287
			}
288
		}
289

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

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

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

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

    
318
			$racoonconf = "# This file is automatically generated. Do not edit\n";			
319
			$racoonconf .= "path pre_shared_key \"{$g['varetc_path']}/psk.txt\";\n\n";
320
			$racoonconf .= "path certificate  \"{$g['varetc_path']}\";\n\n";
321

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

    
334
			/* begin mode_cfg section */
335
			if (is_array($a_client) && isset($a_client['enable'])) {
336

    
337
				$racoonconf .= "\nmode_cfg\n";
338
				$racoonconf .= "{\n";
339

    
340
				if ($a_client['user_source'])
341
					$racoonconf .= "\tauth_source {$a_client['user_source']};\n";
342
				if ($a_client['group_source'])
343
					$racoonconf .= "\tgroup_source {$a_client['group_source']};\n";
344

    
345
				if ($a_client['pool_address'] && $a_client['pool_netbits']) {
346
					$pool_address = $a_client['pool_address'];
347
					$pool_netmask = gen_subnet_mask($a_client['pool_netbits']);
348

    
349
					$pool_address = long2ip32(ip2long($pool_address)+1);
350
					$pool_size = (~ip2long($pool_netmask) & 0xFFFFFFFF) - 2;
351

    
352
					$racoonconf .= "\tpool_size {$pool_size};\n";
353
					$racoonconf .= "\tnetwork4 {$pool_address};\n";
354
					$racoonconf .= "\tnetmask4 {$pool_netmask};\n";
355
				}
356

    
357
				if (isset($a_client['net_list'])) {
358

    
359
					$net_list = '';
360

    
361
					foreach ($a_phase2 as $ph2ent) {
362

    
363
						if (isset($ph2ent['disabled']))
364
							continue;
365

    
366
						if (!isset($ph2ent['mobile']))
367
							continue;
368

    
369
						$localid = ipsec_idinfo_to_cidr($ph2ent['localid'],true);
370

    
371
						if ($net_list)
372
							$net_list .= ", ";
373
						$net_list .= $localid;
374
					}
375

    
376
					if ($net_list)
377
						$racoonconf .= "\tsplit_network include {$net_list};\n";
378
				}
379

    
380
				if ($a_client['dns_server1'])
381
					$racoonconf .= "\tdns4 {$a_client['dns_server1']};\n";
382
				if ($a_client['dns_server2'])
383
					$racoonconf .= "\tdns4 {$a_client['dns_server2']};\n";
384
				if ($a_client['dns_server3'])
385
					$racoonconf .= "\tdns4 {$a_client['dns_server3']};\n";
386
				if ($a_client['dns_server4'])
387
					$racoonconf .= "\tdns4 {$a_client['dns_server4']};\n";
388

    
389
				if ($a_client['wins_server1'])
390
					$racoonconf .= "\twins4 {$a_client['wins_server1']};\n";
391
				if ($a_client['wins_server2'])
392
					$racoonconf .= "\twins4 {$a_client['wins_server2']};\n";
393

    
394
				if ($a_client['dns_domain']) {
395
					$racoonconf .= "\tdefault_domain \"{$a_client['dns_domain']}\";\n";
396
					$racoonconf .= "\tsplit_dns \"{$a_client['dns_domain']}\";\n";
397
				}
398

    
399
				if ($a_client['pfs_group'])
400
					$racoonconf .= "\tpfs_group {$a_client['pfs_group']};\n";
401

    
402
				if ($a_client['login_banner']) {
403
					$fn = "{$g['varetc_path']}/racoon.motd";
404
					$fd1 = fopen($fn, "w");
405
					if (!$fd1) {
406
						printf(gettext("Error: cannot open server %s in vpn.\n"), $fn);
407
						return 1;
408
					}
409

    
410
					fwrite($fd1, $a_client['login_banner']);
411
					fclose($fd1);
412

    
413
					$racoonconf .= "\tbanner \"{$fn}\";\n";
414
				}
415

    
416
				if (isset($a_client['save_passwd']))
417
					$racoonconf .= "\tsave_passwd on;\n";
418

    
419
				$racoonconf .= "}\n\n";
420
			}
421
			/* end mode_cfg section */
422
			
423
			if ($a_client['user_source'] != "system")
424
            {
425
				foreach ($config['system']['authserver'] as $authcfg) {
426
                     if ($authcfg['type'] == 'ldap' and $authcfg['name'] == $a_client['user_source']) 
427
					{
428
                        $thisauthcfg = $authcfg;
429
                    }
430
                }
431

    
432
				/* begin ldapcfg */                        
433
                        $racoonconf .= "ldapcfg {\n";
434
                        $racoonconf .= "\tversion 3;\n";
435
                        $racoonconf .= "\thost \"".$thisauthcfg['host']."\";\n";
436
                        $lport = "389";
437
                        if ($authcfg['port'] != "") {$lport = $authcfg['port'];};
438
                        $racoonconf .= "\tport ".$lport.";\n";
439
                        $racoonconf .= "\tbase \"".$thisauthcfg['ldap_basedn']."\";\n";
440
                        $racoonconf .= "\tsubtree on;\n";
441
                        $racoonconf .= "\tbind_dn \"".$thisauthcfg['ldap_binddn']."\";\n";
442
                        $racoonconf .= "\tbind_pw \"".$thisauthcfg['ldap_bindpw']."\";\n";
443
                        $racoonconf .= "\tattr_user \"".$thisauthcfg['ldap_attr_user']."\";\n";
444
                        $racoonconf .= "}\n\n";
445
				/* end ldapcfg */
446
			}
447
			/* begin remote sections */
448
			if (is_array($a_phase1) && count($a_phase1)) {
449
				/* begin remote */
450
				foreach ($a_phase1 as $ph1ent) {
451

    
452
					if (isset($ph1ent['disabled']))
453
						continue;
454

    
455
					if (isset($ph1ent['mobile']) && !isset($a_client['enable']))
456
						continue;
457

    
458
					$ikeid = $ph1ent['ikeid'];
459

    
460
					$ep = ipsec_get_phase1_src($ph1ent);
461
					if (!$ep)
462
						continue;
463

    
464
					if (!isset($ph1ent['mobile'])) {
465
						$rgip = $rgmap[$ph1ent['remote-gateway']];
466
						if (!$rgip)
467
							continue;
468
					}
469

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

    
472
					switch ($myid_type) {
473

    
474
						case "myaddress":
475
							$myid_type = "address";
476
							$myid_data = $ep;
477
							break;
478

    
479
						case "dyn_dns":
480
							$myid_type = "address";
481
							$myid_data = resolve_retry($ph1ent['myid_data']);
482
							break;
483

    
484
						case "address";
485
							$myid_data = $ph1ent['myid_data'];
486
							break;
487

    
488
						case "fqdn";
489
						case "keyid tag";
490
						case "user_fqdn";
491
						case "asn1dn";
492
							$myid_data = $ph1ent['myid_data'];
493
							if( $myid_data )
494
								$myid_data = "\"".$myid_data."\"";
495
							break;
496
					}
497

    
498
					$peerid_type = $ph1ent['peerid_type'];
499

    
500
					switch ($peerid_type) {
501
						case "peeraddress":
502
							$peerid_type = "address";
503
							$peerid_data = $rgip;
504
							break;
505

    
506
						case "address";
507
							$peerid_data = $ph1ent['peerid_data'];
508
							break;
509

    
510
						case "fqdn";
511
						case "keyid tag";
512
						case "user_fqdn";
513
						case "asn1dn";
514
							$peerid_data = $ph1ent['peerid_data'];
515
							if( $peerid_data )
516
								$peerid_data = "\"".$peerid_data."\"";
517
							break;
518
					}
519

    
520
					$natt = "off";
521
					if (isset($ph1ent['nat_traversal']))
522
						$natt = $ph1ent['nat_traversal'];
523

    
524
					$init = "on";
525
					$genp = !empty($ph1ent['generate_policy']) ? $ph1ent['generate_policy'] : "off";
526
					$pcheck = !empty($ph1ent['proposal_check']) ? $ph1ent['proposal_check'] : $pcheck = "claim";
527
					$passive = "";
528
					if (isset($ph1ent['mobile'])) {
529
						$rgip = "anonymous";
530
						$passive = "passive on;";
531
						/* Mimic 1.2.3's behavior for pure-psk mobile tunnels */
532
						if ($ph1ent['authentication_method'] == "pre_shared_key") {
533
							$pcheck = !empty($ph1ent['proposal_check']) ? $ph1ent['proposal_check'] : $pcheck = "obey";
534
							$genp = !empty($ph1ent['generate_policy']) ? $ph1ent['generate_policy'] : "on";
535
						} else {
536
							$init = "off";
537
							$genp = !empty($ph1ent['generate_policy']) ? $ph1ent['generate_policy'] : "unique";
538
						}
539
					}
540

    
541
					$dpdline1 = '';
542
					$dpdline2 = '';
543
					if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
544
						$dpdline1 = "dpd_delay = {$ph1ent['dpd_delay']};";
545
						$dpdline2 = "dpd_maxfail = {$ph1ent['dpd_maxfail']};";
546
					}
547

    
548
					if (isset ($ph1ent['authentication_method']))
549
						$authmethod = $ph1ent['authentication_method'];
550
					else
551
						$authmethod = 'pre_shared_key';
552

    
553
					$certline = '';
554

    
555
					if (strstr($authmethod,'rsa')) {
556

    
557
						$cert = lookup_cert($ph1ent['certref']);
558

    
559
						if (!$cert)
560
						{
561
							log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
562
							continue;
563
						}
564

    
565
						$certfile = "cert-".$ikeid.".crt";
566
						$certpath = $g['varetc_path']."/".$certfile;
567

    
568
						if (!file_put_contents($certpath, base64_decode($cert['crt'])))
569
						{
570
							log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name']));
571
							continue;
572
						}
573

    
574
						chmod($certpath, 0600);
575

    
576
						$keyfile = "cert-".$ikeid.".key";
577
						$keypath = $g['varetc_path']."/".$keyfile;
578

    
579
						if (!file_put_contents($keypath, base64_decode($cert['prv'])))
580
						{
581
							log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
582
							continue;
583
						}
584

    
585
						chmod($keypath, 0600);
586

    
587
						$ca = lookup_ca($ph1ent['caref']);
588
						if ($ca) {
589
							$cafile = "ca-".$ikeid.".crt";
590
							$capath = $g['varetc_path']."/".$cafile;
591

    
592
							if (!file_put_contents($capath, base64_decode($ca['crt'])))
593
							{
594
								log_error(sprintf(gettext("Error: Cannot write phase1 CA certificate file for %s"), $ph1ent['name']));
595
								continue;
596
							}
597

    
598
							chmod($capath, 0600);
599
							$caline = "ca_type x509 \"".basename($capath)."\";";
600
						}
601

    
602
						$certline = "certificate_type x509 \"".basename($certpath)."\" \"".basename($keypath)."\";";
603

    
604
					}
605

    
606
					$ealgos = '';
607
					$ealg_id = $ph1ent['encryption-algorithm']['name'];
608
					$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
609
					if ($ealg_kl)
610
						$ealgos = $ealgos.$ealg_id." ".$ealg_kl;
611
					else
612
						$ealgos = $ealgos.$ealg_id;
613

    
614
					$lifeline = '';
615
					if ($ph1ent['lifetime'])
616
						$lifeline = "lifetime time {$ph1ent['lifetime']} secs;";
617

    
618
					/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
619
					if (!(($ph1ent['authentication_method'] == "pre_shared_key") && isset($ph1ent['mobile']))) {
620
						$peerid_spec = "peers_identifier {$peerid_type} {$peerid_data};";
621
					}
622

    
623
					/* add remote section to configuration */
624

    
625
					$racoonconf .=<<<EOD
626

    
627
remote {$rgip}
628
{
629
	ph1id {$ikeid};
630
	exchange_mode {$ph1ent['mode']};
631
	my_identifier {$myid_type} {$myid_data};
632
	{$peerid_spec}
633
	ike_frag on;
634
	generate_policy = {$genp};
635
	initial_contact = {$init};
636
	nat_traversal = {$natt};
637
	{$certline}
638
	{$caline}
639
	{$dpdline1}
640
	{$dpdline2}
641
	support_proxy on;
642
	proposal_check {$pcheck};
643
	{$passive}
644

    
645
	proposal
646
	{
647
		authentication_method {$authmethod};
648
		encryption_algorithm ${ealgos};
649
		hash_algorithm {$ph1ent['hash-algorithm']};
650
		dh_group {$ph1ent['dhgroup']};
651
		${lifeline}
652
	}
653
}
654

    
655
EOD;
656
				}
657
				/* end remote */
658
			}
659
			/* end remote sections */
660
		
661
			/* begin sainfo sections */
662
			if (is_array($a_phase2) && count($a_phase2)) {
663

    
664
				/* begin sainfo */
665
				foreach ($a_phase2 as $ph2ent) {
666

    
667
					$ikeid = $ph2ent['ikeid'];
668

    
669
					if( !ipsec_lookup_phase1($ph2ent,$ph1ent))
670
						continue;
671

    
672
					if (isset($ph1ent['disabled']))
673
						continue;
674

    
675
					if (isset($ph2ent['disabled']))
676
						continue;
677

    
678
					if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
679
						continue;
680

    
681
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
682

    
683
						$localid_type = $ph2ent['localid']['type'];
684
						$ph2ent['localid']['mode'] = $ph2ent['mode'];
685
						$localid_data = ipsec_idinfo_to_cidr($ph2ent['localid']);
686
						/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
687
						if (($localid_type == "none") ||
688
							(($ph1ent['authentication_method'] == "xauth_psk_server") ||
689
							($ph1ent['authentication_method'] == "pre_shared_key"))
690
							&& isset($ph1ent['mobile'])
691
							&& (ipsec_get_number_of_phase2($ikeid)==1))
692
							$localid_spec = " ";
693
						else {
694
							if ($localid_type != "address") {
695
								$localid_type = "subnet";
696
							}
697
							$localid_spec = $localid_type." ".$localid_data." any";
698
						}
699

    
700
						if (!isset($ph2ent['mobile'])) {
701
							$remoteid_type = $ph2ent['remoteid']['type'];
702
							if ($remoteid_type != "address")
703
								$remoteid_type = "subnet";
704

    
705
							$remoteid_data = ipsec_idinfo_to_cidr($ph2ent['remoteid']);
706
							$remoteid_spec = $remoteid_type." ".$remoteid_data." any";
707
						} else
708
							$remoteid_spec = "anonymous";
709

    
710
					} else {
711
						$rgip = $rgmap[$ph1ent['remote-gateway']];
712

    
713
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
714
							($ph1ent['authentication_method'] == "pre_shared_key"))
715
							&& isset($ph1ent['mobile']))
716
							$localid_spec = " ";
717
						else {
718
							$localid_data = ipsec_get_phase1_src($ph1ent);
719
							if($ph2ent['mode'] == 'transport') { $localid_data="$localid_data any"; }
720
							$localid_spec = "address {$localid_data}";
721
						}
722
						if (!isset($ph2ent['mobile'])) {
723
							$remoteid_data = $rgmap[$ph1ent['remote-gateway']];
724
							if($ph2ent['mode'] == 'transport') { $remoteid_data="$remoteid_data any"; }
725
							$remoteid_spec = "address {$remoteid_data}";
726
						} else
727
							$remoteid_spec = "anonymous";
728
					}
729

    
730
					if($ph2ent['protocol'] == 'esp') {
731

    
732
						$ealgos = '';
733

    
734
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
735

    
736
							$ealg_id = $ealg['name'];
737
							$ealg_kl = $ealg['keylen'];
738

    
739
							if ($ealg_kl) {
740
								if( $ealg_kl == "auto" ) {
741
									/*   This seems to be required on my system and was not reproducable
742
									 *   on other systems.   For some reason $p2_ealgos is not defined
743
									 *   and needs to be read back in!?  -sullrich Aug 26, 2009 
744
									 */
745
									if(!$p2_ealgos)
746
										require("ipsec.inc");
747
									$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
748
									$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
749
									$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
750
									/* in some cases where include ordering is suspect these variables
751
									   are somehow 0 and we enter this loop forever and timeout after 900
752
									   seconds wrecking bootup */
753
									if($key_hi != 0 and $key_lo !=0 and $key_step !=0) {
754
										for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
755
//											Uncomment the next line if you want to test the comment 5 lines up.											
756
//											echo "$keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step \n";
757
											if ($ealgos)
758
												$ealgos = $ealgos.", ";
759
											$ealgos = $ealgos.$ealg_id." ".$keylen;
760
										}
761
									}
762
								} else {
763
									if ($ealgos)
764
										$ealgos = $ealgos.", ";
765
									$ealgos = $ealgos.$ealg_id." ".$ealg_kl;
766
								}
767
							} else {
768
								if ($ealgos)
769
									$ealgos = $ealgos.", ";
770
								$ealgos = $ealgos.$ealg_id;
771
							}
772
						}
773

    
774
						$ealgosline = "encryption_algorithm {$ealgos};";
775

    
776
					} else {
777

    
778
						$ealgosline = "encryption_algorithm null_enc;";
779
					}
780

    
781
					$halgos = join(",", $ph2ent['hash-algorithm-option']);
782
					$halgosline = "authentication_algorithm {$halgos};";
783

    
784
					$pfsline = '';
785
					if ($ph2ent['pfsgroup'])
786
						$pfsline = "pfs_group {$ph2ent['pfsgroup']};";
787
					if (isset($a_client['pfs_group'])) {
788
						$pfsline = '';
789
						if ($a_client['pfs_group'])
790
							$pfsline = "pfs_group {$a_client['pfs_group']};";
791
					}
792

    
793
					$lifeline = '';
794
					if ($ph2ent['lifetime'])
795
						$lifeline = "lifetime time {$ph2ent['lifetime']} secs;";
796

    
797
					/* add sainfo section to configuration */
798
					
799
					$racoonconf .=<<<EOD
800
					
801
sainfo {$localid_spec} {$remoteid_spec}
802
{
803
	remoteid {$ikeid};
804
	{$ealgosline}
805
	{$halgosline}
806
	{$pfsline}
807
	{$lifeline}
808
	compression_algorithm deflate;
809
}
810

    
811
EOD;
812
				}
813
				/* end sainfo */
814
			}
815
			/* end sainfo sections */
816

    
817
			fwrite($fd, $racoonconf);
818
			fclose($fd);
819
		}
820
		/* end racoon.conf */
821

    
822
		/* generate IPsec policies */
823
		if (is_array($a_phase2) && count($a_phase2)) {
824
			/* generate spd.conf */
825
			$fd = fopen("{$g['varetc_path']}/spd.conf", "w");
826
			if (!$fd) {
827
				printf(gettext("Error: cannot open spd.conf in vpn_ipsec_configure().") . "\n");
828
				return 1;
829
			}
830

    
831
			$spdconf = "";
832

    
833
			/* Try to prevent people from locking themselves out of webgui. Just in case. */
834
			if ($config['interfaces']['lan']) {
835
				$lanip = get_interface_ip("lan");
836
				if (!empty($lanip) && is_ipaddrv4($lanip)) {
837
					$lansn = get_interface_subnet("lan");
838
					$lansa = gen_subnet($lanip, $lansn);
839
					$spdconf .= "spdadd -4 {$lanip}/32 {$lansa}/{$lansn} any -P out none;\n";
840
					$spdconf .= "spdadd -4 {$lansa}/{$lansn} {$lanip}/32 any -P in none;\n";
841
				}
842
				$lanipv6 = get_interface_ipv6("lan");
843
				if (!empty($lanipv6) && is_ipaddrv6($lanipv6)) {
844
					$lansnv6 = get_interface_subnetv6("lan");
845
					$lansav6 = gen_subnetv6($lanipv6, $lansnv6);
846
					$spdconf .= "spdadd -6 {$lanipv6}/128 {$lansav6}/{$lansnv6} any -P out none;\n";
847
					$spdconf .= "spdadd -6 {$lansav6}/{$lansnv6} {$lanipv6}/128 any -P in none;\n";
848
				}
849
			}
850

    
851
			foreach ($a_phase2 as $ph2ent) {
852

    
853
				if( !ipsec_lookup_phase1($ph2ent,$ph1ent))
854
					continue;
855

    
856
				if (isset($ph1ent['mobile']))
857
					continue;
858

    
859
				if (isset($ph1ent['disabled']))
860
					continue;
861

    
862
				if (isset($ph2ent['disabled']))
863
					continue;
864

    
865
				$ep = ipsec_get_phase1_src($ph1ent);
866
				if (!$ep)
867
					continue;
868

    
869
				$rgip = $rgmap[$ph1ent['remote-gateway']];
870
				if(!is_ipaddr($rgip))
871
					continue;
872

    
873
				$ph2ent['localid']['mode'] = $ph2ent['mode'];
874
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'],true);
875
				$remoteid = ipsec_idinfo_to_cidr($ph2ent['remoteid'],true);
876

    
877
				if(($ph2ent['mode'] == "tunnel") or ($ph2ent['mode'] == 'tunnel6')) {
878
					if($ph2ent['mode'] == "tunnel6")
879
						$family = "-6";
880
					else
881
						$family = "-4";
882

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

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

    
889
				} else {
890

    
891
					$localid_data = ipsec_get_phase1_src($ph1ent);
892
					$remoteid_data = $rgmap[$ph1ent['remote-gateway']];
893

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

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

    
900
				}
901

    
902
				/* static route needed? */
903
				if (preg_match("/^carp|^vip/i", $ph1ent['interface']))
904
					$parentinterface = link_carp_interface_to_parent($ph1ent['interface']);
905
				else
906
					$parentinterface = $ph1ent['interface'];
907

    
908
				if (($parentinterface <> "wan") && (is_ipaddr($rgip))) {
909
					/* add endpoint routes to correct gateway on interface */
910
					if (interface_has_gateway($parentinterface)) {
911
						$gatewayip = get_interface_gateway("$parentinterface");
912
						$interfaceip = get_interface_ip($parentinterface);
913
						$subnet_bits = get_interface_subnet($parentinterface);
914
						$subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
915
						/* if the remote gateway is in the local subnet, then don't add a route */
916
						if (! ip_in_subnet($rgip, "{$subnet_ip}/{$subnet_bits}")) {
917
							if(is_ipaddr($gatewayip)) {
918
								/* FIXME: does adding route-to and reply-to on the in/outbound
919
								 * rules fix this? smos@ 13-01-2009 */
920
								// log_error("IPSEC interface is not WAN but {$parentinterface}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
921
								mwexec("/sbin/route delete -host {$rgip}; /sbin/route add -host {$rgip} {$gatewayip}", true);
922
							}
923
						}
924
					}
925
				} elseif(is_ipaddr($rgip)) {
926
					if(stristr($route_str, "{$rgip}")) {
927
						mwexec("/sbin/route delete -host {$rgip}", true);
928
					}
929
				}
930
			}
931

    
932
			fwrite($fd, $spdconf);
933
			fclose($fd);
934
		}
935

    
936
		/* needed for racoonctl admin socket */
937
		if (!is_dir("/var/db/racoon"))
938
			mkdir("/var/db/racoon/");
939
		
940
		/* mange racoon process */
941
		if (is_process_running("racoon")) {
942
			sleep("0.1");
943
			mwexec("/usr/local/sbin/racoonctl -s /var/db/racoon/racoon.sock reload-config", false);
944
			/* load SPD without flushing to be safe on config additions or changes. */
945
			mwexec("/usr/local/sbin/setkey -f {$g['varetc_path']}/spd.conf", false);
946
		} else {
947
			/* flush SA + SPD entries */
948
			mwexec("/usr/local/sbin/setkey -FP", false);
949
 			sleep("0.1");
950
			mwexec("/usr/local/sbin/setkey -F", false);
951
 			sleep("0.1");
952
 			/* start racoon */
953
			$ipsecdebug = isset($config['ipsec']['racoondebug']) ? "-d -v" : "";
954
			mwexec("/usr/local/sbin/racoon {$ipsecdebug} -f {$g['varetc_path']}/racoon.conf", false);
955
 			sleep("0.1");
956
 			/* load SPD */
957
			mwexec("/usr/local/sbin/setkey -f {$g['varetc_path']}/spd.conf", false);
958

    
959
		}
960
		/* start filterdns, if necessary */
961
		if (count($filterdns_list) > 0) {
962
			$interval = 60;
963
			if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
964
				$interval = $ipseccfg['dns-interval'];
965

    
966
			$hostnames = "";
967
			array_unique($filterdns_list);
968
			foreach ($filterdns_list as $hostname)
969
				$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
970
			file_put_contents("{$g['varetc_path']}/filterdns-ipsec.hosts", $hostnames);
971

    
972
			killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
973
			sleep(1);
974
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/filterdns-ipsec.hosts -d 1");
975
		}
976
	
977
		vpn_ipsec_failover_configure();
978

    
979
		if ($g['booting'])
980
			echo "done\n";
981
	}
982

    
983
	return 0;
984
}
985

    
986
/* Forcefully restart IPsec
987
 * This is required for when dynamic interfaces reload
988
 * For all other occasions the normal vpn_ipsec_configure()
989
 * will gracefully reload the settings without restarting
990
 */
991
function vpn_ipsec_force_reload() {
992
	global $config;
993
	global $g;
994

    
995
	$ipseccfg = $config['ipsec'];
996

    
997
	/* kill racoon */
998
	if(is_process_running("racoon"))
999
		mwexec("/usr/bin/killall racoon", true);
1000

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

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

    
1007
	/* wait for flushing to finish */
1008
	sleep(1);
1009

    
1010
	/* if ipsec is enabled, start up again */
1011
	if (isset($ipseccfg['enable'])) {
1012
		log_error(gettext("Forcefully reloading IPsec racoon daemon"));
1013
		vpn_ipsec_configure();
1014
	}
1015

    
1016
}
1017

    
1018
/* master setup for vpn (mpd) */
1019
function vpn_setup() {
1020
	/* start pptpd */
1021
	vpn_pptpd_configure();
1022

    
1023
	/* start pppoe server */
1024
	vpn_pppoes_configure();
1025

    
1026
	/* setup l2tp */
1027
	vpn_l2tp_configure();
1028
}
1029

    
1030
function vpn_netgraph_support() {
1031
	$iflist = get_configured_interface_list();
1032
	foreach ($iflist as $iface) {
1033
		$realif = get_real_interface($iface);
1034
		/* Get support for netgraph(4) from the nic */
1035
		$ifinfo = pfSense_get_interface_addresses($realif);
1036
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
1037
                	pfSense_ngctl_attach(".", $realif);
1038
	}
1039
}
1040

    
1041
function vpn_pptpd_configure() {
1042
	global $config, $g;
1043

    
1044
	$syscfg = $config['system'];
1045
	$pptpdcfg = $config['pptpd'];
1046

    
1047
	if ($g['booting']) {
1048
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
1049
			return 0;
1050

    
1051
		echo gettext("Configuring PPTP VPN service... ");
1052
	} else {
1053
		/* kill mpd */
1054
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1055

    
1056
		/* wait for process to die */
1057
		sleep(3);
1058

    
1059
		if (is_process_running("mpd -b")) {
1060
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1061
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
1062
		}
1063

    
1064
		/* remove mpd.conf, if it exists */
1065
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
1066
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
1067
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
1068
	}
1069

    
1070
	/* make sure pptp-vpn directory exists */
1071
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
1072
		mkdir("{$g['varetc_path']}/pptp-vpn");
1073

    
1074
	switch ($pptpdcfg['mode']) {
1075
		case 'server' :
1076
			/* write mpd.conf */
1077
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1078
			if (!$fd) {
1079
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
1080
				return 1;
1081
			}
1082

    
1083
			$mpdconf = <<<EOD
1084
pptps:
1085

    
1086
EOD;
1087

    
1088
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1089
				$mpdconf .= "	load pt{$i}\n";
1090
			}
1091

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

    
1094
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1095

    
1096
				$mpdconf .= <<<EOD
1097

    
1098
pt{$i}:
1099
	new -i pptpd{$i} pt{$i} pt{$i}
1100
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1101
	load pts
1102

    
1103
EOD;
1104
			}
1105

    
1106
			$mpdconf .=<<<EOD
1107

    
1108
pts:
1109
	set iface disable on-demand
1110
	set iface enable proxy-arp
1111
	set iface enable tcpmssfix
1112
	set iface idle 1800
1113
	set iface up-script /usr/local/sbin/vpn-linkup
1114
	set iface down-script /usr/local/sbin/vpn-linkdown
1115
	set bundle enable multilink
1116
	set bundle enable crypt-reqd
1117
	set link yes acfcomp protocomp
1118
	set link no pap chap
1119
	set link enable chap-msv2
1120
	set link mtu 1460
1121
	set link keep-alive 10 60
1122
	set ipcp yes vjcomp
1123
	set bundle enable compression
1124
	set ccp yes mppc
1125
	set ccp yes mpp-e128
1126
	set ccp yes mpp-stateless
1127

    
1128
EOD;
1129

    
1130
			if (!isset ($pptpdcfg['req128'])) {
1131
				$mpdconf .=<<<EOD
1132
	set ccp yes mpp-e40
1133
	set ccp yes mpp-e56
1134

    
1135
EOD;
1136
			}
1137

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

    
1141
			if (!empty($pptpdcfg['dns1'])) {
1142
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1143
				if (!empty($pptpdcfg['dns2']))
1144
					$mpdconf .= " " . $pptpdcfg['dns2'];
1145
				$mpdconf .= "\n";
1146
			} elseif (isset ($config['dnsmasq']['enable'])) {
1147
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1148
				if ($syscfg['dnsserver'][0])
1149
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1150
				$mpdconf .= "\n";
1151
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1152
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1153
			}
1154

    
1155
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1156
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1157
				$acctport = $authport + 1;
1158
				$mpdconf .=<<<EOD
1159
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1160

    
1161
EOD;
1162
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1163
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1164
				$acctport = $authport + 1;
1165
				$mpdconf .=<<<EOD
1166
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret']}" {$authport} {$acctport}
1167

    
1168
EOD;
1169
			}
1170
			$mpdconf .=<<<EOD
1171
	set radius retries 3
1172
	set radius timeout 10
1173
	set auth enable radius-auth
1174

    
1175
EOD;
1176

    
1177
				if (isset ($pptpdcfg['radius']['accounting'])) {
1178
					$mpdconf .=<<<EOD
1179
	set auth enable radius-acct
1180
	set radius acct-update 300
1181

    
1182
EOD;
1183
				}
1184
			}
1185

    
1186
			fwrite($fd, $mpdconf);
1187
			fclose($fd);
1188

    
1189
			/* write mpd.links */
1190
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1191
			if (!$fd) {
1192
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1193
				return 1;
1194
			}
1195

    
1196
			$mpdlinks = "";
1197

    
1198
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1199
				$mpdlinks .=<<<EOD
1200

    
1201
pt{$i}:
1202
	set link type pptp
1203
	set pptp enable incoming
1204
	set pptp disable originate
1205
	set pptp disable windowing
1206

    
1207
EOD;
1208
			}
1209

    
1210
			fwrite($fd, $mpdlinks);
1211
			fclose($fd);
1212

    
1213
			/* write mpd.secret */
1214
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1215
			if (!$fd) {
1216
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1217
				return 1;
1218
			}
1219

    
1220
			$mpdsecret = "";
1221

    
1222
			if (is_array($pptpdcfg['user'])) {
1223
				foreach ($pptpdcfg['user'] as $user)
1224
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1225
			}
1226

    
1227
			fwrite($fd, $mpdsecret);
1228
			fclose($fd);
1229
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1230

    
1231
			vpn_netgraph_support();
1232

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

    
1236
			break;
1237

    
1238
		case 'redir' :
1239
			break;
1240
	}
1241

    
1242
	if ($g['booting'])
1243
		echo "done\n";
1244

    
1245
	return 0;
1246
}
1247

    
1248
function vpn_pppoes_configure() {
1249
	global $config;
1250

    
1251
	if (is_array($config['pppoes']['pppoe'])) {
1252
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1253
			vpn_pppoe_configure($pppoe);
1254
	}
1255
}
1256

    
1257
function vpn_pppoe_configure(&$pppoecfg) {
1258
	global $config, $g;
1259

    
1260
	$syscfg = $config['system'];
1261

    
1262
	/* create directory if it does not exist */
1263
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1264
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1265

    
1266
	if ($g['booting']) {
1267
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1268
			return 0;
1269

    
1270
		echo gettext("Configuring PPPoE VPN service... ");
1271
	} else {
1272
		/* kill mpd */
1273
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1274

    
1275
		/* wait for process to die */
1276
		sleep(2);
1277

    
1278
	}
1279

    
1280
	switch ($pppoecfg['mode']) {
1281

    
1282
		case 'server' :
1283

    
1284
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1285

    
1286
			if ($pppoecfg['paporchap'] == "chap")
1287
				$paporchap = "set link enable chap";
1288
			else
1289
				$paporchap = "set link enable pap";
1290

    
1291
			/* write mpd.conf */
1292
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1293
			if (!$fd) {
1294
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1295
				return 1;
1296
			}
1297
			$mpdconf = "\n\n";
1298
			$mpdconf .= "poes:\n";
1299

    
1300
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1301
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1302
			}
1303

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

    
1306
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1307

    
1308
				if (isset ($pppoecfg['radius']['radiusissueips']) && isset ($pppoecfg['radius']['server']['enable'])) {
1309
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1310
				} else {
1311
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1312
				}
1313

    
1314
				$mpdconf .=<<<EOD
1315

    
1316
poes{$pppoecfg['pppoeid']}{$i}:
1317
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1318
	{$isssue_ip_type}
1319
	load pppoe_standard
1320

    
1321
EOD;
1322
			}
1323

    
1324
			$mpdconf .=<<<EOD
1325

    
1326
pppoe_standard:
1327
	set bundle no multilink
1328
	set bundle enable compression
1329
	set auth max-logins 1
1330
	set iface up-script /usr/local/sbin/vpn-linkup
1331
	set iface down-script /usr/local/sbin/vpn-linkdown
1332
	set iface idle 0
1333
	set iface disable on-demand
1334
	set iface disable proxy-arp
1335
	set iface enable tcpmssfix
1336
	set iface mtu 1500
1337
	set link no pap chap
1338
	{$paporchap}
1339
	set link keep-alive 60 180
1340
	set ipcp yes vjcomp
1341
	set ipcp no vjcomp
1342
	set link max-redial -1
1343
	set link mtu 1492
1344
	set link mru 1492
1345
	set ccp yes mpp-e40
1346
	set ccp yes mpp-e128
1347
	set ccp yes mpp-stateless
1348
	set link latency 1
1349
	#set ipcp dns 10.10.1.3
1350
	#set bundle accept encryption
1351

    
1352
EOD;
1353

    
1354
			if (!empty($pppoecfg['dns1'])) {
1355
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1356
				if (!empty($pppoecfg['dns2']))
1357
					$mpdconf .= " " . $pppoecfg['dns2'];
1358
				$mpdconf .= "\n";
1359
			} elseif (isset ($config['dnsmasq']['enable'])) {
1360
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1361
				if ($syscfg['dnsserver'][0])
1362
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1363
				$mpdconf .= "\n";
1364
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1365
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1366
			}
1367

    
1368
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1369
				$radiusport = "";
1370
				$radiusacctport = "";
1371
				if (isset($pppoecfg['radius']['server']['port']))
1372
					$radiusport = $pppoecfg['radius']['server']['port'];
1373
				if (isset($pppoecfg['radius']['server']['acctport']))
1374
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1375
				$mpdconf .=<<<EOD
1376
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']} {$radiusport} {$radiusacctport}" 
1377
	set radius retries 3
1378
	set radius timeout 10
1379
	set auth enable radius-auth
1380

    
1381
EOD;
1382

    
1383
				if (isset ($pppoecfg['radius']['accounting'])) {
1384
					$mpdconf .=<<<EOD
1385
	set auth enable radius-acct
1386

    
1387
EOD;
1388
				}
1389
			}
1390

    
1391
			fwrite($fd, $mpdconf);
1392
			fclose($fd);
1393

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

    
1401
			$mpdlinks = "";
1402

    
1403
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1404
				$mpdlinks .=<<<EOD
1405
			
1406
poes{$pppoecfg['pppoeid']}{$i}:
1407
	set phys type pppoe
1408
        set pppoe iface {$pppoe_interface}
1409
        set pppoe service "*"
1410
        set pppoe disable originate
1411
        set pppoe enable incoming
1412

    
1413
EOD;
1414
			}
1415

    
1416
			fwrite($fd, $mpdlinks);
1417
			fclose($fd);
1418

    
1419
			if ($pppoecfg['username']) {
1420
				/* write mpd.secret */
1421
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1422
				if (!$fd) {
1423
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1424
					return 1;
1425
				}
1426

    
1427
				$mpdsecret = "\n\n";
1428

    
1429
				if (!empty($pppoecfg['username'])) {
1430
					$item = explode(" ", $pppoecfg['username']);
1431
					foreach($item as $userdata) {
1432
						$data = explode(":", $userdata);
1433
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1434
					}
1435
				}
1436

    
1437
				fwrite($fd, $mpdsecret);
1438
				fclose($fd);
1439
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1440
			}
1441

    
1442
			/* Get support for netgraph(4) from the nic */
1443
			pfSense_ngctl_attach(".", $pppoe_interface);
1444
			/* fire up mpd */
1445
			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");
1446

    
1447
			break;
1448
	}
1449

    
1450
	if ($g['booting'])
1451
		echo gettext("done") . "\n";
1452

    
1453
	return 0;
1454
}
1455

    
1456
function vpn_l2tp_configure() {
1457
	global $config, $g;
1458

    
1459
	$syscfg = $config['system'];
1460
	$l2tpcfg = $config['l2tp'];
1461

    
1462
	/* create directory if it does not exist */
1463
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1464
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1465

    
1466
	if ($g['booting']) {
1467
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1468
			return 0;
1469

    
1470
		echo gettext("Configuring l2tp VPN service... ");
1471
	} else {
1472
		/* kill mpd */
1473
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1474

    
1475
		/* wait for process to die */
1476
		sleep(8);
1477

    
1478
	}
1479

    
1480
	/* make sure l2tp-vpn directory exists */
1481
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1482
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1483

    
1484
	switch ($l2tpcfg['mode']) {
1485

    
1486
		case 'server' :
1487
			if ($l2tpcfg['paporchap'] == "chap")
1488
				$paporchap = "set link enable chap";
1489
			else
1490
				$paporchap = "set link enable pap";
1491

    
1492
			/* write mpd.conf */
1493
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1494
			if (!$fd) {
1495
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1496
				return 1;
1497
			}
1498
			$mpdconf = "\n\n";
1499
			$mpdconf .=<<<EOD
1500
l2tps:
1501

    
1502
EOD;
1503

    
1504
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1505
				$mpdconf .= "	load l2tp{$i}\n";
1506
			}
1507

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

    
1510
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1511

    
1512
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1513
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1514
				} else {
1515
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1516
				}
1517

    
1518
				$mpdconf .=<<<EOD
1519

    
1520
l2tp{$i}:
1521
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1522
	{$isssue_ip_type}
1523
	load l2tp_standard
1524

    
1525
EOD;
1526
			}
1527

    
1528
			$mpdconf .=<<<EOD
1529

    
1530
l2tp_standard:
1531
        set bundle disable multilink
1532
        set bundle enable compression
1533
        set bundle yes crypt-reqd
1534
        set ipcp yes vjcomp
1535
        # set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1536
        set ccp yes mppc
1537
        set iface disable on-demand
1538
        set iface enable proxy-arp
1539
	set iface up-script /usr/local/sbin/vpn-linkup
1540
	set iface down-script /usr/local/sbin/vpn-linkdown
1541
        set link yes acfcomp protocomp
1542
        set link no pap chap
1543
        set link enable chap
1544
        set link keep-alive 10 180
1545

    
1546
EOD;
1547

    
1548
			if (is_ipaddr($l2tpcfg['wins'])) {
1549
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1550
			}
1551
			if (is_ipaddr($l2tpcfg['dns1'])) {
1552
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1553
				if (is_ipaddr($l2tpcfg['dns2']))
1554
					$mpdconf .= " " . $l2tpcfg['dns2'];
1555
				$mpdconf .= "\n";
1556
			} elseif (isset ($config['dnsmasq']['enable'])) {
1557
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1558
				if ($syscfg['dnsserver'][0])
1559
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1560
				$mpdconf .= "\n";
1561
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1562
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1563
			}
1564

    
1565
			if (isset ($l2tpcfg['radius']['enable'])) {
1566
				$mpdconf .=<<<EOD
1567
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1568
	set radius retries 3
1569
	set radius timeout 10
1570
	set auth enable radius-auth
1571

    
1572
EOD;
1573

    
1574
				if (isset ($l2tpcfg['radius']['accounting'])) {
1575
					$mpdconf .=<<<EOD
1576
	set auth enable radius-acct
1577

    
1578
EOD;
1579
				}
1580
			}
1581

    
1582
			fwrite($fd, $mpdconf);
1583
			fclose($fd);
1584

    
1585
			/* write mpd.links */
1586
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1587
			if (!$fd) {
1588
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1589
				return 1;
1590
			}
1591

    
1592
			$mpdlinks = "";
1593

    
1594
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1595
				$mpdlinks .=<<<EOD
1596

    
1597
l2tp{$i}:
1598
	set link type l2tp
1599
        set l2tp enable incoming
1600
        set l2tp disable originate
1601

    
1602
EOD;
1603
			if (!empty($l2tpcfg['secret']))
1604
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1605
			}
1606

    
1607
			fwrite($fd, $mpdlinks);
1608
			fclose($fd);
1609

    
1610
			/* write mpd.secret */
1611
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1612
			if (!$fd) {
1613
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1614
				return 1;
1615
			}
1616

    
1617
			$mpdsecret = "\n\n";
1618

    
1619
			if (is_array($l2tpcfg['user'])) {
1620
				foreach ($l2tpcfg['user'] as $user)
1621
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1622
			}
1623

    
1624
			fwrite($fd, $mpdsecret);
1625
			fclose($fd);
1626
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1627

    
1628
			vpn_netgraph_support();
1629

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

    
1633
			break;
1634

    
1635
		case 'redir' :
1636
			break;
1637
	}
1638

    
1639
	if ($g['booting'])
1640
		echo "done\n";
1641

    
1642
	return 0;
1643
}
1644

    
1645
/* Walk the tunnels for hostname endpoints. If the hostnames 
1646
 * resolve to a different IP now compared to the DNS cache
1647
 * we reload the policies if the endpoint has changed */
1648
function vpn_ipsec_refresh_policies() {
1649
	global $config;
1650
	global $g;
1651

    
1652
	$ipseccfg = $config['ipsec'];
1653
	$a_phase1 = $config['ipsec']['phase1'];
1654
	$a_phase2 = $config['ipsec']['phase2'];
1655

    
1656
	if (isset($ipseccfg['disable'])) {
1657
		return true;
1658
	}
1659

    
1660
	/* Walk the Ipsec tunnel array */
1661
	if (!is_array($a_phase1) || (!count($a_phase1))) {
1662
		return;
1663
	}
1664

    
1665
	foreach ($a_phase1 as $phase1) {
1666
		if (isset($phase1['disabled'])) {
1667
			continue;
1668
		}
1669
		if (is_ipaddr($phase1['remote-gateway'])) {
1670
			continue;
1671
		}
1672
		if (!is_ipaddr($phase1['remote-gateway'])) {
1673
			$dnscache = compare_hostname_to_dnscache($phase1['remote-gateway']);
1674
			$dnscache = trim($dnscache);
1675
			/* we should have the old IP addresses in the dnscache now */
1676
			if($dnscache <> "") {
1677
				$oldphase1 = $phase1;
1678
				$oldphase1['remote-gateway'] = trim($dnscache);
1679
				/* now we need to find all tunnels for this host */
1680
				if (!is_array($a_phase2) || (!count($a_phase2))) {
1681
					continue;
1682
				}
1683
				foreach ($a_phase2 as $phase2) {
1684
					if($phase2['ikeid'] == $phase1['ikeid']) {
1685
						reload_tunnel_spd_policy ($phase1, $phase2, $oldphase1, $oldphase2);
1686
					}
1687
				}
1688
			}
1689
		}
1690
	}
1691

    
1692
	/* process all generated spd.conf files from tmp which are left behind
1693
	 * behind by either changes of dynamic tunnels or manual edits
1694
	 * scandir() is only available in PHP5 */
1695
	$tmpfiles = array();
1696
	$dh  = opendir($g['tmp_path']);
1697
	while (false !== ($filename = readdir($dh))) {
1698
		if(preg_match("/^spd.conf.reload./", $filename)) {
1699
			$tmpfiles[] = $filename;
1700
		}
1701
	}
1702
	sort($tmpfiles);
1703
	foreach($tmpfiles as $tmpfile) {
1704
		$ret = mwexec("/usr/local/sbin/setkey -f {$g['tmp_path']}/{$tmpfile} 2>&1", false);
1705
		if($ret == 0) {
1706
			unlink_if_exists("{$g['tmp_path']}/{$tmpfile}");
1707
		} else {
1708
			rename("{$g['tmp_path']}/{$tmpfile}", ("{$g['tmp_path']}/failed.{$tmpfile}"));
1709
		}
1710
	}
1711
}
1712

    
1713
/* reloads the tunnel configuration for a tunnel item
1714
 * Will remove and add SPD polices */
1715
function reload_tunnel_spd_policy($phase1, $phase2, $old_phase1, $old_phase2) {
1716
	global $config;
1717
	global $g;
1718

    
1719
	/* if we are not passed a old tunnel array we create one */
1720
	if(empty($old_phase1)) {
1721
		$old_phase1 = $phase1;
1722
	}
1723
	if(empty($old_phase2)) {
1724
		$old_phase2 = $phase2;
1725
	}
1726

    
1727
	$sad_arr = ipsec_dump_sad();
1728

    
1729
	$ep = ipsec_get_phase1_src($phase1);
1730
	$phase2['localid']['mode'] = $phase2['mode'];
1731
	$local_subnet = ipsec_idinfo_to_cidr($phase2['localid']);
1732
	$remote_subnet = ipsec_idinfo_to_cidr($phase2['remoteid']);
1733

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

    
1737
	$old_ep = ipsec_get_phase1_src($old_phase1);
1738
	$old_phase2['localid']['mode'] = $old_phase2['mode'];
1739
	$old_local_subnet = ipsec_idinfo_to_cidr($old_phase2['localid']);
1740
	$old_remote_subnet = ipsec_idinfo_to_cidr($old_phase2['remoteid']);
1741

    
1742
	/* see if this tunnel has a hostname for the remote-gateway, and if so,
1743
	 * try to resolve it now and add it to the list for filterdns */
1744
	$rgip = "";
1745
	if (!is_ipaddr($phase1['remote-gateway'])) {
1746
		if(! $g['booting']) {
1747
			$rgip = resolve_retry($phase1['remote-gateway']);
1748
			add_hostname_to_watch($phase1['remote-gateway']);
1749
		} else {
1750
			add_hostname_to_watch($phase1['remote-gateway']);
1751
		}
1752
		if (!is_ipaddr($rgip)) {
1753
			log_error("Could not determine VPN endpoint for '{$phase1['descr']}'");
1754
			return false;
1755
		}
1756
	} else {
1757
		$rgip = $phase1['remote-gateway'];
1758
	}
1759
	if (!$ep) {
1760
		log_error(sprintf(gettext("Could not determine VPN endpoint for '%s'"), $phase1['descr']));
1761
		return false;
1762
	}
1763

    
1764
	if((!is_ipaddr($old_ep)) || (! is_ipaddr($ep))) {
1765
		log_error(sprintf(gettext("IPSEC: ERROR: One of the endpoints is not a IP address. Old EP '%1\$s' new EP '%2\$s'"), $old_ep, $ep));
1766
	}
1767
	if((! is_ipaddr($rgip)) || (! is_ipaddr($old_gw))) {
1768
		log_error(sprintf(gettext("IPSEC: ERROR: One of the remote endpoints is not a IP address. Old RG '%1\$s' new RG '%2\$s'"), $old_gw, $rgip));
1769
	}
1770

    
1771
	$spdconf = "";
1772
	/* Delete old SPD policies if there are changes between the old and new */
1773
	if(($phase1 != $old_phase1) || ($phase2 != $old_phase2)) {
1774
		if($old_phase2['mode'] == "tunnel6")
1775
			$family = "-6";
1776
		else
1777
			$family = "-4";
1778

    
1779
		$spdconf .= "spddelete {$family} {$old_local_subnet} " .
1780
			"{$old_remote_subnet} any -P out ipsec " .
1781
			"{$old_phase2['protocol']}/tunnel/{$old_ep}-" .
1782
			"{$old_gw}/unique;\n";
1783
		$spdconf .= "spddelete {$family} {$old_remote_subnet} " .
1784
			"{$old_local_subnet} any -P in ipsec " .
1785
			"{$old_phase2['protocol']}/tunnel/{$old_gw}-" .
1786
			"{$old_ep}/unique;\n";
1787

    
1788
		/* zap any existing SA entries */
1789
		foreach($sad_arr as $sad) {
1790
			if(($sad['dst'] == $old_ep) && ($sad['src'] == $old_gw)) {
1791
				$spdconf .= "delete {$family} {$old_ep} {$old_gw} {$old_phase2['protocol']} 0x{$sad['spi']};\n";
1792
			}
1793
			if(($sad['src'] == $oldep) && ($sad['dst'] == $old_gw)) {
1794
				$spdconf .= "delete {$family} {$old_gw} {$old_ep} {$old_phase2['protocol']} 0x{$sad['spi']};\n";
1795
			}
1796
		}
1797
	}
1798

    
1799
	if($phase2['mode'] == "tunnel6")
1800
		$family = "-6";
1801
	else
1802
		$family = "-4";
1803

    
1804
	/* Create new SPD entries for the new configuration */
1805
	/* zap any existing SA entries beforehand */
1806
	foreach($sad_arr as $sad) {
1807
		if(($sad['dst'] == $ep) && ($sad['src'] == $rgip)) {
1808
			$spdconf .= "delete {$family} {$rgip} {$ep} {$phase2['protocol']} 0x{$sad['spi']};\n";
1809
		}
1810
		if(($sad['src'] == $ep) && ($sad['dst'] == $rgip)) {
1811
			$spdconf .= "delete {$family} {$ep} {$rgip} {$phase2['protocol']} 0x{$sad['spi']};\n";
1812
		}
1813
	}
1814
	/* add new SPD policies to replace them */
1815
	$spdconf .= "spdadd {$family} {$local_subnet} " .
1816
		"{$remote_subnet} any -P out ipsec " .
1817
		"{$phase2['protocol']}/tunnel/{$ep}-" .
1818
		"{$rgip}/unique;\n";
1819
	$spdconf .= "spdadd {$family} {$remote_subnet} " .
1820
		"{$local_subnet} any -P in ipsec " .
1821
		"{$phase2['protocol']}/tunnel/{$rgip}-" .
1822
		"{$ep}/unique;\n";
1823

    
1824
	log_error(sprintf(gettext("Reloading IPsec tunnel '%1\$s'. Previous IP '%2\$s', current IP '%3\$s'. Reloading policy"), $phase1['descr'], $old_gw, $rgip));
1825

    
1826
	$now = time();
1827
	$spdfile = tempnam("{$g['tmp_path']}", "spd.conf.reload.{$now}.");
1828
	/* generate temporary spd.conf */
1829
	file_put_contents($spdfile, $spdconf);
1830
	return true;
1831
}
1832

    
1833
function vpn_ipsec_configure_preferoldsa() {
1834
	global $config;
1835
	if(isset($config['ipsec']['preferoldsa']))
1836
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
1837
	else
1838
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
1839
}
1840

    
1841
?>
(52-52/61)