cosmetics
[tomato.git] / release / src / router / www / nas-ftp.asp
blobbc7023a20eb54fdf61c167a1155021879e500386
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 tyle='text/css'>
20 #aft-grid {
21 width: 99%;
23 #aft-grid .co1,
24 #aft-grid .co2 {
25 width: 40%;
27 #aft-grid .co3 {
28 width: 20%;
30 </style>
32 <style type='text/css'>
33 textarea {
34 width: 98%;
35 height: 5em;
37 </style>
39 <script type='text/javascript' src='debug.js'></script>
41 <script type='text/javascript'>
43 // <% 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"); %>
45 ftplimit = nvram.ftp_limit.split(',');
46 if (ftplimit.length != 3) ftplimit = [0,3,60];
48 var aftg = new TomatoGrid();
50 aftg.exist = function(f, v)
52 var data = this.getAllData();
53 for (var i = 0; i < data.length; ++i) {
54 if (data[i][f] == v) return true;
56 return false;
59 aftg.existName = function(name)
61 return this.exist(0, name);
64 aftg.sortCompare = function(a, b) {
65 var da = a.getRowData();
66 var db = b.getRowData();
67 var r = cmpText(da[this.sortColumn], db[this.sortColumn]);
68 return this.sortAscending ? r : -r;
71 aftg.verifyFields = function(row, quiet)
73 var f, s;
74 f = fields.getAll(row);
76 ferror.clear(f[0]);
77 ferror.clear(f[1]);
79 if (!v_length(f[0], quiet, 1)) return 0;
81 s = f[0].value.trim().replace(/\s+/g, ' ');
82 if (s.length > 0) {
83 if (s.search(/^[a-zA-Z0-9_\-]+$/) == -1) {
84 ferror.set(f[0], 'Invalid user name. Only characters "A-Z 0-9 - _" are allowed.', quiet);
85 return 0;
87 if (this.existName(s)) {
88 ferror.set(f[0], 'Duplicate user name.', quiet);
89 return 0;
91 if (s == 'root' || s == 'admin') {
92 ferror.set(f[0], 'User names "root" and "admin" are not allowed.', quiet);
93 return 0;
95 f[0].value = s;
98 if (!v_length(f[1], quiet, 1)) return 0;
99 if (!v_nodelim(f[1], quiet, 'Password', 1)) return 0;
101 return 1;
104 aftg.resetNewEditor = function() {
105 var f;
107 f = fields.getAll(this.newEditor);
108 ferror.clearAll(f);
110 f[0].value = '';
111 f[1].value = '';
112 f[2].selectedIndex = 0;
115 aftg.setup = function()
117 this.init('aft-grid', 'sort', 50, [
118 { type: 'text', maxlen: 50 },
119 { type: 'password', maxlen: 50, peekaboo: 1 },
120 { type: 'select', options: [['Read/Write', 'Read/Write'],['Read Only', 'Read Only'],['View Only', 'View Only'],['Private', 'Private']] }
122 this.headerSet(['User Name', 'Password', 'Access']);
124 var s = nvram.ftp_users.split('>');
125 for (var i = 0; i < s.length; ++i) {
126 var t = s[i].split('<');
127 if (t.length == 3) {
128 this.insertData(-1, t);
132 this.showNewEditor();
133 this.resetNewEditor();
136 function verifyFields(focused, quiet)
138 var a, b;
139 var ok = 1;
141 a = E('_ftp_enable').value;
142 b = E('_ftp_port');
143 elem.display(PR(b), (a != 0));
144 b = E('_f_ftp_sip');
145 elem.display(PR(b), (a == 1));
147 E('_f_limit').disabled = (a != 1);
148 b = E('_f_limit').checked;
149 elem.display(PR('_f_limit_hit'), PR('_f_limit_sec'), (a == 1 && b));
150 E('_ftp_anonymous').disabled = (a == 0);
151 E('_f_ftp_super').disabled = (a == 0);
152 E('_f_log_ftp').disabled = (a == 0);
153 E('_ftp_pubroot').disabled = (a == 0);
154 E('_ftp_pvtroot').disabled = (a == 0);
155 E('_ftp_anonroot').disabled = (a == 0);
156 E('_ftp_dirlist').disabled = (a == 0);
157 E('_ftp_max').disabled = (a == 0);
158 E('_ftp_ipmax').disabled = (a == 0);
159 E('_ftp_rate').disabled = (a == 0);
160 E('_ftp_anonrate').disabled = (a == 0);
161 E('_ftp_staytimeout').disabled = (a == 0);
162 E('_ftp_custom').disabled = (a == 0);
164 if (a != 0) {
165 if (!v_port('_ftp_port', quiet || !ok)) ok = 0;
166 if (!v_range('_ftp_max', quiet || !ok, 0, 12)) ok = 0;
167 if (!v_range('_ftp_ipmax', quiet || !ok, 0, 12)) ok = 0;
168 if (!v_range('_ftp_rate', quiet || !ok, 0, 99999)) ok = 0;
169 if (!v_range('_ftp_anonrate', quiet || !ok, 0, 99999)) ok = 0;
170 if (!v_range('_ftp_staytimeout', quiet || !ok, 0, 65535)) ok = 0;
171 if (!v_length('_ftp_custom', quiet || !ok, 0, 2048)) ok = 0;
172 if (!v_path('_ftp_pubroot', quiet || !ok, 0)) ok = 0;
173 if (!v_path('_ftp_pvtroot', quiet || !ok, 0)) ok = 0;
174 if (!v_path('_ftp_anonroot', quiet || !ok, 0)) ok = 0;
175 if (a == 1 && b) {
176 if (!v_range('_f_limit_hit', quiet || !ok, 1, 100)) ok = 0;
177 if (!v_range('_f_limit_sec', quiet || !ok, 3, 3600)) ok = 0;
181 if (a == 1) {
182 b = E('_f_ftp_sip');
183 if ((b.value.length) && (!_v_iptaddr(b, quiet || !ok, 15, 1, 1))) ok = 0;
184 else ferror.clear(b);
187 return ok;
190 function save()
192 if (aftg.isEditing()) return;
193 if (!verifyFields(null, 0)) return;
195 var fom = E('_fom');
197 var data = aftg.getAllData();
198 var r = [];
199 for (var i = 0; i < data.length; ++i) r.push(data[i].join('<'));
200 fom.ftp_users.value = r.join('>');
202 fom.ftp_sip.value = fom.f_ftp_sip.value.split(/\s*,\s*/).join(',');
203 fom.ftp_super.value = E('_f_ftp_super').checked ? 1 : 0;
204 fom.log_ftp.value = E('_f_log_ftp').checked ? 1 : 0;
206 fom.ftp_limit.value = (E('_f_limit').checked ? 1 : 0) +
207 ',' + E('_f_limit_hit').value + ',' + E('_f_limit_sec').value;
209 form.submit(fom, 1);
211 </script>
213 </head>
214 <body>
215 <form id='_fom' method='post' action='tomato.cgi'>
216 <table id='container' cellspacing=0>
217 <tr><td colspan=2 id='header'>
218 <div class='title'>Tomato</div>
219 <div class='version'>Version <% version(); %></div>
220 </td></tr>
221 <tr id='body'><td id='navi'><script type='text/javascript'>navi()</script></td>
222 <td id='content'>
223 <div id='ident'><% ident(); %></div>
225 <!-- / / / -->
227 <input type='hidden' name='_nextpage' value='nas-ftp.asp'>
228 <input type='hidden' name='_service' value='ftpd-restart'>
230 <input type='hidden' name='ftp_super'>
231 <input type='hidden' name='log_ftp'>
232 <input type='hidden' name='ftp_users'>
233 <input type='hidden' name='ftp_sip'>
234 <input type='hidden' name='ftp_limit'>
236 <div class='section-title'>FTP Server Configuration</div>
237 <div class='section'>
238 <script type='text/javascript'>
239 createFieldTable('', [
240 { title: 'Enable FTP Server', name: 'ftp_enable', type: 'select',
241 options: [['0', 'No'],['1', 'Yes, WAN and LAN'],['2', 'Yes, LAN only']],
242 value: nvram.ftp_enable },
243 { title: 'FTP Port', indent: 2, name: 'ftp_port', type: 'text', maxlen: 5, size: 7, value: fixPort(nvram.ftp_port, 21) },
244 { title: 'Allowed Remote<br>Address(es)', indent: 2, name: 'f_ftp_sip', type: 'text', maxlen: 512, size: 64, value: nvram.ftp_sip,
245 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>' },
246 { title: 'Anonymous Users Access', name: 'ftp_anonymous', type: 'select',
247 options: [['0', 'Disabled'],['1', 'Read/Write'],['2', 'Read Only'],['3', 'Write Only']],
248 value: nvram.ftp_anonymous },
249 { title: 'Allow Admin Login*', name: 'f_ftp_super', type: 'checkbox',
250 suffix: ' <small>Allows users to connect with admin account.</small>',
251 value: nvram.ftp_super == 1 },
252 { title: 'Log FTP requests and responses', name: 'f_log_ftp', type: 'checkbox',
253 value: nvram.log_ftp == 1 }
255 </script>
256 <small><br>*&nbsp;Avoid using this option when FTP server is enabled for WAN. IT PROVIDES FULL ACCESS TO THE ROUTER FILE SYSTEM!</small>
257 </div>
259 <div class='section-title'>Directories</div>
260 <div class='section'>
261 <script type='text/javascript'>
262 createFieldTable('', [
263 { title: 'Public Root Directory*', name: 'ftp_pubroot', type: 'text', maxlen: 256, size: 32,
264 suffix: ' <small>(for authenticated users access)</small>',
265 value: nvram.ftp_pubroot },
266 { title: 'Private Root Directory**', name: 'ftp_pvtroot', type: 'text', maxlen: 256, size: 32,
267 suffix: ' <small>(for authenticated users access in private mode)</small>',
268 value: nvram.ftp_pvtroot },
269 { title: 'Anonymous Root Directory*', name: 'ftp_anonroot', type: 'text', maxlen: 256, size: 32,
270 suffix: ' <small>(for anonymous connections)</small>',
271 value: nvram.ftp_anonroot },
272 { title: 'Directory Listings', name: 'ftp_dirlist', type: 'select',
273 options: [['0', 'Enabled'],['1', 'Disabled'],['2', 'Disabled for Anonymous']],
274 suffix: ' <small>(always enabled for Admin)</small>',
275 value: nvram.ftp_dirlist }
277 </script>
278 <small>
279 <br>*&nbsp;&nbsp;When no directory is specified, /mnt is used as a root directory.
280 <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.
281 </small>
282 </div>
284 <div class='section-title'>Limits</div>
285 <div class='section'>
286 <script type='text/javascript'>
287 createFieldTable('', [
288 { title: 'Maximum Users Allowed to Log in', name: 'ftp_max', type: 'text', maxlen: 5, size: 7,
289 suffix: ' <small>(0 - unlimited)</small>',
290 value: nvram.ftp_max },
291 { title: 'Maximum Connections from the same IP', name: 'ftp_ipmax', type: 'text', maxlen: 5, size: 7,
292 suffix: ' <small>(0 - unlimited)</small>',
293 value: nvram.ftp_ipmax },
294 { title: 'Maximum Bandwidth for Anonymous Users', name: 'ftp_anonrate', type: 'text', maxlen: 5, size: 7,
295 suffix: ' <small>KBytes/sec (0 - unlimited)</small>',
296 value: nvram.ftp_anonrate },
297 { title: 'Maximum Bandwidth for Authenticated Users', name: 'ftp_rate', type: 'text', maxlen: 5, size: 7,
298 suffix: ' <small>KBytes/sec (0 - unlimited)</small>',
299 value: nvram.ftp_rate },
300 { title: 'Idle Timeout', name: 'ftp_staytimeout', type: 'text', maxlen: 5, size: 7,
301 suffix: ' <small>seconds (0 - no timeout)</small>',
302 value: nvram.ftp_staytimeout },
303 { title: 'Limit Connection Attempts', name: 'f_limit', type: 'checkbox',
304 value: ftplimit[0] != 0 },
305 { title: '', indent: 2, multi: [
306 { name: 'f_limit_hit', type: 'text', maxlen: 4, size: 6, suffix: '&nbsp; <small>every</small> &nbsp;', value: ftplimit[1] },
307 { name: 'f_limit_sec', type: 'text', maxlen: 4, size: 6, suffix: '&nbsp; <small>seconds</small>', value: ftplimit[2] }
310 </script>
311 </div>
313 <div class='section-title'>Custom Configuration</div>
314 <div class='section'>
315 <script type='text/javascript'>
316 createFieldTable('', [
317 { 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 }
319 </script>
320 </div>
322 <div class='section-title'>User Accounts</div>
323 <div class='section'>
324 <table class='tomato-grid' cellspacing=1 id='aft-grid'></table>
325 <script type='text/javascript'>aftg.setup();</script>
326 </div>
328 <!-- / / / -->
330 </td></tr>
331 <tr><td id='footer' colspan=2>
332 <span id='footer-msg'></span>
333 <input type='button' value='Save' id='save-button' onclick='save()'>
334 <input type='button' value='Cancel' id='cancel-button' onclick='javascript:reloadPage();'>
335 </td></tr>
336 </table>
337 </form>
338 <script type='text/javascript'>verifyFields(null, 1);</script>
339 </body>
340 </html>