Changeset 2abd59e
- Timestamp:
- May 24, 2019 5:42:11 PM (20 months ago)
- Branches:
- master
- Children:
- c2e2cc2
- Parents:
- 47c64c2e
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
apps/i2ptunnel/java/src/net/i2p/i2ptunnel/ui/GeneralHelper.java
r47c64c2e r2abd59e 570 570 String authType = getProperty(tunnel, "i2cp.leaseSetAuthType", "0"); 571 571 if (authType.equals("2")) { 572 // shared PSK key 573 rv = 4; 574 // per-client PSK key 575 // TODO 576 //rv = 6; 572 if (getProperty(tunnel, "i2cp.leaseSetClient.psk.0", null) != null) { 573 // per-client PSK key 574 rv = 6; 575 } else { 576 // shared PSK key 577 rv = 4; 578 } 577 579 } else if (authType.equals("1")) { 578 580 rv = 8; … … 596 598 public String getBlindedPassword(int tunnel) { 597 599 return getProperty(tunnel, "i2cp.leaseSetSecret", ""); 600 } 601 602 /** 603 * List of b64 name : b64key 604 * Pubkeys for DH, privkeys for PSK 605 * @param isDH true for DH, false for PSK 606 * @return non-null 607 * @since 0.9.41 608 */ 609 public List<String> getClientAuths(int tunnel, boolean isDH) { 610 List<String> rv = new ArrayList<String>(4); 611 String pfx = isDH ? "i2cp.leaseSetClient.dh." : "i2cp.leaseSetClient.psk."; 612 int i = 0; 613 String p; 614 while ((p = getProperty(tunnel, pfx + i, null)) != null) { 615 rv.add(p); 616 i++; 617 } 618 return rv; 598 619 } 599 620 … … 869 890 TunnelConfig._nonProxyNoShowSet.contains(key)) 870 891 continue; 892 if (key.startsWith("i2cp.leaseSetClient.")) 893 continue; 871 894 sorted.put(key, (String)e.getValue()); 872 895 } -
apps/i2ptunnel/java/src/net/i2p/i2ptunnel/ui/TunnelConfig.java
r47c64c2e r2abd59e 3 3 import java.security.GeneralSecurityException; 4 4 import java.util.Arrays; 5 import java.util.ArrayList; 6 import java.util.Collections; 5 7 import java.util.HashSet; 8 import java.util.List; 6 9 import java.util.Map; 7 10 import java.util.Properties; … … 15 18 import net.i2p.crypto.SigType; 16 19 import net.i2p.data.Base64; 20 import net.i2p.data.DataHelper; 17 21 import net.i2p.data.Destination; 18 22 import net.i2p.data.SimpleDataStructure; … … 78 82 private String _filterDefinition; 79 83 private int _encryptMode; 84 private String[] _clientNames; 85 private String[] _clientKeys; 86 private Set<Integer> _clientRevocations; 87 // b64name : b64key 88 private String _newClientName; 89 private String _newClientKey; 90 private boolean _addClientAuth; 80 91 81 92 public TunnelConfig() { … … 270 281 else 271 282 _otherOptions.remove("i2cp.leaseSetSecret"); 283 } 284 285 /** 286 * Multiple entries in form 287 * @since 0.9.41 288 */ 289 public void addClientNames(String[] s) { 290 _clientNames = s; 291 } 292 293 /** 294 * Multiple entries in form 295 * Handles either order addClientName/addClientKey 296 * @since 0.9.41 297 */ 298 public void addClientKeys(String[] s) { 299 _clientKeys = s; 300 } 301 302 /** 303 * Multiple entries in form 304 * @since 0.9.41 305 */ 306 public void revokeClients(String[] s) { 307 _clientRevocations = new HashSet<Integer>(4); 308 for (String k : s) { 309 try { 310 _clientRevocations.add(Integer.valueOf(Integer.parseInt(k))); 311 } catch (NumberFormatException nfe) {} 312 } 313 } 314 315 /** 316 * Handles either order newClientName/newClientKey 317 * @since 0.9.41 318 */ 319 public void newClientName(String s) { 320 _newClientName = s; 321 } 322 323 /** 324 * Handles either order newClientName/newClientKey 325 * @since 0.9.41 326 */ 327 public void newClientKey(String s) { 328 _newClientKey = s; 329 } 330 331 /** 332 * @since 0.9.41 333 */ 334 public void setAddClient(boolean val) { 335 _addClientAuth = val; 272 336 } 273 337 … … 858 922 break; 859 923 924 } 925 926 // per-client keys 927 String pfx; 928 if (_encryptMode == 6 || _encryptMode == 7) { 929 pfx = OPT + "i2cp.leaseSetClient.psk."; 930 } else if (_encryptMode == 8 || _encryptMode == 9) { 931 pfx = OPT + "i2cp.leaseSetClient.dh."; 932 } else { 933 pfx = null; 934 } 935 List<String> clientAuth = null; 936 if (pfx != null) { 937 if (_clientNames != null && _clientKeys != null && _clientNames.length == _clientKeys.length) { 938 clientAuth = new ArrayList<String>(4); 939 } else if (_addClientAuth || _encryptMode == 6 || _encryptMode == 7) { 940 // force one client for per-client PSK 941 clientAuth = new ArrayList<String>(1); 942 if (!_addClientAuth) { 943 _addClientAuth = true; 944 if (_newClientName == null || _newClientName.length() == 0) 945 _newClientName = Base64.encode(DataHelper.getUTF8(GeneralHelper._t("Client", _context) + " 1")); 946 } 947 } 948 } 949 if (pfx != null && clientAuth != null) { 950 if (_clientNames != null && _clientKeys != null && _clientNames.length == _clientKeys.length) { 951 for (int i = 0; i < _clientNames.length; i++) { 952 if (_clientRevocations != null && _clientRevocations.contains(Integer.valueOf(i))) 953 continue; 954 String name = _clientNames[i]; 955 String key = _clientKeys[i]; 956 byte[] b = Base64.decode(key); 957 if (b == null || b.length != 32) 958 continue; 959 if (name.length() > 0) 960 name = Base64.encode(DataHelper.getUTF8(name)); 961 else 962 name = Base64.encode(DataHelper.getUTF8(GeneralHelper._t("Client", _context) + ' ' + (i + 1))); 963 clientAuth.add(name + ':' + key); 964 } 965 } 966 if (_addClientAuth && _newClientName != null) { 967 String name = _newClientName; 968 if (name.length() > 0) 969 name = Base64.encode(DataHelper.getUTF8(name)); 970 else 971 name = Base64.encode(DataHelper.getUTF8(GeneralHelper._t("Client", _context) + ' ' + (clientAuth.size() + 1))); 972 String key; 973 if (_encryptMode == 6 || _encryptMode == 7) { 974 byte[] b = new byte[32]; 975 _context.random().nextBytes(b); 976 key = Base64.encode(b); 977 clientAuth.add(name + ':' + key); 978 } else if (_encryptMode == 8 || _encryptMode == 9) { 979 key = _newClientKey; 980 byte[] b = Base64.decode(key); 981 if (b != null && b.length == 32) { 982 // key required for DH 983 clientAuth.add(name + ':' + key); 984 } 985 } 986 } 987 int i = 0; 988 for (String auth : clientAuth) { 989 config.put(pfx + i, auth); 990 i++; 991 } 860 992 } 861 993 } … … 934 1066 "inbound.randomKey", "outbound.randomKey", "i2cp.leaseSetSigningPrivateKey", "i2cp.leaseSetPrivateKey", 935 1067 I2PTunnelServer.PROP_ALT_PKF, 936 "i2cp.leaseSetSecret", "i2cp.leaseSetType", "i2cp.leaseSetAuthType" 1068 "i2cp.leaseSetSecret", "i2cp.leaseSetType", "i2cp.leaseSetAuthType", "i2cp.leaseSetPrivKey" 937 1069 }; 938 1070 private static final String _httpServerOpts[] = { -
apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java
r47c64c2e r2abd59e 225 225 public String getBlindedPassword(int tunnel) { 226 226 return _helper.getBlindedPassword(tunnel); 227 } 228 229 /** 230 * List of b64 name : b64key 231 * Pubkeys for DH, privkeys for PSK 232 * @param isDH true for DH, false for PSK 233 * @return non-null 234 * @since 0.9.41 235 */ 236 public List<String> getClientAuths(int tunnel, boolean isDH) { 237 return _helper.getClientAuths(tunnel, isDH); 227 238 } 228 239 -
apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java
r47c64c2e r2abd59e 873 873 } 874 874 875 /** 876 * Multiple entries in form 877 * @since 0.9.41 878 */ 879 public void setNofilter_clientName(String[] s) { 880 if (s != null) { 881 _config.addClientNames(s); 882 } 883 } 884 885 886 /** 887 * Multiple entries in form 888 * @since 0.9.41 889 */ 890 public void setclientKey(String[] s) { 891 if (s != null) { 892 _config.addClientKeys(s); 893 } 894 } 895 896 /** 897 * Multiple entries in form 898 * Values are integers 899 * @since 0.9.41 900 */ 901 public void setRevokeClient(String[] s) { 902 if (s != null) { 903 _config.revokeClients(s); 904 } 905 } 906 907 /** 908 * @since 0.9.41 909 */ 910 public void setNofilter_newClientName(String s) { 911 if (s != null) { 912 _config.newClientName(s.trim()); 913 } 914 } 915 916 /** 917 * @since 0.9.41 918 */ 919 public void setNewClientKey(String s) { 920 if (s != null) { 921 _config.newClientKey(s.trim()); 922 } 923 } 924 925 /** 926 * @since 0.9.41 927 */ 928 public void setAddClient(String moo) { 929 _config.setAddClient(true); 930 } 931 875 932 /** @since 0.8.9 */ 876 933 public void setDCC(String moo) { -
apps/i2ptunnel/jsp/editServer.jsi
r47c64c2e r2abd59e 156 156 </tr><tr> 157 157 <td> 158 <div class="displayText" title="<%=intl._t("Read Only: Local Destination (if known)")%>" tabindex="0" onblur="resetScrollLeft(this)"><%=editBean.getDestinationBase64(curTunnel)%></div>158 <div class="displayText" style="user-select: all;" title="<%=intl._t("Read Only: Local Destination (if known)")%>" tabindex="0" onblur="resetScrollLeft(this)"><%=editBean.getDestinationBase64(curTunnel)%></div> 159 159 </td><td> 160 160 <% String value3 = editBean.getPrivateKeyFile(curTunnel); … … 486 486 </tr><tr> 487 487 <td> 488 <% 489 if (allowBlinding && editBean.isAdvanced()) { 490 %> 491 <b><%=intl._t("Optional lookup password")%>:</b> 492 <% 493 } // allowBlinding 494 %> 495 </td><td> 496 <% 497 // even if not shown, we need to preserve the param as a hidden input below 498 // as it's the key we use to decrypt the PSK/DH LS on the router side 499 boolean showSharedKey = curEncryptMode.equals("1") || curEncryptMode.equals("4") || curEncryptMode.equals("5"); 500 if (showSharedKey) { 501 %> 488 502 <b><%=intl._t("Encryption Key")%></b> 489 </td><td> 503 <% 504 } // showSharedKey 505 %> 506 </td> 507 </tr><tr> 508 <td> 490 509 <% 491 510 if (allowBlinding && editBean.isAdvanced()) { 492 511 %> 493 < b><%=intl._t("Optional lookup password")%>:</b>512 <input type="password" name="nofilter_blindedPassword" title="<%=intl._t("Set password required to access this service")%>" value="<%=editBean.getBlindedPassword(curTunnel)%>" class="freetext password" /> 494 513 <% 495 514 } // allowBlinding 496 515 %> 497 </td> 498 </tr><tr> 499 <td> 500 <textarea rows="1" style="height: 3em;" cols="44" id="leasesetKey" name="encryptKey" title="<%=intl._t("Encryption key required to access this service")%>" wrap="off" readonly="readonly"><%=editBean.getEncryptKey(curTunnel)%></textarea> 501 </td><td> 516 </td><td> 517 <input type="<%=showSharedKey ? "text" : "hidden"%>" style="user-select: all;" size="44" id="leasesetKey" name="encryptKey" title="<%=intl._t("Encryption key required to access this service")%>" readonly="readonly" value="<%=editBean.getEncryptKey(curTunnel)%>" class="freetext"/> 518 </td> 519 </tr> 502 520 <% 503 521 if (allowBlinding && editBean.isAdvanced()) { 504 %> 505 <input type="password" name="nofilter_blindedPassword" title="<%=intl._t("Set password required to access this service")%>" value="<%=editBean.getBlindedPassword(curTunnel)%>" class="freetext password" /> 506 <% 522 boolean pskClient = curEncryptMode.equals("6") || curEncryptMode.equals("7"); 523 boolean dhClient = curEncryptMode.equals("8") || curEncryptMode.equals("9"); 524 if (pskClient || dhClient) { 525 // b64Name:b64Key 526 java.util.List<String> clientAuths = editBean.getClientAuths(curTunnel, dhClient); 527 if (!clientAuths.isEmpty()) { 528 %> 529 <tr><td><b><%=intl._t("Revoke?")%> <%=intl._t("Client Name")%></b></td><td><b><%=intl._t("Client Key")%></b></td></tr> 530 <% 531 int i = 0; 532 for (String clientAuth : clientAuths) { 533 String[] split = net.i2p.data.DataHelper.split(clientAuth, ":", 2); 534 String cname, ckey; 535 if (split.length == 2) { 536 cname = split[0]; 537 ckey = split[1]; 538 } else { 539 cname = ""; 540 ckey = split[0]; 541 } 542 if (cname.length() > 0) { 543 cname = net.i2p.data.DataHelper.escapeHTML(net.i2p.data.DataHelper.getUTF8(net.i2p.data.Base64.decode(cname))); 544 } else { 545 cname = intl._t("Client") + ' ' + (i + 1); 546 } 547 %> 548 <tr> 549 <td><input value="<%=i%>" type="checkbox" name="revokeClient" class="tickbox" /> 550 <input type="text" value="<%=cname%>" size="44" name="nofilter_clientName" class="freetext" /></td> 551 <td><input type="text" id="leasesetKey" style="user-select: all;" value="<%=ckey%>" size="44" name="clientKey" readonly="readonly" class="freetext" /> 552 </tr> 553 <% 554 i++; 555 } // for 556 } // isEmpty 557 %> 558 <tr><td><b><%=intl._t("Add?")%> <%=intl._t("Client Name")%></b></td><td> 559 <% 560 if (dhClient) { 561 %> 562 <b><%=intl._t("Client Key")%></b> 563 <% 564 } // dhClient 565 %> 566 </td></tr><tr> 567 <td><input value="1" type="checkbox" name="addClient" class="tickbox" /> 568 <input type="text" value="<%=intl._t("Client") + ' ' + (clientAuths.size() + 1)%>" size="44" name="nofilter_newClientName" class="freetext" /></td> 569 <td> 570 <% 571 if (dhClient) { 572 %> 573 <input type="text" id="leasesetKey" value="" size="44" maxlength="44" name="newClientKey" class="freetext" /> 574 <% 575 } // dhClient 576 %> 577 </td></tr> 578 <% 579 } // pskClient || dhClient 507 580 } // allowBlinding 508 %>509 </td>510 </tr>511 <%512 581 } // !isOffline 513 582 %> -
apps/i2ptunnel/jsp/register.jsp
r47c64c2e r2abd59e 151 151 <tr> 152 152 <td> 153 <div class="displayText" tabindex="0" title="<%=intl._t("Copy and paste this to the registration site")%>"><% he.write(out); %></div>153 <div class="displayText" tabindex="0" style="user-select: all; "title="<%=intl._t("Copy and paste this to the registration site")%>"><% he.write(out); %></div> 154 154 </td> 155 155 </tr> … … 172 172 <tr> 173 173 <td> 174 <div class="displayText" tabindex="0" title="<%=intl._t("Copy and paste this to the registration site")%>"><% he.writeRemove(out); %></div>174 <div class="displayText" tabindex="0" style="user-select: all;" title="<%=intl._t("Copy and paste this to the registration site")%>"><% he.writeRemove(out); %></div> 175 175 </td> 176 176 </tr> … … 212 212 <tr> 213 213 <td> 214 <div class="displayText" tabindex="0" title="<%=intl._t("Copy and paste this to the registration site")%>"><% he.write(out); %></div>214 <div class="displayText" tabindex="0" style="user-select: all;" title="<%=intl._t("Copy and paste this to the registration site")%>"><% he.write(out); %></div> 215 215 </td> 216 216 </tr> … … 245 245 <tr> 246 246 <td> 247 <div class="displayText" tabindex="0" title="<%=intl._t("Copy and paste this to the registration site")%>"><% he.write(out); %></div>247 <div class="displayText" tabindex="0" style="user-select: all;" title="<%=intl._t("Copy and paste this to the registration site")%>"><% he.write(out); %></div> 248 248 </td> 249 249 </tr> … … 282 282 <tr> 283 283 <td> 284 <div class="displayText" tabindex="0" title="<%=intl._t("Copy and paste this to the registration site")%>"><% he.write(out); %></div>284 <div class="displayText" tabindex="0" style="user-select: all;" title="<%=intl._t("Copy and paste this to the registration site")%>"><% he.write(out); %></div> 285 285 </td> 286 286 </tr> … … 319 319 <tr> 320 320 <td> 321 <div class="displayText" tabindex="0" title="<%=intl._t("Copy and paste this to the registration site")%>"><% he.write(out); %></div>321 <div class="displayText" tabindex="0" style="user-select: all;" title="<%=intl._t("Copy and paste this to the registration site")%>"><% he.write(out); %></div> 322 322 </td> 323 323 </tr> … … 352 352 he2.signInner(spk); 353 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>354 %><tr><td><div class="displayText" tabindex="0" style="user-select: all;" title="<%=intl._t("Copy and paste this to the registration site")%>"><% he2.write(out); %></div></td></tr> 355 355 <tr><td class="infohelp"><%=intl._t("This will add an alternate destination for {0}", name)%></td></tr> 356 356 <% … … 386 386 <tr> 387 387 <td> 388 <div class="displayText" tabindex="0" title="<%=intl._t("Copy and paste this to the registration site")%>"><% he.write(out); %></div>388 <div class="displayText" tabindex="0" style="user-select: all;" title="<%=intl._t("Copy and paste this to the registration site")%>"><% he.write(out); %></div> 389 389 </td> 390 390 </tr> -
history.txt
r47c64c2e r2abd59e 1 2019-05-24 zzz 2 * i2ptunnel: 3 - Per-client auth config 4 - Hide encryption key for per-client auth 5 - User-select: all for key fields 6 7 2019-05-23 zzz 8 * i2ptunnel: 9 - Rework server encryption key UI in prep for blinded keys 10 - Remove generate button, automatically generate when required 11 - Refactor auto configuration 12 - Add LS2 option, change to select box 13 - Select box for sig type 14 15 2019-05-22 zzz 16 * Crypto: Add X25519 DH class 17 * Data: Per-client auth for enc. LS2 (proposal 123) 18 * Transport: Use KeyGenerator for X25519 keys 19 1 20 2019-05-21 zzz 2 21 * Profiles: Omit comments from stored profiles -
router/java/src/net/i2p/router/RouterVersion.java
r47c64c2e r2abd59e 19 19 public final static String ID = "Monotone"; 20 20 public final static String VERSION = CoreVersion.VERSION; 21 public final static long BUILD = 5;21 public final static long BUILD = 6; 22 22 23 23 /** for example "-test" */
Note: See TracChangeset
for help on using the changeset viewer.