Projet

Général

Profil

Télécharger (44,1 ko) Statistiques
| Branche: | Tag: | Révision:

univnautes / etc / inc / vpn.inc @ dc63467f

1
<?php
2

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

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

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

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

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

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

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

    
43
require_once("ipsec.inc");
44

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

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

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

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

    
94
	return $convertion;
95
}
96

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

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

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

    
108
	vpn_ipsec_configure_preferoldsa();
109

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
272
		$strongswan = <<<EOD
273

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

    
279
charon {
280

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

    
284
	# NOTE: Allows to send multiple subnets for IKEv1
285
	cisco_unity = yes
286

    
287
	# XXX: There is not much choice here really users win their security!
288
	i_dont_care_about_security_and_use_aggressive_mode_psk=yes
289

    
290
	# And two loggers using syslog. The subsections define the facility to log
291
	# to, currently one of: daemon, auth.
292
	syslog {
293

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

    
306
EOD;
307

    
308
		if (is_array($a_client) && isset($a_client['enable']) && isset($a_client['net_list']))
309
			$strongswan .= "\tcisco_unity = yes\n";
310

    
311
		$strongswan .= "\tplugins {\n";
312

    
313
		if (is_array($a_client) && isset($a_client['enable'])) {
314
			$strongswan .= "\t\tattr {\n";
315
			if ($a_client['pool_address'] && $a_client['pool_netbits'])
316
				$strongswan .= "\t\tsubnet = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
317

    
318
			$cfgservers = array();
319
			if (!empty($a_client['dns_server1']))
320
				$cfgservers[] = $a_client['dns_server1'];
321
			if (!empty($a_client['dns_server2']))
322
				$cfgservers[] = $a_client['dns_server2'];
323
			if (!empty($a_client['dns_server3']))
324
				$cfgservers[] = $a_client['dns_server3'];
325
			if (!empty($a_client['dns_server4']))
326
				$cfgservers[] = $a_client['dns_server4'];
327

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

    
340
			if (isset($a_client['net_list'])) {
341
				$net_list = '';
342
				foreach ($a_phase2 as $ph2ent) {
343
					if (isset($ph2ent['disabled']))
344
						continue;
345

    
346
					if (!isset($ph2ent['mobile']))
347
						continue;
348

    
349
					$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
350

    
351
					if (!empty($net_list))
352
						$net_list .= ",";
353
					$net_list .= $localid;
354
				}
355

    
356
				if (!empty($net_list)) {
357
					$strongswan .= "\t\tsplit-include = {$net_list}\n";
358
					unset($net_list);
359
				}
360
			}
361

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

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

    
374
			if (!empty($a_client['login_banner']))
375
				$strongswan .= "\t\t28672 = {$a_client['login_banner']}\n";
376

    
377
			if (isset($a_client['save_passwd']))
378
				$strongswan .= "\t\t28673 = yes\n";
379

    
380
			if ($a_client['pfs_group'])
381
				$strongswan .= "\t\t28679 = {$a_client['pfs_group']}\n";
382
			$strongswan .= "\t\t}\n";
383

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

    
403
		$strongswan .= "\t}\n}\n";
404
		@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
405
		unset($strongswan);
406

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

    
429
		$pskconf = "";
430

    
431
		if (is_array($a_phase1) && count($a_phase1)) {
432
			foreach ($a_phase1 as $ph1ent) {
433

    
434
				if (isset($ph1ent['disabled']))
435
					continue;
436

    
437
				if (strstr($ph1ent['authentication_method'],'rsa')) {
438
					$certline = '';
439

    
440
					if (strstr($authmethod,'rsa')) {
441

    
442
						$cert = lookup_cert($ph1ent['certref']);
443

    
444
						if (!$cert) {
445
							log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
446
							continue;
447
						}
448

    
449
						chmod($certpath, 0600);
450

    
451
						$keyfile = "cert-{$ikeid}.key";
452
						$keypath = "{$g['varetc_path']}/ipsec/{$keyfile}";
453

    
454
						if (!file_put_contents($keypath, base64_decode($cert['prv']))) {
455
							log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
456
							continue;
457
						}
458

    
459
						chmod($keypath, 0600);
460
						/* XXX" Traffic selectors? */
461
						$pskconf .= " : RSA {$keypath}\n";
462

    
463
						$ca = lookup_ca($ph1ent['caref']);
464
						if ($ca) {
465
							$cafile = "ca-{$ikeid}.crt";
466
							$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts/{$cafile}";
467

    
468
							if (!file_put_contents($capath, base64_decode($ca['crt'])))
469
							{
470
								log_error(sprintf(gettext("Error: Cannot write phase1 CA certificate file for %s"), $ph1ent['name']));
471
								continue;
472
							}
473

    
474
							chmod($capath, 0600);
475
						}
476
					}
477
				} else {
478
					list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, "local");
479
					list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, "peer", $rgmap);
480

    
481
					if (empty($peerid_data))
482
						continue;
483

    
484
					$myid = isset($ph1ent['mobile']) ? trim($myid_data) . " " : "";
485
					$peerid = ($peerid_data != "allusers") ? trim($peerid_data) : "";
486
					if (!empty($ph1ent['pre-shared-key']))
487
						$pskconf .= $myid . $peerid . " : PSK \"" . trim($ph1ent['pre-shared-key']) . "\"\n";
488
				}
489
			}
490
		}
491

    
492
		/* Add user PSKs */
493
		if (is_array($config['system']) && is_array($config['system']['user'])) {
494
			foreach ($config['system']['user'] as $user) {
495
				if (!empty($user['ipsecpsk'])) {
496
					$pskconf .= "{$user['name']} : PSK \"{$user['ipsecpsk']}\"\n";
497
				}
498
			}
499
			unset($user);
500
		}
501

    
502
		/* add PSKs for mobile clients */
503
		if (is_array($ipseccfg['mobilekey'])) {
504
			foreach ($ipseccfg['mobilekey'] as $key) {
505
				if ($key['ident'] == "allusers")
506
					$key['ident'] = '';
507
				$pskconf .= "{$key['ident']} : PSK \"{$key['pre-shared-key']}\"\n";
508
			}
509
			unset($key);
510
		}
511

    
512
		@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
513
		chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
514
		unset($pskconf);
515

    
516
		$natfilterrules = false;
517
		/* begin ipsec.conf */
518
		$ipsecconf = "";
519
		if (is_array($a_phase1) && count($a_phase1))  {
520

    
521
			$ipsecconf .= "# This file is automatically generated. Do not edit\n";
522
			$ipsecconf .= "config setup\n\tuniqueids = yes\n";
523
			$ipsecconf .= "\tcharondebug=\"" . vpn_ipsec_configure_loglevels(true) . "\"\n";
524

    
525
			foreach ($a_phase1 as $ph1ent) {
526
				if (isset($ph1ent['disabled']))
527
					continue;
528

    
529
				if ($ph1ent['mode'] == "aggressive")
530
					$aggressive = "yes";
531
				else
532
					$aggressive = "no";
533

    
534
				$ep = ipsec_get_phase1_src($ph1ent);
535
				if (!$ep)
536
					continue;
537

    
538
				$keyexchange = "ikev1";
539
				if (!empty($ph1ent['iketype']) && $ph1ent['iketype'] != "ikev1") {
540
					$keyexchange = "ikev2";
541
					$passive = "start";
542
				} else
543
					$passive = "route";
544

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

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

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

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

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

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

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

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

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

    
613
				$left_spec = $ep;
614

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

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

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

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

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

    
663
						$leftsubnet_spec[] = $leftsubnet_data;
664

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

    
672
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
673
						    ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) {
674
							$left_spec = "%any";
675
						} else {
676
							$leftsubnet_spec[] = ipsec_get_phase1_src($ph1ent);
677
						}
678

    
679
						if (!isset($ph2ent['mobile']))
680
							$rightsubnet_spec[] = $right_spec;
681
					}
682

    
683
					if (isset($a_client['pfs_group']))
684
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
685

    
686
					if ($ph2ent['protocol'] == 'esp') {
687
						if (is_array($ph2ent['encryption-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
688
							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
689
								$ealg_id = $ealg['name'];
690
								$ealg_kl = $ealg['keylen'];
691

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

    
737

    
738
					if (!empty($ph2ent['lifetime'])) {
739
						if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime']))
740
							$ipseclifetime = intval($ph2ent['lifetime']);
741
					}
742
				}
743
			}
744

    
745
				$ipsecconf .=<<<EOD
746

    
747
conn con{$ph1ent['ikeid']}
748
	aggressive = {$aggressive}
749
	fragmentation = yes
750
	keyexchange = {$keyexchange}
751
	reauth = yes
752
	rekey = yes
753
	reqid = {$ikeid}
754
	installpolicy = yes
755
	{$tunneltype}
756
	{$dpdline}
757
	auto = {$passive}
758
	left = {$left_spec}
759
	right = {$right_spec}
760
	leftid = {$myid_data}
761

    
762
EOD;
763

    
764
				if (!empty($ikelifeline))
765
					$ipsecconf .= "\t{$ikelifeline}\n";
766
				if ($ipseclifetime > 0)
767
					$ipsecconf .= "\tlifetime = {$ipseclifetime}s\n";
768
				if (!empty($rightsubnet_spec))
769
					$ipsecconf .= "\trightsubnet = " . join(",", $rightsubnet_spec) . "\n";
770
				if (!empty($leftsubnet_spec))
771
					$ipsecconf .= "\tleftsubnet = " . join(",", $leftsubnet_spec) . "\n";
772
				if (!empty($ealgosp1))
773
					$ipsecconf .= "\t{$ealgosp1}\n";
774
				if (!empty($ealgoAHsp2arr))
775
					$ipsecconf .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
776
				if (!empty($ealgoESPsp2arr))
777
					$ipsecconf .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
778
				if (!empty($authentication))
779
					$ipsecconf .= "\t{$authentication}\n";
780
				if (!empty($peerid_spec))
781
					$ipsecconf .= "\trightid = {$peerid_spec}\n";
782
			}
783
		}
784
	}
785
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
786
	unset($ipsecconf);
787
	/* end ipsec.conf */
788

    
789
	/* mange process */
790
	if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
791
		/* Read secrets */
792
		mwexec("/usr/local/sbin/ipsec rereadall", false);
793
		/* Update configuration changes */
794
		mwexec("/usr/local/sbin/ipsec reload", false);
795
	} else {
796
		mwexec("/usr/local/sbin/ipsec start", false); 
797
	}
798

    
799
	if ($natfilterrules == true)
800
		filter_configure();
801
	/* start filterdns, if necessary */
802
	if (count($filterdns_list) > 0) {
803
		$interval = 60;
804
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
805
			$interval = $ipseccfg['dns-interval'];
806

    
807
		$hostnames = "";
808
		array_unique($filterdns_list);
809
		foreach ($filterdns_list as $hostname)
810
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
811
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
812
		unset($hostnames);
813

    
814
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
815
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
816
		else {
817
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
818
		}
819
	} else {
820
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
821
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
822
	}
823

    
824
	if ($g['booting'])
825
		echo "done\n";
826

    
827
	return count($filterdns_list);
828
}
829

    
830
/*
831
 * Forcefully restart IPsec
832
 * This is required for when dynamic interfaces reload
833
 * For all other occasions the normal vpn_ipsec_configure()
834
 * will gracefully reload the settings without restarting
835
 */
836
function vpn_ipsec_force_reload($interface = "") {
837
	global $g, $config;
838

    
839
	$ipseccfg = $config['ipsec'];
840

    
841
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
842
		$found = false;
843
		foreach ($ipseccfg['phase1'] as $ipsec) {
844
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
845
				$found = true;
846
				break;
847
			}
848
		}
849
		if (!$found) {
850
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
851
			return;
852
		}
853
	}
854

    
855
	/* if ipsec is enabled, start up again */
856
	if (isset($ipseccfg['enable'])) {
857
		log_error(gettext("Forcefully reloading IPsec"));
858
		vpn_ipsec_configure();
859
	}
860
}
861

    
862
/* master setup for vpn (mpd) */
863
function vpn_setup() {
864
	global $g;
865

    
866
	if ($g['platform'] == 'jail')
867
		return;
868

    
869
	/* start pptpd */
870
	vpn_pptpd_configure();
871

    
872
	/* start pppoe server */
873
	vpn_pppoes_configure();
874

    
875
	/* setup l2tp */
876
	vpn_l2tp_configure();
877
}
878

    
879
function vpn_netgraph_support() {
880
	$iflist = get_configured_interface_list();
881
	foreach ($iflist as $iface) {
882
		$realif = get_real_interface($iface);
883
		/* Get support for netgraph(4) from the nic */
884
		$ifinfo = pfSense_get_interface_addresses($realif);
885
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
886
			pfSense_ngctl_attach(".", $realif);
887
	}
888
}
889

    
890
function vpn_pptpd_configure() {
891
	global $config, $g;
892

    
893
	$syscfg = $config['system'];
894
	$pptpdcfg = $config['pptpd'];
895

    
896
	if ($g['booting']) {
897
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
898
			return 0;
899

    
900
		echo gettext("Configuring PPTP VPN service... ");
901
	} else {
902
		/* kill mpd */
903
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
904

    
905
		/* wait for process to die */
906
		sleep(3);
907

    
908
		if (is_process_running("mpd -b")) {
909
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
910
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
911
		}
912

    
913
		/* remove mpd.conf, if it exists */
914
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
915
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
916
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
917
	}
918

    
919
	if (empty($pptpdcfg['n_pptp_units'])) {
920
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
921
		return;
922
	}
923

    
924
	/* make sure pptp-vpn directory exists */
925
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
926
		mkdir("{$g['varetc_path']}/pptp-vpn");
927

    
928
	switch ($pptpdcfg['mode']) {
929
		case 'server' :
930
			/* write mpd.conf */
931
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
932
			if (!$fd) {
933
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
934
				return 1;
935
			}
936

    
937
			$mpdconf = <<<EOD
938
pptps:
939

    
940
EOD;
941

    
942
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
943
				$mpdconf .= "	load pt{$i}\n";
944
			}
945

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

    
948
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
949

    
950
				$mpdconf .= <<<EOD
951

    
952
pt{$i}:
953
	new -i pptpd{$i} pt{$i} pt{$i}
954
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
955
	load pts
956

    
957
EOD;
958
			}
959

    
960
			$mpdconf .=<<<EOD
961

    
962
pts:
963
	set iface disable on-demand
964
	set iface enable proxy-arp
965
	set iface enable tcpmssfix
966
	set iface idle 1800
967
	set iface up-script /usr/local/sbin/vpn-linkup
968
	set iface down-script /usr/local/sbin/vpn-linkdown
969
	set bundle enable multilink
970
	set bundle enable crypt-reqd
971
	set link yes acfcomp protocomp
972
	set link no pap chap
973
	set link enable chap-msv2
974
	set link mtu 1460
975
	set link keep-alive 10 60
976
	set ipcp yes vjcomp
977
	set bundle enable compression
978
	set ccp yes mppc
979
	set ccp yes mpp-e128
980
	set ccp yes mpp-stateless
981

    
982
EOD;
983

    
984
			if (!isset ($pptpdcfg['req128'])) {
985
				$mpdconf .=<<<EOD
986
	set ccp yes mpp-e40
987
	set ccp yes mpp-e56
988

    
989
EOD;
990
			}
991

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

    
995
			if (!empty($pptpdcfg['dns1'])) {
996
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
997
				if (!empty($pptpdcfg['dns2']))
998
					$mpdconf .= " " . $pptpdcfg['dns2'];
999
				$mpdconf .= "\n";
1000
			} elseif (isset ($config['dnsmasq']['enable'])) {
1001
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1002
				if ($syscfg['dnsserver'][0])
1003
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1004
				$mpdconf .= "\n";
1005
			} elseif (isset($config['unbound']['enable'])) {
1006
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1007
				if ($syscfg['dnsserver'][0])
1008
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1009
				$mpdconf .= "\n";
1010
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1011
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1012
			}
1013

    
1014
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1015
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1016
				$acctport = $authport + 1;
1017
				$mpdconf .=<<<EOD
1018
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1019

    
1020
EOD;
1021
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1022
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1023
				$acctport = $authport + 1;
1024
				$mpdconf .=<<<EOD
1025
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1026

    
1027
EOD;
1028
			}
1029
			$mpdconf .=<<<EOD
1030
	set radius retries 3
1031
	set radius timeout 10
1032
	set auth enable radius-auth
1033

    
1034
EOD;
1035

    
1036
				if (isset ($pptpdcfg['radius']['accounting'])) {
1037
					$mpdconf .=<<<EOD
1038
	set auth enable radius-acct
1039
	set radius acct-update 300
1040

    
1041
EOD;
1042
				}
1043
			}
1044

    
1045
			fwrite($fd, $mpdconf);
1046
			fclose($fd);
1047
			unset($mpdconf);
1048

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

    
1056
			$mpdlinks = "";
1057

    
1058
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1059
				$mpdlinks .=<<<EOD
1060

    
1061
pt{$i}:
1062
	set link type pptp
1063
	set pptp enable incoming
1064
	set pptp disable originate
1065
	set pptp disable windowing
1066

    
1067
EOD;
1068
			}
1069

    
1070
			fwrite($fd, $mpdlinks);
1071
			fclose($fd);
1072
			unset($mpdlinks);
1073

    
1074
			/* write mpd.secret */
1075
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1076
			if (!$fd) {
1077
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1078
				return 1;
1079
			}
1080

    
1081
			$mpdsecret = "";
1082

    
1083
			if (is_array($pptpdcfg['user'])) {
1084
				foreach ($pptpdcfg['user'] as $user) {
1085
					$pass = str_replace('\\', '\\\\', $user['password']);
1086
					$pass = str_replace('"', '\"', $pass);
1087
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1088
				}
1089
			}
1090

    
1091
			fwrite($fd, $mpdsecret);
1092
			fclose($fd);
1093
			unset($mpdsecret);
1094
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1095

    
1096
			vpn_netgraph_support();
1097

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

    
1101
			break;
1102

    
1103
		case 'redir' :
1104
			break;
1105
	}
1106

    
1107
	if ($g['booting'])
1108
		echo "done\n";
1109

    
1110
	return 0;
1111
}
1112

    
1113
function vpn_pppoes_configure() {
1114
	global $config;
1115

    
1116
	if (is_array($config['pppoes']['pppoe'])) {
1117
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1118
			vpn_pppoe_configure($pppoe);
1119
	}
1120
}
1121

    
1122
function vpn_pppoe_configure(&$pppoecfg) {
1123
	global $config, $g;
1124

    
1125
	$syscfg = $config['system'];
1126

    
1127
	/* create directory if it does not exist */
1128
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1129
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1130

    
1131
	if ($g['booting']) {
1132
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1133
			return 0;
1134

    
1135
		echo gettext("Configuring PPPoE VPN service... ");
1136
	} else {
1137
		/* kill mpd */
1138
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1139

    
1140
		/* wait for process to die */
1141
		sleep(2);
1142

    
1143
	}
1144

    
1145
	switch ($pppoecfg['mode']) {
1146

    
1147
		case 'server' :
1148

    
1149
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1150

    
1151
			if ($pppoecfg['paporchap'] == "chap")
1152
				$paporchap = "set link enable chap";
1153
			else
1154
				$paporchap = "set link enable pap";
1155

    
1156
			/* write mpd.conf */
1157
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1158
			if (!$fd) {
1159
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1160
				return 1;
1161
			}
1162
			$mpdconf = "\n\n";
1163
			$mpdconf .= "poes:\n";
1164

    
1165
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1166
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1167
			}
1168

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

    
1171
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1172

    
1173
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1174
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1175
				} else {
1176
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1177
				}
1178

    
1179
				$mpdconf .=<<<EOD
1180

    
1181
poes{$pppoecfg['pppoeid']}{$i}:
1182
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1183
	{$isssue_ip_type}
1184
	load pppoe_standard
1185

    
1186
EOD;
1187
			}
1188

    
1189
			$mpdconf .=<<<EOD
1190

    
1191
pppoe_standard:
1192
	set bundle no multilink
1193
	set bundle enable compression
1194
	set auth max-logins 1
1195
	set iface up-script /usr/local/sbin/vpn-linkup
1196
	set iface down-script /usr/local/sbin/vpn-linkdown
1197
	set iface idle 0
1198
	set iface disable on-demand
1199
	set iface disable proxy-arp
1200
	set iface enable tcpmssfix
1201
	set iface mtu 1500
1202
	set link no pap chap
1203
	{$paporchap}
1204
	set link keep-alive 60 180
1205
	set ipcp yes vjcomp
1206
	set ipcp no vjcomp
1207
	set link max-redial -1
1208
	set link mtu 1492
1209
	set link mru 1492
1210
	set ccp yes mpp-e40
1211
	set ccp yes mpp-e128
1212
	set ccp yes mpp-stateless
1213
	set link latency 1
1214
	#set ipcp dns 10.10.1.3
1215
	#set bundle accept encryption
1216

    
1217
EOD;
1218

    
1219
			if (!empty($pppoecfg['dns1'])) {
1220
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1221
				if (!empty($pppoecfg['dns2']))
1222
					$mpdconf .= " " . $pppoecfg['dns2'];
1223
				$mpdconf .= "\n";
1224
			} elseif (isset ($config['dnsmasq']['enable'])) {
1225
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1226
				if ($syscfg['dnsserver'][0])
1227
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1228
				$mpdconf .= "\n";
1229
			} elseif (isset ($config['unbound']['enable'])) {
1230
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1231
				if ($syscfg['dnsserver'][0])
1232
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1233
				$mpdconf .= "\n";
1234
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1235
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1236
			}
1237

    
1238
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1239
				$radiusport = "";
1240
				$radiusacctport = "";
1241
				if (isset($pppoecfg['radius']['server']['port']))
1242
					$radiusport = $pppoecfg['radius']['server']['port'];
1243
				if (isset($pppoecfg['radius']['server']['acctport']))
1244
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1245
				$mpdconf .=<<<EOD
1246
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1247
	set radius retries 3
1248
	set radius timeout 10
1249
	set auth enable radius-auth
1250

    
1251
EOD;
1252

    
1253
				if (isset ($pppoecfg['radius']['accounting'])) {
1254
					$mpdconf .=<<<EOD
1255
	set auth enable radius-acct
1256

    
1257
EOD;
1258
				}
1259
			}
1260

    
1261
			fwrite($fd, $mpdconf);
1262
			fclose($fd);
1263
			unset($mpdconf);
1264

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

    
1272
			$mpdlinks = "";
1273

    
1274
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1275
				$mpdlinks .=<<<EOD
1276

    
1277
poes{$pppoecfg['pppoeid']}{$i}:
1278
	set phys type pppoe
1279
	set pppoe iface {$pppoe_interface}
1280
	set pppoe service "*"
1281
	set pppoe disable originate
1282
	set pppoe enable incoming
1283

    
1284
EOD;
1285
			}
1286

    
1287
			fwrite($fd, $mpdlinks);
1288
			fclose($fd);
1289
			unset($mpdlinks);
1290

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

    
1299
				$mpdsecret = "\n\n";
1300

    
1301
				if (!empty($pppoecfg['username'])) {
1302
					$item = explode(" ", $pppoecfg['username']);
1303
					foreach($item as $userdata) {
1304
						$data = explode(":", $userdata);
1305
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1306
					}
1307
				}
1308

    
1309
				fwrite($fd, $mpdsecret);
1310
				fclose($fd);
1311
				unset($mpdsecret);
1312
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1313
			}
1314

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

    
1319
			/* Get support for netgraph(4) from the nic */
1320
			pfSense_ngctl_attach(".", $pppoe_interface);
1321
			/* fire up mpd */
1322
			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");
1323

    
1324
			break;
1325
	}
1326

    
1327
	if ($g['booting'])
1328
		echo gettext("done") . "\n";
1329

    
1330
	return 0;
1331
}
1332

    
1333
function vpn_l2tp_configure() {
1334
	global $config, $g;
1335

    
1336
	$syscfg = $config['system'];
1337
	$l2tpcfg = $config['l2tp'];
1338

    
1339
	/* create directory if it does not exist */
1340
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1341
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1342

    
1343
	if ($g['booting']) {
1344
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1345
			return 0;
1346

    
1347
		echo gettext("Configuring l2tp VPN service... ");
1348
	} else {
1349
		/* kill mpd */
1350
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1351

    
1352
		/* wait for process to die */
1353
		sleep(8);
1354

    
1355
	}
1356

    
1357
	/* make sure l2tp-vpn directory exists */
1358
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1359
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1360

    
1361
	switch ($l2tpcfg['mode']) {
1362

    
1363
		case 'server' :
1364
			if ($l2tpcfg['paporchap'] == "chap")
1365
				$paporchap = "set link enable chap";
1366
			else
1367
				$paporchap = "set link enable pap";
1368

    
1369
			/* write mpd.conf */
1370
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1371
			if (!$fd) {
1372
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1373
				return 1;
1374
			}
1375
			$mpdconf = "\n\n";
1376
			$mpdconf .=<<<EOD
1377
l2tps:
1378

    
1379
EOD;
1380

    
1381
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1382
				$mpdconf .= "	load l2tp{$i}\n";
1383
			}
1384

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

    
1387
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1388

    
1389
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1390
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1391
				} else {
1392
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1393
				}
1394

    
1395
				$mpdconf .=<<<EOD
1396

    
1397
l2tp{$i}:
1398
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1399
	{$isssue_ip_type}
1400
	load l2tp_standard
1401

    
1402
EOD;
1403
			}
1404

    
1405
			$mpdconf .=<<<EOD
1406

    
1407
l2tp_standard:
1408
	set bundle disable multilink
1409
	set bundle enable compression
1410
	set bundle yes crypt-reqd
1411
	set ipcp yes vjcomp
1412
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1413
	set ccp yes mppc
1414
	set iface disable on-demand
1415
	set iface enable proxy-arp
1416
	set iface up-script /usr/local/sbin/vpn-linkup
1417
	set iface down-script /usr/local/sbin/vpn-linkdown
1418
	set link yes acfcomp protocomp
1419
	set link no pap chap
1420
	set link enable chap
1421
	set link keep-alive 10 180
1422

    
1423
EOD;
1424

    
1425
			if (is_ipaddr($l2tpcfg['wins'])) {
1426
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1427
			}
1428
			if (is_ipaddr($l2tpcfg['dns1'])) {
1429
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1430
				if (is_ipaddr($l2tpcfg['dns2']))
1431
					$mpdconf .= " " . $l2tpcfg['dns2'];
1432
				$mpdconf .= "\n";
1433
			} elseif (isset ($config['dnsmasq']['enable'])) {
1434
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1435
				if ($syscfg['dnsserver'][0])
1436
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1437
				$mpdconf .= "\n";
1438
			} elseif (isset ($config['unbound']['enable'])) {
1439
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1440
				if ($syscfg['dnsserver'][0])
1441
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1442
				$mpdconf .= "\n";
1443
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1444
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1445
			}
1446

    
1447
			if (isset ($l2tpcfg['radius']['enable'])) {
1448
				$mpdconf .=<<<EOD
1449
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1450
	set radius retries 3
1451
	set radius timeout 10
1452
	set auth enable radius-auth
1453

    
1454
EOD;
1455

    
1456
				if (isset ($l2tpcfg['radius']['accounting'])) {
1457
					$mpdconf .=<<<EOD
1458
	set auth enable radius-acct
1459

    
1460
EOD;
1461
				}
1462
			}
1463

    
1464
			fwrite($fd, $mpdconf);
1465
			fclose($fd);
1466
			unset($mpdconf);
1467

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

    
1475
			$mpdlinks = "";
1476

    
1477
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1478
				$mpdlinks .=<<<EOD
1479

    
1480
l2tp{$i}:
1481
	set link type l2tp
1482
	set l2tp enable incoming
1483
	set l2tp disable originate
1484

    
1485
EOD;
1486
			if (!empty($l2tpcfg['secret']))
1487
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1488
			}
1489

    
1490
			fwrite($fd, $mpdlinks);
1491
			fclose($fd);
1492
			unset($mpdlinks);
1493

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

    
1501
			$mpdsecret = "\n\n";
1502

    
1503
			if (is_array($l2tpcfg['user'])) {
1504
				foreach ($l2tpcfg['user'] as $user)
1505
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1506
			}
1507

    
1508
			fwrite($fd, $mpdsecret);
1509
			fclose($fd);
1510
			unset($mpdsecret);
1511
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1512

    
1513
			vpn_netgraph_support();
1514

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

    
1518
			break;
1519

    
1520
		case 'redir' :
1521
			break;
1522
	}
1523

    
1524
	if ($g['booting'])
1525
		echo "done\n";
1526

    
1527
	return 0;
1528
}
1529

    
1530
function vpn_ipsec_configure_preferoldsa() {
1531
	global $config;
1532
	if(isset($config['ipsec']['preferoldsa']))
1533
		set_single_sysctl("net.key.preferred_oldsa", "-30");
1534
	else
1535
		set_single_sysctl("net.key.preferred_oldsa", "0");
1536
}
1537

    
1538
?>
(59-59/68)