/* * ftp4j - A pure Java FTP client library * * Copyright (C) 2008-2010 Carlo Pelliccia (www.sauronsoftware.it) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version * 2.1, as published by the Free Software Foundation. * * 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 Lesser General Public License 2.1 for more details. * * You should have received a copy of the GNU Lesser General Public * License version 2.1 along with this program. * If not, see . */ package it.sauronsoftware.ftp4j.connectors; import it.sauronsoftware.ftp4j.FTPCommunicationChannel; import it.sauronsoftware.ftp4j.FTPConnector; import it.sauronsoftware.ftp4j.FTPIllegalReplyException; import it.sauronsoftware.ftp4j.FTPReply; import java.io.IOException; import java.net.Socket; /** * This one connects a remote host via a FTP proxy which supports the SITE or * the OPEN proxy method. * * The connector's default value for the * useSuggestedAddressForDataConnections flag is true. * * @author Carlo Pelliccia */ public class FTPProxyConnector extends FTPConnector { /** * Requires the connection to the remote host through a SITE command after * proxy authentication. Default one. */ public static final int STYLE_SITE_COMMAND = 0; /** * Requires the connection to the remote host through a OPEN command without * proxy authentication. */ public static final int STYLE_OPEN_COMMAND = 1; /** * The proxy host name. */ private String proxyHost; /** * The proxy port. */ private int proxyPort; /** * The proxyUser for proxy authentication. */ private String proxyUser; /** * The proxyPass for proxy authentication. */ private String proxyPass; /** * The style used by the proxy. */ public int style = STYLE_SITE_COMMAND; /** * Builds the connector. * * Default value for the style is STYLE_SITE_COMMAND. * * @param proxyHost * The proxy host name. * @param proxyPort * The proxy port. * @param proxyUser * The username for proxy authentication. * @param proxyPass * The password for proxy authentication. */ public FTPProxyConnector(String proxyHost, int proxyPort, String proxyUser, String proxyPass) { super(true); this.proxyHost = proxyHost; this.proxyPort = proxyPort; this.proxyUser = proxyUser; this.proxyPass = proxyPass; } /** * Builds the connector. * * Default value for the style is STYLE_SITE_COMMAND. * * @param proxyHost * The proxy host name. * @param proxyPort * The proxy port. */ public FTPProxyConnector(String proxyHost, int proxyPort) { this(proxyHost, proxyPort, "anonymous", "ftp4j"); } /** * Sets the style used by the proxy. * * {@link FTPProxyConnector#STYLE_SITE_COMMAND} - Requires the connection to * the remote host through a SITE command after proxy authentication. * * {@link FTPProxyConnector#STYLE_OPEN_COMMAND} - Requires the connection to * the remote host through a OPEN command without proxy authentication. * * Default value for the style is STYLE_SITE_COMMAND. * * @param style * The style. * @see FTPProxyConnector#STYLE_SITE_COMMAND * @see FTPProxyConnector#STYLE_OPEN_COMMAND */ public void setStyle(int style) { if (style != STYLE_OPEN_COMMAND && style != STYLE_SITE_COMMAND) { throw new IllegalArgumentException("Invalid style"); } this.style = style; } public Socket connectForCommunicationChannel(String host, int port) throws IOException { Socket socket = tcpConnectForCommunicationChannel(proxyHost, proxyPort); FTPCommunicationChannel communication = new FTPCommunicationChannel( socket, "ASCII"); // Welcome message. FTPReply r; try { r = communication.readFTPReply(); } catch (FTPIllegalReplyException e) { throw new IOException("Invalid proxy response"); } // Does this reply mean "ok"? if (r.getCode() != 220) { // Mmmmm... it seems no! throw new IOException("Invalid proxy response"); } if (style == STYLE_SITE_COMMAND) { // Usefull flags. boolean passwordRequired; // Send the user and read the reply. communication.sendFTPCommand("USER " + proxyUser); try { r = communication.readFTPReply(); } catch (FTPIllegalReplyException e) { throw new IOException("Invalid proxy response"); } switch (r.getCode()) { case 230: // Password isn't required. passwordRequired = false; break; case 331: // Password is required. passwordRequired = true; break; default: // User validation failed. throw new IOException("Proxy authentication failed"); } // Password. if (passwordRequired) { // Send the password. communication.sendFTPCommand("PASS " + proxyPass); try { r = communication.readFTPReply(); } catch (FTPIllegalReplyException e) { throw new IOException("Invalid proxy response"); } if (r.getCode() != 230) { // Authentication failed. throw new IOException("Proxy authentication failed"); } } communication.sendFTPCommand("SITE " + host + ":" + port); } else if (style == STYLE_OPEN_COMMAND) { communication.sendFTPCommand("OPEN " + host + ":" + port); } return socket; } public Socket connectForDataTransferChannel(String host, int port) throws IOException { return tcpConnectForDataTransferChannel(host, port); } }