Project

General

Profile

Download (26.8 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 CPU`;
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");
99
				mwexec("/usr/sbin/setkey -FP");
100
				echo " done.\n";
101
			}
102
		}
103
	}
104

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
174
				$spdconf = "";
175

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

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

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

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

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

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

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

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

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

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

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

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

    
234
			$racoonconf = "";
235

    
236

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

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

    
248
EOD;
249
			}
250

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

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

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

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

    
399
EOD;
400

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

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

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

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

    
506
EOD;
507

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

    
564
	vpn_ipsec_failover_configure();
565

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

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

    
574
	return 0;
575
}
576

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

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

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

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

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

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

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

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

    
607
		case 'server':
608

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

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

    
619
EOD;
620

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

    
625
			if ($config['interfaces']['wan']['ipaddr'] == "pppoe") {
626
				$pptp_mtu = "1440";
627
			} else {
628
				$pptp_mtu = "1460";
629
			}
630

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

    
633
				$clientip = long2ip(ip2long($pptpdcfg['remoteip']) + $i);
634
				$ngif = "ng" . ($i+1);
635

    
636
				$mpdconf .= <<<EOD
637

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

    
643
EOD;
644
			}
645

    
646
			$mpdconf .= <<<EOD
647

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

    
668
EOD;
669

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

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

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

    
696
EOD;
697

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

    
702
EOD;
703
				}
704
			}
705

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

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

    
716
			$mpdlinks = "";
717

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

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

    
728
EOD;
729
			}
730

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

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

    
741
			$mpdsecret = "";
742

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

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

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

    
755
			break;
756

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

    
761
	touch("{$g["tmp_path"]}/filter_dirty");
762

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

    
766
	return 0;
767
}
768

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

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

    
791
function vpn_endpoint_determine($tunnel, $curwanip) {
792

    
793
	global $g, $config;
794

    
795
	if ((!$tunnel['interface']) || ($tunnel['interface'] == "wan")) {
796
		if ($curwanip)
797
			return $curwanip;
798
		else
799
			return null;
800
	} else if ($tunnel['interface'] == "lan") {
801
		return $config['interfaces']['lan']['ipaddr'];
802
	} else {
803
		$oc = $config['interfaces'][$tunnel['interface']];
804

    
805
		if (isset($oc['enable']) && $oc['if']) {
806
			return $oc['ipaddr'];
807
		}
808
	}
809

    
810
	return null;
811
}
812

    
813
function vpn_pppoe_configure() {
814
	global $config, $g;
815

    
816
	$syscfg = $config['system'];
817
	$pppoecfg = $config['pppoe'];
818

    
819
	/* create directory if it does not exist */
820
	if(!is_dir("{$g['varetc_path']}/mpd-vpn"))
821
		mkdir("{$g['varetc_path']}/mpd-vpn");
822
	
823
	if ($g['booting']) {
824
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
825
			return 0;
826

    
827
		echo "Configuring PPPoE VPN service... ";
828
	} else {
829
		/* kill mpd */
830
		killbypid("{$g['varrun_path']}/mpd-vpn.pid");
831

    
832
		/* wait for process to die */
833
		sleep(2);
834
		
835
		vpn_pptpd_configure();
836
	}
837

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

    
842
	switch ($pppoecfg['mode']) {
843

    
844
		case 'server':
845

    
846
			$pppoe_interface = filter_translate_type_to_real_interface($pppoecfg['interface']);
847

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

    
858
EOD;
859

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

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

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

    
869
				$mpdconf .= <<<EOD
870

    
871
pppoe{$i}:
872
	new -i {$ngif} pppoe{$i} pppoe{$i}
873
	set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32
874
	load pppoe_standart
875

    
876
EOD;
877
			}
878

    
879
			$mpdconf .= <<<EOD
880

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

    
910
EOD;
911

    
912
			if (isset($config['dnsmasq']['enable'])) {
913
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
914
				if ($syscfg['dnsserver'][0])
915
					$mpdconf .= " " . $syscfg['dnsserver'][0];
916
				$mpdconf .= "\n";
917
			} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
918
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
919
			}
920

    
921
			if (isset($pppoecfg['radius']['enable'])) {
922
				$mpdconf .= <<<EOD
923
	set radius server {$pppoecfg['radius']['server']} "{$pppoecfg['radius']['secret']}"
924
	set radius retries 3
925
	set radius timeout 10
926
	set bundle enable radius-auth
927
	set bundle disable radius-fallback
928

    
929
EOD;
930

    
931
				if (isset($pppoecfg['radius']['accounting'])) {
932
					$mpdconf .= <<<EOD
933
	set bundle enable radius-acct
934

    
935
EOD;
936
				}
937
			}
938

    
939
			fwrite($fd, $mpdconf);
940
			fclose($fd);
941

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

    
949
			$mpdlinks = "";
950

    
951
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
952
				$mpdlinks .= <<<EOD
953

    
954
pppoe:
955
	set link type pppoe
956
	set pppoe iface {$pppoe_interface}
957

    
958
EOD;
959
			}
960

    
961
			fwrite($fd, $mpdlinks);
962
			fclose($fd);
963

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

    
971
			$mpdsecret = "\n\n";
972

    
973
			if (is_array($pppoecfg['user'])) {
974
				foreach ($pppoecfg['user'] as $user)
975
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
976
			}
977

    
978
			fwrite($fd, $mpdsecret);
979
			fclose($fd);
980
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
981

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

    
985
			break;
986

    
987
		case 'redir':
988
			break;
989
	}
990

    
991
	touch("{$g["tmp_path"]}/filter_dirty");
992

    
993
	if ($g['booting'])
994
		echo "done\n";
995

    
996
	return 0;
997
}
998

    
999
?>
(19-19/24)