Projet

Général

Profil

Télécharger (43,5 ko) Statistiques
| Branche: | Tag: | Révision:

univnautes / etc / inc / vpn.inc @ 75786d2a

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	/sbin/sysctl
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
		exec("/sbin/sysctl net.inet.ip.ipsec_in_use=0");
128

    
129
		return 0;
130
	} else {
131
		mwexec("/sbin/ifconfig enc0 up");
132
		mwexec("/sbin/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
		mwexec("/sbin/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
							foreach ($iflist as $ifent => $ifname) {
223
								if(is_ipaddrv6($ph2ent['pinghost'])) {
224
									$interface_ip = get_interface_ipv6($ifent);
225
									if(!is_ipaddrv6($interface_ip))
226
										continue;
227
									$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
228
									if (ip_in_subnet($interface_ip, $local_subnet)) {
229
										$srcip = $interface_ip;
230
										break;
231
									}
232
								} else {
233
									$interface_ip = get_interface_ip($ifent);
234
									if(!is_ipaddrv4($interface_ip))
235
										continue;
236
									$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
237
									if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) {
238
										$srcip = $interface_ip;
239
										break;
240
									}
241
								}
242
							}
243
							$dstip = $ph2ent['pinghost'];
244
							if(is_ipaddrv6($dstip)) {
245
								$family = "inet6";
246
							} else {
247
								$family = "inet";
248
							}
249
							if (is_ipaddr($srcip))
250
								$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
251
						}
252
					}
253
				}
254
			}
255
			@file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
256
			unset($ipsecpinghosts);
257
		}
258
		unset($iflist);
259

    
260
		$strongswan = <<<EOD
261

    
262
#Automatically generated please do not modify
263
starter {
264
    load_warning = no
265
}
266

    
267
charon {
268

    
269
        # number of worker threads in charon
270
        threads = 16
271

    
272
	# XXX: There is not much choice here really users win their security!
273
	i_dont_care_about_security_and_use_aggressive_mode_psk=yes
274

    
275
	# And two loggers using syslog. The subsections define the facility to log
276
	# to, currently one of: daemon, auth.
277
	syslog {
278

    
279
		identifier = charon
280
		# default level to the LOG_DAEMON facility
281
		daemon {
282
		}
283
		# very minimalistic IKE auditing logs to LOG_AUTHPRIV
284
		auth {
285
		    default = -1
286
		    ike = 1
287
		    ike_name = yes
288
		}
289
	}
290

    
291
EOD;
292

    
293
		if (is_array($a_client) && isset($a_client['enable']) && isset($a_client['net_list']))
294
			$strongswan .= "\tcisco_unity = yes\n";
295

    
296
		$strongswan .= "\tplugins {\n";
297

    
298
		if (is_array($a_client) && isset($a_client['enable'])) {
299
			$strongswan .= "\t\tattr {\n";
300
			if ($a_client['pool_address'] && $a_client['pool_netbits'])
301
				$strongswan .= "\t\tsubnet = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
302

    
303
			$cfgservers = array();
304
			if (!empty($a_client['dns_server1']))
305
				$cfgservers[] = $a_client['dns_server1'];
306
			if (!empty($a_client['dns_server2']))
307
				$cfgservers[] = $a_client['dns_server2'];
308
			if (!empty($a_client['dns_server3']))
309
				$cfgservers[] = $a_client['dns_server3'];
310
			if (!empty($a_client['dns_server4']))
311
				$cfgservers[] = $a_client['dns_server4'];
312

    
313
			if (!empty($cfgservers))
314
				$strongswan .= "\t\tdns = " . implode(",", $cfgservers) . "\n";
315
			unset($cfgservers);
316
			$cfgservers = array();
317
			if (!empty($a_client['wins_server1']))
318
				$cfgservers[] = $a_client['wins_server1'];
319
			if (!empty($a_client['wins_server2']))
320
				$cfgservers[] = $a_client['wins_server2'];
321
			if (!empty($cfgservers))
322
				$strongswan .= "\t\tnbns = " . implode(",", $cfgservers) . "\n";
323
			unset($cfgservers);
324

    
325
			if (isset($a_client['net_list'])) {
326
				$net_list = '';
327
				foreach ($a_phase2 as $ph2ent) {
328
					if (isset($ph2ent['disabled']))
329
						continue;
330

    
331
					if (!isset($ph2ent['mobile']))
332
						continue;
333

    
334
					$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
335

    
336
					if (!empty($net_list))
337
						$net_list .= ",";
338
					$net_list .= $localid;
339
				}
340

    
341
				if (!empty($net_list)) {
342
					$strongswan .= "\t\tsplit-include = {$net_list}\n";
343
					unset($net_list);
344
				}
345
			}
346

    
347
			if (!empty($a_client['dns_domain'])) {
348
				$strongswan .= "\t\t# Search domain and default domain\n";
349
				$strongswan .= "\t\t28674 = {$a_client['dns_domain']}\n";
350
				if (empty($a_client['dns_split']))
351
					$strongswan .= "\t\t28675 = {$a_client['dns_domain']}";
352
				$strongswan .= "\n";
353
			}
354

    
355
			if (!empty($a_client['dns_split'])) {
356
				$strongswan .= "\t\t28675 = {$a_client['dns_split']}\n";
357
			}
358

    
359
			if (!empty($a_client['login_banner']))
360
				$strongswan .= "\t\t28672 = {$a_client['login_banner']}\n";
361

    
362
			if (isset($a_client['save_passwd']))
363
				$strongswan .= "\t\t28673 = yes\n";
364

    
365
			if ($a_client['pfs_group'])
366
				$strongswan .= "\t\t28679 = {$a_client['pfs_group']}\n";
367
			$strongswan .= "\t\t}\n";
368

    
369
			if ($a_client['user_source'] != "none") {
370
				$strongswan .= "\txauth-generic {\n";
371
				$strongswan .= "\t\tscript = /etc/inc/ipsec.auth-user.php\n";
372
				$strongswan .= "\t\tauthcfg = ";
373
				$firstsed = 0;
374
				$authcfgs = explode(",", $a_client['user_source']);
375
				foreach ($authcfgs as $authcfg) {
376
					if ($firstsed > 0)
377
						$strongswan .= ",";
378
					if ($authcfg == "system")
379
						$authcfg = "Local Database";
380
					$strongswan .= $authcfg;
381
					$firstsed = 1;
382
				}
383
				$strongswan .= "\n";
384
				$strongswan .= "\t}\n";
385
			}
386
		}
387

    
388
		$strongswan .= "\t}\n}\n";
389
		@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
390
		unset($strongswan);
391

    
392
		/* generate CA certificates files */
393
		if (is_array($config['ca']) && count($config['ca'])) {
394
			foreach ($config['ca'] as $ca) {
395
				if (!isset($ca['crt'])) {
396
					log_error(sprintf(gettext("Error: Invalid certificate info for %s"), $ca['descr']));
397
					continue;
398
				}
399
				$cert = base64_decode($ca['crt']);
400
				$x509cert = openssl_x509_parse(openssl_x509_read($cert));
401
				if (!is_array($x509cert) || !isset($x509cert['hash'])) {
402
					log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $ca['descr']));
403
					continue;
404
				}
405
				$fname = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts/{$x509cert['hash']}.0";
406
				if (!@file_put_contents($fname, $cert)) {
407
					log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $ca['descr']));
408
					continue;
409
				}
410
				unset($cert);
411
			}
412
		}
413

    
414
		$pskconf = "";
415

    
416
		if (is_array($a_phase1) && count($a_phase1)) {
417
			foreach ($a_phase1 as $ph1ent) {
418

    
419
				if (isset($ph1ent['disabled']))
420
					continue;
421

    
422
				if (strstr($ph1ent['authentication_method'],'rsa')) {
423
					$certline = '';
424

    
425
					if (strstr($authmethod,'rsa')) {
426

    
427
						$cert = lookup_cert($ph1ent['certref']);
428

    
429
						if (!$cert) {
430
							log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
431
							continue;
432
						}
433

    
434
						chmod($certpath, 0600);
435

    
436
						$keyfile = "cert-{$ikeid}.key";
437
						$keypath = "{$g['varetc_path']}/ipsec/{$keyfile}";
438

    
439
						if (!file_put_contents($keypath, base64_decode($cert['prv']))) {
440
							log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
441
							continue;
442
						}
443

    
444
						chmod($keypath, 0600);
445
						/* XXX" Traffic selectors? */
446
						$pskconf .= " : RSA {$keypath}\n";
447

    
448
						$ca = lookup_ca($ph1ent['caref']);
449
						if ($ca) {
450
							$cafile = "ca-{$ikeid}.crt";
451
							$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts/{$cafile}";
452

    
453
							if (!file_put_contents($capath, base64_decode($ca['crt'])))
454
							{
455
								log_error(sprintf(gettext("Error: Cannot write phase1 CA certificate file for %s"), $ph1ent['name']));
456
								continue;
457
							}
458

    
459
							chmod($capath, 0600);
460
						}
461
					}
462
				} else {
463
					list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, "local");
464
					list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, "peer", $rgmap);
465

    
466
					if (empty($peerid_data))
467
						continue;
468

    
469
					$myid = isset($ph1ent['mobile']) ? trim($myid_data) . " " : "";
470
					$peerid = ($peerid_data != "allusers") ? trim($peerid_data) : "";
471
					if (!empty($ph1ent['pre-shared-key']))
472
						$pskconf .= $myid . $peerid . " : PSK \"" . trim($ph1ent['pre-shared-key']) . "\"\n";
473
				}
474
			}
475
		}
476

    
477
		/* Add user PSKs */
478
		foreach ($config['system']['user'] as $user) {
479
			if (!empty($user['ipsecpsk'])) {
480
				$pskconf .= "{$user['name']} : PSK \"{$user['ipsecpsk']}\"\n";
481
			}
482
		}
483

    
484
		/* add PSKs for mobile clients */
485
		if (is_array($ipseccfg['mobilekey'])) {
486
			foreach ($ipseccfg['mobilekey'] as $key) {
487
				if ($key['ident'] == "allusers")
488
					$key['ident'] = '';
489
				$pskconf .= "{$key['ident']} : PSK \"{$key['pre-shared-key']}\"\n";
490
			}
491
		}
492

    
493
		@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
494
		chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
495
		unset($pskconf);
496

    
497
		$natfilterrules = false;
498
		/* begin ipsec.conf */
499
		$ipsecconf = "";
500
		if ((is_array($a_phase1) && count($a_phase1)) || (is_array($a_phase2) && count($a_phase2))) {
501

    
502
			$ipsecconf .= "# This file is automatically generated. Do not edit\n";
503
			if (is_array($a_phase2) && count($a_phase2)) {
504
				$ipsecconf .= "config setup\n\tuniqueids = yes\n";
505
				$ipsecconf .= "\tcharondebug=\"" . vpn_ipsec_configure_loglevels(true) . "\"\n";
506

    
507
				foreach ($a_phase2 as $ph2ent) {
508
					$ikeid = $ph2ent['ikeid'];
509

    
510
					$ph1ent = false;
511
					if (!ipsec_lookup_phase1($ph2ent,$ph1ent))
512
						continue;
513

    
514
					if (isset($ph1ent['disabled']))
515
						continue;
516

    
517
					if (isset($ph2ent['disabled']))
518
						continue;
519

    
520
					if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
521
						continue;
522

    
523
					$ikeid = $ph1ent['ikeid'];
524

    
525
					if ($ph1ent['mode'] == "aggressive")
526
						$aggressive = "yes";
527
					else
528
						$aggressive = "no";
529

    
530
					$ep = ipsec_get_phase1_src($ph1ent);
531
					if (!$ep)
532
						continue;
533

    
534
					$passive = "start";
535
					if (isset($ph1ent['mobile'])) {
536
						$rgip = "%any";
537
						$passive = 'add';
538
					} else
539
						$rgip = $ph1ent['remote-gateway'];
540

    
541
					$keyexchange = "ikev1";
542
					if (!empty($ph1ent['iketype']) && $ph1ent['iketype'] != "ikev1")
543
						$keyexchange = "ikev2";
544

    
545
					list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, "local");
546
					list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, "peer", $rgmap);
547

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

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

    
562
						$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
563
						if (!empty($modp))
564
							$ealgosp1 .= "-{$modp}";
565

    
566
						if ($keyexchange == "ikev1")
567
							$ealgosp1 .= "!";
568
					}
569

    
570
					if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
571
						if ($passive == "start")
572
							$dpdline = "dpdaction = restart";
573
						else
574
							$dpdline = "dpdaction = clear";
575
						$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
576
						$dpdline .= "\n\tdpdtimeout = {$ph1ent['dpd_maxfail']}s";
577
					} else
578
						$dpdline = "dpdaction = none";
579

    
580
					if (!empty($ph1ent['authentication_method']) && (strpos($ph1ent['authentication_method'], "xauth") || strpos($ph1ent['authentication_method'], "hybrid")))
581
						$xauth = "xauth = server";
582

    
583
					$lifeline = '';
584
					if ($ph1ent['lifetime'])
585
						$lifeline = "ikelifetime = {$ph1ent['lifetime']}s";
586

    
587
					$remoteid_spec = '';
588
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
589
						$tunneltype = "type = tunnel";
590

    
591
						$localid_type = $ph2ent['localid']['type'];
592
						$localid_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
593
						/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
594
						if (($localid_type == "none" || $localid_type == "mobile")
595
							&& isset($ph1ent['mobile'])
596
							&& (ipsec_get_number_of_phase2($ikeid)==1))
597
							$localid_spec = "%any";
598
						else {
599
							if ($localid_type != "address") {
600
								$localid_type = "subnet";
601
							}
602
							// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
603
							if (!is_ipaddr($localid_data) && !is_subnet($localid_data) && ($localid_data != "0.0.0.0/0")) {
604
								log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
605
								continue;
606
							}
607
							$localid_spec = $ep;
608
							if (!empty($ph2ent['natlocalid'])) {
609
								$natlocalid_data =  ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
610
								if ($ph2ent['natlocalid']['type'] != "address") {
611
									if (is_subnet($natlocalid_data))
612
										$localid_data = "{$natlocalid_data}|{$localid_data}";
613
								} else {
614
									if (is_ipaddr($natlocalid_data))
615
										$localid_data = "{$natlocalid_data}|{$localid_data}";
616
								}
617
								$natfilterrules = true;
618
							}
619
						}
620

    
621
						if (!isset($ph2ent['mobile'])) {
622
							$remoteid_data = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
623
							$remoteid_spec = "\trightsubnet = {$remoteid_data}";
624
						} else if (!empty($a_client['pool_address']))
625
							$remoteid_spec = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}";
626
					} else {
627
						$tunneltype = "type = transport";
628
						$rgip = $ph1ent['remote-gateway'];
629

    
630
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
631
							($ph1ent['authentication_method'] == "pre_shared_key"))
632
							&& isset($ph1ent['mobile']))
633
							$localid_spec = "%any";
634
						else {
635
							$localid_data = ipsec_get_phase1_src($ph1ent);
636
							$localid_spec = $ep;
637
						}
638
						if (!isset($ph2ent['mobile'])) {
639
							$remoteid_spec = "\trightsubnet = {$rgip}";
640
						}
641
					}
642
					$authentication = "";
643
					switch ($ph1ent['authentication_method']) {
644
					case 'xauth_rsa_server':
645
						$authentication = "leftauth = pubkey\n\trightauth = pubkey";
646
						$authentication .= "\n\trightauth2 = xauth-generic";
647
						break;
648
					case 'xauth_psk_server':
649
						$authentication = "leftauth = psk\n\trightauth = psk";
650
						$authentication .= "\n\trightauth2 = xauth-generic";
651
						break;
652
					case 'pre_shared_key':
653
						$authentication = "leftauth = psk\n\trightauth = psk";
654
						break;
655
					case 'rsasig':
656
						$authentication = "leftauth = pubkey\n\trightauth = pubkey";
657
						break;
658
					case 'hybrid_rsa_server':
659
						$authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
660
						$authentication .= "\n\trightauth2 = xauth";
661
						break;
662
					}
663

    
664
					if (isset($a_client['pfs_group']))
665
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
666

    
667
					$ealgosp2 = '';
668
					if ($ph2ent['protocol'] == 'esp') {
669
						if (is_array($ph2ent['encryption-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
670
							$ealgosp2arr = array();
671
							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
672
								$ealg_id = $ealg['name'];
673
								$ealg_kl = $ealg['keylen'];
674

    
675
								if (!empty($ealg_kl) && $ealg_kl == "auto") {
676
									if (empty($p2_ealgos) || !is_array($p2_ealgos))
677
										require("ipsec.inc");
678
									$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
679
									$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
680
									$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
681
									/* XXX: in some cases where include ordering is suspect these variables
682
									 * are somehow 0 and we enter this loop forever and timeout after 900
683
									 * seconds wrecking bootup */
684
									if ($key_hi != 0 and $key_lo !=0 and $key_step !=0) {
685
										for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
686
											foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
687
												$halgo = str_replace('hmac_', '', $halgo);
688
												$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
689
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
690
												if (!empty($modp))
691
													$tmpealgo .= "-{$modp}";
692
												$ealgosp2arr[] = $tmpealgo;
693
											}
694
										}
695
									}
696
								} else {
697
									foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
698
										$halgo = str_replace('hmac_', '', $halgo);
699
										$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
700
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
701
										if (!empty($modp))
702
											$tmpealgo .= "-{$modp}";
703
										$ealgosp2arr[] = $tmpealgo;
704
									}
705
								}
706
							}
707
							$ealgosp2 = "esp = " . join(",", $ealgosp2arr);
708
							unset($ealgosp2arr);
709
							$ealgosp2 .= "!";
710
						}
711
					} else if ($ph2ent['protocol'] == 'ah') {
712
						if (is_array($ph2ent['hash-algorithm-option'])) {
713
							$ealgosp2 = "ah = " . join(",", $ph2ent['hash-algorithm-option']);
714
							$ealgosp2 = str_replace('hmac_', '', $ealgosp2);
715
							$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
716
							if (!empty($modp))
717
								$ealgosp2 .= "-{$modp}";
718
							$ealgosp2 .= "!";
719
						}
720
					}
721

    
722

    
723
					if ($ph2ent['lifetime'])
724
						$lifeline = "ikelifetime = {$ph2ent['lifetime']}s";
725

    
726
					$ipsecconf .=<<<EOD
727

    
728
conn con{$ph2ent['ikeid']}-{$ph2ent['ikeid']}
729
	aggressive = {$aggressive}
730
	fragmentation = yes
731
	keyexchange = {$keyexchange}
732
	keyingtries = %forever
733
	reauth = yes
734
	reqid = {$ikeid}
735
	installpolicy = yes
736
	{$lifeline}
737
	{$tunneltype}
738
	{$dpdline}
739
	auto = {$passive}
740
	left = {$localid_spec}
741
	leftsubnet = {$localid_data}
742
	right = {$rgip}
743
	leftid = {$myid_data}
744

    
745
EOD;
746

    
747
					if (!empty($remoteid_spec))
748
						$ipsecconf .= "{$remoteid_spec}\n";
749
					if (!empty($ealgosp1))
750
						$ipsecconf .= "\t{$ealgosp1}\n";
751
					if (!empty($ealgosp2))
752
						$ipsecconf .= "\t{$ealgosp2}\n";
753
					if (!empty($authentication))
754
						$ipsecconf .= "\t{$authentication}\n";
755
					if (!empty($peerid_spec))
756
						$ipsecconf .= "\trightid = {$peerid_spec}\n";
757
				}
758
			}
759
		}
760
	}
761
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
762
	unset($ipsecconf);
763
	/* end ipsec.conf */
764

    
765
	/* mange process */
766
	if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
767
		/* Read secrets */
768
		mwexec("/usr/local/sbin/ipsec rereadall", false);
769
		/* Update configuration changes */
770
		mwexec("/usr/local/sbin/ipsec update", false);
771
	} else {
772
		mwexec("/usr/local/sbin/ipsec start", false); 
773
	}
774

    
775
	if ($natfilterrules == true)
776
		filter_configure();
777
	/* start filterdns, if necessary */
778
	if (count($filterdns_list) > 0) {
779
		$interval = 60;
780
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
781
			$interval = $ipseccfg['dns-interval'];
782

    
783
		$hostnames = "";
784
		array_unique($filterdns_list);
785
		foreach ($filterdns_list as $hostname)
786
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
787
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
788
		unset($hostnames);
789

    
790
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
791
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
792
		else {
793
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
794
		}
795
	} else {
796
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
797
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
798
	}
799

    
800
	if ($g['booting'])
801
		echo "done\n";
802

    
803
	return count($filterdns_list);
804
}
805

    
806
/*
807
 * Forcefully restart IPsec
808
 * This is required for when dynamic interfaces reload
809
 * For all other occasions the normal vpn_ipsec_configure()
810
 * will gracefully reload the settings without restarting
811
 */
812
function vpn_ipsec_force_reload($interface = "") {
813
	global $g, $config;
814

    
815
	$ipseccfg = $config['ipsec'];
816

    
817
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
818
		$found = false;
819
		foreach ($ipseccfg['phase1'] as $ipsec) {
820
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
821
				$found = true;
822
				break;
823
			}
824
		}
825
		if (!$found) {
826
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
827
			return;
828
		}
829
	}
830

    
831
	/* if ipsec is enabled, start up again */
832
	if (isset($ipseccfg['enable'])) {
833
		log_error(gettext("Forcefully reloading IPsec"));
834
		vpn_ipsec_configure();
835
	}
836
}
837

    
838
/* master setup for vpn (mpd) */
839
function vpn_setup() {
840
	global $g;
841

    
842
	if ($g['platform'] == 'jail')
843
		return;
844

    
845
	/* start pptpd */
846
	vpn_pptpd_configure();
847

    
848
	/* start pppoe server */
849
	vpn_pppoes_configure();
850

    
851
	/* setup l2tp */
852
	vpn_l2tp_configure();
853
}
854

    
855
function vpn_netgraph_support() {
856
	$iflist = get_configured_interface_list();
857
	foreach ($iflist as $iface) {
858
		$realif = get_real_interface($iface);
859
		/* Get support for netgraph(4) from the nic */
860
		$ifinfo = pfSense_get_interface_addresses($realif);
861
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
862
			pfSense_ngctl_attach(".", $realif);
863
	}
864
}
865

    
866
function vpn_pptpd_configure() {
867
	global $config, $g;
868

    
869
	$syscfg = $config['system'];
870
	$pptpdcfg = $config['pptpd'];
871

    
872
	if ($g['booting']) {
873
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
874
			return 0;
875

    
876
		echo gettext("Configuring PPTP VPN service... ");
877
	} else {
878
		/* kill mpd */
879
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
880

    
881
		/* wait for process to die */
882
		sleep(3);
883

    
884
		if (is_process_running("mpd -b")) {
885
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
886
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
887
		}
888

    
889
		/* remove mpd.conf, if it exists */
890
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
891
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
892
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
893
	}
894

    
895
	if (empty($pptpdcfg['n_pptp_units'])) {
896
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
897
		return;
898
	}
899

    
900
	/* make sure pptp-vpn directory exists */
901
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
902
		mkdir("{$g['varetc_path']}/pptp-vpn");
903

    
904
	switch ($pptpdcfg['mode']) {
905
		case 'server' :
906
			/* write mpd.conf */
907
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
908
			if (!$fd) {
909
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
910
				return 1;
911
			}
912

    
913
			$mpdconf = <<<EOD
914
pptps:
915

    
916
EOD;
917

    
918
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
919
				$mpdconf .= "	load pt{$i}\n";
920
			}
921

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

    
924
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
925

    
926
				$mpdconf .= <<<EOD
927

    
928
pt{$i}:
929
	new -i pptpd{$i} pt{$i} pt{$i}
930
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
931
	load pts
932

    
933
EOD;
934
			}
935

    
936
			$mpdconf .=<<<EOD
937

    
938
pts:
939
	set iface disable on-demand
940
	set iface enable proxy-arp
941
	set iface enable tcpmssfix
942
	set iface idle 1800
943
	set iface up-script /usr/local/sbin/vpn-linkup
944
	set iface down-script /usr/local/sbin/vpn-linkdown
945
	set bundle enable multilink
946
	set bundle enable crypt-reqd
947
	set link yes acfcomp protocomp
948
	set link no pap chap
949
	set link enable chap-msv2
950
	set link mtu 1460
951
	set link keep-alive 10 60
952
	set ipcp yes vjcomp
953
	set bundle enable compression
954
	set ccp yes mppc
955
	set ccp yes mpp-e128
956
	set ccp yes mpp-stateless
957

    
958
EOD;
959

    
960
			if (!isset ($pptpdcfg['req128'])) {
961
				$mpdconf .=<<<EOD
962
	set ccp yes mpp-e40
963
	set ccp yes mpp-e56
964

    
965
EOD;
966
			}
967

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

    
971
			if (!empty($pptpdcfg['dns1'])) {
972
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
973
				if (!empty($pptpdcfg['dns2']))
974
					$mpdconf .= " " . $pptpdcfg['dns2'];
975
				$mpdconf .= "\n";
976
			} elseif (isset ($config['dnsmasq']['enable'])) {
977
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
978
				if ($syscfg['dnsserver'][0])
979
					$mpdconf .= " " . $syscfg['dnsserver'][0];
980
				$mpdconf .= "\n";
981
			} elseif (isset($config['unbound']['enable'])) {
982
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
983
				if ($syscfg['dnsserver'][0])
984
					$mpdconf .= " " . $syscfg['dnsserver'][0];
985
				$mpdconf .= "\n";
986
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
987
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
988
			}
989

    
990
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
991
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
992
				$acctport = $authport + 1;
993
				$mpdconf .=<<<EOD
994
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
995

    
996
EOD;
997
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
998
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
999
				$acctport = $authport + 1;
1000
				$mpdconf .=<<<EOD
1001
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1002

    
1003
EOD;
1004
			}
1005
			$mpdconf .=<<<EOD
1006
	set radius retries 3
1007
	set radius timeout 10
1008
	set auth enable radius-auth
1009

    
1010
EOD;
1011

    
1012
				if (isset ($pptpdcfg['radius']['accounting'])) {
1013
					$mpdconf .=<<<EOD
1014
	set auth enable radius-acct
1015
	set radius acct-update 300
1016

    
1017
EOD;
1018
				}
1019
			}
1020

    
1021
			fwrite($fd, $mpdconf);
1022
			fclose($fd);
1023
			unset($mpdconf);
1024

    
1025
			/* write mpd.links */
1026
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1027
			if (!$fd) {
1028
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1029
				return 1;
1030
			}
1031

    
1032
			$mpdlinks = "";
1033

    
1034
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1035
				$mpdlinks .=<<<EOD
1036

    
1037
pt{$i}:
1038
	set link type pptp
1039
	set pptp enable incoming
1040
	set pptp disable originate
1041
	set pptp disable windowing
1042

    
1043
EOD;
1044
			}
1045

    
1046
			fwrite($fd, $mpdlinks);
1047
			fclose($fd);
1048
			unset($mpdlinks);
1049

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

    
1057
			$mpdsecret = "";
1058

    
1059
			if (is_array($pptpdcfg['user'])) {
1060
				foreach ($pptpdcfg['user'] as $user) {
1061
					$pass = str_replace('\\', '\\\\', $user['password']);
1062
					$pass = str_replace('"', '\"', $pass);
1063
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1064
				}
1065
			}
1066

    
1067
			fwrite($fd, $mpdsecret);
1068
			fclose($fd);
1069
			unset($mpdsecret);
1070
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1071

    
1072
			vpn_netgraph_support();
1073

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

    
1077
			break;
1078

    
1079
		case 'redir' :
1080
			break;
1081
	}
1082

    
1083
	if ($g['booting'])
1084
		echo "done\n";
1085

    
1086
	return 0;
1087
}
1088

    
1089
function vpn_pppoes_configure() {
1090
	global $config;
1091

    
1092
	if (is_array($config['pppoes']['pppoe'])) {
1093
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1094
			vpn_pppoe_configure($pppoe);
1095
	}
1096
}
1097

    
1098
function vpn_pppoe_configure(&$pppoecfg) {
1099
	global $config, $g;
1100

    
1101
	$syscfg = $config['system'];
1102

    
1103
	/* create directory if it does not exist */
1104
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1105
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1106

    
1107
	if ($g['booting']) {
1108
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1109
			return 0;
1110

    
1111
		echo gettext("Configuring PPPoE VPN service... ");
1112
	} else {
1113
		/* kill mpd */
1114
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1115

    
1116
		/* wait for process to die */
1117
		sleep(2);
1118

    
1119
	}
1120

    
1121
	switch ($pppoecfg['mode']) {
1122

    
1123
		case 'server' :
1124

    
1125
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1126

    
1127
			if ($pppoecfg['paporchap'] == "chap")
1128
				$paporchap = "set link enable chap";
1129
			else
1130
				$paporchap = "set link enable pap";
1131

    
1132
			/* write mpd.conf */
1133
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1134
			if (!$fd) {
1135
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1136
				return 1;
1137
			}
1138
			$mpdconf = "\n\n";
1139
			$mpdconf .= "poes:\n";
1140

    
1141
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1142
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1143
			}
1144

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

    
1147
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1148

    
1149
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1150
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1151
				} else {
1152
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1153
				}
1154

    
1155
				$mpdconf .=<<<EOD
1156

    
1157
poes{$pppoecfg['pppoeid']}{$i}:
1158
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1159
	{$isssue_ip_type}
1160
	load pppoe_standard
1161

    
1162
EOD;
1163
			}
1164

    
1165
			$mpdconf .=<<<EOD
1166

    
1167
pppoe_standard:
1168
	set bundle no multilink
1169
	set bundle enable compression
1170
	set auth max-logins 1
1171
	set iface up-script /usr/local/sbin/vpn-linkup
1172
	set iface down-script /usr/local/sbin/vpn-linkdown
1173
	set iface idle 0
1174
	set iface disable on-demand
1175
	set iface disable proxy-arp
1176
	set iface enable tcpmssfix
1177
	set iface mtu 1500
1178
	set link no pap chap
1179
	{$paporchap}
1180
	set link keep-alive 60 180
1181
	set ipcp yes vjcomp
1182
	set ipcp no vjcomp
1183
	set link max-redial -1
1184
	set link mtu 1492
1185
	set link mru 1492
1186
	set ccp yes mpp-e40
1187
	set ccp yes mpp-e128
1188
	set ccp yes mpp-stateless
1189
	set link latency 1
1190
	#set ipcp dns 10.10.1.3
1191
	#set bundle accept encryption
1192

    
1193
EOD;
1194

    
1195
			if (!empty($pppoecfg['dns1'])) {
1196
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1197
				if (!empty($pppoecfg['dns2']))
1198
					$mpdconf .= " " . $pppoecfg['dns2'];
1199
				$mpdconf .= "\n";
1200
			} elseif (isset ($config['dnsmasq']['enable'])) {
1201
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1202
				if ($syscfg['dnsserver'][0])
1203
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1204
				$mpdconf .= "\n";
1205
			} elseif (isset ($config['unbound']['enable'])) {
1206
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1207
				if ($syscfg['dnsserver'][0])
1208
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1209
				$mpdconf .= "\n";
1210
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1211
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1212
			}
1213

    
1214
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1215
				$radiusport = "";
1216
				$radiusacctport = "";
1217
				if (isset($pppoecfg['radius']['server']['port']))
1218
					$radiusport = $pppoecfg['radius']['server']['port'];
1219
				if (isset($pppoecfg['radius']['server']['acctport']))
1220
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1221
				$mpdconf .=<<<EOD
1222
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1223
	set radius retries 3
1224
	set radius timeout 10
1225
	set auth enable radius-auth
1226

    
1227
EOD;
1228

    
1229
				if (isset ($pppoecfg['radius']['accounting'])) {
1230
					$mpdconf .=<<<EOD
1231
	set auth enable radius-acct
1232

    
1233
EOD;
1234
				}
1235
			}
1236

    
1237
			fwrite($fd, $mpdconf);
1238
			fclose($fd);
1239
			unset($mpdconf);
1240

    
1241
			/* write mpd.links */
1242
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1243
			if (!$fd) {
1244
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1245
				return 1;
1246
			}
1247

    
1248
			$mpdlinks = "";
1249

    
1250
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1251
				$mpdlinks .=<<<EOD
1252

    
1253
poes{$pppoecfg['pppoeid']}{$i}:
1254
	set phys type pppoe
1255
	set pppoe iface {$pppoe_interface}
1256
	set pppoe service "*"
1257
	set pppoe disable originate
1258
	set pppoe enable incoming
1259

    
1260
EOD;
1261
			}
1262

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

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

    
1275
				$mpdsecret = "\n\n";
1276

    
1277
				if (!empty($pppoecfg['username'])) {
1278
					$item = explode(" ", $pppoecfg['username']);
1279
					foreach($item as $userdata) {
1280
						$data = explode(":", $userdata);
1281
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1282
					}
1283
				}
1284

    
1285
				fwrite($fd, $mpdsecret);
1286
				fclose($fd);
1287
				unset($mpdsecret);
1288
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1289
			}
1290

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

    
1295
			/* Get support for netgraph(4) from the nic */
1296
			pfSense_ngctl_attach(".", $pppoe_interface);
1297
			/* fire up mpd */
1298
			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");
1299

    
1300
			break;
1301
	}
1302

    
1303
	if ($g['booting'])
1304
		echo gettext("done") . "\n";
1305

    
1306
	return 0;
1307
}
1308

    
1309
function vpn_l2tp_configure() {
1310
	global $config, $g;
1311

    
1312
	$syscfg = $config['system'];
1313
	$l2tpcfg = $config['l2tp'];
1314

    
1315
	/* create directory if it does not exist */
1316
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1317
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1318

    
1319
	if ($g['booting']) {
1320
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1321
			return 0;
1322

    
1323
		echo gettext("Configuring l2tp VPN service... ");
1324
	} else {
1325
		/* kill mpd */
1326
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1327

    
1328
		/* wait for process to die */
1329
		sleep(8);
1330

    
1331
	}
1332

    
1333
	/* make sure l2tp-vpn directory exists */
1334
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1335
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1336

    
1337
	switch ($l2tpcfg['mode']) {
1338

    
1339
		case 'server' :
1340
			if ($l2tpcfg['paporchap'] == "chap")
1341
				$paporchap = "set link enable chap";
1342
			else
1343
				$paporchap = "set link enable pap";
1344

    
1345
			/* write mpd.conf */
1346
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1347
			if (!$fd) {
1348
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1349
				return 1;
1350
			}
1351
			$mpdconf = "\n\n";
1352
			$mpdconf .=<<<EOD
1353
l2tps:
1354

    
1355
EOD;
1356

    
1357
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1358
				$mpdconf .= "	load l2tp{$i}\n";
1359
			}
1360

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

    
1363
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1364

    
1365
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1366
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1367
				} else {
1368
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1369
				}
1370

    
1371
				$mpdconf .=<<<EOD
1372

    
1373
l2tp{$i}:
1374
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1375
	{$isssue_ip_type}
1376
	load l2tp_standard
1377

    
1378
EOD;
1379
			}
1380

    
1381
			$mpdconf .=<<<EOD
1382

    
1383
l2tp_standard:
1384
	set bundle disable multilink
1385
	set bundle enable compression
1386
	set bundle yes crypt-reqd
1387
	set ipcp yes vjcomp
1388
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1389
	set ccp yes mppc
1390
	set iface disable on-demand
1391
	set iface enable proxy-arp
1392
	set iface up-script /usr/local/sbin/vpn-linkup
1393
	set iface down-script /usr/local/sbin/vpn-linkdown
1394
	set link yes acfcomp protocomp
1395
	set link no pap chap
1396
	set link enable chap
1397
	set link keep-alive 10 180
1398

    
1399
EOD;
1400

    
1401
			if (is_ipaddr($l2tpcfg['wins'])) {
1402
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1403
			}
1404
			if (is_ipaddr($l2tpcfg['dns1'])) {
1405
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1406
				if (is_ipaddr($l2tpcfg['dns2']))
1407
					$mpdconf .= " " . $l2tpcfg['dns2'];
1408
				$mpdconf .= "\n";
1409
			} elseif (isset ($config['dnsmasq']['enable'])) {
1410
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1411
				if ($syscfg['dnsserver'][0])
1412
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1413
				$mpdconf .= "\n";
1414
			} elseif (isset ($config['unbound']['enable'])) {
1415
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1416
				if ($syscfg['dnsserver'][0])
1417
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1418
				$mpdconf .= "\n";
1419
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1420
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1421
			}
1422

    
1423
			if (isset ($l2tpcfg['radius']['enable'])) {
1424
				$mpdconf .=<<<EOD
1425
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1426
	set radius retries 3
1427
	set radius timeout 10
1428
	set auth enable radius-auth
1429

    
1430
EOD;
1431

    
1432
				if (isset ($l2tpcfg['radius']['accounting'])) {
1433
					$mpdconf .=<<<EOD
1434
	set auth enable radius-acct
1435

    
1436
EOD;
1437
				}
1438
			}
1439

    
1440
			fwrite($fd, $mpdconf);
1441
			fclose($fd);
1442
			unset($mpdconf);
1443

    
1444
			/* write mpd.links */
1445
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1446
			if (!$fd) {
1447
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1448
				return 1;
1449
			}
1450

    
1451
			$mpdlinks = "";
1452

    
1453
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1454
				$mpdlinks .=<<<EOD
1455

    
1456
l2tp{$i}:
1457
	set link type l2tp
1458
	set l2tp enable incoming
1459
	set l2tp disable originate
1460

    
1461
EOD;
1462
			if (!empty($l2tpcfg['secret']))
1463
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1464
			}
1465

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

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

    
1477
			$mpdsecret = "\n\n";
1478

    
1479
			if (is_array($l2tpcfg['user'])) {
1480
				foreach ($l2tpcfg['user'] as $user)
1481
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1482
			}
1483

    
1484
			fwrite($fd, $mpdsecret);
1485
			fclose($fd);
1486
			unset($mpdsecret);
1487
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1488

    
1489
			vpn_netgraph_support();
1490

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

    
1494
			break;
1495

    
1496
		case 'redir' :
1497
			break;
1498
	}
1499

    
1500
	if ($g['booting'])
1501
		echo "done\n";
1502

    
1503
	return 0;
1504
}
1505

    
1506
function vpn_ipsec_configure_preferoldsa() {
1507
	global $config;
1508
	if(isset($config['ipsec']['preferoldsa']))
1509
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
1510
	else
1511
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
1512
}
1513

    
1514
?>
(58-58/67)