Project

General

Profile

Download (40.1 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	openvpn.inc
4
	
5
	Copyright (C) 2004 Peter Curran (peter@closeconsultants.com).
6
	Copyright (C) 2005 Peter Allgeyer (allgeyer@web.de).
7
	All rights reserved.
8
	
9
	Redistribution and use in source and binary forms, with or without
10
	modification, are permitted provided that the following conditions are met:
11
	
12
	1. Redistributions of source code must retain the above copyright notice,
13
	   this list of conditions and the following disclaimer.
14
	
15
	2. Redistributions in binary form must reproduce the above copyright
16
	   notice, this list of conditions and the following disclaimer in the
17
	   documentation and/or other materials provided with the distribution.
18
	
19
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
23
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
	POSSIBILITY OF SUCH DAMAGE.
29
*/
30
	
31
/* include all configuration functions */
32
require_once("globals.inc");
33
require_once("config.inc");
34
require_once("functions.inc");
35

    
36
function ovpn_configure($reconfigure) {
37
	global $config;
38
	if (is_array($config['ovpn']['server']))
39
		ovpn_server_crl_add();
40
		ovpn_server_ccd_add();
41
		ovpn_config_server($reconfigure);
42
	if (is_array($config['ovpn']['client']))
43
		ovpn_config_client();
44
	return;
45
}
46

    
47
function ovpn_link_tap() {
48
	/* Add a reference to the tap KLM.  If ref count = 1, load it */
49
	global $g;
50
	
51
	if (!is_file($g['vardb_path'] ."/ovpn_tap_link")){
52
		$link_count = 1;
53
		mwexec("/sbin/kldload if_tap");
54
		$fd = fopen($g['vardb_path'] ."/ovpn_tap_link", 'w');
55
	}
56
	//else {
57
	//	$fd = fopen($g['vardb_path'] ."/ovpn_tap_link", 'r+');
58
	//	$link_count = fread($fd, filesize($g['vardb_path'] ."/ovpn_tap_link"));
59
	//	$link_count ++;
60
	//}
61
	//fwrite($fd, $link_count);
62
	//fclose($fd);
63
	return true;
64
}
65

    
66
function ovpn_unlink_tap() {
67
	/* Remove a reference to the tap KLM.  If ref count = 0, unload it */
68
	global $g;
69
	
70
	if (!is_file($g['vardb_path'] ."/ovpn_tap_link"))
71
		return false;  //no file, no links so why are we called?
72
		
73
	$fd = fopen($g['vardb_path'] ."/ovpn_tap_link", 'r+');
74
	$link_count = fread($fd, filesize($g['vardb_path'] ."/ovpn_tap_link"));
75
	$link_count--;
76
	fwrite($fd, $link_count);
77
	fclose($fd);
78
		
79
	if ($link_count == 0)
80
		mwexec("/sbin/kldunload if_tap");
81
	return true;
82
}
83

    
84
/*****************************/	
85
/*  Server related functions */
86
/*****************************/
87

    
88
/* Configure the server */
89
function ovpn_config_server($reconfigure) {
90
	global $config, $g, $d_ovpnsrvdirty_path;
91

    
92
	if(!is_array($config['ovpn']['server']['tunnel']))
93
		return;
94
	foreach ($config['ovpn']['server']['tunnel'] as $id => $server) {
95
		/* get tunnel interface */
96
		$tun = $server['tun_iface'];
97
			
98
		if (isset($server['enable'])) {
99

    
100
			if ($g['booting']) {
101
				echo "Starting OpenVPN server $id... ";
102

    
103
				/* define configuration options */
104
				ovpn_srv_config_generate($id);
105

    
106
				/* Start the openvpn daemon */
107
				mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_srv_{$tun}.conf");
108

    
109
				/* Send the boot message */
110
				echo "done\n";
111

    
112
				/* next server */
113
				continue;
114
			}
115

    
116
			/* send SIGUSR1 to running openvpn daemon */
117
			if ( $reconfigure == "true" && isset($server['dynip'])) {
118
				sigkillbypid($g['varrun_path']."/ovpn_srv_{$tun}.pid", "SIGUSR1");
119
				continue;
120
			}
121

    
122
			/* read dirtyfile */
123
			if (is_readable($d_ovpnsrvdirty_path))
124
				$lines = file($d_ovpnsrvdirty_path);
125

    
126
			/* reconfigure server */
127
			if (is_array($lines) && in_array($tun, $lines)) {
128

    
129
				/* kill running server */
130
				ovpn_server_kill($tun);
131

    
132
				/* remove old certs & keys */
133
				ovpn_server_certs_del($tun);
134

    
135
				/* define configuration options */
136
				ovpn_srv_config_generate($id);
137
			}
138

    
139
			/* Start the openvpn daemon */
140
			if (!is_readable("{$g['varrun_path']}/ovpn_srv_{$tun}.pid"))
141
				mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_srv_{$tun}.conf");
142

    
143
			/* next server */
144
			continue;
145
		}
146

    
147
		/* server disabled */
148
		if (!$g['booting']) {
149
			/* kill running server */
150
			ovpn_server_kill($tun);
151

    
152
			/* Remove old certs & keys */
153
			ovpn_server_certs_del($tun);
154

    
155
			/* stop any processes, unload the tap module */
156
			//if ($server['type'] == "tap")
157
			//	ovpn_unlink_tap();
158
		}
159
	}
160
	return 0;
161
}
162

    
163
/* Kill off a running server process */
164
function ovpn_server_certs_del($tun) {
165
	global $g;
166
	
167
	/* Remove old certs & keys */
168
	unlink_if_exists("{$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem");
169
	unlink_if_exists("{$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem");
170
	unlink_if_exists("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem");
171
	unlink_if_exists("{$g['vardb_path']}/ovpn_dh_{$tun}.pem");
172
	unlink_if_exists("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem");
173
	unlink_if_exists("{$g['varetc_path']}/ovpn_srv_up_{$tun}.sh");
174
	unlink_if_exists("{$g['varetc_path']}/ovpn_srv_{$tun}.conf");
175

    
176
	return 0;
177
}
178

    
179
/* Kill off a running server process */
180
function ovpn_server_kill($tun) {
181
	global $g;
182

    
183
	/* kill running server */
184
	killbypid("{$g['varrun_path']}/ovpn_srv_{$tun}.pid");
185
}
186

    
187
/* Generate the config for a OpenVPN server */
188
function ovpn_srv_config_generate($id) {
189
	global $config, $g;
190
	$server = $config['ovpn']['server']['tunnel'][$id];
191

    
192
	/* get tunnel interface */
193
	$tun = $server['tun_iface'];
194

    
195
	/* get optional interface name */
196
	$iface = ovpn_get_opt_interface($tun);
197

    
198
	/* Copy the TLS-Server certs & keys to disk */
199
	if ($server['authentication_method'] != "pre_shared_key" ) {
200

    
201
		$fd = fopen("{$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem", "w");
202
		if ($fd) {
203
			fwrite($fd, base64_decode($server['ca_cert'])."\n");
204
			fclose($fd);	
205
		}
206

    
207
		$fd = fopen("{$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem", "w");
208
		if ($fd) {
209
			fwrite($fd, base64_decode($server['srv_cert'])."\n");
210
			fclose($fd);	
211
		}
212

    
213
		touch ("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem");
214
		chmod ("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem", 0600);
215
		$fd = fopen("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem", "w");
216
		if ($fd) {
217
			fwrite($fd, base64_decode($server['srv_key'])."\n");
218
			fclose($fd);	
219
		}
220

    
221
		$fd = fopen("{$g['vardb_path']}/ovpn_dh_{$tun}.pem", "w");
222
		if ($fd) {
223
			fwrite($fd, base64_decode($server['dh_param'])."\n");
224
			fclose($fd);	
225
		}
226
	}
227

    
228
	if ($server['authentication_method'] == "pre_shared_key" || isset($server['tlsauth'])) {
229
		touch ("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem");
230
		chmod ("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem", 0600);
231
		$fd = fopen("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem", "w");
232
		if ($fd) {
233
			fwrite($fd, base64_decode($server['pre-shared-key'])."\n");
234
			fclose($fd);	
235
		}
236
	}
237

    
238
	$fd = fopen("{$g['varetc_path']}/ovpn_srv_{$tun}.conf", "w");
239
	if (!$fd) {
240
		printf("Error: cannot open ovpn_srv_{$tun}.conf in ovpn_srv_config_generate($id).\n");
241
		return 1;
242
	}
243

    
244
	/* First the generic stuff:
245
		- We are a server
246
		- We will run without privilege
247
	*/
248
	$ovpn_config = "";
249
	$ovpn_config .= <<<EOD
250
daemon
251
user nobody
252
group nobody
253
verb {$server['verb']}
254
persist-tun
255
persist-key
256
status /var/log/openvpn_{$tun}.log 60
257
writepid {$g['varrun_path']}/ovpn_srv_{$tun}.pid
258
dev {$server['tun_iface']}
259
port {$server['port']}
260
cipher {$server['crypto']}
261

    
262
EOD;
263

    
264
	/* Set protocol being used (p = udp (default), tcp-server) */
265
	if ($server['proto'] == "tcp")
266
		$ovpn_config .= "proto tcp-server\n";
267

    
268
	/* Interface binding - 1 or all */
269
	if ($server['bind_iface'] != 'all')
270
		if ($ipaddr = ovpn_get_ip($server['bind_iface']))
271
			$ovpn_config .= "local {$ipaddr}\n";
272

    
273
	/* are we using dynamic ip addresses? */
274
	if (isset($server['dynip']))
275
		$ovpn_config .= "persist-remote-ip\n";
276

    
277
	/* Client to client routing (off by default) */
278
	if (isset($server['cli2cli']))
279
		$ovpn_config .= "client-to-client\n";
280

    
281
	/* Limit server to a maximum of n concurrent clients. */
282
	if (!empty($server['maxcli']))
283
		$ovpn_config .= "max-clients {$server['maxcli']}\n";
284

    
285
	/* Authentication method */
286
	if ($server['authentication_method'] != "pre_shared_key") {
287

    
288
		$ovpn_config .= <<<EOD
289
client-config-dir {$g['vardb_path']}/ccd
290
ca {$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem
291
cert {$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem
292
key {$g['vardb_path']}/ovpn_srv_key_{$tun}.pem
293
dh {$g['vardb_path']}/ovpn_dh_{$tun}.pem
294

    
295
EOD;
296

    
297
		/* CRL list */
298
		if (isset($server['crlname']) &&
299
		    is_readable("{$g['vardb_path']}/{$server['crlname']}.crl.pem")) {
300
			$ovpn_config .= "crl-verify {$g['vardb_path']}/{$server['crlname']}.crl.pem\n";
301
		}
302

    
303
		/* TLS auth */
304
		if (isset($server['tlsauth']))
305
			$ovpn_config .= "tls-auth {$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem 0\n";
306

    
307
		/* bridging enabled? */
308
		if ($server['bridge'] && $server['type'] == "tap") {
309
			if ($server['method'] == "ovpn") {
310
				$netmask = gen_subnet_mask($config['interfaces'][$server['bridge']]['subnet']);
311
				$ovpn_config .= "server-bridge {$server['gateway']} {$netmask} {$server['range_from']} {$server['range_to']}\n";
312
			} else {
313
				$ovpn_config .= <<<EOD
314
mode server
315
tls-server
316

    
317
EOD;
318
			}
319

    
320
			$lastdigits = substr($tun, 3) + 2;
321
			$ovpn_srv_up = "/sbin/ifconfig " . $tun . " 127.0.0." . $lastdigits . "/32\n";
322

    
323
			$fdo = fopen("{$g['varetc_path']}/ovpn_srv_up_{$tun}.sh", "w");
324
			if ($fdo) {
325
				fwrite($fdo, $ovpn_srv_up);
326
				fclose($fdo);	
327
				chmod ("{$g['varetc_path']}/ovpn_srv_up_{$tun}.sh", 0755);
328
				$ovpn_config .= "up /var/etc/ovpn_srv_up_{$tun}.sh\n";
329
			}
330

    
331
		} else {
332
			/* Not bridged, can be tun or tap, doesn't matter */
333
			$netmask = gen_subnet_mask($server['prefix']);
334

    
335
			if ($server['method'] == "ovpn") {
336
				/* new --server macro simplifies config */
337
				$ovpn_config .= "server {$server['ipblock']} {$netmask}\n";
338
			} else {
339
				$ovpn_config .= <<<EOD
340
mode server
341
tls-server
342
ifconfig {$server['ipblock']} {$netmask}
343

    
344
EOD;
345
			}
346
		} /* end bridging */
347

    
348
		/* Duplicate CNs */
349
		if (isset($server['dupcn']))
350
			$ovpn_config .= "duplicate-cn\n";
351

    
352
	} else {
353
		/* 'authentication_method' == "pre_shared_key" */
354
		$network = gen_subnet($server['lipaddr'], $server['netmask']);
355
		$netmask = gen_subnet_mask($server['netmask']);
356

    
357
		$ovpn_config .= "secret {$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem 0\n";
358

    
359
		if (strstr($server['type'], "tun")) {
360
			$ovpn_config .= "ifconfig {$server['lipaddr']} {$server['ripaddr']}\n";
361
			$ovpn_config .= "route {$network} {$netmask}\n";
362
		} else {
363
			$ovpn_config .= "ifconfig {$server['lipaddr']} {$netmask}\n";
364
		}
365

    
366
		if (isset($server['client-to-client']))
367
			$ovpn_config .= "push \"route {$network} {$netmask}\"\n";
368
		else
369
			$ovpn_config .= "push \"route {$server['lipaddr']}\"\n";
370

    
371
	} /* end authentication_method */
372

    
373
	$push_options = "";
374
	
375
	/* Client push - redirect gateway */
376
	if (isset($server['psh_options']['redir']))  {
377
		if (isset($server['psh_options']['redir_loc']))
378
			$push_config .= "push \"redirect-gateway local\"\n";
379
		else
380
			$push_config .= "push \"redirect-gateway\"\n";
381
		if ($server['method'] != "ovpn")
382
			$push_config .= "push \"route-gateway {$server['ipblock']}\"\n";
383
	}
384

    
385
	/* Client push - route delay */
386
	if (isset($server['psh_options']['rte_delay']))
387
		$push_config .= "push \"route-delay {$server['psh_options']['rte_delay_int']}\"\n";
388

    
389
	/* Client push - ping (note we set both server and client) */
390
	if (isset ($server['psh_options']['ping'])){
391
		$conflict = true;
392
		$interval = $server['psh_options']['ping_int'];
393
		$ovpn_config .= "ping {$server['psh_options']['ping_int']}\n ";
394
		$push_config .= "push \"ping {$server['psh_options']['ping_int']}\"\n";
395
	}
396

    
397
	/* Client push - ping-restart (note server uses 2 x client interval) */
398
	if (isset ($server['psh_options']['pingrst'])){
399
		$conflict = true;
400
		$interval = $server['psh_options']['pingrst_int'];
401
		$ovpn_config .= "ping-restart " . ($interval * 2) . "\n";
402
		$push_config .= "push \"ping-restart $interval\"\n";
403
	}
404

    
405
	/* Client push - ping-exit (set on client) */
406
	if (isset ($server['psh_options']['pingexit'])){
407
		$conflict = true;
408
		$ovpn_config .= "ping-exit {$server['psh_options']['pingexit_int']}\n";
409
		$push_config .= "push \"ping-exit {$server['psh_options']['pingexit_int']}\"\n";
410
	}
411

    
412
	/* Client push - inactive (set on client) */
413
	if (isset ($server['psh_options']['inact'])){
414
		$ovpn_config .= "inactive {$server['psh_options']['inact_int']}\n";
415
		$push_config .= "push \"inactive {$server['psh_options']['inact_int']}\"\n";
416
	}
417

    
418
	if (isset($push_config))
419
		$ovpn_config .= $push_config;
420

    
421
	if (!isset($conflict))
422
		$ovpn_config .= "keepalive 10 60\n";
423

    
424
	/* Expert mode paramters */
425
	if (isset($server['expertmode_enabled']) && is_array($server['expertmode'])) {
426
		$ovpn_config .= ";begin expertmode\n";
427
		foreach ($server['expertmode']['option'] as $option) {
428
			$ovpn_config .= "{$option}\n";
429
		}
430
		$ovpn_config .= ";end expertmode\n";
431
	}
432

    
433
	fwrite($fd, $ovpn_config);
434
	fclose($fd);
435

    
436
	//trigger_error("OVPN: $ovpn_config", E_USER_NOTICE);
437
}
438

    
439
/* Define an OVPN Server tunnel interface in the interfaces array and assign a name */
440
function ovpn_server_iface(){
441
	global $config, $g;
442

    
443
	unset($filter_configure);
444
	unset($bridge_configure);
445
	
446
	foreach ($config['ovpn']['server']['tunnel'] as $id => $server) {
447
		if (isset($server['enable'])) {
448

    
449
			/* get tunnel interface */
450
			$tun = $server['tun_iface'];
451
			
452
			$i = 1;
453
			while (true) {
454
				$ifname = 'opt' . $i;
455
				if (is_array($config['interfaces'][$ifname])) {
456
					if ((isset($config['interfaces'][$ifname]['ovpn']))
457
					     && ($config['interfaces'][$ifname]['ovpn'] == "server_{$tun}"))
458
						/* Already an interface defined - overwrite */
459
						break;
460
				} else {
461

    
462
					/* No existing entry, this is first unused */
463
					$config['interfaces'][$ifname] = array();
464

    
465
					/* add new filter rules */
466
					$filter_configure = true;
467
					break;
468
				}
469
				$i++;
470
			}
471
			$config['interfaces'][$ifname]['descr'] = strtoupper($server['tun_iface']);
472
			$config['interfaces'][$ifname]['if'] = $server['tun_iface'];
473
			if ($server['method'] == "ovpn")
474
				$config['interfaces'][$ifname]['ipaddr'] = long2ip( ip2long($server['ipblock']) + 1);
475
			else
476
				$config['interfaces'][$ifname]['ipaddr'] = $server['ipblock'];
477
			if (isset($server['bridge'])) {
478
				$config['interfaces'][$ifname]['bridge'] = $server['bridge'];
479
				$bridge_configure = true;
480
			} else if (isset($config['interfaces'][$ifname]['bridge'])) {
481
				/* bridge config removed */
482
				unset ($config['interfaces'][$ifname]['bridge']);
483
				$bridge_configure = true;
484
			}
485
			$config['interfaces'][$ifname]['subnet'] = $server['prefix'];
486
			$config['interfaces'][$ifname]['enable'] = isset($server['enable']) ? true : false;
487
			$config['interfaces'][$ifname]['ovpn'] = "server_{$tun}";
488

    
489
			write_config();
490
		}
491
	}
492

    
493
	/* do we have to reconfigure filter rules? */
494
	if (isset($bridge_configure))
495
		interfaces_optional_configure();
496
	else if (isset($filter_configure))
497
		filter_configure();
498

    
499
	return "OpenVPN server interface defined";
500
}
501

    
502
/* Delete a server interface definition */
503
function ovpn_server_iface_del($tun) {
504
	global $config;
505

    
506
	for ($i = 1; is_array($config['interfaces']['opt' . $i]); $i++) {
507
		$ifname = 'opt' . $i;
508
		if ((isset($config['interfaces'][$ifname]['ovpn']))
509
		     && ($config['interfaces'][$ifname]['if'] == "$tun")) {
510
			unset($config['interfaces'][$ifname]);
511
			break;
512
		}
513
	}
514

    
515
	/* shift down other OPTn interfaces to get rid of holes */
516
	$i++;
517

    
518
	/* look at the following OPTn ports */
519
	while (is_array($config['interfaces']['opt' . $i])) {
520
		$config['interfaces']['opt' . ($i - 1)] =
521
			$config['interfaces']['opt' . $i];
522

    
523
		unset($config['interfaces']['opt' . $i]);
524
		$i++;
525
	}
526

    
527
	/* reconfigure filter rules */
528
	interfaces_optional_configure();
529
}
530

    
531
/* Add client config file */
532
function ovpn_server_ccd_add() {
533
	global $config, $g;
534

    
535
	if (is_array($config['ovpn']['server']['ccd'])) {
536
		foreach ($config['ovpn']['server']['ccd'] as $id => $server) {
537
			/* define configuration options */
538
			ovpn_server_ccd_generate($id);
539
		}
540
	}
541
}
542

    
543

    
544
/* Construct client config file */
545
function ovpn_server_ccd_generate($id) {
546
	global $config, $g;
547
	$ovpnccd = $config['ovpn']['server']['ccd'][$id];
548

    
549
	$cn = $ovpnccd['cn'];
550
	$ccd_config = "";
551
        $push_options = "";
552
        
553
	/* Push reset */
554
	if (!isset($ovpnccd['disable']) && isset($ovpnccd['psh_reset']))  {
555
		$ccd_config .= "push-reset\n";
556

    
557
		/* Client push - redirect gateway */
558
		if (isset($ovpnccd['psh_options']['redir']))  {
559
			if (isset($ovpnccd['psh_options']['redir_loc']))
560
				$push_config .= "push \"redirect-gateway local\"\n";
561
			else
562
				$push_config .= "push \"redirect-gateway\"\n";
563
		}
564

    
565
		/* Client push - route delay */
566
		if (isset($ovpnccd['psh_options']['rte_delay']))
567
			$push_config .= "push \"route-delay {$ovpnccd['psh_options']['rte_delay_int']}\"\n";
568

    
569
		/* Client push - ping (note we set both server and client) */
570
		if (isset ($ovpnccd['psh_options']['ping'])){
571
			$ccd_config .= "ping {$server['psh_options']['ping_int']}\n ";
572
			$push_config .= "push \"ping {$ovpnccd['psh_options']['ping_int']}\"\n";
573
		}
574

    
575
		/* Client push - ping-restart (note server uses 2 x client interval) */
576
		if (isset ($ovpnccd['psh_options']['pingrst'])){
577
			$interval = $ovpnccd['psh_options']['pingrst_int'];
578
			$ccd_config .= "ping-restart " . ($interval * 2) . "\n";
579
			$push_config .= "push \"ping-restart $interval\"\n";
580
		}
581

    
582
		/* Client push - ping-exit (set on client) */
583
		if (isset ($ovpnccd['psh_options']['pingexit'])){
584
			$ccd_config .= "ping-exit {$ovpnccd['psh_options']['pingexit_int']}\n";
585
			$push_config .= "push \"ping-exit {$ovpnccd['psh_options']['pingexit_int']}\"\n";
586
		}
587

    
588
		/* Client push - inactive (set on client) */
589
		if (isset ($ovpnccd['psh_options']['inact'])){
590
			$ccd_config .= "inactive {$ovpnccd['psh_options']['inact_int']}\n";
591
			$push_config .= "push \"inactive {$ovpnccd['psh_options']['inact_int']}\"\n";
592
		}
593

    
594
		if (isset($push_config))
595
			$ccd_config .= $push_config;
596
	}
597

    
598
        if (!isset($ovpnccd['disable']) && is_array($ovpnccd['options'])) {
599
                foreach ($ovpnccd['options']['option'] as $option) {
600
                        $ccd_config .= "{$option}\n";
601
                }
602
        }
603

    
604
	/* Disable client from connecting */
605
	if (isset($ovpnccd['disable']))
606
		$ccd_config = "disable\n";
607

    
608
	unlink_if_exists("{$g['vardb_path']}/ccd/{$cn}");
609

    
610
	if (isset($ccd_config) && isset($ovpnccd['enable'])) {
611
		$fd = fopen("{$g['vardb_path']}/ccd/{$cn}", "w");
612
		if ($fd) {
613
			fwrite($fd, $ccd_config."\n");
614
			fclose($fd);    
615
		}
616
	}
617
}
618

    
619
/* Delete client config file */
620
function ovpn_server_ccd_del($cn) {
621
	global $g;
622
	
623
	unlink_if_exists("{$g['vardb_path']}/ccd/{$cn}");
624
	return 0;
625
}
626

    
627
/* Add CRL file */
628
function ovpn_server_crl_add() {
629
	global $config, $g, $d_ovpncrldirty_path;
630

    
631
	if (is_array($config['ovpn']['server']['crl'])) {
632
		foreach ($config['ovpn']['server']['crl'] as $id => $crlent) {
633
			/* get crl file name */
634
			$name = $crlent['crlname'];
635

    
636
			if (isset($crlent['enable'])) {
637
			
638
				/* add file */
639
				ovpn_server_crl_generate($id);
640

    
641
				if ($g['booting']) {
642
					/* next crl file */
643
					continue;
644
				}
645
				
646
				/* read dirtyfile */
647
				if (is_readable($d_ovpncrldirty_path))
648
					$lines = file($d_ovpncrldirty_path);
649

    
650
				/* reconfigure crl file */
651
				if (is_array($lines) && in_array($name, $lines)) {
652

    
653
					/* restart running openvpn daemon */
654
					foreach ($config['ovpn']['server']['tunnel'] as $id => $server) {
655
						$tun = $server['tun_iface'];
656

    
657
						if ($server['enable'] &&
658
						    isset($server['crlname']) && $server['crlname'] == $name)
659
							/* kill running server */
660
							ovpn_server_kill($tun);
661

    
662
							/* Start the openvpn daemon */
663
							mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_srv_{$tun}.conf");
664
					}
665

    
666
				}
667
			
668
				/* next crl file */
669
				continue;
670
			}
671
			
672
			/* crl file disabled: remove file */
673
			ovpn_server_crl_del($name);
674
		}
675
	}
676
	return 0;
677
}
678

    
679
/* Write CRL to file */
680
function ovpn_server_crl_generate($id) {
681
	global $config, $g;
682

    
683
	$ovpncrl = $config['ovpn']['server']['crl'][$id];
684

    
685
	$fd = fopen("{$g['vardb_path']}/{$ovpncrl['crlname']}.crl.pem", "w");
686
	if ($fd) {
687
		fwrite($fd, base64_decode($ovpncrl['crl_list'])."\n");
688
		fclose($fd);
689
	}
690
}
691

    
692
/* Delete CRL file */
693
function ovpn_server_crl_del($name) {
694
	global $config, $g;
695

    
696
	/* have to wipe out the crl from the server config */
697
	foreach ($config['ovpn']['server']['tunnel'] as $id => $server) {
698
		if (isset($server['crlname']) && $server['crlname'] == $name) {
699

    
700
			/* get tunnel interface */
701
			$tun = $server['tun_iface'];
702

    
703
			/* remove crl file entry */
704
			unset($config['ovpn']['server']['tunnel'][$id]['crlname']);
705
			write_config();
706
			
707
			/* kill running server */
708
			ovpn_server_kill($tun);
709

    
710
			/* remove old certs & keys */
711
			ovpn_server_certs_del($tun);
712
			
713
			/* reconfigure daemon */
714
			ovpn_srv_config_generate($id);
715

    
716
			/* Start the openvpn daemon */
717
			mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_srv_{$tun}.conf");
718
		}
719
	}
720

    
721
	unlink_if_exists("{$g['vardb_path']}/{$name}.crl.pem");
722
	return 0;
723
}
724

    
725

    
726
/* Get a list of crl files */
727
function ovpn_get_crl_list() {
728
	global $config;
729

    
730
	$crl_list = array();
731

    
732
	if (is_array($config['ovpn']['server']['crl'])) {
733
		foreach ($config['ovpn']['server']['crl'] as $crlent) {
734
			if (isset($crlent['enable']))
735
				$crl_list[] = $crlent['crlname'];
736
		}
737
	}
738
	return $crl_list;
739
}
740

    
741
/* append interface to $_ovpnsrvdirty_path */
742
function ovpn_srv_dirty($tun) {
743
	global $d_ovpnsrvdirty_path;
744
	
745
	$fd = fopen($d_ovpnsrvdirty_path, 'a');
746
	if ($fd) {
747
		fwrite($fd, $tun);
748
		fclose($fd);
749
	}
750
}
751

    
752
/* append file name to $_ovpncrldirty_path */
753
function ovpn_crl_dirty($name) {
754
	global $d_ovpncrldirty_path;
755
	
756
	$fd = fopen($d_ovpncrldirty_path, 'a');
757
	if ($fd) {
758
		fwrite($fd, $name);
759
		fclose($fd);
760
	}
761
}
762

    
763

    
764
/****************************/
765
/* Client related functions */
766
/****************************/
767

    
768
function ovpn_config_client() {
769
	/* Boot time configuration */
770
	global $config, $g, $d_ovpnclidirty_path;;
771
	
772
	foreach ($config['ovpn']['client']['tunnel'] as $id => $client) {
773

    
774
		/* get tunnel interface */
775
		$tun = $client['if'];
776

    
777
		if (isset($client['enable'])) {
778

    
779
			if ($g['booting']) {
780
				echo "Starting OpenVPN client $id... ";
781
		
782
				/* define configuration options */
783
				ovpn_cli_config_generate($id);
784

    
785
				/* Start openvpn for this client */
786
				mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_cli_{$tun}.conf");
787
		
788
				/* Send the boot message */
789
				echo "done\n";
790

    
791
				/* next client */
792
				continue;
793
			}
794

    
795
			/* read dirtyfile */
796
			if (is_readable($d_ovpnclidirty_path))
797
				$lines = file($d_ovpnclidirty_path);
798

    
799
			/* reconfigure client */
800
			if (is_array($lines) && in_array($tun, $lines)) {
801

    
802
				/* kill running client */
803
				ovpn_client_kill($tun);
804

    
805
				/* remove old certs & keys */
806
				ovpn_client_certs_del($tun);
807

    
808
				/* define configuration options */
809
				ovpn_cli_config_generate($id);
810
			}
811

    
812
			/* Start the openvpn daemon */
813
			if (!is_readable("{$g['varrun_path']}/ovpn_cli_{$tun}.pid"))
814
				mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_cli_{$tun}.conf");
815

    
816
			/* next client */
817
			continue;
818
		}
819

    
820
		/* client disabled */
821
		if (!$g['booting']) {
822
			/* kill running client */
823
			ovpn_client_kill($tun);
824
			
825
			/* remove old certs & keys */
826
			ovpn_client_certs_del($tun);
827

    
828
			/* stop any processes, unload the tap module */
829
			//if ($client['type'] == "tap")
830
			//	ovpn_unlink_tap();
831
		}
832
	}
833
	return 0;
834
}
835

    
836
/* Kill off a running client process */
837
function ovpn_client_certs_del($tun) {
838
	global $g;
839
	
840
	/* Remove old certs & keys */
841
	unlink_if_exists("{$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem");
842
	unlink_if_exists("{$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem");
843
	unlink_if_exists("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem");
844
	unlink_if_exists("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem");
845
	unlink_if_exists("{$g['varetc_path']}/ovpn_cli_up_{$tun}.pem");
846
	unlink_if_exists("{$g['varetc_path']}/ovpn_cli_{$tun}.conf");
847

    
848
	return 0;
849
}
850

    
851
/* Kill off a running client process */
852
function ovpn_client_kill($tun) {
853
	global $g;
854

    
855
	/* kill running client */
856
	killbypid("{$g['varrun_path']}/ovpn_cli_{$tun}.pid");
857
}
858

    
859
/* Generate the config for a OpenVPN client */
860
function ovpn_cli_config_generate($id) {
861
	/* configure the named client */
862
	global $config, $g;
863
	$client = $config['ovpn']['client']['tunnel'][$id];
864

    
865
	/* get tunnel interface */
866
	$tun = $client['if'];
867

    
868
	/* get optional interface name */
869
	$iface = ovpn_get_opt_interface($tun);
870

    
871
	/* Copy the TLS-Client certs & keys to disk */
872
	if ($client['authentication_method'] != "pre_shared_key" ) {
873

    
874
		$fd = fopen("{$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem", "w");
875
		if ($fd) {
876
			fwrite($fd, base64_decode($client['ca_cert'])."\n");
877
			fclose($fd);	
878
		}
879

    
880
		$fd = fopen("{$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem", "w");
881
		if ($fd) {
882
			fwrite($fd, base64_decode($client['cli_cert'])."\n");
883
			fclose($fd);	
884
		}
885

    
886
		touch ("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem");
887
		chmod ("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem", 0600);
888
		$fd = fopen("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem", "w");
889
		if ($fd) {
890
			fwrite($fd, base64_decode($client['cli_key'])."\n");
891
			fclose($fd);	
892
		}
893
	}
894

    
895
	if ($client['authentication_method'] == "pre_shared_key" || isset($client['tlsauth'])) {
896
		touch ("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem");
897
		chmod ("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem", 0600);
898
		$fd = fopen("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem", "w");
899
		if ($fd) {
900
			fwrite($fd, base64_decode($client['pre-shared-key'])."\n");
901
			fclose($fd);	
902
		}
903
	}
904

    
905
	$fd = fopen("{$g['varetc_path']}/ovpn_cli_{$tun}.conf", "w");
906
	if (!$fd) {
907
		printf("Error: cannot open ovpn_cli_{$tun}.conf in ovpn_cli_config_generate($id).\n");
908
		return 1;
909
	}
910

    
911
	/* Client support in 2.0 is very simple */
912
	$ovpn_config = "";
913
	$ovpn_config .= <<<EOD
914
daemon
915
verb 1
916
status /var/log/openvpn_{$tun}.log 60
917
writepid {$g['varrun_path']}/ovpn_cli_{$tun}.pid
918
dev {$client['if']}
919
lport {$client['cport']}
920
remote {$client['saddr']} {$client['sport']}
921
cipher {$client['crypto']}
922

    
923
EOD;
924

    
925
	/* Version 1.0 compatibility; http://openvpn.net/compat.html */
926
	if ($client['ver'] != "2") {
927
		$ovpn_config .= <<<EOD
928
key-method 1
929
tun-mtu 1500
930
tun-mtu-extra 32
931
mssfix 1450
932

    
933
EOD;
934
	}
935

    
936
	/* Set protocol being used (p = udp (default), tcp-client) */
937
	if ($client['proto'] == "tcp")
938
		$ovpn_config .= "proto tcp-client\n";
939

    
940
	/* TLS-Client params */
941
	if ($client['authentication_method'] != "pre_shared_key") {
942
		$ovpn_config .= <<<EOD
943
ca {$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem
944
cert {$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem
945
key {$g['vardb_path']}/ovpn_cli_key_{$tun}.pem
946

    
947
EOD;
948

    
949
		if (isset($client['pull']))
950
			$ovpn_config .= "client\n";
951
		else
952
			$ovpn_config .= "tls-client\n";
953

    
954
		/* TLS auth */
955
		if (isset($client['ns_cert_type']))
956
			$ovpn_config .= "ns-cert-type server\n";
957

    
958
		/* TLS auth */
959
		if (isset($client['tlsauth']))
960
			$ovpn_config .= "tls-auth {$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem 1\n";
961

    
962
		/* bridging enabled? */
963
		if ($client['bridge'] && $client['type'] == "tap") {
964
			$lastdigits = substr($tun, 3) + 2;
965
			$ovpn_cli_up = "/sbin/ifconfig " . $tun . " 127.0.0." . $lastdigits . "/32\n";
966

    
967
			$fdo = fopen("{$g['varetc_path']}/ovpn_cli_up_{$tun}.sh", "w");
968
			if ($fdo) {
969
				fwrite($fdo, $ovpn_cli_up);
970
				fclose($fdo);   
971
				chmod ("{$g['varetc_path']}/ovpn_cli_up_{$tun}.sh", 0755);
972
				$ovpn_config .= "up /var/etc/ovpn_cli_up_{$tun}.sh\n";
973
			}
974
		}
975

    
976
	} else {
977
		/* 'authentication_method' == "pre_shared_key" */
978
		$ovpn_config .= "secret {$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem 0\n";
979

    
980
		$network = gen_subnet($client['lipaddr'], $client['netmask']);
981
		$netmask = gen_subnet_mask($client['netmask']);
982

    
983
		if (strstr($client['type'], "tap"))
984
			$ovpn_config .= "ifconfig {$client['lipaddr']} {$netmask}\n";
985
		else
986
			$ovpn_config .= "ifconfig {$client['lipaddr']} {$client['ripaddr']}\n";
987

    
988
	} /* end authentication_method */
989

    
990
	/* Expert mode paramters */
991
	if (isset($client['expertmode_enabled']) && is_array($client['expertmode'])) {
992
		$ovpn_config .= ";begin expertmode\n";
993
		foreach ($client['expertmode']['option'] as $option) {
994
			$ovpn_config .= "{$option}\n";
995
		}
996
		$ovpn_config .= ";end expertmode\n";
997
	}
998

    
999
	fwrite($fd, $ovpn_config);
1000
	fclose($fd);
1001

    
1002
	/* trigger_error("OVPN: $ovpn_config", E_USER_NOTICE); */
1003
}
1004

    
1005
/* Define an OVPN tunnel interface in the interfaces array for each client */
1006
function ovpn_client_iface(){
1007
	global $config;
1008
		
1009
	unset($filter_configure);
1010
	unset($bridge_configure);
1011

    
1012
	foreach ($config['ovpn']['client']['tunnel'] as $id => $client) {
1013
		if (isset($client['enable'])) {
1014

    
1015
			/* get tunnel interface */
1016
			$tun = $client['if'];
1017

    
1018
			$i = 1;
1019
			while (true) {
1020
				$ifname = 'opt' . $i;
1021
				if (is_array($config['interfaces'][$ifname])) {
1022
					if ((isset($config['interfaces'][$ifname]['ovpn']))
1023
			     		     && ($config['interfaces'][$ifname]['ovpn'] == "client_{$tun}"))
1024
						/* Already an interface defined - overwrite */
1025
						break;
1026
				} else {
1027

    
1028
					/* No existing entry, this is first unused */
1029
					$config['interfaces'][$ifname] = array();
1030

    
1031
					/* add new filter rules */
1032
					$filter_configure = true;
1033
					break;
1034
				}
1035
				$i++;
1036
			}
1037
			$config['interfaces'][$ifname]['descr'] = strtoupper($client['if']);
1038
			$config['interfaces'][$ifname]['if'] = $client['if'];
1039
			$config['interfaces'][$ifname]['ipaddr'] = "0.0.0.0";
1040
			$config['interfaces'][$ifname]['subnet'] = "0";
1041
			if (isset($client['bridge'])) {
1042
				$config['interfaces'][$ifname]['bridge'] = $client['bridge'];
1043
				$bridge_configure = true;
1044
			} else if (isset($config['interfaces'][$ifname]['bridge'])) {
1045
				/* bridge config removed */
1046
				unset ($config['interfaces'][$ifname]['bridge']);
1047
				$bridge_configure = true;
1048
			}
1049
			$config['interfaces'][$ifname]['enable'] = isset($client['enable']) ? true : false;
1050
			$config['interfaces'][$ifname]['ovpn'] = "client_{$tun}";
1051
			write_config();
1052
		}
1053
	}
1054

    
1055
	/* do we have to reconfigure filter rules? */
1056
	if (isset($bridge_configure))
1057
		interfaces_optional_configure();
1058
	else if (isset($filter_configure))
1059
		filter_configure();
1060

    
1061
	return "OpenVPN client interfaces defined";
1062
}
1063

    
1064
/* Delete a client interface definition */
1065
function ovpn_client_iface_del($tun) {
1066
	global $config;
1067

    
1068
	for ($i = 1; is_array($config['interfaces']['opt' . $i]); $i++) {
1069
		$ifname = 'opt' . $i;
1070
		if ((isset($config['interfaces'][$ifname]['ovpn']))
1071
		     && ($config['interfaces'][$ifname]['if'] == "$tun")) {
1072
			unset($config['interfaces'][$ifname]);
1073
			break;
1074
		}
1075
	}
1076

    
1077
	/* shift down other OPTn interfaces to get rid of holes */
1078
	$i++;
1079

    
1080
	/* look at the following OPTn ports */
1081
	while (is_array($config['interfaces']['opt' . $i])) {
1082
		$config['interfaces']['opt' . ($i - 1)] =
1083
			$config['interfaces']['opt' . $i];
1084

    
1085
		unset($config['interfaces']['opt' . $i]);
1086
		$i++;
1087
	}
1088

    
1089
	/* reconfigure filter rules */
1090
	interfaces_optional_configure();
1091
}
1092

    
1093
/* append interface to ovpndirty_path */
1094
function ovpn_cli_dirty($tun) {
1095
	global $d_ovpnclidirty_path;
1096
	
1097
	$fd = fopen($d_ovpnclidirty_path, 'a');
1098
	if ($fd) {
1099
		fwrite($fd, $tun);
1100
		fclose($fd);
1101
	}
1102
}
1103

    
1104

    
1105
/******************/
1106
/* Misc functions */
1107
/******************/
1108

    
1109
/* find the first available device of type $type */
1110
function getnxt_if($type) {
1111
	global $config;
1112

    
1113
	/* initialize variables */
1114
	$iface_list	= array();
1115
	$max		= ($type == 'tun') ? 17 : 4;
1116

    
1117
	/* construct list of valid interfaces */
1118
	for ($i = 0; $i < $max ; $i++)
1119
		array_push($iface_list, $type . $i);
1120
	
1121
	/* delete interface in use from the list */
1122
	if ($a_server = $config['ovpn']['server']['tunnel']) {
1123
		foreach ($a_server as $server) {
1124
			$entry = array();
1125
			array_push($entry, $server['tun_iface']);
1126
			$iface_list = array_diff($iface_list, $entry);
1127
		}
1128
	}
1129

    
1130
	/* same for list of client tunnels  */
1131
	if ($a_client = $config['ovpn']['client']['tunnel']) {
1132
		foreach ($a_client as $client) {
1133
			$entry = array();
1134
			array_push($entry, $client['if']);
1135
			$iface_list = array_diff($iface_list, $entry);
1136
		}
1137
	}
1138
			
1139
	/* return first element of list, if list of interfaces isn't empty */
1140
	if (count($iface_list))
1141
		return array_shift($iface_list);
1142
	else
1143
		return false;
1144
}
1145

    
1146
/* find the next best available port */
1147
function getnxt_port() {
1148

    
1149
	/* construct list of valid ports */
1150
	$port_list = free_port_list();
1151

    
1152
        /* return first element of list, if list of ports isn't empty */
1153
        if (count($port_list))
1154
                return array_shift($port_list);
1155
        else
1156
                return false;
1157
}
1158

    
1159
/* construct list of free ports */
1160
function free_port_list() {
1161
	global $config;
1162

    
1163
	/* initialize variables */
1164
	$port_list	= array();
1165
	$first_port 	= 1194;
1166
	$max		= $first_port + 21;
1167

    
1168
	for ($i = $first_port; $i < $max; $i++)
1169
		array_push($port_list, $i);
1170
        
1171
        /* delete port in use from the list */
1172
        if ($a_server = $config['ovpn']['server']['tunnel']) {
1173
                foreach ($a_server as $server) {
1174
                        $entry = array();
1175
                        array_push($entry, $server['port']);
1176
                        $port_list = array_diff($port_list, $entry);
1177
                }
1178
        }
1179

    
1180
        /* same for list of client tunnels  */
1181
        if ($a_client = $config['ovpn']['client']['tunnel']) {
1182
                foreach ($a_client as $client) {
1183
                        $entry = array();
1184
                        array_push($entry, $client['cport']);
1185
                        $port_list = array_diff($port_list, $entry);
1186
                }
1187
        }
1188

    
1189
	return $port_list;
1190
}
1191

    
1192
/* construct list of used ports */
1193
function used_port_list() {
1194
	global $config;
1195

    
1196
	/* initialize variables */
1197
	$port_list	= array();
1198

    
1199
        /* add used ports to the list */
1200
        if ($a_server = $config['ovpn']['server']['tunnel']) {
1201
                foreach ($a_server as $server) {
1202
                        if (isset($server['enable']))
1203
				array_push($port_list, $server['port']);
1204
                }
1205
        }
1206

    
1207
        /* same for list of client tunnels  */
1208
        if ($a_client = $config['ovpn']['client']['tunnel']) {
1209
                foreach ($a_client as $client) {
1210
                        if (isset($client['enable']))
1211
                        	array_push($port_list, $client['cport']);
1212
                }
1213
        }
1214

    
1215
	return $port_list;
1216
}
1217

    
1218
/* construct list of bindings used for a specified port */
1219
function used_bind_list($port) {
1220
	global $config;
1221

    
1222
	/* initialize variables */
1223
	$bind_list	= array();
1224

    
1225
        /* add used bindings to the list */
1226
        if ($a_server = $config['ovpn']['server']['tunnel']) {
1227
                foreach ($a_server as $server) {
1228
                        if (isset($server['enable']) && $server['port'] == $port)
1229
				array_push($bind_list, $server['bind_iface']);
1230
                }
1231
        }
1232

    
1233
	/* client daemon always binds to 0.0.0.0 */
1234
	if ($a_client = $config['ovpn']['client']['tunnel']) {
1235
		foreach ($a_client as $client) {
1236
			if (isset($client['enable']) && $client['cport'] == $port)
1237
				array_push($bind_list, "all");
1238
		}
1239
	}
1240

    
1241
	/* return list of bindings */
1242
	return $bind_list;
1243
}
1244

    
1245
/* Calculate the last address in a range given the start and /prefix */
1246
function ovpn_calc_end($start, $prefix){
1247
	$first = ip2long($start);
1248
	$last = pow(2,(32 - $prefix)) - 1 + $first;
1249
	return long2ip($last);
1250
}
1251

    
1252
/* Calculate a mask given a /prefix */
1253
function ovpn_calc_mask($prefix){
1254
	return long2ip(ip2long("255.255.255.255") - (pow( 2, (32 - $prefix)) - 1));
1255
}
1256

    
1257
/* Port in use */
1258
function ovpn_port_inuse_server($port){
1259
	global $config;
1260
	if ($a_server = $config['ovpn']['server']['tunnel']) {
1261
		foreach ($a_server as $server) {
1262
			if ($server['port'] == $port) {
1263
				return true;
1264
			}
1265
		}
1266
	}
1267
	return false;
1268
}
1269

    
1270
/* Read in a file from the $_FILES array */
1271
function ovpn_get_file($file){
1272
	global $g;
1273
	
1274
	if (!is_uploaded_file($_FILES[$file]['tmp_name'])){
1275
		trigger_error("Bad file upload".$_FILES[$file]['error'], E_USER_NOTICE);
1276
		return NULL;
1277
	}
1278
	$contents = file_get_contents($_FILES[$file]['tmp_name']);
1279
	return $contents;
1280
}
1281

    
1282

    
1283
/* Get the IP address of a specified interface */
1284
function ovpn_get_ip($iface){
1285
	global $config;
1286
	
1287
	if ($iface == 'wan')
1288
		return get_current_wan_address();
1289
		
1290
	if ($config['interfaces'][$iface]['bridge'])
1291
		/* No bridging (yet) */
1292
		return false;
1293
	return $config['interfaces'][$iface]['ipaddr'];
1294
}
1295
	
1296
	
1297
/* Get a list of the cipher options supported by OpenVPN */
1298
function ovpn_get_cipher_list(){
1299
	
1300
/*	exec("/usr/local/sbin/openvpn --show-ciphers", $raw);
1301
	print_r ($raw);
1302
	
1303
	$ciphers = preg_grep('/ bit default key /', $raw);
1304
	
1305
	for($i = 0; $i <count($ciphers); $i++){
1306
		$tmp = explode(' ',$ciphers[$i]);
1307
		$cipher_list["$tmp[0]"] = "{$tmp[0]} ({$tmp[1]} {$tmp[2]})";
1308
	}
1309
*/
1310
	$cipher_list = array('DES-CBC' => 'DES-CBC (64 bit)',
1311
			     'RC2-CBC' => 'RC2-CBC (128 bit)',
1312
			     'DES-EDE-CBC' => 'DES-EDE-CBC (128 bit)',
1313
			     'DES-EDE3-CBC' => 'DES-EDE3-CBC (192 bit)',
1314
			     'DESX-CBC' => 'DESX-CBC (192 bit)',
1315
			     'BF-CBC' => 'BF-CBC (128 bit)',
1316
			     'RC2-40-CBC' => 'RC2-40-CBC (40 bit)',
1317
			     'CAST5-CBC' => 'CAST5-CBC (128 bit)',
1318
			     'RC5-CBC' => 'RC5-CBC (128 bit)',
1319
			     'RC2-64-CBC' => 'RC2-64-CBC (64 bit)',
1320
			     'AES-128-CBC' => 'AES-128-CBC (128 bit)',
1321
			     'AES-192-CBC' => 'AES-192-CBC (192 bit)',
1322
			     'AES-256-CBC' => 'AES-256-CBC (256 bit)');
1323
	return $cipher_list;
1324
}
1325
		
1326
	
1327
/* Get optional interface */
1328
/* needs tunneling interface (tun0, tun1, tap0, ...) */
1329
/* returns optional interface name (opt2, opt3, ...) */
1330
function ovpn_get_opt_interface($tun){
1331
	global $config;
1332

    
1333
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
1334
		$ifname = 'opt' . $i;
1335

    
1336
		if (isset($config['interfaces']['opt' . $i]['ovpn']))
1337
			if ($config['interfaces'][$ifname]['if'] == "$tun")
1338
				 return $ifname;
1339
	}
1340
	/* not found? */
1341
	return false;
1342
}
1343

    
1344
/* Build a list of the current real interfaces */
1345
function ovpn_real_interface_list(){
1346
	global $config;
1347
	
1348
	$interfaces = array('all' => 'ALL',
1349
			    'lan' => 'LAN',
1350
			    'wan' => 'WAN');
1351
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
1352
		if (isset($config['interfaces']['opt' . $i]['ovpn']))
1353
			/* Hide our own interface */
1354
			break;
1355
		if (isset($config['interfaces']['opt' . $i]['enable']))
1356
			$interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
1357
	}
1358
	return $interfaces;
1359
}
1360

    
1361
/* called by interfaces_opt.php */
1362
function ovpn_ccd_sort() {
1363
	global $g, $config;
1364

    
1365
	function ccdcmp($a, $b) {
1366
		return strcmp($a['cn'][0], $b['cn'][0]);
1367
	}
1368

    
1369
	usort($config['ovpn']['server']['ccd'], "ccdcmp");
1370

    
1371
}
1372

    
1373
/* called by interfaces_opt.php */
1374
function ovpn_config_post() {
1375
	global $_POST, $optcfg, $pconfig;
1376
	
1377
	unset($input_errors);
1378

    
1379
	/* bridge check */
1380
	if ($_POST['bridge'] && strstr($optcfg['if'], "tun"))
1381
		$input_errors[] = "Bridging a tun interface isn't possible.";
1382

    
1383
	if (($_POST['enable'] && !isset($optcfg['enable'])) || (!$_POST['enable'] && isset($optcfg['enable'])))
1384
		$input_errors[] = "Enabling or disabling a tunneling interface isn't supported on this page.";
1385

    
1386
	if ($_POST['ipaddr'] != $optcfg['ipaddr']) 
1387
		$input_errors[] = "Changing the IP address of a tunneling interfaces isn't supported on this page.";
1388

    
1389
	if ($_POST['subnet'] != $optcfg['subnet']) 
1390
		$input_errors[] = "Changing the subnet mask of a tunneling interfaces isn't supported on this page.";
1391

    
1392
	if ($input_errors) {
1393
		$pconfig['ipaddr'] = $optcfg['ipaddr'];
1394
		$pconfig['subnet'] = $optcfg['subnet'];
1395
		$pconfig['bridge'] = $optcfg['bridge'];
1396
		$pconfig['enable'] = isset($optcfg['enable']);
1397
	}
1398

    
1399
	return $input_errors;
1400
}
1401

    
1402
function check_bridging($bridge) {
1403
	global $config;
1404
	unset($input_errors);
1405

    
1406
	/* double bridging? */
1407
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) { 
1408
		if ($i != $index) {
1409
			if ($config['interfaces']['opt' . $i]['bridge'] == $bridge) {
1410
				$input_errors = "Optional interface {$i} " . 
1411
				  "({$config['interfaces']['opt' . $i]['descr']}) is already bridged to " .
1412
				  "the specified interface.";
1413
			} else if ($config['interfaces']['opt' . $i]['bridge'] == "opt{$index}") {
1414
				$input_errors = "Optional interface {$i} " . 
1415
				  "({$config['interfaces']['opt' . $i]['descr']}) is already bridged to " .
1416
				  "this interface.";
1417
			}
1418
		}
1419
	}
1420

    
1421
	if ($config['interfaces'][$bridge]['bridge'])
1422
		$input_errors = "The specified interface is already bridged to another interface.";
1423

    
1424
	return $input_errors;
1425
}
1426

    
1427
/*
1428
function is_specialnet($net) {
1429
	$specialsrcdst = explode(" ", "lan");
1430
	        
1431
	if (in_array($net, $specialsrcdst))
1432
		return true;
1433
	else
1434
		return false;
1435
}
1436
*/
1437

    
1438
	
1439
/* lock openvpn information, decide that the lock file is stale after
1440
   10 seconds */
1441
function ovpn_lock() {
1442
	
1443
	global $g;
1444
	
1445
	$lockfile = "{$g['varrun_path']}/ovpn.lock";
1446
	
1447
	$n = 0;
1448
	while ($n < 10) {
1449
		/* open the lock file in append mode to avoid race condition */
1450
		if ($fd = fopen($lockfile, "x")) {
1451
			/* succeeded */
1452
			fclose($fd);
1453
			return;
1454
		} else {
1455
			/* file locked, wait and try again */
1456
			sleep(1);
1457
			$n++;
1458
		}
1459
	}
1460
}
1461

    
1462
/* unlock configuration file */
1463
function ovpn_unlock() {
1464
	
1465
	global $g;
1466
	
1467
	$lockfile = "{$g['varrun_path']}/ovpn.lock";
1468
	
1469
	if (file_exists($lockfile))
1470
		unlink($lockfile);
1471
}
1472

    
1473
?>
(11-11/24)