Projet

Général

Profil

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

univnautes / etc / inc / vpn.inc @ 95589abd

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']) && !empty($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
				$pool_address = $a_client['pool_address'];
302
				$pool_netmask = gen_subnet_mask($a_client['pool_netbits']);
303
				$pool_address = long2ip32(ip2long($pool_address)+1);
304

    
305
				$strongswan .= "\t\taddress = {$pool_address}\n";
306
				$strongswan .= "\t\tnetmask = {$pool_netmask}\n";
307
			}
308

    
309
			$cfgservers = array();
310
			if (!empty($a_client['dns_server1']))
311
				$cfgservers[] = $a_client['dns_server1'];
312
			if (!empty($a_client['dns_server2']))
313
				$cfgservers[] = $a_client['dns_server2'];
314
			if (!empty($a_client['dns_server3']))
315
				$cfgservers[] = $a_client['dns_server3'];
316
			if (!empty($a_client['dns_server4']))
317
				$cfgservers[] = $a_client['dns_server4'];
318

    
319
			if (!empty($cfgservers))
320
				$strongswan .= "\t\tdns = " . implode(",", $cfgservers) . "\n";
321
			unset($cfgservers);
322
			$cfgservers = array();
323
			if (!empty($a_client['wins_server1']))
324
				$cfgservers[] = $a_client['wins_server1'];
325
			if (!empty($a_client['wins_server2']))
326
				$cfgservers[] = $a_client['wins_server2'];
327
			if (!empty($cfgservers))
328
				$strongswan .= "\t\tnbns = " . implode(",", $cfgservers) . "\n";
329
			unset($cfgservers);
330

    
331
			if (!empty($a_client['net_list'])) {
332
				$net_list = '';
333
				foreach ($a_phase2 as $ph2ent) {
334
					if (isset($ph2ent['disabled']))
335
						continue;
336

    
337
					if (!isset($ph2ent['mobile']))
338
						continue;
339

    
340
					$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
341

    
342
					if ($net_list)
343
						$net_list .= ", ";
344
					$net_list .= $localid;
345
				}
346

    
347
				if (!empty($net_list)) {
348
					$strongswan .= "\t\tsubnet = {$net_list}\n";
349
					$strongswan .= "\t\tsplit-include = {$net_list}\n";
350
					unset($net_list);
351
				}
352
			}
353

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

    
362
			if (!empty($a_client['dns_split'])) {
363
				$strongswan .= "\t\t28675 = {$a_client['dns_split']}\n";
364
			}
365

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

    
369
			if (isset($a_client['save_passwd']))
370
				$strongswan .= "\t\t28673 = yes\n";
371

    
372
			if ($a_client['pfs_group'])
373
				$strongswan .= "\t\t28679 = {$a_client['pfs_group']}\n";
374
			$strongswan .= "\t\t}\n";
375

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

    
395
		$strongswan .= "\t}\n}\n";
396
		@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
397
		unset($strongswan);
398

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

    
421
		$pskconf = "";
422

    
423
		if (is_array($a_phase1) && count($a_phase1)) {
424
			foreach ($a_phase1 as $ph1ent) {
425

    
426
				if (isset($ph1ent['disabled']))
427
					continue;
428

    
429
				if (strstr($ph1ent['authentication_method'],'rsa')) {
430
					$certline = '';
431

    
432
					if (strstr($authmethod,'rsa')) {
433

    
434
						$cert = lookup_cert($ph1ent['certref']);
435

    
436
						if (!$cert) {
437
							log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
438
							continue;
439
						}
440

    
441
						chmod($certpath, 0600);
442

    
443
						$keyfile = "cert-{$ikeid}.key";
444
						$keypath = "{$g['varetc_path']}/ipsec/{$keyfile}";
445

    
446
						if (!file_put_contents($keypath, base64_decode($cert['prv']))) {
447
							log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
448
							continue;
449
						}
450

    
451
						chmod($keypath, 0600);
452
						/* XXX" Traffic selectors? */
453
						$pskconf .= " : RSA {$keypath}\n";
454

    
455
						$ca = lookup_ca($ph1ent['caref']);
456
						if ($ca) {
457
							$cafile = "ca-{$ikeid}.crt";
458
							$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts/{$cafile}";
459

    
460
							if (!file_put_contents($capath, base64_decode($ca['crt'])))
461
							{
462
								log_error(sprintf(gettext("Error: Cannot write phase1 CA certificate file for %s"), $ph1ent['name']));
463
								continue;
464
							}
465

    
466
							chmod($capath, 0600);
467
						}
468
					}
469
				} else {
470
					list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, "local");
471
					list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, "peer", $rgmap);
472

    
473
					if (empty($peerid_data))
474
						continue;
475

    
476
					$myid = isset($ph1ent['mobile']) ? trim($myid_data) . " " : "";
477
					$peerid = ($peerid_data != "allusers") ? trim($peerid_data) : "";
478
					if (!empty($ph1ent['pre-shared-key']))
479
						$pskconf .= $myid . $peerid . " : PSK \"" . trim($ph1ent['pre-shared-key']) . "\"\n";
480
				}
481
			}
482
		}
483

    
484
		/* Add user PSKs */
485
		foreach ($config['system']['user'] as $user) {
486
			if (!empty($user['ipsecpsk'])) {
487
				$pskconf .= "{$user['name']} : PSK \"{$user['ipsecpsk']}\"\n";
488
			}
489
		}
490

    
491
		/* add PSKs for mobile clients */
492
		if (is_array($ipseccfg['mobilekey'])) {
493
			foreach ($ipseccfg['mobilekey'] as $key) {
494
				if ($key['ident'] == "allusers")
495
					$key['ident'] = '';
496
				$pskconf .= "{$key['ident']} : PSK \"{$key['pre-shared-key']}\"\n";
497
			}
498
		}
499

    
500
		@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
501
		chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
502
		unset($pskconf);
503

    
504
		$natfilterrules = false;
505
		/* begin ipsec.conf */
506
		$ipsecconf = "";
507
		if ((is_array($a_phase1) && count($a_phase1)) || (is_array($a_phase2) && count($a_phase2))) {
508

    
509
			$ipsecconf .= "# This file is automatically generated. Do not edit\n";
510
			if (is_array($a_phase2) && count($a_phase2)) {
511
				$ipsecconf .= "config setup\n\tuniqueids = yes\n";
512
				$ipsecconf .= "\tcharondebug=\"" . vpn_ipsec_configure_loglevels(true) . "\"\n";
513

    
514
				foreach ($a_phase2 as $ph2ent) {
515
					$ikeid = $ph2ent['ikeid'];
516

    
517
					$ph1ent = false;
518
					if (!ipsec_lookup_phase1($ph2ent,$ph1ent))
519
						continue;
520

    
521
					if (isset($ph1ent['disabled']))
522
						continue;
523

    
524
					if (isset($ph2ent['disabled']))
525
						continue;
526

    
527
					if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
528
						continue;
529

    
530
					$ikeid = $ph1ent['ikeid'];
531

    
532
					if ($ph1ent['mode'] == "aggressive")
533
						$aggressive = "yes";
534
					else
535
						$aggressive = "no";
536

    
537
					$ep = ipsec_get_phase1_src($ph1ent);
538
					if (!$ep)
539
						continue;
540

    
541
					$passive = "start";
542
					if (isset($ph1ent['mobile'])) {
543
						$rgip = "%any";
544
						$passive = 'add';
545
					} else
546
						$rgip = $ph1ent['remote-gateway'];
547

    
548
					$keyexchange = "ikev1";
549
					if (!empty($ph1ent['iketype']) && $ph1ent['iketype'] != "ikev1")
550
						$keyexchange = "ikev2";
551

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

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

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

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

    
573
						if ($keyexchange == "ikev1")
574
							$ealgosp1 .= "!";
575
					}
576

    
577
					if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
578
						if ($passive == "start")
579
							$dpdline = "dpdaction = restart";
580
						else
581
							$dpdline = "dpdaction = clear";
582
						$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
583
						$dpdline .= "\n\tdpdtimeout = {$ph1ent['dpd_maxfail']}s";
584
					} else
585
						$dpdline = "dpdaction = none";
586

    
587
					if (!empty($ph1ent['authentication_method']) && (strpos($ph1ent['authentication_method'], "xauth") || strpos($ph1ent['authentication_method'], "hybrid")))
588
						$xauth = "xauth = server";
589

    
590
					$lifeline = '';
591
					if ($ph1ent['lifetime'])
592
						$lifeline = "ikelifetime = {$ph1ent['lifetime']}s";
593

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

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

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

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

    
671
					if (isset($a_client['pfs_group']))
672
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
673

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

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

    
729

    
730
					if ($ph2ent['lifetime'])
731
						$lifeline = "ikelifetime = {$ph2ent['lifetime']}s";
732

    
733
					$ipsecconf .=<<<EOD
734

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

    
752
EOD;
753

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

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

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

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

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

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

    
810
	return count($filterdns_list);
811
}
812

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
923
EOD;
924

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

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

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

    
933
				$mpdconf .= <<<EOD
934

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

    
940
EOD;
941
			}
942

    
943
			$mpdconf .=<<<EOD
944

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

    
965
EOD;
966

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

    
972
EOD;
973
			}
974

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

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

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

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

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

    
1017
EOD;
1018

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

    
1024
EOD;
1025
				}
1026
			}
1027

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

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

    
1039
			$mpdlinks = "";
1040

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

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

    
1050
EOD;
1051
			}
1052

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

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

    
1064
			$mpdsecret = "";
1065

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

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

    
1079
			vpn_netgraph_support();
1080

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

    
1084
			break;
1085

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

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

    
1093
	return 0;
1094
}
1095

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

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

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

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

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

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

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

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

    
1126
	}
1127

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

    
1130
		case 'server' :
1131

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

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

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

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

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

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

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

    
1162
				$mpdconf .=<<<EOD
1163

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

    
1169
EOD;
1170
			}
1171

    
1172
			$mpdconf .=<<<EOD
1173

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

    
1200
EOD;
1201

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

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

    
1234
EOD;
1235

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

    
1240
EOD;
1241
				}
1242
			}
1243

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

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

    
1255
			$mpdlinks = "";
1256

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

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

    
1267
EOD;
1268
			}
1269

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

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

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

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

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

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

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

    
1307
			break;
1308
	}
1309

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

    
1313
	return 0;
1314
}
1315

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

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

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

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

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

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

    
1338
	}
1339

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

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

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

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

    
1362
EOD;
1363

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

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

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

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

    
1378
				$mpdconf .=<<<EOD
1379

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

    
1385
EOD;
1386
			}
1387

    
1388
			$mpdconf .=<<<EOD
1389

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

    
1406
EOD;
1407

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

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

    
1437
EOD;
1438

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

    
1443
EOD;
1444
				}
1445
			}
1446

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

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

    
1458
			$mpdlinks = "";
1459

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

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

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

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

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

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

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

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

    
1496
			vpn_netgraph_support();
1497

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

    
1501
			break;
1502

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

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

    
1510
	return 0;
1511
}
1512

    
1513
function vpn_ipsec_configure_preferoldsa() {
1514
	global $config;
1515
	if(isset($config['ipsec']['preferoldsa']))
1516
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
1517
	else
1518
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
1519
}
1520

    
1521
?>
(58-58/67)