diff --git a/.gitignore b/.gitignore index 72810d46..d27251ea 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ broker/runner # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* broker/moquette_store.* +embedding_moquette/target/ diff --git a/ChangeLog.txt b/ChangeLog.txt index 3c473b96..7841735f 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -7,6 +7,7 @@ Version 0.8: Fixed bug #81, on stop of moquette broker it doesn't shutdown due to no shutdown of ringbuffer used on the back of ProtocolProcessor Moved config to be not only filesystem based, but also classpath and memory (fix issue #73) Switched from commit pesistence on every change to time based to fix delay in handling many msgs/sec (fix issue #79) + Changed willMessage and password in CONNECT message from String to byte[] (fix issue #94 and #95) Version 0.7: Fix issue #38, added aligned to MQTT 3.1.1 diff --git a/broker/src/main/java/org/eclipse/moquette/interception/messages/InterceptConnectMessage.java b/broker/src/main/java/org/eclipse/moquette/interception/messages/InterceptConnectMessage.java index 4766f744..35a7bc17 100644 --- a/broker/src/main/java/org/eclipse/moquette/interception/messages/InterceptConnectMessage.java +++ b/broker/src/main/java/org/eclipse/moquette/interception/messages/InterceptConnectMessage.java @@ -57,7 +57,7 @@ public class InterceptConnectMessage extends InterceptAbstractMessage { return msg.getUsername(); } - public String getPassword() { + public byte[] getPassword() { return msg.getPassword(); } @@ -65,7 +65,7 @@ public class InterceptConnectMessage extends InterceptAbstractMessage { return msg.getWillTopic(); } - public String getWillMessage() { + public byte[] getWillMessage() { return msg.getWillMessage(); } } diff --git a/broker/src/main/java/org/eclipse/moquette/spi/impl/ProtocolProcessor.java b/broker/src/main/java/org/eclipse/moquette/spi/impl/ProtocolProcessor.java index 7d448244..2b50e11c 100644 --- a/broker/src/main/java/org/eclipse/moquette/spi/impl/ProtocolProcessor.java +++ b/broker/src/main/java/org/eclipse/moquette/spi/impl/ProtocolProcessor.java @@ -177,7 +177,7 @@ class ProtocolProcessor implements EventHandler { //handle user authentication if (msg.isUserFlag()) { - String pwd = null; + byte[] pwd = null; if (msg.isPasswordFlag()) { pwd = msg.getPassword(); } else if (!this.allowAnonymous) { @@ -225,7 +225,7 @@ class ProtocolProcessor implements EventHandler { //Handle will flag if (msg.isWillFlag()) { AbstractMessage.QOSType willQos = AbstractMessage.QOSType.values()[msg.getWillQos()]; - byte[] willPayload = msg.getWillMessage().getBytes(); + byte[] willPayload = msg.getWillMessage(); ByteBuffer bb = (ByteBuffer) ByteBuffer.allocate(willPayload.length).put(willPayload).flip(); //save the will testament in the clientID store WillMessage will = new WillMessage(msg.getWillTopic(), bb, msg.isWillRetain(),willQos ); diff --git a/broker/src/main/java/org/eclipse/moquette/spi/impl/security/AcceptAllAuthenticator.java b/broker/src/main/java/org/eclipse/moquette/spi/impl/security/AcceptAllAuthenticator.java index 06204fa0..a6f1b0c8 100644 --- a/broker/src/main/java/org/eclipse/moquette/spi/impl/security/AcceptAllAuthenticator.java +++ b/broker/src/main/java/org/eclipse/moquette/spi/impl/security/AcceptAllAuthenticator.java @@ -4,7 +4,7 @@ package org.eclipse.moquette.spi.impl.security; * Created by andrea on 8/23/14. */ public class AcceptAllAuthenticator implements IAuthenticator { - public boolean checkValid(String username, String password) { + public boolean checkValid(String username, byte[] password) { return true; } } diff --git a/broker/src/main/java/org/eclipse/moquette/spi/impl/security/FileAuthenticator.java b/broker/src/main/java/org/eclipse/moquette/spi/impl/security/FileAuthenticator.java index 84d0c477..bd013b1b 100644 --- a/broker/src/main/java/org/eclipse/moquette/spi/impl/security/FileAuthenticator.java +++ b/broker/src/main/java/org/eclipse/moquette/spi/impl/security/FileAuthenticator.java @@ -106,7 +106,7 @@ public class FileAuthenticator implements IAuthenticator { } } - public boolean checkValid(String username, String password) { + public boolean checkValid(String username, byte[] password) { if (username == null || password == null) { LOG.info("username or password was null"); return false; @@ -115,11 +115,7 @@ public class FileAuthenticator implements IAuthenticator { if (foundPwq == null) { return false; } - try { - m_digest.update(password.getBytes("UTF-8")); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } + m_digest.update(password); byte[] digest = m_digest.digest(); String encodedPasswd = new String(Hex.encodeHex(digest)); return foundPwq.equals(encodedPasswd); diff --git a/broker/src/main/java/org/eclipse/moquette/spi/impl/security/IAuthenticator.java b/broker/src/main/java/org/eclipse/moquette/spi/impl/security/IAuthenticator.java index 48da536f..4a13a939 100644 --- a/broker/src/main/java/org/eclipse/moquette/spi/impl/security/IAuthenticator.java +++ b/broker/src/main/java/org/eclipse/moquette/spi/impl/security/IAuthenticator.java @@ -22,5 +22,5 @@ package org.eclipse.moquette.spi.impl.security; */ public interface IAuthenticator { - boolean checkValid(String username, String password); + boolean checkValid(String username, byte[] password); } diff --git a/broker/src/test/java/org/eclipse/moquette/server/ConfigurationClassLoaderTest.java b/broker/src/test/java/org/eclipse/moquette/server/ConfigurationClassLoaderTest.java index 647fcac8..6e71ac00 100644 --- a/broker/src/test/java/org/eclipse/moquette/server/ConfigurationClassLoaderTest.java +++ b/broker/src/test/java/org/eclipse/moquette/server/ConfigurationClassLoaderTest.java @@ -79,7 +79,7 @@ public class ConfigurationClassLoaderTest implements IAuthenticator, IAuthorizat } @Override - public boolean checkValid(String username, String password) { + public boolean checkValid(String username, byte[] password) { return true; } diff --git a/broker/src/test/java/org/eclipse/moquette/server/ServerLowlevelMessagesIntegrationTests.java b/broker/src/test/java/org/eclipse/moquette/server/ServerLowlevelMessagesIntegrationTests.java index 474dcde7..fa25a326 100644 --- a/broker/src/test/java/org/eclipse/moquette/server/ServerLowlevelMessagesIntegrationTests.java +++ b/broker/src/test/java/org/eclipse/moquette/server/ServerLowlevelMessagesIntegrationTests.java @@ -111,7 +111,7 @@ public class ServerLowlevelMessagesIntegrationTests { connectMessage.setClientID("FAKECLNT"); connectMessage.setKeepAlive(keepAlive); connectMessage.setWillFlag(true); - connectMessage.setWillMessage(willTestamentMsg); + connectMessage.setWillMessage(willTestamentMsg.getBytes()); connectMessage.setWillTopic(willTestamentTopic); connectMessage.setWillQos((byte) QOSType.MOST_ONE.ordinal()); diff --git a/broker/src/test/java/org/eclipse/moquette/spi/impl/MockAuthenticator.java b/broker/src/test/java/org/eclipse/moquette/spi/impl/MockAuthenticator.java index 6a99edbd..da21be54 100644 --- a/broker/src/test/java/org/eclipse/moquette/spi/impl/MockAuthenticator.java +++ b/broker/src/test/java/org/eclipse/moquette/spi/impl/MockAuthenticator.java @@ -25,13 +25,13 @@ import org.eclipse.moquette.spi.impl.security.IAuthenticator; */ class MockAuthenticator implements IAuthenticator { - private Map m_userPwds; + private Map m_userPwds; - MockAuthenticator(Map userPwds) { + MockAuthenticator(Map userPwds) { m_userPwds = userPwds; } - public boolean checkValid(String username, String password) { + public boolean checkValid(String username, byte[] password) { if (!m_userPwds.containsKey(username)) { return false; } diff --git a/broker/src/test/java/org/eclipse/moquette/spi/impl/ProtocolProcessorTest.java b/broker/src/test/java/org/eclipse/moquette/spi/impl/ProtocolProcessorTest.java index 1b77b61b..14ae613f 100644 --- a/broker/src/test/java/org/eclipse/moquette/spi/impl/ProtocolProcessorTest.java +++ b/broker/src/test/java/org/eclipse/moquette/spi/impl/ProtocolProcessorTest.java @@ -52,9 +52,9 @@ public class ProtocolProcessorTest { final static String BAD_FORMATTED_TOPIC = "#MQTTClient"; final static String TEST_USER = "fakeuser"; - final static String TEST_PWD = "fakepwd"; + final static byte[] TEST_PWD = "fakepwd".getBytes(); final static String EVIL_TEST_USER = "eviluser"; - final static String EVIL_TEST_PWD = "unsecret"; + final static byte[] EVIL_TEST_PWD = "unsecret".getBytes(); final static List EMPTY_OBSERVERS = Collections.emptyList(); final static BrokerInterceptor NO_OBSERVERS_INTERCEPTOR = new BrokerInterceptor(EMPTY_OBSERVERS); @@ -164,7 +164,7 @@ public class ProtocolProcessorTest { m_sessionStore = memStorage; //m_storageService.initStore(); - Map users = new HashMap<>(); + Map users = new HashMap<>(); users.put(TEST_USER, TEST_PWD); m_mockAuthenticator = new MockAuthenticator(users); @@ -202,7 +202,7 @@ public class ProtocolProcessorTest { connMsg.setClientID("123"); connMsg.setWillFlag(true); connMsg.setWillTopic("topic"); - connMsg.setWillMessage("Topic message"); + connMsg.setWillMessage("Topic message".getBytes()); //Exercise diff --git a/broker/src/test/java/org/eclipse/moquette/spi/impl/security/FileAuthenticatorTest.java b/broker/src/test/java/org/eclipse/moquette/spi/impl/security/FileAuthenticatorTest.java index 425ad568..afc41e05 100644 --- a/broker/src/test/java/org/eclipse/moquette/spi/impl/security/FileAuthenticatorTest.java +++ b/broker/src/test/java/org/eclipse/moquette/spi/impl/security/FileAuthenticatorTest.java @@ -31,7 +31,7 @@ public class FileAuthenticatorTest { String file = getClass().getResource("/password_file.conf").getPath(); IAuthenticator auth = new FileAuthenticator(null, file); - assertTrue(auth.checkValid("testuser", "passwd")); + assertTrue(auth.checkValid("testuser", "passwd".getBytes())); } @Test @@ -39,14 +39,14 @@ public class FileAuthenticatorTest { String file = getClass().getResource("/password_file.conf").getPath(); IAuthenticator auth = new FileAuthenticator(null, file); - assertFalse(auth.checkValid("testuser2", "passwd")); + assertFalse(auth.checkValid("testuser2", "passwd".getBytes())); } @Test public void loadPasswordFile_verifyDirectoryRef() { IAuthenticator auth = new FileAuthenticator("", ""); - assertFalse(auth.checkValid("testuser2", "passwd")); + assertFalse(auth.checkValid("testuser2", "passwd".getBytes())); } } \ No newline at end of file diff --git a/netty_parser/src/main/java/org/eclipse/moquette/parser/netty/ConnectDecoder.java b/netty_parser/src/main/java/org/eclipse/moquette/parser/netty/ConnectDecoder.java index ec2270c9..2a811ba6 100644 --- a/netty_parser/src/main/java/org/eclipse/moquette/parser/netty/ConnectDecoder.java +++ b/netty_parser/src/main/java/org/eclipse/moquette/parser/netty/ConnectDecoder.java @@ -173,7 +173,7 @@ public class ConnectDecoder extends DemuxDecoder { //Decode willMessage if (willFlag) { - String willMessage = Utils.decodeString(in); + byte[] willMessage = Utils.readFixedLengthContent(in); if (willMessage == null) { in.resetReaderIndex(); return; @@ -207,7 +207,7 @@ public class ConnectDecoder extends DemuxDecoder { //Decode password if (passwordFlag) { - String password = Utils.decodeString(in); + byte[] password = Utils.readFixedLengthContent(in); if (password == null) { in.resetReaderIndex(); return; diff --git a/netty_parser/src/main/java/org/eclipse/moquette/parser/netty/ConnectEncoder.java b/netty_parser/src/main/java/org/eclipse/moquette/parser/netty/ConnectEncoder.java index 3e3e97eb..f6994623 100644 --- a/netty_parser/src/main/java/org/eclipse/moquette/parser/netty/ConnectEncoder.java +++ b/netty_parser/src/main/java/org/eclipse/moquette/parser/netty/ConnectEncoder.java @@ -65,12 +65,12 @@ public class ConnectEncoder extends DemuxEncoder { variableHeaderBuff.writeBytes(Utils.encodeString(message.getClientID())); if (message.isWillFlag()) { variableHeaderBuff.writeBytes(Utils.encodeString(message.getWillTopic())); - variableHeaderBuff.writeBytes(Utils.encodeString(message.getWillMessage())); + variableHeaderBuff.writeBytes(Utils.encodeFixedLengthContent(message.getWillMessage())); } if (message.isUserFlag() && message.getUsername() != null) { variableHeaderBuff.writeBytes(Utils.encodeString(message.getUsername())); if (message.isPasswordFlag() && message.getPassword() != null) { - variableHeaderBuff.writeBytes(Utils.encodeString(message.getPassword())); + variableHeaderBuff.writeBytes(Utils.encodeFixedLengthContent(message.getPassword())); } } } diff --git a/netty_parser/src/main/java/org/eclipse/moquette/parser/netty/Utils.java b/netty_parser/src/main/java/org/eclipse/moquette/parser/netty/Utils.java index f9e1b289..16622b2b 100644 --- a/netty_parser/src/main/java/org/eclipse/moquette/parser/netty/Utils.java +++ b/netty_parser/src/main/java/org/eclipse/moquette/parser/netty/Utils.java @@ -117,10 +117,16 @@ public class Utils { * @return the decoded string or null if NEED_DATA */ static String decodeString(ByteBuf in) throws UnsupportedEncodingException { + return new String(readFixedLengthContent(in), "UTF-8"); + } + + /** + * Read a byte array from the buffer, use two bytes as length information followed by length bytes. + * */ + static byte[] readFixedLengthContent(ByteBuf in) throws UnsupportedEncodingException { if (in.readableBytes() < 2) { return null; } - //int strLen = Utils.readWord(in); int strLen = in.readUnsignedShort(); if (in.readableBytes() < strLen) { return null; @@ -128,16 +134,14 @@ public class Utils { byte[] strRaw = new byte[strLen]; in.readBytes(strRaw); - return new String(strRaw, "UTF-8"); + return strRaw; } - - + /** * Return the IoBuffer with string encoded as MSB, LSB and UTF-8 encoded * string content. */ public static ByteBuf encodeString(String str) { - ByteBuf out = Unpooled.buffer(2); byte[] raw; try { raw = str.getBytes("UTF-8"); @@ -147,12 +151,19 @@ public class Utils { LoggerFactory.getLogger(Utils.class).error(null, ex); return null; } - //Utils.writeWord(out, raw.length); - out.writeShort(raw.length); - out.writeBytes(raw); + return encodeFixedLengthContent(raw); + } + + /** + * Return the IoBuffer with string encoded as MSB, LSB and bytes array content. + */ + public static ByteBuf encodeFixedLengthContent(byte[] content) { + ByteBuf out = Unpooled.buffer(2); + out.writeShort(content.length); + out.writeBytes(content); return out; } - + /** * Return the number of bytes to encode the given remaining length value */ diff --git a/netty_parser/src/test/java/org/eclipse/moquette/parser/netty/ConnectDecoderTest.java b/netty_parser/src/test/java/org/eclipse/moquette/parser/netty/ConnectDecoderTest.java index 8a38dddb..f2ed0c14 100644 --- a/netty_parser/src/test/java/org/eclipse/moquette/parser/netty/ConnectDecoderTest.java +++ b/netty_parser/src/test/java/org/eclipse/moquette/parser/netty/ConnectDecoderTest.java @@ -142,7 +142,7 @@ public class ConnectDecoderTest { verifyBaseHeader(message); assertEquals("ABCDEFGH", message.getClientID()); assertEquals("Topic", message.getWillTopic()); - assertEquals("Message", message.getWillMessage()); + assertEquals("Message", new String(message.getWillMessage())); } @@ -167,9 +167,9 @@ public class ConnectDecoderTest { assertEquals(AbstractMessage.CONNECT, message.getMessageType()); assertEquals("ABCDEFGH", message.getClientID()); assertEquals("Topic", message.getWillTopic()); - assertEquals("Message", message.getWillMessage()); + assertEquals("Message", new String(message.getWillMessage())); assertEquals("Fakeuser", message.getUsername()); - assertEquals("pwd", message.getPassword()); + assertEquals("pwd", new String(message.getPassword())); } @Test(expected = CorruptedFrameException.class) diff --git a/netty_parser/src/test/java/org/eclipse/moquette/parser/netty/ConnectEncoderTest.java b/netty_parser/src/test/java/org/eclipse/moquette/parser/netty/ConnectEncoderTest.java index 4b702b2c..a41d9d58 100644 --- a/netty_parser/src/test/java/org/eclipse/moquette/parser/netty/ConnectEncoderTest.java +++ b/netty_parser/src/test/java/org/eclipse/moquette/parser/netty/ConnectEncoderTest.java @@ -75,7 +75,7 @@ public class ConnectEncoderTest { //variable part msg.setClientID("ABCDEF"); msg.setWillTopic("Topic"); - msg.setWillMessage("Message"); + msg.setWillMessage("Message".getBytes()); ByteBuf out = Unpooled.buffer(); @@ -111,9 +111,9 @@ public class ConnectEncoderTest { //variable part msg.setClientID("ABCDEF"); msg.setWillTopic("Topic"); - msg.setWillMessage("Message"); + msg.setWillMessage("Message".getBytes()); msg.setUsername("Pablo"); - msg.setPassword("PBL"); + msg.setPassword("PBL".getBytes()); ByteBuf out = Unpooled.buffer(); diff --git a/parser_commons/src/main/java/org/eclipse/moquette/proto/messages/ConnectMessage.java b/parser_commons/src/main/java/org/eclipse/moquette/proto/messages/ConnectMessage.java index d88c923d..fc1884ff 100644 --- a/parser_commons/src/main/java/org/eclipse/moquette/proto/messages/ConnectMessage.java +++ b/parser_commons/src/main/java/org/eclipse/moquette/proto/messages/ConnectMessage.java @@ -35,10 +35,10 @@ public class ConnectMessage extends AbstractMessage { //Variable part protected String m_username; - protected String m_password; + protected byte[] m_password; protected String m_clientID; protected String m_willtopic; - protected String m_willMessage; + protected byte[] m_willMessage; public ConnectMessage() { m_messageType = AbstractMessage.CONNECT; @@ -116,11 +116,11 @@ public class ConnectMessage extends AbstractMessage { this.m_willRetain = willRetain; } - public String getPassword() { + public byte[] getPassword() { return m_password; } - public void setPassword(String password) { + public void setPassword(byte[] password) { this.m_password = password; } @@ -148,11 +148,11 @@ public class ConnectMessage extends AbstractMessage { this.m_willtopic = topic; } - public String getWillMessage() { + public byte[] getWillMessage() { return m_willMessage; } - public void setWillMessage(String willMessage) { + public void setWillMessage(byte[] willMessage) { this.m_willMessage = willMessage; }