Projet

Général

Profil

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

univnautes / etc / inc / vpn.inc @ 5ed13df0

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
				$strongswan .= "\t\tsubnet = {$a_client['pool_address']}/{$a_client['pool_netmask']}\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 (!empty($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 ($net_list)
337
						$net_list .= ", ";
338
					$net_list .= $localid;
339
				}
340

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

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

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

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

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

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

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

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

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

    
415
		$pskconf = "";
416

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

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

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

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

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

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

    
435
						chmod($certpath, 0600);
436

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
723

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

    
727
					$ipsecconf .=<<<EOD
728

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

    
746
EOD;
747

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

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

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

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

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

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

    
804
	return count($filterdns_list);
805
}
806

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
917
EOD;
918

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

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

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

    
927
				$mpdconf .= <<<EOD
928

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

    
934
EOD;
935
			}
936

    
937
			$mpdconf .=<<<EOD
938

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

    
959
EOD;
960

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

    
966
EOD;
967
			}
968

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

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

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

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

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

    
1011
EOD;
1012

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

    
1018
EOD;
1019
				}
1020
			}
1021

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

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

    
1033
			$mpdlinks = "";
1034

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

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

    
1044
EOD;
1045
			}
1046

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

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

    
1058
			$mpdsecret = "";
1059

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

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

    
1073
			vpn_netgraph_support();
1074

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

    
1078
			break;
1079

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

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

    
1087
	return 0;
1088
}
1089

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

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

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

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

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

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

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

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

    
1120
	}
1121

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

    
1124
		case 'server' :
1125

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

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

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

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

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

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

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

    
1156
				$mpdconf .=<<<EOD
1157

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

    
1163
EOD;
1164
			}
1165

    
1166
			$mpdconf .=<<<EOD
1167

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

    
1194
EOD;
1195

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

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

    
1228
EOD;
1229

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

    
1234
EOD;
1235
				}
1236
			}
1237

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

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

    
1249
			$mpdlinks = "";
1250

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

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

    
1261
EOD;
1262
			}
1263

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

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

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

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

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

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

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

    
1301
			break;
1302
	}
1303

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

    
1307
	return 0;
1308
}
1309

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

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

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

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

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

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

    
1332
	}
1333

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

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

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

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

    
1356
EOD;
1357

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

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

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

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

    
1372
				$mpdconf .=<<<EOD
1373

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

    
1379
EOD;
1380
			}
1381

    
1382
			$mpdconf .=<<<EOD
1383

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

    
1400
EOD;
1401

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

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

    
1431
EOD;
1432

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

    
1437
EOD;
1438
				}
1439
			}
1440

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

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

    
1452
			$mpdlinks = "";
1453

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

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

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

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

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

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

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

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

    
1490
			vpn_netgraph_support();
1491

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

    
1495
			break;
1496

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

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

    
1504
	return 0;
1505
}
1506

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

    
1515
?>
(58-58/67)