Projet

Général

Profil

Télécharger (44,1 ko) Statistiques
| Branche: | Tag: | Révision:

univnautes / etc / inc / vpn.inc @ 23ba08fc

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:	/sbin/ifconfig
38
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/ipsec	/usr/local/libexec/ipsec/charon /usr/local/libexec/ipsec/starter
39
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/filterdns	/usr/local/sbin/mpd4
40
	pfSense_MODULE:	vpn
41
*/
42

    
43
require_once("ipsec.inc");
44

    
45
function vpn_ipsec_configure_loglevels($forconfig = false)
46
{
47
	global $config, $ipsec_loglevels;
48

    
49
	$cfgtext = array();
50
	foreach ($ipsec_loglevels as $lkey => $ldescr) {
51
		if (!isset($config['ipsec']["ipsec_{$lkey}"]))
52
			$forconfig ? $cfgtext[] = "{$lkey} = -1" : 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}"]) <= 5)
55
			$forconfig ? $cfgtext[] = "${lkey} = " . (intval($config['ipsec']["ipsec_{$lkey}"]) - 1) :
56
				mwexec("/usr/local/sbin/ipsec stroke loglevel {$lkey} " . (intval($config['ipsec']["ipsec_{$lkey}"]) - 1) , false);
57
	}
58
	if ($forconfig)
59
		return implode(',', $cfgtext);
60
}
61

    
62
/* include all configuration functions */
63
function vpn_ipsec_convert_to_modp($index)
64
{
65

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

    
94
	return $convertion;
95
}
96

    
97
function vpn_ipsec_configure($ipchg = false)
98
{
99
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos;
100

    
101
	if ($g['platform'] == 'jail')
102
		return;
103

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

    
108
	vpn_ipsec_configure_preferoldsa();
109

    
110
	$syscfg = $config['system'];
111
	$ipseccfg = $config['ipsec'];
112
	$a_phase1 = $config['ipsec']['phase1'];
113
	$a_phase2 = $config['ipsec']['phase2'];
114
	$a_client = $config['ipsec']['client'];
115

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

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

    
125
		/* disallow IPSEC, it is off */
126
		mwexec("/sbin/ifconfig enc0 down");
127
		set_single_sysctl("net.inet.ip.ipsec_in_use", "0");
128

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

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

    
159
		/* fastforwarding is not compatible with ipsec tunnels */
160
		set_single_sysctl("net.inet.ip.fastforwarding", "0");
161

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

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

    
176
				$listeniflist = get_real_interface($a_phase1['interface']);
177

    
178
				$ep = ipsec_get_phase1_src($ph1ent);
179
				if (!is_ipaddr($ep))
180
					continue;
181

    
182
				if(!in_array($ep,$ipmap))
183
					$ipmap[] = $ep;
184

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

    
188
				if (isset ($ph1ent['mobile']))
189
					continue;
190

    
191
				$rg = $ph1ent['remote-gateway'];
192

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

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

    
212
						if (isset($ph2ent['disabled']))
213
							continue;
214

    
215
						if ($ikeid != $ph1ent['ikeid'])
216
							continue;
217

    
218
						/* add an ipsec pinghosts entry */
219
						if ($ph2ent['pinghost']) {
220
							if (!is_array($iflist))
221
								$iflist = get_configured_interface_list();
222
							$viplist = get_configured_vips_list();
223
							$srcip = null;
224
							$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
225
							if(is_ipaddrv6($ph2ent['pinghost'])) {
226
								foreach ($iflist as $ifent => $ifname) {
227
									$interface_ip = get_interface_ipv6($ifent);
228
									if(!is_ipaddrv6($interface_ip))
229
										continue;
230
									if (ip_in_subnet($interface_ip, $local_subnet)) {
231
										$srcip = $interface_ip;
232
										break;
233
									}
234
								}
235
							} else {
236
								foreach ($iflist as $ifent => $ifname) {
237
									$interface_ip = get_interface_ip($ifent);
238
									if(!is_ipaddrv4($interface_ip))
239
										continue;
240
									if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) {
241
										$srcip = $interface_ip;
242
										break;
243
									}
244
								}
245
							}
246
							/* if no valid src IP was found in configured interfaces, try the vips */
247
							if (is_null($srcip)) {
248
								foreach ($viplist as $vip) {
249
									if (ip_in_subnet($vip['ipaddr'], $local_subnet)) {
250
										$srcip = $vip['ipaddr'];
251
										break;
252
									}
253
								}
254
							}
255
							$dstip = $ph2ent['pinghost'];
256
							if(is_ipaddrv6($dstip)) {
257
								$family = "inet6";
258
							} else {
259
								$family = "inet";
260
							}
261
							if (is_ipaddr($srcip))
262
								$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
263
						}
264
					}
265
				}
266
			}
267
			@file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
268
			unset($ipsecpinghosts);
269
		}
270
		unset($iflist);
271

    
272
		$strongswan = <<<EOD
273

    
274
#Automatically generated please do not modify
275
starter {
276
    load_warning = no
277
}
278

    
279
charon {
280

    
281
        # number of worker threads in charon
282
        threads = 16
283

    
284
	# XXX: There is not much choice here really users win their security!
285
	i_dont_care_about_security_and_use_aggressive_mode_psk=yes
286

    
287
	# And two loggers using syslog. The subsections define the facility to log
288
	# to, currently one of: daemon, auth.
289
	syslog {
290

    
291
		identifier = charon
292
		# default level to the LOG_DAEMON facility
293
		daemon {
294
		}
295
		# very minimalistic IKE auditing logs to LOG_AUTHPRIV
296
		auth {
297
		    default = -1
298
		    ike = 1
299
		    ike_name = yes
300
		}
301
	}
302

    
303
EOD;
304

    
305
		if (is_array($a_client) && isset($a_client['enable']) && isset($a_client['net_list']))
306
			$strongswan .= "\tcisco_unity = yes\n";
307

    
308
		$strongswan .= "\tplugins {\n";
309

    
310
		if (is_array($a_client) && isset($a_client['enable'])) {
311
			$strongswan .= "\t\tattr {\n";
312
			if ($a_client['pool_address'] && $a_client['pool_netbits'])
313
				$strongswan .= "\t\tsubnet = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
314

    
315
			$cfgservers = array();
316
			if (!empty($a_client['dns_server1']))
317
				$cfgservers[] = $a_client['dns_server1'];
318
			if (!empty($a_client['dns_server2']))
319
				$cfgservers[] = $a_client['dns_server2'];
320
			if (!empty($a_client['dns_server3']))
321
				$cfgservers[] = $a_client['dns_server3'];
322
			if (!empty($a_client['dns_server4']))
323
				$cfgservers[] = $a_client['dns_server4'];
324

    
325
			if (!empty($cfgservers))
326
				$strongswan .= "\t\tdns = " . implode(",", $cfgservers) . "\n";
327
			unset($cfgservers);
328
			$cfgservers = array();
329
			if (!empty($a_client['wins_server1']))
330
				$cfgservers[] = $a_client['wins_server1'];
331
			if (!empty($a_client['wins_server2']))
332
				$cfgservers[] = $a_client['wins_server2'];
333
			if (!empty($cfgservers))
334
				$strongswan .= "\t\tnbns = " . implode(",", $cfgservers) . "\n";
335
			unset($cfgservers);
336

    
337
			if (isset($a_client['net_list'])) {
338
				$net_list = '';
339
				foreach ($a_phase2 as $ph2ent) {
340
					if (isset($ph2ent['disabled']))
341
						continue;
342

    
343
					if (!isset($ph2ent['mobile']))
344
						continue;
345

    
346
					$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
347

    
348
					if (!empty($net_list))
349
						$net_list .= ",";
350
					$net_list .= $localid;
351
				}
352

    
353
				if (!empty($net_list)) {
354
					$strongswan .= "\t\tsplit-include = {$net_list}\n";
355
					unset($net_list);
356
				}
357
			}
358

    
359
			if (!empty($a_client['dns_domain'])) {
360
				$strongswan .= "\t\t# Search domain and default domain\n";
361
				$strongswan .= "\t\t28674 = {$a_client['dns_domain']}\n";
362
				if (empty($a_client['dns_split']))
363
					$strongswan .= "\t\t28675 = {$a_client['dns_domain']}";
364
				$strongswan .= "\n";
365
			}
366

    
367
			if (!empty($a_client['dns_split'])) {
368
				$strongswan .= "\t\t28675 = {$a_client['dns_split']}\n";
369
			}
370

    
371
			if (!empty($a_client['login_banner']))
372
				$strongswan .= "\t\t28672 = {$a_client['login_banner']}\n";
373

    
374
			if (isset($a_client['save_passwd']))
375
				$strongswan .= "\t\t28673 = yes\n";
376

    
377
			if ($a_client['pfs_group'])
378
				$strongswan .= "\t\t28679 = {$a_client['pfs_group']}\n";
379
			$strongswan .= "\t\t}\n";
380

    
381
			if ($a_client['user_source'] != "none") {
382
				$strongswan .= "\txauth-generic {\n";
383
				$strongswan .= "\t\tscript = /etc/inc/ipsec.auth-user.php\n";
384
				$strongswan .= "\t\tauthcfg = ";
385
				$firstsed = 0;
386
				$authcfgs = explode(",", $a_client['user_source']);
387
				foreach ($authcfgs as $authcfg) {
388
					if ($firstsed > 0)
389
						$strongswan .= ",";
390
					if ($authcfg == "system")
391
						$authcfg = "Local Database";
392
					$strongswan .= $authcfg;
393
					$firstsed = 1;
394
				}
395
				$strongswan .= "\n";
396
				$strongswan .= "\t}\n";
397
			}
398
		}
399

    
400
		$strongswan .= "\t}\n}\n";
401
		@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
402
		unset($strongswan);
403

    
404
		/* generate CA certificates files */
405
		if (is_array($config['ca']) && count($config['ca'])) {
406
			foreach ($config['ca'] as $ca) {
407
				if (!isset($ca['crt'])) {
408
					log_error(sprintf(gettext("Error: Invalid certificate info for %s"), $ca['descr']));
409
					continue;
410
				}
411
				$cert = base64_decode($ca['crt']);
412
				$x509cert = openssl_x509_parse(openssl_x509_read($cert));
413
				if (!is_array($x509cert) || !isset($x509cert['hash'])) {
414
					log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $ca['descr']));
415
					continue;
416
				}
417
				$fname = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts/{$x509cert['hash']}.0";
418
				if (!@file_put_contents($fname, $cert)) {
419
					log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $ca['descr']));
420
					continue;
421
				}
422
				unset($cert);
423
			}
424
		}
425

    
426
		$pskconf = "";
427

    
428
		if (is_array($a_phase1) && count($a_phase1)) {
429
			foreach ($a_phase1 as $ph1ent) {
430

    
431
				if (isset($ph1ent['disabled']))
432
					continue;
433

    
434
				if (strstr($ph1ent['authentication_method'],'rsa')) {
435
					$certline = '';
436

    
437
					if (strstr($authmethod,'rsa')) {
438

    
439
						$cert = lookup_cert($ph1ent['certref']);
440

    
441
						if (!$cert) {
442
							log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
443
							continue;
444
						}
445

    
446
						chmod($certpath, 0600);
447

    
448
						$keyfile = "cert-{$ikeid}.key";
449
						$keypath = "{$g['varetc_path']}/ipsec/{$keyfile}";
450

    
451
						if (!file_put_contents($keypath, base64_decode($cert['prv']))) {
452
							log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
453
							continue;
454
						}
455

    
456
						chmod($keypath, 0600);
457
						/* XXX" Traffic selectors? */
458
						$pskconf .= " : RSA {$keypath}\n";
459

    
460
						$ca = lookup_ca($ph1ent['caref']);
461
						if ($ca) {
462
							$cafile = "ca-{$ikeid}.crt";
463
							$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts/{$cafile}";
464

    
465
							if (!file_put_contents($capath, base64_decode($ca['crt'])))
466
							{
467
								log_error(sprintf(gettext("Error: Cannot write phase1 CA certificate file for %s"), $ph1ent['name']));
468
								continue;
469
							}
470

    
471
							chmod($capath, 0600);
472
						}
473
					}
474
				} else {
475
					list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, "local");
476
					list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, "peer", $rgmap);
477

    
478
					if (empty($peerid_data))
479
						continue;
480

    
481
					$myid = isset($ph1ent['mobile']) ? trim($myid_data) . " " : "";
482
					$peerid = ($peerid_data != "allusers") ? trim($peerid_data) : "";
483
					if (!empty($ph1ent['pre-shared-key']))
484
						$pskconf .= $myid . $peerid . " : PSK \"" . trim($ph1ent['pre-shared-key']) . "\"\n";
485
				}
486
			}
487
		}
488

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

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

    
509
		@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
510
		chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
511
		unset($pskconf);
512

    
513
		$natfilterrules = false;
514
		/* begin ipsec.conf */
515
		$ipsecconf = "";
516
		if (is_array($a_phase1) && count($a_phase1))  {
517

    
518
			$ipsecconf .= "# This file is automatically generated. Do not edit\n";
519
			$ipsecconf .= "config setup\n\tuniqueids = yes\n";
520
			$ipsecconf .= "\tcharondebug=\"" . vpn_ipsec_configure_loglevels(true) . "\"\n";
521

    
522
			foreach ($a_phase1 as $ph1ent) {
523
				if (isset($ph1ent['disabled']))
524
					continue;
525

    
526
				if ($ph1ent['mode'] == "aggressive")
527
					$aggressive = "yes";
528
				else
529
					$aggressive = "no";
530

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

    
535
				$keyexchange = "ikev1";
536
				if (!empty($ph1ent['iketype']) && $ph1ent['iketype'] != "ikev1") {
537
					$keyexchange = "ikev2";
538
					$passive = "start";
539
				} else
540
					$passive = "route";
541

    
542
				if (isset($ph1ent['mobile'])) {
543
					$right_spec = "%any";
544
					$passive = 'add';
545
				} else
546
					$right_spec = $ph1ent['remote-gateway'];
547

    
548
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, "local");
549
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, "peer", $rgmap);
550

    
551
				/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
552
				$peerid_spec = '';
553
				if (!isset($ph1ent['mobile']))
554
					$peerid_spec = $peerid_data;
555

    
556
				if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
557
					$ealgosp1 = '';
558
					$ealg_id = $ph1ent['encryption-algorithm']['name'];
559
					$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
560
					if ($ealg_kl)
561
						$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
562
					else
563
						$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
564

    
565
					$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
566
					if (!empty($modp))
567
						$ealgosp1 .= "-{$modp}";
568

    
569
					if ($keyexchange == "ikev1")
570
						$ealgosp1 .= "!";
571
				}
572

    
573
				if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
574
					if ($passive == "route")
575
						$dpdline = "dpdaction = restart";
576
					else
577
						$dpdline = "dpdaction = clear";
578
					$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
579
					$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
580
					$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
581
				} else
582
					$dpdline = "dpdaction = none";
583

    
584
				$ikelifeline = '';
585
				if ($ph1ent['lifetime'])
586
					$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
587

    
588
				$authentication = "";
589
				switch ($ph1ent['authentication_method']) {
590
				case 'xauth_rsa_server':
591
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
592
					$authentication .= "\n\trightauth2 = xauth-generic";
593
					break;
594
				case 'xauth_psk_server':
595
					$authentication = "leftauth = psk\n\trightauth = psk";
596
					$authentication .= "\n\trightauth2 = xauth-generic";
597
					break;
598
				case 'pre_shared_key':
599
					$authentication = "leftauth = psk\n\trightauth = psk";
600
					break;
601
				case 'rsasig':
602
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
603
					break;
604
				case 'hybrid_rsa_server':
605
					$authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
606
					$authentication .= "\n\trightauth2 = xauth";
607
					break;
608
				}
609

    
610
				$left_spec = $ep;
611

    
612
				$ipseclifetime = 0;
613
				$rightsubnet_spec = array();
614
				$leftsubnet_spec = array();
615
				$ealgoAHsp2arr = array();
616
				$ealgoESPsp2arr = array();
617
			if (is_array($a_phase2) && count($a_phase2)) {
618
				foreach ($a_phase2 as $ph2ent) {
619
					$ikeid = $ph2ent['ikeid'];
620
					if ($ikeid != $ph1ent['ikeid'])
621
						continue;
622

    
623
					if (isset($ph2ent['disabled']))
624
						continue;
625

    
626
					if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
627
						continue;
628

    
629
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
630
						$tunneltype = "type = tunnel";
631

    
632
						$localid_type = $ph2ent['localid']['type'];
633
						$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
634
						/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
635
						if (($localid_type == "none" || $localid_type == "mobile")
636
						    && isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ikeid)==1)) {
637
							$left_spec = '%any';
638
						} else {
639
							if ($localid_type != "address") {
640
								$localid_type = "subnet";
641
							}
642
							// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
643
							if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) {
644
								log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
645
								continue;
646
							}
647
							if (!empty($ph2ent['natlocalid'])) {
648
								$natleftsubnet_data =  ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
649
								if ($ph2ent['natlocalid']['type'] != "address") {
650
									if (is_subnet($natleftsubnet_data))
651
										$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
652
								} else {
653
									if (is_ipaddr($natleftsubnet_data))
654
										$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
655
								}
656
								$natfilterrules = true;
657
							}
658
						}
659

    
660
						$leftsubnet_spec[] = $leftsubnet_data;
661

    
662
						if (!isset($ph2ent['mobile'])) {
663
							$rightsubnet_spec[] = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
664
						} else if (!empty($a_client['pool_address']))
665
							$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
666
					} else {
667
						$tunneltype = "type = transport";
668

    
669
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
670
						    ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) {
671
							$left_spec = "%any";
672
						} else {
673
							$leftsubnet_spec[] = ipsec_get_phase1_src($ph1ent);
674
						}
675

    
676
						if (!isset($ph2ent['mobile']))
677
							$rightsubnet_spec[] = $right_spec;
678
					}
679

    
680
					if (isset($a_client['pfs_group']))
681
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
682

    
683
					if ($ph2ent['protocol'] == 'esp') {
684
						if (is_array($ph2ent['encryption-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
685
							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
686
								$ealg_id = $ealg['name'];
687
								$ealg_kl = $ealg['keylen'];
688

    
689
								if (!empty($ealg_kl) && $ealg_kl == "auto") {
690
									if (empty($p2_ealgos) || !is_array($p2_ealgos))
691
										require("ipsec.inc");
692
									$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
693
									$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
694
									$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
695
									/* XXX: in some cases where include ordering is suspect these variables
696
									 * are somehow 0 and we enter this loop forever and timeout after 900
697
									 * seconds wrecking bootup */
698
									if ($key_hi != 0 and $key_lo !=0 and $key_step !=0) {
699
										for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
700
											foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
701
												$halgo = str_replace('hmac_', '', $halgo);
702
												$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
703
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
704
												if (!empty($modp))
705
													$tmpealgo .= "-{$modp}";
706
												$ealgoESPsp2arr[] = $tmpealgo;
707
											}
708
										}
709
									}
710
								} else {
711
									foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
712
										$halgo = str_replace('hmac_', '', $halgo);
713
										$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
714
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
715
										if (!empty($modp))
716
											$tmpealgo .= "-{$modp}";
717
										$ealgoESPsp2arr[] = $tmpealgo;
718
									}
719
								}
720
							}
721
						}
722
					} else if ($ph2ent['protocol'] == 'ah') {
723
						if (is_array($ph2ent['hash-algorithm-option'])) {
724
							$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
725
							foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
726
								$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
727
								if (!empty($modp))
728
									$tmpAHalgo = "-{$modp}";
729
								$ealgoAHsp2arr[] = $tmpAHalgo;
730
							}
731
						}
732
					}
733

    
734

    
735
					if (!empty($ph2ent['lifetime'])) {
736
						if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime']))
737
							$ipseclifetime = intval($ph2ent['lifetime']);
738
					}
739
				}
740
			}
741

    
742
				$ipsecconf .=<<<EOD
743

    
744
conn con{$ph1ent['ikeid']}
745
	aggressive = {$aggressive}
746
	fragmentation = yes
747
	keyexchange = {$keyexchange}
748
	reauth = yes
749
	rekey = yes
750
	reqid = {$ikeid}
751
	installpolicy = yes
752
	{$tunneltype}
753
	{$dpdline}
754
	auto = {$passive}
755
	left = {$left_spec}
756
	right = {$right_spec}
757
	leftid = {$myid_data}
758

    
759
EOD;
760

    
761
				if (!empty($ikelifeline))
762
					$ipsecconf .= "\t{$ikelifeline}\n";
763
				if ($ipseclifetime > 0)
764
					$ipsecconf .= "\tlifetime = {$ipseclifetime}s\n";
765
				if (!empty($rightsubnet_spec))
766
					$ipsecconf .= "\trightsubnet = " . join(",", $rightsubnet_spec) . "\n";
767
				if (!empty($leftsubnet_spec))
768
					$ipsecconf .= "\tleftsubnet = " . join(",", $leftsubnet_spec) . "\n";
769
				if (!empty($ealgosp1))
770
					$ipsecconf .= "\t{$ealgosp1}\n";
771
				if (!empty($ealgoAHsp2arr))
772
					$ipsecconf .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
773
				if (!empty($ealgoESPsp2arr))
774
					$ipsecconf .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
775
				if (!empty($authentication))
776
					$ipsecconf .= "\t{$authentication}\n";
777
				if (!empty($peerid_spec))
778
					$ipsecconf .= "\trightid = {$peerid_spec}\n";
779
			}
780
		}
781
	}
782
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
783
	unset($ipsecconf);
784
	/* end ipsec.conf */
785

    
786
	/* mange process */
787
	if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
788
		/* Read secrets */
789
		mwexec("/usr/local/sbin/ipsec rereadall", false);
790
		/* Update configuration changes */
791
		mwexec("/usr/local/sbin/ipsec reload", false);
792
	} else {
793
		mwexec("/usr/local/sbin/ipsec start", false); 
794
	}
795

    
796
	if ($natfilterrules == true)
797
		filter_configure();
798
	/* start filterdns, if necessary */
799
	if (count($filterdns_list) > 0) {
800
		$interval = 60;
801
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
802
			$interval = $ipseccfg['dns-interval'];
803

    
804
		$hostnames = "";
805
		array_unique($filterdns_list);
806
		foreach ($filterdns_list as $hostname)
807
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
808
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
809
		unset($hostnames);
810

    
811
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
812
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
813
		else {
814
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
815
		}
816
	} else {
817
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
818
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
819
	}
820

    
821
	if ($g['booting'])
822
		echo "done\n";
823

    
824
	return count($filterdns_list);
825
}
826

    
827
/*
828
 * Forcefully restart IPsec
829
 * This is required for when dynamic interfaces reload
830
 * For all other occasions the normal vpn_ipsec_configure()
831
 * will gracefully reload the settings without restarting
832
 */
833
function vpn_ipsec_force_reload($interface = "") {
834
	global $g, $config;
835

    
836
	$ipseccfg = $config['ipsec'];
837

    
838
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
839
		$found = false;
840
		foreach ($ipseccfg['phase1'] as $ipsec) {
841
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
842
				$found = true;
843
				break;
844
			}
845
		}
846
		if (!$found) {
847
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
848
			return;
849
		}
850
	}
851

    
852
	/* if ipsec is enabled, start up again */
853
	if (isset($ipseccfg['enable'])) {
854
		log_error(gettext("Forcefully reloading IPsec"));
855
		vpn_ipsec_configure();
856
	}
857
}
858

    
859
/* master setup for vpn (mpd) */
860
function vpn_setup() {
861
	global $g;
862

    
863
	if ($g['platform'] == 'jail')
864
		return;
865

    
866
	/* start pptpd */
867
	vpn_pptpd_configure();
868

    
869
	/* start pppoe server */
870
	vpn_pppoes_configure();
871

    
872
	/* setup l2tp */
873
	vpn_l2tp_configure();
874
}
875

    
876
function vpn_netgraph_support() {
877
	$iflist = get_configured_interface_list();
878
	foreach ($iflist as $iface) {
879
		$realif = get_real_interface($iface);
880
		/* Get support for netgraph(4) from the nic */
881
		$ifinfo = pfSense_get_interface_addresses($realif);
882
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
883
			pfSense_ngctl_attach(".", $realif);
884
	}
885
}
886

    
887
function vpn_pptpd_configure() {
888
	global $config, $g;
889

    
890
	$syscfg = $config['system'];
891
	$pptpdcfg = $config['pptpd'];
892

    
893
	if ($g['booting']) {
894
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
895
			return 0;
896

    
897
		echo gettext("Configuring PPTP VPN service... ");
898
	} else {
899
		/* kill mpd */
900
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
901

    
902
		/* wait for process to die */
903
		sleep(3);
904

    
905
		if (is_process_running("mpd -b")) {
906
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
907
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
908
		}
909

    
910
		/* remove mpd.conf, if it exists */
911
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
912
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
913
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
914
	}
915

    
916
	if (empty($pptpdcfg['n_pptp_units'])) {
917
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
918
		return;
919
	}
920

    
921
	/* make sure pptp-vpn directory exists */
922
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
923
		mkdir("{$g['varetc_path']}/pptp-vpn");
924

    
925
	switch ($pptpdcfg['mode']) {
926
		case 'server' :
927
			/* write mpd.conf */
928
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
929
			if (!$fd) {
930
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
931
				return 1;
932
			}
933

    
934
			$mpdconf = <<<EOD
935
pptps:
936

    
937
EOD;
938

    
939
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
940
				$mpdconf .= "	load pt{$i}\n";
941
			}
942

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

    
945
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
946

    
947
				$mpdconf .= <<<EOD
948

    
949
pt{$i}:
950
	new -i pptpd{$i} pt{$i} pt{$i}
951
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
952
	load pts
953

    
954
EOD;
955
			}
956

    
957
			$mpdconf .=<<<EOD
958

    
959
pts:
960
	set iface disable on-demand
961
	set iface enable proxy-arp
962
	set iface enable tcpmssfix
963
	set iface idle 1800
964
	set iface up-script /usr/local/sbin/vpn-linkup
965
	set iface down-script /usr/local/sbin/vpn-linkdown
966
	set bundle enable multilink
967
	set bundle enable crypt-reqd
968
	set link yes acfcomp protocomp
969
	set link no pap chap
970
	set link enable chap-msv2
971
	set link mtu 1460
972
	set link keep-alive 10 60
973
	set ipcp yes vjcomp
974
	set bundle enable compression
975
	set ccp yes mppc
976
	set ccp yes mpp-e128
977
	set ccp yes mpp-stateless
978

    
979
EOD;
980

    
981
			if (!isset ($pptpdcfg['req128'])) {
982
				$mpdconf .=<<<EOD
983
	set ccp yes mpp-e40
984
	set ccp yes mpp-e56
985

    
986
EOD;
987
			}
988

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

    
992
			if (!empty($pptpdcfg['dns1'])) {
993
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
994
				if (!empty($pptpdcfg['dns2']))
995
					$mpdconf .= " " . $pptpdcfg['dns2'];
996
				$mpdconf .= "\n";
997
			} elseif (isset ($config['dnsmasq']['enable'])) {
998
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
999
				if ($syscfg['dnsserver'][0])
1000
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1001
				$mpdconf .= "\n";
1002
			} elseif (isset($config['unbound']['enable'])) {
1003
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1004
				if ($syscfg['dnsserver'][0])
1005
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1006
				$mpdconf .= "\n";
1007
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1008
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1009
			}
1010

    
1011
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1012
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1013
				$acctport = $authport + 1;
1014
				$mpdconf .=<<<EOD
1015
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1016

    
1017
EOD;
1018
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1019
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1020
				$acctport = $authport + 1;
1021
				$mpdconf .=<<<EOD
1022
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1023

    
1024
EOD;
1025
			}
1026
			$mpdconf .=<<<EOD
1027
	set radius retries 3
1028
	set radius timeout 10
1029
	set auth enable radius-auth
1030

    
1031
EOD;
1032

    
1033
				if (isset ($pptpdcfg['radius']['accounting'])) {
1034
					$mpdconf .=<<<EOD
1035
	set auth enable radius-acct
1036
	set radius acct-update 300
1037

    
1038
EOD;
1039
				}
1040
			}
1041

    
1042
			fwrite($fd, $mpdconf);
1043
			fclose($fd);
1044
			unset($mpdconf);
1045

    
1046
			/* write mpd.links */
1047
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1048
			if (!$fd) {
1049
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1050
				return 1;
1051
			}
1052

    
1053
			$mpdlinks = "";
1054

    
1055
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1056
				$mpdlinks .=<<<EOD
1057

    
1058
pt{$i}:
1059
	set link type pptp
1060
	set pptp enable incoming
1061
	set pptp disable originate
1062
	set pptp disable windowing
1063

    
1064
EOD;
1065
			}
1066

    
1067
			fwrite($fd, $mpdlinks);
1068
			fclose($fd);
1069
			unset($mpdlinks);
1070

    
1071
			/* write mpd.secret */
1072
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1073
			if (!$fd) {
1074
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1075
				return 1;
1076
			}
1077

    
1078
			$mpdsecret = "";
1079

    
1080
			if (is_array($pptpdcfg['user'])) {
1081
				foreach ($pptpdcfg['user'] as $user) {
1082
					$pass = str_replace('\\', '\\\\', $user['password']);
1083
					$pass = str_replace('"', '\"', $pass);
1084
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1085
				}
1086
			}
1087

    
1088
			fwrite($fd, $mpdsecret);
1089
			fclose($fd);
1090
			unset($mpdsecret);
1091
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1092

    
1093
			vpn_netgraph_support();
1094

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

    
1098
			break;
1099

    
1100
		case 'redir' :
1101
			break;
1102
	}
1103

    
1104
	if ($g['booting'])
1105
		echo "done\n";
1106

    
1107
	return 0;
1108
}
1109

    
1110
function vpn_pppoes_configure() {
1111
	global $config;
1112

    
1113
	if (is_array($config['pppoes']['pppoe'])) {
1114
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1115
			vpn_pppoe_configure($pppoe);
1116
	}
1117
}
1118

    
1119
function vpn_pppoe_configure(&$pppoecfg) {
1120
	global $config, $g;
1121

    
1122
	$syscfg = $config['system'];
1123

    
1124
	/* create directory if it does not exist */
1125
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1126
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1127

    
1128
	if ($g['booting']) {
1129
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1130
			return 0;
1131

    
1132
		echo gettext("Configuring PPPoE VPN service... ");
1133
	} else {
1134
		/* kill mpd */
1135
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1136

    
1137
		/* wait for process to die */
1138
		sleep(2);
1139

    
1140
	}
1141

    
1142
	switch ($pppoecfg['mode']) {
1143

    
1144
		case 'server' :
1145

    
1146
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1147

    
1148
			if ($pppoecfg['paporchap'] == "chap")
1149
				$paporchap = "set link enable chap";
1150
			else
1151
				$paporchap = "set link enable pap";
1152

    
1153
			/* write mpd.conf */
1154
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1155
			if (!$fd) {
1156
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1157
				return 1;
1158
			}
1159
			$mpdconf = "\n\n";
1160
			$mpdconf .= "poes:\n";
1161

    
1162
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1163
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1164
			}
1165

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

    
1168
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1169

    
1170
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1171
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1172
				} else {
1173
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1174
				}
1175

    
1176
				$mpdconf .=<<<EOD
1177

    
1178
poes{$pppoecfg['pppoeid']}{$i}:
1179
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1180
	{$isssue_ip_type}
1181
	load pppoe_standard
1182

    
1183
EOD;
1184
			}
1185

    
1186
			$mpdconf .=<<<EOD
1187

    
1188
pppoe_standard:
1189
	set bundle no multilink
1190
	set bundle enable compression
1191
	set auth max-logins 1
1192
	set iface up-script /usr/local/sbin/vpn-linkup
1193
	set iface down-script /usr/local/sbin/vpn-linkdown
1194
	set iface idle 0
1195
	set iface disable on-demand
1196
	set iface disable proxy-arp
1197
	set iface enable tcpmssfix
1198
	set iface mtu 1500
1199
	set link no pap chap
1200
	{$paporchap}
1201
	set link keep-alive 60 180
1202
	set ipcp yes vjcomp
1203
	set ipcp no vjcomp
1204
	set link max-redial -1
1205
	set link mtu 1492
1206
	set link mru 1492
1207
	set ccp yes mpp-e40
1208
	set ccp yes mpp-e128
1209
	set ccp yes mpp-stateless
1210
	set link latency 1
1211
	#set ipcp dns 10.10.1.3
1212
	#set bundle accept encryption
1213

    
1214
EOD;
1215

    
1216
			if (!empty($pppoecfg['dns1'])) {
1217
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1218
				if (!empty($pppoecfg['dns2']))
1219
					$mpdconf .= " " . $pppoecfg['dns2'];
1220
				$mpdconf .= "\n";
1221
			} elseif (isset ($config['dnsmasq']['enable'])) {
1222
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1223
				if ($syscfg['dnsserver'][0])
1224
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1225
				$mpdconf .= "\n";
1226
			} elseif (isset ($config['unbound']['enable'])) {
1227
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1228
				if ($syscfg['dnsserver'][0])
1229
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1230
				$mpdconf .= "\n";
1231
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1232
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1233
			}
1234

    
1235
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1236
				$radiusport = "";
1237
				$radiusacctport = "";
1238
				if (isset($pppoecfg['radius']['server']['port']))
1239
					$radiusport = $pppoecfg['radius']['server']['port'];
1240
				if (isset($pppoecfg['radius']['server']['acctport']))
1241
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1242
				$mpdconf .=<<<EOD
1243
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1244
	set radius retries 3
1245
	set radius timeout 10
1246
	set auth enable radius-auth
1247

    
1248
EOD;
1249

    
1250
				if (isset ($pppoecfg['radius']['accounting'])) {
1251
					$mpdconf .=<<<EOD
1252
	set auth enable radius-acct
1253

    
1254
EOD;
1255
				}
1256
			}
1257

    
1258
			fwrite($fd, $mpdconf);
1259
			fclose($fd);
1260
			unset($mpdconf);
1261

    
1262
			/* write mpd.links */
1263
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1264
			if (!$fd) {
1265
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1266
				return 1;
1267
			}
1268

    
1269
			$mpdlinks = "";
1270

    
1271
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1272
				$mpdlinks .=<<<EOD
1273

    
1274
poes{$pppoecfg['pppoeid']}{$i}:
1275
	set phys type pppoe
1276
	set pppoe iface {$pppoe_interface}
1277
	set pppoe service "*"
1278
	set pppoe disable originate
1279
	set pppoe enable incoming
1280

    
1281
EOD;
1282
			}
1283

    
1284
			fwrite($fd, $mpdlinks);
1285
			fclose($fd);
1286
			unset($mpdlinks);
1287

    
1288
			if ($pppoecfg['username']) {
1289
				/* write mpd.secret */
1290
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1291
				if (!$fd) {
1292
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1293
					return 1;
1294
				}
1295

    
1296
				$mpdsecret = "\n\n";
1297

    
1298
				if (!empty($pppoecfg['username'])) {
1299
					$item = explode(" ", $pppoecfg['username']);
1300
					foreach($item as $userdata) {
1301
						$data = explode(":", $userdata);
1302
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1303
					}
1304
				}
1305

    
1306
				fwrite($fd, $mpdsecret);
1307
				fclose($fd);
1308
				unset($mpdsecret);
1309
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1310
			}
1311

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

    
1316
			/* Get support for netgraph(4) from the nic */
1317
			pfSense_ngctl_attach(".", $pppoe_interface);
1318
			/* fire up mpd */
1319
			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");
1320

    
1321
			break;
1322
	}
1323

    
1324
	if ($g['booting'])
1325
		echo gettext("done") . "\n";
1326

    
1327
	return 0;
1328
}
1329

    
1330
function vpn_l2tp_configure() {
1331
	global $config, $g;
1332

    
1333
	$syscfg = $config['system'];
1334
	$l2tpcfg = $config['l2tp'];
1335

    
1336
	/* create directory if it does not exist */
1337
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1338
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1339

    
1340
	if ($g['booting']) {
1341
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1342
			return 0;
1343

    
1344
		echo gettext("Configuring l2tp VPN service... ");
1345
	} else {
1346
		/* kill mpd */
1347
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1348

    
1349
		/* wait for process to die */
1350
		sleep(8);
1351

    
1352
	}
1353

    
1354
	/* make sure l2tp-vpn directory exists */
1355
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1356
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1357

    
1358
	switch ($l2tpcfg['mode']) {
1359

    
1360
		case 'server' :
1361
			if ($l2tpcfg['paporchap'] == "chap")
1362
				$paporchap = "set link enable chap";
1363
			else
1364
				$paporchap = "set link enable pap";
1365

    
1366
			/* write mpd.conf */
1367
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1368
			if (!$fd) {
1369
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1370
				return 1;
1371
			}
1372
			$mpdconf = "\n\n";
1373
			$mpdconf .=<<<EOD
1374
l2tps:
1375

    
1376
EOD;
1377

    
1378
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1379
				$mpdconf .= "	load l2tp{$i}\n";
1380
			}
1381

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

    
1384
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1385

    
1386
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1387
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1388
				} else {
1389
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1390
				}
1391

    
1392
				$mpdconf .=<<<EOD
1393

    
1394
l2tp{$i}:
1395
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1396
	{$isssue_ip_type}
1397
	load l2tp_standard
1398

    
1399
EOD;
1400
			}
1401

    
1402
			$mpdconf .=<<<EOD
1403

    
1404
l2tp_standard:
1405
	set bundle disable multilink
1406
	set bundle enable compression
1407
	set bundle yes crypt-reqd
1408
	set ipcp yes vjcomp
1409
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1410
	set ccp yes mppc
1411
	set iface disable on-demand
1412
	set iface enable proxy-arp
1413
	set iface up-script /usr/local/sbin/vpn-linkup
1414
	set iface down-script /usr/local/sbin/vpn-linkdown
1415
	set link yes acfcomp protocomp
1416
	set link no pap chap
1417
	set link enable chap
1418
	set link keep-alive 10 180
1419

    
1420
EOD;
1421

    
1422
			if (is_ipaddr($l2tpcfg['wins'])) {
1423
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1424
			}
1425
			if (is_ipaddr($l2tpcfg['dns1'])) {
1426
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1427
				if (is_ipaddr($l2tpcfg['dns2']))
1428
					$mpdconf .= " " . $l2tpcfg['dns2'];
1429
				$mpdconf .= "\n";
1430
			} elseif (isset ($config['dnsmasq']['enable'])) {
1431
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1432
				if ($syscfg['dnsserver'][0])
1433
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1434
				$mpdconf .= "\n";
1435
			} elseif (isset ($config['unbound']['enable'])) {
1436
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1437
				if ($syscfg['dnsserver'][0])
1438
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1439
				$mpdconf .= "\n";
1440
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1441
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1442
			}
1443

    
1444
			if (isset ($l2tpcfg['radius']['enable'])) {
1445
				$mpdconf .=<<<EOD
1446
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1447
	set radius retries 3
1448
	set radius timeout 10
1449
	set auth enable radius-auth
1450

    
1451
EOD;
1452

    
1453
				if (isset ($l2tpcfg['radius']['accounting'])) {
1454
					$mpdconf .=<<<EOD
1455
	set auth enable radius-acct
1456

    
1457
EOD;
1458
				}
1459
			}
1460

    
1461
			fwrite($fd, $mpdconf);
1462
			fclose($fd);
1463
			unset($mpdconf);
1464

    
1465
			/* write mpd.links */
1466
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1467
			if (!$fd) {
1468
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1469
				return 1;
1470
			}
1471

    
1472
			$mpdlinks = "";
1473

    
1474
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1475
				$mpdlinks .=<<<EOD
1476

    
1477
l2tp{$i}:
1478
	set link type l2tp
1479
	set l2tp enable incoming
1480
	set l2tp disable originate
1481

    
1482
EOD;
1483
			if (!empty($l2tpcfg['secret']))
1484
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1485
			}
1486

    
1487
			fwrite($fd, $mpdlinks);
1488
			fclose($fd);
1489
			unset($mpdlinks);
1490

    
1491
			/* write mpd.secret */
1492
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1493
			if (!$fd) {
1494
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1495
				return 1;
1496
			}
1497

    
1498
			$mpdsecret = "\n\n";
1499

    
1500
			if (is_array($l2tpcfg['user'])) {
1501
				foreach ($l2tpcfg['user'] as $user)
1502
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1503
			}
1504

    
1505
			fwrite($fd, $mpdsecret);
1506
			fclose($fd);
1507
			unset($mpdsecret);
1508
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1509

    
1510
			vpn_netgraph_support();
1511

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

    
1515
			break;
1516

    
1517
		case 'redir' :
1518
			break;
1519
	}
1520

    
1521
	if ($g['booting'])
1522
		echo "done\n";
1523

    
1524
	return 0;
1525
}
1526

    
1527
function vpn_ipsec_configure_preferoldsa() {
1528
	global $config;
1529
	if(isset($config['ipsec']['preferoldsa']))
1530
		set_single_sysctl("net.key.preferred_oldsa", "-30");
1531
	else
1532
		set_single_sysctl("net.key.preferred_oldsa", "0");
1533
}
1534

    
1535
?>
(59-59/68)