AmqPlainSaslClient.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.client.security.amqplain;
022 
023 import javax.security.auth.callback.Callback;
024 import javax.security.auth.callback.CallbackHandler;
025 import javax.security.auth.callback.NameCallback;
026 import javax.security.auth.callback.PasswordCallback;
027 import javax.security.sasl.SaslClient;
028 import javax.security.sasl.SaslException;
029 
030 import org.apache.qpid.framing.FieldTable;
031 import org.apache.qpid.framing.FieldTableFactory;
032 
033 /**
034  * Implements the "AMQPlain" authentication protocol that uses FieldTables to send username and pwd.
035  *
036  */
037 public class AmqPlainSaslClient implements SaslClient
038 {
039     /**
040      *  The name of this mechanism
041      */
042     public static final String MECHANISM = "AMQPLAIN";
043 
044     private CallbackHandler _cbh;
045 
046     public AmqPlainSaslClient(CallbackHandler cbh)
047     {
048         _cbh = cbh;
049     }
050 
051     public String getMechanismName()
052     {
053         return "AMQPLAIN";
054     }
055 
056     public boolean hasInitialResponse()
057     {
058         return true;
059     }
060 
061     public byte[] evaluateChallenge(byte[] challengethrows SaslException
062     {
063         // we do not care about the prompt or the default name
064         NameCallback nameCallback = new NameCallback("prompt""defaultName");
065         PasswordCallback pwdCallback = new PasswordCallback("prompt"false);
066         Callback[] callbacks = new Callback[]{nameCallback, pwdCallback};
067         try
068         {
069             _cbh.handle(callbacks);
070         }
071         catch (Exception e)
072         {
073             throw new SaslException("Error handling SASL callbacks: " + e, e);
074         }
075         FieldTable table = FieldTableFactory.newFieldTable();
076         table.setString("LOGIN", nameCallback.getName());
077         table.setString("PASSWORD"new String(pwdCallback.getPassword()));
078         return table.getDataAsBytes();
079     }
080 
081     public boolean isComplete()
082     {
083         return true;
084     }
085 
086     public byte[] unwrap(byte[] incoming, int offset, int lenthrows SaslException
087     {
088         throw new SaslException("Not supported");
089     }
090 
091     public byte[] wrap(byte[] outgoing, int offset, int lenthrows SaslException
092     {
093         throw new SaslException("Not supported");
094     }
095 
096     public Object getNegotiatedProperty(String propName)
097     {
098         return null;
099     }
100 
101     public void dispose() throws SaslException
102     {
103         _cbh = null;
104     }
105 }