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.transport;
022
023 import java.util.Collections;
024
025
026 import java.util.ArrayList;
027 import java.util.HashMap;
028 import java.util.List;
029 import java.util.Map;
030 import java.util.concurrent.locks.Condition;
031 import java.util.concurrent.locks.Lock;
032
033 import java.io.UnsupportedEncodingException;
034
035 import org.apache.qpid.QpidException;
036
037 import javax.security.sasl.Sasl;
038 import javax.security.sasl.SaslClient;
039 import javax.security.sasl.SaslException;
040 import javax.security.sasl.SaslServer;
041
042
043 import static org.apache.qpid.transport.Connection.State.*;
044
045
046 /**
047 * ServerDelegate
048 *
049 */
050
051 public class ServerDelegate extends ConnectionDelegate
052 {
053
054 private SaslServer saslServer;
055
056 public void init(Connection conn, ProtocolHeader hdr)
057 {
058 conn.send(new ProtocolHeader(1, 0, 10));
059 List<Object> utf8 = new ArrayList<Object>();
060 utf8.add("utf8");
061 conn.connectionStart(null, Collections.EMPTY_LIST, utf8);
062 }
063
064 @Override public void connectionStartOk(Connection conn, ConnectionStartOk ok)
065 {
066 conn.setLocale(ok.getLocale());
067 String mechanism = ok.getMechanism();
068
069 if (mechanism == null || mechanism.length() == 0)
070 {
071 conn.connectionTune
072 (Integer.MAX_VALUE,
073 org.apache.qpid.transport.network.ConnectionBinding.MAX_FRAME_SIZE,
074 0, Integer.MAX_VALUE);
075 return;
076 }
077
078 try
079 {
080 SaslServer ss = Sasl.createSaslServer
081 (mechanism, "AMQP", "localhost", null, null);
082 if (ss == null)
083 {
084 conn.connectionClose
085 (ConnectionCloseCode.CONNECTION_FORCED,
086 "null SASL mechanism: " + mechanism);
087 return;
088 }
089 conn.setSaslServer(ss);
090 secure(conn, ok.getResponse());
091 }
092 catch (SaslException e)
093 {
094 conn.exception(e);
095 }
096 }
097
098 private void secure(Connection conn, byte[] response)
099 {
100 SaslServer ss = conn.getSaslServer();
101 try
102 {
103 byte[] challenge = ss.evaluateResponse(response);
104 if (ss.isComplete())
105 {
106 ss.dispose();
107 conn.connectionTune
108 (Integer.MAX_VALUE,
109 org.apache.qpid.transport.network.ConnectionBinding.MAX_FRAME_SIZE,
110 0, Integer.MAX_VALUE);
111 }
112 else
113 {
114 conn.connectionSecure(challenge);
115 }
116 }
117 catch (SaslException e)
118 {
119 conn.exception(e);
120 }
121 }
122
123 @Override public void connectionSecureOk(Connection conn, ConnectionSecureOk ok)
124 {
125 secure(conn, ok.getResponse());
126 }
127
128 @Override public void connectionTuneOk(Connection conn, ConnectionTuneOk ok)
129 {
130
131 }
132
133 @Override public void connectionOpen(Connection conn, ConnectionOpen open)
134 {
135 conn.connectionOpenOk(Collections.EMPTY_LIST);
136 conn.setState(OPEN);
137 }
138
139 public Session getSession(Connection conn, SessionAttach atc)
140 {
141 return new Session(conn, new Binary(atc.getName()), 0);
142 }
143
144 @Override public void sessionAttach(Connection conn, SessionAttach atc)
145 {
146 Session ssn = getSession(conn, atc);
147 conn.map(ssn, atc.getChannel());
148 ssn.sessionAttached(atc.getName());
149 ssn.setState(Session.State.OPEN);
150 }
151
152 }
|