/* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * For information about the authors of this project Have a look * at the AUTHORS file in the root of this project. */ package net.sourceforge.fullsync.fs.filesystems; import java.io.File; import java.util.Arrays; import net.sourceforge.fullsync.ConnectionDescription; import net.sourceforge.fullsync.fs.FileSystemAuthProvider; import net.sourceforge.fullsync.impl.SFTPLogger; import net.sourceforge.fullsync.ui.GuiController; import net.sourceforge.fullsync.ui.OptionsDialog; import org.apache.commons.vfs2.FileSystemException; import org.apache.commons.vfs2.FileSystemOptions; import org.apache.commons.vfs2.auth.StaticUserAuthenticator; import org.apache.commons.vfs2.impl.DefaultFileSystemConfigBuilder; import org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder; import org.eclipse.swt.SWT; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.jcraft.jsch.JSch; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; class SFTPAuthProvider implements FileSystemAuthProvider, UIKeyboardInteractive, UserInfo { private static final String sshDirName; private static final Logger logger = LoggerFactory.getLogger("FullSync"); static { JSch.setLogger(new SFTPLogger()); String sshDirPath = System.getProperty("vfs.sftp.sshdir"); if (sshDirPath == null) { sshDirPath = System.getProperty("user.home") + File.separator + ".ssh"; } File sshDir = new File(sshDirPath); if (!sshDir.exists() && !sshDir.mkdirs()) { logger.warn("failed to create the .ssh directory, remembering SSH keys likely won't work... (tried: " + sshDir.getAbsolutePath().toString() + ")"); sshDir = null; sshDirName = null; } else { sshDirName = sshDirPath; } if (null != sshDir) { System.setProperty("vfs.sftp.sshdir", sshDir.getAbsolutePath()); } } private final ConnectionDescription desc; SFTPAuthProvider(final ConnectionDescription _desc) { desc = _desc; } @Override public final void authSetup(final ConnectionDescription description, final FileSystemOptions options) throws FileSystemException { StaticUserAuthenticator auth = new StaticUserAuthenticator(null, description.getParameter(ConnectionDescription.PARAMETER_USERNAME), description.getSecretParameter(ConnectionDescription.PARAMETER_PASSWORD)); DefaultFileSystemConfigBuilder.getInstance().setUserAuthenticator(options, auth); SftpFileSystemConfigBuilder cfg = SftpFileSystemConfigBuilder.getInstance(); //TODO: add cfg.setUserDirIsRoot(opts, false); and handle profile updates if (null != sshDirName) { cfg.setKnownHosts(options, new File(sshDirName, "known_hosts")); } logger.debug("SFTP using knownHosts: ", cfg.getKnownHosts(options)); cfg.setUserInfo(options, this); cfg.setStrictHostKeyChecking(options, "ask"); if ("enabled".equals(description.getParameter("publicKeyAuth"))) { cfg.setPreferredAuthentications(options, "publickey,password,keyboard-interactive"); } else { cfg.setPreferredAuthentications(options, "password,keyboard-interactive"); } } @Override public final String getPassphrase() { logger.debug("SFTP UserInfo::getPassphrase"); return desc.getSecretParameter("keyPassphrase"); } @Override public final String getPassword() { logger.debug("SFTP UserInfo::getPassword"); return desc.getSecretParameter(ConnectionDescription.PARAMETER_PASSWORD); } @Override public final boolean promptPassword(final String message) { logger.debug("SFTP UserInfo::promptPassword: " + message); return true; } @Override public final boolean promptPassphrase(final String message) { logger.debug("SFTP UserInfo::promptPassphrase: " + message); return true; } @Override public final boolean promptYesNo(final String message) { final boolean[] arr = new boolean[] { false }; if (null != desc.getParameter(ConnectionDescription.PARAMETER_INTERACTIVE)) { GuiController.getInstance().getDisplay().syncExec(() -> { OptionsDialog od = new OptionsDialog(GuiController.getInstance().getMainShell(), SWT.ICON_QUESTION); od.setText("Question - FullSync"); //FIXME: translate od.setMessage(message); //FIXE: translate message od.setOptions(new String[] { "Yes", "No" }); //FIXME: translate if ("Yes".equals(od.open())) { //FIXME: translate arr[0] = true; } }); } else { logger.warn("SFTP UserInfo::promptYesNo: " + message + "; automatic decision: No"); } return arr[0]; } @Override public final void showMessage(final String message) { logger.warn("SFTP UserInfo::showMessage: " + message); } @Override public final String[] promptKeyboardInteractive(final String destination, final String name, final String instruction, final String[] prompt, final boolean[] echo) { logger.warn("Suppressed promptKeyboardInteractive:"); logger.warn("Destination: " + destination); logger.warn("Name: " + name); logger.warn("Instruction: " + instruction); logger.warn("Prompt (#" + prompt.length + "): " + Arrays.toString(prompt)); logger.warn("echo: (#" + echo.length + "): " + Arrays.toString(echo)); logger.warn("rejecting prompt automatically"); return null; } }