Project

General

Profile

Download (28.4 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	vpn.inc
4
	Copyright (C) 2004-2006 Scott Ullrich
5
	All rights reserved.
6

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

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

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

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

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

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

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

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

    
45
function vpn_ipsec_failover_configure() {
46
	global $config, $g;
47

    
48
	$sasyncd_text = "";
49

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

    
69
	$fd = fopen("{$g['varetc_path']}/sasyncd.conf", "w");
70
	fwrite($fd, $sasyncd_text);
71
	fclose($fd);
72
	chmod("{$g['varetc_path']}/sasyncd.conf", 0600);
73

    
74
	mwexec("killall sasyncd");
75

    
76
	/* launch sasyncd, oh wise one */
77
	/* mwexec_bg("/usr/local/sbin/sasyncd -d -v -v -v"); */
78
}
79

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

    
97
function vpn_ipsec_configure($ipchg = false) {
98
	global $config, $g, $sa, $sn;
99

    
100
	mwexec("/sbin/ifconfig enc0 create");
101
	mwexec("/sbin/ifconfig enc0 up");
102

    
103
	/* get the automatic /etc/ping_hosts.sh ready */
104
	unlink_if_exists("/var/db/ipsecpinghosts");
105
	touch("/var/db/ipsecpinghosts");
106

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

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

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

    
131
	$curwanip = get_current_wan_address();
132

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

    
140
	if ($g['booting']) {
141
		if (!isset($ipseccfg['enable']))
142
			return 0;
143

    
144
		echo "Configuring IPsec VPN... ";
145
	} else {
146
		/* kill racoon */
147
		mwexec("/usr/bin/killall racoon");
148

    
149
		/* wait for process to die */
150
		sleep(2);
151

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

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

    
160
	if (isset($ipseccfg['enable'])) {
161

    
162
		/* fastforwarding is not compatible with ipsec tunnels */
163
		system("/sbin/sysctl net.inet.ip.fastforwarding=0 >/dev/null 2>&1");
164

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

    
172
		if ((is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) ||
173
				isset($ipseccfg['mobileclients']['enable'])) {
174

    
175
			if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) {
176

    
177
				/* generate spd.conf */
178
				$fd = fopen("{$g['varetc_path']}/spd.conf", "w");
179
				if (!$fd) {
180
					printf("Error: cannot open spd.conf in vpn_ipsec_configure().\n");
181
					return 1;
182
				}
183

    
184
				$spdconf = "";
185

    
186
				$spdconf .= "spdadd {$lansa}/{$lansn} {$lanip}/32 any -P in none;\n";
187
				$spdconf .= "spdadd {$lanip}/32 {$lansa}/{$lansn} any -P out none;\n";
188

    
189
				foreach ($ipseccfg['tunnel'] as $tunnel) {
190

    
191
					if (isset($tunnel['disabled']))
192
						continue;
193

    
194
					$ep = vpn_endpoint_determine($tunnel, $curwanip);
195
					if (!$ep) {
196
						log_error("Could not deterimine VPN endpoint for {$tunnel['descr']}");
197
						continue;	
198
					}
199

    
200
					vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn);
201

    
202
					if(is_domain($tunnel['remote-gateway'])) {
203
						$tmp = gethostbyname($tunnel['remote-gateway']);
204
						if($tmp)
205
							$tunnel['remote-gateway'] = $tmp;
206
					}
207

    
208
					/* add entry to host pinger */
209
					if($tunnel['pinghost']) {
210
						$pfd = fopen("/var/db/ipsecpinghosts","a");
211
						$srcip = find_interface_ip($config['interfaces']['lan']['if']);
212
						$dstip = $tunnel['pinghost'];
213
						fwrite($pfd, "$srcip|$dstip|3\n");
214
						fclose($pfd);
215
					}
216

    
217
					if(isset($tunnel['creategif'])) {
218
						$number_of_gifs = find_last_gif_device();
219
						$number_of_gifs++;
220
						$curwanip = get_current_wan_address();
221

    
222
						mwexec("/sbin/ifconfig gif" . $number_of_gifs . " tunnel" . $curwanip . " " . $tunnel['remote-gateway']);
223
						mwexec("/sbin/ifconfig gif" . $number_of_gifs . " {$lansa}/{$lansn} {$lanip}/32");
224
					}
225

    
226
					$spdconf .= "spdadd {$sa}/{$sn} " .
227
						"{$tunnel['remote-subnet']} any -P out ipsec " .
228
						"{$tunnel['p2']['protocol']}/tunnel/{$ep}-" .
229
						"{$tunnel['remote-gateway']}/unique;\n";
230

    
231
					$spdconf .= "spdadd {$tunnel['remote-subnet']} " .
232
						"{$sa}/{$sn} any -P in ipsec " .
233
						"{$tunnel['p2']['protocol']}/tunnel/{$tunnel['remote-gateway']}-" .
234
						"{$ep}/unique;\n";
235
				
236
					if($tunnel['interface'] <> "wan") {
237
						/* static route needed? */
238
						if(strstr("carp", $tunnel['interface'])) {
239
							
240
						}
241
					}
242
				}
243

    
244
				fwrite($fd, $spdconf);
245
				fclose($fd);
246

    
247
				/* load SPD */
248
				mwexec("/sbin/setkey -c < {$g['varetc_path']}/spd.conf");
249
			}
250

    
251
			/* generate racoon.conf */
252
			$fd = fopen("{$g['varetc_path']}/racoon.conf", "w");
253
			if (!$fd) {
254
				printf("Error: cannot open racoon.conf in vpn_ipsec_configure().\n");
255
				return 1;
256
			}
257

    
258
			$racoonconf = "";
259

    
260
			$racoonconf .= "path pre_shared_key \"{$g['varetc_path']}/psk.txt\";\n\n";
261
			$racoonconf .= "path certificate  \"{$g['varetc_path']}\";\n\n";
262

    
263
			/* generate CA certificates files */
264
			$cacertnum = 0;
265
			if (is_array($ipseccfg['cacert']) && count($ipseccfg['cacert']))
266
				foreach ($ipseccfg['cacert'] as $cacert) {
267
					++$cacertnum;
268
					if (isset($cacert['cert'])) {
269
						$cert = base64_decode($cacert['cert']);
270
						$x509cert = openssl_x509_parse(openssl_x509_read($cert));
271
						if(is_array($x509cert) && isset($x509cert['hash'])) {
272
							$fd1 = fopen("{$g['varetc_path']}/{$x509cert['hash']}.0", "w");
273
							if (!$fd1) {
274
								printf("Error: cannot open {$x509cert['hash']}.0 in vpn.\n");
275
								return 1;
276
							}
277
							chmod("{$g['varetc_path']}/{$x509cert['hash']}.0", 0600);
278
							fwrite($fd1, $cert);
279
							fclose($fd1);
280
						}
281
					}
282
				}
283

    
284
			$tunnelnumber = 0;
285
			if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel']))
286
				foreach ($ipseccfg['tunnel'] as $tunnel) {
287

    
288
				++$tunnelnumber;
289

    
290
				if (isset($tunnel['disabled']))
291
					continue;
292

    
293
				$ep = vpn_endpoint_determine($tunnel, $curwanip);
294
				if (!$ep)
295
					continue;
296

    
297
				vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn);
298

    
299
				if (isset($tunnel['p1']['myident']['myaddress'])) {
300
					$myidentt = "address";
301
					$myident = $ep;
302
				} else if (isset($tunnel['p1']['myident']['address'])) {
303
					$myidentt = "address";
304
					$myident = $tunnel['p1']['myident']['address'];
305
				} else if (isset($tunnel['p1']['myident']['fqdn'])) {
306
					$myidentt = "fqdn";
307
					$myident = $tunnel['p1']['myident']['fqdn'];
308
				} else if (isset($tunnel['p1']['myident']['ufqdn'])) {
309
					$myidentt = "user_fqdn";
310
					$myident = $tunnel['p1']['myident']['ufqdn'];
311
 				} else if (isset($tunnel['p1']['myident']['dyn_dns'])) {
312
					$myidentt = "dyn_dns";
313
					$myident = gethostbyname($tunnel['p1']['myident']['dyn_dns']);
314
 				}
315

    
316
				if (isset($tunnel['p1']['authentication_method'])) {
317
					$authmethod = $tunnel['p1']['authentication_method'];
318
				} else {$authmethod = 'pre_shared_key';}
319

    
320
				$certline = '';
321

    
322
				if ($authmethod == 'rsasig') {
323
					if ($tunnel['p1']['cert'] && $tunnel['p1']['private-key']) {
324
						$cert = base64_decode($tunnel['p1']['cert']);
325
						$private_key = base64_decode($tunnel['p1']['private-key']);
326
					} else {
327
						/* null certificate/key */
328
						$cert = '';
329
						$private_key = '';
330
					}
331

    
332
					if ($tunnel['p1']['peercert'])
333
						$peercert = base64_decode($tunnel['p1']['peercert']);
334
					else
335
						$peercert = '';
336

    
337
					$fd1 = fopen("{$g['varetc_path']}/server{$tunnelnumber}-signed.pem", "w");
338
					if (!$fd1) {
339
						printf("Error: cannot open server{$tunnelnumber}-signed.pem in vpn.\n");
340
						return 1;
341
					}
342
					chmod("{$g['varetc_path']}/server{$tunnelnumber}-signed.pem", 0600);
343
					fwrite($fd1, $cert);
344
					fclose($fd1);
345

    
346
					$fd1 = fopen("{$g['varetc_path']}/server{$tunnelnumber}-key.pem", "w");
347
					if (!$fd1) {
348
						printf("Error: cannot open server{$tunnelnumber}-key.pem in vpn.\n");
349
						return 1;
350
					}
351
					chmod("{$g['varetc_path']}/server{$tunnelnumber}-key.pem", 0600);
352
					fwrite($fd1, $private_key);
353
					fclose($fd1);
354

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

    
357
					if ($peercert!=''){
358
						$fd1 = fopen("{$g['varetc_path']}/peer{$tunnelnumber}-signed.pem", "w");
359
						if (!$fd1) {
360
							printf("Error: cannot open server{$tunnelnumber}-signed.pem in vpn.\n");
361
							return 1;
362
						}
363
						chmod("{$g['varetc_path']}/peer{$tunnelnumber}-signed.pem", 0600);
364
						fwrite($fd1, $peercert);
365
						fclose($fd1);
366
						$certline .= <<<EOD
367

    
368
	peers_certfile "peer{$tunnelnumber}-signed.pem";
369
EOD;
370
					}
371
				}
372
				$racoonconf .= <<<EOD
373
remote {$tunnel['remote-gateway']} \{
374
	exchange_mode {$tunnel['p1']['mode']};
375
	my_identifier {$myidentt} "{$myident}";
376
	{$certline}
377
	peers_identifier address {$tunnel['remote-gateway']};
378
	initial_contact on;
379
	support_proxy on;
380
	proposal_check obey;
381

    
382
	proposal \{
383
		encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
384
		hash_algorithm {$tunnel['p1']['hash-algorithm']};
385
		authentication_method {$authmethod};
386
		dh_group {$tunnel['p1']['dhgroup']};
387

    
388
EOD;
389
				if ($tunnel['p1']['lifetime'])
390
					$racoonconf .= "		lifetime time {$tunnel['p1']['lifetime']} secs;\n";
391

    
392
				$racoonconf .= "	}\n";
393

    
394
				if ($tunnel['p1']['lifetime'])
395
					$racoonconf .= "	lifetime time {$tunnel['p1']['lifetime']} secs;\n";
396

    
397
				$racoonconf .= "}\n\n";
398

    
399
				$p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']);
400
				$p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']);
401

    
402
				$racoonconf .= <<<EOD
403
sainfo address {$sa}/{$sn} any address {$tunnel['remote-subnet']} any \{
404
	encryption_algorithm {$p2ealgos};
405
	authentication_algorithm {$p2halgos};
406
	compression_algorithm deflate;
407

    
408
EOD;
409

    
410
				if ($tunnel['p2']['pfsgroup'])
411
					$racoonconf .= "	pfs_group {$tunnel['p2']['pfsgroup']};\n";
412

    
413
				if ($tunnel['p2']['lifetime'])
414
					$racoonconf .= "	lifetime time {$tunnel['p2']['lifetime']} secs;\n";
415

    
416
				$racoonconf .= "}\n\n";
417
			}
418

    
419
			/* mobile clients? */
420
			if (isset($ipseccfg['mobileclients']['enable'])) {
421

    
422
				$tunnel = $ipseccfg['mobileclients'];
423

    
424
				if (isset($tunnel['p1']['myident']['myaddress'])) {
425
					$myidentt = "address";
426
					$myident = $curwanip;
427
				} else if (isset($tunnel['p1']['myident']['address'])) {
428
					$myidentt = "address";
429
					$myident = $tunnel['p1']['myident']['address'];
430
				} else if (isset($tunnel['p1']['myident']['fqdn'])) {
431
					$myidentt = "fqdn";
432
					$myident = $tunnel['p1']['myident']['fqdn'];
433
				} else if (isset($tunnel['p1']['myident']['ufqdn'])) {
434
					$myidentt = "user_fqdn";
435
					$myident = $tunnel['p1']['myident']['ufqdn'];
436
 				}
437

    
438
				if (isset($tunnel['p1']['authentication_method'])) {
439
					$authmethod = $tunnel['p1']['authentication_method'];
440
				} else {$authmethod = 'pre_shared_key';}
441

    
442
				$certline = '';
443
				if ($authmethod == 'rsasig') {
444
					if ($tunnel['p1']['cert'] && $tunnel['p1']['private-key']) {
445
						$cert = base64_decode($tunnel['p1']['cert']);
446
						$private_key = base64_decode($tunnel['p1']['private-key']);
447
					} else {
448
						/* null certificate/key */
449
						$cert = '';
450
						$private_key = '';
451
					}
452

    
453
					if ($tunnel['p1']['peercert'])
454
						$peercert = base64_decode($tunnel['p1']['peercert']);
455
					else
456
						$peercert = '';
457

    
458
					$fd1 = fopen("{$g['varetc_path']}/server-mobile{$tunnelnumber}-signed.pem", "w");
459
					if (!$fd1) {
460
						printf("Error: cannot open server-mobile{$tunnelnumber}-signed.pem in vpn.\n");
461
						return 1;
462
					}
463
					chmod("{$g['varetc_path']}/server-mobile{$tunnelnumber}-signed.pem", 0600);
464
					fwrite($fd1, $cert);
465
					fclose($fd1);
466

    
467
					$fd1 = fopen("{$g['varetc_path']}/server-mobile{$tunnelnumber}-key.pem", "w");
468
					if (!$fd1) {
469
						printf("Error: cannot open server-mobile{$tunnelnumber}-key.pem in vpn.\n");
470
						return 1;
471
					}
472
					chmod("{$g['varetc_path']}/server-mobile{$tunnelnumber}-key.pem", 0600);
473
					fwrite($fd1, $private_key);
474
					fclose($fd1);
475

    
476
					$certline = "certificate_type x509 \"server-mobile{$tunnelnumber}-signed.pem\" \"server-mobile{$tunnelnumber}-key.pem\";";
477
				}
478
				$racoonconf .= <<<EOD
479
remote anonymous \{
480
	exchange_mode {$tunnel['p1']['mode']};
481
	my_identifier {$myidentt} "{$myident}";
482
	{$certline}
483
	initial_contact on;
484
	passive on;
485
	generate_policy on;
486
	support_proxy on;
487
	proposal_check obey;
488

    
489
	proposal \{
490
		encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
491
		hash_algorithm {$tunnel['p1']['hash-algorithm']};
492
		authentication_method {$authmethod};
493
		dh_group {$tunnel['p1']['dhgroup']};
494

    
495
EOD;
496
				if ($tunnel['p1']['lifetime'])
497
					$racoonconf .= "		lifetime time {$tunnel['p1']['lifetime']} secs;\n";
498

    
499
				$racoonconf .= "	}\n";
500

    
501
				if ($tunnel['p1']['lifetime'])
502
					$racoonconf .= "	lifetime time {$tunnel['p1']['lifetime']} secs;\n";
503

    
504
				$racoonconf .= "}\n\n";
505

    
506
				$p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']);
507
				$p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']);
508

    
509
				$racoonconf .= <<<EOD
510
sainfo anonymous \{
511
	encryption_algorithm {$p2ealgos};
512
	authentication_algorithm {$p2halgos};
513
	compression_algorithm deflate;
514

    
515
EOD;
516

    
517
				if ($tunnel['p2']['pfsgroup'])
518
					$racoonconf .= "	pfs_group {$tunnel['p2']['pfsgroup']};\n";
519

    
520
				if ($tunnel['p2']['lifetime'])
521
					$racoonconf .= "	lifetime time {$tunnel['p2']['lifetime']} secs;\n";
522

    
523
				$racoonconf .= "}\n\n";
524
			}
525

    
526
			fwrite($fd, $racoonconf);
527
			fclose($fd);
528

    
529
			/* generate psk.txt */
530
			$fd = fopen("{$g['varetc_path']}/psk.txt", "w");
531
			if (!$fd) {
532
				printf("Error: cannot open psk.txt in vpn_ipsec_configure().\n");
533
				return 1;
534
			}
535

    
536
			$pskconf = "";
537

    
538
			if (is_array($ipseccfg['tunnel'])) {
539
				foreach ($ipseccfg['tunnel'] as $tunnel) {
540
					if (isset($tunnel['disabled']))
541
						continue;
542
					$pskconf .= "{$tunnel['remote-gateway']}	 {$tunnel['p1']['pre-shared-key']}\n";
543
				}
544
			}
545

    
546
			/* add PSKs for mobile clients */
547
			if (is_array($ipseccfg['mobilekey'])) {
548
				foreach ($ipseccfg['mobilekey'] as $key) {
549
					$pskconf .= "{$key['ident']}	{$key['pre-shared-key']}\n";
550
				}
551
			}
552

    
553
			fwrite($fd, $pskconf);
554
			fclose($fd);
555
			chmod("{$g['varetc_path']}/psk.txt", 0600);
556

    
557
			/* start racoon */
558
			mwexec("/usr/local/sbin/racoon -f {$g['varetc_path']}/racoon.conf");
559
		}
560
	}
561

    
562
	vpn_ipsec_failover_configure();
563

    
564
	if (!$g['booting']) {
565
		/* reload the filter */
566
		touch("{$g["tmp_path"]}/filter_dirty");
567
	}
568

    
569
	if ($g['booting'])
570
		echo "done\n";
571

    
572
	return 0;
573
}
574

    
575
function vpn_pptpd_configure() {
576
	global $config, $g;
577

    
578
	$syscfg = $config['system'];
579
	$pptpdcfg = $config['pptpd'];
580

    
581
    $starting_ng = get_number_of_wan_netgraph_interfaces_needed();
582

    
583
	if ($g['booting']) {
584
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
585
			return 0;
586

    
587
		echo "Configuring PPTP VPN service... ";
588
	} else {
589
		/* kill mpd */
590
        killbypid("{$g['varrun_path']}/mpd-pptpd.pid");
591

    
592
		/* wait for process to die */
593
		sleep(3);
594

    
595
        if (is_process_running("mpd4 -b")) {
596
            killbypid("{$g['varrun_path']}/mpd-pptpd.pid");
597
			log_error("Could not kill mpd within 3 seconds.   Trying again.");
598
		}
599

    
600
		/* remove mpd.conf, if it exists */
601
        unlink_if_exists("{$g['varetc_path']}/mpd-pptpd/mpd.conf");
602
        unlink_if_exists("{$g['varetc_path']}/mpd-pptpd/mpd.links");
603
        unlink_if_exists("{$g['varetc_path']}/mpd-pptpd/mpd.secret");
604
	}
605

    
606
	/* make sure mpd-vpn directory exists */
607
    if (!file_exists("{$g['varetc_path']}/mpd-pptpd"))
608
        mkdir("{$g['varetc_path']}/mpd-pptpd");
609

    
610
	switch ($pptpdcfg['mode']) {
611

    
612
		case 'server':
613

    
614
			/* write mpd.conf */
615
			$fd = fopen("{$g['varetc_path']}/mpd-pptpd/mpd.conf", "w");
616
			if (!$fd) {
617
				printf("Error: cannot open mpd.conf in vpn_pptpd_configure().\n");
618
				return 1;
619
			}
620

    
621
			$mpdconf = <<<EOD
622
startup:
623
pptpd:
624

    
625
EOD;
626

    
627
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
628
				$mpdconf .= "	load pt{$i}\n";
629
			}
630

    
631
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
632

    
633
				$clientip = long2ip(ip2long($pptpdcfg['remoteip']) + $i);
634
				$ngif = "ng" . ($i+1);
635

    
636
				if(isset($pptpdcfg['radius']['radiusissueips']) && isset($pptpdcfg['radius']['enable'])) {
637
					$isssue_ip_type = "set ipcp ranges {$pptpdcfg['localip']}/32 0.0.0.0/0";
638
				} else {
639
					$isssue_ip_type = "set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32";
640
				}
641

    
642
				$mpdconf .= <<<EOD
643

    
644
pt{$i}:
645
	new -i {$ngif} pt{$i} pt{$i}
646
	{$isssue_ip_type}
647
	load pptpd_standard
648

    
649
EOD;
650
			}
651

    
652
			$mpdconf .= <<<EOD
653

    
654
pptpd_standard:
655
	set iface up-script /usr/local/sbin/vpn-linkup
656
	set iface down-script /usr/local/sbin/vpn-linkdown
657
	set iface disable on-demand
658
	set iface enable proxy-arp
659
	set iface idle 1800
660
	set iface enable tcpmssfix
661
	set bundle enable multilink
662
	set link yes acfcomp protocomp
663
	set link no pap chap
664
	set link enable chap
665
	set link mtu 1460
666
	set link keep-alive 10 60
667
	set ipcp yes vjcomp
668
	set bundle enable compression
669
	set ccp yes mppc
670
	set ccp yes mpp-e128
671
	set ccp yes mpp-stateless
672

    
673
EOD;
674

    
675
			if (!isset($pptpdcfg['req128'])) {
676
				$mpdconf .= <<<EOD
677
	set ccp yes mpp-e40
678

    
679
EOD;
680
			}
681
			if  (isset($pptpdcfg["wins"]))
682
				$mpdconf  .=  "	set ipcp nbns {$pptpdcfg['wins']}\n";
683
			if (is_array($pptpdcfg['dnsserver']) && ($pptpdcfg['dnsserver'][0])) {
684
				$mpdconf .= "	set ipcp dns " . join(" ", $pptpdcfg['dnsserver']) . "\n";
685
			} else if (isset($config['dnsmasq']['enable'])) {
686
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
687
				if ($syscfg['dnsserver'][0])
688
					$mpdconf .= " " . $syscfg['dnsserver'][0];
689
				$mpdconf .= "\n";
690
			} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
691
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
692
			}
693

    
694
			if (isset($pptpdcfg['radius']['enable'])) {
695
				$mpdconf .= <<<EOD
696
	load radius
697

    
698
radius: 
699
	set radius retries 3
700
	set radius timeout 3 
701
	set radius me {$pptpdcfg['radius_nasip']}
702
	set auth enable radius-auth 
703
	set radius enable message-authentic
704

    
705
EOD;
706

    
707
				if (isset($pptpdcfg['radius']['secenable'])) {
708
					$mpdconf .= <<<EOD
709
	set radius server {$pptpdcfg['radius']['server2']} "{$pptpdcfg['radius']['secret2']}" 1812 1813 
710

    
711
EOD;
712
				}
713

    
714
			if (isset($pptpdcfg['radius']['enable'])) {
715
				$mpdconf .= <<<EOD
716
	set radius server {$pptpdcfg['radius']['server']} "{$pptpdcfg['radius']['secret']}" 1812 1813 
717

    
718
EOD;
719
			}
720

    
721
				if (isset($pptpdcfg['radius']['accounting'])) {
722
					$mpdconf .= <<<EOD
723
	set auth enable radius-acct 
724
	set auth acct-update {$pptpdcfg['radius_acct_update']}
725
EOD;
726
				}
727
			} else {
728
				$mpdconf .= <<<EOD
729
	set auth enable system
730
	set auth timeout 30
731

    
732
EOD;
733

    
734
		}
735
			fwrite($fd, $mpdconf);
736
			fclose($fd);
737

    
738
			/* write mpd.links */
739
			$fd = fopen("{$g['varetc_path']}/mpd-pptpd/mpd.links", "w");
740
			if (!$fd) {
741
				printf("Error: cannot open mpd.links in vpn_pptpd_configure().\n");
742
				return 1;
743
			}
744

    
745
			$mpdlinks = "";
746

    
747
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
748
				$mpdlinks .= <<<EOD
749

    
750
pt{$i}:
751
	set link type pptp
752
	set pptp self 127.0.0.1
753
	set pptp enable incoming
754
	set pptp disable originate
755

    
756
EOD;
757
			}
758

    
759
			fwrite($fd, $mpdlinks);
760
			fclose($fd);
761

    
762
			/* write mpd.secret */
763
			$fd = fopen("{$g['varetc_path']}/mpd-pptpd/mpd.secret", "w");
764
			if (!$fd) {
765
				printf("Error: cannot open mpd.secret in vpn_pptpd_configure().\n");
766
				return 1;
767
			}
768

    
769
			$mpdsecret = "";
770

    
771
			if (is_array($pptpdcfg['user'])) {
772
				foreach ($pptpdcfg['user'] as $user)
773
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
774
			}
775

    
776
			fwrite($fd, $mpdsecret);
777
			fclose($fd);
778
			chmod("{$g['varetc_path']}/mpd-pptpd/mpd.secret", 0600);
779

    
780
			/* fire up mpd */
781
			mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']}/mpd-pptpd -p {$g['varrun_path']}/mpd-pptpd.pid pptpd");
782

    
783
			break;
784

    
785
		case 'redir':
786
			break;
787
	}
788

    
789
	if (!$g['booting']) {
790
		/* reload the filter */
791
		filter_configure();
792
	}
793

    
794
	if ($g['booting'])
795
		echo "done\n";
796

    
797
	return 0;
798
}
799

    
800
function vpn_localnet_determine($adr, &$sa, &$sn) {
801
	global $config, $g;
802

    
803
	if (isset($adr)) {
804
		if ($adr['network']) {
805
			switch ($adr['network']) {
806
				case 'lan':
807
					$sn = $config['interfaces']['lan']['subnet'];
808
					$sa = gen_subnet($config['interfaces']['lan']['ipaddr'], $sn);
809
					break;
810
			}
811
		} else if ($adr['address']) {
812
			list($sa,$sn) = explode("/", $adr['address']);
813
			if (is_null($sn))
814
				$sn = 32;
815
		}
816
	} else {
817
		$sn = $config['interfaces']['lan']['subnet'];
818
		$sa = gen_subnet($config['interfaces']['lan']['ipaddr'], $sn);
819
	}
820
}
821

    
822
function vpn_endpoint_determine($tunnel, $curwanip) {
823

    
824
	global $g, $config;
825

    
826
	if ((!$tunnel['interface']) || ($tunnel['interface'] == "wan")) {
827
		if ($curwanip)
828
			return $curwanip;
829
		else
830
			return null;
831
	} else if ($tunnel['interface'] == "lan") {
832
		return $config['interfaces']['lan']['ipaddr'];
833
	} else {
834
		$oc = $config['interfaces'][$tunnel['interface']];
835
		/* carp ips, etc */
836
		$ip = find_interface_ip($tunnel['interface']);
837
		if($ip) 
838
			return $ip;
839

    
840
		if (isset($oc['enable']) && $oc['if']) {
841
			return $oc['ipaddr'];
842
		}
843
	}
844

    
845
	return null;
846
}
847

    
848
function vpn_pppoe_configure() {
849
	global $config, $g;
850

    
851
	$syscfg = $config['system'];
852
	$pppoecfg = $config['pppoe'];
853

    
854
   $starting_ng = get_number_of_wan_netgraph_interfaces_needed();
855

    
856
	/* create directory if it does not exist */
857
    if (!is_dir("{$g['varetc_path']}/mpd-pppoe"))
858
        mkdir("{$g['varetc_path']}/mpd-pppoe");
859

    
860
	if ($g['booting']) {
861
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
862
			return 0;
863

    
864
		echo "Configuring PPPoE VPN service... ";
865
    } else {
866
        /* kill mpd */
867
        killbypid("{$g['varrun_path']}/mpd-pppoe.pid");
868

    
869
        /* wait for process to die */
870
        sleep(2);
871

    
872
	}
873

    
874
	/* make sure mpd-vpn directory exists */
875
    if (!file_exists("{$g['varetc_path']}/mpd-pppoe"))
876
        mkdir("{$g['varetc_path']}/mpd-pppoe");
877

    
878
	switch ($pppoecfg['mode']) {
879

    
880
		case 'server':
881

    
882
			$pppoe_interface = filter_translate_type_to_real_interface($pppoecfg['interface']);
883

    
884
			/* write mpd.conf */
885
			$fd = fopen("{$g['varetc_path']}/mpd-pppoe/mpd.conf", "a");
886
			if (!$fd) {
887
				printf("Error: cannot open mpd.conf in vpn_pppoe_configure().\n");
888
				return 1;
889
			}
890
			$mpdconf = "\n\n";
891
			$mpdconf .= <<<EOD
892
startup:
893
pppoe:
894

    
895
EOD;
896

    
897
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
898
				$mpdconf .= "	load pppoe{$i}\n";
899
			}
900

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

    
903
				$clientip = long2ip(ip2long($pppoecfg['remoteip']) + $i);
904
				$ngif = "ng" . ($i+1);
905

    
906
				if(isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['enable'])) {
907
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
908
				} else {
909
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
910
				}
911

    
912
				$mpdconf .= <<<EOD
913

    
914
pppoe{$i}:
915
	new -i {$ngif} pppoe{$i} pppoe{$i}
916
	{$isssue_ip_type}
917
	load pppoe_standart
918

    
919
EOD;
920
			}
921

    
922
			$mpdconf .= <<<EOD
923

    
924
pppoe_standart:
925
	set link type pppoe
926
	set pppoe iface {$pppoe_interface}
927
	set pppoe service "*"
928
	set iface up-script /usr/local/sbin/vpn-linkup
929
	set iface down-script /usr/local/sbin/vpn-linkdown
930
	set bundle enable compression
931
	set auth max-logins 1
932
	set link max-redial -1
933
	set pppoe enable incoming
934
	set pppoe disable originate
935
	set iface disable on-demand
936
	set iface disable proxy-arp
937
	set iface idle 0 
938
	set iface enable tcpmssfix
939
	set bundle no multilink  
940
	set link no acfcomp 
941
	set link no protocomp 
942
	set link no pap chap
943
	set link enable chap
944
	set link keep-alive 30 100 
945
	set link mtu 1460 
946
	set ccp yes mpp-e40
947
	set ccp yes mpp-e128
948
	set ccp yes mpp-stateless
949
	set ipcp no vjcomp 
950

    
951
EOD;
952

    
953
			if (isset($config['dnsmasq']['enable'])) {
954
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
955
				if ($syscfg['dnsserver'][0])
956
					$mpdconf .= " " . $syscfg['dnsserver'][0];
957
				$mpdconf .= "\n";
958
			} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
959
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
960
			}
961

    
962
			if (isset($pppoecfg['radius']['enable'])) {
963
				$mpdconf .= <<<EOD
964
	load radius
965

    
966
radius: 
967
	set radius retries 3
968
	set radius timeout 3 
969
	set radius me {$pppoecfg['radius_nasip']}
970
	set auth enable radius-auth 
971
	set radius enable message-authentic
972

    
973
EOD;
974
				if (isset($pppoecfg['radius']['secenable'])) {
975
					$mpdconf .= <<<EOD
976
	set radius server {$pppoecfg['radius']['server2']} "{$pppoecfg['radius']['secret2']}" 1812 1813 
977

    
978
EOD;
979
				}
980

    
981
			if (isset($pppoecfg['radius']['enable'])) {
982
					$mpdconf .= <<<EOD
983
	set radius server {$pppoecfg['radius']['server']} "{$pppoecfg['radius']['secret']}" 1812 1813 
984

    
985
EOD;
986
				}
987

    
988
				if (isset($pppoecfg['radius']['accounting'])) {
989
					$mpdconf .= <<<EOD
990
	set auth enable radius-acct 
991
	set auth acct-update {$pppoecfg['radius_acct_update']}
992
EOD;
993
			}
994
			} else {
995
				$mpdconf .= <<<EOD
996
	set auth enable system
997
	set auth timeout 30
998

    
999
EOD;
1000
			}
1001
			fwrite($fd, $mpdconf);
1002
			fclose($fd);
1003

    
1004
			/* write mpd.links */
1005
			$fd = fopen("{$g['varetc_path']}/mpd-pppoe/mpd.links", "a");
1006
			if (!$fd) {
1007
				printf("Error: cannot open mpd.links in vpn_pppoe_configure().\n");
1008
				return 1;
1009
			}
1010

    
1011
			$mpdlinks = "";
1012

    
1013
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1014
				$mpdlinks .= <<<EOD
1015

    
1016
pppoe:
1017
	set link type pppoe
1018
	set pppoe iface {$pppoe_interface}
1019
        set pppoe service "*"
1020
	 set pppoe disable incoming
1021
	 set pppoe enable originate
1022

    
1023

    
1024
EOD;
1025
			}
1026

    
1027
			fwrite($fd, $mpdlinks);
1028
			fclose($fd);
1029

    
1030
			/* write mpd.secret */
1031
			$fd = fopen("{$g['varetc_path']}/mpd-pppoe/mpd.secret", "a");
1032
			if (!$fd) {
1033
				printf("Error: cannot open mpd.secret in vpn_pppoe_configure().\n");
1034
				return 1;
1035
			}
1036

    
1037
			$mpdsecret = "\n\n";
1038

    
1039
			if (is_array($pppoecfg['user'])) {
1040
				foreach ($pppoecfg['user'] as $user)
1041
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1042
			}
1043

    
1044
			fwrite($fd, $mpdsecret);
1045
			fclose($fd);
1046
			chmod("{$g['varetc_path']}/mpd-pppoe/mpd.secret", 0600);
1047

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

    
1051
			break;
1052

    
1053
		case 'redir':
1054
			break;
1055
	}
1056

    
1057
	touch("{$g["tmp_path"]}/filter_dirty");
1058

    
1059
	if ($g['booting'])
1060
		echo "done\n";
1061

    
1062
	return 0;
1063
}
1064

    
1065
?>
(23-23/28)