Project

General

Profile

Download (43.8 KB) Statistics
| Branch: | Tag: | Revision:
1 5b237745 Scott Ullrich
<?php
2 979cd6db Scott Ullrich
3 5b237745 Scott Ullrich
/*
4
	vpn.inc
5 979cd6db Scott Ullrich
	Copyright (C) 2004 Scott Ullrich
6 a93e56c5 Matthew Grooms
	Copyright (C) 2008 Shrew Soft Inc
7 6d7de776 Ermal Luçi
	Copyright (C) 2008 Ermal Lu?i
8 cfc707f7 Scott Ullrich
	All rights reserved.
9 17da6c79 Scott Ullrich
10
	originally part of m0n0wall (http://m0n0.ch/wall)
11
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
12
	All rights reserved.
13
14 5b237745 Scott Ullrich
	Redistribution and use in source and binary forms, with or without
15
	modification, are permitted provided that the following conditions are met:
16 17da6c79 Scott Ullrich
17 5b237745 Scott Ullrich
	1. Redistributions of source code must retain the above copyright notice,
18
	   this list of conditions and the following disclaimer.
19 17da6c79 Scott Ullrich
20 5b237745 Scott Ullrich
	2. Redistributions in binary form must reproduce the above copyright
21
	   notice, this list of conditions and the following disclaimer in the
22
	   documentation and/or other materials provided with the distribution.
23 17da6c79 Scott Ullrich
24 5b237745 Scott Ullrich
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
25
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
26
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
28
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33
	POSSIBILITY OF SUCH DAMAGE.
34
*/
35 8f67a8e1 Scott Ullrich
36 5b237745 Scott Ullrich
/* include all configuration functions */
37 979cd6db Scott Ullrich
require_once ("functions.inc");
38 8f67a8e1 Scott Ullrich
39 600dd4e0 Scott Ullrich
function vpn_ipsec_failover_configure() {
40
	global $config, $g;
41
42 649283ef Scott Ullrich
	$sasyncd_text = "";
43 600dd4e0 Scott Ullrich
44 979cd6db Scott Ullrich
	if ($config['installedpackages']['sasyncd'] <> "")
45
		foreach ($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
46
			$enabled = isset ($sasyncd['enable']);
47
			if (!$enabled)
48 dcca036d Scott Ullrich
				return;
49 979cd6db Scott Ullrich
			if ($sasyncd['peerip'] <> "")
50 7dd31990 Scott Ullrich
				$sasyncd_text .= "peer {$sasyncd['peerip']}\n";
51 979cd6db Scott Ullrich
			if ($sasyncd['interface'])
52 7dd31990 Scott Ullrich
				$sasyncd_text .= "carp interface {$sasyncd['interface']}\n";
53 979cd6db Scott Ullrich
			if ($sasyncd['sharedkey'] <> "")
54 7dd31990 Scott Ullrich
				$sasyncd_text .= "sharedkey {$sasyncd['sharedkey']}\n";
55 979cd6db Scott Ullrich
			if ($sasyncd['mode'] <> "")
56 7dd31990 Scott Ullrich
				$sasyncd_text .= "mode {$sasyncd['mode']}\n";
57 979cd6db Scott Ullrich
			if ($sasyncd['listenon'] <> "")
58 7dd31990 Scott Ullrich
				$sasyncd_text .= "listen on {$sasyncd['listenon']}\n";
59 979cd6db Scott Ullrich
			if ($sasyncd['flushmodesync'] <> "")
60 7dd31990 Scott Ullrich
				$sasyncd_text .= "flushmode sync {$sasyncd['flushmodesync']}\n";
61 dcca036d Scott Ullrich
		}
62 e1a74484 Scott Ullrich
63 600dd4e0 Scott Ullrich
	$fd = fopen("{$g['varetc_path']}/sasyncd.conf", "w");
64 649283ef Scott Ullrich
	fwrite($fd, $sasyncd_text);
65 600dd4e0 Scott Ullrich
	fclose($fd);
66
	chmod("{$g['varetc_path']}/sasyncd.conf", 0600);
67 c52719a8 Scott Ullrich
68 73239086 Seth Mos
	mwexec("killall sasyncd", true);
69 c52719a8 Scott Ullrich
70 600dd4e0 Scott Ullrich
	/* launch sasyncd, oh wise one */
71 979cd6db Scott Ullrich
	mwexec_bg("/usr/local/sbin/sasyncd -d -v -v -v");
72 600dd4e0 Scott Ullrich
}
73 8f67a8e1 Scott Ullrich
74
function find_last_gif_device() {
75 979cd6db Scott Ullrich
	$last_gif_found = -1;
76
	$regs = "";
77
	if (!($fp = popen("/sbin/ifconfig -l", "r")))
78
		return -1;
79
	$ifconfig_data = fread($fp, 4096);
80
	pclose($fp);
81
	$ifconfig_array = split(" ", $ifconfig_data);
82
	foreach ($ifconfig_array as $ifconfig) {
83
		ereg("gif(.)", $ifconfig, $regs);
84
		if ($regs[0] && $regs[0] > $last_gif_found) {
85
			$last_gif_found = $regs[1];
86
		}
87
	}
88
	return $last_gif_found;
89 8f67a8e1 Scott Ullrich
}
90
91 a93e56c5 Matthew Grooms
function vpn_ipsec_configure($ipchg = false)
92
{
93
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos;
94 17da6c79 Scott Ullrich
95 0feec714 Scott Ullrich
	mwexec("/sbin/ifconfig enc0 up");
96
97 c1f5a46b Scott Ullrich
	/* get the automatic /etc/ping_hosts.sh ready */
98
	unlink_if_exists("/var/db/ipsecpinghosts");
99
	touch("/var/db/ipsecpinghosts");
100
101 a93e56c5 Matthew Grooms
	if(isset($config['ipsec']['preferredoldsa']))
102 8f67a8e1 Scott Ullrich
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
103 4bfdee6a Bill Marquette
	else
104
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
105 8f67a8e1 Scott Ullrich
106
	$number_of_gifs = find_last_gif_device();
107 a93e56c5 Matthew Grooms
	for ($x = 0; $x < $number_of_gifs; $x++)
108 8f67a8e1 Scott Ullrich
		mwexec("/sbin/ifconfig gif" . $x . " delete");
109
110 85a5da13 Ermal Luçi
	$curwanip = get_interface_ip();
111 600dd4e0 Scott Ullrich
112 8f67a8e1 Scott Ullrich
	$syscfg = $config['system'];
113 5b237745 Scott Ullrich
	$ipseccfg = $config['ipsec'];
114 a93e56c5 Matthew Grooms
	$a_phase1 = $config['ipsec']['phase1'];
115
	$a_phase2 = $config['ipsec']['phase2'];
116 3462a529 Matthew Grooms
	$a_client = $config['ipsec']['client'];
117 5b237745 Scott Ullrich
	$lancfg = $config['interfaces']['lan'];
118 a55e9c70 Ermal Lu?i
	$lanip = get_interface_ip("lan");
119
	$lansn = get_interface_subnet("lan");
120
	$lansa = gen_subnet($lanip, $lansn);
121 8f67a8e1 Scott Ullrich
122 2f1e0311 Seth Mos
	if (!isset($ipseccfg['enable'])) {
123
		mwexec("/sbin/ifconfig enc0 down");
124 8f67a8e1 Scott Ullrich
125 5b237745 Scott Ullrich
		/* kill racoon */
126 73239086 Seth Mos
		mwexec("/usr/bin/killall racoon", true);
127 979cd6db Scott Ullrich
		killbypid("{$g['varrun_path']}/dnswatch-ipsec.pid");
128
		
129
		/* wait for racoon process to die */
130 8f67a8e1 Scott Ullrich
		sleep(2);
131
132 5b237745 Scott Ullrich
		/* send a SIGKILL to be sure */
133
		sigkillbypid("{$g['varrun_path']}/racoon.pid", "KILL");
134 2f1e0311 Seth Mos
135
		/* flush SPD and SAD */
136 6b91fe11 Seth Mos
		mwexec("/usr/local/sbin/setkey -FP");
137
		mwexec("/usr/local/sbin/setkey -F");
138 2f1e0311 Seth Mos
139
		return true;
140 04b46591 Ermal Lu?i
	} else {
141 924876a8 Ermal Lu?i
		if ($g['booting'])
142
			echo "Configuring IPsec VPN... ";
143
144 8f67a8e1 Scott Ullrich
		/* fastforwarding is not compatible with ipsec tunnels */
145 979cd6db Scott Ullrich
		mwexec("/sbin/sysctl net.inet.ip.fastforwarding=0");
146 8f67a8e1 Scott Ullrich
147 5b237745 Scott Ullrich
		if (!$curwanip) {
148
			/* IP address not configured yet, exit */
149
			if ($g['booting'])
150 a63f7d55 Scott Ullrich
				echo "done\n";
151 5b237745 Scott Ullrich
			return 0;
152
		}
153 8f67a8e1 Scott Ullrich
154 ce97a47b Seth Mos
		/* this loads a route table which is used to determine if a route needs to be removed. */
155 2731ebc8 Seth Mos
		exec("/usr/bin/netstat -rn", $route_arr, $retval);
156 ce97a47b Seth Mos
		$route_str = implode("\n", $route_arr);
157
158 a93e56c5 Matthew Grooms
		/* resolve all local, peer addresses and setup pings */
159
		$ipmap = array();
160
		$rgmap = array();
161
		$dnswatch_list = array();
162
		if (is_array($a_phase1) && count($a_phase1)) {
163 87e07f52 mgrooms
164
			/* step through each phase1 entry */
165 a93e56c5 Matthew Grooms
			foreach ($a_phase1 as $ph1ent) {
166
				if (isset($ph1ent['disabled']))
167
					continue;
168 8f67a8e1 Scott Ullrich
169 0af7398a Matthew Grooms
				$ep = ipsec_get_phase1_src($ph1ent);
170 a93e56c5 Matthew Grooms
				if (!$ep)
171
					continue;
172 8f67a8e1 Scott Ullrich
173 a93e56c5 Matthew Grooms
				if(!in_array($ep,$ipmap))
174
					$ipmap[] = $ep;
175 8f67a8e1 Scott Ullrich
176 a93e56c5 Matthew Grooms
				/* see if this tunnel has a hostname for the remote-gateway. If so,
177
				   try to resolve it now and add it to the list for dnswatch */
178 8f67a8e1 Scott Ullrich
179 3462a529 Matthew Grooms
				if (isset ($ph1ent['mobile']))
180
					continue;
181
182 a93e56c5 Matthew Grooms
				$rg = $ph1ent['remote-gateway'];
183 979cd6db Scott Ullrich
184 a93e56c5 Matthew Grooms
				if (!is_ipaddr($rg)) {
185
					$dnswatch_list[] = $rg;
186 c60cae98 Seth Mos
					add_hostname_to_watch($rg);
187 a93e56c5 Matthew Grooms
					$rg = resolve_retry($rg);
188 0af7398a Matthew Grooms
					if (!$rg)
189 979cd6db Scott Ullrich
						continue;
190 a93e56c5 Matthew Grooms
				}
191 8f67a8e1 Scott Ullrich
192 a93e56c5 Matthew Grooms
				$rgmap[$ph1ent['remote-gateway']] = $rg;
193 8f67a8e1 Scott Ullrich
194 87e07f52 mgrooms
				/* step through each phase2 entry */
195
				foreach ($a_phase2 as $ph2ent) {
196
197
					$ikeid = $ph2ent['ikeid'];
198
199
					if (isset($ph2ent['disabled']))
200
						continue;
201
202
					if ($ikeid != $ph1ent['ikeid'])
203
						continue;
204 8ee9b271 Scott Ullrich
205 87e07f52 mgrooms
					/* add an ipsec pinghosts entry */
206
					if ($ph2ent['pinghost']) {
207
						$pfd = fopen("/var/db/ipsecpinghosts", "a");
208
						$iflist = get_configured_interface_list();
209
						foreach ($iflist as $ifent => $ifname) {
210 924876a8 Ermal Lu?i
							$interface_ip = get_interface_ip($ifnet);
211 87e07f52 mgrooms
							$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true);
212
							if (ip_in_subnet($interface_ip, $local_subnet))
213
								$srcip = $interface_ip;
214
						}
215
						$dstip = $ph2ent['pinghost'];
216
						fwrite($pfd, "$srcip|$dstip|3\n");
217
						fclose($pfd);
218 17da6c79 Scott Ullrich
					}
219 a93e56c5 Matthew Grooms
				}
220
			}
221
		}
222 8f67a8e1 Scott Ullrich
223 a93e56c5 Matthew Grooms
		/* generate CA certificates files */
224 73fbece8 mgrooms
		if (is_array($config['system']['ca']) && count($config['system']['ca'])) {
225
			foreach ($config['system']['ca'] as $ca) {
226
				if (!isset($ca['crt'])) {
227
					log_error("Error: Invalid certificate info for {$ca['name']}");
228
					continue;
229
				}
230
				$cert = base64_decode($ca['crt']);
231
				$x509cert = openssl_x509_parse(openssl_x509_read($cert));
232
				if (!is_array($x509cert) || !isset($x509cert['hash'])) {
233
					log_error("Error: Invalid certificate hash info for {$ca['name']}");
234
					continue;
235
				}
236
				$fname = $g['varetc_path']."/".$x509cert['hash'];
237
				if (!file_put_contents($fname, $cert)) {
238
					log_error("Error: Cannot write IPsec CA file for {$ca['name']}");
239
					continue;
240 a93e56c5 Matthew Grooms
				}
241
			}
242
		}
243
		
244
		/* generate psk.txt */
245
		$fd = fopen("{$g['varetc_path']}/psk.txt", "w");
246
		if (!$fd) {
247
			printf("Error: cannot open psk.txt in vpn_ipsec_configure().\n");
248
			return 1;
249
		}
250
251
		$pskconf = "";
252 037b51b3 Seth Mos
253 a93e56c5 Matthew Grooms
		if (is_array($a_phase1) && count($a_phase1)) {
254
			foreach ($a_phase1 as $ph1ent) {
255
256
				if (isset($ph1ent['disabled']))
257
					continue;
258
259 3462a529 Matthew Grooms
				if (strstr($ph1ent['authentication_method'],'rsa'))
260
					continue;
261 a93e56c5 Matthew Grooms
262
				$peerid_type = $ph1ent['peerid_type'];
263
264
				switch ($peerid_type) {
265
					case "peeraddress":
266
						$peerid_type = "address";
267 3462a529 Matthew Grooms
						$peerid_data = $rgmap[$ph1ent['remote-gateway']];
268 a93e56c5 Matthew Grooms
						break;
269
270
					case "address";
271
						$peerid_data = $ph1ent['peerid_data'];
272
						break;
273
274
					case "fqdn";
275
					case "keyid tag";
276
					case "user_fqdn";
277
						$peerid_data = $ph1ent['peerid_data'];
278
						break;
279 5b237745 Scott Ullrich
				}
280 8f67a8e1 Scott Ullrich
281 3462a529 Matthew Grooms
				$pskconf .= "{$peerid_data}\t{$ph1ent['pre-shared-key']}\n";
282 5b237745 Scott Ullrich
			}
283 a93e56c5 Matthew Grooms
		}
284
285
		fwrite($fd, $pskconf);
286
		fclose($fd);
287
		chmod("{$g['varetc_path']}/psk.txt", 0600);
288
			
289
		/* begin racoon.conf */
290
		if ((is_array($a_phase1) && count($a_phase1)) ||
291
			(is_array($a_phase2) && count($a_phase2))) {
292 8f67a8e1 Scott Ullrich
293 5b237745 Scott Ullrich
			$fd = fopen("{$g['varetc_path']}/racoon.conf", "w");
294
			if (!$fd) {
295
				printf("Error: cannot open racoon.conf in vpn_ipsec_configure().\n");
296
				return 1;
297
			}
298 17da6c79 Scott Ullrich
299 6edc48fe Seth Mos
			$racoonconf = "# This file is automatically generated. Do not edit\n";			
300 c52719a8 Scott Ullrich
			$racoonconf .= "path pre_shared_key \"{$g['varetc_path']}/psk.txt\";\n\n";
301 a63f7d55 Scott Ullrich
			$racoonconf .= "path certificate  \"{$g['varetc_path']}\";\n\n";
302 c52719a8 Scott Ullrich
303 a93e56c5 Matthew Grooms
			/* begin listen section */
304
			if (count($ipmap)) {
305
				$racoonconf .= "\nlisten\n";
306
				$racoonconf .= "{\n";
307 6edc48fe Seth Mos
				$racoonconf .= "	adminsock \"/var/run/racoon.sock\" \"root\" \"wheel\" 0660;\n";
308 a93e56c5 Matthew Grooms
				foreach ($ipmap as $addr) {
309
					$racoonconf .= "\tisakmp {$addr} [500];\n";
310
					$racoonconf .= "\tisakmp_natt {$addr} [4500];\n";
311 a63f7d55 Scott Ullrich
				}
312 a93e56c5 Matthew Grooms
				$racoonconf .= "}\n\n";
313
			}
314 c52719a8 Scott Ullrich
315 3462a529 Matthew Grooms
			/* begin mode_cfg section */
316
			if (is_array($a_client) && isset($a_client['enable'])) {
317
318
				$racoonconf .= "\nmode_cfg\n";
319
				$racoonconf .= "{\n";
320
321
				if ($a_client['user_source'])
322
					$racoonconf .= "\tauth_source {$a_client['user_source']};\n";
323
				if ($a_client['group_source'])
324
					$racoonconf .= "\tgroup_source {$a_client['group_source']};\n";
325
326
				if ($a_client['pool_address'] && $a_client['pool_netbits']) {
327
					$pool_address = $a_client['pool_address'];
328
					$pool_netmask = gen_subnet_mask($a_client['pool_netbits']);
329
330
					$pool_address = long2ip(ip2long($pool_address)+1);
331
					$pool_size = ~ip2long($pool_netmask) - 2;
332
333
					$racoonconf .= "\tpool_size {$pool_size};\n";
334
					$racoonconf .= "\tnetwork4 {$pool_address};\n";
335
					$racoonconf .= "\tnetmask4 {$pool_netmask};\n";
336
				}
337
338
				if (isset($a_client['net_list'])) {
339
340
					$net_list = '';
341
342
					foreach ($a_phase2 as $ph2ent) {
343
344
						if (isset($ph2ent['disabled']))
345
							continue;
346
347
						if (!isset($ph2ent['mobile']))
348
							continue;
349
350
						$localid = ipsec_idinfo_to_cidr($ph2ent['localid'],true);
351
352
						if ($net_list)
353
							$net_list .= ", ";
354
						$net_list .= $localid;
355
					}
356
357
					if ($net_list)
358
						$racoonconf .= "\tsplit_network include {$net_list};\n";
359
				}
360
361
				if ($a_client['dns_server1'])
362
					$racoonconf .= "\tdns4 {$a_client['dns_server1']};\n";
363
				if ($a_client['dns_server2'])
364
					$racoonconf .= "\tdns4 {$a_client['dns_server2']};\n";
365
				if ($a_client['dns_server3'])
366
					$racoonconf .= "\tdns4 {$a_client['dns_server3']};\n";
367
				if ($a_client['dns_server4'])
368
					$racoonconf .= "\tdns4 {$a_client['dns_server4']};\n";
369
370
				if ($a_client['wins_server1'])
371
					$racoonconf .= "\twins4 {$a_client['wins_server1']};\n";
372
				if ($a_client['wins_server2'])
373
					$racoonconf .= "\twins4 {$a_client['wins_server2']};\n";
374
375
				if ($a_client['dns_domain'])
376
					$racoonconf .= "\tdefault_domain \"{$a_client['dns_domain']}\";\n";
377
378
				if ($a_client['pfs_group'])
379
					$racoonconf .= "\tpfs_group {$a_client['pfs_group']};\n";
380
381
				if ($a_client['login_banner']) {
382
					$fn = "{$g['varetc_path']}/racoon.motd";
383
					$fd1 = fopen($fn, "w");
384
					if (!$fd1) {
385
						printf("Error: cannot open server{$fn} in vpn.\n");
386
						return 1;
387
					}
388
389
					fwrite($fd1, $a_client['login_banner']);
390
					fclose($fd1);
391
392
					$racoonconf .= "\tbanner \"{$fn}\";\n";
393
				}
394
395
				$racoonconf .= "}\n\n";
396
			}
397
			/* end mode_cfg section */
398
399 a93e56c5 Matthew Grooms
			/* begin remote sections */
400
			if (is_array($a_phase1) && count($a_phase1)) {
401
				/* begin remote */
402
				foreach ($a_phase1 as $ph1ent) {
403 3462a529 Matthew Grooms
404 a93e56c5 Matthew Grooms
					if (isset($ph1ent['disabled']))
405
						continue;
406 c52719a8 Scott Ullrich
407 3462a529 Matthew Grooms
					if (isset($ph1ent['mobile']) && !isset($a_client['enable']))
408
						continue;
409
410 a93e56c5 Matthew Grooms
					$ikeid = $ph1ent['ikeid'];
411 c52719a8 Scott Ullrich
412 0af7398a Matthew Grooms
					$ep = ipsec_get_phase1_src($ph1ent);
413 a93e56c5 Matthew Grooms
					if (!$ep)
414 979cd6db Scott Ullrich
						continue;
415 c52719a8 Scott Ullrich
416 3462a529 Matthew Grooms
					if (!isset($ph1ent['mobile'])) {
417
						$rgip = $rgmap[$ph1ent['remote-gateway']];
418
						if (!$rgip)
419
							continue;
420
					}
421
422 a93e56c5 Matthew Grooms
					$myid_type = $ph1ent['myid_type'];
423 c52719a8 Scott Ullrich
424 a93e56c5 Matthew Grooms
					switch ($myid_type) {
425 725dd10a Scott Ullrich
426 a93e56c5 Matthew Grooms
						case "myaddress":
427
							$myid_type = "address";
428
							$myid_data = $ep;
429
							break;
430
431
						case "dyn_dns":
432
							$myid_data = gethostbyname($ph1ent['myid_data']);
433
							break;
434 c52719a8 Scott Ullrich
435 a93e56c5 Matthew Grooms
						case "address";
436
							$myid_data = $ph1ent['myid_data'];
437
							break;
438
439
						case "fqdn";
440
						case "keyid tag";
441
						case "user_fqdn";
442
						case "asn1dn";
443
							$myid_data = $ph1ent['myid_data'];
444
							if( $myid_data )
445
								$myid_data = "\"".$myid_data."\"";
446
							break;
447 a63f7d55 Scott Ullrich
					}
448 c52719a8 Scott Ullrich
449 a93e56c5 Matthew Grooms
					$peerid_type = $ph1ent['peerid_type'];
450
451
					switch ($peerid_type) {
452
						case "peeraddress":
453
							$peerid_type = "address";
454
							$peerid_data = $rgip;
455
							break;
456
457
						case "address";
458
							$peerid_data = $ph1ent['peerid_data'];
459
							break;
460
461
						case "fqdn";
462
						case "keyid tag";
463
						case "user_fqdn";
464
						case "asn1dn";
465
							$peerid_data = $ph1ent['peerid_data'];
466
							if( $peerid_data )
467
								$peerid_data = "\"".$peerid_data."\"";
468
							break;
469 d597b0b9 Scott Ullrich
					}
470
471 3462a529 Matthew Grooms
					$natt = "off";
472 a93e56c5 Matthew Grooms
					if (isset($ph1ent['nat_traversal']))
473 3462a529 Matthew Grooms
						$natt = $ph1ent['nat_traversal'];
474
475
					$init = "on";
476
					$genp = "off";
477
					if (isset($ph1ent['mobile'])) {
478
						$rgip = "anonymous";
479
						$init = "off";
480
						$genp = "unique";
481
					}
482
483
					$dpdline1 = '';
484
					$dpdline2 = '';
485
					if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
486
						$dpdline1 = "dpd_delay = {$ph1ent['dpd_delay']};";
487
						$dpdline2 = "dpd_maxfail = {$ph1ent['dpd_maxfail']};";
488
					}
489 c52719a8 Scott Ullrich
490 a93e56c5 Matthew Grooms
					if (isset ($ph1ent['authentication_method']))
491
						$authmethod = $ph1ent['authentication_method'];
492
					else
493 979cd6db Scott Ullrich
						$authmethod = 'pre_shared_key';
494 a63f7d55 Scott Ullrich
495 979cd6db Scott Ullrich
					$certline = '';
496
497 3462a529 Matthew Grooms
					if (strstr($authmethod,'rsa')) {
498 c52719a8 Scott Ullrich
499 73fbece8 mgrooms
						$cert = lookup_cert($ph1ent['certref']);
500 979cd6db Scott Ullrich
501 73fbece8 mgrooms
						if (!$cert)
502
						{
503
							log_error("Error: Invalid phase1 certificate reference for {$ph1ent['name']}");
504
							continue;
505 a63f7d55 Scott Ullrich
						}
506 73fbece8 mgrooms
507
						$certfile = "cert-".$ikeid.".crt";
508
						$certpath = $g['varetc_path']."/".$certfile;
509
510
						if (!file_put_contents($certpath, base64_decode($cert['crt'])))
511
						{
512
							log_error("Error: Cannot write phase1 certificate file for {$ph1ent['name']}");
513
							continue;
514 979cd6db Scott Ullrich
						}
515 73fbece8 mgrooms
516
						chmod($certpath, 0600);
517
518
						$keyfile = "cert-".$ikeid.".key";
519
						$keypath = $g['varetc_path']."/".$keyfile;
520
521
						if (!file_put_contents($keypath, base64_decode($cert['crt'])))
522
						{
523
							log_error("Error: Cannot write phase1 key file for {$ph1ent['name']}");
524
							continue;
525 979cd6db Scott Ullrich
						}
526 73fbece8 mgrooms
527
						chmod($keypath, 0600);
528
529
						$certline = "certificate_type x509 \"{$certpath}\" \"{$keypath}.key\";";
530 c52719a8 Scott Ullrich
					}
531 a93e56c5 Matthew Grooms
532
					$ealgos = '';
533
					$ealg_id = $ph1ent['encryption-algorithm']['name'];
534
					$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
535
					if ($ealg_kl)
536
						$ealgos = $ealgos.$ealg_id." ".$ealg_kl;
537
					else
538
						$ealgos = $ealgos.$ealg_id;
539
540
					$lifeline = '';
541
					if ($ph1ent['lifetime'])
542
						$lifeline = "lifetime time {$ph1ent['lifetime']} secs;";
543 3462a529 Matthew Grooms
544 a93e56c5 Matthew Grooms
					/* add remote section to configuration */
545
546 979cd6db Scott Ullrich
					$racoonconf .=<<<EOD
547 3462a529 Matthew Grooms
548 a93e56c5 Matthew Grooms
remote {$rgip}
549
{
550
	ph1id {$ikeid};
551
	exchange_mode {$ph1ent['mode']};
552
	my_identifier {$myid_type} {$myid_data};
553
	peers_identifier {$peerid_type} {$peerid_data};
554
	ike_frag on;
555 3462a529 Matthew Grooms
	generate_policy = {$genp};
556
	initial_contact = {$init};
557
	nat_traversal = {$natt};
558 a63f7d55 Scott Ullrich
	{$certline}
559 3462a529 Matthew Grooms
	{$dpdline1}
560
	{$dpdline2}
561 5b237745 Scott Ullrich
	support_proxy on;
562 a93e56c5 Matthew Grooms
	proposal_check claim;
563 5b237745 Scott Ullrich
564 a93e56c5 Matthew Grooms
	proposal
565
	{
566 a63f7d55 Scott Ullrich
		authentication_method {$authmethod};
567 a93e56c5 Matthew Grooms
		encryption_algorithm ${ealgos};
568
		hash_algorithm {$ph1ent['hash-algorithm']};
569
		dh_group {$ph1ent['dhgroup']};
570
		${lifeline}
571
	}
572
}
573 5b237745 Scott Ullrich
574
EOD;
575 a93e56c5 Matthew Grooms
				}
576
				/* end remote */
577
			}
578
			/* end remote sections */
579
		
580
			/* begin sainfo sections */
581
			if (is_array($a_phase2) && count($a_phase2)) {
582 3462a529 Matthew Grooms
583 a93e56c5 Matthew Grooms
				/* begin sainfo */
584
				foreach ($a_phase2 as $ph2ent) {
585 c52719a8 Scott Ullrich
586 a93e56c5 Matthew Grooms
					$ikeid = $ph2ent['ikeid'];
587 c52719a8 Scott Ullrich
588 4b96b367 mgrooms
					if( !ipsec_lookup_phase1($ph2ent,$ph1ent))
589
						continue;
590
591
					if (isset($ph1ent['disabled']))
592
						continue;
593
594 3462a529 Matthew Grooms
					if (isset($ph2ent['disabled']))
595
						continue;
596
597
					if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
598
						continue;
599
600 4b96b367 mgrooms
					if ($ph2ent['mode'] == 'tunnel') {
601 c52719a8 Scott Ullrich
602 4b96b367 mgrooms
						$localid_type = $ph2ent['localid']['type'];
603
						if ($localid_type != "address")
604
							$localid_type = "subnet";
605 3462a529 Matthew Grooms
606 4b96b367 mgrooms
						$localid_data = ipsec_idinfo_to_cidr($ph2ent['localid']);
607
						$localid_spec = $localid_type." ".$localid_data." any";
608 3462a529 Matthew Grooms
609 4b96b367 mgrooms
						if (!isset($ph2ent['mobile'])) {
610
							$remoteid_type = $ph2ent['remoteid']['type'];
611
							if ($remoteid_type != "address")
612
								$remoteid_type = "subnet";
613 3462a529 Matthew Grooms
614 4b96b367 mgrooms
							$remoteid_data = ipsec_idinfo_to_cidr($ph2ent['remoteid']);
615
							$remoteid_spec = $remoteid_type." ".$remoteid_data." any";
616
						} else
617
							$remoteid_spec = "anonymous";
618 3462a529 Matthew Grooms
619 4b96b367 mgrooms
					} else {
620 5b237745 Scott Ullrich
621 4b96b367 mgrooms
						$rgip = $rgmap[$ph1ent['remote-gateway']];
622 5b237745 Scott Ullrich
623 4b96b367 mgrooms
						$localid_data = ipsec_get_phase1_src($ph1ent);
624
						$localid_spec = "address {$localid_data}";
625
626
						$remoteid_data = $rgmap[$ph1ent['remote-gateway']];
627
						$remoteid_spec = "address {$remoteid_data}";
628 3462a529 Matthew Grooms
					}
629 c52719a8 Scott Ullrich
630 57dc2556 mgrooms
					if($ph2ent['protocol'] == 'esp') {
631 4b96b367 mgrooms
632
						$ealgos = '';
633 c52719a8 Scott Ullrich
634 4b96b367 mgrooms
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
635 c52719a8 Scott Ullrich
636 4b96b367 mgrooms
							$ealg_id = $ealg['name'];
637
							$ealg_kl = $ealg['keylen'];
638 c52719a8 Scott Ullrich
639 4b96b367 mgrooms
							if ($ealg_kl) {
640
								if( $ealg_kl == "auto" ) {
641
									$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
642
									$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
643
									$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
644 c52719a8 Scott Ullrich
645 4b96b367 mgrooms
									for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
646
										if ($ealgos)
647
											$ealgos = $ealgos.", ";
648
										$ealgos = $ealgos.$ealg_id." ".$keylen;
649
									}
650
								} else {
651
									if ($ealgos)
652 a93e56c5 Matthew Grooms
										$ealgos = $ealgos.", ";
653 4b96b367 mgrooms
									$ealgos = $ealgos.$ealg_id." ".$ealg_kl;
654 a93e56c5 Matthew Grooms
								}
655
							} else {
656
								if ($ealgos)
657
									$ealgos = $ealgos.", ";
658 4b96b367 mgrooms
								$ealgos = $ealgos.$ealg_id;
659 979cd6db Scott Ullrich
							}
660 a93e56c5 Matthew Grooms
						}
661 4b96b367 mgrooms
662
						$ealgosline = "encryption_algorithm {$ealgos};";
663
664
					} else {
665
666
						$ealgosline = "encryption_algorithm null_enc;";
667 a63f7d55 Scott Ullrich
					}
668 c52719a8 Scott Ullrich
669 4b96b367 mgrooms
					$halgos = join(",", $ph2ent['hash-algorithm-option']);
670
					$halgosline = "authentication_algorithm {$halgos};";
671
672
					$pfsline = '';
673
					if ($ph2ent['pfsgroup'])
674
						$pfsline = "pfs_group {$ph2ent['pfsgroup']};";
675
					if (isset($a_client['pfs_group'])) {
676
						$pfsline = '';
677
						if ($a_client['pfs_group'])
678
							$pfsline = "pfs_group {$a_client['pfs_group']};";
679
					}
680
681
					$lifeline = '';
682
					if ($ph2ent['lifetime'])
683
						$lifeline = "lifetime time {$ph2ent['lifetime']} secs;";
684
685 a93e56c5 Matthew Grooms
					/* add sainfo section to configuration */
686
					
687
					$racoonconf .=<<<EOD
688
					
689 3462a529 Matthew Grooms
sainfo {$localid_spec} {$remoteid_spec}
690 a93e56c5 Matthew Grooms
{
691
	remoteid {$ikeid};
692 4b96b367 mgrooms
	{$ealgosline}
693
	{$halgosline}
694 3462a529 Matthew Grooms
	{$pfsline}
695
	{$lifeline}
696 4b96b367 mgrooms
	compression_algorithm deflate;
697 a93e56c5 Matthew Grooms
}
698 5b237745 Scott Ullrich
699
EOD;
700 a93e56c5 Matthew Grooms
				}
701
				/* end sainfo */
702 5b237745 Scott Ullrich
			}
703 a93e56c5 Matthew Grooms
			/* end sainfo sections */
704 c52719a8 Scott Ullrich
705 5b237745 Scott Ullrich
			fwrite($fd, $racoonconf);
706
			fclose($fd);
707 a93e56c5 Matthew Grooms
		}
708
		/* end racoon.conf */
709 c52719a8 Scott Ullrich
710 a93e56c5 Matthew Grooms
		/* generate IPsec policies */
711
		if (is_array($a_phase2) && count($a_phase2)) {
712
			/* generate spd.conf */
713
			$fd = fopen("{$g['varetc_path']}/spd.conf", "w");
714 5b237745 Scott Ullrich
			if (!$fd) {
715 a93e56c5 Matthew Grooms
				printf("Error: cannot open spd.conf in vpn_ipsec_configure().\n");
716 5b237745 Scott Ullrich
				return 1;
717
			}
718 c52719a8 Scott Ullrich
719 a93e56c5 Matthew Grooms
			$spdconf = "";
720 c52719a8 Scott Ullrich
721 a93e56c5 Matthew Grooms
			/* What are these SPD entries for?
722
			 * -mgrooms 07/10/2008
723
			 */
724
			$spdconf .= "spdadd {$lanip}/32 {$lansa}/{$lansn} any -P out none;\n";
725
			$spdconf .= "spdadd {$lansa}/{$lansn} {$lanip}/32 any -P in none;\n";
726 c52719a8 Scott Ullrich
727 a93e56c5 Matthew Grooms
			foreach ($a_phase2 as $ph2ent) {
728 3462a529 Matthew Grooms
729 a93e56c5 Matthew Grooms
				if( !ipsec_lookup_phase1($ph2ent,$ph1ent))
730
					continue;
731 c52719a8 Scott Ullrich
732 3462a529 Matthew Grooms
				if (isset($ph1ent['mobile']))
733
					continue;
734
735
				if (isset($ph1ent['disabled']))
736 a93e56c5 Matthew Grooms
					continue;
737
738 3462a529 Matthew Grooms
				if (isset($ph2ent['disabled']))
739 a93e56c5 Matthew Grooms
					continue;
740
741 0af7398a Matthew Grooms
				$ep = ipsec_get_phase1_src($ph1ent);
742 a93e56c5 Matthew Grooms
				if (!$ep)
743
					continue;
744
745
				$rgip = $rgmap[$ph1ent['remote-gateway']];
746
747
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'],true);
748
				$remoteid = ipsec_idinfo_to_cidr($ph2ent['remoteid'],true);
749
750
				if (isset ($ph2ent['creategif'])) {
751
					$number_of_gifs = find_last_gif_device();
752
					$number_of_gifs++;
753 85a5da13 Ermal Luçi
					$curwanip = get_interface_ip();
754 a93e56c5 Matthew Grooms
					if ($config['installedpackages']['sasyncd']['config'] <> "") {
755
						foreach ($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
756
							if ($sasyncd['ip'] <> "")
757
								$curwanip = $sasyncd['ip'];
758
						}
759 eea54038 Seth Mos
					}
760 a93e56c5 Matthew Grooms
					mwexec("/sbin/ifconfig gif" . $number_of_gifs . " tunnel" . $curwanip . " " . $rgip);
761
					mwexec("/sbin/ifconfig gif" . $number_of_gifs . " {$lansa}/{$lansn} {$lanip}/32");
762 eea54038 Seth Mos
				}
763 979cd6db Scott Ullrich
764 4b96b367 mgrooms
				if($ph2ent['mode'] == "tunnel") {
765
766
					$spdconf .= "spdadd {$localid} {$remoteid} any -P out ipsec " .
767
						"{$ph2ent['protocol']}/tunnel/{$ep}-{$rgip}/unique;\n";
768 a93e56c5 Matthew Grooms
769 4b96b367 mgrooms
					$spdconf .= "spdadd {$remoteid} {$localid} any -P in ipsec " .
770
						"{$ph2ent['protocol']}/tunnel/{$rgip}-{$ep}/unique;\n";
771
772
				} else {
773
774
					$spdconf .= "spdadd {$localid} {$remoteid} any -P out ipsec " .
775
						"{$ph2ent['protocol']}/transport//unique;\n";
776
777
					$spdconf .= "spdadd {$remoteid} {$localid} any -P in ipsec " .
778
						"{$ph2ent['protocol']}/transport//unique;\n";
779
780
				}
781 a93e56c5 Matthew Grooms
782
				/* static route needed? */
783
				if (preg_match("/^carp/i", $ph1ent['interface']))
784
					$parentinterface = link_carp_interface_to_parent($ph1ent['interface']);
785
				else
786
					$parentinterface = $ph1ent['interface'];
787
788
				if ($parentinterface <> "wan") {
789
					/* add endpoint routes to correct gateway on interface */
790
					if (interface_has_gateway($parentinterface)) {
791
						$gatewayip = get_interface_gateway("$parentinterface");
792 a55e9c70 Ermal Lu?i
						$interfaceip = get_interface_ip($parentinterface);
793
						$subnet_bits = get_interface_subnet($parentinterface);
794 a93e56c5 Matthew Grooms
						$subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
795
						/* if the remote gateway is in the local subnet, then don't add a route */
796
						if (! ip_in_subnet($rgip, "{$subnet_ip}/{$subnet_bits}")) {
797
							if(is_ipaddr($gatewayip)) {
798 c60cae98 Seth Mos
								/* FIXME: does adding route-to and reply-to on the in/outbound
799
								 * rules fix this? smos@ 13-01-2009 */
800 a93e56c5 Matthew Grooms
								log_error("IPSEC interface is not WAN but {$parentinterface}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
801 ce97a47b Seth Mos
								mwexec("/sbin/route delete -host {$rgip}");
802
								mwexec("/sbin/route add -host {$rgip} {$gatewayip}");
803 a93e56c5 Matthew Grooms
							}
804
						}
805 979cd6db Scott Ullrich
					}
806 b04eb23b Chris Buechler
				} else {
807 52cca3a4 Chris Buechler
					if(stristr($route_str, "{$rgip}")) {
808 2968431b Seth Mos
						mwexec("/sbin/route delete -host {$rgip}", true);
809 ce97a47b Seth Mos
					}
810
				}
811 a93e56c5 Matthew Grooms
			}
812
813
			fwrite($fd, $spdconf);
814
			fclose($fd);
815
		}
816
817 c8423fbf Matthew Grooms
		/* needed for racoonctl admin socket */
818 f0c3eea0 Scott Ullrich
		if (!is_dir("/var/db/racoon"))
819 c8423fbf Matthew Grooms
			mkdir("/var/db/racoon/");
820
		
821 202e5379 Scott Ullrich
		exec("/bin/mkdir -p /var/db/racoon");
822
		
823 a93e56c5 Matthew Grooms
		/* mange racoon process */
824
		if (is_process_running("racoon")) {
825 223547eb Seth Mos
			sleep("0.1");
826
			mwexec("/usr/local/sbin/racoonctl -s /var/run/racoon.sock reload-config", false);
827 f3c8bd98 Ermal Lu?i
			/* load SPD without flushing to be safe on config additions or changes. */
828
			mwexec("/usr/local/sbin/setkey -f {$g['varetc_path']}/spd.conf", false);
829 a93e56c5 Matthew Grooms
		} else {
830
			/* flush SA + SPD entries */
831 c60cae98 Seth Mos
			mwexec("/usr/local/sbin/setkey -FP", false);
832
 			sleep("0.1");
833
			mwexec("/usr/local/sbin/setkey -F", false);
834
 			sleep("0.1");
835
 			/* start racoon */
836
			mwexec("/usr/local/sbin/racoon -f {$g['varetc_path']}/racoon.conf", false);
837
 			sleep("0.1");
838
 			/* load SPD */
839
			mwexec("/usr/local/sbin/setkey -f {$g['varetc_path']}/spd.conf", false);
840 a93e56c5 Matthew Grooms
841
			/* start dnswatch, if necessary */
842
			if (count($dnswatch_list) > 0) {
843
				$interval = 60;
844
				if ($ipseccfg['dns-interval'])
845
					$interval = $ipseccfg['dns-interval'];
846
847
				$hostnames = "";
848 7664f2ef Seth Mos
				array_unique($dnswatch_list);
849 2b8c84e6 Seth Mos
				$hostnames = implode("\n", $dnswatch_list);
850
				file_put_contents("{$g['varetc_path']}/dnswatch-ipsec.hosts", $hostnames);
851 a93e56c5 Matthew Grooms
852 c60cae98 Seth Mos
				killbypid("{$g['varrun_path']}/dnswatch-ipsec.pid");
853 2b8c84e6 Seth Mos
				mwexec("/usr/local/sbin/dnswatch {$g['varrun_path']}/dnswatch-ipsec.pid $interval /etc/rc.newipsecdns {$g['varetc_path']}/dnswatch-ipsec.hosts");
854 2f1e0311 Seth Mos
			}
855 5b237745 Scott Ullrich
		}
856 a93e56c5 Matthew Grooms
	
857 924876a8 Ermal Lu?i
		vpn_ipsec_failover_configure();
858 a63f7d55 Scott Ullrich
859 72bd8df5 Ermal Lu?i
		if ($g['booting'])
860 924876a8 Ermal Lu?i
			echo "done\n";
861 5b237745 Scott Ullrich
	}
862 8f67a8e1 Scott Ullrich
863 5b237745 Scott Ullrich
	return 0;
864
}
865
866 67ee1ec5 Ermal Luçi
/* Forcefully restart IPsec
867
 * This is required for when dynamic interfaces reload
868
 * For all other occasions the normal vpn_ipsec_configure()
869
 * will gracefully reload the settings without restarting
870
 */
871
function vpn_ipsec_force_reload() {
872
	global $config;
873
	global $g;
874
875
	$ipseccfg = $config['ipsec'];
876
877
	/* kill racoon */
878 73239086 Seth Mos
	mwexec("/usr/bin/killall racoon", true);
879 67ee1ec5 Ermal Luçi
880
	/* wait for process to die */
881
	sleep(4);
882
883
	/* send a SIGKILL to be sure */
884
	sigkillbypid("{$g['varrun_path']}/racoon.pid", "KILL");
885
886
	/* wait for flushing to finish */
887
	sleep(1);
888
889
	/* if ipsec is enabled, start up again */
890
	if (isset($ipseccfg['enable'])) {
891
		log_error("Forcefully reloading IPsec racoon daemon");
892
		vpn_ipsec_configure();
893
	}
894
895
}
896
897
/* master setup for vpn (mpd) */
898
function vpn_setup() {
899
	/* start pptpd */
900
	vpn_pptpd_configure();
901
902
	/* start pppoe server */
903
	vpn_pppoe_configure();
904
905
	/* setup l2tp */
906
	vpn_l2tp_configure();
907
}
908
909 5b237745 Scott Ullrich
function vpn_pptpd_configure() {
910
	global $config, $g;
911 c52719a8 Scott Ullrich
912 5b237745 Scott Ullrich
	$syscfg = $config['system'];
913
	$pptpdcfg = $config['pptpd'];
914 c52719a8 Scott Ullrich
915 5b237745 Scott Ullrich
	if ($g['booting']) {
916
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
917
			return 0;
918 c52719a8 Scott Ullrich
919 a63f7d55 Scott Ullrich
		echo "Configuring PPTP VPN service... ";
920 c52719a8 Scott Ullrich
	} else {
921 5b237745 Scott Ullrich
		/* kill mpd */
922 67ee1ec5 Ermal Luçi
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
923 c52719a8 Scott Ullrich
924 5b237745 Scott Ullrich
		/* wait for process to die */
925 48bff85c Scott Ullrich
		sleep(3);
926 c52719a8 Scott Ullrich
927 979cd6db Scott Ullrich
		if (is_process_running("mpd -b")) {
928 67ee1ec5 Ermal Luçi
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
929 48bff85c Scott Ullrich
			log_error("Could not kill mpd within 3 seconds.   Trying again.");
930
		}
931 c52719a8 Scott Ullrich
932 5b237745 Scott Ullrich
		/* remove mpd.conf, if it exists */
933 67ee1ec5 Ermal Luçi
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
934
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
935
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
936 5b237745 Scott Ullrich
	}
937 c52719a8 Scott Ullrich
938 67ee1ec5 Ermal Luçi
	/* make sure pptp-vpn directory exists */
939
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
940
		mkdir("{$g['varetc_path']}/pptp-vpn");
941 c52719a8 Scott Ullrich
942 5b237745 Scott Ullrich
	switch ($pptpdcfg['mode']) {
943 979cd6db Scott Ullrich
		case 'server' :
944 5b237745 Scott Ullrich
			/* write mpd.conf */
945 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
946 5b237745 Scott Ullrich
			if (!$fd) {
947
				printf("Error: cannot open mpd.conf in vpn_pptpd_configure().\n");
948
				return 1;
949
			}
950 c52719a8 Scott Ullrich
951 979cd6db Scott Ullrich
			$mpdconf =<<<EOD
952 5b237745 Scott Ullrich
pptpd:
953
954
EOD;
955
956 a56120f2 Ermal Lu?i
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
957 5b237745 Scott Ullrich
				$mpdconf .= "	load pt{$i}\n";
958
			}
959 c52719a8 Scott Ullrich
960 a56120f2 Ermal Lu?i
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
961 c52719a8 Scott Ullrich
962 5b237745 Scott Ullrich
				$clientip = long2ip(ip2long($pptpdcfg['remoteip']) + $i);
963 c52719a8 Scott Ullrich
964 71569a7e jim-p
				if(isset($pptpdcfg['radius']['radiusissueips']) && isset($pptpdcfg['radius']['server']['enable'])) {
965 a35c2033 Martin Fuchs
					$isssue_ip_type = "set ipcp ranges {$pptpdcfg['localip']}/32 0.0.0.0/0";
966
				} else {
967
					$isssue_ip_type = "set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32";
968
				}
969
970 979cd6db Scott Ullrich
				$mpdconf .=<<<EOD
971 5b237745 Scott Ullrich
972
pt{$i}:
973 67ee1ec5 Ermal Luçi
	new pt{$i} pt{$i}
974 a35c2033 Martin Fuchs
	{$isssue_ip_type}
975 979cd6db Scott Ullrich
	load pts
976 5b237745 Scott Ullrich
977
EOD;
978
			}
979 c52719a8 Scott Ullrich
980 979cd6db Scott Ullrich
			$mpdconf .=<<<EOD
981 5b237745 Scott Ullrich
982 979cd6db Scott Ullrich
pts:
983 5b237745 Scott Ullrich
	set iface disable on-demand
984
	set iface enable proxy-arp
985 07cae4b2 Scott Ullrich
	set iface enable tcpmssfix
986 979cd6db Scott Ullrich
	set iface idle 1800
987 67ee1ec5 Ermal Luçi
	set iface up-script /usr/local/sbin/pptp-linkup
988 979cd6db Scott Ullrich
	set iface down-script /usr/local/sbin/vpn-linkdown
989 5b237745 Scott Ullrich
	set bundle enable multilink
990 979cd6db Scott Ullrich
	set bundle enable crypt-reqd
991 5b237745 Scott Ullrich
	set link yes acfcomp protocomp
992
	set link no pap chap
993 979cd6db Scott Ullrich
	set link enable chap-msv2
994 ee953edc Scott Ullrich
	set link mtu 1460
995 5b237745 Scott Ullrich
	set link keep-alive 10 60
996
	set ipcp yes vjcomp
997
	set bundle enable compression
998
	set ccp yes mppc
999
	set ccp yes mpp-e128
1000
	set ccp yes mpp-stateless
1001
1002
EOD;
1003 c52719a8 Scott Ullrich
1004 979cd6db Scott Ullrich
			if (!isset ($pptpdcfg['req128'])) {
1005
				$mpdconf .=<<<EOD
1006 5b237745 Scott Ullrich
	set ccp yes mpp-e40
1007 979cd6db Scott Ullrich
	set ccp yes mpp-e56
1008 5b237745 Scott Ullrich
1009
EOD;
1010
			}
1011 c8c416db Scott Ullrich
1012 871ce025 Bill Marquette
			if  (isset($pptpdcfg["wins"]) && $pptpdcfg['wins'] != "")
1013 979cd6db Scott Ullrich
				$mpdconf  .=  "	set ipcp nbns {$pptpdcfg['wins']}\n";
1014
			if (is_array($pptpdcfg['dnsserver']) && ($pptpdcfg['dnsserver'][0])) {
1015
				$mpdconf .= "	set ipcp dns " . join(" ", $pptpdcfg['dnsserver']) . "\n";
1016
			} else
1017
				if (isset ($config['dnsmasq']['enable'])) {
1018 a55e9c70 Ermal Lu?i
					$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1019 979cd6db Scott Ullrich
					if ($syscfg['dnsserver'][0])
1020
						$mpdconf .= " " . $syscfg['dnsserver'][0];
1021
					$mpdconf .= "\n";
1022
				} else
1023
					if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1024
						$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1025
					}
1026 07cae4b2 Scott Ullrich
1027 71569a7e jim-p
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1028
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1029 979cd6db Scott Ullrich
				$acctport = $authport + 1;
1030
				$mpdconf .=<<<EOD
1031 71569a7e jim-p
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1032
EOD;
1033
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1034
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1035
				$acctport = $authport + 1;
1036
				$mpdconf .=<<<EOD
1037
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret']}" {$authport} {$acctport}
1038
EOD;
1039
			}
1040
			$mpdconf .=<<<EOD
1041 5b237745 Scott Ullrich
	set radius retries 3
1042 979cd6db Scott Ullrich
	set radius timeout 10
1043 0af9dba4 Ermal Lu?i
	set auth enable radius-auth
1044 5b237745 Scott Ullrich
1045
EOD;
1046
1047 979cd6db Scott Ullrich
				if (isset ($pptpdcfg['radius']['accounting'])) {
1048
					$mpdconf .=<<<EOD
1049 0af9dba4 Ermal Lu?i
	set auth enable radius-acct
1050 979cd6db Scott Ullrich
	set radius acct-update 300
1051 5b237745 Scott Ullrich
1052
EOD;
1053
				}
1054
			}
1055
1056
			fwrite($fd, $mpdconf);
1057
			fclose($fd);
1058 c52719a8 Scott Ullrich
1059 5b237745 Scott Ullrich
			/* write mpd.links */
1060 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1061 5b237745 Scott Ullrich
			if (!$fd) {
1062
				printf("Error: cannot open mpd.links in vpn_pptpd_configure().\n");
1063
				return 1;
1064
			}
1065 c52719a8 Scott Ullrich
1066 5b237745 Scott Ullrich
			$mpdlinks = "";
1067 c52719a8 Scott Ullrich
1068 a56120f2 Ermal Lu?i
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1069 979cd6db Scott Ullrich
				$mpdlinks .=<<<EOD
1070 5b237745 Scott Ullrich
1071
pt{$i}:
1072
	set link type pptp
1073
	set pptp enable incoming
1074
	set pptp disable originate
1075 979cd6db Scott Ullrich
	set pptp disable windowing
1076 5b237745 Scott Ullrich
1077
EOD;
1078
			}
1079
1080
			fwrite($fd, $mpdlinks);
1081
			fclose($fd);
1082 c52719a8 Scott Ullrich
1083 5b237745 Scott Ullrich
			/* write mpd.secret */
1084 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1085 5b237745 Scott Ullrich
			if (!$fd) {
1086
				printf("Error: cannot open mpd.secret in vpn_pptpd_configure().\n");
1087
				return 1;
1088
			}
1089 c52719a8 Scott Ullrich
1090 5b237745 Scott Ullrich
			$mpdsecret = "";
1091 c52719a8 Scott Ullrich
1092 5b237745 Scott Ullrich
			if (is_array($pptpdcfg['user'])) {
1093
				foreach ($pptpdcfg['user'] as $user)
1094
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1095
			}
1096
1097
			fwrite($fd, $mpdsecret);
1098
			fclose($fd);
1099 67ee1ec5 Ermal Luçi
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1100 c52719a8 Scott Ullrich
1101 5b237745 Scott Ullrich
			/* fire up mpd */
1102 67ee1ec5 Ermal Luçi
			mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']}/pptp-vpn -p {$g['varrun_path']}/pptp-vpn.pid -f mpd.conf pptpd");
1103 c52719a8 Scott Ullrich
1104 5b237745 Scott Ullrich
			break;
1105 c52719a8 Scott Ullrich
1106 979cd6db Scott Ullrich
		case 'redir' :
1107 5b237745 Scott Ullrich
			break;
1108
	}
1109 c52719a8 Scott Ullrich
1110 a63f7d55 Scott Ullrich
	if ($g['booting'])
1111
		echo "done\n";
1112 c52719a8 Scott Ullrich
1113 5b237745 Scott Ullrich
	return 0;
1114
}
1115
1116 06e69b03 Scott Ullrich
function vpn_pppoe_configure() {
1117
	global $config, $g;
1118
1119
	$syscfg = $config['system'];
1120
	$pppoecfg = $config['pppoe'];
1121
1122 48918ed5 Scott Ullrich
	/* create directory if it does not exist */
1123 67ee1ec5 Ermal Luçi
	if (!is_dir("{$g['varetc_path']}/pppoe-vpn"))
1124
		mkdir("{$g['varetc_path']}/pppoe-vpn");
1125 c52719a8 Scott Ullrich
1126 06e69b03 Scott Ullrich
	if ($g['booting']) {
1127
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1128
			return 0;
1129
1130
		echo "Configuring PPPoE VPN service... ";
1131 979cd6db Scott Ullrich
	} else {
1132
		/* kill mpd */
1133 67ee1ec5 Ermal Luçi
		killbypid("{$g['varrun_path']}/pppoe-vpn.pid");
1134 979cd6db Scott Ullrich
1135
		/* wait for process to die */
1136
		sleep(2);
1137
1138 06e69b03 Scott Ullrich
	}
1139
1140 67ee1ec5 Ermal Luçi
	/* make sure pppoe-vpn directory exists */
1141
	if (!file_exists("{$g['varetc_path']}/pppoe-vpn"))
1142
		mkdir("{$g['varetc_path']}/pppoe-vpn");
1143 06e69b03 Scott Ullrich
1144
	switch ($pppoecfg['mode']) {
1145
1146 979cd6db Scott Ullrich
		case 'server' :
1147 06e69b03 Scott Ullrich
1148 532b0fb8 Ermal Lu?i
			$pppoe_interface = interface_translate_type_to_real($pppoecfg['interface']);
1149 0301deff Scott Ullrich
1150 979cd6db Scott Ullrich
			if ($pppoecfg['paporchap'] == "chap")
1151
				$paporchap = "set link enable chap";
1152
			else
1153
				$paporchap = "set link enable pap";
1154
1155 06e69b03 Scott Ullrich
			/* write mpd.conf */
1156 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/pppoe-vpn/mpd.conf", "w");
1157 06e69b03 Scott Ullrich
			if (!$fd) {
1158
				printf("Error: cannot open mpd.conf in vpn_pppoe_configure().\n");
1159
				return 1;
1160
			}
1161
			$mpdconf = "\n\n";
1162 979cd6db Scott Ullrich
			$mpdconf .=<<<EOD
1163 06e69b03 Scott Ullrich
pppoe:
1164
1165
EOD;
1166
1167 a429d105 Scott Ullrich
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1168 69a779d5 Scott Ullrich
				$mpdconf .= "	load pppoe{$i}\n";
1169 06e69b03 Scott Ullrich
			}
1170
1171 a429d105 Scott Ullrich
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1172 06e69b03 Scott Ullrich
1173
				$clientip = long2ip(ip2long($pppoecfg['remoteip']) + $i);
1174 c52719a8 Scott Ullrich
1175 979cd6db Scott Ullrich
				if (isset ($pppoecfg['radius']['radiusissueips']) && isset ($pppoecfg['radius']['enable'])) {
1176 5dfdc1fb Scott Ullrich
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1177 5264023a Scott Ullrich
				} else {
1178
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1179 5dfdc1fb Scott Ullrich
				}
1180 c52719a8 Scott Ullrich
1181 979cd6db Scott Ullrich
				$mpdconf .=<<<EOD
1182 06e69b03 Scott Ullrich
1183 2991a0d6 Scott Ullrich
pppoe{$i}:
1184 67ee1ec5 Ermal Luçi
	new pppoe{$i} pppoe{$i}
1185 5dfdc1fb Scott Ullrich
	{$isssue_ip_type}
1186 06e69b03 Scott Ullrich
	load pppoe_standart
1187
1188
EOD;
1189
			}
1190
1191 979cd6db Scott Ullrich
			$mpdconf .=<<<EOD
1192 06e69b03 Scott Ullrich
1193
pppoe_standart:
1194 979cd6db Scott Ullrich
	set bundle no multilink
1195
	set bundle enable compression
1196 78155ff9 Scott Ullrich
	set auth max-logins 1
1197 67ee1ec5 Ermal Luçi
	set iface up-script /usr/local/sbin/pppoe-linkup
1198
        set iface down-script /usr/local/sbin/vpn-linkdown
1199 979cd6db Scott Ullrich
	set iface idle 0
1200 06e69b03 Scott Ullrich
	set iface disable on-demand
1201
	set iface disable proxy-arp
1202
	set iface enable tcpmssfix
1203 979cd6db Scott Ullrich
	set iface mtu 1500
1204 06e69b03 Scott Ullrich
	set link no pap chap
1205 979cd6db Scott Ullrich
	{$paporchap}
1206
	set link keep-alive 60 180
1207
	set ipcp yes vjcomp
1208
	set ipcp no vjcomp
1209
	set link max-redial -1
1210
	set link mtu 1492
1211
	set link mru 1492
1212 06e69b03 Scott Ullrich
	set ccp yes mpp-e40
1213
	set ccp yes mpp-e128
1214
	set ccp yes mpp-stateless
1215 979cd6db Scott Ullrich
	set link latency 1
1216
	#set ipcp dns 10.10.1.3
1217
	#set bundle accept encryption
1218 06e69b03 Scott Ullrich
1219 c8c416db Scott Ullrich
EOD;
1220
1221 979cd6db Scott Ullrich
			if (isset ($config['dnsmasq']['enable'])) {
1222 a55e9c70 Ermal Lu?i
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1223 06e69b03 Scott Ullrich
				if ($syscfg['dnsserver'][0])
1224
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1225
				$mpdconf .= "\n";
1226 979cd6db Scott Ullrich
			} else
1227
				if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1228
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1229
				}
1230 07cae4b2 Scott Ullrich
1231 979cd6db Scott Ullrich
			if (isset ($pppoecfg['radius']['enable'])) {
1232
				$mpdconf .=<<<EOD
1233
	set radius server {$pppoecfg['radius']['server']} "{$pppoecfg['radius']['secret']}"
1234 06e69b03 Scott Ullrich
	set radius retries 3
1235 979cd6db Scott Ullrich
	set radius timeout 10
1236 0af9dba4 Ermal Lu?i
	set auth enable radius-auth
1237 06e69b03 Scott Ullrich
1238
EOD;
1239
1240 979cd6db Scott Ullrich
				if (isset ($pppoecfg['radius']['accounting'])) {
1241
					$mpdconf .=<<<EOD
1242 0af9dba4 Ermal Lu?i
	set auth enable radius-acct
1243 07cae4b2 Scott Ullrich
1244 06e69b03 Scott Ullrich
EOD;
1245
				}
1246
			}
1247
1248
			fwrite($fd, $mpdconf);
1249
			fclose($fd);
1250
1251
			/* write mpd.links */
1252 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/pppoe-vpn/mpd.links", "w");
1253 06e69b03 Scott Ullrich
			if (!$fd) {
1254
				printf("Error: cannot open mpd.links in vpn_pppoe_configure().\n");
1255
				return 1;
1256
			}
1257
1258
			$mpdlinks = "";
1259
1260 a429d105 Scott Ullrich
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1261 979cd6db Scott Ullrich
				$mpdlinks .=<<<EOD
1262 67ee1ec5 Ermal Luçi
			
1263 78155ff9 Scott Ullrich
pppoe{$i}:
1264 67ee1ec5 Ermal Luçi
	set phys type pppoe
1265 78155ff9 Scott Ullrich
        set pppoe iface {$pppoe_interface}
1266
        set pppoe service "*"
1267
        set pppoe disable originate
1268
        set pppoe enable incoming
1269 06e69b03 Scott Ullrich
1270
EOD;
1271
			}
1272
1273
			fwrite($fd, $mpdlinks);
1274
			fclose($fd);
1275
1276
			/* write mpd.secret */
1277 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/pppoe-vpn/mpd.secret", "w");
1278 06e69b03 Scott Ullrich
			if (!$fd) {
1279
				printf("Error: cannot open mpd.secret in vpn_pppoe_configure().\n");
1280
				return 1;
1281
			}
1282
1283
			$mpdsecret = "\n\n";
1284
1285
			if (is_array($pppoecfg['user'])) {
1286
				foreach ($pppoecfg['user'] as $user)
1287
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1288
			}
1289
1290
			fwrite($fd, $mpdsecret);
1291
			fclose($fd);
1292 67ee1ec5 Ermal Luçi
			chmod("{$g['varetc_path']}/pppoe-vpn/mpd.secret", 0600);
1293 979cd6db Scott Ullrich
1294
			/* fire up mpd */
1295 67ee1ec5 Ermal Luçi
			mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']}/pppoe-vpn -p {$g['varrun_path']}/pppoe-vpn.pid pppoe");
1296 979cd6db Scott Ullrich
1297
			break;
1298
1299
		case 'redir' :
1300
			break;
1301
	}
1302
1303
	if ($g['booting'])
1304
		echo "done\n";
1305
1306
	return 0;
1307
}
1308
1309
function vpn_l2tp_configure() {
1310
	global $config, $g;
1311
1312
	$syscfg = $config['system'];
1313
	$l2tpcfg = $config['l2tp'];
1314
1315
	/* create directory if it does not exist */
1316 67ee1ec5 Ermal Luçi
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1317
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1318 979cd6db Scott Ullrich
1319
	if ($g['booting']) {
1320
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1321
			return 0;
1322
1323
		echo "Configuring l2tp VPN service... ";
1324
	} else {
1325
		/* kill mpd */
1326 67ee1ec5 Ermal Luçi
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1327 979cd6db Scott Ullrich
1328
		/* wait for process to die */
1329 01c41d40 Ermal Lu?i
		sleep(8);
1330 979cd6db Scott Ullrich
1331
	}
1332
1333 67ee1ec5 Ermal Luçi
	/* make sure l2tp-vpn directory exists */
1334
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1335
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1336 979cd6db Scott Ullrich
1337
	switch ($l2tpcfg['mode']) {
1338
1339
		case 'server' :
1340
			if ($l2tpcfg['paporchap'] == "chap")
1341
				$paporchap = "set link enable chap";
1342
			else
1343
				$paporchap = "set link enable pap";
1344
1345
			/* write mpd.conf */
1346 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1347 979cd6db Scott Ullrich
			if (!$fd) {
1348
				printf("Error: cannot open mpd.conf in vpn_l2tp_configure().\n");
1349
				return 1;
1350
			}
1351
			$mpdconf = "\n\n";
1352
			$mpdconf .=<<<EOD
1353
l2tp:
1354
1355
EOD;
1356
1357
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1358
				$mpdconf .= "	load l2tp{$i}\n";
1359
			}
1360
1361
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1362
1363
				$clientip = long2ip(ip2long($l2tpcfg['remoteip']) + $i);
1364
1365
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1366
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1367
				} else {
1368
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1369
				}
1370
1371
				$mpdconf .=<<<EOD
1372
1373
l2tp{$i}:
1374 67ee1ec5 Ermal Luçi
	new l2tp{$i} l2tp{$i}
1375 979cd6db Scott Ullrich
	{$isssue_ip_type}
1376
	load l2tp_standard
1377
1378
EOD;
1379
			}
1380
1381
			$mpdconf .=<<<EOD
1382
1383
l2tp_standard:
1384
        set bundle disable multilink
1385
        set bundle enable compression
1386
        set bundle yes crypt-reqd
1387
        set ipcp yes vjcomp
1388
        # set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1389
        set ccp yes mppc
1390
        set iface disable on-demand
1391
        set iface enable proxy-arp
1392 67ee1ec5 Ermal Luçi
	set iface up-script /usr/local/sbin/l2tp-linkup
1393
        set iface down-script /usr/local/sbin/vpn-linkdown
1394 979cd6db Scott Ullrich
        set link yes acfcomp protocomp
1395
        set link no pap chap
1396
        set link enable chap
1397
        set link keep-alive 10 180
1398
1399
EOD;
1400
1401
			if (isset ($config['dnsmasq']['enable'])) {
1402 a55e9c70 Ermal Lu?i
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1403 979cd6db Scott Ullrich
				if ($syscfg['dnsserver'][0])
1404
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1405
				$mpdconf .= "\n";
1406
			} else
1407
				if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1408
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1409
				}
1410
1411
			if (isset ($l2tpcfg['radius']['enable'])) {
1412
				$mpdconf .=<<<EOD
1413
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1414
	set radius retries 3
1415
	set radius timeout 10
1416 0af9dba4 Ermal Lu?i
	set auth enable radius-auth
1417 979cd6db Scott Ullrich
1418
EOD;
1419
1420
				if (isset ($l2tpcfg['radius']['accounting'])) {
1421
					$mpdconf .=<<<EOD
1422 0af9dba4 Ermal Lu?i
	set auth enable radius-acct
1423 979cd6db Scott Ullrich
1424
EOD;
1425
				}
1426
			}
1427
1428
			fwrite($fd, $mpdconf);
1429
			fclose($fd);
1430
1431
			/* write mpd.links */
1432 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1433 979cd6db Scott Ullrich
			if (!$fd) {
1434
				printf("Error: cannot open mpd.links in vpn_l2tp_configure().\n");
1435
				return 1;
1436
			}
1437
1438
			$mpdlinks = "";
1439
1440
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1441
				$mpdlinks .=<<<EOD
1442
1443 daa20efd Ermal Lu?i
l2tp{$i}:
1444 979cd6db Scott Ullrich
	set link type l2tp
1445 eff29d62 Ermal Lu?i
        set l2tp enable incoming
1446
        set l2tp disable originate
1447 979cd6db Scott Ullrich
1448
EOD;
1449 00f9e567 Ermal Lu?i
			if (!empty($l2tpcfg['secret']))
1450
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1451 979cd6db Scott Ullrich
			}
1452
1453
			fwrite($fd, $mpdlinks);
1454
			fclose($fd);
1455
1456
			/* write mpd.secret */
1457 67ee1ec5 Ermal Luçi
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1458 979cd6db Scott Ullrich
			if (!$fd) {
1459
				printf("Error: cannot open mpd.secret in vpn_l2tp_configure().\n");
1460
				return 1;
1461
			}
1462
1463
			$mpdsecret = "\n\n";
1464
1465
			if (is_array($l2tpcfg['user'])) {
1466
				foreach ($l2tpcfg['user'] as $user)
1467
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1468
			}
1469
1470
			fwrite($fd, $mpdsecret);
1471
			fclose($fd);
1472 67ee1ec5 Ermal Luçi
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1473 06e69b03 Scott Ullrich
1474
			/* fire up mpd */
1475 67ee1ec5 Ermal Luçi
			mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']}/l2tp-vpn -p {$g['varrun_path']}/l2tp-vpn.pid l2tp");
1476 06e69b03 Scott Ullrich
1477
			break;
1478
1479 979cd6db Scott Ullrich
		case 'redir' :
1480 06e69b03 Scott Ullrich
			break;
1481
	}
1482
1483
	if ($g['booting'])
1484
		echo "done\n";
1485
1486
	return 0;
1487
}
1488 630cfa6c Scott Ullrich
1489 c60cae98 Seth Mos
/* Walk the tunnels for hostname endpoints. If the hostnames 
1490
 * resolve to a different IP now compared to the DNS cache
1491
 * we reload the policies if the endpoint has changed */
1492
function vpn_ipsec_refresh_policies() {
1493
	global $config;
1494
	global $g;
1495
1496
	$ipseccfg = $config['ipsec'];
1497 9f14066f Seth Mos
	$a_phase1 = $config['ipsec']['phase1'];
1498
	$a_phase2 = $config['ipsec']['phase2'];
1499 c60cae98 Seth Mos
1500 9f14066f Seth Mos
	if (isset($ipseccfg['disable'])) {
1501 c60cae98 Seth Mos
		return true;
1502
	}
1503
1504
	/* Walk the Ipsec tunnel array */
1505 9f14066f Seth Mos
	if (!is_array($a_phase1) || (!count($a_phase1))) {
1506 eb9ae6bb Bill Marquette
		return;
1507 9f14066f Seth Mos
	}
1508 c60cae98 Seth Mos
1509 9f14066f Seth Mos
	foreach ($a_phase1 as $phase1) {
1510
		if (isset($phase1['disabled'])) {
1511
			continue;
1512
		}
1513
		if (is_ipaddr($phase1['remote-gateway'])) {
1514
			continue;
1515
		}
1516
		if (!is_ipaddr($phase1['remote-gateway'])) {
1517
			$dnscache = compare_hostname_to_dnscache($phase1['remote-gateway']);
1518
			$dnscache = trim($dnscache);
1519
			/* we should have the old IP addresses in the dnscache now */
1520
			if($dnscache <> "") {
1521
				$oldphase1 = $phase1;
1522
				$oldphase1['remote-gateway'] = trim($dnscache);
1523
				/* now we need to find all tunnels for this host */
1524
				if (!is_array($a_phase2) || (!count($a_phase2))) {
1525
					continue;
1526
				}
1527
				foreach ($a_phase2 as $phase2) {
1528
					if($phase2['ikeid'] == $phase1['ikeid']) {
1529
						reload_tunnel_spd_policy ($phase1, $phase2, $oldphase1, $oldphase2);
1530
					}
1531 c60cae98 Seth Mos
				}
1532
			}
1533
		}
1534
	}
1535
1536 1d69f52f Seth Mos
	/* process all generated spd.conf files from tmp which are left behind
1537
	 * behind by either changes of dynamic tunnels or manual edits
1538
	 * scandir() is only available in PHP5 */
1539
	$tmpfiles = array();
1540
	$dh  = opendir($g['tmp_path']);
1541
	while (false !== ($filename = readdir($dh))) {
1542 8d534565 Seth Mos
		if(preg_match("/^spd.conf.reload./", $tmpfile)) {
1543
			$tmpfiles[] = $filename;
1544
		}
1545 1d69f52f Seth Mos
	}
1546
	sort($tmpfiles);
1547
	foreach($tmpfiles as $tmpfile) {
1548 8d534565 Seth Mos
		$ret = mwexec("/usr/local/sbin/setkey -f {$g['tmp_path']}/{$tmpfile} 2>&1", false);
1549
		if($ret == 0) {
1550
			unlink_if_exists("{$g['tmp_path']}/{$tmpfile}");
1551
		} else {
1552
			rename("{$g['tmp_path']}/{$tmpfile}", ("{$g['tmp_path']}/failed.{$tmpfile}"));
1553 1d69f52f Seth Mos
		}
1554
	}
1555 c60cae98 Seth Mos
}
1556
1557
/* reloads the tunnel configuration for a tunnel item
1558
 * Will remove and add SPD polices */
1559 9f14066f Seth Mos
function reload_tunnel_spd_policy($phase1, $phase2, $old_phase1, $old_phase2) {
1560 c60cae98 Seth Mos
	global $config;
1561
	global $g;
1562
1563 1d69f52f Seth Mos
	/* if we are not passed a old tunnel array we create one */
1564 9f14066f Seth Mos
	if(empty($old_phase1)) {
1565
		$old_phase1 = $phase1;
1566
	}
1567
	if(empty($old_phase2)) {
1568
		$old_phase2 = $phase2;
1569 1d69f52f Seth Mos
	}
1570
1571 9f14066f Seth Mos
	$sad_arr = ipsec_dump_sad();
1572 1d69f52f Seth Mos
1573 9f14066f Seth Mos
	$ep = ipsec_get_phase1_src($phase1);
1574
	$local_subnet = ipsec_idinfo_to_cidr($phase2['localid']);
1575
	$remote_subnet = ipsec_idinfo_to_cidr($phase2['remoteid']);
1576 c60cae98 Seth Mos
1577 1d69f52f Seth Mos
	/* make sure we pass the oldtunnel array with a IP for the remote gw */
1578 9f14066f Seth Mos
	$old_gw = trim($old_phase1['remote-gateway']);
1579
1580
	$old_ep = ipsec_get_phase1_src($old_phase1);
1581
	$old_local_subnet = ipsec_idinfo_to_cidr($old_phase2['localid']);
1582
	$old_remote_subnet = ipsec_idinfo_to_cidr($old_phase2['remoteid']);
1583 1d69f52f Seth Mos
1584 c60cae98 Seth Mos
	/* see if this tunnel has a hostname for the remote-gateway, and if so,
1585
	 * try to resolve it now and add it to the list for dnswatch */
1586 9f14066f Seth Mos
	if (!is_ipaddr($phase1['remote-gateway'])) {
1587
		$rgip = resolve_retry($phase1['remote-gateway']);
1588
		add_hostname_to_watch($phase1['remote-gateway']);
1589 c60cae98 Seth Mos
		if (!$rgip) {
1590 9f14066f Seth Mos
			log_error("Could not determine VPN endpoint for '{$phase1['descr']}'");
1591 c60cae98 Seth Mos
			return false;
1592
		}
1593
	} else {
1594 9f14066f Seth Mos
		$rgip = $phase1['remote-gateway'];
1595 c60cae98 Seth Mos
	}
1596
	if (!$ep) {
1597 9f14066f Seth Mos
		log_error("Could not determine VPN endpoint for '{$phase1['descr']}'");
1598 c60cae98 Seth Mos
		return false;
1599
	}
1600
1601 287e0c9d Seth Mos
	if((!is_ipaddr($old_ep)) || (! is_ipaddr($ep))) {
1602
		log_error("IPSEC: ERROR: One of the endpoints is not a IP address. Old EP '{$old_ep}' new EP '{$ep}'");
1603
	}
1604
	if((! is_ipaddr($rgip)) || (! is_ipaddr($old_gw))) {
1605
		log_error("IPSEC: ERROR: One of the remote endpoints is not a IP address. Old RG '{$old_gw}' new RG '{$rgip}'");
1606 bd6af475 Seth Mos
	}
1607 1d69f52f Seth Mos
1608 bd6af475 Seth Mos
	$spdconf = "";
1609 1d69f52f Seth Mos
	/* Delete old SPD policies if there are changes between the old and new */
1610 9f14066f Seth Mos
	if(($phase1 != $old_phase1) || ($phase2 != $old_phase2)) {
1611
		$spdconf .= "spddelete {$old_local_subnet} " .
1612
			"{$old_remote_subnet} any -P out ipsec " .
1613
			"{$old_phase2['protocol']}/tunnel/{$old_ep}-" .
1614
			"{$old_gw}/unique;\n";
1615
		$spdconf .= "spddelete {$old_remote_subnet} " .
1616
			"{$old_local_subnet} any -P in ipsec " .
1617
			"{$old_phase2['protocol']}/tunnel/{$old_gw}-" .
1618
			"{$old_ep}/unique;\n";
1619 1d69f52f Seth Mos
1620
		/* zap any existing SA entries */
1621 c60cae98 Seth Mos
		foreach($sad_arr as $sad) {
1622 9f14066f Seth Mos
			if(($sad['dst'] == $old_ep) && ($sad['src'] == $old_gw)) {
1623
				$spdconf .= "delete {$old_ep} {$old_gw} {$old_phase2['protocol']} 0x{$sad['spi']};\n";
1624 c60cae98 Seth Mos
			}
1625 9f14066f Seth Mos
			if(($sad['src'] == $oldep) && ($sad['dst'] == $old_gw)) {
1626
				$spdconf .= "delete {$old_gw} {$old_ep} {$old_phase2['protocol']} 0x{$sad['spi']};\n";
1627 c60cae98 Seth Mos
			}
1628
		}
1629
	}
1630 1d69f52f Seth Mos
1631
	/* Create new SPD entries for the new configuration */
1632
	/* zap any existing SA entries beforehand */
1633 c60cae98 Seth Mos
	foreach($sad_arr as $sad) {
1634 1d69f52f Seth Mos
		if(($sad['dst'] == $ep) && ($sad['src'] == $rgip)) {
1635 9f14066f Seth Mos
			$spdconf .= "delete {$rgip} {$ep} {$phase2['protocol']} 0x{$sad['spi']};\n";
1636 c60cae98 Seth Mos
		}
1637 1d69f52f Seth Mos
		if(($sad['src'] == $ep) && ($sad['dst'] == $rgip)) {
1638 9f14066f Seth Mos
			$spdconf .= "delete {$ep} {$rgip} {$phase2['protocol']} 0x{$sad['spi']};\n";
1639 c60cae98 Seth Mos
		}
1640
	}
1641
	/* add new SPD policies to replace them */
1642 9f14066f Seth Mos
	$spdconf .= "spdadd {$local_subnet} " .
1643
		"{$remote_subnet} any -P out ipsec " .
1644
		"{$phase2['protocol']}/tunnel/{$ep}-" .
1645 1d69f52f Seth Mos
		"{$rgip}/unique;\n";
1646 9f14066f Seth Mos
	$spdconf .= "spdadd {$remote_subnet} " .
1647
		"{$local_subnet} any -P in ipsec " .
1648
		"{$phase2['protocol']}/tunnel/{$rgip}-" .
1649 c60cae98 Seth Mos
		"{$ep}/unique;\n";
1650
1651 70bf5abe Seth Mos
	log_error("Reloading IPsec tunnel '{$phase1['descr']}'. Previous IP '{$old_gw}', current IP '{$rgip}'. Reloading policy");
1652 1d69f52f Seth Mos
1653
	$now = time();
1654
	$spdfile = tempnam("{$g['tmp_path']}", "spd.conf.reload.{$now}.");
1655 c60cae98 Seth Mos
	/* generate temporary spd.conf */
1656 1d69f52f Seth Mos
	file_put_contents($spdfile, $spdconf);
1657 c60cae98 Seth Mos
	return true;
1658
}
1659
1660 72bd8df5 Ermal Lu?i
?>