Project

General

Profile

Download (26 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['ipsec']['preferredoldsa'])) {
91
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
92
	} else {
93
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
94
	}
95

    
96
	$number_of_gifs = find_last_gif_device();
97
	for($x=0; $x<$number_of_gifs; $x++) {
98
		mwexec("/sbin/ifconfig gif" . $x . " delete");
99
	}
100

    
101
	$curwanip = get_current_wan_address();
102
	if($config['installedpackages']['sasyncd']['config'] <> "")
103
		foreach($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
104
			if($sasyncd['ip'] <> "") 
105
				$curwanip = $sasyncd['ip'];
106
		}
107

    
108
	$syscfg = $config['system'];
109
	$ipseccfg = $config['ipsec'];
110
	$lancfg = $config['interfaces']['lan'];
111
	$lanip = $lancfg['ipaddr'];
112
	$lansa = gen_subnet($lancfg['ipaddr'], $lancfg['subnet']);
113
	$lansn = $lancfg['subnet'];
114

    
115
	if ($g['booting']) {
116
		if (!isset($ipseccfg['enable']))
117
			return 0;
118

    
119
		echo "Configuring IPsec VPN... ";
120
	} else {
121
		/* kill racoon */
122
		killbypid("{$g['varrun_path']}/racoon.pid");
123

    
124
		/* wait for process to die */
125
		sleep(2);
126

    
127
		/* send a SIGKILL to be sure */
128
		sigkillbypid("{$g['varrun_path']}/racoon.pid", "KILL");
129
	}
130

    
131
	/* flush SPD and SAD */
132
	mwexec("/usr/sbin/setkey -FP");
133
	mwexec("/usr/sbin/setkey -F");
134

    
135
	if (isset($ipseccfg['enable'])) {
136

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

    
140
		if (!$curwanip) {
141
			/* IP address not configured yet, exit */
142
			if ($g['booting'])
143
				echo "done\n";
144
			return 0;
145
		}
146

    
147
		if ((is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) ||
148
				isset($ipseccfg['mobileclients']['enable'])) {
149

    
150
			if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) {
151

    
152
				/* generate spd.conf */
153
				$fd = fopen("{$g['varetc_path']}/spd.conf", "w");
154
				if (!$fd) {
155
					printf("Error: cannot open spd.conf in vpn_ipsec_configure().\n");
156
					return 1;
157
				}
158

    
159
				$spdconf = "";
160

    
161
				$spdconf .= "spdadd {$lansa}/{$lansn} {$lanip}/32 any -P in none;\n";
162
				$spdconf .= "spdadd {$lanip}/32 {$lansa}/{$lansn} any -P out none;\n";
163

    
164
				foreach ($ipseccfg['tunnel'] as $tunnel) {
165

    
166
					if (isset($tunnel['disabled']))
167
						continue;
168

    
169
					$ep = vpn_endpoint_determine($tunnel, $curwanip);
170
					if (!$ep)
171
						continue;
172

    
173
					vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn);
174

    
175
					if(isset($tunnel['creategif'])) {
176
						$number_of_gifs = find_last_gif_device();
177
						$number_of_gifs++;
178
						$curwanip = get_current_wan_address();
179
						if($config['installedpackages']['sasyncd']['config'] <> "")
180
							foreach($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
181
								if($sasyncd['ip'] <> "") 
182
									$curwanip = $sasyncd['ip'];
183
							}						
184
						mwexec("/sbin/ifconfig gif" . $number_of_gifs . " tunnel" . $curwanip . " " . $tunnel['remote-gateway']);
185
						mwexec("/sbin/ifconfig gif" . $number_of_gifs . " {$lansa}/{$lansn} {$lanip}/32");
186
					}
187

    
188
					$spdconf .= "spdadd {$sa}/{$sn} " .
189
						"{$tunnel['remote-subnet']} any -P out ipsec " .
190
						"{$tunnel['p2']['protocol']}/tunnel/{$ep}-" .
191
						"{$tunnel['remote-gateway']}/unique;\n";
192

    
193
					$spdconf .= "spdadd {$tunnel['remote-subnet']} " .
194
						"{$sa}/{$sn} any -P in ipsec " .
195
						"{$tunnel['p2']['protocol']}/tunnel/{$tunnel['remote-gateway']}-" .
196
						"{$ep}/unique;\n";
197
				}
198

    
199
				fwrite($fd, $spdconf);
200
				fclose($fd);
201

    
202
				/* load SPD */
203
				mwexec("/usr/sbin/setkey -c < {$g['varetc_path']}/spd.conf");
204
			}
205

    
206
			/* generate racoon.conf */
207
			$fd = fopen("{$g['varetc_path']}/racoon.conf", "w");
208
			if (!$fd) {
209
				printf("Error: cannot open racoon.conf in vpn_ipsec_configure().\n");
210
				return 1;
211
			}
212

    
213
			$racoonconf = "";
214

    
215

    
216
	if($config['installedpackages']['sasyncd']['config'] <> "")
217
		foreach($config['installedpackages']['sasyncd']['config'] as $sasyncd) {
218
			if($sasyncd['ip'] <> "") 
219
				$curwanip = $sasyncd['ip'];
220

    
221
				$interface_ip = $sasyncd['ip'];
222
				$racoonconf .= <<<EOD
223
listen {
224
	isakmp {$interface_ip} [500];
225
}
226

    
227
EOD;
228
			}
229

    
230
			$racoonconf = "path pre_shared_key \"{$g['varetc_path']}/psk.txt\";\n\n";
231
			$racoonconf .= "path certificate  \"{$g['varetc_path']}\";\n\n";
232
			
233
			/* generate CA certificates files */
234
			$cacertnum = 0;
235
			if (is_array($ipseccfg['cacert']) && count($ipseccfg['cacert']))
236
				foreach ($ipseccfg['cacert'] as $cacert) {
237
					++$cacertnum;
238
					if (isset($cacert['cert'])) {
239
						$cert = base64_decode($cacert['cert']);
240
						$x509cert = openssl_x509_parse(openssl_x509_read($cert));
241
						if(is_array($x509cert) && isset($x509cert['hash'])) {
242
							$fd1 = fopen("{$g['varetc_path']}/{$x509cert['hash']}.0", "w");
243
							if (!$fd1) {
244
								printf("Error: cannot open {$x509cert['hash']}.0 in vpn.\n");
245
								return 1;
246
							}
247
							chmod("{$g['varetc_path']}/{$x509cert['hash']}.0", 0600);
248
							fwrite($fd1, $cert);
249
							fclose($fd1);
250
						}
251
					}
252
				}
253
						
254
			$tunnelnumber = 0;
255
			if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel']))
256
				foreach ($ipseccfg['tunnel'] as $tunnel) {
257
				
258
				++$tunnelnumber;
259
			
260
				if (isset($tunnel['disabled']))
261
					continue;
262
				
263
				$ep = vpn_endpoint_determine($tunnel, $curwanip);
264
				if (!$ep)
265
					continue;
266
			
267
				vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn);
268
			
269
				if (isset($tunnel['p1']['myident']['myaddress'])) {
270
					$myidentt = "address";
271
					$myident = $ep;
272
				} else if (isset($tunnel['p1']['myident']['address'])) {
273
					$myidentt = "address";
274
					$myident = $tunnel['p1']['myident']['address'];
275
				} else if (isset($tunnel['p1']['myident']['fqdn'])) {
276
					$myidentt = "fqdn";
277
					$myident = $tunnel['p1']['myident']['fqdn'];
278
				} else if (isset($tunnel['p1']['myident']['ufqdn'])) {
279
					$myidentt = "user_fqdn";
280
					$myident = $tunnel['p1']['myident']['ufqdn'];
281
 				} else if (isset($tunnel['p1']['myident']['dyn_dns'])) {
282
					$myidentt = "dyn_dns";
283
					$myident = gethostbyname($tunnel['p1']['myident']['dyn_dns']);
284
 				}
285
				
286
				if (isset($tunnel['p1']['authentication_method'])) {
287
					$authmethod = $tunnel['p1']['authentication_method'];
288
				} else {$authmethod = 'pre_shared_key';}
289
				
290
				$certline = '';	
291
				
292
				if ($authmethod == 'rsasig') {
293
					if ($tunnel['p1']['cert'] && $tunnel['p1']['private-key']) {
294
						$cert = base64_decode($tunnel['p1']['cert']);
295
						$private_key = base64_decode($tunnel['p1']['private-key']);
296
					} else {
297
						/* null certificate/key */
298
						$cert = '';
299
						$private_key = '';
300
					}
301
					
302
					if ($tunnel['p1']['peercert']) 
303
						$peercert = base64_decode($tunnel['p1']['peercert']);
304
					else 
305
						$peercert = '';
306
					
307
					$fd1 = fopen("{$g['varetc_path']}/server{$tunnelnumber}-signed.pem", "w");
308
					if (!$fd1) {
309
						printf("Error: cannot open server{$tunnelnumber}-signed.pem in vpn.\n");
310
						return 1;
311
					}
312
					chmod("{$g['varetc_path']}/server{$tunnelnumber}-signed.pem", 0600);
313
					fwrite($fd1, $cert);
314
					fclose($fd1);
315
					
316
					$fd1 = fopen("{$g['varetc_path']}/server{$tunnelnumber}-key.pem", "w");
317
					if (!$fd1) {
318
						printf("Error: cannot open server{$tunnelnumber}-key.pem in vpn.\n");
319
						return 1;
320
					}
321
					chmod("{$g['varetc_path']}/server{$tunnelnumber}-key.pem", 0600);
322
					fwrite($fd1, $private_key);
323
					fclose($fd1);
324

    
325
					$certline = "certificate_type x509 \"server{$tunnelnumber}-signed.pem\" \"server{$tunnelnumber}-key.pem\";";
326
					
327
					if ($peercert!=''){
328
						$fd1 = fopen("{$g['varetc_path']}/peer{$tunnelnumber}-signed.pem", "w");
329
						if (!$fd1) {
330
							printf("Error: cannot open server{$tunnelnumber}-signed.pem in vpn.\n");
331
							return 1;
332
						}
333
						chmod("{$g['varetc_path']}/peer{$tunnelnumber}-signed.pem", 0600);
334
						fwrite($fd1, $peercert);
335
						fclose($fd1);		
336
						$certline .= <<<EOD
337
						
338
	peers_certfile "peer{$tunnelnumber}-signed.pem";
339
EOD;
340
					} 					
341
				} 
342
				$racoonconf .= <<<EOD
343
remote {$tunnel['remote-gateway']} \{
344
	exchange_mode {$tunnel['p1']['mode']};
345
	my_identifier {$myidentt} "{$myident}";
346
	{$certline}
347
	peers_identifier address {$tunnel['remote-gateway']};
348
	initial_contact on;
349
	support_proxy on;
350
	proposal_check obey;
351

    
352
	proposal \{
353
		encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
354
		hash_algorithm {$tunnel['p1']['hash-algorithm']};
355
		authentication_method {$authmethod};
356
		dh_group {$tunnel['p1']['dhgroup']};
357

    
358
EOD;
359
				if ($tunnel['p1']['lifetime'])
360
					$racoonconf .= "		lifetime time {$tunnel['p1']['lifetime']} secs;\n";
361
				
362
				$racoonconf .= "	}\n";
363
				
364
				if ($tunnel['p1']['lifetime'])
365
					$racoonconf .= "	lifetime time {$tunnel['p1']['lifetime']} secs;\n";
366
					
367
				$racoonconf .= "}\n\n";
368
				
369
				$p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']);
370
				$p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']);
371
				
372
				$racoonconf .= <<<EOD
373
sainfo address {$sa}/{$sn} any address {$tunnel['remote-subnet']} any \{
374
	encryption_algorithm {$p2ealgos};
375
	authentication_algorithm {$p2halgos};
376
	compression_algorithm deflate;
377

    
378
EOD;
379

    
380
				if ($tunnel['p2']['pfsgroup'])
381
					$racoonconf .= "	pfs_group {$tunnel['p2']['pfsgroup']};\n";
382
					
383
				if ($tunnel['p2']['lifetime'])
384
					$racoonconf .= "	lifetime time {$tunnel['p2']['lifetime']} secs;\n";
385
					
386
				$racoonconf .= "}\n\n";
387
			}
388
			
389
			/* mobile clients? */
390
			if (isset($ipseccfg['mobileclients']['enable'])) {
391
				
392
				$tunnel = $ipseccfg['mobileclients'];
393
				
394
				if (isset($tunnel['p1']['myident']['myaddress'])) {
395
					$myidentt = "address";
396
					$myident = $curwanip;
397
				} else if (isset($tunnel['p1']['myident']['address'])) {
398
					$myidentt = "address";
399
					$myident = $tunnel['p1']['myident']['address'];
400
				} else if (isset($tunnel['p1']['myident']['fqdn'])) {
401
					$myidentt = "fqdn";
402
					$myident = $tunnel['p1']['myident']['fqdn'];
403
				} else if (isset($tunnel['p1']['myident']['ufqdn'])) {
404
					$myidentt = "user_fqdn";
405
					$myident = $tunnel['p1']['myident']['ufqdn'];
406
 				}
407
				
408
				if (isset($tunnel['p1']['authentication_method'])) {
409
					$authmethod = $tunnel['p1']['authentication_method'];
410
				} else {$authmethod = 'pre_shared_key';}
411
				
412
				$certline = '';					
413
				if ($authmethod == 'rsasig') {
414
					if ($tunnel['p1']['cert'] && $tunnel['p1']['private-key']) {
415
						$cert = base64_decode($tunnel['p1']['cert']);
416
						$private_key = base64_decode($tunnel['p1']['private-key']);
417
					} else {
418
						/* null certificate/key */
419
						$cert = '';
420
						$private_key = '';
421
					}
422
					
423
					if ($tunnel['p1']['peercert']) 
424
						$peercert = base64_decode($tunnel['p1']['peercert']);
425
					else 
426
						$peercert = '';
427
					
428
					$fd1 = fopen("{$g['varetc_path']}/server-mobile{$tunnelnumber}-signed.pem", "w");
429
					if (!$fd1) {
430
						printf("Error: cannot open server-mobile{$tunnelnumber}-signed.pem in vpn.\n");
431
						return 1;
432
					}
433
					chmod("{$g['varetc_path']}/server-mobile{$tunnelnumber}-signed.pem", 0600);
434
					fwrite($fd1, $cert);
435
					fclose($fd1);
436
					
437
					$fd1 = fopen("{$g['varetc_path']}/server-mobile{$tunnelnumber}-key.pem", "w");
438
					if (!$fd1) {
439
						printf("Error: cannot open server-mobile{$tunnelnumber}-key.pem in vpn.\n");
440
						return 1;
441
					}
442
					chmod("{$g['varetc_path']}/server-mobile{$tunnelnumber}-key.pem", 0600);
443
					fwrite($fd1, $private_key);
444
					fclose($fd1);
445

    
446
					$certline = "certificate_type x509 \"server-mobile{$tunnelnumber}-signed.pem\" \"server-mobile{$tunnelnumber}-key.pem\";";
447
				}
448
				$racoonconf .= <<<EOD
449
remote anonymous \{
450
	exchange_mode {$tunnel['p1']['mode']};
451
	my_identifier {$myidentt} "{$myident}";
452
	{$certline}
453
	initial_contact on;
454
	passive on;
455
	generate_policy on;
456
	support_proxy on;
457
	proposal_check obey;
458

    
459
	proposal \{
460
		encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
461
		hash_algorithm {$tunnel['p1']['hash-algorithm']};
462
		authentication_method {$authmethod};
463
		dh_group {$tunnel['p1']['dhgroup']};
464

    
465
EOD;
466
				if ($tunnel['p1']['lifetime'])
467
					$racoonconf .= "		lifetime time {$tunnel['p1']['lifetime']} secs;\n";
468
				
469
				$racoonconf .= "	}\n";
470
				
471
				if ($tunnel['p1']['lifetime'])
472
					$racoonconf .= "	lifetime time {$tunnel['p1']['lifetime']} secs;\n";
473
					
474
				$racoonconf .= "}\n\n";
475
				
476
				$p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']);
477
				$p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']);
478
				
479
				$racoonconf .= <<<EOD
480
sainfo anonymous \{
481
	encryption_algorithm {$p2ealgos};
482
	authentication_algorithm {$p2halgos};
483
	compression_algorithm deflate;
484

    
485
EOD;
486

    
487
				if ($tunnel['p2']['pfsgroup'])
488
					$racoonconf .= "	pfs_group {$tunnel['p2']['pfsgroup']};\n";
489
					
490
				if ($tunnel['p2']['lifetime'])
491
					$racoonconf .= "	lifetime time {$tunnel['p2']['lifetime']} secs;\n";
492
					
493
				$racoonconf .= "}\n\n";
494
			}
495
			
496
			fwrite($fd, $racoonconf);
497
			fclose($fd);
498
			
499
			/* generate psk.txt */
500
			$fd = fopen("{$g['varetc_path']}/psk.txt", "w");
501
			if (!$fd) {
502
				printf("Error: cannot open psk.txt in vpn_ipsec_configure().\n");
503
				return 1;
504
			}
505
			
506
			$pskconf = "";
507
			
508
			if (is_array($ipseccfg['tunnel'])) {
509
				foreach ($ipseccfg['tunnel'] as $tunnel) {
510
					if (isset($tunnel['disabled']))
511
						continue;
512
					$pskconf .= "{$tunnel['remote-gateway']}	 {$tunnel['p1']['pre-shared-key']}\n";
513
				}
514
			}
515
			
516
			/* add PSKs for mobile clients */
517
			if (is_array($ipseccfg['mobilekey'])) {
518
				foreach ($ipseccfg['mobilekey'] as $key) {
519
					$pskconf .= "{$key['ident']}	{$key['pre-shared-key']}\n";
520
				}
521
			}
522
			
523
			fwrite($fd, $pskconf);
524
			fclose($fd);
525
			chmod("{$g['varetc_path']}/psk.txt", 0600);
526
			
527
			/* start racoon */
528
			mwexec("/usr/local/sbin/racoon -d -f {$g['varetc_path']}/racoon.conf");
529
			
530
			if (is_array($ipseccfg['tunnel'])) {
531
				foreach ($ipseccfg['tunnel'] as $tunnel) {
532
					if (isset($tunnel['auto'])) {
533
						$remotehost = substr($tunnel['remote-subnet'],0,strpos($tunnel['remote-subnet'],"/"));
534
						$srchost = vpn_endpoint_determine($tunnel, $curwanip);
535
						if ($srchost)
536
							mwexec_bg("/sbin/ping -c 10 -S {$srchost} {$remotehost}");
537
					}
538
				}
539
			}
540
		}
541
	}
542

    
543
	vpn_ipsec_failover_configure();
544

    
545
	if (!$g['booting']) {
546
		/* reload the filter */
547
		touch("{$g["tmp_path"]}/filter_dirty");
548
	}
549

    
550
	if ($g['booting'])
551
		echo "done\n";
552

    
553
	return 0;
554
}
555

    
556
function vpn_pptpd_configure() {
557
	global $config, $g;
558

    
559
	$syscfg = $config['system'];
560
	$pptpdcfg = $config['pptpd'];
561

    
562
	if ($g['booting']) {
563
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
564
			return 0;
565

    
566
		echo "Configuring PPTP VPN service... ";
567
	} else {
568
		/* kill mpd */
569
		killbypid("{$g['varrun_path']}/mpd-vpn.pid");
570

    
571
		/* wait for process to die */
572
		sleep(2);
573

    
574
		/* remove mpd.conf, if it exists */
575
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.conf");
576
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.links");
577
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.secret");
578
	}
579

    
580
	/* make sure mpd-vpn directory exists */
581
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
582
		mkdir("{$g['varetc_path']}/mpd-vpn");
583

    
584
	switch ($pptpdcfg['mode']) {
585

    
586
		case 'server':
587

    
588
			/* write mpd.conf */
589
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.conf", "w");
590
			if (!$fd) {
591
				printf("Error: cannot open mpd.conf in vpn_pptpd_configure().\n");
592
				return 1;
593
			}
594

    
595
			$mpdconf = <<<EOD
596
pptpd:
597

    
598
EOD;
599

    
600
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
601
				$mpdconf .= "	load pt{$i}\n";
602
			}
603

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

    
606
				$clientip = long2ip(ip2long($pptpdcfg['remoteip']) + $i);
607
				$ngif = "ng" . ($i+1);
608

    
609
				$mpdconf .= <<<EOD
610

    
611
pt{$i}:
612
	new -i {$ngif} pt{$i} pt{$i}
613
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
614
	load pts
615

    
616
EOD;
617
			}
618

    
619
			$mpdconf .= <<<EOD
620

    
621
pts:
622
	set iface disable on-demand
623
	set iface enable proxy-arp
624
	set iface enable tcpmssfix
625
	set iface idle 1800
626
	set iface up-script /usr/local/sbin/vpn-linkup
627
	set iface down-script /usr/local/sbin/vpn-linkdown
628
	set bundle enable multilink
629
	set bundle enable crypt-reqd
630
	set link yes acfcomp protocomp
631
	set link no pap chap
632
	set link enable chap-msv2
633
	set link mtu 1460
634
	set link keep-alive 10 60
635
	set ipcp yes vjcomp
636
	set bundle enable compression
637
	set ccp yes mppc
638
	set ccp yes mpp-e128
639
	set ccp yes mpp-stateless
640

    
641
EOD;
642

    
643
			if (!isset($pptpdcfg['req128'])) {
644
				$mpdconf .= <<<EOD
645
	set ccp yes mpp-e40
646
	set ccp yes mpp-e56
647

    
648
EOD;
649
			}
650
			if (isset($pptpdcfg["wins"])) 
651
				$mpdconf .= "	set ipcp nbns {$pptpdcfg['wins']}\n";
652
			if (isset($config['dnsmasq']['enable'])) {
653
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
654
				if ($syscfg['dnsserver'][0])
655
					$mpdconf .= " " . $syscfg['dnsserver'][0];
656
				$mpdconf .= "\n";
657
			} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
658
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
659
			}
660

    
661
			if (isset($pptpdcfg['radius']['enable'])) {
662
				$mpdconf .= <<<EOD
663
	set radius server {$pptpdcfg['radius']['server']} "{$pptpdcfg['radius']['secret']}"
664
	set radius retries 3
665
	set radius timeout 10
666
	set bundle enable radius-auth
667
	set bundle disable radius-fallback
668

    
669
EOD;
670

    
671
				if (isset($pptpdcfg['radius']['accounting'])) {
672
					$mpdconf .= <<<EOD
673
	set bundle enable radius-acct
674

    
675
EOD;
676
				}
677
			}
678

    
679
			fwrite($fd, $mpdconf);
680
			fclose($fd);
681

    
682
			/* write mpd.links */
683
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.links", "w");
684
			if (!$fd) {
685
				printf("Error: cannot open mpd.links in vpn_pptpd_configure().\n");
686
				return 1;
687
			}
688

    
689
			$mpdlinks = "";
690

    
691
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
692
				$mpdlinks .= <<<EOD
693

    
694
pt{$i}:
695
	set link type pptp
696
	set pptp enable incoming
697
	set pptp disable originate
698
	set pptp disable windowing
699
	set pptp self 127.0.0.1
700

    
701
EOD;
702
			}
703

    
704
			fwrite($fd, $mpdlinks);
705
			fclose($fd);
706

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

    
714
			$mpdsecret = "";
715

    
716
			if (is_array($pptpdcfg['user'])) {
717
				foreach ($pptpdcfg['user'] as $user)
718
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
719
			}
720

    
721
			fwrite($fd, $mpdsecret);
722
			fclose($fd);
723
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
724

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

    
728
			break;
729

    
730
		case 'redir':
731
			break;
732
	}
733

    
734
	touch("{$g["tmp_path"]}/filter_dirty");
735

    
736
	if ($g['booting'])
737
		echo "done\n";
738

    
739
	return 0;
740
}
741

    
742
function vpn_localnet_determine($adr, &$sa, &$sn) {
743
	global $config, $g;
744

    
745
	if (isset($adr)) {
746
		if ($adr['network']) {
747
			switch ($adr['network']) {
748
				case 'lan':
749
					$sn = $config['interfaces']['lan']['subnet'];
750
					$sa = gen_subnet($config['interfaces']['lan']['ipaddr'], $sn);
751
					break;
752
			}
753
		} else if ($adr['address']) {
754
			list($sa,$sn) = explode("/", $adr['address']);
755
			if (is_null($sn))
756
				$sn = 32;
757
		}
758
	} else {
759
		$sn = $config['interfaces']['lan']['subnet'];
760
		$sa = gen_subnet($config['interfaces']['lan']['ipaddr'], $sn);
761
	}
762
}
763

    
764
function vpn_endpoint_determine($tunnel, $curwanip) {
765

    
766
	global $g, $config;
767

    
768
	if ((!$tunnel['interface']) || ($tunnel['interface'] == "wan")) {
769
		if ($curwanip)
770
			return $curwanip;
771
		else
772
			return null;
773
	} else if ($tunnel['interface'] == "lan") {
774
		return $config['interfaces']['lan']['ipaddr'];
775
	} else {
776
		$oc = $config['interfaces'][$tunnel['interface']];
777

    
778
		if (isset($oc['enable']) && $oc['if']) {
779
			return $oc['ipaddr'];
780
		}
781
	}
782

    
783
	return null;
784
}
785

    
786
function vpn_pppoe_configure() {
787
	global $config, $g;
788

    
789
	$syscfg = $config['system'];
790
	$pppoecfg = $config['pppoe'];
791

    
792
	/* create directory if it does not exist */
793
	if(!dir_exist("{$g['varetc_path']}/mpd-vpn"))
794
		mkdir("{$g['varetc_path']}/mpd-vpn");
795
	
796
	if ($g['booting']) {
797
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
798
			return 0;
799

    
800
		echo "Configuring PPPoE VPN service... ";
801
	} else {
802
		/* kill mpd */
803
		killbypid("{$g['varrun_path']}/mpd-vpn.pid");
804

    
805
		/* wait for process to die */
806
		sleep(2);
807
		
808
		vpn_pptpd_configure();
809
	}
810

    
811
	/* make sure mpd-vpn directory exists */
812
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
813
		mkdir("{$g['varetc_path']}/mpd-vpn");
814

    
815
	switch ($pppoecfg['mode']) {
816

    
817
		case 'server':
818

    
819
			$pppoe_interface = filter_translate_type_to_real_interface($pppoecfg['interface']);
820

    
821
			/* write mpd.conf */
822
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.conf", "a");
823
			if (!$fd) {
824
				printf("Error: cannot open mpd.conf in vpn_pppoe_configure().\n");
825
				return 1;
826
			}
827
			$mpdconf = "\n\n";
828
			$mpdconf .= <<<EOD
829
pppoe:
830

    
831
EOD;
832

    
833
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
834
				$mpdconf .= "	load pppoe{$i}\n";
835
			}
836

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

    
839
				$clientip = long2ip(ip2long($pppoecfg['remoteip']) + $i);
840
				$ngif = "ng" . ($i+1);
841

    
842
				$mpdconf .= <<<EOD
843

    
844
pppoe{$i}:
845
	new -i {$ngif} pppoe{$i} pppoe{$i}
846
	set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32
847
	load pppoe_standart
848

    
849
EOD;
850
			}
851

    
852
			$mpdconf .= <<<EOD
853

    
854
pppoe_standart:
855
	set link type pppoe
856
	set pppoe iface {$pppoe_interface}
857
	set pppoe service "*"
858
	set pppoe disable originate
859
	set pppoe enable incoming
860
	set bundle no multilink
861
	set bundle enable compression
862
	set bundle max-logins 1
863
	set iface idle 0
864
	set iface disable on-demand
865
	set iface disable proxy-arp
866
	set iface enable tcpmssfix
867
	set iface mtu 1500
868
	set link mtu 1500
869
	set link no pap chap
870
	set link enable chap
871
	set link keep-alive 60 180
872
	set ipcp yes vjcomp
873
	set ipcp no vjcomp
874
	set link max-redial -1
875
	set link mtu 1492
876
	set ccp yes mpp-e40
877
	set ccp yes mpp-e128
878
	set ccp yes mpp-stateless
879
	set link latency 1
880
	#set ipcp dns 10.10.1.3
881
	#set bundle accept encryption	
882

    
883
EOD;
884

    
885
			if (isset($config['dnsmasq']['enable'])) {
886
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
887
				if ($syscfg['dnsserver'][0])
888
					$mpdconf .= " " . $syscfg['dnsserver'][0];
889
				$mpdconf .= "\n";
890
			} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
891
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
892
			}
893

    
894
			if (isset($pppoecfg['radius']['enable'])) {
895
				$mpdconf .= <<<EOD
896
	set radius server {$pppoecfg['radius']['server']} "{$pppoecfg['radius']['secret']}"
897
	set radius retries 3
898
	set radius timeout 10
899
	set bundle enable radius-auth
900
	set bundle disable radius-fallback
901

    
902
EOD;
903

    
904
				if (isset($pppoecfg['radius']['accounting'])) {
905
					$mpdconf .= <<<EOD
906
	set bundle enable radius-acct
907

    
908
EOD;
909
				}
910
			}
911

    
912
			fwrite($fd, $mpdconf);
913
			fclose($fd);
914

    
915
			/* write mpd.links */
916
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.links", "a");
917
			if (!$fd) {
918
				printf("Error: cannot open mpd.links in vpn_pppoe_configure().\n");
919
				return 1;
920
			}
921

    
922
			$mpdlinks = "";
923

    
924
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
925
				$mpdlinks .= <<<EOD
926

    
927
pppoe:
928
	set link type pppoe
929
	set pppoe iface {$pppoe_interface}
930

    
931
EOD;
932
			}
933

    
934
			fwrite($fd, $mpdlinks);
935
			fclose($fd);
936

    
937
			/* write mpd.secret */
938
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.secret", "a");
939
			if (!$fd) {
940
				printf("Error: cannot open mpd.secret in vpn_pppoe_configure().\n");
941
				return 1;
942
			}
943

    
944
			$mpdsecret = "\n\n";
945

    
946
			if (is_array($pppoecfg['user'])) {
947
				foreach ($pppoecfg['user'] as $user)
948
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
949
			}
950

    
951
			fwrite($fd, $mpdsecret);
952
			fclose($fd);
953
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
954

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

    
958
			break;
959

    
960
		case 'redir':
961
			break;
962
	}
963

    
964
	touch("{$g["tmp_path"]}/filter_dirty");
965

    
966
	if ($g['booting'])
967
		echo "done\n";
968

    
969
	return 0;
970
}
971

    
972
?>
(18-18/22)