Project

General

Profile

Download (26.6 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($g['booting'] == true) {
91
		/* determine if we should load the via padlock module */
92
		$dmesg_boot = `cat /var/log/dmesg.boot | grep CPU`;
93
		if(stristr($dmesg_boot, "ACE") == true) {		
94
			//echo "Enabling [VIA Padlock] ...";
95
			//mwexec("/sbin/kldload padlock");
96
			//mwexec("/sbin/sysctl net.inet.ipsec.crypto_support=1");
97
			//mwexec("/sbin/setkey -F");
98
			//mwexec("/sbin/setkey -FP");
99
			//echo " done.\n";
100
		}
101
	}
102

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

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

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

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

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

    
132
		echo "Configuring IPsec VPN... ";
133
	} else {
134
		/* kill racoon */
135
		mwexec("/usr/bin/killall racoon");
136

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

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

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

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

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

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

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

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

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

    
172
				$spdconf = "";
173

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

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

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

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

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

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

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

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

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

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

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

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

    
232
			$racoonconf = "";
233

    
234

    
235
	if($config['installedpackages']['sasyncd']['config'] <> "")
236
		foreach($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
237
			if($sasyncd['ip'] <> "") 
238
				$curwanip = $sasyncd['ip'];
239
				/* natt - turn on if <developer/> exists */
240
				if(isset($config['system']['developer']) <> "") {
241
					$lanip = $config['interfaces']['lan']['ipaddr'];
242
					if($lanip <> "") 
243
						$natt = "isakmp_natt {$lanip}[4500];\n";
244
					
245
				}	
246
				$interface_ip = $sasyncd['ip'];
247
				$racoonconf .= <<<EOD
248
listen {
249
	isakmp {$interface_ip} [500];
250
	{$natt}
251
}
252

    
253
EOD;
254
			}
255

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

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

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

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

    
404
EOD;
405

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

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

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

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

    
511
EOD;
512

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

    
558
	vpn_ipsec_failover_configure();
559

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

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

    
568
	return 0;
569
}
570

    
571
function vpn_pptpd_configure() {
572
	global $config, $g;
573

    
574
	$syscfg = $config['system'];
575
	$pptpdcfg = $config['pptpd'];
576

    
577
	if ($g['booting']) {
578
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
579
			return 0;
580

    
581
		echo "Configuring PPTP VPN service... ";
582
	} else {
583
		/* kill mpd */
584
		killbypid("{$g['varrun_path']}/mpd-vpn.pid");
585

    
586
		/* wait for process to die */
587
		sleep(2);
588

    
589
		/* remove mpd.conf, if it exists */
590
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.conf");
591
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.links");
592
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.secret");
593
	}
594

    
595
	/* make sure mpd-vpn directory exists */
596
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
597
		mkdir("{$g['varetc_path']}/mpd-vpn");
598

    
599
	switch ($pptpdcfg['mode']) {
600

    
601
		case 'server':
602

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

    
610
			$mpdconf = <<<EOD
611
pptpd:
612

    
613
EOD;
614

    
615
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
616
				$mpdconf .= "	load pt{$i}\n";
617
			}
618

    
619
			if ($config['interfaces']['wan']['ipaddr'] == "pppoe") {
620
				$pptp_mtu = "1440";
621
			} else {
622
				$pptp_mtu = "1460";
623
			}
624

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

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

    
630
				$mpdconf .= <<<EOD
631

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

    
637
EOD;
638
			}
639

    
640
			$mpdconf .= <<<EOD
641

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

    
662
EOD;
663

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

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

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

    
690
EOD;
691

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

    
696
EOD;
697
				}
698
			}
699

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

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

    
710
			$mpdlinks = "";
711

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

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

    
722
EOD;
723
			}
724

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

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

    
735
			$mpdsecret = "";
736

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

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

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

    
749
			break;
750

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

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

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

    
760
	return 0;
761
}
762

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

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

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

    
787
	global $g, $config;
788

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

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

    
804
	return null;
805
}
806

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

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

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

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

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

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

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

    
838
		case 'server':
839

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

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

    
852
EOD;
853

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

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

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

    
863
				$mpdconf .= <<<EOD
864

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

    
870
EOD;
871
			}
872

    
873
			$mpdconf .= <<<EOD
874

    
875
pppoe_standart:
876
	set link type pppoe
877
	set pppoe iface {$pppoe_interface}
878
	set pppoe service "*"
879
	set pppoe disable originate
880
	set pppoe enable incoming
881
	set bundle no multilink
882
	set bundle enable compression
883
	set bundle max-logins 1
884
	set iface idle 0
885
	set iface disable on-demand
886
	set iface disable proxy-arp
887
	set iface enable tcpmssfix
888
	set iface 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
?>
(21-21/26)