ServerDelegate.java
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(1010));
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 }