Package tigase.auth

Source Code of tigase.auth.SaslPLAIN

/*
* Tigase Jabber/XMPP Server
* Copyright (C) 2004-2007 "Artur Hefczyc" <artur.hefczyc@tigase.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. Look for COPYING file in the top folder.
* If not, see http://www.gnu.org/licenses/.
*
* $Rev: 630 $
* Last modified by $Author: kobit $
* $Date: 2007-07-18 18:38:28 +0100 (Wed, 18 Jul 2007) $
*/
package tigase.auth;

import java.util.Arrays;
import java.util.Map;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.sasl.AuthorizeCallback;
import javax.security.sasl.RealmCallback;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
import java.security.NoSuchAlgorithmException;
import tigase.util.Algorithms;
import tigase.util.JIDUtils;

/**
* Describe class SaslPLAIN here.
*
*
* Created: Mon Nov  6 09:02:31 2006
*
* @author <a href="mailto:artur.hefczyc@tigase.org">Artur Hefczyc</a>
* @version $Rev: 630 $
*/
public class SaslPLAIN implements SaslServer {

  public static final String ENCRYPTION_KEY = "password-encryption";
  public static final String ENCRYPTION_PLAIN = "PLAIN";
  public static final String ENCRYPTION_MD5 = "MD5";
  /**
   * This is LibreSource variant of encoding MD5 sum. The calculation is done
   * the same way but HEX representation of the sum is different:
   * <pre>
   *  StringBuilder sb = new StringBuilder();
   *  for (byte b: md5) {
   *    sb.append(Integer.toHexString(b));
   *  }
   *  </pre>
   *
   */
  public static final String ENCRYPTION_LS_MD5 = "LS-MD5";
  public static final String ENCRYPTION_SHA = "SHA";

  private static final String MECHANISM = "PLAIN";

  private Map<? super String, ?> props = null;
  private CallbackHandler callbackHandler = null;

  private boolean auth_ok = false;

  /**
   * Creates a new <code>SaslPLAIN</code> instance.
   *
   */
  public SaslPLAIN() {}

  protected SaslPLAIN(Map<? super String, ?> props,
    CallbackHandler callbackHandler) {
    this.props = props;
    this.callbackHandler = callbackHandler;
  }

  // Implementation of javax.security.sasl.SaslServer

  /**
   * Describe <code>unwrap</code> method here.
   *
   * @param byteArray a <code>byte[]</code> value
   * @param n an <code>int</code> value
   * @param n1 an <code>int</code> value
   * @return a <code>byte[]</code> value
   * @exception SaslException if an error occurs
   */
  public byte[] unwrap(final byte[] byteArray, final int n, final int n1)
    throws SaslException {
    return null;
  }

//   /**
//    * This is not fully correct HEX representation of digest sum but
//    * this is how Libre Source does it so I have to be compatible with them.
//    *
//    * @param passwd a <code>String</code> value
//    * @return a <code>String</code> value
//    */
//   private String ls_digest(String passwd) throws NoSuchAlgorithmException {
//     byte[] md5 = Algorithms.digest("", passwd, "MD5");
//     StringBuilder sb = new StringBuilder();
//     for (byte b: md5) {
//       sb.append(Integer.toHexString(b));
//     }
//     return sb.toString();
//   }

  /**
   * Describe <code>evaluateResponse</code> method here.
   *
   * @param byteArray a <code>byte[]</code> value
   * @return a <code>byte[]</code> value
   * @exception SaslException if an error occurs
   */
  public byte[] evaluateResponse(final byte[] byteArray) throws SaslException {

    //StringBuilder authz = new StringBuilder();
    // fields are separated with \0 char so let's look for the char
    // position....
    int auth_idx = 0;
    while (byteArray[auth_idx] != 0 && auth_idx < byteArray.length)
    { ++auth_idx;  }
    String authoriz = new String(byteArray, 0, auth_idx);
    int user_idx = ++auth_idx;
    while (byteArray[user_idx] != 0 && user_idx < byteArray.length)
    { ++user_idx;  }
    String user_id = new String(byteArray, auth_idx, user_idx - auth_idx);
    ++user_idx;
    String passwd =
      new String(byteArray, user_idx, byteArray.length - user_idx);
    if (passwd != null) {
      String alg = (String)props.get(ENCRYPTION_KEY);
      if (alg != null) {
        try {
          if (alg.equals(ENCRYPTION_MD5) || alg.equals(ENCRYPTION_SHA)) {
            passwd = Algorithms.hexDigest("", passwd, alg);
          } // end of if (alg != null && !alg.equals())
//           if (alg.equals(ENCRYPTION_LS_MD5)) {
//             passwd = ls_digest(passwd);
//           } // end of if (alg != null && !alg.equals())
        } catch (NoSuchAlgorithmException e) {
          throw
            new SaslException("Password encrypting algorithm is not supported.",
              e);
        } // end of try-catch
    }
    } // end of if (passwd != null)

    if (callbackHandler == null) {
      throw new SaslException("Error: no CallbackHandler available.");
    }
    Callback[] callbacks = new Callback[3];
    NameCallback nc = new NameCallback("User name", user_id);
    PasswordCallback pc = new PasswordCallback("User password", false);
    RealmCallback rc = new RealmCallback("Put domain as realm.");
    callbacks[0] = nc;
    callbacks[1] = pc;
    callbacks[2] = rc;
    try {
      callbackHandler.handle(callbacks);
      char[] real_password = pc.getPassword();
      if (!Arrays.equals(real_password, passwd.toCharArray())) {
        throw new SaslException("Password missmatch.");
      }
      if (authoriz != null && !authoriz.isEmpty()) {
        String realm = rc.getText();
        callbacks = new Callback[1];
        AuthorizeCallback ac =
          new AuthorizeCallback(JIDUtils.getNodeID(user_id, realm), authoriz);
        callbacks[0] = ac;
        callbackHandler.handle(callbacks);
        if (ac.isAuthorized()) {
          auth_ok = true;
        } else {
          throw new SaslException("Not authorized.");
        } // end of else
      } else {
        auth_ok = true;
      } // end of if (authoriz != null && !authoriz.empty()) else
    } catch (Exception e) {
      throw new SaslException("Authorization error.", e);
    } // end of try-catch

    return null;
  }

  /**
   * Describe <code>getAuthorizationID</code> method here.
   *
   * @return a <code>String</code> value
   */
  public String getAuthorizationID() {
    return null;
  }

  /**
   * Describe <code>getMechanismName</code> method here.
   *
   * @return a <code>String</code> value
   */
  public String getMechanismName() {
    return MECHANISM;
  }

  /**
   * Describe <code>getNegotiatedProperty</code> method here.
   *
   * @param string a <code>String</code> value
   * @return an <code>Object</code> value
   */
  public Object getNegotiatedProperty(final String string) {
    return null;
  }

  /**
   * Describe <code>isComplete</code> method here.
   *
   * @return a <code>boolean</code> value
   */
  public boolean isComplete() {
    return auth_ok;
  }

  /**
   * Describe <code>wrap</code> method here.
   *
   * @param byteArray a <code>byte[]</code> value
   * @param n an <code>int</code> value
   * @param n1 an <code>int</code> value
   * @return a <code>byte[]</code> value
   * @exception SaslException if an error occurs
   */
  public byte[] wrap(final byte[] byteArray, final int n, final int n1)
    throws SaslException {
    return null;
  }

  /**
   * Describe <code>dispose</code> method here.
   *
   * @exception SaslException if an error occurs
   */
  public void dispose() throws SaslException {
    props = null;
    callbackHandler = null;
  }

} // SaslPLAIN
TOP

Related Classes of tigase.auth.SaslPLAIN

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.