Changeset 4b722c9


Ignore:
Timestamp:
Mar 14, 2017 2:15:54 PM (3 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
43c3a14
Parents:
1150b4cd
Message:

i2ptunnel: New form to enter private key file for alternate destination

  • Use alt destination for registration if set
  • Another dup check for alt destination

SusiDNS: New button for adding alternate destination

  • Fix nonces on details page with multiple destinations
  • Fix single dest deletion on details page with multiple destinations
  • Set book in all forms to ensure correct book

Blockfile: Fix specified-destination deletion from the correct book

Files:
14 edited

Legend:

Unmodified
Added
Removed
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/TunnelController.java

    r1150b4cd r4b722c9  
    254254        File altFile = getAlternatePrivateKeyFile();
    255255        if (altFile == null)
     256            return false;
     257        if (altFile.equals(keyFile))
    256258            return false;
    257259        if (altFile.exists())
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/ui/GeneralHelper.java

    r1150b4cd r4b722c9  
    265265    }
    266266
     267    /**
     268     *  @return path, non-null, non-empty
     269     */
    267270    public String getPrivateKeyFile(int tunnel) {
    268271        return getPrivateKeyFile(_group, tunnel);
    269272    }
    270273
     274    /**
     275     *  @return path, non-null, non-empty
     276     */
    271277    public String getPrivateKeyFile(TunnelControllerGroup tcg, int tunnel) {
    272278        TunnelController tun = getController(tcg, tunnel);
    273         if (tun != null && tun.getPrivKeyFile() != null)
    274             return tun.getPrivKeyFile();
     279        if (tun != null) {
     280            String rv = tun.getPrivKeyFile();
     281            if (rv != null)
     282                return rv;
     283        }
    275284        if (tunnel < 0)
    276285            tunnel = tcg == null ? 999 : tcg.getControllers().size();
     
    283292        }
    284293        return rv;
     294    }
     295
     296    /**
     297     *  @return path or ""
     298     *  @since 0.9.30
     299     */
     300    public String getAltPrivateKeyFile(int tunnel) {
     301        return getAltPrivateKeyFile(_group, tunnel);
     302    }
     303
     304    /**
     305     *  @return path or ""
     306     *  @since 0.9.30
     307     */
     308    public String getAltPrivateKeyFile(TunnelControllerGroup tcg, int tunnel) {
     309        TunnelController tun = getController(tcg, tunnel);
     310        if (tun != null) {
     311            File f = tun.getAlternatePrivateKeyFile();
     312            if (f != null)
     313                return f.getAbsolutePath();
     314        }
     315        return "";
    285316    }
    286317
     
    349380                try {
    350381                    rv = pkf.getDestination();
     382                    if (rv != null)
     383                        return rv;
     384                } catch (I2PException e) {
     385                } catch (IOException e) {}
     386            }
     387        }
     388        return null;
     389    }
     390
     391    /**
     392     *  Works even if tunnel is not running.
     393     *  @return Destination or null
     394     *  @since 0.9.30
     395     */
     396    public Destination getAltDestination(int tunnel) {
     397        TunnelController tun = getController(tunnel);
     398        if (tun != null) {
     399            // do this the hard way
     400            File keyFile = tun.getAlternatePrivateKeyFile();
     401            if (keyFile != null) {
     402                PrivateKeyFile pkf = new PrivateKeyFile(keyFile);
     403                try {
     404                    Destination rv = pkf.getDestination();
    351405                    if (rv != null)
    352406                        return rv;
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/ui/TunnelConfig.java

    r1150b4cd r4b722c9  
    162162        return _privKeyFile;
    163163    }
     164
     165    /**
     166     *  What filename is this server tunnel's alternate private keys stored in
     167     *  @since 0.9.30
     168     */
     169    public void setAltPrivKeyFile(String file) {
     170        if (file != null)
     171            _otherOptions.put(I2PTunnelServer.PROP_ALT_PKF, file.trim());
     172    }
     173
    164174    /**
    165175     * If called with any value, we want this tunnel to start whenever it is
     
    726736         PROP_MAX_TOTAL_CONNS_MIN, PROP_MAX_TOTAL_CONNS_HOUR, PROP_MAX_TOTAL_CONNS_DAY,
    727737         PROP_MAX_STREAMS, I2PClient.PROP_SIGTYPE,
    728         "inbound.randomKey", "outbound.randomKey", "i2cp.leaseSetSigningPrivateKey", "i2cp.leaseSetPrivateKey"
     738        "inbound.randomKey", "outbound.randomKey", "i2cp.leaseSetSigningPrivateKey", "i2cp.leaseSetPrivateKey",
     739         I2PTunnelServer.PROP_ALT_PKF
    729740        };
    730741    private static final String _httpServerOpts[] = {
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java

    r1150b4cd r4b722c9  
    7070    public String getPrivateKeyFile(int tunnel) {
    7171        return _helper.getPrivateKeyFile(tunnel);
     72    }
     73
     74    /**
     75     *  @return path or ""
     76     *  @since 0.9.30
     77     */
     78    public String getAltPrivateKeyFile(int tunnel) {
     79        return _helper.getAltPrivateKeyFile(tunnel);
    7280    }
    7381   
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java

    r1150b4cd r4b722c9  
    489489        return "";
    490490    }
     491
     492    /**
     493     *  Works even if tunnel is not running.
     494     *  @return Destination or null
     495     *  @since 0.9.30
     496     */
     497    protected Destination getAltDestination(int tunnel) {
     498        return _helper.getAltDestination(tunnel);
     499    }
     500   
     501    /**
     502     *  Works even if tunnel is not running.
     503     *  @return Base64 or ""
     504     *  @since 0.9.30
     505     */
     506    public String getAltDestinationBase64(int tunnel) {
     507        Destination d = getAltDestination(tunnel);
     508        if (d != null)
     509            return d.toBase64();
     510        return "";
     511    }
     512   
     513    /**
     514     *  Works even if tunnel is not running.
     515     *  @return "{52 chars}.b32.i2p" or ""
     516     *  @since 0.9.30
     517     */
     518    public String getAltDestHashBase32(int tunnel) {
     519        Destination d = getAltDestination(tunnel);
     520        if (d != null)
     521            return d.toBase32();
     522        return "";
     523    }
    491524   
    492525    /**
     
    614647        _config.setSpoofedHost(host);
    615648    }
     649
    616650    /** What filename is this server tunnel's private keys stored in */
    617651    public void setPrivKeyFile(String file) {
    618652        _config.setPrivKeyFile(file);
    619653    }
     654
     655    /**
     656     *  What filename is this server tunnel's alternate private keys stored in
     657     *  @since 0.9.30
     658     */
     659    public void setAltPrivKeyFile(String file) {
     660        _config.setAltPrivKeyFile(file);
     661    }
     662
    620663    /**
    621664     * If called with any value (and the form submitted with action=Remove),
  • apps/i2ptunnel/jsp/editServer.jsp

    r1150b4cd r4b722c9  
    670670<% **********************/ %>
    671671
    672          <% if (true /* editBean.isAdvanced() */ ) {
    673                 int currentSigType = editBean.getSigType(curTunnel, tunnelType);
     672         <%
     673            int currentSigType = editBean.getSigType(curTunnel, tunnelType);
     674            if (true /* editBean.isAdvanced() */ ) {
    674675           %>
    675676            <div id="tunnelOptionsField" class="rowItem">
     
    714715            </div>
    715716         <% } // isAdvanced %>
     717
     718         <%
     719            /* alternate dest, only if current dest is set and is DSA_SHA1 */
     720
     721            if (currentSigType == 0 && !"".equals(b64) && !"streamrserver".equals(tunnelType)) {
     722          %><div id="privKeyField" class="rowItem">
     723                <label for="privKeyFile"><%=intl._t("Alternate private key file")%> (Ed25519-SHA-512):</label>
     724                <input type="text" size="30" id="privKeyFile" name="altPrivKeyFile" title="Path to Private Key File" value="<%=editBean.getAltPrivateKeyFile(curTunnel)%>" class="freetext" />               
     725            </div>
     726
     727         <%
     728              String ab64 = editBean.getAltDestinationBase64(curTunnel);
     729              if (!"".equals(ab64)) {
     730          %><div id="destinationField" class="rowItem">
     731                <label for="localDestination"><%=intl._t("Alternate local destination")%>:</label>
     732                <textarea rows="1" style="height: 3em;" cols="60" readonly="readonly" id="localDestination" title="Read Only: Alternate Local Destination" wrap="off" spellcheck="false"><%=ab64%></textarea>               
     733            </div>
     734            <div id="destinationField" class="rowItem">
     735                <label> </label>
     736                <span class="comment"><%=editBean.getAltDestHashBase32(curTunnel)%></span>
     737            </div>
     738            <div id="destinationField" class="rowItem">
     739        <%
     740                ab64 = ab64.replace("=", "%3d");
     741                String name = editBean.getSpoofedHost(curTunnel);
     742                if (name == null || name.equals(""))
     743                    name = editBean.getTunnelName(curTunnel);
     744                // mysite.i2p is set in the installed i2ptunnel.config
     745                if (name != null && !name.equals("") && !name.equals("mysite.i2p") && !name.contains(" ") && name.endsWith(".i2p")) {
     746           %><label>
     747              <a class="control" title="<%=intl._t("Generate QR Code")%>" href="/imagegen/qr?s=320&amp;t=<%=name%>&amp;c=http%3a%2f%2f<%=name%>%2f%3fi2paddresshelper%3d<%=ab64%>" target="_top"><%=intl._t("Generate QR Code")%></a>
     748              </label>
     749              <a class="control" href="/susidns/addressbook.jsp?book=private&amp;hostname=<%=name%>&amp;destination=<%=ab64%>#add"><%=intl._t("Add to local addressbook")%></a>
     750        <%
     751                } else {
     752            %><label> </label>
     753              <span class="comment"><%=intl._t("Set name with .i2p suffix to enable QR code generation")%></span>
     754        <%
     755                }  // name
     756          %></div>
     757        <%
     758              }  // ab64
     759          %><div class="subdivider"><hr /></div>
     760         <% } // currentSigType %>
    716761                 
    717762            <div id="customOptionsField" class="rowItem">
  • apps/i2ptunnel/jsp/register.jsp

    r1150b4cd r4b722c9  
    260260<%
    261261               } else {
     262                   // If set, use the configured alternate destination as the new alias destination,
     263                   // and the configured primary destination as the inner signer.
     264                   // This is backwards from all the other ones, so we have to make a second HostTxtEntry just for this.
     265                   SigningPrivateKey spk3 = null;
     266                   String altdest = null;
     267                   String altdestfile = editBean.getAltPrivateKeyFile(curTunnel);
     268                   if (altdestfile.length() > 0) {
     269                       try {
     270                           PrivateKeyFile pkf3 = new PrivateKeyFile(altdestfile);
     271                           altdest = pkf3.getDestination().toBase64();
     272                           if (!b64.equals(altdest)) {
     273                               // disallow dup
     274                               spk3 = pkf3.getSigningPrivKey();
     275                           }
     276                       } catch (Exception e) {}
     277                   }
     278                   if (spk3 != null) {
     279                       OrderedProperties props2 = new OrderedProperties();
     280                       HostTxtEntry he2 = new HostTxtEntry(name, altdest, props2);
     281                       props2.setProperty(HostTxtEntry.PROP_ACTION, HostTxtEntry.ACTION_ADDDEST);
     282                       props2.setProperty(HostTxtEntry.PROP_OLDDEST, b64);
     283                       he2.signInner(spk);
     284                       he2.sign(spk3);
     285                %><textarea rows="1" style="height: 3em;" cols="60" readonly="readonly" id="localDestination" title="Copy and paste this to the registration site" wrap="off" spellcheck="false"><% he2.write(out); %></textarea>               
     286                <span class="comment"><%=intl._t("This will add an alternate destination for {0}", name)%></span>
     287<%
     288                   } else {
    262289                %><span class="comment"><%=intl._t("This tunnel must be configured with the new destination.")%></span>
    263290                  <span class="comment"><%=intl._t("Enter old destination below.")%></span>
    264291<%
    265                }
     292                   }  // spk3
     293               }  // spk2
    266294          %></div>
    267295            <div class="separator">
  • apps/susidns/src/java/src/i2p/susi/dns/AddressbookBean.java

    r1150b4cd r4b722c9  
    315315                                        if (action.equals(_t("Delete Entry")))
    316316                                                search = null;
     317                                } else if (action.equals(_t("Add Alternate"))) {
     318                                        // button won't be in UI
     319                                        message = "Unsupported";
    317320                                }
    318321                                if( changed ) {
  • apps/susidns/src/java/src/i2p/susi/dns/NamingServiceBean.java

    r1150b4cd r4b722c9  
    232232                            (serial != null && serial.equals(lastSerial))) {
    233233                                boolean changed = false;
    234                                 if (action.equals(_t("Add")) || action.equals(_t("Replace"))) {
     234                                if (action.equals(_t("Add")) || action.equals(_t("Replace")) || action.equals(_t("Add Alternate"))) {
    235235                                        if(hostname != null && destination != null) {
    236236                                                try {
     
    244244                                                        if (oldDest != null && destination.equals(oldDest.toBase64())) {
    245245                                                                message = _t("Host name {0} is already in address book, unchanged.", displayHost);
    246                                                         } else if (oldDest != null && !action.equals(_t("Replace"))) {
     246                                                        } else if (oldDest == null && action.equals(_t("Add Alternate"))) {
     247                                                                message = _t("Host name {0} is not in  the address book.", displayHost);
     248                                                        } else if (oldDest != null && action.equals(_t("Add"))) {
    247249                                                                message = _t("Host name {0} is already in address book with a different destination. Click \"Replace\" to overwrite.", displayHost);
    248250                                                        } else {
     
    251253                                                                        if (oldDest != null) {
    252254                                                                                nsOptions.putAll(outProperties);
    253                                                                                 nsOptions.setProperty("m", Long.toString(_context.clock().now()));
     255                                                                                String now = Long.toString(_context.clock().now());
     256                                                                                if (action.equals(_t("Add Alternate")))
     257                                                                                        nsOptions.setProperty("a", now);
     258                                                                                else
     259                                                                                        nsOptions.setProperty("m", now);
    254260                                                                        }
    255261                                                                        nsOptions.setProperty("s", _t("Manually added via SusiDNS"));
    256                                                                         boolean success = getNamingService().put(host, dest, nsOptions);
     262                                                                        boolean success;
     263                                                                        if (action.equals(_t("Add Alternate"))) {
     264                                                                                // check all for dups
     265                                                                                List<Destination> all = getNamingService().lookupAll(host);
     266                                                                                if (all == null || !all.contains(dest)) {
     267                                                                                        success = getNamingService().addDestination(host, dest, nsOptions);
     268                                                                                } else {
     269                                                                                        // will get generic message below
     270                                                                                        success = false;
     271                                                                                }
     272                                                                        } else {
     273                                                                                success = getNamingService().put(host, dest, nsOptions);
     274                                                                        }
    257275                                                                        if (success) {
    258276                                                                                changed = true;
    259                                                                                 if (oldDest == null)
     277                                                                                if (oldDest == null || action.equals(_t("Add Alternate")))
    260278                                                                                        message = _t("Destination added for {0}.", displayHost);
    261279                                                                                else
     
    286304                                        String name = null;
    287305                                        int deleted = 0;
     306                                        Destination matchDest = null;
     307                                        if (action.equals(_t("Delete Entry"))) {
     308                                                // remove specified dest only in case there is more than one
     309                                                if (destination != null) {
     310                                                        try {
     311                                                                matchDest = new Destination(destination);
     312                                                        } catch (DataFormatException dfe) {}
     313                                                }
     314                                        }
    288315                                        for (String n : deletionMarks) {
    289                                                 boolean success = getNamingService().remove(n, nsOptions);
     316                                                boolean success;
     317                                                if (matchDest != null)
     318                                                        success = getNamingService().remove(n, matchDest, nsOptions);
     319                                                else
     320                                                        success = getNamingService().remove(n, nsOptions);
    290321                                                String uni = AddressBean.toUnicode(n);
    291322                                                String displayHost = uni.equals(n) ? n :  uni + " (" + n + ')';
  • apps/susidns/src/jsp/addressbook.jsp

    r1150b4cd r4b722c9  
    121121<div id="search">
    122122<form method="POST" action="addressbook">
     123<input type="hidden" name="book" value="${book.book}">
    123124<input type="hidden" name="begin" value="0">
    124125<input type="hidden" name="end" value="49">
     
    137138<c:if test="${book.notEmpty}">
    138139<form method="POST" action="addressbook">
     140<input type="hidden" name="book" value="${book.book}">
    139141<input type="hidden" name="serial" value="<%=susiNonce%>">
    140142<input type="hidden" name="begin" value="0">
     
    164166<span class="addrhlpr"><a href="http://${addr.b32}/" target="_top" title="<%=intl._t("Base 32 address")%>">b32</a></span>
    165167</td><td class="names">
    166 <span class="addrhlpr"><a href="details?h=${addr.name}" title="<%=intl._t("More information on this entry")%>"><%=intl._t("details")%></a></span>
     168<span class="addrhlpr"><a href="details?h=${addr.name}&amp;book=${book.book}" title="<%=intl._t("More information on this entry")%>"><%=intl._t("details")%></a></span>
    167169</td>
    168170<td class="destinations"><textarea rows="1" style="height:3em;" wrap="off" cols="40" readonly="readonly" name="dest_${addr.name}" >${addr.destination}</textarea></td>
     
    209211
    210212<form method="POST" action="addressbook">
     213<input type="hidden" name="book" value="${book.book}">
    211214<input type="hidden" name="serial" value="<%=susiNonce%>">
    212215<input type="hidden" name="begin" value="0">
     
    222225<input class="cancel" type="reset" value="<%=intl._t("Cancel")%>" >
    223226<input class="accept" type="submit" name="action" value="<%=intl._t("Replace")%>" >
     227<% if (!book.getBook().equals("published")) { %>
     228  <input class="add" type="submit" name="action" value="<%=intl._t("Add Alternate")%>" >
     229<% } %>
    224230<input class="add" type="submit" name="action" value="<%=intl._t("Add")%>" >
    225231</p>
  • apps/susidns/src/jsp/details.jsp

    r1150b4cd r4b722c9  
    8282            %><p>Not found: <%=detail%></p><%
    8383        } else {
     84            // use one nonce for all
     85            String nonce = book.getSerial();
    8486            for (i2p.susi.dns.AddressBean addr : addrs) {
    8587                String b32 = addr.getB32();
     
    140142<form method="POST" action="addressbook">
    141143<p class="buttons">
    142 <input type="hidden" name="serial" value="${book.serial}">
     144<input type="hidden" name="book" value="${book.book}">
     145<input type="hidden" name="serial" value="<%=nonce%>">
    143146<input type="hidden" name="begin" value="0">
    144147<input type="hidden" name="end" value="49">
    145148<input type="hidden" name="checked" value="<%=detail%>">
     149<input type="hidden" name="destination" value="<%=addr.getDestination()%>">
    146150<input class="delete" type="submit" name="action" value="<%=intl._t("Delete Entry")%>" >
    147151</p>
  • core/java/src/net/i2p/client/naming/BlockfileNamingService.java

    r1150b4cd r4b722c9  
    15791579                    storedOptions.remove(i);
    15801580                    removeReverseEntry(hostname, d);
     1581                    if (options != null) {
     1582                        String list = options.getProperty("list");
     1583                        if (list != null)
     1584                            storedOptions.get(0).setProperty("list", list);
     1585                    }
    15811586                    return put(hostname, newDests, storedOptions, false);
    15821587                }
  • history.txt

    r1150b4cd r4b722c9  
     12017-03-14 zzz
     2 * Blockfile: Fix specified-destination deletion from the correct book
     3 * i2ptunnel:
     4   - New form to enter private key file for alternate destination
     5   - Use alt destination for registration if set
     6 * NBI: Adjust info logging at startup
     7 * SusiDNS:
     8   - New button for adding alternate destination
     9   - Fix nonces on details page with multiple destinations
     10   - Fix single dest deletion on details page with multiple destinations
     11   - Set book in all forms to ensure correct book
     12
    1132017-03-13 zzz
    214 * i2ptunnel:
  • router/java/src/net/i2p/router/RouterVersion.java

    r1150b4cd r4b722c9  
    1919    public final static String ID = "Monotone";
    2020    public final static String VERSION = CoreVersion.VERSION;
    21     public final static long BUILD = 5;
     21    public final static long BUILD = 6;
    2222
    2323    /** for example "-test" */
Note: See TracChangeset for help on using the changeset viewer.