Projet

Général

Profil

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

univnautes / etc / inc / vpn.inc @ 7f1b720f

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
				$rightsourceip = NULL;
614
				$rightsubnet_spec = array();
615
				$leftsubnet_spec = array();
616
				$ealgoAHsp2arr = array();
617
				$ealgoESPsp2arr = array();
618
			if (is_array($a_phase2) && count($a_phase2)) {
619
				foreach ($a_phase2 as $ph2ent) {
620
					$ikeid = $ph2ent['ikeid'];
621
					if ($ikeid != $ph1ent['ikeid'])
622
						continue;
623

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

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

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

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

    
661
						$leftsubnet_spec[] = $leftsubnet_data;
662

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

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

    
679
						if (!isset($ph2ent['mobile']))
680
							$rightsubnet_spec[] = $right_spec;
681
					}
682

    
683
					if (isset($a_client['pfs_group']))
684
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
685

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

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

    
737

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

    
745
				$ipsecconf .=<<<EOD
746

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

    
762
EOD;
763

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

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

    
801
	if ($natfilterrules == true)
802
		filter_configure();
803
	/* start filterdns, if necessary */
804
	if (count($filterdns_list) > 0) {
805
		$interval = 60;
806
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
807
			$interval = $ipseccfg['dns-interval'];
808

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

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

    
826
	if ($g['booting'])
827
		echo "done\n";
828

    
829
	return count($filterdns_list);
830
}
831

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

    
841
	$ipseccfg = $config['ipsec'];
842

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

    
857
	/* if ipsec is enabled, start up again */
858
	if (isset($ipseccfg['enable'])) {
859
		log_error(gettext("Forcefully reloading IPsec"));
860
		vpn_ipsec_configure();
861
	}
862
}
863

    
864
/* master setup for vpn (mpd) */
865
function vpn_setup() {
866
	global $g;
867

    
868
	if ($g['platform'] == 'jail')
869
		return;
870

    
871
	/* start pptpd */
872
	vpn_pptpd_configure();
873

    
874
	/* start pppoe server */
875
	vpn_pppoes_configure();
876

    
877
	/* setup l2tp */
878
	vpn_l2tp_configure();
879
}
880

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

    
892
function vpn_pptpd_configure() {
893
	global $config, $g;
894

    
895
	$syscfg = $config['system'];
896
	$pptpdcfg = $config['pptpd'];
897

    
898
	if ($g['booting']) {
899
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
900
			return 0;
901

    
902
		echo gettext("Configuring PPTP VPN service... ");
903
	} else {
904
		/* kill mpd */
905
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
906

    
907
		/* wait for process to die */
908
		sleep(3);
909

    
910
		if (is_process_running("mpd -b")) {
911
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
912
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
913
		}
914

    
915
		/* remove mpd.conf, if it exists */
916
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
917
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
918
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
919
	}
920

    
921
	if (empty($pptpdcfg['n_pptp_units'])) {
922
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
923
		return;
924
	}
925

    
926
	/* make sure pptp-vpn directory exists */
927
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
928
		mkdir("{$g['varetc_path']}/pptp-vpn");
929

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

    
939
			$mpdconf = <<<EOD
940
pptps:
941

    
942
EOD;
943

    
944
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
945
				$mpdconf .= "	load pt{$i}\n";
946
			}
947

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

    
950
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
951

    
952
				$mpdconf .= <<<EOD
953

    
954
pt{$i}:
955
	new -i pptpd{$i} pt{$i} pt{$i}
956
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
957
	load pts
958

    
959
EOD;
960
			}
961

    
962
			$mpdconf .=<<<EOD
963

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

    
984
EOD;
985

    
986
			if (!isset ($pptpdcfg['req128'])) {
987
				$mpdconf .=<<<EOD
988
	set ccp yes mpp-e40
989
	set ccp yes mpp-e56
990

    
991
EOD;
992
			}
993

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

    
997
			if (!empty($pptpdcfg['dns1'])) {
998
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
999
				if (!empty($pptpdcfg['dns2']))
1000
					$mpdconf .= " " . $pptpdcfg['dns2'];
1001
				$mpdconf .= "\n";
1002
			} elseif (isset ($config['dnsmasq']['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 (isset($config['unbound']['enable'])) {
1008
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1009
				if ($syscfg['dnsserver'][0])
1010
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1011
				$mpdconf .= "\n";
1012
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1013
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1014
			}
1015

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

    
1022
EOD;
1023
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1024
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1025
				$acctport = $authport + 1;
1026
				$mpdconf .=<<<EOD
1027
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1028

    
1029
EOD;
1030
			}
1031
			$mpdconf .=<<<EOD
1032
	set radius retries 3
1033
	set radius timeout 10
1034
	set auth enable radius-auth
1035

    
1036
EOD;
1037

    
1038
				if (isset ($pptpdcfg['radius']['accounting'])) {
1039
					$mpdconf .=<<<EOD
1040
	set auth enable radius-acct
1041
	set radius acct-update 300
1042

    
1043
EOD;
1044
				}
1045
			}
1046

    
1047
			fwrite($fd, $mpdconf);
1048
			fclose($fd);
1049
			unset($mpdconf);
1050

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

    
1058
			$mpdlinks = "";
1059

    
1060
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1061
				$mpdlinks .=<<<EOD
1062

    
1063
pt{$i}:
1064
	set link type pptp
1065
	set pptp enable incoming
1066
	set pptp disable originate
1067
	set pptp disable windowing
1068

    
1069
EOD;
1070
			}
1071

    
1072
			fwrite($fd, $mpdlinks);
1073
			fclose($fd);
1074
			unset($mpdlinks);
1075

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

    
1083
			$mpdsecret = "";
1084

    
1085
			if (is_array($pptpdcfg['user'])) {
1086
				foreach ($pptpdcfg['user'] as $user) {
1087
					$pass = str_replace('\\', '\\\\', $user['password']);
1088
					$pass = str_replace('"', '\"', $pass);
1089
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1090
				}
1091
			}
1092

    
1093
			fwrite($fd, $mpdsecret);
1094
			fclose($fd);
1095
			unset($mpdsecret);
1096
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1097

    
1098
			vpn_netgraph_support();
1099

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

    
1103
			break;
1104

    
1105
		case 'redir' :
1106
			break;
1107
	}
1108

    
1109
	if ($g['booting'])
1110
		echo "done\n";
1111

    
1112
	return 0;
1113
}
1114

    
1115
function vpn_pppoes_configure() {
1116
	global $config;
1117

    
1118
	if (is_array($config['pppoes']['pppoe'])) {
1119
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1120
			vpn_pppoe_configure($pppoe);
1121
	}
1122
}
1123

    
1124
function vpn_pppoe_configure(&$pppoecfg) {
1125
	global $config, $g;
1126

    
1127
	$syscfg = $config['system'];
1128

    
1129
	/* create directory if it does not exist */
1130
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1131
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1132

    
1133
	if ($g['booting']) {
1134
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1135
			return 0;
1136

    
1137
		echo gettext("Configuring PPPoE VPN service... ");
1138
	} else {
1139
		/* kill mpd */
1140
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1141

    
1142
		/* wait for process to die */
1143
		sleep(2);
1144

    
1145
	}
1146

    
1147
	switch ($pppoecfg['mode']) {
1148

    
1149
		case 'server' :
1150

    
1151
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1152

    
1153
			if ($pppoecfg['paporchap'] == "chap")
1154
				$paporchap = "set link enable chap";
1155
			else
1156
				$paporchap = "set link enable pap";
1157

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

    
1167
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1168
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1169
			}
1170

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

    
1173
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1174

    
1175
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1176
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1177
				} else {
1178
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1179
				}
1180

    
1181
				$mpdconf .=<<<EOD
1182

    
1183
poes{$pppoecfg['pppoeid']}{$i}:
1184
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1185
	{$isssue_ip_type}
1186
	load pppoe_standard
1187

    
1188
EOD;
1189
			}
1190

    
1191
			$mpdconf .=<<<EOD
1192

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

    
1219
EOD;
1220

    
1221
			if (!empty($pppoecfg['dns1'])) {
1222
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1223
				if (!empty($pppoecfg['dns2']))
1224
					$mpdconf .= " " . $pppoecfg['dns2'];
1225
				$mpdconf .= "\n";
1226
			} elseif (isset ($config['dnsmasq']['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 (isset ($config['unbound']['enable'])) {
1232
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1233
				if ($syscfg['dnsserver'][0])
1234
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1235
				$mpdconf .= "\n";
1236
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1237
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1238
			}
1239

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

    
1253
EOD;
1254

    
1255
				if (isset ($pppoecfg['radius']['accounting'])) {
1256
					$mpdconf .=<<<EOD
1257
	set auth enable radius-acct
1258

    
1259
EOD;
1260
				}
1261
			}
1262

    
1263
			fwrite($fd, $mpdconf);
1264
			fclose($fd);
1265
			unset($mpdconf);
1266

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

    
1274
			$mpdlinks = "";
1275

    
1276
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1277
				$mpdlinks .=<<<EOD
1278

    
1279
poes{$pppoecfg['pppoeid']}{$i}:
1280
	set phys type pppoe
1281
	set pppoe iface {$pppoe_interface}
1282
	set pppoe service "*"
1283
	set pppoe disable originate
1284
	set pppoe enable incoming
1285

    
1286
EOD;
1287
			}
1288

    
1289
			fwrite($fd, $mpdlinks);
1290
			fclose($fd);
1291
			unset($mpdlinks);
1292

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

    
1301
				$mpdsecret = "\n\n";
1302

    
1303
				if (!empty($pppoecfg['username'])) {
1304
					$item = explode(" ", $pppoecfg['username']);
1305
					foreach($item as $userdata) {
1306
						$data = explode(":", $userdata);
1307
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1308
					}
1309
				}
1310

    
1311
				fwrite($fd, $mpdsecret);
1312
				fclose($fd);
1313
				unset($mpdsecret);
1314
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1315
			}
1316

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

    
1321
			/* Get support for netgraph(4) from the nic */
1322
			pfSense_ngctl_attach(".", $pppoe_interface);
1323
			/* fire up mpd */
1324
			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");
1325

    
1326
			break;
1327
	}
1328

    
1329
	if ($g['booting'])
1330
		echo gettext("done") . "\n";
1331

    
1332
	return 0;
1333
}
1334

    
1335
function vpn_l2tp_configure() {
1336
	global $config, $g;
1337

    
1338
	$syscfg = $config['system'];
1339
	$l2tpcfg = $config['l2tp'];
1340

    
1341
	/* create directory if it does not exist */
1342
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1343
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1344

    
1345
	if ($g['booting']) {
1346
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1347
			return 0;
1348

    
1349
		echo gettext("Configuring l2tp VPN service... ");
1350
	} else {
1351
		/* kill mpd */
1352
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1353

    
1354
		/* wait for process to die */
1355
		sleep(8);
1356

    
1357
	}
1358

    
1359
	/* make sure l2tp-vpn directory exists */
1360
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1361
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1362

    
1363
	switch ($l2tpcfg['mode']) {
1364

    
1365
		case 'server' :
1366
			if ($l2tpcfg['paporchap'] == "chap")
1367
				$paporchap = "set link enable chap";
1368
			else
1369
				$paporchap = "set link enable pap";
1370

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

    
1381
EOD;
1382

    
1383
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1384
				$mpdconf .= "	load l2tp{$i}\n";
1385
			}
1386

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

    
1389
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1390

    
1391
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1392
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1393
				} else {
1394
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1395
				}
1396

    
1397
				$mpdconf .=<<<EOD
1398

    
1399
l2tp{$i}:
1400
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1401
	{$isssue_ip_type}
1402
	load l2tp_standard
1403

    
1404
EOD;
1405
			}
1406

    
1407
			$mpdconf .=<<<EOD
1408

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

    
1425
EOD;
1426

    
1427
			if (is_ipaddr($l2tpcfg['wins'])) {
1428
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1429
			}
1430
			if (is_ipaddr($l2tpcfg['dns1'])) {
1431
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1432
				if (is_ipaddr($l2tpcfg['dns2']))
1433
					$mpdconf .= " " . $l2tpcfg['dns2'];
1434
				$mpdconf .= "\n";
1435
			} elseif (isset ($config['dnsmasq']['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 (isset ($config['unbound']['enable'])) {
1441
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1442
				if ($syscfg['dnsserver'][0])
1443
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1444
				$mpdconf .= "\n";
1445
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1446
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1447
			}
1448

    
1449
			if (isset ($l2tpcfg['radius']['enable'])) {
1450
				$mpdconf .=<<<EOD
1451
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1452
	set radius retries 3
1453
	set radius timeout 10
1454
	set auth enable radius-auth
1455

    
1456
EOD;
1457

    
1458
				if (isset ($l2tpcfg['radius']['accounting'])) {
1459
					$mpdconf .=<<<EOD
1460
	set auth enable radius-acct
1461

    
1462
EOD;
1463
				}
1464
			}
1465

    
1466
			fwrite($fd, $mpdconf);
1467
			fclose($fd);
1468
			unset($mpdconf);
1469

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

    
1477
			$mpdlinks = "";
1478

    
1479
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1480
				$mpdlinks .=<<<EOD
1481

    
1482
l2tp{$i}:
1483
	set link type l2tp
1484
	set l2tp enable incoming
1485
	set l2tp disable originate
1486

    
1487
EOD;
1488
			if (!empty($l2tpcfg['secret']))
1489
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1490
			}
1491

    
1492
			fwrite($fd, $mpdlinks);
1493
			fclose($fd);
1494
			unset($mpdlinks);
1495

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

    
1503
			$mpdsecret = "\n\n";
1504

    
1505
			if (is_array($l2tpcfg['user'])) {
1506
				foreach ($l2tpcfg['user'] as $user)
1507
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1508
			}
1509

    
1510
			fwrite($fd, $mpdsecret);
1511
			fclose($fd);
1512
			unset($mpdsecret);
1513
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1514

    
1515
			vpn_netgraph_support();
1516

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

    
1520
			break;
1521

    
1522
		case 'redir' :
1523
			break;
1524
	}
1525

    
1526
	if ($g['booting'])
1527
		echo "done\n";
1528

    
1529
	return 0;
1530
}
1531

    
1532
function vpn_ipsec_configure_preferoldsa() {
1533
	global $config;
1534
	if(isset($config['ipsec']['preferoldsa']))
1535
		set_single_sysctl("net.key.preferred_oldsa", "-30");
1536
	else
1537
		set_single_sysctl("net.key.preferred_oldsa", "0");
1538
}
1539

    
1540
?>
(59-59/68)