forked from I2P_Developers/i2p.i2p
i2ptunnel: New b32 error page
Do basic b32 checks before looking up with session Util: Fix AIOOBE on bad input to base 32 decode log tweaks b33 decode error message tweaks
This commit is contained in:
@ -1215,12 +1215,39 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
||||
}
|
||||
} else if("i2p".equals(host)) {
|
||||
clientDest = null;
|
||||
} else if (destination.length() >= 60 && destination.toLowerCase(Locale.US).endsWith(".b32.i2p")) {
|
||||
} else if (destination.toLowerCase(Locale.US).endsWith(".b32.i2p")) {
|
||||
int len = destination.length();
|
||||
if (len < 60 || (len >= 61 && len <= 63)) {
|
||||
// 8-59 or 61-63 chars, this won't work
|
||||
String header = getErrorPage("b32", ERR_DESTINATION_UNKNOWN);
|
||||
try {
|
||||
writeErrorMessage(header, _t("Corrupt b32 address"), out, targetRequest, false, destination);
|
||||
} catch (IOException ioe) {}
|
||||
return;
|
||||
}
|
||||
if (len >= 64) {
|
||||
// catch b33 errors before session lookup
|
||||
try {
|
||||
BlindData bd = Blinding.decode(_context, destination);
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Resolved b33 " + bd);
|
||||
// TESTING
|
||||
//sess.sendBlindingInfo(bd, 24*60*60*1000);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Unable to resolve b33 " + destination, iae);
|
||||
// b33 error page
|
||||
String header = getErrorPage("b32", ERR_DESTINATION_UNKNOWN);
|
||||
try {
|
||||
writeErrorMessage(header, iae.getMessage(), out, targetRequest, false, destination);
|
||||
} catch (IOException ioe) {}
|
||||
return;
|
||||
}
|
||||
}
|
||||
// use existing session to look up for efficiency
|
||||
verifySocketManager();
|
||||
I2PSession sess = sockMgr.getSession();
|
||||
if (!sess.isClosed()) {
|
||||
int len = destination.length();
|
||||
if (len == 60) {
|
||||
byte[] hData = Base32.decode(destination.substring(0, 52));
|
||||
if (hData != null) {
|
||||
@ -1234,33 +1261,43 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
||||
} else if (len >= 64) {
|
||||
if (_log.shouldInfo())
|
||||
_log.info("lookup b33 in-session " + destination);
|
||||
try {
|
||||
BlindData bd = Blinding.decode(_context, destination);
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Resolved b33 " + bd);
|
||||
// TESTING
|
||||
//sess.sendBlindingInfo(bd, 24*60*60*1000);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Unable to resolve b33 " + destination, iae);
|
||||
// TODO new error page
|
||||
}
|
||||
LookupResult lresult = sess.lookupDest2(destination, 20*1000);
|
||||
clientDest = lresult.getDestination();
|
||||
int code = lresult.getResultCode();
|
||||
if (code != 0) {
|
||||
if (code != LookupResult.RESULT_SUCCESS) {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Unable to resolve b33 " + destination + " error code " + code);
|
||||
// TODO new form
|
||||
// TODO new form to supply missing data
|
||||
if (code != LookupResult.RESULT_FAILURE) {
|
||||
String header = getErrorPage("b32", ERR_DESTINATION_UNKNOWN);
|
||||
String msg;
|
||||
if (code == LookupResult.RESULT_SECRET_REQUIRED)
|
||||
msg = "b32 address requires lookup password";
|
||||
else if (code == LookupResult.RESULT_KEY_REQUIRED)
|
||||
msg = "b32 address requires encryption key";
|
||||
else if (code == LookupResult.RESULT_SECRET_AND_KEY_REQUIRED)
|
||||
msg = "b32 address requires encryption key and lookup password";
|
||||
else if (code == LookupResult.RESULT_DECRYPTION_FAILURE)
|
||||
msg = "b32 address decryption failure, check encryption key";
|
||||
else
|
||||
msg = "lookup failure code " + code;
|
||||
try {
|
||||
writeErrorMessage(header, msg, out, targetRequest, false, destination);
|
||||
} catch (IOException ioe) {}
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 61-63 chars, this won't work
|
||||
clientDest = _context.namingService().lookup(destination);
|
||||
}
|
||||
} else {
|
||||
if (_log.shouldInfo())
|
||||
_log.info("lookup b32 out of session " + destination);
|
||||
// TODO can't get result code from here
|
||||
clientDest = _context.namingService().lookup(destination);
|
||||
}
|
||||
} else {
|
||||
if (_log.shouldInfo())
|
||||
_log.info("lookup hostname " + destination);
|
||||
clientDest = _context.namingService().lookup(destination);
|
||||
}
|
||||
|
||||
@ -1518,7 +1555,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
|
||||
if(host == null) {
|
||||
return null;
|
||||
}
|
||||
if(host.length() == 60 && host.toLowerCase(Locale.US).endsWith(".b32.i2p")) {
|
||||
if (host.toLowerCase(Locale.US).endsWith(".b32.i2p")) {
|
||||
return host;
|
||||
}
|
||||
Destination dest = _context.namingService().lookup(host);
|
||||
|
@ -209,7 +209,7 @@ public final class Blinding {
|
||||
throw new IllegalArgumentException("Not a .b32.i2p address");
|
||||
byte[] b = Base32.decode(address.substring(0, address.length() - 8));
|
||||
if (b == null)
|
||||
throw new IllegalArgumentException("Bad base32 encoding");
|
||||
throw new IllegalArgumentException("Corrupt b32 address");
|
||||
if (b.length < 35)
|
||||
throw new IllegalArgumentException("Not a new-format address");
|
||||
return decode(ctx, b);
|
||||
@ -234,22 +234,22 @@ public final class Blinding {
|
||||
b[2] ^= (byte) (check >> 16);
|
||||
int flag = b[0] & 0xff;
|
||||
if ((flag & 0xf8) != 0)
|
||||
throw new IllegalArgumentException("Corrupt b32 or unsupported options");
|
||||
throw new IllegalArgumentException("Corrupt b32 address (or unsupported options)");
|
||||
if ((flag & FLAG_TWOBYTE) != 0)
|
||||
throw new IllegalArgumentException("Two byte sig types unsupported");
|
||||
throw new IllegalArgumentException("Two byte signature types unsupported");
|
||||
// TODO two-byte sigtypes
|
||||
int st1 = b[1] & 0xff;
|
||||
int st2 = b[2] & 0xff;
|
||||
SigType sigt1 = SigType.getByCode(st1);
|
||||
SigType sigt2 = SigType.getByCode(st2);
|
||||
if (sigt1 == null)
|
||||
throw new IllegalArgumentException("Unknown sig type " + st1);
|
||||
throw new IllegalArgumentException("Unsupported signature type " + st1);
|
||||
if (!sigt1.isAvailable())
|
||||
throw new IllegalArgumentException("Unavailable sig type " + sigt1);
|
||||
throw new IllegalArgumentException("Unavailable signature type " + sigt1);
|
||||
if (sigt2 == null)
|
||||
throw new IllegalArgumentException("Unknown blinded sig type " + st2);
|
||||
throw new IllegalArgumentException("Unsupported blinded signature type " + st2);
|
||||
if (!sigt2.isAvailable())
|
||||
throw new IllegalArgumentException("Unavailable blinded sig type " + sigt2);
|
||||
throw new IllegalArgumentException("Unavailable blinded signature type " + sigt2);
|
||||
// todo secret/privkey
|
||||
int spkLen = sigt1.getPubkeyLen();
|
||||
if (3 + spkLen > b.length)
|
||||
|
@ -235,6 +235,8 @@ public class Base32 {
|
||||
fivebits = DECODABET[source[i] - '2'];
|
||||
|
||||
if (fivebits >= 0) {
|
||||
if (outBuffPosn >= len58)
|
||||
return null;
|
||||
if (usedbits == 0) {
|
||||
outBuff[outBuffPosn] = (byte) ((fivebits << 3) & 0xf8);
|
||||
usedbits = 5;
|
||||
|
25
installer/resources/proxy/b32-header.ht
Normal file
25
installer/resources/proxy/b32-header.ht
Normal file
@ -0,0 +1,25 @@
|
||||
HTTP/1.1 400 Destination Not Found
|
||||
Content-Type: text/html; charset=UTF-8
|
||||
Cache-Control: no-cache
|
||||
Connection: close
|
||||
Proxy-Connection: close
|
||||
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html><head>
|
||||
<title>_("Website Unreachable")</title>
|
||||
<noscript><style type="text/css">.script {display: none;}</style></noscript>
|
||||
<link rel="shortcut icon" href="http://proxy.i2p/themes/console/images/favicon.ico">
|
||||
<link href="http://proxy.i2p/themes/console/default/console.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="logo">
|
||||
<a href="http://127.0.0.1:7657/" title="_("Router Console")"><img src="http://proxy.i2p/themes/console/images/i2plogo.png" alt="_("I2P Router Console")" border="0"></a><hr>
|
||||
<a href="http://127.0.0.1:7657/config.jsp">_("Configuration")</a> <a href="http://127.0.0.1:7657/help.jsp">_("Help")</a> <a href="http://127.0.0.1:7657/susidns/index">_("Addressbook")</a>
|
||||
</div>
|
||||
<div class="warning" id="warning">
|
||||
<h3>_("Warning: Invalid Destination")</h3>
|
||||
<p>
|
||||
_("The b32 address is invalid.")
|
||||
<hr>
|
||||
<p><b>_("Could not find the following destination:")</b>
|
||||
</p>
|
@ -129,7 +129,7 @@ class LookupDestJob extends JobImpl {
|
||||
Destination d = _blindData.getDestination();
|
||||
if (d != null) {
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("Found cached b33 lookup " + _name + " to " + d);
|
||||
_log.debug("Found cached b33 lookup " + _blindData.getUnblindedPubKey() + " to " + d);
|
||||
returnDest(d);
|
||||
return;
|
||||
}
|
||||
@ -144,7 +144,7 @@ class LookupDestJob extends JobImpl {
|
||||
else
|
||||
code = HostReplyMessage.RESULT_SECRET_REQUIRED;
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("Failed b33 lookup " + _name + " with code " + code);
|
||||
_log.debug("Failed b33 lookup " + _blindData.getUnblindedPubKey() + " with code " + code);
|
||||
returnFail(code);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user