Package mireka.pop.command

Source Code of mireka.pop.command.ApopCommand

package mireka.pop.command;

import static mireka.pop.SessionState.*;

import java.io.IOException;
import java.util.List;

import javax.annotation.concurrent.GuardedBy;

import mireka.login.LoginDecision;
import mireka.login.LoginResult;
import mireka.login.LoginSpecification;
import mireka.pop.CommandParser;
import mireka.pop.CommandSyntaxException;
import mireka.pop.IllegalSessionStateException;
import mireka.pop.Pop3Exception;
import mireka.pop.Session;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ApopCommand extends AbstractLoginCommand {
    private final Logger logger = LoggerFactory.getLogger(ApopCommand.class);
    private final LoginSpecification loginSpecification;
    private String timestamp;
    @GuardedBy("ApopCommand.class")
    private static long uniqueClockValue;

    public ApopCommand(Session session) {
        super(session);
        loginSpecification = session.getServer().getLoginSpecification();
    }

    public String generateTimeStamp() {
        if (timestamp != null)
            throw new IllegalStateException();

        long clockValue = generateUniqueClockValue();
        int random = (int) Math.round(Math.random() * 100000);
        timestamp =
                "<" + random + "." + clockValue + "@"
                        + session.getServer().getHostName() + ">";
        return timestamp;
    }

    private static long generateUniqueClockValue() {
        long millis = System.currentTimeMillis();
        synchronized (ApopCommand.class) {
            if (millis > uniqueClockValue) {
                uniqueClockValue = millis;
            } else {
                ++uniqueClockValue;
            }
            return uniqueClockValue;
        }
    }

    @Override
    public void execute(CommandParser commandParser) throws IOException,
            Pop3Exception {
        if (session.getSessionState() != AUTHORIZATION)
            throw new IllegalSessionStateException();

        List<String> args = commandParser.parseArguments();
        if (args.size() != 2)
            throw new CommandSyntaxException("Two arguments are expected");
        String user = args.get(0);
        String digest = args.get(1);
        byte[] digestBytes = valueOfHex(digest);
        LoginResult result =
                loginSpecification.evaluateApop(user, timestamp, digestBytes);
        if (result.decision == LoginDecision.VALID) {
            startTransaction(result.principal);
        } else {
            logger.debug("Unsuccessful login result: {}", result.decision);
            session.getThread().sendResponse("-ERR [AUTH] permission denied");
            session.setSessionState(AUTHORIZATION);
        }
    }

    private static byte[] valueOfHex(String s) throws CommandSyntaxException {
        if (s.length() != 32)
            throw new CommandSyntaxException(
                    "Second argument must be a 16 bytes hexadecimal number");
        byte[] result = new byte[16];
        for (int i = 0; i < 16; i++) {
            String byteString = s.substring(i * 2, i * 2 + 2);
            try {
                result[i] = (byte) Integer.parseInt(byteString, 16);
            } catch (NumberFormatException e) {
                throw new CommandSyntaxException(
                        "Second argument must be a 16 bytes hexadecimal number");
            }
        }
        return result;
    }
}
TOP

Related Classes of mireka.pop.command.ApopCommand

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.