Projet

Général

Profil

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

univnautes / etc / inc / vpn.inc @ 9879f03a

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
	# And two loggers using syslog. The subsections define the facility to log
273
	# to, currently one of: daemon, auth.
274
	syslog {
275

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

    
288
EOD;
289

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

    
293
		$strongswan .= "\tplugins {\n";
294

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

    
302
				$strongswan .= "\t\taddress = {$pool_address}\n";
303
				$strongswan .= "\t\tnetmask = {$pool_netmask}\n";
304
			}
305

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

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

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

    
334
					if (!isset($ph2ent['mobile']))
335
						continue;
336

    
337
					$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
338

    
339
					if ($net_list)
340
						$net_list .= ", ";
341
					$net_list .= $localid;
342
				}
343

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

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

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

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

    
366
			if (isset($a_client['save_passwd']))
367
				$strongswan .= "\t\t28673 = yes\n";
368

    
369
			if ($a_client['pfs_group'])
370
				$strongswan .= "\t\t28679 = {$a_client['pfs_group']}\n";
371
			$strongswan .= "\t\t}\n";
372

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

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

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

    
418
		$pskconf = "";
419

    
420
		if (is_array($a_phase1) && count($a_phase1)) {
421
			foreach ($a_phase1 as $ph1ent) {
422

    
423
				if (isset($ph1ent['disabled']))
424
					continue;
425

    
426
				if (strstr($ph1ent['authentication_method'],'rsa')) {
427
					$certline = '';
428

    
429
					if (strstr($authmethod,'rsa')) {
430

    
431
						$cert = lookup_cert($ph1ent['certref']);
432

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

    
438
						chmod($certpath, 0600);
439

    
440
						$keyfile = "cert-{$ikeid}.key";
441
						$keypath = "{$g['varetc_path']}/ipsec/{$keyfile}";
442

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

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

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

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

    
463
							chmod($capath, 0600);
464
						}
465
					}
466
				} else {
467

    
468
					$peerid_type = $ph1ent['peerid_type'];
469

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

    
476
						case "address";
477
							$peerid_data = $ph1ent['peerid_data'];
478
							break;
479

    
480
						case "fqdn";
481
						case "keyid tag";
482
						case "user_fqdn";
483
							$peerid_data = $ph1ent['peerid_data'];
484
							break;
485
					}
486

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

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

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

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

    
513
		$natfilterrules = false;
514
		/* begin ipsec.conf */
515
		$ipsecconf = "";
516
		if ((is_array($a_phase1) && count($a_phase1)) || (is_array($a_phase2) && count($a_phase2))) {
517

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

    
523
				foreach ($a_phase2 as $ph2ent) {
524
					$ikeid = $ph2ent['ikeid'];
525

    
526
					$ph1ent = false;
527
					if (!ipsec_lookup_phase1($ph2ent,$ph1ent))
528
						continue;
529

    
530
					if (isset($ph1ent['disabled']))
531
						continue;
532

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

    
536
					if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
537
						continue;
538

    
539
					$ikeid = $ph1ent['ikeid'];
540

    
541
					$ep = ipsec_get_phase1_src($ph1ent);
542
					if (!$ep)
543
						continue;
544

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

    
552
					$keyexchange = "ikev1";
553
					if (!empty($ph1ent['iketype']) && $ph1ent['iketype'] != "ikev1")
554
						$keyexchange = "ikev2";
555

    
556
					$myid_type = $ph1ent['myid_type'];
557
					switch ($myid_type) {
558
					case "myaddress":
559
						$myid_type = "address";
560
						$myid_data = $ep;
561
						break;
562

    
563
					case "dyn_dns":
564
						$myid_type = "address";
565
						$myid_data = resolve_retry($ph1ent['myid_data']);
566
						break;
567

    
568
					case "address";
569
						$myid_data = $ph1ent['myid_data'];
570
						break;
571

    
572
					case "fqdn";
573
					case "keyid tag";
574
					case "user_fqdn";
575
					case "asn1dn";
576
						$myid_data = $ph1ent['myid_data'];
577
						if( $myid_data )
578
							$myid_data = "{$myid_data}";
579
						break;
580
					}
581

    
582
					$peerid_type = $ph1ent['peerid_type'];
583
					switch ($peerid_type) {
584
					case "peeraddress":
585
						$peerid_type = "address";
586
						$peerid_data = $rgip;
587
						break;
588

    
589
					case "address";
590
						$peerid_data = $ph1ent['peerid_data'];
591
						break;
592

    
593
					case "fqdn";
594
					case "keyid tag";
595
					case "user_fqdn";
596
					case "asn1dn";
597
						$peerid_data = $ph1ent['peerid_data'];
598
						if( $peerid_data )
599
							$peerid_data = "{$peerid_data}";
600
						break;
601
					}
602

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

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

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

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

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

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

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

    
643
					if ($ph1ent['mode'] == "aggressive")
644
						$aggressive = "yes";
645
					else
646
						$aggressive = "no";
647

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

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

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

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

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

    
727
					if (isset($a_client['pfs_group']))
728
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
729

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

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

    
785

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

    
789
					$ipsecconf .=<<<EOD
790

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

    
808
EOD;
809

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

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

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

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

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

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

    
866
	return count($filterdns_list);
867
}
868

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

    
878
	$ipseccfg = $config['ipsec'];
879

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

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

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

    
905
	if ($g['platform'] == 'jail')
906
		return;
907

    
908
	/* start pptpd */
909
	vpn_pptpd_configure();
910

    
911
	/* start pppoe server */
912
	vpn_pppoes_configure();
913

    
914
	/* setup l2tp */
915
	vpn_l2tp_configure();
916
}
917

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

    
929
function vpn_pptpd_configure() {
930
	global $config, $g;
931

    
932
	$syscfg = $config['system'];
933
	$pptpdcfg = $config['pptpd'];
934

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

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

    
944
		/* wait for process to die */
945
		sleep(3);
946

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

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

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

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

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

    
976
			$mpdconf = <<<EOD
977
pptps:
978

    
979
EOD;
980

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

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

    
987
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
988

    
989
				$mpdconf .= <<<EOD
990

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

    
996
EOD;
997
			}
998

    
999
			$mpdconf .=<<<EOD
1000

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

    
1021
EOD;
1022

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

    
1028
EOD;
1029
			}
1030

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

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

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

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

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

    
1073
EOD;
1074

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

    
1080
EOD;
1081
				}
1082
			}
1083

    
1084
			fwrite($fd, $mpdconf);
1085
			fclose($fd);
1086
			unset($mpdconf);
1087

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

    
1095
			$mpdlinks = "";
1096

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

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

    
1106
EOD;
1107
			}
1108

    
1109
			fwrite($fd, $mpdlinks);
1110
			fclose($fd);
1111
			unset($mpdlinks);
1112

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

    
1120
			$mpdsecret = "";
1121

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

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

    
1135
			vpn_netgraph_support();
1136

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

    
1140
			break;
1141

    
1142
		case 'redir' :
1143
			break;
1144
	}
1145

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

    
1149
	return 0;
1150
}
1151

    
1152
function vpn_pppoes_configure() {
1153
	global $config;
1154

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

    
1161
function vpn_pppoe_configure(&$pppoecfg) {
1162
	global $config, $g;
1163

    
1164
	$syscfg = $config['system'];
1165

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

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

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

    
1179
		/* wait for process to die */
1180
		sleep(2);
1181

    
1182
	}
1183

    
1184
	switch ($pppoecfg['mode']) {
1185

    
1186
		case 'server' :
1187

    
1188
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1189

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

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

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

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

    
1210
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1211

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

    
1218
				$mpdconf .=<<<EOD
1219

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

    
1225
EOD;
1226
			}
1227

    
1228
			$mpdconf .=<<<EOD
1229

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

    
1256
EOD;
1257

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

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

    
1290
EOD;
1291

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

    
1296
EOD;
1297
				}
1298
			}
1299

    
1300
			fwrite($fd, $mpdconf);
1301
			fclose($fd);
1302
			unset($mpdconf);
1303

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

    
1311
			$mpdlinks = "";
1312

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

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

    
1323
EOD;
1324
			}
1325

    
1326
			fwrite($fd, $mpdlinks);
1327
			fclose($fd);
1328
			unset($mpdlinks);
1329

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

    
1338
				$mpdsecret = "\n\n";
1339

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

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

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

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

    
1363
			break;
1364
	}
1365

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

    
1369
	return 0;
1370
}
1371

    
1372
function vpn_l2tp_configure() {
1373
	global $config, $g;
1374

    
1375
	$syscfg = $config['system'];
1376
	$l2tpcfg = $config['l2tp'];
1377

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

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

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

    
1391
		/* wait for process to die */
1392
		sleep(8);
1393

    
1394
	}
1395

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

    
1400
	switch ($l2tpcfg['mode']) {
1401

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

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

    
1418
EOD;
1419

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

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

    
1426
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1427

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

    
1434
				$mpdconf .=<<<EOD
1435

    
1436
l2tp{$i}:
1437
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1438
	{$isssue_ip_type}
1439
	load l2tp_standard
1440

    
1441
EOD;
1442
			}
1443

    
1444
			$mpdconf .=<<<EOD
1445

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

    
1462
EOD;
1463

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

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

    
1493
EOD;
1494

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

    
1499
EOD;
1500
				}
1501
			}
1502

    
1503
			fwrite($fd, $mpdconf);
1504
			fclose($fd);
1505
			unset($mpdconf);
1506

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

    
1514
			$mpdlinks = "";
1515

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

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

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

    
1529
			fwrite($fd, $mpdlinks);
1530
			fclose($fd);
1531
			unset($mpdlinks);
1532

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

    
1540
			$mpdsecret = "\n\n";
1541

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

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

    
1552
			vpn_netgraph_support();
1553

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

    
1557
			break;
1558

    
1559
		case 'redir' :
1560
			break;
1561
	}
1562

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

    
1566
	return 0;
1567
}
1568

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

    
1577
?>
(58-58/67)