Projet

Général

Profil

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

univnautes / etc / inc / vpn.inc @ 466a5a81

1
<?php
2

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

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

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

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

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

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

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

    
43
require_once("ipsec.inc");
44

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

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

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

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

    
94
	return $convertion;
95
}
96

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

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

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

    
108
	vpn_ipsec_configure_preferoldsa();
109

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
260
		$strongswan = <<<EOD
261

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

    
267
charon {
268

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

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

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

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

    
291
EOD;
292

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
421
		$pskconf = "";
422

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

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

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

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

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

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

    
441
						chmod($certpath, 0600);
442

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
544
					$ep = ipsec_get_phase1_src($ph1ent);
545
					if (!$ep)
546
						continue;
547

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

    
555
					$keyexchange = "ikev1";
556
					if (!empty($ph1ent['iketype']) && $ph1ent['iketype'] != "ikev1")
557
						$keyexchange = "ikev2";
558

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

    
566
					case "dyn_dns":
567
						$myid_type = "address";
568
						$myid_data = resolve_retry($ph1ent['myid_data']);
569
						break;
570

    
571
					case "address";
572
						$myid_data = $ph1ent['myid_data'];
573
						break;
574

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

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

    
592
					case "address";
593
						$peerid_data = $ph1ent['peerid_data'];
594
						break;
595

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

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

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

    
619
						if ($keyexchange == "ikev1")
620
							$ealgosp1 .= "!";
621
					}
622

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

    
633
					if (!empty($ph1ent['authentication_method']) && (strpos($ph1ent['authentication_method'], "xauth") || strpos($ph1ent['authentication_method'], "hybrid")))
634
						$xauth = "xauth = server";
635

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

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

    
646
					if ($ph1ent['mode'] == "aggressive")
647
						$aggressive = "yes";
648
					else
649
						$aggressive = "no";
650

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

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

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

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

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

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

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

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

    
788

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

    
792
					$ipsecconf .=<<<EOD
793

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

    
811
EOD;
812

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

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

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

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

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

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

    
869
	return count($filterdns_list);
870
}
871

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
982
EOD;
983

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

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

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

    
992
				$mpdconf .= <<<EOD
993

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

    
999
EOD;
1000
			}
1001

    
1002
			$mpdconf .=<<<EOD
1003

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

    
1024
EOD;
1025

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

    
1031
EOD;
1032
			}
1033

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

    
1037
			if (!empty($pptpdcfg['dns1'])) {
1038
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1039
				if (!empty($pptpdcfg['dns2']))
1040
					$mpdconf .= " " . $pptpdcfg['dns2'];
1041
				$mpdconf .= "\n";
1042
			} elseif (isset ($config['dnsmasq']['enable'])) {
1043
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1044
				if ($syscfg['dnsserver'][0])
1045
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1046
				$mpdconf .= "\n";
1047
			} elseif (isset($config['unbound']['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 (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1053
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1054
			}
1055

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

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

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

    
1076
EOD;
1077

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

    
1083
EOD;
1084
				}
1085
			}
1086

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

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

    
1098
			$mpdlinks = "";
1099

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

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

    
1109
EOD;
1110
			}
1111

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

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

    
1123
			$mpdsecret = "";
1124

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

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

    
1138
			vpn_netgraph_support();
1139

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

    
1143
			break;
1144

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

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

    
1152
	return 0;
1153
}
1154

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

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

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

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

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

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

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

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

    
1185
	}
1186

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

    
1189
		case 'server' :
1190

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

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

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

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

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

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

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

    
1221
				$mpdconf .=<<<EOD
1222

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

    
1228
EOD;
1229
			}
1230

    
1231
			$mpdconf .=<<<EOD
1232

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

    
1259
EOD;
1260

    
1261
			if (!empty($pppoecfg['dns1'])) {
1262
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1263
				if (!empty($pppoecfg['dns2']))
1264
					$mpdconf .= " " . $pppoecfg['dns2'];
1265
				$mpdconf .= "\n";
1266
			} elseif (isset ($config['dnsmasq']['enable'])) {
1267
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1268
				if ($syscfg['dnsserver'][0])
1269
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1270
				$mpdconf .= "\n";
1271
			} elseif (isset ($config['unbound']['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 (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1277
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1278
			}
1279

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

    
1293
EOD;
1294

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

    
1299
EOD;
1300
				}
1301
			}
1302

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

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

    
1314
			$mpdlinks = "";
1315

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

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

    
1326
EOD;
1327
			}
1328

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

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

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

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

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

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

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

    
1366
			break;
1367
	}
1368

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

    
1372
	return 0;
1373
}
1374

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

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

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

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

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

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

    
1397
	}
1398

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

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

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

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

    
1421
EOD;
1422

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

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

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

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

    
1437
				$mpdconf .=<<<EOD
1438

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

    
1444
EOD;
1445
			}
1446

    
1447
			$mpdconf .=<<<EOD
1448

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

    
1465
EOD;
1466

    
1467
			if (is_ipaddr($l2tpcfg['wins'])) {
1468
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1469
			}
1470
			if (is_ipaddr($l2tpcfg['dns1'])) {
1471
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1472
				if (is_ipaddr($l2tpcfg['dns2']))
1473
					$mpdconf .= " " . $l2tpcfg['dns2'];
1474
				$mpdconf .= "\n";
1475
			} elseif (isset ($config['dnsmasq']['enable'])) {
1476
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1477
				if ($syscfg['dnsserver'][0])
1478
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1479
				$mpdconf .= "\n";
1480
			} elseif (isset ($config['unbound']['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 (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1486
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1487
			}
1488

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

    
1496
EOD;
1497

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

    
1502
EOD;
1503
				}
1504
			}
1505

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

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

    
1517
			$mpdlinks = "";
1518

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

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

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

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

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

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

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

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

    
1555
			vpn_netgraph_support();
1556

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

    
1560
			break;
1561

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

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

    
1569
	return 0;
1570
}
1571

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

    
1580
?>
(58-58/67)