Project

General

Profile

Download (52.4 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2

    
3
/*
4
	vpn.inc
5
	Copyright (C) 2004 Scott Ullrich
6
	Copyright (C) 2008 Shrew Soft Inc
7
	Copyright (C) 2008 Ermal Lu?i
8
	All rights reserved.
9

    
10
	originally part of m0n0wall (http://m0n0.ch/wall)
11
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
12
	All rights reserved.
13

    
14
	Redistribution and use in source and binary forms, with or without
15
	modification, are permitted provided that the following conditions are met:
16

    
17
	1. Redistributions of source code must retain the above copyright notice,
18
	   this list of conditions and the following disclaimer.
19

    
20
	2. Redistributions in binary form must reproduce the above copyright
21
	   notice, this list of conditions and the following disclaimer in the
22
	   documentation and/or other materials provided with the distribution.
23

    
24
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
25
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
26
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
28
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33
	POSSIBILITY OF SUCH DAMAGE.
34
*/
35

    
36
/*
37
	pfSense_BUILDER_BINARIES:	/usr/bin/killall	/usr/local/sbin/sasyncd	/sbin/ifconfig	/sbin/sysctl
38
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/setkey	/sbin/route	/bin/mkdir
39
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/racoonctl	/usr/local/sbin/racoon
40
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/filterdns	/usr/local/sbin/mpd4	
41
	pfSense_MODULE:	vpn
42
*/
43

    
44
/* include all configuration functions */
45

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

    
49

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

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

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

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

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

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

    
91
	vpn_ipsec_configure_preferoldsa();
92

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

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

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

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

    
110
		/* wait for racoon process to die */
111
		sleep(2);
112

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

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

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

    
125
		if ($g['booting'])
126
			echo gettext("Configuring IPsec VPN... ");
127

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

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

    
137
			$ipsecpinghosts = "";
138
			/* step through each phase1 entry */
139
			$ipsecpinghosts = "";
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
				foreach ($a_phase2 as $ph2ent) {
175

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

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

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

    
184
					$ph2ent['localid']['mode'] = $ph2ent['mode'];
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($ph2ent['pinghost'])) {
190
								$interface_ip = get_interface_ipv6($ifent);
191
								if(!is_ipaddrv6($interface_ip))
192
									continue;
193
								$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true);
194
								if (ip_in_subnet($interface_ip, $local_subnet)) {
195
									$srcip = $interface_ip;
196
									break;
197
								}
198
							} else {
199
								$interface_ip = get_interface_ip($ifent);
200
								if(!is_ipaddrv4($interface_ip))
201
									continue;
202
								$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true);
203
								if (ip_in_subnet($interface_ip, $local_subnet)) {
204
									$srcip = $interface_ip;
205
									break;
206
								}
207
							}
208
						}
209
						$dstip = $ph2ent['pinghost'];
210
						if(is_ipaddrv6($dstip)) {
211
							$family = "inet6";
212
						} else {
213
							$family = "inet";
214
						}
215
						if (is_ipaddr($srcip))
216
							$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
217

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

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

    
253
		$pskconf = "";
254

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
335
				$racoonconf .= "\nmode_cfg\n";
336
				$racoonconf .= "{\n";
337

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

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

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

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

    
355
				if (isset($a_client['net_list'])) {
356

    
357
					$net_list = '';
358

    
359
					foreach ($a_phase2 as $ph2ent) {
360

    
361
						if (isset($ph2ent['disabled']))
362
							continue;
363

    
364
						if (!isset($ph2ent['mobile']))
365
							continue;
366

    
367
						$localid = ipsec_idinfo_to_cidr($ph2ent['localid'],true);
368

    
369
						if ($net_list)
370
							$net_list .= ", ";
371
						$net_list .= $localid;
372
					}
373

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

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

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

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

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

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

    
408
					fwrite($fd1, $a_client['login_banner']);
409
					fclose($fd1);
410

    
411
					$racoonconf .= "\tbanner \"{$fn}\";\n";
412
				}
413

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

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

    
428
					/* begin ldapcfg */                        
429
					$racoonconf .= "ldapcfg {\n";
430
					$racoonconf .= "\tversion 3;\n";
431
					$racoonconf .= "\thost \"".$thisauthcfg['host']."\";\n";
432
					$lport = "389";
433
					if ($authcfg['port'] != "")
434
						$lport = $authcfg['port'];
435
					$racoonconf .= "\tport ".$lport.";\n";
436
					$racoonconf .= "\tbase \"".$thisauthcfg['ldap_basedn']."\";\n";
437
					$racoonconf .= "\tsubtree on;\n";
438
					$racoonconf .= "\tbind_dn \"".$thisauthcfg['ldap_binddn']."\";\n";
439
					$racoonconf .= "\tbind_pw \"".$thisauthcfg['ldap_bindpw']."\";\n";
440
					$racoonconf .= "\tattr_user \"".$thisauthcfg['ldap_attr_user']."\";\n";
441
					$racoonconf .= "}\n\n";
442
					/* end ldapcfg */
443
				}
444
			}
445

    
446
			/* begin remote sections */
447
			if (is_array($a_phase1) && count($a_phase1)) {
448
				/* begin remote */
449
				foreach ($a_phase1 as $ph1ent) {
450

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

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

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

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

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

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

    
471
					switch ($myid_type) {
472

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

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

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

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

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

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

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

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

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

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

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

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

    
552
					$certline = '';
553

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

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

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

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

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

    
573
						chmod($certpath, 0600);
574

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

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

    
584
						chmod($keypath, 0600);
585

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

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

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

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

    
603
					}
604

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

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

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

    
622
					/* add remote section to configuration */
623

    
624
					$racoonconf .=<<<EOD
625

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
731
						$ealgos = '';
732

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

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

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

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

    
775
					} else {
776

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

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

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

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

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

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

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

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

    
830
			$spdconf = "";
831

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

    
850
			foreach ($a_phase2 as $ph2ent) {
851

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

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

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

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

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

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

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

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

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

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

    
888
				} else {
889

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

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

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

    
899
				}
900

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

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

    
928
			fwrite($fd, $spdconf);
929
			fclose($fd);
930
		}
931

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

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

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

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

    
975
		if ($g['booting'])
976
			echo "done\n";
977
	}
978

    
979
	return 0;
980
}
981

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

    
991
	$ipseccfg = $config['ipsec'];
992

    
993
	/* kill racoon */
994
	if(is_process_running("racoon"))
995
		mwexec("/usr/bin/killall racoon", true);
996

    
997
	/* wait for process to die */
998
	sleep(4);
999

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

    
1003
	/* wait for flushing to finish */
1004
	sleep(1);
1005

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

    
1012
}
1013

    
1014
/* master setup for vpn (mpd) */
1015
function vpn_setup() {
1016
	global $g;
1017

    
1018
	if ($g['platform'] == 'jail')
1019
		return;
1020

    
1021
	/* start pptpd */
1022
	vpn_pptpd_configure();
1023

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

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

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

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

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

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

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

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

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

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

    
1071
	if (empty($pptpdcfg['n_pptp_units'])) {
1072
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
1073
		return; 
1074
	}
1075

    
1076
	/* make sure pptp-vpn directory exists */
1077
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
1078
		mkdir("{$g['varetc_path']}/pptp-vpn");
1079

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

    
1089
			$mpdconf = <<<EOD
1090
pptps:
1091

    
1092
EOD;
1093

    
1094
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1095
				$mpdconf .= "	load pt{$i}\n";
1096
			}
1097

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

    
1100
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1101

    
1102
				$mpdconf .= <<<EOD
1103

    
1104
pt{$i}:
1105
	new -i pptpd{$i} pt{$i} pt{$i}
1106
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1107
	load pts
1108

    
1109
EOD;
1110
			}
1111

    
1112
			$mpdconf .=<<<EOD
1113

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

    
1134
EOD;
1135

    
1136
			if (!isset ($pptpdcfg['req128'])) {
1137
				$mpdconf .=<<<EOD
1138
	set ccp yes mpp-e40
1139
	set ccp yes mpp-e56
1140

    
1141
EOD;
1142
			}
1143

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

    
1147
			if (!empty($pptpdcfg['dns1'])) {
1148
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1149
				if (!empty($pptpdcfg['dns2']))
1150
					$mpdconf .= " " . $pptpdcfg['dns2'];
1151
				$mpdconf .= "\n";
1152
			} elseif (isset ($config['dnsmasq']['enable'])) {
1153
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1154
				if ($syscfg['dnsserver'][0])
1155
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1156
				$mpdconf .= "\n";
1157
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1158
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1159
			}
1160

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

    
1167
EOD;
1168
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1169
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1170
				$acctport = $authport + 1;
1171
				$mpdconf .=<<<EOD
1172
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret']}" {$authport} {$acctport}
1173

    
1174
EOD;
1175
			}
1176
			$mpdconf .=<<<EOD
1177
	set radius retries 3
1178
	set radius timeout 10
1179
	set auth enable radius-auth
1180

    
1181
EOD;
1182

    
1183
				if (isset ($pptpdcfg['radius']['accounting'])) {
1184
					$mpdconf .=<<<EOD
1185
	set auth enable radius-acct
1186
	set radius acct-update 300
1187

    
1188
EOD;
1189
				}
1190
			}
1191

    
1192
			fwrite($fd, $mpdconf);
1193
			fclose($fd);
1194

    
1195
			/* write mpd.links */
1196
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1197
			if (!$fd) {
1198
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1199
				return 1;
1200
			}
1201

    
1202
			$mpdlinks = "";
1203

    
1204
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1205
				$mpdlinks .=<<<EOD
1206

    
1207
pt{$i}:
1208
	set link type pptp
1209
	set pptp enable incoming
1210
	set pptp disable originate
1211
	set pptp disable windowing
1212

    
1213
EOD;
1214
			}
1215

    
1216
			fwrite($fd, $mpdlinks);
1217
			fclose($fd);
1218

    
1219
			/* write mpd.secret */
1220
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1221
			if (!$fd) {
1222
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1223
				return 1;
1224
			}
1225

    
1226
			$mpdsecret = "";
1227

    
1228
			if (is_array($pptpdcfg['user'])) {
1229
				foreach ($pptpdcfg['user'] as $user) {
1230
					$pass = str_replace('\\', '\\\\', $user['password']);
1231
					$pass = str_replace('"', '\"', $pass);
1232
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1233
				}
1234
			}
1235

    
1236
			fwrite($fd, $mpdsecret);
1237
			fclose($fd);
1238
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1239

    
1240
			vpn_netgraph_support();
1241

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

    
1245
			break;
1246

    
1247
		case 'redir' :
1248
			break;
1249
	}
1250

    
1251
	if ($g['booting'])
1252
		echo "done\n";
1253

    
1254
	return 0;
1255
}
1256

    
1257
function vpn_pppoes_configure() {
1258
	global $config;
1259

    
1260
	if (is_array($config['pppoes']['pppoe'])) {
1261
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1262
			vpn_pppoe_configure($pppoe);
1263
	}
1264
}
1265

    
1266
function vpn_pppoe_configure(&$pppoecfg) {
1267
	global $config, $g;
1268

    
1269
	$syscfg = $config['system'];
1270

    
1271
	/* create directory if it does not exist */
1272
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1273
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1274

    
1275
	if ($g['booting']) {
1276
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1277
			return 0;
1278

    
1279
		echo gettext("Configuring PPPoE VPN service... ");
1280
	} else {
1281
		/* kill mpd */
1282
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1283

    
1284
		/* wait for process to die */
1285
		sleep(2);
1286

    
1287
	}
1288

    
1289
	switch ($pppoecfg['mode']) {
1290

    
1291
		case 'server' :
1292

    
1293
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1294

    
1295
			if ($pppoecfg['paporchap'] == "chap")
1296
				$paporchap = "set link enable chap";
1297
			else
1298
				$paporchap = "set link enable pap";
1299

    
1300
			/* write mpd.conf */
1301
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1302
			if (!$fd) {
1303
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1304
				return 1;
1305
			}
1306
			$mpdconf = "\n\n";
1307
			$mpdconf .= "poes:\n";
1308

    
1309
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1310
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1311
			}
1312

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

    
1315
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1316

    
1317
				if (isset ($pppoecfg['radius']['radiusissueips']) && isset ($pppoecfg['radius']['server']['enable'])) {
1318
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1319
				} else {
1320
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1321
				}
1322

    
1323
				$mpdconf .=<<<EOD
1324

    
1325
poes{$pppoecfg['pppoeid']}{$i}:
1326
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1327
	{$isssue_ip_type}
1328
	load pppoe_standard
1329

    
1330
EOD;
1331
			}
1332

    
1333
			$mpdconf .=<<<EOD
1334

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

    
1361
EOD;
1362

    
1363
			if (!empty($pppoecfg['dns1'])) {
1364
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1365
				if (!empty($pppoecfg['dns2']))
1366
					$mpdconf .= " " . $pppoecfg['dns2'];
1367
				$mpdconf .= "\n";
1368
			} elseif (isset ($config['dnsmasq']['enable'])) {
1369
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1370
				if ($syscfg['dnsserver'][0])
1371
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1372
				$mpdconf .= "\n";
1373
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1374
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1375
			}
1376

    
1377
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1378
				$radiusport = "";
1379
				$radiusacctport = "";
1380
				if (isset($pppoecfg['radius']['server']['port']))
1381
					$radiusport = $pppoecfg['radius']['server']['port'];
1382
				if (isset($pppoecfg['radius']['server']['acctport']))
1383
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1384
				$mpdconf .=<<<EOD
1385
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']} {$radiusport} {$radiusacctport}" 
1386
	set radius retries 3
1387
	set radius timeout 10
1388
	set auth enable radius-auth
1389

    
1390
EOD;
1391

    
1392
				if (isset ($pppoecfg['radius']['accounting'])) {
1393
					$mpdconf .=<<<EOD
1394
	set auth enable radius-acct
1395

    
1396
EOD;
1397
				}
1398
			}
1399

    
1400
			fwrite($fd, $mpdconf);
1401
			fclose($fd);
1402

    
1403
			/* write mpd.links */
1404
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1405
			if (!$fd) {
1406
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1407
				return 1;
1408
			}
1409

    
1410
			$mpdlinks = "";
1411

    
1412
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1413
				$mpdlinks .=<<<EOD
1414
			
1415
poes{$pppoecfg['pppoeid']}{$i}:
1416
	set phys type pppoe
1417
        set pppoe iface {$pppoe_interface}
1418
        set pppoe service "*"
1419
        set pppoe disable originate
1420
        set pppoe enable incoming
1421

    
1422
EOD;
1423
			}
1424

    
1425
			fwrite($fd, $mpdlinks);
1426
			fclose($fd);
1427

    
1428
			if ($pppoecfg['username']) {
1429
				/* write mpd.secret */
1430
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1431
				if (!$fd) {
1432
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1433
					return 1;
1434
				}
1435

    
1436
				$mpdsecret = "\n\n";
1437

    
1438
				if (!empty($pppoecfg['username'])) {
1439
					$item = explode(" ", $pppoecfg['username']);
1440
					foreach($item as $userdata) {
1441
						$data = explode(":", $userdata);
1442
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1443
					}
1444
				}
1445

    
1446
				fwrite($fd, $mpdsecret);
1447
				fclose($fd);
1448
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1449
			}
1450

    
1451
			/* Get support for netgraph(4) from the nic */
1452
			pfSense_ngctl_attach(".", $pppoe_interface);
1453
			/* fire up mpd */
1454
			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");
1455

    
1456
			break;
1457
	}
1458

    
1459
	if ($g['booting'])
1460
		echo gettext("done") . "\n";
1461

    
1462
	return 0;
1463
}
1464

    
1465
function vpn_l2tp_configure() {
1466
	global $config, $g;
1467

    
1468
	$syscfg = $config['system'];
1469
	$l2tpcfg = $config['l2tp'];
1470

    
1471
	/* create directory if it does not exist */
1472
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1473
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1474

    
1475
	if ($g['booting']) {
1476
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1477
			return 0;
1478

    
1479
		echo gettext("Configuring l2tp VPN service... ");
1480
	} else {
1481
		/* kill mpd */
1482
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1483

    
1484
		/* wait for process to die */
1485
		sleep(8);
1486

    
1487
	}
1488

    
1489
	/* make sure l2tp-vpn directory exists */
1490
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1491
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1492

    
1493
	switch ($l2tpcfg['mode']) {
1494

    
1495
		case 'server' :
1496
			if ($l2tpcfg['paporchap'] == "chap")
1497
				$paporchap = "set link enable chap";
1498
			else
1499
				$paporchap = "set link enable pap";
1500

    
1501
			/* write mpd.conf */
1502
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1503
			if (!$fd) {
1504
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1505
				return 1;
1506
			}
1507
			$mpdconf = "\n\n";
1508
			$mpdconf .=<<<EOD
1509
l2tps:
1510

    
1511
EOD;
1512

    
1513
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1514
				$mpdconf .= "	load l2tp{$i}\n";
1515
			}
1516

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

    
1519
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1520

    
1521
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1522
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1523
				} else {
1524
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1525
				}
1526

    
1527
				$mpdconf .=<<<EOD
1528

    
1529
l2tp{$i}:
1530
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1531
	{$isssue_ip_type}
1532
	load l2tp_standard
1533

    
1534
EOD;
1535
			}
1536

    
1537
			$mpdconf .=<<<EOD
1538

    
1539
l2tp_standard:
1540
        set bundle disable multilink
1541
        set bundle enable compression
1542
        set bundle yes crypt-reqd
1543
        set ipcp yes vjcomp
1544
        # set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1545
        set ccp yes mppc
1546
        set iface disable on-demand
1547
        set iface enable proxy-arp
1548
	set iface up-script /usr/local/sbin/vpn-linkup
1549
	set iface down-script /usr/local/sbin/vpn-linkdown
1550
        set link yes acfcomp protocomp
1551
        set link no pap chap
1552
        set link enable chap
1553
        set link keep-alive 10 180
1554

    
1555
EOD;
1556

    
1557
			if (is_ipaddr($l2tpcfg['wins'])) {
1558
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1559
			}
1560
			if (is_ipaddr($l2tpcfg['dns1'])) {
1561
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1562
				if (is_ipaddr($l2tpcfg['dns2']))
1563
					$mpdconf .= " " . $l2tpcfg['dns2'];
1564
				$mpdconf .= "\n";
1565
			} elseif (isset ($config['dnsmasq']['enable'])) {
1566
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1567
				if ($syscfg['dnsserver'][0])
1568
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1569
				$mpdconf .= "\n";
1570
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1571
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1572
			}
1573

    
1574
			if (isset ($l2tpcfg['radius']['enable'])) {
1575
				$mpdconf .=<<<EOD
1576
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1577
	set radius retries 3
1578
	set radius timeout 10
1579
	set auth enable radius-auth
1580

    
1581
EOD;
1582

    
1583
				if (isset ($l2tpcfg['radius']['accounting'])) {
1584
					$mpdconf .=<<<EOD
1585
	set auth enable radius-acct
1586

    
1587
EOD;
1588
				}
1589
			}
1590

    
1591
			fwrite($fd, $mpdconf);
1592
			fclose($fd);
1593

    
1594
			/* write mpd.links */
1595
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1596
			if (!$fd) {
1597
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1598
				return 1;
1599
			}
1600

    
1601
			$mpdlinks = "";
1602

    
1603
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1604
				$mpdlinks .=<<<EOD
1605

    
1606
l2tp{$i}:
1607
	set link type l2tp
1608
        set l2tp enable incoming
1609
        set l2tp disable originate
1610

    
1611
EOD;
1612
			if (!empty($l2tpcfg['secret']))
1613
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1614
			}
1615

    
1616
			fwrite($fd, $mpdlinks);
1617
			fclose($fd);
1618

    
1619
			/* write mpd.secret */
1620
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1621
			if (!$fd) {
1622
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1623
				return 1;
1624
			}
1625

    
1626
			$mpdsecret = "\n\n";
1627

    
1628
			if (is_array($l2tpcfg['user'])) {
1629
				foreach ($l2tpcfg['user'] as $user)
1630
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1631
			}
1632

    
1633
			fwrite($fd, $mpdsecret);
1634
			fclose($fd);
1635
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1636

    
1637
			vpn_netgraph_support();
1638

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

    
1642
			break;
1643

    
1644
		case 'redir' :
1645
			break;
1646
	}
1647

    
1648
	if ($g['booting'])
1649
		echo "done\n";
1650

    
1651
	return 0;
1652
}
1653

    
1654
/* Walk the tunnels for hostname endpoints. If the hostnames 
1655
 * resolve to a different IP now compared to the DNS cache
1656
 * we reload the policies if the endpoint has changed */
1657
function vpn_ipsec_refresh_policies() {
1658
	global $config;
1659
	global $g;
1660

    
1661
	$ipseccfg = $config['ipsec'];
1662
	$a_phase1 = $config['ipsec']['phase1'];
1663
	$a_phase2 = $config['ipsec']['phase2'];
1664

    
1665
	if (isset($ipseccfg['disable'])) {
1666
		return true;
1667
	}
1668

    
1669
	/* Walk the Ipsec tunnel array */
1670
	if (!is_array($a_phase1) || (!count($a_phase1))) {
1671
		return;
1672
	}
1673

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

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

    
1722
/* reloads the tunnel configuration for a tunnel item
1723
 * Will remove and add SPD polices */
1724
function reload_tunnel_spd_policy($phase1, $phase2, $old_phase1, $old_phase2) {
1725
	global $config;
1726
	global $g;
1727

    
1728
	/* if we are not passed a old tunnel array we create one */
1729
	if(empty($old_phase1)) {
1730
		$old_phase1 = $phase1;
1731
	}
1732
	if(empty($old_phase2)) {
1733
		$old_phase2 = $phase2;
1734
	}
1735

    
1736
	$sad_arr = ipsec_dump_sad();
1737

    
1738
	$ep = ipsec_get_phase1_src($phase1);
1739
	$phase2['localid']['mode'] = $phase2['mode'];
1740
	$local_subnet = ipsec_idinfo_to_cidr($phase2['localid']);
1741
	$remote_subnet = ipsec_idinfo_to_cidr($phase2['remoteid']);
1742

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

    
1746
	$old_ep = ipsec_get_phase1_src($old_phase1);
1747
	$old_phase2['localid']['mode'] = $old_phase2['mode'];
1748
	$old_local_subnet = ipsec_idinfo_to_cidr($old_phase2['localid']);
1749
	$old_remote_subnet = ipsec_idinfo_to_cidr($old_phase2['remoteid']);
1750

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

    
1773
	if((!is_ipaddr($old_ep)) || (! is_ipaddr($ep))) {
1774
		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));
1775
	}
1776
	if((! is_ipaddr($rgip)) || (! is_ipaddr($old_gw))) {
1777
		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));
1778
	}
1779

    
1780
	$spdconf = "";
1781
	/* Delete old SPD policies if there are changes between the old and new */
1782
	if(($phase1 != $old_phase1) || ($phase2 != $old_phase2)) {
1783
		if($old_phase2['mode'] == "tunnel6")
1784
			$family = "-6";
1785
		else
1786
			$family = "-4";
1787

    
1788
		$spdconf .= "spddelete {$family} {$old_local_subnet} " .
1789
			"{$old_remote_subnet} any -P out ipsec " .
1790
			"{$old_phase2['protocol']}/tunnel/{$old_ep}-" .
1791
			"{$old_gw}/unique;\n";
1792
		$spdconf .= "spddelete {$family} {$old_remote_subnet} " .
1793
			"{$old_local_subnet} any -P in ipsec " .
1794
			"{$old_phase2['protocol']}/tunnel/{$old_gw}-" .
1795
			"{$old_ep}/unique;\n";
1796

    
1797
		/* zap any existing SA entries */
1798
		foreach($sad_arr as $sad) {
1799
			if(($sad['dst'] == $old_ep) && ($sad['src'] == $old_gw)) {
1800
				$spdconf .= "delete {$family} {$old_ep} {$old_gw} {$old_phase2['protocol']} 0x{$sad['spi']};\n";
1801
			}
1802
			if(($sad['src'] == $oldep) && ($sad['dst'] == $old_gw)) {
1803
				$spdconf .= "delete {$family} {$old_gw} {$old_ep} {$old_phase2['protocol']} 0x{$sad['spi']};\n";
1804
			}
1805
		}
1806
	}
1807

    
1808
	if($phase2['mode'] == "tunnel6")
1809
		$family = "-6";
1810
	else
1811
		$family = "-4";
1812

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

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

    
1835
	$now = time();
1836
	$spdfile = tempnam("{$g['tmp_path']}", "spd.conf.reload.{$now}.");
1837
	/* generate temporary spd.conf */
1838
	file_put_contents($spdfile, $spdconf);
1839
	return true;
1840
}
1841

    
1842
function vpn_ipsec_configure_preferoldsa() {
1843
	global $config;
1844
	if(isset($config['ipsec']['preferoldsa']))
1845
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
1846
	else
1847
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
1848
}
1849

    
1850
?>
(52-52/61)