Project

General

Profile

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