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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
174
				$spdconf = "";
175

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

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

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

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

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

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

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

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

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

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

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

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

    
234
			$racoonconf = "";
235

    
236

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

    
255
EOD;
256
			}
257

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

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

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

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

    
406
EOD;
407

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

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

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

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

    
513
EOD;
514

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

    
571
	vpn_ipsec_failover_configure();
572

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

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

    
581
	return 0;
582
}
583

    
584
function vpn_pptpd_configure() {
585
	global $config, $g;
586

    
587
	$syscfg = $config['system'];
588
	$pptpdcfg = $config['pptpd'];
589

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

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

    
599
		/* wait for process to die */
600
		sleep(2);
601

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

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

    
612
	switch ($pptpdcfg['mode']) {
613

    
614
		case 'server':
615

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

    
623
			$mpdconf = <<<EOD
624
pptpd:
625

    
626
EOD;
627

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

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

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

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

    
643
				$mpdconf .= <<<EOD
644

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

    
650
EOD;
651
			}
652

    
653
			$mpdconf .= <<<EOD
654

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

    
675
EOD;
676

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

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

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

    
703
EOD;
704

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

    
709
EOD;
710
				}
711
			}
712

    
713
			fwrite($fd, $mpdconf);
714
			fclose($fd);
715

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

    
723
			$mpdlinks = "";
724

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

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

    
735
EOD;
736
			}
737

    
738
			fwrite($fd, $mpdlinks);
739
			fclose($fd);
740

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

    
748
			$mpdsecret = "";
749

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

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

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

    
762
			break;
763

    
764
		case 'redir':
765
			break;
766
	}
767

    
768
	touch("{$g["tmp_path"]}/filter_dirty");
769

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

    
773
	return 0;
774
}
775

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

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

    
798
function vpn_endpoint_determine($tunnel, $curwanip) {
799

    
800
	global $g, $config;
801

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

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

    
817
	return null;
818
}
819

    
820
function vpn_pppoe_configure() {
821
	global $config, $g;
822

    
823
	$syscfg = $config['system'];
824
	$pppoecfg = $config['pppoe'];
825

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

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

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

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

    
849
	switch ($pppoecfg['mode']) {
850

    
851
		case 'server':
852

    
853
			$pppoe_interface = filter_translate_type_to_real_interface($pppoecfg['interface']);
854

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

    
865
EOD;
866

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

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

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

    
876
				$mpdconf .= <<<EOD
877

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

    
883
EOD;
884
			}
885

    
886
			$mpdconf .= <<<EOD
887

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

    
917
EOD;
918

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

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

    
936
EOD;
937

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

    
942
EOD;
943
				}
944
			}
945

    
946
			fwrite($fd, $mpdconf);
947
			fclose($fd);
948

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

    
956
			$mpdlinks = "";
957

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

    
961
pppoe:
962
	set link type pppoe
963
	set pppoe iface {$pppoe_interface}
964

    
965
EOD;
966
			}
967

    
968
			fwrite($fd, $mpdlinks);
969
			fclose($fd);
970

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

    
978
			$mpdsecret = "\n\n";
979

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

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

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

    
992
			break;
993

    
994
		case 'redir':
995
			break;
996
	}
997

    
998
	touch("{$g["tmp_path"]}/filter_dirty");
999

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

    
1003
	return 0;
1004
}
1005

    
1006
?>
(20-20/25)