/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.activemq.artemis.core.protocol.stomp.v10; import javax.security.cert.X509Certificate; import java.util.Map; import java.util.concurrent.ScheduledExecutorService; import org.apache.activemq.artemis.core.protocol.stomp.ActiveMQStompException; import org.apache.activemq.artemis.core.protocol.stomp.FrameEventListener; import org.apache.activemq.artemis.core.protocol.stomp.Stomp; import org.apache.activemq.artemis.core.protocol.stomp.StompConnection; import org.apache.activemq.artemis.core.protocol.stomp.StompDecoder; import org.apache.activemq.artemis.core.protocol.stomp.StompFrame; import org.apache.activemq.artemis.core.protocol.stomp.StompVersions; import org.apache.activemq.artemis.core.protocol.stomp.VersionedStompFrameHandler; import org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnection; import org.apache.activemq.artemis.core.server.ActiveMQServerLogger; import org.apache.activemq.artemis.utils.CertificateUtil; import org.apache.activemq.artemis.utils.ExecutorFactory; import static org.apache.activemq.artemis.core.protocol.stomp.ActiveMQStompProtocolMessageBundle.BUNDLE; public class StompFrameHandlerV10 extends VersionedStompFrameHandler implements FrameEventListener { public StompFrameHandlerV10(StompConnection connection, ScheduledExecutorService scheduledExecutorService, ExecutorFactory factory) { super(connection, scheduledExecutorService, factory); decoder = new StompDecoder(this); decoder.init(); connection.addStompEventListener(this); } @Override public StompFrame onConnect(StompFrame frame) { StompFrame response = null; Map<String, String> headers = frame.getHeadersMap(); String login = headers.get(Stomp.Headers.Connect.LOGIN); String passcode = headers.get(Stomp.Headers.Connect.PASSCODE); String clientID = headers.get(Stomp.Headers.Connect.CLIENT_ID); String requestID = headers.get(Stomp.Headers.Connect.REQUEST_ID); X509Certificate[] certificates = null; if (connection.getTransportConnection() instanceof NettyConnection) { certificates = CertificateUtil.getCertsFromChannel(((NettyConnection) connection.getTransportConnection()).getChannel()); } if (connection.validateUser(login, passcode, certificates)) { connection.setClientID(clientID); connection.setValid(true); response = new StompFrameV10(Stomp.Responses.CONNECTED); if (frame.hasHeader(Stomp.Headers.ACCEPT_VERSION)) { response.addHeader(Stomp.Headers.Connected.VERSION, StompVersions.V1_0.toString()); } response.addHeader(Stomp.Headers.Connected.SESSION, connection.getID().toString()); if (requestID != null) { response.addHeader(Stomp.Headers.Connected.RESPONSE_ID, requestID); } } else { //not valid response = new StompFrameV10(Stomp.Responses.ERROR); String responseText = "Security Error occurred: User name [" + login + "] or password is invalid"; response.setBody(responseText); response.addHeader(Stomp.Headers.Error.MESSAGE, responseText); } return response; } @Override public StompFrame onDisconnect(StompFrame frame) { return null; } @Override public StompFrame onUnsubscribe(StompFrame request) { StompFrame response = null; String destination = request.getHeader(Stomp.Headers.Unsubscribe.DESTINATION); String id = request.getHeader(Stomp.Headers.Unsubscribe.ID); String durableSubscriptionName = request.getHeader(Stomp.Headers.Unsubscribe.DURABLE_SUBSCRIBER_NAME); if (durableSubscriptionName == null) { durableSubscriptionName = request.getHeader(Stomp.Headers.Unsubscribe.DURABLE_SUBSCRIPTION_NAME); } String subscriptionID = null; if (id != null) { subscriptionID = id; } else { if (destination == null) { ActiveMQStompException error = BUNDLE.needIDorDestination().setHandler(this); response = error.getFrame(); return response; } subscriptionID = "subscription/" + destination; } try { connection.unsubscribe(subscriptionID, durableSubscriptionName); } catch (ActiveMQStompException e) { return e.getFrame(); } return response; } @Override public StompFrame onAck(StompFrame request) { StompFrame response = null; String messageID = request.getHeader(Stomp.Headers.Ack.MESSAGE_ID); String txID = request.getHeader(Stomp.Headers.TRANSACTION); if (txID != null) { ActiveMQServerLogger.LOGGER.stompTXAckNorSupported(); } try { connection.acknowledge(messageID, null); } catch (ActiveMQStompException e) { response = e.getFrame(); } return response; } @Override public StompFrame onStomp(StompFrame request) { return onUnknown(request.getCommand()); } @Override public StompFrame onNack(StompFrame request) { return onUnknown(request.getCommand()); } @Override public StompFrame createStompFrame(String command) { return new StompFrameV10(command); } @Override public void replySent(StompFrame reply) { if (reply.needsDisconnect()) { connection.destroy(); } } @Override public void requestAccepted(StompFrame request) { // TODO Auto-generated method stub } }