com.tcloud.bee.key.server.service.impl.SaslServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.tcloud.bee.key.server.service.impl.SaslServiceImpl.java

Source

/**
 * Copyright 2013 Trend Micro Incorporated
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.tcloud.bee.key.server.service.impl;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.LinkedList;
import java.util.UUID;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.security.sasl.SaslException;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.hadoop.io.crypto.bee.BeeConstants;
import org.apache.hadoop.io.crypto.bee.key.sasl.KeySaslServer;
import org.apache.hadoop.io.crypto.bee.key.sasl.common.KeyToken;
import org.apache.hadoop.io.crypto.bee.key.sasl.common.SaslParam;
import org.apache.hadoop.io.crypto.bee.key.sasl.common.SaslUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.google.gson.Gson;
import com.tcloud.bee.key.server.service.KeyManageService;
import com.tcloud.bee.key.server.service.KeyTokenStore;
import com.tcloud.bee.key.server.service.SaslService;

@Service("SaslService")
public class SaslServiceImpl implements SaslService {
    final Logger logger = LoggerFactory.getLogger(getClass());

    @Inject
    private KeyTokenStore keyTokenStore;

    @Inject
    private KeyManageService keyManageService;

    private final LinkedList<KeySaslServer> lstKeySaslServer = new LinkedList<KeySaslServer>();

    @PostConstruct
    public void init() {
        logger.debug("into method init()");
        (new Thread() {
            public void run() {
                //Check KeySaslServer's TTL every SaslUtil.SASL_ENTRY_TTL milliseconds
                while (true) {
                    try {
                        long now = new java.util.Date().getTime();
                        //logger.info("Checking to Drop expired KeySaslServer .........." + now);

                        synchronized (getClass()) {
                            LinkedList<KeySaslServer> lstTtlExpired = new LinkedList<KeySaslServer>();
                            for (KeySaslServer srv : lstKeySaslServer) {
                                if (now > srv.getTtl()) {
                                    lstTtlExpired.add(srv);
                                }
                            }
                            for (KeySaslServer srv : lstTtlExpired) {
                                logger.info("This KeySaslServer is expired, drop. UUID: " + srv.getUuid());
                                lstKeySaslServer.remove(srv);
                            }
                        }

                        Thread.sleep(SaslUtil.SASL_ENTRY_TTL);
                    } catch (InterruptedException e) {
                        logger.error("KeySaslServer Checking exception", e);
                    }
                }
            }
        }).start();
    }

    @Override
    public void addServer(KeySaslServer srv) {
        synchronized (getClass()) {
            lstKeySaslServer.add(srv);
        }
    }

    @Override
    public void removeServer(KeySaslServer srv) {
        synchronized (getClass()) {
            lstKeySaslServer.remove(srv);
        }
    }

    @Override
    public KeySaslServer getServer(UUID uuid) {
        synchronized (getClass()) {
            for (KeySaslServer srv : lstKeySaslServer) {
                if (srv.getUuid().equals(uuid)) {
                    return srv;
                }
            }
        }

        return null;
    }

    private SaslParam addServer(SaslParam saslParam) throws SaslException, DecoderException {
        KeyToken keyToken = keyTokenStore.getToken(saslParam.getPwdId());
        if (keyToken == null) {
            logger.warn("The request keyToken not exist: " + saslParam.getPwdId());
            return null;
        }

        UUID uuid = UUID.randomUUID();
        KeySaslServer saslServer = new KeySaslServer(uuid, keyToken);

        byte[] challenge = saslServer.init();
        SaslParam param = new SaslParam(saslParam.getCommand());
        param.setSaslId(uuid);
        param.setChallenge(challenge);
        logger.info("add KeySaslServer. uuid:" + uuid + ", challenge:" + Hex.encodeHexString(param.getChallenge()));
        addServer(saslServer);

        return param;

    }

    private SaslParam authendicate(SaslParam saslParam) throws SaslException {
        SaslParam param = new SaslParam(saslParam.getCommand());
        KeySaslServer saslServer = this.getServer(saslParam.getSaslId());
        if (saslServer == null) {
            param.setChallenge("".getBytes());
            logger.warn("Abnormal behavior! saslServer is null.");
        } else {
            logger.debug("response:" + Hex.encodeHexString(saslParam.getResponse()));
            byte[] challenge = saslServer.auth(saslParam.getResponse());
            param.setChallenge(challenge);
            logger.debug("challenge2:" + Hex.encodeHexString(param.getChallenge()));
        }

        return param;
    }

    private SaslParam sendData(SaslParam saslParam) throws IOException {
        SaslParam param = new SaslParam(saslParam.getCommand());
        KeySaslServer saslServer = this.getServer(saslParam.getSaslId());
        if (saslServer == null) {
            param.setData("".getBytes());
            logger.warn("Abnormal behavior! saslServer is null.");

        } else if (saslServer.getSaslAuthStatus().equals(SaslUtil.SaslAuthStatus.AUTH_SUCCESS)) {
            //byte[] encrypted = saslServer.dataProcess(saslParam.getdata());
            byte[] dataBytes = saslServer.dataProcess(saslParam.getdata(), false);

            //use username & keyName to get real key hex string
            String keyName = new String(dataBytes);
            String tokenUser = saslServer.getTokenUser();
            String keyHexString = "";
            try {
                KeyManageService.QueryResult queryResult = keyManageService.getHexkey(keyName, tokenUser);
                if (queryResult.status == BeeConstants.ResponseStatus.SUCCESS) {
                    keyHexString = queryResult.msg;
                } else {
                    logger.warn("Get key Fail: keyName: " + keyName + ",msg: " + queryResult.msg);
                }

            } catch (FileNotFoundException e) {
                logger.warn("The key file not found: " + e.getMessage());
            }

            dataBytes = saslServer.dataProcess(keyHexString.getBytes(), true);

            //Client site: if ""'s wraped return or just return "", it will throw new Exception("Invalid key length...") 
            param.setData(dataBytes);

        } else {
            param.setData("".getBytes());
            logger.warn("Abnormal behavior! saslServer is still in Auth Processing.");
        }

        return param;
    }

    @Override
    public String getKey(String msg) throws DecoderException, IOException {
        SaslParam saslParam = new Gson().fromJson(msg, SaslParam.class);
        SaslParam saslParamReply = null;

        logger.debug("Sasl command: " + saslParam.getCommand() + ", pwdID: " + saslParam.getPwdId() + ", saslID:"
                + saslParam.getSaslId());

        if (saslParam.getCommand() == SaslUtil.SaslCommand.INIT) {
            saslParamReply = addServer(saslParam);
        } else if (saslParam.getCommand() == SaslUtil.SaslCommand.AUTH) {
            saslParamReply = authendicate(saslParam);
        } else if (saslParam.getCommand() == SaslUtil.SaslCommand.DATA) {
            saslParamReply = sendData(saslParam);
        } else {
            logger.warn("Uknow Sasl Command: {}", saslParam);
        }

        if (saslParamReply == null) {
            logger.warn("The Sasl Parameter to be returned is null");
            return "";
        } else {
            return new Gson().toJson(saslParamReply);
        }
    }

}