Project

General

Profile

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