source: apps/i2ptunnel/jsp/register.jsp @ c2e2cc2

Last change on this file since c2e2cc2 was c2e2cc2, checked in by zzz <zzz@…>, 12 months ago

i2ptunnel: Revert user-select, already in css, doesn't work on input

  • Property mode set to 100644
File size: 17.3 KB
Line 
1<%
2    // NOTE: Do the header carefully so there is no whitespace before the <?xml... line
3
4    response.setHeader("X-Frame-Options", "SAMEORIGIN");
5    response.setHeader("Content-Security-Policy", "default-src 'self'; style-src 'self' 'unsafe-inline'");
6    response.setHeader("X-XSS-Protection", "1; mode=block");
7    response.setHeader("X-Content-Type-Options", "nosniff");
8    response.setHeader("Referrer-Policy", "no-referrer");
9    response.setHeader("Accept-Ranges", "none");
10
11%><%@page pageEncoding="UTF-8"
12%><%@page contentType="text/html" import="java.io.InputStream,net.i2p.i2ptunnel.web.EditBean,net.i2p.servlet.RequestWrapper,net.i2p.client.I2PSessionException,net.i2p.client.naming.HostTxtEntry,net.i2p.data.PrivateKeyFile,net.i2p.data.SigningPrivateKey,net.i2p.util.OrderedProperties"
13%><%@page
14%><?xml version="1.0" encoding="UTF-8"?>
15<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
16<%
17  /* right now using EditBean instead of IndexBean for getSpoofedHost() */
18  /* but might want to POST to it anyway ??? */
19%>
20<jsp:useBean class="net.i2p.i2ptunnel.web.EditBean" id="editBean" scope="request" />
21<jsp:useBean class="net.i2p.i2ptunnel.ui.Messages" id="intl" scope="request" />
22<%
23   RequestWrapper wrequest = new RequestWrapper(request);
24   String tun = wrequest.getParameter("tunnel");
25   int curTunnel = -1;
26   if (tun != null) {
27     try {
28       curTunnel = Integer.parseInt(tun);
29     } catch (NumberFormatException nfe) {
30       curTunnel = -1;
31     }
32   }
33%>
34<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
35<head>
36    <title><%=intl._t("Hidden Services Manager")%> - <%=intl._t("Registration Helper")%></title>
37    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
38    <link href="/themes/console/images/favicon.ico" type="image/x-icon" rel="shortcut icon" />
39
40    <% if (editBean.allowCSS()) {
41  %><link rel="icon" href="<%=editBean.getTheme()%>images/favicon.ico" />
42    <link href="<%=editBean.getTheme()%>i2ptunnel.css?<%=net.i2p.CoreVersion.VERSION%>" rel="stylesheet" type="text/css" /> 
43    <% }
44  %>
45<style type='text/css'>
46input.default { width: 1px; height: 1px; visibility: hidden; }
47</style>
48</head>
49<body id="tunnelRegistration">
50
51<%
52
53  if (editBean.isInitialized()) {
54
55%>
56    <form method="post" enctype="multipart/form-data" action="register" accept-charset="UTF-8">
57        <div class="panel" id="registration">
58<%
59    String tunnelTypeName;
60    String tunnelType;
61    boolean valid = false;
62    if (curTunnel >= 0) {
63        tunnelTypeName = editBean.getTunnelType(curTunnel);
64        tunnelType = editBean.getInternalType(curTunnel);
65      %><h2><%=intl._t("Registration Helper")%> (<%=editBean.getTunnelName(curTunnel)%>)</h2><% 
66    } else {
67        tunnelTypeName = "new";
68        tunnelType = "new";
69      %><h2>Fail</h2><p>Tunnel not found</p><% 
70    }
71    String b64 = editBean.getDestinationBase64(curTunnel);
72    String name = editBean.getSpoofedHost(curTunnel);
73    if (name == null || name.equals(""))
74        name = editBean.getTunnelName(curTunnel);
75%>
76                <input type="hidden" name="tunnel" value="<%=curTunnel%>" />
77                <input type="hidden" name="nonce" value="<%=net.i2p.i2ptunnel.web.IndexBean.getNextNonce()%>" />
78                <input type="hidden" name="type" value="<%=tunnelType%>" />
79                <input type="submit" class="default" name="action" value="Save changes" />
80<%
81    String curEncryptMode = editBean.getEncryptMode(curTunnel);
82    if (!"0".equals(curEncryptMode)) {
83%>
84      <table><tr><td class="infohelp">
85        <%=intl._t("This service uses encrypted leasesets. Registration is not recommended. Registration authentication is disabled.")%>
86      </td></tr>
87<%
88    } else if (!"new".equals(tunnelType)) {
89%>
90
91<table>
92    <tr>
93        <td class="infohelp">
94    <%=intl._t("Please be sure to select, copy, and paste the entire contents of the appropriate authentication data into the form of your favorite registration site")%>
95        </td>
96    </tr>
97    <tr>
98        <td>
99            <b><%=intl._t("Tunnel name")%>:</b> <%=editBean.getTunnelName(curTunnel)%>
100        </td>
101    </tr>
102
103<%
104      if (("httpserver".equals(tunnelType)) || ("httpbidirserver".equals(tunnelType))) {
105          %>
106    <tr><td><b><%=intl._t("Website name")%>:</b> <%=editBean.getSpoofedHost(curTunnel)%></td></tr>
107<%
108       }
109%>
110
111<!--
112    <tr>
113        <th>
114            <b><%=intl._t("Local Destination")%></b>
115        </th>
116    </tr>
117    <tr>
118        <td>
119            <textarea rows="1" style="height: 3em;" cols="60" readonly="readonly" id="localDestination" title="Read Only: Local Destination (if known)" wrap="off" spellcheck="false"><%=editBean.getDestinationBase64(curTunnel)%></textarea>
120        </td>
121    </tr>
122-->
123
124<%
125       if (b64 == null || b64.length() < 516) {
126           %><tr><td class="infohelp"><%=intl._t("Local destination is not available. Start the tunnel.")%></td></tr><%
127       } else if (name == null || name.equals("") || name.contains(" ") || !name.endsWith(".i2p")) {
128           if (("httpserver".equals(tunnelType)) || ("httpbidirserver".equals(tunnelType))) {
129               %><tr><td class="infohelp"><%=intl._t("To enable registration verification, edit tunnel and set name (or website name) to a valid host name ending in '.i2p'")%></td></tr><%
130           } else {
131               %><tr><td class="infohelp"><%=intl._t("To enable registration verification, edit tunnel and set name to a valid host name ending in '.i2p'")%></td></tr><%
132           }
133       } else {
134           SigningPrivateKey spk = editBean.getSigningPrivateKey(curTunnel);
135           if (spk == null) {
136               %><tr><td class="infohelp"><%=intl._t("Destination signing key is not available. Start the tunnel.")%></td></tr><%
137           } else if (spk.isOffline()) {
138               %><tr><td class="infohelp"><%=intl._t("Destination signing key is offline. Use CLI tools on the offline machine.")%></td></tr><%
139           } else {
140               valid = true;
141               OrderedProperties props = new OrderedProperties();
142               HostTxtEntry he = new HostTxtEntry(name, b64, props);
143               he.sign(spk);
144          %>
145
146    <tr>
147        <th>
148            <%=intl._t("Authentication for adding host {0}", name)%>
149        </th>
150    </tr>
151    <tr>
152        <td>
153            <div class="displayText" tabindex="0" "title="<%=intl._t("Copy and paste this to the registration site")%>"><% he.write(out); %></div>
154        </td>
155    </tr>
156</table>
157
158<h3><%=intl._t("Advanced authentication strings")%></h3>
159
160<%
161               props.remove(HostTxtEntry.PROP_SIG);
162               props.setProperty(HostTxtEntry.PROP_ACTION, HostTxtEntry.ACTION_REMOVE);
163               he.signRemove(spk);
164          %>
165
166<table>
167    <tr>
168        <th>
169            <%=intl._t("Authentication for removing host {0}", name)%>
170        </th>
171    </tr>
172    <tr>
173        <td>
174            <div class="displayText" tabindex="0" title="<%=intl._t("Copy and paste this to the registration site")%>"><% he.writeRemove(out); %></div>
175        </td>
176    </tr>
177
178<%
179               String oldname = wrequest.getParameter("oldname");
180               String olddestfile = wrequest.getFilename("olddestfile");
181               SigningPrivateKey spk2 = null;
182               String olddest = null;
183               if (olddestfile != null) {
184                   InputStream destIn = wrequest.getInputStream("olddestfile");
185                   if (destIn.available() > 0) {
186                       try {
187                           PrivateKeyFile pkf2 = new PrivateKeyFile(destIn);
188                           String oldb64 = pkf2.getDestination().toBase64();
189                           if (!b64.equals(oldb64)) {
190                               // disallow dup
191                               olddest = oldb64;
192                               spk2 = pkf2.getSigningPrivKey();
193                           }
194                       } catch (I2PSessionException ise) {
195                           throw new IllegalStateException("Unable to open private key file " + olddestfile, ise);
196                       }
197                   }
198               }
199               props.remove(HostTxtEntry.PROP_SIG);
200          %>
201    <tr>
202        <th>
203                    <%=intl._t("Authentication for changing name")%>
204        </th>
205    </tr>
206<%
207               if (oldname != null && oldname.length() > 0 && !oldname.equals(name)) {
208                   props.setProperty(HostTxtEntry.PROP_ACTION, HostTxtEntry.ACTION_CHANGENAME);
209                   props.setProperty(HostTxtEntry.PROP_OLDNAME, oldname);
210                   he.sign(spk);
211                %>
212    <tr>
213        <td>
214            <div class="displayText" tabindex="0" title="<%=intl._t("Copy and paste this to the registration site")%>"><% he.write(out); %></div>
215        </td>
216    </tr>
217    <tr>
218        <td class="infohelp">
219            <%=intl._t("This will change the name from {0} to {1}, using the same destination", oldname, name)%>
220        </td>
221    </tr>
222
223<%
224               } else {
225                %><tr><td class="infohelp"><%=intl._t("This tunnel must be configured with the new host name.")%>
226                  &nbsp;<%=intl._t("Enter old hostname below.")%></td></tr>
227<%
228               }
229          %>
230
231<%
232               props.remove(HostTxtEntry.PROP_SIG);
233          %>
234    <tr>
235        <th>
236                    <%=intl._t("Authentication for adding alias")%>
237        </th>
238    </tr>
239<%
240               if (oldname != null && oldname.length() > 0 && !oldname.equals(name)) {
241                   props.setProperty(HostTxtEntry.PROP_ACTION, HostTxtEntry.ACTION_ADDNAME);
242                   props.setProperty(HostTxtEntry.PROP_OLDNAME, oldname);
243                   he.sign(spk);
244                %>
245    <tr>
246        <td>
247            <div class="displayText" tabindex="0" title="<%=intl._t("Copy and paste this to the registration site")%>"><% he.write(out); %></div>
248        </td>
249    </tr>
250    <tr>
251        <td class="infohelp">
252            <%=intl._t("This will add an alias {0} for {1}, using the same destination", name, oldname)%>
253        </td>
254    </tr>
255<%
256               } else {
257                %><tr> <td class="infohelp"><%=intl._t("This tunnel must be configured with the new host name.")%>
258                  &nbsp;<%=intl._t("Enter old hostname below.")%></td></tr>
259<%
260               }
261          %>
262
263<%
264               props.remove(HostTxtEntry.PROP_SIG);
265               props.remove(HostTxtEntry.PROP_OLDNAME);
266          %>
267
268    <tr>
269        <th>
270                    <%=intl._t("Authentication for changing destination")%>
271        </th>
272    </tr>
273
274<%
275               if (spk2 != null) {
276                   props.setProperty(HostTxtEntry.PROP_ACTION, HostTxtEntry.ACTION_CHANGEDEST);
277                   props.setProperty(HostTxtEntry.PROP_OLDDEST, olddest);
278                   he.signInner(spk2);
279                   he.sign(spk);
280                %>
281
282    <tr>
283        <td>
284            <div class="displayText" tabindex="0" title="<%=intl._t("Copy and paste this to the registration site")%>"><% he.write(out); %></div>
285        </td>
286    </tr>
287    <tr>
288        <td class="infohelp">
289            <%=intl._t("This will change the destination for {0}", name)%>
290        </td>
291    </tr>
292
293<%
294               } else {
295                %><tr><td class="infohelp"><%=intl._t("This tunnel must be configured with the new destination.")%>
296                  &nbsp;<%=intl._t("Enter old destination below.")%></td></tr>
297<%
298               }
299          %>
300
301<%
302               props.remove(HostTxtEntry.PROP_SIG);
303               props.remove(HostTxtEntry.PROP_OLDSIG);
304          %>
305
306    <tr>
307        <th>
308                    <%=intl._t("Authentication for adding alternate destination")%>
309        </th>
310    </tr>
311
312<%
313               if (spk2 != null) {
314                   props.setProperty(HostTxtEntry.PROP_ACTION, HostTxtEntry.ACTION_ADDDEST);
315                   props.setProperty(HostTxtEntry.PROP_OLDDEST, olddest);
316                   he.signInner(spk2);
317                   he.sign(spk);
318                %>
319    <tr>
320        <td>
321            <div class="displayText" tabindex="0" title="<%=intl._t("Copy and paste this to the registration site")%>"><% he.write(out); %></div>
322        </td>
323    </tr>
324    <tr>
325        <td class="infohelp">
326            <%=intl._t("This will add an alternate destination for {0}", name)%>
327        </td>
328    </tr>
329<%
330               } else {
331                   // If set, use the configured alternate destination as the new alias destination,
332                   // and the configured primary destination as the inner signer.
333                   // This is backwards from all the other ones, so we have to make a second HostTxtEntry just for this.
334                   SigningPrivateKey spk3 = null;
335                   String altdest = null;
336                   String altdestfile = editBean.getAltPrivateKeyFile(curTunnel);
337                   if (altdestfile.length() > 0) {
338                       try {
339                           PrivateKeyFile pkf3 = new PrivateKeyFile(altdestfile);
340                           altdest = pkf3.getDestination().toBase64();
341                           if (!b64.equals(altdest)) {
342                               // disallow dup
343                               spk3 = pkf3.getSigningPrivKey();
344                           }
345                       } catch (Exception e) {}
346                   }
347                   if (spk3 != null) {
348                       OrderedProperties props2 = new OrderedProperties();
349                       HostTxtEntry he2 = new HostTxtEntry(name, altdest, props2);
350                       props2.setProperty(HostTxtEntry.PROP_ACTION, HostTxtEntry.ACTION_ADDDEST);
351                       props2.setProperty(HostTxtEntry.PROP_OLDDEST, b64);
352                       he2.signInner(spk);
353                       he2.sign(spk3);
354                %><tr><td><div class="displayText" tabindex="0" title="<%=intl._t("Copy and paste this to the registration site")%>"><% he2.write(out); %></div></td></tr>
355                <tr><td class="infohelp"><%=intl._t("This will add an alternate destination for {0}", name)%></td></tr>
356<%
357                   } else {
358                %><tr><td class="infohelp"><%=intl._t("This tunnel must be configured with the new destination.")%>
359                  &nbsp;<%=intl._t("Enter old destination below.")%></td></tr>
360<%
361                   }  // spk3
362               }  // spk2
363          %>
364
365<%
366
367
368               props.remove(HostTxtEntry.PROP_SIG);
369               props.remove(HostTxtEntry.PROP_OLDSIG);
370          %>
371
372    <tr>
373        <th>
374                    <%=intl._t("Authentication for adding subdomain")%>
375        </th>
376    </tr>
377<%
378               if (oldname != null && oldname.length() > 0 && !oldname.equals(name) && spk2 != null) {
379                   props.setProperty(HostTxtEntry.PROP_ACTION, HostTxtEntry.ACTION_ADDSUBDOMAIN);
380                   props.setProperty(HostTxtEntry.PROP_OLDNAME, oldname);
381                   props.setProperty(HostTxtEntry.PROP_OLDDEST, olddest);
382                   he.signInner(spk2);
383                   he.sign(spk);
384                %>
385
386    <tr>
387        <td>
388            <div class="displayText" tabindex="0" title="<%=intl._t("Copy and paste this to the registration site")%>"><% he.write(out); %></div>
389        </td>
390    </tr>
391    <tr>
392        <td class="infohelp">
393            <%=intl._t("This will add a subdomain {0} of {1}, with a different destination", name, oldname)%>
394        </td>
395    </tr>
396
397<%
398               } else {
399                %>
400    <tr>
401        <td class="infohelp">
402            <%=intl._t("This tunnel must be configured with the new subdomain and destination.")%>
403            &nbsp;<%=intl._t("Enter higher-level domain and destination below.")%>
404        </td>
405    </tr>
406
407<%
408               }
409          %>
410
411<%
412          }  // spk != null
413       }  // valid b64 and name
414    }  // !"new".equals(tunnelType)
415    if (!valid && curTunnel >= 0) {
416        %>
417    <tr>
418        <td>
419            <a href="edit?tunnel=<%=curTunnel%>"><%=intl._t("Go back and edit the tunnel")%></a>
420        </td>
421    </tr>
422        <%
423    }
424%>
425
426<%
427    if (valid) {
428%>
429
430    <tr>
431        <th>
432            <%=intl._t("Specify old name and destination")%>
433        </th>
434    </tr>
435    <tr>
436        <td class="infohelp">
437            <%=intl._t("This is only required for advanced authentication.")%>
438            &nbsp;<%=intl._t("See above for required items.")%>
439        </td>
440    </tr>
441<%
442               String oldname = wrequest.getParameter("oldname");
443               if (oldname == null) oldname = "";
444          %>
445    <tr>
446        <td>
447            <b><%=intl._t("Old hostname")%>:</b>
448            <input type="text" size="30" maxlength="50" name="oldname" id="oldName" value="<%=oldname%>" class="freetext" />
449        </td>
450    </tr>
451    <tr>
452        <td>
453            <b><%=intl._t("Private Key File for old Destination")%>:</b>
454            <input type="file" name="olddestfile" id="oldDestFile" value="" />
455        </td>
456    </tr>
457    <tr>
458        <td class="buttons">
459                    <input type="hidden" value="true" name="removeConfirm" />
460                    <a class="control" href="list"><%=intl._t("Cancel")%></a>
461                    <button id="controlSave" class="control" type="submit" name="action" value="authenticate"  title="<%=intl._t("Generate Authentication")%>"><%=intl._t("Generate")%></button>
462        </td>
463    </tr>
464
465<%
466     } // valid
467%>
468
469</table>
470</div>
471    </form>
472<%
473
474  } else {
475     %><div id="notReady"><%=intl._t("Tunnels are not initialized yet, please reload in two minutes.")%></div><%
476  }  // isInitialized()
477
478%>
479</body>
480</html>
Note: See TracBrowser for help on using the repository browser.