Project

General

Profile

Download (26.8 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
	if ($g['booting']) {
582
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
583
			return 0;
584

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

    
590
		/* wait for process to die */
591
		sleep(3);
592

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

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

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

    
608
	switch ($pptpdcfg['mode']) {
609

    
610
		case 'server':
611

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

    
619
			$mpdconf = <<<EOD
620
pptpd:
621

    
622
EOD;
623

    
624
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
625
				$mpdconf .= "	load pt{$i}\n";
626
			}
627

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

    
630
				$clientip = long2ip(ip2long($pptpdcfg['remoteip']) + $i);
631
				$ngif = "ng" . ($i+1);
632

    
633
				$mpdconf .= <<<EOD
634

    
635
pt{$i}:
636
	new -i {$ngif} pt{$i} pt{$i}
637
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
638
	load pts
639

    
640
EOD;
641
			}
642

    
643
			$mpdconf .= <<<EOD
644

    
645
pts:
646
	set iface disable on-demand
647
	set iface enable proxy-arp
648
	set iface enable tcpmssfix
649
	set iface idle 1800
650
	set iface up-script /usr/local/sbin/vpn-linkup
651
	set iface down-script /usr/local/sbin/vpn-linkdown
652
	set bundle enable multilink
653
	set bundle enable crypt-reqd
654
	set link yes acfcomp protocomp
655
	set link no pap chap
656
	set link enable chap-msv2
657
	set link mtu 1460
658
	set link keep-alive 10 60
659
	set ipcp yes vjcomp
660
	set bundle enable compression
661
	set ccp yes mppc
662
	set ccp yes mpp-e128
663
	set ccp yes mpp-stateless
664

    
665
EOD;
666

    
667
			if (!isset($pptpdcfg['req128'])) {
668
				$mpdconf .= <<<EOD
669
	set ccp yes mpp-e40
670
	set ccp yes mpp-e56
671

    
672
EOD;
673
			}
674
			if  (isset($pptpdcfg["wins"]))
675
				$mpdconf  .=  "	set ipcp nbns {$pptpdcfg['wins']}\n";
676
			if (is_array($pptpdcfg['dnsserver']) && ($pptpdcfg['dnsserver'][0])) {
677
				$mpdconf .= "	set ipcp dns " . join(" ", $pptpdcfg['dnsserver']) . "\n";
678
			} else if (isset($config['dnsmasq']['enable'])) {
679
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
680
				if ($syscfg['dnsserver'][0])
681
					$mpdconf .= " " . $syscfg['dnsserver'][0];
682
				$mpdconf .= "\n";
683
			} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
684
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
685
			}
686

    
687
			if (isset($pptpdcfg['radius']['enable'])) {
688
				$mpdconf .= <<<EOD
689
	set radius server {$pptpdcfg['radius']['server']} "{$pptpdcfg['radius']['secret']}"
690
	set radius retries 3
691
	set radius timeout 10
692
	set bundle enable radius-auth
693
	set bundle disable radius-fallback
694

    
695
EOD;
696

    
697
				if (isset($pptpdcfg['radius']['accounting'])) {
698
					$mpdconf .= <<<EOD
699
	set bundle enable radius-acct
700

    
701
EOD;
702
				}
703
			}
704

    
705
			fwrite($fd, $mpdconf);
706
			fclose($fd);
707

    
708
			/* write mpd.links */
709
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.links", "w");
710
			if (!$fd) {
711
				printf("Error: cannot open mpd.links in vpn_pptpd_configure().\n");
712
				return 1;
713
			}
714

    
715
			$mpdlinks = "";
716

    
717
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
718
				$mpdlinks .= <<<EOD
719

    
720
pt{$i}:
721
	set link type pptp
722
	set pptp enable incoming
723
	set pptp disable originate
724
	set pptp disable windowing
725
	set pptp self 127.0.0.1
726

    
727
EOD;
728
			}
729

    
730
			fwrite($fd, $mpdlinks);
731
			fclose($fd);
732

    
733
			/* write mpd.secret */
734
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.secret", "w");
735
			if (!$fd) {
736
				printf("Error: cannot open mpd.secret in vpn_pptpd_configure().\n");
737
				return 1;
738
			}
739

    
740
			$mpdsecret = "";
741

    
742
			if (is_array($pptpdcfg['user'])) {
743
				foreach ($pptpdcfg['user'] as $user)
744
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
745
			}
746

    
747
			fwrite($fd, $mpdsecret);
748
			fclose($fd);
749
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
750

    
751
			/* fire up mpd */
752
			mwexec("/usr/local/sbin/mpd -b -d {$g['varetc_path']}/mpd-vpn -p {$g['varrun_path']}/mpd-vpn.pid pptpd");
753

    
754
			break;
755

    
756
		case 'redir':
757
			break;
758
	}
759

    
760
	if (!$g['booting']) {
761
		/* reload the filter */
762
		filter_configure();
763
	}
764

    
765
	if ($g['booting'])
766
		echo "done\n";
767

    
768
	return 0;
769
}
770

    
771
function vpn_localnet_determine($adr, &$sa, &$sn) {
772
	global $config, $g;
773

    
774
	if (isset($adr)) {
775
		if ($adr['network']) {
776
			switch ($adr['network']) {
777
				case 'lan':
778
					$sn = $config['interfaces']['lan']['subnet'];
779
					$sa = gen_subnet($config['interfaces']['lan']['ipaddr'], $sn);
780
					break;
781
			}
782
		} else if ($adr['address']) {
783
			list($sa,$sn) = explode("/", $adr['address']);
784
			if (is_null($sn))
785
				$sn = 32;
786
		}
787
	} else {
788
		$sn = $config['interfaces']['lan']['subnet'];
789
		$sa = gen_subnet($config['interfaces']['lan']['ipaddr'], $sn);
790
	}
791
}
792

    
793
function vpn_endpoint_determine($tunnel, $curwanip) {
794

    
795
	global $g, $config;
796

    
797
	if ((!$tunnel['interface']) || ($tunnel['interface'] == "wan")) {
798
		if ($curwanip)
799
			return $curwanip;
800
		else
801
			return null;
802
	} else if ($tunnel['interface'] == "lan") {
803
		return $config['interfaces']['lan']['ipaddr'];
804
	} else {
805
		$oc = $config['interfaces'][$tunnel['interface']];
806
		/* carp ips, etc */
807
		$ip = find_interface_ip($tunnel['interface']);
808
		if($ip) 
809
			return $ip;
810

    
811
		if (isset($oc['enable']) && $oc['if']) {
812
			return $oc['ipaddr'];
813
		}
814
	}
815

    
816
	return null;
817
}
818

    
819
function vpn_pppoe_configure() {
820
	global $config, $g;
821

    
822
	$syscfg = $config['system'];
823
	$pppoecfg = $config['pppoe'];
824

    
825
	/* create directory if it does not exist */
826
	if(!is_dir("{$g['varetc_path']}/mpd-vpn"))
827
		mkdir("{$g['varetc_path']}/mpd-vpn");
828

    
829
	if ($g['booting']) {
830
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
831
			return 0;
832

    
833
		echo "Configuring PPPoE VPN service... ";
834
	}
835

    
836
	/* make sure mpd-vpn directory exists */
837
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
838
		mkdir("{$g['varetc_path']}/mpd-vpn");
839

    
840
	switch ($pppoecfg['mode']) {
841

    
842
		case 'server':
843

    
844
			$pppoe_interface = filter_translate_type_to_real_interface($pppoecfg['interface']);
845

    
846
			/* write mpd.conf */
847
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.conf", "a");
848
			if (!$fd) {
849
				printf("Error: cannot open mpd.conf in vpn_pppoe_configure().\n");
850
				return 1;
851
			}
852
			$mpdconf = "\n\n";
853
			$mpdconf .= <<<EOD
854
pppoe:
855

    
856
EOD;
857

    
858
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
859
				$mpdconf .= "	load pppoe{$i}\n";
860
			}
861

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

    
864
				$clientip = long2ip(ip2long($pppoecfg['remoteip']) + $i);
865
				$ngif = "ng" . ($i+1);
866

    
867
				if(isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['enable'])) {
868
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
869
					$isssue_ip_type .="\n\tset ipcp yes radius-ip";
870
				} else {
871
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
872
				}
873

    
874
				$mpdconf .= <<<EOD
875

    
876
pppoe{$i}:
877
	new -i {$ngif} pppoe{$i} pppoe{$i}
878
	{$isssue_ip_type}
879
	load pppoe_standart
880

    
881
EOD;
882
			}
883

    
884
			$mpdconf .= <<<EOD
885

    
886
pppoe_standart:
887
	set link type pppoe
888
	set pppoe iface {$pppoe_interface}
889
	set pppoe service "*"
890
	set pppoe disable originate
891
	set pppoe enable incoming
892
	set bundle no multilink
893
	set bundle enable compression
894
	set bundle max-logins 1
895
	set iface idle 0
896
	set iface disable on-demand
897
	set iface disable proxy-arp
898
	set iface enable tcpmssfix
899
	set iface mtu 1500
900
	set link no pap chap
901
	set link enable chap
902
	set link keep-alive 60 180
903
	set ipcp yes vjcomp
904
	set ipcp no vjcomp
905
	set link max-redial -1
906
	set link mtu 1492
907
	set link mru 1492
908
	set ccp yes mpp-e40
909
	set ccp yes mpp-e128
910
	set ccp yes mpp-stateless
911
	set link latency 1
912
	#set ipcp dns 10.10.1.3
913
	#set bundle accept encryption
914

    
915
EOD;
916

    
917
			if (isset($config['dnsmasq']['enable'])) {
918
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
919
				if ($syscfg['dnsserver'][0])
920
					$mpdconf .= " " . $syscfg['dnsserver'][0];
921
				$mpdconf .= "\n";
922
			} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
923
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
924
			}
925

    
926
			if (isset($pppoecfg['radius']['enable'])) {
927
				$mpdconf .= <<<EOD
928
	set radius server {$pppoecfg['radius']['server']} "{$pppoecfg['radius']['secret']}"
929
	set radius retries 3
930
	set radius timeout 10
931
	set bundle enable radius-auth
932
	set bundle disable radius-fallback
933

    
934
EOD;
935

    
936
				if (isset($pppoecfg['radius']['accounting'])) {
937
					$mpdconf .= <<<EOD
938
	set bundle enable radius-acct
939
	set radius acct-update 300
940
EOD;
941
				}
942
			}
943

    
944
			fwrite($fd, $mpdconf);
945
			fclose($fd);
946

    
947
			/* write mpd.links */
948
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.links", "a");
949
			if (!$fd) {
950
				printf("Error: cannot open mpd.links in vpn_pppoe_configure().\n");
951
				return 1;
952
			}
953

    
954
			$mpdlinks = "";
955

    
956
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
957
				$mpdlinks .= <<<EOD
958

    
959
pppoe:
960
	set link type pppoe
961
	set pppoe iface {$pppoe_interface}
962

    
963
EOD;
964
			}
965

    
966
			fwrite($fd, $mpdlinks);
967
			fclose($fd);
968

    
969
			/* write mpd.secret */
970
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.secret", "a");
971
			if (!$fd) {
972
				printf("Error: cannot open mpd.secret in vpn_pppoe_configure().\n");
973
				return 1;
974
			}
975

    
976
			$mpdsecret = "\n\n";
977

    
978
			if (is_array($pppoecfg['user'])) {
979
				foreach ($pppoecfg['user'] as $user)
980
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
981
			}
982

    
983
			fwrite($fd, $mpdsecret);
984
			fclose($fd);
985
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
986

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

    
990
			break;
991

    
992
		case 'redir':
993
			break;
994
	}
995

    
996
	touch("{$g["tmp_path"]}/filter_dirty");
997

    
998
	if ($g['booting'])
999
		echo "done\n";
1000

    
1001
	return 0;
1002
}
1003

    
1004
?>
(22-22/27)