001 /*
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements. See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership. The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License. You may obtain a copy of the License at
010 *
011 * http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied. See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 *
020 */
021 package org.apache.qpid.server.handler;
022
023 import javax.security.sasl.SaslException;
024 import javax.security.sasl.SaslServer;
025
026 import org.apache.log4j.Logger;
027 import org.apache.qpid.AMQException;
028 import org.apache.qpid.framing.ConnectionCloseBody;
029 import org.apache.qpid.framing.ConnectionSecureBody;
030 import org.apache.qpid.framing.ConnectionSecureOkBody;
031 import org.apache.qpid.framing.ConnectionTuneBody;
032 import org.apache.qpid.framing.MethodRegistry;
033 import org.apache.qpid.protocol.AMQConstant;
034 import org.apache.qpid.server.protocol.AMQProtocolSession;
035 import org.apache.qpid.server.registry.ApplicationRegistry;
036 import org.apache.qpid.server.security.auth.AuthenticationResult;
037 import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
038 import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
039 import org.apache.qpid.server.state.AMQState;
040 import org.apache.qpid.server.state.AMQStateManager;
041 import org.apache.qpid.server.state.StateAwareMethodListener;
042
043 public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener<ConnectionSecureOkBody>
044 {
045 private static final Logger _logger = Logger.getLogger(ConnectionSecureOkMethodHandler.class);
046
047 private static ConnectionSecureOkMethodHandler _instance = new ConnectionSecureOkMethodHandler();
048
049 public static ConnectionSecureOkMethodHandler getInstance()
050 {
051 return _instance;
052 }
053
054 private ConnectionSecureOkMethodHandler()
055 {
056 }
057
058 public void methodReceived(AMQStateManager stateManager, ConnectionSecureOkBody body, int channelId) throws AMQException
059 {
060 AMQProtocolSession session = stateManager.getProtocolSession();
061
062 AuthenticationManager authMgr = ApplicationRegistry.getInstance().getAuthenticationManager();
063
064 SaslServer ss = session.getSaslServer();
065 if (ss == null)
066 {
067 throw new AMQException("No SASL context set up in session");
068 }
069 MethodRegistry methodRegistry = session.getMethodRegistry();
070 AuthenticationResult authResult = authMgr.authenticate(ss, body.getResponse());
071 switch (authResult.status)
072 {
073 case ERROR:
074 Exception cause = authResult.getCause();
075
076 _logger.info("Authentication failed:" + (cause == null ? "" : cause.getMessage()));
077
078 // This should be abstracted
079 stateManager.changeState(AMQState.CONNECTION_CLOSING);
080
081 ConnectionCloseBody connectionCloseBody =
082 methodRegistry.createConnectionCloseBody(AMQConstant.NOT_ALLOWED.getCode(),
083 AMQConstant.NOT_ALLOWED.getName(),
084 body.getClazz(),
085 body.getMethod());
086
087 session.writeFrame(connectionCloseBody.generateFrame(0));
088 disposeSaslServer(session);
089 break;
090 case SUCCESS:
091 _logger.info("Connected as: " + ss.getAuthorizationID());
092 stateManager.changeState(AMQState.CONNECTION_NOT_TUNED);
093
094 ConnectionTuneBody tuneBody =
095 methodRegistry.createConnectionTuneBody(0xFFFF,
096 ConnectionStartOkMethodHandler.getConfiguredFrameSize(),
097 ApplicationRegistry.getInstance().getConfiguration().getHeartBeatDelay());
098 session.writeFrame(tuneBody.generateFrame(0));
099 session.setAuthorizedID(new UsernamePrincipal(ss.getAuthorizationID()));
100 disposeSaslServer(session);
101 break;
102 case CONTINUE:
103 stateManager.changeState(AMQState.CONNECTION_NOT_AUTH);
104
105 ConnectionSecureBody secureBody = methodRegistry.createConnectionSecureBody(authResult.challenge);
106 session.writeFrame(secureBody.generateFrame(0));
107 }
108 }
109
110 private void disposeSaslServer(AMQProtocolSession ps)
111 {
112 SaslServer ss = ps.getSaslServer();
113 if (ss != null)
114 {
115 ps.setSaslServer(null);
116 try
117 {
118 ss.dispose();
119 }
120 catch (SaslException e)
121 {
122 _logger.error("Error disposing of Sasl server: " + e);
123 }
124 }
125 }
126 }
|