1
|
<?php
|
2
|
/* $Id$ */
|
3
|
/*
|
4
|
services_dyndns_edit.php
|
5
|
|
6
|
Copyright (C) 2008 Ermal Luçi
|
7
|
Copyright (C) 2013-2015 Electric Sheep Fencing, LP
|
8
|
All rights reserved.
|
9
|
|
10
|
Redistribution and use in source and binary forms, with or without
|
11
|
modification, are permitted provided that the following conditions are met:
|
12
|
|
13
|
1. Redistributions of source code must retain the above copyright notice,
|
14
|
this list of conditions and the following disclaimer.
|
15
|
|
16
|
2. Redistributions in binary form must reproduce the above copyright
|
17
|
notice, this list of conditions and the following disclaimer in the
|
18
|
documentation and/or other materials provided with the distribution.
|
19
|
|
20
|
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
21
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
22
|
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
23
|
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
24
|
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
25
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
26
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
27
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
28
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
29
|
POSSIBILITY OF SUCH DAMAGE.
|
30
|
*/
|
31
|
/*
|
32
|
pfSense_BUILDER_BINARIES: /bin/rm
|
33
|
pfSense_MODULE: dyndns
|
34
|
*/
|
35
|
|
36
|
##|+PRIV
|
37
|
##|*IDENT=page-services-dynamicdnsclient
|
38
|
##|*NAME=Services: Dynamic DNS client page
|
39
|
##|*DESCR=Allow access to the 'Services: Dynamic DNS client' page.
|
40
|
##|*MATCH=services_dyndns_edit.php*
|
41
|
##|-PRIV
|
42
|
|
43
|
/* returns true if $uname is a valid DynDNS username */
|
44
|
function is_dyndns_username($uname) {
|
45
|
if (!is_string($uname))
|
46
|
return false;
|
47
|
|
48
|
if (preg_match("/[^a-z0-9\-\+.@_:]/i", $uname))
|
49
|
return false;
|
50
|
else
|
51
|
return true;
|
52
|
}
|
53
|
|
54
|
require("guiconfig.inc");
|
55
|
|
56
|
if (!is_array($config['dyndnses']['dyndns'])) {
|
57
|
$config['dyndnses']['dyndns'] = array();
|
58
|
}
|
59
|
|
60
|
$a_dyndns = &$config['dyndnses']['dyndns'];
|
61
|
|
62
|
if (is_numericint($_GET['id']))
|
63
|
$id = $_GET['id'];
|
64
|
|
65
|
if (isset($_POST['id']) && is_numericint($_POST['id']))
|
66
|
$id = $_POST['id'];
|
67
|
|
68
|
if (isset($id) && isset($a_dyndns[$id])) {
|
69
|
$pconfig['username'] = $a_dyndns[$id]['username'];
|
70
|
$pconfig['password'] = $a_dyndns[$id]['password'];
|
71
|
$pconfig['host'] = $a_dyndns[$id]['host'];
|
72
|
$pconfig['mx'] = $a_dyndns[$id]['mx'];
|
73
|
$pconfig['type'] = $a_dyndns[$id]['type'];
|
74
|
$pconfig['enable'] = !isset($a_dyndns[$id]['enable']);
|
75
|
$pconfig['interface'] = $a_dyndns[$id]['interface'];
|
76
|
$pconfig['wildcard'] = isset($a_dyndns[$id]['wildcard']);
|
77
|
$pconfig['verboselog'] = isset($a_dyndns[$id]['verboselog']);
|
78
|
$pconfig['curl_ipresolve_v4'] = isset($a_dyndns[$id]['curl_ipresolve_v4']);
|
79
|
$pconfig['curl_ssl_verifypeer'] = isset($a_dyndns[$id]['curl_ssl_verifypeer']);
|
80
|
$pconfig['zoneid'] = $a_dyndns[$id]['zoneid'];
|
81
|
$pconfig['ttl'] = $a_dyndns[$id]['ttl'];
|
82
|
$pconfig['updateurl'] = $a_dyndns[$id]['updateurl'];
|
83
|
$pconfig['resultmatch'] = $a_dyndns[$id]['resultmatch'];
|
84
|
$pconfig['requestif'] = $a_dyndns[$id]['requestif'];
|
85
|
$pconfig['descr'] = $a_dyndns[$id]['descr'];
|
86
|
}
|
87
|
|
88
|
if ($_POST) {
|
89
|
unset($input_errors);
|
90
|
$pconfig = $_POST;
|
91
|
|
92
|
if(($pconfig['type'] == "freedns" || $pconfig['type'] == "namecheap") && $_POST['username'] == "")
|
93
|
$_POST['username'] = "none";
|
94
|
|
95
|
/* input validation */
|
96
|
$reqdfields = array();
|
97
|
$reqdfieldsn = array();
|
98
|
$reqdfields = array("type");
|
99
|
$reqdfieldsn = array(gettext("Service type"));
|
100
|
|
101
|
if ($pconfig['type'] != "custom" && $pconfig['type'] != "custom-v6") {
|
102
|
$reqdfields[] = "host";
|
103
|
$reqdfieldsn[] = gettext("Hostname");
|
104
|
$reqdfields[] = "passwordfld";
|
105
|
$reqdfieldsn[] = gettext("Password");
|
106
|
$reqdfields[] = "username";
|
107
|
$reqdfieldsn[] = gettext("Username");
|
108
|
}else{
|
109
|
$reqdfields[] = "updateurl";
|
110
|
$reqdfieldsn[] = gettext("Update URL");
|
111
|
}
|
112
|
|
113
|
do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
|
114
|
|
115
|
if (isset($_POST['host']) && in_array("host", $reqdfields)) {
|
116
|
/* Namecheap can have a @. in hostname */
|
117
|
if ($pconfig['type'] == "namecheap" && substr($_POST['host'], 0, 2) == '@.')
|
118
|
$host_to_check = substr($_POST['host'], 2);
|
119
|
else
|
120
|
$host_to_check = $_POST['host'];
|
121
|
|
122
|
if ($pconfig['type'] != "custom" && $pconfig['type'] != "custom-v6") {
|
123
|
if (!is_domain($host_to_check))
|
124
|
$input_errors[] = gettext("The hostname contains invalid characters.");
|
125
|
}
|
126
|
|
127
|
unset($host_to_check);
|
128
|
}
|
129
|
if (($_POST['mx'] && !is_domain($_POST['mx'])))
|
130
|
$input_errors[] = gettext("The MX contains invalid characters.");
|
131
|
|
132
|
if ((in_array("username", $reqdfields) && $_POST['username'] && !is_dyndns_username($_POST['username'])) || ((in_array("username", $reqdfields)) && ($_POST['username'] == "")))
|
133
|
$input_errors[] = gettext("The username contains invalid characters.");
|
134
|
|
135
|
if (!$input_errors) {
|
136
|
$dyndns = array();
|
137
|
$dyndns['type'] = $_POST['type'];
|
138
|
$dyndns['username'] = $_POST['username'];
|
139
|
$dyndns['password'] = $_POST['passwordfld'];
|
140
|
$dyndns['host'] = $_POST['host'];
|
141
|
$dyndns['mx'] = $_POST['mx'];
|
142
|
$dyndns['wildcard'] = $_POST['wildcard'] ? true : false;
|
143
|
$dyndns['verboselog'] = $_POST['verboselog'] ? true : false;
|
144
|
$dyndns['curl_ipresolve_v4'] = $_POST['curl_ipresolve_v4'] ? true : false;
|
145
|
$dyndns['curl_ssl_verifypeer'] = $_POST['curl_ssl_verifypeer'] ? true : false;
|
146
|
/* In this place enable means disabled */
|
147
|
if ($_POST['enable'])
|
148
|
unset($dyndns['enable']);
|
149
|
else
|
150
|
$dyndns['enable'] = true;
|
151
|
|
152
|
$dyndns['interface'] = $_POST['interface'];
|
153
|
$dyndns['zoneid'] = $_POST['zoneid'];
|
154
|
$dyndns['ttl'] = $_POST['ttl'];
|
155
|
$dyndns['updateurl'] = $_POST['updateurl'];
|
156
|
// Trim hard-to-type but sometimes returned characters
|
157
|
$dyndns['resultmatch'] = trim($_POST['resultmatch'], "\t\n\r");
|
158
|
($dyndns['type'] == "custom" || $dyndns['type'] == "custom-v6") ? $dyndns['requestif'] = $_POST['requestif'] : $dyndns['requestif'] = $_POST['interface'];
|
159
|
$dyndns['descr'] = $_POST['descr'];
|
160
|
$dyndns['force'] = isset($_POST['force']);
|
161
|
|
162
|
if($dyndns['username'] == "none")
|
163
|
$dyndns['username'] = "";
|
164
|
|
165
|
if (isset($id) && $a_dyndns[$id])
|
166
|
$a_dyndns[$id] = $dyndns;
|
167
|
else {
|
168
|
$a_dyndns[] = $dyndns;
|
169
|
$id = count($a_dyndns) - 1;
|
170
|
}
|
171
|
|
172
|
$dyndns['id'] = $id;
|
173
|
//Probably overkill, but its better to be safe
|
174
|
for($i = 0; $i < count($a_dyndns); $i++) {
|
175
|
$a_dyndns[$i]['id'] = $i;
|
176
|
}
|
177
|
|
178
|
write_config();
|
179
|
|
180
|
services_dyndns_configure_client($dyndns);
|
181
|
|
182
|
header("Location: services_dyndns.php");
|
183
|
exit;
|
184
|
}
|
185
|
}
|
186
|
|
187
|
function build_type_list() {
|
188
|
$types = explode(",", DYNDNS_PROVIDER_DESCRIPTIONS);
|
189
|
$vals = explode(" ", DYNDNS_PROVIDER_VALUES);
|
190
|
$typelist = array();
|
191
|
|
192
|
for ($j = 0; $j < count($vals); $j++)
|
193
|
$typelist[$vals[$j]] = htmlspecialchars($types[$j]);
|
194
|
|
195
|
return($typelist);
|
196
|
}
|
197
|
|
198
|
function build_if_list() {
|
199
|
$list = array();
|
200
|
|
201
|
$iflist = get_configured_interface_with_descr();
|
202
|
|
203
|
foreach ($iflist as $if => $ifdesc)
|
204
|
$list[$if] = $ifdesc;
|
205
|
|
206
|
unset($iflist);
|
207
|
|
208
|
$grouplist = return_gateway_groups_array();
|
209
|
|
210
|
foreach ($grouplist as $name => $group)
|
211
|
$list[$name] = 'GW Group ' . $name;
|
212
|
|
213
|
unset($grouplist);
|
214
|
|
215
|
return($list);
|
216
|
}
|
217
|
|
218
|
$pgtitle = array(gettext("Services"),gettext("Dynamic DNS client"));
|
219
|
include("head.inc");
|
220
|
|
221
|
if ($input_errors)
|
222
|
print_input_errors($input_errors);
|
223
|
|
224
|
if ($savemsg)
|
225
|
print_info_box($savemsg, 'success');
|
226
|
|
227
|
require('classes/Form.class.php');
|
228
|
|
229
|
$form = new Form;
|
230
|
|
231
|
$section = new Form_Section('Dynamic DNS Client');
|
232
|
|
233
|
// Confusingly the 'enable' checkbox is labelled 'Disable', but thats the way it works!
|
234
|
// No action (hide or disable) is taken on selecting this.
|
235
|
$section->addInput(new Form_Checkbox(
|
236
|
'enable',
|
237
|
'Disable',
|
238
|
'Disable this client',
|
239
|
$pconfig['enable']
|
240
|
));
|
241
|
|
242
|
$section->addInput(new Form_Select(
|
243
|
'type',
|
244
|
'Service Type',
|
245
|
$pconfig['type'],
|
246
|
build_type_list()
|
247
|
));
|
248
|
|
249
|
$interfacelist = build_if_list();
|
250
|
|
251
|
$section->addInput(new Form_Select(
|
252
|
'interface',
|
253
|
'Interface to monitor',
|
254
|
$pconfig['interface'],
|
255
|
$interfacelist
|
256
|
));
|
257
|
|
258
|
$section->addInput(new Form_Select(
|
259
|
'requestif',
|
260
|
'Interface to send update from',
|
261
|
$pconfig['request'],
|
262
|
$interfacelist
|
263
|
))->setHelp('This is almost always the same as the Interface to Monitor. ');
|
264
|
|
265
|
$section->addInput(new Form_Input(
|
266
|
'host',
|
267
|
'Hostname',
|
268
|
'text',
|
269
|
$pconfig['host']
|
270
|
))->setHelp('Enter the complete host/domain name. example: myhost.dyndns.org'.
|
271
|
'he.net tunnelbroker: Enter your tunnel ID'.
|
272
|
'GleSYS: Enter your record ID'.
|
273
|
'DNSimple: Enter only the domain name.');
|
274
|
|
275
|
$section->addInput(new Form_Input(
|
276
|
'mx',
|
277
|
'MX',
|
278
|
'text',
|
279
|
$pconfig['mx']
|
280
|
))->setHelp('Note: With DynDNS service you can only use a hostname, not an IP address.'.
|
281
|
'Set this option only if you need a special MX record. Not all services support this.');
|
282
|
|
283
|
$section->addInput(new Form_Checkbox(
|
284
|
'wildcard',
|
285
|
'Wildcards',
|
286
|
'Enable Wildcard',
|
287
|
$pconfig['wildcard']
|
288
|
));
|
289
|
|
290
|
$section->addInput(new Form_Checkbox(
|
291
|
'verboselog',
|
292
|
'Verbose logging',
|
293
|
'Enable verbose logging',
|
294
|
$pconfig['verboselog']
|
295
|
));
|
296
|
|
297
|
$section->addInput(new Form_Checkbox(
|
298
|
'curl_ipresolve_v4',
|
299
|
'CURL options',
|
300
|
'Force IPv4 resolving',
|
301
|
$pconfig['curl_ipresolve_v4']
|
302
|
));
|
303
|
|
304
|
$section->addInput(new Form_Checkbox(
|
305
|
'curl_ssl_verifypeer',
|
306
|
null,
|
307
|
'Verify SSL peer',
|
308
|
$pconfig['curl_ssl_verifypeer']
|
309
|
));
|
310
|
|
311
|
$section->addInput(new Form_Input(
|
312
|
'username',
|
313
|
'Username',
|
314
|
'text',
|
315
|
$pconfig['username']
|
316
|
))->setHelp('Username is required for all types except Namecheap, FreeDNS and Custom Entries.' . '<br />' .
|
317
|
'Route 53: Enter your Access Key ID.' . '<br />' .
|
318
|
'GleSYS: Enter your API user.' . '<br />' .
|
319
|
'For Custom Entries, Username and Password represent HTTP Authentication username and passwords.');
|
320
|
|
321
|
$section->addInput(new Form_Input(
|
322
|
'passwordfld',
|
323
|
'Password',
|
324
|
'password',
|
325
|
$pconfig['passwordfld']
|
326
|
))->setHelp('FreeDNS (freedns.afraid.org): Enter your \"Authentication Token\" provided by FreeDNS.' . '<br />' .
|
327
|
'Route 53: Enter your Secret Access Key.' . '<br />' .
|
328
|
'GleSYS: Enter your API key.' . '<br />' .
|
329
|
'DNSimple: Enter your API token.');
|
330
|
|
331
|
$section->addInput(new Form_Input(
|
332
|
'zoneid',
|
333
|
'Zone ID',
|
334
|
'text',
|
335
|
$pconfig['zoneid']
|
336
|
))->setHelp('Enter Zone ID that you received when you created your domain in Route 53.' . '<br />' .
|
337
|
'DNSimple: Enter the Record ID of record to update.');
|
338
|
|
339
|
$section->addInput(new Form_Input(
|
340
|
'updateurl',
|
341
|
'Update URL',
|
342
|
'text',
|
343
|
$pconfig['updateurl']
|
344
|
))->setHelp('This is the only field required by for Custom Dynamic DNS, and is only used by Custom Entries.');
|
345
|
|
346
|
$section->addInput(new Form_Textarea(
|
347
|
'resultmatch',
|
348
|
'Result Match',
|
349
|
$pconfig['resultmatch']
|
350
|
))->sethelp('This field should be identical to what your DDNS Provider will return if the update succeeds, leave it blank to disable checking of returned results.' . '<br />' .
|
351
|
'If you need the new IP to be included in the request, put %IP% in its place.' . '<br />' .
|
352
|
'If you need to include multiple possible values, separate them with a |. If your provider includes a |, escape it with \\|)' . '<br />' .
|
353
|
'Tabs (\\t), newlines (\\n) and carriage returns (\\r) at the beginning or end of the returned results are removed before comparison.');
|
354
|
|
355
|
$section->addInput(new Form_Input(
|
356
|
'ttl',
|
357
|
'TTL',
|
358
|
'text',
|
359
|
$pconfig['ttl']
|
360
|
))->setHelp('Choose TTL for your dns record.');
|
361
|
|
362
|
$section->addInput(new Form_Input(
|
363
|
'description',
|
364
|
'Description',
|
365
|
'text',
|
366
|
$pconfig['description']
|
367
|
))->setHelp('You may enter a description here for your reference (not parsed).');
|
368
|
|
369
|
if (isset($id) && $a_dyndns[$id]) {
|
370
|
$section->addInput(new Form_Input(
|
371
|
'id',
|
372
|
null,
|
373
|
'hidden',
|
374
|
$id
|
375
|
));
|
376
|
}
|
377
|
|
378
|
$form->add($section);
|
379
|
|
380
|
$form->addGlobal(new Form_Button(
|
381
|
'cancel',
|
382
|
'Cancel',
|
383
|
$referer
|
384
|
))->removeClass('btn-primary')->addClass('btn-default');
|
385
|
|
386
|
print($form);
|
387
|
|
388
|
// Certain input elements are hidden/shown based on the service type in the following script
|
389
|
?>
|
390
|
|
391
|
<script>
|
392
|
//<![CDATA[
|
393
|
events.push(function(){
|
394
|
var visible = false;
|
395
|
|
396
|
// Hides the <div> in which the specified input element lives so that the input, its label and help text are hidden
|
397
|
function hideInput(id, hide) {
|
398
|
if(hide)
|
399
|
$('#' + id).parent().parent('div').addClass('hidden');
|
400
|
else
|
401
|
$('#' + id).parent().parent('div').removeClass('hidden');
|
402
|
}
|
403
|
|
404
|
// Hides the <div> in which the specified checkbox lives so that the checkbox, its label and help text are hidden
|
405
|
function hideCheckbox(id, hide) {
|
406
|
if(hide)
|
407
|
$('#' + id).parent().parent().parent('div').addClass('hidden');
|
408
|
else
|
409
|
$('#' + id).parent().parent().parent('div').removeClass('hidden');
|
410
|
}
|
411
|
|
412
|
function setVisible(service) {
|
413
|
switch(service) {
|
414
|
case "custom" :
|
415
|
case "custom-v6" :
|
416
|
hideInput('resultmatch', false);
|
417
|
hideInput('updateurl', false);
|
418
|
hideInput('requestif', false);
|
419
|
hideCheckbox('curl_ipresolve_v4', false);
|
420
|
hideCheckbox('curl_ssl_verifypeer', false);
|
421
|
hideInput('host', true);
|
422
|
hideInput('mx', true);
|
423
|
hideCheckbox('wildcard', true);
|
424
|
hideInput('zoneid', true);
|
425
|
hideInput('ttl', true);
|
426
|
break;
|
427
|
|
428
|
case "dnsimple":
|
429
|
case "route53":
|
430
|
hideInput('resultmatch', true);
|
431
|
hideInput('updateurl', true);
|
432
|
hideInput('requestif', true);
|
433
|
hideCheckbox('curl_ipresolve_v4', true);
|
434
|
hideCheckbox('curl_ssl_verifypeer', false);
|
435
|
hideInput('host', false);
|
436
|
hideInput('mx', false);
|
437
|
hideCheckbox('wildcard', false);
|
438
|
hideInput('zoneid', false);
|
439
|
hideInput('ttl', false);
|
440
|
break;
|
441
|
|
442
|
default:
|
443
|
hideInput('resultmatch', true);
|
444
|
hideInput('updateurl', true);
|
445
|
hideInput('requestif', true);
|
446
|
hideCheckbox('curl_ipresolve_v4', true);
|
447
|
hideCheckbox('curl_ssl_verifypeer', true);
|
448
|
hideInput('host', false);
|
449
|
hideInput('mx', false);
|
450
|
hideCheckbox('wildcard', false);
|
451
|
hideInput('zoneid', true);
|
452
|
hideInput('ttl', true);
|
453
|
}
|
454
|
}
|
455
|
|
456
|
// When the 'Service type" selector is changed, we show/hide certain elements
|
457
|
$('#type').on('change', function() {
|
458
|
setVisible( this.value );
|
459
|
});
|
460
|
|
461
|
// On initial page load
|
462
|
setVisible($('#type').val());
|
463
|
|
464
|
});
|
465
|
//]]>
|
466
|
</script>
|
467
|
|
468
|
<?php include("foot.inc");
|