Project

General

Profile

Feature #12522 » openvpn_enhanced_overrides_pfsense2.6.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
		}
......
266 335
		$csc['common_name'] = $pconfig['common_name'];
267 336
		$csc['block'] = $pconfig['block'];
268 337
		$csc['description'] = $pconfig['description'];
338

  
269 339
		$csc['tunnel_network'] = $pconfig['tunnel_network'];
270 340
		$csc['tunnel_networkv6'] = $pconfig['tunnel_networkv6'];
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']) {
271 363
			$csc['local_network'] = $pconfig['local_network'];
364
		}
365

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

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

  
273 374
		$csc['remote_network'] = $pconfig['remote_network'];
274 375
		$csc['remote_networkv6'] = $pconfig['remote_networkv6'];
275
		$csc['gwredir'] = $pconfig['gwredir'];
276
		$csc['push_reset'] = $pconfig['push_reset'];
277
		$csc['remove_route'] = $pconfig['remove_route'];
278 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

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

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

  
290 401
		if ($pconfig['ntp_server_enable']) {
291 402
			$csc['ntp_server1'] = $pconfig['ntp_server1'];
292 403
			$csc['ntp_server2'] = $pconfig['ntp_server2'];
......
316 427
			$wc_msg = sprintf(gettext('Added OpenVPN client specific override %1$s %2$s'), $csc['common_name'], $csc['description']);
317 428
		}
318 429

  
319
		if (!empty($old_csc['common_name'])) {
430
		if (!empty_field($old_csc['common_name'])) {
320 431
			openvpn_delete_csc($old_csc);
321 432
		}
322 433
		openvpn_resync_csc($csc);
......
399 510
		true
400 511
		))->setHelp('Select the servers that will utilize this override. When no servers are selected, the override will apply to all servers.');
401 512

  
513
	// Override server client options
514
	$section->addInput(new Form_Checkbox(
515
		'server_overrides_enabled',
516
		'Select Server Overrides',
517
		'Select server options to remove.',
518
		$pconfig['server_overrides_enabled']
519
	))->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' .
520
			'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.',
521
			'<br />');
522

  
523
	$section->addInput(new Form_Checkbox(
524
		'push_reset',
525
		null,
526
		'Remove All Server Options',
527
		$pconfig['push_reset']
528
	))->setHelp('Prevent this client from receiving any server-defined client settings.%1$s' .
529
			'This option will send a push-reset to the client. It will thus remove any server-defined routes, the gateway and topology.%1$s' .
530
			'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.',
531
			'<br />');
532

  
533
	$section->addInput(new Form_Checkbox(
534
		'topology_override',
535
		null,
536
		'Override Server Topology',
537
		$pconfig['topology_override']
538
	));
539

  
540
	$section->addInput(new Form_Select(
541
		'topology',
542
		null,
543
		$pconfig['topology'],
544
		$openvpn_topologies
545
	))->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' .
546
			'NOTE: This will perform a "push topology [selection]" without a previous "push-remove topology". Alternetively you can push the topology in Advanced section.',
547
			'<br />');
548

  
549
	/* as "push-reset" can break subnet topology, 
550
	 * "push-remove route" removes only IPv4/IPv6 routes, see #9702 */
551
	$section->addInput(new Form_Checkbox(
552
		'remove_route',
553
		null,
554
		'Remove Server Local Routes',
555
		$pconfig['remove_route']
556
	))->setHelp('Prevent this client from receiving any server-defined local routes.%1$s' .
557
			'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' .
558
			'NOTE: Remember to either enter the proper gateway and any additional local routes in the below form or in Advanced section.',
559
			'<br />');
560

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

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

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

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

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

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

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

  
402 631
	$form->add($section);
403 632

  
404 633
	$section = new Form_Section('Tunnel Settings');
......
422 651
			'Enter the client IPv6 address and prefix. The prefix must match the IPv6 Tunnel Network prefix on the server. ',
423 652
			'<br />');
424 653

  
654
	$form->add($section);
655

  
656
	$section = new Form_Section('Local Routes Settings');
657

  
658
	$section->addInput(new Form_Checkbox(
659
		'gwredir',
660
		'Redirect IPv4 Gateway',
661
		'Force all client generated traffic through the tunnel.',
662
		$pconfig['gwredir']
663
	));
664

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

  
425 672
	$section->addInput(new Form_Input(
426 673
		'local_network',
427 674
		'IPv4 Local Network/s',
......
441 688
			'<br />');
442 689

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

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

  
714
	$form->add($section);
715

  
716
	$section = new Form_Section('Remote Routes Settings');
717

  
718
	$section->addInput(new Form_Input(
444 719
		'remote_network',
445 720
		'IPv4 Remote Network/s',
446 721
		'text',
......
460 735
		    'NOTE: Remember to add these subnets to the IPv6 Remote Networks list on the corresponding OpenVPN server settings.',
461 736
			'<br />');
462 737

  
463
	$section->addInput(new Form_Checkbox(
464
		'gwredir',
465
		'Redirect Gateway',
466
		'Force all client generated traffic through the tunnel.',
467
		$pconfig['gwredir']
468
	));
469

  
470 738
	$form->add($section);
471 739

  
472
	$section = new Form_Section('Client Settings');
740
	$section = new Form_Section('Other Client Settings');
473 741

  
474 742
	$section->addInput(new Form_Checkbox(
475
		'push_reset',
476
		'Server Definitions',
477
		'Prevent this client from receiving any server-defined client settings. ',
478
		$pconfig['push_reset']
479
	));
743
		'ping_push',
744
		'Ping Interval',
745
		'Push ping to VPN client',
746
		$pconfig['ping_push']
747
	))->setHelp('Override server ping interval.%1$s',
748
				'<br />');
480 749

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

  
483 760
	$section->addInput(new Form_Checkbox(
484
		'remove_route',
485
		'Remove Server Routes',
486
		'Prevent this client from receiving any server-defined routes without removing any other options. ',
487
		$pconfig['remove_route']
761
		'ping_action_push',
762
		'Ping Action',
763
		'Push ping-restart/ping-exit to VPN client',
764
		$pconfig['ping_action_push']
765
	))->setHelp('Override server ping restart/exit.%1$s',
766
				'<br />');
767

  
768
	$section->addInput(new Form_Select(
769
		'ping_action',
770
		'Ping restart or exit',
771
		$pconfig['ping_action'],
772
		$openvpn_ping_action
773
	))->setHelp('Exit or restart OpenVPN after timeout from remote.%1$s',
774
				'<br />');
775

  
776
	$section->addInput(new Form_Input(
777
		'ping_action_seconds',
778
		'Ping restart or exit seconds',
779
		'number',
780
		$pconfig['ping_action_seconds']
781
		    ?: $openvpn_default_keepalive_timeout,
782
		['min' => '0']
488 783
	));
489 784

  
490 785
	$section->addInput(new Form_Checkbox(
......
492 787
		'DNS Default Domain',
493 788
		'Provide a default domain name to clients',
494 789
		$pconfig['dns_domain_enable']
495
	))->toggles('.dnsdomain');
790
	));
496 791

  
497 792
	$group = new Form_Group('DNS Domain');
498 793
	$group->addClass('dnsdomain');
......
512 807
		'DNS Servers',
513 808
		'Provide a DNS server list to clients',
514 809
		$pconfig['dns_server_enable']
515
	))->toggles('.dnsservers');
810
	));
516 811

  
517 812
	$group = new Form_Group(null);
518 813
	$group->addClass('dnsservers');
......
547 842

  
548 843
	$section->add($group);
549 844

  
845
	$section->addInput(new Form_Checkbox(
846
		'push_blockoutsidedns',
847
		'Block Outside DNS',
848
		'Make Windows 10 Clients Block access to DNS servers except across OpenVPN while connected, forcing clients to use only VPN DNS servers.',
849
		$pconfig['push_blockoutsidedns']
850
	))->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.');
851

  
852
	$section->addInput(new Form_Checkbox(
853
		'push_register_dns',
854
		'Force DNS cache update',
855
		'Run "net stop dnscache", "net start dnscache", "ipconfig /flushdns" and "ipconfig /registerdns" on connection initiation.',
856
		$pconfig['push_register_dns']
857
	))->setHelp('This is known to kick Windows into recognizing pushed DNS servers.');
858

  
550 859
	// NTP servers
551 860
	$section->addInput(new Form_Checkbox(
552 861
		'ntp_server_enable',
553 862
		'NTP Servers',
554 863
		'Provide an NTP server list to clients',
555 864
		$pconfig['ntp_server_enable']
556
	))->toggles('.ntpservers');
865
	));
557 866

  
558 867
	$group = new Form_Group(null);
559 868
	$group->addClass('ntpservers');
......
574 883

  
575 884
	$section->add($group);
576 885

  
577
	// NTP servers - For this section we need to use Javascript hiding since there
886
	// Netbios - For this section we need to use Javascript hiding since there
578 887
	// are nested toggles
579 888
	$section->addInput(new Form_Checkbox(
580 889
		'netbios_enable',
......
634 943
	if (!$user_can_edit_advanced) {
635 944
		$custops->setDisabled();
636 945
	}
637
	$section->addInput($custops)->setHelp('Enter any additional options to add for this client specific override, separated by a semicolon. %1$s' .
946
	$section->addInput($custops)->setHelp('Enter any additional options to add for this client specific override, separated by a semicolon.%1$s' .
947
				'The options will be pushed to the client after all above custom options.%1$s' .
638 948
				'EXAMPLE: push "route 10.0.0.0 255.255.255.0"; ',
639 949
				'<br />');
640 950

  
......
663 973
<script type="text/javascript">
664 974
//<![CDATA[
665 975
events.push(function() {
976
	// when option server_overrides_enabled is checked, show override server options
977
	function serveroverrides_change() {
978
		if ($('#server_overrides_enabled').prop('checked')) {
979
			hideCheckbox('push_reset', false);
980
			hideCheckbox('topology_override', false);
981
			topology_change();
982
			push_reset_change();
983
		} else {
984
			hideCheckbox('push_reset', true);
985
			hideCheckbox('topology_override', true);
986
			hideSelect('topology', true);
987
			hideCheckbox('remove_route', true);
988
			hideCheckbox('remove_iroute', true);
989
			hideCheckbox('remove_dnsdomain', true);
990
			hideCheckbox('remove_dnsservers', true);
991
			hideCheckbox('remove_ntpservers', true);
992
			hideCheckbox('remove_netbios_ntype', true);
993
			hideCheckbox('remove_netbios_scope', true);
994
			hideCheckbox('remove_wins', true);
995
		}
996
	}
666 997

  
998
	// when push_reset option is selected, hide push_remove options, but not topology
999
	function push_reset_change() {
1000
		var hide = $('#push_reset').prop('checked');
1001

  
1002
		hideCheckbox('remove_route', hide);
1003
		hideCheckbox('remove_iroute', hide);
1004
		hideCheckbox('remove_dnsdomain', hide);
1005
		hideCheckbox('remove_dnsservers', hide);
1006
		hideCheckbox('remove_ntpservers', hide);
1007
		hideCheckbox('remove_netbios_ntype', hide);
1008
		hideCheckbox('remove_netbios_scope', hide);
1009
		hideCheckbox('remove_wins', hide);
1010
	}
1011

  
1012
	function topology_change() {
1013
		if ($('#topology_override').prop('checked')) {
1014
			hideSelect('topology', false);
1015
		} else {
1016
			hideSelect('topology', true);
1017
		}
1018
	}
1019

  
1020
	function gwredir_change() {
1021
		var hide = $('#gwredir').prop('checked');
1022

  
1023
		hideInput('local_network', hide);
1024
//		hideInput('remote_network', hide);
1025
	}
1026

  
1027
	function gwredir6_change() {
1028
		var hide = $('#gwredir6').prop('checked');
1029

  
1030
		hideInput('local_networkv6', hide);
1031
//		hideInput('remote_networkv6', hide);
1032
	}
1033

  
1034
	function ping_seconds_change() {
1035
		if ($('#ping_push').prop('checked')) {
1036
			hideInput('ping_seconds', false);
1037
		} else {
1038
			hideInput('ping_seconds', true);
1039
		}
1040
	}
1041

  
1042
	function ping_action_change() {
1043
		if ($('#ping_action_push').prop('checked')) {
1044
			hideSelect('ping_action', false);
1045
			hideInput('ping_action_seconds', false);
1046
		} else {
1047
			hideSelect('ping_action', true);
1048
			hideInput('ping_action_seconds', true);
1049
		}
1050
	}
1051

  
1052
	function dnsdomain_change() {
1053
		if ($('#dns_domain_enable').prop('checked')) {
1054
			hideClass('dnsdomain', false);
1055
		} else {
1056
			hideClass('dnsdomain', true);
1057
		}
1058
	}
1059

  
1060
	function dnsservers_change() {
1061
		if ($('#dns_server_enable').prop('checked')) {
1062
			hideClass('dnsservers', false);
1063
		} else {
1064
			hideClass('dnsservers', true);
1065
		}
1066
	}
1067

  
1068
	function ntpservers_change() {
1069
		if ($('#ntp_server_enable').prop('checked')) {
1070
			hideClass('ntpservers', false);
1071
		} else {
1072
			hideClass('ntpservers', true);
1073
		}
1074
	}
1075

  
667 1076
	// Hide/show that section, but have to also respect the wins_server_enable checkbox
668 1077
	function setNetbios() {
669 1078
		if ($('#netbios_enable').prop('checked')) {
......
685 1094

  
686 1095
	// ---------- Click checkbox handlers ---------------------------------------------------------
687 1096

  
1097
	 // On clicking Select Server Overrides Options
1098
	$('#server_overrides_enabled').click(function () {
1099
		serveroverrides_change();
1100
	});
1101

  
1102
	 // On clicking Remove All Server Options
1103
	$('#push_reset').click(function () {
1104
		push_reset_change();
1105
	});
1106

  
1107
	 // On clicking Override Server Topology
1108
	$('#topology_override').click(function () {
1109
		topology_change();
1110
	});
1111

  
1112
	 // On clicking Gateway redirect
1113
	$('#gwredir').click(function () {
1114
		gwredir_change();
1115
	});
1116

  
1117
	 // On clicking Gateway redirect IPv6
1118
	$('#gwredir6').click(function () {
1119
		gwredir6_change();
1120
	});
1121

  
1122
	 // On clicking Ping Interval
1123
	$('#ping_push').click(function () {
1124
		ping_seconds_change();
1125
	});
1126

  
1127
	 // On clicking Ping Action
1128
	$('#ping_action_push').click(function () {
1129
		ping_action_change();
1130
	});
1131

  
1132
	 // On clicking DNS Default Domain
1133
	$('#dns_domain_enable').click(function () {
1134
		dnsdomain_change();
1135
	});
1136

  
1137
	 // On clicking DNS Servers
1138
	$('#dns_server_enable').click(function () {
1139
		dnsservers_change();
1140
	});
1141

  
1142
	 // On clicking NTP Servers
1143
	$('#ntp_server_enable').click(function () {
1144
		ntpservers_change();
1145
	});
1146

  
688 1147
	// On clicking the netbios_enable checkbox
689 1148
	$('#netbios_enable').click(function () {
690 1149
		setNetbios();
......
697 1156

  
698 1157
	// ---------- On initial page load ------------------------------------------------------------
699 1158

  
1159
	// first the options depending on push_reset, and on server_overrides_enabled
1160
	// and finally the global server_overrides_enabled toggle
1161
	push_reset_change();
1162
	topology_change();
1163
	serveroverrides_change();
1164

  
1165
	gwredir_change();
1166
	gwredir6_change();
1167

  
1168
	ping_seconds_change();
1169
	ping_action_change();
1170

  
700 1171
	setNetbios();
1172
	dnsdomain_change();
1173
	dnsservers_change();
1174
	ntpservers_change();
1175

  
701 1176
});
702 1177
//]]>
703 1178
</script>
704
-- a/src/etc/inc/openvpn.inc
1179
++ b/src/etc/inc/openvpn.inc
......
765 765

  
766 766
	if ($settings['netbios_enable']) {
767 767

  
768
		if (!empty($settings['dhcp_nbttype']) && ($settings['dhcp_nbttype'] != 0)) {
769
			$conf .= "push \"dhcp-option NBT {$settings['dhcp_nbttype']}\"\n";
768
		if (!empty($settings['netbios_ntype']) && ($settings['netbios_ntype'] != 0)) {
769
			$conf .= "push \"dhcp-option NBT {$settings['netbios_ntype']}\"\n";
770 770
		}
771
		if (!empty($settings['dhcp_nbtscope'])) {
772
			$conf .= "push \"dhcp-option NBS {$settings['dhcp_nbtscope']}\"\n";
771
		if (!empty($settings['netbios_scope'])) {
772
			$conf .= "push \"dhcp-option NBS {$settings['netbios_scope']}\"\n";
773 773
		}
774 774

  
775 775
		if (!empty($settings['wins_server1'])) {
......
1652 1652
	openvpn_clean_rules($mode, $vpnid);
1653 1653
}
1654 1654

  
1655
// set client specific overrides
1655 1656
function openvpn_resync_csc(& $settings) {
1656 1657
	global $g, $config, $openvpn_tls_server_modes;
1657 1658
	if (isset($settings['disable'])) {
......
1675 1676
		$conf .= "push-reset\n";
1676 1677
	}
1677 1678

  
1679
	if ($settings['push_reset']) {
1680
		$conf .= "push-reset\n";
1681
	}
1682

  
1683
	if ($settings['topology_override']) {
1684
		$conf .= "push \"topology {$settings['topology']}\"\n";
1685
	}
1686

  
1678 1687
	if ($settings['remove_route']) {
1679 1688
		$conf .= "push-remove route\n";
1680 1689
	}
1681 1690

  
1691
	if ($settings['remove_iroute']) {
1692
		$conf .= "push-remove iroute\n";
1693
	}
1694

  
1695
	if ($settings['remove_dnsdomain']) {
1696
		$conf .= "push-remove \"dhcp-option DOMAIN\"\n";
1697
	}
1698

  
1699
	if ($settings['remove_dnsservers']) {
1700
		$conf .= "push-remove \"dhcp-option DNS\"\n";
1701
	}
1702

  
1703
	if ($settings['remove_ntpservers']) {
1704
		$conf .= "push-remove \"dhcp-option NTP\"\n";
1705
	}
1706

  
1707
	if ($settings['remove_netbios_ntype']) {
1708
		$conf .= "push-remove \"dhcp-option NBT\"\n";
1709
	}
1710

  
1711
	if ($settings['remove_netbios_scope']) {
1712
		$conf .= "push-remove \"dhcp-option NBS\"\n";
1713
	}
1714

  
1715
	if ($settings['remove_wins']) {
1716
		$conf .= "push-remove \"dhcp-option WINS\"\n";
1717
	}
1718

  
1682 1719
	if ($settings['local_network']) {
1683 1720
		$conf .= openvpn_gen_routes($settings['local_network'], "ipv4", true);
1684 1721
	}
......
1695 1732
		$conf .= openvpn_gen_routes($settings['remote_networkv6'], "ipv6", false, true);
1696 1733
	}
1697 1734

  
1735
	// push the ipv4 gateway if specified
1736
	if (!empty($settings['gateway']) && is_ipaddrv4($settings['gateway'])) {
1737
		$conf .= "push \"route-gateway {$settings['gateway']}\"\n";
1738
	}
1739

  
1740
	/* Currently route-ipv6-gateway is not supported by openvpn
1741
	if (!empty($settings['gateway']) && is_ipaddrv4($settings['gateway'])) {
1742
		$conf .= "push \"route-ipv6-gateway {$settings['gateway']}\"\n";
1743
	}
1744
	*/
1745

  
1746
	// Ping override options
1747
	if ($settings['ping_push']) {
1748
		$conf .= "push \"ping {$settings['ping_seconds']}\"\n";
1749
	}
1750

  
1751
	if ($settings['ping_action_push']) {
1752
		$action = str_replace("_", "-", $settings['ping_action']);
1753
		$conf .= "push \"{$action} " .
1754
			"{$settings['ping_action_seconds']}\"\n";
1755
	}
1756

  
1757
	// create client specific dhcp options and gateway redirection
1698 1758
	openvpn_add_dhcpopts($settings, $conf);
1699 1759

  
1760
	// custom options are added after all client overrides, and before the tunnel options
1700 1761
	openvpn_add_custom($settings, $conf);
1762

  
1701 1763
	/* Loop through servers, find which ones can use this CSC */
1702 1764
	if (is_array($config['openvpn']['openvpn-server'])) {
1703 1765
		foreach ($config['openvpn']['openvpn-server'] as $serversettings) {
(6-6/9)