Project

General

Profile

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