Project

General

Profile

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

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

    
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("/sbin/setkey -F");
99
			//mwexec("/sbin/setkey -FP");
100
			//echo " done.\n";
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
		mwexec("/usr/bin/killall racoon");
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("/sbin/setkey -FP");
147
	mwexec("/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("/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
				/* natt - turn on if <developer/> exists */
241
				if(isset($config['system']['developer']) <> "") {
242
					$lanip = $config['interfaces']['lan']['ipaddr'];
243
					if($lanip <> "") 
244
						$natt = "isakmp_natt {$lanip}[4500];\n";
245
					
246
				}	
247
				$interface_ip = $sasyncd['ip'];
248
				$racoonconf .= <<<EOD
249
listen {
250
	isakmp {$interface_ip} [500];
251
	{$natt}
252
}
253

    
254
EOD;
255
			}
256

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

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

    
379
	proposal \{
380
		encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
381
		hash_algorithm {$tunnel['p1']['hash-algorithm']};
382
		authentication_method {$authmethod};
383
		dh_group {$tunnel['p1']['dhgroup']};
384

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

    
405
EOD;
406

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

    
473
					$certline = "certificate_type x509 \"server-mobile{$tunnelnumber}-signed.pem\" \"server-mobile{$tunnelnumber}-key.pem\";";
474
				}
475
				$racoonconf .= <<<EOD
476
remote anonymous \{
477
	exchange_mode {$tunnel['p1']['mode']};
478
	my_identifier {$myidentt} "{$myident}";
479
	{$certline}
480
	initial_contact on;
481
	passive on;
482
	generate_policy on;
483
	support_proxy on;
484
	proposal_check obey;
485

    
486
	proposal \{
487
		encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
488
		hash_algorithm {$tunnel['p1']['hash-algorithm']};
489
		authentication_method {$authmethod};
490
		dh_group {$tunnel['p1']['dhgroup']};
491

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

    
512
EOD;
513

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

    
559
	vpn_ipsec_failover_configure();
560

    
561
	if (!$g['booting']) {
562
		/* reload the filter */
563
		touch("{$g["tmp_path"]}/filter_dirty");
564
	}
565

    
566
	if ($g['booting'])
567
		echo "done\n";
568

    
569
	return 0;
570
}
571

    
572
function vpn_pptpd_configure() {
573
	global $config, $g;
574
	
575
	$syscfg = $config['system'];
576
	$pptpdcfg = $config['pptpd'];
577
	
578
	if ($g['booting']) {
579
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
580
			return 0;
581
		
582
		echo "Configuring PPTP VPN service... ";
583
	} else {	
584
		/* kill mpd */
585
		killbypid("{$g['varrun_path']}/mpd-vpn.pid");
586
		
587
		/* wait for process to die */
588
		sleep(2);
589
		
590
		/* remove mpd.conf, if it exists */
591
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.conf");
592
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.links");
593
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.secret");
594
	}
595
		
596
	/* make sure mpd-vpn directory exists */
597
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
598
		mkdir("{$g['varetc_path']}/mpd-vpn");
599
		
600
	switch ($pptpdcfg['mode']) {
601
		
602
		case 'server':
603
			
604
			/* write mpd.conf */
605
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.conf", "w");
606
			if (!$fd) {
607
				printf("Error: cannot open mpd.conf in vpn_pptpd_configure().\n");
608
				return 1;
609
			}
610
				
611
			$mpdconf = <<<EOD
612
pptpd:
613

    
614
EOD;
615

    
616
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
617
				$mpdconf .= "	load pt{$i}\n";
618
			}
619
			
620
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
621
			
622
				$clientip = long2ip(ip2long($pptpdcfg['remoteip']) + $i);
623
				$ngif = "ng" . ($i+1);
624
			
625
				$mpdconf .= <<<EOD
626

    
627
pt{$i}:
628
	new -i {$ngif} pt{$i} pt{$i}
629
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
630
	load pts
631

    
632
EOD;
633
			}
634
			
635
			$mpdconf .= <<<EOD
636

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

    
657
EOD;
658
			
659
			if (!isset($pptpdcfg['req128'])) {
660
				$mpdconf .= <<<EOD
661
	set ccp yes mpp-e40
662
	set ccp yes mpp-e56
663

    
664
EOD;
665
			}
666
			
667
			if (is_array($pptpdcfg['dnsserver']) && ($pptpdcfg['dnsserver'][0])) {
668
				$mpdconf .= "	set ipcp dns " . join(" ", $pptpdcfg['dnsserver']) . "\n";
669
			} else if (isset($config['dnsmasq']['enable'])) {
670
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
671
				if ($syscfg['dnsserver'][0])
672
					$mpdconf .= " " . $syscfg['dnsserver'][0];
673
				$mpdconf .= "\n";
674
			} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
675
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
676
			}
677
			
678
			if (isset($pptpdcfg['radius']['enable'])) {
679
				$mpdconf .= <<<EOD
680
	set radius server {$pptpdcfg['radius']['server']} "{$pptpdcfg['radius']['secret']}"
681
	set radius retries 3
682
	set radius timeout 10
683
	set bundle enable radius-auth
684
	set bundle disable radius-fallback
685

    
686
EOD;
687

    
688
				if (isset($pptpdcfg['radius']['accounting'])) {
689
					$mpdconf .= <<<EOD
690
	set bundle enable radius-acct
691

    
692
EOD;
693
				}
694
			}
695

    
696
			fwrite($fd, $mpdconf);
697
			fclose($fd);
698
			
699
			/* write mpd.links */
700
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.links", "w");
701
			if (!$fd) {
702
				printf("Error: cannot open mpd.links in vpn_pptpd_configure().\n");
703
				return 1;
704
			}
705
			
706
			$mpdlinks = "";
707
			
708
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
709
				$mpdlinks .= <<<EOD
710

    
711
pt{$i}:
712
	set link type pptp
713
	set pptp enable incoming
714
	set pptp disable originate
715
	set pptp disable windowing
716
	set pptp self 127.0.0.1
717

    
718
EOD;
719
			}
720

    
721
			fwrite($fd, $mpdlinks);
722
			fclose($fd);
723
			
724
			/* write mpd.secret */
725
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.secret", "w");
726
			if (!$fd) {
727
				printf("Error: cannot open mpd.secret in vpn_pptpd_configure().\n");
728
				return 1;
729
			}
730
			
731
			$mpdsecret = "";
732
			
733
			if (is_array($pptpdcfg['user'])) {
734
				foreach ($pptpdcfg['user'] as $user)
735
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
736
			}
737

    
738
			fwrite($fd, $mpdsecret);
739
			fclose($fd);
740
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
741
			
742
			/* fire up mpd */
743
			mwexec("/usr/local/sbin/mpd -b -d {$g['varetc_path']}/mpd-vpn -p {$g['varrun_path']}/mpd-vpn.pid pptpd");
744
			
745
			break;
746
			
747
		case 'redir':
748
			break;
749
	}
750
	
751
	if (!$g['booting']) {
752
		/* reload the filter */
753
		filter_configure();
754
	}
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
				if(isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['enable'])) {
863
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
864
					$isssue_ip_type .="\n\tset ipcp yes radius-ip";					
865
				} else {
866
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
867
				}
868
				
869
				$mpdconf .= <<<EOD
870

    
871
pppoe{$i}:
872
	new -i {$ngif} pppoe{$i} pppoe{$i}
873
	{$isssue_ip_type}
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 no pap chap
896
	set link enable chap
897
	set link keep-alive 60 180
898
	set ipcp yes vjcomp
899
	set ipcp no vjcomp
900
	set link max-redial -1
901
	set link mtu 1492
902
	set link mru 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
?>
(22-22/27)