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
        $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("/usr/sbin/setkey -F");
98
			//mwexec("/usr/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("/usr/sbin/setkey -FP");
146
	mwexec("/usr/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("/usr/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 -d -f {$g['varetc_path']}/racoon.conf");
555
			
556
			if (is_array($ipseccfg['tunnel'])) {
557
				foreach ($ipseccfg['tunnel'] as $tunnel) {
558
					if (isset($tunnel['auto'])) {
559
						$remotehost = substr($tunnel['remote-subnet'],0,strpos($tunnel['remote-subnet'],"/"));
560
						$srchost = vpn_endpoint_determine($tunnel, $curwanip);
561
						if ($srchost)
562
							mwexec_bg("/sbin/ping -c 10 -S {$srchost} {$remotehost}");
563
					}
564
				}
565
			}
566
		}
567
	}
568

    
569
	vpn_ipsec_failover_configure();
570

    
571
	if (!$g['booting']) {
572
		/* reload the filter */
573
		touch("{$g["tmp_path"]}/filter_dirty");
574
	}
575

    
576
	if ($g['booting'])
577
		echo "done\n";
578

    
579
	return 0;
580
}
581

    
582
function vpn_pptpd_configure() {
583
	global $config, $g;
584

    
585
	$syscfg = $config['system'];
586
	$pptpdcfg = $config['pptpd'];
587

    
588
	if ($g['booting']) {
589
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
590
			return 0;
591

    
592
		echo "Configuring PPTP VPN service... ";
593
	} else {
594
		/* kill mpd */
595
		killbypid("{$g['varrun_path']}/mpd-vpn.pid");
596

    
597
		/* wait for process to die */
598
		sleep(2);
599

    
600
		/* remove mpd.conf, if it exists */
601
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.conf");
602
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.links");
603
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.secret");
604
	}
605

    
606
	/* make sure mpd-vpn directory exists */
607
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
608
		mkdir("{$g['varetc_path']}/mpd-vpn");
609

    
610
	switch ($pptpdcfg['mode']) {
611

    
612
		case 'server':
613

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

    
621
			$mpdconf = <<<EOD
622
pptpd:
623

    
624
EOD;
625

    
626
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
627
				$mpdconf .= "	load pt{$i}\n";
628
			}
629

    
630
			if ($config['interfaces']['wan']['ipaddr'] == "pppoe") {
631
				$pptp_mtu = "1440";
632
			} else {
633
				$pptp_mtu = "1460";
634
			}
635

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

    
638
				$clientip = long2ip(ip2long($pptpdcfg['remoteip']) + $i);
639
				$ngif = "ng" . ($i+1);
640

    
641
				$mpdconf .= <<<EOD
642

    
643
pt{$i}:
644
	new -i {$ngif} pt{$i} pt{$i}
645
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
646
	load pts
647

    
648
EOD;
649
			}
650

    
651
			$mpdconf .= <<<EOD
652

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

    
673
EOD;
674

    
675
			if (!isset($pptpdcfg['req128'])) {
676
				$mpdconf .= <<<EOD
677
	set ccp yes mpp-e40
678
	set ccp yes mpp-e56
679

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

    
693
			if (isset($pptpdcfg['radius']['enable'])) {
694
				$mpdconf .= <<<EOD
695
	set radius server {$pptpdcfg['radius']['server']} "{$pptpdcfg['radius']['secret']}"
696
	set radius retries 3
697
	set radius timeout 10
698
	set bundle enable radius-auth
699
	set bundle disable radius-fallback
700

    
701
EOD;
702

    
703
				if (isset($pptpdcfg['radius']['accounting'])) {
704
					$mpdconf .= <<<EOD
705
	set bundle enable radius-acct
706

    
707
EOD;
708
				}
709
			}
710

    
711
			fwrite($fd, $mpdconf);
712
			fclose($fd);
713

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

    
721
			$mpdlinks = "";
722

    
723
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
724
				$mpdlinks .= <<<EOD
725

    
726
pt{$i}:
727
	set link type pptp
728
	set pptp enable incoming
729
	set pptp disable originate
730
	set pptp disable windowing
731
	set pptp self 127.0.0.1
732

    
733
EOD;
734
			}
735

    
736
			fwrite($fd, $mpdlinks);
737
			fclose($fd);
738

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

    
746
			$mpdsecret = "";
747

    
748
			if (is_array($pptpdcfg['user'])) {
749
				foreach ($pptpdcfg['user'] as $user)
750
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
751
			}
752

    
753
			fwrite($fd, $mpdsecret);
754
			fclose($fd);
755
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
756

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

    
760
			break;
761

    
762
		case 'redir':
763
			break;
764
	}
765

    
766
	touch("{$g["tmp_path"]}/filter_dirty");
767

    
768
	if ($g['booting'])
769
		echo "done\n";
770

    
771
	return 0;
772
}
773

    
774
function vpn_localnet_determine($adr, &$sa, &$sn) {
775
	global $config, $g;
776

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

    
796
function vpn_endpoint_determine($tunnel, $curwanip) {
797

    
798
	global $g, $config;
799

    
800
	if ((!$tunnel['interface']) || ($tunnel['interface'] == "wan")) {
801
		if ($curwanip)
802
			return $curwanip;
803
		else
804
			return null;
805
	} else if ($tunnel['interface'] == "lan") {
806
		return $config['interfaces']['lan']['ipaddr'];
807
	} else {
808
		$oc = $config['interfaces'][$tunnel['interface']];
809

    
810
		if (isset($oc['enable']) && $oc['if']) {
811
			return $oc['ipaddr'];
812
		}
813
	}
814

    
815
	return null;
816
}
817

    
818
function vpn_pppoe_configure() {
819
	global $config, $g;
820

    
821
	$syscfg = $config['system'];
822
	$pppoecfg = $config['pppoe'];
823

    
824
	/* create directory if it does not exist */
825
	if(!is_dir("{$g['varetc_path']}/mpd-vpn"))
826
		mkdir("{$g['varetc_path']}/mpd-vpn");
827
	
828
	if ($g['booting']) {
829
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
830
			return 0;
831

    
832
		echo "Configuring PPPoE VPN service... ";
833
	} else {
834
		/* kill mpd */
835
		killbypid("{$g['varrun_path']}/mpd-vpn.pid");
836

    
837
		/* wait for process to die */
838
		sleep(2);
839
		
840
		vpn_pptpd_configure();
841
	}
842

    
843
	/* make sure mpd-vpn directory exists */
844
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
845
		mkdir("{$g['varetc_path']}/mpd-vpn");
846

    
847
	switch ($pppoecfg['mode']) {
848

    
849
		case 'server':
850

    
851
			$pppoe_interface = filter_translate_type_to_real_interface($pppoecfg['interface']);
852

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

    
863
EOD;
864

    
865
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
866
				$mpdconf .= "	load pppoe{$i}\n";
867
			}
868

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

    
871
				$clientip = long2ip(ip2long($pppoecfg['remoteip']) + $i);
872
				$ngif = "ng" . ($i+1);
873

    
874
				$mpdconf .= <<<EOD
875

    
876
pppoe{$i}:
877
	new -i {$ngif} pppoe{$i} pppoe{$i}
878
	set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32
879
	load pppoe_standart
880

    
881
EOD;
882
			}
883

    
884
			$mpdconf .= <<<EOD
885

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

    
915
EOD;
916

    
917
			if (isset($config['dnsmasq']['enable'])) {
918
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
919
				if ($syscfg['dnsserver'][0])
920
					$mpdconf .= " " . $syscfg['dnsserver'][0];
921
				$mpdconf .= "\n";
922
			} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
923
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
924
			}
925

    
926
			if (isset($pppoecfg['radius']['enable'])) {
927
				$mpdconf .= <<<EOD
928
	set radius server {$pppoecfg['radius']['server']} "{$pppoecfg['radius']['secret']}"
929
	set radius retries 3
930
	set radius timeout 10
931
	set bundle enable radius-auth
932
	set bundle disable radius-fallback
933

    
934
EOD;
935

    
936
				if (isset($pppoecfg['radius']['accounting'])) {
937
					$mpdconf .= <<<EOD
938
	set bundle enable radius-acct
939

    
940
EOD;
941
				}
942
			}
943

    
944
			fwrite($fd, $mpdconf);
945
			fclose($fd);
946

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

    
954
			$mpdlinks = "";
955

    
956
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
957
				$mpdlinks .= <<<EOD
958

    
959
pppoe:
960
	set link type pppoe
961
	set pppoe iface {$pppoe_interface}
962

    
963
EOD;
964
			}
965

    
966
			fwrite($fd, $mpdlinks);
967
			fclose($fd);
968

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

    
976
			$mpdsecret = "\n\n";
977

    
978
			if (is_array($pppoecfg['user'])) {
979
				foreach ($pppoecfg['user'] as $user)
980
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
981
			}
982

    
983
			fwrite($fd, $mpdsecret);
984
			fclose($fd);
985
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
986

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

    
990
			break;
991

    
992
		case 'redir':
993
			break;
994
	}
995

    
996
	touch("{$g["tmp_path"]}/filter_dirty");
997

    
998
	if ($g['booting'])
999
		echo "done\n";
1000

    
1001
	return 0;
1002
}
1003

    
1004
?>
(20-20/25)