Project

General

Profile

Download (21 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	vpn.inc
5
	Copyright (C) 2004 Scott Ullrich
6
	All rights reserved.
7

    
8
	originally part of m0n0wall (http://m0n0.ch/wall)
9
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
10
	All rights reserved.
11

    
12
	Redistribution and use in source and binary forms, with or without
13
	modification, are permitted provided that the following conditions are met:
14

    
15
	1. Redistributions of source code must retain the above copyright notice,
16
	   this list of conditions and the following disclaimer.
17

    
18
	2. Redistributions in binary form must reproduce the above copyright
19
	   notice, this list of conditions and the following disclaimer in the
20
	   documentation and/or other materials provided with the distribution.
21

    
22
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
23
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
24
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
26
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31
	POSSIBILITY OF SUCH DAMAGE.
32
*/
33
	
34
/* include all configuration functions */
35
require_once("functions.inc");
36
	
37
function vpn_ipsec_failover_configure() {
38
	global $config, $g;
39

    
40
	/* is failover vpn enabled? */
41
	if(!isset($config['ipsec']['failover']['enable']))
42
		return;
43

    
44
	$sasyncd = "";
45

    
46
	if($config['ipsec']['failover']['peer'])
47
		$sasyncd .= "peer {$config['ipsec']['failover']['peer']}\n";
48

    
49
	if($config['ipsec']['failover']['interface'])
50
		$sasyncd .= "carp interface {$config['ipsec']['failover']['interface']}\n";
51

    
52
	if($config['ipsec']['failover']['sharedkey'])
53
		$sasyncd .= "sharedkey {$config['ipsec']['failover']['sharedkey']}\n";
54

    
55
	if($config['ipsec']['failover']['mode'])
56
		$sasyncd .= "mode {$config['ipsec']['failover']['mode']}\n";
57

    
58
	if($config['ipsec']['failover']['listenon'])
59
		$sasyncd .= "listen on {$config['ipsec']['failover']['listenon']}\n";
60

    
61
	if($config['ipsec']['failover']['flushmodesync'])
62
		$sasyncd .= "flushmode sync {$config['ipsec']['failover']['flushmodesync']}\n";
63

    
64
	$fd = fopen("{$g['varetc_path']}/sasyncd.conf", "w");
65
	fwrite($fd, $sasyncd);
66
	fclose($fd);
67
	chmod("{$g['varetc_path']}/sasyncd.conf", 0600);
68
	
69
	/* launch sasyncd, oh wise one */
70
	mwexec("/usr/local/sbin/sasyncd");
71
}
72
	
73
function vpn_ipsec_configure($ipchg = false) {
74
	global $config, $g;
75
	
76
	$curwanip = get_current_wan_address();
77

    
78
	/* setup for failover ipsec */
79
	if($config['ipsec']['failover']['ip'] <> "")
80
		$curwanip = $config['ipsec']['failover']['ip'];
81

    
82
	vpn_ipsec_failover_configure();
83
	
84
	$syscfg = $config['system'];
85
	$ipseccfg = $config['ipsec'];
86
	$lancfg = $config['interfaces']['lan'];
87
	$lanip = $lancfg['ipaddr'];
88
	$lansa = gen_subnet($lancfg['ipaddr'], $lancfg['subnet']);
89
	$lansn = $lancfg['subnet'];
90
	
91
	if ($g['booting']) {
92
		if (!isset($ipseccfg['enable']))
93
			return 0;
94
		
95
		echo "Configuring IPsec VPN... ";
96
	} else {
97
		/* kill racoon */
98
		killbypid("{$g['varrun_path']}/racoon.pid");
99
		
100
		/* wait for process to die */
101
		sleep(2);
102
		
103
		/* send a SIGKILL to be sure */
104
		sigkillbypid("{$g['varrun_path']}/racoon.pid", "KILL");
105
	}
106
	
107
	/* flush SPD and SAD */
108
	mwexec("/usr/sbin/setkey -FP");
109
	mwexec("/usr/sbin/setkey -F");
110
	
111
	/* prefer old SAs only for 30 seconds, then use the new one */
112
	if (!isset($config['ipsec']['preferoldsa']))
113
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
114
	else
115
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=1");
116
	
117
	if (isset($ipseccfg['enable'])) {
118
		
119
		if (!$curwanip) {
120
			/* IP address not configured yet, exit */
121
			if ($g['booting'])
122
				echo "done\n";
123
			return 0;
124
		}
125
		
126
		if ((is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) ||
127
				isset($ipseccfg['mobileclients']['enable'])) {
128
		
129
			if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) {
130
			
131
				/* generate spd.conf */
132
				$fd = fopen("{$g['varetc_path']}/spd.conf", "w");
133
				if (!$fd) {
134
					printf("Error: cannot open spd.conf in vpn_ipsec_configure().\n");
135
					return 1;
136
				}
137
					
138
				$spdconf = "";
139
				
140
				$spdconf .= "spdadd {$lansa}/{$lansn} {$lanip}/32 any -P in none;\n";
141
				$spdconf .= "spdadd {$lanip}/32 {$lansa}/{$lansn} any -P out none;\n";
142
				
143
				foreach ($ipseccfg['tunnel'] as $tunnel) {
144
				
145
					if (isset($tunnel['disabled']))
146
						continue;
147
				
148
					$ep = vpn_endpoint_determine($tunnel, $curwanip);
149
					if (!$ep)
150
						continue;
151
					
152
					vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn);
153
					
154
					if(isset($tunnel['creategif'])) {
155
						$number_of_gifs = find_last_gif_device();
156
						$number_of_gifs++;
157
						$curwanip = get_current_wan_address();
158
						if($config['ipsec']['failover']['ip'] <> "")
159
							$curwanip = $config['ipsec']['failover']['ip'];
160
						mwexec("/sbin/ifconfig gif" . $number_of_gifs . " tunnel" . $curwanip . " " . $tunnel['remote-gateway']);
161
						mwexec("/sbin/ifconfig gif" . $number_of_gifs . " {$lansa}/{$lansn} {$lanip}/32");
162
					}
163
					
164
					$spdconf .= "spdadd {$sa}/{$sn} " . 
165
						"{$tunnel['remote-subnet']} any -P out ipsec " . 
166
						"{$tunnel['p2']['protocol']}/tunnel/{$ep}-" .
167
						"{$tunnel['remote-gateway']}/unique;\n";
168
						
169
					$spdconf .= "spdadd {$tunnel['remote-subnet']} " . 
170
						"{$sa}/{$sn} any -P in ipsec " . 
171
						"{$tunnel['p2']['protocol']}/tunnel/{$tunnel['remote-gateway']}-" .
172
						"{$ep}/unique;\n";
173
				}
174
				
175
				fwrite($fd, $spdconf);
176
				fclose($fd);
177
			
178
				/* load SPD */
179
				mwexec("/usr/sbin/setkey -c < {$g['varetc_path']}/spd.conf");
180
			}
181
			
182
			/* generate racoon.conf */
183
			$fd = fopen("{$g['varetc_path']}/racoon.conf", "w");
184
			if (!$fd) {
185
				printf("Error: cannot open racoon.conf in vpn_ipsec_configure().\n");
186
				return 1;
187
			}
188

    
189
			if($config['ipsec']['failover']['ip'] <> "") {
190

    
191
				$interface_ip = $config['ipsec']['failover']['ip'];
192
				$racoonconf .= <<<EOD
193
listen {
194
	isakmp {$interface_ip} [500];
195
}
196

    
197
EOD;
198
			}
199
				
200
			$racoonconf .= "path pre_shared_key \"{$g['varetc_path']}/psk.txt\";\n\n";
201
			$racoonconf .= "path certificate  \"{$g['varetc_path']}\";\n\n";
202
			
203
			/* generate CA certificates files */
204
			$cacertnum = 0;
205
			if (is_array($ipseccfg['cacert']) && count($ipseccfg['cacert']))
206
				foreach ($ipseccfg['cacert'] as $cacert) {
207
					++$cacertnum;
208
					if (isset($cacert['cert'])) {
209
						$cert = base64_decode($cacert['cert']);
210
						$x509cert = openssl_x509_parse(openssl_x509_read($cert));
211
						if(is_array($x509cert) && isset($x509cert['hash'])) {
212
							$fd1 = fopen("{$g['varetc_path']}/{$x509cert['hash']}.0", "w");
213
							if (!$fd1) {
214
								printf("Error: cannot open {$x509cert['hash']}.0 in vpn.\n");
215
								return 1;
216
							}
217
							chmod("{$g['varetc_path']}/{$x509cert['hash']}.0", 0600);
218
							fwrite($fd1, $cert);
219
							fclose($fd1);
220
						}
221
					}
222
				}
223
						
224
			$tunnelnumber = 0;
225
			if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel']))
226
				foreach ($ipseccfg['tunnel'] as $tunnel) {
227
				
228
				++$tunnelnumber;
229
			
230
				if (isset($tunnel['disabled']))
231
					continue;
232
				
233
				$ep = vpn_endpoint_determine($tunnel, $curwanip);
234
				if (!$ep)
235
					continue;
236
			
237
				vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn);
238
			
239
				if (isset($tunnel['p1']['myident']['myaddress'])) {
240
					$myidentt = "address";
241
					$myident = $ep;
242
				} else if (isset($tunnel['p1']['myident']['address'])) {
243
					$myidentt = "address";
244
					$myident = $tunnel['p1']['myident']['address'];
245
				} else if (isset($tunnel['p1']['myident']['fqdn'])) {
246
					$myidentt = "fqdn";
247
					$myident = $tunnel['p1']['myident']['fqdn'];
248
				} else if (isset($tunnel['p1']['myident']['ufqdn'])) {
249
					$myidentt = "user_fqdn";
250
					$myident = $tunnel['p1']['myident']['ufqdn'];
251
 				}
252
				
253
				if (isset($tunnel['p1']['authentication_method'])) {
254
					$authmethod = $tunnel['p1']['authentication_method'];
255
				} else {$authmethod = 'pre_shared_key';}
256
				
257
				$certline = '';	
258
				
259
				if ($authmethod == 'rsasig') {
260
					if ($tunnel['p1']['cert'] && $tunnel['p1']['private-key']) {
261
						$cert = base64_decode($tunnel['p1']['cert']);
262
						$private_key = base64_decode($tunnel['p1']['private-key']);
263
					} else {
264
						/* null certificate/key */
265
						$cert = '';
266
						$private_key = '';
267
					}
268
					
269
					if ($tunnel['p1']['peercert']) 
270
						$peercert = base64_decode($tunnel['p1']['peercert']);
271
					else 
272
						$peercert = '';
273
					
274
					$fd1 = fopen("{$g['varetc_path']}/server{$tunnelnumber}-signed.pem", "w");
275
					if (!$fd1) {
276
						printf("Error: cannot open server{$tunnelnumber}-signed.pem in vpn.\n");
277
						return 1;
278
					}
279
					chmod("{$g['varetc_path']}/server{$tunnelnumber}-signed.pem", 0600);
280
					fwrite($fd1, $cert);
281
					fclose($fd1);
282
					
283
					$fd1 = fopen("{$g['varetc_path']}/server{$tunnelnumber}-key.pem", "w");
284
					if (!$fd1) {
285
						printf("Error: cannot open server{$tunnelnumber}-key.pem in vpn.\n");
286
						return 1;
287
					}
288
					chmod("{$g['varetc_path']}/server{$tunnelnumber}-key.pem", 0600);
289
					fwrite($fd1, $private_key);
290
					fclose($fd1);
291

    
292
					$certline = "certificate_type x509 \"server{$tunnelnumber}-signed.pem\" \"server{$tunnelnumber}-key.pem\";";
293
					
294
					if ($peercert!=''){
295
						$fd1 = fopen("{$g['varetc_path']}/peer{$tunnelnumber}-signed.pem", "w");
296
						if (!$fd1) {
297
							printf("Error: cannot open server{$tunnelnumber}-signed.pem in vpn.\n");
298
							return 1;
299
						}
300
						chmod("{$g['varetc_path']}/peer{$tunnelnumber}-signed.pem", 0600);
301
						fwrite($fd1, $peercert);
302
						fclose($fd1);		
303
						$certline .= <<<EOD
304
						
305
	peers_certfile "peer{$tunnelnumber}-signed.pem";
306
EOD;
307
					} 					
308
				} 
309
				$racoonconf .= <<<EOD
310
remote {$tunnel['remote-gateway']} \{
311
	exchange_mode {$tunnel['p1']['mode']};
312
	my_identifier {$myidentt} "{$myident}";
313
	{$certline}
314
	peers_identifier address {$tunnel['remote-gateway']};
315
	initial_contact on;
316
	support_proxy on;
317
	proposal_check obey;
318

    
319
	proposal \{
320
		encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
321
		hash_algorithm {$tunnel['p1']['hash-algorithm']};
322
		authentication_method {$authmethod};
323
		dh_group {$tunnel['p1']['dhgroup']};
324

    
325
EOD;
326
				if ($tunnel['p1']['lifetime'])
327
					$racoonconf .= "		lifetime time {$tunnel['p1']['lifetime']} secs;\n";
328
				
329
				$racoonconf .= "	}\n";
330
				
331
				if ($tunnel['p1']['lifetime'])
332
					$racoonconf .= "	lifetime time {$tunnel['p1']['lifetime']} secs;\n";
333
					
334
				$racoonconf .= "}\n\n";
335
				
336
				$p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']);
337
				$p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']);
338
				
339
				$racoonconf .= <<<EOD
340
sainfo address {$sa}/{$sn} any address {$tunnel['remote-subnet']} any \{
341
	encryption_algorithm {$p2ealgos};
342
	authentication_algorithm {$p2halgos};
343
	compression_algorithm deflate;
344

    
345
EOD;
346

    
347
				if ($tunnel['p2']['pfsgroup'])
348
					$racoonconf .= "	pfs_group {$tunnel['p2']['pfsgroup']};\n";
349
					
350
				if ($tunnel['p2']['lifetime'])
351
					$racoonconf .= "	lifetime time {$tunnel['p2']['lifetime']} secs;\n";
352
					
353
				$racoonconf .= "}\n\n";
354
			}
355
			
356
			/* mobile clients? */
357
			if (isset($ipseccfg['mobileclients']['enable'])) {
358
				
359
				$tunnel = $ipseccfg['mobileclients'];
360
				
361
				if (isset($tunnel['p1']['myident']['myaddress'])) {
362
					$myidentt = "address";
363
					$myident = $curwanip;
364
				} else if (isset($tunnel['p1']['myident']['address'])) {
365
					$myidentt = "address";
366
					$myident = $tunnel['p1']['myident']['address'];
367
				} else if (isset($tunnel['p1']['myident']['fqdn'])) {
368
					$myidentt = "fqdn";
369
					$myident = $tunnel['p1']['myident']['fqdn'];
370
				} else if (isset($tunnel['p1']['myident']['ufqdn'])) {
371
					$myidentt = "user_fqdn";
372
					$myident = $tunnel['p1']['myident']['ufqdn'];
373
 				}
374
				
375
				if (isset($tunnel['p1']['authentication_method'])) {
376
					$authmethod = $tunnel['p1']['authentication_method'];
377
				} else {$authmethod = 'pre_shared_key';}
378
				
379
				$certline = '';					
380
				if ($authmethod == 'rsasig') {
381
					if ($tunnel['p1']['cert'] && $tunnel['p1']['private-key']) {
382
						$cert = base64_decode($tunnel['p1']['cert']);
383
						$private_key = base64_decode($tunnel['p1']['private-key']);
384
					} else {
385
						/* null certificate/key */
386
						$cert = '';
387
						$private_key = '';
388
					}
389
					
390
					if ($tunnel['p1']['peercert']) 
391
						$peercert = base64_decode($tunnel['p1']['peercert']);
392
					else 
393
						$peercert = '';
394
					
395
					$fd1 = fopen("{$g['varetc_path']}/server-mobile{$tunnelnumber}-signed.pem", "w");
396
					if (!$fd1) {
397
						printf("Error: cannot open server-mobile{$tunnelnumber}-signed.pem in vpn.\n");
398
						return 1;
399
					}
400
					chmod("{$g['varetc_path']}/server-mobile{$tunnelnumber}-signed.pem", 0600);
401
					fwrite($fd1, $cert);
402
					fclose($fd1);
403
					
404
					$fd1 = fopen("{$g['varetc_path']}/server-mobile{$tunnelnumber}-key.pem", "w");
405
					if (!$fd1) {
406
						printf("Error: cannot open server-mobile{$tunnelnumber}-key.pem in vpn.\n");
407
						return 1;
408
					}
409
					chmod("{$g['varetc_path']}/server-mobile{$tunnelnumber}-key.pem", 0600);
410
					fwrite($fd1, $private_key);
411
					fclose($fd1);
412

    
413
					$certline = "certificate_type x509 \"server-mobile{$tunnelnumber}-signed.pem\" \"server-mobile{$tunnelnumber}-key.pem\";";
414
				}
415
				$racoonconf .= <<<EOD
416
remote anonymous \{
417
	exchange_mode {$tunnel['p1']['mode']};
418
	my_identifier {$myidentt} "{$myident}";
419
	{$certline}
420
	initial_contact on;
421
	passive on;
422
	generate_policy on;
423
	support_proxy on;
424
	proposal_check obey;
425

    
426
	proposal \{
427
		encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
428
		hash_algorithm {$tunnel['p1']['hash-algorithm']};
429
		authentication_method {$authmethod};
430
		dh_group {$tunnel['p1']['dhgroup']};
431

    
432
EOD;
433
				if ($tunnel['p1']['lifetime'])
434
					$racoonconf .= "		lifetime time {$tunnel['p1']['lifetime']} secs;\n";
435
				
436
				$racoonconf .= "	}\n";
437
				
438
				if ($tunnel['p1']['lifetime'])
439
					$racoonconf .= "	lifetime time {$tunnel['p1']['lifetime']} secs;\n";
440
					
441
				$racoonconf .= "}\n\n";
442
				
443
				$p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']);
444
				$p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']);
445
				
446
				$racoonconf .= <<<EOD
447
sainfo anonymous \{
448
	encryption_algorithm {$p2ealgos};
449
	authentication_algorithm {$p2halgos};
450
	compression_algorithm deflate;
451

    
452
EOD;
453

    
454
				if ($tunnel['p2']['pfsgroup'])
455
					$racoonconf .= "	pfs_group {$tunnel['p2']['pfsgroup']};\n";
456
					
457
				if ($tunnel['p2']['lifetime'])
458
					$racoonconf .= "	lifetime time {$tunnel['p2']['lifetime']} secs;\n";
459
					
460
				$racoonconf .= "}\n\n";
461
			}
462
			
463
			fwrite($fd, $racoonconf);
464
			fclose($fd);
465
			
466
			/* generate psk.txt */
467
			$fd = fopen("{$g['varetc_path']}/psk.txt", "w");
468
			if (!$fd) {
469
				printf("Error: cannot open psk.txt in vpn_ipsec_configure().\n");
470
				return 1;
471
			}
472
			
473
			$pskconf = "";
474
			
475
			if (is_array($ipseccfg['tunnel'])) {
476
				foreach ($ipseccfg['tunnel'] as $tunnel) {
477
					if (isset($tunnel['disabled']))
478
						continue;
479
					$pskconf .= "{$tunnel['remote-gateway']}	 {$tunnel['p1']['pre-shared-key']}\n";
480
				}
481
			}
482
			
483
			/* add PSKs for mobile clients */
484
			if (is_array($ipseccfg['mobilekey'])) {
485
				foreach ($ipseccfg['mobilekey'] as $key) {
486
					$pskconf .= "{$key['ident']}	{$key['pre-shared-key']}\n";
487
				}
488
			}
489
			
490
			fwrite($fd, $pskconf);
491
			fclose($fd);
492
			chmod("{$g['varetc_path']}/psk.txt", 0600);
493
			
494
			/* start racoon */
495
			echo " racoon ";
496
			mwexec("/usr/local/sbin/racoon -d -f {$g['varetc_path']}/racoon.conf");
497
			
498
			if (is_array($ipseccfg['tunnel'])) {
499
				foreach ($ipseccfg['tunnel'] as $tunnel) {
500
					if (isset($tunnel['auto'])) {
501
						$remotehost = substr($tunnel['remote-subnet'],0,strpos($tunnel['remote-subnet'],"/"));
502
						$srchost = vpn_endpoint_determine($tunnel, $curwanip);
503
						if ($srchost)
504
							mwexec_bg("/sbin/ping -c 5 -S {$srchost} {$remotehost}");
505
					}
506
				}
507
			}
508
		}
509
	}
510
	
511
	if (!$g['booting']) {
512
		/* set the reload filter dity flag */
513
		touch("{$g['tmp_path']}/filter_boot_dirty");
514
	}
515
	
516
	if ($g['booting'])
517
		echo "done\n";
518
	
519
	return 0;
520
}
521

    
522
function vpn_pptpd_configure() {
523
	global $config, $g;
524
	
525
	$syscfg = $config['system'];
526
	$pptpdcfg = $config['pptpd'];
527
	
528
	if ($g['booting']) {
529
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
530
			return 0;
531
		
532
		echo "Configuring PPTP VPN service... ";
533
	} else {	
534
		/* kill mpd */
535
		killbypid("{$g['varrun_path']}/mpd-vpn.pid");
536
		
537
		/* wait for process to die */
538
		sleep(2);
539
		
540
		/* remove mpd.conf, if it exists */
541
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.conf");
542
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.links");
543
		unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.secret");
544
	}
545
		
546
	/* make sure mpd-vpn directory exists */
547
	if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
548
		mkdir("{$g['varetc_path']}/mpd-vpn");
549
		
550
	switch ($pptpdcfg['mode']) {
551
		
552
		case 'server':
553
			
554
			/* write mpd.conf */
555
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.conf", "w");
556
			if (!$fd) {
557
				printf("Error: cannot open mpd.conf in vpn_pptpd_configure().\n");
558
				return 1;
559
			}
560
				
561
			$mpdconf = <<<EOD
562
pptpd:
563

    
564
EOD;
565

    
566
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
567
				$mpdconf .= "	load pt{$i}\n";
568
			}
569
			
570
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
571
			
572
				$clientip = long2ip(ip2long($pptpdcfg['remoteip']) + $i);
573
				$ngif = "ng" . ($i+1);
574
			
575
				$mpdconf .= <<<EOD
576

    
577
pt{$i}:
578
	new -i {$ngif} pt{$i} pt{$i}
579
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
580
	load pts
581

    
582
EOD;
583
			}
584
			
585
			$mpdconf .= <<<EOD
586

    
587
pts:
588
	set iface disable on-demand
589
	set iface enable proxy-arp
590
	set iface enable tcpmssfix
591
	set iface idle 1800
592
	set iface up-script /usr/local/sbin/vpn-linkup
593
	set iface down-script /usr/local/sbin/vpn-linkdown
594
	set bundle enable multilink
595
	set bundle enable crypt-reqd
596
	set link yes acfcomp protocomp
597
	set link no pap chap
598
	set link enable chap-msv2
599
	set link mtu 1460
600
	set link keep-alive 10 60
601
	set ipcp yes vjcomp
602
	set bundle enable compression
603
	set ccp yes mppc
604
	set ccp yes mpp-e128
605
	set ccp yes mpp-stateless
606

    
607
EOD;
608
			
609
			if (!isset($pptpdcfg['req128'])) {
610
				$mpdconf .= <<<EOD
611
	set ccp yes mpp-e40
612
	set ccp yes mpp-e56
613

    
614
EOD;
615
			}
616
			
617
			if (is_array($pptpdcfg['dnsserver']) && ($pptpdcfg['dnsserver'][0])) {
618
				$mpdconf .= "	set ipcp dns " . join(" ", $pptpdcfg['dnsserver']) . "\n";
619
			} else if (isset($config['dnsmasq']['enable'])) {
620
				$mpdconf .= "	set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
621
				if ($syscfg['dnsserver'][0])
622
					$mpdconf .= " " . $syscfg['dnsserver'][0];
623
				$mpdconf .= "\n";
624
			} else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
625
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
626
			}
627
			
628
			if (isset($pptpdcfg['radius']['enable'])) {
629
				$mpdconf .= <<<EOD
630
	set radius server {$pptpdcfg['radius']['server']} "{$pptpdcfg['radius']['secret']}"
631
	set radius retries 3
632
	set radius timeout 10
633
	set bundle enable radius-auth
634
	set bundle disable radius-fallback
635

    
636
EOD;
637

    
638
				if (isset($pptpdcfg['radius']['accounting'])) {
639
					$mpdconf .= <<<EOD
640
	set bundle enable radius-acct
641

    
642
EOD;
643
				}
644
			}
645

    
646
			fwrite($fd, $mpdconf);
647
			fclose($fd);
648
			
649
			/* write mpd.links */
650
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.links", "w");
651
			if (!$fd) {
652
				printf("Error: cannot open mpd.links in vpn_pptpd_configure().\n");
653
				return 1;
654
			}
655
			
656
			$mpdlinks = "";
657
			
658
			for ($i = 0; $i < $g['n_pptp_units']; $i++) {
659
				$mpdlinks .= <<<EOD
660

    
661
pt{$i}:
662
	set link type pptp
663
	set pptp enable incoming
664
	set pptp disable originate
665
	set pptp disable windowing
666
	set pptp self 127.0.0.1
667

    
668
EOD;
669
			}
670

    
671
			fwrite($fd, $mpdlinks);
672
			fclose($fd);
673
			
674
			/* write mpd.secret */
675
			$fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.secret", "w");
676
			if (!$fd) {
677
				printf("Error: cannot open mpd.secret in vpn_pptpd_configure().\n");
678
				return 1;
679
			}
680
			
681
			$mpdsecret = "";
682
			
683
			if (is_array($pptpdcfg['user'])) {
684
				foreach ($pptpdcfg['user'] as $user)
685
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
686
			}
687

    
688
			fwrite($fd, $mpdsecret);
689
			fclose($fd);
690
			chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
691
			
692
			/* fire up mpd */
693
			mwexec("/usr/local/sbin/mpd -b -d {$g['varetc_path']}/mpd-vpn -p {$g['varrun_path']}/mpd-vpn.pid pptpd");
694
			
695
			break;
696
			
697
		case 'redir':
698
			break;
699
	}
700
	
701
	if (!$g['booting']) {
702
		/* reload the filter */
703
		filter_configure();
704
	}
705
	
706
	if ($g['booting'])
707
		echo "done\n";
708
	
709
	return 0;
710
}
711

    
712
function vpn_localnet_determine($adr, &$sa, &$sn) {
713
	global $config, $g;
714

    
715
	if (isset($adr)) {
716
		if ($adr['network']) {			
717
			switch ($adr['network']) {
718
				case 'lan':
719
					$sn = $config['interfaces']['lan']['subnet'];
720
					$sa = gen_subnet($config['interfaces']['lan']['ipaddr'], $sn);
721
					break;
722
			}
723
		} else if ($adr['address']) {
724
			list($sa,$sn) = explode("/", $adr['address']);
725
			if (is_null($sn))
726
				$sn = 32;
727
		}
728
	} else {
729
		$sn = $config['interfaces']['lan']['subnet'];
730
		$sa = gen_subnet($config['interfaces']['lan']['ipaddr'], $sn);
731
	}
732
}
733

    
734
function vpn_endpoint_determine($tunnel, $curwanip) {
735
	
736
	global $g, $config;
737
	
738
	if ((!$tunnel['interface']) || ($tunnel['interface'] == "wan")) {
739
		if ($curwanip)
740
			return $curwanip;
741
		else
742
			return null;
743
	} else if ($tunnel['interface'] == "lan") {
744
		return $config['interfaces']['lan']['ipaddr'];
745
	} else {
746
		$oc = $config['interfaces'][$tunnel['interface']];
747
		
748
		if (isset($oc['enable']) && $oc['if']) {
749
			return $oc['ipaddr'];
750
		}
751
	}
752
	
753
	return null;
754
}
755
	
756
?>
(17-17/21)