Project

General

Profile

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