Project

General

Profile

Download (25.9 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
	if ($g['booting']) {
793
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
794
			return 0;
795

    
796
		echo "Configuring PPPoE VPN service... ";
797
	} else {
798
		/* kill mpd */
799
		killbypid("{$g['varrun_path']}/mpd-vpn.pid");
800

    
801
		/* wait for process to die */
802
		sleep(2);
803
		
804
		vpn_pptpd_configure();
805
	}
806

    
807
	/* make sure mpd-vpn directory exists */
808
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
809
		mkdir("{$g['varetc_path']}/mpd-vpn");
810

    
811
	switch ($pppoecfg['mode']) {
812

    
813
		case 'server':
814

    
815
			$pppoe_interface = filter_translate_type_to_real_interface($pppoecfg['interface']);
816

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

    
827
EOD;
828

    
829
			for ($i = 0; $i < $g['n_pppoe_units']; $i++) {
830
				$mpdconf .= "	load pppoe{$i}\n";
831
			}
832

    
833
			for ($i = 0; $i < $g['n_pppoe_units']; $i++) {
834

    
835
				$clientip = long2ip(ip2long($pppoecfg['remoteip']) + $i);
836
				$ngif = "ng" . ($i+1);
837

    
838
				$mpdconf .= <<<EOD
839

    
840
pppoe{$i}:
841
	new -i {$ngif} pppoe{$i} pppoe{$i}
842
	set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32
843
	load pppoe_standart
844

    
845
EOD;
846
			}
847

    
848
			$mpdconf .= <<<EOD
849

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

    
879
EOD;
880

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

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

    
898
EOD;
899

    
900
				if (isset($pppoecfg['radius']['accounting'])) {
901
					$mpdconf .= <<<EOD
902
	set bundle enable radius-acct
903

    
904
EOD;
905
				}
906
			}
907

    
908
			fwrite($fd, $mpdconf);
909
			fclose($fd);
910

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

    
918
			$mpdlinks = "";
919

    
920
			for ($i = 0; $i < $g['n_pppoe_units']; $i++) {
921
				$mpdlinks .= <<<EOD
922

    
923
pppoe:
924
	set link type pppoe
925
	#set pppoe iface lnc0
926

    
927
EOD;
928
			}
929

    
930
			fwrite($fd, $mpdlinks);
931
			fclose($fd);
932

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

    
940
			$mpdsecret = "\n\n";
941

    
942
			if (is_array($pppoecfg['user'])) {
943
				foreach ($pppoecfg['user'] as $user)
944
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
945
			}
946

    
947
			fwrite($fd, $mpdsecret);
948
			fclose($fd);
949
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
950

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

    
954
			break;
955

    
956
		case 'redir':
957
			break;
958
	}
959

    
960
	touch("{$g["tmp_path"]}/filter_dirty");
961

    
962
	if ($g['booting'])
963
		echo "done\n";
964

    
965
	return 0;
966
}
967

    
968
?>
(18-18/22)