/*
 * Copyright 2006 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

import java.net.*;
import java.io.*;
import java.util.regex.*;
import java.security.*;
import javax.net.ssl.*;

/*
 * This class handles one client connection. It will interpret and act on the
 * commands (like USER, GET, PUT etc...) sent through the socket passed to
 * the constructor.
 *
 * To function it needs to be provided 2 handlers, one for the filesystem
 * and one for authentication.
 * @see FileSystemHandler
 * @see AuthHandler
 * @see #setHandlers(FtpFileSystemHandler,FtpAuthHandler)
 */

public class FtpCommandHandler extends Thread {
    private FtpServer parent = null;
    private Socket cmd = null;
    private Socket oldCmd = null;
    private InetAddress clientAddr = null;
    private ServerSocket pasv = null;

    private BufferedReader in = null;

    private PrintStream out = null;

    private FtpFileSystemHandler fsh = null;
    private FtpAuthHandler auth = null;

    private boolean done = false;

    private String username = null;
    private String password = null;
    private String account = null;
    private boolean logged = false;
    private boolean epsvAll = false;
    private int dataPort = 0;
    private InetAddress dataAddress = null;
    private boolean pasvEnabled = true;
    private boolean portEnabled = true;
    private boolean extendedEnabled = true;
    private boolean binary = true;
    private String renameFrom = null;
    private long restart = 0;
    private boolean useCrypto = false;
    private boolean useDataCrypto = false;
    private SSLSocketFactory sslFact = null;

    private final int ERROR = -1;
    private final int QUIT = 0;
    private final int USER = 1;
    private final int PASS = 2;
    private final int CWD = 3;
    private final int CDUP = 4;
    private final int PWD = 5;
    private final int TYPE = 6;
    private final int NOOP = 7;
    private final int RETR = 8;
    private final int PORT = 9;
    private final int PASV = 10;
    private final int EPSV = 11;
    private final int EPRT = 12;
    private final int SYST = 13;
    private final int STOR = 14;
    private final int STOU = 15;
    private final int LIST = 16;
    private final int NLST = 17;
    private final int RNFR = 18;
    private final int RNTO = 19;
    private final int DELE = 20;
    private final int REST = 21;
    private final int AUTH = 22;
    private final int FEAT = 23;
    private final int CCC = 24;
    private final int PROT = 25;
    private final int PBSZ = 26;

    private String[] commands =
    { "QUIT", "USER", "PASS", "CWD", "CDUP", "PWD", "TYPE", "NOOP", "RETR",
      "PORT", "PASV", "EPSV", "EPRT", "SYST", "STOR", "STOU", "LIST", "NLST",
      "RNFR", "RNTO", "DELE", "REST", "AUTH", "FEAT", "CCC", "PROT", "PBSZ"
    };

    private boolean isPasvSet() {
        if (pasv != null && !pasvEnabled) {
            try {
                pasv.close();
            } catch ( IOException e) {

            }
            pasv = null;
        }
        if (pasvEnabled && pasv != null)
            return true;
        return false;
    }

    private OutputStream getOutDataStream() throws IOException {
        if (isPasvSet()) {
            Socket s = pasv.accept();
            if (useCrypto && useDataCrypto) {
                SSLSocket ssl = (SSLSocket) sslFact.createSocket(s, clientAddr.getHostName(), s.getPort(), true);
                ssl.setUseClientMode(false);
                s = ssl;
            }
            return s.getOutputStream();
        }
        if (dataAddress != null) {
            Socket s;
            if (useCrypto) {
                s = sslFact.createSocket(dataAddress, dataPort);
            } else
                s = new Socket(dataAddress, dataPort);
            dataAddress = null;
            dataPort = 0;
            return s.getOutputStream();
        }
        return null;
    }

    private InputStream getInDataStream() throws IOException {
        if (isPasvSet()) {
            Socket s = pasv.accept();
            if (useCrypto && useDataCrypto) {
                SSLSocket ssl = (SSLSocket) sslFact.createSocket(s, clientAddr.getHostName(), s.getPort(), true);
                ssl.setUseClientMode(false);
                s = ssl;
            }
            return s.getInputStream();
        }
        if (dataAddress != null) {
            Socket s;
            if (useCrypto) {
                s = sslFact.createSocket(dataAddress, dataPort);
            } else
                s = new Socket(dataAddress, dataPort);
            dataAddress = null;
            dataPort = 0;
            return s.getInputStream();
        }
        return null;
    }

    private void parsePort(String port_arg) throws IOException {
        if (epsvAll) {
            out.println("501 PORT not allowed after EPSV ALL.");
            return;
        }
        if (!portEnabled) {
            out.println("500 PORT command is disabled, please use PASV.");
            return;
        }
        StringBuffer host;
        int i = 0, j = 4;
        while (j > 0) {
            i = port_arg.indexOf(',', i + 1);
            if (i < 0)
                break;
            j--;
        }
        if (j != 0) {
            out.println("500 '" + port_arg + "': command not understood.");
            return;
        }
        try {
            host = new StringBuffer(port_arg.substring(0, i));
            for (j = 0; j < host.length(); j++)
                if (host.charAt(j) == ',')
                    host.setCharAt(j, '.');
            String ports = port_arg.substring(i + 1);
            i = ports.indexOf(',');
            dataPort = Integer.parseInt(ports.substring(0, i)) << 8;
            dataPort += (Integer.parseInt(ports.substring(i + 1)));
            dataAddress = InetAddress.getByName(host.toString());
            out.println("200 Command okay.");
        } catch (Exception ex3) {
            dataPort = 0;
            dataAddress = null;
            out.println("500 '" + port_arg + "': command not understood.");
        }
    }

    private void parseEprt(String arg) {
        if (epsvAll) {
            out.println("501 PORT not allowed after EPSV ALL");
            return;
        }
        if (!extendedEnabled || !portEnabled) {
            out.println("500 EPRT is disabled, use PASV instead");
            return;
        }
        Pattern p = Pattern.compile("\\|(\\d)\\|(.*)\\|(\\d+)\\|");
        Matcher m = p.matcher(arg);
        if (!m.find()) {
            out.println("500 '" + arg + "': command not understood.");
            return;
        }
        try {
            dataAddress = InetAddress.getByName(m.group(2));
        } catch (UnknownHostException e) {
            out.println("500 " + arg + ": invalid address.");
            dataAddress = null;
            return;
        }
        dataPort = Integer.parseInt(m.group(3));
        out.println("200 Command okay.");
    }

    private void doPasv() {
        if (!pasvEnabled) {
            out.println("500 PASV is disabled, use PORT.");
            return;
        }
        try {
            if (pasv == null)
                pasv = new ServerSocket(0);
            int port = pasv.getLocalPort();
            InetAddress rAddress = cmd.getLocalAddress();
            if (rAddress instanceof Inet6Address) {
                out.println("500 PASV illegal over IPv6 addresses, use EPSV.");
                return;
            }
            byte[] a = rAddress.getAddress();
            out.println("227 Entering Passive Mode " + a[0] + "," + a[1] + "," + a[2] + "," + a[3] + "," +
                        (port >> 8) + "," + (port & 0xff) );
        } catch (IOException e) {
            out.println("425 can't build data connection: Connection refused.");
        }
    }

    private void doEpsv(String arg) {
        if (!extendedEnabled || !pasvEnabled) {
            out.println("500 EPSV disabled, use PORT or PASV.");
            return;
        }
        if ("all".equalsIgnoreCase(arg)) {
            out.println("200 EPSV ALL Command successful.");
            epsvAll = true;
            return;
        }
        try {
            if (pasv == null)
                pasv = new ServerSocket(0);
            int port = pasv.getLocalPort();
            out.println("229 Entering Extended Passive Mode (|||" + port + "|)");
        } catch (IOException e) {
            out.println("500 Can't create data connection.");
        }
    }

    private void doRetr(String arg) {
        try {
            OutputStream dOut = getOutDataStream();
            if (dOut != null) {
                InputStream dIn = fsh.getFile(arg);
                if (dIn == null) {
                    out.println("550 File not found.");
                    dOut.close();
                    return;
                }
                out.println("150 Opening " + (binary ? "BINARY " : "ASCII ") + " data connection for file " + arg +
                            "(" + fsh.getFileSize(arg) + " bytes).");
                if (binary) {
                    byte[] buf = new byte[2048];
                    dOut = new BufferedOutputStream(dOut);
                    int count;
                    if (restart > 0) {
                        dIn.skip(restart);
                        restart = 0;
                    }
                    do {
                        count = dIn.read(buf);
                        if (count > 0)
                            dOut.write(buf, 0, count);
                    } while (count >= 0);
                    dOut.close();
                    dIn.close();
                    out.println("226 Transfer complete.");
                }
            }
        } catch (IOException e) {

        }
    }

    private void doStor(String arg, boolean unique) {
        try {
            InputStream dIn = getInDataStream();
            if (dIn != null) {
                OutputStream dOut = fsh.putFile(arg);
                if (dOut == null) {
                    out.println("500 Can't create file " + arg);
                    dIn.close();
                    return;
                }
                out.println("150 Opening " + (binary ? "BINARY " : "ASCII ") + " data connection for file " + arg);
                if (binary) {
                    byte[] buf = new byte[2048];
                    dOut = new BufferedOutputStream(dOut);
                    int count;
                    do {
                        count = dIn.read(buf);
                        if (count > 0)
                            dOut.write(buf, 0, count);
                    } while (count >= 0);
                    dOut.close();
                    dIn.close();
                    out.println("226 Transfer complete.");
                }
            }
        } catch (IOException e) {

        }
    }

    private void doList() {
        try {
            OutputStream dOut = getOutDataStream();
            if (dOut != null) {
                InputStream dIn = fsh.listCurrentDir();
                if (dIn == null) {
                    out.println("550 File not found.");
                    dOut.close();
                    return;
                }
                out.println("150 Opening ASCII data connection for file list");
                byte[] buf = new byte[2048];
                dOut = new BufferedOutputStream(dOut);
                int count;
                do {
                    count = dIn.read(buf);
                    if (count > 0)
                        dOut.write(buf, 0, count);
                } while (count >= 0);
                dOut.close();
                dIn.close();
                out.println("226 Transfer complete.");
            }
        } catch (IOException e) {

        }
    }

    private boolean useTLS() {
        if (sslFact == null) {
            sslFact = (SSLSocketFactory) SSLSocketFactory.getDefault();
        }
        if (sslFact == null)
            return false;
        return true;
    }

    private void stopTLS() {
        if (useCrypto) {
            SSLSocket ssl = (SSLSocket) cmd;
            try {
                ssl.close();
            } catch (IOException e) {
                // nada
            }
            cmd = oldCmd;
            oldCmd = null;
            try {
                in = new BufferedReader(new InputStreamReader(cmd.getInputStream()));
                out = new PrintStream(cmd.getOutputStream(), true, "ISO8859_1");
            } catch (Exception ex) {

            }
        }
    }

    public void setHandlers(FtpFileSystemHandler f, FtpAuthHandler a) {
        fsh = f;
        auth = a;
    }

    public FtpCommandHandler(Socket cl, FtpServer p) {
        parent = p;
        cmd = cl;
        clientAddr = cl.getInetAddress();
    }

    public void terminate() {
        done = true;
    }

    private int parseCmd(StringBuffer cmd) {

        if (cmd == null || cmd.length() < 3) // Shortest command is 3 char long
            return ERROR;
        int blank = cmd.indexOf(" ");
        if (blank < 0)
            blank = cmd.length();
        if (blank < 3)
            return ERROR;
        String s = cmd.substring(0,blank);
        cmd.delete(0, blank + 1);
        System.out.println("parse: cmd = " + s + " arg = " +cmd.toString());
        for (int i = 0; i < commands.length; i++)
            if (s.equalsIgnoreCase(commands[i]))
                return i;
        // Unknown command
        return ERROR;
    }

    private boolean checkLogged() {
        if (!logged) {
            out.println("530 Not logged in.");
            return false;
        }
        return true;
    }

    public void run() {
        try {
            // cmd.setSoTimeout(2000);
            in = new BufferedReader(new InputStreamReader(cmd.getInputStream()));
            out = new PrintStream(cmd.getOutputStream(), true, "ISO8859_1");
            out.println("220 Java FTP test server (j2se 6.0) ready.");
            out.flush();
            if (auth.authType() == 0) // No auth needed
                logged = true;
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }

        String str;
        StringBuffer buf;
        int res;
        while (!done) {
            try {
                str = in.readLine();
                System.out.println("line: " + str);
                buf = new StringBuffer(str);
                res = parseCmd(buf);
                switch (res) {
                case ERROR:
                    out.println("500 '" + str +"': command not understood.");
                    break;
                case QUIT:
                    out.println("221 Goodbye.");
                    done = true;
                    break;
                case USER:
                    logged = false;
                    username = buf.toString();
                    if (auth.authType() > 1)
                        out.println("331 User name okay, need password.");
                    else {
                        if (auth.authenticate(username, null)) {
                            out.println("230 User logged in, proceed.");
                            logged = true;
                        } else {
                            out.println("331 User name okay, need password.");
                        }
                    }
                    break;
                case PASS:
                    if (logged || (username == null)) {
                        out.println("503 Login with USER first.");
                        break;
                    }
                    password = buf.toString();
                    if (auth.authType() == 3) {
                        out.println("332 Need account for login.");
                        break;
                    }
                    if (auth.authenticate(username, password)) {
                        logged = true;
                        out.println("230 User " + username + " logged in.");
                        break;
                    }
                    out.println("530 Login incorrect.");
                    username = null;
                    break;
                case CWD:
                    if (checkLogged()) {
                        String path = buf.toString();
                        if (fsh.cd(path)) {
                            out.println("250 CWD command successful.");
                        } else {
                            out.println("550 " + path + ": no such file or directory.");
                        }
                    }
                    break;
                case CDUP:
                    if (checkLogged()) {
                        if (fsh.cdUp())
                            out.println("250 CWD command successful.");
                        else
                            out.println("550 invalid path.");
                    }
                    break;
                case PWD:
                    if (checkLogged()) {
                        String s = fsh.pwd();
                        out.println("257 \"" + s + "\" is current directory");
                    }
                    break;
                case NOOP:
                    if (checkLogged()) {
                        out.println("200 NOOP command successful.");
                    }
                    break;
                case PORT:
                    if (checkLogged()) {
                        parsePort(buf.toString());
                    }
                    break;
                case EPRT:
                    if (checkLogged()) {
                        parseEprt(buf.toString());
                    }
                    break;
                case PASV:
                    if (checkLogged())
                        doPasv();
                    break;
                case EPSV:
                    if (checkLogged())
                        doEpsv(buf.toString());
                    break;
                case RETR:
                    if (checkLogged()) {
                        doRetr(buf.toString());
                    }
                    break;
                case SYST:
                    if (checkLogged()) {
                        out.println("215 UNIX Type: L8 Version: Java 6.0");
                    }
                    break;
                case TYPE:
                    if (checkLogged()) {
                        String arg = buf.toString();
                        if (arg.length() != 1 || "AIE".indexOf(arg.charAt(0)) < 0) {
                            out.println("500 'TYPE " + arg + "' command not understood.");
                            continue;
                        }
                        out.println("200 Type set to " + buf.toString() + ".");
                        if (arg.charAt(0) == 'I')
                            binary = true;
                        else
                            binary = false;
                    }
                    break;
                case STOR:
                case STOU:
                    // TODO: separate STOR and STOU (Store Unique)
                    if (checkLogged()) {
                        doStor(buf.toString(), false);
                    }
                    break;
                case LIST:
                    if (checkLogged()) {
                        doList();
                    }
                    break;
                case NLST:
                    // TODO: implememt
                    break;
                case DELE:
                    if (checkLogged()) {
                        String arg = buf.toString();
                        if (fsh.removeFile(arg)) {
                            out.println("250 file " + arg + " deleted.");
                            break;
                        }
                        out.println("550 " + arg + ": no such file or directory.");
                    }
                    break;
                case RNFR:
                    if (checkLogged()) {
                        if (renameFrom != null) {
                            out.println("503 Bad sequence of commands.");
                            break;
                        }
                        renameFrom = buf.toString();
                        if (fsh.fileExists(renameFrom)) {
                            out.println("350 File or directory exists, ready for destination name.");
                        } else {
                            out.println("550 " + renameFrom + ": no such file or directory");
                            renameFrom = null;
                        }
                    }
                    break;
                case RNTO:
                    if (checkLogged()) {
                        if (renameFrom == null) {
                            out.println("503 Bad sequence of commands.");
                            break;
                        }
                        if (fsh.rename(renameFrom, buf.toString())) {
                            out.println("250 Rename successful");
                        } else {
                            out.println("550 Rename ");
                        }
                        renameFrom = null;
                    }
                    break;
                case REST:
                    if (checkLogged()) {
                        String arg = buf.toString();
                        restart = Long.parseLong(arg);
                        if (restart > 0)
                            out.println("350 Restarting at " + restart + ". Send STORE or RETRIEVE to initiate transfer");
                        else
                            out.println("501 Syntax error in command of arguments.");
                    }
                    break;
                case FEAT:
                    out.println("211-Features:");
                    out.println(" REST STREAM");
                    out.println(" PBSZ");
                    out.println(" AUTH TLS");
                    out.println(" PROT P");
                    out.println(" CCC");
                    out.println("211 End");
                    break;
                case AUTH:
                    if ("TLS".equalsIgnoreCase(buf.toString()) && useTLS()) {
                        out.println("234 TLS Authentication OK.");
                        out.flush();
                        SSLSocket ssl;
                        String[] suites = sslFact.getSupportedCipherSuites();
                        try {
                            ssl = (SSLSocket) sslFact.createSocket(cmd, cmd.getInetAddress().getHostName(), cmd.getPort(), false);
                            ssl.setUseClientMode(false);
                            ssl.setEnabledCipherSuites(suites);
                            ssl.startHandshake();
                        } catch (IOException ioe) {
                            ioe.printStackTrace();
                            out.println("550 Unable to create secure channel.");
                            break;
                        }
                        oldCmd = cmd;
                        cmd = ssl;
                        out = new PrintStream(cmd.getOutputStream(), true, "ISO8859_1");
                        in = new BufferedReader(new InputStreamReader(cmd.getInputStream()));
                        System.out.println("Secure socket created!");
                        useCrypto = true;
                        break;
                    }
                    out.println("501 Unknown or unsupported AUTH type");
                    break;
                case CCC:
                    out.println("200 Command OK.");
                    stopTLS();
                    break;
                case PROT:
                    String arg = buf.toString();
                    if ("C".equalsIgnoreCase(arg)) {
                        // PROT C : Clear protection level
                        // No protection on data channel;
                        useDataCrypto = false;
                        out.println("200 Command OK.");
                        break;
                    }
                    if ("P".equalsIgnoreCase(arg)) {
                        // PROT P : Private protection level
                        // Data channel is integrity and confidentiality protected
                        useDataCrypto = true;
                        out.println("200 Command OK.");
                        break;
                    }
                    out.println("537 Requested PROT level not supported by security mechanism.");
                    break;
                case PBSZ:
                    // TODO: finish
                    out.println("200 Command OK.");
                    break;

                }

            } catch (InterruptedIOException ie) {
                // loop
            } catch (IOException e) {
                e.printStackTrace();
                return;
            }
        }
        try {
            in.close();
            out.close();
            cmd.close();
        } catch (IOException e) {
        }
        parent.removeClient(this);
    }
}
