001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.vfs2.provider.ftps;
018
019import javax.net.ssl.KeyManager;
020import javax.net.ssl.TrustManager;
021
022import org.apache.commons.net.util.TrustManagerUtils;
023import org.apache.commons.vfs2.FileSystemOptions;
024import org.apache.commons.vfs2.provider.ftp.FtpFileSystemConfigBuilder;
025
026/**
027 * The configuration builder for various FTPS configuration options.
028 *
029 * @since 2.0
030 */
031public final class FtpsFileSystemConfigBuilder extends FtpFileSystemConfigBuilder {
032    private static final String _PREFIX = FtpsFileSystemConfigBuilder.class.getName();
033
034    private static final FtpsFileSystemConfigBuilder BUILDER = new FtpsFileSystemConfigBuilder();
035
036    private static final String FTPS_MODE = _PREFIX + ".FTPS_MODE";
037    private static final String PROT = _PREFIX + ".PROT";
038    private static final String KEY_MANAGER = _PREFIX + ".KEY_MANAGER";
039    private static final String TRUST_MANAGER = _PREFIX + ".TRUST_MANAGER";
040
041    private FtpsFileSystemConfigBuilder() {
042        super("ftps.");
043    }
044
045    /**
046     * Gets the singleton builder.
047     *
048     * @return the singleton builder.
049     */
050    public static FtpsFileSystemConfigBuilder getInstance() {
051        return BUILDER;
052    }
053
054    /**
055     * Set FTPS mode, either "implicit" or "explicit".
056     *
057     * <p>
058     * Note, that implicit mode is not standardized and considered as deprecated. Some unit tests for VFS fail with
059     * implicit mode and it is not yet clear if its a problem with Commons VFS/Commons Net or our test server Apache
060     * FTP/SSHD.
061     * </p>
062     *
063     * @param opts The FileSystemOptions.
064     * @param ftpsMode The mode to establish a FTPS connection.
065     * @see <a href="http://en.wikipedia.org/wiki/FTPS#Implicit">Wikipedia: FTPS/Implicit</a>
066     * @since 2.1
067     */
068    public void setFtpsMode(final FileSystemOptions opts, final FtpsMode ftpsMode) {
069        setParam(opts, FTPS_MODE, ftpsMode);
070    }
071
072    /**
073     * Return the FTPS mode. Defaults to "explicit" if not defined.
074     *
075     * @param opts The FileSystemOptions.
076     * @return The file type.
077     * @see #setFtpsType
078     */
079    public FtpsMode getFtpsMode(final FileSystemOptions opts) {
080        return getEnum(FtpsMode.class, opts, FTPS_MODE, FtpsMode.EXPLICIT);
081    }
082
083    /**
084     * Set FTPS type, either "implicit" or "explicit".
085     * <p>
086     * Note, that implicit mode is not standardized and considered as deprecated. Some unit tests for VFS fail with
087     * implicit mode and it is not yet clear if its a problem with Commons VFS/Commons Net or our test server Apache
088     * FTP/SSHD.
089     * </p>
090     *
091     * @param opts The FileSystemOptions.
092     * @param ftpsType The file type.
093     * @see <a href="http://en.wikipedia.org/wiki/FTPS#Implicit">Wikipedia: FTPS/Implicit</a>
094     * @deprecated As of 2.1, use {@link #setFtpsMode(FileSystemOptions, FtpsMode)}
095     */
096    @Deprecated
097    public void setFtpsType(final FileSystemOptions opts, final String ftpsType) {
098        final FtpsMode mode;
099        if (ftpsType != null) {
100            mode = FtpsMode.valueOf(ftpsType.toUpperCase());
101            if (mode == null) {
102                throw new IllegalArgumentException("Not a proper FTPS mode: " + ftpsType);
103            }
104        } else {
105            mode = null;
106        }
107        setFtpsMode(opts, mode);
108    }
109
110    /**
111     * Return the FTPS type. Defaults to "explicit" if not defined.
112     *
113     * @param opts The FileSystemOptions.
114     * @return The file type.
115     * @see #setFtpsType
116     * @deprecated As of 2.1, use {@link #getFtpsMode(FileSystemOptions)}
117     */
118    @Deprecated
119    public String getFtpsType(final FileSystemOptions opts) {
120        return getFtpsMode(opts).name().toLowerCase();
121    }
122
123    /**
124     * Gets the data channel protection level (PROT).
125     *
126     * @param opts The FileSystemOptions.
127     * @return The PROT value.
128     * @see org.apache.commons.net.ftp.FTPSClient#execPROT(String)
129     * @since 2.1
130     */
131    public FtpsDataChannelProtectionLevel getDataChannelProtectionLevel(final FileSystemOptions opts) {
132        return getEnum(FtpsDataChannelProtectionLevel.class, opts, PROT);
133    }
134
135    /**
136     * Sets the data channel protection level (PROT).
137     *
138     * @param opts The FileSystemOptions.
139     * @param prot The PROT value, {@code null} has no effect.
140     * @see org.apache.commons.net.ftp.FTPSClient#execPROT(String)
141     * @since 2.1
142     */
143    public void setDataChannelProtectionLevel(final FileSystemOptions opts, final FtpsDataChannelProtectionLevel prot) {
144        setParam(opts, PROT, prot);
145    }
146
147    /**
148     * Gets the KeyManager used to provide a client-side certificate if the FTPS server requests it.
149     *
150     * @param opts The FileSystemOptions.
151     * @return the key manager instance or {@code null}
152     * @see org.apache.commons.net.ftp.FTPSClient#setKeyManager(KeyManager)
153     * @since 2.1
154     */
155    public KeyManager getKeyManager(final FileSystemOptions opts) {
156        return (KeyManager) getParam(opts, KEY_MANAGER);
157    }
158
159    /**
160     * Sets the KeyManager used to provide a client-side certificate if the FTPS server requests it.
161     *
162     * @param opts The FileSystemOptions.
163     * @param keyManager The key manager instance.
164     * @see org.apache.commons.net.ftp.FTPSClient#setKeyManager(KeyManager)
165     * @since 2.1
166     */
167    public void setKeyManager(final FileSystemOptions opts, final KeyManager keyManager) {
168        setParam(opts, KEY_MANAGER, keyManager);
169    }
170
171    /**
172     * Gets the TrustManager that validates the FTPS server's certificate.
173     * <p>
174     * If the params do not contain the key for the trust manager, it will return a trust manger that simply checks this
175     * certificate for validity.
176     * </p>
177     *
178     * @param opts The FileSystemOptions.
179     * @return the trust manager instance or {@code null}
180     * @see org.apache.commons.net.ftp.FTPSClient#setTrustManager(TrustManager)
181     * @since 2.1
182     */
183    public TrustManager getTrustManager(final FileSystemOptions opts) {
184        final TrustManager trustManager;
185        if (hasParam(opts, TRUST_MANAGER)) {
186            trustManager = (TrustManager) getParam(opts, TRUST_MANAGER);
187        } else {
188            trustManager = TrustManagerUtils.getValidateServerCertificateTrustManager();
189        }
190        return trustManager;
191    }
192
193    /**
194     * Sets the TrustManager that validates the FTPS server's certificate.
195     *
196     * @param opts The FileSystemOptions.
197     * @param trustManager The trust manager instance.
198     * @see org.apache.commons.net.ftp.FTPSClient#setTrustManager(TrustManager)
199     * @since 2.1
200     */
201    public void setTrustManager(final FileSystemOptions opts, final TrustManager trustManager) {
202        setParam(opts, TRUST_MANAGER, trustManager);
203    }
204}