Project

General

Profile

Download (56.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 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 0c21eb70 Ermal
				$vip = "";
909 f85da3b5 Ermal
				if (is_ipaddr($ph1ent['interface'])) {
910 e08a5153 Ermal
					$vip = find_virtual_ip_alias($ph1ent['interface']);
911 7238e0cf Ermal
					$parentinterface = $vip['interface'];
912
				} else
913 a93e56c5 Matthew Grooms
					$parentinterface = $ph1ent['interface'];
914
915 58070e1c Chris Buechler
				if (is_ipaddr($rgip)) {
916 a93e56c5 Matthew Grooms
					/* add endpoint routes to correct gateway on interface */
917
					if (interface_has_gateway($parentinterface)) {
918
						$gatewayip = get_interface_gateway("$parentinterface");
919 0c21eb70 Ermal
						if (empty($vip))
920
							$interfaceip = get_interface_ip($parentinterface);
921
						else
922
							$interfaceip = $vip['subnet'];
923 a55e9c70 Ermal Lu?i
						$subnet_bits = get_interface_subnet($parentinterface);
924 a93e56c5 Matthew Grooms
						$subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
925
						/* if the remote gateway is in the local subnet, then don't add a route */
926
						if (! ip_in_subnet($rgip, "{$subnet_ip}/{$subnet_bits}")) {
927
							if(is_ipaddr($gatewayip)) {
928 c60cae98 Seth Mos
								/* FIXME: does adding route-to and reply-to on the in/outbound
929
								 * rules fix this? smos@ 13-01-2009 */
930 131f3a50 jim-p
								// log_error("IPSEC interface is not WAN but {$parentinterface}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
931 8ff6b72c Ermal
								mwexec("/sbin/route change -host {$rgip} {$gatewayip}", true);
932 a93e56c5 Matthew Grooms
							}
933
						}
934 979cd6db Scott Ullrich
					}
935 09628a07 Renato Botelho
				}
936 a93e56c5 Matthew Grooms
			}
937
		}
938 52c9f9fa Ermal
		@file_put_contents("{$g['varetc_path']}/ipsec/spd.conf", $spdconf);
939 a49784a2 Ermal
		unset($spdconf);
940 a93e56c5 Matthew Grooms
941
		/* mange racoon process */
942
		if (is_process_running("racoon")) {
943 223547eb Seth Mos
			sleep("0.1");
944 6b5e978b Ermal
			mwexec("/usr/local/sbin/racoonctl -s /var/db/racoon/racoon.sock reload-config", false);
945 f3c8bd98 Ermal Lu?i
			/* load SPD without flushing to be safe on config additions or changes. */
946 52c9f9fa Ermal
			mwexec("/usr/local/sbin/setkey -f {$g['varetc_path']}/ipsec/spd.conf", false);
947 a93e56c5 Matthew Grooms
		} else {
948
			/* flush SA + SPD entries */
949 c60cae98 Seth Mos
			mwexec("/usr/local/sbin/setkey -FP", false);
950 09628a07 Renato Botelho
			sleep("0.1");
951 c60cae98 Seth Mos
			mwexec("/usr/local/sbin/setkey -F", false);
952 09628a07 Renato Botelho
			sleep("0.1");
953
			/* start racoon */
954 127eb8e0 jim-p
			$ipsecdebug = isset($config['ipsec']['racoondebug']) ? "-d -v" : "";
955 52c9f9fa Ermal
			mwexec("/usr/local/sbin/racoon {$ipsecdebug} -f {$g['varetc_path']}/ipsec/racoon.conf", false);
956 09628a07 Renato Botelho
			sleep("0.1");
957
			/* load SPD */
958 52c9f9fa Ermal
			mwexec("/usr/local/sbin/setkey -f {$g['varetc_path']}/ipsec/spd.conf", false);
959 a93e56c5 Matthew Grooms
960 d161b4d4 smos
		}
961 3c107b76 Ermal
		if ($natfilterrules == true)
962
			filter_configure();
963 d161b4d4 smos
		/* start filterdns, if necessary */
964
		if (count($filterdns_list) > 0) {
965
			$interval = 60;
966
			if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
967
				$interval = $ipseccfg['dns-interval'];
968
969
			$hostnames = "";
970
			array_unique($filterdns_list);
971
			foreach ($filterdns_list as $hostname)
972 4e192846 Ermal
				$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
973 52c9f9fa Ermal
			file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
974 a49784a2 Ermal
			unset($hostnames);
975 d161b4d4 smos
976 5d6495a7 Ermal
			if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
977
				sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
978
			else {
979
				mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
980
			}
981 7b5eab84 bcyrill
		} else {
982
			killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
983
			@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
984 5b237745 Scott Ullrich
		}
985 09628a07 Renato Botelho
986 924876a8 Ermal Lu?i
		vpn_ipsec_failover_configure();
987 a63f7d55 Scott Ullrich
988 72bd8df5 Ermal Lu?i
		if ($g['booting'])
989 924876a8 Ermal Lu?i
			echo "done\n";
990 8f67a8e1 Scott Ullrich
991 6a781df6 Ermal
		return count($filterdns_list);
992
	}
993 5b237745 Scott Ullrich
}
994
995 09628a07 Renato Botelho
/*
996 52c9f9fa Ermal
 * Forcefully restart IPsec
997 67ee1ec5 Ermal Luçi
 * This is required for when dynamic interfaces reload
998
 * For all other occasions the normal vpn_ipsec_configure()
999
 * will gracefully reload the settings without restarting
1000
 */
1001 aa752473 Renato Botelho
function vpn_ipsec_force_reload($interface = "") {
1002
	global $g, $config;
1003 67ee1ec5 Ermal Luçi
1004
	$ipseccfg = $config['ipsec'];
1005
1006 aa752473 Renato Botelho
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1007
		$found = false;
1008
		foreach ($ipseccfg['phase1'] as $ipsec) {
1009
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1010
				$found = true;
1011
				break;
1012
			}
1013
		}
1014
		if (!$found) {
1015
			log_error(sprintf(gettext("Ignoring IPsec racoon daemon reload since there are no tunnels on interface %s"), $interface));
1016
			return;
1017
		}
1018
	}
1019
1020 52c9f9fa Ermal
	/* send a SIGKILL to be sure */
1021
	killbypid("{$g['varrun_path']}/racoon.pid");
1022 67ee1ec5 Ermal Luçi
1023
	/* wait for process to die */
1024
	sleep(4);
1025
1026 52c9f9fa Ermal
	/* kill racoon forcefully */
1027
	if (is_process_running("racoon"))
1028
		mwexec("/usr/bin/killall -9 racoon", true);
1029 67ee1ec5 Ermal Luçi
1030
	/* wait for flushing to finish */
1031
	sleep(1);
1032
1033
	/* if ipsec is enabled, start up again */
1034
	if (isset($ipseccfg['enable'])) {
1035 89ceb4ba Renato Botelho
		log_error(gettext("Forcefully reloading IPsec racoon daemon"));
1036 67ee1ec5 Ermal Luçi
		vpn_ipsec_configure();
1037
	}
1038
}
1039
1040
/* master setup for vpn (mpd) */
1041
function vpn_setup() {
1042 7734aea6 Andrew Thompson
	global $g;
1043
1044
	if ($g['platform'] == 'jail')
1045
		return;
1046
1047 67ee1ec5 Ermal Luçi
	/* start pptpd */
1048
	vpn_pptpd_configure();
1049
1050
	/* start pppoe server */
1051 0e642c78 Ermal
	vpn_pppoes_configure();
1052 67ee1ec5 Ermal Luçi
1053
	/* setup l2tp */
1054
	vpn_l2tp_configure();
1055
}
1056
1057 67b057a9 Ermal
function vpn_netgraph_support() {
1058
	$iflist = get_configured_interface_list();
1059
	foreach ($iflist as $iface) {
1060
		$realif = get_real_interface($iface);
1061
		/* Get support for netgraph(4) from the nic */
1062 c513c309 Ermal
		$ifinfo = pfSense_get_interface_addresses($realif);
1063
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
1064 09628a07 Renato Botelho
			pfSense_ngctl_attach(".", $realif);
1065 67b057a9 Ermal
	}
1066
}
1067
1068 5b237745 Scott Ullrich
function vpn_pptpd_configure() {
1069
	global $config, $g;
1070 c52719a8 Scott Ullrich
1071 5b237745 Scott Ullrich
	$syscfg = $config['system'];
1072
	$pptpdcfg = $config['pptpd'];
1073 c52719a8 Scott Ullrich
1074 5b237745 Scott Ullrich
	if ($g['booting']) {
1075
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
1076
			return 0;
1077 c52719a8 Scott Ullrich
1078 89ceb4ba Renato Botelho
		echo gettext("Configuring PPTP VPN service... ");
1079 c52719a8 Scott Ullrich
	} else {
1080 5b237745 Scott Ullrich
		/* kill mpd */
1081 67ee1ec5 Ermal Luçi
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1082 c52719a8 Scott Ullrich
1083 5b237745 Scott Ullrich
		/* wait for process to die */
1084 48bff85c Scott Ullrich
		sleep(3);
1085 c52719a8 Scott Ullrich
1086 979cd6db Scott Ullrich
		if (is_process_running("mpd -b")) {
1087 67ee1ec5 Ermal Luçi
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1088 89ceb4ba Renato Botelho
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
1089 48bff85c Scott Ullrich
		}
1090 c52719a8 Scott Ullrich
1091 5b237745 Scott Ullrich
		/* remove mpd.conf, if it exists */
1092 67ee1ec5 Ermal Luçi
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
1093
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
1094
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
1095 5b237745 Scott Ullrich
	}
1096 c52719a8 Scott Ullrich
1097 1fb8d314 Ermal
	if (empty($pptpdcfg['n_pptp_units'])) {
1098
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
1099 09628a07 Renato Botelho
		return;
1100 1fb8d314 Ermal
	}
1101
1102 67ee1ec5 Ermal Luçi
	/* make sure pptp-vpn directory exists */
1103
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
1104
		mkdir("{$g['varetc_path']}/pptp-vpn");
1105 c52719a8 Scott Ullrich
1106 5b237745 Scott Ullrich
	switch ($pptpdcfg['mode']) {
1107 979cd6db Scott Ullrich
		case 'server' :
1108 5b237745 Scott Ullrich
			/* write mpd.conf */
1109 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1110 5b237745 Scott Ullrich
			if (!$fd) {
1111 89ceb4ba Renato Botelho
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
1112 5b237745 Scott Ullrich
				return 1;
1113
			}
1114 c52719a8 Scott Ullrich
1115 045c9cc9 sullrich
			$mpdconf = <<<EOD
1116 a6607b5f jim-p
pptps:
1117 5b237745 Scott Ullrich
1118
EOD;
1119
1120 f2b4ff2b sullrich
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1121 5b237745 Scott Ullrich
				$mpdconf .= "	load pt{$i}\n";
1122
			}
1123 c52719a8 Scott Ullrich
1124 f2b4ff2b sullrich
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1125 c52719a8 Scott Ullrich
1126 96033063 Erik Fonnesbeck
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1127 c52719a8 Scott Ullrich
1128 045c9cc9 sullrich
				$mpdconf .= <<<EOD
1129 5b237745 Scott Ullrich
1130
pt{$i}:
1131 bfa6d878 Ermal Lu?i
	new -i pptpd{$i} pt{$i} pt{$i}
1132 045c9cc9 sullrich
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1133 979cd6db Scott Ullrich
	load pts
1134 5b237745 Scott Ullrich
1135
EOD;
1136
			}
1137 c52719a8 Scott Ullrich
1138 979cd6db Scott Ullrich
			$mpdconf .=<<<EOD
1139 5b237745 Scott Ullrich
1140 979cd6db Scott Ullrich
pts:
1141 5b237745 Scott Ullrich
	set iface disable on-demand
1142
	set iface enable proxy-arp
1143 07cae4b2 Scott Ullrich
	set iface enable tcpmssfix
1144 979cd6db Scott Ullrich
	set iface idle 1800
1145 e9a95ac8 jim-p
	set iface up-script /usr/local/sbin/vpn-linkup
1146
	set iface down-script /usr/local/sbin/vpn-linkdown
1147 5b237745 Scott Ullrich
	set bundle enable multilink
1148 979cd6db Scott Ullrich
	set bundle enable crypt-reqd
1149 5b237745 Scott Ullrich
	set link yes acfcomp protocomp
1150
	set link no pap chap
1151 979cd6db Scott Ullrich
	set link enable chap-msv2
1152 ee953edc Scott Ullrich
	set link mtu 1460
1153 5b237745 Scott Ullrich
	set link keep-alive 10 60
1154
	set ipcp yes vjcomp
1155
	set bundle enable compression
1156
	set ccp yes mppc
1157
	set ccp yes mpp-e128
1158
	set ccp yes mpp-stateless
1159
1160
EOD;
1161 c52719a8 Scott Ullrich
1162 979cd6db Scott Ullrich
			if (!isset ($pptpdcfg['req128'])) {
1163
				$mpdconf .=<<<EOD
1164 5b237745 Scott Ullrich
	set ccp yes mpp-e40
1165 979cd6db Scott Ullrich
	set ccp yes mpp-e56
1166 5b237745 Scott Ullrich
1167
EOD;
1168
			}
1169 c8c416db Scott Ullrich
1170 871ce025 Bill Marquette
			if  (isset($pptpdcfg["wins"]) && $pptpdcfg['wins'] != "")
1171 979cd6db Scott Ullrich
				$mpdconf  .=  "	set ipcp nbns {$pptpdcfg['wins']}\n";
1172 09f2bf85 jim-p
1173
			if (!empty($pptpdcfg['dns1'])) {
1174
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1175
				if (!empty($pptpdcfg['dns2']))
1176
					$mpdconf .= " " . $pptpdcfg['dns2'];
1177
				$mpdconf .= "\n";
1178
			} elseif (isset ($config['dnsmasq']['enable'])) {
1179
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1180
				if ($syscfg['dnsserver'][0])
1181
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1182
				$mpdconf .= "\n";
1183
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1184
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1185
			}
1186 07cae4b2 Scott Ullrich
1187 71569a7e jim-p
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1188
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1189 979cd6db Scott Ullrich
				$acctport = $authport + 1;
1190
				$mpdconf .=<<<EOD
1191 71569a7e jim-p
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1192 35b91f77 sullrich
1193 71569a7e jim-p
EOD;
1194
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1195
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1196
				$acctport = $authport + 1;
1197
				$mpdconf .=<<<EOD
1198 846a6dc2 jim-p
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1199 35b91f77 sullrich
1200 71569a7e jim-p
EOD;
1201
			}
1202
			$mpdconf .=<<<EOD
1203 5b237745 Scott Ullrich
	set radius retries 3
1204 979cd6db Scott Ullrich
	set radius timeout 10
1205 0af9dba4 Ermal Lu?i
	set auth enable radius-auth
1206 5b237745 Scott Ullrich
1207
EOD;
1208
1209 979cd6db Scott Ullrich
				if (isset ($pptpdcfg['radius']['accounting'])) {
1210
					$mpdconf .=<<<EOD
1211 0af9dba4 Ermal Lu?i
	set auth enable radius-acct
1212 979cd6db Scott Ullrich
	set radius acct-update 300
1213 5b237745 Scott Ullrich
1214
EOD;
1215
				}
1216
			}
1217
1218
			fwrite($fd, $mpdconf);
1219
			fclose($fd);
1220 a49784a2 Ermal
			unset($mpdconf);
1221 c52719a8 Scott Ullrich
1222 5b237745 Scott Ullrich
			/* write mpd.links */
1223 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1224 5b237745 Scott Ullrich
			if (!$fd) {
1225 89ceb4ba Renato Botelho
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1226 5b237745 Scott Ullrich
				return 1;
1227
			}
1228 c52719a8 Scott Ullrich
1229 5b237745 Scott Ullrich
			$mpdlinks = "";
1230 c52719a8 Scott Ullrich
1231 a56120f2 Ermal Lu?i
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1232 979cd6db Scott Ullrich
				$mpdlinks .=<<<EOD
1233 5b237745 Scott Ullrich
1234
pt{$i}:
1235
	set link type pptp
1236
	set pptp enable incoming
1237
	set pptp disable originate
1238 979cd6db Scott Ullrich
	set pptp disable windowing
1239 5b237745 Scott Ullrich
1240
EOD;
1241
			}
1242
1243
			fwrite($fd, $mpdlinks);
1244
			fclose($fd);
1245 a49784a2 Ermal
			unset($mpdlinks);
1246 c52719a8 Scott Ullrich
1247 5b237745 Scott Ullrich
			/* write mpd.secret */
1248 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1249 5b237745 Scott Ullrich
			if (!$fd) {
1250 89ceb4ba Renato Botelho
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1251 5b237745 Scott Ullrich
				return 1;
1252
			}
1253 c52719a8 Scott Ullrich
1254 5b237745 Scott Ullrich
			$mpdsecret = "";
1255 c52719a8 Scott Ullrich
1256 5b237745 Scott Ullrich
			if (is_array($pptpdcfg['user'])) {
1257 4cf82d52 jim-p
				foreach ($pptpdcfg['user'] as $user) {
1258 4222087e jim-p
					$pass = str_replace('\\', '\\\\', $user['password']);
1259
					$pass = str_replace('"', '\"', $pass);
1260 4cf82d52 jim-p
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1261
				}
1262 5b237745 Scott Ullrich
			}
1263
1264
			fwrite($fd, $mpdsecret);
1265
			fclose($fd);
1266 a49784a2 Ermal
			unset($mpdsecret);
1267 67ee1ec5 Ermal Luçi
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1268 c52719a8 Scott Ullrich
1269 67b057a9 Ermal
			vpn_netgraph_support();
1270
1271 5b237745 Scott Ullrich
			/* fire up mpd */
1272 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");
1273 c52719a8 Scott Ullrich
1274 5b237745 Scott Ullrich
			break;
1275 c52719a8 Scott Ullrich
1276 979cd6db Scott Ullrich
		case 'redir' :
1277 5b237745 Scott Ullrich
			break;
1278
	}
1279 c52719a8 Scott Ullrich
1280 a63f7d55 Scott Ullrich
	if ($g['booting'])
1281
		echo "done\n";
1282 c52719a8 Scott Ullrich
1283 5b237745 Scott Ullrich
	return 0;
1284
}
1285
1286 0e642c78 Ermal
function vpn_pppoes_configure() {
1287
	global $config;
1288
1289
	if (is_array($config['pppoes']['pppoe'])) {
1290
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1291
			vpn_pppoe_configure($pppoe);
1292
	}
1293
}
1294
1295
function vpn_pppoe_configure(&$pppoecfg) {
1296 06e69b03 Scott Ullrich
	global $config, $g;
1297
1298
	$syscfg = $config['system'];
1299
1300 48918ed5 Scott Ullrich
	/* create directory if it does not exist */
1301 0e642c78 Ermal
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1302
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1303 c52719a8 Scott Ullrich
1304 06e69b03 Scott Ullrich
	if ($g['booting']) {
1305
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1306
			return 0;
1307
1308 89ceb4ba Renato Botelho
		echo gettext("Configuring PPPoE VPN service... ");
1309 979cd6db Scott Ullrich
	} else {
1310
		/* kill mpd */
1311 0e642c78 Ermal
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1312 979cd6db Scott Ullrich
1313
		/* wait for process to die */
1314
		sleep(2);
1315
1316 06e69b03 Scott Ullrich
	}
1317
1318
	switch ($pppoecfg['mode']) {
1319
1320 979cd6db Scott Ullrich
		case 'server' :
1321 06e69b03 Scott Ullrich
1322 0e642c78 Ermal
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1323 0301deff Scott Ullrich
1324 979cd6db Scott Ullrich
			if ($pppoecfg['paporchap'] == "chap")
1325
				$paporchap = "set link enable chap";
1326
			else
1327
				$paporchap = "set link enable pap";
1328
1329 06e69b03 Scott Ullrich
			/* write mpd.conf */
1330 0e642c78 Ermal
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1331 06e69b03 Scott Ullrich
			if (!$fd) {
1332 89ceb4ba Renato Botelho
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1333 06e69b03 Scott Ullrich
				return 1;
1334
			}
1335
			$mpdconf = "\n\n";
1336 a6607b5f jim-p
			$mpdconf .= "poes:\n";
1337 06e69b03 Scott Ullrich
1338 a429d105 Scott Ullrich
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1339 0e642c78 Ermal
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1340 06e69b03 Scott Ullrich
			}
1341
1342 a429d105 Scott Ullrich
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1343 06e69b03 Scott Ullrich
1344 96033063 Erik Fonnesbeck
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1345 c52719a8 Scott Ullrich
1346 b0943409 Ermal
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1347 5dfdc1fb Scott Ullrich
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1348 5264023a Scott Ullrich
				} else {
1349
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1350 5dfdc1fb Scott Ullrich
				}
1351 c52719a8 Scott Ullrich
1352 979cd6db Scott Ullrich
				$mpdconf .=<<<EOD
1353 06e69b03 Scott Ullrich
1354 0e642c78 Ermal
poes{$pppoecfg['pppoeid']}{$i}:
1355
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1356 5dfdc1fb Scott Ullrich
	{$isssue_ip_type}
1357 f856e762 jim-p
	load pppoe_standard
1358 06e69b03 Scott Ullrich
1359
EOD;
1360
			}
1361
1362 979cd6db Scott Ullrich
			$mpdconf .=<<<EOD
1363 06e69b03 Scott Ullrich
1364 f856e762 jim-p
pppoe_standard:
1365 979cd6db Scott Ullrich
	set bundle no multilink
1366
	set bundle enable compression
1367 78155ff9 Scott Ullrich
	set auth max-logins 1
1368 e9a95ac8 jim-p
	set iface up-script /usr/local/sbin/vpn-linkup
1369
	set iface down-script /usr/local/sbin/vpn-linkdown
1370 979cd6db Scott Ullrich
	set iface idle 0
1371 06e69b03 Scott Ullrich
	set iface disable on-demand
1372
	set iface disable proxy-arp
1373
	set iface enable tcpmssfix
1374 979cd6db Scott Ullrich
	set iface mtu 1500
1375 06e69b03 Scott Ullrich
	set link no pap chap
1376 979cd6db Scott Ullrich
	{$paporchap}
1377
	set link keep-alive 60 180
1378
	set ipcp yes vjcomp
1379
	set ipcp no vjcomp
1380
	set link max-redial -1
1381
	set link mtu 1492
1382
	set link mru 1492
1383 06e69b03 Scott Ullrich
	set ccp yes mpp-e40
1384
	set ccp yes mpp-e128
1385
	set ccp yes mpp-stateless
1386 979cd6db Scott Ullrich
	set link latency 1
1387
	#set ipcp dns 10.10.1.3
1388
	#set bundle accept encryption
1389 06e69b03 Scott Ullrich
1390 c8c416db Scott Ullrich
EOD;
1391
1392 09f2bf85 jim-p
			if (!empty($pppoecfg['dns1'])) {
1393
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1394
				if (!empty($pppoecfg['dns2']))
1395
					$mpdconf .= " " . $pppoecfg['dns2'];
1396
				$mpdconf .= "\n";
1397
			} elseif (isset ($config['dnsmasq']['enable'])) {
1398 a55e9c70 Ermal Lu?i
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1399 06e69b03 Scott Ullrich
				if ($syscfg['dnsserver'][0])
1400
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1401
				$mpdconf .= "\n";
1402 09f2bf85 jim-p
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1403 979cd6db Scott Ullrich
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1404 09f2bf85 jim-p
			}
1405 07cae4b2 Scott Ullrich
1406 37d7de2d jim-p
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1407 c3583058 Ermal
				$radiusport = "";
1408
				$radiusacctport = "";
1409
				if (isset($pppoecfg['radius']['server']['port']))
1410
					$radiusport = $pppoecfg['radius']['server']['port'];
1411
				if (isset($pppoecfg['radius']['server']['acctport']))
1412
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1413 979cd6db Scott Ullrich
				$mpdconf .=<<<EOD
1414 b0943409 Ermal
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1415 06e69b03 Scott Ullrich
	set radius retries 3
1416 979cd6db Scott Ullrich
	set radius timeout 10
1417 0af9dba4 Ermal Lu?i
	set auth enable radius-auth
1418 06e69b03 Scott Ullrich
1419
EOD;
1420
1421 979cd6db Scott Ullrich
				if (isset ($pppoecfg['radius']['accounting'])) {
1422
					$mpdconf .=<<<EOD
1423 0af9dba4 Ermal Lu?i
	set auth enable radius-acct
1424 07cae4b2 Scott Ullrich
1425 06e69b03 Scott Ullrich
EOD;
1426
				}
1427
			}
1428
1429
			fwrite($fd, $mpdconf);
1430
			fclose($fd);
1431 a49784a2 Ermal
			unset($mpdconf);
1432 06e69b03 Scott Ullrich
1433
			/* write mpd.links */
1434 0e642c78 Ermal
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1435 06e69b03 Scott Ullrich
			if (!$fd) {
1436 89ceb4ba Renato Botelho
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1437 06e69b03 Scott Ullrich
				return 1;
1438
			}
1439
1440
			$mpdlinks = "";
1441
1442 a429d105 Scott Ullrich
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1443 979cd6db Scott Ullrich
				$mpdlinks .=<<<EOD
1444 09628a07 Renato Botelho
1445 0e642c78 Ermal
poes{$pppoecfg['pppoeid']}{$i}:
1446 67ee1ec5 Ermal Luçi
	set phys type pppoe
1447 09628a07 Renato Botelho
	set pppoe iface {$pppoe_interface}
1448
	set pppoe service "*"
1449
	set pppoe disable originate
1450
	set pppoe enable incoming
1451 06e69b03 Scott Ullrich
1452
EOD;
1453
			}
1454
1455
			fwrite($fd, $mpdlinks);
1456
			fclose($fd);
1457 a49784a2 Ermal
			unset($mpdlinks);
1458 06e69b03 Scott Ullrich
1459 0e642c78 Ermal
			if ($pppoecfg['username']) {
1460
				/* write mpd.secret */
1461
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1462
				if (!$fd) {
1463 8c04b1ae Renato Botelho
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1464 0e642c78 Ermal
					return 1;
1465
				}
1466 06e69b03 Scott Ullrich
1467 0e642c78 Ermal
				$mpdsecret = "\n\n";
1468 06e69b03 Scott Ullrich
1469 0e642c78 Ermal
				if (!empty($pppoecfg['username'])) {
1470
					$item = explode(" ", $pppoecfg['username']);
1471
					foreach($item as $userdata) {
1472
						$data = explode(":", $userdata);
1473 90388e48 Ermal
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1474 0e642c78 Ermal
					}
1475
				}
1476 06e69b03 Scott Ullrich
1477 0e642c78 Ermal
				fwrite($fd, $mpdsecret);
1478
				fclose($fd);
1479 a49784a2 Ermal
				unset($mpdsecret);
1480 0e642c78 Ermal
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1481
			}
1482 979cd6db Scott Ullrich
1483 062676f8 Ermal
			/* Check if previous instance is still up */
1484
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid"))
1485
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1486
1487 67b057a9 Ermal
			/* Get support for netgraph(4) from the nic */
1488
			pfSense_ngctl_attach(".", $pppoe_interface);
1489 979cd6db Scott Ullrich
			/* fire up mpd */
1490 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");
1491 979cd6db Scott Ullrich
1492
			break;
1493
	}
1494
1495
	if ($g['booting'])
1496 561130e4 Carlos Eduardo Ramos
		echo gettext("done") . "\n";
1497 979cd6db Scott Ullrich
1498
	return 0;
1499
}
1500
1501
function vpn_l2tp_configure() {
1502
	global $config, $g;
1503
1504
	$syscfg = $config['system'];
1505
	$l2tpcfg = $config['l2tp'];
1506
1507
	/* create directory if it does not exist */
1508 67ee1ec5 Ermal Luçi
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1509
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1510 979cd6db Scott Ullrich
1511
	if ($g['booting']) {
1512
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1513
			return 0;
1514
1515 89ceb4ba Renato Botelho
		echo gettext("Configuring l2tp VPN service... ");
1516 979cd6db Scott Ullrich
	} else {
1517
		/* kill mpd */
1518 67ee1ec5 Ermal Luçi
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1519 979cd6db Scott Ullrich
1520
		/* wait for process to die */
1521 01c41d40 Ermal Lu?i
		sleep(8);
1522 979cd6db Scott Ullrich
1523
	}
1524
1525 67ee1ec5 Ermal Luçi
	/* make sure l2tp-vpn directory exists */
1526
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1527
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1528 979cd6db Scott Ullrich
1529
	switch ($l2tpcfg['mode']) {
1530
1531
		case 'server' :
1532
			if ($l2tpcfg['paporchap'] == "chap")
1533
				$paporchap = "set link enable chap";
1534
			else
1535
				$paporchap = "set link enable pap";
1536
1537
			/* write mpd.conf */
1538 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1539 979cd6db Scott Ullrich
			if (!$fd) {
1540 89ceb4ba Renato Botelho
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1541 979cd6db Scott Ullrich
				return 1;
1542
			}
1543
			$mpdconf = "\n\n";
1544
			$mpdconf .=<<<EOD
1545 a6607b5f jim-p
l2tps:
1546 979cd6db Scott Ullrich
1547
EOD;
1548
1549
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1550
				$mpdconf .= "	load l2tp{$i}\n";
1551
			}
1552
1553
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1554
1555 96033063 Erik Fonnesbeck
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1556 979cd6db Scott Ullrich
1557
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1558
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1559
				} else {
1560
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1561
				}
1562
1563
				$mpdconf .=<<<EOD
1564
1565
l2tp{$i}:
1566 2c7feef7 jim-p
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1567 979cd6db Scott Ullrich
	{$isssue_ip_type}
1568
	load l2tp_standard
1569
1570
EOD;
1571
			}
1572
1573
			$mpdconf .=<<<EOD
1574
1575
l2tp_standard:
1576 09628a07 Renato Botelho
	set bundle disable multilink
1577
	set bundle enable compression
1578
	set bundle yes crypt-reqd
1579
	set ipcp yes vjcomp
1580
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1581
	set ccp yes mppc
1582
	set iface disable on-demand
1583
	set iface enable proxy-arp
1584 e9a95ac8 jim-p
	set iface up-script /usr/local/sbin/vpn-linkup
1585
	set iface down-script /usr/local/sbin/vpn-linkdown
1586 09628a07 Renato Botelho
	set link yes acfcomp protocomp
1587
	set link no pap chap
1588
	set link enable chap
1589
	set link keep-alive 10 180
1590 979cd6db Scott Ullrich
1591
EOD;
1592
1593 c8cc0c1c smos
			if (is_ipaddr($l2tpcfg['wins'])) {
1594
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1595
			}
1596
			if (is_ipaddr($l2tpcfg['dns1'])) {
1597 09f2bf85 jim-p
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1598 c8cc0c1c smos
				if (is_ipaddr($l2tpcfg['dns2']))
1599 09f2bf85 jim-p
					$mpdconf .= " " . $l2tpcfg['dns2'];
1600
				$mpdconf .= "\n";
1601
			} elseif (isset ($config['dnsmasq']['enable'])) {
1602 a55e9c70 Ermal Lu?i
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1603 979cd6db Scott Ullrich
				if ($syscfg['dnsserver'][0])
1604
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1605
				$mpdconf .= "\n";
1606 09f2bf85 jim-p
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1607 979cd6db Scott Ullrich
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1608 09f2bf85 jim-p
			}
1609 979cd6db Scott Ullrich
1610
			if (isset ($l2tpcfg['radius']['enable'])) {
1611
				$mpdconf .=<<<EOD
1612
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1613
	set radius retries 3
1614
	set radius timeout 10
1615 0af9dba4 Ermal Lu?i
	set auth enable radius-auth
1616 979cd6db Scott Ullrich
1617
EOD;
1618
1619
				if (isset ($l2tpcfg['radius']['accounting'])) {
1620
					$mpdconf .=<<<EOD
1621 0af9dba4 Ermal Lu?i
	set auth enable radius-acct
1622 979cd6db Scott Ullrich
1623
EOD;
1624
				}
1625
			}
1626
1627
			fwrite($fd, $mpdconf);
1628
			fclose($fd);
1629 a49784a2 Ermal
			unset($mpdconf);
1630 979cd6db Scott Ullrich
1631
			/* write mpd.links */
1632 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1633 979cd6db Scott Ullrich
			if (!$fd) {
1634 89ceb4ba Renato Botelho
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1635 979cd6db Scott Ullrich
				return 1;
1636
			}
1637
1638
			$mpdlinks = "";
1639
1640
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1641
				$mpdlinks .=<<<EOD
1642
1643 daa20efd Ermal Lu?i
l2tp{$i}:
1644 979cd6db Scott Ullrich
	set link type l2tp
1645 09628a07 Renato Botelho
	set l2tp enable incoming
1646
	set l2tp disable originate
1647 979cd6db Scott Ullrich
1648
EOD;
1649 00f9e567 Ermal Lu?i
			if (!empty($l2tpcfg['secret']))
1650
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1651 979cd6db Scott Ullrich
			}
1652
1653
			fwrite($fd, $mpdlinks);
1654
			fclose($fd);
1655 a49784a2 Ermal
			unset($mpdlinks);
1656 979cd6db Scott Ullrich
1657
			/* write mpd.secret */
1658 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1659 979cd6db Scott Ullrich
			if (!$fd) {
1660 89ceb4ba Renato Botelho
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1661 979cd6db Scott Ullrich
				return 1;
1662
			}
1663
1664
			$mpdsecret = "\n\n";
1665
1666
			if (is_array($l2tpcfg['user'])) {
1667
				foreach ($l2tpcfg['user'] as $user)
1668
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1669
			}
1670
1671
			fwrite($fd, $mpdsecret);
1672
			fclose($fd);
1673 a49784a2 Ermal
			unset($mpdsecret);
1674 67ee1ec5 Ermal Luçi
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1675 06e69b03 Scott Ullrich
1676 67b057a9 Ermal
			vpn_netgraph_support();
1677
1678 06e69b03 Scott Ullrich
			/* fire up mpd */
1679 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");
1680 06e69b03 Scott Ullrich
1681
			break;
1682
1683 979cd6db Scott Ullrich
		case 'redir' :
1684 06e69b03 Scott Ullrich
			break;
1685
	}
1686
1687
	if ($g['booting'])
1688
		echo "done\n";
1689
1690
	return 0;
1691
}
1692 630cfa6c Scott Ullrich
1693 09628a07 Renato Botelho
/* Walk the tunnels for hostname endpoints. If the hostnames
1694 c60cae98 Seth Mos
 * resolve to a different IP now compared to the DNS cache
1695
 * we reload the policies if the endpoint has changed */
1696
function vpn_ipsec_refresh_policies() {
1697
	global $config;
1698
	global $g;
1699
1700
	$ipseccfg = $config['ipsec'];
1701 9f14066f Seth Mos
	$a_phase1 = $config['ipsec']['phase1'];
1702
	$a_phase2 = $config['ipsec']['phase2'];
1703 c60cae98 Seth Mos
1704 9f14066f Seth Mos
	if (isset($ipseccfg['disable'])) {
1705 c60cae98 Seth Mos
		return true;
1706
	}
1707
1708
	/* Walk the Ipsec tunnel array */
1709 52c9f9fa Ermal
	if (!is_array($a_phase1) || (!count($a_phase1)))
1710 eb9ae6bb Bill Marquette
		return;
1711 c60cae98 Seth Mos
1712 9f14066f Seth Mos
	foreach ($a_phase1 as $phase1) {
1713 52c9f9fa Ermal
		if (isset($phase1['disabled']))
1714 9f14066f Seth Mos
			continue;
1715 52c9f9fa Ermal
		if (is_ipaddr($phase1['remote-gateway']))
1716 9f14066f Seth Mos
			continue;
1717 da6aebbb Renato Botelho
		$dnscache = compare_hostname_to_dnscache($phase1['remote-gateway']);
1718
		$dnscache = trim($dnscache);
1719
		/* we should have the old IP addresses in the dnscache now */
1720
		if(!empty($dnscache)) {
1721
			$oldphase1 = $phase1;
1722
			$oldphase1['remote-gateway'] = $dnscache;
1723
			/* now we need to find all tunnels for this host */
1724
			if (!is_array($a_phase2) || (!count($a_phase2)))
1725
				continue;
1726
			foreach ($a_phase2 as $phase2) {
1727
				if ($phase2['ikeid'] == $phase1['ikeid'])
1728
					reload_tunnel_spd_policy ($phase1, $phase2, $oldphase1, $oldphase2);
1729 c60cae98 Seth Mos
			}
1730
		}
1731
	}
1732
1733 52c9f9fa Ermal
	/* process all generated temporary spd.conf files */
1734
	$tmpfiles = glob("{$g['tmp_path']}/spd.conf.reload.*");
1735 1d69f52f Seth Mos
	foreach($tmpfiles as $tmpfile) {
1736 52c9f9fa Ermal
		$ret = mwexec("/usr/local/sbin/setkey -f {$tmpfile} 2>&1", false);
1737
		if ($ret == 0)
1738
			unlink_if_exists($tmpfile);
1739
		else {
1740
			$tmpfile = basename($tmpfile);
1741
			@rename("{$g['tmp_path']}/{$tmpfile}", ("{$g['tmp_path']}/failed.{$tmpfile}"));
1742 1d69f52f Seth Mos
		}
1743
	}
1744 c60cae98 Seth Mos
}
1745
1746 6fd8526b Rafael Abdo
/* remove SPD polices */
1747
function remove_tunnel_spd_policy($phase1,$phase2) {
1748
	global $config;
1749
	global $g;
1750
1751 96a6f4cb bcyrill
	if (!$phase1 || !$phase2)
1752
		return false;
1753
1754
	if (isset($phase1['mobile']))
1755
		return false;
1756
1757 6fd8526b Rafael Abdo
	$spdconf = "";
1758 96a6f4cb bcyrill
	$ep = ipsec_get_phase1_src($phase1);
1759
	$gw = trim($phase1['remote-gateway']);
1760
	$sad_arr = ipsec_dump_sad();
1761 d83045b5 Ermal
	$remote_subnet = ipsec_idinfo_to_cidr($phase2['remoteid'], false, $phase2['mode']);
1762 96a6f4cb bcyrill
1763
	if (!empty($phase2['natlocalid']))
1764 d83045b5 Ermal
		$local_subnet = ipsec_idinfo_to_cidr($phase2['natlocalid'], false, $phase2['mode']);
1765 96a6f4cb bcyrill
	else
1766 d83045b5 Ermal
		$local_subnet = ipsec_idinfo_to_cidr($phase2['localid'], false, $phase2['mode']);
1767 96a6f4cb bcyrill
1768
	if ($phase2['mode'] == "tunnel6")
1769
		$family = "-6";
1770
	else
1771
		$family = "-4";
1772
1773
	$spdconf .= "spddelete {$family} {$local_subnet} " .
1774
		"{$remote_subnet} any -P out ipsec " .
1775
		"{$phase2['protocol']}/tunnel/{$ep}-" .
1776
		"{$gw}/unique;\n";
1777
1778
	$spdconf .= "spddelete {$family} {$remote_subnet} " .
1779
		"{$local_subnet} any -P in ipsec " .
1780
		"{$phase2['protocol']}/tunnel/{$gw}-" .
1781
		"{$ep}/unique;\n";
1782
1783
	/* zap any existing SA entries */
1784
	foreach($sad_arr as $sad) {
1785
		if(($sad['dst'] == $ep) && ($sad['src'] == $gw))
1786
			$spdconf .= "delete {$family} {$ep} {$gw} {$phase2['protocol']} 0x{$sad['spi']};\n";
1787
		if(($sad['src'] == $ep) && ($sad['dst'] == $_gw))
1788
			$spdconf .= "delete {$family} {$gw} {$ep} {$phase2['protocol']} 0x{$sad['spi']};\n";
1789 6fd8526b Rafael Abdo
	}
1790
1791
	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));
1792
1793
	$now = time();
1794
	$spdfile = tempnam("{$g['tmp_path']}", "spd.conf.reload.{$now}.");
1795
	/* generate temporary spd.conf */
1796
	@file_put_contents($spdfile, $spdconf);
1797
	unset($spdconf);
1798 96a6f4cb bcyrill
1799 6fd8526b Rafael Abdo
	return true;
1800
}
1801
1802 c60cae98 Seth Mos
/* reloads the tunnel configuration for a tunnel item
1803
 * Will remove and add SPD polices */
1804 9f14066f Seth Mos
function reload_tunnel_spd_policy($phase1, $phase2, $old_phase1, $old_phase2) {
1805 c60cae98 Seth Mos
	global $config;
1806
	global $g;
1807
1808 1d69f52f Seth Mos
	/* if we are not passed a old tunnel array we create one */
1809 9f14066f Seth Mos
	if(empty($old_phase1)) {
1810
		$old_phase1 = $phase1;
1811
	}
1812
	if(empty($old_phase2)) {
1813
		$old_phase2 = $phase2;
1814 1d69f52f Seth Mos
	}
1815
1816 9f14066f Seth Mos
	$sad_arr = ipsec_dump_sad();
1817 1d69f52f Seth Mos
1818 9f14066f Seth Mos
	$ep = ipsec_get_phase1_src($phase1);
1819 d83045b5 Ermal
	$local_subnet = ipsec_idinfo_to_cidr($phase2['localid'], false, $phase2['mode']);
1820
	$remote_subnet = ipsec_idinfo_to_cidr($phase2['remoteid'], false, $phase2['mode']);
1821 c60cae98 Seth Mos
1822 1d69f52f Seth Mos
	/* make sure we pass the oldtunnel array with a IP for the remote gw */
1823 9f14066f Seth Mos
	$old_gw = trim($old_phase1['remote-gateway']);
1824
1825
	$old_ep = ipsec_get_phase1_src($old_phase1);
1826 d83045b5 Ermal
	$old_local_subnet = ipsec_idinfo_to_cidr($old_phase2['localid'], false, $old_phase2['mode']);
1827
	$old_remote_subnet = ipsec_idinfo_to_cidr($old_phase2['remoteid'], false, $old_phase2['mode']);
1828 1d69f52f Seth Mos
1829 c60cae98 Seth Mos
	/* see if this tunnel has a hostname for the remote-gateway, and if so,
1830 f8c10a18 Ermal
	 * try to resolve it now and add it to the list for filterdns */
1831 603b4346 smos
	$rgip = "";
1832 9f14066f Seth Mos
	if (!is_ipaddr($phase1['remote-gateway'])) {
1833 d0399410 smos
		if(! $g['booting']) {
1834
			$rgip = resolve_retry($phase1['remote-gateway']);
1835
			add_hostname_to_watch($phase1['remote-gateway']);
1836
		} else {
1837
			add_hostname_to_watch($phase1['remote-gateway']);
1838
		}
1839 8ab8d853 jim-p
		if (isset($phase1['mobile'])) {
1840
			/* Don't log anything here, it's normal and we should skip it. */
1841
			return false;
1842
		} elseif (!is_ipaddr($rgip)) {
1843 9f14066f Seth Mos
			log_error("Could not determine VPN endpoint for '{$phase1['descr']}'");
1844 c60cae98 Seth Mos
			return false;
1845
		}
1846
	} else {
1847 9f14066f Seth Mos
		$rgip = $phase1['remote-gateway'];
1848 c60cae98 Seth Mos
	}
1849
	if (!$ep) {
1850 89ceb4ba Renato Botelho
		log_error(sprintf(gettext("Could not determine VPN endpoint for '%s'"), $phase1['descr']));
1851 c60cae98 Seth Mos
		return false;
1852
	}
1853
1854 287e0c9d Seth Mos
	if((!is_ipaddr($old_ep)) || (! is_ipaddr($ep))) {
1855 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));
1856 287e0c9d Seth Mos
	}
1857
	if((! is_ipaddr($rgip)) || (! is_ipaddr($old_gw))) {
1858 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));
1859 bd6af475 Seth Mos
	}
1860 1d69f52f Seth Mos
1861 bd6af475 Seth Mos
	$spdconf = "";
1862 1d69f52f Seth Mos
	/* Delete old SPD policies if there are changes between the old and new */
1863 9f14066f Seth Mos
	if(($phase1 != $old_phase1) || ($phase2 != $old_phase2)) {
1864 98790f61 Seth Mos
		if($old_phase2['mode'] == "tunnel6")
1865
			$family = "-6";
1866
		else
1867
			$family = "-4";
1868
1869
		$spdconf .= "spddelete {$family} {$old_local_subnet} " .
1870 9f14066f Seth Mos
			"{$old_remote_subnet} any -P out ipsec " .
1871
			"{$old_phase2['protocol']}/tunnel/{$old_ep}-" .
1872
			"{$old_gw}/unique;\n";
1873 3c107b76 Ermal
		if (!empty($old_phase2['natlocalid']))
1874 d83045b5 Ermal
			$old_local_subnet = ipsec_idinfo_to_cidr($old_phase2['natlocalid'], false, $old_phase2['mode']);
1875 98790f61 Seth Mos
		$spdconf .= "spddelete {$family} {$old_remote_subnet} " .
1876 9f14066f Seth Mos
			"{$old_local_subnet} any -P in ipsec " .
1877
			"{$old_phase2['protocol']}/tunnel/{$old_gw}-" .
1878
			"{$old_ep}/unique;\n";
1879 1d69f52f Seth Mos
1880
		/* zap any existing SA entries */
1881 c60cae98 Seth Mos
		foreach($sad_arr as $sad) {
1882 9f14066f Seth Mos
			if(($sad['dst'] == $old_ep) && ($sad['src'] == $old_gw)) {
1883 98790f61 Seth Mos
				$spdconf .= "delete {$family} {$old_ep} {$old_gw} {$old_phase2['protocol']} 0x{$sad['spi']};\n";
1884 c60cae98 Seth Mos
			}
1885 9f14066f Seth Mos
			if(($sad['src'] == $oldep) && ($sad['dst'] == $old_gw)) {
1886 98790f61 Seth Mos
				$spdconf .= "delete {$family} {$old_gw} {$old_ep} {$old_phase2['protocol']} 0x{$sad['spi']};\n";
1887 c60cae98 Seth Mos
			}
1888
		}
1889
	}
1890 1d69f52f Seth Mos
1891 98790f61 Seth Mos
	if($phase2['mode'] == "tunnel6")
1892
		$family = "-6";
1893
	else
1894
		$family = "-4";
1895
1896 1d69f52f Seth Mos
	/* Create new SPD entries for the new configuration */
1897
	/* zap any existing SA entries beforehand */
1898 c60cae98 Seth Mos
	foreach($sad_arr as $sad) {
1899 1d69f52f Seth Mos
		if(($sad['dst'] == $ep) && ($sad['src'] == $rgip)) {
1900 98790f61 Seth Mos
			$spdconf .= "delete {$family} {$rgip} {$ep} {$phase2['protocol']} 0x{$sad['spi']};\n";
1901 c60cae98 Seth Mos
		}
1902 1d69f52f Seth Mos
		if(($sad['src'] == $ep) && ($sad['dst'] == $rgip)) {
1903 98790f61 Seth Mos
			$spdconf .= "delete {$family} {$ep} {$rgip} {$phase2['protocol']} 0x{$sad['spi']};\n";
1904 c60cae98 Seth Mos
		}
1905
	}
1906
	/* add new SPD policies to replace them */
1907 03131eb9 Renato Botelho
	if (!isset($phase1['disabled']) && !isset($phase2['disabled'])) {
1908 f00278f1 Pierre POMES
		$spdconf .= "spdadd {$family} {$local_subnet} " .
1909
			"{$remote_subnet} any -P out ipsec " .
1910
			"{$phase2['protocol']}/tunnel/{$ep}-" .
1911
			"{$rgip}/unique;\n";
1912 3c107b76 Ermal
1913
		if (!empty($phase2['natlocalid']))
1914 d83045b5 Ermal
			$local_subnet = ipsec_idinfo_to_cidr($phase2['natlocalid'], false, $phase2['mode']);
1915 f00278f1 Pierre POMES
		$spdconf .= "spdadd {$family} {$remote_subnet} " .
1916
			"{$local_subnet} any -P in ipsec " .
1917
			"{$phase2['protocol']}/tunnel/{$rgip}-" .
1918
			"{$ep}/unique;\n";
1919
	}
1920 c60cae98 Seth Mos
1921 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));
1922 1d69f52f Seth Mos
1923
	$now = time();
1924
	$spdfile = tempnam("{$g['tmp_path']}", "spd.conf.reload.{$now}.");
1925 c60cae98 Seth Mos
	/* generate temporary spd.conf */
1926 52c9f9fa Ermal
	@file_put_contents($spdfile, $spdconf);
1927 a49784a2 Ermal
	unset($spdconf);
1928 083a9e6d Renato Botelho
	/* remove static route to old gw */
1929
	if (is_ipaddr($old_gw))
1930
		mwexec("/sbin/route delete {$old_gw}", true);
1931 c60cae98 Seth Mos
	return true;
1932
}
1933
1934 7b2fdac4 jim-p
function vpn_ipsec_configure_preferoldsa() {
1935
	global $config;
1936
	if(isset($config['ipsec']['preferoldsa']))
1937
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
1938
	else
1939
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
1940
}
1941 9734b054 Scott Ullrich
1942 c513c309 Ermal
?>