Column sorting fixes, thanks to Tony550
[tomato.git] / release / src / router / www / vpn-pptp-server.asp
blob461e61a04db8f2829413767a263399428cfae51a
1 <!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN'>
2 <!--
3 Tomato PPTPd GUI
4 Copyright (C) 2012 Augusto Bott
5 http://code.google.com/p/tomato-sdhc-vlan/
7 Tomato GUI
8 Copyright (C) 2006-2007 Jonathan Zarate
9 http://www.polarcloud.com/tomato/
10 For use with Tomato Firmware only.
11 No part of this file may be used without permission.
12 -->
13 <html>
14 <head>
15 <meta http-equiv='content-type' content='text/html;charset=utf-8'>
16 <meta name='robots' content='noindex,nofollow'>
17 <title>[<% ident(); %>] VPN: PPTP Server</title>
18 <link rel='stylesheet' type='text/css' href='tomato.css'>
19 <% css(); %>
20 <script type='text/javascript' src='tomato.js'></script>
21 <style type='text/css'>
22 #ul-grid .co2 {
23 text-align: center;
25 textarea {
26 width: 98%;
27 height: 10em;
29 </style>
30 <script type='text/javascript' src='interfaces.js'></script>
31 <script type='text/javascript'>
32 // <% nvram("lan_ipaddr,lan_netmask,pptpd_enable,pptpd_remoteip,pptpd_forcemppe,pptpd_broadcast,pptpd_users,pptpd_dns1,pptpd_dns2,pptpd_wins1,pptpd_wins2,pptpd_mtu,pptpd_mru,pptpd_custom");%>
34 if (nvram.pptpd_remoteip == '') nvram.pptpd_remoteip = '172.19.0.1-6';
35 if (nvram.pptpd_forcemppe == '') nvram.pptpd_forcemppe = '1';
37 var ul = new TomatoGrid();
38 ul.setup = function() {
39 this.init('ul-grid', 'sort', 6, [
40 { type: 'text', maxlen: 32, size: 32 },
41 { type: 'text', maxlen: 32, size: 32 } ]);
43 this.headerSet(['Username', 'Password']);
45 var r = nvram.pptpd_users.split('>');
46 for (var i = 0; i < r.length; ++i) {
47 var l = r[i].split('<');
48 if (l.length == 2)
49 ul.insertData(-1, l);
52 ul.recolor();
53 ul.showNewEditor();
54 ul.resetNewEditor();
55 ul.sort(0);
58 ul.exist = function(f, v) {
59 var data = this.getAllData();
60 for (var i = 0; i < data.length; ++i) {
61 if (data[i][f] == v) return true;
63 return false;
66 ul.existUser = function(user) {
67 return this.exist(0, user);
70 function v_pptpd_secret(e, quiet) {
71 var s;
72 if ((e = E(e)) == null) return 0;
73 s = e.value.trim().replace(/\s+/g, '');
74 if (s.length < 1) {
75 ferror.set(e, "Username and password can not be empty.", quiet);
76 return 0;
78 if (s.length > 32) {
79 ferror.set(e, "Invalid entry: max 32 characters are allowed.", quiet);
80 return 0;
82 if (s.search(/^[.a-zA-Z0-9_\- ]+$/) == -1) {
83 ferror.set(e, "Invalid entry. Only characters \"A-Z 0-9 . - _\" are allowed.", quiet);
84 return 0;
86 e.value = s;
87 ferror.clear(e);
88 return 1;
91 ul.verifyFields = function(row, quiet) {
92 var f, s;
93 f = fields.getAll(row);
95 if (!v_pptpd_secret(f[0], quiet)) return 0;
97 if (this.existUser(f[0].value)) {
98 ferror.set(f[0], 'Duplicate User', quiet);
99 return 0;
102 if (!v_pptpd_secret(f[1], quiet)) return 0;
104 return 1;
107 ul.dataToView = function(data) {
108 return [data[0], '<center><small><i>Secret</i></small></center>'];
111 function save() {
112 if (ul.isEditing()) return;
114 if ((E('_f_pptpd_enable').checked) && (!verifyFields(null, 0))) return;
116 if ((E('_f_pptpd_enable').checked) && (ul.getDataCount() < 1)) {
117 var e = E('footer-msg');
118 e.innerHTML = 'Cannot proceed: at least one user must be defined.';
119 e.style.visibility = 'visible';
120 setTimeout(
121 function() {
122 e.innerHTML = '';
123 e.style.visibility = 'hidden';
124 }, 5000);
125 return;
128 ul.resetNewEditor();
130 var fom = E('_fom');
131 var uldata = ul.getAllData();
133 var s = '';
134 for (var i = 0; i < uldata.length; ++i) {
135 s += uldata[i].join('<') + '>';
137 fom.pptpd_users.value = s;
139 fom.pptpd_enable.value = E('_f_pptpd_enable').checked ? 1 : 0;
141 var a = E('_f_pptpd_startip').value;
142 var b = E('_f_pptpd_endip').value;
143 if ((fixIP(a) != null) && (fixIP(b) != null)) {
144 var c = b.split('.').splice(3, 1);
145 fom.pptpd_remoteip.value = a + '-' + c;
148 if (fom.pptpd_dns1.value == '0.0.0.0') fom.pptpd_dns1.value = '';
149 if (fom.pptpd_dns2.value == '0.0.0.0') fom.pptpd_dns2.value = '';
150 if (fom.pptpd_wins1.value == '0.0.0.0') fom.pptpd_wins1.value = '';
151 if (fom.pptpd_wins2.value == '0.0.0.0') fom.pptpd_wins2.value = '';
153 form.submit(fom, 1);
156 function submit_complete() {
157 /* REMOVE-BEGIN */
158 // reloadPage();
159 /* REMOVE-END */
160 verifyFields(null, 1);
163 function verifyFields(focused, quiet) {
164 var c = !E('_f_pptpd_enable').checked;
165 E('_pptpd_dns1').disabled = c;
166 E('_pptpd_dns2').disabled = c;
167 E('_pptpd_wins1').disabled = c;
168 E('_pptpd_wins2').disabled = c;
169 E('_pptpd_mtu').disabled = c;
170 E('_pptpd_mru').disabled = c;
171 E('_pptpd_forcemppe').disabled = c;
172 E('_pptpd_broadcast').disabled = c;
173 E('_f_pptpd_startip').disabled = c;
174 E('_f_pptpd_endip').disabled = c;
175 E('_pptpd_custom').disabled = c;
177 var a = E('_f_pptpd_startip');
178 /* REMOVE-BEGIN */
180 if ((a.value == '') || (a.value == '0.0.0.0')) {
181 var l;
182 var m = aton(nvram.lan_ipaddr) & aton(nvram.lan_netmask);
183 var o = (m) ^ (~ aton(nvram.lan_netmask))
184 var n = o - m;
185 do {
186 if (--n < 0) {
187 a.value = '';
188 return;
190 m++;
191 } while (((l = fixIP(ntoa(m), 1)) == null) || (l == nvram.lan_ipaddr) );
192 a.value = l;
195 /* REMOVE-END */
196 var b = E('_f_pptpd_endip');
197 /* REMOVE-BEGIN */
199 if ((b.value == '') || (b.value == '0.0.0.0')) {
200 var l;
201 var m = aton(nvram.lan_ipaddr) & aton(nvram.lan_netmask);
202 var o = (m) ^ (~ aton(nvram.lan_netmask));
203 var n = o - m;
204 do {
205 if (--n < 0) {
206 b.value = '';
207 return;
209 o--;
210 } while (((l = fixIP(ntoa(o), 1)) == null) || (l == nvram.lan_ipaddr) || (Math.abs((aton(a.value) - (aton(l)))) > 5) );
211 b.value = l;
214 var net = getNetworkAddress(nvram.lan_ipaddr, nvram.lan_netmask);
215 var brd = getBroadcastAddress(net, nvram.lan_netmask);
217 if ((aton(a.value) >= aton(brd)) || (aton(a.value) <= aton(net))) {
218 ferror.set(a, 'Invalid starting IP address (outside valid range).', quiet);
219 return 0;
220 } else {
221 ferror.clear(a);
224 if ((aton(b.value) >= aton(brd)) || (aton(b.value) <= aton(net))) {
225 ferror.set(b, 'Invalid final IP address (outside valid range)', quiet);
226 return 0;
227 } else {
228 ferror.clear(b);
231 /* REMOVE-END */
232 if (Math.abs((aton(a.value) - (aton(b.value)))) > 5) {
233 ferror.set(a, 'Invalid range (max 6 IPs)', quiet);
234 ferror.set(b, 'Invalid range (max 6 IPs)', quiet);
235 elem.setInnerHTML('pptpd_count', '(?)');
236 return 0;
237 } else {
238 ferror.clear(a);
239 ferror.clear(b);
242 if (aton(a.value) > aton(b.value)) {
243 var d = a.value;
244 a.value = b.value;
245 b.value = d;
248 elem.setInnerHTML('pptpd_count', '(' + ((aton(b.value) - aton(a.value)) + 1) + ')');
249 /* REMOVE-BEGIN */
250 // AB TODO - move to ul.onOk, onAdd,onDelete?
251 // elem.setInnerHTML('user_count', '(total ' + (ul.getDataCount()) + ')');
252 /* REMOVE-END */
253 if (!v_ipz('_pptpd_dns1', quiet)) return 0;
254 if (!v_ipz('_pptpd_dns2', quiet)) return 0;
255 if (!v_ipz('_pptpd_wins1', quiet)) return 0;
256 if (!v_ipz('_pptpd_wins2', quiet)) return 0;
257 if (!v_range('_pptpd_mtu', quiet, 576, 1500)) return 0;
258 if (!v_range('_pptpd_mru', quiet, 576, 1500)) return 0;
260 if (!v_ip('_f_pptpd_startip', quiet)) return 0;
261 if (!v_ip('_f_pptpd_endip', quiet)) return 0;
263 return 1;
266 function init() {
267 var c;
268 if (((c = cookie.get('vpn_pptpd_notes_vis')) != null) && (c == '1')) toggleVisibility("notes");
269 if (((c = cookie.get('vpn_pptpd_settings_vis')) != null) && (c == '0')) toggleVisibility("settings");
270 if (((c = cookie.get('vpn_pptpd_userlist_vis')) != null) && (c == '0')) toggleVisibility("userlist");
272 if (nvram.pptpd_remoteip.indexOf('-') != -1) {
273 var tmp = nvram.pptpd_remoteip.split('-');
274 E('_f_pptpd_startip').value = tmp[0];
275 E('_f_pptpd_endip').value = tmp[0].split('.').splice(0,3).join('.') + '.' + tmp[1];
278 ul.setup();
280 verifyFields(null, 1);
283 function toggleVisibility(whichone) {
284 if (E('sesdiv_' + whichone).style.display == '') {
285 E('sesdiv_' + whichone).style.display = 'none';
286 E('sesdiv_' + whichone + '_showhide').innerHTML = '(Click here to show)';
287 cookie.set('vpn_pptpd_' + whichone + '_vis', 0);
288 } else {
289 E('sesdiv_' + whichone).style.display='';
290 E('sesdiv_' + whichone + '_showhide').innerHTML = '(Click here to hide)';
291 cookie.set('vpn_pptpd_' + whichone + '_vis', 1);
295 </script>
296 </head>
297 <body onload='init()'>
298 <form id='_fom' method='post' action='tomato.cgi'>
299 <table id='container' cellspacing=0>
300 <tr><td colspan=2 id='header'>
301 <div class='title'>Tomato</div>
302 <div class='version'>Version <% version(); %></div>
303 </td></tr>
304 <tr id='body'><td id='navi'><script type='text/javascript'>navi()</script></td>
305 <td id='content'>
306 <div id='ident'><% ident(); %></div>
307 <input type='hidden' name='_nextpage' value='vpn-pptpd.asp'>
308 <input type='hidden' name='_nextwait' value='5'>
309 <input type='hidden' name='_service' value='firewall-restart,pptpd-restart,dnsmasq-restart'>
310 <input type='hidden' name='pptpd_users'>
311 <input type='hidden' name='pptpd_enable'>
312 <input type='hidden' name='pptpd_remoteip'>
314 <div class='section-title'>PPTP Server Configuration <small><i><a href='javascript:toggleVisibility("settings");'><span id='sesdiv_settings_showhide'>(Click here to hide)</span></a></i></small></div>
315 <div class='section' id='sesdiv_settings'>
316 <script type='text/javascript'>
317 createFieldTable('', [
318 { title: 'Enable', name: 'f_pptpd_enable', type: 'checkbox', value: nvram.pptpd_enable == '1' },
319 { title: 'Local IP Address/Netmask', text: (nvram.lan_ipaddr + ' / ' + nvram.lan_netmask) },
320 { title: 'Remote IP Address Range', multi: [
321 { name: 'f_pptpd_startip', type: 'text', maxlen: 15, size: 17, value: nvram.dhcpd_startip, suffix: '&nbsp;-&nbsp;' },
322 { name: 'f_pptpd_endip', type: 'text', maxlen: 15, size: 17, value: nvram.dhcpd_endip, suffix: ' <i id="pptpd_count"></i>' }
323 ] },
324 { title: 'Broadcast Relay Mode', name: 'pptpd_broadcast', type: 'select', options: [['disable','Disabled'], ['br0','LAN to VPN Clients'], ['ppp','VPN Clients to LAN'], ['br0ppp','Both']], value: nvram.pptpd_broadcast },
325 { title: 'Encryption', name: 'pptpd_forcemppe', type: 'select', options: [[0, 'None'], [1, 'MPPE-128']], value: nvram.pptpd_forcemppe },
326 { title: 'DNS Servers', name: 'pptpd_dns1', type: 'text', maxlen: 15, size: 17, value: nvram.pptpd_dns1 },
327 { title: '', name: 'pptpd_dns2', type: 'text', maxlen: 15, size: 17, value: nvram.pptpd_dns2 },
328 { title: 'WINS Servers', name: 'pptpd_wins1', type: 'text', maxlen: 15, size: 17, value: nvram.pptpd_wins1 },
329 { title: '', name: 'pptpd_wins2', type: 'text', maxlen: 15, size: 17, value: nvram.pptpd_wins2 },
330 { title: 'MTU', name: 'pptpd_mtu', type: 'text', maxlen: 4, size: 6, value: (nvram.pptpd_mtu ? nvram.pptpd_mtu : 1450)},
331 { title: 'MRU', name: 'pptpd_mru', type: 'text', maxlen: 4, size: 6, value: (nvram.pptpd_mru ? nvram.pptpd_mru : 1450)},
332 { title: '<a href="http://poptop.sourceforge.net/" target="_new">Poptop</a><br>Custom configuration', name: 'pptpd_custom', type: 'textarea', value: nvram.pptpd_custom }
335 </script>
336 </div>
338 <div class='section-title'>PPTP User List <small><i><a href='javascript:toggleVisibility("userlist");'><span id='sesdiv_userlist_showhide'>(Click here to hide)</span></a></i></small></div>
339 <!-- REMOVE-BEGIN -->
340 <!-- <div class='section-title'>PPTP User List <small> <span id='user_count'></span> <i><a href='javascript:toggleVisibility("userlist");'><span id='sesdiv_userlist_showhide'>(Click here to hide)</span></a></i></small></div> -->
341 <!--REMOVE-END -->
342 <div class='section' id='sesdiv_userlist'>
343 <table class='tomato-grid' cellspacing=1 id='ul-grid'></table>
344 </div>
346 <div class='section-title'>Notes <small><i><a href='javascript:toggleVisibility("notes");'><span id='sesdiv_notes_showhide'>(Click here to show)</span></a></i></small></div>
347 <div class='section' id='sesdiv_notes' style='display:none'>
348 <ul>
349 <li><b>Local IP Address/Netmask</b> - Address to be used at the local end of the tunnelled PPP links between the server and the VPN clients.</li>
350 <li><b>Remote IP Address Range</b> - Remote IP addresses to be used on the tunnelled PPP links (max 6).</li>
351 <li><b>Broadcast Relay Mode</b> - Turns on broadcast relay between VPN clients and LAN interface.</li>
352 <li><b>Enable Encryption</b> - Enabling this option will turn on VPN channel encryption, but it might lead to reduced channel bandwidth.</li>
353 <li><b>DNS Servers</b> - Allows defining DNS servers manually (if none are set, the router/local IP address should be used by VPN clients).</li>
354 <li><b>WINS Servers</b> - Allows configuring extra WINS servers for VPN clients, in addition to the WINS server defined on <a href=basic-network.asp>Basic/Network</a>.</li>
355 <li><b>MTU</b> - Maximum Transmission Unit. Max packet size the PPTP interface will be able to send without packet fragmentation.</li>
356 <li><b>MRU</b> - Maximum Receive Unit. Max packet size the PPTP interface will be able to receive without packet fragmentation.</li>
357 </ul>
359 <small>
360 <ul>
361 <li><b>Other relevant notes/hints:</b>
362 <ul>
363 <li>Try to avoid any conflicts and/or overlaps between the address ranges configured/available for DHCP and VPN clients on your local networks.</li>
364 </ul>
365 </small>
366 </div>
368 <br>
369 <div style="float:right;text-align:right">
370 &raquo; <a href="vpn-pptp-online.asp">PPTP Online</a>
371 </div>
373 </td></tr>
374 <tr><td id='footer' colspan=2>
375 <span id='footer-msg'></span>
376 <input type='button' value='Save' id='save-button' onclick='save()'>
377 <input type='button' value='Cancel' id='cancel-button' onclick='javascript:reloadPage();'>
378 </td></tr>
379 </table>
380 </form>
381 </body>
382 </html>