Project

General

Profile

Download (37.6 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("/usr/local/sbin/setkey -F");
118
			//mwexec("/usr/local/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("/usr/local/sbin/setkey -FP");
160
		mwexec("/usr/local/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

    
233
					/* if list */
234
        				$iflist = get_configured_interface_list();
235

    
236
			            foreach ($iflist as $ifent => $ifname) {
237
			            	$interface_ip = find_interface_ip($config['interfaces'][$ifname]['if']);
238
			            	if (ip_in_subnet($interface_ip, $sa . "/" . $sn))
239
			                	$srcip = find_interface_ip($config['interfaces'][$ifname]['if']);
240
			            }
241
						$dstip = $tunnel['pinghost'];
242
						fwrite($pfd, "$srcip|$dstip|3\n");
243
						fclose($pfd);
244
					}
245

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

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

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

    
269
					/* static route needed? */
270
					if(preg_match("/^carp/i", $tunnel['interface'])) {
271
						$parentinterface = link_carp_interface_to_parent($tunnel['interface']);
272
					} else {
273
						$parentinterface = $tunnel['interface'];
274
					}
275
					if($parentinterface <> "wan") {
276
						/* add endpoint routes to correct gateway on interface */
277
						if(interface_has_gateway($parentinterface)) {
278
							$gatewayip = get_interface_gateway("$parentinterface");
279
							$interfaceip = $config['interfaces'][$parentinterface]['ipaddr'];
280
							$subnet_bits = $config['interfaces'][$parentinterface]['subnet'];
281
							$subnet_ip = gen_subnet("{$interfaceip}", "{$subnet_bits}");
282
							/* if the remote gateway is in the local subnet, then don't add a route */
283
							if(! ip_in_subnet($tunnel['remote-gateway'], "{$subnet_ip}/{$subnet_bits}")) {
284
								if(is_ipaddr($gatewayip)) {
285
									log_error("IPSEC interface is not WAN but {$tunnel['interface']}, adding static route for VPN endpoint {$tunnel['remote-gateway']} via {$gatewayip}");
286
									mwexec("/sbin/route delete -host {$tunnel['remote-gateway']};/sbin/route add -host {$tunnel['remote-gateway']} {$gatewayip}");
287
								}
288
							}
289
						}
290
					} else {
291
						mwexec("/sbin/route delete -host {$tunnel['remote-gateway']}");
292
					}
293

    
294
				}
295

    
296
				fwrite($fd, $spdconf);
297
				fclose($fd);
298
			}
299

    
300
			/* generate racoon.conf */
301
			$fd = fopen("{$g['varetc_path']}/racoon.conf", "w");
302
			if (!$fd) {
303
				printf("Error: cannot open racoon.conf in vpn_ipsec_configure().\n");
304
				return 1;
305
			}
306

    
307
			$racoonconf = "";
308

    
309
			$racoonconf .= "path pre_shared_key \"{$g['varetc_path']}/psk.txt\";\n\n";
310
			$racoonconf .= "path certificate  \"{$g['varetc_path']}\";\n\n";
311

    
312
			/* generate CA certificates files */
313
			$cacertnum = 0;
314
			if (is_array($ipseccfg['cacert']) && count($ipseccfg['cacert']))
315
				foreach ($ipseccfg['cacert'] as $cacert) {
316
					++ $cacertnum;
317
					if (isset ($cacert['cert'])) {
318
						$cert = base64_decode($cacert['cert']);
319
						$x509cert = openssl_x509_parse(openssl_x509_read($cert));
320
						if (is_array($x509cert) && isset ($x509cert['hash'])) {
321
							$fd1 = fopen("{$g['varetc_path']}/{$x509cert['hash']}.0", "w");
322
							if (!$fd1) {
323
								printf("Error: cannot open {$x509cert['hash']}.0 in vpn.\n");
324
								return 1;
325
							}
326
							chmod("{$g['varetc_path']}/{$x509cert['hash']}.0", 0600);
327
							fwrite($fd1, $cert);
328
							fclose($fd1);
329
						}
330
					}
331
				}
332

    
333
			$tunnelnumber = 0;
334
			if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel']))
335
				foreach ($ipseccfg['tunnel'] as $tunnel) {
336

    
337
					++ $tunnelnumber;
338

    
339
					if (isset ($tunnel['disabled']))
340
						continue;
341

    
342

    
343
					  $rgip = $rgmap[$tunnel['remote-gateway']];
344
					   if (!$rgip)
345
					           continue;
346

    
347
					$ep = vpn_endpoint_determine($tunnel, $curwanip);
348
					if (!$ep)
349
						continue;
350

    
351
					vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn);
352

    
353
					if (isset ($tunnel['p1']['myident']['myaddress'])) {
354
						$myidentt = "address";
355
						$myident = $ep;
356
					} elseif (isset ($tunnel['p1']['myident']['address'])) {
357
						$myidentt = "address";
358
						$myident = $tunnel['p1']['myident']['address'];
359
					} elseif (isset ($tunnel['p1']['myident']['fqdn'])) {
360
						$myidentt = "fqdn";
361
						$myident = $tunnel['p1']['myident']['fqdn'];
362
					} elseif (isset ($tunnel['p1']['myident']['ufqdn'])) {
363
						$myidentt = "user_fqdn";
364
						$myident = $tunnel['p1']['myident']['ufqdn'];
365
					} else if (isset($tunnel['p1']['myident']['asn1dn'])) {
366
						$myidentt = "asn1dn";
367
						$myident = $tunnel['p1']['myident']['asn1dn'];					
368
					} else if (isset($tunnel['p1']['myident']['asn1dn'])) {
369
						$myidentt = "asn1dn";
370
						$myident = $tunnel['p1']['myident']['asn1dn'];						
371
					} elseif (isset ($tunnel['p1']['myident']['dyn_dns'])) {
372
						$myidentt = "dyn_dns";
373
						$myident = gethostbyname($tunnel['p1']['myident']['dyn_dns']);
374
					}
375

    
376
					if (!($myidentt == "asn1dn" && $myident == "")) {
377
						$myident = " \"{$myident}\"";
378
					}
379

    
380
					$nattline = '';
381
					if (isset($tunnel['natt'])) {
382
						$nattline = "nat_traversal on;";
383
					}
384

    
385
					if (isset ($tunnel['p1']['authentication_method'])) {
386
						$authmethod = $tunnel['p1']['authentication_method'];
387
					} else {
388
						$authmethod = 'pre_shared_key';
389
					}
390

    
391
					$certline = '';
392

    
393
					if ($authmethod == 'rsasig') {
394
						if ($tunnel['p1']['cert'] && $tunnel['p1']['private-key']) {
395
							$cert = base64_decode($tunnel['p1']['cert']);
396
							$private_key = base64_decode($tunnel['p1']['private-key']);
397
						} else {
398
							/* null certificate/key */
399
							$cert = '';
400
							$private_key = '';
401
						}
402

    
403
						if ($tunnel['p1']['peercert'])
404
							$peercert = base64_decode($tunnel['p1']['peercert']);
405
						else
406
							$peercert = '';
407

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

    
417
						$fd1 = fopen("{$g['varetc_path']}/server{$tunnelnumber}-key.pem", "w");
418
						if (!$fd1) {
419
							printf("Error: cannot open server{$tunnelnumber}-key.pem in vpn.\n");
420
							return 1;
421
						}
422
						chmod("{$g['varetc_path']}/server{$tunnelnumber}-key.pem", 0600);
423
						fwrite($fd1, $private_key);
424
						fclose($fd1);
425

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

    
428
						if ($peercert != '') {
429
							$fd1 = fopen("{$g['varetc_path']}/peer{$tunnelnumber}-signed.pem", "w");
430
							if (!$fd1) {
431
								printf("Error: cannot open server{$tunnelnumber}-signed.pem in vpn.\n");
432
								return 1;
433
							}
434
							chmod("{$g['varetc_path']}/peer{$tunnelnumber}-signed.pem", 0600);
435
							fwrite($fd1, $peercert);
436
							fclose($fd1);
437
							$certline .=<<<EOD
438

    
439
	peers_certfile "peer{$tunnelnumber}-signed.pem";
440
EOD;
441
						}
442
					}
443
					$myidentifier = $myidentt;
444
					if (!empty($myident)) 
445
						$myidentifier .= ' "' . $myident . '"';					
446
					$racoonconf .=<<<EOD
447
remote {$tunnel['remote-gateway']} {
448
	exchange_mode {$tunnel['p1']['mode']};
449
	my_identifier {$myidentt}{$myident};
450
	{$nattline}
451
	{$certline}
452
	peers_identifier address {$rgip};
453
	initial_contact on;
454
	dpd_delay 120;                   # DPD poll every 120 seconds
455
	ike_frag on;
456
	support_proxy on;
457
	proposal_check obey;
458

    
459
	proposal \{
460
		encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
461
		hash_algorithm {$tunnel['p1']['hash-algorithm']};
462
		authentication_method {$authmethod};
463
		dh_group {$tunnel['p1']['dhgroup']};
464

    
465
EOD;
466
					if ($tunnel['p1']['lifetime'])
467
						$racoonconf .= "		lifetime time {$tunnel['p1']['lifetime']} secs;\n";
468

    
469
					$racoonconf .= "	}\n";
470

    
471
					if ($tunnel['p1']['lifetime'])
472
						$racoonconf .= "	lifetime time {$tunnel['p1']['lifetime']} secs;\n";
473

    
474
					$racoonconf .= "}\n\n";
475

    
476
					$p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']);
477
					$p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']);
478

    
479
					$racoonconf .=<<<EOD
480
sainfo address {$sa}/{$sn} any address {$tunnel['remote-subnet']} any \{
481
	encryption_algorithm {$p2ealgos};
482
	authentication_algorithm {$p2halgos};
483
	compression_algorithm deflate;
484

    
485
EOD;
486

    
487
					if ($tunnel['p2']['pfsgroup'])
488
						$racoonconf .= "	pfs_group {$tunnel['p2']['pfsgroup']};\n";
489

    
490
					if ($tunnel['p2']['lifetime'])
491
						$racoonconf .= "	lifetime time {$tunnel['p2']['lifetime']} secs;\n";
492

    
493
					$racoonconf .= "}\n\n";
494
				}
495

    
496
			/* mobile clients? */
497
			if (isset ($ipseccfg['mobileclients']['enable'])) {
498

    
499
				$tunnel = $ipseccfg['mobileclients'];
500

    
501
				if (isset ($tunnel['p1']['myident']['myaddress'])) {
502
					$myidentt = "address";
503
					$myident = $curwanip;
504
				} else
505
					if (isset ($tunnel['p1']['myident']['address'])) {
506
						$myidentt = "address";
507
						$myident = $tunnel['p1']['myident']['address'];
508
					} else
509
						if (isset ($tunnel['p1']['myident']['fqdn'])) {
510
							$myidentt = "fqdn";
511
							$myident = $tunnel['p1']['myident']['fqdn'];
512
						} else
513
							if (isset ($tunnel['p1']['myident']['ufqdn'])) {
514
								$myidentt = "user_fqdn";
515
								$myident = $tunnel['p1']['myident']['ufqdn'];
516
							}
517

    
518
				if (isset ($tunnel['p1']['authentication_method'])) {
519
					$authmethod = $tunnel['p1']['authentication_method'];
520
				} else {
521
					$authmethod = 'pre_shared_key';
522
				}
523

    
524
				$certline = '';
525
				if ($authmethod == 'rsasig') {
526
					if ($tunnel['p1']['cert'] && $tunnel['p1']['private-key']) {
527
						$cert = base64_decode($tunnel['p1']['cert']);
528
						$private_key = base64_decode($tunnel['p1']['private-key']);
529
					} else {
530
						/* null certificate/key */
531
						$cert = '';
532
						$private_key = '';
533
					}
534

    
535
					if ($tunnel['p1']['peercert'])
536
						$peercert = base64_decode($tunnel['p1']['peercert']);
537
					else
538
						$peercert = '';
539

    
540
					$fd1 = fopen("{$g['varetc_path']}/server-mobile{$tunnelnumber}-signed.pem", "w");
541
					if (!$fd1) {
542
						printf("Error: cannot open server-mobile{$tunnelnumber}-signed.pem in vpn.\n");
543
						return 1;
544
					}
545
					chmod("{$g['varetc_path']}/server-mobile{$tunnelnumber}-signed.pem", 0600);
546
					fwrite($fd1, $cert);
547
					fclose($fd1);
548

    
549
					$fd1 = fopen("{$g['varetc_path']}/server-mobile{$tunnelnumber}-key.pem", "w");
550
					if (!$fd1) {
551
						printf("Error: cannot open server-mobile{$tunnelnumber}-key.pem in vpn.\n");
552
						return 1;
553
					}
554
					chmod("{$g['varetc_path']}/server-mobile{$tunnelnumber}-key.pem", 0600);
555
					fwrite($fd1, $private_key);
556
					fclose($fd1);
557

    
558
					$certline = "certificate_type x509 \"server-mobile{$tunnelnumber}-signed.pem\" \"server-mobile{$tunnelnumber}-key.pem\";";
559
				}
560
				$racoonconf .=<<<EOD
561
remote anonymous \{
562
	exchange_mode {$tunnel['p1']['mode']};
563
	my_identifier {$myidentt}{$myident};
564
	{$certline}
565
	initial_contact on;
566
	dpd_delay 120;                   # DPD poll every 120 seconds
567
	ike_frag on;
568
	passive on;
569
	generate_policy on;
570
	support_proxy on;
571
	proposal_check obey;
572

    
573
	proposal \{
574
		encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
575
		hash_algorithm {$tunnel['p1']['hash-algorithm']};
576
		authentication_method {$authmethod};
577
		dh_group {$tunnel['p1']['dhgroup']};
578

    
579
EOD;
580
				if ($tunnel['p1']['lifetime'])
581
					$racoonconf .= "		lifetime time {$tunnel['p1']['lifetime']} secs;\n";
582

    
583
				$racoonconf .= "	}\n";
584

    
585
				if ($tunnel['p1']['lifetime'])
586
					$racoonconf .= "	lifetime time {$tunnel['p1']['lifetime']} secs;\n";
587

    
588
				$racoonconf .= "}\n\n";
589

    
590
				$p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']);
591
				$p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']);
592

    
593
				$racoonconf .=<<<EOD
594
sainfo anonymous \{
595
	encryption_algorithm {$p2ealgos};
596
	authentication_algorithm {$p2halgos};
597
	compression_algorithm deflate;
598

    
599
EOD;
600

    
601
				if ($tunnel['p2']['pfsgroup'])
602
					$racoonconf .= "	pfs_group {$tunnel['p2']['pfsgroup']};\n";
603

    
604
				if ($tunnel['p2']['lifetime'])
605
					$racoonconf .= "	lifetime time {$tunnel['p2']['lifetime']} secs;\n";
606

    
607
				$racoonconf .= "}\n\n";
608
			}
609

    
610
			fwrite($fd, $racoonconf);
611
			fclose($fd);
612

    
613
			/* generate psk.txt */
614
			$fd = fopen("{$g['varetc_path']}/psk.txt", "w");
615
			if (!$fd) {
616
				printf("Error: cannot open psk.txt in vpn_ipsec_configure().\n");
617
				return 1;
618
			}
619

    
620
			$pskconf = "";
621

    
622
			if (is_array($ipseccfg['tunnel'])) {
623
				foreach ($ipseccfg['tunnel'] as $tunnel) {
624
					if (isset ($tunnel['disabled']))
625
						continue;
626
                   $rgip = $rgmap[$tunnel['remote-gateway']];
627
                   if (!$rgip)
628
                           continue;
629
                   $pskconf .= "{$rgip}     {$tunnel['p1']['pre-shared-key']}\n";
630
				}
631
			}
632

    
633
			/* add PSKs for mobile clients */
634
			if (is_array($ipseccfg['mobilekey'])) {
635
				foreach ($ipseccfg['mobilekey'] as $key) {
636
					$pskconf .= "{$key['ident']}	{$key['pre-shared-key']}\n";
637
				}
638
			}
639

    
640
			fwrite($fd, $pskconf);
641
			fclose($fd);
642
			chmod("{$g['varetc_path']}/psk.txt", 0600);
643

    
644

    
645
			if(is_process_running("racoon")) {
646
				/* We are already online, reload */
647
				mwexec("/usr/bin/killall -HUP racoon");
648
				/* flush SPD entries */
649
				mwexec("/usr/local/sbin/setkey -FP");
650
				mwexec("/usr/local/sbin/setkey -F");
651
				/* load SPD */
652
				mwexec("/usr/local/sbin/setkey -f {$g['varetc_path']}/spd.conf");
653
				sleep(1);
654
				/* We are already online, reload */
655
				mwexec("/usr/bin/killall -HUP racoon");
656
				sleep(1);
657
				mwexec("/usr/bin/killall -HUP racoon");
658
			} else {
659
				/* start racoon */
660
				mwexec("/usr/local/sbin/racoon -f {$g['varetc_path']}/racoon.conf");
661
				/* flush SA + SPD  entries*/
662
				mwexec("/usr/local/sbin/setkey -FP");
663
				mwexec("/usr/local/sbin/setkey -F");
664
				/* load SPD */
665
				mwexec("/usr/local/sbin/setkey -f {$g['varetc_path']}/spd.conf");
666
				sleep(1);
667
				/* We are already online, reload */
668
				mwexec("/usr/bin/killall -HUP racoon");
669
				sleep(1);
670
				mwexec("/usr/bin/killall -HUP racoon");
671

    
672
				/* start dnswatch, if necessary */
673
				if (count($dnswatch_list) > 0) {
674
					$interval = 60;
675
					if ($ipseccfg['dns-interval']) {
676
						$interval = $ipseccfg['dns-interval'];
677
					}
678
			
679
					$hostnames = "";
680
					foreach ($dnswatch_list as $dns) {
681
						$hostnames .= " " . escapeshellarg($dns);
682
					}
683
					mwexec("/usr/local/bin/dnswatch {$g['varrun_path']}/dnswatch-ipsec.pid $interval " .
684
					escapeshellarg("/etc/rc.newipsecdns") . $hostnames);
685
				}
686
			}
687

    
688
			if (is_array($ipseccfg['tunnel'])) {
689
				foreach ($ipseccfg['tunnel'] as $tunnel) {
690
					if (isset ($tunnel['auto'])) {
691
						$remotehost = substr($tunnel['remote-subnet'], 0, strpos($tunnel['remote-subnet'], "/"));
692
						$srchost = vpn_endpoint_determine($tunnel, $curwanip);
693
						if ($srchost)
694
							mwexec_bg("/sbin/ping -c 10 -S {$srchost} {$remotehost}");
695
					}
696
				}
697
			}
698
		}
699
	}
700

    
701
	vpn_ipsec_failover_configure();
702

    
703
	if (!$g['booting']) {
704
		/* reload the filter */
705
		touch("{$g["tmp_path"]}/filter_dirty");
706
	}
707

    
708
	if ($g['booting'])
709
		echo "done\n";
710

    
711
	return 0;
712
}
713

    
714
function vpn_pptpd_configure() {
715
	global $config, $g;
716

    
717
	$syscfg = $config['system'];
718
	$pptpdcfg = $config['pptpd'];
719

    
720
	$starting_ng = get_number_of_wan_netgraph_interfaces_needed();
721

    
722
	if ($g['booting']) {
723
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
724
			return 0;
725

    
726
		echo "Configuring PPTP VPN service... ";
727
	} else {
728
		/* kill mpd */
729
		killbypid("{$g['varrun_path']}/mpd-vpn.pid");
730

    
731
		/* wait for process to die */
732
		sleep(3);
733

    
734
		if (is_process_running("mpd -b")) {
735
			killbypid("{$g['varrun_path']}/mpd-vpn.pid");
736
			log_error("Could not kill mpd within 3 seconds.   Trying again.");
737
		}
738

    
739
		/* remove mpd.conf, if it exists */
740
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.conf");
741
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.links");
742
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.secret");
743
	}
744

    
745
	/* make sure mpd-vpn directory exists */
746
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
747
		mkdir("{$g['varetc_path']}/mpd-vpn");
748

    
749
	switch ($pptpdcfg['mode']) {
750
		case 'server' :
751
			/* write mpd.conf */
752
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.conf", "w");
753
			if (!$fd) {
754
				printf("Error: cannot open mpd.conf in vpn_pptpd_configure().\n");
755
				return 1;
756
			}
757

    
758
			$mpdconf =<<<EOD
759
pptpd:
760

    
761
EOD;
762

    
763
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
764
				$mpdconf .= "	load pt{$i}\n";
765
			}
766

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

    
769
				$clientip = long2ip(ip2long($pptpdcfg['remoteip']) + $i);
770
				$ngif = "ng" . ($i + $starting_ng);
771

    
772
				if(isset($pptpdcfg['radius']['radiusissueips']) && isset($pptpdcfg['radius']['enable'])) {
773
					$isssue_ip_type = "set ipcp ranges {$pptpdcfg['localip']}/32 0.0.0.0/0";
774
					$isssue_ip_type .="\n\tset ipcp yes radius-ip";
775
				} else {
776
					$isssue_ip_type = "set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32";
777
				}
778

    
779
				$mpdconf .=<<<EOD
780

    
781
pt{$i}:
782
	new -i {$ngif} pt{$i} pt{$i}
783
	{$isssue_ip_type}
784
	load pts
785

    
786
EOD;
787
			}
788

    
789
			$mpdconf .=<<<EOD
790

    
791
pts:
792
	set iface disable on-demand
793
	set iface enable proxy-arp
794
	set iface enable tcpmssfix
795
	set iface idle 1800
796
	set iface up-script /usr/local/sbin/vpn-linkup
797
	set iface down-script /usr/local/sbin/vpn-linkdown
798
	set bundle enable multilink
799
	set bundle enable crypt-reqd
800
	set link yes acfcomp protocomp
801
	set link no pap chap
802
	set link enable chap-msv2
803
	set link mtu 1460
804
	set link keep-alive 10 60
805
	set ipcp yes vjcomp
806
	set bundle enable compression
807
	set ccp yes mppc
808
	set ccp yes mpp-e128
809
	set ccp yes mpp-stateless
810

    
811
EOD;
812

    
813
			if (!isset ($pptpdcfg['req128'])) {
814
				$mpdconf .=<<<EOD
815
	set ccp yes mpp-e40
816
	set ccp yes mpp-e56
817

    
818
EOD;
819
			}
820

    
821
			if  (isset($pptpdcfg["wins"]))
822
				$mpdconf  .=  "	set ipcp nbns {$pptpdcfg['wins']}\n";
823
			if (is_array($pptpdcfg['dnsserver']) && ($pptpdcfg['dnsserver'][0])) {
824
				$mpdconf .= "	set ipcp dns " . join(" ", $pptpdcfg['dnsserver']) . "\n";
825
			} else
826
				if (isset ($config['dnsmasq']['enable'])) {
827
					$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
828
					if ($syscfg['dnsserver'][0])
829
						$mpdconf .= " " . $syscfg['dnsserver'][0];
830
					$mpdconf .= "\n";
831
				} else
832
					if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
833
						$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
834
					}
835

    
836
			if (isset ($pptpdcfg['radius']['enable'])) {
837
				$authport = isset($pptpdcfg['radius']['port']) ? $pptpdcfg['radius']['port'] : 1812;
838
				$acctport = $authport + 1;
839
				$mpdconf .=<<<EOD
840
	set radius server {$pptpdcfg['radius']['server']} "{$pptpdcfg['radius']['secret']}" {$authport} {$acctport}
841
	set radius retries 3
842
	set radius timeout 10
843
	set bundle enable radius-auth
844
	set bundle disable radius-fallback
845

    
846
EOD;
847

    
848
				if (isset ($pptpdcfg['radius']['accounting'])) {
849
					$mpdconf .=<<<EOD
850
	set bundle enable radius-acct
851
	set radius acct-update 300
852

    
853
EOD;
854
				}
855
			}
856

    
857
			fwrite($fd, $mpdconf);
858
			fclose($fd);
859

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

    
867
			$mpdlinks = "";
868

    
869
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
870
				$mpdlinks .=<<<EOD
871

    
872
pt{$i}:
873
	set link type pptp
874
	set pptp enable incoming
875
	set pptp disable originate
876
	set pptp disable windowing
877
	set pptp self 127.0.0.1
878

    
879
EOD;
880
			}
881

    
882
			fwrite($fd, $mpdlinks);
883
			fclose($fd);
884

    
885
			/* write mpd.secret */
886
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.secret", "w");
887
			if (!$fd) {
888
				printf("Error: cannot open mpd.secret in vpn_pptpd_configure().\n");
889
				return 1;
890
			}
891

    
892
			$mpdsecret = "";
893

    
894
			if (is_array($pptpdcfg['user'])) {
895
				foreach ($pptpdcfg['user'] as $user)
896
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
897
			}
898

    
899
			fwrite($fd, $mpdsecret);
900
			fclose($fd);
901
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
902

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

    
906
			break;
907

    
908
		case 'redir' :
909
			break;
910
	}
911

    
912
	if (!$g['booting']) {
913
		/* reload the filter */
914
		filter_configure();
915
	}
916

    
917
	if ($g['booting'])
918
		echo "done\n";
919

    
920
	return 0;
921
}
922

    
923
function vpn_localnet_determine($adr, & $sa, & $sn) {
924
	global $config, $g;
925

    
926
	if (isset ($adr)) {
927
		if ($adr['network']) {
928
			switch ($adr['network']) {
929
				case 'lan' :
930
					$sn = $config['interfaces']['lan']['subnet'];
931
					$sa = gen_subnet($config['interfaces']['lan']['ipaddr'], $sn);
932
					break;
933
			}
934
		} else
935
			if ($adr['address']) {
936
				list ($sa, $sn) = explode("/", $adr['address']);
937
				if (is_null($sn))
938
					$sn = 32;
939
			}
940
	} else {
941
		$sn = $config['interfaces']['lan']['subnet'];
942
		$sa = gen_subnet($config['interfaces']['lan']['ipaddr'], $sn);
943
	}
944
}
945

    
946
function vpn_endpoint_determine($tunnel, $curwanip) {
947

    
948
	global $g, $config;
949

    
950
	if ((!$tunnel['interface']) || ($tunnel['interface'] == "wan")) {
951
		if ($curwanip)
952
			return $curwanip;
953
		else
954
			return null;
955
	} elseif ($tunnel['interface'] == "lan") {
956
		return $config['interfaces']['lan']['ipaddr'];
957
	} else {
958
		$iface = $config['interfaces'][$tunnel['interface']]['if'];
959
		$oc = $config['interfaces'][$tunnel['interface']];
960
		/* carp ips, etc */
961
		$ip = find_interface_ip($iface);
962
		if($ip) 
963
			return $ip;
964
			
965
		if (isset ($oc['enable']) && $oc['if']) {
966
			return $oc['ipaddr'];
967
		}
968
	}
969

    
970
	return null;
971
}
972

    
973
function vpn_pppoe_configure() {
974
	global $config, $g;
975

    
976
	$syscfg = $config['system'];
977
	$pppoecfg = $config['pppoe'];
978

    
979
	$starting_ng = get_number_of_wan_netgraph_interfaces_needed();
980

    
981
	/* create directory if it does not exist */
982
	if (!is_dir("{$g['varetc_path']}/mpd-vpn"))
983
		mkdir("{$g['varetc_path']}/mpd-vpn");
984

    
985
	if ($g['booting']) {
986
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
987
			return 0;
988

    
989
		echo "Configuring PPPoE VPN service... ";
990
	} else {
991
		/* kill mpd */
992
		killbypid("{$g['varrun_path']}/mpd-vpn.pid");
993

    
994
		/* wait for process to die */
995
		sleep(2);
996

    
997
	}
998

    
999
	/* make sure mpd-vpn directory exists */
1000
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
1001
		mkdir("{$g['varetc_path']}/mpd-vpn");
1002

    
1003
	switch ($pppoecfg['mode']) {
1004

    
1005
		case 'server' :
1006

    
1007
			$pppoe_interface = filter_translate_type_to_real_interface($pppoecfg['interface']);
1008

    
1009
			if ($pppoecfg['paporchap'] == "chap")
1010
				$paporchap = "set link enable chap";
1011
			else
1012
				$paporchap = "set link enable pap";
1013

    
1014
			/* write mpd.conf */
1015
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.conf", "a");
1016
			if (!$fd) {
1017
				printf("Error: cannot open mpd.conf in vpn_pppoe_configure().\n");
1018
				return 1;
1019
			}
1020
			$mpdconf = "\n\n";
1021
			$mpdconf .=<<<EOD
1022
startup:
1023
pppoe:
1024

    
1025
EOD;
1026

    
1027
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1028
				$mpdconf .= "	load pppoe{$i}\n";
1029
			}
1030

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

    
1033
				$clientip = long2ip(ip2long($pppoecfg['remoteip']) + $i);
1034
				$ngif = "ng" . ($i + $starting_ng);
1035

    
1036
				if (isset ($pppoecfg['radius']['radiusissueips']) && isset ($pppoecfg['radius']['enable'])) {
1037
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1038
					$isssue_ip_type .= "\n\tset ipcp yes radius-ip";
1039
				} else {
1040
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1041
				}
1042

    
1043
				$mpdconf .=<<<EOD
1044

    
1045
pppoe{$i}:
1046
	new -i {$ngif} pppoe{$i} pppoe{$i}
1047
	{$isssue_ip_type}
1048
	load pppoe_standart
1049

    
1050
EOD;
1051
			}
1052

    
1053
			$mpdconf .=<<<EOD
1054

    
1055
pppoe_standart:
1056
	set bundle no multilink
1057
	set bundle enable compression
1058
	set auth max-logins 1
1059
	set iface idle 0
1060
	set iface disable on-demand
1061
	set iface disable proxy-arp
1062
	set iface enable tcpmssfix
1063
	set iface mtu 1500
1064
	set link no pap chap
1065
	{$paporchap}
1066
	set link keep-alive 60 180
1067
	set ipcp yes vjcomp
1068
	set ipcp no vjcomp
1069
	set link max-redial -1
1070
	set link mtu 1492
1071
	set link mru 1492
1072
	set ccp yes mpp-e40
1073
	set ccp yes mpp-e128
1074
	set ccp yes mpp-stateless
1075
	set link latency 1
1076
	#set ipcp dns 10.10.1.3
1077
	#set bundle accept encryption
1078

    
1079
EOD;
1080

    
1081
			if (isset ($config['dnsmasq']['enable'])) {
1082
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
1083
				if ($syscfg['dnsserver'][0])
1084
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1085
				$mpdconf .= "\n";
1086
			} else
1087
				if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1088
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1089
				}
1090

    
1091
			if (isset ($pppoecfg['radius']['enable'])) {
1092
				$mpdconf .=<<<EOD
1093
	set radius server {$pppoecfg['radius']['server']} "{$pppoecfg['radius']['secret']}"
1094
	set ipcp radius-ip
1095
	set radius retries 3
1096
	set radius timeout 10
1097
	set bundle enable radius-auth
1098
	set bundle disable radius-fallback
1099

    
1100
EOD;
1101

    
1102
				if (isset ($pppoecfg['radius']['accounting'])) {
1103
					$mpdconf .=<<<EOD
1104
	set bundle enable radius-acct
1105

    
1106
EOD;
1107
				}
1108
			}
1109

    
1110
			fwrite($fd, $mpdconf);
1111
			fclose($fd);
1112

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

    
1120
			$mpdlinks = "";
1121

    
1122
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1123
				$mpdlinks .=<<<EOD
1124

    
1125
pppoe{$i}:
1126
        set phys type pppoe
1127
        set pppoe iface {$pppoe_interface}
1128
        set pppoe service "*"
1129
        set pppoe disable originate
1130
        set pppoe enable incoming
1131

    
1132
EOD;
1133
			}
1134

    
1135
			fwrite($fd, $mpdlinks);
1136
			fclose($fd);
1137

    
1138
			/* write mpd.secret */
1139
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.secret", "a");
1140
			if (!$fd) {
1141
				printf("Error: cannot open mpd.secret in vpn_pppoe_configure().\n");
1142
				return 1;
1143
			}
1144

    
1145
			$mpdsecret = "\n\n";
1146

    
1147
			if (is_array($pppoecfg['user'])) {
1148
				foreach ($pppoecfg['user'] as $user)
1149
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1150
			}
1151

    
1152
			fwrite($fd, $mpdsecret);
1153
			fclose($fd);
1154
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
1155

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

    
1159
			break;
1160

    
1161
		case 'redir' :
1162
			break;
1163
	}
1164

    
1165
	touch("{$g["tmp_path"]}/filter_dirty");
1166

    
1167
	if ($g['booting'])
1168
		echo "done\n";
1169

    
1170
	return 0;
1171
}
1172

    
1173
function vpn_l2tp_configure() {
1174
	global $config, $g;
1175

    
1176
	$syscfg = $config['system'];
1177
	$l2tpcfg = $config['l2tp'];
1178

    
1179
	mwexec("/sbin/kldload /boot/kernel/ng_l2tp.ko");
1180

    
1181
	$starting_ng = get_number_of_wan_netgraph_interfaces_needed();
1182

    
1183
	/* create directory if it does not exist */
1184
	if (!is_dir("{$g['varetc_path']}/mpd-vpn"))
1185
		mkdir("{$g['varetc_path']}/mpd-vpn");
1186

    
1187
	if ($g['booting']) {
1188
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1189
			return 0;
1190

    
1191
		echo "Configuring l2tp VPN service... ";
1192
	} else {
1193
		/* kill mpd */
1194
		killbypid("{$g['varrun_path']}/mpd-vpn.pid");
1195

    
1196
		/* wait for process to die */
1197
		sleep(2);
1198

    
1199
	}
1200

    
1201
	/* make sure mpd-vpn directory exists */
1202
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
1203
		mkdir("{$g['varetc_path']}/mpd-vpn");
1204

    
1205
	switch ($l2tpcfg['mode']) {
1206

    
1207
		case 'server' :
1208

    
1209
			$l2tp_interface = filter_translate_type_to_real_interface($l2tpcfg['interface']);
1210

    
1211
			if ($l2tpcfg['paporchap'] == "chap")
1212
				$paporchap = "set link enable chap";
1213
			else
1214
				$paporchap = "set link enable pap";
1215

    
1216
			/* write mpd.conf */
1217
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.conf", "a");
1218
			if (!$fd) {
1219
				printf("Error: cannot open mpd.conf in vpn_l2tp_configure().\n");
1220
				return 1;
1221
			}
1222
			$mpdconf = "\n\n";
1223
			$mpdconf .=<<<EOD
1224
l2tp:
1225

    
1226
EOD;
1227

    
1228
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1229
				$mpdconf .= "	load l2tp{$i}\n";
1230
			}
1231

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

    
1234
				$clientip = long2ip(ip2long($l2tpcfg['remoteip']) + $i);
1235
				$ngif = "ng" . ($i + $starting_ng);
1236

    
1237
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1238
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1239
					$isssue_ip_type .= "\n\tset ipcp yes radius-ip";
1240
				} else {
1241
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1242
				}
1243

    
1244
				$mpdconf .=<<<EOD
1245

    
1246
l2tp{$i}:
1247
	new -i {$ngif} l2tp{$i} l2tp{$i}
1248
	{$isssue_ip_type}
1249
	load l2tp_standard
1250

    
1251
EOD;
1252
			}
1253

    
1254
			$mpdconf .=<<<EOD
1255

    
1256
l2tp_standard:
1257
        set bundle disable multilink
1258
        set bundle enable compression
1259
        set bundle yes crypt-reqd
1260
        set ipcp yes vjcomp
1261
        # set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1262
        set ccp yes mppc
1263
        set iface disable on-demand
1264
        set iface enable proxy-arp
1265
        set link yes acfcomp protocomp
1266
        set link no pap chap
1267
        set link enable chap
1268
        set link keep-alive 10 180
1269

    
1270
EOD;
1271

    
1272
			if (isset ($config['dnsmasq']['enable'])) {
1273
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
1274
				if ($syscfg['dnsserver'][0])
1275
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1276
				$mpdconf .= "\n";
1277
			} else
1278
				if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1279
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1280
				}
1281

    
1282
			if (isset ($l2tpcfg['radius']['enable'])) {
1283
				$mpdconf .=<<<EOD
1284
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1285
	set ipcp radius-ip
1286
	set radius retries 3
1287
	set radius timeout 10
1288
	set bundle enable radius-auth
1289
	set bundle disable radius-fallback
1290

    
1291
EOD;
1292

    
1293
				if (isset ($l2tpcfg['radius']['accounting'])) {
1294
					$mpdconf .=<<<EOD
1295
	set bundle enable radius-acct
1296

    
1297
EOD;
1298
				}
1299
			}
1300

    
1301
			fwrite($fd, $mpdconf);
1302
			fclose($fd);
1303

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

    
1311
			$mpdlinks = "";
1312

    
1313
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1314
				$mpdlinks .=<<<EOD
1315

    
1316
l2tp:
1317
	set link type l2tp
1318
	set l2tp iface {$l2tp_interface}
1319

    
1320
EOD;
1321
			}
1322

    
1323
			fwrite($fd, $mpdlinks);
1324
			fclose($fd);
1325

    
1326
			/* write mpd.secret */
1327
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.secret", "a");
1328
			if (!$fd) {
1329
				printf("Error: cannot open mpd.secret in vpn_l2tp_configure().\n");
1330
				return 1;
1331
			}
1332

    
1333
			$mpdsecret = "\n\n";
1334

    
1335
			if (is_array($l2tpcfg['user'])) {
1336
				foreach ($l2tpcfg['user'] as $user)
1337
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1338
			}
1339

    
1340
			fwrite($fd, $mpdsecret);
1341
			fclose($fd);
1342
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
1343

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

    
1347
			break;
1348

    
1349
		case 'redir' :
1350
			break;
1351
	}
1352

    
1353
	touch("{$g["tmp_path"]}/filter_dirty");
1354

    
1355
	if ($g['booting'])
1356
		echo "done\n";
1357

    
1358
	return 0;
1359
}
1360

    
1361
/* Forcefully restart IPsec
1362
 * This is required for when dynamic interfaces reload
1363
 * For all other occasions the normal vpn_ipsec_configure()
1364
 * will gracefully reload the settings without restarting
1365
 */
1366
function vpn_ipsec_force_reload() {
1367
	global $config;
1368
	global $g;
1369

    
1370
	$ipseccfg = $config['ipsec'];
1371

    
1372
	/* kill racoon */
1373
	mwexec("/usr/bin/killall racoon");
1374

    
1375
	/* wait for process to die */
1376
	sleep(4);
1377

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

    
1381
	/* wait for flushing to finish */
1382
	sleep(1);
1383

    
1384
	/* if ipsec is enabled, start up again */
1385
	if (isset($ipseccfg['enable'])) {
1386
		log_error("Forcefully reloading IPsec racoon daemon");
1387
		vpn_ipsec_configure();
1388
	}
1389

    
1390
}
1391

    
1392
?>
(24-24/29)