Project

General

Profile

Download (43.8 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2

    
3
/*
4
	vpn.inc
5
	Copyright (C) 2004 Scott Ullrich
6
	Copyright (C) 2008 Shrew Soft Inc
7
	Copyright (C) 2008 Ermal Lu�i
8
	All rights reserved.
9

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

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

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

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

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

    
36
/*
37
	pfSense_BUILDER_BINARIES:	/usr/bin/killall	/usr/local/sbin/sasyncd	/sbin/ifconfig	/sbin/sysctl
38
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/setkey	/sbin/route	/bin/mkdir
39
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/ipsec	/usr/local/libexec/ipsec/charon /usr/local/libexec/ipsec/starter
40
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/filterdns	/usr/local/sbin/mpd4
41
	pfSense_MODULE:	vpn
42
*/
43

    
44
require_once("ipsec.inc");
45

    
46
function vpn_ipsec_configure_loglevels()
47
{
48
	global $config;
49

    
50
	foreach ($ipsec_loglevels as $lkey => $ldescr) {
51
		if (empty($config['ipsec']["ipsec_{$lkey}"]))
52
			mwexec("/usr/local/sbin/ipsec stroke loglevel {$lkey} -1", false);
53
		else if (is_numeric($config['ipsec']["ipsec_{$lkey}"]) &&
54
		    intval($config['ipsec']["ipsec_{$lkey}"]) >= 1 && intval($config['ipsec']["ipsec_{$lkey}"]) <= 4)
55
			mwexec("/usr/local/sbin/ipsec stroke loglevel {$lkey} " . (intval($config['ipsec']["ipsec_{$lkey}"]) - 1) , false);
56
	}
57
}
58

    
59
/* include all configuration functions */
60
function vpn_ipsec_convert_to_modp($index)
61
{
62

    
63
	$convertion = "";
64
	switch ($index) {
65
	case '1':
66
		$convertion = "modp768";
67
		break;
68
	case '2':
69
		$convertion = "modp1024";
70
		break;
71
	case '5':
72
		$convertion = "modp1536";
73
		break;
74
	case '14':
75
		$convertion = "modp2048";
76
		break;
77
	case '15':
78
		$convertion = "modp3072";
79
		break;
80
	case '16':      
81
		$convertion = "modp4096";
82
		break;
83
	case '17':
84
		$convertion = "modp6144";
85
		break;
86
	case '18':
87
		$convertion = "modp8192";
88
		break;
89
	}
90

    
91
	return $convertion;
92
}
93

    
94
function vpn_ipsec_configure($ipchg = false)
95
{
96
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos;
97

    
98
	if ($g['platform'] == 'jail')
99
		return;
100

    
101
	/* get the automatic ping_hosts.sh ready */
102
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
103
	touch("{$g['vardb_path']}/ipsecpinghosts");
104

    
105
	vpn_ipsec_configure_preferoldsa();
106

    
107
	$syscfg = $config['system'];
108
	$ipseccfg = $config['ipsec'];
109
	$a_phase1 = $config['ipsec']['phase1'];
110
	$a_phase2 = $config['ipsec']['phase2'];
111
	$a_client = $config['ipsec']['client'];
112

    
113
	if (!isset($ipseccfg['enable'])) {
114
		/* try to stop charon */
115
		mwexec("/usr/local/sbin/ipsec stop");
116
		/* Stop dynamic monitoring */
117
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
118

    
119
		/* wait for process to die */
120
		sleep(2);
121

    
122
		/* flush SPD and SAD 
123
		mwexec("/usr/local/sbin/setkey -F");
124
		mwexec("/usr/local/sbin/setkey -FP");
125
		*/
126

    
127
		/* disallow IPSEC, it is off */
128
		mwexec("/sbin/ifconfig enc0 down");
129
		exec("/sbin/sysctl net.inet.ip.ipsec_in_use=0");
130

    
131
		return 0;
132
	} else {
133
		mwexec("/sbin/ifconfig enc0 up");
134
		mwexec("/sbin/sysctl net.inet.ip.ipsec_in_use=1");
135
		/* needed for config files */
136
		if (!is_dir("{$g['varetc_path']}/ipsec"))
137
			mkdir("{$g['varetc_path']}/ipsec");
138
		if (!is_dir("{$g['varetc_path']}/ipsec/cacerts"))
139
			mkdir("{$g['varetc_path']}/ipsec/cacerts");
140
		if (!is_dir("{$g['varetc_path']}/ipsec/private"))
141
			mkdir("{$g['varetc_path']}/ipsec/private");
142
		if (!is_dir("{$g['varetc_path']}/ipsec/crls"))
143
			mkdir("{$g['varetc_path']}/ipsec/crls");
144
		if (!is_dir("{$g['varetc_path']}/ipsec/certs"))
145
			mkdir("{$g['varetc_path']}/ipsec/certs");
146
		if (!is_dir("{$g['varetc_path']}/ipsec/aacerts"))
147
			mkdir("{$g['varetc_path']}/ipsec/aacerts");
148
		if (!is_dir("{$g['varetc_path']}/ipsec/acerts"))
149
			mkdir("{$g['varetc_path']}/ipsec/acerts");
150
		if (!is_dir("{$g['varetc_path']}/ipsec/reqs"))
151
			mkdir("{$g['varetc_path']}/ipsec/reqs");
152
		
153

    
154
		if ($g['booting'])
155
			echo gettext("Configuring IPsec VPN... ");
156

    
157
		/* fastforwarding is not compatible with ipsec tunnels */
158
		mwexec("/sbin/sysctl net.inet.ip.fastforwarding=0");
159

    
160
		/* resolve all local, peer addresses and setup pings */
161
		$ipmap = array();
162
		$rgmap = array();
163
		$filterdns_list = array();
164
		$listeniflist = array();
165
		unset($iflist);
166
		if (is_array($a_phase1) && count($a_phase1)) {
167

    
168
			$ipsecpinghosts = "";
169
			/* step through each phase1 entry */
170
			foreach ($a_phase1 as $ph1ent) {
171
				if (isset($ph1ent['disabled']))
172
					continue;
173

    
174
				$listeniflist = get_real_interface($a_phase1['interface']);
175

    
176
				$ep = ipsec_get_phase1_src($ph1ent);
177
				if (!is_ipaddr($ep))
178
					continue;
179

    
180
				if(!in_array($ep,$ipmap))
181
					$ipmap[] = $ep;
182

    
183
				/* see if this tunnel has a hostname for the remote-gateway. If so,
184
				   try to resolve it now and add it to the list for filterdns */
185

    
186
				if (isset ($ph1ent['mobile']))
187
					continue;
188

    
189
				$rg = $ph1ent['remote-gateway'];
190

    
191
				if (!is_ipaddr($rg)) {
192
					$filterdns_list[] = "{$rg}";
193
					add_hostname_to_watch($rg);
194
					if(! $g['booting'])
195
						$rg = resolve_retry($rg);
196
					if (!is_ipaddr($rg))
197
						continue;
198
				}
199
				if(array_search($rg, $rgmap)) {
200
					log_error("The remote gateway {$rg} already exists on another phase 1 entry");
201
					continue;
202
				}
203
				$rgmap[$ph1ent['remote-gateway']] = $rg;
204

    
205
				if (is_array($a_phase2)) {
206
					/* step through each phase2 entry */
207
					foreach ($a_phase2 as $ph2ent) {
208
						$ikeid = $ph2ent['ikeid'];
209

    
210
						if (isset($ph2ent['disabled']))
211
							continue;
212

    
213
						if ($ikeid != $ph1ent['ikeid'])
214
							continue;
215

    
216
						/* add an ipsec pinghosts entry */
217
						if ($ph2ent['pinghost']) {
218
							if (!is_array($iflist))
219
								$iflist = get_configured_interface_list();
220
							foreach ($iflist as $ifent => $ifname) {
221
								if(is_ipaddrv6($ph2ent['pinghost'])) {
222
									$interface_ip = get_interface_ipv6($ifent);
223
									if(!is_ipaddrv6($interface_ip))
224
										continue;
225
									$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
226
									if (ip_in_subnet($interface_ip, $local_subnet)) {
227
										$srcip = $interface_ip;
228
										break;
229
									}
230
								} else {
231
									$interface_ip = get_interface_ip($ifent);
232
									if(!is_ipaddrv4($interface_ip))
233
										continue;
234
									$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
235
									if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) {
236
										$srcip = $interface_ip;
237
										break;
238
									}
239
								}
240
							}
241
							$dstip = $ph2ent['pinghost'];
242
							if(is_ipaddrv6($dstip)) {
243
								$family = "inet6";
244
							} else {
245
								$family = "inet";
246
							}
247
							if (is_ipaddr($srcip))
248
								$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
249
						}
250
					}
251
				}
252
			}
253
			@file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
254
			unset($ipsecpinghosts);
255
		}
256
		unset($iflist);
257

    
258
		$strongswan = <<<EOD
259

    
260
#Automatically generated please do not modify
261
starter {
262
    load_warning = no
263
}
264

    
265
charon {
266

    
267
        # number of worker threads in charon
268
        threads = 16
269

    
270
	# And two loggers using syslog. The subsections define the facility to log
271
	# to, currently one of: daemon, auth.
272
	syslog {
273

    
274
		identifier = charon
275
		# default level to the LOG_DAEMON facility
276
		daemon {
277
		}
278
		# very minimalistic IKE auditing logs to LOG_AUTHPRIV
279
		auth {
280
		    default = -1
281
		    ike = 1
282
		}
283
	}
284

    
285
EOD;
286

    
287
		if (is_array($a_client) && isset($a_client['enable']) && !empty($a_client['net_list']))
288
			$strongswan .= "\tcisco_unity = yes\n";
289

    
290
		$strongswan .= "\tplugins {\n";
291

    
292
		if (is_array($a_client) && isset($a_client['enable'])) {
293
			$strongswan .= "\t\tattr {\n";
294
			if ($a_client['pool_address'] && $a_client['pool_netbits']) {
295
				$pool_address = $a_client['pool_address'];
296
				$pool_netmask = gen_subnet_mask($a_client['pool_netbits']);
297
				$pool_address = long2ip32(ip2long($pool_address)+1);
298

    
299
				$strongswan .= "\t\taddress = {$pool_address}\n";
300
				$strongswan .= "\t\tnetmask = {$pool_netmask}\n";
301
			}
302

    
303
			$cfgservers = array();
304
			if (!empty($a_client['dns_server1']))
305
				$cfgservers[] = $a_client['dns_server1'];
306
			if (!empty($a_client['dns_server2']))
307
				$cfgservers[] = $a_client['dns_server2'];
308
			if (!empty($a_client['dns_server3']))
309
				$cfgservers[] = $a_client['dns_server3'];
310
			if (!empty($a_client['dns_server4']))
311
				$cfgservers[] = $a_client['dns_server4'];
312

    
313
			if (!empty($cfgservers))
314
				$strongswan .= "\t\tdns = " . implode(",", $cfgservers) . "\n";
315
			unset($cfgservers);
316
			$cfgservers = array();
317
			if (!empty($a_client['wins_server1']))
318
				$cfgservers[] = $a_client['wins_server1'];
319
			if (!empty($a_client['wins_server2']))
320
				$cfgservers[] = $a_client['wins_server2'];
321
			if (!empty($cfgservers))
322
				$strongswan .= "\t\tnbns = " . implode(",", $cfgservers) . "\n";
323
			unset($cfgservers);
324

    
325
			if (!empty($a_client['net_list'])) {
326
				$net_list = '';
327
				foreach ($a_phase2 as $ph2ent) {
328
					if (isset($ph2ent['disabled']))
329
						continue;
330

    
331
					if (!isset($ph2ent['mobile']))
332
						continue;
333

    
334
					$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
335

    
336
					if ($net_list)
337
						$net_list .= ", ";
338
					$net_list .= $localid;
339
				}
340

    
341
				if (!empty($net_list)) {
342
					$strongswan .= "\t\tsubnet = {$net_list}\n";
343
					$strongswan .= "\t\tsplit-include = {$net_list}\n";
344
					unset($net_list);
345
				}
346
			}
347

    
348
			if (!empty($a_client['dns_domain'])) {
349
				$strongswan .= "\t\t# Search domain and default domain\n";
350
				$strongswan .= "\t\t28674 = {$a_client['dns_domain']}\n";
351
				if (empty($a_client['dns_split']))
352
					$strongswan .= "\t\t28675 = {$a_client['dns_domain']}";
353
				$strongswan .= "\n";
354
			}
355

    
356
			if (!empty($a_client['dns_split'])) {
357
				$strongswan .= "\t\t28675 = {$a_client['dns_split']}\n";
358
			}
359

    
360
			if (!empty($a_client['login_banner']))
361
				$strongswan .= "\t\t28672 = {$a_client['login_banner']}\n";
362

    
363
			if (isset($a_client['save_passwd']))
364
				$strongswan .= "\t\t28673 = yes\n";
365

    
366
			if ($a_client['pfs_group'])
367
				$strongswan .= "\t\t28679 = {$a_client['pfs_group']}\n";
368
			$strongswan .= "\t\t}\n";
369

    
370
			if ($a_client['user_source'] != "none") {
371
				$strongswan .= "\txauth-generic {\n";
372
				$strongswan .= "\t\tscript = /etc/inc/ipsec.auth-user.php\n";
373
				$strongswan .= "\t\tauthcfg = ";
374
				$firstsed = 0;
375
				$authcfgs = explode(",", $a_client['user_source']);
376
				foreach ($authcfgs as $authcfg) {
377
					if ($firstsed > 0)
378
						$strongswan .= ",";
379
					if ($authcfg == "system")
380
						$authcfg = "Local Database";
381
					$strongswan .= $authcfg;
382
					$firstsed = 1;
383
				}
384
				$strongswan .= "\n";
385
				$strongswan .= "\t}\n";
386
			}
387
		}
388

    
389
		$strongswan .= "\t}\n}\n";
390
		@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
391
		unset($strongswan);
392

    
393
		/* generate CA certificates files */
394
		if (is_array($config['ca']) && count($config['ca'])) {
395
			foreach ($config['ca'] as $ca) {
396
				if (!isset($ca['crt'])) {
397
					log_error(sprintf(gettext("Error: Invalid certificate info for %s"), $ca['descr']));
398
					continue;
399
				}
400
				$cert = base64_decode($ca['crt']);
401
				$x509cert = openssl_x509_parse(openssl_x509_read($cert));
402
				if (!is_array($x509cert) || !isset($x509cert['hash'])) {
403
					log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $ca['descr']));
404
					continue;
405
				}
406
				$fname = "{$g['varetc_path']}/ipsec/cacerts/{$x509cert['hash']}.0";
407
				if (!@file_put_contents($fname, $cert)) {
408
					log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $ca['descr']));
409
					continue;
410
				}
411
				unset($cert);
412
			}
413
		}
414

    
415
		$pskconf = "";
416

    
417
		if (is_array($a_phase1) && count($a_phase1)) {
418
			foreach ($a_phase1 as $ph1ent) {
419

    
420
				if (isset($ph1ent['disabled']))
421
					continue;
422

    
423
				if (strstr($ph1ent['authentication_method'],'rsa')) {
424
					$certline = '';
425

    
426
					if (strstr($authmethod,'rsa')) {
427

    
428
						$cert = lookup_cert($ph1ent['certref']);
429

    
430
						if (!$cert) {
431
							log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
432
							continue;
433
						}
434

    
435
						chmod($certpath, 0600);
436

    
437
						$keyfile = "cert-{$ikeid}.key";
438
						$keypath = "{$g['varetc_path']}/ipsec/{$keyfile}";
439

    
440
						if (!file_put_contents($keypath, base64_decode($cert['prv']))) {
441
							log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
442
							continue;
443
						}
444

    
445
						chmod($keypath, 0600);
446
						/* XXX" Traffic selectors? */
447
						$pskconf .= " : RSA {$keypath}\n";
448

    
449
						$ca = lookup_ca($ph1ent['caref']);
450
						if ($ca) {
451
							$cafile = "ca-{$ikeid}.crt";
452
							$capath = "{$g['varetc_path']}/ipsec/cacerts/{$cafile}";
453

    
454
							if (!file_put_contents($capath, base64_decode($ca['crt'])))
455
							{
456
								log_error(sprintf(gettext("Error: Cannot write phase1 CA certificate file for %s"), $ph1ent['name']));
457
								continue;
458
							}
459

    
460
							chmod($capath, 0600);
461
						}
462
					}
463
				} else {
464

    
465
					$peerid_type = $ph1ent['peerid_type'];
466

    
467
					switch ($peerid_type) {
468
						case "peeraddress":
469
							$peerid_type = "address";
470
							$peerid_data = $rgmap[$ph1ent['remote-gateway']];
471
							break;
472

    
473
						case "address";
474
							$peerid_data = $ph1ent['peerid_data'];
475
							break;
476

    
477
						case "fqdn";
478
						case "keyid tag";
479
						case "user_fqdn";
480
							$peerid_data = $ph1ent['peerid_data'];
481
							break;
482
					}
483

    
484
					if (!empty($peerid_data) && !empty($ph1ent['pre-shared-key']))
485
						$pskconf .= trim($peerid_data) . " : PSK \"" . trim($ph1ent['pre-shared-key']) . "\"\n";
486
				}
487
			}
488
		}
489

    
490
		/* Add user PSKs */
491
		foreach ($config['system']['user'] as $user) {
492
			if (!empty($user['ipsecpsk'])) {
493
				$pskconf .= "{$user['name']} : PSK \"{$user['ipsecpsk']}\"\n";
494
			}
495
		}
496

    
497
		/* add PSKs for mobile clients */
498
		if (is_array($ipseccfg['mobilekey'])) {
499
			foreach ($ipseccfg['mobilekey'] as $key) {
500
				$pskconf .= "{$key['ident']} : PSK \"{$key['pre-shared-key']}\"\n";
501
			}
502
		}
503

    
504
		@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
505
		chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
506
		unset($pskconf);
507

    
508
		$natfilterrules = false;
509
		/* begin ipsec.conf */
510
		$ipsecconf = "";
511
		if ((is_array($a_phase1) && count($a_phase1)) || (is_array($a_phase2) && count($a_phase2))) {
512

    
513
			$ipsecconf .= "# This file is automatically generated. Do not edit\n";
514
			if (is_array($a_phase2) && count($a_phase2)) {
515
				$ipsecconf .= "config setup\n\tuniqueids = yes\n";
516

    
517
				foreach ($a_phase2 as $ph2ent) {
518
					$ikeid = $ph2ent['ikeid'];
519

    
520
					$ph1ent = false;
521
					if (!ipsec_lookup_phase1($ph2ent,$ph1ent))
522
						continue;
523

    
524
					if (isset($ph1ent['disabled']))
525
						continue;
526

    
527
					if (isset($ph2ent['disabled']))
528
						continue;
529

    
530
					$ikeid = $ph1ent['ikeid'];
531

    
532
					$ep = ipsec_get_phase1_src($ph1ent);
533
					if (!$ep)
534
						continue;
535

    
536
					if (!isset($ph1ent['mobile'])) {
537
						$rgip = $rgmap[$ph1ent['remote-gateway']];
538
						if (!$rgip)
539
							continue;
540
					}
541

    
542
					$myid_type = $ph1ent['myid_type'];
543

    
544
					switch ($myid_type) {
545
					case "myaddress":
546
						$myid_type = "address";
547
						$myid_data = $ep;
548
						break;
549

    
550
					case "dyn_dns":
551
						$myid_type = "address";
552
						$myid_data = resolve_retry($ph1ent['myid_data']);
553
						break;
554

    
555
					case "address";
556
						$myid_data = $ph1ent['myid_data'];
557
						break;
558

    
559
					case "fqdn";
560
					case "keyid tag";
561
					case "user_fqdn";
562
					case "asn1dn";
563
						$myid_data = $ph1ent['myid_data'];
564
						if( $myid_data )
565
							$myid_data = "\"{$myid_data}\"";
566
						break;
567
					}
568

    
569
					$peerid_type = $ph1ent['peerid_type'];
570

    
571
					switch ($peerid_type) {
572
					case "peeraddress":
573
						$peerid_type = "address";
574
						$peerid_data = $rgip;
575
						break;
576

    
577
					case "address";
578
						$peerid_data = $ph1ent['peerid_data'];
579
						break;
580

    
581
					case "fqdn";
582
					case "keyid tag";
583
					case "user_fqdn";
584
					case "asn1dn";
585
						$peerid_data = $ph1ent['peerid_data'];
586
						if( $peerid_data )
587
							$peerid_data = "\"{$peerid_data}\"";
588
						break;
589
					}
590

    
591
					$genp = "no";
592
					if (!empty($ph1ent['generate_policy']) && $ph1ent['generate_policy'] != "off")
593
						$genp = "yes";
594
						
595
					$passive = "start";
596
					if (isset($ph1ent['mobile'])) {
597
						$rgip = "%any";
598
						$passive = "route";
599
					}
600

    
601
					$keyexchange = "ikev1";
602
					if (!empty($ph1ent['iketype']) && $ph1ent['iketype'] != "ikev1")
603
						$keyexchange = "ikev2";
604

    
605
					if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
606
						$ealgosp1 = '';
607
						$ealg_id = $ph1ent['encryption-algorithm']['name'];
608
						$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
609
						if ($ealg_kl)
610
							$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
611
						else
612
							$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
613

    
614
						$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
615
						if (!empty($modp))
616
							$ealgosp1 .= "-{$modp}";
617

    
618
						if ($keyexchange == "ikev1")
619
							$ealgosp1 .= "!";
620
					}
621

    
622
					if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
623
						if ($passive == "start")
624
							$dpdline = "dpdaction = restart";
625
						else
626
							$dpdline = "dpdaction = clear";
627
						$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
628
						$dpdline .= "\n\tdpdtimeout = {$ph1ent['dpd_maxfail']}s";
629
					} else
630
						$dpdline = "dpdaction = none";
631

    
632
					if (!empty($ph1ent['authentication_method']) && (strstr($ph1ent['authentication_method'], "xauth") || strstr($ph1ent['authentication_method'], "hybrid")))
633
						$xauth = "xauth = server";
634

    
635

    
636
					$lifeline = '';
637
					if ($ph1ent['lifetime'])
638
						$lifeline = "ikelifetime = {$ph1ent['lifetime']}s";
639

    
640
					/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
641
					$peerid_spec = '';
642
					if (!(($ph1ent['authentication_method'] == "pre_shared_key") && isset($ph1ent['mobile']))) {
643
						$peerid_spec = $peerid_data;
644
					}
645

    
646
					if (empty($ph1ent['mode']))
647
						$aggressive = "no";
648
					else if ($ph1ent['mode'] == "aggressive")
649
						$aggressive = "yes";
650
					else if ($ph1ent['mode'] == "main")
651
						$aggressive = "no";
652
					else
653
						$aggressive = "no";
654

    
655
					if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
656
						continue;
657

    
658
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
659
						$tunneltype = "type = tunnel";
660

    
661
						$localid_type = $ph2ent['localid']['type'];
662
						$localid_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
663
						/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
664
						if (($localid_type == "none" || $localid_type == "mobile")
665
							&& isset($ph1ent['mobile'])
666
							&& (ipsec_get_number_of_phase2($ikeid)==1))
667
							$localid_spec = "%any";
668
						else {
669
							if ($localid_type != "address") {
670
								$localid_type = "subnet";
671
							}
672
							// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
673
							if (!is_ipaddr($localid_data) && !is_subnet($localid_data) && ($localid_data != "0.0.0.0/0")) {
674
								log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
675
								continue;
676
							}
677
							$localid_spec = $ep;
678
							if (!empty($ph2ent['natlocalid'])) {
679
								$natlocalid_data =  ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
680
								if ($ph2ent['natlocalid']['type'] != "address") {
681
									if (is_subnet($natlocalid_data))
682
										$localid_data = "{$natlocalid_data}|{$localid_data}";
683
								} else {
684
									if (is_ipaddr($natlocalid_data))
685
										$localid_data = "{$natlocalid_data}|{$localid_data}";
686
								}
687
								$natfilterrules = true;
688
							}
689
						}
690

    
691
						if (!isset($ph2ent['mobile'])) {
692
							$remoteid_type = $ph2ent['remoteid']['type'];
693
							if ($remoteid_type != "address")
694
								$remoteid_type = "subnet";
695

    
696
							$remoteid_data = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
697
							$remoteid_spec = $remoteid_data;
698
						}
699

    
700
					} else {
701
						$tunneltype = "type = transport";
702
						$rgip = $rgmap[$ph1ent['remote-gateway']];
703

    
704
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
705
							($ph1ent['authentication_method'] == "pre_shared_key"))
706
							&& isset($ph1ent['mobile']))
707
							$localid_spec = "%any";
708
						else {
709
							$localid_data = ipsec_get_phase1_src($ph1ent);
710
							$localid_spec = $ep;
711
						}
712
						if (!isset($ph2ent['mobile'])) {
713
							$remoteid_data = $rgmap[$ph1ent['remote-gateway']];
714
							$remoteid_spec = $remoteid_data;
715
						}
716
					}
717
					$authentication = "";
718
					switch ($ph1ent['authentication_method']) {
719
					case 'xauth_rsa_server':
720
						$authentication = "leftauth = pubkey\n\trightauth = pubkey";
721
						$authentication .= "\n\leftauth2 = xauth-generic";
722
						break;
723
					case 'xauth_psk_server':
724
						$authentication = "leftauth = psk\n\trightauth = psk";
725
						$authentication .= "\n\tleftauth2 = xauth-generic";
726
						break;
727
					case 'pre_shared_key':
728
						$authentication = "leftauth = psk\n\trightauth = psk";
729
						break;
730
					case 'rsasig':
731
						$authentication = "leftauth = pubkey\n\trightauth = pubkey";
732
						break;
733
					case 'hybrid_rsa_server':
734
						$authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
735
						$authentication .= "\n\trightauth2 = xauth";
736
						break;
737
					}
738

    
739
					if (isset($a_client['pfs_group']))
740
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
741
					$ealgosp2 = '';
742
					if ($ph2ent['protocol'] == 'esp') {
743
						if (is_array($ph2ent['encryption-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
744
							$ealgosp2arr = array();
745
							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
746
								$ealg_id = $ealg['name'];
747
								$ealg_kl = $ealg['keylen'];
748

    
749
								if (!empty($ealg_kl) && $ealg_kl == "auto") {
750
									if (empty($p2_ealgos) || !is_array($p2_ealgos))
751
										require("ipsec.inc");
752
									$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
753
									$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
754
									$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
755
									/* XXX: in some cases where include ordering is suspect these variables
756
									 * are somehow 0 and we enter this loop forever and timeout after 900
757
									 * seconds wrecking bootup */
758
									if ($key_hi != 0 and $key_lo !=0 and $key_step !=0) {
759
										for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
760
											foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
761
												$halgo = str_replace('hmac_', '', $halgo);
762
												$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
763
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
764
												if (!empty($modp))
765
													$tmpealgo .= "-{$modp}";
766
												$ealgosp2arr[] = $tmpealgo;
767
											}
768
										}
769
									}
770
								} else {
771
									foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
772
										$halgo = str_replace('hmac_', '', $halgo);
773
										$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
774
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
775
										if (!empty($modp))
776
											$tmpealgo .= "-{$modp}";
777
										$ealgosp2arr[] = $tmpealgo;
778
									}
779
								}
780
							}
781
							$ealgosp2 = "esp = " . join(",", $ealgosp2arr);
782
							unset($ealgosp2arr);
783
							$ealgosp2 .= "!";
784
						}
785
					} else if ($ph2ent['protocol'] == 'ah') {
786
						if (is_array($ph2ent['hash-algorithm-option'])) {
787
							$ealgosp2 = "ah = " . join(",", $ph2ent['hash-algorithm-option']);
788
							$ealgosp2 = str_replace('hmac_', '', $ealgosp2);
789
							$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
790
							if (!empty($modp))
791
								$ealgosp2 .= "-{$modp}";
792
							$ealgosp2 .= "!";
793
						}
794
					}
795

    
796

    
797
					if ($ph2ent['lifetime'])
798
						$lifeline = "ikelifetime = {$ph2ent['lifetime']}s";
799

    
800
					$ipsecconf .=<<<EOD
801

    
802
conn con{$ph2ent['ikeid']}{$ph2ent['ikeid']}
803
	aggressive = {$aggressive}
804
	fragmentation = yes
805
	keyexchange = {$keyexchange}
806
	keyingtries = %forever
807
	reauth = yes
808
	reqid = {$ikeid}
809
	installpolicy = yes
810
	{$lifeline}
811
	{$tunneltype}
812
	{$dpdline}
813
	auto = {$passive}
814
	left = {$localid_spec}
815
	leftsubnet = {$localid_data}
816
	right = {$rgip}
817
	leftid = {$myid_data}
818

    
819
EOD;
820

    
821
					if (!empty($remoteid_spec))
822
						$ipsecconf .= "\trightsubnet = $remoteid_spec\n";
823
					if (!empty($ealgosp1))
824
						$ipsecconf .= "\t{$ealgosp1}\n";
825
					if (!empty($ealgosp2))
826
						$ipsecconf .= "\t{$ealgosp2}\n";
827
					if (!empty($authentication))
828
						$ipsecconf .= "\t{$authentication}\n";
829
					if (!empty($peerid_spec))
830
						$ipsecconf .= "\trightid = {$peerid_spec}\n";
831
				}
832
			}
833
		}
834
	}
835
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
836
	unset($ipsecconf);
837
	/* end ipsec.conf */
838

    
839
	/* mange process */
840
	if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
841
		/* Read secrets */
842
		mwexec("/usr/local/sbin/ipsec rereadall", false);
843
		/* Update configuration changes */
844
		mwexec("/usr/local/sbin/ipsec update", false);
845
	} else {
846
		mwexec("/usr/local/sbin/ipsec start", false); 
847
	}
848
	if ($natfilterrules == true)
849
		filter_configure();
850
	/* start filterdns, if necessary */
851
	if (count($filterdns_list) > 0) {
852
		$interval = 60;
853
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
854
			$interval = $ipseccfg['dns-interval'];
855

    
856
		$hostnames = "";
857
		array_unique($filterdns_list);
858
		foreach ($filterdns_list as $hostname)
859
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
860
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
861
		unset($hostnames);
862

    
863
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
864
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
865
		else {
866
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
867
		}
868
	} else {
869
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
870
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
871
	}
872

    
873
	if ($g['booting'])
874
		echo "done\n";
875

    
876
	return count($filterdns_list);
877
}
878

    
879
/*
880
 * Forcefully restart IPsec
881
 * This is required for when dynamic interfaces reload
882
 * For all other occasions the normal vpn_ipsec_configure()
883
 * will gracefully reload the settings without restarting
884
 */
885
function vpn_ipsec_force_reload($interface = "") {
886
	global $g, $config;
887

    
888
	$ipseccfg = $config['ipsec'];
889

    
890
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
891
		$found = false;
892
		foreach ($ipseccfg['phase1'] as $ipsec) {
893
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
894
				$found = true;
895
				break;
896
			}
897
		}
898
		if (!$found) {
899
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
900
			return;
901
		}
902
	}
903

    
904
	/* if ipsec is enabled, start up again */
905
	if (isset($ipseccfg['enable'])) {
906
		log_error(gettext("Forcefully reloading IPsec"));
907
		vpn_ipsec_configure();
908
	}
909
}
910

    
911
/* master setup for vpn (mpd) */
912
function vpn_setup() {
913
	global $g;
914

    
915
	if ($g['platform'] == 'jail')
916
		return;
917

    
918
	/* start pptpd */
919
	vpn_pptpd_configure();
920

    
921
	/* start pppoe server */
922
	vpn_pppoes_configure();
923

    
924
	/* setup l2tp */
925
	vpn_l2tp_configure();
926
}
927

    
928
function vpn_netgraph_support() {
929
	$iflist = get_configured_interface_list();
930
	foreach ($iflist as $iface) {
931
		$realif = get_real_interface($iface);
932
		/* Get support for netgraph(4) from the nic */
933
		$ifinfo = pfSense_get_interface_addresses($realif);
934
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
935
			pfSense_ngctl_attach(".", $realif);
936
	}
937
}
938

    
939
function vpn_pptpd_configure() {
940
	global $config, $g;
941

    
942
	$syscfg = $config['system'];
943
	$pptpdcfg = $config['pptpd'];
944

    
945
	if ($g['booting']) {
946
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
947
			return 0;
948

    
949
		echo gettext("Configuring PPTP VPN service... ");
950
	} else {
951
		/* kill mpd */
952
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
953

    
954
		/* wait for process to die */
955
		sleep(3);
956

    
957
		if (is_process_running("mpd -b")) {
958
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
959
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
960
		}
961

    
962
		/* remove mpd.conf, if it exists */
963
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
964
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
965
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
966
	}
967

    
968
	if (empty($pptpdcfg['n_pptp_units'])) {
969
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
970
		return;
971
	}
972

    
973
	/* make sure pptp-vpn directory exists */
974
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
975
		mkdir("{$g['varetc_path']}/pptp-vpn");
976

    
977
	switch ($pptpdcfg['mode']) {
978
		case 'server' :
979
			/* write mpd.conf */
980
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
981
			if (!$fd) {
982
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
983
				return 1;
984
			}
985

    
986
			$mpdconf = <<<EOD
987
pptps:
988

    
989
EOD;
990

    
991
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
992
				$mpdconf .= "	load pt{$i}\n";
993
			}
994

    
995
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
996

    
997
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
998

    
999
				$mpdconf .= <<<EOD
1000

    
1001
pt{$i}:
1002
	new -i pptpd{$i} pt{$i} pt{$i}
1003
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1004
	load pts
1005

    
1006
EOD;
1007
			}
1008

    
1009
			$mpdconf .=<<<EOD
1010

    
1011
pts:
1012
	set iface disable on-demand
1013
	set iface enable proxy-arp
1014
	set iface enable tcpmssfix
1015
	set iface idle 1800
1016
	set iface up-script /usr/local/sbin/vpn-linkup
1017
	set iface down-script /usr/local/sbin/vpn-linkdown
1018
	set bundle enable multilink
1019
	set bundle enable crypt-reqd
1020
	set link yes acfcomp protocomp
1021
	set link no pap chap
1022
	set link enable chap-msv2
1023
	set link mtu 1460
1024
	set link keep-alive 10 60
1025
	set ipcp yes vjcomp
1026
	set bundle enable compression
1027
	set ccp yes mppc
1028
	set ccp yes mpp-e128
1029
	set ccp yes mpp-stateless
1030

    
1031
EOD;
1032

    
1033
			if (!isset ($pptpdcfg['req128'])) {
1034
				$mpdconf .=<<<EOD
1035
	set ccp yes mpp-e40
1036
	set ccp yes mpp-e56
1037

    
1038
EOD;
1039
			}
1040

    
1041
			if  (isset($pptpdcfg["wins"]) && $pptpdcfg['wins'] != "")
1042
				$mpdconf  .=  "	set ipcp nbns {$pptpdcfg['wins']}\n";
1043

    
1044
			if (!empty($pptpdcfg['dns1'])) {
1045
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1046
				if (!empty($pptpdcfg['dns2']))
1047
					$mpdconf .= " " . $pptpdcfg['dns2'];
1048
				$mpdconf .= "\n";
1049
			} elseif (isset ($config['dnsmasq']['enable'])) {
1050
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1051
				if ($syscfg['dnsserver'][0])
1052
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1053
				$mpdconf .= "\n";
1054
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1055
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1056
			}
1057

    
1058
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1059
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1060
				$acctport = $authport + 1;
1061
				$mpdconf .=<<<EOD
1062
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1063

    
1064
EOD;
1065
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1066
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1067
				$acctport = $authport + 1;
1068
				$mpdconf .=<<<EOD
1069
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1070

    
1071
EOD;
1072
			}
1073
			$mpdconf .=<<<EOD
1074
	set radius retries 3
1075
	set radius timeout 10
1076
	set auth enable radius-auth
1077

    
1078
EOD;
1079

    
1080
				if (isset ($pptpdcfg['radius']['accounting'])) {
1081
					$mpdconf .=<<<EOD
1082
	set auth enable radius-acct
1083
	set radius acct-update 300
1084

    
1085
EOD;
1086
				}
1087
			}
1088

    
1089
			fwrite($fd, $mpdconf);
1090
			fclose($fd);
1091
			unset($mpdconf);
1092

    
1093
			/* write mpd.links */
1094
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1095
			if (!$fd) {
1096
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1097
				return 1;
1098
			}
1099

    
1100
			$mpdlinks = "";
1101

    
1102
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1103
				$mpdlinks .=<<<EOD
1104

    
1105
pt{$i}:
1106
	set link type pptp
1107
	set pptp enable incoming
1108
	set pptp disable originate
1109
	set pptp disable windowing
1110

    
1111
EOD;
1112
			}
1113

    
1114
			fwrite($fd, $mpdlinks);
1115
			fclose($fd);
1116
			unset($mpdlinks);
1117

    
1118
			/* write mpd.secret */
1119
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1120
			if (!$fd) {
1121
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1122
				return 1;
1123
			}
1124

    
1125
			$mpdsecret = "";
1126

    
1127
			if (is_array($pptpdcfg['user'])) {
1128
				foreach ($pptpdcfg['user'] as $user) {
1129
					$pass = str_replace('\\', '\\\\', $user['password']);
1130
					$pass = str_replace('"', '\"', $pass);
1131
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1132
				}
1133
			}
1134

    
1135
			fwrite($fd, $mpdsecret);
1136
			fclose($fd);
1137
			unset($mpdsecret);
1138
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1139

    
1140
			vpn_netgraph_support();
1141

    
1142
			/* fire up mpd */
1143
			mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']}/pptp-vpn -p {$g['varrun_path']}/pptp-vpn.pid -s pptps pptps");
1144

    
1145
			break;
1146

    
1147
		case 'redir' :
1148
			break;
1149
	}
1150

    
1151
	if ($g['booting'])
1152
		echo "done\n";
1153

    
1154
	return 0;
1155
}
1156

    
1157
function vpn_pppoes_configure() {
1158
	global $config;
1159

    
1160
	if (is_array($config['pppoes']['pppoe'])) {
1161
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1162
			vpn_pppoe_configure($pppoe);
1163
	}
1164
}
1165

    
1166
function vpn_pppoe_configure(&$pppoecfg) {
1167
	global $config, $g;
1168

    
1169
	$syscfg = $config['system'];
1170

    
1171
	/* create directory if it does not exist */
1172
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1173
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1174

    
1175
	if ($g['booting']) {
1176
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1177
			return 0;
1178

    
1179
		echo gettext("Configuring PPPoE VPN service... ");
1180
	} else {
1181
		/* kill mpd */
1182
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1183

    
1184
		/* wait for process to die */
1185
		sleep(2);
1186

    
1187
	}
1188

    
1189
	switch ($pppoecfg['mode']) {
1190

    
1191
		case 'server' :
1192

    
1193
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1194

    
1195
			if ($pppoecfg['paporchap'] == "chap")
1196
				$paporchap = "set link enable chap";
1197
			else
1198
				$paporchap = "set link enable pap";
1199

    
1200
			/* write mpd.conf */
1201
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1202
			if (!$fd) {
1203
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1204
				return 1;
1205
			}
1206
			$mpdconf = "\n\n";
1207
			$mpdconf .= "poes:\n";
1208

    
1209
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1210
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1211
			}
1212

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

    
1215
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1216

    
1217
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1218
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1219
				} else {
1220
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1221
				}
1222

    
1223
				$mpdconf .=<<<EOD
1224

    
1225
poes{$pppoecfg['pppoeid']}{$i}:
1226
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1227
	{$isssue_ip_type}
1228
	load pppoe_standard
1229

    
1230
EOD;
1231
			}
1232

    
1233
			$mpdconf .=<<<EOD
1234

    
1235
pppoe_standard:
1236
	set bundle no multilink
1237
	set bundle enable compression
1238
	set auth max-logins 1
1239
	set iface up-script /usr/local/sbin/vpn-linkup
1240
	set iface down-script /usr/local/sbin/vpn-linkdown
1241
	set iface idle 0
1242
	set iface disable on-demand
1243
	set iface disable proxy-arp
1244
	set iface enable tcpmssfix
1245
	set iface mtu 1500
1246
	set link no pap chap
1247
	{$paporchap}
1248
	set link keep-alive 60 180
1249
	set ipcp yes vjcomp
1250
	set ipcp no vjcomp
1251
	set link max-redial -1
1252
	set link mtu 1492
1253
	set link mru 1492
1254
	set ccp yes mpp-e40
1255
	set ccp yes mpp-e128
1256
	set ccp yes mpp-stateless
1257
	set link latency 1
1258
	#set ipcp dns 10.10.1.3
1259
	#set bundle accept encryption
1260

    
1261
EOD;
1262

    
1263
			if (!empty($pppoecfg['dns1'])) {
1264
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1265
				if (!empty($pppoecfg['dns2']))
1266
					$mpdconf .= " " . $pppoecfg['dns2'];
1267
				$mpdconf .= "\n";
1268
			} elseif (isset ($config['dnsmasq']['enable'])) {
1269
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1270
				if ($syscfg['dnsserver'][0])
1271
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1272
				$mpdconf .= "\n";
1273
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1274
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1275
			}
1276

    
1277
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1278
				$radiusport = "";
1279
				$radiusacctport = "";
1280
				if (isset($pppoecfg['radius']['server']['port']))
1281
					$radiusport = $pppoecfg['radius']['server']['port'];
1282
				if (isset($pppoecfg['radius']['server']['acctport']))
1283
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1284
				$mpdconf .=<<<EOD
1285
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1286
	set radius retries 3
1287
	set radius timeout 10
1288
	set auth enable radius-auth
1289

    
1290
EOD;
1291

    
1292
				if (isset ($pppoecfg['radius']['accounting'])) {
1293
					$mpdconf .=<<<EOD
1294
	set auth enable radius-acct
1295

    
1296
EOD;
1297
				}
1298
			}
1299

    
1300
			fwrite($fd, $mpdconf);
1301
			fclose($fd);
1302
			unset($mpdconf);
1303

    
1304
			/* write mpd.links */
1305
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1306
			if (!$fd) {
1307
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1308
				return 1;
1309
			}
1310

    
1311
			$mpdlinks = "";
1312

    
1313
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1314
				$mpdlinks .=<<<EOD
1315

    
1316
poes{$pppoecfg['pppoeid']}{$i}:
1317
	set phys type pppoe
1318
	set pppoe iface {$pppoe_interface}
1319
	set pppoe service "*"
1320
	set pppoe disable originate
1321
	set pppoe enable incoming
1322

    
1323
EOD;
1324
			}
1325

    
1326
			fwrite($fd, $mpdlinks);
1327
			fclose($fd);
1328
			unset($mpdlinks);
1329

    
1330
			if ($pppoecfg['username']) {
1331
				/* write mpd.secret */
1332
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1333
				if (!$fd) {
1334
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1335
					return 1;
1336
				}
1337

    
1338
				$mpdsecret = "\n\n";
1339

    
1340
				if (!empty($pppoecfg['username'])) {
1341
					$item = explode(" ", $pppoecfg['username']);
1342
					foreach($item as $userdata) {
1343
						$data = explode(":", $userdata);
1344
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1345
					}
1346
				}
1347

    
1348
				fwrite($fd, $mpdsecret);
1349
				fclose($fd);
1350
				unset($mpdsecret);
1351
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1352
			}
1353

    
1354
			/* Check if previous instance is still up */
1355
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid"))
1356
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1357

    
1358
			/* Get support for netgraph(4) from the nic */
1359
			pfSense_ngctl_attach(".", $pppoe_interface);
1360
			/* fire up mpd */
1361
			mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn -p {$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid -s poes poes");
1362

    
1363
			break;
1364
	}
1365

    
1366
	if ($g['booting'])
1367
		echo gettext("done") . "\n";
1368

    
1369
	return 0;
1370
}
1371

    
1372
function vpn_l2tp_configure() {
1373
	global $config, $g;
1374

    
1375
	$syscfg = $config['system'];
1376
	$l2tpcfg = $config['l2tp'];
1377

    
1378
	/* create directory if it does not exist */
1379
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1380
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1381

    
1382
	if ($g['booting']) {
1383
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1384
			return 0;
1385

    
1386
		echo gettext("Configuring l2tp VPN service... ");
1387
	} else {
1388
		/* kill mpd */
1389
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1390

    
1391
		/* wait for process to die */
1392
		sleep(8);
1393

    
1394
	}
1395

    
1396
	/* make sure l2tp-vpn directory exists */
1397
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1398
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1399

    
1400
	switch ($l2tpcfg['mode']) {
1401

    
1402
		case 'server' :
1403
			if ($l2tpcfg['paporchap'] == "chap")
1404
				$paporchap = "set link enable chap";
1405
			else
1406
				$paporchap = "set link enable pap";
1407

    
1408
			/* write mpd.conf */
1409
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1410
			if (!$fd) {
1411
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1412
				return 1;
1413
			}
1414
			$mpdconf = "\n\n";
1415
			$mpdconf .=<<<EOD
1416
l2tps:
1417

    
1418
EOD;
1419

    
1420
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1421
				$mpdconf .= "	load l2tp{$i}\n";
1422
			}
1423

    
1424
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1425

    
1426
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1427

    
1428
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1429
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1430
				} else {
1431
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1432
				}
1433

    
1434
				$mpdconf .=<<<EOD
1435

    
1436
l2tp{$i}:
1437
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1438
	{$isssue_ip_type}
1439
	load l2tp_standard
1440

    
1441
EOD;
1442
			}
1443

    
1444
			$mpdconf .=<<<EOD
1445

    
1446
l2tp_standard:
1447
	set bundle disable multilink
1448
	set bundle enable compression
1449
	set bundle yes crypt-reqd
1450
	set ipcp yes vjcomp
1451
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1452
	set ccp yes mppc
1453
	set iface disable on-demand
1454
	set iface enable proxy-arp
1455
	set iface up-script /usr/local/sbin/vpn-linkup
1456
	set iface down-script /usr/local/sbin/vpn-linkdown
1457
	set link yes acfcomp protocomp
1458
	set link no pap chap
1459
	set link enable chap
1460
	set link keep-alive 10 180
1461

    
1462
EOD;
1463

    
1464
			if (is_ipaddr($l2tpcfg['wins'])) {
1465
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1466
			}
1467
			if (is_ipaddr($l2tpcfg['dns1'])) {
1468
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1469
				if (is_ipaddr($l2tpcfg['dns2']))
1470
					$mpdconf .= " " . $l2tpcfg['dns2'];
1471
				$mpdconf .= "\n";
1472
			} elseif (isset ($config['dnsmasq']['enable'])) {
1473
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1474
				if ($syscfg['dnsserver'][0])
1475
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1476
				$mpdconf .= "\n";
1477
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1478
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1479
			}
1480

    
1481
			if (isset ($l2tpcfg['radius']['enable'])) {
1482
				$mpdconf .=<<<EOD
1483
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1484
	set radius retries 3
1485
	set radius timeout 10
1486
	set auth enable radius-auth
1487

    
1488
EOD;
1489

    
1490
				if (isset ($l2tpcfg['radius']['accounting'])) {
1491
					$mpdconf .=<<<EOD
1492
	set auth enable radius-acct
1493

    
1494
EOD;
1495
				}
1496
			}
1497

    
1498
			fwrite($fd, $mpdconf);
1499
			fclose($fd);
1500
			unset($mpdconf);
1501

    
1502
			/* write mpd.links */
1503
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1504
			if (!$fd) {
1505
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1506
				return 1;
1507
			}
1508

    
1509
			$mpdlinks = "";
1510

    
1511
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1512
				$mpdlinks .=<<<EOD
1513

    
1514
l2tp{$i}:
1515
	set link type l2tp
1516
	set l2tp enable incoming
1517
	set l2tp disable originate
1518

    
1519
EOD;
1520
			if (!empty($l2tpcfg['secret']))
1521
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1522
			}
1523

    
1524
			fwrite($fd, $mpdlinks);
1525
			fclose($fd);
1526
			unset($mpdlinks);
1527

    
1528
			/* write mpd.secret */
1529
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1530
			if (!$fd) {
1531
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1532
				return 1;
1533
			}
1534

    
1535
			$mpdsecret = "\n\n";
1536

    
1537
			if (is_array($l2tpcfg['user'])) {
1538
				foreach ($l2tpcfg['user'] as $user)
1539
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1540
			}
1541

    
1542
			fwrite($fd, $mpdsecret);
1543
			fclose($fd);
1544
			unset($mpdsecret);
1545
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1546

    
1547
			vpn_netgraph_support();
1548

    
1549
			/* fire up mpd */
1550
			mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']}/l2tp-vpn -p {$g['varrun_path']}/l2tp-vpn.pid -s l2tps l2tps");
1551

    
1552
			break;
1553

    
1554
		case 'redir' :
1555
			break;
1556
	}
1557

    
1558
	if ($g['booting'])
1559
		echo "done\n";
1560

    
1561
	return 0;
1562
}
1563

    
1564
function vpn_ipsec_configure_preferoldsa() {
1565
	global $config;
1566
	if(isset($config['ipsec']['preferoldsa']))
1567
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
1568
	else
1569
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
1570
}
1571

    
1572
?>
(58-58/67)