Project

General

Profile

Download (52.9 KB) Statistics
| Branch: | Tag: | Revision:
1 5b237745 Scott Ullrich
<?php
2 979cd6db Scott Ullrich
3 5b237745 Scott Ullrich
/*
4
	vpn.inc
5 979cd6db Scott Ullrich
	Copyright (C) 2004 Scott Ullrich
6 a93e56c5 Matthew Grooms
	Copyright (C) 2008 Shrew Soft Inc
7 6d7de776 Ermal Luçi
	Copyright (C) 2008 Ermal Lu?i
8 cfc707f7 Scott Ullrich
	All rights reserved.
9 17da6c79 Scott Ullrich
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 5b237745 Scott Ullrich
	Redistribution and use in source and binary forms, with or without
15
	modification, are permitted provided that the following conditions are met:
16 17da6c79 Scott Ullrich
17 5b237745 Scott Ullrich
	1. Redistributions of source code must retain the above copyright notice,
18
	   this list of conditions and the following disclaimer.
19 17da6c79 Scott Ullrich
20 5b237745 Scott Ullrich
	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 17da6c79 Scott Ullrich
24 5b237745 Scott Ullrich
	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 8f67a8e1 Scott Ullrich
36 523855b0 Scott Ullrich
/*
37
	pfSense_BUILDER_BINARIES:	/usr/bin/killall	/usr/local/sbin/sasyncd	/sbin/ifconfig	/sbin/sysctl
38 320bba64 Ermal
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/setkey	/sbin/route	/bin/mkdir
39 523855b0 Scott Ullrich
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/racoonctl	/usr/local/sbin/racoon
40 f8c10a18 Ermal
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/filterdns	/usr/local/sbin/mpd4	
41 523855b0 Scott Ullrich
	pfSense_MODULE:	vpn
42
*/
43
44 5b237745 Scott Ullrich
/* include all configuration functions */
45 8f67a8e1 Scott Ullrich
46 600dd4e0 Scott Ullrich
function vpn_ipsec_failover_configure() {
47
	global $config, $g;
48
49
50 920af30f Ermal Lu?i
	if (is_array($config['installedpackages']['sasyncd'])) {
51
		$sasyncd_text = "";
52 979cd6db Scott Ullrich
		foreach ($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
53
			$enabled = isset ($sasyncd['enable']);
54
			if (!$enabled)
55 dcca036d Scott Ullrich
				return;
56 979cd6db Scott Ullrich
			if ($sasyncd['peerip'] <> "")
57 7dd31990 Scott Ullrich
				$sasyncd_text .= "peer {$sasyncd['peerip']}\n";
58 979cd6db Scott Ullrich
			if ($sasyncd['interface'])
59 7dd31990 Scott Ullrich
				$sasyncd_text .= "carp interface {$sasyncd['interface']}\n";
60 979cd6db Scott Ullrich
			if ($sasyncd['sharedkey'] <> "")
61 7dd31990 Scott Ullrich
				$sasyncd_text .= "sharedkey {$sasyncd['sharedkey']}\n";
62 979cd6db Scott Ullrich
			if ($sasyncd['mode'] <> "")
63 7dd31990 Scott Ullrich
				$sasyncd_text .= "mode {$sasyncd['mode']}\n";
64 979cd6db Scott Ullrich
			if ($sasyncd['listenon'] <> "")
65 7dd31990 Scott Ullrich
				$sasyncd_text .= "listen on {$sasyncd['listenon']}\n";
66 979cd6db Scott Ullrich
			if ($sasyncd['flushmodesync'] <> "")
67 7dd31990 Scott Ullrich
				$sasyncd_text .= "flushmode sync {$sasyncd['flushmodesync']}\n";
68 dcca036d Scott Ullrich
		}
69 e1a74484 Scott Ullrich
70 920af30f Ermal Lu?i
		file_put_contents("{$g['varetc_path']}/sasyncd.conf", $sasyncd_text);
71
		chmod("{$g['varetc_path']}/sasyncd.conf", 0600);
72 c52719a8 Scott Ullrich
73 920af30f Ermal Lu?i
		if(is_process_running("sasyncd"))
74
			mwexec("killall sasyncd", true);
75 c52719a8 Scott Ullrich
76 920af30f Ermal Lu?i
		/* launch sasyncd, oh wise one */
77
		mwexec_bg("/usr/local/sbin/sasyncd -d -v -v -v");
78
	}
79 600dd4e0 Scott Ullrich
}
80 8f67a8e1 Scott Ullrich
81 a93e56c5 Matthew Grooms
function vpn_ipsec_configure($ipchg = false)
82
{
83
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos;
84 17da6c79 Scott Ullrich
85 7734aea6 Andrew Thompson
	if ($g['platform'] == 'jail')
86
		return;
87 f41c9fd5 Ermal Lu?i
	/* get the automatic ping_hosts.sh ready */
88 cdd5b2ce Ermal Lu?i
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
89
	touch("{$g['vardb_path']}/ipsecpinghosts");
90 c1f5a46b Scott Ullrich
91 7b2fdac4 jim-p
	vpn_ipsec_configure_preferoldsa();
92 8f67a8e1 Scott Ullrich
93
	$syscfg = $config['system'];
94 5b237745 Scott Ullrich
	$ipseccfg = $config['ipsec'];
95 a93e56c5 Matthew Grooms
	$a_phase1 = $config['ipsec']['phase1'];
96
	$a_phase2 = $config['ipsec']['phase2'];
97 3462a529 Matthew Grooms
	$a_client = $config['ipsec']['client'];
98 8f67a8e1 Scott Ullrich
99 2f1e0311 Seth Mos
	if (!isset($ipseccfg['enable'])) {
100
		mwexec("/sbin/ifconfig enc0 down");
101 8f67a8e1 Scott Ullrich
102 98c02cac Ermal
		/* send a SIGKILL to be sure */
103
		sigkillbypid("{$g['varrun_path']}/racoon.pid", "KILL");
104
105 5b237745 Scott Ullrich
		/* kill racoon */
106 99f98b80 sullrich
		if(is_process_running("racoon"))
107
			mwexec("/usr/bin/killall racoon", true);
108 f8c10a18 Ermal
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
109 98c02cac Ermal
110 979cd6db Scott Ullrich
		/* wait for racoon process to die */
111 8f67a8e1 Scott Ullrich
		sleep(2);
112
113 2f1e0311 Seth Mos
		/* flush SPD and SAD */
114 6b91fe11 Seth Mos
		mwexec("/usr/local/sbin/setkey -F");
115 98c02cac Ermal
		mwexec("/usr/local/sbin/setkey -FP");
116
117 84fa0d60 Scott Ullrich
		/* disallow IPSEC, it is off */
118 79eea0c1 Ermal
		exec("/sbin/sysctl net.inet.ip.ipsec_in_use=0");
119 2f1e0311 Seth Mos
120
		return true;
121 04b46591 Ermal Lu?i
	} else {
122 3bb6bfd2 Ermal
		mwexec("/sbin/ifconfig enc0 up");
123 6706a83a Ermal
		mwexec("/sbin/sysctl net.inet.ip.ipsec_in_use=1");
124 3bb6bfd2 Ermal
125 924876a8 Ermal Lu?i
		if ($g['booting'])
126 89ceb4ba Renato Botelho
			echo gettext("Configuring IPsec VPN... ");
127 924876a8 Ermal Lu?i
128 8f67a8e1 Scott Ullrich
		/* fastforwarding is not compatible with ipsec tunnels */
129 979cd6db Scott Ullrich
		mwexec("/sbin/sysctl net.inet.ip.fastforwarding=0");
130 8f67a8e1 Scott Ullrich
131 a93e56c5 Matthew Grooms
		/* resolve all local, peer addresses and setup pings */
132
		$ipmap = array();
133
		$rgmap = array();
134 f8c10a18 Ermal
		$filterdns_list = array();
135 a93e56c5 Matthew Grooms
		if (is_array($a_phase1) && count($a_phase1)) {
136 87e07f52 mgrooms
137 ac463c00 smos
			$ipsecpinghosts = "";
138 87e07f52 mgrooms
			/* step through each phase1 entry */
139 80c1e99f Seth Mos
			$ipsecpinghosts = "";
140 a93e56c5 Matthew Grooms
			foreach ($a_phase1 as $ph1ent) {
141
				if (isset($ph1ent['disabled']))
142
					continue;
143 8f67a8e1 Scott Ullrich
144 0af7398a Matthew Grooms
				$ep = ipsec_get_phase1_src($ph1ent);
145 fb17f629 Seth Mos
				if (!is_ipaddr($ep))
146 a93e56c5 Matthew Grooms
					continue;
147 8f67a8e1 Scott Ullrich
148 a93e56c5 Matthew Grooms
				if(!in_array($ep,$ipmap))
149
					$ipmap[] = $ep;
150 8f67a8e1 Scott Ullrich
151 a93e56c5 Matthew Grooms
				/* see if this tunnel has a hostname for the remote-gateway. If so,
152 f8c10a18 Ermal
				   try to resolve it now and add it to the list for filterdns */
153 8f67a8e1 Scott Ullrich
154 3462a529 Matthew Grooms
				if (isset ($ph1ent['mobile']))
155
					continue;
156
157 a93e56c5 Matthew Grooms
				$rg = $ph1ent['remote-gateway'];
158 979cd6db Scott Ullrich
159 a93e56c5 Matthew Grooms
				if (!is_ipaddr($rg)) {
160 f8c10a18 Ermal
					$filterdns_list[] = "{$rg}";
161 c60cae98 Seth Mos
					add_hostname_to_watch($rg);
162 621a459a smos
					if(! $g['booting'])
163
						$rg = resolve_retry($rg);
164
					if (!is_ipaddr($rg))
165 979cd6db Scott Ullrich
						continue;
166 a93e56c5 Matthew Grooms
				}
167 829fa12e smos
				if(array_search($rg, $rgmap)) {
168
					log_error("The remote gateway {$rg} already exists on another phase 1 entry");
169
					continue;
170
				}
171 a93e56c5 Matthew Grooms
				$rgmap[$ph1ent['remote-gateway']] = $rg;
172 8f67a8e1 Scott Ullrich
173 a11df336 jim-p
				if (is_array($a_phase2)) {
174
					/* step through each phase2 entry */
175
					foreach ($a_phase2 as $ph2ent) {
176
						$ikeid = $ph2ent['ikeid'];
177
178
						if (isset($ph2ent['disabled']))
179
							continue;
180
181
						if ($ikeid != $ph1ent['ikeid'])
182
							continue;
183
184
						$ph2ent['localid']['mode'] = $ph2ent['mode'];
185
						/* add an ipsec pinghosts entry */
186
						if ($ph2ent['pinghost']) {
187
							$iflist = get_configured_interface_list();
188
							foreach ($iflist as $ifent => $ifname) {
189
								if(is_ipaddrv6($ph2ent['pinghost'])) {
190
									$interface_ip = get_interface_ipv6($ifent);
191
									if(!is_ipaddrv6($interface_ip))
192
										continue;
193
									$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true);
194
									if (ip_in_subnet($interface_ip, $local_subnet)) {
195
										$srcip = $interface_ip;
196
										break;
197
									}
198
								} else {
199
									$interface_ip = get_interface_ip($ifent);
200
									if(!is_ipaddrv4($interface_ip))
201
										continue;
202
									$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true);
203
									if (ip_in_subnet($interface_ip, $local_subnet)) {
204
										$srcip = $interface_ip;
205
										break;
206
									}
207 fb17f629 Seth Mos
								}
208 a11df336 jim-p
							}
209
							$dstip = $ph2ent['pinghost'];
210
							if(is_ipaddrv6($dstip)) {
211
								$family = "inet6";
212 fb17f629 Seth Mos
							} else {
213 a11df336 jim-p
								$family = "inet";
214 741077bc Ermal Lu?i
							}
215 a11df336 jim-p
							if (is_ipaddr($srcip))
216
								$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
217 87e07f52 mgrooms
						}
218 17da6c79 Scott Ullrich
					}
219 a11df336 jim-p
					file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
220 a93e56c5 Matthew Grooms
				}
221
			}
222
		}
223 8f67a8e1 Scott Ullrich
224 a93e56c5 Matthew Grooms
		/* generate CA certificates files */
225 1e332e98 jim-p
		if (is_array($config['ca']) && count($config['ca'])) {
226
			foreach ($config['ca'] as $ca) {
227 73fbece8 mgrooms
				if (!isset($ca['crt'])) {
228 4816e5ca Renato Botelho
					log_error(sprintf(gettext("Error: Invalid certificate info for %s"), $ca['descr']));
229 73fbece8 mgrooms
					continue;
230
				}
231
				$cert = base64_decode($ca['crt']);
232
				$x509cert = openssl_x509_parse(openssl_x509_read($cert));
233
				if (!is_array($x509cert) || !isset($x509cert['hash'])) {
234 4816e5ca Renato Botelho
					log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $ca['descr']));
235 73fbece8 mgrooms
					continue;
236
				}
237 dd30341d Eirik Oeverby
				$fname = $g['varetc_path']."/".$x509cert['hash'].".0";
238 73fbece8 mgrooms
				if (!file_put_contents($fname, $cert)) {
239 4816e5ca Renato Botelho
					log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $ca['descr']));
240 73fbece8 mgrooms
					continue;
241 a93e56c5 Matthew Grooms
				}
242
			}
243
		}
244
		
245
		/* generate psk.txt */
246
		$fd = fopen("{$g['varetc_path']}/psk.txt", "w");
247
		if (!$fd) {
248 89ceb4ba Renato Botelho
			printf(gettext("Error: cannot open psk.txt in vpn_ipsec_configure().") . "\n");
249 a93e56c5 Matthew Grooms
			return 1;
250
		}
251
252
		$pskconf = "";
253 037b51b3 Seth Mos
254 a93e56c5 Matthew Grooms
		if (is_array($a_phase1) && count($a_phase1)) {
255
			foreach ($a_phase1 as $ph1ent) {
256
257
				if (isset($ph1ent['disabled']))
258
					continue;
259
260 3462a529 Matthew Grooms
				if (strstr($ph1ent['authentication_method'],'rsa'))
261
					continue;
262 a93e56c5 Matthew Grooms
263
				$peerid_type = $ph1ent['peerid_type'];
264
265
				switch ($peerid_type) {
266
					case "peeraddress":
267
						$peerid_type = "address";
268 3462a529 Matthew Grooms
						$peerid_data = $rgmap[$ph1ent['remote-gateway']];
269 a93e56c5 Matthew Grooms
						break;
270
271
					case "address";
272
						$peerid_data = $ph1ent['peerid_data'];
273
						break;
274
275
					case "fqdn";
276
					case "keyid tag";
277
					case "user_fqdn";
278
						$peerid_data = $ph1ent['peerid_data'];
279
						break;
280 5b237745 Scott Ullrich
				}
281 8f67a8e1 Scott Ullrich
282 a7af5ddc jim-p
				if (!empty($peerid_data) && !empty($ph1ent['pre-shared-key']))
283
					$pskconf .= trim($peerid_data) . "\t" . trim($ph1ent['pre-shared-key']) . "\n";
284 5b237745 Scott Ullrich
			}
285 a93e56c5 Matthew Grooms
		}
286
287 4ed2dde7 jim-p
		/* Add user PSKs */
288
		foreach ($config['system']['user'] as $user) {
289
			if (!empty($user['ipsecpsk'])) {
290
				$pskconf .= "{$user['name']}\t{$user['ipsecpsk']}\n";
291
			}
292
		}
293
294 2ef1b601 jim-p
		/* add PSKs for mobile clients */
295
		if (is_array($ipseccfg['mobilekey'])) {
296
			foreach ($ipseccfg['mobilekey'] as $key) {
297 4ed2dde7 jim-p
				$pskconf .= "{$key['ident']}\t{$key['pre-shared-key']}\n";
298 2ef1b601 jim-p
			}
299
		}
300
301 a93e56c5 Matthew Grooms
		fwrite($fd, $pskconf);
302
		fclose($fd);
303
		chmod("{$g['varetc_path']}/psk.txt", 0600);
304
			
305
		/* begin racoon.conf */
306
		if ((is_array($a_phase1) && count($a_phase1)) ||
307
			(is_array($a_phase2) && count($a_phase2))) {
308 8f67a8e1 Scott Ullrich
309 5b237745 Scott Ullrich
			$fd = fopen("{$g['varetc_path']}/racoon.conf", "w");
310
			if (!$fd) {
311 89ceb4ba Renato Botelho
				printf(gettext("Error: cannot open racoon.conf in vpn_ipsec_configure().") . "\n");
312 5b237745 Scott Ullrich
				return 1;
313
			}
314 17da6c79 Scott Ullrich
315 6edc48fe Seth Mos
			$racoonconf = "# This file is automatically generated. Do not edit\n";			
316 c52719a8 Scott Ullrich
			$racoonconf .= "path pre_shared_key \"{$g['varetc_path']}/psk.txt\";\n\n";
317 a63f7d55 Scott Ullrich
			$racoonconf .= "path certificate  \"{$g['varetc_path']}\";\n\n";
318 c52719a8 Scott Ullrich
319 a93e56c5 Matthew Grooms
			/* begin listen section */
320
			if (count($ipmap)) {
321
				$racoonconf .= "\nlisten\n";
322
				$racoonconf .= "{\n";
323 98718ac1 pierrepomes
				$racoonconf .= "	adminsock \"/var/db/racoon/racoon.sock\" \"root\" \"wheel\" 0660;\n";
324 a93e56c5 Matthew Grooms
				foreach ($ipmap as $addr) {
325
					$racoonconf .= "\tisakmp {$addr} [500];\n";
326
					$racoonconf .= "\tisakmp_natt {$addr} [4500];\n";
327 a63f7d55 Scott Ullrich
				}
328 a93e56c5 Matthew Grooms
				$racoonconf .= "}\n\n";
329
			}
330 c52719a8 Scott Ullrich
331 3462a529 Matthew Grooms
			/* begin mode_cfg section */
332
			if (is_array($a_client) && isset($a_client['enable'])) {
333
334
				$racoonconf .= "\nmode_cfg\n";
335
				$racoonconf .= "{\n";
336
337
				if ($a_client['user_source'])
338
					$racoonconf .= "\tauth_source {$a_client['user_source']};\n";
339
				if ($a_client['group_source'])
340
					$racoonconf .= "\tgroup_source {$a_client['group_source']};\n";
341
342
				if ($a_client['pool_address'] && $a_client['pool_netbits']) {
343
					$pool_address = $a_client['pool_address'];
344
					$pool_netmask = gen_subnet_mask($a_client['pool_netbits']);
345
346 96033063 Erik Fonnesbeck
					$pool_address = long2ip32(ip2long($pool_address)+1);
347
					$pool_size = (~ip2long($pool_netmask) & 0xFFFFFFFF) - 2;
348 3462a529 Matthew Grooms
349
					$racoonconf .= "\tpool_size {$pool_size};\n";
350
					$racoonconf .= "\tnetwork4 {$pool_address};\n";
351
					$racoonconf .= "\tnetmask4 {$pool_netmask};\n";
352
				}
353
354
				if (isset($a_client['net_list'])) {
355
356
					$net_list = '';
357
358
					foreach ($a_phase2 as $ph2ent) {
359
360
						if (isset($ph2ent['disabled']))
361
							continue;
362
363
						if (!isset($ph2ent['mobile']))
364
							continue;
365
366
						$localid = ipsec_idinfo_to_cidr($ph2ent['localid'],true);
367
368
						if ($net_list)
369
							$net_list .= ", ";
370
						$net_list .= $localid;
371
					}
372
373
					if ($net_list)
374
						$racoonconf .= "\tsplit_network include {$net_list};\n";
375
				}
376
377
				if ($a_client['dns_server1'])
378
					$racoonconf .= "\tdns4 {$a_client['dns_server1']};\n";
379
				if ($a_client['dns_server2'])
380
					$racoonconf .= "\tdns4 {$a_client['dns_server2']};\n";
381
				if ($a_client['dns_server3'])
382
					$racoonconf .= "\tdns4 {$a_client['dns_server3']};\n";
383
				if ($a_client['dns_server4'])
384
					$racoonconf .= "\tdns4 {$a_client['dns_server4']};\n";
385
386
				if ($a_client['wins_server1'])
387
					$racoonconf .= "\twins4 {$a_client['wins_server1']};\n";
388
				if ($a_client['wins_server2'])
389
					$racoonconf .= "\twins4 {$a_client['wins_server2']};\n";
390
391 5281b3e8 Chris Buechler
				if ($a_client['dns_domain']) {
392 3462a529 Matthew Grooms
					$racoonconf .= "\tdefault_domain \"{$a_client['dns_domain']}\";\n";
393 5281b3e8 Chris Buechler
					$racoonconf .= "\tsplit_dns \"{$a_client['dns_domain']}\";\n";
394
				}
395 3462a529 Matthew Grooms
396
				if ($a_client['pfs_group'])
397
					$racoonconf .= "\tpfs_group {$a_client['pfs_group']};\n";
398
399
				if ($a_client['login_banner']) {
400
					$fn = "{$g['varetc_path']}/racoon.motd";
401
					$fd1 = fopen($fn, "w");
402
					if (!$fd1) {
403 b1e4005f Vinicius Coque
						printf(gettext("Error: cannot open server %s in vpn.\n"), $fn);
404 3462a529 Matthew Grooms
						return 1;
405
					}
406
407
					fwrite($fd1, $a_client['login_banner']);
408
					fclose($fd1);
409
410
					$racoonconf .= "\tbanner \"{$fn}\";\n";
411
				}
412
413 4178a1dd jim-p
				if (isset($a_client['save_passwd']))
414
					$racoonconf .= "\tsave_passwd on;\n";
415
416 3462a529 Matthew Grooms
				$racoonconf .= "}\n\n";
417
			}
418
			/* end mode_cfg section */
419 64f3141f Bryan Haase
			
420 96267107 Ermal
			if ($a_client['user_source'] != "system") {
421
				if (is_array($config['system']['authserver'])) {
422
					foreach ($config['system']['authserver'] as $authcfg) {
423
						if ($authcfg['type'] == 'ldap' and $authcfg['name'] == $a_client['user_source']) 
424
							$thisauthcfg = $authcfg;
425
					}
426
427
					/* begin ldapcfg */                        
428
					$racoonconf .= "ldapcfg {\n";
429
					$racoonconf .= "\tversion 3;\n";
430
					$racoonconf .= "\thost \"".$thisauthcfg['host']."\";\n";
431
					$lport = "389";
432
					if ($authcfg['port'] != "")
433
						$lport = $authcfg['port'];
434
					$racoonconf .= "\tport ".$lport.";\n";
435
					$racoonconf .= "\tbase \"".$thisauthcfg['ldap_basedn']."\";\n";
436
					$racoonconf .= "\tsubtree on;\n";
437
					$racoonconf .= "\tbind_dn \"".$thisauthcfg['ldap_binddn']."\";\n";
438
					$racoonconf .= "\tbind_pw \"".$thisauthcfg['ldap_bindpw']."\";\n";
439
					$racoonconf .= "\tattr_user \"".$thisauthcfg['ldap_attr_user']."\";\n";
440
					$racoonconf .= "}\n\n";
441
					/* end ldapcfg */
442
				}
443 e9ccd9b1 Bryan Haase
			}
444 96267107 Ermal
445 a93e56c5 Matthew Grooms
			/* begin remote sections */
446
			if (is_array($a_phase1) && count($a_phase1)) {
447
				/* begin remote */
448
				foreach ($a_phase1 as $ph1ent) {
449 3462a529 Matthew Grooms
450 a93e56c5 Matthew Grooms
					if (isset($ph1ent['disabled']))
451
						continue;
452 c52719a8 Scott Ullrich
453 3462a529 Matthew Grooms
					if (isset($ph1ent['mobile']) && !isset($a_client['enable']))
454
						continue;
455
456 a93e56c5 Matthew Grooms
					$ikeid = $ph1ent['ikeid'];
457 c52719a8 Scott Ullrich
458 0af7398a Matthew Grooms
					$ep = ipsec_get_phase1_src($ph1ent);
459 a93e56c5 Matthew Grooms
					if (!$ep)
460 979cd6db Scott Ullrich
						continue;
461 c52719a8 Scott Ullrich
462 3462a529 Matthew Grooms
					if (!isset($ph1ent['mobile'])) {
463
						$rgip = $rgmap[$ph1ent['remote-gateway']];
464
						if (!$rgip)
465
							continue;
466
					}
467
468 a93e56c5 Matthew Grooms
					$myid_type = $ph1ent['myid_type'];
469 c52719a8 Scott Ullrich
470 a93e56c5 Matthew Grooms
					switch ($myid_type) {
471 725dd10a Scott Ullrich
472 a93e56c5 Matthew Grooms
						case "myaddress":
473
							$myid_type = "address";
474
							$myid_data = $ep;
475
							break;
476
477
						case "dyn_dns":
478 19ef5120 Ermal Lu?i
							$myid_type = "address";
479 6c4f3b54 Seth Mos
							$myid_data = resolve_retry($ph1ent['myid_data']);
480 a93e56c5 Matthew Grooms
							break;
481 c52719a8 Scott Ullrich
482 a93e56c5 Matthew Grooms
						case "address";
483
							$myid_data = $ph1ent['myid_data'];
484
							break;
485
486
						case "fqdn";
487
						case "keyid tag";
488
						case "user_fqdn";
489
						case "asn1dn";
490
							$myid_data = $ph1ent['myid_data'];
491
							if( $myid_data )
492
								$myid_data = "\"".$myid_data."\"";
493
							break;
494 a63f7d55 Scott Ullrich
					}
495 c52719a8 Scott Ullrich
496 a93e56c5 Matthew Grooms
					$peerid_type = $ph1ent['peerid_type'];
497
498
					switch ($peerid_type) {
499
						case "peeraddress":
500
							$peerid_type = "address";
501
							$peerid_data = $rgip;
502
							break;
503
504
						case "address";
505
							$peerid_data = $ph1ent['peerid_data'];
506
							break;
507
508
						case "fqdn";
509
						case "keyid tag";
510
						case "user_fqdn";
511
						case "asn1dn";
512
							$peerid_data = $ph1ent['peerid_data'];
513
							if( $peerid_data )
514
								$peerid_data = "\"".$peerid_data."\"";
515
							break;
516 d597b0b9 Scott Ullrich
					}
517
518 3462a529 Matthew Grooms
					$natt = "off";
519 a93e56c5 Matthew Grooms
					if (isset($ph1ent['nat_traversal']))
520 3462a529 Matthew Grooms
						$natt = $ph1ent['nat_traversal'];
521
522
					$init = "on";
523 5cd9e96a jim-p
					$genp = !empty($ph1ent['generate_policy']) ? $ph1ent['generate_policy'] : "off";
524 4ccea790 jim-p
					$pcheck = !empty($ph1ent['proposal_check']) ? $ph1ent['proposal_check'] : $pcheck = "claim";
525 cee72940 jim-p
					$passive = "";
526 3462a529 Matthew Grooms
					if (isset($ph1ent['mobile'])) {
527
						$rgip = "anonymous";
528 9c04a8c0 Chris Buechler
						$passive = "passive on;";
529 10d171f2 jim-p
						/* Mimic 1.2.3's behavior for pure-psk mobile tunnels */
530 d98f1fa9 jim-p
						if ($ph1ent['authentication_method'] == "pre_shared_key") {
531 4ccea790 jim-p
							$pcheck = !empty($ph1ent['proposal_check']) ? $ph1ent['proposal_check'] : $pcheck = "obey";
532 5cd9e96a jim-p
							$genp = !empty($ph1ent['generate_policy']) ? $ph1ent['generate_policy'] : "on";
533 d98f1fa9 jim-p
						} else {
534
							$init = "off";
535 5cd9e96a jim-p
							$genp = !empty($ph1ent['generate_policy']) ? $ph1ent['generate_policy'] : "unique";
536 d98f1fa9 jim-p
						}
537 3462a529 Matthew Grooms
					}
538
539
					$dpdline1 = '';
540
					$dpdline2 = '';
541
					if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
542
						$dpdline1 = "dpd_delay = {$ph1ent['dpd_delay']};";
543
						$dpdline2 = "dpd_maxfail = {$ph1ent['dpd_maxfail']};";
544
					}
545 c52719a8 Scott Ullrich
546 a93e56c5 Matthew Grooms
					if (isset ($ph1ent['authentication_method']))
547
						$authmethod = $ph1ent['authentication_method'];
548
					else
549 979cd6db Scott Ullrich
						$authmethod = 'pre_shared_key';
550 a63f7d55 Scott Ullrich
551 979cd6db Scott Ullrich
					$certline = '';
552
553 3462a529 Matthew Grooms
					if (strstr($authmethod,'rsa')) {
554 c52719a8 Scott Ullrich
555 73fbece8 mgrooms
						$cert = lookup_cert($ph1ent['certref']);
556 979cd6db Scott Ullrich
557 73fbece8 mgrooms
						if (!$cert)
558
						{
559 89ceb4ba Renato Botelho
							log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
560 73fbece8 mgrooms
							continue;
561 a63f7d55 Scott Ullrich
						}
562 73fbece8 mgrooms
563
						$certfile = "cert-".$ikeid.".crt";
564
						$certpath = $g['varetc_path']."/".$certfile;
565
566
						if (!file_put_contents($certpath, base64_decode($cert['crt'])))
567
						{
568 89ceb4ba Renato Botelho
							log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name']));
569 73fbece8 mgrooms
							continue;
570 979cd6db Scott Ullrich
						}
571 73fbece8 mgrooms
572
						chmod($certpath, 0600);
573
574
						$keyfile = "cert-".$ikeid.".key";
575
						$keypath = $g['varetc_path']."/".$keyfile;
576
577 dd30341d Eirik Oeverby
						if (!file_put_contents($keypath, base64_decode($cert['prv'])))
578 73fbece8 mgrooms
						{
579 89ceb4ba Renato Botelho
							log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
580 73fbece8 mgrooms
							continue;
581 979cd6db Scott Ullrich
						}
582 73fbece8 mgrooms
583
						chmod($keypath, 0600);
584
585 a22d475f jim-p
						$ca = lookup_ca($ph1ent['caref']);
586 dc291feb jim-p
						if ($ca) {
587
							$cafile = "ca-".$ikeid.".crt";
588
							$capath = $g['varetc_path']."/".$cafile;
589
590
							if (!file_put_contents($capath, base64_decode($ca['crt'])))
591
							{
592 89ceb4ba Renato Botelho
								log_error(sprintf(gettext("Error: Cannot write phase1 CA certificate file for %s"), $ph1ent['name']));
593 dc291feb jim-p
								continue;
594
							}
595 96ef83a7 jim-p
596 dc291feb jim-p
							chmod($capath, 0600);
597
							$caline = "ca_type x509 \"".basename($capath)."\";";
598 96ef83a7 jim-p
						}
599
600 dd30341d Eirik Oeverby
						$certline = "certificate_type x509 \"".basename($certpath)."\" \"".basename($keypath)."\";";
601 96ef83a7 jim-p
602 c52719a8 Scott Ullrich
					}
603 a93e56c5 Matthew Grooms
604
					$ealgos = '';
605
					$ealg_id = $ph1ent['encryption-algorithm']['name'];
606
					$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
607
					if ($ealg_kl)
608
						$ealgos = $ealgos.$ealg_id." ".$ealg_kl;
609
					else
610
						$ealgos = $ealgos.$ealg_id;
611
612
					$lifeline = '';
613
					if ($ph1ent['lifetime'])
614
						$lifeline = "lifetime time {$ph1ent['lifetime']} secs;";
615 3462a529 Matthew Grooms
616 36d047f5 jim-p
					/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
617
					if (!(($ph1ent['authentication_method'] == "pre_shared_key") && isset($ph1ent['mobile']))) {
618
						$peerid_spec = "peers_identifier {$peerid_type} {$peerid_data};";
619
					}
620
621 a93e56c5 Matthew Grooms
					/* add remote section to configuration */
622
623 979cd6db Scott Ullrich
					$racoonconf .=<<<EOD
624 3462a529 Matthew Grooms
625 a93e56c5 Matthew Grooms
remote {$rgip}
626
{
627
	ph1id {$ikeid};
628
	exchange_mode {$ph1ent['mode']};
629
	my_identifier {$myid_type} {$myid_data};
630 36d047f5 jim-p
	{$peerid_spec}
631 a93e56c5 Matthew Grooms
	ike_frag on;
632 3462a529 Matthew Grooms
	generate_policy = {$genp};
633
	initial_contact = {$init};
634
	nat_traversal = {$natt};
635 a63f7d55 Scott Ullrich
	{$certline}
636 96ef83a7 jim-p
	{$caline}
637 3462a529 Matthew Grooms
	{$dpdline1}
638
	{$dpdline2}
639 5b237745 Scott Ullrich
	support_proxy on;
640 bdf4ad85 jim-p
	proposal_check {$pcheck};
641
	{$passive}
642 5b237745 Scott Ullrich
643 a93e56c5 Matthew Grooms
	proposal
644
	{
645 a63f7d55 Scott Ullrich
		authentication_method {$authmethod};
646 a93e56c5 Matthew Grooms
		encryption_algorithm ${ealgos};
647
		hash_algorithm {$ph1ent['hash-algorithm']};
648
		dh_group {$ph1ent['dhgroup']};
649
		${lifeline}
650
	}
651
}
652 5b237745 Scott Ullrich
653
EOD;
654 a93e56c5 Matthew Grooms
				}
655
				/* end remote */
656
			}
657
			/* end remote sections */
658
		
659
			/* begin sainfo sections */
660
			if (is_array($a_phase2) && count($a_phase2)) {
661 3462a529 Matthew Grooms
662 a93e56c5 Matthew Grooms
				/* begin sainfo */
663
				foreach ($a_phase2 as $ph2ent) {
664 c52719a8 Scott Ullrich
665 a93e56c5 Matthew Grooms
					$ikeid = $ph2ent['ikeid'];
666 c52719a8 Scott Ullrich
667 4b96b367 mgrooms
					if( !ipsec_lookup_phase1($ph2ent,$ph1ent))
668
						continue;
669
670
					if (isset($ph1ent['disabled']))
671
						continue;
672
673 3462a529 Matthew Grooms
					if (isset($ph2ent['disabled']))
674
						continue;
675
676
					if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
677
						continue;
678
679 98790f61 Seth Mos
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
680 c52719a8 Scott Ullrich
681 4b96b367 mgrooms
						$localid_type = $ph2ent['localid']['type'];
682 98790f61 Seth Mos
						$ph2ent['localid']['mode'] = $ph2ent['mode'];
683 4b96b367 mgrooms
						$localid_data = ipsec_idinfo_to_cidr($ph2ent['localid']);
684 8f5c3d8d Pierre POMES
						/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
685 8ab82dec jim-p
						if (($localid_type == "none") ||
686
							(($ph1ent['authentication_method'] == "xauth_psk_server") ||
687
							($ph1ent['authentication_method'] == "pre_shared_key"))
688 8f5c3d8d Pierre POMES
							&& isset($ph1ent['mobile'])
689
							&& (ipsec_get_number_of_phase2($ikeid)==1))
690 63017a73 Ermal Lu?i
							$localid_spec = " ";
691 aab78bd9 pierrepomes
						else {
692 20699f3f jim-p
							if ($localid_type != "address") {
693
								$localid_type = "subnet";
694
							}
695 cf0a2714 jim-p
							// Don't let an empty subnet into racoon.conf, it can cause parse errors. Ticket #2201.
696
							if (!is_subnet($localid_data)) {
697
								log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
698
								continue;
699
							}
700 20699f3f jim-p
							$localid_spec = $localid_type." ".$localid_data." any";
701
						}
702 3462a529 Matthew Grooms
703 4b96b367 mgrooms
						if (!isset($ph2ent['mobile'])) {
704
							$remoteid_type = $ph2ent['remoteid']['type'];
705
							if ($remoteid_type != "address")
706
								$remoteid_type = "subnet";
707 3462a529 Matthew Grooms
708 4b96b367 mgrooms
							$remoteid_data = ipsec_idinfo_to_cidr($ph2ent['remoteid']);
709
							$remoteid_spec = $remoteid_type." ".$remoteid_data." any";
710
						} else
711
							$remoteid_spec = "anonymous";
712 3462a529 Matthew Grooms
713 4b96b367 mgrooms
					} else {
714
						$rgip = $rgmap[$ph1ent['remote-gateway']];
715 5b237745 Scott Ullrich
716 20699f3f jim-p
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
717
							($ph1ent['authentication_method'] == "pre_shared_key"))
718
							&& isset($ph1ent['mobile']))
719
							$localid_spec = " ";
720
						else {
721
							$localid_data = ipsec_get_phase1_src($ph1ent);
722
							if($ph2ent['mode'] == 'transport') { $localid_data="$localid_data any"; }
723
							$localid_spec = "address {$localid_data}";
724
						}
725
						if (!isset($ph2ent['mobile'])) {
726
							$remoteid_data = $rgmap[$ph1ent['remote-gateway']];
727
							if($ph2ent['mode'] == 'transport') { $remoteid_data="$remoteid_data any"; }
728
							$remoteid_spec = "address {$remoteid_data}";
729
						} else
730
							$remoteid_spec = "anonymous";
731 3462a529 Matthew Grooms
					}
732 c52719a8 Scott Ullrich
733 57dc2556 mgrooms
					if($ph2ent['protocol'] == 'esp') {
734 4b96b367 mgrooms
735
						$ealgos = '';
736 c52719a8 Scott Ullrich
737 4b96b367 mgrooms
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
738 c52719a8 Scott Ullrich
739 4b96b367 mgrooms
							$ealg_id = $ealg['name'];
740
							$ealg_kl = $ealg['keylen'];
741 c52719a8 Scott Ullrich
742 4b96b367 mgrooms
							if ($ealg_kl) {
743
								if( $ealg_kl == "auto" ) {
744 4ae540e5 Scott Ullrich
									/*   This seems to be required on my system and was not reproducable
745
									 *   on other systems.   For some reason $p2_ealgos is not defined
746
									 *   and needs to be read back in!?  -sullrich Aug 26, 2009 
747
									 */
748
									if(!$p2_ealgos)
749
										require("ipsec.inc");
750 4b96b367 mgrooms
									$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
751
									$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
752
									$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
753 d86d411a Scott Ullrich
									/* in some cases where include ordering is suspect these variables
754
									   are somehow 0 and we enter this loop forever and timeout after 900
755
									   seconds wrecking bootup */
756 52bcf4b2 Scott Ullrich
									if($key_hi != 0 and $key_lo !=0 and $key_step !=0) {
757 d86d411a Scott Ullrich
										for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
758 4ae540e5 Scott Ullrich
//											Uncomment the next line if you want to test the comment 5 lines up.											
759 68e74187 Scott Ullrich
//											echo "$keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step \n";
760 d86d411a Scott Ullrich
											if ($ealgos)
761
												$ealgos = $ealgos.", ";
762
											$ealgos = $ealgos.$ealg_id." ".$keylen;
763
										}
764 4b96b367 mgrooms
									}
765
								} else {
766
									if ($ealgos)
767 a93e56c5 Matthew Grooms
										$ealgos = $ealgos.", ";
768 4b96b367 mgrooms
									$ealgos = $ealgos.$ealg_id." ".$ealg_kl;
769 a93e56c5 Matthew Grooms
								}
770
							} else {
771
								if ($ealgos)
772
									$ealgos = $ealgos.", ";
773 4b96b367 mgrooms
								$ealgos = $ealgos.$ealg_id;
774 979cd6db Scott Ullrich
							}
775 a93e56c5 Matthew Grooms
						}
776 4b96b367 mgrooms
777
						$ealgosline = "encryption_algorithm {$ealgos};";
778
779
					} else {
780
781
						$ealgosline = "encryption_algorithm null_enc;";
782 a63f7d55 Scott Ullrich
					}
783 c52719a8 Scott Ullrich
784 4b96b367 mgrooms
					$halgos = join(",", $ph2ent['hash-algorithm-option']);
785
					$halgosline = "authentication_algorithm {$halgos};";
786
787
					$pfsline = '';
788
					if ($ph2ent['pfsgroup'])
789
						$pfsline = "pfs_group {$ph2ent['pfsgroup']};";
790
					if (isset($a_client['pfs_group'])) {
791
						$pfsline = '';
792
						if ($a_client['pfs_group'])
793
							$pfsline = "pfs_group {$a_client['pfs_group']};";
794
					}
795
796
					$lifeline = '';
797
					if ($ph2ent['lifetime'])
798
						$lifeline = "lifetime time {$ph2ent['lifetime']} secs;";
799
800 a93e56c5 Matthew Grooms
					/* add sainfo section to configuration */
801
					
802
					$racoonconf .=<<<EOD
803
					
804 3462a529 Matthew Grooms
sainfo {$localid_spec} {$remoteid_spec}
805 a93e56c5 Matthew Grooms
{
806
	remoteid {$ikeid};
807 4b96b367 mgrooms
	{$ealgosline}
808
	{$halgosline}
809 3462a529 Matthew Grooms
	{$pfsline}
810
	{$lifeline}
811 4b96b367 mgrooms
	compression_algorithm deflate;
812 a93e56c5 Matthew Grooms
}
813 5b237745 Scott Ullrich
814
EOD;
815 a93e56c5 Matthew Grooms
				}
816
				/* end sainfo */
817 5b237745 Scott Ullrich
			}
818 a93e56c5 Matthew Grooms
			/* end sainfo sections */
819 c52719a8 Scott Ullrich
820 5b237745 Scott Ullrich
			fwrite($fd, $racoonconf);
821
			fclose($fd);
822 a93e56c5 Matthew Grooms
		}
823
		/* end racoon.conf */
824 c52719a8 Scott Ullrich
825 a93e56c5 Matthew Grooms
		/* generate IPsec policies */
826 7dcf1cc7 jim-p
		/* generate spd.conf */
827
		$fd = fopen("{$g['varetc_path']}/spd.conf", "w");
828
		if (!$fd) {
829
			printf(gettext("Error: cannot open spd.conf in vpn_ipsec_configure().") . "\n");
830
			return 1;
831
		}
832 c52719a8 Scott Ullrich
833 7dcf1cc7 jim-p
		$spdconf = "";
834
		if (is_array($a_phase2) && count($a_phase2)) {
835 e1bcba1f Ermal Lu?i
			/* Try to prevent people from locking themselves out of webgui. Just in case. */
836
			if ($config['interfaces']['lan']) {
837 6c74ac23 Ermal
				$lanip = get_interface_ip("lan");
838 98790f61 Seth Mos
				if (!empty($lanip) && is_ipaddrv4($lanip)) {
839 6c74ac23 Ermal
					$lansn = get_interface_subnet("lan");
840
					$lansa = gen_subnet($lanip, $lansn);
841 98790f61 Seth Mos
					$spdconf .= "spdadd -4 {$lanip}/32 {$lansa}/{$lansn} any -P out none;\n";
842
					$spdconf .= "spdadd -4 {$lansa}/{$lansn} {$lanip}/32 any -P in none;\n";
843
				}
844
				$lanipv6 = get_interface_ipv6("lan");
845
				if (!empty($lanipv6) && is_ipaddrv6($lanipv6)) {
846
					$lansnv6 = get_interface_subnetv6("lan");
847
					$lansav6 = gen_subnetv6($lanipv6, $lansnv6);
848
					$spdconf .= "spdadd -6 {$lanipv6}/128 {$lansav6}/{$lansnv6} any -P out none;\n";
849
					$spdconf .= "spdadd -6 {$lansav6}/{$lansnv6} {$lanipv6}/128 any -P in none;\n";
850 6c74ac23 Ermal
				}
851 e1bcba1f Ermal Lu?i
			}
852 c52719a8 Scott Ullrich
853 a93e56c5 Matthew Grooms
			foreach ($a_phase2 as $ph2ent) {
854 3462a529 Matthew Grooms
855 a93e56c5 Matthew Grooms
				if( !ipsec_lookup_phase1($ph2ent,$ph1ent))
856
					continue;
857 c52719a8 Scott Ullrich
858 3462a529 Matthew Grooms
				if (isset($ph1ent['mobile']))
859
					continue;
860
861
				if (isset($ph1ent['disabled']))
862 a93e56c5 Matthew Grooms
					continue;
863
864 3462a529 Matthew Grooms
				if (isset($ph2ent['disabled']))
865 a93e56c5 Matthew Grooms
					continue;
866
867 0af7398a Matthew Grooms
				$ep = ipsec_get_phase1_src($ph1ent);
868 a93e56c5 Matthew Grooms
				if (!$ep)
869
					continue;
870
871
				$rgip = $rgmap[$ph1ent['remote-gateway']];
872 71e91e50 smos
				if(!is_ipaddr($rgip))
873 41393f1e smos
					continue;
874 a93e56c5 Matthew Grooms
875 98790f61 Seth Mos
				$ph2ent['localid']['mode'] = $ph2ent['mode'];
876 a93e56c5 Matthew Grooms
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'],true);
877
				$remoteid = ipsec_idinfo_to_cidr($ph2ent['remoteid'],true);
878
879 cf0a2714 jim-p
				// Error will be logged above, no need to log this twice. #2201
880
				if (!is_subnet($localid))
881
					continue;
882
883 98790f61 Seth Mos
				if(($ph2ent['mode'] == "tunnel") or ($ph2ent['mode'] == 'tunnel6')) {
884
					if($ph2ent['mode'] == "tunnel6")
885
						$family = "-6";
886
					else
887
						$family = "-4";
888 4b96b367 mgrooms
889 98790f61 Seth Mos
					$spdconf .= "spdadd {$family} {$localid} {$remoteid} any -P out ipsec " .
890 4b96b367 mgrooms
						"{$ph2ent['protocol']}/tunnel/{$ep}-{$rgip}/unique;\n";
891 a93e56c5 Matthew Grooms
892 98790f61 Seth Mos
					$spdconf .= "spdadd {$family} {$remoteid} {$localid} any -P in ipsec " .
893 4b96b367 mgrooms
						"{$ph2ent['protocol']}/tunnel/{$rgip}-{$ep}/unique;\n";
894
895
				} else {
896
897 dd30341d Eirik Oeverby
					$localid_data = ipsec_get_phase1_src($ph1ent);
898
					$remoteid_data = $rgmap[$ph1ent['remote-gateway']];
899 4b96b367 mgrooms
900 dd30341d Eirik Oeverby
					$spdconf .= "spdadd {$localid_data} {$remoteid_data} any -P out ipsec " .
901
						"{$ph2ent['protocol']}/transport//require;\n";
902
903
					$spdconf .= "spdadd {$remoteid_data} {$localid_data} any -P in ipsec " .
904
						"{$ph2ent['protocol']}/transport//require;\n";
905 4b96b367 mgrooms
906
				}
907 a93e56c5 Matthew Grooms
908
				/* static route needed? */
909 63017a73 Ermal Lu?i
				if (preg_match("/^carp|^vip/i", $ph1ent['interface']))
910 a93e56c5 Matthew Grooms
					$parentinterface = link_carp_interface_to_parent($ph1ent['interface']);
911
				else
912
					$parentinterface = $ph1ent['interface'];
913
914 71e91e50 smos
				if (($parentinterface <> "wan") && (is_ipaddr($rgip))) {
915 a93e56c5 Matthew Grooms
					/* add endpoint routes to correct gateway on interface */
916
					if (interface_has_gateway($parentinterface)) {
917
						$gatewayip = get_interface_gateway("$parentinterface");
918 a55e9c70 Ermal Lu?i
						$interfaceip = get_interface_ip($parentinterface);
919
						$subnet_bits = get_interface_subnet($parentinterface);
920 a93e56c5 Matthew Grooms
						$subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
921
						/* if the remote gateway is in the local subnet, then don't add a route */
922
						if (! ip_in_subnet($rgip, "{$subnet_ip}/{$subnet_bits}")) {
923
							if(is_ipaddr($gatewayip)) {
924 c60cae98 Seth Mos
								/* FIXME: does adding route-to and reply-to on the in/outbound
925
								 * rules fix this? smos@ 13-01-2009 */
926 131f3a50 jim-p
								// log_error("IPSEC interface is not WAN but {$parentinterface}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
927 8ff6b72c Ermal
								mwexec("/sbin/route change -host {$rgip} {$gatewayip}", true);
928 a93e56c5 Matthew Grooms
							}
929
						}
930 979cd6db Scott Ullrich
					}
931 320bba64 Ermal
				} else if(is_ipaddr($rgip))
932
					mwexec("/sbin/route delete -host {$rgip}", true);
933 a93e56c5 Matthew Grooms
			}
934
935
		}
936 7dcf1cc7 jim-p
		fwrite($fd, $spdconf);
937
		fclose($fd);
938 a93e56c5 Matthew Grooms
939 c8423fbf Matthew Grooms
		/* needed for racoonctl admin socket */
940 f0c3eea0 Scott Ullrich
		if (!is_dir("/var/db/racoon"))
941 c8423fbf Matthew Grooms
			mkdir("/var/db/racoon/");
942
		
943 a93e56c5 Matthew Grooms
		/* mange racoon process */
944
		if (is_process_running("racoon")) {
945 223547eb Seth Mos
			sleep("0.1");
946 6b5e978b Ermal
			mwexec("/usr/local/sbin/racoonctl -s /var/db/racoon/racoon.sock reload-config", false);
947 f3c8bd98 Ermal Lu?i
			/* load SPD without flushing to be safe on config additions or changes. */
948
			mwexec("/usr/local/sbin/setkey -f {$g['varetc_path']}/spd.conf", false);
949 a93e56c5 Matthew Grooms
		} else {
950
			/* flush SA + SPD entries */
951 c60cae98 Seth Mos
			mwexec("/usr/local/sbin/setkey -FP", false);
952
 			sleep("0.1");
953
			mwexec("/usr/local/sbin/setkey -F", false);
954
 			sleep("0.1");
955
 			/* start racoon */
956 127eb8e0 jim-p
			$ipsecdebug = isset($config['ipsec']['racoondebug']) ? "-d -v" : "";
957
			mwexec("/usr/local/sbin/racoon {$ipsecdebug} -f {$g['varetc_path']}/racoon.conf", false);
958 c60cae98 Seth Mos
 			sleep("0.1");
959
 			/* load SPD */
960
			mwexec("/usr/local/sbin/setkey -f {$g['varetc_path']}/spd.conf", false);
961 a93e56c5 Matthew Grooms
962 d161b4d4 smos
		}
963
		/* start filterdns, if necessary */
964
		if (count($filterdns_list) > 0) {
965
			$interval = 60;
966
			if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
967
				$interval = $ipseccfg['dns-interval'];
968
969
			$hostnames = "";
970
			array_unique($filterdns_list);
971
			foreach ($filterdns_list as $hostname)
972 4e192846 Ermal
				$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
973 d161b4d4 smos
			file_put_contents("{$g['varetc_path']}/filterdns-ipsec.hosts", $hostnames);
974
975
			killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
976 8c218e1d Ermal
			sleep(1);
977 d161b4d4 smos
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/filterdns-ipsec.hosts -d 1");
978 5b237745 Scott Ullrich
		}
979 a93e56c5 Matthew Grooms
	
980 924876a8 Ermal Lu?i
		vpn_ipsec_failover_configure();
981 a63f7d55 Scott Ullrich
982 72bd8df5 Ermal Lu?i
		if ($g['booting'])
983 924876a8 Ermal Lu?i
			echo "done\n";
984 5b237745 Scott Ullrich
	}
985 8f67a8e1 Scott Ullrich
986 5b237745 Scott Ullrich
	return 0;
987
}
988
989 67ee1ec5 Ermal Luçi
/* Forcefully restart IPsec
990
 * This is required for when dynamic interfaces reload
991
 * For all other occasions the normal vpn_ipsec_configure()
992
 * will gracefully reload the settings without restarting
993
 */
994
function vpn_ipsec_force_reload() {
995
	global $config;
996
	global $g;
997
998
	$ipseccfg = $config['ipsec'];
999
1000
	/* kill racoon */
1001 99f98b80 sullrich
	if(is_process_running("racoon"))
1002
		mwexec("/usr/bin/killall racoon", true);
1003 67ee1ec5 Ermal Luçi
1004
	/* wait for process to die */
1005
	sleep(4);
1006
1007
	/* send a SIGKILL to be sure */
1008
	sigkillbypid("{$g['varrun_path']}/racoon.pid", "KILL");
1009
1010
	/* wait for flushing to finish */
1011
	sleep(1);
1012
1013
	/* if ipsec is enabled, start up again */
1014
	if (isset($ipseccfg['enable'])) {
1015 89ceb4ba Renato Botelho
		log_error(gettext("Forcefully reloading IPsec racoon daemon"));
1016 67ee1ec5 Ermal Luçi
		vpn_ipsec_configure();
1017
	}
1018
1019
}
1020
1021
/* master setup for vpn (mpd) */
1022
function vpn_setup() {
1023 7734aea6 Andrew Thompson
	global $g;
1024
1025
	if ($g['platform'] == 'jail')
1026
		return;
1027
1028 67ee1ec5 Ermal Luçi
	/* start pptpd */
1029
	vpn_pptpd_configure();
1030
1031
	/* start pppoe server */
1032 0e642c78 Ermal
	vpn_pppoes_configure();
1033 67ee1ec5 Ermal Luçi
1034
	/* setup l2tp */
1035
	vpn_l2tp_configure();
1036
}
1037
1038 67b057a9 Ermal
function vpn_netgraph_support() {
1039
	$iflist = get_configured_interface_list();
1040
	foreach ($iflist as $iface) {
1041
		$realif = get_real_interface($iface);
1042
		/* Get support for netgraph(4) from the nic */
1043 c513c309 Ermal
		$ifinfo = pfSense_get_interface_addresses($realif);
1044
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
1045
                	pfSense_ngctl_attach(".", $realif);
1046 67b057a9 Ermal
	}
1047
}
1048
1049 5b237745 Scott Ullrich
function vpn_pptpd_configure() {
1050
	global $config, $g;
1051 c52719a8 Scott Ullrich
1052 5b237745 Scott Ullrich
	$syscfg = $config['system'];
1053
	$pptpdcfg = $config['pptpd'];
1054 c52719a8 Scott Ullrich
1055 5b237745 Scott Ullrich
	if ($g['booting']) {
1056
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
1057
			return 0;
1058 c52719a8 Scott Ullrich
1059 89ceb4ba Renato Botelho
		echo gettext("Configuring PPTP VPN service... ");
1060 c52719a8 Scott Ullrich
	} else {
1061 5b237745 Scott Ullrich
		/* kill mpd */
1062 67ee1ec5 Ermal Luçi
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1063 c52719a8 Scott Ullrich
1064 5b237745 Scott Ullrich
		/* wait for process to die */
1065 48bff85c Scott Ullrich
		sleep(3);
1066 c52719a8 Scott Ullrich
1067 979cd6db Scott Ullrich
		if (is_process_running("mpd -b")) {
1068 67ee1ec5 Ermal Luçi
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1069 89ceb4ba Renato Botelho
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
1070 48bff85c Scott Ullrich
		}
1071 c52719a8 Scott Ullrich
1072 5b237745 Scott Ullrich
		/* remove mpd.conf, if it exists */
1073 67ee1ec5 Ermal Luçi
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
1074
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
1075
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
1076 5b237745 Scott Ullrich
	}
1077 c52719a8 Scott Ullrich
1078 1fb8d314 Ermal
	if (empty($pptpdcfg['n_pptp_units'])) {
1079
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
1080
		return; 
1081
	}
1082
1083 67ee1ec5 Ermal Luçi
	/* make sure pptp-vpn directory exists */
1084
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
1085
		mkdir("{$g['varetc_path']}/pptp-vpn");
1086 c52719a8 Scott Ullrich
1087 5b237745 Scott Ullrich
	switch ($pptpdcfg['mode']) {
1088 979cd6db Scott Ullrich
		case 'server' :
1089 5b237745 Scott Ullrich
			/* write mpd.conf */
1090 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1091 5b237745 Scott Ullrich
			if (!$fd) {
1092 89ceb4ba Renato Botelho
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
1093 5b237745 Scott Ullrich
				return 1;
1094
			}
1095 c52719a8 Scott Ullrich
1096 045c9cc9 sullrich
			$mpdconf = <<<EOD
1097 a6607b5f jim-p
pptps:
1098 5b237745 Scott Ullrich
1099
EOD;
1100
1101 f2b4ff2b sullrich
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1102 5b237745 Scott Ullrich
				$mpdconf .= "	load pt{$i}\n";
1103
			}
1104 c52719a8 Scott Ullrich
1105 f2b4ff2b sullrich
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1106 c52719a8 Scott Ullrich
1107 96033063 Erik Fonnesbeck
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1108 c52719a8 Scott Ullrich
1109 045c9cc9 sullrich
				$mpdconf .= <<<EOD
1110 5b237745 Scott Ullrich
1111
pt{$i}:
1112 bfa6d878 Ermal Lu?i
	new -i pptpd{$i} pt{$i} pt{$i}
1113 045c9cc9 sullrich
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1114 979cd6db Scott Ullrich
	load pts
1115 5b237745 Scott Ullrich
1116
EOD;
1117
			}
1118 c52719a8 Scott Ullrich
1119 979cd6db Scott Ullrich
			$mpdconf .=<<<EOD
1120 5b237745 Scott Ullrich
1121 979cd6db Scott Ullrich
pts:
1122 5b237745 Scott Ullrich
	set iface disable on-demand
1123
	set iface enable proxy-arp
1124 07cae4b2 Scott Ullrich
	set iface enable tcpmssfix
1125 979cd6db Scott Ullrich
	set iface idle 1800
1126 e9a95ac8 jim-p
	set iface up-script /usr/local/sbin/vpn-linkup
1127
	set iface down-script /usr/local/sbin/vpn-linkdown
1128 5b237745 Scott Ullrich
	set bundle enable multilink
1129 979cd6db Scott Ullrich
	set bundle enable crypt-reqd
1130 5b237745 Scott Ullrich
	set link yes acfcomp protocomp
1131
	set link no pap chap
1132 979cd6db Scott Ullrich
	set link enable chap-msv2
1133 ee953edc Scott Ullrich
	set link mtu 1460
1134 5b237745 Scott Ullrich
	set link keep-alive 10 60
1135
	set ipcp yes vjcomp
1136
	set bundle enable compression
1137
	set ccp yes mppc
1138
	set ccp yes mpp-e128
1139
	set ccp yes mpp-stateless
1140
1141
EOD;
1142 c52719a8 Scott Ullrich
1143 979cd6db Scott Ullrich
			if (!isset ($pptpdcfg['req128'])) {
1144
				$mpdconf .=<<<EOD
1145 5b237745 Scott Ullrich
	set ccp yes mpp-e40
1146 979cd6db Scott Ullrich
	set ccp yes mpp-e56
1147 5b237745 Scott Ullrich
1148
EOD;
1149
			}
1150 c8c416db Scott Ullrich
1151 871ce025 Bill Marquette
			if  (isset($pptpdcfg["wins"]) && $pptpdcfg['wins'] != "")
1152 979cd6db Scott Ullrich
				$mpdconf  .=  "	set ipcp nbns {$pptpdcfg['wins']}\n";
1153 09f2bf85 jim-p
1154
			if (!empty($pptpdcfg['dns1'])) {
1155
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1156
				if (!empty($pptpdcfg['dns2']))
1157
					$mpdconf .= " " . $pptpdcfg['dns2'];
1158
				$mpdconf .= "\n";
1159
			} elseif (isset ($config['dnsmasq']['enable'])) {
1160
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1161
				if ($syscfg['dnsserver'][0])
1162
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1163
				$mpdconf .= "\n";
1164
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1165
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1166
			}
1167 07cae4b2 Scott Ullrich
1168 71569a7e jim-p
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1169
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1170 979cd6db Scott Ullrich
				$acctport = $authport + 1;
1171
				$mpdconf .=<<<EOD
1172 71569a7e jim-p
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1173 35b91f77 sullrich
1174 71569a7e jim-p
EOD;
1175
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1176
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1177
				$acctport = $authport + 1;
1178
				$mpdconf .=<<<EOD
1179 846a6dc2 jim-p
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1180 35b91f77 sullrich
1181 71569a7e jim-p
EOD;
1182
			}
1183
			$mpdconf .=<<<EOD
1184 5b237745 Scott Ullrich
	set radius retries 3
1185 979cd6db Scott Ullrich
	set radius timeout 10
1186 0af9dba4 Ermal Lu?i
	set auth enable radius-auth
1187 5b237745 Scott Ullrich
1188
EOD;
1189
1190 979cd6db Scott Ullrich
				if (isset ($pptpdcfg['radius']['accounting'])) {
1191
					$mpdconf .=<<<EOD
1192 0af9dba4 Ermal Lu?i
	set auth enable radius-acct
1193 979cd6db Scott Ullrich
	set radius acct-update 300
1194 5b237745 Scott Ullrich
1195
EOD;
1196
				}
1197
			}
1198
1199
			fwrite($fd, $mpdconf);
1200
			fclose($fd);
1201 c52719a8 Scott Ullrich
1202 5b237745 Scott Ullrich
			/* write mpd.links */
1203 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1204 5b237745 Scott Ullrich
			if (!$fd) {
1205 89ceb4ba Renato Botelho
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1206 5b237745 Scott Ullrich
				return 1;
1207
			}
1208 c52719a8 Scott Ullrich
1209 5b237745 Scott Ullrich
			$mpdlinks = "";
1210 c52719a8 Scott Ullrich
1211 a56120f2 Ermal Lu?i
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1212 979cd6db Scott Ullrich
				$mpdlinks .=<<<EOD
1213 5b237745 Scott Ullrich
1214
pt{$i}:
1215
	set link type pptp
1216
	set pptp enable incoming
1217
	set pptp disable originate
1218 979cd6db Scott Ullrich
	set pptp disable windowing
1219 5b237745 Scott Ullrich
1220
EOD;
1221
			}
1222
1223
			fwrite($fd, $mpdlinks);
1224
			fclose($fd);
1225 c52719a8 Scott Ullrich
1226 5b237745 Scott Ullrich
			/* write mpd.secret */
1227 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1228 5b237745 Scott Ullrich
			if (!$fd) {
1229 89ceb4ba Renato Botelho
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1230 5b237745 Scott Ullrich
				return 1;
1231
			}
1232 c52719a8 Scott Ullrich
1233 5b237745 Scott Ullrich
			$mpdsecret = "";
1234 c52719a8 Scott Ullrich
1235 5b237745 Scott Ullrich
			if (is_array($pptpdcfg['user'])) {
1236 4cf82d52 jim-p
				foreach ($pptpdcfg['user'] as $user) {
1237 4222087e jim-p
					$pass = str_replace('\\', '\\\\', $user['password']);
1238
					$pass = str_replace('"', '\"', $pass);
1239 4cf82d52 jim-p
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1240
				}
1241 5b237745 Scott Ullrich
			}
1242
1243
			fwrite($fd, $mpdsecret);
1244
			fclose($fd);
1245 67ee1ec5 Ermal Luçi
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1246 c52719a8 Scott Ullrich
1247 67b057a9 Ermal
			vpn_netgraph_support();
1248
1249 5b237745 Scott Ullrich
			/* fire up mpd */
1250 a6607b5f jim-p
			mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']}/pptp-vpn -p {$g['varrun_path']}/pptp-vpn.pid -s pptps pptps");
1251 c52719a8 Scott Ullrich
1252 5b237745 Scott Ullrich
			break;
1253 c52719a8 Scott Ullrich
1254 979cd6db Scott Ullrich
		case 'redir' :
1255 5b237745 Scott Ullrich
			break;
1256
	}
1257 c52719a8 Scott Ullrich
1258 a63f7d55 Scott Ullrich
	if ($g['booting'])
1259
		echo "done\n";
1260 c52719a8 Scott Ullrich
1261 5b237745 Scott Ullrich
	return 0;
1262
}
1263
1264 0e642c78 Ermal
function vpn_pppoes_configure() {
1265
	global $config;
1266
1267
	if (is_array($config['pppoes']['pppoe'])) {
1268
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1269
			vpn_pppoe_configure($pppoe);
1270
	}
1271
}
1272
1273
function vpn_pppoe_configure(&$pppoecfg) {
1274 06e69b03 Scott Ullrich
	global $config, $g;
1275
1276
	$syscfg = $config['system'];
1277
1278 48918ed5 Scott Ullrich
	/* create directory if it does not exist */
1279 0e642c78 Ermal
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1280
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1281 c52719a8 Scott Ullrich
1282 06e69b03 Scott Ullrich
	if ($g['booting']) {
1283
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1284
			return 0;
1285
1286 89ceb4ba Renato Botelho
		echo gettext("Configuring PPPoE VPN service... ");
1287 979cd6db Scott Ullrich
	} else {
1288
		/* kill mpd */
1289 0e642c78 Ermal
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1290 979cd6db Scott Ullrich
1291
		/* wait for process to die */
1292
		sleep(2);
1293
1294 06e69b03 Scott Ullrich
	}
1295
1296
	switch ($pppoecfg['mode']) {
1297
1298 979cd6db Scott Ullrich
		case 'server' :
1299 06e69b03 Scott Ullrich
1300 0e642c78 Ermal
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1301 0301deff Scott Ullrich
1302 979cd6db Scott Ullrich
			if ($pppoecfg['paporchap'] == "chap")
1303
				$paporchap = "set link enable chap";
1304
			else
1305
				$paporchap = "set link enable pap";
1306
1307 06e69b03 Scott Ullrich
			/* write mpd.conf */
1308 0e642c78 Ermal
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1309 06e69b03 Scott Ullrich
			if (!$fd) {
1310 89ceb4ba Renato Botelho
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1311 06e69b03 Scott Ullrich
				return 1;
1312
			}
1313
			$mpdconf = "\n\n";
1314 a6607b5f jim-p
			$mpdconf .= "poes:\n";
1315 06e69b03 Scott Ullrich
1316 a429d105 Scott Ullrich
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1317 0e642c78 Ermal
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1318 06e69b03 Scott Ullrich
			}
1319
1320 a429d105 Scott Ullrich
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1321 06e69b03 Scott Ullrich
1322 96033063 Erik Fonnesbeck
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1323 c52719a8 Scott Ullrich
1324 b0943409 Ermal
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1325 5dfdc1fb Scott Ullrich
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1326 5264023a Scott Ullrich
				} else {
1327
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1328 5dfdc1fb Scott Ullrich
				}
1329 c52719a8 Scott Ullrich
1330 979cd6db Scott Ullrich
				$mpdconf .=<<<EOD
1331 06e69b03 Scott Ullrich
1332 0e642c78 Ermal
poes{$pppoecfg['pppoeid']}{$i}:
1333
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1334 5dfdc1fb Scott Ullrich
	{$isssue_ip_type}
1335 f856e762 jim-p
	load pppoe_standard
1336 06e69b03 Scott Ullrich
1337
EOD;
1338
			}
1339
1340 979cd6db Scott Ullrich
			$mpdconf .=<<<EOD
1341 06e69b03 Scott Ullrich
1342 f856e762 jim-p
pppoe_standard:
1343 979cd6db Scott Ullrich
	set bundle no multilink
1344
	set bundle enable compression
1345 78155ff9 Scott Ullrich
	set auth max-logins 1
1346 e9a95ac8 jim-p
	set iface up-script /usr/local/sbin/vpn-linkup
1347
	set iface down-script /usr/local/sbin/vpn-linkdown
1348 979cd6db Scott Ullrich
	set iface idle 0
1349 06e69b03 Scott Ullrich
	set iface disable on-demand
1350
	set iface disable proxy-arp
1351
	set iface enable tcpmssfix
1352 979cd6db Scott Ullrich
	set iface mtu 1500
1353 06e69b03 Scott Ullrich
	set link no pap chap
1354 979cd6db Scott Ullrich
	{$paporchap}
1355
	set link keep-alive 60 180
1356
	set ipcp yes vjcomp
1357
	set ipcp no vjcomp
1358
	set link max-redial -1
1359
	set link mtu 1492
1360
	set link mru 1492
1361 06e69b03 Scott Ullrich
	set ccp yes mpp-e40
1362
	set ccp yes mpp-e128
1363
	set ccp yes mpp-stateless
1364 979cd6db Scott Ullrich
	set link latency 1
1365
	#set ipcp dns 10.10.1.3
1366
	#set bundle accept encryption
1367 06e69b03 Scott Ullrich
1368 c8c416db Scott Ullrich
EOD;
1369
1370 09f2bf85 jim-p
			if (!empty($pppoecfg['dns1'])) {
1371
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1372
				if (!empty($pppoecfg['dns2']))
1373
					$mpdconf .= " " . $pppoecfg['dns2'];
1374
				$mpdconf .= "\n";
1375
			} elseif (isset ($config['dnsmasq']['enable'])) {
1376 a55e9c70 Ermal Lu?i
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1377 06e69b03 Scott Ullrich
				if ($syscfg['dnsserver'][0])
1378
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1379
				$mpdconf .= "\n";
1380 09f2bf85 jim-p
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1381 979cd6db Scott Ullrich
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1382 09f2bf85 jim-p
			}
1383 07cae4b2 Scott Ullrich
1384 37d7de2d jim-p
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1385 c3583058 Ermal
				$radiusport = "";
1386
				$radiusacctport = "";
1387
				if (isset($pppoecfg['radius']['server']['port']))
1388
					$radiusport = $pppoecfg['radius']['server']['port'];
1389
				if (isset($pppoecfg['radius']['server']['acctport']))
1390
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1391 979cd6db Scott Ullrich
				$mpdconf .=<<<EOD
1392 b0943409 Ermal
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1393 06e69b03 Scott Ullrich
	set radius retries 3
1394 979cd6db Scott Ullrich
	set radius timeout 10
1395 0af9dba4 Ermal Lu?i
	set auth enable radius-auth
1396 06e69b03 Scott Ullrich
1397
EOD;
1398
1399 979cd6db Scott Ullrich
				if (isset ($pppoecfg['radius']['accounting'])) {
1400
					$mpdconf .=<<<EOD
1401 0af9dba4 Ermal Lu?i
	set auth enable radius-acct
1402 07cae4b2 Scott Ullrich
1403 06e69b03 Scott Ullrich
EOD;
1404
				}
1405
			}
1406
1407
			fwrite($fd, $mpdconf);
1408
			fclose($fd);
1409
1410
			/* write mpd.links */
1411 0e642c78 Ermal
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1412 06e69b03 Scott Ullrich
			if (!$fd) {
1413 89ceb4ba Renato Botelho
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1414 06e69b03 Scott Ullrich
				return 1;
1415
			}
1416
1417
			$mpdlinks = "";
1418
1419 a429d105 Scott Ullrich
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1420 979cd6db Scott Ullrich
				$mpdlinks .=<<<EOD
1421 67ee1ec5 Ermal Luçi
			
1422 0e642c78 Ermal
poes{$pppoecfg['pppoeid']}{$i}:
1423 67ee1ec5 Ermal Luçi
	set phys type pppoe
1424 78155ff9 Scott Ullrich
        set pppoe iface {$pppoe_interface}
1425
        set pppoe service "*"
1426
        set pppoe disable originate
1427
        set pppoe enable incoming
1428 06e69b03 Scott Ullrich
1429
EOD;
1430
			}
1431
1432
			fwrite($fd, $mpdlinks);
1433
			fclose($fd);
1434
1435 0e642c78 Ermal
			if ($pppoecfg['username']) {
1436
				/* write mpd.secret */
1437
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1438
				if (!$fd) {
1439 8c04b1ae Renato Botelho
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1440 0e642c78 Ermal
					return 1;
1441
				}
1442 06e69b03 Scott Ullrich
1443 0e642c78 Ermal
				$mpdsecret = "\n\n";
1444 06e69b03 Scott Ullrich
1445 0e642c78 Ermal
				if (!empty($pppoecfg['username'])) {
1446
					$item = explode(" ", $pppoecfg['username']);
1447
					foreach($item as $userdata) {
1448
						$data = explode(":", $userdata);
1449 90388e48 Ermal
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1450 0e642c78 Ermal
					}
1451
				}
1452 06e69b03 Scott Ullrich
1453 0e642c78 Ermal
				fwrite($fd, $mpdsecret);
1454
				fclose($fd);
1455
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1456
			}
1457 979cd6db Scott Ullrich
1458 67b057a9 Ermal
			/* Get support for netgraph(4) from the nic */
1459
			pfSense_ngctl_attach(".", $pppoe_interface);
1460 979cd6db Scott Ullrich
			/* fire up mpd */
1461 a6607b5f jim-p
			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");
1462 979cd6db Scott Ullrich
1463
			break;
1464
	}
1465
1466
	if ($g['booting'])
1467 561130e4 Carlos Eduardo Ramos
		echo gettext("done") . "\n";
1468 979cd6db Scott Ullrich
1469
	return 0;
1470
}
1471
1472
function vpn_l2tp_configure() {
1473
	global $config, $g;
1474
1475
	$syscfg = $config['system'];
1476
	$l2tpcfg = $config['l2tp'];
1477
1478
	/* create directory if it does not exist */
1479 67ee1ec5 Ermal Luçi
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1480
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1481 979cd6db Scott Ullrich
1482
	if ($g['booting']) {
1483
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1484
			return 0;
1485
1486 89ceb4ba Renato Botelho
		echo gettext("Configuring l2tp VPN service... ");
1487 979cd6db Scott Ullrich
	} else {
1488
		/* kill mpd */
1489 67ee1ec5 Ermal Luçi
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1490 979cd6db Scott Ullrich
1491
		/* wait for process to die */
1492 01c41d40 Ermal Lu?i
		sleep(8);
1493 979cd6db Scott Ullrich
1494
	}
1495
1496 67ee1ec5 Ermal Luçi
	/* make sure l2tp-vpn directory exists */
1497
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1498
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1499 979cd6db Scott Ullrich
1500
	switch ($l2tpcfg['mode']) {
1501
1502
		case 'server' :
1503
			if ($l2tpcfg['paporchap'] == "chap")
1504
				$paporchap = "set link enable chap";
1505
			else
1506
				$paporchap = "set link enable pap";
1507
1508
			/* write mpd.conf */
1509 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1510 979cd6db Scott Ullrich
			if (!$fd) {
1511 89ceb4ba Renato Botelho
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1512 979cd6db Scott Ullrich
				return 1;
1513
			}
1514
			$mpdconf = "\n\n";
1515
			$mpdconf .=<<<EOD
1516 a6607b5f jim-p
l2tps:
1517 979cd6db Scott Ullrich
1518
EOD;
1519
1520
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1521
				$mpdconf .= "	load l2tp{$i}\n";
1522
			}
1523
1524
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1525
1526 96033063 Erik Fonnesbeck
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1527 979cd6db Scott Ullrich
1528
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1529
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1530
				} else {
1531
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1532
				}
1533
1534
				$mpdconf .=<<<EOD
1535
1536
l2tp{$i}:
1537 2c7feef7 jim-p
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1538 979cd6db Scott Ullrich
	{$isssue_ip_type}
1539
	load l2tp_standard
1540
1541
EOD;
1542
			}
1543
1544
			$mpdconf .=<<<EOD
1545
1546
l2tp_standard:
1547
        set bundle disable multilink
1548
        set bundle enable compression
1549
        set bundle yes crypt-reqd
1550
        set ipcp yes vjcomp
1551
        # set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1552
        set ccp yes mppc
1553
        set iface disable on-demand
1554
        set iface enable proxy-arp
1555 e9a95ac8 jim-p
	set iface up-script /usr/local/sbin/vpn-linkup
1556
	set iface down-script /usr/local/sbin/vpn-linkdown
1557 979cd6db Scott Ullrich
        set link yes acfcomp protocomp
1558
        set link no pap chap
1559
        set link enable chap
1560
        set link keep-alive 10 180
1561
1562
EOD;
1563
1564 c8cc0c1c smos
			if (is_ipaddr($l2tpcfg['wins'])) {
1565
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1566
			}
1567
			if (is_ipaddr($l2tpcfg['dns1'])) {
1568 09f2bf85 jim-p
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1569 c8cc0c1c smos
				if (is_ipaddr($l2tpcfg['dns2']))
1570 09f2bf85 jim-p
					$mpdconf .= " " . $l2tpcfg['dns2'];
1571
				$mpdconf .= "\n";
1572
			} elseif (isset ($config['dnsmasq']['enable'])) {
1573 a55e9c70 Ermal Lu?i
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1574 979cd6db Scott Ullrich
				if ($syscfg['dnsserver'][0])
1575
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1576
				$mpdconf .= "\n";
1577 09f2bf85 jim-p
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1578 979cd6db Scott Ullrich
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1579 09f2bf85 jim-p
			}
1580 979cd6db Scott Ullrich
1581
			if (isset ($l2tpcfg['radius']['enable'])) {
1582
				$mpdconf .=<<<EOD
1583
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1584
	set radius retries 3
1585
	set radius timeout 10
1586 0af9dba4 Ermal Lu?i
	set auth enable radius-auth
1587 979cd6db Scott Ullrich
1588
EOD;
1589
1590
				if (isset ($l2tpcfg['radius']['accounting'])) {
1591
					$mpdconf .=<<<EOD
1592 0af9dba4 Ermal Lu?i
	set auth enable radius-acct
1593 979cd6db Scott Ullrich
1594
EOD;
1595
				}
1596
			}
1597
1598
			fwrite($fd, $mpdconf);
1599
			fclose($fd);
1600
1601
			/* write mpd.links */
1602 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1603 979cd6db Scott Ullrich
			if (!$fd) {
1604 89ceb4ba Renato Botelho
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1605 979cd6db Scott Ullrich
				return 1;
1606
			}
1607
1608
			$mpdlinks = "";
1609
1610
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1611
				$mpdlinks .=<<<EOD
1612
1613 daa20efd Ermal Lu?i
l2tp{$i}:
1614 979cd6db Scott Ullrich
	set link type l2tp
1615 eff29d62 Ermal Lu?i
        set l2tp enable incoming
1616
        set l2tp disable originate
1617 979cd6db Scott Ullrich
1618
EOD;
1619 00f9e567 Ermal Lu?i
			if (!empty($l2tpcfg['secret']))
1620
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1621 979cd6db Scott Ullrich
			}
1622
1623
			fwrite($fd, $mpdlinks);
1624
			fclose($fd);
1625
1626
			/* write mpd.secret */
1627 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1628 979cd6db Scott Ullrich
			if (!$fd) {
1629 89ceb4ba Renato Botelho
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1630 979cd6db Scott Ullrich
				return 1;
1631
			}
1632
1633
			$mpdsecret = "\n\n";
1634
1635
			if (is_array($l2tpcfg['user'])) {
1636
				foreach ($l2tpcfg['user'] as $user)
1637
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1638
			}
1639
1640
			fwrite($fd, $mpdsecret);
1641
			fclose($fd);
1642 67ee1ec5 Ermal Luçi
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1643 06e69b03 Scott Ullrich
1644 67b057a9 Ermal
			vpn_netgraph_support();
1645
1646 06e69b03 Scott Ullrich
			/* fire up mpd */
1647 a6607b5f jim-p
			mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']}/l2tp-vpn -p {$g['varrun_path']}/l2tp-vpn.pid -s l2tps l2tps");
1648 06e69b03 Scott Ullrich
1649
			break;
1650
1651 979cd6db Scott Ullrich
		case 'redir' :
1652 06e69b03 Scott Ullrich
			break;
1653
	}
1654
1655
	if ($g['booting'])
1656
		echo "done\n";
1657
1658
	return 0;
1659
}
1660 630cfa6c Scott Ullrich
1661 c60cae98 Seth Mos
/* Walk the tunnels for hostname endpoints. If the hostnames 
1662
 * resolve to a different IP now compared to the DNS cache
1663
 * we reload the policies if the endpoint has changed */
1664
function vpn_ipsec_refresh_policies() {
1665
	global $config;
1666
	global $g;
1667
1668
	$ipseccfg = $config['ipsec'];
1669 9f14066f Seth Mos
	$a_phase1 = $config['ipsec']['phase1'];
1670
	$a_phase2 = $config['ipsec']['phase2'];
1671 c60cae98 Seth Mos
1672 9f14066f Seth Mos
	if (isset($ipseccfg['disable'])) {
1673 c60cae98 Seth Mos
		return true;
1674
	}
1675
1676
	/* Walk the Ipsec tunnel array */
1677 9f14066f Seth Mos
	if (!is_array($a_phase1) || (!count($a_phase1))) {
1678 eb9ae6bb Bill Marquette
		return;
1679 9f14066f Seth Mos
	}
1680 c60cae98 Seth Mos
1681 9f14066f Seth Mos
	foreach ($a_phase1 as $phase1) {
1682
		if (isset($phase1['disabled'])) {
1683
			continue;
1684
		}
1685
		if (is_ipaddr($phase1['remote-gateway'])) {
1686
			continue;
1687
		}
1688
		if (!is_ipaddr($phase1['remote-gateway'])) {
1689
			$dnscache = compare_hostname_to_dnscache($phase1['remote-gateway']);
1690
			$dnscache = trim($dnscache);
1691
			/* we should have the old IP addresses in the dnscache now */
1692
			if($dnscache <> "") {
1693
				$oldphase1 = $phase1;
1694
				$oldphase1['remote-gateway'] = trim($dnscache);
1695
				/* now we need to find all tunnels for this host */
1696
				if (!is_array($a_phase2) || (!count($a_phase2))) {
1697
					continue;
1698
				}
1699
				foreach ($a_phase2 as $phase2) {
1700 98718ac1 pierrepomes
					if($phase2['ikeid'] == $phase1['ikeid']) {
1701
						reload_tunnel_spd_policy ($phase1, $phase2, $oldphase1, $oldphase2);
1702
					}
1703 c60cae98 Seth Mos
				}
1704
			}
1705
		}
1706
	}
1707
1708 1d69f52f Seth Mos
	/* process all generated spd.conf files from tmp which are left behind
1709
	 * behind by either changes of dynamic tunnels or manual edits
1710
	 * scandir() is only available in PHP5 */
1711
	$tmpfiles = array();
1712
	$dh  = opendir($g['tmp_path']);
1713
	while (false !== ($filename = readdir($dh))) {
1714 98718ac1 pierrepomes
		if(preg_match("/^spd.conf.reload./", $filename)) {
1715 8d534565 Seth Mos
			$tmpfiles[] = $filename;
1716
		}
1717 1d69f52f Seth Mos
	}
1718
	sort($tmpfiles);
1719
	foreach($tmpfiles as $tmpfile) {
1720 8d534565 Seth Mos
		$ret = mwexec("/usr/local/sbin/setkey -f {$g['tmp_path']}/{$tmpfile} 2>&1", false);
1721
		if($ret == 0) {
1722
			unlink_if_exists("{$g['tmp_path']}/{$tmpfile}");
1723
		} else {
1724
			rename("{$g['tmp_path']}/{$tmpfile}", ("{$g['tmp_path']}/failed.{$tmpfile}"));
1725 1d69f52f Seth Mos
		}
1726
	}
1727 c60cae98 Seth Mos
}
1728
1729
/* reloads the tunnel configuration for a tunnel item
1730
 * Will remove and add SPD polices */
1731 9f14066f Seth Mos
function reload_tunnel_spd_policy($phase1, $phase2, $old_phase1, $old_phase2) {
1732 c60cae98 Seth Mos
	global $config;
1733
	global $g;
1734
1735 1d69f52f Seth Mos
	/* if we are not passed a old tunnel array we create one */
1736 9f14066f Seth Mos
	if(empty($old_phase1)) {
1737
		$old_phase1 = $phase1;
1738
	}
1739
	if(empty($old_phase2)) {
1740
		$old_phase2 = $phase2;
1741 1d69f52f Seth Mos
	}
1742
1743 9f14066f Seth Mos
	$sad_arr = ipsec_dump_sad();
1744 1d69f52f Seth Mos
1745 9f14066f Seth Mos
	$ep = ipsec_get_phase1_src($phase1);
1746 98790f61 Seth Mos
	$phase2['localid']['mode'] = $phase2['mode'];
1747 9f14066f Seth Mos
	$local_subnet = ipsec_idinfo_to_cidr($phase2['localid']);
1748
	$remote_subnet = ipsec_idinfo_to_cidr($phase2['remoteid']);
1749 c60cae98 Seth Mos
1750 1d69f52f Seth Mos
	/* make sure we pass the oldtunnel array with a IP for the remote gw */
1751 9f14066f Seth Mos
	$old_gw = trim($old_phase1['remote-gateway']);
1752
1753
	$old_ep = ipsec_get_phase1_src($old_phase1);
1754 98790f61 Seth Mos
	$old_phase2['localid']['mode'] = $old_phase2['mode'];
1755 9f14066f Seth Mos
	$old_local_subnet = ipsec_idinfo_to_cidr($old_phase2['localid']);
1756
	$old_remote_subnet = ipsec_idinfo_to_cidr($old_phase2['remoteid']);
1757 1d69f52f Seth Mos
1758 c60cae98 Seth Mos
	/* see if this tunnel has a hostname for the remote-gateway, and if so,
1759 f8c10a18 Ermal
	 * try to resolve it now and add it to the list for filterdns */
1760 603b4346 smos
	$rgip = "";
1761 9f14066f Seth Mos
	if (!is_ipaddr($phase1['remote-gateway'])) {
1762 d0399410 smos
		if(! $g['booting']) {
1763
			$rgip = resolve_retry($phase1['remote-gateway']);
1764
			add_hostname_to_watch($phase1['remote-gateway']);
1765
		} else {
1766
			add_hostname_to_watch($phase1['remote-gateway']);
1767
		}
1768 71e91e50 smos
		if (!is_ipaddr($rgip)) {
1769 9f14066f Seth Mos
			log_error("Could not determine VPN endpoint for '{$phase1['descr']}'");
1770 c60cae98 Seth Mos
			return false;
1771
		}
1772
	} else {
1773 9f14066f Seth Mos
		$rgip = $phase1['remote-gateway'];
1774 c60cae98 Seth Mos
	}
1775
	if (!$ep) {
1776 89ceb4ba Renato Botelho
		log_error(sprintf(gettext("Could not determine VPN endpoint for '%s'"), $phase1['descr']));
1777 c60cae98 Seth Mos
		return false;
1778
	}
1779
1780 287e0c9d Seth Mos
	if((!is_ipaddr($old_ep)) || (! is_ipaddr($ep))) {
1781 addc0439 Renato Botelho
		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));
1782 287e0c9d Seth Mos
	}
1783
	if((! is_ipaddr($rgip)) || (! is_ipaddr($old_gw))) {
1784 addc0439 Renato Botelho
		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));
1785 bd6af475 Seth Mos
	}
1786 1d69f52f Seth Mos
1787 bd6af475 Seth Mos
	$spdconf = "";
1788 1d69f52f Seth Mos
	/* Delete old SPD policies if there are changes between the old and new */
1789 9f14066f Seth Mos
	if(($phase1 != $old_phase1) || ($phase2 != $old_phase2)) {
1790 98790f61 Seth Mos
		if($old_phase2['mode'] == "tunnel6")
1791
			$family = "-6";
1792
		else
1793
			$family = "-4";
1794
1795
		$spdconf .= "spddelete {$family} {$old_local_subnet} " .
1796 9f14066f Seth Mos
			"{$old_remote_subnet} any -P out ipsec " .
1797
			"{$old_phase2['protocol']}/tunnel/{$old_ep}-" .
1798
			"{$old_gw}/unique;\n";
1799 98790f61 Seth Mos
		$spdconf .= "spddelete {$family} {$old_remote_subnet} " .
1800 9f14066f Seth Mos
			"{$old_local_subnet} any -P in ipsec " .
1801
			"{$old_phase2['protocol']}/tunnel/{$old_gw}-" .
1802
			"{$old_ep}/unique;\n";
1803 1d69f52f Seth Mos
1804
		/* zap any existing SA entries */
1805 c60cae98 Seth Mos
		foreach($sad_arr as $sad) {
1806 9f14066f Seth Mos
			if(($sad['dst'] == $old_ep) && ($sad['src'] == $old_gw)) {
1807 98790f61 Seth Mos
				$spdconf .= "delete {$family} {$old_ep} {$old_gw} {$old_phase2['protocol']} 0x{$sad['spi']};\n";
1808 c60cae98 Seth Mos
			}
1809 9f14066f Seth Mos
			if(($sad['src'] == $oldep) && ($sad['dst'] == $old_gw)) {
1810 98790f61 Seth Mos
				$spdconf .= "delete {$family} {$old_gw} {$old_ep} {$old_phase2['protocol']} 0x{$sad['spi']};\n";
1811 c60cae98 Seth Mos
			}
1812
		}
1813
	}
1814 1d69f52f Seth Mos
1815 98790f61 Seth Mos
	if($phase2['mode'] == "tunnel6")
1816
		$family = "-6";
1817
	else
1818
		$family = "-4";
1819
1820 1d69f52f Seth Mos
	/* Create new SPD entries for the new configuration */
1821
	/* zap any existing SA entries beforehand */
1822 c60cae98 Seth Mos
	foreach($sad_arr as $sad) {
1823 1d69f52f Seth Mos
		if(($sad['dst'] == $ep) && ($sad['src'] == $rgip)) {
1824 98790f61 Seth Mos
			$spdconf .= "delete {$family} {$rgip} {$ep} {$phase2['protocol']} 0x{$sad['spi']};\n";
1825 c60cae98 Seth Mos
		}
1826 1d69f52f Seth Mos
		if(($sad['src'] == $ep) && ($sad['dst'] == $rgip)) {
1827 98790f61 Seth Mos
			$spdconf .= "delete {$family} {$ep} {$rgip} {$phase2['protocol']} 0x{$sad['spi']};\n";
1828 c60cae98 Seth Mos
		}
1829
	}
1830
	/* add new SPD policies to replace them */
1831 98790f61 Seth Mos
	$spdconf .= "spdadd {$family} {$local_subnet} " .
1832 9f14066f Seth Mos
		"{$remote_subnet} any -P out ipsec " .
1833
		"{$phase2['protocol']}/tunnel/{$ep}-" .
1834 1d69f52f Seth Mos
		"{$rgip}/unique;\n";
1835 98790f61 Seth Mos
	$spdconf .= "spdadd {$family} {$remote_subnet} " .
1836 9f14066f Seth Mos
		"{$local_subnet} any -P in ipsec " .
1837
		"{$phase2['protocol']}/tunnel/{$rgip}-" .
1838 c60cae98 Seth Mos
		"{$ep}/unique;\n";
1839
1840 addc0439 Renato Botelho
	log_error(sprintf(gettext("Reloading IPsec tunnel '%1\$s'. Previous IP '%2\$s', current IP '%3\$s'. Reloading policy"), $phase1['descr'], $old_gw, $rgip));
1841 1d69f52f Seth Mos
1842
	$now = time();
1843
	$spdfile = tempnam("{$g['tmp_path']}", "spd.conf.reload.{$now}.");
1844 c60cae98 Seth Mos
	/* generate temporary spd.conf */
1845 1d69f52f Seth Mos
	file_put_contents($spdfile, $spdconf);
1846 c60cae98 Seth Mos
	return true;
1847
}
1848
1849 7b2fdac4 jim-p
function vpn_ipsec_configure_preferoldsa() {
1850
	global $config;
1851
	if(isset($config['ipsec']['preferoldsa']))
1852
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
1853
	else
1854
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
1855
}
1856 9734b054 Scott Ullrich
1857 c513c309 Ermal
?>