Project

General

Profile

Download (27.5 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	vpn.inc
4
	Copyright (C) 2004-2006 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
/* master setup for vpn (mpd) */
37
function vpn_setup() {
38
	/* start pptpd */
39
	vpn_pptpd_configure();
40

    
41
	/* start pppoe server */
42
	vpn_pppoe_configure();	
43
}
44

    
45
function vpn_ipsec_failover_configure() {
46
	global $config, $g;
47

    
48
	$sasyncd_text = "";
49

    
50
	if($config['installedpackages']['sasyncd']['config'] <> "")
51
		foreach($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
52
			$enabled = isset($sasyncd['enable']);
53
			if(!$enabled)
54
				return;
55
			if($sasyncd['peerip'] <> "")
56
				$sasyncd_text .= "peer {$sasyncd['peerip']}\n";
57
			if($sasyncd['interface'])
58
				$sasyncd_text .= "carp interface {$sasyncd['interface']}\n";
59
			if($sasyncd['sharedkey'] <> "")
60
				$sasyncd_text .= "sharedkey {$sasyncd['sharedkey']}\n";
61
			if($sasyncd['mode'] <> "")
62
				$sasyncd_text .= "mode {$sasyncd['mode']}\n";
63
			if($sasyncd['listenon'] <> "")
64
				$sasyncd_text .= "listen on {$sasyncd['listenon']}\n";
65
			if($sasyncd['flushmodesync'] <> "")
66
				$sasyncd_text .= "flushmode sync {$sasyncd['flushmodesync']}\n";
67
		}
68

    
69
	$fd = fopen("{$g['varetc_path']}/sasyncd.conf", "w");
70
	fwrite($fd, $sasyncd_text);
71
	fclose($fd);
72
	chmod("{$g['varetc_path']}/sasyncd.conf", 0600);
73
	
74
	mwexec("killall sasyncd");
75
	
76
	/* launch sasyncd, oh wise one */
77
	mwexec_bg("/usr/local/sbin/sasyncd -d -v -v -v");
78
}
79

    
80
function find_last_gif_device() {
81
	 	$regs = "";
82
        $last_gif_found = -1;
83
        if (!($fp = popen("/sbin/ifconfig -l", "r"))) return -1;
84
        $ifconfig_data = fread($fp, 4096);
85
        pclose($fp);
86
        $ifconfig_array = split(" ", $ifconfig_data);
87
        foreach ($ifconfig_array as $ifconfig) {
88
                ereg("gif(.)", $ifconfig, $regs);
89
                if($regs[0]) {
90
                        if($regs[0] > $last_gif_found)
91
                                $last_gif_found = $regs[1];
92
                }
93
        }
94
        return $last_gif_found;
95
}
96

    
97
function vpn_ipsec_configure($ipchg = false) {
98
	global $config, $g, $sa, $sn;
99

    
100
	/* get the automatic /etc/ping_hosts.sh ready */
101
	unlink_if_exists("/var/db/ipsecpinghosts");
102
	touch("/var/db/ipsecpinghosts");
103

    
104
	if($g['booting'] == true) {
105
		/* determine if we should load the via padlock module */
106
		$dmesg_boot = `cat /var/log/dmesg.boot | grep CPU`;
107
		if(stristr($dmesg_boot, "ACE") == true) {		
108
			//echo "Enabling [VIA Padlock] ...";
109
			//mwexec("/sbin/kldload padlock");
110
			//mwexec("/sbin/sysctl net.inet.ipsec.crypto_support=1");
111
			//mwexec("/sbin/setkey -F");
112
			//mwexec("/sbin/setkey -FP");
113
			//echo " done.\n";
114
		}
115
	}
116

    
117
	if(isset($config['ipsec']['preferredoldsa'])) {
118
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
119
	} else {
120
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
121
	}
122

    
123
	$number_of_gifs = find_last_gif_device();
124
	for($x=0; $x<$number_of_gifs; $x++) {
125
		mwexec("/sbin/ifconfig gif" . $x . " delete");
126
	}
127

    
128
	$curwanip = get_current_wan_address();
129
	if($config['installedpackages']['sasyncd']['config'] <> "")
130
		foreach($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
131
			if($sasyncd['ip'] <> "") 
132
				$curwanip = $sasyncd['ip'];
133
		}
134

    
135
	$syscfg = $config['system'];
136
	$ipseccfg = $config['ipsec'];
137
	$lancfg = $config['interfaces']['lan'];
138
	$lanip = $lancfg['ipaddr'];
139
	$lansa = gen_subnet($lancfg['ipaddr'], $lancfg['subnet']);
140
	$lansn = $lancfg['subnet'];
141

    
142
	if ($g['booting']) {
143
		if (!isset($ipseccfg['enable']))
144
			return 0;
145

    
146
		echo "Configuring IPsec VPN... ";
147
	} else {
148
		/* kill racoon */
149
		mwexec("/usr/bin/killall racoon");
150

    
151
		/* wait for process to die */
152
		sleep(2);
153

    
154
		/* send a SIGKILL to be sure */
155
		sigkillbypid("{$g['varrun_path']}/racoon.pid", "KILL");
156
	}
157

    
158
	/* flush SPD and SAD */
159
	mwexec("/sbin/setkey -FP");
160
	mwexec("/sbin/setkey -F");
161

    
162
	if (isset($ipseccfg['enable'])) {
163

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

    
167
		if (!$curwanip) {
168
			/* IP address not configured yet, exit */
169
			if ($g['booting'])
170
				echo "done\n";
171
			return 0;
172
		}
173

    
174
		if ((is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) ||
175
				isset($ipseccfg['mobileclients']['enable'])) {
176

    
177
			if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) {
178

    
179
				/* generate spd.conf */
180
				$fd = fopen("{$g['varetc_path']}/spd.conf", "w");
181
				if (!$fd) {
182
					printf("Error: cannot open spd.conf in vpn_ipsec_configure().\n");
183
					return 1;
184
				}
185

    
186
				$spdconf = "";
187

    
188
				$spdconf .= "spdadd {$lansa}/{$lansn} {$lanip}/32 any -P in none;\n";
189
				$spdconf .= "spdadd {$lanip}/32 {$lansa}/{$lansn} any -P out none;\n";
190

    
191
				foreach ($ipseccfg['tunnel'] as $tunnel) {
192

    
193
					if (isset($tunnel['disabled']))
194
						continue;
195

    
196
					$ep = vpn_endpoint_determine($tunnel, $curwanip);
197
					if (!$ep)
198
						continue;
199

    
200
					vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn);
201

    
202
					if(is_domain($tunnel['remote-gateway'])) {
203
						$tmp = gethostbyname($tunnel['remote-gateway']);
204
						if($tmp)
205
							$tunnel['remote-gateway'] = $tmp;
206
					}
207

    
208
					/* add entry to host pinger */
209
					if($tunnel['pinghost']) {
210
						$pfd = fopen("/var/db/ipsecpinghosts","a");
211
						$srcip = find_interface_ip($config['interfaces']['lan']['if']);
212
						$dstip = $tunnel['pinghost'];
213
						fwrite($pfd, "$srcip|$dstip|3\n");
214
						fclose($pfd);
215
					}
216

    
217
					if(isset($tunnel['creategif'])) {
218
						$number_of_gifs = find_last_gif_device();
219
						$number_of_gifs++;
220
						$curwanip = get_current_wan_address();
221
						if($config['installedpackages']['sasyncd']['config'] <> "")
222
							foreach($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
223
								if($sasyncd['ip'] <> "") 
224
									$curwanip = $sasyncd['ip'];
225
							}						
226
						mwexec("/sbin/ifconfig gif" . $number_of_gifs . " tunnel" . $curwanip . " " . $tunnel['remote-gateway']);
227
						mwexec("/sbin/ifconfig gif" . $number_of_gifs . " {$lansa}/{$lansn} {$lanip}/32");
228
					}
229

    
230
					$spdconf .= "spdadd {$sa}/{$sn} " .
231
						"{$tunnel['remote-subnet']} any -P out ipsec " .
232
						"{$tunnel['p2']['protocol']}/tunnel/{$ep}-" .
233
						"{$tunnel['remote-gateway']}/unique;\n";
234

    
235
					$spdconf .= "spdadd {$tunnel['remote-subnet']} " .
236
						"{$sa}/{$sn} any -P in ipsec " .
237
						"{$tunnel['p2']['protocol']}/tunnel/{$tunnel['remote-gateway']}-" .
238
						"{$ep}/unique;\n";
239
				}
240

    
241
				fwrite($fd, $spdconf);
242
				fclose($fd);
243

    
244
				/* load SPD */
245
				mwexec("/sbin/setkey -c < {$g['varetc_path']}/spd.conf");
246
			}
247

    
248
			/* generate racoon.conf */
249
			$fd = fopen("{$g['varetc_path']}/racoon.conf", "w");
250
			if (!$fd) {
251
				printf("Error: cannot open racoon.conf in vpn_ipsec_configure().\n");
252
				return 1;
253
			}
254

    
255
			$racoonconf = "";
256

    
257

    
258
	if($config['installedpackages']['sasyncd']['config'] <> "")
259
		foreach($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
260
			if($sasyncd['ip'] <> "") 
261
				$curwanip = $sasyncd['ip'];
262
				/* natt - turn on if <developer/> exists */
263
				if(isset($config['system']['developer']) <> "") {
264
					$lanip = $config['interfaces']['lan']['ipaddr'];
265
					if($lanip <> "") 
266
						$natt = "isakmp_natt {$lanip}[4500];\n";
267
					
268
				}	
269
				$interface_ip = $sasyncd['ip'];
270
				$racoonconf .= <<<EOD
271
listen {
272
	isakmp {$interface_ip} [500];
273
	{$natt}
274
}
275

    
276
EOD;
277
			}
278

    
279
			$racoonconf = "path pre_shared_key \"{$g['varetc_path']}/psk.txt\";\n\n";
280
			$racoonconf .= "path certificate  \"{$g['varetc_path']}\";\n\n";
281
			
282
			/* generate CA certificates files */
283
			$cacertnum = 0;
284
			if (is_array($ipseccfg['cacert']) && count($ipseccfg['cacert']))
285
				foreach ($ipseccfg['cacert'] as $cacert) {
286
					++$cacertnum;
287
					if (isset($cacert['cert'])) {
288
						$cert = base64_decode($cacert['cert']);
289
						$x509cert = openssl_x509_parse(openssl_x509_read($cert));
290
						if(is_array($x509cert) && isset($x509cert['hash'])) {
291
							$fd1 = fopen("{$g['varetc_path']}/{$x509cert['hash']}.0", "w");
292
							if (!$fd1) {
293
								printf("Error: cannot open {$x509cert['hash']}.0 in vpn.\n");
294
								return 1;
295
							}
296
							chmod("{$g['varetc_path']}/{$x509cert['hash']}.0", 0600);
297
							fwrite($fd1, $cert);
298
							fclose($fd1);
299
						}
300
					}
301
				}
302
						
303
			$tunnelnumber = 0;
304
			if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel']))
305
				foreach ($ipseccfg['tunnel'] as $tunnel) {
306
				
307
				++$tunnelnumber;
308
			
309
				if (isset($tunnel['disabled']))
310
					continue;
311
				
312
				$ep = vpn_endpoint_determine($tunnel, $curwanip);
313
				if (!$ep)
314
					continue;
315
			
316
				vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn);
317
			
318
				if (isset($tunnel['p1']['myident']['myaddress'])) {
319
					$myidentt = "address";
320
					$myident = $ep;
321
				} else if (isset($tunnel['p1']['myident']['address'])) {
322
					$myidentt = "address";
323
					$myident = $tunnel['p1']['myident']['address'];
324
				} else if (isset($tunnel['p1']['myident']['fqdn'])) {
325
					$myidentt = "fqdn";
326
					$myident = $tunnel['p1']['myident']['fqdn'];
327
				} else if (isset($tunnel['p1']['myident']['ufqdn'])) {
328
					$myidentt = "user_fqdn";
329
					$myident = $tunnel['p1']['myident']['ufqdn'];
330
 				} else if (isset($tunnel['p1']['myident']['dyn_dns'])) {
331
					$myidentt = "dyn_dns";
332
					$myident = gethostbyname($tunnel['p1']['myident']['dyn_dns']);
333
 				}
334
				
335
				if (isset($tunnel['p1']['authentication_method'])) {
336
					$authmethod = $tunnel['p1']['authentication_method'];
337
				} else {$authmethod = 'pre_shared_key';}
338
				
339
				$certline = '';	
340
				
341
				if ($authmethod == 'rsasig') {
342
					if ($tunnel['p1']['cert'] && $tunnel['p1']['private-key']) {
343
						$cert = base64_decode($tunnel['p1']['cert']);
344
						$private_key = base64_decode($tunnel['p1']['private-key']);
345
					} else {
346
						/* null certificate/key */
347
						$cert = '';
348
						$private_key = '';
349
					}
350
					
351
					if ($tunnel['p1']['peercert']) 
352
						$peercert = base64_decode($tunnel['p1']['peercert']);
353
					else 
354
						$peercert = '';
355
					
356
					$fd1 = fopen("{$g['varetc_path']}/server{$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']}/server{$tunnelnumber}-signed.pem", 0600);
362
					fwrite($fd1, $cert);
363
					fclose($fd1);
364
					
365
					$fd1 = fopen("{$g['varetc_path']}/server{$tunnelnumber}-key.pem", "w");
366
					if (!$fd1) {
367
						printf("Error: cannot open server{$tunnelnumber}-key.pem in vpn.\n");
368
						return 1;
369
					}
370
					chmod("{$g['varetc_path']}/server{$tunnelnumber}-key.pem", 0600);
371
					fwrite($fd1, $private_key);
372
					fclose($fd1);
373

    
374
					$certline = "certificate_type x509 \"server{$tunnelnumber}-signed.pem\" \"server{$tunnelnumber}-key.pem\";";
375
					
376
					if ($peercert!=''){
377
						$fd1 = fopen("{$g['varetc_path']}/peer{$tunnelnumber}-signed.pem", "w");
378
						if (!$fd1) {
379
							printf("Error: cannot open server{$tunnelnumber}-signed.pem in vpn.\n");
380
							return 1;
381
						}
382
						chmod("{$g['varetc_path']}/peer{$tunnelnumber}-signed.pem", 0600);
383
						fwrite($fd1, $peercert);
384
						fclose($fd1);		
385
						$certline .= <<<EOD
386
						
387
	peers_certfile "peer{$tunnelnumber}-signed.pem";
388
EOD;
389
					} 					
390
				} 
391
				$racoonconf .= <<<EOD
392
remote {$tunnel['remote-gateway']} \{
393
	exchange_mode {$tunnel['p1']['mode']};
394
	my_identifier {$myidentt} "{$myident}";
395
	{$certline}
396
	peers_identifier address {$tunnel['remote-gateway']};
397
	initial_contact on;
398
	support_proxy on;
399
	proposal_check obey;
400

    
401
	proposal \{
402
		encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
403
		hash_algorithm {$tunnel['p1']['hash-algorithm']};
404
		authentication_method {$authmethod};
405
		dh_group {$tunnel['p1']['dhgroup']};
406

    
407
EOD;
408
				if ($tunnel['p1']['lifetime'])
409
					$racoonconf .= "		lifetime time {$tunnel['p1']['lifetime']} secs;\n";
410
				
411
				$racoonconf .= "	}\n";
412
				
413
				if ($tunnel['p1']['lifetime'])
414
					$racoonconf .= "	lifetime time {$tunnel['p1']['lifetime']} secs;\n";
415
					
416
				$racoonconf .= "}\n\n";
417
				
418
				$p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']);
419
				$p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']);
420
				
421
				$racoonconf .= <<<EOD
422
sainfo address {$sa}/{$sn} any address {$tunnel['remote-subnet']} any \{
423
	encryption_algorithm {$p2ealgos};
424
	authentication_algorithm {$p2halgos};
425
	compression_algorithm deflate;
426

    
427
EOD;
428

    
429
				if ($tunnel['p2']['pfsgroup'])
430
					$racoonconf .= "	pfs_group {$tunnel['p2']['pfsgroup']};\n";
431
					
432
				if ($tunnel['p2']['lifetime'])
433
					$racoonconf .= "	lifetime time {$tunnel['p2']['lifetime']} secs;\n";
434
					
435
				$racoonconf .= "}\n\n";
436
			}
437
			
438
			/* mobile clients? */
439
			if (isset($ipseccfg['mobileclients']['enable'])) {
440
				
441
				$tunnel = $ipseccfg['mobileclients'];
442
				
443
				if (isset($tunnel['p1']['myident']['myaddress'])) {
444
					$myidentt = "address";
445
					$myident = $curwanip;
446
				} else if (isset($tunnel['p1']['myident']['address'])) {
447
					$myidentt = "address";
448
					$myident = $tunnel['p1']['myident']['address'];
449
				} else if (isset($tunnel['p1']['myident']['fqdn'])) {
450
					$myidentt = "fqdn";
451
					$myident = $tunnel['p1']['myident']['fqdn'];
452
				} else if (isset($tunnel['p1']['myident']['ufqdn'])) {
453
					$myidentt = "user_fqdn";
454
					$myident = $tunnel['p1']['myident']['ufqdn'];
455
 				}
456
				
457
				if (isset($tunnel['p1']['authentication_method'])) {
458
					$authmethod = $tunnel['p1']['authentication_method'];
459
				} else {$authmethod = 'pre_shared_key';}
460
				
461
				$certline = '';					
462
				if ($authmethod == 'rsasig') {
463
					if ($tunnel['p1']['cert'] && $tunnel['p1']['private-key']) {
464
						$cert = base64_decode($tunnel['p1']['cert']);
465
						$private_key = base64_decode($tunnel['p1']['private-key']);
466
					} else {
467
						/* null certificate/key */
468
						$cert = '';
469
						$private_key = '';
470
					}
471
					
472
					if ($tunnel['p1']['peercert']) 
473
						$peercert = base64_decode($tunnel['p1']['peercert']);
474
					else 
475
						$peercert = '';
476
					
477
					$fd1 = fopen("{$g['varetc_path']}/server-mobile{$tunnelnumber}-signed.pem", "w");
478
					if (!$fd1) {
479
						printf("Error: cannot open server-mobile{$tunnelnumber}-signed.pem in vpn.\n");
480
						return 1;
481
					}
482
					chmod("{$g['varetc_path']}/server-mobile{$tunnelnumber}-signed.pem", 0600);
483
					fwrite($fd1, $cert);
484
					fclose($fd1);
485
					
486
					$fd1 = fopen("{$g['varetc_path']}/server-mobile{$tunnelnumber}-key.pem", "w");
487
					if (!$fd1) {
488
						printf("Error: cannot open server-mobile{$tunnelnumber}-key.pem in vpn.\n");
489
						return 1;
490
					}
491
					chmod("{$g['varetc_path']}/server-mobile{$tunnelnumber}-key.pem", 0600);
492
					fwrite($fd1, $private_key);
493
					fclose($fd1);
494

    
495
					$certline = "certificate_type x509 \"server-mobile{$tunnelnumber}-signed.pem\" \"server-mobile{$tunnelnumber}-key.pem\";";
496
				}
497
				$racoonconf .= <<<EOD
498
remote anonymous \{
499
	exchange_mode {$tunnel['p1']['mode']};
500
	my_identifier {$myidentt} "{$myident}";
501
	{$certline}
502
	initial_contact on;
503
	passive on;
504
	generate_policy on;
505
	support_proxy on;
506
	proposal_check obey;
507

    
508
	proposal \{
509
		encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
510
		hash_algorithm {$tunnel['p1']['hash-algorithm']};
511
		authentication_method {$authmethod};
512
		dh_group {$tunnel['p1']['dhgroup']};
513

    
514
EOD;
515
				if ($tunnel['p1']['lifetime'])
516
					$racoonconf .= "		lifetime time {$tunnel['p1']['lifetime']} secs;\n";
517
				
518
				$racoonconf .= "	}\n";
519
				
520
				if ($tunnel['p1']['lifetime'])
521
					$racoonconf .= "	lifetime time {$tunnel['p1']['lifetime']} secs;\n";
522
					
523
				$racoonconf .= "}\n\n";
524
				
525
				$p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']);
526
				$p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']);
527
				
528
				$racoonconf .= <<<EOD
529
sainfo anonymous \{
530
	encryption_algorithm {$p2ealgos};
531
	authentication_algorithm {$p2halgos};
532
	compression_algorithm deflate;
533

    
534
EOD;
535

    
536
				if ($tunnel['p2']['pfsgroup'])
537
					$racoonconf .= "	pfs_group {$tunnel['p2']['pfsgroup']};\n";
538
					
539
				if ($tunnel['p2']['lifetime'])
540
					$racoonconf .= "	lifetime time {$tunnel['p2']['lifetime']} secs;\n";
541
					
542
				$racoonconf .= "}\n\n";
543
			}
544
			
545
			fwrite($fd, $racoonconf);
546
			fclose($fd);
547
			
548
			/* generate psk.txt */
549
			$fd = fopen("{$g['varetc_path']}/psk.txt", "w");
550
			if (!$fd) {
551
				printf("Error: cannot open psk.txt in vpn_ipsec_configure().\n");
552
				return 1;
553
			}
554
			
555
			$pskconf = "";
556
			
557
			if (is_array($ipseccfg['tunnel'])) {
558
				foreach ($ipseccfg['tunnel'] as $tunnel) {
559
					if (isset($tunnel['disabled']))
560
						continue;
561
					$pskconf .= "{$tunnel['remote-gateway']}	 {$tunnel['p1']['pre-shared-key']}\n";
562
				}
563
			}
564
			
565
			/* add PSKs for mobile clients */
566
			if (is_array($ipseccfg['mobilekey'])) {
567
				foreach ($ipseccfg['mobilekey'] as $key) {
568
					$pskconf .= "{$key['ident']}	{$key['pre-shared-key']}\n";
569
				}
570
			}
571
			
572
			fwrite($fd, $pskconf);
573
			fclose($fd);
574
			chmod("{$g['varetc_path']}/psk.txt", 0600);
575
			
576
			/* start racoon */
577
			mwexec("/usr/local/sbin/racoon -f {$g['varetc_path']}/racoon.conf");
578
		}
579
	}
580

    
581
	vpn_ipsec_failover_configure();
582

    
583
	if (!$g['booting']) {
584
		/* reload the filter */
585
		touch("{$g["tmp_path"]}/filter_dirty");
586
	}
587

    
588
	if ($g['booting'])
589
		echo "done\n";
590

    
591
	return 0;
592
}
593

    
594
function vpn_pptpd_configure() {
595
	global $config, $g;
596
	
597
	$syscfg = $config['system'];
598
	$pptpdcfg = $config['pptpd'];
599
	
600
	if ($g['booting']) {
601
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
602
			return 0;
603
		
604
		echo "Configuring PPTP VPN service... ";
605
	} else {	
606
		/* kill mpd */
607
		killbypid("{$g['varrun_path']}/mpd-vpn.pid");
608
		
609
		/* wait for process to die */
610
		sleep(3);
611
		
612
		if(is_process_running("mpd -b")) {
613
			killbypid("{$g['varrun_path']}/mpd-vpn.pid");
614
			log_error("Could not kill mpd within 3 seconds.   Trying again.");
615
		}
616
		
617
		/* remove mpd.conf, if it exists */
618
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.conf");
619
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.links");
620
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.secret");
621
	}
622
		
623
	/* make sure mpd-vpn directory exists */
624
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
625
		mkdir("{$g['varetc_path']}/mpd-vpn");
626
		
627
	switch ($pptpdcfg['mode']) {
628
		
629
		case 'server':
630
			
631
			/* write mpd.conf */
632
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.conf", "w");
633
			if (!$fd) {
634
				printf("Error: cannot open mpd.conf in vpn_pptpd_configure().\n");
635
				return 1;
636
			}
637
				
638
			$mpdconf = <<<EOD
639
pptpd:
640

    
641
EOD;
642

    
643
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
644
				$mpdconf .= "	load pt{$i}\n";
645
			}
646
			
647
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
648
			
649
				$clientip = long2ip(ip2long($pptpdcfg['remoteip']) + $i);
650
				$ngif = "ng" . ($i+1);
651
			
652
				$mpdconf .= <<<EOD
653

    
654
pt{$i}:
655
	new -i {$ngif} pt{$i} pt{$i}
656
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
657
	load pts
658

    
659
EOD;
660
			}
661
			
662
			$mpdconf .= <<<EOD
663

    
664
pts:
665
	set iface disable on-demand
666
	set iface enable proxy-arp
667
	set iface enable tcpmssfix
668
	set iface idle 1800
669
	set iface up-script /usr/local/sbin/vpn-linkup
670
	set iface down-script /usr/local/sbin/vpn-linkdown
671
	set bundle enable multilink
672
	set bundle enable crypt-reqd
673
	set link yes acfcomp protocomp
674
	set link no pap chap
675
	set link enable chap-msv2
676
	set link mtu 1460
677
	set link keep-alive 10 60
678
	set ipcp yes vjcomp
679
	set bundle enable compression
680
	set ccp yes mppc
681
	set ccp yes mpp-e128
682
	set ccp yes mpp-stateless
683

    
684
EOD;
685
			
686
			if (!isset($pptpdcfg['req128'])) {
687
				$mpdconf .= <<<EOD
688
	set ccp yes mpp-e40
689
	set ccp yes mpp-e56
690

    
691
EOD;
692
			}
693
			
694
			if (is_array($pptpdcfg['dnsserver']) && ($pptpdcfg['dnsserver'][0])) {
695
				$mpdconf .= "	set ipcp dns " . join(" ", $pptpdcfg['dnsserver']) . "\n";
696
			} else if (isset($config['dnsmasq']['enable'])) {
697
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
698
				if ($syscfg['dnsserver'][0])
699
					$mpdconf .= " " . $syscfg['dnsserver'][0];
700
				$mpdconf .= "\n";
701
			} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
702
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
703
			}
704
			
705
			if (isset($pptpdcfg['radius']['enable'])) {
706
				$mpdconf .= <<<EOD
707
	set radius server {$pptpdcfg['radius']['server']} "{$pptpdcfg['radius']['secret']}"
708
	set radius retries 3
709
	set radius timeout 10
710
	set bundle enable radius-auth
711
	set bundle disable radius-fallback
712

    
713
EOD;
714

    
715
				if (isset($pptpdcfg['radius']['accounting'])) {
716
					$mpdconf .= <<<EOD
717
	set bundle enable radius-acct
718

    
719
EOD;
720
				}
721
			}
722

    
723
			fwrite($fd, $mpdconf);
724
			fclose($fd);
725
			
726
			/* write mpd.links */
727
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.links", "w");
728
			if (!$fd) {
729
				printf("Error: cannot open mpd.links in vpn_pptpd_configure().\n");
730
				return 1;
731
			}
732
			
733
			$mpdlinks = "";
734
			
735
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
736
				$mpdlinks .= <<<EOD
737

    
738
pt{$i}:
739
	set link type pptp
740
	set pptp enable incoming
741
	set pptp disable originate
742
	set pptp disable windowing
743
	set pptp self 127.0.0.1
744

    
745
EOD;
746
			}
747

    
748
			fwrite($fd, $mpdlinks);
749
			fclose($fd);
750
			
751
			/* write mpd.secret */
752
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.secret", "w");
753
			if (!$fd) {
754
				printf("Error: cannot open mpd.secret in vpn_pptpd_configure().\n");
755
				return 1;
756
			}
757
			
758
			$mpdsecret = "";
759
			
760
			if (is_array($pptpdcfg['user'])) {
761
				foreach ($pptpdcfg['user'] as $user)
762
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
763
			}
764

    
765
			fwrite($fd, $mpdsecret);
766
			fclose($fd);
767
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
768
			
769
			/* fire up mpd */
770
			mwexec("/usr/local/sbin/mpd -b -d {$g['varetc_path']}/mpd-vpn -p {$g['varrun_path']}/mpd-vpn.pid pptpd");
771
			
772
			break;
773
			
774
		case 'redir':
775
			break;
776
	}
777
	
778
	if (!$g['booting']) {
779
		/* reload the filter */
780
		filter_configure();
781
	}
782
	
783
	if ($g['booting'])
784
		echo "done\n";
785
	
786
	return 0;
787
}
788

    
789
function vpn_localnet_determine($adr, &$sa, &$sn) {
790
	global $config, $g;
791

    
792
	if (isset($adr)) {
793
		if ($adr['network']) {			
794
			switch ($adr['network']) {
795
				case 'lan':
796
					$sn = $config['interfaces']['lan']['subnet'];
797
					$sa = gen_subnet($config['interfaces']['lan']['ipaddr'], $sn);
798
					break;
799
			}
800
		} else if ($adr['address']) {
801
			list($sa,$sn) = explode("/", $adr['address']);
802
			if (is_null($sn))
803
				$sn = 32;
804
		}
805
	} else {
806
		$sn = $config['interfaces']['lan']['subnet'];
807
		$sa = gen_subnet($config['interfaces']['lan']['ipaddr'], $sn);
808
	}
809
}
810

    
811
function vpn_endpoint_determine($tunnel, $curwanip) {
812
	
813
	global $g, $config;
814
	
815
	if ((!$tunnel['interface']) || ($tunnel['interface'] == "wan")) {
816
		if ($curwanip)
817
			return $curwanip;
818
		else
819
			return null;
820
	} else if ($tunnel['interface'] == "lan") {
821
		return $config['interfaces']['lan']['ipaddr'];
822
	} else {
823
		$oc = $config['interfaces'][$tunnel['interface']];
824
		
825
		if (isset($oc['enable']) && $oc['if']) {
826
			return $oc['ipaddr'];
827
		}
828
	}
829
	
830
	return null;
831
}
832

    
833
function vpn_pppoe_configure() {
834
	global $config, $g;
835

    
836
	$syscfg = $config['system'];
837
	$pppoecfg = $config['pppoe'];
838

    
839
	/* create directory if it does not exist */
840
	if(!is_dir("{$g['varetc_path']}/mpd-vpn"))
841
		mkdir("{$g['varetc_path']}/mpd-vpn");
842
	
843
	if ($g['booting']) {
844
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
845
			return 0;
846

    
847
		echo "Configuring PPPoE VPN service... ";
848
	}
849

    
850
	/* make sure mpd-vpn directory exists */
851
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
852
		mkdir("{$g['varetc_path']}/mpd-vpn");
853

    
854
	switch ($pppoecfg['mode']) {
855

    
856
		case 'server':
857

    
858
			$pppoe_interface = filter_translate_type_to_real_interface($pppoecfg['interface']);
859

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

    
870
EOD;
871

    
872
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
873
				$mpdconf .= "	load pppoe{$i}\n";
874
			}
875

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

    
878
				$clientip = long2ip(ip2long($pppoecfg['remoteip']) + $i);
879
				$ngif = "ng" . ($i+1);
880
				
881
				if(isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['enable'])) {
882
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
883
					$isssue_ip_type .="\n\tset ipcp yes radius-ip";					
884
				} else {
885
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
886
				}
887
				
888
				$mpdconf .= <<<EOD
889

    
890
pppoe{$i}:
891
	new -i {$ngif} pppoe{$i} pppoe{$i}
892
	{$isssue_ip_type}
893
	load pppoe_standart
894

    
895
EOD;
896
			}
897

    
898
			$mpdconf .= <<<EOD
899

    
900
pppoe_standart:
901
	set link type pppoe
902
	set pppoe iface {$pppoe_interface}
903
	set pppoe service "*"
904
	set pppoe disable originate
905
	set pppoe enable incoming
906
	set bundle no multilink
907
	set bundle enable compression
908
	set bundle max-logins 1
909
	set iface idle 0
910
	set iface disable on-demand
911
	set iface disable proxy-arp
912
	set iface enable tcpmssfix
913
	set iface mtu 1500
914
	set link no pap chap
915
	set link enable chap
916
	set link keep-alive 60 180
917
	set ipcp yes vjcomp
918
	set ipcp no vjcomp
919
	set link max-redial -1
920
	set link mtu 1492
921
	set link mru 1492	
922
	set ccp yes mpp-e40
923
	set ccp yes mpp-e128
924
	set ccp yes mpp-stateless
925
	set link latency 1
926
	#set ipcp dns 10.10.1.3
927
	#set bundle accept encryption	
928

    
929
EOD;
930

    
931
			if (isset($config['dnsmasq']['enable'])) {
932
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
933
				if ($syscfg['dnsserver'][0])
934
					$mpdconf .= " " . $syscfg['dnsserver'][0];
935
				$mpdconf .= "\n";
936
			} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
937
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
938
			}
939

    
940
			if (isset($pppoecfg['radius']['enable'])) {
941
				$mpdconf .= <<<EOD
942
	set radius server {$pppoecfg['radius']['server']} "{$pppoecfg['radius']['secret']}"
943
	set radius retries 3
944
	set radius timeout 10
945
	set bundle enable radius-auth
946
	set bundle disable radius-fallback
947

    
948
EOD;
949

    
950
				if (isset($pppoecfg['radius']['accounting'])) {
951
					$mpdconf .= <<<EOD
952
	set bundle enable radius-acct
953

    
954
EOD;
955
				}
956
			}
957

    
958
			fwrite($fd, $mpdconf);
959
			fclose($fd);
960

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

    
968
			$mpdlinks = "";
969

    
970
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
971
				$mpdlinks .= <<<EOD
972

    
973
pppoe:
974
	set link type pppoe
975
	set pppoe iface {$pppoe_interface}
976

    
977
EOD;
978
			}
979

    
980
			fwrite($fd, $mpdlinks);
981
			fclose($fd);
982

    
983
			/* write mpd.secret */
984
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.secret", "a");
985
			if (!$fd) {
986
				printf("Error: cannot open mpd.secret in vpn_pppoe_configure().\n");
987
				return 1;
988
			}
989

    
990
			$mpdsecret = "\n\n";
991

    
992
			if (is_array($pppoecfg['user'])) {
993
				foreach ($pppoecfg['user'] as $user)
994
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
995
			}
996

    
997
			fwrite($fd, $mpdsecret);
998
			fclose($fd);
999
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
1000

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

    
1004
			break;
1005

    
1006
		case 'redir':
1007
			break;
1008
	}
1009

    
1010
	touch("{$g["tmp_path"]}/filter_dirty");
1011

    
1012
	if ($g['booting'])
1013
		echo "done\n";
1014

    
1015
	return 0;
1016
}
1017

    
1018
?>
(22-22/27)