Project

General

Profile

Download (54.2 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
			killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
981
			sleep(1);
982
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
983
		}
984
	
985
		vpn_ipsec_failover_configure();
986

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

    
991
	return 0;
992
}
993

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

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

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

    
1009
	/* wait for process to die */
1010
	sleep(4);
1011

    
1012
	/* kill racoon forcefully */
1013
	if (is_process_running("racoon"))
1014
		mwexec("/usr/bin/killall -9 racoon", true);
1015

    
1016
	/* wait for flushing to finish */
1017
	sleep(1);
1018

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

    
1026
/* master setup for vpn (mpd) */
1027
function vpn_setup() {
1028
	global $g;
1029

    
1030
	if ($g['platform'] == 'jail')
1031
		return;
1032

    
1033
	/* start pptpd */
1034
	vpn_pptpd_configure();
1035

    
1036
	/* start pppoe server */
1037
	vpn_pppoes_configure();
1038

    
1039
	/* setup l2tp */
1040
	vpn_l2tp_configure();
1041
}
1042

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

    
1054
function vpn_pptpd_configure() {
1055
	global $config, $g;
1056

    
1057
	$syscfg = $config['system'];
1058
	$pptpdcfg = $config['pptpd'];
1059

    
1060
	if ($g['booting']) {
1061
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
1062
			return 0;
1063

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

    
1069
		/* wait for process to die */
1070
		sleep(3);
1071

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

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

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

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

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

    
1101
			$mpdconf = <<<EOD
1102
pptps:
1103

    
1104
EOD;
1105

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

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

    
1112
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1113

    
1114
				$mpdconf .= <<<EOD
1115

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

    
1121
EOD;
1122
			}
1123

    
1124
			$mpdconf .=<<<EOD
1125

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

    
1146
EOD;
1147

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

    
1153
EOD;
1154
			}
1155

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

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

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

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

    
1186
EOD;
1187
			}
1188
			$mpdconf .=<<<EOD
1189
	set radius retries 3
1190
	set radius timeout 10
1191
	set auth enable radius-auth
1192

    
1193
EOD;
1194

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

    
1200
EOD;
1201
				}
1202
			}
1203

    
1204
			fwrite($fd, $mpdconf);
1205
			fclose($fd);
1206
			unset($mpdconf);
1207

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

    
1215
			$mpdlinks = "";
1216

    
1217
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1218
				$mpdlinks .=<<<EOD
1219

    
1220
pt{$i}:
1221
	set link type pptp
1222
	set pptp enable incoming
1223
	set pptp disable originate
1224
	set pptp disable windowing
1225

    
1226
EOD;
1227
			}
1228

    
1229
			fwrite($fd, $mpdlinks);
1230
			fclose($fd);
1231
			unset($mpdlinks);
1232

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

    
1240
			$mpdsecret = "";
1241

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

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

    
1255
			vpn_netgraph_support();
1256

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

    
1260
			break;
1261

    
1262
		case 'redir' :
1263
			break;
1264
	}
1265

    
1266
	if ($g['booting'])
1267
		echo "done\n";
1268

    
1269
	return 0;
1270
}
1271

    
1272
function vpn_pppoes_configure() {
1273
	global $config;
1274

    
1275
	if (is_array($config['pppoes']['pppoe'])) {
1276
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1277
			vpn_pppoe_configure($pppoe);
1278
	}
1279
}
1280

    
1281
function vpn_pppoe_configure(&$pppoecfg) {
1282
	global $config, $g;
1283

    
1284
	$syscfg = $config['system'];
1285

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

    
1290
	if ($g['booting']) {
1291
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1292
			return 0;
1293

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

    
1299
		/* wait for process to die */
1300
		sleep(2);
1301

    
1302
	}
1303

    
1304
	switch ($pppoecfg['mode']) {
1305

    
1306
		case 'server' :
1307

    
1308
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1309

    
1310
			if ($pppoecfg['paporchap'] == "chap")
1311
				$paporchap = "set link enable chap";
1312
			else
1313
				$paporchap = "set link enable pap";
1314

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

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

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

    
1330
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1331

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

    
1338
				$mpdconf .=<<<EOD
1339

    
1340
poes{$pppoecfg['pppoeid']}{$i}:
1341
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1342
	{$isssue_ip_type}
1343
	load pppoe_standard
1344

    
1345
EOD;
1346
			}
1347

    
1348
			$mpdconf .=<<<EOD
1349

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

    
1376
EOD;
1377

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

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

    
1405
EOD;
1406

    
1407
				if (isset ($pppoecfg['radius']['accounting'])) {
1408
					$mpdconf .=<<<EOD
1409
	set auth enable radius-acct
1410

    
1411
EOD;
1412
				}
1413
			}
1414

    
1415
			fwrite($fd, $mpdconf);
1416
			fclose($fd);
1417
			unset($mpdconf);
1418

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

    
1426
			$mpdlinks = "";
1427

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

    
1438
EOD;
1439
			}
1440

    
1441
			fwrite($fd, $mpdlinks);
1442
			fclose($fd);
1443
			unset($mpdlinks);
1444

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

    
1453
				$mpdsecret = "\n\n";
1454

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

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

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

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

    
1478
			break;
1479
	}
1480

    
1481
	if ($g['booting'])
1482
		echo gettext("done") . "\n";
1483

    
1484
	return 0;
1485
}
1486

    
1487
function vpn_l2tp_configure() {
1488
	global $config, $g;
1489

    
1490
	$syscfg = $config['system'];
1491
	$l2tpcfg = $config['l2tp'];
1492

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

    
1497
	if ($g['booting']) {
1498
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1499
			return 0;
1500

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

    
1506
		/* wait for process to die */
1507
		sleep(8);
1508

    
1509
	}
1510

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

    
1515
	switch ($l2tpcfg['mode']) {
1516

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

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

    
1533
EOD;
1534

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

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

    
1541
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1542

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

    
1549
				$mpdconf .=<<<EOD
1550

    
1551
l2tp{$i}:
1552
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1553
	{$isssue_ip_type}
1554
	load l2tp_standard
1555

    
1556
EOD;
1557
			}
1558

    
1559
			$mpdconf .=<<<EOD
1560

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

    
1577
EOD;
1578

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

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

    
1603
EOD;
1604

    
1605
				if (isset ($l2tpcfg['radius']['accounting'])) {
1606
					$mpdconf .=<<<EOD
1607
	set auth enable radius-acct
1608

    
1609
EOD;
1610
				}
1611
			}
1612

    
1613
			fwrite($fd, $mpdconf);
1614
			fclose($fd);
1615
			unset($mpdconf);
1616

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

    
1624
			$mpdlinks = "";
1625

    
1626
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1627
				$mpdlinks .=<<<EOD
1628

    
1629
l2tp{$i}:
1630
	set link type l2tp
1631
        set l2tp enable incoming
1632
        set l2tp disable originate
1633

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

    
1639
			fwrite($fd, $mpdlinks);
1640
			fclose($fd);
1641
			unset($mpdlinks);
1642

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

    
1650
			$mpdsecret = "\n\n";
1651

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

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

    
1662
			vpn_netgraph_support();
1663

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

    
1667
			break;
1668

    
1669
		case 'redir' :
1670
			break;
1671
	}
1672

    
1673
	if ($g['booting'])
1674
		echo "done\n";
1675

    
1676
	return 0;
1677
}
1678

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

    
1686
	$ipseccfg = $config['ipsec'];
1687
	$a_phase1 = $config['ipsec']['phase1'];
1688
	$a_phase2 = $config['ipsec']['phase2'];
1689

    
1690
	if (isset($ipseccfg['disable'])) {
1691
		return true;
1692
	}
1693

    
1694
	/* Walk the Ipsec tunnel array */
1695
	if (!is_array($a_phase1) || (!count($a_phase1)))
1696
		return;
1697

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

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

    
1734
/* reloads the tunnel configuration for a tunnel item
1735
 * Will remove and add SPD polices */
1736
function reload_tunnel_spd_policy($phase1, $phase2, $old_phase1, $old_phase2) {
1737
	global $config;
1738
	global $g;
1739

    
1740
	/* if we are not passed a old tunnel array we create one */
1741
	if(empty($old_phase1)) {
1742
		$old_phase1 = $phase1;
1743
	}
1744
	if(empty($old_phase2)) {
1745
		$old_phase2 = $phase2;
1746
	}
1747

    
1748
	$sad_arr = ipsec_dump_sad();
1749

    
1750
	$ep = ipsec_get_phase1_src($phase1);
1751
	$phase2['localid']['mode'] = $phase2['mode'];
1752
	$local_subnet = ipsec_idinfo_to_cidr($phase2['localid']);
1753
	$remote_subnet = ipsec_idinfo_to_cidr($phase2['remoteid']);
1754

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

    
1758
	$old_ep = ipsec_get_phase1_src($old_phase1);
1759
	$old_phase2['localid']['mode'] = $old_phase2['mode'];
1760
	$old_local_subnet = ipsec_idinfo_to_cidr($old_phase2['localid']);
1761
	$old_remote_subnet = ipsec_idinfo_to_cidr($old_phase2['remoteid']);
1762

    
1763
	/* see if this tunnel has a hostname for the remote-gateway, and if so,
1764
	 * try to resolve it now and add it to the list for filterdns */
1765
	$rgip = "";
1766
	if (!is_ipaddr($phase1['remote-gateway'])) {
1767
		if(! $g['booting']) {
1768
			$rgip = resolve_retry($phase1['remote-gateway']);
1769
			add_hostname_to_watch($phase1['remote-gateway']);
1770
		} else {
1771
			add_hostname_to_watch($phase1['remote-gateway']);
1772
		}
1773
		if (!is_ipaddr($rgip)) {
1774
			log_error("Could not determine VPN endpoint for '{$phase1['descr']}'");
1775
			return false;
1776
		}
1777
	} else {
1778
		$rgip = $phase1['remote-gateway'];
1779
	}
1780
	if (!$ep) {
1781
		log_error(sprintf(gettext("Could not determine VPN endpoint for '%s'"), $phase1['descr']));
1782
		return false;
1783
	}
1784

    
1785
	if((!is_ipaddr($old_ep)) || (! is_ipaddr($ep))) {
1786
		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));
1787
	}
1788
	if((! is_ipaddr($rgip)) || (! is_ipaddr($old_gw))) {
1789
		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));
1790
	}
1791

    
1792
	$spdconf = "";
1793
	/* Delete old SPD policies if there are changes between the old and new */
1794
	if(($phase1 != $old_phase1) || ($phase2 != $old_phase2)) {
1795
		if($old_phase2['mode'] == "tunnel6")
1796
			$family = "-6";
1797
		else
1798
			$family = "-4";
1799

    
1800
		$spdconf .= "spddelete {$family} {$old_local_subnet} " .
1801
			"{$old_remote_subnet} any -P out ipsec " .
1802
			"{$old_phase2['protocol']}/tunnel/{$old_ep}-" .
1803
			"{$old_gw}/unique;\n";
1804
		if (!empty($old_phase2['natlocalid']))
1805
			$old_local_subnet = ipsec_idinfo_to_cidr($old_phase2['natlocalid']);
1806
		$spdconf .= "spddelete {$family} {$old_remote_subnet} " .
1807
			"{$old_local_subnet} any -P in ipsec " .
1808
			"{$old_phase2['protocol']}/tunnel/{$old_gw}-" .
1809
			"{$old_ep}/unique;\n";
1810

    
1811
		/* zap any existing SA entries */
1812
		foreach($sad_arr as $sad) {
1813
			if(($sad['dst'] == $old_ep) && ($sad['src'] == $old_gw)) {
1814
				$spdconf .= "delete {$family} {$old_ep} {$old_gw} {$old_phase2['protocol']} 0x{$sad['spi']};\n";
1815
			}
1816
			if(($sad['src'] == $oldep) && ($sad['dst'] == $old_gw)) {
1817
				$spdconf .= "delete {$family} {$old_gw} {$old_ep} {$old_phase2['protocol']} 0x{$sad['spi']};\n";
1818
			}
1819
		}
1820
	}
1821

    
1822
	if($phase2['mode'] == "tunnel6")
1823
		$family = "-6";
1824
	else
1825
		$family = "-4";
1826

    
1827
	/* Create new SPD entries for the new configuration */
1828
	/* zap any existing SA entries beforehand */
1829
	foreach($sad_arr as $sad) {
1830
		if(($sad['dst'] == $ep) && ($sad['src'] == $rgip)) {
1831
			$spdconf .= "delete {$family} {$rgip} {$ep} {$phase2['protocol']} 0x{$sad['spi']};\n";
1832
		}
1833
		if(($sad['src'] == $ep) && ($sad['dst'] == $rgip)) {
1834
			$spdconf .= "delete {$family} {$ep} {$rgip} {$phase2['protocol']} 0x{$sad['spi']};\n";
1835
		}
1836
	}
1837
	/* add new SPD policies to replace them */
1838
	if (!isset($phase1['disabled'])) {
1839
		$spdconf .= "spdadd {$family} {$local_subnet} " .
1840
			"{$remote_subnet} any -P out ipsec " .
1841
			"{$phase2['protocol']}/tunnel/{$ep}-" .
1842
			"{$rgip}/unique;\n";
1843

    
1844
		if (!empty($phase2['natlocalid']))
1845
			$local_subnet = ipsec_idinfo_to_cidr($phase2['natlocalid']);
1846
		$spdconf .= "spdadd {$family} {$remote_subnet} " .
1847
			"{$local_subnet} any -P in ipsec " .
1848
			"{$phase2['protocol']}/tunnel/{$rgip}-" .
1849
			"{$ep}/unique;\n";
1850
	}
1851

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

    
1854
	$now = time();
1855
	$spdfile = tempnam("{$g['tmp_path']}", "spd.conf.reload.{$now}.");
1856
	/* generate temporary spd.conf */
1857
	@file_put_contents($spdfile, $spdconf);
1858
	unset($spdconf);
1859
	return true;
1860
}
1861

    
1862
function vpn_ipsec_configure_preferoldsa() {
1863
	global $config;
1864
	if(isset($config['ipsec']['preferoldsa']))
1865
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
1866
	else
1867
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
1868
}
1869

    
1870
?>
(59-59/68)