Projet

Général

Profil

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

univnautes / etc / inc / vpn.inc @ b31a2c76

1
<?php
2

    
3
/*
4
	vpn.inc
5
	Copyright (C) 2004 Scott Ullrich
6
	Copyright (C) 2008 Shrew Soft Inc
7
	Copyright (C) 2008 Ermal Lu�i
8
	All rights reserved.
9

    
10
	originally part of m0n0wall (http://m0n0.ch/wall)
11
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
12
	All rights reserved.
13

    
14
	Redistribution and use in source and binary forms, with or without
15
	modification, are permitted provided that the following conditions are met:
16

    
17
	1. Redistributions of source code must retain the above copyright notice,
18
	   this list of conditions and the following disclaimer.
19

    
20
	2. Redistributions in binary form must reproduce the above copyright
21
	   notice, this list of conditions and the following disclaimer in the
22
	   documentation and/or other materials provided with the distribution.
23

    
24
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
25
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
26
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
28
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33
	POSSIBILITY OF SUCH DAMAGE.
34
*/
35

    
36
/*
37
	pfSense_BUILDER_BINARIES:	/sbin/ifconfig
38
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/ipsec	/usr/local/libexec/ipsec/charon /usr/local/libexec/ipsec/starter
39
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/filterdns	/usr/local/sbin/mpd4
40
	pfSense_MODULE:	vpn
41
*/
42

    
43
require_once("ipsec.inc");
44

    
45
function vpn_ipsec_configure_loglevels($forconfig = false)
46
{
47
	global $config, $ipsec_loglevels;
48

    
49
	$cfgtext = array();
50
	foreach ($ipsec_loglevels as $lkey => $ldescr) {
51
		if (!isset($config['ipsec']["ipsec_{$lkey}"]))
52
			$forconfig ? $cfgtext[] = "{$lkey} = -1" : mwexec("/usr/local/sbin/ipsec stroke loglevel {$lkey} -1", false);
53
		else if (is_numeric($config['ipsec']["ipsec_{$lkey}"]) &&
54
		    intval($config['ipsec']["ipsec_{$lkey}"]) >= 1 && intval($config['ipsec']["ipsec_{$lkey}"]) <= 5)
55
			$forconfig ? $cfgtext[] = "${lkey} = " . (intval($config['ipsec']["ipsec_{$lkey}"]) - 1) :
56
				mwexec("/usr/local/sbin/ipsec stroke loglevel {$lkey} " . (intval($config['ipsec']["ipsec_{$lkey}"]) - 1) , false);
57
	}
58
	if ($forconfig)
59
		return implode(',', $cfgtext);
60
}
61

    
62
/* include all configuration functions */
63
function vpn_ipsec_convert_to_modp($index)
64
{
65

    
66
	$convertion = "";
67
	switch ($index) {
68
	case '1':
69
		$convertion = "modp768";
70
		break;
71
	case '2':
72
		$convertion = "modp1024";
73
		break;
74
	case '5':
75
		$convertion = "modp1536";
76
		break;
77
	case '14':
78
		$convertion = "modp2048";
79
		break;
80
	case '15':
81
		$convertion = "modp3072";
82
		break;
83
	case '16':      
84
		$convertion = "modp4096";
85
		break;
86
	case '17':
87
		$convertion = "modp6144";
88
		break;
89
	case '18':
90
		$convertion = "modp8192";
91
		break;
92
	}
93

    
94
	return $convertion;
95
}
96

    
97
function vpn_ipsec_configure($ipchg = false)
98
{
99
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos;
100

    
101
	if ($g['platform'] == 'jail')
102
		return;
103

    
104
	/* get the automatic ping_hosts.sh ready */
105
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
106
	touch("{$g['vardb_path']}/ipsecpinghosts");
107

    
108
	vpn_ipsec_configure_preferoldsa();
109

    
110
	$syscfg = $config['system'];
111
	$ipseccfg = $config['ipsec'];
112
	$a_phase1 = $config['ipsec']['phase1'];
113
	$a_phase2 = $config['ipsec']['phase2'];
114
	$a_client = $config['ipsec']['client'];
115

    
116
	if (!isset($ipseccfg['enable'])) {
117
		/* try to stop charon */
118
		mwexec("/usr/local/sbin/ipsec stop");
119
		/* Stop dynamic monitoring */
120
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
121

    
122
		/* wait for process to die */
123
		sleep(2);
124

    
125
		/* disallow IPSEC, it is off */
126
		mwexec("/sbin/ifconfig enc0 down");
127
		set_single_sysctl("net.inet.ip.ipsec_in_use", "0");
128

    
129
		return 0;
130
	} else {
131
		mwexec("/sbin/ifconfig enc0 up");
132
		set_single_sysctl("net.inet.ip.ipsec_in_use", "1");
133
		/* needed for config files */
134
		if (!is_dir("{$g['varetc_path']}/ipsec"))
135
			mkdir("{$g['varetc_path']}/ipsec");
136
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d"))
137
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d");
138
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/cacerts"))
139
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/cacerts");
140
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/private"))
141
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/private");
142
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/crls"))
143
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/crls");
144
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/certs"))
145
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/certs");
146
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts"))
147
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts");
148
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/acerts"))
149
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/acerts");
150
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts"))
151
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts");
152
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/reqs"))
153
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/reqs");
154
		
155

    
156
		if ($g['booting'])
157
			echo gettext("Configuring IPsec VPN... ");
158

    
159
		/* fastforwarding is not compatible with ipsec tunnels */
160
		set_single_sysctl("net.inet.ip.fastforwarding", "0");
161

    
162
		/* resolve all local, peer addresses and setup pings */
163
		$ipmap = array();
164
		$rgmap = array();
165
		$filterdns_list = array();
166
		$listeniflist = array();
167
		unset($iflist);
168
		if (is_array($a_phase1) && count($a_phase1)) {
169

    
170
			$ipsecpinghosts = "";
171
			/* step through each phase1 entry */
172
			foreach ($a_phase1 as $ph1ent) {
173
				if (isset($ph1ent['disabled']))
174
					continue;
175

    
176
				$listeniflist = get_real_interface($a_phase1['interface']);
177

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

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

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

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

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

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

    
207
				if (is_array($a_phase2)) {
208
					/* step through each phase2 entry */
209
					foreach ($a_phase2 as $ph2ent) {
210
						$ikeid = $ph2ent['ikeid'];
211

    
212
						if (isset($ph2ent['disabled']))
213
							continue;
214

    
215
						if ($ikeid != $ph1ent['ikeid'])
216
							continue;
217

    
218
						/* add an ipsec pinghosts entry */
219
						if ($ph2ent['pinghost']) {
220
							if (!is_array($iflist))
221
								$iflist = get_configured_interface_list();
222
							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
						$rekey = "rekey = yes";
545
					} else {
546
						$rekey = "rekey = yes";
547
					}
548

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

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

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

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

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

    
574
					if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
575
						if ($passive == "start")
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
					if (!empty($ph1ent['authentication_method']) && (strpos($ph1ent['authentication_method'], "xauth") || strpos($ph1ent['authentication_method'], "hybrid")))
586
						$xauth = "xauth = server";
587

    
588
					$ikelifeline = '';
589
					if ($ph1ent['lifetime'])
590
						$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
591

    
592
					$remoteid_spec = '';
593
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
594
						$tunneltype = "type = tunnel";
595

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

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

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

    
669
					if (isset($a_client['pfs_group']))
670
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
671

    
672
					$ealgosp2 = '';
673
					if ($ph2ent['protocol'] == 'esp') {
674
						if (is_array($ph2ent['encryption-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
675
							$ealgosp2arr = array();
676
							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
677
								$ealg_id = $ealg['name'];
678
								$ealg_kl = $ealg['keylen'];
679

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

    
727

    
728
					$ipseclifetime = '';
729
					if ($ph2ent['lifetime'])
730
						$ipseclifeline = "lifetime = {$ph2ent['lifetime']}s";
731

    
732
					$ipsecconf .=<<<EOD
733

    
734
conn con{$ph1ent['ikeid']}-{$ph2ent['uniqid']}
735
	aggressive = {$aggressive}
736
	fragmentation = yes
737
	keyexchange = {$keyexchange}
738
	keyingtries = %forever
739
	reauth = yes
740
	{$rekey}
741
	reqid = {$ikeid}
742
	installpolicy = yes
743
	{$ikelifeline}
744
	{$ipseclifeline}
745
	{$tunneltype}
746
	{$dpdline}
747
	auto = {$passive}
748
	left = {$localid_spec}
749
	leftsubnet = {$localid_data}
750
	right = {$rgip}
751
	leftid = {$myid_data}
752

    
753
EOD;
754

    
755
					if (!empty($remoteid_spec))
756
						$ipsecconf .= "{$remoteid_spec}\n";
757
					if (!empty($ealgosp1))
758
						$ipsecconf .= "\t{$ealgosp1}\n";
759
					if (!empty($ealgosp2))
760
						$ipsecconf .= "\t{$ealgosp2}\n";
761
					if (!empty($authentication))
762
						$ipsecconf .= "\t{$authentication}\n";
763
					if (!empty($peerid_spec))
764
						$ipsecconf .= "\trightid = {$peerid_spec}\n";
765
				}
766
			}
767
		}
768
	}
769
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
770
	unset($ipsecconf);
771
	/* end ipsec.conf */
772

    
773
	/* mange process */
774
	if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
775
		/* Read secrets */
776
		mwexec("/usr/local/sbin/ipsec rereadall", false);
777
		/* Update configuration changes */
778
		mwexec("/usr/local/sbin/ipsec update", false);
779
	} else {
780
		mwexec("/usr/local/sbin/ipsec start", false); 
781
	}
782

    
783
	if ($natfilterrules == true)
784
		filter_configure();
785
	/* start filterdns, if necessary */
786
	if (count($filterdns_list) > 0) {
787
		$interval = 60;
788
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
789
			$interval = $ipseccfg['dns-interval'];
790

    
791
		$hostnames = "";
792
		array_unique($filterdns_list);
793
		foreach ($filterdns_list as $hostname)
794
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
795
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
796
		unset($hostnames);
797

    
798
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
799
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
800
		else {
801
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
802
		}
803
	} else {
804
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
805
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
806
	}
807

    
808
	if ($g['booting'])
809
		echo "done\n";
810

    
811
	return count($filterdns_list);
812
}
813

    
814
/*
815
 * Forcefully restart IPsec
816
 * This is required for when dynamic interfaces reload
817
 * For all other occasions the normal vpn_ipsec_configure()
818
 * will gracefully reload the settings without restarting
819
 */
820
function vpn_ipsec_force_reload($interface = "") {
821
	global $g, $config;
822

    
823
	$ipseccfg = $config['ipsec'];
824

    
825
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
826
		$found = false;
827
		foreach ($ipseccfg['phase1'] as $ipsec) {
828
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
829
				$found = true;
830
				break;
831
			}
832
		}
833
		if (!$found) {
834
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
835
			return;
836
		}
837
	}
838

    
839
	/* if ipsec is enabled, start up again */
840
	if (isset($ipseccfg['enable'])) {
841
		log_error(gettext("Forcefully reloading IPsec"));
842
		vpn_ipsec_configure();
843
	}
844
}
845

    
846
/* master setup for vpn (mpd) */
847
function vpn_setup() {
848
	global $g;
849

    
850
	if ($g['platform'] == 'jail')
851
		return;
852

    
853
	/* start pptpd */
854
	vpn_pptpd_configure();
855

    
856
	/* start pppoe server */
857
	vpn_pppoes_configure();
858

    
859
	/* setup l2tp */
860
	vpn_l2tp_configure();
861
}
862

    
863
function vpn_netgraph_support() {
864
	$iflist = get_configured_interface_list();
865
	foreach ($iflist as $iface) {
866
		$realif = get_real_interface($iface);
867
		/* Get support for netgraph(4) from the nic */
868
		$ifinfo = pfSense_get_interface_addresses($realif);
869
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
870
			pfSense_ngctl_attach(".", $realif);
871
	}
872
}
873

    
874
function vpn_pptpd_configure() {
875
	global $config, $g;
876

    
877
	$syscfg = $config['system'];
878
	$pptpdcfg = $config['pptpd'];
879

    
880
	if ($g['booting']) {
881
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
882
			return 0;
883

    
884
		echo gettext("Configuring PPTP VPN service... ");
885
	} else {
886
		/* kill mpd */
887
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
888

    
889
		/* wait for process to die */
890
		sleep(3);
891

    
892
		if (is_process_running("mpd -b")) {
893
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
894
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
895
		}
896

    
897
		/* remove mpd.conf, if it exists */
898
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
899
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
900
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
901
	}
902

    
903
	if (empty($pptpdcfg['n_pptp_units'])) {
904
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
905
		return;
906
	}
907

    
908
	/* make sure pptp-vpn directory exists */
909
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
910
		mkdir("{$g['varetc_path']}/pptp-vpn");
911

    
912
	switch ($pptpdcfg['mode']) {
913
		case 'server' :
914
			/* write mpd.conf */
915
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
916
			if (!$fd) {
917
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
918
				return 1;
919
			}
920

    
921
			$mpdconf = <<<EOD
922
pptps:
923

    
924
EOD;
925

    
926
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
927
				$mpdconf .= "	load pt{$i}\n";
928
			}
929

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

    
932
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
933

    
934
				$mpdconf .= <<<EOD
935

    
936
pt{$i}:
937
	new -i pptpd{$i} pt{$i} pt{$i}
938
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
939
	load pts
940

    
941
EOD;
942
			}
943

    
944
			$mpdconf .=<<<EOD
945

    
946
pts:
947
	set iface disable on-demand
948
	set iface enable proxy-arp
949
	set iface enable tcpmssfix
950
	set iface idle 1800
951
	set iface up-script /usr/local/sbin/vpn-linkup
952
	set iface down-script /usr/local/sbin/vpn-linkdown
953
	set bundle enable multilink
954
	set bundle enable crypt-reqd
955
	set link yes acfcomp protocomp
956
	set link no pap chap
957
	set link enable chap-msv2
958
	set link mtu 1460
959
	set link keep-alive 10 60
960
	set ipcp yes vjcomp
961
	set bundle enable compression
962
	set ccp yes mppc
963
	set ccp yes mpp-e128
964
	set ccp yes mpp-stateless
965

    
966
EOD;
967

    
968
			if (!isset ($pptpdcfg['req128'])) {
969
				$mpdconf .=<<<EOD
970
	set ccp yes mpp-e40
971
	set ccp yes mpp-e56
972

    
973
EOD;
974
			}
975

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

    
979
			if (!empty($pptpdcfg['dns1'])) {
980
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
981
				if (!empty($pptpdcfg['dns2']))
982
					$mpdconf .= " " . $pptpdcfg['dns2'];
983
				$mpdconf .= "\n";
984
			} elseif (isset ($config['dnsmasq']['enable'])) {
985
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
986
				if ($syscfg['dnsserver'][0])
987
					$mpdconf .= " " . $syscfg['dnsserver'][0];
988
				$mpdconf .= "\n";
989
			} elseif (isset($config['unbound']['enable'])) {
990
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
991
				if ($syscfg['dnsserver'][0])
992
					$mpdconf .= " " . $syscfg['dnsserver'][0];
993
				$mpdconf .= "\n";
994
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
995
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
996
			}
997

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

    
1004
EOD;
1005
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1006
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1007
				$acctport = $authport + 1;
1008
				$mpdconf .=<<<EOD
1009
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1010

    
1011
EOD;
1012
			}
1013
			$mpdconf .=<<<EOD
1014
	set radius retries 3
1015
	set radius timeout 10
1016
	set auth enable radius-auth
1017

    
1018
EOD;
1019

    
1020
				if (isset ($pptpdcfg['radius']['accounting'])) {
1021
					$mpdconf .=<<<EOD
1022
	set auth enable radius-acct
1023
	set radius acct-update 300
1024

    
1025
EOD;
1026
				}
1027
			}
1028

    
1029
			fwrite($fd, $mpdconf);
1030
			fclose($fd);
1031
			unset($mpdconf);
1032

    
1033
			/* write mpd.links */
1034
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1035
			if (!$fd) {
1036
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1037
				return 1;
1038
			}
1039

    
1040
			$mpdlinks = "";
1041

    
1042
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1043
				$mpdlinks .=<<<EOD
1044

    
1045
pt{$i}:
1046
	set link type pptp
1047
	set pptp enable incoming
1048
	set pptp disable originate
1049
	set pptp disable windowing
1050

    
1051
EOD;
1052
			}
1053

    
1054
			fwrite($fd, $mpdlinks);
1055
			fclose($fd);
1056
			unset($mpdlinks);
1057

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

    
1065
			$mpdsecret = "";
1066

    
1067
			if (is_array($pptpdcfg['user'])) {
1068
				foreach ($pptpdcfg['user'] as $user) {
1069
					$pass = str_replace('\\', '\\\\', $user['password']);
1070
					$pass = str_replace('"', '\"', $pass);
1071
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1072
				}
1073
			}
1074

    
1075
			fwrite($fd, $mpdsecret);
1076
			fclose($fd);
1077
			unset($mpdsecret);
1078
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1079

    
1080
			vpn_netgraph_support();
1081

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

    
1085
			break;
1086

    
1087
		case 'redir' :
1088
			break;
1089
	}
1090

    
1091
	if ($g['booting'])
1092
		echo "done\n";
1093

    
1094
	return 0;
1095
}
1096

    
1097
function vpn_pppoes_configure() {
1098
	global $config;
1099

    
1100
	if (is_array($config['pppoes']['pppoe'])) {
1101
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1102
			vpn_pppoe_configure($pppoe);
1103
	}
1104
}
1105

    
1106
function vpn_pppoe_configure(&$pppoecfg) {
1107
	global $config, $g;
1108

    
1109
	$syscfg = $config['system'];
1110

    
1111
	/* create directory if it does not exist */
1112
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1113
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1114

    
1115
	if ($g['booting']) {
1116
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1117
			return 0;
1118

    
1119
		echo gettext("Configuring PPPoE VPN service... ");
1120
	} else {
1121
		/* kill mpd */
1122
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1123

    
1124
		/* wait for process to die */
1125
		sleep(2);
1126

    
1127
	}
1128

    
1129
	switch ($pppoecfg['mode']) {
1130

    
1131
		case 'server' :
1132

    
1133
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1134

    
1135
			if ($pppoecfg['paporchap'] == "chap")
1136
				$paporchap = "set link enable chap";
1137
			else
1138
				$paporchap = "set link enable pap";
1139

    
1140
			/* write mpd.conf */
1141
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1142
			if (!$fd) {
1143
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1144
				return 1;
1145
			}
1146
			$mpdconf = "\n\n";
1147
			$mpdconf .= "poes:\n";
1148

    
1149
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1150
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1151
			}
1152

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

    
1155
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1156

    
1157
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1158
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1159
				} else {
1160
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1161
				}
1162

    
1163
				$mpdconf .=<<<EOD
1164

    
1165
poes{$pppoecfg['pppoeid']}{$i}:
1166
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1167
	{$isssue_ip_type}
1168
	load pppoe_standard
1169

    
1170
EOD;
1171
			}
1172

    
1173
			$mpdconf .=<<<EOD
1174

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

    
1201
EOD;
1202

    
1203
			if (!empty($pppoecfg['dns1'])) {
1204
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1205
				if (!empty($pppoecfg['dns2']))
1206
					$mpdconf .= " " . $pppoecfg['dns2'];
1207
				$mpdconf .= "\n";
1208
			} elseif (isset ($config['dnsmasq']['enable'])) {
1209
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1210
				if ($syscfg['dnsserver'][0])
1211
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1212
				$mpdconf .= "\n";
1213
			} elseif (isset ($config['unbound']['enable'])) {
1214
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1215
				if ($syscfg['dnsserver'][0])
1216
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1217
				$mpdconf .= "\n";
1218
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1219
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1220
			}
1221

    
1222
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1223
				$radiusport = "";
1224
				$radiusacctport = "";
1225
				if (isset($pppoecfg['radius']['server']['port']))
1226
					$radiusport = $pppoecfg['radius']['server']['port'];
1227
				if (isset($pppoecfg['radius']['server']['acctport']))
1228
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1229
				$mpdconf .=<<<EOD
1230
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1231
	set radius retries 3
1232
	set radius timeout 10
1233
	set auth enable radius-auth
1234

    
1235
EOD;
1236

    
1237
				if (isset ($pppoecfg['radius']['accounting'])) {
1238
					$mpdconf .=<<<EOD
1239
	set auth enable radius-acct
1240

    
1241
EOD;
1242
				}
1243
			}
1244

    
1245
			fwrite($fd, $mpdconf);
1246
			fclose($fd);
1247
			unset($mpdconf);
1248

    
1249
			/* write mpd.links */
1250
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1251
			if (!$fd) {
1252
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1253
				return 1;
1254
			}
1255

    
1256
			$mpdlinks = "";
1257

    
1258
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1259
				$mpdlinks .=<<<EOD
1260

    
1261
poes{$pppoecfg['pppoeid']}{$i}:
1262
	set phys type pppoe
1263
	set pppoe iface {$pppoe_interface}
1264
	set pppoe service "*"
1265
	set pppoe disable originate
1266
	set pppoe enable incoming
1267

    
1268
EOD;
1269
			}
1270

    
1271
			fwrite($fd, $mpdlinks);
1272
			fclose($fd);
1273
			unset($mpdlinks);
1274

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

    
1283
				$mpdsecret = "\n\n";
1284

    
1285
				if (!empty($pppoecfg['username'])) {
1286
					$item = explode(" ", $pppoecfg['username']);
1287
					foreach($item as $userdata) {
1288
						$data = explode(":", $userdata);
1289
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1290
					}
1291
				}
1292

    
1293
				fwrite($fd, $mpdsecret);
1294
				fclose($fd);
1295
				unset($mpdsecret);
1296
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1297
			}
1298

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

    
1303
			/* Get support for netgraph(4) from the nic */
1304
			pfSense_ngctl_attach(".", $pppoe_interface);
1305
			/* fire up mpd */
1306
			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");
1307

    
1308
			break;
1309
	}
1310

    
1311
	if ($g['booting'])
1312
		echo gettext("done") . "\n";
1313

    
1314
	return 0;
1315
}
1316

    
1317
function vpn_l2tp_configure() {
1318
	global $config, $g;
1319

    
1320
	$syscfg = $config['system'];
1321
	$l2tpcfg = $config['l2tp'];
1322

    
1323
	/* create directory if it does not exist */
1324
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1325
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1326

    
1327
	if ($g['booting']) {
1328
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1329
			return 0;
1330

    
1331
		echo gettext("Configuring l2tp VPN service... ");
1332
	} else {
1333
		/* kill mpd */
1334
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1335

    
1336
		/* wait for process to die */
1337
		sleep(8);
1338

    
1339
	}
1340

    
1341
	/* make sure l2tp-vpn directory exists */
1342
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1343
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1344

    
1345
	switch ($l2tpcfg['mode']) {
1346

    
1347
		case 'server' :
1348
			if ($l2tpcfg['paporchap'] == "chap")
1349
				$paporchap = "set link enable chap";
1350
			else
1351
				$paporchap = "set link enable pap";
1352

    
1353
			/* write mpd.conf */
1354
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1355
			if (!$fd) {
1356
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1357
				return 1;
1358
			}
1359
			$mpdconf = "\n\n";
1360
			$mpdconf .=<<<EOD
1361
l2tps:
1362

    
1363
EOD;
1364

    
1365
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1366
				$mpdconf .= "	load l2tp{$i}\n";
1367
			}
1368

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

    
1371
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1372

    
1373
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1374
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1375
				} else {
1376
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1377
				}
1378

    
1379
				$mpdconf .=<<<EOD
1380

    
1381
l2tp{$i}:
1382
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1383
	{$isssue_ip_type}
1384
	load l2tp_standard
1385

    
1386
EOD;
1387
			}
1388

    
1389
			$mpdconf .=<<<EOD
1390

    
1391
l2tp_standard:
1392
	set bundle disable multilink
1393
	set bundle enable compression
1394
	set bundle yes crypt-reqd
1395
	set ipcp yes vjcomp
1396
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1397
	set ccp yes mppc
1398
	set iface disable on-demand
1399
	set iface enable proxy-arp
1400
	set iface up-script /usr/local/sbin/vpn-linkup
1401
	set iface down-script /usr/local/sbin/vpn-linkdown
1402
	set link yes acfcomp protocomp
1403
	set link no pap chap
1404
	set link enable chap
1405
	set link keep-alive 10 180
1406

    
1407
EOD;
1408

    
1409
			if (is_ipaddr($l2tpcfg['wins'])) {
1410
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1411
			}
1412
			if (is_ipaddr($l2tpcfg['dns1'])) {
1413
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1414
				if (is_ipaddr($l2tpcfg['dns2']))
1415
					$mpdconf .= " " . $l2tpcfg['dns2'];
1416
				$mpdconf .= "\n";
1417
			} elseif (isset ($config['dnsmasq']['enable'])) {
1418
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1419
				if ($syscfg['dnsserver'][0])
1420
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1421
				$mpdconf .= "\n";
1422
			} elseif (isset ($config['unbound']['enable'])) {
1423
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1424
				if ($syscfg['dnsserver'][0])
1425
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1426
				$mpdconf .= "\n";
1427
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1428
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1429
			}
1430

    
1431
			if (isset ($l2tpcfg['radius']['enable'])) {
1432
				$mpdconf .=<<<EOD
1433
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1434
	set radius retries 3
1435
	set radius timeout 10
1436
	set auth enable radius-auth
1437

    
1438
EOD;
1439

    
1440
				if (isset ($l2tpcfg['radius']['accounting'])) {
1441
					$mpdconf .=<<<EOD
1442
	set auth enable radius-acct
1443

    
1444
EOD;
1445
				}
1446
			}
1447

    
1448
			fwrite($fd, $mpdconf);
1449
			fclose($fd);
1450
			unset($mpdconf);
1451

    
1452
			/* write mpd.links */
1453
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1454
			if (!$fd) {
1455
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1456
				return 1;
1457
			}
1458

    
1459
			$mpdlinks = "";
1460

    
1461
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1462
				$mpdlinks .=<<<EOD
1463

    
1464
l2tp{$i}:
1465
	set link type l2tp
1466
	set l2tp enable incoming
1467
	set l2tp disable originate
1468

    
1469
EOD;
1470
			if (!empty($l2tpcfg['secret']))
1471
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1472
			}
1473

    
1474
			fwrite($fd, $mpdlinks);
1475
			fclose($fd);
1476
			unset($mpdlinks);
1477

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

    
1485
			$mpdsecret = "\n\n";
1486

    
1487
			if (is_array($l2tpcfg['user'])) {
1488
				foreach ($l2tpcfg['user'] as $user)
1489
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1490
			}
1491

    
1492
			fwrite($fd, $mpdsecret);
1493
			fclose($fd);
1494
			unset($mpdsecret);
1495
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1496

    
1497
			vpn_netgraph_support();
1498

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

    
1502
			break;
1503

    
1504
		case 'redir' :
1505
			break;
1506
	}
1507

    
1508
	if ($g['booting'])
1509
		echo "done\n";
1510

    
1511
	return 0;
1512
}
1513

    
1514
function vpn_ipsec_configure_preferoldsa() {
1515
	global $config;
1516
	if(isset($config['ipsec']['preferoldsa']))
1517
		set_single_sysctl("net.key.preferred_oldsa", "-30");
1518
	else
1519
		set_single_sysctl("net.key.preferred_oldsa", "0");
1520
}
1521

    
1522
?>
(59-59/68)