Consistently log authentication failures for all interfaces

This commit is contained in:
zzz
2016-11-06 17:20:35 +00:00
parent 81bbf554e8
commit c9c29520b4
7 changed files with 74 additions and 16 deletions

View File

@ -304,7 +304,7 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
return AuthResult.AUTH_GOOD; return AuthResult.AUTH_GOOD;
} }
} }
_log.logAlways(Log.WARN, "PROXY AUTH FAILURE: user " + user); _log.logAlways(Log.WARN, "HTTP proxy authentication failed, user: " + user);
} catch (UnsupportedEncodingException uee) { } catch (UnsupportedEncodingException uee) {
_log.error(getPrefix(requestId) + "No UTF-8 support? B64: " + authorization, uee); _log.error(getPrefix(requestId) + "No UTF-8 support? B64: " + authorization, uee);
} catch (ArrayIndexOutOfBoundsException aioobe) { } catch (ArrayIndexOutOfBoundsException aioobe) {
@ -363,7 +363,7 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
String ha1 = getTunnel().getClientOptions().getProperty(PROP_PROXY_DIGEST_PREFIX + user + String ha1 = getTunnel().getClientOptions().getProperty(PROP_PROXY_DIGEST_PREFIX + user +
PROP_PROXY_DIGEST_SUFFIX); PROP_PROXY_DIGEST_SUFFIX);
if (ha1 == null) { if (ha1 == null) {
_log.logAlways(Log.WARN, "PROXY AUTH FAILURE: user " + user); _log.logAlways(Log.WARN, "HTTP proxy authentication failed, user: " + user);
return AuthResult.AUTH_BAD; return AuthResult.AUTH_BAD;
} }
// get H(A2) // get H(A2)
@ -373,7 +373,7 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
String kd = ha1 + ':' + nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + ha2; String kd = ha1 + ':' + nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + ha2;
String hkd = PasswordManager.md5Hex(kd); String hkd = PasswordManager.md5Hex(kd);
if (!response.equals(hkd)) { if (!response.equals(hkd)) {
_log.logAlways(Log.WARN, "PROXY AUTH FAILURE: user " + user); _log.logAlways(Log.WARN, "HTTP proxy authentication failed, user: " + user);
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info("Bad digest auth: " + DataHelper.toString(args)); _log.info("Bad digest auth: " + DataHelper.toString(args));
return AuthResult.AUTH_BAD; return AuthResult.AUTH_BAD;

View File

@ -131,26 +131,32 @@ class SOCKS5Server extends SOCKSServer {
*/ */
private void verifyPassword(DataInputStream in, DataOutputStream out) throws IOException, SOCKSException { private void verifyPassword(DataInputStream in, DataOutputStream out) throws IOException, SOCKSException {
int c = in.readUnsignedByte(); int c = in.readUnsignedByte();
if (c != AUTH_VERSION) if (c != AUTH_VERSION) {
_log.logAlways(Log.WARN, "SOCKS proxy authentication failed");
throw new SOCKSException("Unsupported authentication version"); throw new SOCKSException("Unsupported authentication version");
}
c = in.readUnsignedByte(); c = in.readUnsignedByte();
if (c <= 0) if (c <= 0) {
_log.logAlways(Log.WARN, "SOCKS proxy authentication failed");
throw new SOCKSException("Bad authentication"); throw new SOCKSException("Bad authentication");
}
byte[] user = new byte[c]; byte[] user = new byte[c];
String u = new String(user, "UTF-8");
in.readFully(user); in.readFully(user);
c = in.readUnsignedByte(); c = in.readUnsignedByte();
if (c <= 0) if (c <= 0) {
_log.logAlways(Log.WARN, "SOCKS proxy authentication failed, user: " + u);
throw new SOCKSException("Bad authentication"); throw new SOCKSException("Bad authentication");
}
byte[] pw = new byte[c]; byte[] pw = new byte[c];
in.readFully(pw); in.readFully(pw);
// Hopefully these are in UTF-8, since that's what our config file is in // Hopefully these are in UTF-8, since that's what our config file is in
// these throw UnsupportedEncodingException which is an IOE // these throw UnsupportedEncodingException which is an IOE
String u = new String(user, "UTF-8");
String p = new String(pw, "UTF-8"); String p = new String(pw, "UTF-8");
String configUser = props.getProperty(I2PTunnelHTTPClientBase.PROP_USER); String configUser = props.getProperty(I2PTunnelHTTPClientBase.PROP_USER);
String configPW = props.getProperty(I2PTunnelHTTPClientBase.PROP_PW); String configPW = props.getProperty(I2PTunnelHTTPClientBase.PROP_PW);
if ((!u.equals(configUser)) || (!p.equals(configPW))) { if ((!u.equals(configUser)) || (!p.equals(configPW))) {
_log.error("SOCKS authorization failure"); _log.logAlways(Log.WARN, "SOCKS proxy authentication failed, user: " + u);
sendAuthReply(AUTH_FAILURE, out); sendAuthReply(AUTH_FAILURE, out);
throw new SOCKSException("SOCKS authorization failure"); throw new SOCKSException("SOCKS authorization failure");
} }

View File

@ -48,6 +48,7 @@ import org.eclipse.jetty.server.AbstractConnector;
import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.NCSARequestLog; import org.eclipse.jetty.server.NCSARequestLog;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.UserIdentity;
import org.eclipse.jetty.server.bio.SocketConnector; import org.eclipse.jetty.server.bio.SocketConnector;
import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.DefaultHandler; import org.eclipse.jetty.server.handler.DefaultHandler;
@ -848,7 +849,8 @@ public class RouterConsoleRunner implements RouterApp {
enable = false; enable = false;
ctx.router().saveConfig(PROP_CONSOLE_PW, "false"); ctx.router().saveConfig(PROP_CONSOLE_PW, "false");
} else { } else {
HashLoginService realm = new HashLoginService(JETTY_REALM); HashLoginService realm = new CustomHashLoginService(JETTY_REALM, context.getContextPath(),
ctx.logManager().getLog(RouterConsoleRunner.class));
sec.setLoginService(realm); sec.setLoginService(realm);
sec.setAuthenticator(authenticator); sec.setAuthenticator(authenticator);
String[] role = new String[] {JETTY_ROLE}; String[] role = new String[] {JETTY_ROLE};
@ -932,6 +934,30 @@ public class RouterConsoleRunner implements RouterApp {
context.setSecurityHandler(sec); context.setSecurityHandler(sec);
} }
/**
* For logging authentication failures
* @since 0.9.28
*/
private static class CustomHashLoginService extends HashLoginService {
private final String _webapp;
private final net.i2p.util.Log _log;
public CustomHashLoginService(String realm, String webapp, net.i2p.util.Log log) {
super(realm);
_webapp = webapp;
_log = log;
}
@Override
public UserIdentity login(String username, Object credentials) {
UserIdentity rv = super.login(username, credentials);
if (rv == null)
//_log.logAlways(net.i2p.util.Log.WARN, "Console authentication failed, webapp: " + _webapp + ", user: " + username);
_log.logAlways(net.i2p.util.Log.WARN, "Console authentication failed, user: " + username);
return rv;
}
}
/** @since 0.8.8 */ /** @since 0.8.8 */
private class ServerShutdown implements Runnable { private class ServerShutdown implements Runnable {
public void run() { public void run() {

View File

@ -91,14 +91,23 @@ class SAMHandlerFactory {
if (Boolean.parseBoolean(i2cpProps.getProperty(SAMBridge.PROP_AUTH))) { if (Boolean.parseBoolean(i2cpProps.getProperty(SAMBridge.PROP_AUTH))) {
String user = props.getProperty("USER"); String user = props.getProperty("USER");
String pw = props.getProperty("PASSWORD"); String pw = props.getProperty("PASSWORD");
if (user == null || pw == null) if (user == null || pw == null) {
if (user == null)
log.logAlways(Log.WARN, "SAM authentication failed");
else
log.logAlways(Log.WARN, "SAM authentication failed, user: " + user);
throw new SAMException("USER and PASSWORD required"); throw new SAMException("USER and PASSWORD required");
}
String savedPW = i2cpProps.getProperty(SAMBridge.PROP_PW_PREFIX + user + SAMBridge.PROP_PW_SUFFIX); String savedPW = i2cpProps.getProperty(SAMBridge.PROP_PW_PREFIX + user + SAMBridge.PROP_PW_SUFFIX);
if (savedPW == null) if (savedPW == null) {
log.logAlways(Log.WARN, "SAM authentication failed, user: " + user);
throw new SAMException("Authorization failed"); throw new SAMException("Authorization failed");
}
PasswordManager pm = new PasswordManager(I2PAppContext.getGlobalContext()); PasswordManager pm = new PasswordManager(I2PAppContext.getGlobalContext());
if (!pm.checkHash(savedPW, pw)) if (!pm.checkHash(savedPW, pw)) {
log.logAlways(Log.WARN, "SAM authentication failed, user: " + user);
throw new SAMException("Authorization failed"); throw new SAMException("Authorization failed");
}
} }
// Let's answer positively // Let's answer positively

View File

@ -1,3 +1,20 @@
2016-11-06 zzz
* Console: Add Java 9 log warning (ticket #1870)
* Security: Consistently log authentication failures for all interfaces
* Util: Consolidate linux service detection code
2016-11-05 zzz
* Build: Add support for using libtomcat8-java package
* Console: Add message to ignore InstanceManager warning (ticket #1818)
* SusiDNS: Fix jsp EL syntax error with EL 3.0 (Tomcat 8) (ticket #1870)
2016-11-04 zzz
* Console: Improve handling and logging of webapps that fail to start
* i2psnark: Add launch-i2psnark.bat (ticket #1871)
* Transports:
- New config i2np.allowLocal, fixes test networks (ticket #1875)
- New configs i2np.udp.minpeers and i2np.udp.minv6peers, for testing (ticket #1876)
2016-10-29 zzz 2016-10-29 zzz
* Console: Java 9 fixes for classloader (ticket #1870) * Console: Java 9 fixes for classloader (ticket #1870)
@ -47,7 +64,7 @@
* Console: Fix HTML error on /configservice * Console: Fix HTML error on /configservice
* Debian: Update package descriptions, allow Java 9 * Debian: Update package descriptions, allow Java 9
* i2psnark: Add ids to rows, add to per-torrent show peers link * i2psnark: Add ids to rows, add to per-torrent show peers link
* SSU: Fix minimum version check for IPv6 peer test (ticket #1861) * SSU: Fix minimum version check for IPv6 peer test (tickets #1829, #1861)
* 2016-10-17 0.9.27 released * 2016-10-17 0.9.27 released

View File

@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */ /** deprecated */
public final static String ID = "Monotone"; public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION; public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 6; public final static long BUILD = 7;
/** for example "-test" */ /** for example "-test" */
public final static String EXTRA = ""; public final static String EXTRA = "";

View File

@ -329,14 +329,14 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi
pw = props.getProperty("i2cp.password"); pw = props.getProperty("i2cp.password");
} }
if (user == null || user.length() == 0 || pw == null || pw.length() == 0) { if (user == null || user.length() == 0 || pw == null || pw.length() == 0) {
_log.error("I2CP auth failed"); _log.logAlways(Log.WARN, "I2CP authentication failed");
_runner.disconnectClient("Authorization required, specify i2cp.username and i2cp.password in options"); _runner.disconnectClient("Authorization required, specify i2cp.username and i2cp.password in options");
_authorized = false; _authorized = false;
return false; return false;
} }
PasswordManager mgr = new PasswordManager(_context); PasswordManager mgr = new PasswordManager(_context);
if (!mgr.checkHash(PROP_AUTH, user, pw)) { if (!mgr.checkHash(PROP_AUTH, user, pw)) {
_log.error("I2CP auth failed user: " + user); _log.logAlways(Log.WARN, "I2CP authentication failed, user: " + user);
_runner.disconnectClient("Authorization failed, user = " + user); _runner.disconnectClient("Authorization failed, user = " + user);
_authorized = false; _authorized = false;
return false; return false;