Project

General

Profile

Download (27.2 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
	/* get the automatic /etc/ping_hosts.sh ready */
101
	unlink_if_exists("/var/db/ipsecpinghosts");
102
	touch("/var/db/ipsecpinghosts");
103

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

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

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

    
128
	$curwanip = get_current_wan_address();
129
	if($config['installedpackages']['sasyncd']['config'] <> "")
130
		foreach($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
131
			if($sasyncd['ip'] <> "")
132
				$curwanip = $sasyncd['ip'];
133
		}
134

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

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

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

    
151
		/* wait for process to die */
152
		sleep(2);
153

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

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

    
162
	if (isset($ipseccfg['enable'])) {
163

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

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

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

    
177
			if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) {
178

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

    
186
				$spdconf = "";
187

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

    
191
				foreach ($ipseccfg['tunnel'] as $tunnel) {
192

    
193
					if (isset($tunnel['disabled']))
194
						continue;
195

    
196
					$ep = vpn_endpoint_determine($tunnel, $curwanip);
197
					if (!$ep)
198
						continue;
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
						if($config['installedpackages']['sasyncd']['config'] <> "")
222
							foreach($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
223
								if($sasyncd['ip'] <> "")
224
									$curwanip = $sasyncd['ip'];
225
							}
226
						mwexec("/sbin/ifconfig gif" . $number_of_gifs . " tunnel" . $curwanip . " " . $tunnel['remote-gateway']);
227
						mwexec("/sbin/ifconfig gif" . $number_of_gifs . " {$lansa}/{$lansn} {$lanip}/32");
228
					}
229

    
230
					$spdconf .= "spdadd {$sa}/{$sn} " .
231
						"{$tunnel['remote-subnet']} any -P out ipsec " .
232
						"{$tunnel['p2']['protocol']}/tunnel/{$ep}-" .
233
						"{$tunnel['remote-gateway']}/unique;\n";
234

    
235
					$spdconf .= "spdadd {$tunnel['remote-subnet']} " .
236
						"{$sa}/{$sn} any -P in ipsec " .
237
						"{$tunnel['p2']['protocol']}/tunnel/{$tunnel['remote-gateway']}-" .
238
						"{$ep}/unique;\n";
239
				}
240

    
241
				fwrite($fd, $spdconf);
242
				fclose($fd);
243

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

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

    
255
			$racoonconf = "";
256

    
257

    
258
	if($config['installedpackages']['sasyncd']['config'] <> "")
259
		foreach($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
260
			if($sasyncd['ip'] <> "")
261
				$curwanip = $sasyncd['ip'];
262
				/* natt - turn on if <developer/> exists */
263
				if(isset($config['system']['developer']) <> "") {
264
					$lanip = $config['interfaces']['lan']['ipaddr'];
265
					if($lanip <> "")
266
						$natt = "isakmp_natt {$lanip}[4500];\n";
267

    
268
				}
269
				$interface_ip = $sasyncd['ip'];
270
				$racoonconf .= <<<EOD
271
listen {
272
	isakmp {$interface_ip} [500];
273
	{$natt}
274
}
275

    
276
EOD;
277
			}
278

    
279
			$racoonconf .= "path pre_shared_key \"{$g['varetc_path']}/psk.txt\";\n\n";
280
			$racoonconf .= "path certificate  \"{$g['varetc_path']}\";\n\n";
281

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

    
303
			$tunnelnumber = 0;
304
			if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel']))
305
				foreach ($ipseccfg['tunnel'] as $tunnel) {
306

    
307
				++$tunnelnumber;
308

    
309
				if (isset($tunnel['disabled']))
310
					continue;
311

    
312
				$ep = vpn_endpoint_determine($tunnel, $curwanip);
313
				if (!$ep)
314
					continue;
315

    
316
				vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn);
317

    
318
				if (isset($tunnel['p1']['myident']['myaddress'])) {
319
					$myidentt = "address";
320
					$myident = $ep;
321
				} else if (isset($tunnel['p1']['myident']['address'])) {
322
					$myidentt = "address";
323
					$myident = $tunnel['p1']['myident']['address'];
324
				} else if (isset($tunnel['p1']['myident']['fqdn'])) {
325
					$myidentt = "fqdn";
326
					$myident = $tunnel['p1']['myident']['fqdn'];
327
				} else if (isset($tunnel['p1']['myident']['ufqdn'])) {
328
					$myidentt = "user_fqdn";
329
					$myident = $tunnel['p1']['myident']['ufqdn'];
330
 				} else if (isset($tunnel['p1']['myident']['dyn_dns'])) {
331
					$myidentt = "dyn_dns";
332
					$myident = gethostbyname($tunnel['p1']['myident']['dyn_dns']);
333
 				}
334

    
335
				if (isset($tunnel['p1']['authentication_method'])) {
336
					$authmethod = $tunnel['p1']['authentication_method'];
337
				} else {$authmethod = 'pre_shared_key';}
338

    
339
				$certline = '';
340

    
341
				if ($authmethod == 'rsasig') {
342
					if ($tunnel['p1']['cert'] && $tunnel['p1']['private-key']) {
343
						$cert = base64_decode($tunnel['p1']['cert']);
344
						$private_key = base64_decode($tunnel['p1']['private-key']);
345
					} else {
346
						/* null certificate/key */
347
						$cert = '';
348
						$private_key = '';
349
					}
350

    
351
					if ($tunnel['p1']['peercert'])
352
						$peercert = base64_decode($tunnel['p1']['peercert']);
353
					else
354
						$peercert = '';
355

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

    
365
					$fd1 = fopen("{$g['varetc_path']}/server{$tunnelnumber}-key.pem", "w");
366
					if (!$fd1) {
367
						printf("Error: cannot open server{$tunnelnumber}-key.pem in vpn.\n");
368
						return 1;
369
					}
370
					chmod("{$g['varetc_path']}/server{$tunnelnumber}-key.pem", 0600);
371
					fwrite($fd1, $private_key);
372
					fclose($fd1);
373

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

    
376
					if ($peercert!=''){
377
						$fd1 = fopen("{$g['varetc_path']}/peer{$tunnelnumber}-signed.pem", "w");
378
						if (!$fd1) {
379
							printf("Error: cannot open server{$tunnelnumber}-signed.pem in vpn.\n");
380
							return 1;
381
						}
382
						chmod("{$g['varetc_path']}/peer{$tunnelnumber}-signed.pem", 0600);
383
						fwrite($fd1, $peercert);
384
						fclose($fd1);
385
						$certline .= <<<EOD
386

    
387
	peers_certfile "peer{$tunnelnumber}-signed.pem";
388
EOD;
389
					}
390
				}
391
				$racoonconf .= <<<EOD
392
remote {$tunnel['remote-gateway']} \{
393
	exchange_mode {$tunnel['p1']['mode']};
394
	my_identifier {$myidentt} "{$myident}";
395
	{$certline}
396
	peers_identifier address {$tunnel['remote-gateway']};
397
	initial_contact on;
398
	support_proxy on;
399
	proposal_check obey;
400

    
401
	proposal \{
402
		encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
403
		hash_algorithm {$tunnel['p1']['hash-algorithm']};
404
		authentication_method {$authmethod};
405
		dh_group {$tunnel['p1']['dhgroup']};
406

    
407
EOD;
408
				if ($tunnel['p1']['lifetime'])
409
					$racoonconf .= "		lifetime time {$tunnel['p1']['lifetime']} secs;\n";
410

    
411
				$racoonconf .= "	}\n";
412

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

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

    
418
				$p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']);
419
				$p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']);
420

    
421
				$racoonconf .= <<<EOD
422
sainfo address {$sa}/{$sn} any address {$tunnel['remote-subnet']} any \{
423
	encryption_algorithm {$p2ealgos};
424
	authentication_algorithm {$p2halgos};
425
	compression_algorithm deflate;
426

    
427
EOD;
428

    
429
				if ($tunnel['p2']['pfsgroup'])
430
					$racoonconf .= "	pfs_group {$tunnel['p2']['pfsgroup']};\n";
431

    
432
				if ($tunnel['p2']['lifetime'])
433
					$racoonconf .= "	lifetime time {$tunnel['p2']['lifetime']} secs;\n";
434

    
435
				$racoonconf .= "}\n\n";
436
			}
437

    
438
			/* mobile clients? */
439
			if (isset($ipseccfg['mobileclients']['enable'])) {
440

    
441
				$tunnel = $ipseccfg['mobileclients'];
442

    
443
				if (isset($tunnel['p1']['myident']['myaddress'])) {
444
					$myidentt = "address";
445
					$myident = $curwanip;
446
				} else if (isset($tunnel['p1']['myident']['address'])) {
447
					$myidentt = "address";
448
					$myident = $tunnel['p1']['myident']['address'];
449
				} else if (isset($tunnel['p1']['myident']['fqdn'])) {
450
					$myidentt = "fqdn";
451
					$myident = $tunnel['p1']['myident']['fqdn'];
452
				} else if (isset($tunnel['p1']['myident']['ufqdn'])) {
453
					$myidentt = "user_fqdn";
454
					$myident = $tunnel['p1']['myident']['ufqdn'];
455
 				}
456

    
457
				if (isset($tunnel['p1']['authentication_method'])) {
458
					$authmethod = $tunnel['p1']['authentication_method'];
459
				} else {$authmethod = 'pre_shared_key';}
460

    
461
				$certline = '';
462
				if ($authmethod == 'rsasig') {
463
					if ($tunnel['p1']['cert'] && $tunnel['p1']['private-key']) {
464
						$cert = base64_decode($tunnel['p1']['cert']);
465
						$private_key = base64_decode($tunnel['p1']['private-key']);
466
					} else {
467
						/* null certificate/key */
468
						$cert = '';
469
						$private_key = '';
470
					}
471

    
472
					if ($tunnel['p1']['peercert'])
473
						$peercert = base64_decode($tunnel['p1']['peercert']);
474
					else
475
						$peercert = '';
476

    
477
					$fd1 = fopen("{$g['varetc_path']}/server-mobile{$tunnelnumber}-signed.pem", "w");
478
					if (!$fd1) {
479
						printf("Error: cannot open server-mobile{$tunnelnumber}-signed.pem in vpn.\n");
480
						return 1;
481
					}
482
					chmod("{$g['varetc_path']}/server-mobile{$tunnelnumber}-signed.pem", 0600);
483
					fwrite($fd1, $cert);
484
					fclose($fd1);
485

    
486
					$fd1 = fopen("{$g['varetc_path']}/server-mobile{$tunnelnumber}-key.pem", "w");
487
					if (!$fd1) {
488
						printf("Error: cannot open server-mobile{$tunnelnumber}-key.pem in vpn.\n");
489
						return 1;
490
					}
491
					chmod("{$g['varetc_path']}/server-mobile{$tunnelnumber}-key.pem", 0600);
492
					fwrite($fd1, $private_key);
493
					fclose($fd1);
494

    
495
					$certline = "certificate_type x509 \"server-mobile{$tunnelnumber}-signed.pem\" \"server-mobile{$tunnelnumber}-key.pem\";";
496
				}
497
				$racoonconf .= <<<EOD
498
remote anonymous \{
499
	exchange_mode {$tunnel['p1']['mode']};
500
	my_identifier {$myidentt} "{$myident}";
501
	{$certline}
502
	initial_contact on;
503
	passive on;
504
	generate_policy on;
505
	support_proxy on;
506
	proposal_check obey;
507

    
508
	proposal \{
509
		encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
510
		hash_algorithm {$tunnel['p1']['hash-algorithm']};
511
		authentication_method {$authmethod};
512
		dh_group {$tunnel['p1']['dhgroup']};
513

    
514
EOD;
515
				if ($tunnel['p1']['lifetime'])
516
					$racoonconf .= "		lifetime time {$tunnel['p1']['lifetime']} secs;\n";
517

    
518
				$racoonconf .= "	}\n";
519

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

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

    
525
				$p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']);
526
				$p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']);
527

    
528
				$racoonconf .= <<<EOD
529
sainfo anonymous \{
530
	encryption_algorithm {$p2ealgos};
531
	authentication_algorithm {$p2halgos};
532
	compression_algorithm deflate;
533

    
534
EOD;
535

    
536
				if ($tunnel['p2']['pfsgroup'])
537
					$racoonconf .= "	pfs_group {$tunnel['p2']['pfsgroup']};\n";
538

    
539
				if ($tunnel['p2']['lifetime'])
540
					$racoonconf .= "	lifetime time {$tunnel['p2']['lifetime']} secs;\n";
541

    
542
				$racoonconf .= "}\n\n";
543
			}
544

    
545
			fwrite($fd, $racoonconf);
546
			fclose($fd);
547

    
548
			/* generate psk.txt */
549
			$fd = fopen("{$g['varetc_path']}/psk.txt", "w");
550
			if (!$fd) {
551
				printf("Error: cannot open psk.txt in vpn_ipsec_configure().\n");
552
				return 1;
553
			}
554

    
555
			$pskconf = "";
556

    
557
			if (is_array($ipseccfg['tunnel'])) {
558
				foreach ($ipseccfg['tunnel'] as $tunnel) {
559
					if (isset($tunnel['disabled']))
560
						continue;
561
					$pskconf .= "{$tunnel['remote-gateway']}	 {$tunnel['p1']['pre-shared-key']}\n";
562
				}
563
			}
564

    
565
			/* add PSKs for mobile clients */
566
			if (is_array($ipseccfg['mobilekey'])) {
567
				foreach ($ipseccfg['mobilekey'] as $key) {
568
					$pskconf .= "{$key['ident']}	{$key['pre-shared-key']}\n";
569
				}
570
			}
571

    
572
			fwrite($fd, $pskconf);
573
			fclose($fd);
574
			chmod("{$g['varetc_path']}/psk.txt", 0600);
575

    
576
			/* start racoon */
577
			mwexec("/usr/local/sbin/racoon -f {$g['varetc_path']}/racoon.conf");
578
		}
579
	}
580

    
581
	vpn_ipsec_failover_configure();
582

    
583
	if (!$g['booting']) {
584
		/* reload the filter */
585
		touch("{$g["tmp_path"]}/filter_dirty");
586
	}
587

    
588
	if ($g['booting'])
589
		echo "done\n";
590

    
591
	return 0;
592
}
593

    
594
function vpn_pptpd_configure() {
595
	global $config, $g;
596

    
597
	$syscfg = $config['system'];
598
	$pptpdcfg = $config['pptpd'];
599

    
600
	if ($g['booting']) {
601
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
602
			return 0;
603

    
604
		echo "Configuring PPTP VPN service... ";
605
	} else {
606
		/* kill mpd */
607
		killbypid("{$g['varrun_path']}/mpd-vpn.pid");
608

    
609
		/* wait for process to die */
610
		sleep(3);
611

    
612
		if(is_process_running("mpd -b")) {
613
			killbypid("{$g['varrun_path']}/mpd-vpn.pid");
614
			log_error("Could not kill mpd within 3 seconds.   Trying again.");
615
		}
616

    
617
		/* remove mpd.conf, if it exists */
618
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.conf");
619
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.links");
620
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.secret");
621
	}
622

    
623
	/* make sure mpd-vpn directory exists */
624
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
625
		mkdir("{$g['varetc_path']}/mpd-vpn");
626

    
627
	switch ($pptpdcfg['mode']) {
628

    
629
		case 'server':
630

    
631
			/* write mpd.conf */
632
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.conf", "w");
633
			if (!$fd) {
634
				printf("Error: cannot open mpd.conf in vpn_pptpd_configure().\n");
635
				return 1;
636
			}
637

    
638
			$mpdconf = <<<EOD
639
pptpd:
640

    
641
EOD;
642

    
643
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
644
				$mpdconf .= "	load pt{$i}\n";
645
			}
646

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

    
649
				$clientip = long2ip(ip2long($pptpdcfg['remoteip']) + $i);
650
				$ngif = "ng" . ($i+1);
651

    
652
				$mpdconf .= <<<EOD
653

    
654
pt{$i}:
655
	new -i {$ngif} pt{$i} pt{$i}
656
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
657
	load pts
658

    
659
EOD;
660
			}
661

    
662
			$mpdconf .= <<<EOD
663

    
664
pts:
665
	set iface disable on-demand
666
	set iface enable proxy-arp
667
	set iface enable tcpmssfix
668
	set iface idle 1800
669
	set iface up-script /usr/local/sbin/vpn-linkup
670
	set iface down-script /usr/local/sbin/vpn-linkdown
671
	set bundle enable multilink
672
	set bundle enable crypt-reqd
673
	set link yes acfcomp protocomp
674
	set link no pap chap
675
	set link enable chap-msv2
676
	set link mtu 1460
677
	set link keep-alive 10 60
678
	set ipcp yes vjcomp
679
	set bundle enable compression
680
	set ccp yes mppc
681
	set ccp yes mpp-e128
682
	set ccp yes mpp-stateless
683

    
684
EOD;
685

    
686
			if (!isset($pptpdcfg['req128'])) {
687
				$mpdconf .= <<<EOD
688
	set ccp yes mpp-e40
689
	set ccp yes mpp-e56
690

    
691
EOD;
692
			}
693

    
694
			if (is_array($pptpdcfg['dnsserver']) && ($pptpdcfg['dnsserver'][0])) {
695
				$mpdconf .= "	set ipcp dns " . join(" ", $pptpdcfg['dnsserver']) . "\n";
696
			} else if (isset($config['dnsmasq']['enable'])) {
697
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
698
				if ($syscfg['dnsserver'][0])
699
					$mpdconf .= " " . $syscfg['dnsserver'][0];
700
				$mpdconf .= "\n";
701
			} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
702
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
703
			}
704

    
705
			if (isset($pptpdcfg['radius']['enable'])) {
706
				$mpdconf .= <<<EOD
707
	set radius server {$pptpdcfg['radius']['server']} "{$pptpdcfg['radius']['secret']}"
708
	set radius retries 3
709
	set radius timeout 10
710
	set bundle enable radius-auth
711
	set bundle disable radius-fallback
712

    
713
EOD;
714

    
715
				if (isset($pptpdcfg['radius']['accounting'])) {
716
					$mpdconf .= <<<EOD
717
	set bundle enable radius-acct
718

    
719
EOD;
720
				}
721
			}
722

    
723
			fwrite($fd, $mpdconf);
724
			fclose($fd);
725

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

    
733
			$mpdlinks = "";
734

    
735
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
736
				$mpdlinks .= <<<EOD
737

    
738
pt{$i}:
739
	set link type pptp
740
	set pptp enable incoming
741
	set pptp disable originate
742
	set pptp disable windowing
743
	set pptp self 127.0.0.1
744

    
745
EOD;
746
			}
747

    
748
			fwrite($fd, $mpdlinks);
749
			fclose($fd);
750

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

    
758
			$mpdsecret = "";
759

    
760
			if (is_array($pptpdcfg['user'])) {
761
				foreach ($pptpdcfg['user'] as $user)
762
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
763
			}
764

    
765
			fwrite($fd, $mpdsecret);
766
			fclose($fd);
767
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
768

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

    
772
			break;
773

    
774
		case 'redir':
775
			break;
776
	}
777

    
778
	if (!$g['booting']) {
779
		/* reload the filter */
780
		filter_configure();
781
	}
782

    
783
	if ($g['booting'])
784
		echo "done\n";
785

    
786
	return 0;
787
}
788

    
789
function vpn_localnet_determine($adr, &$sa, &$sn) {
790
	global $config, $g;
791

    
792
	if (isset($adr)) {
793
		if ($adr['network']) {
794
			switch ($adr['network']) {
795
				case 'lan':
796
					$sn = $config['interfaces']['lan']['subnet'];
797
					$sa = gen_subnet($config['interfaces']['lan']['ipaddr'], $sn);
798
					break;
799
			}
800
		} else if ($adr['address']) {
801
			list($sa,$sn) = explode("/", $adr['address']);
802
			if (is_null($sn))
803
				$sn = 32;
804
		}
805
	} else {
806
		$sn = $config['interfaces']['lan']['subnet'];
807
		$sa = gen_subnet($config['interfaces']['lan']['ipaddr'], $sn);
808
	}
809
}
810

    
811
function vpn_endpoint_determine($tunnel, $curwanip) {
812

    
813
	global $g, $config;
814

    
815
	if ((!$tunnel['interface']) || ($tunnel['interface'] == "wan")) {
816
		if ($curwanip)
817
			return $curwanip;
818
		else
819
			return null;
820
	} else if ($tunnel['interface'] == "lan") {
821
		return $config['interfaces']['lan']['ipaddr'];
822
	} else {
823
		$oc = $config['interfaces'][$tunnel['interface']];
824

    
825
		if (isset($oc['enable']) && $oc['if']) {
826
			return $oc['ipaddr'];
827
		}
828
	}
829

    
830
	return null;
831
}
832

    
833
function vpn_pppoe_configure() {
834
	global $config, $g;
835

    
836
	$syscfg = $config['system'];
837
	$pppoecfg = $config['pppoe'];
838

    
839
	/* create directory if it does not exist */
840
	if(!is_dir("{$g['varetc_path']}/mpd-vpn"))
841
		mkdir("{$g['varetc_path']}/mpd-vpn");
842

    
843
	if ($g['booting']) {
844
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
845
			return 0;
846

    
847
		echo "Configuring PPPoE VPN service... ";
848
	}
849

    
850
	/* make sure mpd-vpn directory exists */
851
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
852
		mkdir("{$g['varetc_path']}/mpd-vpn");
853

    
854
	switch ($pppoecfg['mode']) {
855

    
856
		case 'server':
857

    
858
			$pppoe_interface = filter_translate_type_to_real_interface($pppoecfg['interface']);
859

    
860
			/* write mpd.conf */
861
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.conf", "a");
862
			if (!$fd) {
863
				printf("Error: cannot open mpd.conf in vpn_pppoe_configure().\n");
864
				return 1;
865
			}
866
			$mpdconf = "\n\n";
867
			$mpdconf .= <<<EOD
868
pppoe:
869

    
870
EOD;
871

    
872
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
873
				$mpdconf .= "	load pppoe{$i}\n";
874
			}
875

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

    
878
				$clientip = long2ip(ip2long($pppoecfg['remoteip']) + $i);
879
				$ngif = "ng" . ($i+1);
880

    
881
				if(isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['enable'])) {
882
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
883
					$isssue_ip_type .="\n\tset ipcp yes radius-ip";
884
				} else {
885
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
886
				}
887

    
888
				$mpdconf .= <<<EOD
889

    
890
pppoe{$i}:
891
	new -i {$ngif} pppoe{$i} pppoe{$i}
892
	{$isssue_ip_type}
893
	load pppoe_standart
894

    
895
EOD;
896
			}
897

    
898
			$mpdconf .= <<<EOD
899

    
900
pppoe_standart:
901
	set link type pppoe
902
	set pppoe iface {$pppoe_interface}
903
	set pppoe service "*"
904
	set pppoe disable originate
905
	set pppoe enable incoming
906
	set bundle no multilink
907
	set bundle enable compression
908
	set bundle max-logins 1
909
	set iface idle 0
910
	set iface disable on-demand
911
	set iface disable proxy-arp
912
	set iface enable tcpmssfix
913
	set iface mtu 1500
914
	set link no pap chap
915
	set link enable chap
916
	set link keep-alive 60 180
917
	set ipcp yes vjcomp
918
	set ipcp no vjcomp
919
	set link max-redial -1
920
	set link mtu 1492
921
	set link mru 1492
922
	set ccp yes mpp-e40
923
	set ccp yes mpp-e128
924
	set ccp yes mpp-stateless
925
	set link latency 1
926
	#set ipcp dns 10.10.1.3
927
	#set bundle accept encryption
928

    
929
EOD;
930

    
931
			if (isset($config['dnsmasq']['enable'])) {
932
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
933
				if ($syscfg['dnsserver'][0])
934
					$mpdconf .= " " . $syscfg['dnsserver'][0];
935
				$mpdconf .= "\n";
936
			} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
937
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
938
			}
939

    
940
			if (isset($pppoecfg['radius']['enable'])) {
941
				$mpdconf .= <<<EOD
942
	set radius server {$pppoecfg['radius']['server']} "{$pppoecfg['radius']['secret']}"
943
	set radius retries 3
944
	set radius timeout 10
945
	set bundle enable radius-auth
946
	set bundle disable radius-fallback
947

    
948
EOD;
949

    
950
				if (isset($pppoecfg['radius']['accounting'])) {
951
					$mpdconf .= <<<EOD
952
	set bundle enable radius-acct
953

    
954
EOD;
955
				}
956
			}
957

    
958
			fwrite($fd, $mpdconf);
959
			fclose($fd);
960

    
961
			/* write mpd.links */
962
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.links", "a");
963
			if (!$fd) {
964
				printf("Error: cannot open mpd.links in vpn_pppoe_configure().\n");
965
				return 1;
966
			}
967

    
968
			$mpdlinks = "";
969

    
970
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
971
				$mpdlinks .= <<<EOD
972

    
973
pppoe:
974
	set link type pppoe
975
	set pppoe iface {$pppoe_interface}
976

    
977
EOD;
978
			}
979

    
980
			fwrite($fd, $mpdlinks);
981
			fclose($fd);
982

    
983
			/* write mpd.secret */
984
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.secret", "a");
985
			if (!$fd) {
986
				printf("Error: cannot open mpd.secret in vpn_pppoe_configure().\n");
987
				return 1;
988
			}
989

    
990
			$mpdsecret = "\n\n";
991

    
992
			if (is_array($pppoecfg['user'])) {
993
				foreach ($pppoecfg['user'] as $user)
994
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
995
			}
996

    
997
			fwrite($fd, $mpdsecret);
998
			fclose($fd);
999
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
1000

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

    
1004
			break;
1005

    
1006
		case 'redir':
1007
			break;
1008
	}
1009

    
1010
	touch("{$g["tmp_path"]}/filter_dirty");
1011

    
1012
	if ($g['booting'])
1013
		echo "done\n";
1014

    
1015
	return 0;
1016
}
1017

    
1018
?>
(22-22/27)