Project

General

Profile

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

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

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

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

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

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

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

    
36
/*
37
	pfSense_BUILDER_BINARIES:	/usr/bin/killall	/usr/local/sbin/sasyncd	/sbin/ifconfig	/sbin/sysctl
38
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/setkey	/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

    
88
	/* get the automatic ping_hosts.sh ready */
89
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
90
	touch("{$g['vardb_path']}/ipsecpinghosts");
91

    
92
	vpn_ipsec_configure_preferoldsa();
93

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

    
100
	if (!isset($ipseccfg['enable'])) {
101
		/* try to stop racoon*/
102
		killbypid("{$g['varrun_path']}/racoon.pid");
103
		/* Stop dynamic monitoring */
104
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
105

    
106
		/* kill racoon forcefully */
107
		if (is_process_running("racoon"))
108
			mwexec("/usr/bin/killall -9 racoon", true);
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
		mwexec("/sbin/ifconfig enc0 down");
119
		exec("/sbin/sysctl net.inet.ip.ipsec_in_use=0");
120

    
121
		return 0;
122
	} else {
123
		mwexec("/sbin/ifconfig enc0 up");
124
		mwexec("/sbin/sysctl net.inet.ip.ipsec_in_use=1");
125
		/* needed for racoonctl admin socket */
126
		if (!is_dir("/var/db/racoon"))
127
			mkdir("/var/db/racoon/");
128
		/* needed for config files */
129
		if (!is_dir("{$g['varetc_path']}/ipsec"))
130
			mkdir("{$g['varetc_path']}/ipsec");
131
		
132

    
133
		if ($g['booting'])
134
			echo gettext("Configuring IPsec VPN... ");
135

    
136
		/* fastforwarding is not compatible with ipsec tunnels */
137
		mwexec("/sbin/sysctl net.inet.ip.fastforwarding=0");
138

    
139
		/* resolve all local, peer addresses and setup pings */
140
		$ipmap = array();
141
		$rgmap = array();
142
		$filterdns_list = array();
143
		unset($iflist);
144
		if (is_array($a_phase1) && count($a_phase1)) {
145

    
146
			$ipsecpinghosts = "";
147
			/* step through each phase1 entry */
148
			foreach ($a_phase1 as $ph1ent) {
149
				if (isset($ph1ent['disabled']))
150
					continue;
151

    
152
				$ep = ipsec_get_phase1_src($ph1ent);
153
				if (!is_ipaddr($ep))
154
					continue;
155

    
156
				if(!in_array($ep,$ipmap))
157
					$ipmap[] = $ep;
158

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

    
162
				if (isset ($ph1ent['mobile']))
163
					continue;
164

    
165
				$rg = $ph1ent['remote-gateway'];
166

    
167
				if (!is_ipaddr($rg)) {
168
					$filterdns_list[] = "{$rg}";
169
					add_hostname_to_watch($rg);
170
					if(! $g['booting'])
171
						$rg = resolve_retry($rg);
172
					if (!is_ipaddr($rg))
173
						continue;
174
				}
175
				if(array_search($rg, $rgmap)) {
176
					log_error("The remote gateway {$rg} already exists on another phase 1 entry");
177
					continue;
178
				}
179
				$rgmap[$ph1ent['remote-gateway']] = $rg;
180

    
181
				if (is_array($a_phase2)) {
182
					/* step through each phase2 entry */
183
					foreach ($a_phase2 as $ph2ent) {
184
						$ikeid = $ph2ent['ikeid'];
185

    
186
						if (isset($ph2ent['disabled']))
187
							continue;
188

    
189
						if ($ikeid != $ph1ent['ikeid'])
190
							continue;
191

    
192
						/* add an ipsec pinghosts entry */
193
						if ($ph2ent['pinghost']) {
194
							if (!is_array($iflist))
195
								$iflist = get_configured_interface_list();
196
							foreach ($iflist as $ifent => $ifname) {
197
								if(is_ipaddrv6($ph2ent['pinghost'])) {
198
									$interface_ip = get_interface_ipv6($ifent);
199
									if(!is_ipaddrv6($interface_ip))
200
										continue;
201
									$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
202
									if (ip_in_subnet($interface_ip, $local_subnet)) {
203
										$srcip = $interface_ip;
204
										break;
205
									}
206
								} else {
207
									$interface_ip = get_interface_ip($ifent);
208
									if(!is_ipaddrv4($interface_ip))
209
										continue;
210
									$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
211
									if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) {
212
										$srcip = $interface_ip;
213
										break;
214
									}
215
								}
216
							}
217
							$dstip = $ph2ent['pinghost'];
218
							if(is_ipaddrv6($dstip)) {
219
								$family = "inet6";
220
							} else {
221
								$family = "inet";
222
							}
223
							if (is_ipaddr($srcip))
224
								$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
225
						}
226
					}
227
				}
228
			}
229
			@file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
230
			unset($ipsecpinghosts);
231
		}
232

    
233
		/* generate CA certificates files */
234
		if (is_array($config['ca']) && count($config['ca'])) {
235
			foreach ($config['ca'] as $ca) {
236
				if (!isset($ca['crt'])) {
237
					log_error(sprintf(gettext("Error: Invalid certificate info for %s"), $ca['descr']));
238
					continue;
239
				}
240
				$cert = base64_decode($ca['crt']);
241
				$x509cert = openssl_x509_parse(openssl_x509_read($cert));
242
				if (!is_array($x509cert) || !isset($x509cert['hash'])) {
243
					log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $ca['descr']));
244
					continue;
245
				}
246
				$fname = "{$g['varetc_path']}/ipsec/{$x509cert['hash']}.0";
247
				if (!@file_put_contents($fname, $cert)) {
248
					log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $ca['descr']));
249
					continue;
250
				}
251
				unset($cert);
252
			}
253
		}
254
		
255
		$pskconf = "";
256

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
331
				$racoonconf .= "\nmode_cfg\n";
332
				$racoonconf .= "{\n";
333

    
334
				if (!empty($a_client['user_source']))
335
					$racoonconf .= "\tauth_source external;\n";
336
				if (!empty($a_client['group_source']) && $a_client['group_source'] != "none")
337
					$racoonconf .= "\tgroup_source {$a_client['group_source']};\n";
338

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

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

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

    
351
				if (isset($a_client['net_list'])) {
352

    
353
					$net_list = '';
354

    
355
					foreach ($a_phase2 as $ph2ent) {
356

    
357
						if (isset($ph2ent['disabled']))
358
							continue;
359

    
360
						if (!isset($ph2ent['mobile']))
361
							continue;
362

    
363
						$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
364

    
365
						if ($net_list)
366
							$net_list .= ", ";
367
						$net_list .= $localid;
368
					}
369

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

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

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

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

    
394
				if ($a_client['dns_split']) {
395
					$domain_array = preg_split("/[ ,]+/",$a_client['dns_split']);
396
					$domain_string = implode('", "', $domain_array);
397
					$racoonconf .= "\tsplit_dns \"{$domain_string}\";\n";
398
				}
399

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

    
403
				if ($a_client['login_banner']) {
404
					@file_put_contents("{$g['varetc_path']}/ipsec/racoon.motd", $a_client['login_banner']);
405
					$racoonconf .= "\tbanner \"{$g['varetc_path']}/ipsec/racoon.motd\";\n";
406
				}
407

    
408
				if (isset($a_client['save_passwd']))
409
					$racoonconf .= "\tsave_passwd on;\n";
410

    
411
				$racoonconf .= "}\n\n";
412
			}
413
			/* end mode_cfg section */
414
			
415
			if ($a_client['user_source'] != "none") {
416
				$authcfgs = explode(",", $a_client['user_source']);
417
				$sed = "\$authmodes=array(";
418
				$firstsed = 0;
419
				foreach ($authcfgs as $authcfg) {
420
					if ($authcfg == "system")
421
						$authcfg = "Local Database";
422
					if ($firstsed > 0)
423
						$sed .= ",";
424
					$firstsed = 1;
425
					$sed .= "\"{$authcfg}\"";
426
				}
427
				$sed .= ");\\\n";
428
				if ($a_client['strictusercn'])
429
					$sed .= "\$strictusercn = true;";
430
				mwexec("/bin/cat /etc/inc/ipsec.auth-user.php | /usr/bin/sed 's/\/\/<template>/{$sed}/g' >  {$g['varetc_path']}/ipsec/ipsec.php");
431
				mwexec("/bin/chmod a+x {$g['varetc_path']}/ipsec/ipsec.php");
432
				$racoonconf .= "extcfg { script \"{$g['varetc_path']}/ipsec/ipsec.php\" }\n";
433
			}
434

    
435
			/* begin remote sections */
436
			if (is_array($a_phase1) && count($a_phase1)) {
437
				/* begin remote */
438
				foreach ($a_phase1 as $ph1ent) {
439

    
440
					if (isset($ph1ent['disabled']))
441
						continue;
442

    
443
					if (isset($ph1ent['mobile']) && !isset($a_client['enable']))
444
						continue;
445

    
446
					$ikeid = $ph1ent['ikeid'];
447

    
448
					$ep = ipsec_get_phase1_src($ph1ent);
449
					if (!$ep)
450
						continue;
451

    
452
					if (!isset($ph1ent['mobile'])) {
453
						$rgip = $rgmap[$ph1ent['remote-gateway']];
454
						if (!$rgip)
455
							continue;
456
					}
457

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

    
460
					switch ($myid_type) {
461

    
462
						case "myaddress":
463
							$myid_type = "address";
464
							$myid_data = $ep;
465
							break;
466

    
467
						case "dyn_dns":
468
							$myid_type = "address";
469
							$myid_data = resolve_retry($ph1ent['myid_data']);
470
							break;
471

    
472
						case "address";
473
							$myid_data = $ph1ent['myid_data'];
474
							break;
475

    
476
						case "fqdn";
477
						case "keyid tag";
478
						case "user_fqdn";
479
						case "asn1dn";
480
							$myid_data = $ph1ent['myid_data'];
481
							if( $myid_data )
482
								$myid_data = "\"".$myid_data."\"";
483
							break;
484
					}
485

    
486
					$peerid_type = $ph1ent['peerid_type'];
487

    
488
					switch ($peerid_type) {
489
						case "peeraddress":
490
							$peerid_type = "address";
491
							$peerid_data = $rgip;
492
							break;
493

    
494
						case "address";
495
							$peerid_data = $ph1ent['peerid_data'];
496
							break;
497

    
498
						case "fqdn";
499
						case "keyid tag";
500
						case "user_fqdn";
501
						case "asn1dn";
502
							$peerid_data = $ph1ent['peerid_data'];
503
							if( $peerid_data )
504
								$peerid_data = "\"".$peerid_data."\"";
505
							break;
506
					}
507

    
508
					$natt = "off";
509
					if (isset($ph1ent['nat_traversal']))
510
						$natt = $ph1ent['nat_traversal'];
511

    
512
					$init = "on";
513
					$genp = !empty($ph1ent['generate_policy']) ? $ph1ent['generate_policy'] : "off";
514
					$pcheck = !empty($ph1ent['proposal_check']) ? $ph1ent['proposal_check'] : $pcheck = "claim";
515
					$passive = "";
516
					if (isset($ph1ent['mobile'])) {
517
						$rgip = "anonymous";
518
						$passive = "passive on;";
519
						$pcheck = !empty($ph1ent['proposal_check']) ? $ph1ent['proposal_check'] : $pcheck = "obey";
520
						/* Mimic 1.2.3's behavior for pure-psk mobile tunnels */
521
						if ($ph1ent['authentication_method'] == "pre_shared_key") {
522
							$genp = !empty($ph1ent['generate_policy']) ? $ph1ent['generate_policy'] : "on";
523
						} else {
524
							$init = "off";
525
							$genp = !empty($ph1ent['generate_policy']) ? $ph1ent['generate_policy'] : "unique";
526
						}
527
					}
528

    
529
					$dpdline1 = '';
530
					$dpdline2 = '';
531
					if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
532
						$dpdline1 = "dpd_delay = {$ph1ent['dpd_delay']};";
533
						$dpdline2 = "dpd_maxfail = {$ph1ent['dpd_maxfail']};";
534
					}
535

    
536
					if (isset ($ph1ent['authentication_method']))
537
						$authmethod = $ph1ent['authentication_method'];
538
					else
539
						$authmethod = 'pre_shared_key';
540

    
541
					$certline = '';
542

    
543
					if (strstr($authmethod,'rsa')) {
544

    
545
						$cert = lookup_cert($ph1ent['certref']);
546

    
547
						if (!$cert)
548
						{
549
							log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
550
							continue;
551
						}
552

    
553
						$certfile = "cert-{$ikeid}.crt";
554
						$certpath = "{$g['varetc_path']}/ipsec/{$certfile}";
555

    
556
						if (!file_put_contents($certpath, base64_decode($cert['crt'])))
557
						{
558
							log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name']));
559
							continue;
560
						}
561

    
562
						chmod($certpath, 0600);
563

    
564
						$keyfile = "cert-{$ikeid}.key";
565
						$keypath = "{$g['varetc_path']}/ipsec/{$keyfile}";
566

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

    
573
						chmod($keypath, 0600);
574

    
575
						$ca = lookup_ca($ph1ent['caref']);
576
						if ($ca) {
577
							$cafile = "ca-{$ikeid}.crt";
578
							$capath = "{$g['varetc_path']}/ipsec/{$cafile}";
579

    
580
							if (!file_put_contents($capath, base64_decode($ca['crt'])))
581
							{
582
								log_error(sprintf(gettext("Error: Cannot write phase1 CA certificate file for %s"), $ph1ent['name']));
583
								continue;
584
							}
585

    
586
							chmod($capath, 0600);
587
							$caline = "ca_type x509 \"{$cafile}\";";
588
						}
589

    
590
						$certline = "certificate_type x509 \"{$certfile}\" \"{$keyfile}\";";
591

    
592
					}
593

    
594
					$ealgos = '';
595
					$ealg_id = $ph1ent['encryption-algorithm']['name'];
596
					$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
597
					if ($ealg_kl)
598
						$ealgos = $ealgos.$ealg_id." ".$ealg_kl;
599
					else
600
						$ealgos = $ealgos.$ealg_id;
601

    
602
					$lifeline = '';
603
					if ($ph1ent['lifetime'])
604
						$lifeline = "lifetime time {$ph1ent['lifetime']} secs;";
605

    
606
					/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
607
					if (!(($ph1ent['authentication_method'] == "pre_shared_key") && isset($ph1ent['mobile']))) {
608
						$peerid_spec = "peers_identifier {$peerid_type} {$peerid_data};";
609
					}
610

    
611
					/* add remote section to configuration */
612

    
613
					$racoonconf .=<<<EOD
614

    
615
remote {$rgip}
616
{
617
	ph1id {$ikeid};
618
	exchange_mode {$ph1ent['mode']};
619
	my_identifier {$myid_type} {$myid_data};
620
	{$peerid_spec}
621
	ike_frag on;
622
	generate_policy = {$genp};
623
	initial_contact = {$init};
624
	nat_traversal = {$natt};
625
	{$certline}
626
	{$caline}
627
	{$dpdline1}
628
	{$dpdline2}
629
	support_proxy on;
630
	proposal_check {$pcheck};
631
	{$passive}
632

    
633
	proposal
634
	{
635
		authentication_method {$authmethod};
636
		encryption_algorithm ${ealgos};
637
		hash_algorithm {$ph1ent['hash-algorithm']};
638
		dh_group {$ph1ent['dhgroup']};
639
		${lifeline}
640
	}
641
}
642

    
643
EOD;
644
				}
645
				/* end remote */
646
			}
647
			/* end remote sections */
648
		
649
			/* begin sainfo sections */
650
			if (is_array($a_phase2) && count($a_phase2)) {
651

    
652
				/* begin sainfo */
653
				foreach ($a_phase2 as $ph2ent) {
654

    
655
					$ikeid = $ph2ent['ikeid'];
656

    
657
					if( !ipsec_lookup_phase1($ph2ent,$ph1ent))
658
						continue;
659

    
660
					if (isset($ph1ent['disabled']))
661
						continue;
662

    
663
					if (isset($ph2ent['disabled']))
664
						continue;
665

    
666
					if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
667
						continue;
668

    
669
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
670

    
671
						$localid_type = $ph2ent['localid']['type'];
672
						$localid_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
673
						/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
674
						if (($localid_type == "none") ||
675
							(($ph1ent['authentication_method'] == "xauth_psk_server") ||
676
							($ph1ent['authentication_method'] == "pre_shared_key"))
677
							&& isset($ph1ent['mobile'])
678
							&& (ipsec_get_number_of_phase2($ikeid)==1))
679
							$localid_spec = " ";
680
						else {
681
							if ($localid_type != "address") {
682
								$localid_type = "subnet";
683
							}
684
							// Don't let an empty subnet into racoon.conf, it can cause parse errors. Ticket #2201.
685
							if (!is_ipaddr($localid_data) && !is_subnet($localid_data) && ($localid_data != "0.0.0.0/0")) {
686
								log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
687
								continue;
688
							}
689
							$localid_spec = "{$localid_type} {$localid_data} any";
690
							if (!empty($ph2ent['natlocalid'])) {
691
								$natlocalid_data =  ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
692
								if ($ph2ent['natlocalid']['type'] != "address") {
693
									if (is_subnet($natlocalid_data))
694
										$localid_spec .= " nat subnet {$natlocalid_data} any";
695
								} else {
696
									if (is_ipaddr($natlocalid_data))
697
										$localid_spec .= " nat address {$natlocalid_data} any";
698
								}
699
							}
700
						}
701

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

    
707
							$remoteid_data = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
708
							$remoteid_spec = $remoteid_type." ".$remoteid_data." any";
709
						} else
710
							$remoteid_spec = "anonymous";
711

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

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

    
732
					if($ph2ent['protocol'] == 'esp') {
733

    
734
						$ealgos = '';
735

    
736
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
737

    
738
							$ealg_id = $ealg['name'];
739
							$ealg_kl = $ealg['keylen'];
740

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

    
776
						$ealgosline = "encryption_algorithm {$ealgos};";
777

    
778
					} else {
779

    
780
						$ealgosline = "encryption_algorithm null_enc;";
781
					}
782

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

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

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

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

    
813
EOD;
814
				}
815
				/* end sainfo */
816
			}
817
			/* end sainfo sections */
818
		}
819
		@file_put_contents("{$g['varetc_path']}/ipsec/racoon.conf", $racoonconf);
820
		unset($racoonconf);
821
		/* end racoon.conf */
822

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

    
846
			foreach ($a_phase2 as $ph2ent) {
847

    
848
				if( !ipsec_lookup_phase1($ph2ent,$ph1ent))
849
					continue;
850

    
851
				if (isset($ph1ent['mobile']))
852
					continue;
853

    
854
				if (isset($ph1ent['disabled']))
855
					continue;
856

    
857
				if (isset($ph2ent['disabled']))
858
					continue;
859

    
860
				$ep = ipsec_get_phase1_src($ph1ent);
861
				if (!$ep)
862
					continue;
863

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

    
868
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
869
				$remoteid = ipsec_idinfo_to_cidr($ph2ent['remoteid'], true, $ph2ent['mode']);
870

    
871
				if(($ph2ent['mode'] == "tunnel") or ($ph2ent['mode'] == 'tunnel6')) {
872
					// Error will be logged above, no need to log this twice. #2201
873
					if (!is_subnet($localid))
874
						continue;
875

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

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

    
884
					if (!empty($ph2ent['natlocalid'])) {
885
						$natlocalid = ipsec_idinfo_to_cidr($ph2ent['natlocalid'], true, $ph2ent['mode']);
886
						$spdconf .= "spdadd {$family} {$remoteid} {$natlocalid} any -P in ipsec " .
887
							"{$ph2ent['protocol']}/tunnel/{$rgip}-{$ep}/unique;\n";
888
						$natfilterrules = true;
889
					} else
890
						$spdconf .= "spdadd {$family} {$remoteid} {$localid} any -P in ipsec " .
891
							"{$ph2ent['protocol']}/tunnel/{$rgip}-{$ep}/unique;\n";
892

    
893
				} else {
894

    
895
					$localid_data = ipsec_get_phase1_src($ph1ent);
896
					$remoteid_data = $rgmap[$ph1ent['remote-gateway']];
897

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

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

    
904
				}
905

    
906
				/* static route needed? */
907
				if (is_ipaddr($ph1ent['interface'])) {
908
					$vip = find_virtual_ip_alias($ph1ent['interface']);
909
					if (preg_match("/^carp|^[a-z0-9]+_vip/i", $vip['interface']))
910
						$parentinterface = link_carp_interface_to_parent($vip['interface']);
911
					else
912
						$parentinterface = $vip['interface'];
913
				} else if (preg_match("/^carp|^[a-z0-9]+_vip/i", $ph1ent['interface']))
914
					$parentinterface = link_carp_interface_to_parent($ph1ent['interface']);
915
				else
916
					$parentinterface = $ph1ent['interface'];
917

    
918
				if (is_ipaddr($rgip)) {
919
					/* add endpoint routes to correct gateway on interface */
920
					if (interface_has_gateway($parentinterface)) {
921
						$gatewayip = get_interface_gateway("$parentinterface");
922
						$interfaceip = get_interface_ip($parentinterface);
923
						$subnet_bits = get_interface_subnet($parentinterface);
924
						$subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
925
						/* if the remote gateway is in the local subnet, then don't add a route */
926
						if (! ip_in_subnet($rgip, "{$subnet_ip}/{$subnet_bits}")) {
927
							if(is_ipaddr($gatewayip)) {
928
								/* FIXME: does adding route-to and reply-to on the in/outbound
929
								 * rules fix this? smos@ 13-01-2009 */
930
								// log_error("IPSEC interface is not WAN but {$parentinterface}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
931
								mwexec("/sbin/route change -host {$rgip} {$gatewayip}", true);
932
							}
933
						}
934
					}
935
				} 
936
			}
937
		}
938
		@file_put_contents("{$g['varetc_path']}/ipsec/spd.conf", $spdconf);
939
		unset($spdconf);
940

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

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

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

    
976
			if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
977
				sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
978
			else {
979
				mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
980
			}
981
		} else {
982
			killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
983
			@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
984
		}
985
	
986
		vpn_ipsec_failover_configure();
987

    
988
		if ($g['booting'])
989
			echo "done\n";
990

    
991
		return count($filterdns_list);
992
	}
993
}
994

    
995
/* 
996
 * Forcefully restart IPsec
997
 * This is required for when dynamic interfaces reload
998
 * For all other occasions the normal vpn_ipsec_configure()
999
 * will gracefully reload the settings without restarting
1000
 */
1001
function vpn_ipsec_force_reload($interface = "") {
1002
	global $g, $config;
1003

    
1004
	$ipseccfg = $config['ipsec'];
1005

    
1006
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1007
		$found = false;
1008
		foreach ($ipseccfg['phase1'] as $ipsec) {
1009
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1010
				$found = true;
1011
				break;
1012
			}
1013
		}
1014
		if (!$found) {
1015
			log_error(sprintf(gettext("Ignoring IPsec racoon daemon reload since there are no tunnels on interface %s"), $interface));
1016
			return;
1017
		}
1018
	}
1019

    
1020
	/* send a SIGKILL to be sure */
1021
	killbypid("{$g['varrun_path']}/racoon.pid");
1022

    
1023
	/* wait for process to die */
1024
	sleep(4);
1025

    
1026
	/* kill racoon forcefully */
1027
	if (is_process_running("racoon"))
1028
		mwexec("/usr/bin/killall -9 racoon", true);
1029

    
1030
	/* wait for flushing to finish */
1031
	sleep(1);
1032

    
1033
	/* if ipsec is enabled, start up again */
1034
	if (isset($ipseccfg['enable'])) {
1035
		log_error(gettext("Forcefully reloading IPsec racoon daemon"));
1036
		vpn_ipsec_configure();
1037
	}
1038
}
1039

    
1040
/* master setup for vpn (mpd) */
1041
function vpn_setup() {
1042
	global $g;
1043

    
1044
	if ($g['platform'] == 'jail')
1045
		return;
1046

    
1047
	/* start pptpd */
1048
	vpn_pptpd_configure();
1049

    
1050
	/* start pppoe server */
1051
	vpn_pppoes_configure();
1052

    
1053
	/* setup l2tp */
1054
	vpn_l2tp_configure();
1055
}
1056

    
1057
function vpn_netgraph_support() {
1058
	$iflist = get_configured_interface_list();
1059
	foreach ($iflist as $iface) {
1060
		$realif = get_real_interface($iface);
1061
		/* Get support for netgraph(4) from the nic */
1062
		$ifinfo = pfSense_get_interface_addresses($realif);
1063
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
1064
                	pfSense_ngctl_attach(".", $realif);
1065
	}
1066
}
1067

    
1068
function vpn_pptpd_configure() {
1069
	global $config, $g;
1070

    
1071
	$syscfg = $config['system'];
1072
	$pptpdcfg = $config['pptpd'];
1073

    
1074
	if ($g['booting']) {
1075
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
1076
			return 0;
1077

    
1078
		echo gettext("Configuring PPTP VPN service... ");
1079
	} else {
1080
		/* kill mpd */
1081
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1082

    
1083
		/* wait for process to die */
1084
		sleep(3);
1085

    
1086
		if (is_process_running("mpd -b")) {
1087
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1088
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
1089
		}
1090

    
1091
		/* remove mpd.conf, if it exists */
1092
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
1093
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
1094
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
1095
	}
1096

    
1097
	if (empty($pptpdcfg['n_pptp_units'])) {
1098
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
1099
		return; 
1100
	}
1101

    
1102
	/* make sure pptp-vpn directory exists */
1103
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
1104
		mkdir("{$g['varetc_path']}/pptp-vpn");
1105

    
1106
	switch ($pptpdcfg['mode']) {
1107
		case 'server' :
1108
			/* write mpd.conf */
1109
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1110
			if (!$fd) {
1111
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
1112
				return 1;
1113
			}
1114

    
1115
			$mpdconf = <<<EOD
1116
pptps:
1117

    
1118
EOD;
1119

    
1120
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1121
				$mpdconf .= "	load pt{$i}\n";
1122
			}
1123

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

    
1126
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1127

    
1128
				$mpdconf .= <<<EOD
1129

    
1130
pt{$i}:
1131
	new -i pptpd{$i} pt{$i} pt{$i}
1132
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1133
	load pts
1134

    
1135
EOD;
1136
			}
1137

    
1138
			$mpdconf .=<<<EOD
1139

    
1140
pts:
1141
	set iface disable on-demand
1142
	set iface enable proxy-arp
1143
	set iface enable tcpmssfix
1144
	set iface idle 1800
1145
	set iface up-script /usr/local/sbin/vpn-linkup
1146
	set iface down-script /usr/local/sbin/vpn-linkdown
1147
	set bundle enable multilink
1148
	set bundle enable crypt-reqd
1149
	set link yes acfcomp protocomp
1150
	set link no pap chap
1151
	set link enable chap-msv2
1152
	set link mtu 1460
1153
	set link keep-alive 10 60
1154
	set ipcp yes vjcomp
1155
	set bundle enable compression
1156
	set ccp yes mppc
1157
	set ccp yes mpp-e128
1158
	set ccp yes mpp-stateless
1159

    
1160
EOD;
1161

    
1162
			if (!isset ($pptpdcfg['req128'])) {
1163
				$mpdconf .=<<<EOD
1164
	set ccp yes mpp-e40
1165
	set ccp yes mpp-e56
1166

    
1167
EOD;
1168
			}
1169

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

    
1173
			if (!empty($pptpdcfg['dns1'])) {
1174
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1175
				if (!empty($pptpdcfg['dns2']))
1176
					$mpdconf .= " " . $pptpdcfg['dns2'];
1177
				$mpdconf .= "\n";
1178
			} elseif (isset ($config['dnsmasq']['enable'])) {
1179
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1180
				if ($syscfg['dnsserver'][0])
1181
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1182
				$mpdconf .= "\n";
1183
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1184
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1185
			}
1186

    
1187
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1188
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1189
				$acctport = $authport + 1;
1190
				$mpdconf .=<<<EOD
1191
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1192

    
1193
EOD;
1194
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1195
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1196
				$acctport = $authport + 1;
1197
				$mpdconf .=<<<EOD
1198
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1199

    
1200
EOD;
1201
			}
1202
			$mpdconf .=<<<EOD
1203
	set radius retries 3
1204
	set radius timeout 10
1205
	set auth enable radius-auth
1206

    
1207
EOD;
1208

    
1209
				if (isset ($pptpdcfg['radius']['accounting'])) {
1210
					$mpdconf .=<<<EOD
1211
	set auth enable radius-acct
1212
	set radius acct-update 300
1213

    
1214
EOD;
1215
				}
1216
			}
1217

    
1218
			fwrite($fd, $mpdconf);
1219
			fclose($fd);
1220
			unset($mpdconf);
1221

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

    
1229
			$mpdlinks = "";
1230

    
1231
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1232
				$mpdlinks .=<<<EOD
1233

    
1234
pt{$i}:
1235
	set link type pptp
1236
	set pptp enable incoming
1237
	set pptp disable originate
1238
	set pptp disable windowing
1239

    
1240
EOD;
1241
			}
1242

    
1243
			fwrite($fd, $mpdlinks);
1244
			fclose($fd);
1245
			unset($mpdlinks);
1246

    
1247
			/* write mpd.secret */
1248
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1249
			if (!$fd) {
1250
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1251
				return 1;
1252
			}
1253

    
1254
			$mpdsecret = "";
1255

    
1256
			if (is_array($pptpdcfg['user'])) {
1257
				foreach ($pptpdcfg['user'] as $user) {
1258
					$pass = str_replace('\\', '\\\\', $user['password']);
1259
					$pass = str_replace('"', '\"', $pass);
1260
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1261
				}
1262
			}
1263

    
1264
			fwrite($fd, $mpdsecret);
1265
			fclose($fd);
1266
			unset($mpdsecret);
1267
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1268

    
1269
			vpn_netgraph_support();
1270

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

    
1274
			break;
1275

    
1276
		case 'redir' :
1277
			break;
1278
	}
1279

    
1280
	if ($g['booting'])
1281
		echo "done\n";
1282

    
1283
	return 0;
1284
}
1285

    
1286
function vpn_pppoes_configure() {
1287
	global $config;
1288

    
1289
	if (is_array($config['pppoes']['pppoe'])) {
1290
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1291
			vpn_pppoe_configure($pppoe);
1292
	}
1293
}
1294

    
1295
function vpn_pppoe_configure(&$pppoecfg) {
1296
	global $config, $g;
1297

    
1298
	$syscfg = $config['system'];
1299

    
1300
	/* create directory if it does not exist */
1301
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1302
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1303

    
1304
	if ($g['booting']) {
1305
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1306
			return 0;
1307

    
1308
		echo gettext("Configuring PPPoE VPN service... ");
1309
	} else {
1310
		/* kill mpd */
1311
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1312

    
1313
		/* wait for process to die */
1314
		sleep(2);
1315

    
1316
	}
1317

    
1318
	switch ($pppoecfg['mode']) {
1319

    
1320
		case 'server' :
1321

    
1322
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1323

    
1324
			if ($pppoecfg['paporchap'] == "chap")
1325
				$paporchap = "set link enable chap";
1326
			else
1327
				$paporchap = "set link enable pap";
1328

    
1329
			/* write mpd.conf */
1330
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1331
			if (!$fd) {
1332
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1333
				return 1;
1334
			}
1335
			$mpdconf = "\n\n";
1336
			$mpdconf .= "poes:\n";
1337

    
1338
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1339
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1340
			}
1341

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

    
1344
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1345

    
1346
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1347
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1348
				} else {
1349
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1350
				}
1351

    
1352
				$mpdconf .=<<<EOD
1353

    
1354
poes{$pppoecfg['pppoeid']}{$i}:
1355
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1356
	{$isssue_ip_type}
1357
	load pppoe_standard
1358

    
1359
EOD;
1360
			}
1361

    
1362
			$mpdconf .=<<<EOD
1363

    
1364
pppoe_standard:
1365
	set bundle no multilink
1366
	set bundle enable compression
1367
	set auth max-logins 1
1368
	set iface up-script /usr/local/sbin/vpn-linkup
1369
	set iface down-script /usr/local/sbin/vpn-linkdown
1370
	set iface idle 0
1371
	set iface disable on-demand
1372
	set iface disable proxy-arp
1373
	set iface enable tcpmssfix
1374
	set iface mtu 1500
1375
	set link no pap chap
1376
	{$paporchap}
1377
	set link keep-alive 60 180
1378
	set ipcp yes vjcomp
1379
	set ipcp no vjcomp
1380
	set link max-redial -1
1381
	set link mtu 1492
1382
	set link mru 1492
1383
	set ccp yes mpp-e40
1384
	set ccp yes mpp-e128
1385
	set ccp yes mpp-stateless
1386
	set link latency 1
1387
	#set ipcp dns 10.10.1.3
1388
	#set bundle accept encryption
1389

    
1390
EOD;
1391

    
1392
			if (!empty($pppoecfg['dns1'])) {
1393
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1394
				if (!empty($pppoecfg['dns2']))
1395
					$mpdconf .= " " . $pppoecfg['dns2'];
1396
				$mpdconf .= "\n";
1397
			} elseif (isset ($config['dnsmasq']['enable'])) {
1398
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1399
				if ($syscfg['dnsserver'][0])
1400
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1401
				$mpdconf .= "\n";
1402
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1403
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1404
			}
1405

    
1406
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1407
				$radiusport = "";
1408
				$radiusacctport = "";
1409
				if (isset($pppoecfg['radius']['server']['port']))
1410
					$radiusport = $pppoecfg['radius']['server']['port'];
1411
				if (isset($pppoecfg['radius']['server']['acctport']))
1412
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1413
				$mpdconf .=<<<EOD
1414
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1415
	set radius retries 3
1416
	set radius timeout 10
1417
	set auth enable radius-auth
1418

    
1419
EOD;
1420

    
1421
				if (isset ($pppoecfg['radius']['accounting'])) {
1422
					$mpdconf .=<<<EOD
1423
	set auth enable radius-acct
1424

    
1425
EOD;
1426
				}
1427
			}
1428

    
1429
			fwrite($fd, $mpdconf);
1430
			fclose($fd);
1431
			unset($mpdconf);
1432

    
1433
			/* write mpd.links */
1434
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1435
			if (!$fd) {
1436
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1437
				return 1;
1438
			}
1439

    
1440
			$mpdlinks = "";
1441

    
1442
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1443
				$mpdlinks .=<<<EOD
1444
			
1445
poes{$pppoecfg['pppoeid']}{$i}:
1446
	set phys type pppoe
1447
        set pppoe iface {$pppoe_interface}
1448
        set pppoe service "*"
1449
        set pppoe disable originate
1450
        set pppoe enable incoming
1451

    
1452
EOD;
1453
			}
1454

    
1455
			fwrite($fd, $mpdlinks);
1456
			fclose($fd);
1457
			unset($mpdlinks);
1458

    
1459
			if ($pppoecfg['username']) {
1460
				/* write mpd.secret */
1461
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1462
				if (!$fd) {
1463
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1464
					return 1;
1465
				}
1466

    
1467
				$mpdsecret = "\n\n";
1468

    
1469
				if (!empty($pppoecfg['username'])) {
1470
					$item = explode(" ", $pppoecfg['username']);
1471
					foreach($item as $userdata) {
1472
						$data = explode(":", $userdata);
1473
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1474
					}
1475
				}
1476

    
1477
				fwrite($fd, $mpdsecret);
1478
				fclose($fd);
1479
				unset($mpdsecret);
1480
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1481
			}
1482

    
1483
			/* Check if previous instance is still up */
1484
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid"))
1485
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1486

    
1487
			/* Get support for netgraph(4) from the nic */
1488
			pfSense_ngctl_attach(".", $pppoe_interface);
1489
			/* fire up mpd */
1490
			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");
1491

    
1492
			break;
1493
	}
1494

    
1495
	if ($g['booting'])
1496
		echo gettext("done") . "\n";
1497

    
1498
	return 0;
1499
}
1500

    
1501
function vpn_l2tp_configure() {
1502
	global $config, $g;
1503

    
1504
	$syscfg = $config['system'];
1505
	$l2tpcfg = $config['l2tp'];
1506

    
1507
	/* create directory if it does not exist */
1508
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1509
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1510

    
1511
	if ($g['booting']) {
1512
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1513
			return 0;
1514

    
1515
		echo gettext("Configuring l2tp VPN service... ");
1516
	} else {
1517
		/* kill mpd */
1518
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1519

    
1520
		/* wait for process to die */
1521
		sleep(8);
1522

    
1523
	}
1524

    
1525
	/* make sure l2tp-vpn directory exists */
1526
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1527
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1528

    
1529
	switch ($l2tpcfg['mode']) {
1530

    
1531
		case 'server' :
1532
			if ($l2tpcfg['paporchap'] == "chap")
1533
				$paporchap = "set link enable chap";
1534
			else
1535
				$paporchap = "set link enable pap";
1536

    
1537
			/* write mpd.conf */
1538
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1539
			if (!$fd) {
1540
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1541
				return 1;
1542
			}
1543
			$mpdconf = "\n\n";
1544
			$mpdconf .=<<<EOD
1545
l2tps:
1546

    
1547
EOD;
1548

    
1549
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1550
				$mpdconf .= "	load l2tp{$i}\n";
1551
			}
1552

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

    
1555
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1556

    
1557
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1558
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1559
				} else {
1560
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1561
				}
1562

    
1563
				$mpdconf .=<<<EOD
1564

    
1565
l2tp{$i}:
1566
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1567
	{$isssue_ip_type}
1568
	load l2tp_standard
1569

    
1570
EOD;
1571
			}
1572

    
1573
			$mpdconf .=<<<EOD
1574

    
1575
l2tp_standard:
1576
        set bundle disable multilink
1577
        set bundle enable compression
1578
        set bundle yes crypt-reqd
1579
        set ipcp yes vjcomp
1580
        # set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1581
        set ccp yes mppc
1582
        set iface disable on-demand
1583
        set iface enable proxy-arp
1584
	set iface up-script /usr/local/sbin/vpn-linkup
1585
	set iface down-script /usr/local/sbin/vpn-linkdown
1586
        set link yes acfcomp protocomp
1587
        set link no pap chap
1588
        set link enable chap
1589
        set link keep-alive 10 180
1590

    
1591
EOD;
1592

    
1593
			if (is_ipaddr($l2tpcfg['wins'])) {
1594
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1595
			}
1596
			if (is_ipaddr($l2tpcfg['dns1'])) {
1597
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1598
				if (is_ipaddr($l2tpcfg['dns2']))
1599
					$mpdconf .= " " . $l2tpcfg['dns2'];
1600
				$mpdconf .= "\n";
1601
			} elseif (isset ($config['dnsmasq']['enable'])) {
1602
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1603
				if ($syscfg['dnsserver'][0])
1604
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1605
				$mpdconf .= "\n";
1606
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1607
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1608
			}
1609

    
1610
			if (isset ($l2tpcfg['radius']['enable'])) {
1611
				$mpdconf .=<<<EOD
1612
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1613
	set radius retries 3
1614
	set radius timeout 10
1615
	set auth enable radius-auth
1616

    
1617
EOD;
1618

    
1619
				if (isset ($l2tpcfg['radius']['accounting'])) {
1620
					$mpdconf .=<<<EOD
1621
	set auth enable radius-acct
1622

    
1623
EOD;
1624
				}
1625
			}
1626

    
1627
			fwrite($fd, $mpdconf);
1628
			fclose($fd);
1629
			unset($mpdconf);
1630

    
1631
			/* write mpd.links */
1632
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1633
			if (!$fd) {
1634
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1635
				return 1;
1636
			}
1637

    
1638
			$mpdlinks = "";
1639

    
1640
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1641
				$mpdlinks .=<<<EOD
1642

    
1643
l2tp{$i}:
1644
	set link type l2tp
1645
        set l2tp enable incoming
1646
        set l2tp disable originate
1647

    
1648
EOD;
1649
			if (!empty($l2tpcfg['secret']))
1650
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1651
			}
1652

    
1653
			fwrite($fd, $mpdlinks);
1654
			fclose($fd);
1655
			unset($mpdlinks);
1656

    
1657
			/* write mpd.secret */
1658
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1659
			if (!$fd) {
1660
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1661
				return 1;
1662
			}
1663

    
1664
			$mpdsecret = "\n\n";
1665

    
1666
			if (is_array($l2tpcfg['user'])) {
1667
				foreach ($l2tpcfg['user'] as $user)
1668
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1669
			}
1670

    
1671
			fwrite($fd, $mpdsecret);
1672
			fclose($fd);
1673
			unset($mpdsecret);
1674
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1675

    
1676
			vpn_netgraph_support();
1677

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

    
1681
			break;
1682

    
1683
		case 'redir' :
1684
			break;
1685
	}
1686

    
1687
	if ($g['booting'])
1688
		echo "done\n";
1689

    
1690
	return 0;
1691
}
1692

    
1693
/* Walk the tunnels for hostname endpoints. If the hostnames 
1694
 * resolve to a different IP now compared to the DNS cache
1695
 * we reload the policies if the endpoint has changed */
1696
function vpn_ipsec_refresh_policies() {
1697
	global $config;
1698
	global $g;
1699

    
1700
	$ipseccfg = $config['ipsec'];
1701
	$a_phase1 = $config['ipsec']['phase1'];
1702
	$a_phase2 = $config['ipsec']['phase2'];
1703

    
1704
	if (isset($ipseccfg['disable'])) {
1705
		return true;
1706
	}
1707

    
1708
	/* Walk the Ipsec tunnel array */
1709
	if (!is_array($a_phase1) || (!count($a_phase1)))
1710
		return;
1711

    
1712
	foreach ($a_phase1 as $phase1) {
1713
		if (isset($phase1['disabled']))
1714
			continue;
1715
		if (is_ipaddr($phase1['remote-gateway']))
1716
			continue;
1717
		if (!is_ipaddr($phase1['remote-gateway'])) {
1718
			$dnscache = compare_hostname_to_dnscache($phase1['remote-gateway']);
1719
			$dnscache = trim($dnscache);
1720
			/* we should have the old IP addresses in the dnscache now */
1721
			if(!empty($dnscache)) {
1722
				$oldphase1 = $phase1;
1723
				$oldphase1['remote-gateway'] = $dnscache;
1724
				/* now we need to find all tunnels for this host */
1725
				if (!is_array($a_phase2) || (!count($a_phase2)))
1726
					continue;
1727
				foreach ($a_phase2 as $phase2) {
1728
					if ($phase2['ikeid'] == $phase1['ikeid'])
1729
						reload_tunnel_spd_policy ($phase1, $phase2, $oldphase1, $oldphase2);
1730
				}
1731
			}
1732
		}
1733
	}
1734

    
1735
	/* process all generated temporary spd.conf files */
1736
	$tmpfiles = glob("{$g['tmp_path']}/spd.conf.reload.*");
1737
	foreach($tmpfiles as $tmpfile) {
1738
		$ret = mwexec("/usr/local/sbin/setkey -f {$tmpfile} 2>&1", false);
1739
		if ($ret == 0)
1740
			unlink_if_exists($tmpfile);
1741
		else {
1742
			$tmpfile = basename($tmpfile);
1743
			@rename("{$g['tmp_path']}/{$tmpfile}", ("{$g['tmp_path']}/failed.{$tmpfile}"));
1744
		}
1745
	}
1746
}
1747

    
1748
/* remove SPD polices */
1749
function remove_tunnel_spd_policy($phase1,$phase2) {
1750
	global $config;
1751
	global $g;
1752

    
1753
	if (!$phase1 || !$phase2)
1754
		return false;
1755

    
1756
	if (isset($phase1['mobile']))
1757
		return false;
1758

    
1759
	$spdconf = "";
1760
	$ep = ipsec_get_phase1_src($phase1);
1761
	$gw = trim($phase1['remote-gateway']);
1762
	$sad_arr = ipsec_dump_sad();
1763
	$remote_subnet = ipsec_idinfo_to_cidr($phase2['remoteid'], false, $phase2['mode']);
1764

    
1765
	if (!empty($phase2['natlocalid']))
1766
		$local_subnet = ipsec_idinfo_to_cidr($phase2['natlocalid'], false, $phase2['mode']);
1767
	else
1768
		$local_subnet = ipsec_idinfo_to_cidr($phase2['localid'], false, $phase2['mode']);
1769

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

    
1775
	$spdconf .= "spddelete {$family} {$local_subnet} " .
1776
		"{$remote_subnet} any -P out ipsec " .
1777
		"{$phase2['protocol']}/tunnel/{$ep}-" .
1778
		"{$gw}/unique;\n";
1779

    
1780
	$spdconf .= "spddelete {$family} {$remote_subnet} " .
1781
		"{$local_subnet} any -P in ipsec " .
1782
		"{$phase2['protocol']}/tunnel/{$gw}-" .
1783
		"{$ep}/unique;\n";
1784

    
1785
	/* zap any existing SA entries */
1786
	foreach($sad_arr as $sad) {
1787
		if(($sad['dst'] == $ep) && ($sad['src'] == $gw))
1788
			$spdconf .= "delete {$family} {$ep} {$gw} {$phase2['protocol']} 0x{$sad['spi']};\n";
1789
		if(($sad['src'] == $ep) && ($sad['dst'] == $_gw))
1790
			$spdconf .= "delete {$family} {$gw} {$ep} {$phase2['protocol']} 0x{$sad['spi']};\n";
1791
	}
1792

    
1793
	log_error(sprintf(gettext("Removing SPDs from tunnel gw '%1\$s'. Local Subnet '%2\$s' and Remote Subnet '%3\$s'. Reloading policy"),$phase1['remote-gateway'],$local_subnet,$remote_subnet));
1794

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

    
1801
	return true;
1802
}
1803

    
1804
/* reloads the tunnel configuration for a tunnel item
1805
 * Will remove and add SPD polices */
1806
function reload_tunnel_spd_policy($phase1, $phase2, $old_phase1, $old_phase2) {
1807
	global $config;
1808
	global $g;
1809

    
1810
	/* if we are not passed a old tunnel array we create one */
1811
	if(empty($old_phase1)) {
1812
		$old_phase1 = $phase1;
1813
	}
1814
	if(empty($old_phase2)) {
1815
		$old_phase2 = $phase2;
1816
	}
1817

    
1818
	$sad_arr = ipsec_dump_sad();
1819

    
1820
	$ep = ipsec_get_phase1_src($phase1);
1821
	$local_subnet = ipsec_idinfo_to_cidr($phase2['localid'], false, $phase2['mode']);
1822
	$remote_subnet = ipsec_idinfo_to_cidr($phase2['remoteid'], false, $phase2['mode']);
1823

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

    
1827
	$old_ep = ipsec_get_phase1_src($old_phase1);
1828
	$old_local_subnet = ipsec_idinfo_to_cidr($old_phase2['localid'], false, $old_phase2['mode']);
1829
	$old_remote_subnet = ipsec_idinfo_to_cidr($old_phase2['remoteid'], false, $old_phase2['mode']);
1830

    
1831
	/* see if this tunnel has a hostname for the remote-gateway, and if so,
1832
	 * try to resolve it now and add it to the list for filterdns */
1833
	$rgip = "";
1834
	if (!is_ipaddr($phase1['remote-gateway'])) {
1835
		if(! $g['booting']) {
1836
			$rgip = resolve_retry($phase1['remote-gateway']);
1837
			add_hostname_to_watch($phase1['remote-gateway']);
1838
		} else {
1839
			add_hostname_to_watch($phase1['remote-gateway']);
1840
		}
1841
		if (!is_ipaddr($rgip)) {
1842
			log_error("Could not determine VPN endpoint for '{$phase1['descr']}'");
1843
			return false;
1844
		}
1845
	} else {
1846
		$rgip = $phase1['remote-gateway'];
1847
	}
1848
	if (!$ep) {
1849
		log_error(sprintf(gettext("Could not determine VPN endpoint for '%s'"), $phase1['descr']));
1850
		return false;
1851
	}
1852

    
1853
	if((!is_ipaddr($old_ep)) || (! is_ipaddr($ep))) {
1854
		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));
1855
	}
1856
	if((! is_ipaddr($rgip)) || (! is_ipaddr($old_gw))) {
1857
		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));
1858
	}
1859

    
1860
	$spdconf = "";
1861
	/* Delete old SPD policies if there are changes between the old and new */
1862
	if(($phase1 != $old_phase1) || ($phase2 != $old_phase2)) {
1863
		if($old_phase2['mode'] == "tunnel6")
1864
			$family = "-6";
1865
		else
1866
			$family = "-4";
1867

    
1868
		$spdconf .= "spddelete {$family} {$old_local_subnet} " .
1869
			"{$old_remote_subnet} any -P out ipsec " .
1870
			"{$old_phase2['protocol']}/tunnel/{$old_ep}-" .
1871
			"{$old_gw}/unique;\n";
1872
		if (!empty($old_phase2['natlocalid']))
1873
			$old_local_subnet = ipsec_idinfo_to_cidr($old_phase2['natlocalid'], false, $old_phase2['mode']);
1874
		$spdconf .= "spddelete {$family} {$old_remote_subnet} " .
1875
			"{$old_local_subnet} any -P in ipsec " .
1876
			"{$old_phase2['protocol']}/tunnel/{$old_gw}-" .
1877
			"{$old_ep}/unique;\n";
1878

    
1879
		/* zap any existing SA entries */
1880
		foreach($sad_arr as $sad) {
1881
			if(($sad['dst'] == $old_ep) && ($sad['src'] == $old_gw)) {
1882
				$spdconf .= "delete {$family} {$old_ep} {$old_gw} {$old_phase2['protocol']} 0x{$sad['spi']};\n";
1883
			}
1884
			if(($sad['src'] == $oldep) && ($sad['dst'] == $old_gw)) {
1885
				$spdconf .= "delete {$family} {$old_gw} {$old_ep} {$old_phase2['protocol']} 0x{$sad['spi']};\n";
1886
			}
1887
		}
1888
	}
1889

    
1890
	if($phase2['mode'] == "tunnel6")
1891
		$family = "-6";
1892
	else
1893
		$family = "-4";
1894

    
1895
	/* Create new SPD entries for the new configuration */
1896
	/* zap any existing SA entries beforehand */
1897
	foreach($sad_arr as $sad) {
1898
		if(($sad['dst'] == $ep) && ($sad['src'] == $rgip)) {
1899
			$spdconf .= "delete {$family} {$rgip} {$ep} {$phase2['protocol']} 0x{$sad['spi']};\n";
1900
		}
1901
		if(($sad['src'] == $ep) && ($sad['dst'] == $rgip)) {
1902
			$spdconf .= "delete {$family} {$ep} {$rgip} {$phase2['protocol']} 0x{$sad['spi']};\n";
1903
		}
1904
	}
1905
	/* add new SPD policies to replace them */
1906
	if (!isset($phase1['disabled'])) {
1907
		$spdconf .= "spdadd {$family} {$local_subnet} " .
1908
			"{$remote_subnet} any -P out ipsec " .
1909
			"{$phase2['protocol']}/tunnel/{$ep}-" .
1910
			"{$rgip}/unique;\n";
1911

    
1912
		if (!empty($phase2['natlocalid']))
1913
			$local_subnet = ipsec_idinfo_to_cidr($phase2['natlocalid'], false, $phase2['mode']);
1914
		$spdconf .= "spdadd {$family} {$remote_subnet} " .
1915
			"{$local_subnet} any -P in ipsec " .
1916
			"{$phase2['protocol']}/tunnel/{$rgip}-" .
1917
			"{$ep}/unique;\n";
1918
	}
1919

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

    
1922
	$now = time();
1923
	$spdfile = tempnam("{$g['tmp_path']}", "spd.conf.reload.{$now}.");
1924
	/* generate temporary spd.conf */
1925
	@file_put_contents($spdfile, $spdconf);
1926
	unset($spdconf);
1927
	return true;
1928
}
1929

    
1930
function vpn_ipsec_configure_preferoldsa() {
1931
	global $config;
1932
	if(isset($config['ipsec']['preferoldsa']))
1933
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
1934
	else
1935
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
1936
}
1937

    
1938
?>
(57-57/66)