Project

General

Profile

Download (21.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
	/* launch sasyncd, oh wise one */
66
	mwexec_bg("/usr/local/sbin/sasyncd -d -v -v -v");
67
}
68

    
69
function find_last_gif_device() {
70
        $last_gif_found = -1;
71
        if (!($fp = popen("/sbin/ifconfig -l", "r"))) return -1;
72
        $ifconfig_data = fread($fp, 4096);
73
        pclose($fp);
74
        $ifconfig_array = split(" ", $ifconfig_data);
75
        foreach ($ifconfig_array as $ifconfig) {
76
                ereg("gif(.)", $ifconfig, $regs);
77
                if($regs[0]) {
78
                        if($regs[0] > $last_gif_found)
79
                                $last_gif_found = $regs[1];
80
                }
81
        }
82
        return $last_gif_found;
83
}
84

    
85
function vpn_ipsec_configure($ipchg = false) {
86
	global $config, $g;
87

    
88
	if(isset($config['ipsec']['preferredoldsa'])) {
89
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
90
	} else {
91
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
92
	}
93

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

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

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

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

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

    
122
		/* wait for process to die */
123
		sleep(2);
124

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

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

    
133
	if (isset($ipseccfg['enable'])) {
134

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

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

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

    
148
			if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) {
149

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

    
157
				$spdconf = "";
158

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

    
162
				foreach ($ipseccfg['tunnel'] as $tunnel) {
163

    
164
					if (isset($tunnel['disabled']))
165
						continue;
166

    
167
					$ep = vpn_endpoint_determine($tunnel, $curwanip);
168
					if (!$ep)
169
						continue;
170

    
171
					vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn);
172

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

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

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

    
197
				fwrite($fd, $spdconf);
198
				fclose($fd);
199

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

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

    
211
			$racoonconf = "";
212

    
213

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

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

    
225
EOD;
226
			}
227

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

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

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

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

    
376
EOD;
377

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

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

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

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

    
483
EOD;
484

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

    
541
	vpn_ipsec_failover_configure();
542

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

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

    
551
	return 0;
552
}
553

    
554
function vpn_pptpd_configure() {
555
	global $config, $g;
556

    
557
	$syscfg = $config['system'];
558
	$pptpdcfg = $config['pptpd'];
559

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

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

    
569
		/* wait for process to die */
570
		sleep(2);
571

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

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

    
582
	switch ($pptpdcfg['mode']) {
583

    
584
		case 'server':
585

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

    
593
			$mpdconf = <<<EOD
594
pptpd:
595

    
596
EOD;
597

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

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

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

    
607
				$mpdconf .= <<<EOD
608

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

    
614
EOD;
615
			}
616

    
617
			$mpdconf .= <<<EOD
618

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

    
639
EOD;
640

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

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

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

    
667
EOD;
668

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

    
673
EOD;
674
				}
675
			}
676

    
677
			fwrite($fd, $mpdconf);
678
			fclose($fd);
679

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

    
687
			$mpdlinks = "";
688

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

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

    
699
EOD;
700
			}
701

    
702
			fwrite($fd, $mpdlinks);
703
			fclose($fd);
704

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

    
712
			$mpdsecret = "";
713

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

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

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

    
726
			break;
727

    
728
		case 'redir':
729
			break;
730
	}
731

    
732
	touch("{$g["tmp_path"]}/filter_dirty");
733

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

    
737
	return 0;
738
}
739

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

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

    
762
function vpn_endpoint_determine($tunnel, $curwanip) {
763

    
764
	global $g, $config;
765

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

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

    
781
	return null;
782
}
783

    
784
?>
(18-18/22)