SessionRegistry sessions = new SessionRegistry(subscriptions, queueRepository, authorizator); dispatcher = new PostOffice(subscriptions, retainedRepository, sessions, interceptor, authorizator); final BrokerConfiguration brokerConfig = new BrokerConfiguration(config); MQTTConnectionFactory connectionFactory = new MQTTConnectionFactory(brokerConfig, authenticator, sessions, dispatcher);
private boolean login(MqttConnectMessage msg, final String clientId) { // handle user authentication if (msg.variableHeader().hasUserName()) { byte[] pwd = null; if (msg.variableHeader().hasPassword()) { pwd = msg.payload().password().getBytes(StandardCharsets.UTF_8); } else if (!brokerConfig.isAllowAnonymous()) { LOG.error("Client didn't supply any password and MQTT anonymous mode is disabled CId={}", clientId); return false; } final String login = msg.payload().userName(); if (!authenticator.checkValid(clientId, login, pwd)) { LOG.error("Authenticator has rejected the MQTT credentials CId={}, username={}", clientId, login); return false; } NettyUtils.userName(channel, login); } else if (!brokerConfig.isAllowAnonymous()) { LOG.error("Client didn't supply any credentials and MQTT anonymous mode is disabled. CId={}", clientId); return false; } return true; }
if (!brokerConfig.isAllowZeroByteClientId()) { LOG.warn("Broker doesn't permit MQTT empty client ID. Username: {}, channel: {}", username, channel); abortConnection(CONNECTION_REFUSED_IDENTIFIER_REJECTED);
@Before public void setUp() { connMsg = MqttMessageBuilders.connect().protocolVersion(MqttVersion.MQTT_3_1).cleanSession(true); BrokerConfiguration config = new BrokerConfiguration(true, true, false); createMQTTConnection(config); }
@Test public void prohibitAnonymousClient() { MqttConnectMessage msg = connMsg.clientId(FAKE_CLIENT_ID).build(); BrokerConfiguration config = new BrokerConfiguration(false, true, false); sut = createMQTTConnection(config); channel = (EmbeddedChannel) sut.channel; // Exercise sut.processConnect(msg); // Verify assertEqualsConnAck(CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD, channel.readOutbound()); assertFalse("Connection must be closed by the broker", channel.isOpen()); }
@Test public void prohibitAnonymousClient_providingUsername() { MqttConnectMessage msg = connMsg.clientId(FAKE_CLIENT_ID) .username(TEST_USER + "_fake") .build(); BrokerConfiguration config = new BrokerConfiguration(false, true, false); createMQTTConnection(config); // Exercise sut.processConnect(msg); // Verify assertEqualsConnAck(CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD, channel.readOutbound()); assertFalse("Connection should be closed by the broker.", channel.isOpen()); }
@Test public void testZeroByteClientIdNotAllowed() { BrokerConfiguration config = new BrokerConfiguration(false, false, false); sut = createMQTTConnection(config); channel = (EmbeddedChannel) sut.channel; // Connect message with clean session set to true and client id is null. MqttConnectMessage msg = connMsg.clientId(null) .protocolVersion(MqttVersion.MQTT_3_1_1) .cleanSession(true) .build(); sut.processConnect(msg); assertEqualsConnAck("Zero byte client identifiers are not allowed", CONNECTION_REFUSED_IDENTIFIER_REJECTED, channel.readOutbound()); assertFalse("Connection must closed", channel.isOpen()); }
@Test public void testBindWithSameClientIDBadCredentialsDoesntDropExistingClient() { // Connect a client1 MqttConnectMessage msg = connMsg.clientId(FAKE_CLIENT_ID) .username(TEST_USER) .password(TEST_PWD) .build(); sut.processConnect(msg); assertEqualsConnAck(CONNECTION_ACCEPTED, channel.readOutbound()); // create another connect same clientID but with bad credentials MqttConnectMessage evilClientConnMsg = MqttMessageBuilders.connect() .protocolVersion(MqttVersion.MQTT_3_1) .clientId(FAKE_CLIENT_ID) .username(EVIL_TEST_USER) .password(EVIL_TEST_PWD) .build(); EmbeddedChannel evilChannel = new EmbeddedChannel(); // Exercise BrokerConfiguration config = new BrokerConfiguration(true, true, false); final MQTTConnection evilConnection = createMQTTConnection(config, evilChannel, postOffice); evilConnection.processConnect(evilClientConnMsg); // Verify // the evil client gets a not auth notification assertEqualsConnAck(CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD, evilChannel.readOutbound()); // the good client remains connected assertTrue("Original connected client must remain connected", channel.isOpen()); assertFalse("Channel trying to connect with bad credentials must be closed", evilChannel.isOpen()); }