Project

General

Profile

Download (37.9 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2

    
3
/*
4
	vpn.inc
5
	Copyright (C) 2004 Scott Ullrich
6
	Copyright (C) 2008 Shrew Soft Inc
7
	Copyright (C) 2008 Ermal Lu?i
8
	All rights reserved.
9

    
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
	Redistribution and use in source and binary forms, with or without
15
	modification, are permitted provided that the following conditions are met:
16

    
17
	1. Redistributions of source code must retain the above copyright notice,
18
	   this list of conditions and the following disclaimer.
19

    
20
	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

    
24
	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

    
36
/* include all configuration functions */
37
require_once ("functions.inc");
38

    
39
function vpn_ipsec_failover_configure() {
40
	global $config, $g;
41

    
42
	$sasyncd_text = "";
43

    
44
	if ($config['installedpackages']['sasyncd'] <> "")
45
		foreach ($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
46
			$enabled = isset ($sasyncd['enable']);
47
			if (!$enabled)
48
				return;
49
			if ($sasyncd['peerip'] <> "")
50
				$sasyncd_text .= "peer {$sasyncd['peerip']}\n";
51
			if ($sasyncd['interface'])
52
				$sasyncd_text .= "carp interface {$sasyncd['interface']}\n";
53
			if ($sasyncd['sharedkey'] <> "")
54
				$sasyncd_text .= "sharedkey {$sasyncd['sharedkey']}\n";
55
			if ($sasyncd['mode'] <> "")
56
				$sasyncd_text .= "mode {$sasyncd['mode']}\n";
57
			if ($sasyncd['listenon'] <> "")
58
				$sasyncd_text .= "listen on {$sasyncd['listenon']}\n";
59
			if ($sasyncd['flushmodesync'] <> "")
60
				$sasyncd_text .= "flushmode sync {$sasyncd['flushmodesync']}\n";
61
		}
62

    
63
	$fd = fopen("{$g['varetc_path']}/sasyncd.conf", "w");
64
	fwrite($fd, $sasyncd_text);
65
	fclose($fd);
66
	chmod("{$g['varetc_path']}/sasyncd.conf", 0600);
67

    
68
	mwexec("killall sasyncd", true);
69

    
70
	/* launch sasyncd, oh wise one */
71
	mwexec_bg("/usr/local/sbin/sasyncd -d -v -v -v");
72
}
73

    
74
function find_last_gif_device() {
75
	$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
}
90

    
91
function vpn_ipsec_configure($ipchg = false)
92
{
93
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos;
94

    
95
	mwexec("/sbin/ifconfig enc0 up");
96

    
97
	/* get the automatic /etc/ping_hosts.sh ready */
98
	unlink_if_exists("/var/db/ipsecpinghosts");
99
	touch("/var/db/ipsecpinghosts");
100

    
101
	if ($g['booting'] == true) {
102
		/* determine if we should load the via padlock module */
103
		$dmesg_boot = `/usr/bin/grep CPU {$g['varlog_path']}/dmesg.boot`;
104
		if (stristr($dmesg_boot, "ACE") == true) {
105
			//echo "Enabling [VIA Padlock] ...";
106
			//mwexec("/sbin/kldload padlock");
107
			//mwexec("/sbin/sysctl net.inet.ipsec.crypto_support=1");
108
			//mwexec("/usr/local/sbin/setkey -F");
109
			//mwexec("/usr/local/sbin/setkey -FP");
110
			//echo " done.\n";
111
		}
112
	}
113

    
114
	if(isset($config['ipsec']['preferredoldsa']))
115
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
116
	else
117
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
118

    
119
	$number_of_gifs = find_last_gif_device();
120
	for ($x = 0; $x < $number_of_gifs; $x++)
121
		mwexec("/sbin/ifconfig gif" . $x . " delete");
122

    
123
	$curwanip = get_interface_ip();
124

    
125
	$syscfg = $config['system'];
126
	$ipseccfg = $config['ipsec'];
127
	$a_phase1 = $config['ipsec']['phase1'];
128
	$a_phase2 = $config['ipsec']['phase2'];
129
	$a_client = $config['ipsec']['client'];
130
	$lancfg = $config['interfaces']['lan'];
131
	$lanip = $lancfg['ipaddr'];
132
	$lansa = gen_subnet($lancfg['ipaddr'], $lancfg['subnet']);
133
	$lansn = $lancfg['subnet'];
134

    
135
	if (!isset($ipseccfg['enable'])) {
136
		mwexec("/sbin/ifconfig enc0 down");
137
		mwexec("/sbin/ifconfig enc0 destroy");
138

    
139
		/* kill racoon */
140
		mwexec("/usr/bin/killall racoon", true);
141
		killbypid("{$g['varrun_path']}/dnswatch-ipsec.pid");
142
		
143
		/* wait for racoon process to die */
144
		sleep(2);
145

    
146
		/* send a SIGKILL to be sure */
147
		sigkillbypid("{$g['varrun_path']}/racoon.pid", "KILL");
148

    
149
		/* flush SPD and SAD */
150
		mwexec("/usr/local/sbin/setkey -FP");
151
		mwexec("/usr/local/sbin/setkey -F");
152

    
153
		return true;
154
	}
155

    
156
	if ($g['booting'])
157
		echo "Configuring IPsec VPN... ";
158

    
159
	if (isset ($ipseccfg['enable'])) {
160
		/* fastforwarding is not compatible with ipsec tunnels */
161
		mwexec("/sbin/sysctl net.inet.ip.fastforwarding=0");
162

    
163
		if (!$curwanip) {
164
			/* IP address not configured yet, exit */
165
			if ($g['booting'])
166
				echo "done\n";
167
			return 0;
168
		}
169

    
170
		/* this loads a route table which is used to determine if a route needs to be removed. */
171
		exec("/usr/bin/netstat -rn", $route_arr, $retval);
172
		$route_str = implode("\n", $route_arr);
173

    
174
		/* resolve all local, peer addresses and setup pings */
175
		$ipmap = array();
176
		$rgmap = array();
177
		$dnswatch_list = array();
178
		if (is_array($a_phase1) && count($a_phase1)) {
179
			foreach ($a_phase1 as $ph1ent) {
180
				if (isset($ph1ent['disabled']))
181
					continue;
182

    
183
				$ep = ipsec_get_phase1_src($ph1ent);
184
				if (!$ep)
185
					continue;
186

    
187
				if(!in_array($ep,$ipmap))
188
					$ipmap[] = $ep;
189

    
190
				/* see if this tunnel has a hostname for the remote-gateway. If so,
191
				   try to resolve it now and add it to the list for dnswatch */
192

    
193
				if (isset ($ph1ent['mobile']))
194
					continue;
195

    
196
				$rg = $ph1ent['remote-gateway'];
197

    
198
				if (!is_ipaddr($rg)) {
199
					$dnswatch_list[] = $rg;
200
					$rg = resolve_retry($rg);
201
					if (!$rg)
202
						continue;
203
				}
204

    
205
				$rgmap[$ph1ent['remote-gateway']] = $rg;
206

    
207
				/* add an ipsec pinghosts entry */
208

    
209
				if ($ph1ent['pinghost']) {
210
					$pfd = fopen("/var/db/ipsecpinghosts", "a");
211
					$iflist = get_configured_interface_list();
212
					foreach ($iflist as $ifent => $ifname) {
213
						$interface_ip = find_interface_ip($config['interfaces'][$ifname]['if']);
214
						if (ip_in_subnet($interface_ip, $sa . "/" . $sn))
215
						$srcip = find_interface_ip($config['interfaces'][$ifname]['if']);
216
					}
217
					$dstip = $ph1ent['pinghost'];
218
					fwrite($pfd, "$srcip|$dstip|3\n");
219
					fclose($pfd);
220
				}
221
			}
222
		}
223

    
224
		/* generate CA certificates files */
225
		$cacertnum = 0;
226
		if (is_array($ipseccfg['cacert']) && count($ipseccfg['cacert'])) {
227
			foreach ($ipseccfg['cacert'] as $cacert) {
228
				++ $cacertnum;
229
				if (isset ($cacert['cert'])) {
230
					$cert = base64_decode($cacert['cert']);
231
					$x509cert = openssl_x509_parse(openssl_x509_read($cert));
232
					if (is_array($x509cert) && isset ($x509cert['hash'])) {
233
						$fd1 = fopen("{$g['varetc_path']}/{$x509cert['hash']}.0", "w");
234
						if (!$fd1) {
235
							printf("Error: cannot open {$x509cert['hash']}.0 in vpn.\n");
236
							return 1;
237
						}
238
						chmod("{$g['varetc_path']}/{$x509cert['hash']}.0", 0600);
239
						fwrite($fd1, $cert);
240
						fclose($fd1);
241
					}
242
				}
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

    
255
		if (is_array($a_phase1) && count($a_phase1)) {
256
			foreach ($a_phase1 as $ph1ent) {
257

    
258
				if (isset($ph1ent['disabled']))
259
					continue;
260

    
261
				if (strstr($ph1ent['authentication_method'],'rsa'))
262
					continue;
263

    
264
				$peerid_type = $ph1ent['peerid_type'];
265

    
266
				switch ($peerid_type) {
267
					case "peeraddress":
268
						$peerid_type = "address";
269
						$peerid_data = $rgmap[$ph1ent['remote-gateway']];
270
						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
				}
282

    
283
				$pskconf .= "{$peerid_data}\t{$ph1ent['pre-shared-key']}\n";
284
			}
285
		}
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

    
295
			$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

    
301
			$racoonconf = "";
302

    
303
			$racoonconf .= "path pre_shared_key \"{$g['varetc_path']}/psk.txt\";\n\n";
304
			$racoonconf .= "path certificate  \"{$g['varetc_path']}\";\n\n";
305

    
306
			/* begin listen section */
307
			if (count($ipmap)) {
308
				$racoonconf .= "\nlisten\n";
309
				$racoonconf .= "{\n";
310
				foreach ($ipmap as $addr) {
311
					$racoonconf .= "\tisakmp {$addr} [500];\n";
312
					$racoonconf .= "\tisakmp_natt {$addr} [4500];\n";
313
				}
314
				$racoonconf .= "}\n\n";
315
			}
316

    
317
			/* 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
			/* begin remote sections */
402
			if (is_array($a_phase1) && count($a_phase1)) {
403
				/* begin remote */
404
				foreach ($a_phase1 as $ph1ent) {
405

    
406
					if (isset($ph1ent['disabled']))
407
						continue;
408

    
409
					if (isset($ph1ent['mobile']) && !isset($a_client['enable']))
410
						continue;
411

    
412
					$ikeid = $ph1ent['ikeid'];
413

    
414
					$ep = ipsec_get_phase1_src($ph1ent);
415
					if (!$ep)
416
						continue;
417

    
418
					if (!isset($ph1ent['mobile'])) {
419
						$rgip = $rgmap[$ph1ent['remote-gateway']];
420
						if (!$rgip)
421
							continue;
422
					}
423

    
424
					$myid_type = $ph1ent['myid_type'];
425

    
426
					switch ($myid_type) {
427

    
428
						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

    
437
						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
					}
450

    
451
					$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
					}
472

    
473
					$natt = "off";
474
					if (isset($ph1ent['nat_traversal']))
475
						$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

    
492
					if (isset ($ph1ent['authentication_method']))
493
						$authmethod = $ph1ent['authentication_method'];
494
					else
495
						$authmethod = 'pre_shared_key';
496

    
497
					$certline = '';
498

    
499
					if (strstr($authmethod,'rsa')) {
500
						if ($ph1ent['cert'] && $ph1ent['private-key']) {
501
							$cert = base64_decode($ph1ent['cert']);
502
							$private_key = base64_decode($ph1ent['private-key']);
503
						} else {
504
							/* null certificate/key */
505
							$cert = '';
506
							$private_key = '';
507
						}
508

    
509
						if ($ph1ent['peercert'])
510
							$peercert = base64_decode($ph1ent['peercert']);
511
						else
512
							$peercert = '';
513

    
514
						$fd1 = fopen("{$g['varetc_path']}/server{$ikeid}-signed.pem", "w");
515
						if (!$fd1) {
516
							printf("Error: cannot open server{$ikeid}-signed.pem in vpn.\n");
517
							return 1;
518
						}
519
						
520
						chmod("{$g['varetc_path']}/server{$ikeid}-signed.pem", 0600);
521
						fwrite($fd1, $cert);
522
						fclose($fd1);
523

    
524
						$fd1 = fopen("{$g['varetc_path']}/server{$ikeid}-key.pem", "w");
525
						if (!$fd1) {
526
							printf("Error: cannot open server{$ikeid}-key.pem in vpn.\n");
527
							return 1;
528
						}
529
						chmod("{$g['varetc_path']}/server{$ikeid}-key.pem", 0600);
530
						fwrite($fd1, $private_key);
531
						fclose($fd1);
532

    
533
						$certline = "certificate_type x509 \"server{$ikeid}-signed.pem\" \"server{$ikeid}-key.pem\";";
534

    
535
						if ($peercert != '') {
536
							$fd1 = fopen("{$g['varetc_path']}/peer{$ikeid}-signed.pem", "w");
537
							if (!$fd1) {
538
								printf("Error: cannot open server{$ikeid}-signed.pem in vpn.\n");
539
								return 1;
540
							}
541
							chmod("{$g['varetc_path']}/peer{$ikeid}-signed.pem", 0600);
542
							fwrite($fd1, $peercert);
543
							fclose($fd1);
544
							$certline .="peers_certfile \"peer{$ikeid}-signed.pem\"";
545
						}
546
					}
547

    
548
					$ealgos = '';
549
					$ealg_id = $ph1ent['encryption-algorithm']['name'];
550
					$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
551
					if ($ealg_kl)
552
						$ealgos = $ealgos.$ealg_id." ".$ealg_kl;
553
					else
554
						$ealgos = $ealgos.$ealg_id;
555

    
556
					$lifeline = '';
557
					if ($ph1ent['lifetime'])
558
						$lifeline = "lifetime time {$ph1ent['lifetime']} secs;";
559

    
560
					/* add remote section to configuration */
561

    
562
					$racoonconf .=<<<EOD
563

    
564
remote {$rgip}
565
{
566
	ph1id {$ikeid};
567
	exchange_mode {$ph1ent['mode']};
568
	my_identifier {$myid_type} {$myid_data};
569
	peers_identifier {$peerid_type} {$peerid_data};
570
	ike_frag on;
571
	generate_policy = {$genp};
572
	initial_contact = {$init};
573
	nat_traversal = {$natt};
574
	{$certline}
575
	{$dpdline1}
576
	{$dpdline2}
577
	support_proxy on;
578
	proposal_check claim;
579

    
580
	proposal
581
	{
582
		authentication_method {$authmethod};
583
		encryption_algorithm ${ealgos};
584
		hash_algorithm {$ph1ent['hash-algorithm']};
585
		dh_group {$ph1ent['dhgroup']};
586
		${lifeline}
587
	}
588
}
589

    
590
EOD;
591
				}
592
				/* end remote */
593
			}
594
			/* end remote sections */
595
		
596
			/* begin sainfo sections */
597
			if (is_array($a_phase2) && count($a_phase2)) {
598

    
599
				/* begin sainfo */
600
				foreach ($a_phase2 as $ph2ent) {
601

    
602
					$ikeid = $ph2ent['ikeid'];
603

    
604
					if (isset($ph2ent['disabled']))
605
						continue;
606

    
607
					if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
608
						continue;
609

    
610
					$localid_type = $ph2ent['localid']['type'];
611
					if ($localid_type != "address")
612
						$localid_type = "subnet";
613

    
614
					$localid_data = ipsec_idinfo_to_cidr($ph2ent['localid']);
615
					$localid_spec = $localid_type." ".$localid_data." any";
616

    
617
					if (!isset($ph2ent['mobile'])) {
618

    
619
						$remoteid_type = $ph2ent['remoteid']['type'];
620
						if ($remoteid_type != "address")
621
							$remoteid_type = "subnet";
622

    
623
						$remoteid_data = ipsec_idinfo_to_cidr($ph2ent['remoteid']);
624
						$remoteid_spec = $remoteid_type." ".$remoteid_data." any";
625

    
626
					} else
627
						$remoteid_spec = "anonymous";
628

    
629
					$ealgos = '';
630
					$halgos = join(",", $ph2ent['hash-algorithm-option']);
631

    
632
					$pfsline = '';
633
					if ($ph2ent['pfsgroup'])
634
						$pfsline = "pfs_group {$ph2ent['pfsgroup']};";
635
					if (isset($a_client['pfs_group'])) {
636
						$pfsline = '';
637
						if ($a_client['pfs_group'])
638
							$pfsline = "pfs_group {$a_client['pfs_group']};";
639
					}
640

    
641
					$lifeline = '';
642
					if ($ph2ent['lifetime'])
643
						$lifeline = "lifetime time {$ph2ent['lifetime']} secs;";
644

    
645
					foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
646

    
647
						$ealg_id = $ealg['name'];
648
						$ealg_kl = $ealg['keylen'];
649

    
650
						if ($ealg_kl) {
651
							if( $ealg_kl == "auto" ) {
652
								$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
653
								$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
654
								$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
655

    
656
								for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
657
									if( $ealgos )
658
										$ealgos = $ealgos.", ";
659
									$ealgos = $ealgos.$ealg_id." ".$keylen;
660
								}
661
							} else {
662
								if ($ealgos)
663
									$ealgos = $ealgos.", ";
664
								$ealgos = $ealgos.$ealg_id." ".$ealg_kl;
665
							}
666
						} else {
667
							if ($ealgos)
668
								$ealgos = $ealgos.", ";
669
							$ealgos = $ealgos.$ealg_id;
670
						}
671
					}
672

    
673
					/* add sainfo section to configuration */
674
					
675
					$racoonconf .=<<<EOD
676
					
677
sainfo {$localid_spec} {$remoteid_spec}
678
{
679
	remoteid {$ikeid};
680
	encryption_algorithm {$ealgos};
681
	authentication_algorithm {$halgos};
682
	compression_algorithm deflate;
683
	{$pfsline}
684
	{$lifeline}
685
}
686

    
687
EOD;
688
				}
689
				/* end sainfo */
690
			}
691
			/* end sainfo sections */
692

    
693
			fwrite($fd, $racoonconf);
694
			fclose($fd);
695
		}
696
		/* end racoon.conf */
697

    
698
		/* generate IPsec policies */
699
		if (is_array($a_phase2) && count($a_phase2)) {
700
			/* generate spd.conf */
701
			$fd = fopen("{$g['varetc_path']}/spd.conf", "w");
702
			if (!$fd) {
703
				printf("Error: cannot open spd.conf in vpn_ipsec_configure().\n");
704
				return 1;
705
			}
706

    
707
			$spdconf = "";
708

    
709
			/* What are these SPD entries for?
710
			 * -mgrooms 07/10/2008
711
			 */
712
			$spdconf .= "spdadd {$lanip}/32 {$lansa}/{$lansn} any -P out none;\n";
713
			$spdconf .= "spdadd {$lansa}/{$lansn} {$lanip}/32 any -P in none;\n";
714

    
715
			foreach ($a_phase2 as $ph2ent) {
716

    
717
				if( !ipsec_lookup_phase1($ph2ent,$ph1ent))
718
					continue;
719

    
720
				if (isset($ph1ent['mobile']))
721
					continue;
722

    
723
				if (isset($ph1ent['disabled']))
724
					continue;
725

    
726
				if (isset($ph2ent['disabled']))
727
					continue;
728

    
729
				$ep = ipsec_get_phase1_src($ph1ent);
730
				if (!$ep)
731
					continue;
732

    
733
				$rgip = $rgmap[$ph1ent['remote-gateway']];
734

    
735
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'],true);
736
				$remoteid = ipsec_idinfo_to_cidr($ph2ent['remoteid'],true);
737

    
738
				if (isset ($ph2ent['creategif'])) {
739
					$number_of_gifs = find_last_gif_device();
740
					$number_of_gifs++;
741
					$curwanip = get_interface_ip();
742
					if ($config['installedpackages']['sasyncd']['config'] <> "") {
743
						foreach ($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
744
							if ($sasyncd['ip'] <> "")
745
								$curwanip = $sasyncd['ip'];
746
						}
747
					}
748
					mwexec("/sbin/ifconfig gif" . $number_of_gifs . " tunnel" . $curwanip . " " . $rgip);
749
					mwexec("/sbin/ifconfig gif" . $number_of_gifs . " {$lansa}/{$lansn} {$lanip}/32");
750
				}
751

    
752
				$spdconf .= "spdadd {$localid} {$remoteid} any -P out ipsec " .
753
					"{$ph2ent['protocol']}/tunnel/{$ep}-{$rgip}/unique;\n";
754

    
755
				$spdconf .= "spdadd {$remoteid} {$localid} any -P in ipsec " .
756
					"{$ph2ent['protocol']}/tunnel/{$rgip}-{$ep}/unique;\n";
757

    
758
				/* static route needed? */
759
				if (preg_match("/^carp/i", $ph1ent['interface']))
760
					$parentinterface = link_carp_interface_to_parent($ph1ent['interface']);
761
				else
762
					$parentinterface = $ph1ent['interface'];
763

    
764
				if ($parentinterface <> "wan") {
765
					/* add endpoint routes to correct gateway on interface */
766
					if (interface_has_gateway($parentinterface)) {
767
						$gatewayip = get_interface_gateway("$parentinterface");
768
						$interfaceip = $config['interfaces'][$parentinterface]['ipaddr'];
769
						$subnet_bits = $config['interfaces'][$parentinterface]['subnet'];
770
						$subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
771
						/* if the remote gateway is in the local subnet, then don't add a route */
772
						if (! ip_in_subnet($rgip, "{$subnet_ip}/{$subnet_bits}")) {
773
							if(is_ipaddr($gatewayip)) {
774
								log_error("IPSEC interface is not WAN but {$parentinterface}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
775
								mwexec("/sbin/route delete -host {$rgip}");
776
								mwexec("/sbin/route add -host {$rgip} {$gatewayip}");
777
							}
778
						}
779
					}
780
				}
781
				else
782
				{
783
					if(stristr($route_str, "/{$rgip}/")) {
784
						mwexec("/sbin/route delete -host {$rgip}");
785
					}
786
				}
787
			}
788

    
789
			fwrite($fd, $spdconf);
790
			fclose($fd);
791
		}
792

    
793
		/* needed for racoonctl admin socket */
794
		if (!file_exists("/var/db/racoon"))
795
			mkdir("/var/db/racoon/");
796
		
797
		/* mange racoon process */
798
		if (is_process_running("racoon")) {
799
			/* We are already online, reload */
800
			mwexec("/usr/bin/killall -HUP racoon", true);
801
			/* flush SPD entries */
802
			mwexec("/usr/local/sbin/setkey -FP");
803
			mwexec("/usr/local/sbin/setkey -F");
804
			/* load SPD */
805
			mwexec("/usr/local/sbin/setkey -f {$g['varetc_path']}/spd.conf");
806
			/* We are already online, reload */
807
			mwexec("/usr/bin/killall -HUP racoon", true);
808
		} else {
809
			/* start racoon */
810
			mwexec("/usr/local/sbin/racoon -f {$g['varetc_path']}/racoon.conf");
811
			/* flush SA + SPD entries */
812
			mwexec("/usr/local/sbin/setkey -FP");
813
			mwexec("/usr/local/sbin/setkey -F");
814
			/* load SPD */
815
			mwexec("/usr/local/sbin/setkey -f {$g['varetc_path']}/spd.conf");
816
			/* We are already online, reload */
817
			mwexec("/usr/bin/killall -HUP racoon", true);
818

    
819
			/* start dnswatch, if necessary */
820
			if (count($dnswatch_list) > 0) {
821
				$interval = 60;
822
				if ($ipseccfg['dns-interval'])
823
					$interval = $ipseccfg['dns-interval'];
824

    
825
				$hostnames = "";
826
				foreach ($dnswatch_list as $dns)
827
					$hostnames .= " " . escapeshellarg($dns);
828

    
829
				mwexec("/usr/local/bin/dnswatch {$g['varrun_path']}/dnswatch-ipsec.pid $interval " .
830
				escapeshellarg("/etc/rc.newipsecdns") . $hostname);
831
			}
832
		}
833
	}
834
	
835
	vpn_ipsec_failover_configure();
836

    
837
	if (!$g['booting']) {
838
		/* reload the filter */
839
		touch("{$g["tmp_path"]}/filter_dirty");
840
	}
841

    
842
	if ($g['booting'])
843
		echo "done\n";
844

    
845
	return 0;
846
}
847

    
848
/* Forcefully restart IPsec
849
 * This is required for when dynamic interfaces reload
850
 * For all other occasions the normal vpn_ipsec_configure()
851
 * will gracefully reload the settings without restarting
852
 */
853
function vpn_ipsec_force_reload() {
854
	global $config;
855
	global $g;
856

    
857
	$ipseccfg = $config['ipsec'];
858

    
859
	/* kill racoon */
860
	mwexec("/usr/bin/killall racoon", true);
861

    
862
	/* wait for process to die */
863
	sleep(4);
864

    
865
	/* send a SIGKILL to be sure */
866
	sigkillbypid("{$g['varrun_path']}/racoon.pid", "KILL");
867

    
868
	/* wait for flushing to finish */
869
	sleep(1);
870

    
871
	/* if ipsec is enabled, start up again */
872
	if (isset($ipseccfg['enable'])) {
873
		log_error("Forcefully reloading IPsec racoon daemon");
874
		vpn_ipsec_configure();
875
	}
876

    
877
}
878

    
879
/* master setup for vpn (mpd) */
880
function vpn_setup() {
881
	/* start pptpd */
882
	vpn_pptpd_configure();
883

    
884
	/* start pppoe server */
885
	vpn_pppoe_configure();
886

    
887
	/* setup l2tp */
888
	vpn_l2tp_configure();
889
}
890

    
891
function vpn_pptpd_configure() {
892
	global $config, $g;
893

    
894
	$syscfg = $config['system'];
895
	$pptpdcfg = $config['pptpd'];
896

    
897
	if ($g['booting']) {
898
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
899
			return 0;
900

    
901
		echo "Configuring PPTP VPN service... ";
902
	} else {
903
		/* kill mpd */
904
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
905

    
906
		/* wait for process to die */
907
		sleep(3);
908

    
909
		if (is_process_running("mpd -b")) {
910
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
911
			log_error("Could not kill mpd within 3 seconds.   Trying again.");
912
		}
913

    
914
		/* remove mpd.conf, if it exists */
915
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
916
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
917
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
918
	}
919

    
920
	/* make sure pptp-vpn directory exists */
921
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
922
		mkdir("{$g['varetc_path']}/pptp-vpn");
923

    
924
	switch ($pptpdcfg['mode']) {
925
		case 'server' :
926
			/* write mpd.conf */
927
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
928
			if (!$fd) {
929
				printf("Error: cannot open mpd.conf in vpn_pptpd_configure().\n");
930
				return 1;
931
			}
932

    
933
			$mpdconf =<<<EOD
934
pptpd:
935

    
936
EOD;
937

    
938
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
939
				$mpdconf .= "	load pt{$i}\n";
940
			}
941

    
942
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
943

    
944
				$clientip = long2ip(ip2long($pptpdcfg['remoteip']) + $i);
945

    
946
				if(isset($pptpdcfg['radius']['radiusissueips']) && isset($pptpdcfg['radius']['enable'])) {
947
					$isssue_ip_type = "set ipcp ranges {$pptpdcfg['localip']}/32 0.0.0.0/0";
948
					$isssue_ip_type .="\n\tset ipcp yes radius-ip";
949
				} else {
950
					$isssue_ip_type = "set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32";
951
				}
952

    
953
				$mpdconf .=<<<EOD
954

    
955
pt{$i}:
956
	new pt{$i} pt{$i}
957
	{$isssue_ip_type}
958
	load pts
959

    
960
EOD;
961
			}
962

    
963
			$mpdconf .=<<<EOD
964

    
965
pts:
966
	set iface disable on-demand
967
	set iface enable proxy-arp
968
	set iface enable tcpmssfix
969
	set iface idle 1800
970
	set iface up-script /usr/local/sbin/pptp-linkup
971
	set iface down-script /usr/local/sbin/vpn-linkdown
972
	set bundle enable multilink
973
	set bundle enable crypt-reqd
974
	set link yes acfcomp protocomp
975
	set link no pap chap
976
	set link enable chap-msv2
977
	set link mtu 1460
978
	set link keep-alive 10 60
979
	set ipcp yes vjcomp
980
	set bundle enable compression
981
	set ccp yes mppc
982
	set ccp yes mpp-e128
983
	set ccp yes mpp-stateless
984

    
985
EOD;
986

    
987
			if (!isset ($pptpdcfg['req128'])) {
988
				$mpdconf .=<<<EOD
989
	set ccp yes mpp-e40
990
	set ccp yes mpp-e56
991

    
992
EOD;
993
			}
994

    
995
			if  (isset($pptpdcfg["wins"]))
996
				$mpdconf  .=  "	set ipcp nbns {$pptpdcfg['wins']}\n";
997
			if (is_array($pptpdcfg['dnsserver']) && ($pptpdcfg['dnsserver'][0])) {
998
				$mpdconf .= "	set ipcp dns " . join(" ", $pptpdcfg['dnsserver']) . "\n";
999
			} else
1000
				if (isset ($config['dnsmasq']['enable'])) {
1001
					$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
1002
					if ($syscfg['dnsserver'][0])
1003
						$mpdconf .= " " . $syscfg['dnsserver'][0];
1004
					$mpdconf .= "\n";
1005
				} else
1006
					if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1007
						$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1008
					}
1009

    
1010
			if (isset ($pptpdcfg['radius']['enable'])) {
1011
				$authport = isset($pptpdcfg['radius']['port']) ? $pptpdcfg['radius']['port'] : 1812;
1012
				$acctport = $authport + 1;
1013
				$mpdconf .=<<<EOD
1014
	set radius server {$pptpdcfg['radius']['server']} "{$pptpdcfg['radius']['secret']}" {$authport} {$acctport}
1015
	set radius retries 3
1016
	set radius timeout 10
1017
	set bundle enable radius-auth
1018
	set bundle disable radius-fallback
1019

    
1020
EOD;
1021

    
1022
				if (isset ($pptpdcfg['radius']['accounting'])) {
1023
					$mpdconf .=<<<EOD
1024
	set bundle enable radius-acct
1025
	set radius acct-update 300
1026

    
1027
EOD;
1028
				}
1029
			}
1030

    
1031
			fwrite($fd, $mpdconf);
1032
			fclose($fd);
1033

    
1034
			/* write mpd.links */
1035
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1036
			if (!$fd) {
1037
				printf("Error: cannot open mpd.links in vpn_pptpd_configure().\n");
1038
				return 1;
1039
			}
1040

    
1041
			$mpdlinks = "";
1042

    
1043
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
1044
				$mpdlinks .=<<<EOD
1045

    
1046
pt{$i}:
1047
	set link type pptp
1048
	set pptp enable incoming
1049
	set pptp disable originate
1050
	set pptp disable windowing
1051
	set pptp self 127.0.0.1
1052

    
1053
EOD;
1054
			}
1055

    
1056
			fwrite($fd, $mpdlinks);
1057
			fclose($fd);
1058

    
1059
			/* write mpd.secret */
1060
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1061
			if (!$fd) {
1062
				printf("Error: cannot open mpd.secret in vpn_pptpd_configure().\n");
1063
				return 1;
1064
			}
1065

    
1066
			$mpdsecret = "";
1067

    
1068
			if (is_array($pptpdcfg['user'])) {
1069
				foreach ($pptpdcfg['user'] as $user)
1070
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1071
			}
1072

    
1073
			fwrite($fd, $mpdsecret);
1074
			fclose($fd);
1075
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1076

    
1077
			/* fire up mpd */
1078
			mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']}/pptp-vpn -p {$g['varrun_path']}/pptp-vpn.pid -f mpd.conf pptpd");
1079

    
1080
			break;
1081

    
1082
		case 'redir' :
1083
			break;
1084
	}
1085

    
1086
	if (!$g['booting']) {
1087
		/* reload the filter */
1088
		filter_configure();
1089
	}
1090

    
1091
	if ($g['booting'])
1092
		echo "done\n";
1093

    
1094
	return 0;
1095
}
1096

    
1097
function vpn_pppoe_configure() {
1098
	global $config, $g;
1099

    
1100
	$syscfg = $config['system'];
1101
	$pppoecfg = $config['pppoe'];
1102

    
1103
	/* create directory if it does not exist */
1104
	if (!is_dir("{$g['varetc_path']}/pppoe-vpn"))
1105
		mkdir("{$g['varetc_path']}/pppoe-vpn");
1106

    
1107
	if ($g['booting']) {
1108
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1109
			return 0;
1110

    
1111
		echo "Configuring PPPoE VPN service... ";
1112
	} else {
1113
		/* kill mpd */
1114
		killbypid("{$g['varrun_path']}/pppoe-vpn.pid");
1115

    
1116
		/* wait for process to die */
1117
		sleep(2);
1118

    
1119
	}
1120

    
1121
	/* make sure pppoe-vpn directory exists */
1122
	if (!file_exists("{$g['varetc_path']}/pppoe-vpn"))
1123
		mkdir("{$g['varetc_path']}/pppoe-vpn");
1124

    
1125
	switch ($pppoecfg['mode']) {
1126

    
1127
		case 'server' :
1128

    
1129
			$pppoe_interface = filter_translate_type_to_real_interface($pppoecfg['interface']);
1130

    
1131
			if ($pppoecfg['paporchap'] == "chap")
1132
				$paporchap = "set link enable chap";
1133
			else
1134
				$paporchap = "set link enable pap";
1135

    
1136
			/* write mpd.conf */
1137
			$fd = fopen("{$g['varetc_path']}/pppoe-vpn/mpd.conf", "w");
1138
			if (!$fd) {
1139
				printf("Error: cannot open mpd.conf in vpn_pppoe_configure().\n");
1140
				return 1;
1141
			}
1142
			$mpdconf = "\n\n";
1143
			$mpdconf .=<<<EOD
1144
pppoe:
1145

    
1146
EOD;
1147

    
1148
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1149
				$mpdconf .= "	load pppoe{$i}\n";
1150
			}
1151

    
1152
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1153

    
1154
				$clientip = long2ip(ip2long($pppoecfg['remoteip']) + $i);
1155

    
1156
				if (isset ($pppoecfg['radius']['radiusissueips']) && isset ($pppoecfg['radius']['enable'])) {
1157
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1158
					$isssue_ip_type .= "\n\tset ipcp yes radius-ip";
1159
				} else {
1160
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1161
				}
1162

    
1163
				$mpdconf .=<<<EOD
1164

    
1165
pppoe{$i}:
1166
	new pppoe{$i} pppoe{$i}
1167
	{$isssue_ip_type}
1168
	load pppoe_standart
1169

    
1170
EOD;
1171
			}
1172

    
1173
			$mpdconf .=<<<EOD
1174

    
1175
pppoe_standart:
1176
	set bundle no multilink
1177
	set bundle enable compression
1178
	set auth max-logins 1
1179
	set iface up-script /usr/local/sbin/pppoe-linkup
1180
        set iface down-script /usr/local/sbin/vpn-linkdown
1181
	set iface idle 0
1182
	set iface disable on-demand
1183
	set iface disable proxy-arp
1184
	set iface enable tcpmssfix
1185
	set iface mtu 1500
1186
	set link no pap chap
1187
	{$paporchap}
1188
	set link keep-alive 60 180
1189
	set ipcp yes vjcomp
1190
	set ipcp no vjcomp
1191
	set link max-redial -1
1192
	set link mtu 1492
1193
	set link mru 1492
1194
	set ccp yes mpp-e40
1195
	set ccp yes mpp-e128
1196
	set ccp yes mpp-stateless
1197
	set link latency 1
1198
	#set ipcp dns 10.10.1.3
1199
	#set bundle accept encryption
1200

    
1201
EOD;
1202

    
1203
			if (isset ($config['dnsmasq']['enable'])) {
1204
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
1205
				if ($syscfg['dnsserver'][0])
1206
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1207
				$mpdconf .= "\n";
1208
			} else
1209
				if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1210
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1211
				}
1212

    
1213
			if (isset ($pppoecfg['radius']['enable'])) {
1214
				$mpdconf .=<<<EOD
1215
	set radius server {$pppoecfg['radius']['server']} "{$pppoecfg['radius']['secret']}"
1216
	set ipcp radius-ip
1217
	set radius retries 3
1218
	set radius timeout 10
1219
	set bundle enable radius-auth
1220
	set bundle disable radius-fallback
1221

    
1222
EOD;
1223

    
1224
				if (isset ($pppoecfg['radius']['accounting'])) {
1225
					$mpdconf .=<<<EOD
1226
	set bundle enable radius-acct
1227

    
1228
EOD;
1229
				}
1230
			}
1231

    
1232
			fwrite($fd, $mpdconf);
1233
			fclose($fd);
1234

    
1235
			/* write mpd.links */
1236
			$fd = fopen("{$g['varetc_path']}/pppoe-vpn/mpd.links", "w");
1237
			if (!$fd) {
1238
				printf("Error: cannot open mpd.links in vpn_pppoe_configure().\n");
1239
				return 1;
1240
			}
1241

    
1242
			$mpdlinks = "";
1243

    
1244
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1245
				$mpdlinks .=<<<EOD
1246
			
1247
pppoe{$i}:
1248
	set phys type pppoe
1249
        set pppoe iface {$pppoe_interface}
1250
        set pppoe service "*"
1251
        set pppoe disable originate
1252
        set pppoe enable incoming
1253

    
1254
EOD;
1255
			}
1256

    
1257
			fwrite($fd, $mpdlinks);
1258
			fclose($fd);
1259

    
1260
			/* write mpd.secret */
1261
			$fd = fopen("{$g['varetc_path']}/pppoe-vpn/mpd.secret", "w");
1262
			if (!$fd) {
1263
				printf("Error: cannot open mpd.secret in vpn_pppoe_configure().\n");
1264
				return 1;
1265
			}
1266

    
1267
			$mpdsecret = "\n\n";
1268

    
1269
			if (is_array($pppoecfg['user'])) {
1270
				foreach ($pppoecfg['user'] as $user)
1271
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1272
			}
1273

    
1274
			fwrite($fd, $mpdsecret);
1275
			fclose($fd);
1276
			chmod("{$g['varetc_path']}/pppoe-vpn/mpd.secret", 0600);
1277

    
1278
			/* fire up mpd */
1279
			mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']}/pppoe-vpn -p {$g['varrun_path']}/pppoe-vpn.pid pppoe");
1280

    
1281
			break;
1282

    
1283
		case 'redir' :
1284
			break;
1285
	}
1286

    
1287
	touch("{$g["tmp_path"]}/filter_dirty");
1288

    
1289
	if ($g['booting'])
1290
		echo "done\n";
1291

    
1292
	return 0;
1293
}
1294

    
1295
function vpn_l2tp_configure() {
1296
	global $config, $g;
1297

    
1298
	$syscfg = $config['system'];
1299
	$l2tpcfg = $config['l2tp'];
1300

    
1301
	mwexec("/sbin/kldload /boot/kernel/ng_l2tp.ko");
1302

    
1303
	/* create directory if it does not exist */
1304
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1305
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1306

    
1307
	if ($g['booting']) {
1308
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1309
			return 0;
1310

    
1311
		echo "Configuring l2tp VPN service... ";
1312
	} else {
1313
		/* kill mpd */
1314
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1315

    
1316
		/* wait for process to die */
1317
		sleep(2);
1318

    
1319
	}
1320

    
1321
	/* make sure l2tp-vpn directory exists */
1322
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1323
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1324

    
1325
	switch ($l2tpcfg['mode']) {
1326

    
1327
		case 'server' :
1328

    
1329
			$l2tp_interface = filter_translate_type_to_real_interface($l2tpcfg['interface']);
1330

    
1331
			if ($l2tpcfg['paporchap'] == "chap")
1332
				$paporchap = "set link enable chap";
1333
			else
1334
				$paporchap = "set link enable pap";
1335

    
1336
			/* write mpd.conf */
1337
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1338
			if (!$fd) {
1339
				printf("Error: cannot open mpd.conf in vpn_l2tp_configure().\n");
1340
				return 1;
1341
			}
1342
			$mpdconf = "\n\n";
1343
			$mpdconf .=<<<EOD
1344
l2tp:
1345

    
1346
EOD;
1347

    
1348
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1349
				$mpdconf .= "	load l2tp{$i}\n";
1350
			}
1351

    
1352
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1353

    
1354
				$clientip = long2ip(ip2long($l2tpcfg['remoteip']) + $i);
1355

    
1356
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1357
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1358
					$isssue_ip_type .= "\n\tset ipcp yes radius-ip";
1359
				} else {
1360
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1361
				}
1362

    
1363
				$mpdconf .=<<<EOD
1364

    
1365
l2tp{$i}:
1366
	new l2tp{$i} l2tp{$i}
1367
	{$isssue_ip_type}
1368
	load l2tp_standard
1369

    
1370
EOD;
1371
			}
1372

    
1373
			$mpdconf .=<<<EOD
1374

    
1375
l2tp_standard:
1376
        set bundle disable multilink
1377
        set bundle enable compression
1378
        set bundle yes crypt-reqd
1379
        set ipcp yes vjcomp
1380
        # set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1381
        set ccp yes mppc
1382
        set iface disable on-demand
1383
        set iface enable proxy-arp
1384
	set iface up-script /usr/local/sbin/l2tp-linkup
1385
        set iface down-script /usr/local/sbin/vpn-linkdown
1386
        set link yes acfcomp protocomp
1387
        set link no pap chap
1388
        set link enable chap
1389
        set link keep-alive 10 180
1390

    
1391
EOD;
1392

    
1393
			if (isset ($config['dnsmasq']['enable'])) {
1394
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
1395
				if ($syscfg['dnsserver'][0])
1396
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1397
				$mpdconf .= "\n";
1398
			} else
1399
				if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1400
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1401
				}
1402

    
1403
			if (isset ($l2tpcfg['radius']['enable'])) {
1404
				$mpdconf .=<<<EOD
1405
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1406
	set ipcp radius-ip
1407
	set radius retries 3
1408
	set radius timeout 10
1409
	set bundle enable radius-auth
1410
	set bundle disable radius-fallback
1411

    
1412
EOD;
1413

    
1414
				if (isset ($l2tpcfg['radius']['accounting'])) {
1415
					$mpdconf .=<<<EOD
1416
	set bundle enable radius-acct
1417

    
1418
EOD;
1419
				}
1420
			}
1421

    
1422
			fwrite($fd, $mpdconf);
1423
			fclose($fd);
1424

    
1425
			/* write mpd.links */
1426
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1427
			if (!$fd) {
1428
				printf("Error: cannot open mpd.links in vpn_l2tp_configure().\n");
1429
				return 1;
1430
			}
1431

    
1432
			$mpdlinks = "";
1433

    
1434
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1435
				$mpdlinks .=<<<EOD
1436

    
1437
l2tp:
1438
	set link type l2tp
1439
	set l2tp iface {$l2tp_interface}
1440

    
1441
EOD;
1442
			}
1443

    
1444
			fwrite($fd, $mpdlinks);
1445
			fclose($fd);
1446

    
1447
			/* write mpd.secret */
1448
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1449
			if (!$fd) {
1450
				printf("Error: cannot open mpd.secret in vpn_l2tp_configure().\n");
1451
				return 1;
1452
			}
1453

    
1454
			$mpdsecret = "\n\n";
1455

    
1456
			if (is_array($l2tpcfg['user'])) {
1457
				foreach ($l2tpcfg['user'] as $user)
1458
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1459
			}
1460

    
1461
			fwrite($fd, $mpdsecret);
1462
			fclose($fd);
1463
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1464

    
1465
			/* fire up mpd */
1466
			mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']}/l2tp-vpn -p {$g['varrun_path']}/l2tp-vpn.pid l2tp");
1467

    
1468
			break;
1469

    
1470
		case 'redir' :
1471
			break;
1472
	}
1473

    
1474
	touch("{$g["tmp_path"]}/filter_dirty");
1475

    
1476
	if ($g['booting'])
1477
		echo "done\n";
1478

    
1479
	return 0;
1480
}
1481
?>
(32-32/37)