UI cleanup, phase 2 (partially cosmetic)
[tomato.git] / release / src-rt-6.x.4708 / router / www / nas-ftp.asp
blobf8f482f28769dfc51b5021bd3100f8a6a8231999
1 <!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN'>
2 <!--
3 Tomato GUI
4 FTP Server - !!TB
6 For use with Tomato Firmware only.
7 No part of this file may be used without permission.
8 -->
9 <html>
10 <head>
11 <meta http-equiv='content-type' content='text/html;charset=utf-8'>
12 <meta name='robots' content='noindex,nofollow'>
13 <title>[<% ident(); %>] NAS: FTP Server</title>
14 <link rel='stylesheet' type='text/css' href='tomato.css'>
15 <link rel='stylesheet' type='text/css' href='color.css'>
16 <script type='text/javascript' src='tomato.js'></script>
18 <!-- / / / -->
19 <style type='text/css'>
20 #aft-grid {
21 width: 99%;
23 #aft-grid .co1 {
24 width: 20%;
26 #aft-grid .co2 {
27 width: 20%;
29 #aft-grid .co3 {
30 width: 15%;
32 #aft-grid .co4 {
33 width: 45%;
35 </style>
37 <style type='text/css'>
38 textarea {
39 width: 98%;
40 height: 5em;
42 </style>
44 <script type='text/javascript' src='debug.js'></script>
46 <script type='text/javascript'>
48 // <% nvram("ftp_enable,ftp_super,ftp_anonymous,ftp_dirlist,ftp_port,ftp_max,ftp_ipmax,ftp_staytimeout,ftp_rate,ftp_anonrate,ftp_anonroot,ftp_pubroot,ftp_pvtroot,ftp_custom,ftp_users,ftp_sip,ftp_limit,log_ftp"); %>
50 ftplimit = nvram.ftp_limit.split(',');
51 if (ftplimit.length != 3) ftplimit = [0,3,60];
53 var aftg = new TomatoGrid();
55 aftg.exist = function(f, v)
57 var data = this.getAllData();
58 for (var i = 0; i < data.length; ++i) {
59 if (data[i][f] == v) return true;
61 return false;
64 aftg.existName = function(name)
66 return this.exist(0, name);
69 aftg.sortCompare = function(a, b) {
70 var da = a.getRowData();
71 var db = b.getRowData();
72 var r = cmpText(da[this.sortColumn], db[this.sortColumn]);
73 return this.sortAscending ? r : -r;
76 aftg.verifyFields = function(row, quiet)
78 var f, s;
79 f = fields.getAll(row);
81 ferror.clear(f[0]);
82 ferror.clear(f[1]);
83 ferror.clear(f[3]);
85 if (!v_length(f[0], quiet, 1)) return 0;
87 s = f[0].value.trim().replace(/\s+/g, ' ');
88 if (s.length > 0) {
89 if (s.search(/^[a-zA-Z0-9_\-]+$/) == -1) {
90 ferror.set(f[0], 'Invalid user name. Only characters "A-Z 0-9 - _" are allowed.', quiet);
91 return 0;
93 if (this.existName(s)) {
94 ferror.set(f[0], 'Duplicate user name.', quiet);
95 return 0;
97 if (s == 'root' || s == 'admin') {
98 ferror.set(f[0], 'User names "root" and "admin" are not allowed.', quiet);
99 return 0;
101 f[0].value = s;
104 if (!v_length(f[1], quiet, 1)) return 0;
105 if (!v_nodelim(f[1], quiet, 'Password', 1)) return 0;
106 if (f[2].value == 'Private') {
107 f[3].value = '';
108 f[3].disabled = true;
110 else {
111 f[3].disabled = false;
112 if (!v_nodelim(f[3], quiet, 'Root Directory', 1) || !v_path(f[3], quiet, 0)) return 0;
115 return 1;
118 aftg.resetNewEditor = function() {
119 var f;
121 f = fields.getAll(this.newEditor);
122 ferror.clearAll(f);
124 f[0].value = '';
125 f[1].value = '';
126 f[2].selectedIndex = 0;
127 f[3].value = '';
130 aftg.setup = function()
132 this.init('aft-grid', 'sort', 50, [
133 { type: 'text', maxlen: 50 },
134 { type: 'password', maxlen: 50, peekaboo: 1 },
135 { type: 'select', options: [['Read/Write', 'Read/Write'],['Read Only', 'Read Only'],['View Only', 'View Only'],['Private', 'Private']] },
136 { type: 'text', maxlen: 128 }
138 this.headerSet(['User Name', 'Password', 'Access', 'Root Directory*']);
140 var s = nvram.ftp_users.split('>');
141 for (var i = 0; i < s.length; ++i) {
142 var t = s[i].split('<');
143 if (t.length == 3) {
144 t.push('');
146 if (t.length == 4) {
147 this.insertData(-1, t);
151 this.showNewEditor();
152 this.resetNewEditor();
155 function verifyFields(focused, quiet)
157 var a, b;
158 var ok = 1;
160 a = E('_ftp_enable').value;
161 b = E('_ftp_port');
162 elem.display(PR(b), (a != 0));
163 b = E('_f_ftp_sip');
164 elem.display(PR(b), (a == 1));
166 E('_f_limit').disabled = (a != 1);
167 b = E('_f_limit').checked;
168 elem.display(PR('_f_limit_hit'), PR('_f_limit_sec'), (a == 1 && b));
169 E('_ftp_anonymous').disabled = (a == 0);
170 E('_f_ftp_super').disabled = (a == 0);
171 E('_f_log_ftp').disabled = (a == 0);
172 E('_ftp_pubroot').disabled = (a == 0);
173 E('_ftp_pvtroot').disabled = (a == 0);
174 E('_ftp_anonroot').disabled = (a == 0);
175 E('_ftp_dirlist').disabled = (a == 0);
176 E('_ftp_max').disabled = (a == 0);
177 E('_ftp_ipmax').disabled = (a == 0);
178 E('_ftp_rate').disabled = (a == 0);
179 E('_ftp_anonrate').disabled = (a == 0);
180 E('_ftp_staytimeout').disabled = (a == 0);
181 E('_ftp_custom').disabled = (a == 0);
183 if (a != 0) {
184 if (!v_port('_ftp_port', quiet || !ok)) ok = 0;
185 if (!v_range('_ftp_max', quiet || !ok, 0, 12)) ok = 0;
186 if (!v_range('_ftp_ipmax', quiet || !ok, 0, 12)) ok = 0;
187 if (!v_range('_ftp_rate', quiet || !ok, 0, 99999)) ok = 0;
188 if (!v_range('_ftp_anonrate', quiet || !ok, 0, 99999)) ok = 0;
189 if (!v_range('_ftp_staytimeout', quiet || !ok, 0, 65535)) ok = 0;
190 if (!v_length('_ftp_custom', quiet || !ok, 0, 2048)) ok = 0;
191 if (!v_path('_ftp_pubroot', quiet || !ok, 0)) ok = 0;
192 if (!v_path('_ftp_pvtroot', quiet || !ok, 0)) ok = 0;
193 if (!v_path('_ftp_anonroot', quiet || !ok, 0)) ok = 0;
194 if (a == 1 && b) {
195 if (!v_range('_f_limit_hit', quiet || !ok, 1, 100)) ok = 0;
196 if (!v_range('_f_limit_sec', quiet || !ok, 3, 3600)) ok = 0;
200 if (a == 1) {
201 b = E('_f_ftp_sip');
202 if ((b.value.length) && (!_v_iptaddr(b, quiet || !ok, 15, 1, 1))) ok = 0;
203 else ferror.clear(b);
206 return ok;
209 function save()
211 if (aftg.isEditing()) return;
212 if (!verifyFields(null, 0)) return;
214 var fom = E('_fom');
216 var data = aftg.getAllData();
217 var r = [];
218 for (var i = 0; i < data.length; ++i) r.push(data[i].join('<'));
219 fom.ftp_users.value = r.join('>');
221 fom.ftp_sip.value = fom.f_ftp_sip.value.split(/\s*,\s*/).join(',');
222 fom.ftp_super.value = E('_f_ftp_super').checked ? 1 : 0;
223 fom.log_ftp.value = E('_f_log_ftp').checked ? 1 : 0;
225 fom.ftp_limit.value = (E('_f_limit').checked ? 1 : 0) +
226 ',' + E('_f_limit_hit').value + ',' + E('_f_limit_sec').value;
228 form.submit(fom, 1);
230 </script>
232 </head>
233 <body>
234 <form id='_fom' method='post' action='tomato.cgi'>
235 <table id='container' cellspacing=0>
236 <tr><td colspan=2 id='header'>
237 <div class='title'>Tomato</div>
238 <div class='version'>Version <% version(); %></div>
239 </td></tr>
240 <tr id='body'><td id='navi'><script type='text/javascript'>navi()</script></td>
241 <td id='content'>
242 <div id='ident'><% ident(); %></div>
244 <!-- / / / -->
246 <input type='hidden' name='_nextpage' value='nas-ftp.asp'>
247 <input type='hidden' name='_service' value='ftpd-restart'>
249 <input type='hidden' name='ftp_super'>
250 <input type='hidden' name='log_ftp'>
251 <input type='hidden' name='ftp_users'>
252 <input type='hidden' name='ftp_sip'>
253 <input type='hidden' name='ftp_limit'>
255 <div class='section-title'>FTP Server Configuration</div>
256 <div class='section'>
257 <script type='text/javascript'>
258 createFieldTable('', [
259 { title: 'Enable FTP Server', name: 'ftp_enable', type: 'select',
260 options: [['0', 'No'],['1', 'Yes, WAN and LAN'],['2', 'Yes, LAN only']],
261 value: nvram.ftp_enable },
262 { title: 'FTP Port', indent: 2, name: 'ftp_port', type: 'text', maxlen: 5, size: 7, value: fixPort(nvram.ftp_port, 21) },
263 { title: 'Allowed Remote<br>Address(es)', indent: 2, name: 'f_ftp_sip', type: 'text', maxlen: 512, size: 64, value: nvram.ftp_sip,
264 suffix: '<br><small>(optional; ex: "1.1.1.1", "1.1.1.0/24", "1.1.1.1 - 2.2.2.2" or "me.example.com")</small>' },
265 { title: 'Anonymous Users Access', name: 'ftp_anonymous', type: 'select',
266 options: [['0', 'Disabled'],['1', 'Read/Write'],['2', 'Read Only'],['3', 'Write Only']],
267 value: nvram.ftp_anonymous },
268 { title: 'Allow Admin Login*', name: 'f_ftp_super', type: 'checkbox',
269 suffix: ' <small>Allows users to connect with admin account.</small>',
270 value: nvram.ftp_super == 1 },
271 { title: 'Log FTP requests and responses', name: 'f_log_ftp', type: 'checkbox',
272 value: nvram.log_ftp == 1 }
274 </script>
275 <small><br>*&nbsp;Avoid using this option when FTP server is enabled for WAN. IT PROVIDES FULL ACCESS TO THE ROUTER FILE SYSTEM!</small>
276 </div>
278 <div class='section-title'>Directories</div>
279 <div class='section'>
280 <script type='text/javascript'>
281 createFieldTable('', [
282 { title: 'Anonymous Root Directory*', name: 'ftp_anonroot', type: 'text', maxlen: 256, size: 32,
283 suffix: ' <small>(for anonymous connections)</small>',
284 value: nvram.ftp_anonroot },
285 { title: 'Public Root Directory*', name: 'ftp_pubroot', type: 'text', maxlen: 256, size: 32,
286 suffix: ' <small>(for authenticated users access, if not specified for the user)</small>',
287 value: nvram.ftp_pubroot },
288 { title: 'Private Root Directory**', name: 'ftp_pvtroot', type: 'text', maxlen: 256, size: 32,
289 suffix: ' <small>(for authenticated users access in private mode)</small>',
290 value: nvram.ftp_pvtroot },
291 { title: 'Directory Listings', name: 'ftp_dirlist', type: 'select',
292 options: [['0', 'Enabled'],['1', 'Disabled'],['2', 'Disabled for Anonymous']],
293 suffix: ' <small>(always enabled for Admin)</small>',
294 value: nvram.ftp_dirlist }
296 </script>
297 <small>
298 <br>*&nbsp;&nbsp;When no directory is specified, /mnt is used as a root directory.
299 <br>**&nbsp;In private mode, the root directory is the directory under the "Private Root Directory" with the name matching the name of the user.
300 </small>
301 </div>
303 <div class='section-title'>Limits</div>
304 <div class='section'>
305 <script type='text/javascript'>
306 createFieldTable('', [
307 { title: 'Maximum Users Allowed to Log in', name: 'ftp_max', type: 'text', maxlen: 5, size: 7,
308 suffix: ' <small>(0 - unlimited)</small>',
309 value: nvram.ftp_max },
310 { title: 'Maximum Connections from the same IP', name: 'ftp_ipmax', type: 'text', maxlen: 5, size: 7,
311 suffix: ' <small>(0 - unlimited)</small>',
312 value: nvram.ftp_ipmax },
313 { title: 'Maximum Bandwidth for Anonymous Users', name: 'ftp_anonrate', type: 'text', maxlen: 5, size: 7,
314 suffix: ' <small>KBytes/s (0 - unlimited)</small>',
315 value: nvram.ftp_anonrate },
316 { title: 'Maximum Bandwidth for Authenticated Users', name: 'ftp_rate', type: 'text', maxlen: 5, size: 7,
317 suffix: ' <small>KBytes/s (0 - unlimited)</small>',
318 value: nvram.ftp_rate },
319 { title: 'Idle Timeout', name: 'ftp_staytimeout', type: 'text', maxlen: 5, size: 7,
320 suffix: ' <small>seconds (0 - no timeout)</small>',
321 value: nvram.ftp_staytimeout },
322 { title: 'Limit Connection Attempts', name: 'f_limit', type: 'checkbox',
323 value: ftplimit[0] != 0 },
324 { title: '', indent: 2, multi: [
325 { name: 'f_limit_hit', type: 'text', maxlen: 4, size: 6, suffix: '&nbsp; <small>every</small> &nbsp;', value: ftplimit[1] },
326 { name: 'f_limit_sec', type: 'text', maxlen: 4, size: 6, suffix: '&nbsp; <small>seconds</small>', value: ftplimit[2] }
329 </script>
330 </div>
332 <div class='section-title'>Custom Configuration</div>
333 <div class='section'>
334 <script type='text/javascript'>
335 createFieldTable('', [
336 { title: '<a href="http://vsftpd.beasts.org/vsftpd_conf.html" target="_new">Vsftpd</a><br>Custom Configuration', name: 'ftp_custom', type: 'textarea', value: nvram.ftp_custom }
338 </script>
339 </div>
341 <div class='section-title'>User Accounts</div>
342 <div class='section'>
343 <table class='tomato-grid' cellspacing=1 id='aft-grid'></table>
344 <script type='text/javascript'>aftg.setup();</script>
345 <small>
346 *&nbsp;&nbsp;When no Root Directory is specified for the user, the default "Public Root Directory" is used.
347 </small>
348 </div>
350 <!-- / / / -->
352 </td></tr>
353 <tr><td id='footer' colspan=2>
354 <span id='footer-msg'></span>
355 <input type='button' value='Save' id='save-button' onclick='save()'>
356 <input type='button' value='Cancel' id='cancel-button' onclick='javascript:reloadPage();'>
357 </td></tr>
358 </table>
359 </form>
360 <script type='text/javascript'>verifyFields(null, 1);</script>
361 </body>
362 </html>