Projet

Général

Profil

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

univnautes / etc / inc / vpn.inc @ ae170e96

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
						if (empty($leftsubnet_spec[$leftsubnet_data]))
664
							$leftsubnet_spec[$leftsubnet_data] = $leftsubnet_data;
665

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

    
677
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
678
						    ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) {
679
							$left_spec = "%any";
680
						} else {
681
							$tmpsubnet = ipsec_get_phase1_src($ph1ent);
682
							if ($leftsubnet_spec[$tmpsubnet])
683
								$leftsubnet_spec[$tmpsubnet] = $tmpsubnet;
684
						}
685

    
686
						if (!isset($ph2ent['mobile'])) {
687
							if (empty($rightsubnet_spec[$right_spec]))
688
								$rightsubnet_spec[$right_spec] = $right_spec;
689
						}
690
					}
691

    
692
					if (isset($a_client['pfs_group']))
693
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
694

    
695
					if ($ph2ent['protocol'] == 'esp') {
696
						if (is_array($ph2ent['encryption-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
697
							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
698
								$ealg_id = $ealg['name'];
699
								$ealg_kl = $ealg['keylen'];
700

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

    
746

    
747
					if (!empty($ph2ent['lifetime'])) {
748
						if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime']))
749
							$ipseclifetime = intval($ph2ent['lifetime']);
750
					}
751
				}
752
			}
753

    
754
				$ipsecconf .=<<<EOD
755

    
756
conn con{$ph1ent['ikeid']}
757
	aggressive = {$aggressive}
758
	fragmentation = yes
759
	keyexchange = {$keyexchange}
760
	reauth = yes
761
	rekey = yes
762
	reqid = {$ikeid}
763
	installpolicy = yes
764
	{$tunneltype}
765
	{$dpdline}
766
	auto = {$passive}
767
	left = {$left_spec}
768
	right = {$right_spec}
769
	leftid = {$myid_data}
770

    
771
EOD;
772

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

    
800
	/* mange process */
801
	if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
802
		/* Read secrets */
803
		mwexec("/usr/local/sbin/ipsec rereadall", false);
804
		/* Update configuration changes */
805
		mwexec("/usr/local/sbin/ipsec reload", false);
806
	} else {
807
		mwexec("/usr/local/sbin/ipsec start", false); 
808
	}
809

    
810
	if ($natfilterrules == true)
811
		filter_configure();
812
	/* start filterdns, if necessary */
813
	if (count($filterdns_list) > 0) {
814
		$interval = 60;
815
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
816
			$interval = $ipseccfg['dns-interval'];
817

    
818
		$hostnames = "";
819
		array_unique($filterdns_list);
820
		foreach ($filterdns_list as $hostname)
821
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
822
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
823
		unset($hostnames);
824

    
825
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
826
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
827
		else {
828
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
829
		}
830
	} else {
831
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
832
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
833
	}
834

    
835
	if ($g['booting'])
836
		echo "done\n";
837

    
838
	return count($filterdns_list);
839
}
840

    
841
/*
842
 * Forcefully restart IPsec
843
 * This is required for when dynamic interfaces reload
844
 * For all other occasions the normal vpn_ipsec_configure()
845
 * will gracefully reload the settings without restarting
846
 */
847
function vpn_ipsec_force_reload($interface = "") {
848
	global $g, $config;
849

    
850
	$ipseccfg = $config['ipsec'];
851

    
852
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
853
		$found = false;
854
		foreach ($ipseccfg['phase1'] as $ipsec) {
855
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
856
				$found = true;
857
				break;
858
			}
859
		}
860
		if (!$found) {
861
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
862
			return;
863
		}
864
	}
865

    
866
	/* if ipsec is enabled, start up again */
867
	if (isset($ipseccfg['enable'])) {
868
		log_error(gettext("Forcefully reloading IPsec"));
869
		vpn_ipsec_configure();
870
	}
871
}
872

    
873
/* master setup for vpn (mpd) */
874
function vpn_setup() {
875
	global $g;
876

    
877
	if ($g['platform'] == 'jail')
878
		return;
879

    
880
	/* start pptpd */
881
	vpn_pptpd_configure();
882

    
883
	/* start pppoe server */
884
	vpn_pppoes_configure();
885

    
886
	/* setup l2tp */
887
	vpn_l2tp_configure();
888
}
889

    
890
function vpn_netgraph_support() {
891
	$iflist = get_configured_interface_list();
892
	foreach ($iflist as $iface) {
893
		$realif = get_real_interface($iface);
894
		/* Get support for netgraph(4) from the nic */
895
		$ifinfo = pfSense_get_interface_addresses($realif);
896
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
897
			pfSense_ngctl_attach(".", $realif);
898
	}
899
}
900

    
901
function vpn_pptpd_configure() {
902
	global $config, $g;
903

    
904
	$syscfg = $config['system'];
905
	$pptpdcfg = $config['pptpd'];
906

    
907
	if ($g['booting']) {
908
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
909
			return 0;
910

    
911
		echo gettext("Configuring PPTP VPN service... ");
912
	} else {
913
		/* kill mpd */
914
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
915

    
916
		/* wait for process to die */
917
		sleep(3);
918

    
919
		if (is_process_running("mpd -b")) {
920
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
921
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
922
		}
923

    
924
		/* remove mpd.conf, if it exists */
925
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
926
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
927
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
928
	}
929

    
930
	if (empty($pptpdcfg['n_pptp_units'])) {
931
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
932
		return;
933
	}
934

    
935
	/* make sure pptp-vpn directory exists */
936
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
937
		mkdir("{$g['varetc_path']}/pptp-vpn");
938

    
939
	switch ($pptpdcfg['mode']) {
940
		case 'server' :
941
			/* write mpd.conf */
942
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
943
			if (!$fd) {
944
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
945
				return 1;
946
			}
947

    
948
			$mpdconf = <<<EOD
949
pptps:
950

    
951
EOD;
952

    
953
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
954
				$mpdconf .= "	load pt{$i}\n";
955
			}
956

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

    
959
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
960

    
961
				$mpdconf .= <<<EOD
962

    
963
pt{$i}:
964
	new -i pptpd{$i} pt{$i} pt{$i}
965
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
966
	load pts
967

    
968
EOD;
969
			}
970

    
971
			$mpdconf .=<<<EOD
972

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

    
993
EOD;
994

    
995
			if (!isset ($pptpdcfg['req128'])) {
996
				$mpdconf .=<<<EOD
997
	set ccp yes mpp-e40
998
	set ccp yes mpp-e56
999

    
1000
EOD;
1001
			}
1002

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

    
1006
			if (!empty($pptpdcfg['dns1'])) {
1007
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1008
				if (!empty($pptpdcfg['dns2']))
1009
					$mpdconf .= " " . $pptpdcfg['dns2'];
1010
				$mpdconf .= "\n";
1011
			} elseif (isset ($config['dnsmasq']['enable'])) {
1012
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1013
				if ($syscfg['dnsserver'][0])
1014
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1015
				$mpdconf .= "\n";
1016
			} elseif (isset($config['unbound']['enable'])) {
1017
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1018
				if ($syscfg['dnsserver'][0])
1019
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1020
				$mpdconf .= "\n";
1021
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1022
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1023
			}
1024

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

    
1031
EOD;
1032
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1033
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1034
				$acctport = $authport + 1;
1035
				$mpdconf .=<<<EOD
1036
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1037

    
1038
EOD;
1039
			}
1040
			$mpdconf .=<<<EOD
1041
	set radius retries 3
1042
	set radius timeout 10
1043
	set auth enable radius-auth
1044

    
1045
EOD;
1046

    
1047
				if (isset ($pptpdcfg['radius']['accounting'])) {
1048
					$mpdconf .=<<<EOD
1049
	set auth enable radius-acct
1050
	set radius acct-update 300
1051

    
1052
EOD;
1053
				}
1054
			}
1055

    
1056
			fwrite($fd, $mpdconf);
1057
			fclose($fd);
1058
			unset($mpdconf);
1059

    
1060
			/* write mpd.links */
1061
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1062
			if (!$fd) {
1063
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1064
				return 1;
1065
			}
1066

    
1067
			$mpdlinks = "";
1068

    
1069
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1070
				$mpdlinks .=<<<EOD
1071

    
1072
pt{$i}:
1073
	set link type pptp
1074
	set pptp enable incoming
1075
	set pptp disable originate
1076
	set pptp disable windowing
1077

    
1078
EOD;
1079
			}
1080

    
1081
			fwrite($fd, $mpdlinks);
1082
			fclose($fd);
1083
			unset($mpdlinks);
1084

    
1085
			/* write mpd.secret */
1086
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1087
			if (!$fd) {
1088
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1089
				return 1;
1090
			}
1091

    
1092
			$mpdsecret = "";
1093

    
1094
			if (is_array($pptpdcfg['user'])) {
1095
				foreach ($pptpdcfg['user'] as $user) {
1096
					$pass = str_replace('\\', '\\\\', $user['password']);
1097
					$pass = str_replace('"', '\"', $pass);
1098
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1099
				}
1100
			}
1101

    
1102
			fwrite($fd, $mpdsecret);
1103
			fclose($fd);
1104
			unset($mpdsecret);
1105
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1106

    
1107
			vpn_netgraph_support();
1108

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

    
1112
			break;
1113

    
1114
		case 'redir' :
1115
			break;
1116
	}
1117

    
1118
	if ($g['booting'])
1119
		echo "done\n";
1120

    
1121
	return 0;
1122
}
1123

    
1124
function vpn_pppoes_configure() {
1125
	global $config;
1126

    
1127
	if (is_array($config['pppoes']['pppoe'])) {
1128
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1129
			vpn_pppoe_configure($pppoe);
1130
	}
1131
}
1132

    
1133
function vpn_pppoe_configure(&$pppoecfg) {
1134
	global $config, $g;
1135

    
1136
	$syscfg = $config['system'];
1137

    
1138
	/* create directory if it does not exist */
1139
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1140
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1141

    
1142
	if ($g['booting']) {
1143
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1144
			return 0;
1145

    
1146
		echo gettext("Configuring PPPoE VPN service... ");
1147
	} else {
1148
		/* kill mpd */
1149
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1150

    
1151
		/* wait for process to die */
1152
		sleep(2);
1153

    
1154
	}
1155

    
1156
	switch ($pppoecfg['mode']) {
1157

    
1158
		case 'server' :
1159

    
1160
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1161

    
1162
			if ($pppoecfg['paporchap'] == "chap")
1163
				$paporchap = "set link enable chap";
1164
			else
1165
				$paporchap = "set link enable pap";
1166

    
1167
			/* write mpd.conf */
1168
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1169
			if (!$fd) {
1170
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1171
				return 1;
1172
			}
1173
			$mpdconf = "\n\n";
1174
			$mpdconf .= "poes:\n";
1175

    
1176
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1177
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1178
			}
1179

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

    
1182
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1183

    
1184
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1185
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1186
				} else {
1187
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1188
				}
1189

    
1190
				$mpdconf .=<<<EOD
1191

    
1192
poes{$pppoecfg['pppoeid']}{$i}:
1193
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1194
	{$isssue_ip_type}
1195
	load pppoe_standard
1196

    
1197
EOD;
1198
			}
1199

    
1200
			$mpdconf .=<<<EOD
1201

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

    
1228
EOD;
1229

    
1230
			if (!empty($pppoecfg['dns1'])) {
1231
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1232
				if (!empty($pppoecfg['dns2']))
1233
					$mpdconf .= " " . $pppoecfg['dns2'];
1234
				$mpdconf .= "\n";
1235
			} elseif (isset ($config['dnsmasq']['enable'])) {
1236
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1237
				if ($syscfg['dnsserver'][0])
1238
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1239
				$mpdconf .= "\n";
1240
			} elseif (isset ($config['unbound']['enable'])) {
1241
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1242
				if ($syscfg['dnsserver'][0])
1243
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1244
				$mpdconf .= "\n";
1245
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1246
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1247
			}
1248

    
1249
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1250
				$radiusport = "";
1251
				$radiusacctport = "";
1252
				if (isset($pppoecfg['radius']['server']['port']))
1253
					$radiusport = $pppoecfg['radius']['server']['port'];
1254
				if (isset($pppoecfg['radius']['server']['acctport']))
1255
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1256
				$mpdconf .=<<<EOD
1257
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1258
	set radius retries 3
1259
	set radius timeout 10
1260
	set auth enable radius-auth
1261

    
1262
EOD;
1263

    
1264
				if (isset ($pppoecfg['radius']['accounting'])) {
1265
					$mpdconf .=<<<EOD
1266
	set auth enable radius-acct
1267

    
1268
EOD;
1269
				}
1270
			}
1271

    
1272
			fwrite($fd, $mpdconf);
1273
			fclose($fd);
1274
			unset($mpdconf);
1275

    
1276
			/* write mpd.links */
1277
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1278
			if (!$fd) {
1279
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1280
				return 1;
1281
			}
1282

    
1283
			$mpdlinks = "";
1284

    
1285
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1286
				$mpdlinks .=<<<EOD
1287

    
1288
poes{$pppoecfg['pppoeid']}{$i}:
1289
	set phys type pppoe
1290
	set pppoe iface {$pppoe_interface}
1291
	set pppoe service "*"
1292
	set pppoe disable originate
1293
	set pppoe enable incoming
1294

    
1295
EOD;
1296
			}
1297

    
1298
			fwrite($fd, $mpdlinks);
1299
			fclose($fd);
1300
			unset($mpdlinks);
1301

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

    
1310
				$mpdsecret = "\n\n";
1311

    
1312
				if (!empty($pppoecfg['username'])) {
1313
					$item = explode(" ", $pppoecfg['username']);
1314
					foreach($item as $userdata) {
1315
						$data = explode(":", $userdata);
1316
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1317
					}
1318
				}
1319

    
1320
				fwrite($fd, $mpdsecret);
1321
				fclose($fd);
1322
				unset($mpdsecret);
1323
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1324
			}
1325

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

    
1330
			/* Get support for netgraph(4) from the nic */
1331
			pfSense_ngctl_attach(".", $pppoe_interface);
1332
			/* fire up mpd */
1333
			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");
1334

    
1335
			break;
1336
	}
1337

    
1338
	if ($g['booting'])
1339
		echo gettext("done") . "\n";
1340

    
1341
	return 0;
1342
}
1343

    
1344
function vpn_l2tp_configure() {
1345
	global $config, $g;
1346

    
1347
	$syscfg = $config['system'];
1348
	$l2tpcfg = $config['l2tp'];
1349

    
1350
	/* create directory if it does not exist */
1351
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1352
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1353

    
1354
	if ($g['booting']) {
1355
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1356
			return 0;
1357

    
1358
		echo gettext("Configuring l2tp VPN service... ");
1359
	} else {
1360
		/* kill mpd */
1361
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1362

    
1363
		/* wait for process to die */
1364
		sleep(8);
1365

    
1366
	}
1367

    
1368
	/* make sure l2tp-vpn directory exists */
1369
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1370
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1371

    
1372
	switch ($l2tpcfg['mode']) {
1373

    
1374
		case 'server' :
1375
			if ($l2tpcfg['paporchap'] == "chap")
1376
				$paporchap = "set link enable chap";
1377
			else
1378
				$paporchap = "set link enable pap";
1379

    
1380
			/* write mpd.conf */
1381
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1382
			if (!$fd) {
1383
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1384
				return 1;
1385
			}
1386
			$mpdconf = "\n\n";
1387
			$mpdconf .=<<<EOD
1388
l2tps:
1389

    
1390
EOD;
1391

    
1392
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1393
				$mpdconf .= "	load l2tp{$i}\n";
1394
			}
1395

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

    
1398
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1399

    
1400
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1401
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1402
				} else {
1403
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1404
				}
1405

    
1406
				$mpdconf .=<<<EOD
1407

    
1408
l2tp{$i}:
1409
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1410
	{$isssue_ip_type}
1411
	load l2tp_standard
1412

    
1413
EOD;
1414
			}
1415

    
1416
			$mpdconf .=<<<EOD
1417

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

    
1434
EOD;
1435

    
1436
			if (is_ipaddr($l2tpcfg['wins'])) {
1437
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1438
			}
1439
			if (is_ipaddr($l2tpcfg['dns1'])) {
1440
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1441
				if (is_ipaddr($l2tpcfg['dns2']))
1442
					$mpdconf .= " " . $l2tpcfg['dns2'];
1443
				$mpdconf .= "\n";
1444
			} elseif (isset ($config['dnsmasq']['enable'])) {
1445
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1446
				if ($syscfg['dnsserver'][0])
1447
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1448
				$mpdconf .= "\n";
1449
			} elseif (isset ($config['unbound']['enable'])) {
1450
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1451
				if ($syscfg['dnsserver'][0])
1452
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1453
				$mpdconf .= "\n";
1454
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1455
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1456
			}
1457

    
1458
			if (isset ($l2tpcfg['radius']['enable'])) {
1459
				$mpdconf .=<<<EOD
1460
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1461
	set radius retries 3
1462
	set radius timeout 10
1463
	set auth enable radius-auth
1464

    
1465
EOD;
1466

    
1467
				if (isset ($l2tpcfg['radius']['accounting'])) {
1468
					$mpdconf .=<<<EOD
1469
	set auth enable radius-acct
1470

    
1471
EOD;
1472
				}
1473
			}
1474

    
1475
			fwrite($fd, $mpdconf);
1476
			fclose($fd);
1477
			unset($mpdconf);
1478

    
1479
			/* write mpd.links */
1480
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1481
			if (!$fd) {
1482
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1483
				return 1;
1484
			}
1485

    
1486
			$mpdlinks = "";
1487

    
1488
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1489
				$mpdlinks .=<<<EOD
1490

    
1491
l2tp{$i}:
1492
	set link type l2tp
1493
	set l2tp enable incoming
1494
	set l2tp disable originate
1495

    
1496
EOD;
1497
			if (!empty($l2tpcfg['secret']))
1498
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1499
			}
1500

    
1501
			fwrite($fd, $mpdlinks);
1502
			fclose($fd);
1503
			unset($mpdlinks);
1504

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

    
1512
			$mpdsecret = "\n\n";
1513

    
1514
			if (is_array($l2tpcfg['user'])) {
1515
				foreach ($l2tpcfg['user'] as $user)
1516
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1517
			}
1518

    
1519
			fwrite($fd, $mpdsecret);
1520
			fclose($fd);
1521
			unset($mpdsecret);
1522
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1523

    
1524
			vpn_netgraph_support();
1525

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

    
1529
			break;
1530

    
1531
		case 'redir' :
1532
			break;
1533
	}
1534

    
1535
	if ($g['booting'])
1536
		echo "done\n";
1537

    
1538
	return 0;
1539
}
1540

    
1541
function vpn_ipsec_configure_preferoldsa() {
1542
	global $config;
1543
	if(isset($config['ipsec']['preferoldsa']))
1544
		set_single_sysctl("net.key.preferred_oldsa", "-30");
1545
	else
1546
		set_single_sysctl("net.key.preferred_oldsa", "0");
1547
}
1548

    
1549
?>
(59-59/68)