List of usage examples for io.netty.handler.codec.mqtt MqttConnectReturnCode CONNECTION_REFUSED_NOT_AUTHORIZED
MqttConnectReturnCode CONNECTION_REFUSED_NOT_AUTHORIZED
To view the source code for io.netty.handler.codec.mqtt MqttConnectReturnCode CONNECTION_REFUSED_NOT_AUTHORIZED.
Click Source Link
From source file:com.caricah.iotracah.core.handlers.ConnectionHandler.java
License:Apache License
/** * * 3.1.4 Response/* ww w .jav a 2 s . c o m*/ * <p> * Note that a Server MAY support multiple protocols (including earlier versions of this protocol) * on the same TCP port or other network endpoint. If the Server determines that the protocol is MQTT 3.1.1 * then it validates the connection attempt as follows. * <p> * 1. If the Server does not receive a CONNECT Packet within a reasonable amount of time after * the Network Connection is established, the Server SHOULD close the connection. * <p> * 2. The Server MUST validate that the CONNECT Packet conforms to section 3.1 and close * the Network Connection without sending a CONNACK if it does not conform [MQTT-3.1.4-1]. * <p> * 3. The Server MAY check that the contents of the CONNECT Packet meet any further restrictions * and MAY perform authentication and authorization checks. If any of these checks fail, * it SHOULD send an appropriate CONNACK response with a non-zero return code as described * in section 3.2 and it MUST close the Network Connection. * <p> * If validation is successful the Server performs the following steps. * <p> * 1. If the ClientId represents a Client already connected to the Server then * the Server MUST disconnect the existing Client [MQTT-3.1.4-2]. * 2. The Server MUST perform the processing of CleanSession that is described * in section 3.1.2.4 [MQTT-3.1.4-3]. * 3. The Server MUST acknowledge the CONNECT Packet with a CONNACK Packet * containing a zero return code [MQTT-3.1.4-4]. * 4. Start message delivery and keep alive monitoring. * <p> * Clients are allowed to send further Control Packets immediately after sending a CONNECT Packet; * Clients need not wait for a CONNACK Packet to arrive from the Server. If the Server rejects the CONNECT, * it MUST NOT process any data sent by the Client after the CONNECT Packet [MQTT-3.1.4-5]. * <p> * Non normative comment * Clients typically wait for a CONNACK Packet, * However, if the Client exploits its freedom to send Control Packets before it receives a CONNACK, * it might simplify the Client implementation as it does not have to police the connected state. * The Client accepts that any data that it sends before it receives a CONNACK packet from the * Server will not be processed if the Server rejects the connection. * * @return * @throws RetriableException * @throws UnRetriableException */ @Override public void handle(ConnectMessage connectMessage) throws RetriableException, UnRetriableException { log.debug(" handle : client initiating a new connection."); /** * 2. The Server MUST validate that the CONNECT Packet conforms to section 3.1 and close * the Network Connection without sending a CONNACK if it does not conform [MQTT-3.1.4-1]. * * 3.1[ The Server MUST process a second CONNECT Packet sent from a Client as a protocol * violation and disconnect the Client [MQTT-3.1.0-2]. See section 4.8 for information about handling errors.] * * */ try { if (!MqttVersion.MQTT_3_1_1.protocolName().equals(connectMessage.getProtocolName()) && !MqttVersion.MQTT_3_1.protocolName().equals(connectMessage.getProtocolName())) { /** * If the protocol name is incorrect the Server MAY disconnect the Client, * or it MAY continue processing the CONNECT packet in accordance with some other specification. * In the latter case, the Server MUST NOT continue to process the CONNECT packet in line with * this specification [MQTT-3.1.2-1]. * */ throw new UnknownProtocalException(); } if (MqttVersion.MQTT_3_1_1.protocolLevel() != connectMessage.getProtocalLevel() && MqttVersion.MQTT_3_1.protocolLevel() != connectMessage.getProtocalLevel()) { /** * The 8 bit unsigned value that represents the revision level of the protocol used by the Client. * The value of the Protocol Level field for the version 3.1.1 of the protocol is 4 (0x04). * The Server MUST respond to the CONNECT Packet with a CONNACK return code 0x01 (unacceptable protocol level) * and then disconnect the Client if the Protocol Level is not supported by the Server [MQTT-3.1.2-2]. */ throw new MqttUnacceptableProtocolVersionException(); } else { log.debug(" handle: the required protocal was selected."); } //TODO: The Server MUST validate that the reserved flag in the CONNECT Control Packet is set to zero and disconnect the Client if it is not zero [MQTT-3.1.2-3]. //We now proceed to openning a session on our core service interface. boolean cleanSession = connectMessage.isCleanSession(); /** * The Server MUST allow ClientIds which are between 1 and 23 UTF-8 encoded bytes in length, * and that contain only the characters * "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" [MQTT-3.1.3-5]. * * The Server MAY allow ClientIds that contain more than 23 encoded bytes. * The Server MAY allow ClientIds that contain characters not included in the list given above. * * * A Server MAY allow a Client to supply a ClientId that has a length of zero bytes, * however if it does so the Server MUST treat this as a special case and assign a unique ClientId to that Client. * It MUST then process the CONNECT packet as if the Client had provided that unique ClientId [MQTT-3.1.3-6]. * */ String clientIdentifier = connectMessage.getClientId(); /** * If the Client supplies a zero-byte ClientId, the Client MUST also set CleanSession to 1 [MQTT-3.1.3-7]. * * If the Client supplies a zero-byte ClientId with CleanSession set to 0, * the Server MUST respond to the CONNECT Packet with a CONNACK return code 0x02 (Identifier rejected) * and then close the Network Connection [MQTT-3.1.3-8]. */ if ((null == clientIdentifier || clientIdentifier.isEmpty())) { if (!cleanSession) { throw new MqttIdentifierRejectedException(); } } else { //Run a regular expression to check for invalid characters in our clientIdentifier. if (!pattern.matcher(clientIdentifier).matches()) { throw new MqttIdentifierRejectedException(); } } log.debug(" handle: we are ready now to obtain the core session."); Observable<IOTClient> newClientObservable = openSubject(connectMessage.getCluster(), connectMessage.getNodeId(), connectMessage.getConnectionId(), clientIdentifier, cleanSession, connectMessage.getUserName(), connectMessage.getPassword(), connectMessage.getKeepAliveTime(), connectMessage.getSourceHost(), connectMessage.getProtocol()); newClientObservable.subscribe( (iotSession) -> { log.debug(" handle: obtained a client session : {}. ", iotSession); /** * 3. The Server MAY check that the contents of the CONNECT Packet meet any further restrictions * and MAY perform authentication and authorization checks. If any of these checks fail, * it SHOULD send an appropriate CONNACK response with a non-zero return code as described * in section 3.2 and it MUST close the Network Connection. * */ //Respond to server with a connection successfull. ConnectAcknowledgeMessage connectAcknowledgeMessage = ConnectAcknowledgeMessage.from( connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_ACCEPTED); connectAcknowledgeMessage = iotSession.copyTransmissionData(connectAcknowledgeMessage); connectAcknowledgeMessage.setAuthKey(iotSession.getAuthKey()); pushToServer(connectAcknowledgeMessage); if (connectMessage.isHasWill()) { /** * If the Will Flag is set to 1 this indicates that, if the Connect request is accepted, * a Will Message MUST be stored on the Server and associated with the Network Connection. * The Will Message MUST be published when the Network Connection is subsequently closed unless * the Will Message has been deleted by the Server on receipt of a DISCONNECT Packet [MQTT-3.1.2-8]. */ PublishMessage publishMessage = PublishMessage.from(PublishMessage.ID_TO_SHOW_IS_WILL, false, connectMessage.getWillQos(), false, connectMessage.getWillTopic(), ByteBuffer.wrap(connectMessage.getWillMessage().getBytes()), false); publishMessage.setClientId(iotSession.getSessionId()); publishMessage.setSessionId(iotSession.getSessionId()); publishMessage.setPartitionId(iotSession.getPartitionId()); // We have the appropriate id's to save the will. getDatastore().saveWill(iotSession, publishMessage); log.debug(" handle: message has will : {} ", publishMessage); } else { //We need to clear the existing will if any. getDatastore().removeWill(iotSession); } //Perform a reset for our session. getWorker().getSessionResetManager().process(iotSession); }, (e) -> { log.error(" onError : Problems ", e); ConnectAcknowledgeMessage connectAcknowledgeMessage; if (e instanceof AuthenticationException) { connectAcknowledgeMessage = ConnectAcknowledgeMessage.from(connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD); } else if (e instanceof AuthorizationException) { connectAcknowledgeMessage = ConnectAcknowledgeMessage.from(connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED); } else { connectAcknowledgeMessage = ConnectAcknowledgeMessage.from(connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_SERVER_UNAVAILABLE); } connectAcknowledgeMessage.copyTransmissionData(connectMessage); pushToServer(connectAcknowledgeMessage); }, () -> { }); } catch (MqttUnacceptableProtocolVersionException | MqttIdentifierRejectedException | AuthenticationException | UnknownProtocalException e) { log.debug(" handle : Client connection issues ", e); //Respond to server with a connection unsuccessfull. ConnectAcknowledgeMessage connectAcknowledgeMessage; if (e instanceof MqttIdentifierRejectedException) { connectAcknowledgeMessage = ConnectAcknowledgeMessage.from(connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_IDENTIFIER_REJECTED); } else if (e instanceof MqttUnacceptableProtocolVersionException) { connectAcknowledgeMessage = ConnectAcknowledgeMessage.from(connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_UNACCEPTABLE_PROTOCOL_VERSION); } else if (e instanceof UnknownProtocalException) { connectAcknowledgeMessage = ConnectAcknowledgeMessage.from(connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_UNACCEPTABLE_PROTOCOL_VERSION); } else { connectAcknowledgeMessage = ConnectAcknowledgeMessage.from(connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_SERVER_UNAVAILABLE); } connectAcknowledgeMessage.copyTransmissionData(connectMessage); throw new ShutdownException(connectAcknowledgeMessage); } catch (Exception systemError) { ConnectAcknowledgeMessage connectAcknowledgeMessage = ConnectAcknowledgeMessage.from( connectMessage.isDup(), connectMessage.getQos(), connectMessage.isRetain(), connectMessage.getKeepAliveTime(), MqttConnectReturnCode.CONNECTION_REFUSED_SERVER_UNAVAILABLE); connectAcknowledgeMessage.copyTransmissionData(connectMessage); log.error(" handle : System experienced the error ", systemError); throw new ShutdownException(connectAcknowledgeMessage); } }
From source file:io.vertx.mqtt.test.MqttConnectionTest.java
License:Apache License
@Test public void refusedNotAuthorized(TestContext context) { this.expectedReturnCode = MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED; try {/*from w ww .ja v a 2s. co m*/ MemoryPersistence persistence = new MemoryPersistence(); MqttClient client = new MqttClient(String.format("tcp://%s:%d", MQTT_SERVER_HOST, MQTT_SERVER_PORT), "12345", persistence); client.connect(); context.assertTrue(false); } catch (MqttException e) { context.assertTrue(e.getReasonCode() == MqttException.REASON_CODE_NOT_AUTHORIZED); e.printStackTrace(); } }
From source file:io.vertx.mqtt.test.server.MqttServerConnectionTest.java
License:Apache License
@Test public void refusedNotAuthorized(TestContext context) { this.expectedReturnCode = MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED; try {/*from w ww . jav a 2 s . c o m*/ MemoryPersistence persistence = new MemoryPersistence(); MqttClient client = new MqttClient(String.format("tcp://%s:%d", MQTT_SERVER_HOST, MQTT_SERVER_PORT), "12345", persistence); client.connect(); context.fail(); } catch (MqttException e) { context.assertTrue(e.getReasonCode() == MqttException.REASON_CODE_NOT_AUTHORIZED); } }
From source file:net.anyflow.lannister.packetreceiver.ConnectReceiver.java
License:Apache License
private boolean filterPlugins(ChannelHandlerContext ctx, MqttConnectMessage msg) { String clientId = msg.payload().clientIdentifier(); String userName = msg.variableHeader().hasUserName() ? msg.payload().userName() : null; String password = msg.variableHeader().hasPassword() ? msg.payload().password() : null; if (Plugins.SELF.get(ServiceChecker.class).isServiceAvailable() == false) { sendNoneAcceptMessage(ctx, MqttConnectReturnCode.CONNECTION_REFUSED_SERVER_UNAVAILABLE); return false; }/*from w w w. j a v a 2 s .com*/ if (Plugins.SELF.get(Authenticator.class).isValid(clientId) == false) { sendNoneAcceptMessage(ctx, MqttConnectReturnCode.CONNECTION_REFUSED_IDENTIFIER_REJECTED); // [MQTT-3.1.3-9] return false; } if (Plugins.SELF.get(Authenticator.class).isValid(clientId, userName, password) == false) { sendNoneAcceptMessage(ctx, MqttConnectReturnCode.CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD); return false; } if (Plugins.SELF.get(Authorizer.class).isAuthorized(clientId, userName) == false) { sendNoneAcceptMessage(ctx, MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED); return false; } return true; }
From source file:net.anyflow.lannister.packetreceiver.ConnectReceiverTest.java
License:Apache License
@Test public void testCONNECTION_REFUSED_NOT_AUTHORIZED() throws Exception { Authorizer prev = Plugins.SELF.put(Authorizer.class, new Authorizer() { @Override/*from ww w . j ava 2s . c o m*/ public Plugin clone() { return this; } @Override public boolean isAuthorized(String clientId, String username) { return false; } }); MqttConnAckMessage ret = executeNormalChannelRead0(TestUtil.newClientId(), true, null); Assert.assertEquals(ret.variableHeader().connectReturnCode(), MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED); Plugins.SELF.put(Authorizer.class, prev); }
From source file:org.eclipse.hono.adapter.mqtt.AbstractVertxBasedMqttProtocolAdapter.java
License:Open Source License
private Future<Device> handleEndpointConnectionWithAuthentication(final MqttEndpoint endpoint) { if (endpoint.auth() == null) { LOG.debug("connection request from device [clientId: {}] rejected: {}", endpoint.clientIdentifier(), "device did not provide credentials in CONNECT packet"); return rejected(MqttConnectReturnCode.CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD); } else {/* w w w . j a v a 2s . com*/ final DeviceCredentials credentials = getCredentials(endpoint.auth()); if (credentials == null) { LOG.debug("connection request from device [clientId: {}] rejected: {}", endpoint.clientIdentifier(), "device provided malformed credentials in CONNECT packet"); return rejected(MqttConnectReturnCode.CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD); } else { return getTenantConfiguration(credentials.getTenantId()).compose(tenantConfig -> { if (tenantConfig.isAdapterEnabled(getTypeName())) { LOG.debug("protocol adapter [{}] is enabled for tenant [{}]", getTypeName(), credentials.getTenantId()); return Future.succeededFuture(tenantConfig); } else { LOG.debug("protocol adapter [{}] is disabled for tenant [{}]", getTypeName(), credentials.getTenantId()); return Future.failedFuture(new ClientErrorException(HttpURLConnection.HTTP_FORBIDDEN, "adapter disabled for tenant")); } }).compose(tenantConfig -> { final Future<Device> result = Future.future(); usernamePasswordAuthProvider.authenticate(credentials, result.completer()); return result; }).compose(authenticatedDevice -> { LOG.debug("successfully authenticated device [tenant-id: {}, auth-id: {}, device-id: {}]", authenticatedDevice.getTenantId(), credentials.getAuthId(), authenticatedDevice.getDeviceId()); return triggerLinkCreation(authenticatedDevice.getTenantId()).map(done -> { onAuthenticationSuccess(endpoint, authenticatedDevice); return null; }).compose(ok -> accepted(authenticatedDevice)); }).recover(t -> { LOG.debug("cannot establish connection with device [tenant-id: {}, auth-id: {}]", credentials.getTenantId(), credentials.getAuthId(), t); if (t instanceof ServerErrorException) { // one of the services we depend on might not be available (yet) return rejected(MqttConnectReturnCode.CONNECTION_REFUSED_SERVER_UNAVAILABLE); } else { // validation of credentials has failed return rejected(MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED); } }); } } }
From source file:org.eclipse.hono.adapter.mqtt.AbstractVertxBasedMqttProtocolAdapterTest.java
License:Open Source License
/** * Verifies that an adapter rejects a connection attempt from a device that belongs to a tenant for which the * adapter is disabled./*from ww w. ja v a2 s. c o m*/ */ @Test public void testEndpointHandlerRejectsDeviceOfDisabledTenant() { // GIVEN an adapter final MqttServer server = getMqttServer(false); // which is disabled for tenant "my-tenant" final TenantObject myTenantConfig = TenantObject.from("my-tenant", true); myTenantConfig.addAdapterConfiguration(new JsonObject() .put(TenantConstants.FIELD_ADAPTERS_TYPE, ADAPTER_TYPE).put(TenantConstants.FIELD_ENABLED, false)); when(tenantClient.get("my-tenant")).thenReturn(Future.succeededFuture(myTenantConfig)); final AbstractVertxBasedMqttProtocolAdapter<ProtocolAdapterProperties> adapter = getAdapter(server); forceClientMocksToConnected(); // WHEN a device of "my-tenant" tries to connect final MqttAuth deviceCredentials = new MqttAuth("device@my-tenant", "irrelevant"); final MqttEndpoint endpoint = mock(MqttEndpoint.class); when(endpoint.auth()).thenReturn(deviceCredentials); adapter.handleEndpointConnection(endpoint); // THEN the connection is not established verify(endpoint).reject(MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED); }
From source file:org.eclipse.hono.adapter.mqtt.VertxBasedMqttProtocolAdapter.java
License:Open Source License
void handleCredentialsResult(final AsyncResult<String> attempt, final MqttEndpoint endpoint, final UsernamePasswordCredentials authObject) { if (attempt.succeeded()) { String logicalDeviceId = attempt.result(); LOG.trace("successfully authenticated device id <{}>", logicalDeviceId); endpoint.accept(false);//w ww.j av a2s .com endpoint.publishHandler(message -> { final ResourceIdentifier resource = ResourceIdentifier.fromString(message.topicName()); if (!validateCredentialsWithTopicStructure(resource, authObject.getTenantId(), logicalDeviceId)) { // if MQTT client does not conform to the topic structure, close the connection (MQTT has no way for errors) endpoint.close(); } else { publishMessage(endpoint, authObject.getTenantId(), logicalDeviceId, message, resource); } }); endpoint.closeHandler(v -> { LOG.debug("connection closed with client [{}], authId [{}], deviceId [{}]", endpoint.clientIdentifier(), authObject.getAuthId(), logicalDeviceId); if (registrationAssertions.remove(endpoint) != null) LOG.trace("removed registration assertion for client [{}]", endpoint.clientIdentifier()); }); } else { endpoint.reject(MqttConnectReturnCode.CONNECTION_REFUSED_NOT_AUTHORIZED); } }