Projet

Général

Profil

Télécharger (45,6 ko) Statistiques
| Branche: | Tag: | Révision:

univnautes / etc / inc / vpn.inc @ 76fa9adb

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
				$ikeid = $ph1ent['ikeid'];
177
				$listeniflist = get_real_interface($a_phase1['interface']);
178

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

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

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

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

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

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

    
208
				if (is_array($a_phase2)) {
209
					/* step through each phase2 entry */
210
					foreach ($a_phase2 as $ph2ent) {
211
						if (isset($ph2ent['disabled']))
212
							continue;
213

    
214
						if ($ikeid != $ph2ent['ikeid'])
215
							continue;
216

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

    
271
		$strongswan = <<<EOD
272

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

    
278
charon {
279

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

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

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

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

    
302
EOD;
303

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
425
		$pskconf = "";
426

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

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

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

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

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

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

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

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

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

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

    
571
					$ealgosp1 .= "!";
572
				}
573

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

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

    
589
				$rightsourceip = NULL;
590
				if (!empty($a_client['pool_address'])) 
591
					$rightsourceip = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
592

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

    
615
				$left_spec = $ep;
616

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

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

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

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

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

    
664
						if (empty($leftsubnet_spec[$leftsubnet_data]))
665
							$leftsubnet_spec[$leftsubnet_data] = $leftsubnet_data;
666

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

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

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

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

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

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

    
763

    
764
					if (!empty($ph2ent['lifetime'])) {
765
						if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime']))
766
							$ipseclifetime = intval($ph2ent['lifetime']);
767
					}
768
				}
769
			}
770

    
771
				$ipsecconf .=<<<EOD
772

    
773
conn con{$ph1ent['ikeid']}
774
	aggressive = {$aggressive}
775
	fragmentation = yes
776
	keyexchange = {$keyexchange}
777
	reauth = yes
778
	rekey = yes
779
	reqid = {$ikeid}
780
	installpolicy = yes
781
	{$tunneltype}
782
	{$dpdline}
783
	auto = {$passive}
784
	left = {$left_spec}
785
	right = {$right_spec}
786
	leftid = {$myid_data}
787

    
788
EOD;
789

    
790
				if (!empty($ikelifeline))
791
					$ipsecconf .= "\t{$ikelifeline}\n";
792
				if ($ipseclifetime > 0)
793
					$ipsecconf .= "\tlifetime = {$ipseclifetime}s\n";
794
				if (!empty($rightsourceip))
795
					$ipsecconf .= "{$rightsourceip}";
796
				if (!empty($rightsubnet_spec))
797
					$ipsecconf .= "\trightsubnet = " . join(",", $rightsubnet_spec) . "\n";
798
				if (!empty($leftsubnet_spec))
799
					$ipsecconf .= "\tleftsubnet = " . join(",", $leftsubnet_spec) . "\n";
800
				if (!empty($ealgosp1))
801
					$ipsecconf .= "\t{$ealgosp1}\n";
802
				if (!empty($ealgoAHsp2arr))
803
					$ipsecconf .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
804
				if (!empty($ealgoESPsp2arr)) {
805
					file_put_contents("/var/etc/ipsec/dump_test", print_r($ealgoESPsp2arr, true));
806
					$ipsecconf .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
807
				}
808
				if (!empty($authentication))
809
					$ipsecconf .= "\t{$authentication}\n";
810
				if (!empty($peerid_spec))
811
					$ipsecconf .= "\trightid = {$peerid_spec}\n";
812
			}
813
		}
814
	}
815
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
816
	unset($ipsecconf);
817
	/* end ipsec.conf */
818

    
819
	/* mange process */
820
	if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
821
		/* Read secrets */
822
		mwexec("/usr/local/sbin/ipsec rereadall", false);
823
		/* Update configuration changes */
824
		mwexec("/usr/local/sbin/ipsec reload", false);
825
	} else {
826
		mwexec("/usr/local/sbin/ipsec start", false); 
827
	}
828

    
829
	if ($natfilterrules == true)
830
		filter_configure();
831
	/* start filterdns, if necessary */
832
	if (count($filterdns_list) > 0) {
833
		$interval = 60;
834
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
835
			$interval = $ipseccfg['dns-interval'];
836

    
837
		$hostnames = "";
838
		array_unique($filterdns_list);
839
		foreach ($filterdns_list as $hostname)
840
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
841
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
842
		unset($hostnames);
843

    
844
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
845
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
846
		else {
847
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
848
		}
849
	} else {
850
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
851
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
852
	}
853

    
854
	if ($g['booting'])
855
		echo "done\n";
856

    
857
	return count($filterdns_list);
858
}
859

    
860
/*
861
 * Forcefully restart IPsec
862
 * This is required for when dynamic interfaces reload
863
 * For all other occasions the normal vpn_ipsec_configure()
864
 * will gracefully reload the settings without restarting
865
 */
866
function vpn_ipsec_force_reload($interface = "") {
867
	global $g, $config;
868

    
869
	$ipseccfg = $config['ipsec'];
870

    
871
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
872
		$found = false;
873
		foreach ($ipseccfg['phase1'] as $ipsec) {
874
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
875
				$found = true;
876
				break;
877
			}
878
		}
879
		if (!$found) {
880
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
881
			return;
882
		}
883
	}
884

    
885
	/* if ipsec is enabled, start up again */
886
	if (isset($ipseccfg['enable'])) {
887
		log_error(gettext("Forcefully reloading IPsec"));
888
		vpn_ipsec_configure();
889
	}
890
}
891

    
892
/* master setup for vpn (mpd) */
893
function vpn_setup() {
894
	global $g;
895

    
896
	if ($g['platform'] == 'jail')
897
		return;
898

    
899
	/* start pptpd */
900
	vpn_pptpd_configure();
901

    
902
	/* start pppoe server */
903
	vpn_pppoes_configure();
904

    
905
	/* setup l2tp */
906
	vpn_l2tp_configure();
907
}
908

    
909
function vpn_netgraph_support() {
910
	$iflist = get_configured_interface_list();
911
	foreach ($iflist as $iface) {
912
		$realif = get_real_interface($iface);
913
		/* Get support for netgraph(4) from the nic */
914
		$ifinfo = pfSense_get_interface_addresses($realif);
915
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
916
			pfSense_ngctl_attach(".", $realif);
917
	}
918
}
919

    
920
function vpn_pptpd_configure() {
921
	global $config, $g;
922

    
923
	$syscfg = $config['system'];
924
	$pptpdcfg = $config['pptpd'];
925

    
926
	if ($g['booting']) {
927
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
928
			return 0;
929

    
930
		echo gettext("Configuring PPTP VPN service... ");
931
	} else {
932
		/* kill mpd */
933
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
934

    
935
		/* wait for process to die */
936
		sleep(3);
937

    
938
		if (is_process_running("mpd -b")) {
939
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
940
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
941
		}
942

    
943
		/* remove mpd.conf, if it exists */
944
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
945
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
946
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
947
	}
948

    
949
	if (empty($pptpdcfg['n_pptp_units'])) {
950
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
951
		return;
952
	}
953

    
954
	/* make sure pptp-vpn directory exists */
955
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
956
		mkdir("{$g['varetc_path']}/pptp-vpn");
957

    
958
	switch ($pptpdcfg['mode']) {
959
		case 'server' :
960
			/* write mpd.conf */
961
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
962
			if (!$fd) {
963
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
964
				return 1;
965
			}
966

    
967
			$mpdconf = <<<EOD
968
pptps:
969

    
970
EOD;
971

    
972
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
973
				$mpdconf .= "	load pt{$i}\n";
974
			}
975

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

    
978
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
979

    
980
				$mpdconf .= <<<EOD
981

    
982
pt{$i}:
983
	new -i pptpd{$i} pt{$i} pt{$i}
984
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
985
	load pts
986

    
987
EOD;
988
			}
989

    
990
			$mpdconf .=<<<EOD
991

    
992
pts:
993
	set iface disable on-demand
994
	set iface enable proxy-arp
995
	set iface enable tcpmssfix
996
	set iface idle 1800
997
	set iface up-script /usr/local/sbin/vpn-linkup
998
	set iface down-script /usr/local/sbin/vpn-linkdown
999
	set bundle enable multilink
1000
	set bundle enable crypt-reqd
1001
	set link yes acfcomp protocomp
1002
	set link no pap chap
1003
	set link enable chap-msv2
1004
	set link mtu 1460
1005
	set link keep-alive 10 60
1006
	set ipcp yes vjcomp
1007
	set bundle enable compression
1008
	set ccp yes mppc
1009
	set ccp yes mpp-e128
1010
	set ccp yes mpp-stateless
1011

    
1012
EOD;
1013

    
1014
			if (!isset ($pptpdcfg['req128'])) {
1015
				$mpdconf .=<<<EOD
1016
	set ccp yes mpp-e40
1017
	set ccp yes mpp-e56
1018

    
1019
EOD;
1020
			}
1021

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

    
1025
			if (!empty($pptpdcfg['dns1'])) {
1026
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1027
				if (!empty($pptpdcfg['dns2']))
1028
					$mpdconf .= " " . $pptpdcfg['dns2'];
1029
				$mpdconf .= "\n";
1030
			} elseif (isset ($config['dnsmasq']['enable'])) {
1031
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1032
				if ($syscfg['dnsserver'][0])
1033
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1034
				$mpdconf .= "\n";
1035
			} elseif (isset($config['unbound']['enable'])) {
1036
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1037
				if ($syscfg['dnsserver'][0])
1038
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1039
				$mpdconf .= "\n";
1040
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1041
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1042
			}
1043

    
1044
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1045
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1046
				$acctport = $authport + 1;
1047
				$mpdconf .=<<<EOD
1048
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1049

    
1050
EOD;
1051
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1052
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1053
				$acctport = $authport + 1;
1054
				$mpdconf .=<<<EOD
1055
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1056

    
1057
EOD;
1058
			}
1059
			$mpdconf .=<<<EOD
1060
	set radius retries 3
1061
	set radius timeout 10
1062
	set auth enable radius-auth
1063

    
1064
EOD;
1065

    
1066
				if (isset ($pptpdcfg['radius']['accounting'])) {
1067
					$mpdconf .=<<<EOD
1068
	set auth enable radius-acct
1069
	set radius acct-update 300
1070

    
1071
EOD;
1072
				}
1073
			}
1074

    
1075
			fwrite($fd, $mpdconf);
1076
			fclose($fd);
1077
			unset($mpdconf);
1078

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

    
1086
			$mpdlinks = "";
1087

    
1088
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1089
				$mpdlinks .=<<<EOD
1090

    
1091
pt{$i}:
1092
	set link type pptp
1093
	set pptp enable incoming
1094
	set pptp disable originate
1095
	set pptp disable windowing
1096

    
1097
EOD;
1098
			}
1099

    
1100
			fwrite($fd, $mpdlinks);
1101
			fclose($fd);
1102
			unset($mpdlinks);
1103

    
1104
			/* write mpd.secret */
1105
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1106
			if (!$fd) {
1107
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1108
				return 1;
1109
			}
1110

    
1111
			$mpdsecret = "";
1112

    
1113
			if (is_array($pptpdcfg['user'])) {
1114
				foreach ($pptpdcfg['user'] as $user) {
1115
					$pass = str_replace('\\', '\\\\', $user['password']);
1116
					$pass = str_replace('"', '\"', $pass);
1117
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1118
				}
1119
			}
1120

    
1121
			fwrite($fd, $mpdsecret);
1122
			fclose($fd);
1123
			unset($mpdsecret);
1124
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1125

    
1126
			vpn_netgraph_support();
1127

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

    
1131
			break;
1132

    
1133
		case 'redir' :
1134
			break;
1135
	}
1136

    
1137
	if ($g['booting'])
1138
		echo "done\n";
1139

    
1140
	return 0;
1141
}
1142

    
1143
function vpn_pppoes_configure() {
1144
	global $config;
1145

    
1146
	if (is_array($config['pppoes']['pppoe'])) {
1147
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1148
			vpn_pppoe_configure($pppoe);
1149
	}
1150
}
1151

    
1152
function vpn_pppoe_configure(&$pppoecfg) {
1153
	global $config, $g;
1154

    
1155
	$syscfg = $config['system'];
1156

    
1157
	/* create directory if it does not exist */
1158
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1159
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1160

    
1161
	if ($g['booting']) {
1162
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1163
			return 0;
1164

    
1165
		echo gettext("Configuring PPPoE VPN service... ");
1166
	} else {
1167
		/* kill mpd */
1168
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1169

    
1170
		/* wait for process to die */
1171
		sleep(2);
1172

    
1173
	}
1174

    
1175
	switch ($pppoecfg['mode']) {
1176

    
1177
		case 'server' :
1178

    
1179
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1180

    
1181
			if ($pppoecfg['paporchap'] == "chap")
1182
				$paporchap = "set link enable chap";
1183
			else
1184
				$paporchap = "set link enable pap";
1185

    
1186
			/* write mpd.conf */
1187
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1188
			if (!$fd) {
1189
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1190
				return 1;
1191
			}
1192
			$mpdconf = "\n\n";
1193
			$mpdconf .= "poes:\n";
1194

    
1195
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1196
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1197
			}
1198

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

    
1201
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1202

    
1203
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1204
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1205
				} else {
1206
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1207
				}
1208

    
1209
				$mpdconf .=<<<EOD
1210

    
1211
poes{$pppoecfg['pppoeid']}{$i}:
1212
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1213
	{$isssue_ip_type}
1214
	load pppoe_standard
1215

    
1216
EOD;
1217
			}
1218

    
1219
			$mpdconf .=<<<EOD
1220

    
1221
pppoe_standard:
1222
	set bundle no multilink
1223
	set bundle enable compression
1224
	set auth max-logins 1
1225
	set iface up-script /usr/local/sbin/vpn-linkup
1226
	set iface down-script /usr/local/sbin/vpn-linkdown
1227
	set iface idle 0
1228
	set iface disable on-demand
1229
	set iface disable proxy-arp
1230
	set iface enable tcpmssfix
1231
	set iface mtu 1500
1232
	set link no pap chap
1233
	{$paporchap}
1234
	set link keep-alive 60 180
1235
	set ipcp yes vjcomp
1236
	set ipcp no vjcomp
1237
	set link max-redial -1
1238
	set link mtu 1492
1239
	set link mru 1492
1240
	set ccp yes mpp-e40
1241
	set ccp yes mpp-e128
1242
	set ccp yes mpp-stateless
1243
	set link latency 1
1244
	#set ipcp dns 10.10.1.3
1245
	#set bundle accept encryption
1246

    
1247
EOD;
1248

    
1249
			if (!empty($pppoecfg['dns1'])) {
1250
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1251
				if (!empty($pppoecfg['dns2']))
1252
					$mpdconf .= " " . $pppoecfg['dns2'];
1253
				$mpdconf .= "\n";
1254
			} elseif (isset ($config['dnsmasq']['enable'])) {
1255
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1256
				if ($syscfg['dnsserver'][0])
1257
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1258
				$mpdconf .= "\n";
1259
			} elseif (isset ($config['unbound']['enable'])) {
1260
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1261
				if ($syscfg['dnsserver'][0])
1262
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1263
				$mpdconf .= "\n";
1264
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1265
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1266
			}
1267

    
1268
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1269
				$radiusport = "";
1270
				$radiusacctport = "";
1271
				if (isset($pppoecfg['radius']['server']['port']))
1272
					$radiusport = $pppoecfg['radius']['server']['port'];
1273
				if (isset($pppoecfg['radius']['server']['acctport']))
1274
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1275
				$mpdconf .=<<<EOD
1276
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1277
	set radius retries 3
1278
	set radius timeout 10
1279
	set auth enable radius-auth
1280

    
1281
EOD;
1282

    
1283
				if (isset ($pppoecfg['radius']['accounting'])) {
1284
					$mpdconf .=<<<EOD
1285
	set auth enable radius-acct
1286

    
1287
EOD;
1288
				}
1289
			}
1290

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

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

    
1302
			$mpdlinks = "";
1303

    
1304
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1305
				$mpdlinks .=<<<EOD
1306

    
1307
poes{$pppoecfg['pppoeid']}{$i}:
1308
	set phys type pppoe
1309
	set pppoe iface {$pppoe_interface}
1310
	set pppoe service "*"
1311
	set pppoe disable originate
1312
	set pppoe enable incoming
1313

    
1314
EOD;
1315
			}
1316

    
1317
			fwrite($fd, $mpdlinks);
1318
			fclose($fd);
1319
			unset($mpdlinks);
1320

    
1321
			if ($pppoecfg['username']) {
1322
				/* write mpd.secret */
1323
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1324
				if (!$fd) {
1325
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1326
					return 1;
1327
				}
1328

    
1329
				$mpdsecret = "\n\n";
1330

    
1331
				if (!empty($pppoecfg['username'])) {
1332
					$item = explode(" ", $pppoecfg['username']);
1333
					foreach($item as $userdata) {
1334
						$data = explode(":", $userdata);
1335
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1336
					}
1337
				}
1338

    
1339
				fwrite($fd, $mpdsecret);
1340
				fclose($fd);
1341
				unset($mpdsecret);
1342
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1343
			}
1344

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

    
1349
			/* Get support for netgraph(4) from the nic */
1350
			pfSense_ngctl_attach(".", $pppoe_interface);
1351
			/* fire up mpd */
1352
			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");
1353

    
1354
			break;
1355
	}
1356

    
1357
	if ($g['booting'])
1358
		echo gettext("done") . "\n";
1359

    
1360
	return 0;
1361
}
1362

    
1363
function vpn_l2tp_configure() {
1364
	global $config, $g;
1365

    
1366
	$syscfg = $config['system'];
1367
	$l2tpcfg = $config['l2tp'];
1368

    
1369
	/* create directory if it does not exist */
1370
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1371
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1372

    
1373
	if ($g['booting']) {
1374
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1375
			return 0;
1376

    
1377
		echo gettext("Configuring l2tp VPN service... ");
1378
	} else {
1379
		/* kill mpd */
1380
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1381

    
1382
		/* wait for process to die */
1383
		sleep(8);
1384

    
1385
	}
1386

    
1387
	/* make sure l2tp-vpn directory exists */
1388
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1389
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1390

    
1391
	switch ($l2tpcfg['mode']) {
1392

    
1393
		case 'server' :
1394
			if ($l2tpcfg['paporchap'] == "chap")
1395
				$paporchap = "set link enable chap";
1396
			else
1397
				$paporchap = "set link enable pap";
1398

    
1399
			/* write mpd.conf */
1400
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1401
			if (!$fd) {
1402
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1403
				return 1;
1404
			}
1405
			$mpdconf = "\n\n";
1406
			$mpdconf .=<<<EOD
1407
l2tps:
1408

    
1409
EOD;
1410

    
1411
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1412
				$mpdconf .= "	load l2tp{$i}\n";
1413
			}
1414

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

    
1417
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1418

    
1419
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1420
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1421
				} else {
1422
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1423
				}
1424

    
1425
				$mpdconf .=<<<EOD
1426

    
1427
l2tp{$i}:
1428
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1429
	{$isssue_ip_type}
1430
	load l2tp_standard
1431

    
1432
EOD;
1433
			}
1434

    
1435
			$mpdconf .=<<<EOD
1436

    
1437
l2tp_standard:
1438
	set bundle disable multilink
1439
	set bundle enable compression
1440
	set bundle yes crypt-reqd
1441
	set ipcp yes vjcomp
1442
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1443
	set ccp yes mppc
1444
	set iface disable on-demand
1445
	set iface enable proxy-arp
1446
	set iface up-script /usr/local/sbin/vpn-linkup
1447
	set iface down-script /usr/local/sbin/vpn-linkdown
1448
	set link yes acfcomp protocomp
1449
	set link no pap chap
1450
	set link enable chap
1451
	set link keep-alive 10 180
1452

    
1453
EOD;
1454

    
1455
			if (is_ipaddr($l2tpcfg['wins'])) {
1456
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1457
			}
1458
			if (is_ipaddr($l2tpcfg['dns1'])) {
1459
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1460
				if (is_ipaddr($l2tpcfg['dns2']))
1461
					$mpdconf .= " " . $l2tpcfg['dns2'];
1462
				$mpdconf .= "\n";
1463
			} elseif (isset ($config['dnsmasq']['enable'])) {
1464
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1465
				if ($syscfg['dnsserver'][0])
1466
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1467
				$mpdconf .= "\n";
1468
			} elseif (isset ($config['unbound']['enable'])) {
1469
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1470
				if ($syscfg['dnsserver'][0])
1471
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1472
				$mpdconf .= "\n";
1473
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1474
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1475
			}
1476

    
1477
			if (isset ($l2tpcfg['radius']['enable'])) {
1478
				$mpdconf .=<<<EOD
1479
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1480
	set radius retries 3
1481
	set radius timeout 10
1482
	set auth enable radius-auth
1483

    
1484
EOD;
1485

    
1486
				if (isset ($l2tpcfg['radius']['accounting'])) {
1487
					$mpdconf .=<<<EOD
1488
	set auth enable radius-acct
1489

    
1490
EOD;
1491
				}
1492
			}
1493

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

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

    
1505
			$mpdlinks = "";
1506

    
1507
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1508
				$mpdlinks .=<<<EOD
1509

    
1510
l2tp{$i}:
1511
	set link type l2tp
1512
	set l2tp enable incoming
1513
	set l2tp disable originate
1514

    
1515
EOD;
1516
			if (!empty($l2tpcfg['secret']))
1517
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1518
			}
1519

    
1520
			fwrite($fd, $mpdlinks);
1521
			fclose($fd);
1522
			unset($mpdlinks);
1523

    
1524
			/* write mpd.secret */
1525
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1526
			if (!$fd) {
1527
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1528
				return 1;
1529
			}
1530

    
1531
			$mpdsecret = "\n\n";
1532

    
1533
			if (is_array($l2tpcfg['user'])) {
1534
				foreach ($l2tpcfg['user'] as $user)
1535
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1536
			}
1537

    
1538
			fwrite($fd, $mpdsecret);
1539
			fclose($fd);
1540
			unset($mpdsecret);
1541
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1542

    
1543
			vpn_netgraph_support();
1544

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

    
1548
			break;
1549

    
1550
		case 'redir' :
1551
			break;
1552
	}
1553

    
1554
	if ($g['booting'])
1555
		echo "done\n";
1556

    
1557
	return 0;
1558
}
1559

    
1560
function vpn_ipsec_configure_preferoldsa() {
1561
	global $config;
1562
	if(isset($config['ipsec']['preferoldsa']))
1563
		set_single_sysctl("net.key.preferred_oldsa", "-30");
1564
	else
1565
		set_single_sysctl("net.key.preferred_oldsa", "0");
1566
}
1567

    
1568
?>
(59-59/68)