Project

General

Profile

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

    
3
/*
4
	vpn.inc
5
	Copyright (C) 2004 Scott Ullrich
6
	All rights reserved.
7

    
8
	originally part of m0n0wall (http://m0n0.ch/wall)
9
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
10
	All rights reserved.
11

    
12
	Redistribution and use in source and binary forms, with or without
13
	modification, are permitted provided that the following conditions are met:
14

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

    
18
	2. Redistributions in binary form must reproduce the above copyright
19
	   notice, this list of conditions and the following disclaimer in the
20
	   documentation and/or other materials provided with the distribution.
21

    
22
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
23
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
24
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
26
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31
	POSSIBILITY OF SUCH DAMAGE.
32
*/
33

    
34
/* include all configuration functions */
35
require_once ("functions.inc");
36

    
37
/* master setup for vpn (mpd) */
38
function vpn_setup() {
39
	/* start pptpd */
40
	vpn_pptpd_configure();
41

    
42
	/* start pppoe server */
43
	vpn_pppoe_configure();
44

    
45
	/* setup l2tp */
46
	vpn_l2tp_configure();
47
}
48

    
49
function vpn_ipsec_failover_configure() {
50
	global $config, $g;
51

    
52
	$sasyncd_text = "";
53

    
54
	if ($config['installedpackages']['sasyncd'] <> "")
55
		foreach ($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
56
			$enabled = isset ($sasyncd['enable']);
57
			if (!$enabled)
58
				return;
59
			if ($sasyncd['peerip'] <> "")
60
				$sasyncd_text .= "peer {$sasyncd['peerip']}\n";
61
			if ($sasyncd['interface'])
62
				$sasyncd_text .= "carp interface {$sasyncd['interface']}\n";
63
			if ($sasyncd['sharedkey'] <> "")
64
				$sasyncd_text .= "sharedkey {$sasyncd['sharedkey']}\n";
65
			if ($sasyncd['mode'] <> "")
66
				$sasyncd_text .= "mode {$sasyncd['mode']}\n";
67
			if ($sasyncd['listenon'] <> "")
68
				$sasyncd_text .= "listen on {$sasyncd['listenon']}\n";
69
			if ($sasyncd['flushmodesync'] <> "")
70
				$sasyncd_text .= "flushmode sync {$sasyncd['flushmodesync']}\n";
71
		}
72

    
73
	$fd = fopen("{$g['varetc_path']}/sasyncd.conf", "w");
74
	fwrite($fd, $sasyncd_text);
75
	fclose($fd);
76
	chmod("{$g['varetc_path']}/sasyncd.conf", 0600);
77

    
78
	mwexec("killall sasyncd");
79

    
80
	/* launch sasyncd, oh wise one */
81
	mwexec_bg("/usr/local/sbin/sasyncd -d -v -v -v");
82
}
83

    
84
function find_last_gif_device() {
85
	$last_gif_found = -1;
86
	$regs = "";
87
	if (!($fp = popen("/sbin/ifconfig -l", "r")))
88
		return -1;
89
	$ifconfig_data = fread($fp, 4096);
90
	pclose($fp);
91
	$ifconfig_array = split(" ", $ifconfig_data);
92
	foreach ($ifconfig_array as $ifconfig) {
93
		ereg("gif(.)", $ifconfig, $regs);
94
		if ($regs[0] && $regs[0] > $last_gif_found) {
95
			$last_gif_found = $regs[1];
96
		}
97
	}
98
	return $last_gif_found;
99
}
100

    
101
function vpn_ipsec_configure($ipchg = false) {
102
	global $config, $g, $sa, $sn;
103

    
104
	mwexec("/sbin/ifconfig enc0 up");
105

    
106
	/* get the automatic /etc/ping_hosts.sh ready */
107
	unlink_if_exists("/var/db/ipsecpinghosts");
108
	touch("/var/db/ipsecpinghosts");
109

    
110
	if ($g['booting'] == true) {
111
		/* determine if we should load the via padlock module */
112
		$dmesg_boot = `/usr/bin/grep CPU {$g['varlog_path']}/dmesg.boot`;
113
		if (stristr($dmesg_boot, "ACE") == true) {
114
			//echo "Enabling [VIA Padlock] ...";
115
			//mwexec("/sbin/kldload padlock");
116
			//mwexec("/sbin/sysctl net.inet.ipsec.crypto_support=1");
117
			//mwexec("/sbin/setkey -F");
118
			//mwexec("/sbin/setkey -FP");
119
			//echo " done.\n";
120
		}
121
	}
122

    
123
	if(isset($config['ipsec']['preferredoldsa'])) {
124
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
125
	} else {
126
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
127
	}
128

    
129
	$number_of_gifs = find_last_gif_device();
130
	for ($x = 0; $x < $number_of_gifs; $x++) {
131
		mwexec("/sbin/ifconfig gif" . $x . " delete");
132
	}
133

    
134
	$curwanip = get_current_wan_address();
135

    
136
	$syscfg = $config['system'];
137
	$ipseccfg = $config['ipsec'];
138
	$lancfg = $config['interfaces']['lan'];
139
	$lanip = $lancfg['ipaddr'];
140
	$lansa = gen_subnet($lancfg['ipaddr'], $lancfg['subnet']);
141
	$lansn = $lancfg['subnet'];
142

    
143

    
144
	if (!isset($ipseccfg['enable'])) {
145
		mwexec("/sbin/ifconfig enc0 down");
146
		mwexec("/sbin/ifconfig enc0 destroy");
147

    
148
		/* kill racoon */
149
		mwexec("/usr/bin/killall racoon");
150
		killbypid("{$g['varrun_path']}/dnswatch-ipsec.pid");
151
		
152
		/* wait for racoon process to die */
153
		sleep(2);
154

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

    
158
		/* flush SPD and SAD */
159
		mwexec("/sbin/setkey -FP");
160
		mwexec("/sbin/setkey -F");
161

    
162
		return true;
163
	}
164

    
165
	if ($g['booting']) {
166
		echo "Configuring IPsec VPN... ";
167
	}
168

    
169
	if (isset ($ipseccfg['enable'])) {
170
		/* fastforwarding is not compatible with ipsec tunnels */
171
		mwexec("/sbin/sysctl net.inet.ip.fastforwarding=0");
172

    
173
		if (!$curwanip) {
174
			/* IP address not configured yet, exit */
175
			if ($g['booting'])
176
				echo "done\n";
177
			return 0;
178
		}
179

    
180
		if ((is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) ||
181
		  isset ($ipseccfg['mobileclients']['enable'])) {
182
		  
183
			$dnswatch_list = array();
184
			$rgmap = array();
185
		  
186
			if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) {
187
				/* generate spd.conf */
188
				$fd = fopen("{$g['varetc_path']}/spd.conf", "w");
189
				if (!$fd) {
190
					printf("Error: cannot open spd.conf in vpn_ipsec_configure().\n");
191
					return 1;
192
				}
193

    
194
				$spdconf = "";
195

    
196
				$spdconf .= "spdadd {$lansa}/{$lansn} {$lanip}/32 any -P in none;\n";
197
				$spdconf .= "spdadd {$lanip}/32 {$lansa}/{$lansn} any -P out none;\n";
198

    
199
				foreach ($ipseccfg['tunnel'] as $tunnel) {
200
					if (isset ($tunnel['disabled']))
201
						continue;
202

    
203
				   /* see if this tunnel has a hostname for the remote-gateway, and if so,
204
				      try to resolve it now and add it to the list for dnswatch */
205
				   if (!is_ipaddr($tunnel['remote-gateway'])) {
206
				           $dnswatch_list[] = $tunnel['remote-gateway'];
207
				           $rgip = resolve_retry($tunnel['remote-gateway']);
208
				
209
				           if (!$rgip)
210
				                   continue;
211
				
212
				   } else {
213
				           $rgip = $tunnel['remote-gateway'];
214
				   }
215
				   $rgmap[$tunnel['remote-gateway']] = $rgip;
216

    
217
					$ep = vpn_endpoint_determine($tunnel, $curwanip);
218
					if (!$ep)
219
						continue;
220

    
221
					vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn);
222

    
223
					if (is_domain($tunnel['remote-gateway'])) {
224
						$tmp = gethostbyname($tunnel['remote-gateway']);
225
						if ($tmp)
226
							$tunnel['remote-gateway'] = $tmp;
227
					}
228

    
229
					/* add entry to host pinger */
230
					if ($tunnel['pinghost']) {
231
						$pfd = fopen("/var/db/ipsecpinghosts", "a");
232
						$iflist = array("lan" => "lan", "wan" => "wan");
233
			          	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++)
234
			          		$iflist['opt' . $i] = "opt{$i}";
235
			            foreach ($iflist as $ifent => $ifname) {
236
			            	$interface_ip = find_interface_ip($config['interfaces'][$ifname]['if']);
237
			            	if (ip_in_subnet($interface_ip, $sa . "/" . $sn))
238
			                	$srcip = find_interface_ip($config['interfaces'][$ifname]['if']);
239
			            }
240
						$dstip = $tunnel['pinghost'];
241
						fwrite($pfd, "$srcip|$dstip|3\n");
242
						fclose($pfd);
243
					}
244

    
245
					if (isset ($tunnel['creategif'])) {
246
						$number_of_gifs = find_last_gif_device();
247
						$number_of_gifs++;
248
						$curwanip = get_current_wan_address();
249
						if ($config['installedpackages']['sasyncd']['config'] <> "")
250
							foreach ($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
251
								if ($sasyncd['ip'] <> "")
252
									$curwanip = $sasyncd['ip'];
253
							}
254
						mwexec("/sbin/ifconfig gif" . $number_of_gifs . " tunnel" . $curwanip . " " . $tunnel['remote-gateway']);
255
						mwexec("/sbin/ifconfig gif" . $number_of_gifs . " {$lansa}/{$lansn} {$lanip}/32");
256
					}
257

    
258
					$spdconf .= "spdadd {$sa}/{$sn} " .
259
					  "{$tunnel['remote-subnet']} any -P out ipsec " .
260
					  "{$tunnel['p2']['protocol']}/tunnel/{$ep}-" .
261
					  "{$rgip}/unique;\n";
262

    
263
					$spdconf .= "spdadd {$tunnel['remote-subnet']} " .
264
					  "{$sa}/{$sn} any -P in ipsec " .
265
					  "{$tunnel['p2']['protocol']}/tunnel/{$rgip}-" .
266
					  "{$ep}/unique;\n";
267
				}
268

    
269
				fwrite($fd, $spdconf);
270
				fclose($fd);
271
			}
272

    
273
			/* generate racoon.conf */
274
			$fd = fopen("{$g['varetc_path']}/racoon.conf", "w");
275
			if (!$fd) {
276
				printf("Error: cannot open racoon.conf in vpn_ipsec_configure().\n");
277
				return 1;
278
			}
279

    
280
			$racoonconf = "";
281

    
282
			$racoonconf .= "path pre_shared_key \"{$g['varetc_path']}/psk.txt\";\n\n";
283
			$racoonconf .= "path certificate  \"{$g['varetc_path']}\";\n\n";
284

    
285
			/* generate CA certificates files */
286
			$cacertnum = 0;
287
			if (is_array($ipseccfg['cacert']) && count($ipseccfg['cacert']))
288
				foreach ($ipseccfg['cacert'] as $cacert) {
289
					++ $cacertnum;
290
					if (isset ($cacert['cert'])) {
291
						$cert = base64_decode($cacert['cert']);
292
						$x509cert = openssl_x509_parse(openssl_x509_read($cert));
293
						if (is_array($x509cert) && isset ($x509cert['hash'])) {
294
							$fd1 = fopen("{$g['varetc_path']}/{$x509cert['hash']}.0", "w");
295
							if (!$fd1) {
296
								printf("Error: cannot open {$x509cert['hash']}.0 in vpn.\n");
297
								return 1;
298
							}
299
							chmod("{$g['varetc_path']}/{$x509cert['hash']}.0", 0600);
300
							fwrite($fd1, $cert);
301
							fclose($fd1);
302
						}
303
					}
304
				}
305

    
306
			$tunnelnumber = 0;
307
			if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel']))
308
				foreach ($ipseccfg['tunnel'] as $tunnel) {
309

    
310
					++ $tunnelnumber;
311

    
312
					if (isset ($tunnel['disabled']))
313
						continue;
314

    
315

    
316
					  $rgip = $rgmap[$tunnel['remote-gateway']];
317
					   if (!$rgip)
318
					           continue;
319

    
320
					$ep = vpn_endpoint_determine($tunnel, $curwanip);
321
					if (!$ep)
322
						continue;
323

    
324
					vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn);
325

    
326
					if (isset ($tunnel['p1']['myident']['myaddress'])) {
327
						$myidentt = "address";
328
						$myident = $ep;
329
					} elseif (isset ($tunnel['p1']['myident']['address'])) {
330
						$myidentt = "address";
331
						$myident = $tunnel['p1']['myident']['address'];
332
					} elseif (isset ($tunnel['p1']['myident']['fqdn'])) {
333
						$myidentt = "fqdn";
334
						$myident = $tunnel['p1']['myident']['fqdn'];
335
					} elseif (isset ($tunnel['p1']['myident']['ufqdn'])) {
336
						$myidentt = "user_fqdn";
337
						$myident = $tunnel['p1']['myident']['ufqdn'];
338
					} else if (isset($tunnel['p1']['myident']['asn1dn'])) {
339
						$myidentt = "asn1dn";
340
						$myident = $tunnel['p1']['myident']['asn1dn'];					
341
					} else if (isset($tunnel['p1']['myident']['asn1dn'])) {
342
						$myidentt = "asn1dn";
343
						$myident = $tunnel['p1']['myident']['asn1dn'];						
344
					} elseif (isset ($tunnel['p1']['myident']['dyn_dns'])) {
345
						$myidentt = "dyn_dns";
346
						$myident = gethostbyname($tunnel['p1']['myident']['dyn_dns']);
347
					}
348

    
349
					if (!($myidentt == "asn1dn" && $myident == "")) {
350
						$myident = " \"".$myident."\"";
351
					}
352

    
353
					if (!($myidentt == "asn1dn" && $myident == "")) {
354
						$myident = " \"".$myident."\"";
355
					}
356

    
357
					$nattline = '';
358
					if (isset($tunnel['natt'])) {
359
						$nattline = "nat_traversal on;";
360
					}
361

    
362
					if (isset ($tunnel['p1']['authentication_method'])) {
363
						$authmethod = $tunnel['p1']['authentication_method'];
364
					} else {
365
						$authmethod = 'pre_shared_key';
366
					}
367

    
368
					$certline = '';
369

    
370
					if ($authmethod == 'rsasig') {
371
						if ($tunnel['p1']['cert'] && $tunnel['p1']['private-key']) {
372
							$cert = base64_decode($tunnel['p1']['cert']);
373
							$private_key = base64_decode($tunnel['p1']['private-key']);
374
						} else {
375
							/* null certificate/key */
376
							$cert = '';
377
							$private_key = '';
378
						}
379

    
380
						if ($tunnel['p1']['peercert'])
381
							$peercert = base64_decode($tunnel['p1']['peercert']);
382
						else
383
							$peercert = '';
384

    
385
						$fd1 = fopen("{$g['varetc_path']}/server{$tunnelnumber}-signed.pem", "w");
386
						if (!$fd1) {
387
							printf("Error: cannot open server{$tunnelnumber}-signed.pem in vpn.\n");
388
							return 1;
389
						}
390
						chmod("{$g['varetc_path']}/server{$tunnelnumber}-signed.pem", 0600);
391
						fwrite($fd1, $cert);
392
						fclose($fd1);
393

    
394
						$fd1 = fopen("{$g['varetc_path']}/server{$tunnelnumber}-key.pem", "w");
395
						if (!$fd1) {
396
							printf("Error: cannot open server{$tunnelnumber}-key.pem in vpn.\n");
397
							return 1;
398
						}
399
						chmod("{$g['varetc_path']}/server{$tunnelnumber}-key.pem", 0600);
400
						fwrite($fd1, $private_key);
401
						fclose($fd1);
402

    
403
						$certline = "certificate_type x509 \"server{$tunnelnumber}-signed.pem\" \"server{$tunnelnumber}-key.pem\";";
404

    
405
						if ($peercert != '') {
406
							$fd1 = fopen("{$g['varetc_path']}/peer{$tunnelnumber}-signed.pem", "w");
407
							if (!$fd1) {
408
								printf("Error: cannot open server{$tunnelnumber}-signed.pem in vpn.\n");
409
								return 1;
410
							}
411
							chmod("{$g['varetc_path']}/peer{$tunnelnumber}-signed.pem", 0600);
412
							fwrite($fd1, $peercert);
413
							fclose($fd1);
414
							$certline .=<<<EOD
415

    
416
	peers_certfile "peer{$tunnelnumber}-signed.pem";
417
EOD;
418
						}
419
					}
420
					$myidentifier = $myidentt;
421
					if (!empty($myident)) 
422
						$myidentifier .= ' "' . $myident . '"';					
423
					$racoonconf .=<<<EOD
424
remote {$tunnel['remote-gateway']} \{
425
	exchange_mode {$tunnel['p1']['mode']};
426
	my_identifier {$myidentt}{$myident};
427
	{$nattline}
428
	{$certline}
429
	peers_identifier address {$rgip};
430
	initial_contact on;
431
	dpd_delay 120;                   # DPD poll every 120 seconds
432
	ike_frag on;
433
	support_proxy on;
434
	proposal_check obey;
435

    
436
	proposal \{
437
		encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
438
		hash_algorithm {$tunnel['p1']['hash-algorithm']};
439
		authentication_method {$authmethod};
440
		dh_group {$tunnel['p1']['dhgroup']};
441

    
442
EOD;
443
					if ($tunnel['p1']['lifetime'])
444
						$racoonconf .= "		lifetime time {$tunnel['p1']['lifetime']} secs;\n";
445

    
446
					$racoonconf .= "	}\n";
447

    
448
					if ($tunnel['p1']['lifetime'])
449
						$racoonconf .= "	lifetime time {$tunnel['p1']['lifetime']} secs;\n";
450

    
451
					$racoonconf .= "}\n\n";
452

    
453
					$p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']);
454
					$p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']);
455

    
456
					$racoonconf .=<<<EOD
457
sainfo address {$sa}/{$sn} any address {$tunnel['remote-subnet']} any \{
458
	encryption_algorithm {$p2ealgos};
459
	authentication_algorithm {$p2halgos};
460
	compression_algorithm deflate;
461

    
462
EOD;
463

    
464
					if ($tunnel['p2']['pfsgroup'])
465
						$racoonconf .= "	pfs_group {$tunnel['p2']['pfsgroup']};\n";
466

    
467
					if ($tunnel['p2']['lifetime'])
468
						$racoonconf .= "	lifetime time {$tunnel['p2']['lifetime']} secs;\n";
469

    
470
					$racoonconf .= "}\n\n";
471
				}
472

    
473
			/* mobile clients? */
474
			if (isset ($ipseccfg['mobileclients']['enable'])) {
475

    
476
				$tunnel = $ipseccfg['mobileclients'];
477

    
478
				if (isset ($tunnel['p1']['myident']['myaddress'])) {
479
					$myidentt = "address";
480
					$myident = $curwanip;
481
				} else
482
					if (isset ($tunnel['p1']['myident']['address'])) {
483
						$myidentt = "address";
484
						$myident = $tunnel['p1']['myident']['address'];
485
					} else
486
						if (isset ($tunnel['p1']['myident']['fqdn'])) {
487
							$myidentt = "fqdn";
488
							$myident = $tunnel['p1']['myident']['fqdn'];
489
						} else
490
							if (isset ($tunnel['p1']['myident']['ufqdn'])) {
491
								$myidentt = "user_fqdn";
492
								$myident = $tunnel['p1']['myident']['ufqdn'];
493
							}
494

    
495
				if (isset ($tunnel['p1']['authentication_method'])) {
496
					$authmethod = $tunnel['p1']['authentication_method'];
497
				} else {
498
					$authmethod = 'pre_shared_key';
499
				}
500

    
501
				$certline = '';
502
				if ($authmethod == 'rsasig') {
503
					if ($tunnel['p1']['cert'] && $tunnel['p1']['private-key']) {
504
						$cert = base64_decode($tunnel['p1']['cert']);
505
						$private_key = base64_decode($tunnel['p1']['private-key']);
506
					} else {
507
						/* null certificate/key */
508
						$cert = '';
509
						$private_key = '';
510
					}
511

    
512
					if ($tunnel['p1']['peercert'])
513
						$peercert = base64_decode($tunnel['p1']['peercert']);
514
					else
515
						$peercert = '';
516

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

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

    
535
					$certline = "certificate_type x509 \"server-mobile{$tunnelnumber}-signed.pem\" \"server-mobile{$tunnelnumber}-key.pem\";";
536
				}
537
				$racoonconf .=<<<EOD
538
remote anonymous \{
539
	exchange_mode {$tunnel['p1']['mode']};
540
	my_identifier {$myidentt}{$myident};
541
	{$certline}
542
	initial_contact on;
543
	dpd_delay 120;                   # DPD poll every 120 seconds
544
	ike_frag on;
545
	passive on;
546
	generate_policy on;
547
	support_proxy on;
548
	proposal_check obey;
549

    
550
	proposal \{
551
		encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
552
		hash_algorithm {$tunnel['p1']['hash-algorithm']};
553
		authentication_method {$authmethod};
554
		dh_group {$tunnel['p1']['dhgroup']};
555

    
556
EOD;
557
				if ($tunnel['p1']['lifetime'])
558
					$racoonconf .= "		lifetime time {$tunnel['p1']['lifetime']} secs;\n";
559

    
560
				$racoonconf .= "	}\n";
561

    
562
				if ($tunnel['p1']['lifetime'])
563
					$racoonconf .= "	lifetime time {$tunnel['p1']['lifetime']} secs;\n";
564

    
565
				$racoonconf .= "}\n\n";
566

    
567
				$p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']);
568
				$p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']);
569

    
570
				$racoonconf .=<<<EOD
571
sainfo anonymous \{
572
	encryption_algorithm {$p2ealgos};
573
	authentication_algorithm {$p2halgos};
574
	compression_algorithm deflate;
575

    
576
EOD;
577

    
578
				if ($tunnel['p2']['pfsgroup'])
579
					$racoonconf .= "	pfs_group {$tunnel['p2']['pfsgroup']};\n";
580

    
581
				if ($tunnel['p2']['lifetime'])
582
					$racoonconf .= "	lifetime time {$tunnel['p2']['lifetime']} secs;\n";
583

    
584
				$racoonconf .= "}\n\n";
585
			}
586

    
587
			fwrite($fd, $racoonconf);
588
			fclose($fd);
589

    
590
			/* generate psk.txt */
591
			$fd = fopen("{$g['varetc_path']}/psk.txt", "w");
592
			if (!$fd) {
593
				printf("Error: cannot open psk.txt in vpn_ipsec_configure().\n");
594
				return 1;
595
			}
596

    
597
			$pskconf = "";
598

    
599
			if (is_array($ipseccfg['tunnel'])) {
600
				foreach ($ipseccfg['tunnel'] as $tunnel) {
601
					if (isset ($tunnel['disabled']))
602
						continue;
603
                   $rgip = $rgmap[$tunnel['remote-gateway']];
604
                   if (!$rgip)
605
                           continue;
606
                   $pskconf .= "{$rgip}     {$tunnel['p1']['pre-shared-key']}\n";
607
				}
608
			}
609

    
610
			/* add PSKs for mobile clients */
611
			if (is_array($ipseccfg['mobilekey'])) {
612
				foreach ($ipseccfg['mobilekey'] as $key) {
613
					$pskconf .= "{$key['ident']}	{$key['pre-shared-key']}\n";
614
				}
615
			}
616

    
617
			fwrite($fd, $pskconf);
618
			fclose($fd);
619
			chmod("{$g['varetc_path']}/psk.txt", 0600);
620

    
621

    
622
			if(is_process_running("racoon")) {
623
				/* We are already online, reload */
624
				mwexec("/usr/bin/killall -HUP racoon");
625
				/* flush SPD entries */
626
				mwexec("/sbin/setkey -FP");
627
				mwexec("/sbin/setkey -F");
628
				/* load SPD */
629
				mwexec("/sbin/setkey -f {$g['varetc_path']}/spd.conf");
630
				sleep(1);
631
				/* We are already online, reload */
632
				mwexec("/usr/bin/killall -HUP racoon");
633
				sleep(1);
634
				mwexec("/usr/bin/killall -HUP racoon");
635
			} else {
636
				/* start racoon */
637
				mwexec("/usr/local/sbin/racoon -f {$g['varetc_path']}/racoon.conf");
638
				/* flush SA + SPD  entries*/
639
				mwexec("/sbin/setkey -FP");
640
				mwexec("/sbin/setkey -F");
641
				/* load SPD */
642
				mwexec("/sbin/setkey -f {$g['varetc_path']}/spd.conf");
643
				sleep(1);
644
				/* We are already online, reload */
645
				mwexec("/usr/bin/killall -HUP racoon");
646
				sleep(1);
647
				mwexec("/usr/bin/killall -HUP racoon");
648

    
649
				/* start dnswatch, if necessary */
650
				if (count($dnswatch_list) > 0) {
651
					$interval = 60;
652
					if ($ipseccfg['dns-interval']) {
653
						$interval = $ipseccfg['dns-interval'];
654
					}
655
			
656
					$hostnames = "";
657
					foreach ($dnswatch_list as $dns) {
658
						$hostnames .= " " . escapeshellarg($dns);
659
					}
660
					mwexec("/usr/local/bin/dnswatch {$g['varrun_path']}/dnswatch-ipsec.pid $interval " .
661
					escapeshellarg("/etc/rc.newipsecdns") . $hostnames);
662
				}
663
			}
664

    
665
			if (is_array($ipseccfg['tunnel'])) {
666
				foreach ($ipseccfg['tunnel'] as $tunnel) {
667
					if (isset ($tunnel['auto'])) {
668
						$remotehost = substr($tunnel['remote-subnet'], 0, strpos($tunnel['remote-subnet'], "/"));
669
						$srchost = vpn_endpoint_determine($tunnel, $curwanip);
670
						if ($srchost)
671
							mwexec_bg("/sbin/ping -c 10 -S {$srchost} {$remotehost}");
672
					}
673
				}
674
			}
675
		}
676
	}
677

    
678
	vpn_ipsec_failover_configure();
679

    
680
	if (!$g['booting']) {
681
		/* reload the filter */
682
		touch("{$g["tmp_path"]}/filter_dirty");
683
	}
684

    
685
	if ($g['booting'])
686
		echo "done\n";
687

    
688
	return 0;
689
}
690

    
691
function vpn_pptpd_configure() {
692
	global $config, $g;
693

    
694
	$syscfg = $config['system'];
695
	$pptpdcfg = $config['pptpd'];
696

    
697
	$starting_ng = get_number_of_wan_netgraph_interfaces_needed();
698

    
699
	if ($g['booting']) {
700
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
701
			return 0;
702

    
703
		echo "Configuring PPTP VPN service... ";
704
	} else {
705
		/* kill mpd */
706
		killbypid("{$g['varrun_path']}/mpd-vpn.pid");
707

    
708
		/* wait for process to die */
709
		sleep(3);
710

    
711
		if (is_process_running("mpd -b")) {
712
			killbypid("{$g['varrun_path']}/mpd-vpn.pid");
713
			log_error("Could not kill mpd within 3 seconds.   Trying again.");
714
		}
715

    
716
		/* remove mpd.conf, if it exists */
717
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.conf");
718
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.links");
719
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.secret");
720
	}
721

    
722
	/* make sure mpd-vpn directory exists */
723
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
724
		mkdir("{$g['varetc_path']}/mpd-vpn");
725

    
726
	switch ($pptpdcfg['mode']) {
727
		case 'server' :
728
			/* write mpd.conf */
729
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.conf", "w");
730
			if (!$fd) {
731
				printf("Error: cannot open mpd.conf in vpn_pptpd_configure().\n");
732
				return 1;
733
			}
734

    
735
			$mpdconf =<<<EOD
736
pptpd:
737

    
738
EOD;
739

    
740
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
741
				$mpdconf .= "	load pt{$i}\n";
742
			}
743

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

    
746
				$clientip = long2ip(ip2long($pptpdcfg['remoteip']) + $i);
747
				$ngif = "ng" . ($i + $starting_ng);
748

    
749
				if(isset($pptpdcfg['radius']['radiusissueips']) && isset($pptpdcfg['radius']['enable'])) {
750
					$isssue_ip_type = "set ipcp ranges {$pptpdcfg['localip']}/32 0.0.0.0/0";
751
					$isssue_ip_type .="\n\tset ipcp yes radius-ip";
752
				} else {
753
					$isssue_ip_type = "set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32";
754
				}
755

    
756
				$mpdconf .=<<<EOD
757

    
758
pt{$i}:
759
	new -i {$ngif} pt{$i} pt{$i}
760
	{$isssue_ip_type}
761
	load pts
762

    
763
EOD;
764
			}
765

    
766
			$mpdconf .=<<<EOD
767

    
768
pts:
769
	set iface disable on-demand
770
	set iface enable proxy-arp
771
	set iface enable tcpmssfix
772
	set iface idle 1800
773
	set iface up-script /usr/local/sbin/vpn-linkup
774
	set iface down-script /usr/local/sbin/vpn-linkdown
775
	set bundle enable multilink
776
	set bundle enable crypt-reqd
777
	set link yes acfcomp protocomp
778
	set link no pap chap
779
	set link enable chap-msv2
780
	set link mtu 1460
781
	set link keep-alive 10 60
782
	set ipcp yes vjcomp
783
	set bundle enable compression
784
	set ccp yes mppc
785
	set ccp yes mpp-e128
786
	set ccp yes mpp-stateless
787

    
788
EOD;
789

    
790
			if (!isset ($pptpdcfg['req128'])) {
791
				$mpdconf .=<<<EOD
792
	set ccp yes mpp-e40
793
	set ccp yes mpp-e56
794

    
795
EOD;
796
			}
797

    
798
			if  (isset($pptpdcfg["wins"]))
799
				$mpdconf  .=  "	set ipcp nbns {$pptpdcfg['wins']}\n";
800
			if (is_array($pptpdcfg['dnsserver']) && ($pptpdcfg['dnsserver'][0])) {
801
				$mpdconf .= "	set ipcp dns " . join(" ", $pptpdcfg['dnsserver']) . "\n";
802
			} else
803
				if (isset ($config['dnsmasq']['enable'])) {
804
					$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
805
					if ($syscfg['dnsserver'][0])
806
						$mpdconf .= " " . $syscfg['dnsserver'][0];
807
					$mpdconf .= "\n";
808
				} else
809
					if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
810
						$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
811
					}
812

    
813
			if (isset ($pptpdcfg['radius']['enable'])) {
814
				$authport = isset($pptpdcfg['radius']['port']) ? $pptpdcfg['radius']['port'] : 1812;
815
				$acctport = $authport + 1;
816
				$mpdconf .=<<<EOD
817
	set radius server {$pptpdcfg['radius']['server']} "{$pptpdcfg['radius']['secret']}" {$authport} {$acctport}
818
	set radius retries 3
819
	set radius timeout 10
820
	set bundle enable radius-auth
821
	set bundle disable radius-fallback
822

    
823
EOD;
824

    
825
				if (isset ($pptpdcfg['radius']['accounting'])) {
826
					$mpdconf .=<<<EOD
827
	set bundle enable radius-acct
828
	set radius acct-update 300
829

    
830
EOD;
831
				}
832
			}
833

    
834
			fwrite($fd, $mpdconf);
835
			fclose($fd);
836

    
837
			/* write mpd.links */
838
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.links", "w");
839
			if (!$fd) {
840
				printf("Error: cannot open mpd.links in vpn_pptpd_configure().\n");
841
				return 1;
842
			}
843

    
844
			$mpdlinks = "";
845

    
846
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
847
				$mpdlinks .=<<<EOD
848

    
849
pt{$i}:
850
	set link type pptp
851
	set pptp enable incoming
852
	set pptp disable originate
853
	set pptp disable windowing
854
	set pptp self 127.0.0.1
855

    
856
EOD;
857
			}
858

    
859
			fwrite($fd, $mpdlinks);
860
			fclose($fd);
861

    
862
			/* write mpd.secret */
863
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.secret", "w");
864
			if (!$fd) {
865
				printf("Error: cannot open mpd.secret in vpn_pptpd_configure().\n");
866
				return 1;
867
			}
868

    
869
			$mpdsecret = "";
870

    
871
			if (is_array($pptpdcfg['user'])) {
872
				foreach ($pptpdcfg['user'] as $user)
873
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
874
			}
875

    
876
			fwrite($fd, $mpdsecret);
877
			fclose($fd);
878
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
879

    
880
			/* fire up mpd */
881
			mwexec("/usr/local/sbin/mpd -b -d {$g['varetc_path']}/mpd-vpn -p {$g['varrun_path']}/mpd-vpn.pid pptpd -c {$g['varetc_path']}/mpd-vpn/mpd.conf");
882

    
883
			break;
884

    
885
		case 'redir' :
886
			break;
887
	}
888

    
889
	if (!$g['booting']) {
890
		/* reload the filter */
891
		filter_configure();
892
	}
893

    
894
	if ($g['booting'])
895
		echo "done\n";
896

    
897
	return 0;
898
}
899

    
900
function vpn_localnet_determine($adr, & $sa, & $sn) {
901
	global $config, $g;
902

    
903
	if (isset ($adr)) {
904
		if ($adr['network']) {
905
			switch ($adr['network']) {
906
				case 'lan' :
907
					$sn = $config['interfaces']['lan']['subnet'];
908
					$sa = gen_subnet($config['interfaces']['lan']['ipaddr'], $sn);
909
					break;
910
			}
911
		} else
912
			if ($adr['address']) {
913
				list ($sa, $sn) = explode("/", $adr['address']);
914
				if (is_null($sn))
915
					$sn = 32;
916
			}
917
	} else {
918
		$sn = $config['interfaces']['lan']['subnet'];
919
		$sa = gen_subnet($config['interfaces']['lan']['ipaddr'], $sn);
920
	}
921
}
922

    
923
function vpn_endpoint_determine($tunnel, $curwanip) {
924

    
925
	global $g, $config;
926

    
927
	if ((!$tunnel['interface']) || ($tunnel['interface'] == "wan")) {
928
		if ($curwanip)
929
			return $curwanip;
930
		else
931
			return null;
932
	} elseif ($tunnel['interface'] == "lan") {
933
		return $config['interfaces']['lan']['ipaddr'];
934
	} else {
935
		$oc = $config['interfaces'][$tunnel['interface']];
936
		/* carp ips, etc */
937
		$ip = find_interface_ip($tunnel['interface']);
938
		if($ip) 
939
			return $ip;
940
			
941
		if (isset ($oc['enable']) && $oc['if']) {
942
			return $oc['ipaddr'];
943
		}
944
	}
945

    
946
	return null;
947
}
948

    
949
function vpn_pppoe_configure() {
950
	global $config, $g;
951

    
952
	$syscfg = $config['system'];
953
	$pppoecfg = $config['pppoe'];
954

    
955
	$starting_ng = get_number_of_wan_netgraph_interfaces_needed();
956

    
957
	/* create directory if it does not exist */
958
	if (!is_dir("{$g['varetc_path']}/mpd-vpn"))
959
		mkdir("{$g['varetc_path']}/mpd-vpn");
960

    
961
	if ($g['booting']) {
962
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
963
			return 0;
964

    
965
		echo "Configuring PPPoE VPN service... ";
966
	} else {
967
		/* kill mpd */
968
		killbypid("{$g['varrun_path']}/mpd-vpn.pid");
969

    
970
		/* wait for process to die */
971
		sleep(2);
972

    
973
	}
974

    
975
	/* make sure mpd-vpn directory exists */
976
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
977
		mkdir("{$g['varetc_path']}/mpd-vpn");
978

    
979
	switch ($pppoecfg['mode']) {
980

    
981
		case 'server' :
982

    
983
			$pppoe_interface = filter_translate_type_to_real_interface($pppoecfg['interface']);
984

    
985
			if ($pppoecfg['paporchap'] == "chap")
986
				$paporchap = "set link enable chap";
987
			else
988
				$paporchap = "set link enable pap";
989

    
990
			/* write mpd.conf */
991
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.conf", "a");
992
			if (!$fd) {
993
				printf("Error: cannot open mpd.conf in vpn_pppoe_configure().\n");
994
				return 1;
995
			}
996
			$mpdconf = "\n\n";
997
			$mpdconf .=<<<EOD
998
pppoe:
999

    
1000
EOD;
1001

    
1002
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1003
				$mpdconf .= "	load pppoe{$i}\n";
1004
			}
1005

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

    
1008
				$clientip = long2ip(ip2long($pppoecfg['remoteip']) + $i);
1009
				$ngif = "ng" . ($i + $starting_ng);
1010

    
1011
				if (isset ($pppoecfg['radius']['radiusissueips']) && isset ($pppoecfg['radius']['enable'])) {
1012
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1013
					$isssue_ip_type .= "\n\tset ipcp yes radius-ip";
1014
				} else {
1015
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1016
				}
1017

    
1018
				$mpdconf .=<<<EOD
1019

    
1020
pppoe{$i}:
1021
	new -i {$ngif} pppoe{$i} pppoe{$i}
1022
	{$isssue_ip_type}
1023
	load pppoe_standart
1024

    
1025
EOD;
1026
			}
1027

    
1028
			$mpdconf .=<<<EOD
1029

    
1030
pppoe_standart:
1031
	set link type pppoe
1032
	set pppoe iface {$pppoe_interface}
1033
	set pppoe service "*"
1034
	set pppoe disable originate
1035
	set pppoe enable incoming
1036
	set bundle no multilink
1037
	set bundle enable compression
1038
	set bundle max-logins 1
1039
	set iface idle 0
1040
	set iface disable on-demand
1041
	set iface disable proxy-arp
1042
	set iface enable tcpmssfix
1043
	set iface mtu 1500
1044
	set link no pap chap
1045
	{$paporchap}
1046
	set link keep-alive 60 180
1047
	set ipcp yes vjcomp
1048
	set ipcp no vjcomp
1049
	set link max-redial -1
1050
	set link mtu 1492
1051
	set link mru 1492
1052
	set ccp yes mpp-e40
1053
	set ccp yes mpp-e128
1054
	set ccp yes mpp-stateless
1055
	set link latency 1
1056
	#set ipcp dns 10.10.1.3
1057
	#set bundle accept encryption
1058

    
1059
EOD;
1060

    
1061
			if (isset ($config['dnsmasq']['enable'])) {
1062
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
1063
				if ($syscfg['dnsserver'][0])
1064
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1065
				$mpdconf .= "\n";
1066
			} else
1067
				if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1068
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1069
				}
1070

    
1071
			if (isset ($pppoecfg['radius']['enable'])) {
1072
				$mpdconf .=<<<EOD
1073
	set radius server {$pppoecfg['radius']['server']} "{$pppoecfg['radius']['secret']}"
1074
	set ipcp radius-ip
1075
	set radius retries 3
1076
	set radius timeout 10
1077
	set bundle enable radius-auth
1078
	set bundle disable radius-fallback
1079

    
1080
EOD;
1081

    
1082
				if (isset ($pppoecfg['radius']['accounting'])) {
1083
					$mpdconf .=<<<EOD
1084
	set bundle enable radius-acct
1085

    
1086
EOD;
1087
				}
1088
			}
1089

    
1090
			fwrite($fd, $mpdconf);
1091
			fclose($fd);
1092

    
1093
			/* write mpd.links */
1094
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.links", "a");
1095
			if (!$fd) {
1096
				printf("Error: cannot open mpd.links in vpn_pppoe_configure().\n");
1097
				return 1;
1098
			}
1099

    
1100
			$mpdlinks = "";
1101

    
1102
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1103
				$mpdlinks .=<<<EOD
1104

    
1105
pppoe:
1106
	set link type pppoe
1107
	set pppoe iface {$pppoe_interface}
1108

    
1109
EOD;
1110
			}
1111

    
1112
			fwrite($fd, $mpdlinks);
1113
			fclose($fd);
1114

    
1115
			/* write mpd.secret */
1116
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.secret", "a");
1117
			if (!$fd) {
1118
				printf("Error: cannot open mpd.secret in vpn_pppoe_configure().\n");
1119
				return 1;
1120
			}
1121

    
1122
			$mpdsecret = "\n\n";
1123

    
1124
			if (is_array($pppoecfg['user'])) {
1125
				foreach ($pppoecfg['user'] as $user)
1126
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1127
			}
1128

    
1129
			fwrite($fd, $mpdsecret);
1130
			fclose($fd);
1131
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
1132

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

    
1136
			break;
1137

    
1138
		case 'redir' :
1139
			break;
1140
	}
1141

    
1142
	touch("{$g["tmp_path"]}/filter_dirty");
1143

    
1144
	if ($g['booting'])
1145
		echo "done\n";
1146

    
1147
	return 0;
1148
}
1149

    
1150
function vpn_l2tp_configure() {
1151
	global $config, $g;
1152

    
1153
	$syscfg = $config['system'];
1154
	$l2tpcfg = $config['l2tp'];
1155

    
1156
	mwexec("/sbin/kldload /boot/kernel/ng_l2tp.ko");
1157

    
1158
	$starting_ng = get_number_of_wan_netgraph_interfaces_needed();
1159

    
1160
	/* create directory if it does not exist */
1161
	if (!is_dir("{$g['varetc_path']}/mpd-vpn"))
1162
		mkdir("{$g['varetc_path']}/mpd-vpn");
1163

    
1164
	if ($g['booting']) {
1165
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1166
			return 0;
1167

    
1168
		echo "Configuring l2tp VPN service... ";
1169
	} else {
1170
		/* kill mpd */
1171
		killbypid("{$g['varrun_path']}/mpd-vpn.pid");
1172

    
1173
		/* wait for process to die */
1174
		sleep(2);
1175

    
1176
	}
1177

    
1178
	/* make sure mpd-vpn directory exists */
1179
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
1180
		mkdir("{$g['varetc_path']}/mpd-vpn");
1181

    
1182
	switch ($l2tpcfg['mode']) {
1183

    
1184
		case 'server' :
1185

    
1186
			$l2tp_interface = filter_translate_type_to_real_interface($l2tpcfg['interface']);
1187

    
1188
			if ($l2tpcfg['paporchap'] == "chap")
1189
				$paporchap = "set link enable chap";
1190
			else
1191
				$paporchap = "set link enable pap";
1192

    
1193
			/* write mpd.conf */
1194
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.conf", "a");
1195
			if (!$fd) {
1196
				printf("Error: cannot open mpd.conf in vpn_l2tp_configure().\n");
1197
				return 1;
1198
			}
1199
			$mpdconf = "\n\n";
1200
			$mpdconf .=<<<EOD
1201
l2tp:
1202

    
1203
EOD;
1204

    
1205
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1206
				$mpdconf .= "	load l2tp{$i}\n";
1207
			}
1208

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

    
1211
				$clientip = long2ip(ip2long($l2tpcfg['remoteip']) + $i);
1212
				$ngif = "ng" . ($i + $starting_ng);
1213

    
1214
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1215
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1216
					$isssue_ip_type .= "\n\tset ipcp yes radius-ip";
1217
				} else {
1218
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1219
				}
1220

    
1221
				$mpdconf .=<<<EOD
1222

    
1223
l2tp{$i}:
1224
	new -i {$ngif} l2tp{$i} l2tp{$i}
1225
	{$isssue_ip_type}
1226
	load l2tp_standard
1227

    
1228
EOD;
1229
			}
1230

    
1231
			$mpdconf .=<<<EOD
1232

    
1233
l2tp_standard:
1234
        set bundle disable multilink
1235
        set bundle enable compression
1236
        set bundle yes crypt-reqd
1237
        set ipcp yes vjcomp
1238
        # set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1239
        set ccp yes mppc
1240
        set iface disable on-demand
1241
        set iface enable proxy-arp
1242
        set link yes acfcomp protocomp
1243
        set link no pap chap
1244
        set link enable chap
1245
        set link keep-alive 10 180
1246

    
1247
EOD;
1248

    
1249
			if (isset ($config['dnsmasq']['enable'])) {
1250
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
1251
				if ($syscfg['dnsserver'][0])
1252
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1253
				$mpdconf .= "\n";
1254
			} else
1255
				if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1256
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1257
				}
1258

    
1259
			if (isset ($l2tpcfg['radius']['enable'])) {
1260
				$mpdconf .=<<<EOD
1261
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1262
	set ipcp radius-ip
1263
	set radius retries 3
1264
	set radius timeout 10
1265
	set bundle enable radius-auth
1266
	set bundle disable radius-fallback
1267

    
1268
EOD;
1269

    
1270
				if (isset ($l2tpcfg['radius']['accounting'])) {
1271
					$mpdconf .=<<<EOD
1272
	set bundle enable radius-acct
1273

    
1274
EOD;
1275
				}
1276
			}
1277

    
1278
			fwrite($fd, $mpdconf);
1279
			fclose($fd);
1280

    
1281
			/* write mpd.links */
1282
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.links", "a");
1283
			if (!$fd) {
1284
				printf("Error: cannot open mpd.links in vpn_l2tp_configure().\n");
1285
				return 1;
1286
			}
1287

    
1288
			$mpdlinks = "";
1289

    
1290
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1291
				$mpdlinks .=<<<EOD
1292

    
1293
l2tp:
1294
	set link type l2tp
1295
	set l2tp iface {$l2tp_interface}
1296

    
1297
EOD;
1298
			}
1299

    
1300
			fwrite($fd, $mpdlinks);
1301
			fclose($fd);
1302

    
1303
			/* write mpd.secret */
1304
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.secret", "a");
1305
			if (!$fd) {
1306
				printf("Error: cannot open mpd.secret in vpn_l2tp_configure().\n");
1307
				return 1;
1308
			}
1309

    
1310
			$mpdsecret = "\n\n";
1311

    
1312
			if (is_array($l2tpcfg['user'])) {
1313
				foreach ($l2tpcfg['user'] as $user)
1314
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1315
			}
1316

    
1317
			fwrite($fd, $mpdsecret);
1318
			fclose($fd);
1319
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
1320

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

    
1324
			break;
1325

    
1326
		case 'redir' :
1327
			break;
1328
	}
1329

    
1330
	touch("{$g["tmp_path"]}/filter_dirty");
1331

    
1332
	if ($g['booting'])
1333
		echo "done\n";
1334

    
1335
	return 0;
1336
}
1337

    
1338
/* Forcefully restart IPsec
1339
 * This is required for when dynamic interfaces reload
1340
 * For all other occasions the normal vpn_ipsec_configure()
1341
 * will gracefully reload the settings without restarting
1342
 */
1343
function vpn_ipsec_force_reload() {
1344
	global $config;
1345
	global $g;
1346

    
1347
	$ipseccfg = $config['ipsec'];
1348

    
1349
	/* kill racoon */
1350
	mwexec("/usr/bin/killall racoon");
1351

    
1352
	/* wait for process to die */
1353
	sleep(4);
1354

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

    
1358
	/* wait for flushing to finish */
1359
	sleep(1);
1360

    
1361
	/* if ipsec is enabled, start up again */
1362
	if (isset($ipseccfg['enable'])) {
1363
		log_error("Forcefully reloading IPsec racoon daemon");
1364
		vpn_ipsec_configure();
1365
	}
1366

    
1367
}
1368

    
1369
?>
(24-24/29)