Projet

Général

Profil

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

univnautes / etc / inc / vpn.inc @ f9fb8d2b

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 = $ph1ent['remote-gateway'];
537
						//$rgip = $rgmap[$ph1ent['remote-gateway']];
538
						//if (!$rgip)
539
						//	continue;
540
					}
541

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

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

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

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

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

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

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

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

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

    
591
					$passive = "start";
592
					if (isset($ph1ent['mobile'])) {
593
						$rgip = "%any";
594
						$passive = "route";
595
					}
596

    
597
					$keyexchange = "ikev1";
598
					if (!empty($ph1ent['iketype']) && $ph1ent['iketype'] != "ikev1")
599
						$keyexchange = "ikev2";
600

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

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

    
614
						if ($keyexchange == "ikev1")
615
							$ealgosp1 .= "!";
616
					}
617

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

    
628
					if (!empty($ph1ent['authentication_method']) && (strstr($ph1ent['authentication_method'], "xauth") || strstr($ph1ent['authentication_method'], "hybrid")))
629
						$xauth = "xauth = server";
630

    
631

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

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

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

    
651
					if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
652
						continue;
653

    
654
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
655
						$tunneltype = "type = tunnel";
656

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

    
687
						if (!isset($ph2ent['mobile'])) {
688
							$remoteid_type = $ph2ent['remoteid']['type'];
689
							if ($remoteid_type != "address")
690
								$remoteid_type = "subnet";
691

    
692
							$remoteid_data = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
693
							$remoteid_spec = $remoteid_data;
694
						}
695

    
696
					} else {
697
						$tunneltype = "type = transport";
698
						//$rgip = $rgmap[$ph1ent['remote-gateway']];
699
						$rgip = $ph1ent['remote-gateway'];
700

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

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

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

    
793

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

    
797
					$ipsecconf .=<<<EOD
798

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

    
816
EOD;
817

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

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

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

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

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

    
874
	return count($filterdns_list);
875
}
876

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

    
886
	$ipseccfg = $config['ipsec'];
887

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

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

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

    
913
	if ($g['platform'] == 'jail')
914
		return;
915

    
916
	/* start pptpd */
917
	vpn_pptpd_configure();
918

    
919
	/* start pppoe server */
920
	vpn_pppoes_configure();
921

    
922
	/* setup l2tp */
923
	vpn_l2tp_configure();
924
}
925

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

    
937
function vpn_pptpd_configure() {
938
	global $config, $g;
939

    
940
	$syscfg = $config['system'];
941
	$pptpdcfg = $config['pptpd'];
942

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

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

    
952
		/* wait for process to die */
953
		sleep(3);
954

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

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

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

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

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

    
984
			$mpdconf = <<<EOD
985
pptps:
986

    
987
EOD;
988

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

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

    
995
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
996

    
997
				$mpdconf .= <<<EOD
998

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

    
1004
EOD;
1005
			}
1006

    
1007
			$mpdconf .=<<<EOD
1008

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

    
1029
EOD;
1030

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

    
1036
EOD;
1037
			}
1038

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

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

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

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

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

    
1081
EOD;
1082

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

    
1088
EOD;
1089
				}
1090
			}
1091

    
1092
			fwrite($fd, $mpdconf);
1093
			fclose($fd);
1094
			unset($mpdconf);
1095

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

    
1103
			$mpdlinks = "";
1104

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

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

    
1114
EOD;
1115
			}
1116

    
1117
			fwrite($fd, $mpdlinks);
1118
			fclose($fd);
1119
			unset($mpdlinks);
1120

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

    
1128
			$mpdsecret = "";
1129

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

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

    
1143
			vpn_netgraph_support();
1144

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

    
1148
			break;
1149

    
1150
		case 'redir' :
1151
			break;
1152
	}
1153

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

    
1157
	return 0;
1158
}
1159

    
1160
function vpn_pppoes_configure() {
1161
	global $config;
1162

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

    
1169
function vpn_pppoe_configure(&$pppoecfg) {
1170
	global $config, $g;
1171

    
1172
	$syscfg = $config['system'];
1173

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

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

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

    
1187
		/* wait for process to die */
1188
		sleep(2);
1189

    
1190
	}
1191

    
1192
	switch ($pppoecfg['mode']) {
1193

    
1194
		case 'server' :
1195

    
1196
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1197

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

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

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

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

    
1218
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1219

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

    
1226
				$mpdconf .=<<<EOD
1227

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

    
1233
EOD;
1234
			}
1235

    
1236
			$mpdconf .=<<<EOD
1237

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

    
1264
EOD;
1265

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

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

    
1298
EOD;
1299

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

    
1304
EOD;
1305
				}
1306
			}
1307

    
1308
			fwrite($fd, $mpdconf);
1309
			fclose($fd);
1310
			unset($mpdconf);
1311

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

    
1319
			$mpdlinks = "";
1320

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

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

    
1331
EOD;
1332
			}
1333

    
1334
			fwrite($fd, $mpdlinks);
1335
			fclose($fd);
1336
			unset($mpdlinks);
1337

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

    
1346
				$mpdsecret = "\n\n";
1347

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

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

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

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

    
1371
			break;
1372
	}
1373

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

    
1377
	return 0;
1378
}
1379

    
1380
function vpn_l2tp_configure() {
1381
	global $config, $g;
1382

    
1383
	$syscfg = $config['system'];
1384
	$l2tpcfg = $config['l2tp'];
1385

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

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

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

    
1399
		/* wait for process to die */
1400
		sleep(8);
1401

    
1402
	}
1403

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

    
1408
	switch ($l2tpcfg['mode']) {
1409

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

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

    
1426
EOD;
1427

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

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

    
1434
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1435

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

    
1442
				$mpdconf .=<<<EOD
1443

    
1444
l2tp{$i}:
1445
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1446
	{$isssue_ip_type}
1447
	load l2tp_standard
1448

    
1449
EOD;
1450
			}
1451

    
1452
			$mpdconf .=<<<EOD
1453

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

    
1470
EOD;
1471

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

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

    
1501
EOD;
1502

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

    
1507
EOD;
1508
				}
1509
			}
1510

    
1511
			fwrite($fd, $mpdconf);
1512
			fclose($fd);
1513
			unset($mpdconf);
1514

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

    
1522
			$mpdlinks = "";
1523

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

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

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

    
1537
			fwrite($fd, $mpdlinks);
1538
			fclose($fd);
1539
			unset($mpdlinks);
1540

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

    
1548
			$mpdsecret = "\n\n";
1549

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

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

    
1560
			vpn_netgraph_support();
1561

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

    
1565
			break;
1566

    
1567
		case 'redir' :
1568
			break;
1569
	}
1570

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

    
1574
	return 0;
1575
}
1576

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

    
1585
?>
(58-58/67)