This commit is contained in:
@@ -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/
|
||||
|
||||
@@ -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
|
||||
|
||||
+2
-2
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ class ProtocolProcessor implements EventHandler<ValueEvent> {
|
||||
|
||||
//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<ValueEvent> {
|
||||
//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 );
|
||||
|
||||
+1
-1
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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());
|
||||
|
||||
|
||||
@@ -25,13 +25,13 @@ import org.eclipse.moquette.spi.impl.security.IAuthenticator;
|
||||
*/
|
||||
class MockAuthenticator implements IAuthenticator {
|
||||
|
||||
private Map<String, String> m_userPwds;
|
||||
private Map<String, byte[]> m_userPwds;
|
||||
|
||||
MockAuthenticator(Map<String, String> userPwds) {
|
||||
MockAuthenticator(Map<String, byte[]> 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;
|
||||
}
|
||||
|
||||
@@ -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<InterceptHandler> 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<String, String> users = new HashMap<>();
|
||||
Map<String, byte[]> 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
|
||||
|
||||
+3
-3
@@ -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()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -65,12 +65,12 @@ public class ConnectEncoder extends DemuxEncoder<ConnectMessage> {
|
||||
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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
+3
-3
@@ -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)
|
||||
|
||||
+3
-3
@@ -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();
|
||||
|
||||
|
||||
+6
-6
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user