Project

General

Profile

Download (57.7 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	vpn.inc
4

    
5
	part of pfSense (https://www.pfsense.org)
6
	Copyright (C) 2008 Shrew Soft Inc
7
	Copyright (c) 2004-2016 Electric Sheep Fencing, LLC.
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
22
	   the documentation and/or other materials provided with the
23
	   distribution.
24

    
25
	3. All advertising materials mentioning features or use of this software
26
	   must display the following acknowledgment:
27
	   "This product includes software developed by the pfSense Project
28
	   for use in the pfSense® software distribution. (http://www.pfsense.org/).
29

    
30
	4. The names "pfSense" and "pfSense Project" must not be used to
31
	   endorse or promote products derived from this software without
32
	   prior written permission. For written permission, please contact
33
	   coreteam@pfsense.org.
34

    
35
	5. Products derived from this software may not be called "pfSense"
36
	   nor may "pfSense" appear in their names without prior written
37
	   permission of the Electric Sheep Fencing, LLC.
38

    
39
	6. Redistributions of any form whatsoever must retain the following
40
	   acknowledgment:
41

    
42
	"This product includes software developed by the pfSense Project
43
	for use in the pfSense software distribution (http://www.pfsense.org/).
44

    
45
	THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
46
	EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47
	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
48
	PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
49
	ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50
	SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
51
	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52
	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53
	HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
54
	STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
55
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
56
	OF THE POSSIBILITY OF SUCH DAMAGE.
57
*/
58

    
59
require_once("ipsec.inc");
60
require_once("filter.inc");
61

    
62
function vpn_update_daemon_loglevel($category, $level) {
63
	global $ipsec_log_cats, $ipsec_log_sevs;
64

    
65
	if (in_array($category, array_keys($ipsec_log_cats), true) && in_array(intval($level), array_keys($ipsec_log_sevs), true)) {
66

    
67
		/* if you're setting to -1, need to add "--" to args */
68
		$argterm = "";
69
		if ($level == "-1") {
70
			$argterm = "--";
71
		}
72

    
73
		mwexec("/usr/local/sbin/ipsec stroke loglevel {$category} {$argterm} {$level}");
74
	}
75
}
76

    
77
function vpn_logging_cfgtxt() {
78
	global $config, $ipsec_log_cats, $ipsec_log_sevs;
79

    
80
	$cfgtext = array();
81
	foreach (array_keys($ipsec_log_cats) as $cat) {
82
		if (is_numeric($config['ipsec']['logging'][$cat]) &&
83
		    in_array(intval($config['ipsec']['logging'][$cat]), array_keys($ipsec_log_sevs), true)) {
84
			$cfgtext[] = "${cat} = {$config['ipsec']['logging'][$cat]}";
85
		}
86
	}
87

    
88
	return $cfgtext;
89
}
90

    
91
/* include all configuration functions */
92
function vpn_ipsec_convert_to_modp($index) {
93

    
94
	$convertion = "";
95
	switch ($index) {
96
		case '1':
97
			$convertion = "modp768";
98
			break;
99
		case '2':
100
			$convertion = "modp1024";
101
			break;
102
		case '5':
103
			$convertion = "modp1536";
104
			break;
105
		case '14':
106
			$convertion = "modp2048";
107
			break;
108
		case '15':
109
			$convertion = "modp3072";
110
			break;
111
		case '16':
112
			$convertion = "modp4096";
113
			break;
114
		case '17':
115
			$convertion = "modp6144";
116
			break;
117
		case '18':
118
			$convertion = "modp8192";
119
			break;
120
		case '19':
121
			$convertion = "ecp256";
122
			break;
123
		case '20':
124
			$convertion = "ecp384";
125
			break;
126
		case '21':
127
			$convertion = "ecp521";
128
			break;
129
		case '22':
130
			$convertion = "modp1024s160";
131
			break;
132
		case '23':
133
			$convertion = "modp2048s224";
134
			break;
135
		case '24':
136
			$convertion = "modp2048s256";
137
			break;
138
		case '28':
139
			$convertion = "ecp256bp";
140
			break;
141
		case '29':
142
			$convertion = "ecp384bp";
143
			break;
144
		case '30':
145
			$convertion = "ecp512bp";
146
			break;
147
	}
148

    
149
	return $convertion;
150
}
151

    
152
function vpn_ipsec_configure($restart = false) {
153
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos, $ipsec_idhandling;
154

    
155
	/* get the automatic ping_hosts.sh ready */
156
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
157
	touch("{$g['vardb_path']}/ipsecpinghosts");
158
	$ipsecpinghostsactive = false;
159

    
160
	/* service may have been enabled, disabled, or otherwise changed in a way requiring rule updates */
161
	filter_configure();
162

    
163
	$syscfg = $config['system'];
164
	$ipseccfg = $config['ipsec'];
165
	if (!ipsec_enabled()) {
166
		/* try to stop charon */
167
		mwexec("/usr/local/sbin/ipsec stop");
168
		/* Stop dynamic monitoring */
169
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
170

    
171
		/* wait for process to die */
172
		sleep(2);
173

    
174
		/* IPSEC is off, shutdown enc interface.*/
175
		mwexec("/sbin/ifconfig enc0 down");
176

    
177
		return 0;
178
	}
179

    
180
	$a_phase1 = $config['ipsec']['phase1'];
181
	$a_phase2 = $config['ipsec']['phase2'];
182
	$a_client = $config['ipsec']['client'];
183

    
184
	$certpath = "{$g['varetc_path']}/ipsec/ipsec.d/certs";
185
	$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts";
186
	$keypath = "{$g['varetc_path']}/ipsec/ipsec.d/private";
187
	$crlpath = "{$g['varetc_path']}/ipsec/ipsec.d/crls";
188

    
189
	mwexec("/sbin/ifconfig enc0 up");
190
	if (php_uname('m') != "amd64") {
191
		set_single_sysctl("net.inet.ipsec.directdispatch", "0");
192
	}
193

    
194
	/* needed for config files */
195
	if (!is_dir("{$g['varetc_path']}/ipsec")) {
196
		mkdir("{$g['varetc_path']}/ipsec");
197
	}
198
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d")) {
199
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d");
200
	}
201
	// delete these paths first to ensure old CAs, certs and CRLs aren't left behind. redmine #5238
202
	rmdir_recursive($capath);
203
	rmdir_recursive($keypath);
204
	rmdir_recursive($crlpath);
205
	rmdir_recursive($certpath);
206
	if (!is_dir($capath)) {
207
		mkdir($capath);
208
	}
209
	if (!is_dir($keypath)) {
210
		mkdir($keypath);
211
	}
212
	if (!is_dir($crlpath)) {
213
		mkdir($crlpath);
214
	}
215
	if (!is_dir($certpath)) {
216
		mkdir($certpath);
217
	}
218
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts")) {
219
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts");
220
	}
221
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/acerts")) {
222
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/acerts");
223
	}
224
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts")) {
225
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts");
226
	}
227
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/reqs")) {
228
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/reqs");
229
	}
230

    
231
	if (!file_exists("/usr/local/etc/ipsec.d") ||
232
	    !is_link("/usr/local/etc/ipsec.d")) {
233
		conf_mount_rw();
234
		if (file_exists("/usr/local/etc/ipsec.d")) {
235
			rmdir_recursive("/usr/local/etc/ipsec.d");
236
		}
237
		@symlink("{$g['varetc_path']}/ipsec/ipsec.d",
238
		    "/usr/local/etc/ipsec.d");
239
		conf_mount_ro();
240
	}
241
	if (!file_exists("{$g['varetc_path']}/etc/strongswan.d") ||
242
	    !is_link("{$g['varetc_path']}/etc/strongswan.d")) {
243
		conf_mount_rw();
244
		if (is_link("{$g['varetc_path']}/etc/strongswan.d")) {
245
			@unlink("{$g['varetc_path']}/etc/strongswan.d");
246
		} else {
247
			rmdir_recursive("{$g['varetc_path']}/etc/strongswan.d");
248
		}
249
		@symlink("/usr/local/etc/strongswan.d",
250
		    "{$g['varetc_path']}/ipsec/strongswan.d");
251
		conf_mount_ro();
252
	}
253
	if (!file_exists("/usr/local/etc/strongswan.conf") ||
254
	    !is_link("/usr/local/etc/strongswan.conf")) {
255
		conf_mount_rw();
256
		@unlink("/usr/local/etc/strongswan.conf");
257
		@symlink("{$g['varetc_path']}/ipsec/strongswan.conf",
258
		    "/usr/local/etc/strongswan.conf");
259
		conf_mount_ro();
260
	}
261
	if (!file_exists("/usr/local/etc/ipsec.conf") ||
262
	    !is_link("/usr/local/etc/ipsec.conf")) {
263
		conf_mount_rw();
264
		@unlink("/usr/local/etc/ipsec.conf");
265
		@symlink("{$g['varetc_path']}/ipsec/ipsec.conf",
266
		    "/usr/local/etc/ipsec.conf");
267
		conf_mount_ro();
268
	}
269

    
270
	if (platform_booting()) {
271
		echo gettext("Configuring IPsec VPN... ");
272
	}
273

    
274
	/* resolve all local, peer addresses and setup pings */
275
	$ipmap = array();
276
	$rgmap = array();
277
	$filterdns_list = array();
278
	$listeniflist = array();
279
	$aggressive_mode_psk = false;
280
	unset($iflist);
281
	$ifacesuse = array();
282
	$mobile_ipsec_auth = "";
283
	if (is_array($a_phase1) && count($a_phase1)) {
284

    
285
		$ipsecpinghosts = "";
286
		/* step through each phase1 entry */
287
		foreach ($a_phase1 as $ph1ent) {
288
			if (isset($ph1ent['disabled'])) {
289
				continue;
290
			}
291

    
292
			if (strpos($ph1ent['interface'], '_vip')) {
293
				$vpninterface = explode('_vip', $ph1ent['interface']);
294
				$ifacesuse[] = get_real_interface($vpninterface[0]);
295
			} else {
296
				$vpninterface = get_failover_interface($ph1ent['interface']);
297
				if (strpos($vpninterface, '_vip')) {
298
					$vpninterface = explode('_vip', $vpninterface);
299
					$ifacesuse[] = get_real_interface($vpninterface[0]);
300
				} elseif (!empty($vpninterface)) {
301
					$ifacesuse[] = $vpninterface;
302
				}
303
			}
304

    
305
			if ($ph1ent['mode'] == "aggressive" && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
306
				$aggressive_mode_psk = true;
307
			}
308

    
309
			$ikeid = $ph1ent['ikeid'];
310
			$listeniflist = get_real_interface($a_phase1['interface']);
311

    
312
			$ep = ipsec_get_phase1_src($ph1ent);
313
			if (!is_ipaddr($ep)) {
314
				log_error("IPsec ERROR: Could not find phase 1 source for connection {$ph1ent['descr']}. Omitting from configuration file.");
315
				continue;
316
			}
317

    
318
			if (!in_array($ep, $ipmap)) {
319
				$ipmap[] = $ep;
320
			}
321

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

    
325
			if (isset ($ph1ent['mobile'])) {
326
				$mobile_ipsec_auth = $ph1ent['authentication_method'];
327
				continue;
328
			}
329

    
330
			$rg = $ph1ent['remote-gateway'];
331

    
332
			if (!is_ipaddr($rg)) {
333
				$filterdns_list[] = "{$rg}";
334
				add_hostname_to_watch($rg);
335
				if (!platform_booting()) {
336
					$rg = resolve_retry($rg);
337
				}
338
				if (!is_ipaddr($rg)) {
339
					continue;
340
				}
341
			}
342
			if (array_search($rg, $rgmap)) {
343
				log_error("The remote gateway {$rg} already exists on another phase 1 entry");
344
				continue;
345
			}
346
			$rgmap[$ph1ent['remote-gateway']] = $rg;
347

    
348
			if (is_array($a_phase2)) {
349
				/* step through each phase2 entry */
350
				foreach ($a_phase2 as $ph2ent) {
351
					if (isset($ph2ent['disabled'])) {
352
						continue;
353
					}
354

    
355
					if ($ikeid != $ph2ent['ikeid']) {
356
						continue;
357
					}
358

    
359
					/* add an ipsec pinghosts entry */
360
					if ($ph2ent['pinghost']) {
361
						if (!is_array($iflist)) {
362
							$iflist = get_configured_interface_list();
363
						}
364
						$srcip = null;
365
						$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
366
						if (is_ipaddrv6($ph2ent['pinghost'])) {
367
							foreach ($iflist as $ifent => $ifname) {
368
								$interface_ip = get_interface_ipv6($ifent);
369
								if (!is_ipaddrv6($interface_ip)) {
370
									continue;
371
								}
372
								if (ip_in_subnet($interface_ip, $local_subnet)) {
373
									$srcip = $interface_ip;
374
									break;
375
								}
376
							}
377
						} else {
378
							foreach ($iflist as $ifent => $ifname) {
379
								$interface_ip = get_interface_ip($ifent);
380
								if (!is_ipaddrv4($interface_ip)) {
381
									continue;
382
								}
383
								if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) {
384
									$srcip = $interface_ip;
385
									break;
386
								}
387
							}
388
						}
389
						/* if no valid src IP was found in configured interfaces, try the vips */
390
						if (is_null($srcip)) {
391
							$viplist = get_configured_vips_list();
392
							foreach ($viplist as $vip) {
393
								if (ip_in_subnet($vip['ipaddr'], $local_subnet)) {
394
									$srcip = $vip['ipaddr'];
395
									break;
396
								}
397
							}
398
						}
399
						$dstip = $ph2ent['pinghost'];
400
						if (is_ipaddrv6($dstip)) {
401
							$family = "inet6";
402
						} else {
403
							$family = "inet";
404
						}
405
						if (is_ipaddr($srcip)) {
406
							$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
407
							$ipsecpinghostsactive = true;
408
						}
409
					}
410
				}
411
			}
412
		}
413
		@file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
414
		unset($ipsecpinghosts);
415
	}
416
	unset($iflist);
417

    
418
	$accept_unencrypted = "";
419
	if (isset($config['ipsec']['acceptunencryptedmainmode'])) {
420
		$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
421
	}
422

    
423
	$stronconf = '';
424
	if (file_exists("{$g['varetc_path']}/ipsec/strongswan.conf")) {
425
		$stronconf = file_get_contents("{$g['varetc_path']}/ipsec/strongswan.conf");
426
	}
427

    
428
	$i_dont_care_about_security_and_use_aggressive_mode_psk = "";
429
	if ($aggressive_mode_psk) {
430
		log_error("WARNING: Setting i_dont_care_about_security_and_use_aggressive_mode_psk option because a phase 1 is configured using aggressive mode with pre-shared keys. This is not a secure configuration.");
431
		if (!empty($stronconf) && strpos($stronconf, 'i_dont_care_about_security_and_use_aggressive_mode_psk') === FALSE) {
432
			$restart = true;
433
		}
434
		$i_dont_care_about_security_and_use_aggressive_mode_psk = "i_dont_care_about_security_and_use_aggressive_mode_psk=yes";
435
	}
436

    
437
	$unity_enabled = isset($config['ipsec']['unityplugin']) ? 'yes' : 'no';
438

    
439
	$makebeforebreak = '';
440
	if (isset($config['ipsec']['makebeforebreak'])) {
441
		$makebeforebreak = 'make_before_break = yes';
442
	}
443

    
444
	if (isset($config['ipsec']['enableinterfacesuse'])) {
445
		if (!empty($ifacesuse)) {
446
			$ifacesuse = 'interfaces_use = ' . implode(',', array_unique($ifacesuse));
447
		} else {
448
			$ifacesuse = '';
449
		}
450
	} else {
451
		$ifacesuse = '';
452
	}
453

    
454
	unset($stronconf);
455

    
456
	$strongswanlog = "";
457
	$ipsecloglevels = vpn_logging_cfgtxt();
458
	if (is_array($ipsecloglevels)) {
459
		foreach ($ipsecloglevels as $loglevel) {
460
			$strongswanlog .= "\t\t\t" . $loglevel . "\n";
461
		}
462
	}
463
	$strongswan = <<<EOD
464

    
465
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten.
466
starter {
467
	load_warning = no
468
	config_file = {$g['varetc_path']}/ipsec/ipsec.conf
469
}
470

    
471
charon {
472
# number of worker threads in charon
473
	threads = 16
474
	ikesa_table_size = 32
475
	ikesa_table_segments = 4
476
	init_limit_half_open = 1000
477
	install_routes = no
478
	load_modular = yes
479
	{$i_dont_care_about_security_and_use_aggressive_mode_psk}
480
	{$accept_unencrypted}
481
	cisco_unity = {$unity_enabled}
482
	{$ifacesuse}
483
	{$makebeforebreak}
484

    
485
	syslog {
486
		identifier = charon
487
		# log everything under daemon since it ends up in the same place regardless with our syslog.conf
488
		daemon {
489
			ike_name = yes
490
{$strongswanlog}
491
		}
492
		# disable logging under auth so logs aren't duplicated
493
		auth {
494
			default = -1
495
		}
496
	}
497

    
498
	plugins {
499
		# Load defaults
500
		include {$g['varetc_path']}/ipsec/strongswan.d/charon/*.conf
501

    
502
		stroke {
503
			secrets_file = {$g['varetc_path']}/ipsec/ipsec.secrets
504
		}
505

    
506
		unity {
507
			load = {$unity_enabled}
508
		}
509

    
510
EOD;
511

    
512
	/* Find RADIUS servers designated for Mobile IPsec user auth */
513
	$radius_server_txt = "";
514
	$user_sources = explode(',', $config['ipsec']['client']['user_source']);
515
	foreach ($user_sources as $user_source) {
516
		$auth_server = auth_get_authserver($user_source);
517
		$nice_user_source = strtolower(preg_replace('/\s+/', '_', $user_source));
518
		if ($auth_server && $auth_server['type'] === 'radius') {
519
			$radius_server_txt .= <<<EOD
520
				{$nice_user_source} {
521
					address = {$auth_server['host']}
522
					secret = "{$auth_server['radius_secret']}"
523
					auth_port = {$auth_server['radius_auth_port']}
524
					acct_port = {$auth_server['radius_acct_port']}
525
				}
526

    
527
EOD;
528
		}
529
	}
530

    
531
	/* write an eap-radius config section if appropriate */
532
	if (strlen($radius_server_txt) && ($mobile_ipsec_auth === "eap-radius")) {
533
		$strongswan .= <<<EOD
534
		eap-radius {
535
			class_group = yes
536
			eap_start = no
537
			servers {
538
{$radius_server_txt}
539
			}
540
		}
541

    
542
EOD;
543
	}
544

    
545
	if (is_array($a_client) && isset($a_client['enable'])) {
546
		$strongswan .= "\t\tattr {\n";
547

    
548
		$cfgservers = array();
549
		if (!empty($a_client['dns_server1'])) {
550
			$cfgservers[] = $a_client['dns_server1'];
551
		}
552
		if (!empty($a_client['dns_server2'])) {
553
			$cfgservers[] = $a_client['dns_server2'];
554
		}
555
		if (!empty($a_client['dns_server3'])) {
556
			$cfgservers[] = $a_client['dns_server3'];
557
		}
558
		if (!empty($a_client['dns_server4'])) {
559
			$cfgservers[] = $a_client['dns_server4'];
560
		}
561

    
562
		if (!empty($cfgservers)) {
563
			$strongswan .= "\t\t\tdns = " . implode(",", $cfgservers) . "\n";
564
		}
565
		unset($cfgservers);
566
		$cfgservers = array();
567
		if (!empty($a_client['wins_server1'])) {
568
			$cfgservers[] = $a_client['wins_server1'];
569
		}
570
		if (!empty($a_client['wins_server2'])) {
571
			$cfgservers[] = $a_client['wins_server2'];
572
		}
573
		if (!empty($cfgservers)) {
574
			$strongswan .= "\t\t\tnbns = " . implode(",", $cfgservers) . "\n";
575
		}
576
		unset($cfgservers);
577

    
578
		if (isset($a_client['net_list']) && is_array($a_phase2)) {
579
			$net_list = '';
580
			foreach ($a_phase2 as $ph2ent) {
581
				if (isset($ph2ent['disabled'])) {
582
					continue;
583
				}
584

    
585
				if (!isset($ph2ent['mobile'])) {
586
					continue;
587
				}
588

    
589
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
590

    
591
				if (!empty($net_list)) {
592
					$net_list .= ",";
593
				}
594
				$net_list .= $localid;
595
			}
596

    
597
			if (!empty($net_list)) {
598
				$strongswan .= "\t\t\tsubnet = {$net_list}\n";
599
				$strongswan .= "\t\t\tsplit-include = {$net_list}\n";
600
				unset($net_list);
601
			}
602
		}
603

    
604
		if (!empty($a_client['dns_domain'])) {
605
			$strongswan .= "\t\t\t# Search domain and default domain\n";
606
			$strongswan .= "\t\t\t28674 = \"{$a_client['dns_domain']}\"\n";
607
			if (empty($a_client['dns_split'])) {
608
				$strongswan .= "\t\t\t28675 = \"{$a_client['dns_domain']}\"";
609
			}
610
			$strongswan .= "\n";
611
		}
612

    
613
		if (!empty($a_client['dns_split'])) {
614
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
615
		}
616

    
617
		if (!empty($a_client['login_banner'])) {
618
			$strongswan .= "\t\t\t28672 = \"{$a_client['login_banner']}\"\n";
619
		}
620

    
621
		if (isset($a_client['save_passwd'])) {
622
			$strongswan .= "\t\t\t28673 = 1\n";
623
		}
624

    
625
		if ($a_client['pfs_group']) {
626
			$strongswan .= "\t\t\t28679 = \"{$a_client['pfs_group']}\"\n";
627
		}
628
		$strongswan .= "\t\t}\n";
629

    
630
		if ($a_client['user_source'] != "none") {
631
			$strongswan .= "\t\txauth-generic {\n";
632
			$strongswan .= "\t\t\tscript = /etc/inc/ipsec.auth-user.php\n";
633
			$strongswan .= "\t\t\tauthcfg = ";
634
			$firstsed = 0;
635
			$authcfgs = explode(",", $a_client['user_source']);
636
			foreach ($authcfgs as $authcfg) {
637
				if ($firstsed > 0) {
638
					$strongswan .= ",";
639
				}
640
				if ($authcfg == "system") {
641
					$authcfg = "Local Database";
642
				}
643
				$strongswan .= $authcfg;
644
				$firstsed = 1;
645
			}
646
			$strongswan .= "\n";
647
			$strongswan .= "\t\t}\n";
648
		}
649
	}
650

    
651
	$strongswan .= "\n\t}\n}\n";
652
	@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
653
	unset($strongswan);
654

    
655
	/* write out CRL files */
656
	if (is_array($config['crl']) && count($config['crl'])) {
657
		foreach ($config['crl'] as $crl) {
658
			if (!isset($crl['text'])) {
659
				log_error(sprintf(gettext("Warning: Missing CRL data for %s"), $crl['descr']));
660
				continue;
661
			}
662
			$fpath = "{$crlpath}/{$crl['refid']}.crl";
663
			if (!@file_put_contents($fpath, base64_decode($crl['text']))) {
664
				log_error(sprintf(gettext("Error: Cannot write IPsec CRL file for %s"), $crl['descr']));
665
				continue;
666
			}
667
		}
668
	}
669

    
670
	$pskconf = "";
671

    
672
	$vpncas = array();
673
	if (is_array($a_phase1) && count($a_phase1)) {
674
		foreach ($a_phase1 as $ph1ent) {
675

    
676
			if (isset($ph1ent['disabled'])) {
677
				continue;
678
			}
679

    
680
			if (strstr($ph1ent['authentication_method'], 'rsa') ||
681
			    in_array($ph1ent['authentication_method'], array('eap-mschapv2', 'eap-tls', 'eap-radius'))) {
682
				$certline = '';
683

    
684
				$ikeid = $ph1ent['ikeid'];
685
				$cert = lookup_cert($ph1ent['certref']);
686

    
687
				if (!$cert) {
688
					log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
689
					continue;
690
				}
691

    
692
				/* add signing CA cert chain of server cert
693
				 * to the list of CAs to write
694
				 */
695
				$cachain = ca_chain_array($cert);
696
				if ($cachain && is_array($cachain)) {
697
					foreach ($cachain as $cacrt) {
698
						$vpncas[$cacrt['refid']] = $cacrt;
699
					}
700
				}
701

    
702
				@chmod($certpath, 0600);
703

    
704
				$ph1keyfile = "{$keypath}/cert-{$ikeid}.key";
705
				if (!file_put_contents($ph1keyfile, base64_decode($cert['prv']))) {
706
					log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
707
					continue;
708
				}
709
				@chmod($ph1keyfile, 0600);
710

    
711
				$ph1certfile = "{$certpath}/cert-{$ikeid}.crt";
712
				if (!file_put_contents($ph1certfile, base64_decode($cert['crt']))) {
713
					log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name']));
714
					@unlink($ph1keyfile);
715
					continue;
716
				}
717
				@chmod($ph1certfile, 0600);
718

    
719
				/* XXX" Traffic selectors? */
720
				$pskconf .= " : RSA {$ph1keyfile}\n";
721
			} else {
722
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
723
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
724

    
725
				$myid = trim($myid_data);
726

    
727
				if (empty($peerid_data)) {
728
					continue;
729
				}
730

    
731
				if ($myid_type == 'fqdn' && !empty($myid)) {
732
					$myid = "@{$myid}";
733
				}
734

    
735
				$myid = isset($ph1ent['mobile']) ? trim($myid_data) : "%any";
736

    
737
				$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
738

    
739
				if ($peerid_type == 'fqdn' && !empty($peerid)) {
740
					$peerid = "@{$peerid}";
741
				}
742

    
743
				if (!empty($ph1ent['pre-shared-key'])) {
744
					$pskconf .= "{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
745
					if (isset($ph1ent['mobile'])) {
746
						$pskconf .= " : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
747
					}
748
				}
749
			}
750

    
751
			/* if the client authenticates with a cert add the
752
			 * client cert CA chain to the list of CAs to write
753
			 */
754
			if (in_array($ph1ent['authentication_method'],
755
			array('rsasig', 'eap-tls', 'xauth_rsa_server'))) {
756

    
757
				if (!empty($ph1ent['caref']) && !array_key_exists($ph1ent['caref'], $vpncas)) {
758
					$thisca = lookup_ca($ph1ent['caref']);
759
					$vpncas[$ph1ent['caref']] = $thisca;
760

    
761
					/* follow chain up to root */
762
					$cachain = ca_chain_array($thisca);
763
					if ($cachain and is_array($cachain)) {
764
						foreach ($cachain as $cacrt) {
765
							$vpncas[$cacrt['refid']] = $cacrt;
766
						}
767
					}
768
				}
769
			}
770
		}
771
	}
772

    
773
	/* write the required CAs */
774
	foreach ($vpncas as $carefid => $cadata) {
775
		$cacrt = base64_decode($cadata['crt']);
776
		$cacrtattrs = openssl_x509_parse($cacrt);
777
		if (!is_array($cacrtattrs) || !isset($cacrtattrs['hash'])) {
778
			log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $cadata['descr']));
779
			continue;
780
		}
781
		$cafilename = "{$capath}/{$cacrtattrs['hash']}.0.crt";
782
		if (!@file_put_contents($cafilename, $cacrt)) {
783
				log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $cadata['descr']));
784
				continue;
785
		}
786
	}
787

    
788
	/* Add user PSKs */
789
	if (is_array($config['system']) && is_array($config['system']['user'])) {
790
		foreach ($config['system']['user'] as $user) {
791
			if (!empty($user['ipsecpsk'])) {
792
				$pskconf .= "{$myid} {$user['name']} : PSK 0s" . base64_encode($user['ipsecpsk']) . "\n";
793
			}
794
		}
795
		unset($user);
796
	}
797

    
798
	/* add PSKs for mobile clients */
799
	if (is_array($ipseccfg['mobilekey'])) {
800
		foreach ($ipseccfg['mobilekey'] as $key) {
801
			if ($key['ident'] == "allusers") {
802
				$key['ident'] = '%any';
803
			}
804
			if ($key['ident'] == "any") {
805
				$key['ident'] = '%any';
806
			}
807
			if (empty($key['type'])) {
808
				$key['type'] = 'PSK';
809
			}
810
			$pskconf .= "{$myid} {$key['ident']} : {$key['type']} 0s" . base64_encode($key['pre-shared-key']) . "\n";
811
		}
812
		unset($key);
813
	}
814

    
815
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
816
	chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
817
	unset($pskconf);
818

    
819
	$uniqueids = 'yes';
820
	if (!empty($config['ipsec']['uniqueids'])) {
821
		if (array_key_exists($config['ipsec']['uniqueids'], $ipsec_idhandling)) {
822
			$uniqueids = $config['ipsec']['uniqueids'];
823
		}
824
	}
825
	$natfilterrules = false;
826
	/* begin ipsec.conf */
827
	$ipsecconf = "";
828
	$enablecompression = false;
829
	if (is_array($a_phase1) && count($a_phase1)) {
830

    
831
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
832
		$ipsecconf .= "config setup\n\tuniqueids = {$uniqueids}\n";
833

    
834
		if (isset($config['ipsec']['strictcrlpolicy'])) {
835
			$ipsecconf .= "\tstrictcrlpolicy = yes \n";
836
		}
837

    
838
		if (!isset($config['ipsec']['noshuntlaninterfaces'])) {
839
			if ($config['interfaces']['lan']) {
840
				$lanip = get_interface_ip("lan");
841
				if (!empty($lanip) && is_ipaddrv4($lanip)) {
842
					$lansn = get_interface_subnet("lan");
843
					$lansa = gen_subnet($lanip, $lansn);
844
					$ipsecconf .= <<<EOD
845

    
846
conn bypasslan
847
	leftsubnet = {$lansa}/{$lansn}
848
	rightsubnet = {$lansa}/{$lansn}
849
	authby = never
850
	type = passthrough
851
	auto = route
852

    
853
EOD;
854
				}
855
			}
856
		}
857

    
858
		foreach ($a_phase1 as $ph1ent) {
859
			if (isset($ph1ent['disabled'])) {
860
				continue;
861
			}
862

    
863
			if ($ph1ent['mode'] == "aggressive") {
864
				$aggressive = "yes";
865
			} else {
866
				$aggressive = "no";
867
			}
868

    
869
			$ep = ipsec_get_phase1_src($ph1ent);
870
			if (!$ep) {
871
				continue;
872
			}
873

    
874
			$ikeid = $ph1ent['ikeid'];
875
			$keyexchange = "ikev1";
876
			$passive = "route";
877
			if (!empty($ph1ent['iketype'])) {
878
				if ($ph1ent['iketype'] == "ikev2") {
879
					$keyexchange = "ikev2";
880
					//$passive = "start";
881
				}
882
			}
883

    
884
			if (isset($ph1ent['mobile'])) {
885
				$right_spec = "%any";
886
				$passive = 'add';
887
			} else {
888
				if (isset($ph1ent['responderonly'])) {
889
					$passive = 'add';
890
				}
891

    
892
				$right_spec = $ph1ent['remote-gateway'];
893
				if (is_ipaddr($right_spec)) {
894
					$sourcehost = $right_spec;
895
				} else {
896
					$sourcehost = $rgmap['remote-gateway'];
897
				}
898

    
899
				if ($ph1ent['protocol'] == 'inet') {
900
					if (strpos($ph1ent['interface'], '_vip')) {
901
						$vpninterface = explode('_vip', $ph1ent['interface']);
902
						$ifacesuse = get_real_interface($vpninterface[0]);
903
						$vpninterface = $vpninterface[0];
904
					} else {
905
						$ifacesuse = get_failover_interface($ph1ent['interface']);
906
						if (strpos($ifacesuse, '_vip')) {
907
							$vpninterface = explode('_vip', $ifacesuse);
908
							$ifacesuse = get_real_interface($vpninterface[0]);
909
							$vpninterface = $vpninterface[0];
910
						} else {
911
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
912
						}
913
					}
914

    
915
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
916
						$gatewayip = get_interface_gateway($vpninterface);
917
						$interfaceip = get_interface_ip($vpninterface);
918
						$subnet_bits = get_interface_subnet($vpninterface);
919
						$subnet_ip = gen_subnetv4($interfaceip, $subnet_bits);
920
						/* if the remote gateway is in the local subnet, then don't add a route */
921
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
922
							if (is_ipaddrv4($gatewayip)) {
923
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
924
								mwexec("/sbin/route change -host {$sourcehost} {$gatewayip}", true);
925
							}
926
						}
927
					}
928
				} else if ($ph1ent['protocol'] == 'inet6') {
929
					if (strpos($ph1ent['interface'], '_vip')) {
930
						$vpninterface = explode('_vip', $ph1ent['interface']);
931
						$ifacesuse = get_real_interface($vpninterface[0]);
932
						$vpninterface = $vpninterface[0];
933
					} else {
934
						$ifacesuse = get_failover_interface($ph1ent['interface']);
935
						if (strpos($ifacesuse, '_vip')) {
936
							$vpninterface = explode('_vip', $ifacesuse);
937
							$ifacesuse = get_real_interface($vpninterface[0]);
938
							$vpninterface = $vpninterface[0];
939
						} else {
940
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
941
						}
942
					}
943

    
944
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
945
						$gatewayip = get_interface_gateway_v6($vpninterface);
946
						$interfaceip = get_interface_ipv6($vpninterface);
947
						$subnet_bits = get_interface_subnetv6($vpninterface);
948
						$subnet_ip = gen_subnetv6($interfaceip, $subnet_bits);
949
						/* if the remote gateway is in the local subnet, then don't add a route */
950
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
951
							if (is_ipaddrv6($gatewayip)) {
952
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
953
								mwexec("/sbin/route change -inet6 -host {$sourcehost} {$gatewayip}", true);
954
							}
955
						}
956
					}
957
				}
958
			}
959

    
960
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
961
			if ($myid_type != 'address' && $myid_type != 'keyid' && $myid_type != 'asn1dn') {
962
				$myid_data = "{$myid_type}:{$myid_data}";
963
			} elseif ($myid_type == "asn1dn" && !empty($myid_data)) {
964
				if ($myid_data[0] == '#') {
965
				/* asn1dn needs double quotes */
966
					$myid_data = "\"{$myid_type}:{$myid_data}\"";
967
				} else {
968
					$myid_data = "\"{$myid_data}\"";
969
				}
970
			}
971
			$leftid = '';
972
			if (!empty($myid_data)) {
973
				$leftid = "leftid = {$myid_data}";
974
			}
975

    
976
			$peerid_spec = '';
977
			if (isset($ph1ent['mobile']) && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
978
				// Only specify peer ID if we are not dealing with mobile PSK
979
			} else {
980
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
981
				if ($peerid_type == 'any') {
982
					$peerid_spec = '';
983
				} elseif ($peerid_type != 'address' && $peerid_type != 'keyid' && $peerid_type != 'asn1dn') {
984
					$peerid_spec = "{$peerid_type}:{$peerid_data}";
985
				} elseif ($peerid_type == "asn1dn") {
986
					/* asn1dn needs double quotes */
987
					if ($peerid_data[0] == '#') {
988
						$peerid_spec = "\"{$peerid_type}:{$peerid_data}\"";
989
					} elseif (!empty($peerid_data)) {
990
						$peerid_spec = "\"{$peerid_data}\"";
991
					}
992
				} else {
993
					$peerid_spec = $peerid_data;
994
				}
995
			}
996

    
997
			if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
998
				$ealgosp1 = '';
999
				$ealg_id = $ph1ent['encryption-algorithm']['name'];
1000
				$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
1001
				if ($ealg_kl) {
1002
					$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
1003
				} else {
1004
					$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
1005
				}
1006

    
1007
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
1008
				if (!empty($modp)) {
1009
					$ealgosp1 .= "-{$modp}";
1010
				}
1011

    
1012
				$ealgosp1 .= "!";
1013
			}
1014

    
1015
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
1016
				if ($passive == "route") {
1017
					$dpdline = "dpdaction = restart";
1018
				} else {
1019
					$dpdline = "dpdaction = clear";
1020
				}
1021
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
1022
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
1023
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
1024
			} else {
1025
				$dpdline = "dpdaction = none";
1026
			}
1027

    
1028
			$ikelifeline = '';
1029
			if ($ph1ent['lifetime']) {
1030
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
1031
			}
1032

    
1033
			$rightsourceip = NULL;
1034
			if (isset($ph1ent['mobile'])) {
1035
				$rightsourceips = array();
1036
				if (!empty($a_client['pool_address'])) {
1037
					$rightsourceips[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1038
				}
1039
				if (!empty($a_client['pool_address_v6'])) {
1040
					$rightsourceips[] = "{$a_client['pool_address_v6']}/{$a_client['pool_netbits_v6']}";
1041
				}
1042
				if ($ph1ent['authentication_method'] == "eap-radius" && !count($rightsourceips)) {
1043
					$rightsourceips[] = "%radius";
1044
				}
1045
				if (count($rightsourceips)) {
1046
					$rightsourceip = "\trightsourceip = " . implode(',', $rightsourceips) . "\n";
1047
				}
1048
			}
1049

    
1050
			if (!empty($ph1ent['caref'])) {
1051
				$ca = lookup_ca($ph1ent['caref']);
1052
				if ($ca) {
1053
					$casubarr = cert_get_subject_array($ca['crt']);
1054
					$casub = "";
1055
					foreach ($casubarr as $casubfield) {
1056
						if (empty($casub)) {
1057
							$casub = "/";
1058
						}
1059
						$casub .= "{$casubfield['a']}={$casubfield['v']}/";
1060
					}
1061

    
1062
				}
1063
			}
1064

    
1065
			$authentication = "";
1066
			switch ($ph1ent['authentication_method']) {
1067
				case 'eap-mschapv2':
1068
					if (isset($ph1ent['mobile'])) {
1069
						$authentication = "eap_identity=%any\n\t";
1070
						$authentication .= "leftauth=pubkey\n\trightauth=eap-mschapv2";
1071
						if (!empty($ph1ent['certref'])) {
1072
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1073
							$authentication .= "\n\tleftsendcert=always";
1074
						}
1075
					}
1076
					break;
1077
				case 'eap-tls':
1078
					if (isset($ph1ent['mobile'])) {
1079
						$authentication = "eap_identity=%identity\n\t";
1080
						$authentication .= "leftauth=pubkey\n\trightauth=eap-tls";
1081
						if (!empty($ph1ent['certref'])) {
1082
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1083
							$authentication .= "\n\tleftsendcert=always";
1084
						}
1085
					} else {
1086
						$authentication = "leftauth=eap-tls\n\trightauth=eap-tls";
1087
						if (!empty($ph1ent['certref'])) {
1088
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1089
							$authentication .= "\n\tleftsendcert=always";
1090
						}
1091
					}
1092
					if (isset($casub)) {
1093
						$authentication .= "\n\trightca=\"$casub\"";
1094
					}
1095
					break;
1096
				case 'eap-radius':
1097
					if (isset($ph1ent['mobile'])) {
1098
						$authentication = "eap_identity=%identity\n\t";
1099
						$authentication .= "leftauth=pubkey\n\trightauth=eap-radius";
1100
						if (!empty($ph1ent['certref'])) {
1101
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1102
							$authentication .= "\n\tleftsendcert=always";
1103
						}
1104
					} else {
1105
						$authentication = "leftauth=eap-radius\n\trightauth=eap-radius";
1106
						if (!empty($ph1ent['certref'])) {
1107
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1108
							$authentication .= "\n\tleftsendcert=always";
1109
						}
1110
					}
1111
					break;
1112
				case 'xauth_rsa_server':
1113
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
1114
					$authentication .= "\n\trightauth2 = xauth-generic";
1115
					if (!empty($ph1ent['certref'])) {
1116
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1117
					}
1118
					if (isset($casub)) {
1119
						$authentication .= "\n\trightca=\"$casub\"";
1120
					}
1121
					break;
1122
				case 'xauth_psk_server':
1123
					$authentication = "leftauth = psk\n\trightauth = psk";
1124
					$authentication .= "\n\trightauth2 = xauth-generic";
1125
					break;
1126
				case 'pre_shared_key':
1127
					$authentication = "leftauth = psk\n\trightauth = psk";
1128
					break;
1129
				case 'rsasig':
1130
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
1131
					if (!empty($ph1ent['certref'])) {
1132
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1133
					}
1134
					if (isset($casub)) {
1135
						$authentication .= "\n\trightca=\"$casub\"";
1136
					}
1137
					break;
1138
				case 'hybrid_rsa_server':
1139
					$authentication = "leftauth = pubkey\n\trightauth = xauth-generic";
1140
					if (!empty($ph1ent['certref'])) {
1141
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1142
					}
1143
					break;
1144
			}
1145

    
1146
			$left_spec = $ep;
1147

    
1148
			if (isset($ph1ent['reauth_enable'])) {
1149
				$reauth = "reauth = no";
1150
			} else {
1151
				$reauth = "reauth = yes";
1152
			}
1153
			if (isset($ph1ent['rekey_enable'])) {
1154
				$rekey = "rekey = no";
1155
			} else {
1156
				$rekey = "rekey = yes";
1157
			}
1158

    
1159
			if ($ph1ent['nat_traversal'] == 'off') {
1160
				$forceencaps = 'forceencaps = no';
1161
			} else if ($ph1ent['nat_traversal'] == 'force') {
1162
				$forceencaps = 'forceencaps = yes';
1163
			} else {
1164
				$forceencaps = 'forceencaps = no';
1165
			}
1166

    
1167
			if ($ph1ent['mobike'] == 'on') {
1168
				$mobike = 'mobike = yes';
1169
			} else {
1170
				$mobike = 'mobike = no';
1171
			}
1172

    
1173
			$ipseclifetime = 0;
1174
			$rightsubnet_spec = array();
1175
			$leftsubnet_spec = array();
1176
			$reqids = array();
1177
			$ealgoAHsp2arr = array();
1178
			$ealgoESPsp2arr = array();
1179
		if (is_array($a_phase2) && count($a_phase2)) {
1180
			foreach ($a_phase2 as $ph2ent) {
1181
				if ($ikeid != $ph2ent['ikeid']) {
1182
					continue;
1183
				}
1184

    
1185
				if (isset($ph2ent['disabled'])) {
1186
					continue;
1187
				}
1188

    
1189
				if (isset($ph2ent['mobile']) && !isset($a_client['enable'])) {
1190
					continue;
1191
				}
1192

    
1193
				if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
1194
					$tunneltype = "type = tunnel";
1195

    
1196
					$localid_type = $ph2ent['localid']['type'];
1197
					$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
1198

    
1199
					/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
1200
					if (($localid_type == "none" || $localid_type == "mobile") &&
1201
					    isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ikeid) == 1)) {
1202
						$left_spec = '%any';
1203
					} else {
1204
						if ($localid_type != "address") {
1205
							$localid_type = "subnet";
1206
						}
1207
						// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
1208
						if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) {
1209
							log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
1210
							continue;
1211
						}
1212
						if (!empty($ph2ent['natlocalid'])) {
1213
							$natleftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
1214
							if ($ph2ent['natlocalid']['type'] != "address") {
1215
								if (is_subnet($natleftsubnet_data)) {
1216
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
1217
								}
1218
							} else {
1219
								if (is_ipaddr($natleftsubnet_data)) {
1220
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
1221
								}
1222
							}
1223
							$natfilterrules = true;
1224
						}
1225
					}
1226

    
1227
					$leftsubnet_spec[] = $leftsubnet_data;
1228

    
1229
					if (!isset($ph2ent['mobile'])) {
1230
						$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
1231
						$rightsubnet_spec[] = $tmpsubnet;
1232
					} else if (!empty($a_client['pool_address'])) {
1233
						$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1234
					}
1235
				} else {
1236
					$tunneltype = "type = transport";
1237

    
1238
					if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
1239
					     ($ph1ent['authentication_method'] == "pre_shared_key")) &&
1240
					    isset($ph1ent['mobile'])) {
1241
						$left_spec = "%any";
1242
					} else {
1243
						$tmpsubnet = ipsec_get_phase1_src($ph1ent);
1244
						$leftsubnet_spec[] = $tmpsubnet;
1245
					}
1246

    
1247
					if (!isset($ph2ent['mobile'])) {
1248
						$rightsubnet_spec[] = $right_spec;
1249
					}
1250
				}
1251

    
1252
				if (isset($a_client['pfs_group']) && isset($ph2ent['mobile'])) {
1253
					$ph2ent['pfsgroup'] = $a_client['pfs_group'];
1254
				}
1255

    
1256
				if ($ph2ent['protocol'] == 'esp') {
1257
					if (is_array($ph2ent['encryption-algorithm-option'])) {
1258
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
1259
							$ealg_id = $ealg['name'];
1260
							$ealg_kl = $ealg['keylen'];
1261

    
1262
							if (!empty($ealg_kl) && $ealg_kl == "auto") {
1263
								if (empty($p2_ealgos) || !is_array($p2_ealgos)) {
1264
									require("ipsec.inc");
1265
								}
1266
								$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
1267
								$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
1268
								$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
1269
								/* XXX: in some cases where include ordering is suspect these variables
1270
								 * are somehow 0 and we enter this loop forever and timeout after 900
1271
								 * seconds wrecking bootup */
1272
								if ($key_hi != 0 and $key_lo != 0 and $key_step != 0) {
1273
									for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
1274
										if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1275
											foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1276
												$halgo = str_replace('hmac_', '', $halgo);
1277
												$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
1278
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1279
												if (!empty($modp)) {
1280
													$tmpealgo .= "-{$modp}";
1281
												}
1282
												$ealgoESPsp2arr[] = $tmpealgo;
1283
											}
1284
										} else {
1285
											$tmpealgo = "{$ealg_id}{$keylen}";
1286
											$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1287
											if (!empty($modp)) {
1288
												$tmpealgo .= "-{$modp}";
1289
											}
1290
											$ealgoESPsp2arr[] = $tmpealgo;
1291
										}
1292
									}
1293
								}
1294
							} else {
1295
								if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1296
									foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1297
										$halgo = str_replace('hmac_', '', $halgo);
1298
										$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
1299
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1300
										if (!empty($modp)) {
1301
											$tmpealgo .= "-{$modp}";
1302
										}
1303
										$ealgoESPsp2arr[] = $tmpealgo;
1304
									}
1305
								} else {
1306
									$tmpealgo = "{$ealg_id}{$ealg_kl}";
1307
									$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1308
									if (!empty($modp)) {
1309
										$tmpealgo .= "-{$modp}";
1310
									}
1311
									$ealgoESPsp2arr[] = $tmpealgo;
1312
								}
1313
							}
1314
						}
1315
					}
1316
				} else if ($ph2ent['protocol'] == 'ah') {
1317
					if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1318
						$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1319
						foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
1320
							$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
1321
							if (!empty($modp)) {
1322
								$tmpAHalgo = "-{$modp}";
1323
							}
1324
							$ealgoAHsp2arr[] = $tmpAHalgo;
1325
						}
1326
					}
1327
				}
1328

    
1329
				$reqids[] = $ph2ent['reqid'];
1330

    
1331
				if (!empty($ph2ent['lifetime'])) {
1332
					if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) {
1333
						$ipseclifetime = intval($ph2ent['lifetime']);
1334
					}
1335
				}
1336

    
1337
			}
1338
		}
1339

    
1340
			$ipsecconnect =<<<EOD
1341
	fragmentation = yes
1342
	keyexchange = {$keyexchange}
1343
	{$reauth}
1344
	{$forceencaps}
1345
	{$mobike}
1346
	{$rekey}
1347
	installpolicy = yes
1348
	{$tunneltype}
1349
	{$dpdline}
1350
	auto = {$passive}
1351
	left = {$left_spec}
1352
	right = {$right_spec}
1353
	{$leftid}
1354

    
1355
EOD;
1356

    
1357
			if (isset($config['ipsec']['compression'])) {
1358
				$ipsecconnect .= "\tcompress = yes\n";
1359
				$enablecompression = true;
1360
			}
1361
			if (!empty($ikelifeline)) {
1362
				$ipsecconnect .= "\t{$ikelifeline}\n";
1363
			}
1364
			if ($ipseclifetime > 0) {
1365
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
1366
			}
1367
			if (!empty($rightsourceip)) {
1368
				$ipsecconnect .= "{$rightsourceip}";
1369
			}
1370
			if (!empty($ealgosp1)) {
1371
				$ipsecconnect .= "\t{$ealgosp1}\n";
1372
			}
1373
			if (!empty($ealgoAHsp2arr)) {
1374
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
1375
			}
1376
			if (!empty($ealgoESPsp2arr)) {
1377
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
1378
			}
1379
			if (!empty($authentication)) {
1380
				$ipsecconnect .= "\t{$authentication}\n";
1381
			}
1382
			if (!empty($peerid_spec)) {
1383
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
1384
			}
1385
			if ($keyexchange == 'ikev1') {
1386
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
1387
			}
1388

    
1389
			if (!isset($ph1ent['mobile']) && $keyexchange == 'ikev1') {
1390
				if (!empty($rightsubnet_spec)) {
1391
					$ipsecfin = '';
1392
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
1393
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
1394
						//if (!empty($reqids[$idx])) {
1395
						//	$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
1396
						//}
1397
						$ipsecfin .= $ipsecconnect;
1398
						$ipsecfin .= "\trightsubnet = {$rsubnet}\n";
1399
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n";
1400
					}
1401
				} else {
1402
					log_error("No phase2 specifications for tunnel with REQID = {$ikeid}");
1403
				}
1404
			} else {
1405
				$ipsecfin = "\nconn con{$ph1ent['ikeid']}\n";
1406
				//if (!empty($reqids[$idx])) {
1407
				//	$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
1408
				//}
1409
				$ipsecfin .= $ipsecconnect;
1410
				if (!isset($ph1ent['mobile']) && !empty($rightsubnet_spec)) {
1411
					$tempsubnets = array();
1412
					foreach ($rightsubnet_spec as $rightsubnet) {
1413
						$tempsubnets[$rightsubnet] = $rightsubnet;
1414
					}
1415
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "\n";
1416
					unset($tempsubnets, $rightsubnet);
1417
				}
1418
				if (!empty($leftsubnet_spec)) {
1419
					$tempsubnets = array();
1420
					foreach ($leftsubnet_spec as $leftsubnet) {
1421
						$tempsubnets[$leftsubnet] = $leftsubnet;
1422
					}
1423
					$ipsecfin .= "\tleftsubnet = " . join(",", $tempsubnets) . "\n";
1424
					unset($tempsubnets, $leftsubnet);
1425
				}
1426
			}
1427
			$ipsecconf .= $ipsecfin;
1428
			unset($ipsecfin);
1429
		}
1430
	}
1431

    
1432
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1433
	unset($ipsecconf);
1434
	/* end ipsec.conf */
1435

    
1436
	if ($enablecompression === true) {
1437
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1438
	} else {
1439
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1440
	}
1441

    
1442
	/* manage process */
1443
	if ($restart === true) {
1444
		mwexec("/usr/local/sbin/ipsec restart", false);
1445
	} else {
1446
		if (isvalidpid("{$g['varrun_path']}/starter.charon.pid")) {
1447
			/* Update configuration changes */
1448
			/* Read secrets */
1449
			mwexec("/usr/local/sbin/ipsec rereadall", false);
1450
			mwexec("/usr/local/sbin/ipsec reload", false);
1451
		} else {
1452
			mwexec("/usr/local/sbin/ipsec start", false);
1453
		}
1454
	}
1455

    
1456
	// run ping_hosts.sh once if it's enabled to avoid wait for minicron
1457
	if ($ipsecpinghostsactive == true) {
1458
		mwexec_bg("/usr/local/bin/ping_hosts.sh");
1459
	}
1460

    
1461
	if ($natfilterrules == true) {
1462
		filter_configure();
1463
	}
1464
	/* start filterdns, if necessary */
1465
	if (count($filterdns_list) > 0) {
1466
		$interval = 60;
1467
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) {
1468
			$interval = $ipseccfg['dns-interval'];
1469
		}
1470

    
1471
		$hostnames = "";
1472
		array_unique($filterdns_list);
1473
		foreach ($filterdns_list as $hostname) {
1474
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1475
		}
1476
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1477
		unset($hostnames);
1478

    
1479
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid")) {
1480
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1481
		} else {
1482
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1483
		}
1484
	} else {
1485
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1486
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1487
	}
1488

    
1489
	if (platform_booting()) {
1490
		echo "done\n";
1491
	}
1492

    
1493
	return count($filterdns_list);
1494
}
1495

    
1496
/*
1497
 * Forcefully restart IPsec
1498
 * This is required for when dynamic interfaces reload
1499
 * For all other occasions the normal vpn_ipsec_configure()
1500
 * will gracefully reload the settings without restarting
1501
 */
1502
function vpn_ipsec_force_reload($interface = "") {
1503
	global $g, $config;
1504

    
1505
	$ipseccfg = $config['ipsec'];
1506

    
1507
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1508
		$found = false;
1509
		foreach ($ipseccfg['phase1'] as $ipsec) {
1510
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1511
				$found = true;
1512
				break;
1513
			}
1514
		}
1515
		if (!$found) {
1516
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1517
			return;
1518
		}
1519
	}
1520

    
1521
	/* if ipsec is enabled, start up again */
1522
	if (isset($ipseccfg['enable'])) {
1523
		log_error(gettext("Forcefully reloading IPsec"));
1524
		vpn_ipsec_configure();
1525
	}
1526
}
1527

    
1528
/* master setup for vpn (mpd) */
1529
function vpn_setup() {
1530
	/* start pppoe server */
1531
	vpn_pppoes_configure();
1532

    
1533
	/* setup l2tp */
1534
	vpn_l2tp_configure();
1535
}
1536

    
1537
function vpn_netgraph_support() {
1538
	$iflist = get_configured_interface_list();
1539
	foreach ($iflist as $iface) {
1540
		$realif = get_real_interface($iface);
1541
		/* Get support for netgraph(4) from the nic */
1542
		$ifinfo = pfSense_get_interface_addresses($realif);
1543
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) {
1544
			pfSense_ngctl_attach(".", $realif);
1545
		}
1546
	}
1547
}
1548

    
1549
function vpn_pppoes_configure() {
1550
	global $config;
1551

    
1552
	if (is_array($config['pppoes']['pppoe'])) {
1553
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
1554
			vpn_pppoe_configure($pppoe);
1555
		}
1556
	}
1557
}
1558

    
1559
function vpn_pppoe_configure(&$pppoecfg) {
1560
	global $config, $g;
1561

    
1562
	$syscfg = $config['system'];
1563

    
1564
	/* create directory if it does not exist */
1565
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
1566
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1567
	}
1568

    
1569
	if (platform_booting()) {
1570
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
1571
			return 0;
1572
		}
1573

    
1574
		echo gettext("Configuring PPPoE Server service... ");
1575
	} else {
1576
		/* kill mpd */
1577
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1578

    
1579
		/* wait for process to die */
1580
		sleep(2);
1581

    
1582
	}
1583

    
1584
	switch ($pppoecfg['mode']) {
1585

    
1586
		case 'server':
1587

    
1588
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1589

    
1590
			if ($pppoecfg['paporchap'] == "chap") {
1591
				$paporchap = "set link enable chap";
1592
			} else {
1593
				$paporchap = "set link enable pap";
1594
			}
1595

    
1596
			/* write mpd.conf */
1597
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1598
			if (!$fd) {
1599
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1600
				return 1;
1601
			}
1602
			$mpdconf = "\n\n";
1603
			$mpdconf .= "poes:\n";
1604

    
1605
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1606
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1607
			}
1608

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

    
1611
				$clientip = ip_after($pppoecfg['remoteip'], $i);
1612

    
1613
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1614
					$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1615
				} else {
1616
					$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1617
				}
1618

    
1619
				$mpdconf .=<<<EOD
1620

    
1621
poes{$pppoecfg['pppoeid']}{$i}:
1622
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1623
	{$issue_ip_type}
1624
	load pppoe_standard
1625

    
1626
EOD;
1627
			}
1628
			if (is_numeric($pppoecfg['n_pppoe_maxlogin']) && ($pppoecfg['n_pppoe_maxlogin'] > 0)) {
1629
				$pppoemaxlogins = $pppoecfg['n_pppoe_maxlogin'];
1630
			} else {
1631
				$pppoemaxlogins = 1;
1632
			}
1633

    
1634
			$mpdconf .=<<<EOD
1635

    
1636
pppoe_standard:
1637
	set bundle no multilink
1638
	set bundle enable compression
1639
	set auth max-logins {$pppoemaxlogins}
1640
	set iface up-script /usr/local/sbin/vpn-linkup
1641
	set iface down-script /usr/local/sbin/vpn-linkdown
1642
	set iface idle 0
1643
	set iface disable on-demand
1644
	set iface disable proxy-arp
1645
	set iface enable tcpmssfix
1646
	set iface mtu 1500
1647
	set link no pap chap
1648
	{$paporchap}
1649
	set link keep-alive 60 180
1650
	set ipcp yes vjcomp
1651
	set ipcp no vjcomp
1652
	set link max-redial -1
1653
	set link mtu 1492
1654
	set link mru 1492
1655
	set ccp yes mpp-e40
1656
	set ccp yes mpp-e128
1657
	set ccp yes mpp-stateless
1658
	set link latency 1
1659
	#set ipcp dns 10.10.1.3
1660
	#set bundle accept encryption
1661

    
1662
EOD;
1663

    
1664
			if (!empty($pppoecfg['dns1'])) {
1665
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1666
				if (!empty($pppoecfg['dns2'])) {
1667
					$mpdconf .= " " . $pppoecfg['dns2'];
1668
				}
1669
				$mpdconf .= "\n";
1670
			} elseif (isset ($config['dnsmasq']['enable'])) {
1671
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1672
				if ($syscfg['dnsserver'][0]) {
1673
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1674
				}
1675
				$mpdconf .= "\n";
1676
			} elseif (isset ($config['unbound']['enable'])) {
1677
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1678
				if ($syscfg['dnsserver'][0]) {
1679
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1680
				}
1681
				$mpdconf .= "\n";
1682
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1683
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1684
			}
1685

    
1686
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1687
				$radiusport = "";
1688
				$radiusacctport = "";
1689
				if (isset($pppoecfg['radius']['server']['port'])) {
1690
					$radiusport = $pppoecfg['radius']['server']['port'];
1691
				}
1692
				if (isset($pppoecfg['radius']['server']['acctport'])) {
1693
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1694
				}
1695
				$mpdconf .=<<<EOD
1696
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1697
	set radius retries 3
1698
	set radius timeout 10
1699
	set auth enable radius-auth
1700

    
1701
EOD;
1702

    
1703
				if (isset ($pppoecfg['radius']['accounting'])) {
1704
					$mpdconf .=<<<EOD
1705
	set auth enable radius-acct
1706

    
1707
EOD;
1708
				}
1709
			}
1710

    
1711
			fwrite($fd, $mpdconf);
1712
			fclose($fd);
1713
			unset($mpdconf);
1714

    
1715
			/* write mpd.links */
1716
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1717
			if (!$fd) {
1718
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1719
				return 1;
1720
			}
1721

    
1722
			$mpdlinks = "";
1723

    
1724
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1725
				$mpdlinks .=<<<EOD
1726

    
1727
poes{$pppoecfg['pppoeid']}{$i}:
1728
	set phys type pppoe
1729
	set pppoe iface {$pppoe_interface}
1730
	set pppoe service "*"
1731
	set pppoe disable originate
1732
	set pppoe enable incoming
1733

    
1734
EOD;
1735
			}
1736

    
1737
			fwrite($fd, $mpdlinks);
1738
			fclose($fd);
1739
			unset($mpdlinks);
1740

    
1741
			if ($pppoecfg['username']) {
1742
				/* write mpd.secret */
1743
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1744
				if (!$fd) {
1745
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1746
					return 1;
1747
				}
1748

    
1749
				$mpdsecret = "\n\n";
1750

    
1751
				if (!empty($pppoecfg['username'])) {
1752
					$item = explode(" ", $pppoecfg['username']);
1753
					foreach ($item as $userdata) {
1754
						$data = explode(":", $userdata);
1755
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1756
					}
1757
				}
1758

    
1759
				fwrite($fd, $mpdsecret);
1760
				fclose($fd);
1761
				unset($mpdsecret);
1762
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1763
			}
1764

    
1765
			/* Check if previous instance is still up */
1766
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
1767
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1768
			}
1769

    
1770
			/* Get support for netgraph(4) from the nic */
1771
			pfSense_ngctl_attach(".", $pppoe_interface);
1772
			/* fire up mpd */
1773
			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");
1774

    
1775
			break;
1776
	}
1777

    
1778
	if (platform_booting()) {
1779
		echo gettext("done") . "\n";
1780
	}
1781

    
1782
	return 0;
1783
}
1784

    
1785
function vpn_l2tp_configure() {
1786
	global $config, $g;
1787

    
1788
	$syscfg = $config['system'];
1789
	$l2tpcfg = $config['l2tp'];
1790

    
1791
	/* create directory if it does not exist */
1792
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
1793
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1794
	}
1795

    
1796
	if (platform_booting()) {
1797
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
1798
			return 0;
1799
		}
1800

    
1801
		echo gettext("Configuring l2tp VPN service... ");
1802
	} else {
1803
		/* kill mpd */
1804
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1805

    
1806
		/* wait for process to die */
1807
		sleep(8);
1808

    
1809
	}
1810

    
1811
	/* make sure l2tp-vpn directory exists */
1812
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
1813
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1814
	}
1815

    
1816
	switch ($l2tpcfg['mode']) {
1817

    
1818
		case 'server':
1819
			$l2tp_listen="";
1820
			$ipaddr = get_interface_ip(get_failover_interface($l2tpcfg['interface']));
1821
			if (is_ipaddrv4($ipaddr)) {
1822
				$l2tp_listen="set l2tp self $ipaddr";
1823
			}
1824

    
1825
			switch ($l2tpcfg['paporchap']) {
1826
				case 'chap':
1827
					$paporchap = "set link enable chap";
1828
					break;
1829
				case 'chap-msv2':
1830
					$paporchap = "set link enable chap-msv2";
1831
					break;
1832
				default:
1833
					$paporchap = "set link enable pap";
1834
					break;
1835
			}
1836

    
1837
			/* write mpd.conf */
1838
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1839
			if (!$fd) {
1840
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1841
				return 1;
1842
			}
1843
			$mpdconf = "\n\n";
1844
			$mpdconf .=<<<EOD
1845
l2tps:
1846

    
1847
EOD;
1848

    
1849
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1850
				$mpdconf .= "	load l2tp{$i}\n";
1851
			}
1852

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

    
1855
				$clientip = ip_after($l2tpcfg['remoteip'], $i);
1856

    
1857
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1858
					$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1859
				} else {
1860
					$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1861
				}
1862

    
1863
				$mpdconf .=<<<EOD
1864

    
1865
l2tp{$i}:
1866
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1867
	{$issue_ip_type}
1868
	load l2tp_standard
1869

    
1870
EOD;
1871
			}
1872

    
1873
			$mpdconf .=<<<EOD
1874

    
1875
l2tp_standard:
1876
	set bundle disable multilink
1877
	set bundle enable compression
1878
	set bundle yes crypt-reqd
1879
	set ipcp yes vjcomp
1880
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1881
	set ccp yes mppc
1882
	set iface disable on-demand
1883
	set iface enable proxy-arp
1884
	set iface up-script /usr/local/sbin/vpn-linkup
1885
	set iface down-script /usr/local/sbin/vpn-linkdown
1886
	set link yes acfcomp protocomp
1887
	set link no pap chap
1888
	{$paporchap}
1889
	{$l2tp_listen}
1890
	set link keep-alive 10 180
1891

    
1892
EOD;
1893

    
1894
			if (is_ipaddr($l2tpcfg['wins'])) {
1895
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1896
			}
1897
			if (is_ipaddr($l2tpcfg['dns1'])) {
1898
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1899
				if (is_ipaddr($l2tpcfg['dns2'])) {
1900
					$mpdconf .= " " . $l2tpcfg['dns2'];
1901
				}
1902
				$mpdconf .= "\n";
1903
			} elseif (isset ($config['dnsmasq']['enable'])) {
1904
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1905
				if ($syscfg['dnsserver'][0]) {
1906
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1907
				}
1908
				$mpdconf .= "\n";
1909
			} elseif (isset ($config['unbound']['enable'])) {
1910
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1911
				if ($syscfg['dnsserver'][0]) {
1912
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1913
				}
1914
				$mpdconf .= "\n";
1915
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1916
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1917
			}
1918

    
1919
			if (isset ($l2tpcfg['radius']['enable'])) {
1920
				$mpdconf .=<<<EOD
1921
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1922
	set radius retries 3
1923
	set radius timeout 10
1924
	set auth enable radius-auth
1925

    
1926
EOD;
1927

    
1928
				if (isset ($l2tpcfg['radius']['accounting'])) {
1929
					$mpdconf .=<<<EOD
1930
	set auth enable radius-acct
1931

    
1932
EOD;
1933
				}
1934
			}
1935

    
1936
			fwrite($fd, $mpdconf);
1937
			fclose($fd);
1938
			unset($mpdconf);
1939

    
1940
			/* write mpd.links */
1941
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1942
			if (!$fd) {
1943
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1944
				return 1;
1945
			}
1946

    
1947
			$mpdlinks = "";
1948

    
1949
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1950
				$mpdlinks .=<<<EOD
1951

    
1952
l2tp{$i}:
1953
	set link type l2tp
1954
	set l2tp enable incoming
1955
	set l2tp disable originate
1956

    
1957
EOD;
1958
				if (!empty($l2tpcfg['secret'])) {
1959
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1960
				}
1961
			}
1962

    
1963
			fwrite($fd, $mpdlinks);
1964
			fclose($fd);
1965
			unset($mpdlinks);
1966

    
1967
			/* write mpd.secret */
1968
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1969
			if (!$fd) {
1970
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1971
				return 1;
1972
			}
1973

    
1974
			$mpdsecret = "\n\n";
1975

    
1976
			if (is_array($l2tpcfg['user'])) {
1977
				foreach ($l2tpcfg['user'] as $user) {
1978
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1979
				}
1980
			}
1981

    
1982
			fwrite($fd, $mpdsecret);
1983
			fclose($fd);
1984
			unset($mpdsecret);
1985
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1986

    
1987
			vpn_netgraph_support();
1988

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

    
1992
			break;
1993

    
1994
		case 'redir':
1995
			break;
1996
	}
1997

    
1998
	if (platform_booting()) {
1999
		echo "done\n";
2000
	}
2001

    
2002
	return 0;
2003
}
2004

    
2005
?>
(57-57/65)