org.jmqtt.auth.impl.FileAuthenticator.java Source code

Java tutorial

Introduction

Here is the source code for org.jmqtt.auth.impl.FileAuthenticator.java

Source

/*
 * Copyright (c) 2012-2015 The original author or authors
 * ------------------------------------------------------
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * and Apache License v2.0 which accompanies this distribution.
 *
 * The Eclipse Public License is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * The Apache License v2.0 is available at
 * http://www.opensource.org/licenses/apache2.0.php
 *
 * You may elect to redistribute this code under either of these licenses.
 */
package org.jmqtt.auth.impl;

import org.apache.commons.codec.binary.Hex;
import org.jmqtt.auth.IAuthenticator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;

/**
 * Load user credentials from a text file.
 * Each line of the file is formatted as "<username>:<sha256(password)>". The username mustn't contains : char.
 * <p>
 * To encode your password from command line on Linux systems, you could use:
 * <pre>
 *     echo -n "yourpassword" | sha256sum
 * </pre>
 * NB -n is important because echo append a newline by default at the of string. -n avoid this behaviour.
 *
 * @author andrea
 */
public class FileAuthenticator implements IAuthenticator {

    private static final Logger LOG = LoggerFactory.getLogger(FileAuthenticator.class);

    private Map<String, String> identities = new HashMap<>();
    private MessageDigest digest;

    public FileAuthenticator(String parent, String filePath) {
        File file = new File(parent, filePath);
        LOG.info("Loading password file: " + file);
        if (file.isDirectory()) {
            LOG.warn(String.format("Bad file reference %s is a directory", file));
            return;
        }
        try {
            this.digest = MessageDigest.getInstance("SHA-256");
        } catch (NoSuchAlgorithmException nsaex) {
            LOG.error("Can't find SHA-256 for password encoding", nsaex);
            throw new RuntimeException(nsaex);
        }

        try {
            FileReader reader = new FileReader(file);
            parse(reader);
        } catch (FileNotFoundException fex) {
            LOG.warn(String.format("Parsing not existing file %s", file), fex);
        } catch (ParseException pex) {
            LOG.warn(String.format("Format error in parsing password file %s", file), pex);
        }
    }

    private void parse(Reader reader) throws ParseException {
        if (reader == null) {
            return;
        }

        BufferedReader br = new BufferedReader(reader);
        String line;
        try {
            while ((line = br.readLine()) != null) {
                int commentMarker = line.indexOf('#');
                if (commentMarker != -1) {
                    if (commentMarker == 0) {
                        //skip its a comment
                        continue;
                    } else {
                        //it's a malformed comment
                        throw new ParseException(line, commentMarker);
                    }
                } else {
                    if (line.isEmpty() || line.matches("^\\s*$")) {
                        //skip it's a black line
                        continue;
                    }

                    //split till the first space
                    int delimiterIdx = line.indexOf(':');
                    String username = line.substring(0, delimiterIdx).trim();
                    String password = line.substring(delimiterIdx + 1).trim();

                    identities.put(username, password);
                }
            }
        } catch (IOException ex) {
            throw new ParseException("Failed to read", 1);
        }
    }

    @Override
    public boolean checkValid(String clientId, String username, byte[] password, boolean allowZeroByteClientId) {
        if (username == null || password == null) {
            LOG.info("username or password was null");
            return false;
        }
        String foundPwq = identities.get(username);
        if (foundPwq == null) {
            return false;
        }
        digest.update(password);
        byte[] digest = this.digest.digest();
        String encodedPasswd = new String(Hex.encodeHex(digest));
        return foundPwq.equals(encodedPasswd);
    }

}