Project

General

Profile

Download (26.7 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	vpn.inc
4
	Copyright (C) 2004 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
function vpn_ipsec_failover_configure() {
37
	global $config, $g;
38

    
39
	$sasyncd_text = "";
40

    
41
	if($config['installedpackages']['sasyncd']['config'] <> "")
42
		foreach($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
43
			$enabled = isset($sasyncd['enable']);
44
			if(!$enabled)
45
				return;
46
			if($sasyncd['peerip'] <> "")
47
				$sasyncd_text .= "peer {$sasyncd['peerip']}\n";
48
			if($sasyncd['interface'])
49
				$sasyncd_text .= "carp interface {$sasyncd['interface']}\n";
50
			if($sasyncd['sharedkey'] <> "")
51
				$sasyncd_text .= "sharedkey {$sasyncd['sharedkey']}\n";
52
			if($sasyncd['mode'] <> "")
53
				$sasyncd_text .= "mode {$sasyncd['mode']}\n";
54
			if($sasyncd['listenon'] <> "")
55
				$sasyncd_text .= "listen on {$sasyncd['listenon']}\n";
56
			if($sasyncd['flushmodesync'] <> "")
57
				$sasyncd_text .= "flushmode sync {$sasyncd['flushmodesync']}\n";
58
		}
59

    
60
	$fd = fopen("{$g['varetc_path']}/sasyncd.conf", "w");
61
	fwrite($fd, $sasyncd_text);
62
	fclose($fd);
63
	chmod("{$g['varetc_path']}/sasyncd.conf", 0600);
64
	
65
	mwexec("killall sasyncd");
66
	
67
	/* launch sasyncd, oh wise one */
68
	mwexec_bg("/usr/local/sbin/sasyncd -d -v -v -v");
69
}
70

    
71
function find_last_gif_device() {
72
        $last_gif_found = -1;
73
        if (!($fp = popen("/sbin/ifconfig -l", "r"))) return -1;
74
        $ifconfig_data = fread($fp, 4096);
75
        pclose($fp);
76
        $ifconfig_array = split(" ", $ifconfig_data);
77
        foreach ($ifconfig_array as $ifconfig) {
78
                ereg("gif(.)", $ifconfig, $regs);
79
                if($regs[0]) {
80
                        if($regs[0] > $last_gif_found)
81
                                $last_gif_found = $regs[1];
82
                }
83
        }
84
        return $last_gif_found;
85
}
86

    
87
function vpn_ipsec_configure($ipchg = false) {
88
	global $config, $g;
89

    
90
	if(isset($config['system']['developer'])) {
91
		if($g['booting'] == true) {
92
			/* determine if we should load the via padlock module */
93
			$dmesg_boot = `cat /var/log/dmesg.boot | grep Features`;
94
			if(stristr($dmesg_boot, "ACE") == true) {		
95
				echo "Enabling [VIA Padlock] ...";
96
				mwexec("/sbin/kldload padlock");
97
				mwexec("/sbin/sysctl net.inet.ipsec.crypto_support=1");
98
				mwexec("/usr/sbin/setkey -F;/usr/sbin/setkey -FP");
99
				echo " done.";
100
			}
101
		}
102
	}
103

    
104
	if(isset($config['ipsec']['preferredoldsa'])) {
105
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
106
	} else {
107
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
108
	}
109

    
110
	$number_of_gifs = find_last_gif_device();
111
	for($x=0; $x<$number_of_gifs; $x++) {
112
		mwexec("/sbin/ifconfig gif" . $x . " delete");
113
	}
114

    
115
	$curwanip = get_current_wan_address();
116
	if($config['installedpackages']['sasyncd']['config'] <> "")
117
		foreach($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
118
			if($sasyncd['ip'] <> "") 
119
				$curwanip = $sasyncd['ip'];
120
		}
121

    
122
	$syscfg = $config['system'];
123
	$ipseccfg = $config['ipsec'];
124
	$lancfg = $config['interfaces']['lan'];
125
	$lanip = $lancfg['ipaddr'];
126
	$lansa = gen_subnet($lancfg['ipaddr'], $lancfg['subnet']);
127
	$lansn = $lancfg['subnet'];
128

    
129
	if ($g['booting']) {
130
		if (!isset($ipseccfg['enable']))
131
			return 0;
132

    
133
		echo "Configuring IPsec VPN... ";
134
	} else {
135
		/* kill racoon */
136
		killbypid("{$g['varrun_path']}/racoon.pid");
137

    
138
		/* wait for process to die */
139
		sleep(2);
140

    
141
		/* send a SIGKILL to be sure */
142
		sigkillbypid("{$g['varrun_path']}/racoon.pid", "KILL");
143
	}
144

    
145
	/* flush SPD and SAD */
146
	mwexec("/usr/sbin/setkey -FP");
147
	mwexec("/usr/sbin/setkey -F");
148

    
149
	if (isset($ipseccfg['enable'])) {
150

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

    
154
		if (!$curwanip) {
155
			/* IP address not configured yet, exit */
156
			if ($g['booting'])
157
				echo "done\n";
158
			return 0;
159
		}
160

    
161
		if ((is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) ||
162
				isset($ipseccfg['mobileclients']['enable'])) {
163

    
164
			if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) {
165

    
166
				/* generate spd.conf */
167
				$fd = fopen("{$g['varetc_path']}/spd.conf", "w");
168
				if (!$fd) {
169
					printf("Error: cannot open spd.conf in vpn_ipsec_configure().\n");
170
					return 1;
171
				}
172

    
173
				$spdconf = "";
174

    
175
				$spdconf .= "spdadd {$lansa}/{$lansn} {$lanip}/32 any -P in none;\n";
176
				$spdconf .= "spdadd {$lanip}/32 {$lansa}/{$lansn} any -P out none;\n";
177

    
178
				foreach ($ipseccfg['tunnel'] as $tunnel) {
179

    
180
					if (isset($tunnel['disabled']))
181
						continue;
182

    
183
					$ep = vpn_endpoint_determine($tunnel, $curwanip);
184
					if (!$ep)
185
						continue;
186

    
187
					vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn);
188

    
189
					if(is_domain($tunnel['remote-gateway'])) {
190
						$tmp = gethostbyname($tunnel['remote-gateway']);
191
						if($tmp)
192
							$tunnel['remote-gateway'] = $tmp;
193
					}
194

    
195
					if(isset($tunnel['creategif'])) {
196
						$number_of_gifs = find_last_gif_device();
197
						$number_of_gifs++;
198
						$curwanip = get_current_wan_address();
199
						if($config['installedpackages']['sasyncd']['config'] <> "")
200
							foreach($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
201
								if($sasyncd['ip'] <> "") 
202
									$curwanip = $sasyncd['ip'];
203
							}						
204
						mwexec("/sbin/ifconfig gif" . $number_of_gifs . " tunnel" . $curwanip . " " . $tunnel['remote-gateway']);
205
						mwexec("/sbin/ifconfig gif" . $number_of_gifs . " {$lansa}/{$lansn} {$lanip}/32");
206
					}
207

    
208
					$spdconf .= "spdadd {$sa}/{$sn} " .
209
						"{$tunnel['remote-subnet']} any -P out ipsec " .
210
						"{$tunnel['p2']['protocol']}/tunnel/{$ep}-" .
211
						"{$tunnel['remote-gateway']}/unique;\n";
212

    
213
					$spdconf .= "spdadd {$tunnel['remote-subnet']} " .
214
						"{$sa}/{$sn} any -P in ipsec " .
215
						"{$tunnel['p2']['protocol']}/tunnel/{$tunnel['remote-gateway']}-" .
216
						"{$ep}/unique;\n";
217
				}
218

    
219
				fwrite($fd, $spdconf);
220
				fclose($fd);
221

    
222
				/* load SPD */
223
				mwexec("/usr/sbin/setkey -c < {$g['varetc_path']}/spd.conf");
224
			}
225

    
226
			/* generate racoon.conf */
227
			$fd = fopen("{$g['varetc_path']}/racoon.conf", "w");
228
			if (!$fd) {
229
				printf("Error: cannot open racoon.conf in vpn_ipsec_configure().\n");
230
				return 1;
231
			}
232

    
233
			$racoonconf = "";
234

    
235

    
236
	if($config['installedpackages']['sasyncd']['config'] <> "")
237
		foreach($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
238
			if($sasyncd['ip'] <> "") 
239
				$curwanip = $sasyncd['ip'];
240

    
241
				$interface_ip = $sasyncd['ip'];
242
				$racoonconf .= <<<EOD
243
listen {
244
	isakmp {$interface_ip} [500];
245
}
246

    
247
EOD;
248
			}
249

    
250
			$racoonconf = "path pre_shared_key \"{$g['varetc_path']}/psk.txt\";\n\n";
251
			$racoonconf .= "path certificate  \"{$g['varetc_path']}\";\n\n";
252
			
253
			/* generate CA certificates files */
254
			$cacertnum = 0;
255
			if (is_array($ipseccfg['cacert']) && count($ipseccfg['cacert']))
256
				foreach ($ipseccfg['cacert'] as $cacert) {
257
					++$cacertnum;
258
					if (isset($cacert['cert'])) {
259
						$cert = base64_decode($cacert['cert']);
260
						$x509cert = openssl_x509_parse(openssl_x509_read($cert));
261
						if(is_array($x509cert) && isset($x509cert['hash'])) {
262
							$fd1 = fopen("{$g['varetc_path']}/{$x509cert['hash']}.0", "w");
263
							if (!$fd1) {
264
								printf("Error: cannot open {$x509cert['hash']}.0 in vpn.\n");
265
								return 1;
266
							}
267
							chmod("{$g['varetc_path']}/{$x509cert['hash']}.0", 0600);
268
							fwrite($fd1, $cert);
269
							fclose($fd1);
270
						}
271
					}
272
				}
273
						
274
			$tunnelnumber = 0;
275
			if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel']))
276
				foreach ($ipseccfg['tunnel'] as $tunnel) {
277
				
278
				++$tunnelnumber;
279
			
280
				if (isset($tunnel['disabled']))
281
					continue;
282
				
283
				$ep = vpn_endpoint_determine($tunnel, $curwanip);
284
				if (!$ep)
285
					continue;
286
			
287
				vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn);
288
			
289
				if (isset($tunnel['p1']['myident']['myaddress'])) {
290
					$myidentt = "address";
291
					$myident = $ep;
292
				} else if (isset($tunnel['p1']['myident']['address'])) {
293
					$myidentt = "address";
294
					$myident = $tunnel['p1']['myident']['address'];
295
				} else if (isset($tunnel['p1']['myident']['fqdn'])) {
296
					$myidentt = "fqdn";
297
					$myident = $tunnel['p1']['myident']['fqdn'];
298
				} else if (isset($tunnel['p1']['myident']['ufqdn'])) {
299
					$myidentt = "user_fqdn";
300
					$myident = $tunnel['p1']['myident']['ufqdn'];
301
 				} else if (isset($tunnel['p1']['myident']['dyn_dns'])) {
302
					$myidentt = "dyn_dns";
303
					$myident = gethostbyname($tunnel['p1']['myident']['dyn_dns']);
304
 				}
305
				
306
				if (isset($tunnel['p1']['authentication_method'])) {
307
					$authmethod = $tunnel['p1']['authentication_method'];
308
				} else {$authmethod = 'pre_shared_key';}
309
				
310
				$certline = '';	
311
				
312
				if ($authmethod == 'rsasig') {
313
					if ($tunnel['p1']['cert'] && $tunnel['p1']['private-key']) {
314
						$cert = base64_decode($tunnel['p1']['cert']);
315
						$private_key = base64_decode($tunnel['p1']['private-key']);
316
					} else {
317
						/* null certificate/key */
318
						$cert = '';
319
						$private_key = '';
320
					}
321
					
322
					if ($tunnel['p1']['peercert']) 
323
						$peercert = base64_decode($tunnel['p1']['peercert']);
324
					else 
325
						$peercert = '';
326
					
327
					$fd1 = fopen("{$g['varetc_path']}/server{$tunnelnumber}-signed.pem", "w");
328
					if (!$fd1) {
329
						printf("Error: cannot open server{$tunnelnumber}-signed.pem in vpn.\n");
330
						return 1;
331
					}
332
					chmod("{$g['varetc_path']}/server{$tunnelnumber}-signed.pem", 0600);
333
					fwrite($fd1, $cert);
334
					fclose($fd1);
335
					
336
					$fd1 = fopen("{$g['varetc_path']}/server{$tunnelnumber}-key.pem", "w");
337
					if (!$fd1) {
338
						printf("Error: cannot open server{$tunnelnumber}-key.pem in vpn.\n");
339
						return 1;
340
					}
341
					chmod("{$g['varetc_path']}/server{$tunnelnumber}-key.pem", 0600);
342
					fwrite($fd1, $private_key);
343
					fclose($fd1);
344

    
345
					$certline = "certificate_type x509 \"server{$tunnelnumber}-signed.pem\" \"server{$tunnelnumber}-key.pem\";";
346
					
347
					if ($peercert!=''){
348
						$fd1 = fopen("{$g['varetc_path']}/peer{$tunnelnumber}-signed.pem", "w");
349
						if (!$fd1) {
350
							printf("Error: cannot open server{$tunnelnumber}-signed.pem in vpn.\n");
351
							return 1;
352
						}
353
						chmod("{$g['varetc_path']}/peer{$tunnelnumber}-signed.pem", 0600);
354
						fwrite($fd1, $peercert);
355
						fclose($fd1);		
356
						$certline .= <<<EOD
357
						
358
	peers_certfile "peer{$tunnelnumber}-signed.pem";
359
EOD;
360
					} 					
361
				} 
362
				$racoonconf .= <<<EOD
363
remote {$tunnel['remote-gateway']} \{
364
	exchange_mode {$tunnel['p1']['mode']};
365
	my_identifier {$myidentt} "{$myident}";
366
	{$certline}
367
	peers_identifier address {$tunnel['remote-gateway']};
368
	initial_contact on;
369
	support_proxy on;
370
	proposal_check obey;
371

    
372
	proposal \{
373
		encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
374
		hash_algorithm {$tunnel['p1']['hash-algorithm']};
375
		authentication_method {$authmethod};
376
		dh_group {$tunnel['p1']['dhgroup']};
377

    
378
EOD;
379
				if ($tunnel['p1']['lifetime'])
380
					$racoonconf .= "		lifetime time {$tunnel['p1']['lifetime']} secs;\n";
381
				
382
				$racoonconf .= "	}\n";
383
				
384
				if ($tunnel['p1']['lifetime'])
385
					$racoonconf .= "	lifetime time {$tunnel['p1']['lifetime']} secs;\n";
386
					
387
				$racoonconf .= "}\n\n";
388
				
389
				$p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']);
390
				$p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']);
391
				
392
				$racoonconf .= <<<EOD
393
sainfo address {$sa}/{$sn} any address {$tunnel['remote-subnet']} any \{
394
	encryption_algorithm {$p2ealgos};
395
	authentication_algorithm {$p2halgos};
396
	compression_algorithm deflate;
397

    
398
EOD;
399

    
400
				if ($tunnel['p2']['pfsgroup'])
401
					$racoonconf .= "	pfs_group {$tunnel['p2']['pfsgroup']};\n";
402
					
403
				if ($tunnel['p2']['lifetime'])
404
					$racoonconf .= "	lifetime time {$tunnel['p2']['lifetime']} secs;\n";
405
					
406
				$racoonconf .= "}\n\n";
407
			}
408
			
409
			/* mobile clients? */
410
			if (isset($ipseccfg['mobileclients']['enable'])) {
411
				
412
				$tunnel = $ipseccfg['mobileclients'];
413
				
414
				if (isset($tunnel['p1']['myident']['myaddress'])) {
415
					$myidentt = "address";
416
					$myident = $curwanip;
417
				} else if (isset($tunnel['p1']['myident']['address'])) {
418
					$myidentt = "address";
419
					$myident = $tunnel['p1']['myident']['address'];
420
				} else if (isset($tunnel['p1']['myident']['fqdn'])) {
421
					$myidentt = "fqdn";
422
					$myident = $tunnel['p1']['myident']['fqdn'];
423
				} else if (isset($tunnel['p1']['myident']['ufqdn'])) {
424
					$myidentt = "user_fqdn";
425
					$myident = $tunnel['p1']['myident']['ufqdn'];
426
 				}
427
				
428
				if (isset($tunnel['p1']['authentication_method'])) {
429
					$authmethod = $tunnel['p1']['authentication_method'];
430
				} else {$authmethod = 'pre_shared_key';}
431
				
432
				$certline = '';					
433
				if ($authmethod == 'rsasig') {
434
					if ($tunnel['p1']['cert'] && $tunnel['p1']['private-key']) {
435
						$cert = base64_decode($tunnel['p1']['cert']);
436
						$private_key = base64_decode($tunnel['p1']['private-key']);
437
					} else {
438
						/* null certificate/key */
439
						$cert = '';
440
						$private_key = '';
441
					}
442
					
443
					if ($tunnel['p1']['peercert']) 
444
						$peercert = base64_decode($tunnel['p1']['peercert']);
445
					else 
446
						$peercert = '';
447
					
448
					$fd1 = fopen("{$g['varetc_path']}/server-mobile{$tunnelnumber}-signed.pem", "w");
449
					if (!$fd1) {
450
						printf("Error: cannot open server-mobile{$tunnelnumber}-signed.pem in vpn.\n");
451
						return 1;
452
					}
453
					chmod("{$g['varetc_path']}/server-mobile{$tunnelnumber}-signed.pem", 0600);
454
					fwrite($fd1, $cert);
455
					fclose($fd1);
456
					
457
					$fd1 = fopen("{$g['varetc_path']}/server-mobile{$tunnelnumber}-key.pem", "w");
458
					if (!$fd1) {
459
						printf("Error: cannot open server-mobile{$tunnelnumber}-key.pem in vpn.\n");
460
						return 1;
461
					}
462
					chmod("{$g['varetc_path']}/server-mobile{$tunnelnumber}-key.pem", 0600);
463
					fwrite($fd1, $private_key);
464
					fclose($fd1);
465

    
466
					$certline = "certificate_type x509 \"server-mobile{$tunnelnumber}-signed.pem\" \"server-mobile{$tunnelnumber}-key.pem\";";
467
				}
468
				$racoonconf .= <<<EOD
469
remote anonymous \{
470
	exchange_mode {$tunnel['p1']['mode']};
471
	my_identifier {$myidentt} "{$myident}";
472
	{$certline}
473
	initial_contact on;
474
	passive on;
475
	generate_policy on;
476
	support_proxy on;
477
	proposal_check obey;
478

    
479
	proposal \{
480
		encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
481
		hash_algorithm {$tunnel['p1']['hash-algorithm']};
482
		authentication_method {$authmethod};
483
		dh_group {$tunnel['p1']['dhgroup']};
484

    
485
EOD;
486
				if ($tunnel['p1']['lifetime'])
487
					$racoonconf .= "		lifetime time {$tunnel['p1']['lifetime']} secs;\n";
488
				
489
				$racoonconf .= "	}\n";
490
				
491
				if ($tunnel['p1']['lifetime'])
492
					$racoonconf .= "	lifetime time {$tunnel['p1']['lifetime']} secs;\n";
493
					
494
				$racoonconf .= "}\n\n";
495
				
496
				$p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']);
497
				$p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']);
498
				
499
				$racoonconf .= <<<EOD
500
sainfo anonymous \{
501
	encryption_algorithm {$p2ealgos};
502
	authentication_algorithm {$p2halgos};
503
	compression_algorithm deflate;
504

    
505
EOD;
506

    
507
				if ($tunnel['p2']['pfsgroup'])
508
					$racoonconf .= "	pfs_group {$tunnel['p2']['pfsgroup']};\n";
509
					
510
				if ($tunnel['p2']['lifetime'])
511
					$racoonconf .= "	lifetime time {$tunnel['p2']['lifetime']} secs;\n";
512
					
513
				$racoonconf .= "}\n\n";
514
			}
515
			
516
			fwrite($fd, $racoonconf);
517
			fclose($fd);
518
			
519
			/* generate psk.txt */
520
			$fd = fopen("{$g['varetc_path']}/psk.txt", "w");
521
			if (!$fd) {
522
				printf("Error: cannot open psk.txt in vpn_ipsec_configure().\n");
523
				return 1;
524
			}
525
			
526
			$pskconf = "";
527
			
528
			if (is_array($ipseccfg['tunnel'])) {
529
				foreach ($ipseccfg['tunnel'] as $tunnel) {
530
					if (isset($tunnel['disabled']))
531
						continue;
532
					$pskconf .= "{$tunnel['remote-gateway']}	 {$tunnel['p1']['pre-shared-key']}\n";
533
				}
534
			}
535
			
536
			/* add PSKs for mobile clients */
537
			if (is_array($ipseccfg['mobilekey'])) {
538
				foreach ($ipseccfg['mobilekey'] as $key) {
539
					$pskconf .= "{$key['ident']}	{$key['pre-shared-key']}\n";
540
				}
541
			}
542
			
543
			fwrite($fd, $pskconf);
544
			fclose($fd);
545
			chmod("{$g['varetc_path']}/psk.txt", 0600);
546
			
547
			/* start racoon */
548
			mwexec("/usr/local/sbin/racoon -d -f {$g['varetc_path']}/racoon.conf");
549
			
550
			if (is_array($ipseccfg['tunnel'])) {
551
				foreach ($ipseccfg['tunnel'] as $tunnel) {
552
					if (isset($tunnel['auto'])) {
553
						$remotehost = substr($tunnel['remote-subnet'],0,strpos($tunnel['remote-subnet'],"/"));
554
						$srchost = vpn_endpoint_determine($tunnel, $curwanip);
555
						if ($srchost)
556
							mwexec_bg("/sbin/ping -c 10 -S {$srchost} {$remotehost}");
557
					}
558
				}
559
			}
560
		}
561
	}
562

    
563
	vpn_ipsec_failover_configure();
564

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

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

    
573
	return 0;
574
}
575

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

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

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

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

    
591
		/* wait for process to die */
592
		sleep(2);
593

    
594
		/* remove mpd.conf, if it exists */
595
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.conf");
596
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.links");
597
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.secret");
598
	}
599

    
600
	/* make sure mpd-vpn directory exists */
601
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
602
		mkdir("{$g['varetc_path']}/mpd-vpn");
603

    
604
	switch ($pptpdcfg['mode']) {
605

    
606
		case 'server':
607

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

    
615
			$mpdconf = <<<EOD
616
pptpd:
617

    
618
EOD;
619

    
620
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
621
				$mpdconf .= "	load pt{$i}\n";
622
			}
623

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

    
626
				$clientip = long2ip(ip2long($pptpdcfg['remoteip']) + $i);
627
				$ngif = "ng" . ($i+1);
628

    
629
				$mpdconf .= <<<EOD
630

    
631
pt{$i}:
632
	new -i {$ngif} pt{$i} pt{$i}
633
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
634
	load pts
635

    
636
EOD;
637
			}
638

    
639
			$mpdconf .= <<<EOD
640

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

    
661
EOD;
662

    
663
			if (!isset($pptpdcfg['req128'])) {
664
				$mpdconf .= <<<EOD
665
	set ccp yes mpp-e40
666
	set ccp yes mpp-e56
667

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

    
681
			if (isset($pptpdcfg['radius']['enable'])) {
682
				$mpdconf .= <<<EOD
683
	set radius server {$pptpdcfg['radius']['server']} "{$pptpdcfg['radius']['secret']}"
684
	set radius retries 3
685
	set radius timeout 10
686
	set bundle enable radius-auth
687
	set bundle disable radius-fallback
688

    
689
EOD;
690

    
691
				if (isset($pptpdcfg['radius']['accounting'])) {
692
					$mpdconf .= <<<EOD
693
	set bundle enable radius-acct
694

    
695
EOD;
696
				}
697
			}
698

    
699
			fwrite($fd, $mpdconf);
700
			fclose($fd);
701

    
702
			/* write mpd.links */
703
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.links", "w");
704
			if (!$fd) {
705
				printf("Error: cannot open mpd.links in vpn_pptpd_configure().\n");
706
				return 1;
707
			}
708

    
709
			$mpdlinks = "";
710

    
711
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
712
				$mpdlinks .= <<<EOD
713

    
714
pt{$i}:
715
	set link type pptp
716
	set pptp enable incoming
717
	set pptp disable originate
718
	set pptp disable windowing
719
	set pptp self 127.0.0.1
720

    
721
EOD;
722
			}
723

    
724
			fwrite($fd, $mpdlinks);
725
			fclose($fd);
726

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

    
734
			$mpdsecret = "";
735

    
736
			if (is_array($pptpdcfg['user'])) {
737
				foreach ($pptpdcfg['user'] as $user)
738
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
739
			}
740

    
741
			fwrite($fd, $mpdsecret);
742
			fclose($fd);
743
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
744

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

    
748
			break;
749

    
750
		case 'redir':
751
			break;
752
	}
753

    
754
	touch("{$g["tmp_path"]}/filter_dirty");
755

    
756
	if ($g['booting'])
757
		echo "done\n";
758

    
759
	return 0;
760
}
761

    
762
function vpn_localnet_determine($adr, &$sa, &$sn) {
763
	global $config, $g;
764

    
765
	if (isset($adr)) {
766
		if ($adr['network']) {
767
			switch ($adr['network']) {
768
				case 'lan':
769
					$sn = $config['interfaces']['lan']['subnet'];
770
					$sa = gen_subnet($config['interfaces']['lan']['ipaddr'], $sn);
771
					break;
772
			}
773
		} else if ($adr['address']) {
774
			list($sa,$sn) = explode("/", $adr['address']);
775
			if (is_null($sn))
776
				$sn = 32;
777
		}
778
	} else {
779
		$sn = $config['interfaces']['lan']['subnet'];
780
		$sa = gen_subnet($config['interfaces']['lan']['ipaddr'], $sn);
781
	}
782
}
783

    
784
function vpn_endpoint_determine($tunnel, $curwanip) {
785

    
786
	global $g, $config;
787

    
788
	if ((!$tunnel['interface']) || ($tunnel['interface'] == "wan")) {
789
		if ($curwanip)
790
			return $curwanip;
791
		else
792
			return null;
793
	} else if ($tunnel['interface'] == "lan") {
794
		return $config['interfaces']['lan']['ipaddr'];
795
	} else {
796
		$oc = $config['interfaces'][$tunnel['interface']];
797

    
798
		if (isset($oc['enable']) && $oc['if']) {
799
			return $oc['ipaddr'];
800
		}
801
	}
802

    
803
	return null;
804
}
805

    
806
function vpn_pppoe_configure() {
807
	global $config, $g;
808

    
809
	$syscfg = $config['system'];
810
	$pppoecfg = $config['pppoe'];
811

    
812
	/* create directory if it does not exist */
813
	if(!is_dir("{$g['varetc_path']}/mpd-vpn"))
814
		mkdir("{$g['varetc_path']}/mpd-vpn");
815
	
816
	if ($g['booting']) {
817
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
818
			return 0;
819

    
820
		echo "Configuring PPPoE VPN service... ";
821
	} else {
822
		/* kill mpd */
823
		killbypid("{$g['varrun_path']}/mpd-vpn.pid");
824

    
825
		/* wait for process to die */
826
		sleep(2);
827
		
828
		vpn_pptpd_configure();
829
	}
830

    
831
	/* make sure mpd-vpn directory exists */
832
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
833
		mkdir("{$g['varetc_path']}/mpd-vpn");
834

    
835
	switch ($pppoecfg['mode']) {
836

    
837
		case 'server':
838

    
839
			$pppoe_interface = filter_translate_type_to_real_interface($pppoecfg['interface']);
840

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

    
851
EOD;
852

    
853
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
854
				$mpdconf .= "	load pppoe{$i}\n";
855
			}
856

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

    
859
				$clientip = long2ip(ip2long($pppoecfg['remoteip']) + $i);
860
				$ngif = "ng" . ($i+1);
861

    
862
				$mpdconf .= <<<EOD
863

    
864
pppoe{$i}:
865
	new -i {$ngif} pppoe{$i} pppoe{$i}
866
	set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32
867
	load pppoe_standart
868

    
869
EOD;
870
			}
871

    
872
			$mpdconf .= <<<EOD
873

    
874
pppoe_standart:
875
	set link type pppoe
876
	set pppoe iface {$pppoe_interface}
877
	set pppoe service "*"
878
	set pppoe disable originate
879
	set pppoe enable incoming
880
	set bundle no multilink
881
	set bundle enable compression
882
	set bundle max-logins 1
883
	set iface idle 0
884
	set iface disable on-demand
885
	set iface disable proxy-arp
886
	set iface enable tcpmssfix
887
	set iface mtu 1500
888
	set link mtu 1500
889
	set link no pap chap
890
	set link enable chap
891
	set link keep-alive 60 180
892
	set ipcp yes vjcomp
893
	set ipcp no vjcomp
894
	set link max-redial -1
895
	set link mtu 1492
896
	set ccp yes mpp-e40
897
	set ccp yes mpp-e128
898
	set ccp yes mpp-stateless
899
	set link latency 1
900
	#set ipcp dns 10.10.1.3
901
	#set bundle accept encryption	
902

    
903
EOD;
904

    
905
			if (isset($config['dnsmasq']['enable'])) {
906
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
907
				if ($syscfg['dnsserver'][0])
908
					$mpdconf .= " " . $syscfg['dnsserver'][0];
909
				$mpdconf .= "\n";
910
			} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
911
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
912
			}
913

    
914
			if (isset($pppoecfg['radius']['enable'])) {
915
				$mpdconf .= <<<EOD
916
	set radius server {$pppoecfg['radius']['server']} "{$pppoecfg['radius']['secret']}"
917
	set radius retries 3
918
	set radius timeout 10
919
	set bundle enable radius-auth
920
	set bundle disable radius-fallback
921

    
922
EOD;
923

    
924
				if (isset($pppoecfg['radius']['accounting'])) {
925
					$mpdconf .= <<<EOD
926
	set bundle enable radius-acct
927

    
928
EOD;
929
				}
930
			}
931

    
932
			fwrite($fd, $mpdconf);
933
			fclose($fd);
934

    
935
			/* write mpd.links */
936
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.links", "a");
937
			if (!$fd) {
938
				printf("Error: cannot open mpd.links in vpn_pppoe_configure().\n");
939
				return 1;
940
			}
941

    
942
			$mpdlinks = "";
943

    
944
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
945
				$mpdlinks .= <<<EOD
946

    
947
pppoe:
948
	set link type pppoe
949
	set pppoe iface {$pppoe_interface}
950

    
951
EOD;
952
			}
953

    
954
			fwrite($fd, $mpdlinks);
955
			fclose($fd);
956

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

    
964
			$mpdsecret = "\n\n";
965

    
966
			if (is_array($pppoecfg['user'])) {
967
				foreach ($pppoecfg['user'] as $user)
968
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
969
			}
970

    
971
			fwrite($fd, $mpdsecret);
972
			fclose($fd);
973
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
974

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

    
978
			break;
979

    
980
		case 'redir':
981
			break;
982
	}
983

    
984
	touch("{$g["tmp_path"]}/filter_dirty");
985

    
986
	if ($g['booting'])
987
		echo "done\n";
988

    
989
	return 0;
990
}
991

    
992
?>
(18-18/23)