From c9c29520b4514dc3ad25a120ebba440762388aea Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 6 Nov 2016 17:20:35 +0000 Subject: [PATCH] Consistently log authentication failures for all interfaces --- .../i2ptunnel/I2PTunnelHTTPClientBase.java | 6 ++-- .../net/i2p/i2ptunnel/socks/SOCKS5Server.java | 16 +++++++---- .../i2p/router/web/RouterConsoleRunner.java | 28 ++++++++++++++++++- .../src/net/i2p/sam/SAMHandlerFactory.java | 15 ++++++++-- history.txt | 19 ++++++++++++- .../src/net/i2p/router/RouterVersion.java | 2 +- .../client/ClientMessageEventListener.java | 4 +-- 7 files changed, 74 insertions(+), 16 deletions(-) diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientBase.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientBase.java index 2d6e053b03..4908042dd6 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientBase.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClientBase.java @@ -304,7 +304,7 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem 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) { _log.error(getPrefix(requestId) + "No UTF-8 support? B64: " + authorization, uee); } catch (ArrayIndexOutOfBoundsException aioobe) { @@ -363,7 +363,7 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem String ha1 = getTunnel().getClientOptions().getProperty(PROP_PROXY_DIGEST_PREFIX + user + PROP_PROXY_DIGEST_SUFFIX); 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; } // get H(A2) @@ -373,7 +373,7 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem String kd = ha1 + ':' + nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + ha2; String hkd = PasswordManager.md5Hex(kd); 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)) _log.info("Bad digest auth: " + DataHelper.toString(args)); return AuthResult.AUTH_BAD; diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKS5Server.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKS5Server.java index 823497f281..d790d7dba3 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKS5Server.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/socks/SOCKS5Server.java @@ -131,26 +131,32 @@ class SOCKS5Server extends SOCKSServer { */ private void verifyPassword(DataInputStream in, DataOutputStream out) throws IOException, SOCKSException { 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"); + } c = in.readUnsignedByte(); - if (c <= 0) + if (c <= 0) { + _log.logAlways(Log.WARN, "SOCKS proxy authentication failed"); throw new SOCKSException("Bad authentication"); + } byte[] user = new byte[c]; + String u = new String(user, "UTF-8"); in.readFully(user); c = in.readUnsignedByte(); - if (c <= 0) + if (c <= 0) { + _log.logAlways(Log.WARN, "SOCKS proxy authentication failed, user: " + u); throw new SOCKSException("Bad authentication"); + } byte[] pw = new byte[c]; in.readFully(pw); // Hopefully these are in UTF-8, since that's what our config file is in // these throw UnsupportedEncodingException which is an IOE - String u = new String(user, "UTF-8"); String p = new String(pw, "UTF-8"); String configUser = props.getProperty(I2PTunnelHTTPClientBase.PROP_USER); String configPW = props.getProperty(I2PTunnelHTTPClientBase.PROP_PW); 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); throw new SOCKSException("SOCKS authorization failure"); } diff --git a/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java b/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java index ae9cb0eb72..7b0414d2e6 100644 --- a/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java +++ b/apps/routerconsole/java/src/net/i2p/router/web/RouterConsoleRunner.java @@ -48,6 +48,7 @@ import org.eclipse.jetty.server.AbstractConnector; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.NCSARequestLog; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.UserIdentity; import org.eclipse.jetty.server.bio.SocketConnector; import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.handler.DefaultHandler; @@ -848,7 +849,8 @@ public class RouterConsoleRunner implements RouterApp { enable = false; ctx.router().saveConfig(PROP_CONSOLE_PW, "false"); } else { - HashLoginService realm = new HashLoginService(JETTY_REALM); + HashLoginService realm = new CustomHashLoginService(JETTY_REALM, context.getContextPath(), + ctx.logManager().getLog(RouterConsoleRunner.class)); sec.setLoginService(realm); sec.setAuthenticator(authenticator); String[] role = new String[] {JETTY_ROLE}; @@ -932,6 +934,30 @@ public class RouterConsoleRunner implements RouterApp { 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 */ private class ServerShutdown implements Runnable { public void run() { diff --git a/apps/sam/java/src/net/i2p/sam/SAMHandlerFactory.java b/apps/sam/java/src/net/i2p/sam/SAMHandlerFactory.java index 54e9c56b56..c6ed6243b6 100644 --- a/apps/sam/java/src/net/i2p/sam/SAMHandlerFactory.java +++ b/apps/sam/java/src/net/i2p/sam/SAMHandlerFactory.java @@ -91,14 +91,23 @@ class SAMHandlerFactory { if (Boolean.parseBoolean(i2cpProps.getProperty(SAMBridge.PROP_AUTH))) { String user = props.getProperty("USER"); 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"); + } 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"); + } 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"); + } } // Let's answer positively diff --git a/history.txt b/history.txt index 0c3a302a71..a79cbb3c67 100644 --- a/history.txt +++ b/history.txt @@ -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 * Console: Java 9 fixes for classloader (ticket #1870) @@ -47,7 +64,7 @@ * Console: Fix HTML error on /configservice * Debian: Update package descriptions, allow Java 9 * 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 diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java index c10128fe62..fecba78d69 100644 --- a/router/java/src/net/i2p/router/RouterVersion.java +++ b/router/java/src/net/i2p/router/RouterVersion.java @@ -18,7 +18,7 @@ public class RouterVersion { /** deprecated */ public final static String ID = "Monotone"; public final static String VERSION = CoreVersion.VERSION; - public final static long BUILD = 6; + public final static long BUILD = 7; /** for example "-test" */ public final static String EXTRA = ""; diff --git a/router/java/src/net/i2p/router/client/ClientMessageEventListener.java b/router/java/src/net/i2p/router/client/ClientMessageEventListener.java index a50a6c9bce..b6893b59c0 100644 --- a/router/java/src/net/i2p/router/client/ClientMessageEventListener.java +++ b/router/java/src/net/i2p/router/client/ClientMessageEventListener.java @@ -329,14 +329,14 @@ class ClientMessageEventListener implements I2CPMessageReader.I2CPMessageEventLi pw = props.getProperty("i2cp.password"); } 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"); _authorized = false; return false; } PasswordManager mgr = new PasswordManager(_context); 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); _authorized = false; return false;