Project

General

Profile

Feature #12522 » openvpn_enhanced_overrides_master.patch

Phil Wardt, 04/11/2022 04:07 AM

View differences:

src/usr/local/www/vpn_openvpn_csc.php
35 35
require_once("pkg-utils.inc");
36 36

  
37 37
global $openvpn_tls_server_modes;
38
global $openvpn_topologies;
39
global $openvpn_ping_action, $openvpn_default_keepalive_interval, $openvpn_default_keepalive_timeout;
38 40

  
41
// check if submitted form field is not empty
42
function empty_field($str) {
43
	$has_text = !is_bool($str) && strlen($str) > 0;
44
	return !$has_text;
45
}
46

  
39 47
init_config_arr(array('openvpn', 'openvpn-csc'));
40 48
$a_csc = &$config['openvpn']['openvpn-csc'];
41 49
init_config_arr(array('openvpn', 'openvpn-server'));
......
64 72
		exit;
65 73
	}
66 74

  
67
	if (!$user_can_edit_advanced && !empty($a_csc[$id]['custom_options'])) {
75
	if (!$user_can_edit_advanced && !empty_field($a_csc[$id]['custom_options'])) {
68 76
		$input_errors[] = gettext("This user does not have sufficient privileges to delete an instance with Advanced options set.");
69 77
	} else {
70 78
		$wc_msg = sprintf(gettext('Deleted OpenVPN client specific override %1$s %2$s'), $a_csc[$id]['common_name'], $a_csc[$id]['description']);
......
86 94

  
87 95
		$pconfig['tunnel_network'] = $a_csc[$id]['tunnel_network'];
88 96
		$pconfig['tunnel_networkv6'] = $a_csc[$id]['tunnel_networkv6'];
97

  
98
		$pconfig['push_reset'] = $a_csc[$id]['push_reset'];
99
		$pconfig['topology_override'] = $a_csc[$id]['topology_override'];
100
		$pconfig['topology'] = $a_csc[$id]['topology'];
101
		$pconfig['remove_route'] = $a_csc[$id]['remove_route'];
102
		$pconfig['remove_iroute'] = $a_csc[$id]['remove_iroute'];
103
		$pconfig['remove_dnsdomain'] = $a_csc[$id]['remove_dnsdomain'];
104
		$pconfig['remove_dnsservers'] = $a_csc[$id]['remove_dnsservers'];
105
		$pconfig['remove_ntpservers'] = $a_csc[$id]['remove_ntpservers'];
106
		$pconfig['remove_netbios_ntype'] = $a_csc[$id]['remove_netbios_ntype'];
107
		$pconfig['remove_netbios_scope'] = $a_csc[$id]['remove_netbios_scope'];
108
		$pconfig['remove_wins'] = $a_csc[$id]['remove_wins'];
109

  
110
		if ($pconfig['push_reset'] ||
111
				$pconfig['topology_override'] ||
112
				$pconfig['remove_route'] ||
113
				$pconfig['remove_iroute'] ||
114
				$pconfig['remove_dnsdomain'] ||
115
				$pconfig['remove_dnsservers'] ||
116
				$pconfig['remove_ntpservers'] ||
117
				$pconfig['remove_netbios_ntype'] ||
118
				$pconfig['remove_netbios_scope'] ||
119
				$pconfig['remove_wins']) {
120
			$pconfig['server_overrides_enabled'] = true;
121
		}
122

  
123
		$pconfig['gwredir'] = $a_csc[$id]['gwredir'];
124
		$pconfig['gwredir6'] = $a_csc[$id]['gwredir6'];
89 125
		$pconfig['local_network'] = $a_csc[$id]['local_network'];
90 126
		$pconfig['local_networkv6'] = $a_csc[$id]['local_networkv6'];
127
		$pconfig['gateway'] = $a_csc[$id]['gateway'];
128
		//$pconfig['gateway6'] = $a_csc[$id]['gateway6'];
129

  
91 130
		$pconfig['remote_network'] = $a_csc[$id]['remote_network'];
92 131
		$pconfig['remote_networkv6'] = $a_csc[$id]['remote_networkv6'];
93
		$pconfig['gwredir'] = $a_csc[$id]['gwredir'];
94 132

  
95
		$pconfig['push_reset'] = $a_csc[$id]['push_reset'];
96
		$pconfig['remove_route'] = $a_csc[$id]['remove_route'];
133
		$pconfig['ping_push'] = $a_csc[$id]['ping_push'];
134
		$pconfig['ping_seconds'] = $a_csc[$id]['ping_seconds'];
135
		$pconfig['ping_action_push'] = $a_csc[$id]['ping_action_push'];
136
		$pconfig['ping_action'] = $a_csc[$id]['ping_action'];
137
		$pconfig['ping_action_seconds'] = $a_csc[$id]['ping_action_seconds'];
97 138

  
98 139
		$pconfig['dns_domain'] = $a_csc[$id]['dns_domain'];
99
		if ($pconfig['dns_domain']) {
140
		if (!empty_field($pconfig['dns_domain'])) {
100 141
			$pconfig['dns_domain_enable'] = true;
101 142
		}
102 143

  
......
105 146
		$pconfig['dns_server3'] = $a_csc[$id]['dns_server3'];
106 147
		$pconfig['dns_server4'] = $a_csc[$id]['dns_server4'];
107 148

  
108
		if ($pconfig['dns_server1'] ||
109
		    $pconfig['dns_server2'] ||
110
		    $pconfig['dns_server3'] ||
111
		    $pconfig['dns_server4']) {
149
		if (!empty_field($pconfig['dns_server1']) ||
150
				!empty_field($pconfig['dns_server2']) ||
151
				!empty_field($pconfig['dns_server3']) ||
152
				!empty_field($pconfig['dns_server4'])) {
112 153
			$pconfig['dns_server_enable'] = true;
113 154
		}
114 155

  
156
		$pconfig['push_blockoutsidedns'] = $a_csc[$id]['push_blockoutsidedns'];
157
		$pconfig['push_register_dns'] = $a_csc[$id]['push_register_dns'];
158

  
115 159
		$pconfig['ntp_server1'] = $a_csc[$id]['ntp_server1'];
116 160
		$pconfig['ntp_server2'] = $a_csc[$id]['ntp_server2'];
117 161

  
118
		if ($pconfig['ntp_server1'] ||
119
		    $pconfig['ntp_server2']) {
162
		if (!empty_field($pconfig['ntp_server1']) ||
163
				!empty_field($pconfig['ntp_server2'])) {
120 164
			$pconfig['ntp_server_enable'] = true;
121 165
		}
122 166

  
......
127 171
		$pconfig['wins_server1'] = $a_csc[$id]['wins_server1'];
128 172
		$pconfig['wins_server2'] = $a_csc[$id]['wins_server2'];
129 173

  
130
		if ($pconfig['wins_server1'] ||
131
		    $pconfig['wins_server2']) {
174
		if (!empty_field($pconfig['wins_server1']) ||
175
				!empty_field($pconfig['wins_server2'])) {
132 176
			$pconfig['wins_server_enable'] = true;
133 177
		}
134 178

  
135 179
		$pconfig['nbdd_server1'] = $a_csc[$id]['nbdd_server1'];
136
		if ($pconfig['nbdd_server1']) {
180
		if (!empty_field($pconfig['nbdd_server1'])) {
137 181
			$pconfig['nbdd_server_enable'] = true;
138 182
		}
139 183
	}
......
155 199
	    !$user_can_edit_advanced) {
156 200
		$input_errors[] = gettext("This user does not have sufficient privileges to edit Advanced options on this instance.");
157 201
	}
158
	if (!$user_can_edit_advanced && !empty($a_csc[$id]['custom_options'])) {
202
	if (!$user_can_edit_advanced && !empty_field($a_csc[$id]['custom_options'])) {
203
		// restore custom options field to its original value
159 204
		$pconfig['custom_options'] = $a_csc[$id]['custom_options'];
160 205
	}
161 206

  
......
171 216
		}
172 217
	}
173 218

  
174
	if (!empty($pconfig['tunnel_network']) && !openvpn_validate_tunnel_network($pconfig['tunnel_network'], 'ipv4')) {
219
	if (!empty_field($pconfig['tunnel_network']) && !openvpn_validate_tunnel_network($pconfig['tunnel_network'], 'ipv4')) {
175 220
		$input_errors[] = gettext("The field 'IPv4 Tunnel Network' must contain a valid IPv4 subnet with CIDR mask or an alias with a single IPv4 subnet with CIDR mask.");
176 221
	}
177 222

  
178
	if (!empty($pconfig['tunnel_networkv6']) && !openvpn_validate_tunnel_network($pconfig['tunnel_networkv6'], 'ipv6')) {
223
	if (!empty_field($pconfig['tunnel_networkv6']) && !openvpn_validate_tunnel_network($pconfig['tunnel_networkv6'], 'ipv6')) {
179 224
		$input_errors[] = gettext("The field 'IPv6 Tunnel Network' must contain a valid IPv6 prefix or an alias with a single IPv6 prefix.");
180 225
	}
181 226

  
182
	if ($result = openvpn_validate_cidr($pconfig['local_network'], 'IPv4 Local Network', true, "ipv4", true)) {
227
	if ($pconfig['server_overrides_enabled'] && $pconfig['topology_override'] && !array_key_exists($pconfig['topology'], $openvpn_topologies)) {
228
		$input_errors[] = gettext("The field 'Topology' contains an invalid selection");
229
	}
230

  
231
	if (!$pconfig['gwredir'] && ($result = openvpn_validate_cidr($pconfig['local_network'], 'IPv4 Local Network', true, "ipv4", true))) {
183 232
		$input_errors[] = $result;
184 233
	}
185 234

  
186
	if ($result = openvpn_validate_cidr($pconfig['local_networkv6'], 'IPv6 Local Network', true, "ipv6", true)) {
235
	if (!$pconfig['gwredir6'] && ($result = openvpn_validate_cidr($pconfig['local_networkv6'], 'IPv6 Local Network', true, "ipv6", true))) {
187 236
		$input_errors[] = $result;
188 237
	}
189 238

  
239
	if (!empty_field($pconfig['gateway']) && !is_ipaddrv4($pconfig['gateway'])) {
240
		$input_errors[] = gettext("A valid IPv4 address must be specified for the gateway.");
241
	}
242

  
243
	/*
244
	if (!empty_field($pconfig['gateway6']) && !is_ipaddrv6($pconfig['gateway6'])) {
245
		$input_errors[] = gettext("A valid IPv6 address must be specified for the gateway.");
246
	}
247
	*/
248

  
190 249
	if ($result = openvpn_validate_cidr($pconfig['remote_network'], 'IPv4 Remote Network', true, "ipv4", true)) {
191 250
		$input_errors[] = $result;
192 251
	}
......
195 254
		$input_errors[] = $result;
196 255
	}
197 256

  
257
	if ($pconfig['ping_push'] && !is_numericint($pconfig['ping_seconds'])) {
258
		$input_errors[] = gettext("The supplied Ping Seconds value is invalid.");
259
	}
260
	if ($pconfig['ping_action_push'] && !array_key_exists($pconfig['ping_action'], $openvpn_ping_action)) {
261
		$input_errors[] = gettext("The field 'Ping Action' contains an invalid selection");
262
	}
263
	if ($pconfig['ping_action_push'] && !is_numericint($pconfig['ping_action_seconds'])) {
264
		$input_errors[] = gettext("The supplied Ping Restart or Exit Seconds value is invalid.");
265
	}
266

  
198 267
	if ($pconfig['dns_server_enable']) {
199
		if (!empty($pconfig['dns_server1']) && !is_ipaddr(trim($pconfig['dns_server1']))) {
268
		if (!empty_field($pconfig['dns_server1']) && !is_ipaddr(trim($pconfig['dns_server1']))) {
200 269
			$input_errors[] = gettext("The field 'DNS Server #1' must contain a valid IP address");
201 270
		}
202
		if (!empty($pconfig['dns_server2']) && !is_ipaddr(trim($pconfig['dns_server2']))) {
271
		if (!empty_field($pconfig['dns_server2']) && !is_ipaddr(trim($pconfig['dns_server2']))) {
203 272
			$input_errors[] = gettext("The field 'DNS Server #2' must contain a valid IP address");
204 273
		}
205
		if (!empty($pconfig['dns_server3']) && !is_ipaddr(trim($pconfig['dns_server3']))) {
274
		if (!empty_field($pconfig['dns_server3']) && !is_ipaddr(trim($pconfig['dns_server3']))) {
206 275
			$input_errors[] = gettext("The field 'DNS Server #3' must contain a valid IP address");
207 276
		}
208
		if (!empty($pconfig['dns_server4']) && !is_ipaddr(trim($pconfig['dns_server4']))) {
277
		if (!empty_field($pconfig['dns_server4']) && !is_ipaddr(trim($pconfig['dns_server4']))) {
209 278
			$input_errors[] = gettext("The field 'DNS Server #4' must contain a valid IP address");
210 279
		}
211 280
	}
212 281

  
213 282
	if ($pconfig['ntp_server_enable']) {
214
		if (!empty($pconfig['ntp_server1']) && !is_ipaddr(trim($pconfig['ntp_server1']))) {
283
		if (!empty_field($pconfig['ntp_server1']) && !is_ipaddr(trim($pconfig['ntp_server1']))) {
215 284
			$input_errors[] = gettext("The field 'NTP Server #1' must contain a valid IP address");
216 285
		}
217
		if (!empty($pconfig['ntp_server2']) && !is_ipaddr(trim($pconfig['ntp_server2']))) {
286
		if (!empty_field($pconfig['ntp_server2']) && !is_ipaddr(trim($pconfig['ntp_server2']))) {
218 287
			$input_errors[] = gettext("The field 'NTP Server #2' must contain a valid IP address");
219 288
		}
220
		if (!empty($pconfig['ntp_server3']) && !is_ipaddr(trim($pconfig['ntp_server3']))) {
289
		if (!empty_field($pconfig['ntp_server3']) && !is_ipaddr(trim($pconfig['ntp_server3']))) {
221 290
			$input_errors[] = gettext("The field 'NTP Server #3' must contain a valid IP address");
222 291
		}
223
		if (!empty($pconfig['ntp_server4']) && !is_ipaddr(trim($pconfig['ntp_server4']))) {
292
		if (!empty_field($pconfig['ntp_server4']) && !is_ipaddr(trim($pconfig['ntp_server4']))) {
224 293
			$input_errors[] = gettext("The field 'NTP Server #4' must contain a valid IP address");
225 294
		}
226 295
	}
227 296

  
228 297
	if ($pconfig['netbios_enable']) {
229 298
		if ($pconfig['wins_server_enable']) {
230
			if (!empty($pconfig['wins_server1']) && !is_ipaddr(trim($pconfig['wins_server1']))) {
299
			if (!empty_field($pconfig['wins_server1']) && !is_ipaddr(trim($pconfig['wins_server1']))) {
231 300
				$input_errors[] = gettext("The field 'WINS Server #1' must contain a valid IP address");
232 301
			}
233
			if (!empty($pconfig['wins_server2']) && !is_ipaddr(trim($pconfig['wins_server2']))) {
302
			if (!empty_field($pconfig['wins_server2']) && !is_ipaddr(trim($pconfig['wins_server2']))) {
234 303
				$input_errors[] = gettext("The field 'WINS Server #2' must contain a valid IP address");
235 304
			}
236 305
		}
237 306
		if ($pconfig['nbdd_server_enable']) {
238
			if (!empty($pconfig['nbdd_server1']) && !is_ipaddr(trim($pconfig['nbdd_server1']))) {
307
			if (!empty_field($pconfig['nbdd_server1']) && !is_ipaddr(trim($pconfig['nbdd_server1']))) {
239 308
				$input_errors[] = gettext("The field 'NetBIOS Data Distribution Server #1' must contain a valid IP address");
240 309
			}
241 310
		}
......
269 338
		foreach (array('', 'v6') as $ntype) {
270 339
			$csc["tunnel_network{$ntype}"] = openvpn_tunnel_network_fix($pconfig["tunnel_network{$ntype}"]);
271 340
		}
341

  
342
		if ($pconfig['server_overrides_enabled']) {
343
			$csc['push_reset'] = $pconfig['push_reset'];
344
			if (!$pconfig['push_reset']) {
345
				$csc['remove_route'] = $pconfig['remove_route'];
346
				$csc['remove_iroute'] = $pconfig['remove_iroute'];
347
				$csc['remove_dnsdomain'] = $pconfig['remove_dnsdomain'];
348
				$csc['remove_dnsservers'] = $pconfig['remove_dnsservers'];
349
				$csc['remove_ntpservers'] = $pconfig['remove_ntpservers'];
350
				$csc['remove_netbios_ntype'] = $pconfig['remove_netbios_ntype'];
351
				$csc['remove_netbios_scope'] = $pconfig['remove_netbios_scope'];
352
				$csc['remove_wins'] = $pconfig['remove_wins'];
353
			}
354

  
355
			$csc['topology_override'] = $pconfig['topology_override'];
356
			if ($pconfig['topology_override']) {
357
				$csc['topology'] = $pconfig['topology'];
358
			}
359
		}
360

  
361
		$csc['gwredir'] = $pconfig['gwredir'];
362
		if (!$pconfig['gwredir']) {
272 363
			$csc['local_network'] = $pconfig['local_network'];
364
		}
365

  
366
		$csc['gwredir6'] = $pconfig['gwredir6'];
367
		if (!$pconfig['gwredir6']) {
273 368
			$csc['local_networkv6'] = $pconfig['local_networkv6'];
369
		}
370

  
371
		$csc['gateway'] = $pconfig['gateway'];
372
		//$csc['gateway6'] = $pconfig['gateway6'];
373

  
274 374
		$csc['remote_network'] = $pconfig['remote_network'];
275 375
		$csc['remote_networkv6'] = $pconfig['remote_networkv6'];
276
		$csc['gwredir'] = $pconfig['gwredir'];
277
		$csc['push_reset'] = $pconfig['push_reset'];
278
		$csc['remove_route'] = $pconfig['remove_route'];
279 376

  
377
		$csc['ping_push'] = $pconfig['ping_push'];
378
		if ($pconfig['ping_push']) {
379
			$csc['ping_seconds'] = $pconfig['ping_seconds'];
380
		}
381
		$csc['ping_action_push'] = $pconfig['ping_action_push'];
382
		if ($pconfig['ping_action_push']) {
383
			$csc['ping_action'] = $pconfig['ping_action'];
384
			$csc['ping_action_seconds'] = $pconfig['ping_action_seconds'];
385
		}
386

  
280 387
		if ($pconfig['dns_domain_enable']) {
281 388
			$csc['dns_domain'] = $pconfig['dns_domain'];
282 389
		}
......
288 395
			$csc['dns_server4'] = $pconfig['dns_server4'];
289 396
		}
290 397

  
398
		$csc['push_blockoutsidedns'] = $pconfig['push_blockoutsidedns'];
399
		$csc['push_register_dns'] = $pconfig['push_register_dns'];
400

  
291 401
		if ($pconfig['ntp_server_enable']) {
292 402
			$csc['ntp_server1'] = $pconfig['ntp_server1'];
293 403
			$csc['ntp_server2'] = $pconfig['ntp_server2'];
......
323 433
			$wc_msg = sprintf(gettext('Added OpenVPN client specific override %1$s %2$s'), $csc['common_name'], $csc['description']);
324 434
		}
325 435

  
326
		if (!empty($old_csc['common_name'])) {
436
		if (!empty_field($old_csc['common_name'])) {
327 437
			openvpn_delete_csc($old_csc);
328 438
		}
329 439
		openvpn_resync_csc($csc);
......
406 516
		true
407 517
		))->setHelp('Select the servers that will utilize this override. When no servers are selected, the override will apply to all servers.');
408 518

  
519
	// Override server client options
520
	$section->addInput(new Form_Checkbox(
521
		'server_overrides_enabled',
522
		'Select Server Overrides',
523
		'Select server options to remove.',
524
		$pconfig['server_overrides_enabled']
525
	))->setHelp('If unchecked, any client options specified in below form or Advanced section will be pushed to the client after the server options.%1$s' .
526
			'If checked, you can select the server options you want to remove. Any specified client option in below form or Advanced section will thus override the corresponding server-defined options.',
527
			'<br />');
528

  
529
	$section->addInput(new Form_Checkbox(
530
		'push_reset',
531
		null,
532
		'Remove All Server Options',
533
		$pconfig['push_reset']
534
	))->setHelp('Prevent this client from receiving any server-defined client settings.%1$s' .
535
			'This option will send a push-reset to the client. It will thus remove any server-defined routes, the gateway and topology.%1$s' .
536
			'For the client to properly connect, you will need to enter at least the gateway and topology in the below form or in Advanced section.',
537
			'<br />');
538

  
539
	$section->addInput(new Form_Checkbox(
540
		'topology_override',
541
		null,
542
		'Override Server Topology',
543
		$pconfig['topology_override']
544
	));
545

  
546
	$section->addInput(new Form_Select(
547
		'topology',
548
		null,
549
		$pconfig['topology'],
550
		$openvpn_topologies
551
	))->setHelp('This will push the selected topology to the client. It should only be set when option "Remove All Server Options" is checked. It must match the actual topology specified in server.%1$s' .
552
			'NOTE: This will perform a "push topology [selection]" without a previous "push-remove topology". Alternetively you can push the topology in Advanced section.',
553
			'<br />');
554

  
555
	/* as "push-reset" can break subnet topology, 
556
	 * "push-remove route" removes only IPv4/IPv6 routes, see #9702 */
557
	$section->addInput(new Form_Checkbox(
558
		'remove_route',
559
		null,
560
		'Remove Server Local Routes',
561
		$pconfig['remove_route']
562
	))->setHelp('Prevent this client from receiving any server-defined local routes.%1$s' .
563
			'This option will send a "push-remove route" to the client, removing any server-defined ipv4 or ipv6 local routes, including the gateway.%1$s' .
564
			'NOTE: Remember to either enter the proper gateway and any additional local routes in the below form or in Advanced section.',
565
			'<br />');
566

  
567
	$section->addInput(new Form_Checkbox(
568
		'remove_iroute',
569
		null,
570
		'Remove Server Remote Routes',
571
		$pconfig['remove_iroute']
572
	))->setHelp('Prevent this client from receiving any server-defined remote routes.%1$s' .
573
			'This option will send a "push-remove iroute" to the client, removing any server-defined ipv4 or ipv6 remote routes%1$s' .
574
			'NOTE: You can set new client specific remote routes in below form or in Advanced section.',
575
			'<br />');
576

  
577
	$section->addInput(new Form_Checkbox(
578
		'remove_dnsdomain',
579
		null,
580
		'Remove Server DNS Domains',
581
		$pconfig['remove_dnsdomain']
582
	))->setHelp('Prevent this client from receiving any server-defined remote DNS domains.%1$s' .
583
			'This option will send a "push-remove dhcp-option DOMAIN" to the client, removing any server-defined DNS domains.%1$s' .
584
			'NOTE: You can set new client specific DNS domain in below form or in Advanced section.',
585
			'<br />');
586

  
587
	$section->addInput(new Form_Checkbox(
588
		'remove_dnsservers',
589
		null,
590
		'Remove Server DNS Servers',
591
		$pconfig['remove_dnsservers']
592
	))->setHelp('Prevent this client from receiving any server-defined DNS Servers.%1$s' .
593
			'This option will send a "push-remove dhcp-option DNS" to the client, removing any server-defined ipv4 or ipv6 DNS servers.%1$s' .
594
			'NOTE: You can set new client specific DNS servers in below form or in Advanced section.',
595
			'<br />');
596

  
597
	$section->addInput(new Form_Checkbox(
598
		'remove_ntpservers',
599
		null,
600
		'Remove Server NTP Options.',
601
		$pconfig['remove_ntpservers']
602
	))->setHelp('Prevent this client from receiving any server-defined NTP Servers.%1$s' .
603
			'This option will send a "push-remove dhcp-option NTP" to the client, removing any server-defined NTP servers.%1$s' .
604
			'NOTE: You can set new client specific NTP servers in below form or in Advanced section.',
605
			'<br />');
606

  
607
	$section->addInput(new Form_Checkbox(
608
		'remove_netbios_ntype',
609
		null,
610
		'Remove Server Netbios Type',
611
		$pconfig['remove_netbios_ntype']
612
	))->setHelp('Prevent this client from receiving any server-defined Netbios Node Type.%1$s' .
613
			'This option will send a "push-remove dhcp-option NBT" to the client, removing any server-defined Netbios Node Type.%1$s' .
614
			'NOTE: You can set new client specific Netbios options in below form or in Advanced section.',
615
			'<br />');
616

  
617
	$section->addInput(new Form_Checkbox(
618
		'remove_netbios_scope',
619
		null,
620
		'Remove Server Netbios Scope',
621
		$pconfig['remove_netbios_scope']
622
	))->setHelp('Prevent this client from receiving any server-defined Netbios Scope.%1$s' .
623
			'This option will send a "push-remove dhcp-option NBS" to the client, removing any server-defined Netbios Scope.%1$s' .
624
			'NOTE: You can set new client specific Netbios Scope in below form or in Advanced section.',
625
			'<br />');
626

  
627
	$section->addInput(new Form_Checkbox(
628
		'remove_wins',
629
		null,
630
		'Remove Server WINS Options',
631
		$pconfig['remove_wins']
632
	))->setHelp('Prevent this client from receiving any server-defined WINS servers.%1$s' .
633
			'This option will send a "push-remove dhcp-option WINS" to the client, removing any server-defined WINS servers.%1$s' .
634
			'NOTE: You can set new client specific WINS servers in below form or in Advanced section.',
635
			'<br />');
636

  
409 637
	$form->add($section);
410 638

  
411 639
	$section = new Form_Section('Tunnel Settings');
......
429 657
			'Enter the client IPv6 address and prefix. The prefix must match the IPv6 Tunnel Network prefix on the server. ',
430 658
			'<br />');
431 659

  
660
	$form->add($section);
661

  
662
	$section = new Form_Section('Local Routes Settings');
663

  
664
	$section->addInput(new Form_Checkbox(
665
		'gwredir',
666
		'Redirect IPv4 Gateway',
667
		'Force all client generated traffic through the tunnel.',
668
		$pconfig['gwredir']
669
	));
670

  
671
	$section->addInput(new Form_Checkbox(
672
		'gwredir6',
673
		'Redirect IPv6 Gateway',
674
		'Force all client-generated IPv6 traffic through the tunnel.',
675
		$pconfig['gwredir6']
676
	));
677

  
432 678
	$section->addInput(new Form_Input(
433 679
		'local_network',
434 680
		'IPv4 Local Network/s',
......
448 694
			'<br />');
449 695

  
450 696
	$section->addInput(new Form_Input(
697
		'gateway',
698
		'IPv4 Gateway',
699
		'text',
700
		$pconfig['gateway']
701
	))->setHelp('This is the IPv4 Gateway to push to the client. Normally it is left blank and configured on the server. ' .
702
			'The gateway IP should be entered if any of the options "Remove Server Local Routes" or "Remove All Server Options" is checked, ' .
703
			'as these 2 options will remove the gateway defined on the server and connection from the client will likely fail.%1$s' .
704
			'NOTE: Remember that, unless configured specifically, the gateway should match the IPv4 Tunnel gateway configured on the selected OpenVPN servers settings.',
705
			'<br />');
706

  
707
	/*
708
	$section->addInput(new Form_Input(
709
		'gateway6',
710
		'IPv6 Gateway',
711
		'text',
712
		$pconfig['gateway6']
713
	))->setHelp('This is the IPv6 Gateway to push to the client. Normally it is left blank and configured on the server. ' .
714
			'The gateway IP should be entered if any of the options "Remove Server Local Routes" or "Remove All Server Options" is checked, ' .
715
			'as these 2 options will remove the gateway defined on the server and connection from the client will likely fail.%1$s' .
716
			'NOTE: Remember that, unless configured specifically, the gateway should match the IPv4 Tunnel gateway configured on the selected OpenVPN servers settings.',
717
			'<br />');
718
	*/
719

  
720
	$form->add($section);
721

  
722
	$section = new Form_Section('Remote Routes Settings');
723

  
724
	$section->addInput(new Form_Input(
451 725
		'remote_network',
452 726
		'IPv4 Remote Network/s',
453 727
		'text',
......
467 741
		    'NOTE: Remember to add these subnets to the IPv6 Remote Networks list on the corresponding OpenVPN server settings.',
468 742
			'<br />');
469 743

  
470
	$section->addInput(new Form_Checkbox(
471
		'gwredir',
472
		'Redirect Gateway',
473
		'Force all client generated traffic through the tunnel.',
474
		$pconfig['gwredir']
475
	));
476

  
477 744
	$form->add($section);
478 745

  
479
	$section = new Form_Section('Client Settings');
746
	$section = new Form_Section('Other Client Settings');
480 747

  
481 748
	$section->addInput(new Form_Checkbox(
482
		'push_reset',
483
		'Server Definitions',
484
		'Prevent this client from receiving any server-defined client settings. ',
485
		$pconfig['push_reset']
486
	));
749
		'ping_push',
750
		'Ping Interval',
751
		'Push ping to VPN client',
752
		$pconfig['ping_push']
753
	))->setHelp('Override server ping interval.%1$s',
754
				'<br />');
487 755

  
488
	/* as "push-reset" can break subnet topology, 
489
	 * "push-remove route" removes only IPv4/IPv6 routes, see #9702 */
756
	$section->addInput(new Form_Input(
757
		'ping_seconds',
758
		'Ping Seconds',
759
		'number',
760
		$pconfig['ping_seconds'] ?: $openvpn_default_keepalive_interval,
761
		['min' => '0']
762
	))->setHelp('Ping remote over the TCP/UDP control channel if no ' .
763
	    'packets have been sent for at least n seconds.%1$s',
764
	    '<br />');
765

  
490 766
	$section->addInput(new Form_Checkbox(
491
		'remove_route',
492
		'Remove Server Routes',
493
		'Prevent this client from receiving any server-defined routes without removing any other options. ',
494
		$pconfig['remove_route']
767
		'ping_action_push',
768
		'Ping Action',
769
		'Push ping-restart/ping-exit to VPN client',
770
		$pconfig['ping_action_push']
771
	))->setHelp('Override server ping restart/exit.%1$s',
772
				'<br />');
773

  
774
	$section->addInput(new Form_Select(
775
		'ping_action',
776
		'Ping restart or exit',
777
		$pconfig['ping_action'],
778
		$openvpn_ping_action
779
	))->setHelp('Exit or restart OpenVPN after timeout from remote.%1$s',
780
				'<br />');
781

  
782
	$section->addInput(new Form_Input(
783
		'ping_action_seconds',
784
		'Ping restart or exit seconds',
785
		'number',
786
		$pconfig['ping_action_seconds']
787
		    ?: $openvpn_default_keepalive_timeout,
788
		['min' => '0']
495 789
	));
496 790

  
497 791
	$section->addInput(new Form_Checkbox(
......
499 793
		'DNS Default Domain',
500 794
		'Provide a default domain name to clients',
501 795
		$pconfig['dns_domain_enable']
502
	))->toggles('.dnsdomain');
796
	));
503 797

  
504 798
	$group = new Form_Group('DNS Domain');
505 799
	$group->addClass('dnsdomain');
......
519 813
		'DNS Servers',
520 814
		'Provide a DNS server list to clients',
521 815
		$pconfig['dns_server_enable']
522
	))->toggles('.dnsservers');
816
	));
523 817

  
524 818
	$group = new Form_Group(null);
525 819
	$group->addClass('dnsservers');
......
554 848

  
555 849
	$section->add($group);
556 850

  
851
	$section->addInput(new Form_Checkbox(
852
		'push_blockoutsidedns',
853
		'Block Outside DNS',
854
		'Make Windows 10 Clients Block access to DNS servers except across OpenVPN while connected, forcing clients to use only VPN DNS servers.',
855
		$pconfig['push_blockoutsidedns']
856
	))->setHelp('Requires Windows 10 and OpenVPN 2.3.9 or later. Only Windows 10 is prone to DNS leakage in this way, other clients will ignore the option as they are not affected.');
857

  
858
	$section->addInput(new Form_Checkbox(
859
		'push_register_dns',
860
		'Force DNS cache update',
861
		'Run "net stop dnscache", "net start dnscache", "ipconfig /flushdns" and "ipconfig /registerdns" on connection initiation.',
862
		$pconfig['push_register_dns']
863
	))->setHelp('This is known to kick Windows into recognizing pushed DNS servers.');
864

  
557 865
	// NTP servers
558 866
	$section->addInput(new Form_Checkbox(
559 867
		'ntp_server_enable',
560 868
		'NTP Servers',
561 869
		'Provide an NTP server list to clients',
562 870
		$pconfig['ntp_server_enable']
563
	))->toggles('.ntpservers');
871
	));
564 872

  
565 873
	$group = new Form_Group(null);
566 874
	$group->addClass('ntpservers');
......
581 889

  
582 890
	$section->add($group);
583 891

  
584
	// NTP servers - For this section we need to use Javascript hiding since there
892
	// Netbios - For this section we need to use Javascript hiding since there
585 893
	// are nested toggles
586 894
	$section->addInput(new Form_Checkbox(
587 895
		'netbios_enable',
......
641 949
	if (!$user_can_edit_advanced) {
642 950
		$custops->setDisabled();
643 951
	}
644
	$section->addInput($custops)->setHelp('Enter any additional options to add for this client specific override, separated by a semicolon. %1$s' .
952
	$section->addInput($custops)->setHelp('Enter any additional options to add for this client specific override, separated by a semicolon.%1$s' .
953
				'The options will be pushed to the client after all above custom options.%1$s' .
645 954
				'EXAMPLE: push "route 10.0.0.0 255.255.255.0"; ',
646 955
				'<br />');
647 956

  
......
670 979
<script type="text/javascript">
671 980
//<![CDATA[
672 981
events.push(function() {
982
	// when option server_overrides_enabled is checked, show override server options
983
	function serveroverrides_change() {
984
		if ($('#server_overrides_enabled').prop('checked')) {
985
			hideCheckbox('push_reset', false);
986
			hideCheckbox('topology_override', false);
987
			topology_change();
988
			push_reset_change();
989
		} else {
990
			hideCheckbox('push_reset', true);
991
			hideCheckbox('topology_override', true);
992
			hideSelect('topology', true);
993
			hideCheckbox('remove_route', true);
994
			hideCheckbox('remove_iroute', true);
995
			hideCheckbox('remove_dnsdomain', true);
996
			hideCheckbox('remove_dnsservers', true);
997
			hideCheckbox('remove_ntpservers', true);
998
			hideCheckbox('remove_netbios_ntype', true);
999
			hideCheckbox('remove_netbios_scope', true);
1000
			hideCheckbox('remove_wins', true);
1001
		}
1002
	}
673 1003

  
1004
	// when push_reset option is selected, hide push_remove options, but not topology
1005
	function push_reset_change() {
1006
		var hide = $('#push_reset').prop('checked');
1007

  
1008
		hideCheckbox('remove_route', hide);
1009
		hideCheckbox('remove_iroute', hide);
1010
		hideCheckbox('remove_dnsdomain', hide);
1011
		hideCheckbox('remove_dnsservers', hide);
1012
		hideCheckbox('remove_ntpservers', hide);
1013
		hideCheckbox('remove_netbios_ntype', hide);
1014
		hideCheckbox('remove_netbios_scope', hide);
1015
		hideCheckbox('remove_wins', hide);
1016
	}
1017

  
1018
	function topology_change() {
1019
		if ($('#topology_override').prop('checked')) {
1020
			hideSelect('topology', false);
1021
		} else {
1022
			hideSelect('topology', true);
1023
		}
1024
	}
1025

  
1026
	function gwredir_change() {
1027
		var hide = $('#gwredir').prop('checked');
1028

  
1029
		hideInput('local_network', hide);
1030
//		hideInput('remote_network', hide);
1031
	}
1032

  
1033
	function gwredir6_change() {
1034
		var hide = $('#gwredir6').prop('checked');
1035

  
1036
		hideInput('local_networkv6', hide);
1037
//		hideInput('remote_networkv6', hide);
1038
	}
1039

  
1040
	function ping_seconds_change() {
1041
		if ($('#ping_push').prop('checked')) {
1042
			hideInput('ping_seconds', false);
1043
		} else {
1044
			hideInput('ping_seconds', true);
1045
		}
1046
	}
1047

  
1048
	function ping_action_change() {
1049
		if ($('#ping_action_push').prop('checked')) {
1050
			hideSelect('ping_action', false);
1051
			hideInput('ping_action_seconds', false);
1052
		} else {
1053
			hideSelect('ping_action', true);
1054
			hideInput('ping_action_seconds', true);
1055
		}
1056
	}
1057

  
1058
	function dnsdomain_change() {
1059
		if ($('#dns_domain_enable').prop('checked')) {
1060
			hideClass('dnsdomain', false);
1061
		} else {
1062
			hideClass('dnsdomain', true);
1063
		}
1064
	}
1065

  
1066
	function dnsservers_change() {
1067
		if ($('#dns_server_enable').prop('checked')) {
1068
			hideClass('dnsservers', false);
1069
		} else {
1070
			hideClass('dnsservers', true);
1071
		}
1072
	}
1073

  
1074
	function ntpservers_change() {
1075
		if ($('#ntp_server_enable').prop('checked')) {
1076
			hideClass('ntpservers', false);
1077
		} else {
1078
			hideClass('ntpservers', true);
1079
		}
1080
	}
1081

  
674 1082
	// Hide/show that section, but have to also respect the wins_server_enable checkbox
675 1083
	function setNetbios() {
676 1084
		if ($('#netbios_enable').prop('checked')) {
......
692 1100

  
693 1101
	// ---------- Click checkbox handlers ---------------------------------------------------------
694 1102

  
1103
	 // On clicking Select Server Overrides Options
1104
	$('#server_overrides_enabled').click(function () {
1105
		serveroverrides_change();
1106
	});
1107

  
1108
	 // On clicking Remove All Server Options
1109
	$('#push_reset').click(function () {
1110
		push_reset_change();
1111
	});
1112

  
1113
	 // On clicking Override Server Topology
1114
	$('#topology_override').click(function () {
1115
		topology_change();
1116
	});
1117

  
1118
	 // On clicking Gateway redirect
1119
	$('#gwredir').click(function () {
1120
		gwredir_change();
1121
	});
1122

  
1123
	 // On clicking Gateway redirect IPv6
1124
	$('#gwredir6').click(function () {
1125
		gwredir6_change();
1126
	});
1127

  
1128
	 // On clicking Ping Interval
1129
	$('#ping_push').click(function () {
1130
		ping_seconds_change();
1131
	});
1132

  
1133
	 // On clicking Ping Action
1134
	$('#ping_action_push').click(function () {
1135
		ping_action_change();
1136
	});
1137

  
1138
	 // On clicking DNS Default Domain
1139
	$('#dns_domain_enable').click(function () {
1140
		dnsdomain_change();
1141
	});
1142

  
1143
	 // On clicking DNS Servers
1144
	$('#dns_server_enable').click(function () {
1145
		dnsservers_change();
1146
	});
1147

  
1148
	 // On clicking NTP Servers
1149
	$('#ntp_server_enable').click(function () {
1150
		ntpservers_change();
1151
	});
1152

  
695 1153
	// On clicking the netbios_enable checkbox
696 1154
	$('#netbios_enable').click(function () {
697 1155
		setNetbios();
......
704 1162

  
705 1163
	// ---------- On initial page load ------------------------------------------------------------
706 1164

  
1165
	// first the options depending on push_reset, and on server_overrides_enabled
1166
	// and finally the global server_overrides_enabled toggle
1167
	push_reset_change();
1168
	topology_change();
1169
	serveroverrides_change();
1170

  
1171
	gwredir_change();
1172
	gwredir6_change();
1173

  
1174
	ping_seconds_change();
1175
	ping_action_change();
1176

  
707 1177
	setNetbios();
1178
	dnsdomain_change();
1179
	dnsservers_change();
1180
	ntpservers_change();
1181

  
708 1182
});
709 1183
//]]>
710 1184
</script>
711
-- a/src/etc/inc/openvpn.inc
1185
++ b/src/etc/inc/openvpn.inc
......
772 772

  
773 773
	if ($settings['netbios_enable']) {
774 774

  
775
		if (!empty($settings['dhcp_nbttype']) && ($settings['dhcp_nbttype'] != 0)) {
776
			$conf .= "push \"dhcp-option NBT {$settings['dhcp_nbttype']}\"\n";
775
		if (!empty($settings['netbios_ntype']) && ($settings['netbios_ntype'] != 0)) {
776
			$conf .= "push \"dhcp-option NBT {$settings['netbios_ntype']}\"\n";
777 777
		}
778
		if (!empty($settings['dhcp_nbtscope'])) {
779
			$conf .= "push \"dhcp-option NBS {$settings['dhcp_nbtscope']}\"\n";
778
		if (!empty($settings['netbios_scope'])) {
779
			$conf .= "push \"dhcp-option NBS {$settings['netbios_scope']}\"\n";
780 780
		}
781 781

  
782 782
		if (!empty($settings['wins_server1'])) {
......
1692 1692
	services_unbound_configure(false);
1693 1693
}
1694 1694

  
1695
// set client specific overrides
1695 1696
function openvpn_resync_csc(& $settings) {
1696 1697
	global $g, $config, $openvpn_tls_server_modes;
1697 1698
	if (isset($settings['disable'])) {
......
1715 1716
		$conf .= "push-reset\n";
1716 1717
	}
1717 1718

  
1719
	if ($settings['push_reset']) {
1720
		$conf .= "push-reset\n";
1721
	}
1722

  
1723
	if ($settings['topology_override']) {
1724
		$conf .= "push \"topology {$settings['topology']}\"\n";
1725
	}
1726

  
1718 1727
	if ($settings['remove_route']) {
1719 1728
		$conf .= "push-remove route\n";
1720 1729
	}
1721 1730

  
1731
	if ($settings['remove_iroute']) {
1732
		$conf .= "push-remove iroute\n";
1733
	}
1734

  
1735
	if ($settings['remove_dnsdomain']) {
1736
		$conf .= "push-remove \"dhcp-option DOMAIN\"\n";
1737
	}
1738

  
1739
	if ($settings['remove_dnsservers']) {
1740
		$conf .= "push-remove \"dhcp-option DNS\"\n";
1741
	}
1742

  
1743
	if ($settings['remove_ntpservers']) {
1744
		$conf .= "push-remove \"dhcp-option NTP\"\n";
1745
	}
1746

  
1747
	if ($settings['remove_netbios_ntype']) {
1748
		$conf .= "push-remove \"dhcp-option NBT\"\n";
1749
	}
1750

  
1751
	if ($settings['remove_netbios_scope']) {
1752
		$conf .= "push-remove \"dhcp-option NBS\"\n";
1753
	}
1754

  
1755
	if ($settings['remove_wins']) {
1756
		$conf .= "push-remove \"dhcp-option WINS\"\n";
1757
	}
1758

  
1722 1759
	if ($settings['local_network']) {
1723 1760
		$conf .= openvpn_gen_routes($settings['local_network'], "ipv4", true);
1724 1761
	}
......
1735 1772
		$conf .= openvpn_gen_routes($settings['remote_networkv6'], "ipv6", false, true);
1736 1773
	}
1737 1774

  
1775
	// push the ipv4 gateway if specified
1776
	if (!empty($settings['gateway']) && is_ipaddrv4($settings['gateway'])) {
1777
		$conf .= "push \"route-gateway {$settings['gateway']}\"\n";
1778
	}
1779

  
1780
	/* Currently route-ipv6-gateway is not supported by openvpn
1781
	if (!empty($settings['gateway']) && is_ipaddrv4($settings['gateway'])) {
1782
		$conf .= "push \"route-ipv6-gateway {$settings['gateway']}\"\n";
1783
	}
1784
	*/
1785

  
1786
	// Ping override options
1787
	if ($settings['ping_push']) {
1788
		$conf .= "push \"ping {$settings['ping_seconds']}\"\n";
1789
	}
1790

  
1791
	if ($settings['ping_action_push']) {
1792
		$action = str_replace("_", "-", $settings['ping_action']);
1793
		$conf .= "push \"{$action} " .
1794
			"{$settings['ping_action_seconds']}\"\n";
1795
	}
1796

  
1797
	// create client specific dhcp options and gateway redirection
1738 1798
	openvpn_add_dhcpopts($settings, $conf);
1739 1799

  
1800
	// custom options are added after all client overrides, and before the tunnel options
1740 1801
	openvpn_add_custom($settings, $conf);
1802

  
1741 1803
	/* Loop through servers, find which ones can use this CSC */
1742 1804
	if (is_array($config['openvpn']['openvpn-server'])) {
1743 1805
		foreach ($config['openvpn']['openvpn-server'] as $serversettings) {
(5-5/14)