Project

General

Profile

Download (56 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 true;
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
			$ipsecpinghosts = "";
149
			foreach ($a_phase1 as $ph1ent) {
150
				if (isset($ph1ent['disabled']))
151
					continue;
152

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

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

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

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

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

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

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

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

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

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

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

    
259
		if (is_array($a_phase1) && count($a_phase1)) {
260
			foreach ($a_phase1 as $ph1ent) {
261

    
262
				if (isset($ph1ent['disabled']))
263
					continue;
264

    
265
				if (strstr($ph1ent['authentication_method'],'rsa'))
266
					continue;
267

    
268
				$peerid_type = $ph1ent['peerid_type'];
269

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

    
276
					case "address";
277
						$peerid_data = $ph1ent['peerid_data'];
278
						break;
279

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

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

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

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

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

    
314
			$racoonconf .= "# This file is automatically generated. Do not edit\n";			
315
			$racoonconf .= "path pre_shared_key \"{$g['varetc_path']}/ipsec/psk.txt\";\n\n";
316
			$racoonconf .= "path certificate  \"{$g['varetc_path']}/ipsec\";\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 (!empty($a_client['user_source']))
337
					$racoonconf .= "\tauth_source external;\n";
338
				if (!empty($a_client['group_source']) && $a_client['group_source'] != "none")
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
					if (empty($a_client['dns_split']))
393
						$racoonconf .= "\tsplit_dns \"{$a_client['dns_domain']}\";\n";
394
				}
395

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

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

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

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

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

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

    
442
					if (isset($ph1ent['disabled']))
443
						continue;
444

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

    
448
					$ikeid = $ph1ent['ikeid'];
449

    
450
					$ep = ipsec_get_phase1_src($ph1ent);
451
					if (!$ep)
452
						continue;
453

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

    
460
					$myid_type = $ph1ent['myid_type'];
461

    
462
					switch ($myid_type) {
463

    
464
						case "myaddress":
465
							$myid_type = "address";
466
							$myid_data = $ep;
467
							break;
468

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

    
474
						case "address";
475
							$myid_data = $ph1ent['myid_data'];
476
							break;
477

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

    
488
					$peerid_type = $ph1ent['peerid_type'];
489

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

    
496
						case "address";
497
							$peerid_data = $ph1ent['peerid_data'];
498
							break;
499

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

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

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

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

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

    
543
					$certline = '';
544

    
545
					if (strstr($authmethod,'rsa')) {
546

    
547
						$cert = lookup_cert($ph1ent['certref']);
548

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

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

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

    
564
						chmod($certpath, 0600);
565

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

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

    
575
						chmod($keypath, 0600);
576

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

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

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

    
592
						$certline = "certificate_type x509 \"{$certfile}\" \"{$keyfile}\";";
593

    
594
					}
595

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

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

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

    
613
					/* add remote section to configuration */
614

    
615
					$racoonconf .=<<<EOD
616

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

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

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

    
654
				/* begin sainfo */
655
				foreach ($a_phase2 as $ph2ent) {
656

    
657
					$ikeid = $ph2ent['ikeid'];
658

    
659
					if( !ipsec_lookup_phase1($ph2ent,$ph1ent))
660
						continue;
661

    
662
					if (isset($ph1ent['disabled']))
663
						continue;
664

    
665
					if (isset($ph2ent['disabled']))
666
						continue;
667

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

    
671
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
672

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

    
705
						if (!isset($ph2ent['mobile'])) {
706
							$remoteid_type = $ph2ent['remoteid']['type'];
707
							if ($remoteid_type != "address")
708
								$remoteid_type = "subnet";
709

    
710
							$remoteid_data = ipsec_idinfo_to_cidr($ph2ent['remoteid']);
711
							$remoteid_spec = $remoteid_type." ".$remoteid_data." any";
712
						} else
713
							$remoteid_spec = "anonymous";
714

    
715
					} else {
716
						$rgip = $rgmap[$ph1ent['remote-gateway']];
717

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

    
735
					if($ph2ent['protocol'] == 'esp') {
736

    
737
						$ealgos = '';
738

    
739
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
740

    
741
							$ealg_id = $ealg['name'];
742
							$ealg_kl = $ealg['keylen'];
743

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

    
779
						$ealgosline = "encryption_algorithm {$ealgos};";
780

    
781
					} else {
782

    
783
						$ealgosline = "encryption_algorithm null_enc;";
784
					}
785

    
786
					$halgos = join(",", $ph2ent['hash-algorithm-option']);
787
					$halgosline = "authentication_algorithm {$halgos};";
788

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

    
798
					$lifeline = '';
799
					if ($ph2ent['lifetime'])
800
						$lifeline = "lifetime time {$ph2ent['lifetime']} secs;";
801

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

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

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

    
849
			foreach ($a_phase2 as $ph2ent) {
850

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

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

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

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

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

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

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

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

    
880
					if($ph2ent['mode'] == "tunnel6")
881
						$family = "-6";
882
					else
883
						$family = "-4";
884

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

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

    
897
				} else {
898

    
899
					$localid_data = ipsec_get_phase1_src($ph1ent);
900
					$remoteid_data = $rgmap[$ph1ent['remote-gateway']];
901

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

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

    
908
				}
909

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

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

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

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

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

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

    
990
		if ($g['booting'])
991
			echo "done\n";
992
	}
993

    
994
	return 0;
995
}
996

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

    
1007
	$ipseccfg = $config['ipsec'];
1008

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

    
1012
	/* wait for process to die */
1013
	sleep(4);
1014

    
1015
	/* kill racoon forcefully */
1016
	if (is_process_running("racoon"))
1017
		mwexec("/usr/bin/killall -9 racoon", true);
1018

    
1019
	/* wait for flushing to finish */
1020
	sleep(1);
1021

    
1022
	/* if ipsec is enabled, start up again */
1023
	if (isset($ipseccfg['enable'])) {
1024
		log_error(gettext("Forcefully reloading IPsec racoon daemon"));
1025
		vpn_ipsec_configure();
1026
	}
1027
}
1028

    
1029
/* master setup for vpn (mpd) */
1030
function vpn_setup() {
1031
	global $g;
1032

    
1033
	if ($g['platform'] == 'jail')
1034
		return;
1035

    
1036
	/* start pptpd */
1037
	vpn_pptpd_configure();
1038

    
1039
	/* start pppoe server */
1040
	vpn_pppoes_configure();
1041

    
1042
	/* setup l2tp */
1043
	vpn_l2tp_configure();
1044
}
1045

    
1046
function vpn_netgraph_support() {
1047
	$iflist = get_configured_interface_list();
1048
	foreach ($iflist as $iface) {
1049
		$realif = get_real_interface($iface);
1050
		/* Get support for netgraph(4) from the nic */
1051
		$ifinfo = pfSense_get_interface_addresses($realif);
1052
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
1053
                	pfSense_ngctl_attach(".", $realif);
1054
	}
1055
}
1056

    
1057
function vpn_pptpd_configure() {
1058
	global $config, $g;
1059

    
1060
	$syscfg = $config['system'];
1061
	$pptpdcfg = $config['pptpd'];
1062

    
1063
	if ($g['booting']) {
1064
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
1065
			return 0;
1066

    
1067
		echo gettext("Configuring PPTP VPN service... ");
1068
	} else {
1069
		/* kill mpd */
1070
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1071

    
1072
		/* wait for process to die */
1073
		sleep(3);
1074

    
1075
		if (is_process_running("mpd -b")) {
1076
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1077
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
1078
		}
1079

    
1080
		/* remove mpd.conf, if it exists */
1081
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
1082
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
1083
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
1084
	}
1085

    
1086
	if (empty($pptpdcfg['n_pptp_units'])) {
1087
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
1088
		return; 
1089
	}
1090

    
1091
	/* make sure pptp-vpn directory exists */
1092
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
1093
		mkdir("{$g['varetc_path']}/pptp-vpn");
1094

    
1095
	switch ($pptpdcfg['mode']) {
1096
		case 'server' :
1097
			/* write mpd.conf */
1098
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1099
			if (!$fd) {
1100
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
1101
				return 1;
1102
			}
1103

    
1104
			$mpdconf = <<<EOD
1105
pptps:
1106

    
1107
EOD;
1108

    
1109
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1110
				$mpdconf .= "	load pt{$i}\n";
1111
			}
1112

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

    
1115
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1116

    
1117
				$mpdconf .= <<<EOD
1118

    
1119
pt{$i}:
1120
	new -i pptpd{$i} pt{$i} pt{$i}
1121
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1122
	load pts
1123

    
1124
EOD;
1125
			}
1126

    
1127
			$mpdconf .=<<<EOD
1128

    
1129
pts:
1130
	set iface disable on-demand
1131
	set iface enable proxy-arp
1132
	set iface enable tcpmssfix
1133
	set iface idle 1800
1134
	set iface up-script /usr/local/sbin/vpn-linkup
1135
	set iface down-script /usr/local/sbin/vpn-linkdown
1136
	set bundle enable multilink
1137
	set bundle enable crypt-reqd
1138
	set link yes acfcomp protocomp
1139
	set link no pap chap
1140
	set link enable chap-msv2
1141
	set link mtu 1460
1142
	set link keep-alive 10 60
1143
	set ipcp yes vjcomp
1144
	set bundle enable compression
1145
	set ccp yes mppc
1146
	set ccp yes mpp-e128
1147
	set ccp yes mpp-stateless
1148

    
1149
EOD;
1150

    
1151
			if (!isset ($pptpdcfg['req128'])) {
1152
				$mpdconf .=<<<EOD
1153
	set ccp yes mpp-e40
1154
	set ccp yes mpp-e56
1155

    
1156
EOD;
1157
			}
1158

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

    
1162
			if (!empty($pptpdcfg['dns1'])) {
1163
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1164
				if (!empty($pptpdcfg['dns2']))
1165
					$mpdconf .= " " . $pptpdcfg['dns2'];
1166
				$mpdconf .= "\n";
1167
			} elseif (isset ($config['dnsmasq']['enable'])) {
1168
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1169
				if ($syscfg['dnsserver'][0])
1170
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1171
				$mpdconf .= "\n";
1172
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1173
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1174
			}
1175

    
1176
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1177
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1178
				$acctport = $authport + 1;
1179
				$mpdconf .=<<<EOD
1180
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1181

    
1182
EOD;
1183
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1184
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1185
				$acctport = $authport + 1;
1186
				$mpdconf .=<<<EOD
1187
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1188

    
1189
EOD;
1190
			}
1191
			$mpdconf .=<<<EOD
1192
	set radius retries 3
1193
	set radius timeout 10
1194
	set auth enable radius-auth
1195

    
1196
EOD;
1197

    
1198
				if (isset ($pptpdcfg['radius']['accounting'])) {
1199
					$mpdconf .=<<<EOD
1200
	set auth enable radius-acct
1201
	set radius acct-update 300
1202

    
1203
EOD;
1204
				}
1205
			}
1206

    
1207
			fwrite($fd, $mpdconf);
1208
			fclose($fd);
1209
			unset($mpdconf);
1210

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

    
1218
			$mpdlinks = "";
1219

    
1220
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1221
				$mpdlinks .=<<<EOD
1222

    
1223
pt{$i}:
1224
	set link type pptp
1225
	set pptp enable incoming
1226
	set pptp disable originate
1227
	set pptp disable windowing
1228

    
1229
EOD;
1230
			}
1231

    
1232
			fwrite($fd, $mpdlinks);
1233
			fclose($fd);
1234
			unset($mpdlinks);
1235

    
1236
			/* write mpd.secret */
1237
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1238
			if (!$fd) {
1239
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1240
				return 1;
1241
			}
1242

    
1243
			$mpdsecret = "";
1244

    
1245
			if (is_array($pptpdcfg['user'])) {
1246
				foreach ($pptpdcfg['user'] as $user) {
1247
					$pass = str_replace('\\', '\\\\', $user['password']);
1248
					$pass = str_replace('"', '\"', $pass);
1249
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1250
				}
1251
			}
1252

    
1253
			fwrite($fd, $mpdsecret);
1254
			fclose($fd);
1255
			unset($mpdsecret);
1256
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1257

    
1258
			vpn_netgraph_support();
1259

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

    
1263
			break;
1264

    
1265
		case 'redir' :
1266
			break;
1267
	}
1268

    
1269
	if ($g['booting'])
1270
		echo "done\n";
1271

    
1272
	return 0;
1273
}
1274

    
1275
function vpn_pppoes_configure() {
1276
	global $config;
1277

    
1278
	if (is_array($config['pppoes']['pppoe'])) {
1279
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1280
			vpn_pppoe_configure($pppoe);
1281
	}
1282
}
1283

    
1284
function vpn_pppoe_configure(&$pppoecfg) {
1285
	global $config, $g;
1286

    
1287
	$syscfg = $config['system'];
1288

    
1289
	/* create directory if it does not exist */
1290
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1291
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1292

    
1293
	if ($g['booting']) {
1294
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1295
			return 0;
1296

    
1297
		echo gettext("Configuring PPPoE VPN service... ");
1298
	} else {
1299
		/* kill mpd */
1300
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1301

    
1302
		/* wait for process to die */
1303
		sleep(2);
1304

    
1305
	}
1306

    
1307
	switch ($pppoecfg['mode']) {
1308

    
1309
		case 'server' :
1310

    
1311
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1312

    
1313
			if ($pppoecfg['paporchap'] == "chap")
1314
				$paporchap = "set link enable chap";
1315
			else
1316
				$paporchap = "set link enable pap";
1317

    
1318
			/* write mpd.conf */
1319
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1320
			if (!$fd) {
1321
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1322
				return 1;
1323
			}
1324
			$mpdconf = "\n\n";
1325
			$mpdconf .= "poes:\n";
1326

    
1327
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1328
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1329
			}
1330

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

    
1333
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1334

    
1335
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1336
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1337
				} else {
1338
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1339
				}
1340

    
1341
				$mpdconf .=<<<EOD
1342

    
1343
poes{$pppoecfg['pppoeid']}{$i}:
1344
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1345
	{$isssue_ip_type}
1346
	load pppoe_standard
1347

    
1348
EOD;
1349
			}
1350

    
1351
			$mpdconf .=<<<EOD
1352

    
1353
pppoe_standard:
1354
	set bundle no multilink
1355
	set bundle enable compression
1356
	set auth max-logins 1
1357
	set iface up-script /usr/local/sbin/vpn-linkup
1358
	set iface down-script /usr/local/sbin/vpn-linkdown
1359
	set iface idle 0
1360
	set iface disable on-demand
1361
	set iface disable proxy-arp
1362
	set iface enable tcpmssfix
1363
	set iface mtu 1500
1364
	set link no pap chap
1365
	{$paporchap}
1366
	set link keep-alive 60 180
1367
	set ipcp yes vjcomp
1368
	set ipcp no vjcomp
1369
	set link max-redial -1
1370
	set link mtu 1492
1371
	set link mru 1492
1372
	set ccp yes mpp-e40
1373
	set ccp yes mpp-e128
1374
	set ccp yes mpp-stateless
1375
	set link latency 1
1376
	#set ipcp dns 10.10.1.3
1377
	#set bundle accept encryption
1378

    
1379
EOD;
1380

    
1381
			if (!empty($pppoecfg['dns1'])) {
1382
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1383
				if (!empty($pppoecfg['dns2']))
1384
					$mpdconf .= " " . $pppoecfg['dns2'];
1385
				$mpdconf .= "\n";
1386
			} elseif (isset ($config['dnsmasq']['enable'])) {
1387
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1388
				if ($syscfg['dnsserver'][0])
1389
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1390
				$mpdconf .= "\n";
1391
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1392
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1393
			}
1394

    
1395
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1396
				$radiusport = "";
1397
				$radiusacctport = "";
1398
				if (isset($pppoecfg['radius']['server']['port']))
1399
					$radiusport = $pppoecfg['radius']['server']['port'];
1400
				if (isset($pppoecfg['radius']['server']['acctport']))
1401
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1402
				$mpdconf .=<<<EOD
1403
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1404
	set radius retries 3
1405
	set radius timeout 10
1406
	set auth enable radius-auth
1407

    
1408
EOD;
1409

    
1410
				if (isset ($pppoecfg['radius']['accounting'])) {
1411
					$mpdconf .=<<<EOD
1412
	set auth enable radius-acct
1413

    
1414
EOD;
1415
				}
1416
			}
1417

    
1418
			fwrite($fd, $mpdconf);
1419
			fclose($fd);
1420
			unset($mpdconf);
1421

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

    
1429
			$mpdlinks = "";
1430

    
1431
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1432
				$mpdlinks .=<<<EOD
1433
			
1434
poes{$pppoecfg['pppoeid']}{$i}:
1435
	set phys type pppoe
1436
        set pppoe iface {$pppoe_interface}
1437
        set pppoe service "*"
1438
        set pppoe disable originate
1439
        set pppoe enable incoming
1440

    
1441
EOD;
1442
			}
1443

    
1444
			fwrite($fd, $mpdlinks);
1445
			fclose($fd);
1446
			unset($mpdlinks);
1447

    
1448
			if ($pppoecfg['username']) {
1449
				/* write mpd.secret */
1450
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1451
				if (!$fd) {
1452
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1453
					return 1;
1454
				}
1455

    
1456
				$mpdsecret = "\n\n";
1457

    
1458
				if (!empty($pppoecfg['username'])) {
1459
					$item = explode(" ", $pppoecfg['username']);
1460
					foreach($item as $userdata) {
1461
						$data = explode(":", $userdata);
1462
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1463
					}
1464
				}
1465

    
1466
				fwrite($fd, $mpdsecret);
1467
				fclose($fd);
1468
				unset($mpdsecret);
1469
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1470
			}
1471

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

    
1476
			/* Get support for netgraph(4) from the nic */
1477
			pfSense_ngctl_attach(".", $pppoe_interface);
1478
			/* fire up mpd */
1479
			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");
1480

    
1481
			break;
1482
	}
1483

    
1484
	if ($g['booting'])
1485
		echo gettext("done") . "\n";
1486

    
1487
	return 0;
1488
}
1489

    
1490
function vpn_l2tp_configure() {
1491
	global $config, $g;
1492

    
1493
	$syscfg = $config['system'];
1494
	$l2tpcfg = $config['l2tp'];
1495

    
1496
	/* create directory if it does not exist */
1497
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1498
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1499

    
1500
	if ($g['booting']) {
1501
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1502
			return 0;
1503

    
1504
		echo gettext("Configuring l2tp VPN service... ");
1505
	} else {
1506
		/* kill mpd */
1507
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1508

    
1509
		/* wait for process to die */
1510
		sleep(8);
1511

    
1512
	}
1513

    
1514
	/* make sure l2tp-vpn directory exists */
1515
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1516
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1517

    
1518
	switch ($l2tpcfg['mode']) {
1519

    
1520
		case 'server' :
1521
			if ($l2tpcfg['paporchap'] == "chap")
1522
				$paporchap = "set link enable chap";
1523
			else
1524
				$paporchap = "set link enable pap";
1525

    
1526
			/* write mpd.conf */
1527
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1528
			if (!$fd) {
1529
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1530
				return 1;
1531
			}
1532
			$mpdconf = "\n\n";
1533
			$mpdconf .=<<<EOD
1534
l2tps:
1535

    
1536
EOD;
1537

    
1538
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1539
				$mpdconf .= "	load l2tp{$i}\n";
1540
			}
1541

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

    
1544
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1545

    
1546
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1547
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1548
				} else {
1549
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1550
				}
1551

    
1552
				$mpdconf .=<<<EOD
1553

    
1554
l2tp{$i}:
1555
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1556
	{$isssue_ip_type}
1557
	load l2tp_standard
1558

    
1559
EOD;
1560
			}
1561

    
1562
			$mpdconf .=<<<EOD
1563

    
1564
l2tp_standard:
1565
        set bundle disable multilink
1566
        set bundle enable compression
1567
        set bundle yes crypt-reqd
1568
        set ipcp yes vjcomp
1569
        # set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1570
        set ccp yes mppc
1571
        set iface disable on-demand
1572
        set iface enable proxy-arp
1573
	set iface up-script /usr/local/sbin/vpn-linkup
1574
	set iface down-script /usr/local/sbin/vpn-linkdown
1575
        set link yes acfcomp protocomp
1576
        set link no pap chap
1577
        set link enable chap
1578
        set link keep-alive 10 180
1579

    
1580
EOD;
1581

    
1582
			if (is_ipaddr($l2tpcfg['wins'])) {
1583
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1584
			}
1585
			if (is_ipaddr($l2tpcfg['dns1'])) {
1586
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1587
				if (is_ipaddr($l2tpcfg['dns2']))
1588
					$mpdconf .= " " . $l2tpcfg['dns2'];
1589
				$mpdconf .= "\n";
1590
			} elseif (isset ($config['dnsmasq']['enable'])) {
1591
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1592
				if ($syscfg['dnsserver'][0])
1593
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1594
				$mpdconf .= "\n";
1595
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1596
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1597
			}
1598

    
1599
			if (isset ($l2tpcfg['radius']['enable'])) {
1600
				$mpdconf .=<<<EOD
1601
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1602
	set radius retries 3
1603
	set radius timeout 10
1604
	set auth enable radius-auth
1605

    
1606
EOD;
1607

    
1608
				if (isset ($l2tpcfg['radius']['accounting'])) {
1609
					$mpdconf .=<<<EOD
1610
	set auth enable radius-acct
1611

    
1612
EOD;
1613
				}
1614
			}
1615

    
1616
			fwrite($fd, $mpdconf);
1617
			fclose($fd);
1618
			unset($mpdconf);
1619

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

    
1627
			$mpdlinks = "";
1628

    
1629
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1630
				$mpdlinks .=<<<EOD
1631

    
1632
l2tp{$i}:
1633
	set link type l2tp
1634
        set l2tp enable incoming
1635
        set l2tp disable originate
1636

    
1637
EOD;
1638
			if (!empty($l2tpcfg['secret']))
1639
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1640
			}
1641

    
1642
			fwrite($fd, $mpdlinks);
1643
			fclose($fd);
1644
			unset($mpdlinks);
1645

    
1646
			/* write mpd.secret */
1647
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1648
			if (!$fd) {
1649
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1650
				return 1;
1651
			}
1652

    
1653
			$mpdsecret = "\n\n";
1654

    
1655
			if (is_array($l2tpcfg['user'])) {
1656
				foreach ($l2tpcfg['user'] as $user)
1657
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1658
			}
1659

    
1660
			fwrite($fd, $mpdsecret);
1661
			fclose($fd);
1662
			unset($mpdsecret);
1663
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1664

    
1665
			vpn_netgraph_support();
1666

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

    
1670
			break;
1671

    
1672
		case 'redir' :
1673
			break;
1674
	}
1675

    
1676
	if ($g['booting'])
1677
		echo "done\n";
1678

    
1679
	return 0;
1680
}
1681

    
1682
/* Walk the tunnels for hostname endpoints. If the hostnames 
1683
 * resolve to a different IP now compared to the DNS cache
1684
 * we reload the policies if the endpoint has changed */
1685
function vpn_ipsec_refresh_policies() {
1686
	global $config;
1687
	global $g;
1688

    
1689
	$ipseccfg = $config['ipsec'];
1690
	$a_phase1 = $config['ipsec']['phase1'];
1691
	$a_phase2 = $config['ipsec']['phase2'];
1692

    
1693
	if (isset($ipseccfg['disable'])) {
1694
		return true;
1695
	}
1696

    
1697
	/* Walk the Ipsec tunnel array */
1698
	if (!is_array($a_phase1) || (!count($a_phase1)))
1699
		return;
1700

    
1701
	foreach ($a_phase1 as $phase1) {
1702
		if (isset($phase1['disabled']))
1703
			continue;
1704
		if (is_ipaddr($phase1['remote-gateway']))
1705
			continue;
1706
		if (!is_ipaddr($phase1['remote-gateway'])) {
1707
			$dnscache = compare_hostname_to_dnscache($phase1['remote-gateway']);
1708
			$dnscache = trim($dnscache);
1709
			/* we should have the old IP addresses in the dnscache now */
1710
			if(!empty($dnscache)) {
1711
				$oldphase1 = $phase1;
1712
				$oldphase1['remote-gateway'] = $dnscache;
1713
				/* now we need to find all tunnels for this host */
1714
				if (!is_array($a_phase2) || (!count($a_phase2)))
1715
					continue;
1716
				foreach ($a_phase2 as $phase2) {
1717
					if ($phase2['ikeid'] == $phase1['ikeid'])
1718
						reload_tunnel_spd_policy ($phase1, $phase2, $oldphase1, $oldphase2);
1719
				}
1720
			}
1721
		}
1722
	}
1723

    
1724
	/* process all generated temporary spd.conf files */
1725
	$tmpfiles = glob("{$g['tmp_path']}/spd.conf.reload.*");
1726
	foreach($tmpfiles as $tmpfile) {
1727
		$ret = mwexec("/usr/local/sbin/setkey -f {$tmpfile} 2>&1", false);
1728
		if ($ret == 0)
1729
			unlink_if_exists($tmpfile);
1730
		else {
1731
			$tmpfile = basename($tmpfile);
1732
			@rename("{$g['tmp_path']}/{$tmpfile}", ("{$g['tmp_path']}/failed.{$tmpfile}"));
1733
		}
1734
	}
1735
}
1736

    
1737
/* remove SPD polices */
1738
function remove_tunnel_spd_policy($phase1,$phase2) {
1739
	global $config;
1740
	global $g;
1741

    
1742
	if (!$phase1 || !$phase2)
1743
		return false;
1744

    
1745
	if (isset($phase1['mobile']))
1746
		return false;
1747

    
1748
	$spdconf = "";
1749
	$ep = ipsec_get_phase1_src($phase1);
1750
	$gw = trim($phase1['remote-gateway']);
1751
	$sad_arr = ipsec_dump_sad();
1752
	$remote_subnet = ipsec_idinfo_to_cidr($phase2['remoteid']);
1753

    
1754
	if (!empty($phase2['natlocalid']))
1755
		$local_subnet = ipsec_idinfo_to_cidr($phase2['natlocalid']);
1756
	else
1757
		$local_subnet = ipsec_idinfo_to_cidr($phase2['localid']);
1758

    
1759
	if ($phase2['mode'] == "tunnel6")
1760
		$family = "-6";
1761
	else
1762
		$family = "-4";
1763

    
1764
	$spdconf .= "spddelete {$family} {$local_subnet} " .
1765
		"{$remote_subnet} any -P out ipsec " .
1766
		"{$phase2['protocol']}/tunnel/{$ep}-" .
1767
		"{$gw}/unique;\n";
1768

    
1769
	$spdconf .= "spddelete {$family} {$remote_subnet} " .
1770
		"{$local_subnet} any -P in ipsec " .
1771
		"{$phase2['protocol']}/tunnel/{$gw}-" .
1772
		"{$ep}/unique;\n";
1773

    
1774
	/* zap any existing SA entries */
1775
	foreach($sad_arr as $sad) {
1776
		if(($sad['dst'] == $ep) && ($sad['src'] == $gw))
1777
			$spdconf .= "delete {$family} {$ep} {$gw} {$phase2['protocol']} 0x{$sad['spi']};\n";
1778
		if(($sad['src'] == $ep) && ($sad['dst'] == $_gw))
1779
			$spdconf .= "delete {$family} {$gw} {$ep} {$phase2['protocol']} 0x{$sad['spi']};\n";
1780
	}
1781

    
1782
	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));
1783

    
1784
	$now = time();
1785
	$spdfile = tempnam("{$g['tmp_path']}", "spd.conf.reload.{$now}.");
1786
	/* generate temporary spd.conf */
1787
	@file_put_contents($spdfile, $spdconf);
1788
	unset($spdconf);
1789

    
1790
	return true;
1791
}
1792

    
1793
/* reloads the tunnel configuration for a tunnel item
1794
 * Will remove and add SPD polices */
1795
function reload_tunnel_spd_policy($phase1, $phase2, $old_phase1, $old_phase2) {
1796
	global $config;
1797
	global $g;
1798

    
1799
	/* if we are not passed a old tunnel array we create one */
1800
	if(empty($old_phase1)) {
1801
		$old_phase1 = $phase1;
1802
	}
1803
	if(empty($old_phase2)) {
1804
		$old_phase2 = $phase2;
1805
	}
1806

    
1807
	$sad_arr = ipsec_dump_sad();
1808

    
1809
	$ep = ipsec_get_phase1_src($phase1);
1810
	$phase2['localid']['mode'] = $phase2['mode'];
1811
	$local_subnet = ipsec_idinfo_to_cidr($phase2['localid']);
1812
	$remote_subnet = ipsec_idinfo_to_cidr($phase2['remoteid']);
1813

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

    
1817
	$old_ep = ipsec_get_phase1_src($old_phase1);
1818
	$old_phase2['localid']['mode'] = $old_phase2['mode'];
1819
	$old_local_subnet = ipsec_idinfo_to_cidr($old_phase2['localid']);
1820
	$old_remote_subnet = ipsec_idinfo_to_cidr($old_phase2['remoteid']);
1821

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

    
1844
	if((!is_ipaddr($old_ep)) || (! is_ipaddr($ep))) {
1845
		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));
1846
	}
1847
	if((! is_ipaddr($rgip)) || (! is_ipaddr($old_gw))) {
1848
		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));
1849
	}
1850

    
1851
	$spdconf = "";
1852
	/* Delete old SPD policies if there are changes between the old and new */
1853
	if(($phase1 != $old_phase1) || ($phase2 != $old_phase2)) {
1854
		if($old_phase2['mode'] == "tunnel6")
1855
			$family = "-6";
1856
		else
1857
			$family = "-4";
1858

    
1859
		$spdconf .= "spddelete {$family} {$old_local_subnet} " .
1860
			"{$old_remote_subnet} any -P out ipsec " .
1861
			"{$old_phase2['protocol']}/tunnel/{$old_ep}-" .
1862
			"{$old_gw}/unique;\n";
1863
		if (!empty($old_phase2['natlocalid']))
1864
			$old_local_subnet = ipsec_idinfo_to_cidr($old_phase2['natlocalid']);
1865
		$spdconf .= "spddelete {$family} {$old_remote_subnet} " .
1866
			"{$old_local_subnet} any -P in ipsec " .
1867
			"{$old_phase2['protocol']}/tunnel/{$old_gw}-" .
1868
			"{$old_ep}/unique;\n";
1869

    
1870
		/* zap any existing SA entries */
1871
		foreach($sad_arr as $sad) {
1872
			if(($sad['dst'] == $old_ep) && ($sad['src'] == $old_gw)) {
1873
				$spdconf .= "delete {$family} {$old_ep} {$old_gw} {$old_phase2['protocol']} 0x{$sad['spi']};\n";
1874
			}
1875
			if(($sad['src'] == $oldep) && ($sad['dst'] == $old_gw)) {
1876
				$spdconf .= "delete {$family} {$old_gw} {$old_ep} {$old_phase2['protocol']} 0x{$sad['spi']};\n";
1877
			}
1878
		}
1879
	}
1880

    
1881
	if($phase2['mode'] == "tunnel6")
1882
		$family = "-6";
1883
	else
1884
		$family = "-4";
1885

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

    
1903
		if (!empty($phase2['natlocalid']))
1904
			$local_subnet = ipsec_idinfo_to_cidr($phase2['natlocalid']);
1905
		$spdconf .= "spdadd {$family} {$remote_subnet} " .
1906
			"{$local_subnet} any -P in ipsec " .
1907
			"{$phase2['protocol']}/tunnel/{$rgip}-" .
1908
			"{$ep}/unique;\n";
1909
	}
1910

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

    
1913
	$now = time();
1914
	$spdfile = tempnam("{$g['tmp_path']}", "spd.conf.reload.{$now}.");
1915
	/* generate temporary spd.conf */
1916
	@file_put_contents($spdfile, $spdconf);
1917
	unset($spdconf);
1918
	return true;
1919
}
1920

    
1921
function vpn_ipsec_configure_preferoldsa() {
1922
	global $config;
1923
	if(isset($config['ipsec']['preferoldsa']))
1924
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
1925
	else
1926
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
1927
}
1928

    
1929
?>
(58-58/67)