Project

General

Profile

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

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

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

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

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

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

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

    
36
/*
37
	pfSense_BUILDER_BINARIES:	/usr/bin/killall	/usr/local/sbin/sasyncd	/sbin/ifconfig	/sbin/sysctl
38
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/setkey	/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
		/* resolve all local, peer addresses and setup pings */
130
		$ipmap = array();
131
		$rgmap = array();
132
		$filterdns_list = array();
133
		if (is_array($a_phase1) && count($a_phase1)) {
134

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
251
		$pskconf = "";
252

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
355
					$net_list = '';
356

    
357
					foreach ($a_phase2 as $ph2ent) {
358

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
449
					if (isset($ph1ent['disabled']))
450
						continue;
451

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

    
455
					$ikeid = $ph1ent['ikeid'];
456

    
457
					$ep = ipsec_get_phase1_src($ph1ent);
458
					if (!$ep)
459
						continue;
460

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

    
467
					$myid_type = $ph1ent['myid_type'];
468

    
469
					switch ($myid_type) {
470

    
471
						case "myaddress":
472
							$myid_type = "address";
473
							$myid_data = $ep;
474
							break;
475

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

    
481
						case "address";
482
							$myid_data = $ph1ent['myid_data'];
483
							break;
484

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

    
495
					$peerid_type = $ph1ent['peerid_type'];
496

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

    
503
						case "address";
504
							$peerid_data = $ph1ent['peerid_data'];
505
							break;
506

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

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

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

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

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

    
550
					$certline = '';
551

    
552
					if (strstr($authmethod,'rsa')) {
553

    
554
						$cert = lookup_cert($ph1ent['certref']);
555

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

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

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

    
571
						chmod($certpath, 0600);
572

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

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

    
582
						chmod($keypath, 0600);
583

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

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

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

    
599
						$certline = "certificate_type x509 \"".basename($certpath)."\" \"".basename($keypath)."\";";
600

    
601
					}
602

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

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

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

    
620
					/* add remote section to configuration */
621

    
622
					$racoonconf .=<<<EOD
623

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

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

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

    
661
				/* begin sainfo */
662
				foreach ($a_phase2 as $ph2ent) {
663

    
664
					$ikeid = $ph2ent['ikeid'];
665

    
666
					if( !ipsec_lookup_phase1($ph2ent,$ph1ent))
667
						continue;
668

    
669
					if (isset($ph1ent['disabled']))
670
						continue;
671

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

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

    
678
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
679

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

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

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

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

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

    
727
					if($ph2ent['protocol'] == 'esp') {
728

    
729
						$ealgos = '';
730

    
731
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
732

    
733
							$ealg_id = $ealg['name'];
734
							$ealg_kl = $ealg['keylen'];
735

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

    
771
						$ealgosline = "encryption_algorithm {$ealgos};";
772

    
773
					} else {
774

    
775
						$ealgosline = "encryption_algorithm null_enc;";
776
					}
777

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

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

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

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

    
808
EOD;
809
				}
810
				/* end sainfo */
811
			}
812
			/* end sainfo sections */
813

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

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

    
828
			$spdconf = "";
829

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

    
848
			foreach ($a_phase2 as $ph2ent) {
849

    
850
				if( !ipsec_lookup_phase1($ph2ent,$ph1ent))
851
					continue;
852

    
853
				if (isset($ph1ent['mobile']))
854
					continue;
855

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

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

    
862
				$ep = ipsec_get_phase1_src($ph1ent);
863
				if (!$ep)
864
					continue;
865

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

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

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

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

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

    
886
				} else {
887

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

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

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

    
897
				}
898

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

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

    
926
			fwrite($fd, $spdconf);
927
			fclose($fd);
928
		}
929

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

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

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

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

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

    
977
	return 0;
978
}
979

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

    
989
	$ipseccfg = $config['ipsec'];
990

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

    
995
	/* wait for process to die */
996
	sleep(4);
997

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

    
1001
	/* wait for flushing to finish */
1002
	sleep(1);
1003

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

    
1010
}
1011

    
1012
/* master setup for vpn (mpd) */
1013
function vpn_setup() {
1014
	/* start pptpd */
1015
	vpn_pptpd_configure();
1016

    
1017
	/* start pppoe server */
1018
	vpn_pppoes_configure();
1019

    
1020
	/* setup l2tp */
1021
	vpn_l2tp_configure();
1022
}
1023

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

    
1035
function vpn_pptpd_configure() {
1036
	global $config, $g;
1037

    
1038
	$syscfg = $config['system'];
1039
	$pptpdcfg = $config['pptpd'];
1040

    
1041
	if ($g['booting']) {
1042
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
1043
			return 0;
1044

    
1045
		echo gettext("Configuring PPTP VPN service... ");
1046
	} else {
1047
		/* kill mpd */
1048
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1049

    
1050
		/* wait for process to die */
1051
		sleep(3);
1052

    
1053
		if (is_process_running("mpd -b")) {
1054
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1055
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
1056
		}
1057

    
1058
		/* remove mpd.conf, if it exists */
1059
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
1060
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
1061
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
1062
	}
1063

    
1064
	if (empty($pptpdcfg['n_pptp_units'])) {
1065
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
1066
		return; 
1067
	}
1068

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

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

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

    
1085
EOD;
1086

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

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

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

    
1095
				$mpdconf .= <<<EOD
1096

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

    
1102
EOD;
1103
			}
1104

    
1105
			$mpdconf .=<<<EOD
1106

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

    
1127
EOD;
1128

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

    
1134
EOD;
1135
			}
1136

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

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

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

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

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

    
1174
EOD;
1175

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

    
1181
EOD;
1182
				}
1183
			}
1184

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

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

    
1195
			$mpdlinks = "";
1196

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

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

    
1206
EOD;
1207
			}
1208

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

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

    
1219
			$mpdsecret = "";
1220

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

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

    
1233
			vpn_netgraph_support();
1234

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

    
1238
			break;
1239

    
1240
		case 'redir' :
1241
			break;
1242
	}
1243

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

    
1247
	return 0;
1248
}
1249

    
1250
function vpn_pppoes_configure() {
1251
	global $config;
1252

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

    
1259
function vpn_pppoe_configure(&$pppoecfg) {
1260
	global $config, $g;
1261

    
1262
	$syscfg = $config['system'];
1263

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

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

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

    
1277
		/* wait for process to die */
1278
		sleep(2);
1279

    
1280
	}
1281

    
1282
	switch ($pppoecfg['mode']) {
1283

    
1284
		case 'server' :
1285

    
1286
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1287

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

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

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

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

    
1308
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1309

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

    
1316
				$mpdconf .=<<<EOD
1317

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

    
1323
EOD;
1324
			}
1325

    
1326
			$mpdconf .=<<<EOD
1327

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

    
1354
EOD;
1355

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

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

    
1383
EOD;
1384

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

    
1389
EOD;
1390
				}
1391
			}
1392

    
1393
			fwrite($fd, $mpdconf);
1394
			fclose($fd);
1395

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

    
1403
			$mpdlinks = "";
1404

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

    
1415
EOD;
1416
			}
1417

    
1418
			fwrite($fd, $mpdlinks);
1419
			fclose($fd);
1420

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

    
1429
				$mpdsecret = "\n\n";
1430

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

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

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

    
1449
			break;
1450
	}
1451

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

    
1455
	return 0;
1456
}
1457

    
1458
function vpn_l2tp_configure() {
1459
	global $config, $g;
1460

    
1461
	$syscfg = $config['system'];
1462
	$l2tpcfg = $config['l2tp'];
1463

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

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

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

    
1477
		/* wait for process to die */
1478
		sleep(8);
1479

    
1480
	}
1481

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

    
1486
	switch ($l2tpcfg['mode']) {
1487

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

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

    
1504
EOD;
1505

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

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

    
1512
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1513

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

    
1520
				$mpdconf .=<<<EOD
1521

    
1522
l2tp{$i}:
1523
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1524
	{$isssue_ip_type}
1525
	load l2tp_standard
1526

    
1527
EOD;
1528
			}
1529

    
1530
			$mpdconf .=<<<EOD
1531

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

    
1548
EOD;
1549

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

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

    
1574
EOD;
1575

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

    
1580
EOD;
1581
				}
1582
			}
1583

    
1584
			fwrite($fd, $mpdconf);
1585
			fclose($fd);
1586

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

    
1594
			$mpdlinks = "";
1595

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

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

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

    
1609
			fwrite($fd, $mpdlinks);
1610
			fclose($fd);
1611

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

    
1619
			$mpdsecret = "\n\n";
1620

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

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

    
1630
			vpn_netgraph_support();
1631

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

    
1635
			break;
1636

    
1637
		case 'redir' :
1638
			break;
1639
	}
1640

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

    
1644
	return 0;
1645
}
1646

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

    
1654
	$ipseccfg = $config['ipsec'];
1655
	$a_phase1 = $config['ipsec']['phase1'];
1656
	$a_phase2 = $config['ipsec']['phase2'];
1657

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

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

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

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

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

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

    
1729
	$sad_arr = ipsec_dump_sad();
1730

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

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

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

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

    
1766
	if((!is_ipaddr($old_ep)) || (! is_ipaddr($ep))) {
1767
		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));
1768
	}
1769
	if((! is_ipaddr($rgip)) || (! is_ipaddr($old_gw))) {
1770
		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));
1771
	}
1772

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

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

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

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

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

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

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

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

    
1843
?>
(52-52/61)