End Of Life - discontinue this branch!
[tomato.git] / release / src / router / www / restrict-edit.asp
blob7279724c12651b44ac99a2f04e2fe1ceb89d3391
1 <!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN'>
2 <!--
3 Tomato GUI
4 Copyright (C) 2006-2010 Jonathan Zarate
5 http://www.polarcloud.com/tomato/
7 For use with Tomato Firmware only.
8 No part of this file may be used without permission.
9 -->
10 <html>
11 <head>
12 <meta http-equiv='content-type' content='text/html;charset=utf-8'>
13 <meta name='robots' content='noindex,nofollow'>
14 <title>[<% ident(); %>] Edit Access Restrictions</title>
15 <link rel='stylesheet' type='text/css' href='tomato.css'>
16 <link rel='stylesheet' type='text/css' href='color.css'>
17 <script type='text/javascript' src='tomato.js'></script>
18 <script type='text/javascript' src='protocols.js'></script>
20 <!-- / / / -->
22 <style type='text/css'>
23 #res-comp-grid {
24 width: 60%;
26 #res-bp-grid .box1, #res-bp-grid .box2 {
27 width: 20%;
28 float: left;
30 #res-bp-grid .box3 {
31 width: 60%;
32 float: left;
34 #res-bp-grid .box4 {
35 width: 30%;
36 float: left;
37 clear: left;
38 padding-top: 2px;
40 #res-bp-grid .box5 {
41 width: 70%;
42 float: left;
43 padding-top: 2px;
45 #res-bp-grid .box6 {
46 width: 30%;
47 float: left;
48 padding-top: 2px;
50 #res-bp-grid .box7 {
51 width: 70%;
52 float: left;
53 padding-top: 2px;
56 textarea {
57 width: 99%;
58 height: 20em;
60 </style>
62 <script type='text/javascript' src='debug.js'></script>
64 <script type='text/javascript'>
65 // <% nvram(''); %> // http_id
67 // {enable}|{begin_mins}|{end_mins}|{dow}|{comp[<comp]}|{rules<rules[...]>}|{http[ ...]}|{http_file}|{desc}
68 // <% rrule(); %>
69 if ((rule = rrule.match(/^(\d+)\|(-?\d+)\|(-?\d+)\|(\d+)\|(.*?)\|(.*?)\|([^|]*?)\|(\d+)\|(.*)$/m)) == null) {
70 rule = ['', 1, 1380, 240, 31, '', '', '', 0, 'New Rule ' + (rruleN + 1)];
72 rule[2] *= 1;
73 rule[3] *= 1;
74 rule[4] *= 1;
75 rule[8] *= 1;
77 // <% layer7(); %>
78 layer7.sort();
79 for (i = 0; i < layer7.length; ++i)
80 layer7[i] = [layer7[i],layer7[i]];
81 layer7.unshift(['', 'Layer 7 (disabled)']);
83 var ipp2p = [
84 [0,'IPP2P (disabled)'],[0xFFFF,'All IPP2P Filters'],[1,'AppleJuice'],[2,'Ares'],[4,'BitTorrent'],[8,'Direct Connect'],
85 [16,'eDonkey'],[32,'Gnutella'],[64,'Kazaa'],[128,'Mute'],
86 /* LINUX26-BEGIN */
87 [4096,'PPLive/UUSee'],
88 /* LINUX26-END */
89 [256,'SoulSeek'],[512,'Waste'],[1024,'WinMX'],[2048,'XDCC']
90 /* LINUX26-BEGIN */
91 ,[8192,'Xunlei/QQCyclone']
92 /* LINUX26-END */
95 var dowNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
99 var cg = new TomatoGrid();
101 cg.verifyFields = function(row, quiet) {
102 var f = fields.getAll(row)[0];
103 if (v_mac(f, true)) return true;
104 if (_v_iptaddr(f, true, false, true, true)) return true;
106 ferror.set(f, 'Invalid MAC address or IP address/range', quiet);
107 return false;
110 cg.setup = function() {
111 var a, i, count, ex;
113 this.init('res-comp-grid', 'sort', 140, [ { type: 'text', maxlen: 32 } ] );
114 this.headerSet(['MAC / IP Address']);
115 this.showNewEditor();
116 this.resetNewEditor();
118 if (rule[5] == '~') return; // wireless disable rule
120 ex = 0;
121 count = 0;
122 a = rule[5].split('>');
123 for (i = 0; i < a.length; ++i) {
124 if (!a[i].length) continue;
125 if (a[i] == '!') {
126 ex = 1;
128 else {
129 cg.insertData(-1, [a[i]]);
130 ++count;
134 a = E('_f_comp_all')
135 if (count) {
136 a.value = ex ? 2 : 1;
138 else {
139 a.value = 0;
144 var bpg = new TomatoGrid();
146 bpg.verifyFields = function(row, quiet) {
147 var f = fields.getAll(row);
148 ferror.clearAll(f);
149 this.enDiFields(row);
151 if ((f[5].selectedIndex != 0) && ((!v_length(f[6], quiet, 1)) || (!_v_iptaddr(f[6], quiet, false, true, true)))) return 0;
152 if ((f[1].selectedIndex != 0) && (!v_iptport(f[2], quiet))) return 0;
154 if ((f[1].selectedIndex == 0) && (f[3].selectedIndex == 0) && (f[4].selectedIndex == 0) && (f[5].selectedIndex == 0)) {
155 var m = 'Please enter a specific address or port, or select an application match';
156 ferror.set(f[3], m, 1);
157 ferror.set(f[4], m, 1);
158 ferror.set(f[5], m, 1);
159 ferror.set(f[1], m, quiet);
160 return 0;
163 ferror.clear(f[1]);
164 ferror.clear(f[3]);
165 ferror.clear(f[4]);
166 ferror.clear(f[5]);
167 ferror.clear(f[6]);
168 return 1;
171 bpg.dataToView = function(data) {
172 var s, i;
174 s = '';
175 if (data[5] != 0) s = ((data[5] == 1) ? 'To ' : 'From ') + data[6] + ', ';
177 if (data[0] <= -2) s += (s.length ? 'a' : 'A') + 'ny protocol';
178 else if (data[0] == -1) s += 'TCP/UDP';
179 else if (data[0] >= 0) s += protocols[data[0]] || data[0];
181 if (data[0] >= -1) {
182 if (data[1] == 'd') s += ', dst port ';
183 else if (data[1] == 's') s += ', src port ';
184 else if (data[1] == 'x') s += ', port ';
185 else s += ', all ports';
186 if (data[1] != 'a') s += data[2].replace(/:/g, '-');
189 if (data[3] != 0) {
190 for (i = 0; i < ipp2p.length; ++i) {
191 if (data[3] == ipp2p[i][0]) {
192 s += ', IPP2P: ' + ipp2p[i][1];
193 break;
197 else if (data[4] != '') {
198 s += ', L7: ' + data[4];
201 return [s];
204 bpg.fieldValuesToData = function(row) {
205 var f = fields.getAll(row);
206 return [f[0].value, f[1].value, (f[1].selectedIndex == 0) ? '' : f[2].value, f[3].value, f[4].value, f[5].value, (f[5].selectedIndex == 0) ? '' : f[6].value];
209 bpg.resetNewEditor = function() {
210 var f = fields.getAll(this.newEditor);
211 f[0].selectedIndex = 0;
212 f[1].selectedIndex = 0;
213 f[2].value = '';
214 f[3].selectedIndex = 0;
215 f[4].selectedIndex = 0;
216 f[5].selectedIndex = 0;
217 f[6].value = '';
218 this.enDiFields(this.newEditor);
219 ferror.clearAll(fields.getAll(this.newEditor));
222 bpg._createEditor = bpg.createEditor;
223 bpg.createEditor = function(which, rowIndex, source) {
224 var row = this._createEditor(which, rowIndex, source);
225 if (which == 'edit') this.enDiFields(row);
226 return row;
229 bpg.enDiFields = function(row) {
230 var x;
231 var f = fields.getAll(row);
233 x = f[0].value;
234 x = ((x != -1) && (x != 6) && (x != 17));
235 f[1].disabled = x;
236 if (f[1].selectedIndex == 0) x = 1;
237 f[2].disabled = x;
238 f[3].disabled = (f[4].selectedIndex != 0);
239 f[4].disabled = (f[3].selectedIndex != 0);
240 f[6].disabled = (f[5].selectedIndex == 0);
243 bpg.setup = function() {
244 var a, i, r, count, protos;
246 protos = [[-2, 'Any Protocol'],[-1,'TCP/UDP'],[6,'TCP'],[17,'UDP']];
247 for (i = 0; i < 256; ++i) {
248 if ((i != 6) && (i != 17)) protos.push([i, protocols[i] || i]);
251 this.init('res-bp-grid', 'sort', 140, [ { multi: [
252 { type: 'select', prefix: '<div class="box1">', suffix: '</div>', options: protos },
253 { type: 'select', prefix: '<div class="box2">', suffix: '</div>',
254 options: [['a','Any Port'],['d','Dst Port'],['s','Src Port'],['x','Src or Dst']] },
255 { type: 'text', prefix: '<div class="box3">', suffix: '</div>', maxlen: 32 },
256 { type: 'select', prefix: '<div class="box4">', suffix: '</div>', options: ipp2p },
257 { type: 'select', prefix: '<div class="box5">', suffix: '</div>', options: layer7 },
258 { type: 'select', prefix: '<div class="box6">', suffix: '</div>',
259 options: [[0,'Any Address'],[1,'Dst IP'],[2,'Src IP']] },
260 { type: 'text', prefix: '<div class="box7">', suffix: '</div>', maxlen: 64 }
261 ] } ] );
262 this.headerSet(['Rules']);
263 this.showNewEditor();
264 this.resetNewEditor();
265 count = 0;
267 // ---- proto<dir<port<ipp2p<layer7[<addr_type<addr]
269 a = rule[6].split('>');
270 for (i = 0; i < a.length; ++i) {
271 r = a[i].split('<');
272 if (r.length == 5) {
273 // ---- fixup for backward compatibility
274 r.push('0');
275 r.push('');
277 if (r.length == 7) {
278 r[2] = r[2].replace(/:/g, '-');
279 this.insertData(-1, r);
280 ++count;
283 return count;
288 function verifyFields(focused, quiet)
290 var b, e;
292 tgHideIcons();
294 elem.display(PR('_f_sched_begin'), !E('_f_sched_allday').checked);
295 elem.display(PR('_f_sched_sun'), !E('_f_sched_everyday').checked);
297 b = E('rt_norm').checked;
298 elem.display(PR('_f_comp_all'), PR('_f_block_all'), b);
300 elem.display(PR('res-comp-grid'), b && E('_f_comp_all').value != 0);
301 elem.display(PR('res-bp-grid'), PR('_f_block_http'), PR('_f_activex'), b && !E('_f_block_all').checked);
303 ferror.clear('_f_comp_all');
305 e = E('_f_block_http');
306 e.value = e.value.replace(/[|"']/g, ' ');
307 if (!v_length(e, quiet, 0, 2048 - 16)) return 0;
309 e = E('_f_desc');
310 e.value = e.value.replace(/\|/g, '_');
311 if (!v_length(e, quiet, 1)) return 0;
313 return 1;
316 function cancelRule()
318 document.location = 'restrict.asp';
321 function removeRule()
323 if (!confirm('Delete this rule?')) return;
325 E('delete-button').disabled = 1;
327 e = E('_rrule');
328 e.name = 'rrule' + rruleN;
329 e.value = '';
330 form.submit('_fom');
333 function saveRule()
335 if (!verifyFields(null, false)) return;
336 if ((cg.isEditing()) || (bpg.isEditing())) return;
338 var a, b, e, s, n, data;
340 data = [];
341 data.push(E('_f_enabled').checked ? '1' : '0');
342 if (E('_f_sched_allday').checked) data.push(-1, -1);
343 else data.push(E('_f_sched_begin').value, E('_f_sched_end').value);
345 if (E('_f_sched_everyday').checked) {
346 n = 0x7F;
348 else {
349 n = 0;
350 for (i = 0; i < 7; ++i) {
351 if (E('_f_sched_' + dowNames[i].toLowerCase()).checked) n |= (1 << i);
353 if (n == 0) n = 0x7F;
355 data.push(n);
357 if (E('rt_norm').checked) {
358 e = E('_f_comp_all');
359 if (e.value != 0) {
360 a = cg.getAllData();
361 if (a.length == 0) {
362 ferror.set(e, 'No MAC or IP address was specified', 0);
363 return;
365 if (e.value == 2) a.unshift('!');
366 data.push(a.join('>'));
368 else {
369 data.push('');
372 if (E('_f_block_all').checked) {
373 data.push('', '', '0');
375 else {
376 var check = 0;
377 a = bpg.getAllData();
378 check += a.length;
379 b = [];
380 for (i = 0; i < a.length; ++i) {
381 a[i][2] = a[i][2].replace(/-/g, ':');
382 b.push(a[i].join('<'));
384 data.push(b.join('>'));
386 a = E('_f_block_http').value.replace(/\r+/g, ' ').replace(/\n+/g, '\n').replace(/ +/g, ' ').replace(/^\s+|\s+$/g, '');
387 check += a.length;
388 data.push(a);
390 n = 0;
391 if (E('_f_activex').checked) n = 1;
392 if (E('_f_flash').checked) n |= 2;
393 if (E('_f_java').checked) n |= 4;
394 data.push(n);
396 if (((check + n) == 0) && (data[0] == 1)) {
397 alert('Please specify what items should be blocked.');
398 return;
402 else {
403 data.push('~');
404 data.push('', '', '', '0');
407 data.push(E('_f_desc').value);
408 data = data.join('|');
410 if (data.length >= 2048) {
411 alert('This rule is too big. Please reduce by ' + (data.length - 2048) + ' characters.');
412 return;
415 e = E('_rrule');
416 e.name = 'rrule' + rruleN;
417 e.value = data;
419 E('delete-button').disabled = 1;
420 form.submit('_fom');
423 function init()
425 cg.recolor();
426 bpg.recolor();
429 function earlyInit()
431 var count;
433 cg.setup();
435 count = bpg.setup();
436 E('_f_block_all').checked = (count == 0) && (rule[7].search(/[^\s\r\n]/) == -1) && (rule[8] == 0);
437 verifyFields(null, 1);
439 </script>
440 </head>
441 <body onload='init()'>
442 <form name='_fom' id='_fom' method='post' action='tomato.cgi'>
443 <table id='container' cellspacing=0>
444 <tr><td colspan=2 id='header'>
445 <div class='title'>Tomato</div>
446 <div class='version'>Version <% version(); %></div>
447 </td></tr>
448 <tr id='body'><td id='navi'><script type='text/javascript'>navi()</script></td>
449 <td id='content'>
450 <div id='ident'><% ident(); %></div>
452 <!-- / / / -->
454 <input type='hidden' name='_nextpage' value='restrict.asp'>
455 <input type='hidden' name='_service' value='restrict-restart'>
456 <input type='hidden' name='rruleNN' id='_rrule' value=''>
458 <div class='section-title'>Access Restriction</div>
459 <div class='section'>
460 <script type='text/javascript'>
461 W('<div style="float:right"><small>'+ 'ID: ' + rruleN.pad(2) + '</small>&nbsp;</div><br>');
462 tm = [];
463 for (i = 0; i < 1440; i += 15) tm.push([i, timeString(i)]);
465 createFieldTable('', [
466 { title: 'Enabled', name: 'f_enabled', type: 'checkbox', value: rule[1] == '1' },
467 { title: 'Description', name: 'f_desc', type: 'text', maxlen: 32, size: 35, value: rule[9] },
468 { title: 'Schedule', multi: [
469 { name: 'f_sched_allday', type: 'checkbox', suffix: ' All Day &nbsp; ', value: (rule[2] < 0) || (rule[3] < 0) },
470 { name: 'f_sched_everyday', type: 'checkbox', suffix: ' Everyday', value: (rule[4] & 0x7F) == 0x7F } ] },
471 { title: 'Time', indent: 2, multi: [
472 { name: 'f_sched_begin', type: 'select', options: tm, value: (rule[2] < 0) ? 0 : rule[2], suffix: ' - ' },
473 { name: 'f_sched_end', type: 'select', options: tm, value: (rule[3] < 0) ? 0 : rule[3] } ] },
474 { title: 'Days', indent: 2, multi: [
475 { name: 'f_sched_sun', type: 'checkbox', suffix: ' Sun &nbsp; ', value: (rule[4] & 1) },
476 { name: 'f_sched_mon', type: 'checkbox', suffix: ' Mon &nbsp; ', value: (rule[4] & (1 << 1)) },
477 { name: 'f_sched_tue', type: 'checkbox', suffix: ' Tue &nbsp; ', value: (rule[4] & (1 << 2)) },
478 { name: 'f_sched_wed', type: 'checkbox', suffix: ' Wed &nbsp; ', value: (rule[4] & (1 << 3)) },
479 { name: 'f_sched_thu', type: 'checkbox', suffix: ' Thu &nbsp; ', value: (rule[4] & (1 << 4)) },
480 { name: 'f_sched_fri', type: 'checkbox', suffix: ' Fri &nbsp; ', value: (rule[4] & (1 << 5)) },
481 { name: 'f_sched_sat', type: 'checkbox', suffix: ' Sat', value: (rule[4] & (1 << 6)) } ] },
482 { title: 'Type', name: 'f_type', id: 'rt_norm', type: 'radio', suffix: ' Normal Access Restriction', value: (rule[5] != '~') },
483 { title: '', name: 'f_type', id: 'rt_wl', type: 'radio', suffix: ' Disable Wireless', value: (rule[5] == '~') },
484 { title: 'Applies To', name: 'f_comp_all', type: 'select', options: [[0,'All Computers / Devices'],[1,'The Following...'],[2,'All Except...']], value: 0 },
485 { title: '&nbsp;', text: '<table class="tomato-grid" cellspacing=1 id="res-comp-grid"></table>' },
486 { title: 'Blocked Resources', name: 'f_block_all', type: 'checkbox', suffix: ' Block All Internet Access', value: 0 },
487 { title: 'Port /<br>Application', indent: 2, text: '<table class="tomato-grid" cellspacing=1 id="res-bp-grid"></table>' },
488 { title: 'HTTP Request', indent: 2, name: 'f_block_http', type: 'textarea', value: rule[7] },
489 { title: 'HTTP Requested Files', indent: 2, multi: [
490 { name: 'f_activex', type: 'checkbox', suffix: ' ActiveX (ocx, cab) &nbsp;&nbsp;', value: (rule[8] & 1) },
491 { name: 'f_flash', type: 'checkbox', suffix: ' Flash (swf) &nbsp;&nbsp;', value: (rule[8] & 2) },
492 { name: 'f_java', type: 'checkbox', suffix: ' Java (class, jar) &nbsp;&nbsp;', value: (rule[8] & 4) } ] }
494 </script>
495 </div>
497 <!-- / / / -->
499 </td></tr>
500 <tr><td id='footer' colspan=2>
501 <span id='footer-msg'></span>
502 <input type='button' value='Delete...' id='delete-button' onclick='removeRule()'>
503 &nbsp;
504 <input type='button' value='Save' id='save-button' onclick='saveRule()'>
505 <input type='button' value='Cancel' id='cancel-button' onclick='cancelRule()'>
506 </td></tr>
507 </table>
508 <br><br>
509 </form>
510 <script type='text/javascript'>earlyInit();</script>
511 </body>
512 </html>