Projet

Général

Profil

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

univnautes / etc / inc / vpn.inc @ 7a1f391a

1
<?php
2

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

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

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

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

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

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

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

    
43
require_once("ipsec.inc");
44

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

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

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

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

    
94
	return $convertion;
95
}
96

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

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

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

    
108
	vpn_ipsec_configure_preferoldsa();
109

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

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

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

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

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

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

    
159
		/* fastforwarding is not compatible with ipsec tunnels */
160
		mwexec("/sbin/sysctl net.inet.ip.fastforwarding=0");
161

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

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

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

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

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

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

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

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

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

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

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

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

    
218
						/* add an ipsec pinghosts entry */
219
						if ($ph2ent['pinghost']) {
220
							if (!is_array($iflist))
221
								$iflist = get_configured_interface_list();
222
							foreach ($iflist as $ifent => $ifname) {
223
								if(is_ipaddrv6($ph2ent['pinghost'])) {
224
									$interface_ip = get_interface_ipv6($ifent);
225
									if(!is_ipaddrv6($interface_ip))
226
										continue;
227
									$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
228
									if (ip_in_subnet($interface_ip, $local_subnet)) {
229
										$srcip = $interface_ip;
230
										break;
231
									}
232
								} else {
233
									$interface_ip = get_interface_ip($ifent);
234
									if(!is_ipaddrv4($interface_ip))
235
										continue;
236
									$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
237
									if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) {
238
										$srcip = $interface_ip;
239
										break;
240
									}
241
								}
242
							}
243
							$dstip = $ph2ent['pinghost'];
244
							if(is_ipaddrv6($dstip)) {
245
								$family = "inet6";
246
							} else {
247
								$family = "inet";
248
							}
249
							if (is_ipaddr($srcip))
250
								$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
251
						}
252
					}
253
				}
254
			}
255
			@file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
256
			unset($ipsecpinghosts);
257
		}
258
		unset($iflist);
259

    
260
		$strongswan = <<<EOD
261

    
262
#Automatically generated please do not modify
263
starter {
264
    load_warning = no
265
}
266

    
267
charon {
268

    
269
        # number of worker threads in charon
270
        threads = 16
271

    
272
	# XXX: There is not much choice here really users win their security!
273
	i_dont_care_about_security_and_use_aggressive_mode_psk=yes
274

    
275
	# And two loggers using syslog. The subsections define the facility to log
276
	# to, currently one of: daemon, auth.
277
	syslog {
278

    
279
		identifier = charon
280
		# default level to the LOG_DAEMON facility
281
		daemon {
282
		}
283
		# very minimalistic IKE auditing logs to LOG_AUTHPRIV
284
		auth {
285
		    default = -1
286
		    ike = 1
287
		    ike_name = yes
288
		}
289
	}
290

    
291
EOD;
292

    
293
		if (is_array($a_client) && isset($a_client['enable']) && !empty($a_client['net_list']))
294
			$strongswan .= "\tcisco_unity = yes\n";
295

    
296
		$strongswan .= "\tplugins {\n";
297

    
298
		if (is_array($a_client) && isset($a_client['enable'])) {
299
			$strongswan .= "\t\tattr {\n";
300
			if ($a_client['pool_address'] && $a_client['pool_netbits']) {
301
				$pool_address = $a_client['pool_address'];
302
				$pool_netmask = gen_subnet_mask($a_client['pool_netbits']);
303
				$pool_address = long2ip32(ip2long($pool_address)+1);
304

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
421
		$pskconf = "";
422

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

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

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

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

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

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

    
441
						chmod($certpath, 0600);
442

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

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

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

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

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

    
466
							chmod($capath, 0600);
467
						}
468
					}
469
				} else {
470

    
471
					$peerid_type = $ph1ent['peerid_type'];
472

    
473
					switch ($peerid_type) {
474
						case "peeraddress":
475
							$peerid_type = "address";
476
							$peerid_data = $rgmap[$ph1ent['remote-gateway']];
477
							break;
478

    
479
						case "address";
480
							$peerid_data = $ph1ent['peerid_data'];
481
							break;
482

    
483
						case "fqdn";
484
						case "keyid tag";
485
						case "user_fqdn";
486
							$peerid_data = $ph1ent['peerid_data'];
487
							break;
488
					}
489

    
490
					if (!empty($peerid_data) && !empty($ph1ent['pre-shared-key']))
491
						$pskconf .= trim($peerid_data) . " : PSK \"" . trim($ph1ent['pre-shared-key']) . "\"\n";
492
				}
493
			}
494
		}
495

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

    
503
		/* add PSKs for mobile clients */
504
		if (is_array($ipseccfg['mobilekey'])) {
505
			foreach ($ipseccfg['mobilekey'] as $key) {
506
				if ($key['ident'] == "allusers")
507
					$key['ident'] = '';
508
				$pskconf .= "{$key['ident']} : PSK \"{$key['pre-shared-key']}\"\n";
509
			}
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)) || (is_array($a_phase2) && count($a_phase2))) {
520

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

    
526
				foreach ($a_phase2 as $ph2ent) {
527
					$ikeid = $ph2ent['ikeid'];
528

    
529
					$ph1ent = false;
530
					if (!ipsec_lookup_phase1($ph2ent,$ph1ent))
531
						continue;
532

    
533
					if (isset($ph1ent['disabled']))
534
						continue;
535

    
536
					if (isset($ph2ent['disabled']))
537
						continue;
538

    
539
					if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
540
						continue;
541

    
542
					$ikeid = $ph1ent['ikeid'];
543

    
544
					if ($ph1ent['mode'] == "aggressive")
545
						$aggressive = "yes";
546
					else
547
						$aggressive = "no";
548

    
549
					$ep = ipsec_get_phase1_src($ph1ent);
550
					if (!$ep)
551
						continue;
552

    
553
					$passive = "start";
554
					if (isset($ph1ent['mobile'])) {
555
						$rgip = "%any";
556
						$passive = 'add';
557
					} else
558
						$rgip = $ph1ent['remote-gateway'];
559

    
560
					$keyexchange = "ikev1";
561
					if (!empty($ph1ent['iketype']) && $ph1ent['iketype'] != "ikev1")
562
						$keyexchange = "ikev2";
563

    
564
					$myid_type = $ph1ent['myid_type'];
565
					switch ($myid_type) {
566
					case "myaddress":
567
						$myid_type = "address";
568
						$myid_data = $ep;
569
						break;
570

    
571
					case "dyn_dns":
572
						$myid_type = "address";
573
						$myid_data = resolve_retry($ph1ent['myid_data']);
574
						break;
575

    
576
					case "address";
577
						$myid_data = $ph1ent['myid_data'];
578
						break;
579

    
580
					case "fqdn";
581
					case "keyid tag";
582
					case "user_fqdn";
583
					case "asn1dn";
584
						$myid_data = $ph1ent['myid_data'];
585
						if( $myid_data )
586
							$myid_data = "{$myid_data}";
587
						break;
588
					}
589

    
590
					$peerid_type = $ph1ent['peerid_type'];
591
					switch ($peerid_type) {
592
					case "peeraddress":
593
						$peerid_type = "address";
594
						$peerid_data = $rgip;
595
						break;
596

    
597
					case "address";
598
						$peerid_data = $ph1ent['peerid_data'];
599
						break;
600

    
601
					case "fqdn";
602
					case "keyid tag";
603
					case "user_fqdn";
604
					case "asn1dn";
605
						$peerid_data = $ph1ent['peerid_data'];
606
						if( $peerid_data )
607
							$peerid_data = "{$peerid_data}";
608
						break;
609
					}
610

    
611
					/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
612
					$peerid_spec = '';
613
					if (!isset($ph1ent['mobile']))
614
						$peerid_spec = $peerid_data;
615

    
616
					if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
617
						$ealgosp1 = '';
618
						$ealg_id = $ph1ent['encryption-algorithm']['name'];
619
						$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
620
						if ($ealg_kl)
621
							$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
622
						else
623
							$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
624

    
625
						$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
626
						if (!empty($modp))
627
							$ealgosp1 .= "-{$modp}";
628

    
629
						if ($keyexchange == "ikev1")
630
							$ealgosp1 .= "!";
631
					}
632

    
633
					if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
634
						if ($passive == "start")
635
							$dpdline = "dpdaction = restart";
636
						else
637
							$dpdline = "dpdaction = clear";
638
						$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
639
						$dpdline .= "\n\tdpdtimeout = {$ph1ent['dpd_maxfail']}s";
640
					} else
641
						$dpdline = "dpdaction = none";
642

    
643
					if (!empty($ph1ent['authentication_method']) && (strpos($ph1ent['authentication_method'], "xauth") || strpos($ph1ent['authentication_method'], "hybrid")))
644
						$xauth = "xauth = server";
645

    
646
					$lifeline = '';
647
					if ($ph1ent['lifetime'])
648
						$lifeline = "ikelifetime = {$ph1ent['lifetime']}s";
649

    
650
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
651
						$tunneltype = "type = tunnel";
652

    
653
						$localid_type = $ph2ent['localid']['type'];
654
						$localid_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
655
						/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
656
						if (($localid_type == "none" || $localid_type == "mobile")
657
							&& isset($ph1ent['mobile'])
658
							&& (ipsec_get_number_of_phase2($ikeid)==1))
659
							$localid_spec = "%any";
660
						else {
661
							if ($localid_type != "address") {
662
								$localid_type = "subnet";
663
							}
664
							// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
665
							if (!is_ipaddr($localid_data) && !is_subnet($localid_data) && ($localid_data != "0.0.0.0/0")) {
666
								log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
667
								continue;
668
							}
669
							$localid_spec = $ep;
670
							if (!empty($ph2ent['natlocalid'])) {
671
								$natlocalid_data =  ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
672
								if ($ph2ent['natlocalid']['type'] != "address") {
673
									if (is_subnet($natlocalid_data))
674
										$localid_data = "{$natlocalid_data}|{$localid_data}";
675
								} else {
676
									if (is_ipaddr($natlocalid_data))
677
										$localid_data = "{$natlocalid_data}|{$localid_data}";
678
								}
679
								$natfilterrules = true;
680
							}
681
						}
682

    
683
						if (!isset($ph2ent['mobile'])) {
684
							$remoteid_type = $ph2ent['remoteid']['type'];
685
							if ($remoteid_type != "address")
686
								$remoteid_type = "subnet";
687

    
688
							$remoteid_data = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
689
							$remoteid_spec = $remoteid_data;
690
						}
691
					} else {
692
						$tunneltype = "type = transport";
693
						$rgip = $ph1ent['remote-gateway'];
694

    
695
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
696
							($ph1ent['authentication_method'] == "pre_shared_key"))
697
							&& isset($ph1ent['mobile']))
698
							$localid_spec = "%any";
699
						else {
700
							$localid_data = ipsec_get_phase1_src($ph1ent);
701
							$localid_spec = $ep;
702
						}
703
						if (!isset($ph2ent['mobile'])) {
704
							$remoteid_spec = $rgip;
705
						}
706
					}
707
					$authentication = "";
708
					switch ($ph1ent['authentication_method']) {
709
					case 'xauth_rsa_server':
710
						$authentication = "leftauth = pubkey\n\trightauth = pubkey";
711
						$authentication .= "\n\trightauth2 = xauth-generic";
712
						break;
713
					case 'xauth_psk_server':
714
						$authentication = "leftauth = psk\n\trightauth = psk";
715
						$authentication .= "\n\trightauth2 = xauth-generic";
716
						break;
717
					case 'pre_shared_key':
718
						$authentication = "leftauth = psk\n\trightauth = psk";
719
						break;
720
					case 'rsasig':
721
						$authentication = "leftauth = pubkey\n\trightauth = pubkey";
722
						break;
723
					case 'hybrid_rsa_server':
724
						$authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
725
						$authentication .= "\n\trightauth2 = xauth";
726
						break;
727
					}
728

    
729
					if (isset($a_client['pfs_group']))
730
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
731

    
732
					$ealgosp2 = '';
733
					if ($ph2ent['protocol'] == 'esp') {
734
						if (is_array($ph2ent['encryption-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
735
							$ealgosp2arr = array();
736
							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
737
								$ealg_id = $ealg['name'];
738
								$ealg_kl = $ealg['keylen'];
739

    
740
								if (!empty($ealg_kl) && $ealg_kl == "auto") {
741
									if (empty($p2_ealgos) || !is_array($p2_ealgos))
742
										require("ipsec.inc");
743
									$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
744
									$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
745
									$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
746
									/* XXX: in some cases where include ordering is suspect these variables
747
									 * are somehow 0 and we enter this loop forever and timeout after 900
748
									 * seconds wrecking bootup */
749
									if ($key_hi != 0 and $key_lo !=0 and $key_step !=0) {
750
										for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
751
											foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
752
												$halgo = str_replace('hmac_', '', $halgo);
753
												$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
754
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
755
												if (!empty($modp))
756
													$tmpealgo .= "-{$modp}";
757
												$ealgosp2arr[] = $tmpealgo;
758
											}
759
										}
760
									}
761
								} else {
762
									foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
763
										$halgo = str_replace('hmac_', '', $halgo);
764
										$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
765
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
766
										if (!empty($modp))
767
											$tmpealgo .= "-{$modp}";
768
										$ealgosp2arr[] = $tmpealgo;
769
									}
770
								}
771
							}
772
							$ealgosp2 = "esp = " . join(",", $ealgosp2arr);
773
							unset($ealgosp2arr);
774
							$ealgosp2 .= "!";
775
						}
776
					} else if ($ph2ent['protocol'] == 'ah') {
777
						if (is_array($ph2ent['hash-algorithm-option'])) {
778
							$ealgosp2 = "ah = " . join(",", $ph2ent['hash-algorithm-option']);
779
							$ealgosp2 = str_replace('hmac_', '', $ealgosp2);
780
							$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
781
							if (!empty($modp))
782
								$ealgosp2 .= "-{$modp}";
783
							$ealgosp2 .= "!";
784
						}
785
					}
786

    
787

    
788
					if ($ph2ent['lifetime'])
789
						$lifeline = "ikelifetime = {$ph2ent['lifetime']}s";
790

    
791
					$ipsecconf .=<<<EOD
792

    
793
conn con{$ph2ent['ikeid']}-{$ph2ent['ikeid']}
794
	aggressive = {$aggressive}
795
	fragmentation = yes
796
	keyexchange = {$keyexchange}
797
	keyingtries = %forever
798
	reauth = yes
799
	reqid = {$ikeid}
800
	installpolicy = yes
801
	{$lifeline}
802
	{$tunneltype}
803
	{$dpdline}
804
	auto = {$passive}
805
	left = {$localid_spec}
806
	leftsubnet = {$localid_data}
807
	right = {$rgip}
808
	leftid = {$myid_data}
809

    
810
EOD;
811

    
812
					if (!empty($remoteid_spec))
813
						$ipsecconf .= "\trightsubnet = $remoteid_spec\n";
814
					if (!empty($ealgosp1))
815
						$ipsecconf .= "\t{$ealgosp1}\n";
816
					if (!empty($ealgosp2))
817
						$ipsecconf .= "\t{$ealgosp2}\n";
818
					if (!empty($authentication))
819
						$ipsecconf .= "\t{$authentication}\n";
820
					if (!empty($peerid_spec))
821
						$ipsecconf .= "\trightid = {$peerid_spec}\n";
822
				}
823
			}
824
		}
825
	}
826
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
827
	unset($ipsecconf);
828
	/* end ipsec.conf */
829

    
830
	/* mange process */
831
	if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
832
		/* Read secrets */
833
		mwexec("/usr/local/sbin/ipsec rereadall", false);
834
		/* Update configuration changes */
835
		mwexec("/usr/local/sbin/ipsec update", false);
836
	} else {
837
		mwexec("/usr/local/sbin/ipsec start", false); 
838
	}
839

    
840
	if ($natfilterrules == true)
841
		filter_configure();
842
	/* start filterdns, if necessary */
843
	if (count($filterdns_list) > 0) {
844
		$interval = 60;
845
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
846
			$interval = $ipseccfg['dns-interval'];
847

    
848
		$hostnames = "";
849
		array_unique($filterdns_list);
850
		foreach ($filterdns_list as $hostname)
851
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
852
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
853
		unset($hostnames);
854

    
855
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
856
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
857
		else {
858
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
859
		}
860
	} else {
861
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
862
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
863
	}
864

    
865
	if ($g['booting'])
866
		echo "done\n";
867

    
868
	return count($filterdns_list);
869
}
870

    
871
/*
872
 * Forcefully restart IPsec
873
 * This is required for when dynamic interfaces reload
874
 * For all other occasions the normal vpn_ipsec_configure()
875
 * will gracefully reload the settings without restarting
876
 */
877
function vpn_ipsec_force_reload($interface = "") {
878
	global $g, $config;
879

    
880
	$ipseccfg = $config['ipsec'];
881

    
882
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
883
		$found = false;
884
		foreach ($ipseccfg['phase1'] as $ipsec) {
885
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
886
				$found = true;
887
				break;
888
			}
889
		}
890
		if (!$found) {
891
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
892
			return;
893
		}
894
	}
895

    
896
	/* if ipsec is enabled, start up again */
897
	if (isset($ipseccfg['enable'])) {
898
		log_error(gettext("Forcefully reloading IPsec"));
899
		vpn_ipsec_configure();
900
	}
901
}
902

    
903
/* master setup for vpn (mpd) */
904
function vpn_setup() {
905
	global $g;
906

    
907
	if ($g['platform'] == 'jail')
908
		return;
909

    
910
	/* start pptpd */
911
	vpn_pptpd_configure();
912

    
913
	/* start pppoe server */
914
	vpn_pppoes_configure();
915

    
916
	/* setup l2tp */
917
	vpn_l2tp_configure();
918
}
919

    
920
function vpn_netgraph_support() {
921
	$iflist = get_configured_interface_list();
922
	foreach ($iflist as $iface) {
923
		$realif = get_real_interface($iface);
924
		/* Get support for netgraph(4) from the nic */
925
		$ifinfo = pfSense_get_interface_addresses($realif);
926
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
927
			pfSense_ngctl_attach(".", $realif);
928
	}
929
}
930

    
931
function vpn_pptpd_configure() {
932
	global $config, $g;
933

    
934
	$syscfg = $config['system'];
935
	$pptpdcfg = $config['pptpd'];
936

    
937
	if ($g['booting']) {
938
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
939
			return 0;
940

    
941
		echo gettext("Configuring PPTP VPN service... ");
942
	} else {
943
		/* kill mpd */
944
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
945

    
946
		/* wait for process to die */
947
		sleep(3);
948

    
949
		if (is_process_running("mpd -b")) {
950
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
951
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
952
		}
953

    
954
		/* remove mpd.conf, if it exists */
955
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
956
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
957
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
958
	}
959

    
960
	if (empty($pptpdcfg['n_pptp_units'])) {
961
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
962
		return;
963
	}
964

    
965
	/* make sure pptp-vpn directory exists */
966
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
967
		mkdir("{$g['varetc_path']}/pptp-vpn");
968

    
969
	switch ($pptpdcfg['mode']) {
970
		case 'server' :
971
			/* write mpd.conf */
972
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
973
			if (!$fd) {
974
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
975
				return 1;
976
			}
977

    
978
			$mpdconf = <<<EOD
979
pptps:
980

    
981
EOD;
982

    
983
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
984
				$mpdconf .= "	load pt{$i}\n";
985
			}
986

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

    
989
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
990

    
991
				$mpdconf .= <<<EOD
992

    
993
pt{$i}:
994
	new -i pptpd{$i} pt{$i} pt{$i}
995
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
996
	load pts
997

    
998
EOD;
999
			}
1000

    
1001
			$mpdconf .=<<<EOD
1002

    
1003
pts:
1004
	set iface disable on-demand
1005
	set iface enable proxy-arp
1006
	set iface enable tcpmssfix
1007
	set iface idle 1800
1008
	set iface up-script /usr/local/sbin/vpn-linkup
1009
	set iface down-script /usr/local/sbin/vpn-linkdown
1010
	set bundle enable multilink
1011
	set bundle enable crypt-reqd
1012
	set link yes acfcomp protocomp
1013
	set link no pap chap
1014
	set link enable chap-msv2
1015
	set link mtu 1460
1016
	set link keep-alive 10 60
1017
	set ipcp yes vjcomp
1018
	set bundle enable compression
1019
	set ccp yes mppc
1020
	set ccp yes mpp-e128
1021
	set ccp yes mpp-stateless
1022

    
1023
EOD;
1024

    
1025
			if (!isset ($pptpdcfg['req128'])) {
1026
				$mpdconf .=<<<EOD
1027
	set ccp yes mpp-e40
1028
	set ccp yes mpp-e56
1029

    
1030
EOD;
1031
			}
1032

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

    
1036
			if (!empty($pptpdcfg['dns1'])) {
1037
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1038
				if (!empty($pptpdcfg['dns2']))
1039
					$mpdconf .= " " . $pptpdcfg['dns2'];
1040
				$mpdconf .= "\n";
1041
			} elseif (isset ($config['dnsmasq']['enable'])) {
1042
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1043
				if ($syscfg['dnsserver'][0])
1044
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1045
				$mpdconf .= "\n";
1046
			} elseif (isset($config['unbound']['enable'])) {
1047
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1048
				if ($syscfg['dnsserver'][0])
1049
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1050
				$mpdconf .= "\n";
1051
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1052
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1053
			}
1054

    
1055
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1056
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1057
				$acctport = $authport + 1;
1058
				$mpdconf .=<<<EOD
1059
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1060

    
1061
EOD;
1062
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1063
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1064
				$acctport = $authport + 1;
1065
				$mpdconf .=<<<EOD
1066
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1067

    
1068
EOD;
1069
			}
1070
			$mpdconf .=<<<EOD
1071
	set radius retries 3
1072
	set radius timeout 10
1073
	set auth enable radius-auth
1074

    
1075
EOD;
1076

    
1077
				if (isset ($pptpdcfg['radius']['accounting'])) {
1078
					$mpdconf .=<<<EOD
1079
	set auth enable radius-acct
1080
	set radius acct-update 300
1081

    
1082
EOD;
1083
				}
1084
			}
1085

    
1086
			fwrite($fd, $mpdconf);
1087
			fclose($fd);
1088
			unset($mpdconf);
1089

    
1090
			/* write mpd.links */
1091
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1092
			if (!$fd) {
1093
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1094
				return 1;
1095
			}
1096

    
1097
			$mpdlinks = "";
1098

    
1099
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1100
				$mpdlinks .=<<<EOD
1101

    
1102
pt{$i}:
1103
	set link type pptp
1104
	set pptp enable incoming
1105
	set pptp disable originate
1106
	set pptp disable windowing
1107

    
1108
EOD;
1109
			}
1110

    
1111
			fwrite($fd, $mpdlinks);
1112
			fclose($fd);
1113
			unset($mpdlinks);
1114

    
1115
			/* write mpd.secret */
1116
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1117
			if (!$fd) {
1118
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1119
				return 1;
1120
			}
1121

    
1122
			$mpdsecret = "";
1123

    
1124
			if (is_array($pptpdcfg['user'])) {
1125
				foreach ($pptpdcfg['user'] as $user) {
1126
					$pass = str_replace('\\', '\\\\', $user['password']);
1127
					$pass = str_replace('"', '\"', $pass);
1128
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1129
				}
1130
			}
1131

    
1132
			fwrite($fd, $mpdsecret);
1133
			fclose($fd);
1134
			unset($mpdsecret);
1135
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1136

    
1137
			vpn_netgraph_support();
1138

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

    
1142
			break;
1143

    
1144
		case 'redir' :
1145
			break;
1146
	}
1147

    
1148
	if ($g['booting'])
1149
		echo "done\n";
1150

    
1151
	return 0;
1152
}
1153

    
1154
function vpn_pppoes_configure() {
1155
	global $config;
1156

    
1157
	if (is_array($config['pppoes']['pppoe'])) {
1158
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1159
			vpn_pppoe_configure($pppoe);
1160
	}
1161
}
1162

    
1163
function vpn_pppoe_configure(&$pppoecfg) {
1164
	global $config, $g;
1165

    
1166
	$syscfg = $config['system'];
1167

    
1168
	/* create directory if it does not exist */
1169
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1170
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1171

    
1172
	if ($g['booting']) {
1173
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1174
			return 0;
1175

    
1176
		echo gettext("Configuring PPPoE VPN service... ");
1177
	} else {
1178
		/* kill mpd */
1179
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1180

    
1181
		/* wait for process to die */
1182
		sleep(2);
1183

    
1184
	}
1185

    
1186
	switch ($pppoecfg['mode']) {
1187

    
1188
		case 'server' :
1189

    
1190
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1191

    
1192
			if ($pppoecfg['paporchap'] == "chap")
1193
				$paporchap = "set link enable chap";
1194
			else
1195
				$paporchap = "set link enable pap";
1196

    
1197
			/* write mpd.conf */
1198
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1199
			if (!$fd) {
1200
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1201
				return 1;
1202
			}
1203
			$mpdconf = "\n\n";
1204
			$mpdconf .= "poes:\n";
1205

    
1206
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1207
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1208
			}
1209

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

    
1212
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1213

    
1214
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1215
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1216
				} else {
1217
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1218
				}
1219

    
1220
				$mpdconf .=<<<EOD
1221

    
1222
poes{$pppoecfg['pppoeid']}{$i}:
1223
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1224
	{$isssue_ip_type}
1225
	load pppoe_standard
1226

    
1227
EOD;
1228
			}
1229

    
1230
			$mpdconf .=<<<EOD
1231

    
1232
pppoe_standard:
1233
	set bundle no multilink
1234
	set bundle enable compression
1235
	set auth max-logins 1
1236
	set iface up-script /usr/local/sbin/vpn-linkup
1237
	set iface down-script /usr/local/sbin/vpn-linkdown
1238
	set iface idle 0
1239
	set iface disable on-demand
1240
	set iface disable proxy-arp
1241
	set iface enable tcpmssfix
1242
	set iface mtu 1500
1243
	set link no pap chap
1244
	{$paporchap}
1245
	set link keep-alive 60 180
1246
	set ipcp yes vjcomp
1247
	set ipcp no vjcomp
1248
	set link max-redial -1
1249
	set link mtu 1492
1250
	set link mru 1492
1251
	set ccp yes mpp-e40
1252
	set ccp yes mpp-e128
1253
	set ccp yes mpp-stateless
1254
	set link latency 1
1255
	#set ipcp dns 10.10.1.3
1256
	#set bundle accept encryption
1257

    
1258
EOD;
1259

    
1260
			if (!empty($pppoecfg['dns1'])) {
1261
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1262
				if (!empty($pppoecfg['dns2']))
1263
					$mpdconf .= " " . $pppoecfg['dns2'];
1264
				$mpdconf .= "\n";
1265
			} elseif (isset ($config['dnsmasq']['enable'])) {
1266
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1267
				if ($syscfg['dnsserver'][0])
1268
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1269
				$mpdconf .= "\n";
1270
			} elseif (isset ($config['unbound']['enable'])) {
1271
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1272
				if ($syscfg['dnsserver'][0])
1273
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1274
				$mpdconf .= "\n";
1275
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1276
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1277
			}
1278

    
1279
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1280
				$radiusport = "";
1281
				$radiusacctport = "";
1282
				if (isset($pppoecfg['radius']['server']['port']))
1283
					$radiusport = $pppoecfg['radius']['server']['port'];
1284
				if (isset($pppoecfg['radius']['server']['acctport']))
1285
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1286
				$mpdconf .=<<<EOD
1287
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1288
	set radius retries 3
1289
	set radius timeout 10
1290
	set auth enable radius-auth
1291

    
1292
EOD;
1293

    
1294
				if (isset ($pppoecfg['radius']['accounting'])) {
1295
					$mpdconf .=<<<EOD
1296
	set auth enable radius-acct
1297

    
1298
EOD;
1299
				}
1300
			}
1301

    
1302
			fwrite($fd, $mpdconf);
1303
			fclose($fd);
1304
			unset($mpdconf);
1305

    
1306
			/* write mpd.links */
1307
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1308
			if (!$fd) {
1309
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1310
				return 1;
1311
			}
1312

    
1313
			$mpdlinks = "";
1314

    
1315
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1316
				$mpdlinks .=<<<EOD
1317

    
1318
poes{$pppoecfg['pppoeid']}{$i}:
1319
	set phys type pppoe
1320
	set pppoe iface {$pppoe_interface}
1321
	set pppoe service "*"
1322
	set pppoe disable originate
1323
	set pppoe enable incoming
1324

    
1325
EOD;
1326
			}
1327

    
1328
			fwrite($fd, $mpdlinks);
1329
			fclose($fd);
1330
			unset($mpdlinks);
1331

    
1332
			if ($pppoecfg['username']) {
1333
				/* write mpd.secret */
1334
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1335
				if (!$fd) {
1336
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1337
					return 1;
1338
				}
1339

    
1340
				$mpdsecret = "\n\n";
1341

    
1342
				if (!empty($pppoecfg['username'])) {
1343
					$item = explode(" ", $pppoecfg['username']);
1344
					foreach($item as $userdata) {
1345
						$data = explode(":", $userdata);
1346
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1347
					}
1348
				}
1349

    
1350
				fwrite($fd, $mpdsecret);
1351
				fclose($fd);
1352
				unset($mpdsecret);
1353
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1354
			}
1355

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

    
1360
			/* Get support for netgraph(4) from the nic */
1361
			pfSense_ngctl_attach(".", $pppoe_interface);
1362
			/* fire up mpd */
1363
			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");
1364

    
1365
			break;
1366
	}
1367

    
1368
	if ($g['booting'])
1369
		echo gettext("done") . "\n";
1370

    
1371
	return 0;
1372
}
1373

    
1374
function vpn_l2tp_configure() {
1375
	global $config, $g;
1376

    
1377
	$syscfg = $config['system'];
1378
	$l2tpcfg = $config['l2tp'];
1379

    
1380
	/* create directory if it does not exist */
1381
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1382
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1383

    
1384
	if ($g['booting']) {
1385
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1386
			return 0;
1387

    
1388
		echo gettext("Configuring l2tp VPN service... ");
1389
	} else {
1390
		/* kill mpd */
1391
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1392

    
1393
		/* wait for process to die */
1394
		sleep(8);
1395

    
1396
	}
1397

    
1398
	/* make sure l2tp-vpn directory exists */
1399
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1400
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1401

    
1402
	switch ($l2tpcfg['mode']) {
1403

    
1404
		case 'server' :
1405
			if ($l2tpcfg['paporchap'] == "chap")
1406
				$paporchap = "set link enable chap";
1407
			else
1408
				$paporchap = "set link enable pap";
1409

    
1410
			/* write mpd.conf */
1411
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1412
			if (!$fd) {
1413
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1414
				return 1;
1415
			}
1416
			$mpdconf = "\n\n";
1417
			$mpdconf .=<<<EOD
1418
l2tps:
1419

    
1420
EOD;
1421

    
1422
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1423
				$mpdconf .= "	load l2tp{$i}\n";
1424
			}
1425

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

    
1428
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1429

    
1430
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1431
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1432
				} else {
1433
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1434
				}
1435

    
1436
				$mpdconf .=<<<EOD
1437

    
1438
l2tp{$i}:
1439
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1440
	{$isssue_ip_type}
1441
	load l2tp_standard
1442

    
1443
EOD;
1444
			}
1445

    
1446
			$mpdconf .=<<<EOD
1447

    
1448
l2tp_standard:
1449
	set bundle disable multilink
1450
	set bundle enable compression
1451
	set bundle yes crypt-reqd
1452
	set ipcp yes vjcomp
1453
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1454
	set ccp yes mppc
1455
	set iface disable on-demand
1456
	set iface enable proxy-arp
1457
	set iface up-script /usr/local/sbin/vpn-linkup
1458
	set iface down-script /usr/local/sbin/vpn-linkdown
1459
	set link yes acfcomp protocomp
1460
	set link no pap chap
1461
	set link enable chap
1462
	set link keep-alive 10 180
1463

    
1464
EOD;
1465

    
1466
			if (is_ipaddr($l2tpcfg['wins'])) {
1467
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1468
			}
1469
			if (is_ipaddr($l2tpcfg['dns1'])) {
1470
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1471
				if (is_ipaddr($l2tpcfg['dns2']))
1472
					$mpdconf .= " " . $l2tpcfg['dns2'];
1473
				$mpdconf .= "\n";
1474
			} elseif (isset ($config['dnsmasq']['enable'])) {
1475
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1476
				if ($syscfg['dnsserver'][0])
1477
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1478
				$mpdconf .= "\n";
1479
			} elseif (isset ($config['unbound']['enable'])) {
1480
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1481
				if ($syscfg['dnsserver'][0])
1482
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1483
				$mpdconf .= "\n";
1484
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1485
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1486
			}
1487

    
1488
			if (isset ($l2tpcfg['radius']['enable'])) {
1489
				$mpdconf .=<<<EOD
1490
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1491
	set radius retries 3
1492
	set radius timeout 10
1493
	set auth enable radius-auth
1494

    
1495
EOD;
1496

    
1497
				if (isset ($l2tpcfg['radius']['accounting'])) {
1498
					$mpdconf .=<<<EOD
1499
	set auth enable radius-acct
1500

    
1501
EOD;
1502
				}
1503
			}
1504

    
1505
			fwrite($fd, $mpdconf);
1506
			fclose($fd);
1507
			unset($mpdconf);
1508

    
1509
			/* write mpd.links */
1510
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1511
			if (!$fd) {
1512
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1513
				return 1;
1514
			}
1515

    
1516
			$mpdlinks = "";
1517

    
1518
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1519
				$mpdlinks .=<<<EOD
1520

    
1521
l2tp{$i}:
1522
	set link type l2tp
1523
	set l2tp enable incoming
1524
	set l2tp disable originate
1525

    
1526
EOD;
1527
			if (!empty($l2tpcfg['secret']))
1528
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1529
			}
1530

    
1531
			fwrite($fd, $mpdlinks);
1532
			fclose($fd);
1533
			unset($mpdlinks);
1534

    
1535
			/* write mpd.secret */
1536
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1537
			if (!$fd) {
1538
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1539
				return 1;
1540
			}
1541

    
1542
			$mpdsecret = "\n\n";
1543

    
1544
			if (is_array($l2tpcfg['user'])) {
1545
				foreach ($l2tpcfg['user'] as $user)
1546
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1547
			}
1548

    
1549
			fwrite($fd, $mpdsecret);
1550
			fclose($fd);
1551
			unset($mpdsecret);
1552
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1553

    
1554
			vpn_netgraph_support();
1555

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

    
1559
			break;
1560

    
1561
		case 'redir' :
1562
			break;
1563
	}
1564

    
1565
	if ($g['booting'])
1566
		echo "done\n";
1567

    
1568
	return 0;
1569
}
1570

    
1571
function vpn_ipsec_configure_preferoldsa() {
1572
	global $config;
1573
	if(isset($config['ipsec']['preferoldsa']))
1574
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
1575
	else
1576
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
1577
}
1578

    
1579
?>
(58-58/67)