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.sftp;
018
019import java.util.Arrays;
020import java.util.Collection;
021import java.util.Collections;
022
023import org.apache.commons.vfs2.Capability;
024import org.apache.commons.vfs2.FileName;
025import org.apache.commons.vfs2.FileSystem;
026import org.apache.commons.vfs2.FileSystemConfigBuilder;
027import org.apache.commons.vfs2.FileSystemException;
028import org.apache.commons.vfs2.FileSystemOptions;
029import org.apache.commons.vfs2.UserAuthenticationData;
030import org.apache.commons.vfs2.provider.AbstractOriginatingFileProvider;
031import org.apache.commons.vfs2.provider.GenericFileName;
032import org.apache.commons.vfs2.util.UserAuthenticatorUtils;
033
034import com.jcraft.jsch.Session;
035
036/**
037 * A provider for accessing files over SFTP.
038 */
039public class SftpFileProvider extends AbstractOriginatingFileProvider {
040
041    /** User Information. */
042    public static final String ATTR_USER_INFO = "UI";
043
044    /** Authentication types. */
045    public static final UserAuthenticationData.Type[] AUTHENTICATOR_TYPES = {
046            UserAuthenticationData.USERNAME, UserAuthenticationData.PASSWORD };
047
048    /** The provider's capabilities. */
049    protected static final Collection<Capability> capabilities = Collections.unmodifiableCollection(Arrays.asList(Capability.CREATE, Capability.DELETE,
050        Capability.RENAME, Capability.GET_TYPE, Capability.LIST_CHILDREN, Capability.READ_CONTENT, Capability.URI, Capability.WRITE_CONTENT,
051        Capability.GET_LAST_MODIFIED, Capability.SET_LAST_MODIFIED_FILE, Capability.RANDOM_ACCESS_READ, Capability.APPEND_CONTENT));
052
053    /**
054     * Creates a new Session.
055     *
056     * @return A Session, never null.
057     */
058    static Session createSession(final GenericFileName rootName, final FileSystemOptions fileSystemOptions)
059            throws FileSystemException {
060        UserAuthenticationData authData = null;
061        try {
062            authData = UserAuthenticatorUtils.authenticate(fileSystemOptions, AUTHENTICATOR_TYPES);
063
064            return SftpClientFactory.createConnection(rootName.getHostName(), rootName.getPort(),
065                    UserAuthenticatorUtils.getData(authData, UserAuthenticationData.USERNAME,
066                            UserAuthenticatorUtils.toChar(rootName.getUserName())),
067                    UserAuthenticatorUtils.getData(authData, UserAuthenticationData.PASSWORD,
068                            UserAuthenticatorUtils.toChar(rootName.getPassword())),
069                    fileSystemOptions);
070        } catch (final Exception e) {
071            throw new FileSystemException("vfs.provider.sftp/connect.error", rootName, e);
072        } finally {
073            UserAuthenticatorUtils.cleanup(authData);
074        }
075    }
076
077    /**
078     * Constructs a new provider.
079     */
080    public SftpFileProvider() {
081        setFileNameParser(SftpFileNameParser.getInstance());
082    }
083
084    /**
085     * Creates a {@link FileSystem}.
086     */
087    @Override
088    protected FileSystem doCreateFileSystem(final FileName name, final FileSystemOptions fileSystemOptions)
089            throws FileSystemException {
090        // Create the file system
091        return new SftpFileSystem((GenericFileName) name, createSession((GenericFileName) name, fileSystemOptions),
092                fileSystemOptions);
093    }
094
095    @Override
096    public Collection<Capability> getCapabilities() {
097        return capabilities;
098    }
099
100    @Override
101    public FileSystemConfigBuilder getConfigBuilder() {
102        return SftpFileSystemConfigBuilder.getInstance();
103    }
104}