/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.ftpserver.command.impl;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.List;

import org.apache.ftpserver.command.AbstractCommand;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.FtpReply;
import org.apache.ftpserver.ftplet.FtpRequest;
import org.apache.ftpserver.impl.FtpIoSession;
import org.apache.ftpserver.impl.FtpServerContext;
import org.apache.ftpserver.impl.LocalizedFtpReply;
import org.apache.ftpserver.ssl.ClientAuth;
import org.apache.ftpserver.ssl.SslConfiguration;
import org.apache.mina.filter.ssl.SslFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <strong>Internal class, do not use directly.</strong>
 * 
 * This server supports explicit SSL support.
 *
 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
 */
public class AUTH extends AbstractCommand {

    private static final String SSL_SESSION_FILTER_NAME = "sslSessionFilter";

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

    private static final List<String> VALID_AUTH_TYPES = Arrays.asList("SSL", "TLS", "TLS-C", "TLS-P");

    /**
     * Execute command
     */
    public void execute(final FtpIoSession session, final FtpServerContext context, final FtpRequest request)
        throws IOException, FtpException {

    // reset state variables
    session.resetState();

    // argument check
    if (!request.hasArgument()) {
        session.write(LocalizedFtpReply.translate(session, request, context,
            FtpReply.REPLY_501_SYNTAX_ERROR_IN_PARAMETERS_OR_ARGUMENTS, "AUTH", null));
        return;
    }

    // check SSL configuration
    if (session.getListener().getSslConfiguration() == null) {
        session.write(LocalizedFtpReply.translate(session, request, context, 431, "AUTH", null));
        return;
    }

    // check that we don't already have a SSL filter in place due to running
    // in implicit mode
    // or because the AUTH command has already been issued. This is what the
    // RFC says:

    // "Some servers will allow the AUTH command to be reissued in order
    // to establish new authentication. The AUTH command, if accepted,
    // removes any state associated with prior FTP Security commands.
    // The server must also require that the user reauthorize (that is,
    // reissue some or all of the USER, PASS, and ACCT commands) in this
    // case (see section 4 for an explanation of "authorize" in this
    // context)."

    // Here we choose not to support reissued AUTH
    if (session.getFilterChain().contains(SslFilter.class)) {
        session.write(LocalizedFtpReply.translate(session, request, context, 534, "AUTH", null));
        return;
    }

    // check parameter
    String authType = request.getArgument().toUpperCase();
    if (VALID_AUTH_TYPES.contains(authType)) {
        if (authType.equals("TLS-C")) {
        authType = "TLS";
        } else if (authType.equals("TLS-P")) {
        authType = "SSL";
        }

        try {
        secureSession(session, authType);
        session.write(LocalizedFtpReply.translate(session, request, context, 234, "AUTH." + authType, null));
        } catch (FtpException ex) {
        throw ex;
        } catch (Exception ex) {
        LOG.warn("AUTH.execute()", ex);
        throw new FtpException("AUTH.execute()", ex);
        }
    } else {
        session.write(LocalizedFtpReply.translate(session, request, context,
            FtpReply.REPLY_502_COMMAND_NOT_IMPLEMENTED, "AUTH", null));
    }
    }

    private void secureSession(final FtpIoSession session, final String type)
        throws GeneralSecurityException, FtpException {
        SslConfiguration ssl = session.getListener().getSslConfiguration();
    
        if (ssl != null) {
            session.setAttribute(SslFilter.DISABLE_ENCRYPTION_ONCE);
    
            SslFilter sslFilter = new SslFilter(ssl.getSSLContext());
            if (ssl.getClientAuth() == ClientAuth.NEED) {
            sslFilter.setNeedClientAuth(true);
            } else if (ssl.getClientAuth() == ClientAuth.WANT) {
            sslFilter.setWantClientAuth(true);
            }
    
            // note that we do not care about the protocol, we allow both types
            // and leave it to the SSL handshake to determine the protocol to
            // use. Thus the type argument is ignored.
    
            if (ssl.getEnabledCipherSuites() != null) {
            sslFilter.setEnabledCipherSuites(ssl.getEnabledCipherSuites());
            }
    
            if (ssl.getEnabledProtocol() != null) {
            sslFilter.setEnabledProtocols(new String[] { ssl.getEnabledProtocol() });
            }
    
            session.getFilterChain().addFirst(SSL_SESSION_FILTER_NAME, sslFilter);
    
            if ("SSL".equals(type)) {
            session.getDataConnection().setSecure(true);
            }
        } else {
            throw new FtpException("Socket factory SSL not configured");
        }
    }
}
