com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator.java Source code

Java tutorial

Introduction

Here is the source code for com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator.java

Source

/*
 *    This program is free software; you can redistribute it and/or modify it under the terms of 
 * the GNU AFFERO GENERAL PUBLIC LICENSE as published by the Free Software Foundation; either version 3 of the License, 
 * or (at your option) any later version. 
 * 
 *    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 AFFERO GENERAL PUBLIC LICENSE for more details. 
 *    You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE along with this program; 
 * if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package com.meidusa.amoeba.mysql.server;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.Collections;
import java.util.Map;

import org.apache.commons.collections.map.LRUMap;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.meidusa.amoeba.mysql.io.MySqlPacketConstant;
import com.meidusa.amoeba.mysql.net.MysqlClientConnection;
import com.meidusa.amoeba.mysql.net.packet.AuthenticationPacket;
import com.meidusa.amoeba.mysql.util.CharsetMapping;
import com.meidusa.amoeba.mysql.util.Security;
import com.meidusa.amoeba.net.AuthResponseData;
import com.meidusa.amoeba.net.Authenticator;
import com.meidusa.amoeba.net.AuthingableConnection;
import com.meidusa.amoeba.util.StringUtil;

/**
 * 
 * @author <a href=mailto:piratebase@sina.com>Struct chen</a>
 */
@SuppressWarnings("unchecked")
public class MysqlClientAuthenticator extends Authenticator<AuthenticationPacket> implements MySqlPacketConstant {
    protected static Logger logger = Logger.getLogger(MysqlClientAuthenticator.class);
    private Map map = Collections.synchronizedMap(new LRUMap(1000));

    protected String user;
    protected String password;

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public MysqlClientAuthenticator() {

    }

    protected void processAuthentication(AuthingableConnection conn, AuthenticationPacket autheticationPacket,
            AuthResponseData rdata) {
        MysqlClientConnection mysqlConn = (MysqlClientConnection) conn;

        if (logger.isInfoEnabled()) {
            logger.info("Accepting conn=" + conn);
        }
        String errorMessage = "";

        if ((autheticationPacket.clientParam & CLIENT_COMPRESS) != 0) {
            rdata.code = AuthResponseData.ERROR;
            rdata.message = " cannot use COMPRESSED PROTOCOL over amoeba!";
            return;
        }

        if ((autheticationPacket.clientParam & CLIENT_PROTOCOL_41) == 0) {
            rdata.code = AuthResponseData.ERROR;
            rdata.message = " must use new protocol version 4.1 over amoeba";
            return;
        }

        try {
            mysqlConn.setCharset(CharsetMapping.INDEX_TO_CHARSET[autheticationPacket.charsetNumber & 0xff]);
            boolean passwordchecked = false;
            if (logger.isDebugEnabled()) {
                logger.debug("client charset="
                        + CharsetMapping.INDEX_TO_CHARSET[autheticationPacket.charsetNumber & 0xff]);
                if (conn.getInetAddress() != null && map.get(conn.getInetAddress().getHostAddress()) == null) {
                    map.put(conn.getInetAddress().getHostAddress(), Boolean.TRUE);
                    long clientParam = autheticationPacket.clientParam;
                    StringBuilder builder = new StringBuilder();
                    builder.append("\n");
                    builder.append("===========").append(conn.getInetAddress().getHostAddress())
                            .append("   Client Flag ==============\n");
                    builder.append("CLIENT_LONG_PASSWORD:").append(((clientParam & CLIENT_LONG_PASSWORD) != 0))
                            .append("\n");
                    builder.append("CLIENT_FOUND_ROWS:").append(((clientParam & CLIENT_FOUND_ROWS) != 0))
                            .append("\n");
                    builder.append("CLIENT_LONG_FLAG:").append(((clientParam & CLIENT_LONG_FLAG) != 0))
                            .append("\n");
                    builder.append("CLIENT_CONNECT_WITH_DB:").append(((clientParam & CLIENT_CONNECT_WITH_DB) != 0))
                            .append("\n");
                    builder.append("CLIENT_NO_SCHEMA:").append(((clientParam & CLIENT_NO_SCHEMA) != 0))
                            .append("\n");
                    builder.append("CLIENT_COMPRESS:").append(((clientParam & CLIENT_COMPRESS) != 0)).append("\n");
                    builder.append("CLIENT_ODBC:").append(((clientParam & CLIENT_ODBC) != 0)).append("\n");
                    builder.append("CLIENT_LOCAL_FILES:").append(((clientParam & CLIENT_LOCAL_FILES) != 0))
                            .append("\n");
                    builder.append("CLIENT_IGNORE_SPACE:").append(((clientParam & CLIENT_IGNORE_SPACE) != 0))
                            .append("\n");
                    builder.append("CLIENT_PROTOCOL_41:").append(((clientParam & CLIENT_PROTOCOL_41) != 0))
                            .append("\n");
                    builder.append("CLIENT_INTERACTIVE:").append(((clientParam & CLIENT_INTERACTIVE) != 0))
                            .append("\n");
                    builder.append("CLIENT_SSL:").append(((clientParam & CLIENT_SSL) != 0)).append("\n");
                    builder.append("CLIENT_IGNORE_SIGPIPE:").append(((clientParam & CLIENT_IGNORE_SIGPIPE) != 0))
                            .append("\n");
                    builder.append("CLIENT_TRANSACTIONS:").append(((clientParam & CLIENT_TRANSACTIONS) != 0))
                            .append("\n");
                    builder.append("CLIENT_RESERVED:").append(((clientParam & CLIENT_RESERVED) != 0)).append("\n");
                    builder.append("CLIENT_SECURE_CONNECTION:")
                            .append(((clientParam & CLIENT_SECURE_CONNECTION) != 0)).append("\n");
                    builder.append("CLIENT_MULTI_STATEMENTS:")
                            .append(((clientParam & CLIENT_MULTI_STATEMENTS) != 0)).append("\n");
                    builder.append("CLIENT_MULTI_RESULTS:").append(((clientParam & CLIENT_MULTI_RESULTS) != 0))
                            .append("\n");
                    builder.append("===========================END Client Flag===============================\n");
                    logger.debug(builder.toString());
                }
            }

            if (!StringUtil.isEmpty(getPassword())) {
                String encryptPassword = new String(Security.scramble411(getPassword(), mysqlConn.getSeed()),
                        AuthenticationPacket.CODE_PAGE_1252);

                passwordchecked = StringUtils.equals(
                        new String(autheticationPacket.encryptedPassword, AuthenticationPacket.CODE_PAGE_1252),
                        encryptPassword);
            } else {
                if (autheticationPacket.encryptedPassword == null
                        || autheticationPacket.encryptedPassword.length == 0) {
                    passwordchecked = true;
                }
            }
            if (StringUtil.equals(getUser(), autheticationPacket.user) && passwordchecked) {
                rdata.code = AuthResponseData.SUCCESS;
                if (logger.isDebugEnabled()) {
                    logger.debug(autheticationPacket.toString());
                }
            } else {
                rdata.code = AuthResponseData.ERROR;
                rdata.message = "Access denied for user '" + autheticationPacket.user + "'@'" + conn.getSocketId()
                        + "'" + (autheticationPacket.encryptedPassword != null ? "(using password: YES)" : "");
            }

            mysqlConn.setSchema(autheticationPacket.database);
        } catch (UnsupportedEncodingException e) {
            errorMessage = e.getMessage();
            rdata.code = AuthResponseData.ERROR;
            rdata.message = errorMessage;
            logger.error("UnsupportedEncodingException error", e);
        } catch (NoSuchAlgorithmException e) {
            errorMessage = e.getMessage();
            rdata.code = AuthResponseData.ERROR;
            rdata.message = errorMessage;
            logger.error("NoSuchAlgorithmException error", e);
        } catch (Exception e) {
            errorMessage = e.getMessage();
            logger.error("processAuthentication error", e);
            rdata.code = AuthResponseData.ERROR;
            rdata.message = errorMessage;
        }

    }
}