Merge pull request #185 from bemisguided/master

Add clientID to the IAuthenticator interface
This commit is contained in:
Andrea Selva
2016-06-28 13:08:22 +02:00
committed by GitHub
11 changed files with 51 additions and 37 deletions
@@ -58,7 +58,7 @@ import org.slf4j.LoggerFactory;
/**
* Class responsible to handle the logic of MQTT protocol it's the director of
* the protocol execution.
* the protocol execution.
*
* Used by the front facing class SimpleMessaging.
*
@@ -167,7 +167,7 @@ public class ProtocolProcessor {
failedCredentials(channel);
return;
}
if (!m_authenticator.checkValid(msg.getUsername(), pwd)) {
if (!m_authenticator.checkValid(msg.getClientID(), msg.getUsername(), pwd)) {
failedCredentials(channel);
channel.close();
return;
@@ -6,7 +6,7 @@ import io.moquette.spi.security.IAuthenticator;
* Created by andrea on 8/23/14.
*/
public class AcceptAllAuthenticator implements IAuthenticator {
public boolean checkValid(String username, byte[] password) {
public boolean checkValid(String clientId, String username, byte[] password) {
return true;
}
}
@@ -63,7 +63,7 @@ public class DBAuthenticator implements IAuthenticator {
}
@Override
public synchronized boolean checkValid(String username, byte[] password) {
public synchronized boolean checkValid(String clientId, String username, byte[] password) {
// Check Username / Password in DB using sqlQuery
if (username == null || password == null) {
LOG.info("username or password was null");
@@ -106,8 +106,9 @@ public class FileAuthenticator implements IAuthenticator {
throw new ParseException("Failed to read", 1);
}
}
public boolean checkValid(String username, byte[] password) {
@Override
public boolean checkValid(String clientId, String username, byte[] password) {
if (username == null || password == null) {
LOG.info("username or password was null");
return false;
@@ -22,5 +22,5 @@ package io.moquette.spi.security;
*/
public interface IAuthenticator {
boolean checkValid(String username, byte[] password);
boolean checkValid(String clientId, String username, byte[] password);
}
@@ -72,7 +72,7 @@ public class ConfigurationClassLoaderTest implements IAuthenticator, IAuthorizat
}
@Override
public boolean checkValid(String username, byte[] password) {
public boolean checkValid(String clientID, String username, byte[] password) {
return true;
}
@@ -16,6 +16,7 @@
package io.moquette.spi.impl;
import java.util.Map;
import java.util.Set;
import io.moquette.spi.security.IAuthenticator;
@@ -25,14 +26,19 @@ import io.moquette.spi.security.IAuthenticator;
* @author andrea
*/
class MockAuthenticator implements IAuthenticator {
private Set<String> m_clientIds;
private Map<String, byte[]> m_userPwds;
MockAuthenticator(Map<String, byte[]> userPwds) {
MockAuthenticator(Set<String> clientIds, Map<String, byte[]> userPwds) {
m_clientIds = clientIds;
m_userPwds = userPwds;
}
public boolean checkValid(String username, byte[] password) {
public boolean checkValid(String clientId, String username, byte[] password) {
if (!m_clientIds.contains(clientId)) {
return false;
}
if (!m_userPwds.containsKey(username)) {
return false;
}
@@ -83,10 +83,13 @@ public class ProtocolProcessorTest {
m_messagesStore = memStorage.messagesStore();
m_sessionStore = memStorage.sessionsStore();
//m_messagesStore.initStore();
Set<String> clientIds = new HashSet<>();
clientIds.add(FAKE_CLIENT_ID);
clientIds.add(FAKE_CLIENT_ID2);
Map<String, byte[]> users = new HashMap<>();
users.put(TEST_USER, TEST_PWD);
m_mockAuthenticator = new MockAuthenticator(users);
m_mockAuthenticator = new MockAuthenticator(clientIds, users);
subscriptions = new SubscriptionsStore();
subscriptions.init(memStorage.sessionsStore());
@@ -30,7 +30,9 @@ import org.junit.Before;
import org.junit.Test;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import static io.moquette.parser.netty.Utils.VERSION_3_1_1;
import static io.moquette.parser.proto.messages.ConnAckMessage.BAD_USERNAME_OR_PASSWORD;
@@ -71,9 +73,11 @@ public class ProtocolProcessor_CONNECT_Test {
m_sessionStore = memStorage.sessionsStore();
//m_messagesStore.initStore();
Set<String> clientIds = new HashSet<>();
clientIds.add(ProtocolProcessorTest.FAKE_CLIENT_ID);
Map<String, byte[]> users = new HashMap<>();
users.put(ProtocolProcessorTest.TEST_USER, ProtocolProcessorTest.TEST_PWD);
m_mockAuthenticator = new MockAuthenticator(users);
m_mockAuthenticator = new MockAuthenticator(clientIds, users);
subscriptions = new SubscriptionsStore();
subscriptions.init(m_sessionStore);
@@ -106,7 +110,7 @@ public class ProtocolProcessor_CONNECT_Test {
@Test
public void testWill() {
connMsg.setClientID("123");
connMsg.setClientID(ProtocolProcessorTest.FAKE_CLIENT_ID);
connMsg.setWillFlag(true);
connMsg.setWillTopic("topic");
connMsg.setWillMessage("Topic message".getBytes());
@@ -125,7 +129,7 @@ public class ProtocolProcessor_CONNECT_Test {
@Test
public void validAuthentication() {
connMsg.setClientID("123");
connMsg.setClientID(ProtocolProcessorTest.FAKE_CLIENT_ID);
connMsg.setUserFlag(true);
connMsg.setPasswordFlag(true);
connMsg.setUsername(ProtocolProcessorTest.TEST_USER);
@@ -140,7 +144,7 @@ public class ProtocolProcessor_CONNECT_Test {
@Test
public void noPasswdAuthentication() {
connMsg.setClientID("123");
connMsg.setClientID(ProtocolProcessorTest.FAKE_CLIENT_ID);
connMsg.setUserFlag(true);
connMsg.setPasswordFlag(false);
connMsg.setUsername(ProtocolProcessorTest.TEST_USER);
@@ -154,7 +158,7 @@ public class ProtocolProcessor_CONNECT_Test {
@Test
public void invalidAuthentication() {
connMsg.setClientID("123");
connMsg.setClientID(ProtocolProcessorTest.FAKE_CLIENT_ID);
connMsg.setUserFlag(true);
connMsg.setPasswordFlag(true);
connMsg.setUsername(ProtocolProcessorTest.TEST_USER + "_fake");
@@ -169,7 +173,7 @@ public class ProtocolProcessor_CONNECT_Test {
@Test
public void prohibitAnonymousClient() {
connMsg.setClientID("123");
connMsg.setClientID(ProtocolProcessorTest.FAKE_CLIENT_ID);
m_processor.init(subscriptions, m_messagesStore, m_sessionStore, m_mockAuthenticator, false,
new PermitAllAuthorizator(), ProtocolProcessorTest.NO_OBSERVERS_INTERCEPTOR);
@@ -182,7 +186,7 @@ public class ProtocolProcessor_CONNECT_Test {
@Test
public void prohibitAnonymousClient_providingUsername() {
connMsg.setClientID("123");
connMsg.setClientID(ProtocolProcessorTest.FAKE_CLIENT_ID);
connMsg.setUserFlag(true);
connMsg.setUsername(ProtocolProcessorTest.TEST_USER + "_fake");
m_processor.init(subscriptions, m_messagesStore, m_sessionStore, m_mockAuthenticator, false,
@@ -197,7 +201,7 @@ public class ProtocolProcessor_CONNECT_Test {
@Test
public void acceptAnonymousClient() {
connMsg.setClientID("123");
connMsg.setClientID(ProtocolProcessorTest.FAKE_CLIENT_ID);
m_processor.init(subscriptions, m_messagesStore, m_sessionStore, m_mockAuthenticator, true,
new PermitAllAuthorizator(), ProtocolProcessorTest.NO_OBSERVERS_INTERCEPTOR);
@@ -214,7 +218,7 @@ public class ProtocolProcessor_CONNECT_Test {
new PermitAllAuthorizator(), ProtocolProcessorTest.NO_OBSERVERS_INTERCEPTOR);
//first connect with clean session true
connMsg.setClientID("123");
connMsg.setClientID(ProtocolProcessorTest.FAKE_CLIENT_ID);
connMsg.setCleanSession(true);
m_processor.processConnect(m_session, connMsg);
assertEqualsConnAck(CONNECTION_ACCEPTED, m_session.readOutbound());
@@ -225,12 +229,12 @@ public class ProtocolProcessor_CONNECT_Test {
m_session = new EmbeddedChannel();
ConnectMessage secondConnMsg = new ConnectMessage();
secondConnMsg.setProtocolVersion((byte) 0x03);
secondConnMsg.setClientID("123");
secondConnMsg.setClientID(ProtocolProcessorTest.FAKE_CLIENT_ID);
m_processor.processConnect(m_session, secondConnMsg);
assertEqualsConnAck(CONNECTION_ACCEPTED, m_session.readOutbound());
//Verify client session is clean false
ClientSession session = m_sessionStore.sessionForClient("123");
ClientSession session = m_sessionStore.sessionForClient(ProtocolProcessorTest.FAKE_CLIENT_ID);
assertFalse(session.isCleanSession());
//Verify
@@ -240,7 +244,7 @@ public class ProtocolProcessor_CONNECT_Test {
@Test
public void connectWithSameClientIDBadCredentialsDoesntDropExistingClient() {
//Connect a client1
connMsg.setClientID("Client1");
connMsg.setClientID(ProtocolProcessorTest.FAKE_CLIENT_ID);
connMsg.setUserFlag(true);
connMsg.setPasswordFlag(true);
connMsg.setUsername(ProtocolProcessorTest.TEST_USER);
@@ -251,7 +255,7 @@ public class ProtocolProcessor_CONNECT_Test {
//create another connect same clientID but with bad credentials
ConnectMessage evilClientConnMsg = new ConnectMessage();
evilClientConnMsg.setProtocolVersion((byte) 0x03);
evilClientConnMsg.setClientID("Client1");
evilClientConnMsg.setClientID(ProtocolProcessorTest.FAKE_CLIENT_ID);
evilClientConnMsg.setUserFlag(true);
evilClientConnMsg.setPasswordFlag(true);
evilClientConnMsg.setUsername(ProtocolProcessorTest.EVIL_TEST_USER);
@@ -274,9 +278,9 @@ public class ProtocolProcessor_CONNECT_Test {
public void testConnAckContainsSessionPresentFlag() throws InterruptedException {
connMsg = new ConnectMessage();
connMsg.setProtocolVersion(VERSION_3_1_1);
connMsg.setClientID("CliID");
connMsg.setClientID(ProtocolProcessorTest.FAKE_CLIENT_ID);
connMsg.setCleanSession(false);
NettyUtils.clientID(m_session, "CliID");
NettyUtils.clientID(m_session, ProtocolProcessorTest.FAKE_CLIENT_ID);
NettyUtils.cleanSession(m_session, false);
//Connect a first time
@@ -298,7 +302,7 @@ public class ProtocolProcessor_CONNECT_Test {
//connect with clean a false and subscribe to a topic
connMsg = new ConnectMessage();
connMsg.setProtocolVersion(VERSION_3_1_1);
connMsg.setClientID("CliID");
connMsg.setClientID(ProtocolProcessorTest.FAKE_CLIENT_ID);
connMsg.setCleanSession(false);
m_processor.processConnect(m_session, connMsg);
assertEqualsConnAck(CONNECTION_ACCEPTED, m_session.readOutbound());
@@ -307,10 +311,10 @@ public class ProtocolProcessor_CONNECT_Test {
SubscribeMessage subscribeMsg = new SubscribeMessage();
subscribeMsg.addSubscription(new SubscribeMessage.Couple((byte) AbstractMessage.QOSType.MOST_ONE.ordinal(),
ProtocolProcessorTest.FAKE_TOPIC));
NettyUtils.clientID(m_session, "CliID");
NettyUtils.clientID(m_session, ProtocolProcessorTest.FAKE_CLIENT_ID);
NettyUtils.cleanSession(m_session, false);
m_processor.processSubscribe(m_session, subscribeMsg);
Subscription expectedSubscription = new Subscription("CliID", ProtocolProcessorTest.FAKE_TOPIC,
Subscription expectedSubscription = new Subscription(ProtocolProcessorTest.FAKE_CLIENT_ID, ProtocolProcessorTest.FAKE_TOPIC,
AbstractMessage.QOSType.MOST_ONE);
assertTrue(subscriptions.contains(expectedSubscription));
assertEqualsSubAck(m_session.readOutbound());
@@ -57,19 +57,19 @@ public class DBAuthenticatorTest {
@Test
public void Db_verifyValid() {
final DBAuthenticator dbAuthenticator = new DBAuthenticator(ORG_H2_DRIVER, JDBC_H2_MEM_TEST, "SELECT PASSWORD FROM ACCOUNT WHERE LOGIN=?", SHA_256);
assertTrue(dbAuthenticator.checkValid("dbuser","password".getBytes()));
assertTrue(dbAuthenticator.checkValid(null, "dbuser","password".getBytes()));
}
@Test
public void Db_verifyInvalidLogin(){
final DBAuthenticator dbAuthenticator = new DBAuthenticator(ORG_H2_DRIVER, JDBC_H2_MEM_TEST, "SELECT PASSWORD FROM ACCOUNT WHERE LOGIN=?", SHA_256);
assertFalse(dbAuthenticator.checkValid("dbuser2","password".getBytes()));
assertFalse(dbAuthenticator.checkValid(null, "dbuser2","password".getBytes()));
}
@Test
public void Db_verifyInvalidPassword(){
final DBAuthenticator dbAuthenticator = new DBAuthenticator(ORG_H2_DRIVER, JDBC_H2_MEM_TEST, "SELECT PASSWORD FROM ACCOUNT WHERE LOGIN=?", SHA_256);
assertFalse(dbAuthenticator.checkValid("dbuser","wrongPassword".getBytes()));
assertFalse(dbAuthenticator.checkValid(null, "dbuser","wrongPassword".getBytes()));
}
@@ -32,7 +32,7 @@ public class FileAuthenticatorTest {
String file = getClass().getResource("/password_file.conf").getPath();
IAuthenticator auth = new FileAuthenticator(null, file);
assertTrue(auth.checkValid("testuser", "passwd".getBytes()));
assertTrue(auth.checkValid(null, "testuser", "passwd".getBytes()));
}
@Test
@@ -40,14 +40,14 @@ public class FileAuthenticatorTest {
String file = getClass().getResource("/password_file.conf").getPath();
IAuthenticator auth = new FileAuthenticator(null, file);
assertFalse(auth.checkValid("testuser2", "passwd".getBytes()));
assertFalse(auth.checkValid(null, "testuser2", "passwd".getBytes()));
}
@Test
public void loadPasswordFile_verifyDirectoryRef() {
IAuthenticator auth = new FileAuthenticator("", "");
assertFalse(auth.checkValid("testuser2", "passwd".getBytes()));
assertFalse(auth.checkValid(null, "testuser2", "passwd".getBytes()));
}
}