Projet

Général

Profil

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

univnautes / etc / inc / vpn.inc @ 3b68ec45

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
				$passive = "route";
537
				if (!empty($ph1ent['iketype']) && $ph1ent['iketype'] != "ikev1") {
538
					$keyexchange = "ikev2";
539
					//$passive = "start";
540
				} else
541
					$passive = "route";
542

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

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

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

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

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

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

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

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

    
589
				$authentication = "";
590
				$rightsourceip = NULL;
591
				switch ($ph1ent['authentication_method']) {
592
				case 'xauth_rsa_server':
593
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
594
					$authentication .= "\n\trightauth2 = xauth-generic";
595
					break;
596
				case 'xauth_psk_server':
597
					$authentication = "leftauth = psk\n\trightauth = psk";
598
					$authentication .= "\n\trightauth2 = xauth-generic";
599
					if (!empty($a_client['pool_address'])) 
600
						$rightsourceip = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
601
					break;
602
				case 'pre_shared_key':
603
					$authentication = "leftauth = psk\n\trightauth = psk";
604
					break;
605
				case 'rsasig':
606
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
607
					break;
608
				case 'hybrid_rsa_server':
609
					$authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
610
					$authentication .= "\n\trightauth2 = xauth";
611
					break;
612
				}
613

    
614
				$left_spec = $ep;
615

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

    
627
					if (isset($ph2ent['disabled']))
628
						continue;
629

    
630
					if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
631
						continue;
632

    
633
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
634
						$tunneltype = "type = tunnel";
635

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

    
664
						$leftsubnet_spec[] = $leftsubnet_data;
665

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

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

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

    
685
					if (isset($a_client['pfs_group']))
686
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
687

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

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

    
739

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

    
747
				$ipsecconf .=<<<EOD
748

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

    
764
EOD;
765

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

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

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

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

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

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

    
831
	return count($filterdns_list);
832
}
833

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

    
843
	$ipseccfg = $config['ipsec'];
844

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

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

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

    
870
	if ($g['platform'] == 'jail')
871
		return;
872

    
873
	/* start pptpd */
874
	vpn_pptpd_configure();
875

    
876
	/* start pppoe server */
877
	vpn_pppoes_configure();
878

    
879
	/* setup l2tp */
880
	vpn_l2tp_configure();
881
}
882

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

    
894
function vpn_pptpd_configure() {
895
	global $config, $g;
896

    
897
	$syscfg = $config['system'];
898
	$pptpdcfg = $config['pptpd'];
899

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

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

    
909
		/* wait for process to die */
910
		sleep(3);
911

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

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

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

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

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

    
941
			$mpdconf = <<<EOD
942
pptps:
943

    
944
EOD;
945

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

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

    
952
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
953

    
954
				$mpdconf .= <<<EOD
955

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

    
961
EOD;
962
			}
963

    
964
			$mpdconf .=<<<EOD
965

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

    
986
EOD;
987

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

    
993
EOD;
994
			}
995

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

    
999
			if (!empty($pptpdcfg['dns1'])) {
1000
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1001
				if (!empty($pptpdcfg['dns2']))
1002
					$mpdconf .= " " . $pptpdcfg['dns2'];
1003
				$mpdconf .= "\n";
1004
			} elseif (isset ($config['dnsmasq']['enable'])) {
1005
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1006
				if ($syscfg['dnsserver'][0])
1007
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1008
				$mpdconf .= "\n";
1009
			} elseif (isset($config['unbound']['enable'])) {
1010
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1011
				if ($syscfg['dnsserver'][0])
1012
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1013
				$mpdconf .= "\n";
1014
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1015
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1016
			}
1017

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

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

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

    
1038
EOD;
1039

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

    
1045
EOD;
1046
				}
1047
			}
1048

    
1049
			fwrite($fd, $mpdconf);
1050
			fclose($fd);
1051
			unset($mpdconf);
1052

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

    
1060
			$mpdlinks = "";
1061

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

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

    
1071
EOD;
1072
			}
1073

    
1074
			fwrite($fd, $mpdlinks);
1075
			fclose($fd);
1076
			unset($mpdlinks);
1077

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

    
1085
			$mpdsecret = "";
1086

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

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

    
1100
			vpn_netgraph_support();
1101

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

    
1105
			break;
1106

    
1107
		case 'redir' :
1108
			break;
1109
	}
1110

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

    
1114
	return 0;
1115
}
1116

    
1117
function vpn_pppoes_configure() {
1118
	global $config;
1119

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

    
1126
function vpn_pppoe_configure(&$pppoecfg) {
1127
	global $config, $g;
1128

    
1129
	$syscfg = $config['system'];
1130

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

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

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

    
1144
		/* wait for process to die */
1145
		sleep(2);
1146

    
1147
	}
1148

    
1149
	switch ($pppoecfg['mode']) {
1150

    
1151
		case 'server' :
1152

    
1153
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1154

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

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

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

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

    
1175
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1176

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

    
1183
				$mpdconf .=<<<EOD
1184

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

    
1190
EOD;
1191
			}
1192

    
1193
			$mpdconf .=<<<EOD
1194

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

    
1221
EOD;
1222

    
1223
			if (!empty($pppoecfg['dns1'])) {
1224
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1225
				if (!empty($pppoecfg['dns2']))
1226
					$mpdconf .= " " . $pppoecfg['dns2'];
1227
				$mpdconf .= "\n";
1228
			} elseif (isset ($config['dnsmasq']['enable'])) {
1229
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1230
				if ($syscfg['dnsserver'][0])
1231
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1232
				$mpdconf .= "\n";
1233
			} elseif (isset ($config['unbound']['enable'])) {
1234
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1235
				if ($syscfg['dnsserver'][0])
1236
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1237
				$mpdconf .= "\n";
1238
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1239
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1240
			}
1241

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

    
1255
EOD;
1256

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

    
1261
EOD;
1262
				}
1263
			}
1264

    
1265
			fwrite($fd, $mpdconf);
1266
			fclose($fd);
1267
			unset($mpdconf);
1268

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

    
1276
			$mpdlinks = "";
1277

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

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

    
1288
EOD;
1289
			}
1290

    
1291
			fwrite($fd, $mpdlinks);
1292
			fclose($fd);
1293
			unset($mpdlinks);
1294

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

    
1303
				$mpdsecret = "\n\n";
1304

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

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

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

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

    
1328
			break;
1329
	}
1330

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

    
1334
	return 0;
1335
}
1336

    
1337
function vpn_l2tp_configure() {
1338
	global $config, $g;
1339

    
1340
	$syscfg = $config['system'];
1341
	$l2tpcfg = $config['l2tp'];
1342

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

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

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

    
1356
		/* wait for process to die */
1357
		sleep(8);
1358

    
1359
	}
1360

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

    
1365
	switch ($l2tpcfg['mode']) {
1366

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

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

    
1383
EOD;
1384

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

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

    
1391
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1392

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

    
1399
				$mpdconf .=<<<EOD
1400

    
1401
l2tp{$i}:
1402
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1403
	{$isssue_ip_type}
1404
	load l2tp_standard
1405

    
1406
EOD;
1407
			}
1408

    
1409
			$mpdconf .=<<<EOD
1410

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

    
1427
EOD;
1428

    
1429
			if (is_ipaddr($l2tpcfg['wins'])) {
1430
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1431
			}
1432
			if (is_ipaddr($l2tpcfg['dns1'])) {
1433
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1434
				if (is_ipaddr($l2tpcfg['dns2']))
1435
					$mpdconf .= " " . $l2tpcfg['dns2'];
1436
				$mpdconf .= "\n";
1437
			} elseif (isset ($config['dnsmasq']['enable'])) {
1438
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1439
				if ($syscfg['dnsserver'][0])
1440
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1441
				$mpdconf .= "\n";
1442
			} elseif (isset ($config['unbound']['enable'])) {
1443
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1444
				if ($syscfg['dnsserver'][0])
1445
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1446
				$mpdconf .= "\n";
1447
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1448
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1449
			}
1450

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

    
1458
EOD;
1459

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

    
1464
EOD;
1465
				}
1466
			}
1467

    
1468
			fwrite($fd, $mpdconf);
1469
			fclose($fd);
1470
			unset($mpdconf);
1471

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

    
1479
			$mpdlinks = "";
1480

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

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

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

    
1494
			fwrite($fd, $mpdlinks);
1495
			fclose($fd);
1496
			unset($mpdlinks);
1497

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

    
1505
			$mpdsecret = "\n\n";
1506

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

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

    
1517
			vpn_netgraph_support();
1518

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

    
1522
			break;
1523

    
1524
		case 'redir' :
1525
			break;
1526
	}
1527

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

    
1531
	return 0;
1532
}
1533

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

    
1542
?>
(59-59/68)