Projet

Général

Profil

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

univnautes / etc / inc / vpn.inc @ 5d37d515

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

    
613
				$left_spec = $ep;
614

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

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

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

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

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

    
663
						$leftsubnet_spec[] = $leftsubnet_data;
664

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

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

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

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

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

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

    
738

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

    
746
				$ipsecconf .=<<<EOD
747

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

    
763
EOD;
764

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

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

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

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

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

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

    
830
	return count($filterdns_list);
831
}
832

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
943
EOD;
944

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

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

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

    
953
				$mpdconf .= <<<EOD
954

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

    
960
EOD;
961
			}
962

    
963
			$mpdconf .=<<<EOD
964

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

    
985
EOD;
986

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

    
992
EOD;
993
			}
994

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

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

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

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

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

    
1037
EOD;
1038

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

    
1044
EOD;
1045
				}
1046
			}
1047

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

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

    
1059
			$mpdlinks = "";
1060

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

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

    
1070
EOD;
1071
			}
1072

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

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

    
1084
			$mpdsecret = "";
1085

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

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

    
1099
			vpn_netgraph_support();
1100

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

    
1104
			break;
1105

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

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

    
1113
	return 0;
1114
}
1115

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

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

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

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

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

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

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

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

    
1146
	}
1147

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

    
1150
		case 'server' :
1151

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

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

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

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

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

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

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

    
1182
				$mpdconf .=<<<EOD
1183

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

    
1189
EOD;
1190
			}
1191

    
1192
			$mpdconf .=<<<EOD
1193

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

    
1220
EOD;
1221

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

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

    
1254
EOD;
1255

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

    
1260
EOD;
1261
				}
1262
			}
1263

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

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

    
1275
			$mpdlinks = "";
1276

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

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

    
1287
EOD;
1288
			}
1289

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

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

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

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

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

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

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

    
1327
			break;
1328
	}
1329

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

    
1333
	return 0;
1334
}
1335

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

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

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

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

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

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

    
1358
	}
1359

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

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

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

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

    
1382
EOD;
1383

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

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

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

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

    
1398
				$mpdconf .=<<<EOD
1399

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

    
1405
EOD;
1406
			}
1407

    
1408
			$mpdconf .=<<<EOD
1409

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

    
1426
EOD;
1427

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

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

    
1457
EOD;
1458

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

    
1463
EOD;
1464
				}
1465
			}
1466

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

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

    
1478
			$mpdlinks = "";
1479

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

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

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

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

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

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

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

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

    
1516
			vpn_netgraph_support();
1517

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

    
1521
			break;
1522

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

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

    
1530
	return 0;
1531
}
1532

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

    
1541
?>
(59-59/68)