Projet

Général

Profil

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

univnautes / etc / inc / vpn.inc @ 00311d6a

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
				$rightsourceip = NULL;
617
				$rightsubnet_spec = array();
618
				$leftsubnet_spec = array();
619
				$ealgoAHsp2arr = array();
620
				$ealgoESPsp2arr = array();
621
			if (is_array($a_phase2) && count($a_phase2)) {
622
				foreach ($a_phase2 as $ph2ent) {
623
					$ikeid = $ph2ent['ikeid'];
624
					if ($ikeid != $ph1ent['ikeid'])
625
						continue;
626

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

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

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

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

    
664
						$leftsubnet_spec[] = $leftsubnet_data;
665

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

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

    
682
						if (!isset($ph2ent['mobile']))
683
							$rightsubnet_spec[] = $right_spec;
684
					}
685

    
686
					if (isset($a_client['pfs_group']))
687
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
688

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

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

    
740

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

    
748
				$ipsecconf .=<<<EOD
749

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

    
765
EOD;
766

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

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

    
804
	if ($natfilterrules == true)
805
		filter_configure();
806
	/* start filterdns, if necessary */
807
	if (count($filterdns_list) > 0) {
808
		$interval = 60;
809
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
810
			$interval = $ipseccfg['dns-interval'];
811

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

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

    
829
	if ($g['booting'])
830
		echo "done\n";
831

    
832
	return count($filterdns_list);
833
}
834

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

    
844
	$ipseccfg = $config['ipsec'];
845

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

    
860
	/* if ipsec is enabled, start up again */
861
	if (isset($ipseccfg['enable'])) {
862
		log_error(gettext("Forcefully reloading IPsec"));
863
		vpn_ipsec_configure();
864
	}
865
}
866

    
867
/* master setup for vpn (mpd) */
868
function vpn_setup() {
869
	global $g;
870

    
871
	if ($g['platform'] == 'jail')
872
		return;
873

    
874
	/* start pptpd */
875
	vpn_pptpd_configure();
876

    
877
	/* start pppoe server */
878
	vpn_pppoes_configure();
879

    
880
	/* setup l2tp */
881
	vpn_l2tp_configure();
882
}
883

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

    
895
function vpn_pptpd_configure() {
896
	global $config, $g;
897

    
898
	$syscfg = $config['system'];
899
	$pptpdcfg = $config['pptpd'];
900

    
901
	if ($g['booting']) {
902
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
903
			return 0;
904

    
905
		echo gettext("Configuring PPTP VPN service... ");
906
	} else {
907
		/* kill mpd */
908
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
909

    
910
		/* wait for process to die */
911
		sleep(3);
912

    
913
		if (is_process_running("mpd -b")) {
914
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
915
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
916
		}
917

    
918
		/* remove mpd.conf, if it exists */
919
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
920
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
921
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
922
	}
923

    
924
	if (empty($pptpdcfg['n_pptp_units'])) {
925
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
926
		return;
927
	}
928

    
929
	/* make sure pptp-vpn directory exists */
930
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
931
		mkdir("{$g['varetc_path']}/pptp-vpn");
932

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

    
942
			$mpdconf = <<<EOD
943
pptps:
944

    
945
EOD;
946

    
947
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
948
				$mpdconf .= "	load pt{$i}\n";
949
			}
950

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

    
953
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
954

    
955
				$mpdconf .= <<<EOD
956

    
957
pt{$i}:
958
	new -i pptpd{$i} pt{$i} pt{$i}
959
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
960
	load pts
961

    
962
EOD;
963
			}
964

    
965
			$mpdconf .=<<<EOD
966

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

    
987
EOD;
988

    
989
			if (!isset ($pptpdcfg['req128'])) {
990
				$mpdconf .=<<<EOD
991
	set ccp yes mpp-e40
992
	set ccp yes mpp-e56
993

    
994
EOD;
995
			}
996

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

    
1000
			if (!empty($pptpdcfg['dns1'])) {
1001
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1002
				if (!empty($pptpdcfg['dns2']))
1003
					$mpdconf .= " " . $pptpdcfg['dns2'];
1004
				$mpdconf .= "\n";
1005
			} elseif (isset ($config['dnsmasq']['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 (isset($config['unbound']['enable'])) {
1011
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1012
				if ($syscfg['dnsserver'][0])
1013
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1014
				$mpdconf .= "\n";
1015
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1016
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1017
			}
1018

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

    
1025
EOD;
1026
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1027
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1028
				$acctport = $authport + 1;
1029
				$mpdconf .=<<<EOD
1030
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1031

    
1032
EOD;
1033
			}
1034
			$mpdconf .=<<<EOD
1035
	set radius retries 3
1036
	set radius timeout 10
1037
	set auth enable radius-auth
1038

    
1039
EOD;
1040

    
1041
				if (isset ($pptpdcfg['radius']['accounting'])) {
1042
					$mpdconf .=<<<EOD
1043
	set auth enable radius-acct
1044
	set radius acct-update 300
1045

    
1046
EOD;
1047
				}
1048
			}
1049

    
1050
			fwrite($fd, $mpdconf);
1051
			fclose($fd);
1052
			unset($mpdconf);
1053

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

    
1061
			$mpdlinks = "";
1062

    
1063
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1064
				$mpdlinks .=<<<EOD
1065

    
1066
pt{$i}:
1067
	set link type pptp
1068
	set pptp enable incoming
1069
	set pptp disable originate
1070
	set pptp disable windowing
1071

    
1072
EOD;
1073
			}
1074

    
1075
			fwrite($fd, $mpdlinks);
1076
			fclose($fd);
1077
			unset($mpdlinks);
1078

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

    
1086
			$mpdsecret = "";
1087

    
1088
			if (is_array($pptpdcfg['user'])) {
1089
				foreach ($pptpdcfg['user'] as $user) {
1090
					$pass = str_replace('\\', '\\\\', $user['password']);
1091
					$pass = str_replace('"', '\"', $pass);
1092
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1093
				}
1094
			}
1095

    
1096
			fwrite($fd, $mpdsecret);
1097
			fclose($fd);
1098
			unset($mpdsecret);
1099
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1100

    
1101
			vpn_netgraph_support();
1102

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

    
1106
			break;
1107

    
1108
		case 'redir' :
1109
			break;
1110
	}
1111

    
1112
	if ($g['booting'])
1113
		echo "done\n";
1114

    
1115
	return 0;
1116
}
1117

    
1118
function vpn_pppoes_configure() {
1119
	global $config;
1120

    
1121
	if (is_array($config['pppoes']['pppoe'])) {
1122
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1123
			vpn_pppoe_configure($pppoe);
1124
	}
1125
}
1126

    
1127
function vpn_pppoe_configure(&$pppoecfg) {
1128
	global $config, $g;
1129

    
1130
	$syscfg = $config['system'];
1131

    
1132
	/* create directory if it does not exist */
1133
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1134
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1135

    
1136
	if ($g['booting']) {
1137
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1138
			return 0;
1139

    
1140
		echo gettext("Configuring PPPoE VPN service... ");
1141
	} else {
1142
		/* kill mpd */
1143
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1144

    
1145
		/* wait for process to die */
1146
		sleep(2);
1147

    
1148
	}
1149

    
1150
	switch ($pppoecfg['mode']) {
1151

    
1152
		case 'server' :
1153

    
1154
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1155

    
1156
			if ($pppoecfg['paporchap'] == "chap")
1157
				$paporchap = "set link enable chap";
1158
			else
1159
				$paporchap = "set link enable pap";
1160

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

    
1170
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1171
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1172
			}
1173

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

    
1176
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1177

    
1178
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1179
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1180
				} else {
1181
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1182
				}
1183

    
1184
				$mpdconf .=<<<EOD
1185

    
1186
poes{$pppoecfg['pppoeid']}{$i}:
1187
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1188
	{$isssue_ip_type}
1189
	load pppoe_standard
1190

    
1191
EOD;
1192
			}
1193

    
1194
			$mpdconf .=<<<EOD
1195

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

    
1222
EOD;
1223

    
1224
			if (!empty($pppoecfg['dns1'])) {
1225
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1226
				if (!empty($pppoecfg['dns2']))
1227
					$mpdconf .= " " . $pppoecfg['dns2'];
1228
				$mpdconf .= "\n";
1229
			} elseif (isset ($config['dnsmasq']['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 (isset ($config['unbound']['enable'])) {
1235
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1236
				if ($syscfg['dnsserver'][0])
1237
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1238
				$mpdconf .= "\n";
1239
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1240
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1241
			}
1242

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

    
1256
EOD;
1257

    
1258
				if (isset ($pppoecfg['radius']['accounting'])) {
1259
					$mpdconf .=<<<EOD
1260
	set auth enable radius-acct
1261

    
1262
EOD;
1263
				}
1264
			}
1265

    
1266
			fwrite($fd, $mpdconf);
1267
			fclose($fd);
1268
			unset($mpdconf);
1269

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

    
1277
			$mpdlinks = "";
1278

    
1279
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1280
				$mpdlinks .=<<<EOD
1281

    
1282
poes{$pppoecfg['pppoeid']}{$i}:
1283
	set phys type pppoe
1284
	set pppoe iface {$pppoe_interface}
1285
	set pppoe service "*"
1286
	set pppoe disable originate
1287
	set pppoe enable incoming
1288

    
1289
EOD;
1290
			}
1291

    
1292
			fwrite($fd, $mpdlinks);
1293
			fclose($fd);
1294
			unset($mpdlinks);
1295

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

    
1304
				$mpdsecret = "\n\n";
1305

    
1306
				if (!empty($pppoecfg['username'])) {
1307
					$item = explode(" ", $pppoecfg['username']);
1308
					foreach($item as $userdata) {
1309
						$data = explode(":", $userdata);
1310
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1311
					}
1312
				}
1313

    
1314
				fwrite($fd, $mpdsecret);
1315
				fclose($fd);
1316
				unset($mpdsecret);
1317
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1318
			}
1319

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

    
1324
			/* Get support for netgraph(4) from the nic */
1325
			pfSense_ngctl_attach(".", $pppoe_interface);
1326
			/* fire up mpd */
1327
			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");
1328

    
1329
			break;
1330
	}
1331

    
1332
	if ($g['booting'])
1333
		echo gettext("done") . "\n";
1334

    
1335
	return 0;
1336
}
1337

    
1338
function vpn_l2tp_configure() {
1339
	global $config, $g;
1340

    
1341
	$syscfg = $config['system'];
1342
	$l2tpcfg = $config['l2tp'];
1343

    
1344
	/* create directory if it does not exist */
1345
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1346
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1347

    
1348
	if ($g['booting']) {
1349
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1350
			return 0;
1351

    
1352
		echo gettext("Configuring l2tp VPN service... ");
1353
	} else {
1354
		/* kill mpd */
1355
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1356

    
1357
		/* wait for process to die */
1358
		sleep(8);
1359

    
1360
	}
1361

    
1362
	/* make sure l2tp-vpn directory exists */
1363
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1364
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1365

    
1366
	switch ($l2tpcfg['mode']) {
1367

    
1368
		case 'server' :
1369
			if ($l2tpcfg['paporchap'] == "chap")
1370
				$paporchap = "set link enable chap";
1371
			else
1372
				$paporchap = "set link enable pap";
1373

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

    
1384
EOD;
1385

    
1386
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1387
				$mpdconf .= "	load l2tp{$i}\n";
1388
			}
1389

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

    
1392
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1393

    
1394
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1395
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1396
				} else {
1397
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1398
				}
1399

    
1400
				$mpdconf .=<<<EOD
1401

    
1402
l2tp{$i}:
1403
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1404
	{$isssue_ip_type}
1405
	load l2tp_standard
1406

    
1407
EOD;
1408
			}
1409

    
1410
			$mpdconf .=<<<EOD
1411

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

    
1428
EOD;
1429

    
1430
			if (is_ipaddr($l2tpcfg['wins'])) {
1431
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1432
			}
1433
			if (is_ipaddr($l2tpcfg['dns1'])) {
1434
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1435
				if (is_ipaddr($l2tpcfg['dns2']))
1436
					$mpdconf .= " " . $l2tpcfg['dns2'];
1437
				$mpdconf .= "\n";
1438
			} elseif (isset ($config['dnsmasq']['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 (isset ($config['unbound']['enable'])) {
1444
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1445
				if ($syscfg['dnsserver'][0])
1446
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1447
				$mpdconf .= "\n";
1448
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1449
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1450
			}
1451

    
1452
			if (isset ($l2tpcfg['radius']['enable'])) {
1453
				$mpdconf .=<<<EOD
1454
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1455
	set radius retries 3
1456
	set radius timeout 10
1457
	set auth enable radius-auth
1458

    
1459
EOD;
1460

    
1461
				if (isset ($l2tpcfg['radius']['accounting'])) {
1462
					$mpdconf .=<<<EOD
1463
	set auth enable radius-acct
1464

    
1465
EOD;
1466
				}
1467
			}
1468

    
1469
			fwrite($fd, $mpdconf);
1470
			fclose($fd);
1471
			unset($mpdconf);
1472

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

    
1480
			$mpdlinks = "";
1481

    
1482
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1483
				$mpdlinks .=<<<EOD
1484

    
1485
l2tp{$i}:
1486
	set link type l2tp
1487
	set l2tp enable incoming
1488
	set l2tp disable originate
1489

    
1490
EOD;
1491
			if (!empty($l2tpcfg['secret']))
1492
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1493
			}
1494

    
1495
			fwrite($fd, $mpdlinks);
1496
			fclose($fd);
1497
			unset($mpdlinks);
1498

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

    
1506
			$mpdsecret = "\n\n";
1507

    
1508
			if (is_array($l2tpcfg['user'])) {
1509
				foreach ($l2tpcfg['user'] as $user)
1510
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1511
			}
1512

    
1513
			fwrite($fd, $mpdsecret);
1514
			fclose($fd);
1515
			unset($mpdsecret);
1516
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1517

    
1518
			vpn_netgraph_support();
1519

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

    
1523
			break;
1524

    
1525
		case 'redir' :
1526
			break;
1527
	}
1528

    
1529
	if ($g['booting'])
1530
		echo "done\n";
1531

    
1532
	return 0;
1533
}
1534

    
1535
function vpn_ipsec_configure_preferoldsa() {
1536
	global $config;
1537
	if(isset($config['ipsec']['preferoldsa']))
1538
		set_single_sysctl("net.key.preferred_oldsa", "-30");
1539
	else
1540
		set_single_sysctl("net.key.preferred_oldsa", "0");
1541
}
1542

    
1543
?>
(59-59/68)