Project

General

Profile

Download (27.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
	if($config['installedpackages']['sasyncd']['config'] <> "")
133
		foreach($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
134
			if($sasyncd['ip'] <> "")
135
				$curwanip = $sasyncd['ip'];
136
		}
137

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

    
145
	if ($g['booting']) {
146
		if (!isset($ipseccfg['enable']))
147
			return 0;
148

    
149
		echo "Configuring IPsec VPN... ";
150
	} else {
151
		/* kill racoon */
152
		mwexec("/usr/bin/killall racoon");
153

    
154
		/* wait for process to die */
155
		sleep(2);
156

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

    
161
	/* flush SPD and SAD */
162
	mwexec("/sbin/setkey -FP");
163
	mwexec("/sbin/setkey -F");
164

    
165
	if (isset($ipseccfg['enable'])) {
166

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

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

    
177
		if ((is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) ||
178
				isset($ipseccfg['mobileclients']['enable'])) {
179

    
180
			if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) {
181

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

    
189
				$spdconf = "";
190

    
191
				$spdconf .= "spdadd {$lansa}/{$lansn} {$lanip}/32 any -P in none;\n";
192
				$spdconf .= "spdadd {$lanip}/32 {$lansa}/{$lansn} any -P out none;\n";
193

    
194
				foreach ($ipseccfg['tunnel'] as $tunnel) {
195

    
196
					if (isset($tunnel['disabled']))
197
						continue;
198

    
199
					$ep = vpn_endpoint_determine($tunnel, $curwanip);
200
					if (!$ep)
201
						continue;
202

    
203
					vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn);
204

    
205
					if(is_domain($tunnel['remote-gateway'])) {
206
						$tmp = gethostbyname($tunnel['remote-gateway']);
207
						if($tmp)
208
							$tunnel['remote-gateway'] = $tmp;
209
					}
210

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

    
220
					if(isset($tunnel['creategif'])) {
221
						$number_of_gifs = find_last_gif_device();
222
						$number_of_gifs++;
223
						$curwanip = get_current_wan_address();
224
						if($config['installedpackages']['sasyncd']['config'] <> "")
225
							foreach($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
226
								if($sasyncd['ip'] <> "")
227
									$curwanip = $sasyncd['ip'];
228
							}
229
						mwexec("/sbin/ifconfig gif" . $number_of_gifs . " tunnel" . $curwanip . " " . $tunnel['remote-gateway']);
230
						mwexec("/sbin/ifconfig gif" . $number_of_gifs . " {$lansa}/{$lansn} {$lanip}/32");
231
					}
232

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

    
238
					$spdconf .= "spdadd {$tunnel['remote-subnet']} " .
239
						"{$sa}/{$sn} any -P in ipsec " .
240
						"{$tunnel['p2']['protocol']}/tunnel/{$tunnel['remote-gateway']}-" .
241
						"{$ep}/unique;\n";
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

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

    
271
				}
272
				$interface_ip = $sasyncd['ip'];
273
				if($interface_ip <> "") {
274
					$racoonconf .= <<<EOD
275
listen {
276
	isakmp {$interface_ip} [500];
277
	{$natt}
278
}
279

    
280
EOD;
281
				}
282
			}
283

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

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

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

    
312
				++$tunnelnumber;
313

    
314
				if (isset($tunnel['disabled']))
315
					continue;
316

    
317
				$ep = vpn_endpoint_determine($tunnel, $curwanip);
318
				if (!$ep)
319
					continue;
320

    
321
				vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn);
322

    
323
				if (isset($tunnel['p1']['myident']['myaddress'])) {
324
					$myidentt = "address";
325
					$myident = $ep;
326
				} else if (isset($tunnel['p1']['myident']['address'])) {
327
					$myidentt = "address";
328
					$myident = $tunnel['p1']['myident']['address'];
329
				} else if (isset($tunnel['p1']['myident']['fqdn'])) {
330
					$myidentt = "fqdn";
331
					$myident = $tunnel['p1']['myident']['fqdn'];
332
				} else if (isset($tunnel['p1']['myident']['ufqdn'])) {
333
					$myidentt = "user_fqdn";
334
					$myident = $tunnel['p1']['myident']['ufqdn'];
335
 				} else if (isset($tunnel['p1']['myident']['dyn_dns'])) {
336
					$myidentt = "dyn_dns";
337
					$myident = gethostbyname($tunnel['p1']['myident']['dyn_dns']);
338
 				}
339

    
340
				if (isset($tunnel['p1']['authentication_method'])) {
341
					$authmethod = $tunnel['p1']['authentication_method'];
342
				} else {$authmethod = 'pre_shared_key';}
343

    
344
				$certline = '';
345

    
346
				if ($authmethod == 'rsasig') {
347
					if ($tunnel['p1']['cert'] && $tunnel['p1']['private-key']) {
348
						$cert = base64_decode($tunnel['p1']['cert']);
349
						$private_key = base64_decode($tunnel['p1']['private-key']);
350
					} else {
351
						/* null certificate/key */
352
						$cert = '';
353
						$private_key = '';
354
					}
355

    
356
					if ($tunnel['p1']['peercert'])
357
						$peercert = base64_decode($tunnel['p1']['peercert']);
358
					else
359
						$peercert = '';
360

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

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

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

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

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

    
406
	proposal \{
407
		encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
408
		hash_algorithm {$tunnel['p1']['hash-algorithm']};
409
		authentication_method {$authmethod};
410
		dh_group {$tunnel['p1']['dhgroup']};
411

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

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

    
418
				if ($tunnel['p1']['lifetime'])
419
					$racoonconf .= "	lifetime time {$tunnel['p1']['lifetime']} secs;\n";
420

    
421
				$racoonconf .= "}\n\n";
422

    
423
				$p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']);
424
				$p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']);
425

    
426
				$racoonconf .= <<<EOD
427
sainfo address {$sa}/{$sn} any address {$tunnel['remote-subnet']} any \{
428
	encryption_algorithm {$p2ealgos};
429
	authentication_algorithm {$p2halgos};
430
	compression_algorithm deflate;
431

    
432
EOD;
433

    
434
				if ($tunnel['p2']['pfsgroup'])
435
					$racoonconf .= "	pfs_group {$tunnel['p2']['pfsgroup']};\n";
436

    
437
				if ($tunnel['p2']['lifetime'])
438
					$racoonconf .= "	lifetime time {$tunnel['p2']['lifetime']} secs;\n";
439

    
440
				$racoonconf .= "}\n\n";
441
			}
442

    
443
			/* mobile clients? */
444
			if (isset($ipseccfg['mobileclients']['enable'])) {
445

    
446
				$tunnel = $ipseccfg['mobileclients'];
447

    
448
				if (isset($tunnel['p1']['myident']['myaddress'])) {
449
					$myidentt = "address";
450
					$myident = $curwanip;
451
				} else if (isset($tunnel['p1']['myident']['address'])) {
452
					$myidentt = "address";
453
					$myident = $tunnel['p1']['myident']['address'];
454
				} else if (isset($tunnel['p1']['myident']['fqdn'])) {
455
					$myidentt = "fqdn";
456
					$myident = $tunnel['p1']['myident']['fqdn'];
457
				} else if (isset($tunnel['p1']['myident']['ufqdn'])) {
458
					$myidentt = "user_fqdn";
459
					$myident = $tunnel['p1']['myident']['ufqdn'];
460
 				}
461

    
462
				if (isset($tunnel['p1']['authentication_method'])) {
463
					$authmethod = $tunnel['p1']['authentication_method'];
464
				} else {$authmethod = 'pre_shared_key';}
465

    
466
				$certline = '';
467
				if ($authmethod == 'rsasig') {
468
					if ($tunnel['p1']['cert'] && $tunnel['p1']['private-key']) {
469
						$cert = base64_decode($tunnel['p1']['cert']);
470
						$private_key = base64_decode($tunnel['p1']['private-key']);
471
					} else {
472
						/* null certificate/key */
473
						$cert = '';
474
						$private_key = '';
475
					}
476

    
477
					if ($tunnel['p1']['peercert'])
478
						$peercert = base64_decode($tunnel['p1']['peercert']);
479
					else
480
						$peercert = '';
481

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

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

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

    
513
	proposal \{
514
		encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
515
		hash_algorithm {$tunnel['p1']['hash-algorithm']};
516
		authentication_method {$authmethod};
517
		dh_group {$tunnel['p1']['dhgroup']};
518

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

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

    
525
				if ($tunnel['p1']['lifetime'])
526
					$racoonconf .= "	lifetime time {$tunnel['p1']['lifetime']} secs;\n";
527

    
528
				$racoonconf .= "}\n\n";
529

    
530
				$p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']);
531
				$p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']);
532

    
533
				$racoonconf .= <<<EOD
534
sainfo anonymous \{
535
	encryption_algorithm {$p2ealgos};
536
	authentication_algorithm {$p2halgos};
537
	compression_algorithm deflate;
538

    
539
EOD;
540

    
541
				if ($tunnel['p2']['pfsgroup'])
542
					$racoonconf .= "	pfs_group {$tunnel['p2']['pfsgroup']};\n";
543

    
544
				if ($tunnel['p2']['lifetime'])
545
					$racoonconf .= "	lifetime time {$tunnel['p2']['lifetime']} secs;\n";
546

    
547
				$racoonconf .= "}\n\n";
548
			}
549

    
550
			fwrite($fd, $racoonconf);
551
			fclose($fd);
552

    
553
			/* generate psk.txt */
554
			$fd = fopen("{$g['varetc_path']}/psk.txt", "w");
555
			if (!$fd) {
556
				printf("Error: cannot open psk.txt in vpn_ipsec_configure().\n");
557
				return 1;
558
			}
559

    
560
			$pskconf = "";
561

    
562
			if (is_array($ipseccfg['tunnel'])) {
563
				foreach ($ipseccfg['tunnel'] as $tunnel) {
564
					if (isset($tunnel['disabled']))
565
						continue;
566
					$pskconf .= "{$tunnel['remote-gateway']}	 {$tunnel['p1']['pre-shared-key']}\n";
567
				}
568
			}
569

    
570
			/* add PSKs for mobile clients */
571
			if (is_array($ipseccfg['mobilekey'])) {
572
				foreach ($ipseccfg['mobilekey'] as $key) {
573
					$pskconf .= "{$key['ident']}	{$key['pre-shared-key']}\n";
574
				}
575
			}
576

    
577
			fwrite($fd, $pskconf);
578
			fclose($fd);
579
			chmod("{$g['varetc_path']}/psk.txt", 0600);
580

    
581
			/* start racoon */
582
			mwexec("/usr/local/sbin/racoon -f {$g['varetc_path']}/racoon.conf");
583
		}
584
	}
585

    
586
	vpn_ipsec_failover_configure();
587

    
588
	if (!$g['booting']) {
589
		/* reload the filter */
590
		touch("{$g["tmp_path"]}/filter_dirty");
591
	}
592

    
593
	if ($g['booting'])
594
		echo "done\n";
595

    
596
	return 0;
597
}
598

    
599
function vpn_pptpd_configure() {
600
	global $config, $g;
601

    
602
	$syscfg = $config['system'];
603
	$pptpdcfg = $config['pptpd'];
604

    
605
	if ($g['booting']) {
606
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
607
			return 0;
608

    
609
		echo "Configuring PPTP VPN service... ";
610
	} else {
611
		/* kill mpd */
612
		killbypid("{$g['varrun_path']}/mpd-vpn.pid");
613

    
614
		/* wait for process to die */
615
		sleep(3);
616

    
617
		if(is_process_running("mpd -b")) {
618
			killbypid("{$g['varrun_path']}/mpd-vpn.pid");
619
			log_error("Could not kill mpd within 3 seconds.   Trying again.");
620
		}
621

    
622
		/* remove mpd.conf, if it exists */
623
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.conf");
624
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.links");
625
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.secret");
626
	}
627

    
628
	/* make sure mpd-vpn directory exists */
629
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
630
		mkdir("{$g['varetc_path']}/mpd-vpn");
631

    
632
	switch ($pptpdcfg['mode']) {
633

    
634
		case 'server':
635

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

    
643
			$mpdconf = <<<EOD
644
pptpd:
645

    
646
EOD;
647

    
648
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
649
				$mpdconf .= "	load pt{$i}\n";
650
			}
651

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

    
654
				$clientip = long2ip(ip2long($pptpdcfg['remoteip']) + $i);
655
				$ngif = "ng" . ($i+1);
656

    
657
				$mpdconf .= <<<EOD
658

    
659
pt{$i}:
660
	new -i {$ngif} pt{$i} pt{$i}
661
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
662
	load pts
663

    
664
EOD;
665
			}
666

    
667
			$mpdconf .= <<<EOD
668

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

    
689
EOD;
690

    
691
			if (!isset($pptpdcfg['req128'])) {
692
				$mpdconf .= <<<EOD
693
	set ccp yes mpp-e40
694
	set ccp yes mpp-e56
695

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

    
711
			if (isset($pptpdcfg['radius']['enable'])) {
712
				$mpdconf .= <<<EOD
713
	set radius server {$pptpdcfg['radius']['server']} "{$pptpdcfg['radius']['secret']}"
714
	set radius retries 3
715
	set radius timeout 10
716
	set bundle enable radius-auth
717
	set bundle disable radius-fallback
718

    
719
EOD;
720

    
721
				if (isset($pptpdcfg['radius']['accounting'])) {
722
					$mpdconf .= <<<EOD
723
	set bundle enable radius-acct
724

    
725
EOD;
726
				}
727
			}
728

    
729
			fwrite($fd, $mpdconf);
730
			fclose($fd);
731

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

    
739
			$mpdlinks = "";
740

    
741
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
742
				$mpdlinks .= <<<EOD
743

    
744
pt{$i}:
745
	set link type pptp
746
	set pptp enable incoming
747
	set pptp disable originate
748
	set pptp disable windowing
749
	set pptp self 127.0.0.1
750

    
751
EOD;
752
			}
753

    
754
			fwrite($fd, $mpdlinks);
755
			fclose($fd);
756

    
757
			/* write mpd.secret */
758
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.secret", "w");
759
			if (!$fd) {
760
				printf("Error: cannot open mpd.secret in vpn_pptpd_configure().\n");
761
				return 1;
762
			}
763

    
764
			$mpdsecret = "";
765

    
766
			if (is_array($pptpdcfg['user'])) {
767
				foreach ($pptpdcfg['user'] as $user)
768
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
769
			}
770

    
771
			fwrite($fd, $mpdsecret);
772
			fclose($fd);
773
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
774

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

    
778
			break;
779

    
780
		case 'redir':
781
			break;
782
	}
783

    
784
	if (!$g['booting']) {
785
		/* reload the filter */
786
		filter_configure();
787
	}
788

    
789
	if ($g['booting'])
790
		echo "done\n";
791

    
792
	return 0;
793
}
794

    
795
function vpn_localnet_determine($adr, &$sa, &$sn) {
796
	global $config, $g;
797

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

    
817
function vpn_endpoint_determine($tunnel, $curwanip) {
818

    
819
	global $g, $config;
820

    
821
	if ((!$tunnel['interface']) || ($tunnel['interface'] == "wan")) {
822
		if ($curwanip)
823
			return $curwanip;
824
		else
825
			return null;
826
	} else if ($tunnel['interface'] == "lan") {
827
		return $config['interfaces']['lan']['ipaddr'];
828
	} else {
829
		$oc = $config['interfaces'][$tunnel['interface']];
830

    
831
		if (isset($oc['enable']) && $oc['if']) {
832
			return $oc['ipaddr'];
833
		}
834
	}
835

    
836
	return null;
837
}
838

    
839
function vpn_pppoe_configure() {
840
	global $config, $g;
841

    
842
	$syscfg = $config['system'];
843
	$pppoecfg = $config['pppoe'];
844

    
845
	/* create directory if it does not exist */
846
	if(!is_dir("{$g['varetc_path']}/mpd-vpn"))
847
		mkdir("{$g['varetc_path']}/mpd-vpn");
848

    
849
	if ($g['booting']) {
850
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
851
			return 0;
852

    
853
		echo "Configuring PPPoE VPN service... ";
854
	}
855

    
856
	/* make sure mpd-vpn directory exists */
857
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
858
		mkdir("{$g['varetc_path']}/mpd-vpn");
859

    
860
	switch ($pppoecfg['mode']) {
861

    
862
		case 'server':
863

    
864
			$pppoe_interface = filter_translate_type_to_real_interface($pppoecfg['interface']);
865

    
866
			/* write mpd.conf */
867
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.conf", "a");
868
			if (!$fd) {
869
				printf("Error: cannot open mpd.conf in vpn_pppoe_configure().\n");
870
				return 1;
871
			}
872
			$mpdconf = "\n\n";
873
			$mpdconf .= <<<EOD
874
pppoe:
875

    
876
EOD;
877

    
878
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
879
				$mpdconf .= "	load pppoe{$i}\n";
880
			}
881

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

    
884
				$clientip = long2ip(ip2long($pppoecfg['remoteip']) + $i);
885
				$ngif = "ng" . ($i+1);
886

    
887
				if(isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['enable'])) {
888
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
889
					$isssue_ip_type .="\n\tset ipcp yes radius-ip";
890
				} else {
891
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
892
				}
893

    
894
				$mpdconf .= <<<EOD
895

    
896
pppoe{$i}:
897
	new -i {$ngif} pppoe{$i} pppoe{$i}
898
	{$isssue_ip_type}
899
	load pppoe_standart
900

    
901
EOD;
902
			}
903

    
904
			$mpdconf .= <<<EOD
905

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

    
935
EOD;
936

    
937
			if (isset($config['dnsmasq']['enable'])) {
938
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
939
				if ($syscfg['dnsserver'][0])
940
					$mpdconf .= " " . $syscfg['dnsserver'][0];
941
				$mpdconf .= "\n";
942
			} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
943
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
944
			}
945

    
946
			if (isset($pppoecfg['radius']['enable'])) {
947
				$mpdconf .= <<<EOD
948
	set radius server {$pppoecfg['radius']['server']} "{$pppoecfg['radius']['secret']}"
949
	set radius retries 3
950
	set radius timeout 10
951
	set bundle enable radius-auth
952
	set bundle disable radius-fallback
953

    
954
EOD;
955

    
956
				if (isset($pppoecfg['radius']['accounting'])) {
957
					$mpdconf .= <<<EOD
958
	set bundle enable radius-acct
959

    
960
EOD;
961
				}
962
			}
963

    
964
			fwrite($fd, $mpdconf);
965
			fclose($fd);
966

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

    
974
			$mpdlinks = "";
975

    
976
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
977
				$mpdlinks .= <<<EOD
978

    
979
pppoe:
980
	set link type pppoe
981
	set pppoe iface {$pppoe_interface}
982

    
983
EOD;
984
			}
985

    
986
			fwrite($fd, $mpdlinks);
987
			fclose($fd);
988

    
989
			/* write mpd.secret */
990
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.secret", "a");
991
			if (!$fd) {
992
				printf("Error: cannot open mpd.secret in vpn_pppoe_configure().\n");
993
				return 1;
994
			}
995

    
996
			$mpdsecret = "\n\n";
997

    
998
			if (is_array($pppoecfg['user'])) {
999
				foreach ($pppoecfg['user'] as $user)
1000
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1001
			}
1002

    
1003
			fwrite($fd, $mpdsecret);
1004
			fclose($fd);
1005
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
1006

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

    
1010
			break;
1011

    
1012
		case 'redir':
1013
			break;
1014
	}
1015

    
1016
	touch("{$g["tmp_path"]}/filter_dirty");
1017

    
1018
	if ($g['booting'])
1019
		echo "done\n";
1020

    
1021
	return 0;
1022
}
1023

    
1024
?>
(22-22/27)