Projet

Général

Profil

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

univnautes / etc / inc / vpn.inc @ 6ae8b844

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()
46
{
47
	global $config, $ipsec_loglevels;
48

    
49
	foreach ($ipsec_loglevels as $lkey => $ldescr) {
50
		if (empty($config['ipsec']["ipsec_{$lkey}"]))
51
			mwexec("/usr/local/sbin/ipsec stroke loglevel {$lkey} -1", false);
52
		else if (is_numeric($config['ipsec']["ipsec_{$lkey}"]) &&
53
		    intval($config['ipsec']["ipsec_{$lkey}"]) >= 1 && intval($config['ipsec']["ipsec_{$lkey}"]) <= 5)
54
			mwexec("/usr/local/sbin/ipsec stroke loglevel {$lkey} " . (intval($config['ipsec']["ipsec_{$lkey}"]) - 1) , false);
55
	}
56
}
57

    
58
/* include all configuration functions */
59
function vpn_ipsec_convert_to_modp($index)
60
{
61

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

    
90
	return $convertion;
91
}
92

    
93
function vpn_ipsec_configure($ipchg = false)
94
{
95
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos;
96

    
97
	if ($g['platform'] == 'jail')
98
		return;
99

    
100
	/* get the automatic ping_hosts.sh ready */
101
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
102
	touch("{$g['vardb_path']}/ipsecpinghosts");
103

    
104
	vpn_ipsec_configure_preferoldsa();
105

    
106
	$syscfg = $config['system'];
107
	$ipseccfg = $config['ipsec'];
108
	$a_phase1 = $config['ipsec']['phase1'];
109
	$a_phase2 = $config['ipsec']['phase2'];
110
	$a_client = $config['ipsec']['client'];
111

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

    
118
		/* wait for process to die */
119
		sleep(2);
120

    
121
		/* disallow IPSEC, it is off */
122
		mwexec("/sbin/ifconfig enc0 down");
123
		exec("/sbin/sysctl net.inet.ip.ipsec_in_use=0");
124

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

    
152
		if ($g['booting'])
153
			echo gettext("Configuring IPsec VPN... ");
154

    
155
		/* fastforwarding is not compatible with ipsec tunnels */
156
		mwexec("/sbin/sysctl net.inet.ip.fastforwarding=0");
157

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

    
166
			$ipsecpinghosts = "";
167
			/* step through each phase1 entry */
168
			foreach ($a_phase1 as $ph1ent) {
169
				if (isset($ph1ent['disabled']))
170
					continue;
171

    
172
				$listeniflist = get_real_interface($a_phase1['interface']);
173

    
174
				$ep = ipsec_get_phase1_src($ph1ent);
175
				if (!is_ipaddr($ep))
176
					continue;
177

    
178
				if(!in_array($ep,$ipmap))
179
					$ipmap[] = $ep;
180

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

    
184
				if (isset ($ph1ent['mobile']))
185
					continue;
186

    
187
				$rg = $ph1ent['remote-gateway'];
188

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

    
203
				if (is_array($a_phase2)) {
204
					/* step through each phase2 entry */
205
					foreach ($a_phase2 as $ph2ent) {
206
						$ikeid = $ph2ent['ikeid'];
207

    
208
						if (isset($ph2ent['disabled']))
209
							continue;
210

    
211
						if ($ikeid != $ph1ent['ikeid'])
212
							continue;
213

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

    
256
		$strongswan = <<<EOD
257

    
258
#Automatically generated please do not modify
259
starter {
260
    load_warning = no
261
}
262

    
263
charon {
264

    
265
        # number of worker threads in charon
266
        threads = 16
267

    
268
	# And two loggers using syslog. The subsections define the facility to log
269
	# to, currently one of: daemon, auth.
270
	syslog {
271

    
272
		identifier = charon
273
		# default level to the LOG_DAEMON facility
274
		daemon {
275
		}
276
		# very minimalistic IKE auditing logs to LOG_AUTHPRIV
277
		auth {
278
		    default = -1
279
		    ike = 1
280
		    ike_name = yes
281
		}
282
	}
283

    
284
EOD;
285

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

    
289
		$strongswan .= "\tplugins {\n";
290

    
291
		if (is_array($a_client) && isset($a_client['enable'])) {
292
			$strongswan .= "\t\tattr {\n";
293
			if ($a_client['pool_address'] && $a_client['pool_netbits']) {
294
				$pool_address = $a_client['pool_address'];
295
				$pool_netmask = gen_subnet_mask($a_client['pool_netbits']);
296
				$pool_address = long2ip32(ip2long($pool_address)+1);
297

    
298
				$strongswan .= "\t\taddress = {$pool_address}\n";
299
				$strongswan .= "\t\tnetmask = {$pool_netmask}\n";
300
			}
301

    
302
			$cfgservers = array();
303
			if (!empty($a_client['dns_server1']))
304
				$cfgservers[] = $a_client['dns_server1'];
305
			if (!empty($a_client['dns_server2']))
306
				$cfgservers[] = $a_client['dns_server2'];
307
			if (!empty($a_client['dns_server3']))
308
				$cfgservers[] = $a_client['dns_server3'];
309
			if (!empty($a_client['dns_server4']))
310
				$cfgservers[] = $a_client['dns_server4'];
311

    
312
			if (!empty($cfgservers))
313
				$strongswan .= "\t\tdns = " . implode(",", $cfgservers) . "\n";
314
			unset($cfgservers);
315
			$cfgservers = array();
316
			if (!empty($a_client['wins_server1']))
317
				$cfgservers[] = $a_client['wins_server1'];
318
			if (!empty($a_client['wins_server2']))
319
				$cfgservers[] = $a_client['wins_server2'];
320
			if (!empty($cfgservers))
321
				$strongswan .= "\t\tnbns = " . implode(",", $cfgservers) . "\n";
322
			unset($cfgservers);
323

    
324
			if (!empty($a_client['net_list'])) {
325
				$net_list = '';
326
				foreach ($a_phase2 as $ph2ent) {
327
					if (isset($ph2ent['disabled']))
328
						continue;
329

    
330
					if (!isset($ph2ent['mobile']))
331
						continue;
332

    
333
					$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
334

    
335
					if ($net_list)
336
						$net_list .= ", ";
337
					$net_list .= $localid;
338
				}
339

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

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

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

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

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

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

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

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

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

    
414
		$pskconf = "";
415

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

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

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

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

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

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

    
434
						chmod($certpath, 0600);
435

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

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

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

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

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

    
459
							chmod($capath, 0600);
460
						}
461
					}
462
				} else {
463

    
464
					$peerid_type = $ph1ent['peerid_type'];
465

    
466
					switch ($peerid_type) {
467
						case "peeraddress":
468
							$peerid_type = "address";
469
							$peerid_data = $rgmap[$ph1ent['remote-gateway']];
470
							break;
471

    
472
						case "address";
473
							$peerid_data = $ph1ent['peerid_data'];
474
							break;
475

    
476
						case "fqdn";
477
						case "keyid tag";
478
						case "user_fqdn";
479
							$peerid_data = $ph1ent['peerid_data'];
480
							break;
481
					}
482

    
483
					if (!empty($peerid_data) && !empty($ph1ent['pre-shared-key']))
484
						$pskconf .= trim($peerid_data) . " : PSK \"" . trim($ph1ent['pre-shared-key']) . "\"\n";
485
				}
486
			}
487
		}
488

    
489
		/* Add user PSKs */
490
		foreach ($config['system']['user'] as $user) {
491
			if (!empty($user['ipsecpsk'])) {
492
				$pskconf .= "{$user['name']} : PSK \"{$user['ipsecpsk']}\"\n";
493
			}
494
		}
495

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

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

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

    
512
			$ipsecconf .= "# This file is automatically generated. Do not edit\n";
513
			if (is_array($a_phase2) && count($a_phase2)) {
514
				$ipsecconf .= "config setup\n\tuniqueids = yes\n";
515

    
516
				foreach ($a_phase2 as $ph2ent) {
517
					$ikeid = $ph2ent['ikeid'];
518

    
519
					$ph1ent = false;
520
					if (!ipsec_lookup_phase1($ph2ent,$ph1ent))
521
						continue;
522

    
523
					if (isset($ph1ent['disabled']))
524
						continue;
525

    
526
					if (isset($ph2ent['disabled']))
527
						continue;
528

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

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

    
535
					if (!isset($ph1ent['mobile'])) {
536
						$rgip = $rgmap[$ph1ent['remote-gateway']];
537
						if (!$rgip)
538
							continue;
539
					}
540

    
541
					$myid_type = $ph1ent['myid_type'];
542

    
543
					switch ($myid_type) {
544
					case "myaddress":
545
						$myid_type = "address";
546
						$myid_data = $ep;
547
						break;
548

    
549
					case "dyn_dns":
550
						$myid_type = "address";
551
						$myid_data = resolve_retry($ph1ent['myid_data']);
552
						break;
553

    
554
					case "address";
555
						$myid_data = $ph1ent['myid_data'];
556
						break;
557

    
558
					case "fqdn";
559
					case "keyid tag";
560
					case "user_fqdn";
561
					case "asn1dn";
562
						$myid_data = $ph1ent['myid_data'];
563
						if( $myid_data )
564
							$myid_data = "\"{$myid_data}\"";
565
						break;
566
					}
567

    
568
					$peerid_type = $ph1ent['peerid_type'];
569

    
570
					switch ($peerid_type) {
571
					case "peeraddress":
572
						$peerid_type = "address";
573
						$peerid_data = $rgip;
574
						break;
575

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

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

    
590
					$genp = "no";
591
					if (!empty($ph1ent['generate_policy']) && $ph1ent['generate_policy'] != "off")
592
						$genp = "yes";
593
						
594
					$passive = "start";
595
					if (isset($ph1ent['mobile'])) {
596
						$rgip = "%any";
597
						$passive = "route";
598
					}
599

    
600
					$keyexchange = "ikev1";
601
					if (!empty($ph1ent['iketype']) && $ph1ent['iketype'] != "ikev1")
602
						$keyexchange = "ikev2";
603

    
604
					if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
605
						$ealgosp1 = '';
606
						$ealg_id = $ph1ent['encryption-algorithm']['name'];
607
						$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
608
						if ($ealg_kl)
609
							$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
610
						else
611
							$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
612

    
613
						$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
614
						if (!empty($modp))
615
							$ealgosp1 .= "-{$modp}";
616

    
617
						if ($keyexchange == "ikev1")
618
							$ealgosp1 .= "!";
619
					}
620

    
621
					if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
622
						if ($passive == "start")
623
							$dpdline = "dpdaction = restart";
624
						else
625
							$dpdline = "dpdaction = clear";
626
						$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
627
						$dpdline .= "\n\tdpdtimeout = {$ph1ent['dpd_maxfail']}s";
628
					} else
629
						$dpdline = "dpdaction = none";
630

    
631
					if (!empty($ph1ent['authentication_method']) && (strstr($ph1ent['authentication_method'], "xauth") || strstr($ph1ent['authentication_method'], "hybrid")))
632
						$xauth = "xauth = server";
633

    
634

    
635
					$lifeline = '';
636
					if ($ph1ent['lifetime'])
637
						$lifeline = "ikelifetime = {$ph1ent['lifetime']}s";
638

    
639
					/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
640
					$peerid_spec = '';
641
					if (!(($ph1ent['authentication_method'] == "pre_shared_key") && isset($ph1ent['mobile']))) {
642
						$peerid_spec = $peerid_data;
643
					}
644

    
645
					if (empty($ph1ent['mode']))
646
						$aggressive = "no";
647
					else if ($ph1ent['mode'] == "aggressive")
648
						$aggressive = "yes";
649
					else if ($ph1ent['mode'] == "main")
650
						$aggressive = "no";
651
					else
652
						$aggressive = "no";
653

    
654
					if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
655
						continue;
656

    
657
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
658
						$tunneltype = "type = tunnel";
659

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

    
690
						if (!isset($ph2ent['mobile'])) {
691
							$remoteid_type = $ph2ent['remoteid']['type'];
692
							if ($remoteid_type != "address")
693
								$remoteid_type = "subnet";
694

    
695
							$remoteid_data = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
696
							$remoteid_spec = $remoteid_data;
697
						}
698

    
699
					} else {
700
						$tunneltype = "type = transport";
701
						$rgip = $rgmap[$ph1ent['remote-gateway']];
702

    
703
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
704
							($ph1ent['authentication_method'] == "pre_shared_key"))
705
							&& isset($ph1ent['mobile']))
706
							$localid_spec = "%any";
707
						else {
708
							$localid_data = ipsec_get_phase1_src($ph1ent);
709
							$localid_spec = $ep;
710
						}
711
						if (!isset($ph2ent['mobile'])) {
712
							$remoteid_data = $rgmap[$ph1ent['remote-gateway']];
713
							$remoteid_spec = $remoteid_data;
714
						}
715
					}
716
					$authentication = "";
717
					switch ($ph1ent['authentication_method']) {
718
					case 'xauth_rsa_server':
719
						$authentication = "leftauth = pubkey\n\trightauth = pubkey";
720
						$authentication .= "\n\leftauth2 = xauth-generic";
721
						break;
722
					case 'xauth_psk_server':
723
						$authentication = "leftauth = psk\n\trightauth = psk";
724
						$authentication .= "\n\tleftauth2 = xauth-generic";
725
						break;
726
					case 'pre_shared_key':
727
						$authentication = "leftauth = psk\n\trightauth = psk";
728
						break;
729
					case 'rsasig':
730
						$authentication = "leftauth = pubkey\n\trightauth = pubkey";
731
						break;
732
					case 'hybrid_rsa_server':
733
						$authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
734
						$authentication .= "\n\trightauth2 = xauth";
735
						break;
736
					}
737

    
738
					if (isset($a_client['pfs_group']))
739
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
740
					$ealgosp2 = '';
741
					if ($ph2ent['protocol'] == 'esp') {
742
						if (is_array($ph2ent['encryption-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
743
							$ealgosp2arr = array();
744
							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
745
								$ealg_id = $ealg['name'];
746
								$ealg_kl = $ealg['keylen'];
747

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

    
795

    
796
					if ($ph2ent['lifetime'])
797
						$lifeline = "ikelifetime = {$ph2ent['lifetime']}s";
798

    
799
					$ipsecconf .=<<<EOD
800

    
801
conn con{$ph2ent['ikeid']}-{$ph2ent['ikeid']}
802
	aggressive = {$aggressive}
803
	fragmentation = yes
804
	keyexchange = {$keyexchange}
805
	keyingtries = %forever
806
	reauth = yes
807
	reqid = {$ikeid}
808
	installpolicy = yes
809
	{$lifeline}
810
	{$tunneltype}
811
	{$dpdline}
812
	auto = {$passive}
813
	left = {$localid_spec}
814
	leftsubnet = {$localid_data}
815
	right = {$rgip}
816
	leftid = {$myid_data}
817

    
818
EOD;
819

    
820
					if (!empty($remoteid_spec))
821
						$ipsecconf .= "\trightsubnet = $remoteid_spec\n";
822
					if (!empty($ealgosp1))
823
						$ipsecconf .= "\t{$ealgosp1}\n";
824
					if (!empty($ealgosp2))
825
						$ipsecconf .= "\t{$ealgosp2}\n";
826
					if (!empty($authentication))
827
						$ipsecconf .= "\t{$authentication}\n";
828
					if (!empty($peerid_spec))
829
						$ipsecconf .= "\trightid = {$peerid_spec}\n";
830
				}
831
			}
832
		}
833
	}
834
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
835
	unset($ipsecconf);
836
	/* end ipsec.conf */
837

    
838
	/* mange process */
839
	if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
840
		/* Read secrets */
841
		mwexec("/usr/local/sbin/ipsec rereadall", false);
842
		/* Update configuration changes */
843
		mwexec("/usr/local/sbin/ipsec update", false);
844
	} else {
845
		mwexec("/usr/local/sbin/ipsec start", false); 
846
	}
847
	vpn_ipsec_configure_loglevels();
848
	if ($natfilterrules == true)
849
		filter_configure();
850
	/* start filterdns, if necessary */
851
	if (count($filterdns_list) > 0) {
852
		$interval = 60;
853
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
854
			$interval = $ipseccfg['dns-interval'];
855

    
856
		$hostnames = "";
857
		array_unique($filterdns_list);
858
		foreach ($filterdns_list as $hostname)
859
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
860
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
861
		unset($hostnames);
862

    
863
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
864
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
865
		else {
866
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
867
		}
868
	} else {
869
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
870
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
871
	}
872

    
873
	if ($g['booting'])
874
		echo "done\n";
875

    
876
	return count($filterdns_list);
877
}
878

    
879
/*
880
 * Forcefully restart IPsec
881
 * This is required for when dynamic interfaces reload
882
 * For all other occasions the normal vpn_ipsec_configure()
883
 * will gracefully reload the settings without restarting
884
 */
885
function vpn_ipsec_force_reload($interface = "") {
886
	global $g, $config;
887

    
888
	$ipseccfg = $config['ipsec'];
889

    
890
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
891
		$found = false;
892
		foreach ($ipseccfg['phase1'] as $ipsec) {
893
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
894
				$found = true;
895
				break;
896
			}
897
		}
898
		if (!$found) {
899
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
900
			return;
901
		}
902
	}
903

    
904
	/* if ipsec is enabled, start up again */
905
	if (isset($ipseccfg['enable'])) {
906
		log_error(gettext("Forcefully reloading IPsec"));
907
		vpn_ipsec_configure();
908
	}
909
}
910

    
911
/* master setup for vpn (mpd) */
912
function vpn_setup() {
913
	global $g;
914

    
915
	if ($g['platform'] == 'jail')
916
		return;
917

    
918
	/* start pptpd */
919
	vpn_pptpd_configure();
920

    
921
	/* start pppoe server */
922
	vpn_pppoes_configure();
923

    
924
	/* setup l2tp */
925
	vpn_l2tp_configure();
926
}
927

    
928
function vpn_netgraph_support() {
929
	$iflist = get_configured_interface_list();
930
	foreach ($iflist as $iface) {
931
		$realif = get_real_interface($iface);
932
		/* Get support for netgraph(4) from the nic */
933
		$ifinfo = pfSense_get_interface_addresses($realif);
934
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
935
			pfSense_ngctl_attach(".", $realif);
936
	}
937
}
938

    
939
function vpn_pptpd_configure() {
940
	global $config, $g;
941

    
942
	$syscfg = $config['system'];
943
	$pptpdcfg = $config['pptpd'];
944

    
945
	if ($g['booting']) {
946
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
947
			return 0;
948

    
949
		echo gettext("Configuring PPTP VPN service... ");
950
	} else {
951
		/* kill mpd */
952
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
953

    
954
		/* wait for process to die */
955
		sleep(3);
956

    
957
		if (is_process_running("mpd -b")) {
958
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
959
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
960
		}
961

    
962
		/* remove mpd.conf, if it exists */
963
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
964
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
965
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
966
	}
967

    
968
	if (empty($pptpdcfg['n_pptp_units'])) {
969
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
970
		return;
971
	}
972

    
973
	/* make sure pptp-vpn directory exists */
974
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
975
		mkdir("{$g['varetc_path']}/pptp-vpn");
976

    
977
	switch ($pptpdcfg['mode']) {
978
		case 'server' :
979
			/* write mpd.conf */
980
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
981
			if (!$fd) {
982
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
983
				return 1;
984
			}
985

    
986
			$mpdconf = <<<EOD
987
pptps:
988

    
989
EOD;
990

    
991
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
992
				$mpdconf .= "	load pt{$i}\n";
993
			}
994

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

    
997
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
998

    
999
				$mpdconf .= <<<EOD
1000

    
1001
pt{$i}:
1002
	new -i pptpd{$i} pt{$i} pt{$i}
1003
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1004
	load pts
1005

    
1006
EOD;
1007
			}
1008

    
1009
			$mpdconf .=<<<EOD
1010

    
1011
pts:
1012
	set iface disable on-demand
1013
	set iface enable proxy-arp
1014
	set iface enable tcpmssfix
1015
	set iface idle 1800
1016
	set iface up-script /usr/local/sbin/vpn-linkup
1017
	set iface down-script /usr/local/sbin/vpn-linkdown
1018
	set bundle enable multilink
1019
	set bundle enable crypt-reqd
1020
	set link yes acfcomp protocomp
1021
	set link no pap chap
1022
	set link enable chap-msv2
1023
	set link mtu 1460
1024
	set link keep-alive 10 60
1025
	set ipcp yes vjcomp
1026
	set bundle enable compression
1027
	set ccp yes mppc
1028
	set ccp yes mpp-e128
1029
	set ccp yes mpp-stateless
1030

    
1031
EOD;
1032

    
1033
			if (!isset ($pptpdcfg['req128'])) {
1034
				$mpdconf .=<<<EOD
1035
	set ccp yes mpp-e40
1036
	set ccp yes mpp-e56
1037

    
1038
EOD;
1039
			}
1040

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

    
1044
			if (!empty($pptpdcfg['dns1'])) {
1045
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1046
				if (!empty($pptpdcfg['dns2']))
1047
					$mpdconf .= " " . $pptpdcfg['dns2'];
1048
				$mpdconf .= "\n";
1049
			} elseif (isset ($config['dnsmasq']['enable'])) {
1050
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1051
				if ($syscfg['dnsserver'][0])
1052
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1053
				$mpdconf .= "\n";
1054
			} elseif (isset($config['unbound']['enable'])) {
1055
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1056
				if ($syscfg['dnsserver'][0])
1057
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1058
				$mpdconf .= "\n";
1059
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1060
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1061
			}
1062

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

    
1069
EOD;
1070
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1071
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1072
				$acctport = $authport + 1;
1073
				$mpdconf .=<<<EOD
1074
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1075

    
1076
EOD;
1077
			}
1078
			$mpdconf .=<<<EOD
1079
	set radius retries 3
1080
	set radius timeout 10
1081
	set auth enable radius-auth
1082

    
1083
EOD;
1084

    
1085
				if (isset ($pptpdcfg['radius']['accounting'])) {
1086
					$mpdconf .=<<<EOD
1087
	set auth enable radius-acct
1088
	set radius acct-update 300
1089

    
1090
EOD;
1091
				}
1092
			}
1093

    
1094
			fwrite($fd, $mpdconf);
1095
			fclose($fd);
1096
			unset($mpdconf);
1097

    
1098
			/* write mpd.links */
1099
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1100
			if (!$fd) {
1101
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1102
				return 1;
1103
			}
1104

    
1105
			$mpdlinks = "";
1106

    
1107
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1108
				$mpdlinks .=<<<EOD
1109

    
1110
pt{$i}:
1111
	set link type pptp
1112
	set pptp enable incoming
1113
	set pptp disable originate
1114
	set pptp disable windowing
1115

    
1116
EOD;
1117
			}
1118

    
1119
			fwrite($fd, $mpdlinks);
1120
			fclose($fd);
1121
			unset($mpdlinks);
1122

    
1123
			/* write mpd.secret */
1124
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1125
			if (!$fd) {
1126
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1127
				return 1;
1128
			}
1129

    
1130
			$mpdsecret = "";
1131

    
1132
			if (is_array($pptpdcfg['user'])) {
1133
				foreach ($pptpdcfg['user'] as $user) {
1134
					$pass = str_replace('\\', '\\\\', $user['password']);
1135
					$pass = str_replace('"', '\"', $pass);
1136
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1137
				}
1138
			}
1139

    
1140
			fwrite($fd, $mpdsecret);
1141
			fclose($fd);
1142
			unset($mpdsecret);
1143
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1144

    
1145
			vpn_netgraph_support();
1146

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

    
1150
			break;
1151

    
1152
		case 'redir' :
1153
			break;
1154
	}
1155

    
1156
	if ($g['booting'])
1157
		echo "done\n";
1158

    
1159
	return 0;
1160
}
1161

    
1162
function vpn_pppoes_configure() {
1163
	global $config;
1164

    
1165
	if (is_array($config['pppoes']['pppoe'])) {
1166
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1167
			vpn_pppoe_configure($pppoe);
1168
	}
1169
}
1170

    
1171
function vpn_pppoe_configure(&$pppoecfg) {
1172
	global $config, $g;
1173

    
1174
	$syscfg = $config['system'];
1175

    
1176
	/* create directory if it does not exist */
1177
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1178
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1179

    
1180
	if ($g['booting']) {
1181
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1182
			return 0;
1183

    
1184
		echo gettext("Configuring PPPoE VPN service... ");
1185
	} else {
1186
		/* kill mpd */
1187
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1188

    
1189
		/* wait for process to die */
1190
		sleep(2);
1191

    
1192
	}
1193

    
1194
	switch ($pppoecfg['mode']) {
1195

    
1196
		case 'server' :
1197

    
1198
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1199

    
1200
			if ($pppoecfg['paporchap'] == "chap")
1201
				$paporchap = "set link enable chap";
1202
			else
1203
				$paporchap = "set link enable pap";
1204

    
1205
			/* write mpd.conf */
1206
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1207
			if (!$fd) {
1208
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1209
				return 1;
1210
			}
1211
			$mpdconf = "\n\n";
1212
			$mpdconf .= "poes:\n";
1213

    
1214
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1215
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1216
			}
1217

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

    
1220
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1221

    
1222
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1223
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1224
				} else {
1225
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1226
				}
1227

    
1228
				$mpdconf .=<<<EOD
1229

    
1230
poes{$pppoecfg['pppoeid']}{$i}:
1231
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1232
	{$isssue_ip_type}
1233
	load pppoe_standard
1234

    
1235
EOD;
1236
			}
1237

    
1238
			$mpdconf .=<<<EOD
1239

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

    
1266
EOD;
1267

    
1268
			if (!empty($pppoecfg['dns1'])) {
1269
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1270
				if (!empty($pppoecfg['dns2']))
1271
					$mpdconf .= " " . $pppoecfg['dns2'];
1272
				$mpdconf .= "\n";
1273
			} elseif (isset ($config['dnsmasq']['enable'])) {
1274
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1275
				if ($syscfg['dnsserver'][0])
1276
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1277
				$mpdconf .= "\n";
1278
			} elseif (isset ($config['unbound']['enable'])) {
1279
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1280
				if ($syscfg['dnsserver'][0])
1281
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1282
				$mpdconf .= "\n";
1283
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1284
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1285
			}
1286

    
1287
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1288
				$radiusport = "";
1289
				$radiusacctport = "";
1290
				if (isset($pppoecfg['radius']['server']['port']))
1291
					$radiusport = $pppoecfg['radius']['server']['port'];
1292
				if (isset($pppoecfg['radius']['server']['acctport']))
1293
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1294
				$mpdconf .=<<<EOD
1295
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1296
	set radius retries 3
1297
	set radius timeout 10
1298
	set auth enable radius-auth
1299

    
1300
EOD;
1301

    
1302
				if (isset ($pppoecfg['radius']['accounting'])) {
1303
					$mpdconf .=<<<EOD
1304
	set auth enable radius-acct
1305

    
1306
EOD;
1307
				}
1308
			}
1309

    
1310
			fwrite($fd, $mpdconf);
1311
			fclose($fd);
1312
			unset($mpdconf);
1313

    
1314
			/* write mpd.links */
1315
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1316
			if (!$fd) {
1317
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1318
				return 1;
1319
			}
1320

    
1321
			$mpdlinks = "";
1322

    
1323
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1324
				$mpdlinks .=<<<EOD
1325

    
1326
poes{$pppoecfg['pppoeid']}{$i}:
1327
	set phys type pppoe
1328
	set pppoe iface {$pppoe_interface}
1329
	set pppoe service "*"
1330
	set pppoe disable originate
1331
	set pppoe enable incoming
1332

    
1333
EOD;
1334
			}
1335

    
1336
			fwrite($fd, $mpdlinks);
1337
			fclose($fd);
1338
			unset($mpdlinks);
1339

    
1340
			if ($pppoecfg['username']) {
1341
				/* write mpd.secret */
1342
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1343
				if (!$fd) {
1344
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1345
					return 1;
1346
				}
1347

    
1348
				$mpdsecret = "\n\n";
1349

    
1350
				if (!empty($pppoecfg['username'])) {
1351
					$item = explode(" ", $pppoecfg['username']);
1352
					foreach($item as $userdata) {
1353
						$data = explode(":", $userdata);
1354
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1355
					}
1356
				}
1357

    
1358
				fwrite($fd, $mpdsecret);
1359
				fclose($fd);
1360
				unset($mpdsecret);
1361
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1362
			}
1363

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

    
1368
			/* Get support for netgraph(4) from the nic */
1369
			pfSense_ngctl_attach(".", $pppoe_interface);
1370
			/* fire up mpd */
1371
			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");
1372

    
1373
			break;
1374
	}
1375

    
1376
	if ($g['booting'])
1377
		echo gettext("done") . "\n";
1378

    
1379
	return 0;
1380
}
1381

    
1382
function vpn_l2tp_configure() {
1383
	global $config, $g;
1384

    
1385
	$syscfg = $config['system'];
1386
	$l2tpcfg = $config['l2tp'];
1387

    
1388
	/* create directory if it does not exist */
1389
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1390
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1391

    
1392
	if ($g['booting']) {
1393
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1394
			return 0;
1395

    
1396
		echo gettext("Configuring l2tp VPN service... ");
1397
	} else {
1398
		/* kill mpd */
1399
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1400

    
1401
		/* wait for process to die */
1402
		sleep(8);
1403

    
1404
	}
1405

    
1406
	/* make sure l2tp-vpn directory exists */
1407
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1408
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1409

    
1410
	switch ($l2tpcfg['mode']) {
1411

    
1412
		case 'server' :
1413
			if ($l2tpcfg['paporchap'] == "chap")
1414
				$paporchap = "set link enable chap";
1415
			else
1416
				$paporchap = "set link enable pap";
1417

    
1418
			/* write mpd.conf */
1419
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1420
			if (!$fd) {
1421
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1422
				return 1;
1423
			}
1424
			$mpdconf = "\n\n";
1425
			$mpdconf .=<<<EOD
1426
l2tps:
1427

    
1428
EOD;
1429

    
1430
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1431
				$mpdconf .= "	load l2tp{$i}\n";
1432
			}
1433

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

    
1436
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1437

    
1438
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1439
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1440
				} else {
1441
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1442
				}
1443

    
1444
				$mpdconf .=<<<EOD
1445

    
1446
l2tp{$i}:
1447
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1448
	{$isssue_ip_type}
1449
	load l2tp_standard
1450

    
1451
EOD;
1452
			}
1453

    
1454
			$mpdconf .=<<<EOD
1455

    
1456
l2tp_standard:
1457
	set bundle disable multilink
1458
	set bundle enable compression
1459
	set bundle yes crypt-reqd
1460
	set ipcp yes vjcomp
1461
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1462
	set ccp yes mppc
1463
	set iface disable on-demand
1464
	set iface enable proxy-arp
1465
	set iface up-script /usr/local/sbin/vpn-linkup
1466
	set iface down-script /usr/local/sbin/vpn-linkdown
1467
	set link yes acfcomp protocomp
1468
	set link no pap chap
1469
	set link enable chap
1470
	set link keep-alive 10 180
1471

    
1472
EOD;
1473

    
1474
			if (is_ipaddr($l2tpcfg['wins'])) {
1475
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1476
			}
1477
			if (is_ipaddr($l2tpcfg['dns1'])) {
1478
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1479
				if (is_ipaddr($l2tpcfg['dns2']))
1480
					$mpdconf .= " " . $l2tpcfg['dns2'];
1481
				$mpdconf .= "\n";
1482
			} elseif (isset ($config['dnsmasq']['enable'])) {
1483
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1484
				if ($syscfg['dnsserver'][0])
1485
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1486
				$mpdconf .= "\n";
1487
			} elseif (isset ($config['unbound']['enable'])) {
1488
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1489
				if ($syscfg['dnsserver'][0])
1490
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1491
				$mpdconf .= "\n";
1492
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1493
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1494
			}
1495

    
1496
			if (isset ($l2tpcfg['radius']['enable'])) {
1497
				$mpdconf .=<<<EOD
1498
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1499
	set radius retries 3
1500
	set radius timeout 10
1501
	set auth enable radius-auth
1502

    
1503
EOD;
1504

    
1505
				if (isset ($l2tpcfg['radius']['accounting'])) {
1506
					$mpdconf .=<<<EOD
1507
	set auth enable radius-acct
1508

    
1509
EOD;
1510
				}
1511
			}
1512

    
1513
			fwrite($fd, $mpdconf);
1514
			fclose($fd);
1515
			unset($mpdconf);
1516

    
1517
			/* write mpd.links */
1518
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1519
			if (!$fd) {
1520
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1521
				return 1;
1522
			}
1523

    
1524
			$mpdlinks = "";
1525

    
1526
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1527
				$mpdlinks .=<<<EOD
1528

    
1529
l2tp{$i}:
1530
	set link type l2tp
1531
	set l2tp enable incoming
1532
	set l2tp disable originate
1533

    
1534
EOD;
1535
			if (!empty($l2tpcfg['secret']))
1536
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1537
			}
1538

    
1539
			fwrite($fd, $mpdlinks);
1540
			fclose($fd);
1541
			unset($mpdlinks);
1542

    
1543
			/* write mpd.secret */
1544
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1545
			if (!$fd) {
1546
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1547
				return 1;
1548
			}
1549

    
1550
			$mpdsecret = "\n\n";
1551

    
1552
			if (is_array($l2tpcfg['user'])) {
1553
				foreach ($l2tpcfg['user'] as $user)
1554
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1555
			}
1556

    
1557
			fwrite($fd, $mpdsecret);
1558
			fclose($fd);
1559
			unset($mpdsecret);
1560
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1561

    
1562
			vpn_netgraph_support();
1563

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

    
1567
			break;
1568

    
1569
		case 'redir' :
1570
			break;
1571
	}
1572

    
1573
	if ($g['booting'])
1574
		echo "done\n";
1575

    
1576
	return 0;
1577
}
1578

    
1579
function vpn_ipsec_configure_preferoldsa() {
1580
	global $config;
1581
	if(isset($config['ipsec']['preferoldsa']))
1582
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
1583
	else
1584
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
1585
}
1586

    
1587
?>
(58-58/67)