Make automatic firewall rules optional
[tomato.git] / release / src / router / www / vpn-client.asp
blobb54a3d3a913e6232fbdc20d34c9cd029bc7716a3
1 <!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN'>
2 <!--
3 Tomato GUI
4 Copyright (C) 2006-2008 Jonathan Zarate
5 http://www.polarcloud.com/tomato/
7 Portions Copyright (C) 2008-2009 Keith Moyer, tomatovpn@keithmoyer.com
9 For use with Tomato Firmware only.
10 No part of this file may be used without permission.
11 -->
12 <html>
13 <head>
14 <meta http-equiv='content-type' content='text/html;charset=utf-8'>
15 <meta name='robots' content='noindex,nofollow'>
16 <title>[<% ident(); %>] VPN: Client</title>
17 <link rel='stylesheet' type='text/css' href='tomato.css'>
18 <link rel='stylesheet' type='text/css' href='color.css'>
19 <script type='text/javascript' src='tomato.js'></script>
20 <script type='text/javascript'>
22 // <% nvram("vpn_client1_if,vpn_client1_bridge,vpn_client1_nat,vpn_client1_proto,vpn_client1_addr,vpn_client1_port,vpn_client1_retry,vpn_client1_firewall,vpn_client1_crypt,vpn_client1_comp,vpn_client1_cipher,vpn_client1_local,vpn_client1_remote,vpn_client1_nm,vpn_client1_hmac,vpn_client1_custom,vpn_client1_static,vpn_client1_ca,vpn_client1_crt,vpn_client1_key,vpn_client2_if,vpn_client2_bridge,vpn_client2_nat,vpn_client2_proto,vpn_client2_addr,vpn_client2_port,vpn_client2_retry,vpn_client2_firewall,vpn_client2_crypt,vpn_client2_comp,vpn_client2_cipher,vpn_client2_local,vpn_client2_remote,vpn_client2_nm,vpn_client2_hmac,vpn_client2_custom,vpn_client2_static,vpn_client2_ca,vpn_client2_crt,vpn_client2_key"); %>
24 tabs = [['client1', 'Client 1'],['client2', 'Client 2']];
25 ciphers = [['default','Use Default'],['none','None']<% vpnciphers(); %>];
27 changed = 0;
28 vpn1up = parseInt('<% psup("vpnclient1"); %>');
29 vpn2up = parseInt('<% psup("vpnclient2"); %>');
31 function tabSelect(name)
33 tabHigh(name);
35 for (var i = 0; i < tabs.length; ++i)
37 var on = (name == tabs[i][0]);
38 elem.display(tabs[i][0] + '-tab', on);
41 cookie.set('vpn_client_tab', name);
44 function toggle(service, isup)
46 if (changed && !confirm("Unsaved changes will be lost. Continue anyway?")) return;
48 E('_' + service + '_button').disabled = true;
49 form.submitHidden('service.cgi', {
50 _redirect: 'vpn-client.asp',
51 _sleep: '3',
52 _service: service + (isup ? '-stop' : '-start')
53 });
56 function verifyFields(focused, quiet)
58 var ret = 1;
60 // When settings change, make sure we restart the right client
61 if (focused)
63 changed = 1;
65 var clientindex = focused.name.indexOf("client");
66 if (clientindex >= 0)
68 var clientnumber = focused.name.substring(clientindex+6,clientindex+7);
69 var stripped = focused.name.substring(0,clientindex+6)+focused.name.substring(clientindex+7);
71 if (stripped == 'vpn_client_local')
72 E('_f_vpn_client'+clientnumber+'_local').value = focused.value;
73 else if (stripped == 'f_vpn_client_local')
74 E('_vpn_client'+clientnumber+'_local').value = focused.value;
76 if (eval('vpn'+clientnumber+'up') && fom._service.value.indexOf('client'+clientnumber) < 0)
78 var fom = E('_fom');
79 if ( fom._service.value != "" ) fom._service.value += ",";
80 fom._service.value += 'vpnclient'+clientnumber+'-restart';
85 // Element varification
86 for (i = 0; i < tabs.length; ++i)
88 t = tabs[i][0];
90 if (!v_ip('_vpn_'+t+'_addr', true) && !v_domain('_vpn_'+t+'_addr', true)) { ferror.set(E('_vpn_'+t+'_addr'), "Invalid server address.", quiet); ret = 0; }
91 if (!v_port('_vpn_'+t+'_port', quiet)) ret = 0;
92 if (!v_ip('_vpn_'+t+'_local', quiet, 1)) ret = 0;
93 if (!v_ip('_f_vpn_'+t+'_local', true, 1)) ret = 0;
94 if (!v_ip('_vpn_'+t+'_remote', quiet, 1)) ret = 0;
95 if (!v_netmask('_vpn_'+t+'_nm', quiet)) ret = 0;
96 if (!v_range('_vpn_'+t+'_retry', quiet, -1, 32767)) ret = 0;
99 // Visability changes
100 for (i = 0; i < tabs.length; ++i)
102 t = tabs[i][0];
104 fw = E('_vpn_'+t+'_firewall');
105 auth = E('_vpn_'+t+'_crypt');
106 iface = E('_vpn_'+t+'_if');
107 bridge = E('_f_vpn_'+t+'_bridge');
108 nat = E('_f_vpn_'+t+'_nat');
109 hmac = E('_vpn_'+t+'_hmac');
111 elem.display(PR('_vpn_'+t+'_ca'), PR('_vpn_'+t+'_crt'), PR('_vpn_'+t+'_key'), PR('_vpn_'+t+'_hmac'), auth.value == "tls");
112 elem.display(PR('_vpn_'+t+'_static'), auth.value == "secret" || (auth.value == "tls" && hmac.value >= 0));
113 elem.display(E(t+'_custom_crypto_text'), auth.value == "custom");
114 elem.display(PR('_f_vpn_'+t+'_bridge'), iface.value == "tap");
115 elem.display(E(t+'_bridge_warn_text'), !bridge.checked);
116 elem.display(PR('_f_vpn_'+t+'_nat'), fw.value != "custom" && (iface.value == "tun" || !bridge.checked));
117 elem.display(E(t+'_nat_warn_text'), fw.value != "custom" && (!nat.checked || (auth.value == "secret" && iface.value == "tun")));
118 elem.display(PR('_vpn_'+t+'_local'), auth.value == "secret" && iface.value == "tun");
119 elem.display(PR('_f_vpn_'+t+'_local'), auth.value == "secret" && (iface.value == "tap" && !bridge.checked));
122 return ret;
125 function save()
127 if (!verifyFields(null, false)) return;
129 var fom = E('_fom');
131 for (i = 0; i < tabs.length; ++i)
133 t = tabs[i][0];
135 E('vpn_'+t+'_bridge').value = E('_f_vpn_'+t+'_bridge').checked ? 1 : 0;
136 E('vpn_'+t+'_nat').value = E('_f_vpn_'+t+'_nat').checked ? 1 : 0;
139 form.submit(fom, 1);
141 changed = 0;
143 </script>
145 <style type='text/css'>
146 textarea {
147 width: 98%;
148 height: 10em;
150 </style>
152 </head>
153 <body>
154 <form id='_fom' method='post' action='tomato.cgi'>
155 <table id='container' cellspacing=0>
156 <tr><td colspan=2 id='header'>
157 <div class='title'>Tomato</div>
158 <div class='version'>Version <% version(); %></div>
159 </td></tr>
160 <tr id='body'><td id='navi'><script type='text/javascript'>navi()</script></td>
161 <td id='content'>
162 <div id='ident'><% ident(); %></div>
164 <input type='hidden' name='_nextpage' value='vpn-client.asp'>
165 <input type='hidden' name='_nextwait' value='5'>
166 <input type='hidden' name='_service' value=''>
168 <div class='section-title'>VPN Client Configuration</div>
169 <div class='section'>
170 <script type='text/javascript'>
171 tabCreate.apply(this, tabs);
173 for (i = 0; i < tabs.length; ++i)
175 t = tabs[i][0];
176 W('<div id=\''+t+'-tab\'>');
177 W('<input type=\'hidden\' id=\'vpn_'+t+'_bridge\' name=\'vpn_'+t+'_bridge\'>');
178 W('<input type=\'hidden\' id=\'vpn_'+t+'_nat\' name=\'vpn_'+t+'_nat\'>');
179 createFieldTable('', [
180 { title: 'Interface Type', name: 'vpn_'+t+'_if', type: 'select', options: [ ['tap','TAP'], ['tun','TUN'] ], value: eval( 'nvram.vpn_'+t+'_if' ) },
181 { title: 'Protocol', name: 'vpn_'+t+'_proto', type: 'select', options: [ ['udp','UDP'], ['tcp-client','TCP'] ], value: eval( 'nvram.vpn_'+t+'_proto' ) },
182 { title: 'Server Address/Port', multi: [
183 { name: 'vpn_'+t+'_addr', type: 'text', size: 17, value: eval( 'nvram.vpn_'+t+'_addr' ) },
184 { name: 'vpn_'+t+'_port', type: 'text', maxlen: 5, size: 7, value: eval( 'nvram.vpn_'+t+'_port' ) } ] },
185 { title: 'Firewall', name: 'vpn_'+t+'_firewall', type: 'select', options: [ ['auto', 'Automatic'], ['custom', 'Custom'] ], value: eval( 'nvram.vpn_'+t+'_firewall' ) },
186 { title: 'Authorization Mode', name: 'vpn_'+t+'_crypt', type: 'select', options: [ ['tls', 'TLS'], ['secret', 'Static Key'], ['custom', 'Custom'] ], value: eval( 'nvram.vpn_'+t+'_crypt' ),
187 suffix: '<span id=\''+t+'_custom_crypto_text\'>&nbsp;<small>(configured below...)</small></span>' },
188 { title: 'Extra HMAC authorization (tls-auth)', name: 'vpn_'+t+'_hmac', type: 'select', options: [ [-1, 'Disabled'], [2, 'Bi-directional'], [0, 'Incoming (0)'], [1, 'Outgoing (1)'] ], value: eval( 'nvram.vpn_'+t+'_hmac' ) },
189 { title: 'Server is on the same subnet', name: 'f_vpn_'+t+'_bridge', type: 'checkbox', value: eval( 'nvram.vpn_'+t+'_bridge' ) != 0,
190 suffix: '<span style="color: red" id=\''+t+'_bridge_warn_text\'>&nbsp<small>Warning: Cannot bridge distinct subnets. Defaulting to routed mode.<small></span>' },
191 { title: 'Create NAT on tunnel', name: 'f_vpn_'+t+'_nat', type: 'checkbox', value: eval( 'nvram.vpn_'+t+'_nat' ) != 0,
192 suffix: '<span style="font-style: italic" id=\''+t+'_nat_warn_text\'>&nbsp<small>Routes must be configured manually.<small></span>' },
193 { title: 'Local/remote endpoint addresses', multi: [
194 { name: 'vpn_'+t+'_local', type: 'text', maxlen: 15, size: 17, value: eval( 'nvram.vpn_'+t+'_local' ) },
195 { name: 'vpn_'+t+'_remote', type: 'text', maxlen: 15, size: 17, value: eval( 'nvram.vpn_'+t+'_remote' ) } ] },
196 { title: 'Tunnel address/netmask', multi: [
197 { name: 'f_vpn_'+t+'_local', type: 'text', maxlen: 15, size: 17, value: eval( 'nvram.vpn_'+t+'_local' ) },
198 { name: 'vpn_'+t+'_nm', type: 'text', maxlen: 15, size: 17, value: eval( 'nvram.vpn_'+t+'_nm' ) } ] },
199 { title: 'Encryption cipher', name: 'vpn_'+t+'_cipher', type: 'select', options: ciphers, value: eval( 'nvram.vpn_'+t+'_cipher' ) },
200 { title: 'Compression', name: 'vpn_'+t+'_comp', type: 'select', options: [ ['yes', 'Enabled'], ['no', 'Disabled'], ['adaptive', 'Adaptive'] ], value: eval( 'nvram.vpn_'+t+'_comp' ) },
201 { title: 'Connection retry', name: 'vpn_'+t+'_retry', type: 'text', maxlen: 5, size: 7, value: eval( 'nvram.vpn_'+t+'_retry' ),
202 suffix: '&nbsp;<small>(in seconds; -1 for infinite)</small>' },
203 { title: 'Custom Configuration', name: 'vpn_'+t+'_custom', type: 'textarea', value: eval( 'nvram.vpn_'+t+'_custom' ) },
204 { title: 'Static Key', name: 'vpn_'+t+'_static', type: 'textarea', value: eval( 'nvram.vpn_'+t+'_static' ) },
205 { title: 'Certificate Authority', name: 'vpn_'+t+'_ca', type: 'textarea', value: eval( 'nvram.vpn_'+t+'_ca' ) },
206 { title: 'Client Certificate', name: 'vpn_'+t+'_crt', type: 'textarea', value: eval( 'nvram.vpn_'+t+'_crt' ) },
207 { title: 'Client Key', name: 'vpn_'+t+'_key', type: 'textarea', value: eval( 'nvram.vpn_'+t+'_key' ) }
209 W('<input type="button" value="' + (eval('vpn'+(i+1)+'up') ? 'Stop' : 'Start') + ' Now" onclick="toggle(\'vpn'+t+'\', vpn'+(i+1)+'up)" id="_vpn'+t+'_button">');
210 W('</div>');
213 </script>
214 </div>
216 </td></tr>
217 <tr><td id='footer' colspan=2>
218 <span id='footer-msg'></span>
219 <input type='button' value='Save' id='save-button' onclick='save()'>
220 <input type='button' value='Cancel' id='cancel-button' onclick='javascript:reloadPage();'>
221 </td></tr>
222 </table>
223 </form>
224 <script type='text/javascript'>tabSelect(cookie.get('vpn_client_tab') || tabs[0][0]); verifyFields(null, 1);</script>
225 </body>
226 </html>