Changed willMessage and password in CONNECT message from String to byte[] (fix issue #94 and #95)

This commit is contained in:
andsel
2015-09-16 23:25:15 +02:00
parent 9a7ec7fd62
commit e08cf95135
18 changed files with 58 additions and 49 deletions
+1
View File
@@ -35,3 +35,4 @@ broker/runner
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid* hs_err_pid*
broker/moquette_store.* broker/moquette_store.*
embedding_moquette/target/
+1
View File
@@ -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 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) 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) 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: Version 0.7:
Fix issue #38, added aligned to MQTT 3.1.1 Fix issue #38, added aligned to MQTT 3.1.1
@@ -57,7 +57,7 @@ public class InterceptConnectMessage extends InterceptAbstractMessage {
return msg.getUsername(); return msg.getUsername();
} }
public String getPassword() { public byte[] getPassword() {
return msg.getPassword(); return msg.getPassword();
} }
@@ -65,7 +65,7 @@ public class InterceptConnectMessage extends InterceptAbstractMessage {
return msg.getWillTopic(); return msg.getWillTopic();
} }
public String getWillMessage() { public byte[] getWillMessage() {
return msg.getWillMessage(); return msg.getWillMessage();
} }
} }
@@ -177,7 +177,7 @@ class ProtocolProcessor implements EventHandler<ValueEvent> {
//handle user authentication //handle user authentication
if (msg.isUserFlag()) { if (msg.isUserFlag()) {
String pwd = null; byte[] pwd = null;
if (msg.isPasswordFlag()) { if (msg.isPasswordFlag()) {
pwd = msg.getPassword(); pwd = msg.getPassword();
} else if (!this.allowAnonymous) { } else if (!this.allowAnonymous) {
@@ -225,7 +225,7 @@ class ProtocolProcessor implements EventHandler<ValueEvent> {
//Handle will flag //Handle will flag
if (msg.isWillFlag()) { if (msg.isWillFlag()) {
AbstractMessage.QOSType willQos = AbstractMessage.QOSType.values()[msg.getWillQos()]; 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(); ByteBuffer bb = (ByteBuffer) ByteBuffer.allocate(willPayload.length).put(willPayload).flip();
//save the will testament in the clientID store //save the will testament in the clientID store
WillMessage will = new WillMessage(msg.getWillTopic(), bb, msg.isWillRetain(),willQos ); WillMessage will = new WillMessage(msg.getWillTopic(), bb, msg.isWillRetain(),willQos );
@@ -4,7 +4,7 @@ package org.eclipse.moquette.spi.impl.security;
* Created by andrea on 8/23/14. * Created by andrea on 8/23/14.
*/ */
public class AcceptAllAuthenticator implements IAuthenticator { public class AcceptAllAuthenticator implements IAuthenticator {
public boolean checkValid(String username, String password) { public boolean checkValid(String username, byte[] password) {
return true; 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) { if (username == null || password == null) {
LOG.info("username or password was null"); LOG.info("username or password was null");
return false; return false;
@@ -115,11 +115,7 @@ public class FileAuthenticator implements IAuthenticator {
if (foundPwq == null) { if (foundPwq == null) {
return false; return false;
} }
try { m_digest.update(password);
m_digest.update(password.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
byte[] digest = m_digest.digest(); byte[] digest = m_digest.digest();
String encodedPasswd = new String(Hex.encodeHex(digest)); String encodedPasswd = new String(Hex.encodeHex(digest));
return foundPwq.equals(encodedPasswd); return foundPwq.equals(encodedPasswd);
@@ -22,5 +22,5 @@ package org.eclipse.moquette.spi.impl.security;
*/ */
public interface IAuthenticator { 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 @Override
public boolean checkValid(String username, String password) { public boolean checkValid(String username, byte[] password) {
return true; return true;
} }
@@ -111,7 +111,7 @@ public class ServerLowlevelMessagesIntegrationTests {
connectMessage.setClientID("FAKECLNT"); connectMessage.setClientID("FAKECLNT");
connectMessage.setKeepAlive(keepAlive); connectMessage.setKeepAlive(keepAlive);
connectMessage.setWillFlag(true); connectMessage.setWillFlag(true);
connectMessage.setWillMessage(willTestamentMsg); connectMessage.setWillMessage(willTestamentMsg.getBytes());
connectMessage.setWillTopic(willTestamentTopic); connectMessage.setWillTopic(willTestamentTopic);
connectMessage.setWillQos((byte) QOSType.MOST_ONE.ordinal()); connectMessage.setWillQos((byte) QOSType.MOST_ONE.ordinal());
@@ -25,13 +25,13 @@ import org.eclipse.moquette.spi.impl.security.IAuthenticator;
*/ */
class MockAuthenticator implements 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; m_userPwds = userPwds;
} }
public boolean checkValid(String username, String password) { public boolean checkValid(String username, byte[] password) {
if (!m_userPwds.containsKey(username)) { if (!m_userPwds.containsKey(username)) {
return false; return false;
} }
@@ -52,9 +52,9 @@ public class ProtocolProcessorTest {
final static String BAD_FORMATTED_TOPIC = "#MQTTClient"; final static String BAD_FORMATTED_TOPIC = "#MQTTClient";
final static String TEST_USER = "fakeuser"; 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_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 List<InterceptHandler> EMPTY_OBSERVERS = Collections.emptyList();
final static BrokerInterceptor NO_OBSERVERS_INTERCEPTOR = new BrokerInterceptor(EMPTY_OBSERVERS); final static BrokerInterceptor NO_OBSERVERS_INTERCEPTOR = new BrokerInterceptor(EMPTY_OBSERVERS);
@@ -164,7 +164,7 @@ public class ProtocolProcessorTest {
m_sessionStore = memStorage; m_sessionStore = memStorage;
//m_storageService.initStore(); //m_storageService.initStore();
Map<String, String> users = new HashMap<>(); Map<String, byte[]> users = new HashMap<>();
users.put(TEST_USER, TEST_PWD); users.put(TEST_USER, TEST_PWD);
m_mockAuthenticator = new MockAuthenticator(users); m_mockAuthenticator = new MockAuthenticator(users);
@@ -202,7 +202,7 @@ public class ProtocolProcessorTest {
connMsg.setClientID("123"); connMsg.setClientID("123");
connMsg.setWillFlag(true); connMsg.setWillFlag(true);
connMsg.setWillTopic("topic"); connMsg.setWillTopic("topic");
connMsg.setWillMessage("Topic message"); connMsg.setWillMessage("Topic message".getBytes());
//Exercise //Exercise
@@ -31,7 +31,7 @@ public class FileAuthenticatorTest {
String file = getClass().getResource("/password_file.conf").getPath(); String file = getClass().getResource("/password_file.conf").getPath();
IAuthenticator auth = new FileAuthenticator(null, file); IAuthenticator auth = new FileAuthenticator(null, file);
assertTrue(auth.checkValid("testuser", "passwd")); assertTrue(auth.checkValid("testuser", "passwd".getBytes()));
} }
@Test @Test
@@ -39,14 +39,14 @@ public class FileAuthenticatorTest {
String file = getClass().getResource("/password_file.conf").getPath(); String file = getClass().getResource("/password_file.conf").getPath();
IAuthenticator auth = new FileAuthenticator(null, file); IAuthenticator auth = new FileAuthenticator(null, file);
assertFalse(auth.checkValid("testuser2", "passwd")); assertFalse(auth.checkValid("testuser2", "passwd".getBytes()));
} }
@Test @Test
public void loadPasswordFile_verifyDirectoryRef() { public void loadPasswordFile_verifyDirectoryRef() {
IAuthenticator auth = new FileAuthenticator("", ""); 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 //Decode willMessage
if (willFlag) { if (willFlag) {
String willMessage = Utils.decodeString(in); byte[] willMessage = Utils.readFixedLengthContent(in);
if (willMessage == null) { if (willMessage == null) {
in.resetReaderIndex(); in.resetReaderIndex();
return; return;
@@ -207,7 +207,7 @@ public class ConnectDecoder extends DemuxDecoder {
//Decode password //Decode password
if (passwordFlag) { if (passwordFlag) {
String password = Utils.decodeString(in); byte[] password = Utils.readFixedLengthContent(in);
if (password == null) { if (password == null) {
in.resetReaderIndex(); in.resetReaderIndex();
return; return;
@@ -65,12 +65,12 @@ public class ConnectEncoder extends DemuxEncoder<ConnectMessage> {
variableHeaderBuff.writeBytes(Utils.encodeString(message.getClientID())); variableHeaderBuff.writeBytes(Utils.encodeString(message.getClientID()));
if (message.isWillFlag()) { if (message.isWillFlag()) {
variableHeaderBuff.writeBytes(Utils.encodeString(message.getWillTopic())); variableHeaderBuff.writeBytes(Utils.encodeString(message.getWillTopic()));
variableHeaderBuff.writeBytes(Utils.encodeString(message.getWillMessage())); variableHeaderBuff.writeBytes(Utils.encodeFixedLengthContent(message.getWillMessage()));
} }
if (message.isUserFlag() && message.getUsername() != null) { if (message.isUserFlag() && message.getUsername() != null) {
variableHeaderBuff.writeBytes(Utils.encodeString(message.getUsername())); variableHeaderBuff.writeBytes(Utils.encodeString(message.getUsername()));
if (message.isPasswordFlag() && message.getPassword() != null) { 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 * @return the decoded string or null if NEED_DATA
*/ */
static String decodeString(ByteBuf in) throws UnsupportedEncodingException { 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) { if (in.readableBytes() < 2) {
return null; return null;
} }
//int strLen = Utils.readWord(in);
int strLen = in.readUnsignedShort(); int strLen = in.readUnsignedShort();
if (in.readableBytes() < strLen) { if (in.readableBytes() < strLen) {
return null; return null;
@@ -128,16 +134,14 @@ public class Utils {
byte[] strRaw = new byte[strLen]; byte[] strRaw = new byte[strLen];
in.readBytes(strRaw); in.readBytes(strRaw);
return new String(strRaw, "UTF-8"); return strRaw;
} }
/** /**
* Return the IoBuffer with string encoded as MSB, LSB and UTF-8 encoded * Return the IoBuffer with string encoded as MSB, LSB and UTF-8 encoded
* string content. * string content.
*/ */
public static ByteBuf encodeString(String str) { public static ByteBuf encodeString(String str) {
ByteBuf out = Unpooled.buffer(2);
byte[] raw; byte[] raw;
try { try {
raw = str.getBytes("UTF-8"); raw = str.getBytes("UTF-8");
@@ -147,12 +151,19 @@ public class Utils {
LoggerFactory.getLogger(Utils.class).error(null, ex); LoggerFactory.getLogger(Utils.class).error(null, ex);
return null; return null;
} }
//Utils.writeWord(out, raw.length); return encodeFixedLengthContent(raw);
out.writeShort(raw.length); }
out.writeBytes(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 out;
} }
/** /**
* Return the number of bytes to encode the given remaining length value * Return the number of bytes to encode the given remaining length value
*/ */
@@ -142,7 +142,7 @@ public class ConnectDecoderTest {
verifyBaseHeader(message); verifyBaseHeader(message);
assertEquals("ABCDEFGH", message.getClientID()); assertEquals("ABCDEFGH", message.getClientID());
assertEquals("Topic", message.getWillTopic()); 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(AbstractMessage.CONNECT, message.getMessageType());
assertEquals("ABCDEFGH", message.getClientID()); assertEquals("ABCDEFGH", message.getClientID());
assertEquals("Topic", message.getWillTopic()); assertEquals("Topic", message.getWillTopic());
assertEquals("Message", message.getWillMessage()); assertEquals("Message", new String(message.getWillMessage()));
assertEquals("Fakeuser", message.getUsername()); assertEquals("Fakeuser", message.getUsername());
assertEquals("pwd", message.getPassword()); assertEquals("pwd", new String(message.getPassword()));
} }
@Test(expected = CorruptedFrameException.class) @Test(expected = CorruptedFrameException.class)
@@ -75,7 +75,7 @@ public class ConnectEncoderTest {
//variable part //variable part
msg.setClientID("ABCDEF"); msg.setClientID("ABCDEF");
msg.setWillTopic("Topic"); msg.setWillTopic("Topic");
msg.setWillMessage("Message"); msg.setWillMessage("Message".getBytes());
ByteBuf out = Unpooled.buffer(); ByteBuf out = Unpooled.buffer();
@@ -111,9 +111,9 @@ public class ConnectEncoderTest {
//variable part //variable part
msg.setClientID("ABCDEF"); msg.setClientID("ABCDEF");
msg.setWillTopic("Topic"); msg.setWillTopic("Topic");
msg.setWillMessage("Message"); msg.setWillMessage("Message".getBytes());
msg.setUsername("Pablo"); msg.setUsername("Pablo");
msg.setPassword("PBL"); msg.setPassword("PBL".getBytes());
ByteBuf out = Unpooled.buffer(); ByteBuf out = Unpooled.buffer();
@@ -35,10 +35,10 @@ public class ConnectMessage extends AbstractMessage {
//Variable part //Variable part
protected String m_username; protected String m_username;
protected String m_password; protected byte[] m_password;
protected String m_clientID; protected String m_clientID;
protected String m_willtopic; protected String m_willtopic;
protected String m_willMessage; protected byte[] m_willMessage;
public ConnectMessage() { public ConnectMessage() {
m_messageType = AbstractMessage.CONNECT; m_messageType = AbstractMessage.CONNECT;
@@ -116,11 +116,11 @@ public class ConnectMessage extends AbstractMessage {
this.m_willRetain = willRetain; this.m_willRetain = willRetain;
} }
public String getPassword() { public byte[] getPassword() {
return m_password; return m_password;
} }
public void setPassword(String password) { public void setPassword(byte[] password) {
this.m_password = password; this.m_password = password;
} }
@@ -148,11 +148,11 @@ public class ConnectMessage extends AbstractMessage {
this.m_willtopic = topic; this.m_willtopic = topic;
} }
public String getWillMessage() { public byte[] getWillMessage() {
return m_willMessage; return m_willMessage;
} }
public void setWillMessage(String willMessage) { public void setWillMessage(byte[] willMessage) {
this.m_willMessage = willMessage; this.m_willMessage = willMessage;
} }