Project

General

Profile

Download (29.5 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 (!isset($ipseccfg['enable'])) {
141
		mwexec("/sbin/ifconfig enc0 down");
142
		mwexec("/sbin/ifconfig enc0 destroy");
143

    
144
		/* kill racoon */
145
		mwexec("/usr/bin/killall racoon");
146

    
147
		/* wait for process to die */
148
		sleep(2);
149

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

    
153
		/* flush SPD and SAD */
154
		mwexec("/sbin/setkey -FP");
155
		mwexec("/sbin/setkey -F");
156

    
157
		return true;
158
	}
159

    
160
	if ($g['booting']) {
161
		echo "Configuring IPsec VPN... ";
162
	}
163

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

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

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

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

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

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

    
188
				$spdconf = "";
189

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

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

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

    
198
					$ep = vpn_endpoint_determine($tunnel, $curwanip);
199
					if (!$ep) {
200
						log_error("Could not deterimine VPN endpoint for {$tunnel['descr']}");
201
						continue;	
202
					}
203

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

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

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

    
221
					if(isset($tunnel['creategif'])) {
222
						$number_of_gifs = find_last_gif_device();
223
						$number_of_gifs++;
224
						$curwanip = get_current_wan_address();
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
					if($tunnel['interface'] <> "wan") {
241
						/* static route needed? */
242
						if(strstr("carp", $tunnel['interface'])) {
243
							
244
						}
245
					}
246
				}
247

    
248
				fwrite($fd, $spdconf);
249
				fclose($fd);
250

    
251
				/* load SPD */
252
				mwexec("/sbin/setkey -c < {$g['varetc_path']}/spd.conf");
253
			}
254

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

    
262
			$racoonconf = "";
263

    
264
			$racoonconf .= "path pre_shared_key \"{$g['varetc_path']}/psk.txt\";\n\n";
265
			$racoonconf .= "path certificate  \"{$g['varetc_path']}\";\n\n";
266

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

    
288
			$tunnelnumber = 0;
289
			if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel']))
290
				foreach ($ipseccfg['tunnel'] as $tunnel) {
291

    
292
				++$tunnelnumber;
293

    
294
				if (isset($tunnel['disabled']))
295
					continue;
296

    
297
				$ep = vpn_endpoint_determine($tunnel, $curwanip);
298
				if (!$ep)
299
					continue;
300

    
301
				vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn);
302

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

    
320
				if (isset($tunnel['p1']['authentication_method'])) {
321
					$authmethod = $tunnel['p1']['authentication_method'];
322
				} else {$authmethod = 'pre_shared_key';}
323

    
324
				$certline = '';
325

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

    
336
					if ($tunnel['p1']['peercert'])
337
						$peercert = base64_decode($tunnel['p1']['peercert']);
338
					else
339
						$peercert = '';
340

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

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

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

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

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

    
386
	proposal \{
387
		encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
388
		hash_algorithm {$tunnel['p1']['hash-algorithm']};
389
		authentication_method {$authmethod};
390
		dh_group {$tunnel['p1']['dhgroup']};
391

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

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

    
398
				if ($tunnel['p1']['lifetime'])
399
					$racoonconf .= "	lifetime time {$tunnel['p1']['lifetime']} secs;\n";
400

    
401
				$racoonconf .= "}\n\n";
402

    
403
				$p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']);
404
				$p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']);
405

    
406
				$racoonconf .= <<<EOD
407
sainfo address {$sa}/{$sn} any address {$tunnel['remote-subnet']} any \{
408
	encryption_algorithm {$p2ealgos};
409
	authentication_algorithm {$p2halgos};
410
	compression_algorithm deflate;
411

    
412
EOD;
413

    
414
				if ($tunnel['p2']['pfsgroup'])
415
					$racoonconf .= "	pfs_group {$tunnel['p2']['pfsgroup']};\n";
416

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

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

    
423
			/* mobile clients? */
424
			if (isset($ipseccfg['mobileclients']['enable'])) {
425

    
426
				$tunnel = $ipseccfg['mobileclients'];
427

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

    
442
				if (isset($tunnel['p1']['authentication_method'])) {
443
					$authmethod = $tunnel['p1']['authentication_method'];
444
				} else {$authmethod = 'pre_shared_key';}
445

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

    
457
					if ($tunnel['p1']['peercert'])
458
						$peercert = base64_decode($tunnel['p1']['peercert']);
459
					else
460
						$peercert = '';
461

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

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

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

    
493
	proposal \{
494
		encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
495
		hash_algorithm {$tunnel['p1']['hash-algorithm']};
496
		authentication_method {$authmethod};
497
		dh_group {$tunnel['p1']['dhgroup']};
498

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

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

    
505
				if ($tunnel['p1']['lifetime'])
506
					$racoonconf .= "	lifetime time {$tunnel['p1']['lifetime']} secs;\n";
507

    
508
				$racoonconf .= "}\n\n";
509

    
510
				$p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']);
511
				$p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']);
512

    
513
				$racoonconf .= <<<EOD
514
sainfo anonymous \{
515
	encryption_algorithm {$p2ealgos};
516
	authentication_algorithm {$p2halgos};
517
	compression_algorithm deflate;
518

    
519
EOD;
520

    
521
				if ($tunnel['p2']['pfsgroup'])
522
					$racoonconf .= "	pfs_group {$tunnel['p2']['pfsgroup']};\n";
523

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

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

    
530
			fwrite($fd, $racoonconf);
531
			fclose($fd);
532

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

    
540
			$pskconf = "";
541

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

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

    
557
			fwrite($fd, $pskconf);
558
			fclose($fd);
559
			chmod("{$g['varetc_path']}/psk.txt", 0600);
560

    
561
			if(is_process_running("racoon")) {
562
				/* We are already online, reload */
563
				mwexec("/usr/local/sbin/racoonctl reload-config");
564
				sleep(1);
565
				exec("/usr/bin/ps auxw | grep \"/usr/local/sbin/[r]acoon\" | awk '{print $2}'", $racoonpid);
566
				if(! empty($racoonpid)) {
567
					mwexec("/usr/bin/kill -HUP $racoonpid[0]");
568
				}
569
			} else {
570
				/* sleep for a bit */
571
				sleep (2);
572

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

    
579
	vpn_ipsec_failover_configure();
580

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

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

    
589
	return 0;
590
}
591

    
592
function vpn_pptpd_configure() {
593
	global $config, $g;
594

    
595
	$syscfg = $config['system'];
596
	$pptpdcfg = $config['pptpd'];
597

    
598
    $starting_ng = get_number_of_wan_netgraph_interfaces_needed();
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-pptpd.pid");
608

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

    
612
        if (is_process_running("mpd4 -b")) {
613
            killbypid("{$g['varrun_path']}/mpd-pptpd.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-pptpd/mpd.conf");
619
        unlink_if_exists("{$g['varetc_path']}/mpd-pptpd/mpd.links");
620
        unlink_if_exists("{$g['varetc_path']}/mpd-pptpd/mpd.secret");
621
	}
622

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

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

    
629
		case 'server':
630

    
631
			/* write mpd.conf */
632
			$fd = fopen("{$g['varetc_path']}/mpd-pptpd/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
startup:
640
pptpd:
641

    
642
EOD;
643

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

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

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

    
653
				if(isset($pptpdcfg['radius']['radiusissueips']) && isset($pptpdcfg['radius']['enable'])) {
654
					$isssue_ip_type = "set ipcp ranges {$pptpdcfg['localip']}/32 0.0.0.0/0";
655
				} else {
656
					$isssue_ip_type = "set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32";
657
				}
658

    
659
				$mpdconf .= <<<EOD
660

    
661
pt{$i}:
662
	new -i {$ngif} pt{$i} pt{$i}
663
	{$isssue_ip_type}
664
	load pptpd_standard
665

    
666
EOD;
667
			}
668

    
669
			$mpdconf .= <<<EOD
670

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

    
690
EOD;
691

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

    
696
EOD;
697
			}
698
			if (isset($pptpdcfg['wins'])) {
699
				$mpdconf .= <<<EOD
700
	set ipcp nbns {$pptpdcfg['wins']}
701

    
702
EOD;
703
			}
704
		       if (isset($pptpdcfg['dns1'])) {
705
					$mpdconf .= <<<EOD
706
	set ipcp dns {$pptpdcfg['dns1']} {$pptpdcfg['dns2']}
707

    
708
EOD;
709
			} else if (isset($config['dnsmasq']['enable'])) {
710
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
711
				if ($syscfg['dnsserver'][0])
712
					$mpdconf .= " " . $syscfg['dnsserver'][0];
713
				$mpdconf .= "\n";
714
			} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
715
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
716
			}
717

    
718
			if (isset($pptpdcfg['radius']['server']['enable'])) {
719
				$mpdconf .= <<<EOD
720
	load radius
721

    
722
radius: 
723
	set radius retries 3
724
	set radius timeout 3 
725
	set radius me {$pptpdcfg['radius']['nasip']}
726
	set auth enable radius-auth 
727
	set radius enable message-authentic
728

    
729
EOD;
730

    
731
				if (isset($pptpdcfg['radius']['server2']['enable'])) {
732
					$mpdconf .= <<<EOD
733
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret']}" {$pptpdcfg['radius']['server2']['port']} {$pptpdcfg['radius']['server2']['acctport']} 
734

    
735
EOD;
736
				}
737

    
738
			if (isset($pptpdcfg['radius']['server']['enable'])) {
739
				$mpdconf .= <<<EOD
740
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$pptpdcfg['radius']['server']['port']} {$pptpdcfg['radius']['server']['acctport']} 
741

    
742
EOD;
743
			}
744

    
745
				if (isset($pptpdcfg['radius']['accounting'])) {
746
					$mpdconf .= <<<EOD
747
	set auth enable radius-acct 
748
	set auth acct-update {$pptpdcfg['radius']['acct_update']}
749
EOD;
750
				}
751
			} else {
752
				$mpdconf .= <<<EOD
753
	set auth enable system
754
	set auth timeout 30
755

    
756
EOD;
757

    
758
		}
759
			fwrite($fd, $mpdconf);
760
			fclose($fd);
761

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

    
769
			$mpdlinks = "";
770

    
771
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
772
				$mpdlinks .= <<<EOD
773

    
774
pt{$i}:
775
	set link type pptp
776
	set pptp self 127.0.0.1
777
	set pptp enable incoming
778
	set pptp disable originate
779

    
780
EOD;
781
			}
782

    
783
			fwrite($fd, $mpdlinks);
784
			fclose($fd);
785

    
786
			/* write mpd.secret */
787
			$fd = fopen("{$g['varetc_path']}/mpd-pptpd/mpd.secret", "w");
788
			if (!$fd) {
789
				printf("Error: cannot open mpd.secret in vpn_pptpd_configure().\n");
790
				return 1;
791
			}
792

    
793
			$mpdsecret = "";
794

    
795
			if (is_array($pptpdcfg['user'])) {
796
				foreach ($pptpdcfg['user'] as $user)
797
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
798
			}
799

    
800
			fwrite($fd, $mpdsecret);
801
			fclose($fd);
802
			chmod("{$g['varetc_path']}/mpd-pptpd/mpd.secret", 0600);
803

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

    
807
			break;
808

    
809
		case 'redir':
810
			break;
811
	}
812

    
813
	if (!$g['booting']) {
814
		/* reload the filter */
815
		filter_configure();
816
	}
817

    
818
	if ($g['booting'])
819
		echo "done\n";
820

    
821
	return 0;
822
}
823

    
824
function vpn_localnet_determine($adr, &$sa, &$sn) {
825
	global $config, $g;
826

    
827
	if (isset($adr)) {
828
		if ($adr['network']) {
829
			switch ($adr['network']) {
830
				case 'lan':
831
					$sn = $config['interfaces']['lan']['subnet'];
832
					$sa = gen_subnet($config['interfaces']['lan']['ipaddr'], $sn);
833
					break;
834
			}
835
		} else if ($adr['address']) {
836
			list($sa,$sn) = explode("/", $adr['address']);
837
			if (is_null($sn))
838
				$sn = 32;
839
		}
840
	} else {
841
		$sn = $config['interfaces']['lan']['subnet'];
842
		$sa = gen_subnet($config['interfaces']['lan']['ipaddr'], $sn);
843
	}
844
}
845

    
846
function vpn_endpoint_determine($tunnel, $curwanip) {
847

    
848
	global $g, $config;
849

    
850
	if ((!$tunnel['interface']) || ($tunnel['interface'] == "wan")) {
851
		if ($curwanip)
852
			return $curwanip;
853
		else
854
			return null;
855
	} else if ($tunnel['interface'] == "lan") {
856
		return $config['interfaces']['lan']['ipaddr'];
857
	} else {
858
		$oc = $config['interfaces'][$tunnel['interface']];
859
		/* carp ips, etc */
860
		$ip = find_interface_ip($tunnel['interface']);
861
		if($ip) 
862
			return $ip;
863

    
864
		if (isset($oc['enable']) && $oc['if']) {
865
			return $oc['ipaddr'];
866
		}
867
	}
868

    
869
	return null;
870
}
871

    
872
function vpn_pppoe_configure() {
873
	global $config, $g;
874

    
875
	$syscfg = $config['system'];
876
	$pppoecfg = $config['pppoe'];
877

    
878
   $starting_ng = get_number_of_wan_netgraph_interfaces_needed();
879

    
880
	/* create directory if it does not exist */
881
    if (!is_dir("{$g['varetc_path']}/mpd-pppoe"))
882
        mkdir("{$g['varetc_path']}/mpd-pppoe");
883

    
884
	if ($g['booting']) {
885
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
886
			return 0;
887

    
888
		echo "Configuring PPPoE VPN service... ";
889
    } else {
890
        /* kill mpd */
891
        killbypid("{$g['varrun_path']}/mpd-pppoe.pid");
892

    
893
        /* wait for process to die */
894
        sleep(2);
895
        unlink_if_exists("{$g['varetc_path']}/mpd-pppoe/mpd.conf");
896
        unlink_if_exists("{$g['varetc_path']}/mpd-pppoe/mpd.links");
897
        unlink_if_exists("{$g['varetc_path']}/mpd-pppoe/mpd.secret");
898
	}
899

    
900
	/* make sure mpd-vpn directory exists */
901
    if (!file_exists("{$g['varetc_path']}/mpd-pppoe"))
902
        mkdir("{$g['varetc_path']}/mpd-pppoe");
903

    
904
	switch ($pppoecfg['mode']) {
905

    
906
		case 'server':
907

    
908
			$pppoe_interface = filter_translate_type_to_real_interface($pppoecfg['interface']);
909

    
910
			/* write mpd.conf */
911
			$fd = fopen("{$g['varetc_path']}/mpd-pppoe/mpd.conf", "a");
912
			if (!$fd) {
913
				printf("Error: cannot open mpd.conf in vpn_pppoe_configure().\n");
914
				return 1;
915
			}
916
			$mpdconf = "\n\n";
917
			$mpdconf .= <<<EOD
918
startup:
919
pppoe:
920

    
921
EOD;
922

    
923
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
924
				$mpdconf .= "	load pppoe{$i}\n";
925
			}
926

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

    
929
				$clientip = long2ip(ip2long($pppoecfg['remoteip']) + $i);
930
				$ngif = "ng" . ($i+1);
931

    
932
				if(isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['enable'])) {
933
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
934
				} else {
935
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
936
				}
937

    
938
				$mpdconf .= <<<EOD
939

    
940
pppoe{$i}:
941
	new -i {$ngif} pppoe{$i} pppoe{$i}
942
	{$isssue_ip_type}
943
	load pppoe_standart
944

    
945
EOD;
946
			}
947

    
948
			$mpdconf .= <<<EOD
949

    
950
pppoe_standart:
951
	set link type pppoe
952
	set pppoe iface {$pppoe_interface}
953
	set pppoe service "*"
954
	set iface up-script /usr/local/sbin/vpn-linkup
955
	set iface down-script /usr/local/sbin/vpn-linkdown
956
	set bundle enable compression
957
	set auth max-logins 1
958
	set link max-redial -1
959
	set pppoe enable incoming
960
	set pppoe disable originate
961
	set iface disable on-demand
962
	set iface disable proxy-arp
963
	set iface idle 0 
964
	set iface enable tcpmssfix
965
	set bundle no multilink  
966
	set link no acfcomp 
967
	set link no protocomp 
968
	set link no pap chap
969
	set link enable chap
970
	set link keep-alive 30 100 
971
	set link mtu 1460 
972
	set ccp yes mpp-e40
973
	set ccp yes mpp-e128
974
	set ccp yes mpp-stateless
975
	set ipcp no vjcomp 
976

    
977
EOD;
978
		if (isset($pppoecfg['dns1'])) {
979
					$mpdconf .= <<<EOD
980
	set ipcp dns {$pppoecfg['dns1']} {$pppoecfg['dns2']}
981

    
982
EOD;
983

    
984
			} else if (isset($config['dnsmasq']['enable'])) {
985
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
986
				if ($syscfg['dnsserver'][0])
987
					$mpdconf .= " " . $syscfg['dnsserver'][0];
988
				$mpdconf .= "\n";
989
			} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
990
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
991
			}
992

    
993
			if (isset($pppoecfg['radius']['server']['enable'])) {
994
				$mpdconf .= <<<EOD
995
	load radius
996

    
997
radius: 
998
	set radius retries 3
999
	set radius timeout 3 
1000
	set radius me {$pppoecfg['radius']['nasip']}
1001
	set auth enable radius-auth 
1002
	set radius enable message-authentic
1003

    
1004
EOD;
1005
				if (isset($pppoecfg['radius']['server2']['enable'])) {
1006
					$mpdconf .= <<<EOD
1007
	set radius server {$pppoecfg['radius']['server2']['ip']} "{$pppoecfg['radius']['server2']['secret']}" {$pppoecfg['radius']['server2']['port']} {$pppoecfg['radius']['server2']['acctport']}
1008

    
1009
EOD;
1010
				}
1011

    
1012
			if (isset($pppoecfg['radius']['server']['enable'])) {
1013
					$mpdconf .= <<<EOD
1014
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$pppoecfg['radius']['server']['port']} {$pppoecfg['radius']['server']['acctport']}
1015

    
1016
EOD;
1017
				}
1018

    
1019
				if (isset($pppoecfg['radius']['accounting'])) {
1020
					$mpdconf .= <<<EOD
1021
	set auth enable radius-acct 
1022
	set auth acct-update {$pppoecfg['radius']['acct_update']}
1023
EOD;
1024
			}
1025
			} else {
1026
				$mpdconf .= <<<EOD
1027
	set auth enable system
1028
	set auth timeout 30
1029

    
1030
EOD;
1031
			}
1032
			fwrite($fd, $mpdconf);
1033
			fclose($fd);
1034

    
1035
			/* write mpd.links */
1036
			$fd = fopen("{$g['varetc_path']}/mpd-pppoe/mpd.links", "a");
1037
			if (!$fd) {
1038
				printf("Error: cannot open mpd.links in vpn_pppoe_configure().\n");
1039
				return 1;
1040
			}
1041

    
1042
			$mpdlinks = "";
1043

    
1044
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1045
				$mpdlinks .= <<<EOD
1046

    
1047
pppoe:
1048
	set link type pppoe
1049
	set pppoe iface {$pppoe_interface}
1050
        set pppoe service "*"
1051
	 set pppoe disable incoming
1052
	 set pppoe enable originate
1053

    
1054

    
1055
EOD;
1056
			}
1057

    
1058
			fwrite($fd, $mpdlinks);
1059
			fclose($fd);
1060

    
1061
			/* write mpd.secret */
1062
			$fd = fopen("{$g['varetc_path']}/mpd-pppoe/mpd.secret", "a");
1063
			if (!$fd) {
1064
				printf("Error: cannot open mpd.secret in vpn_pppoe_configure().\n");
1065
				return 1;
1066
			}
1067

    
1068
			$mpdsecret = "\n\n";
1069

    
1070
			if (is_array($pppoecfg['user'])) {
1071
				foreach ($pppoecfg['user'] as $user)
1072
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1073
			}
1074

    
1075
			fwrite($fd, $mpdsecret);
1076
			fclose($fd);
1077
			chmod("{$g['varetc_path']}/mpd-pppoe/mpd.secret", 0600);
1078

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

    
1082
			break;
1083

    
1084
		case 'redir':
1085
			break;
1086
	}
1087

    
1088
	touch("{$g["tmp_path"]}/filter_dirty");
1089

    
1090
	if ($g['booting'])
1091
		echo "done\n";
1092

    
1093
	return 0;
1094
}
1095

    
1096
?>
(24-24/29)