Beispiel #1
0
        /// <summary>
        /// Opens a FXP PASV connection between the source FTP Server and the destination FTP Server
        /// </summary>
        /// <param name="remoteClient">FtpClient instance of the destination FTP Server</param>
        /// <returns>A data stream ready to be used</returns>
        private FtpFxpSession OpenPassiveFXPConnection(FtpClient remoteClient)
        {
            FtpReply  reply;
            Match     m;
            FtpClient sourceClient      = null;
            FtpClient destinationClient = null;

            if (EnableThreadSafeDataConnections)
            {
                sourceClient = CloneConnection();
                sourceClient._AutoDispose = true;
                sourceClient.CopyStateFlags(this);
                sourceClient.Connect();
                sourceClient.SetWorkingDirectory(GetWorkingDirectory());
            }
            else
            {
                sourceClient = this;
            }

            if (remoteClient.EnableThreadSafeDataConnections)
            {
                destinationClient = remoteClient.CloneConnection();
                destinationClient._AutoDispose = true;
                destinationClient.CopyStateFlags(remoteClient);
                destinationClient.Connect();
                destinationClient.SetWorkingDirectory(destinationClient.GetWorkingDirectory());
            }
            else
            {
                destinationClient = remoteClient;
            }

            sourceClient.SetDataType(sourceClient.FXPDataType);
            destinationClient.SetDataType(destinationClient.FXPDataType);

            // send PASV command to destination FTP server to get passive port to be used from source FTP server
            if (!(reply = destinationClient.Execute("PASV")).Success)
            {
                throw new FtpCommandException(reply);
            }

            m = Regex.Match(reply.Message, @"(?<quad1>\d+)," + @"(?<quad2>\d+)," + @"(?<quad3>\d+)," + @"(?<quad4>\d+)," + @"(?<port1>\d+)," + @"(?<port2>\d+)");

            if (!m.Success || m.Groups.Count != 7)
            {
                throw new FtpException("Malformed PASV response: " + reply.Message);
            }

            // Instruct source server to open a connection to the destination Server

            if (!(reply = sourceClient.Execute($"PORT {m.Value}")).Success)
            {
                throw new FtpCommandException(reply);
            }

            return(new FtpFxpSession {
                SourceServer = sourceClient, TargetServer = destinationClient
            });
        }
        /// <summary>
        /// Opens a FXP PASV connection between the source FTP Server and the destination FTP Server
        /// </summary>
        /// <param name="remoteClient">FtpClient instance of the destination FTP Server</param>
        /// <returns>A data stream ready to be used</returns>
        private FtpFxpSession OpenPassiveFXPConnection(FtpClient remoteClient, bool trackProgress)
        {
            FtpReply  reply, reply2;
            Match     m;
            FtpClient sourceClient      = null;
            FtpClient destinationClient = null;
            FtpClient progressClient    = null;

            // create a new connection to the source FTP server if EnableThreadSafeDataConnections is set
            if (EnableThreadSafeDataConnections)
            {
                sourceClient = CloneConnection();
                sourceClient._AutoDispose = true;
                sourceClient.CopyStateFlags(this);
                sourceClient.Connect();
                sourceClient.SetWorkingDirectory(GetWorkingDirectory());
            }
            else
            {
                sourceClient = this;
            }

            // create a new connection to the target FTP server if EnableThreadSafeDataConnections is set
            if (remoteClient.EnableThreadSafeDataConnections)
            {
                destinationClient = remoteClient.CloneConnection();
                destinationClient._AutoDispose = true;
                destinationClient.CopyStateFlags(remoteClient);
                destinationClient.Connect();
                destinationClient.SetWorkingDirectory(remoteClient.GetWorkingDirectory());
            }
            else
            {
                destinationClient = remoteClient;
            }

            // create a new connection to the target FTP server to track progress
            // if progress tracking is enabled during this FXP transfer
            if (trackProgress)
            {
                progressClient = remoteClient.CloneConnection();
                progressClient._AutoDispose = true;
                progressClient.CopyStateFlags(remoteClient);
                progressClient.Connect();
                progressClient.SetWorkingDirectory(remoteClient.GetWorkingDirectory());
            }

            sourceClient.SetDataType(sourceClient.FXPDataType);
            destinationClient.SetDataType(destinationClient.FXPDataType);

            // send PASV/CPSV commands to destination FTP server to get passive port to be used from source FTP server
            // first try with PASV - commonly supported by all servers
            if (!(reply = destinationClient.Execute("PASV")).Success)
            {
                // then try with CPSV - known to be supported by glFTPd server
                // FIXES #666 - glFTPd server - 435 Failed TLS negotiation on data channel
                if (!(reply2 = destinationClient.Execute("CPSV")).Success)
                {
                    throw new FtpCommandException(reply);
                }
                else
                {
                    // use the CPSV response and extract the port from it
                    reply = reply2;
                }
            }

            // extract port from response
            m = Regex.Match(reply.Message, @"(?<quad1>\d+)," + @"(?<quad2>\d+)," + @"(?<quad3>\d+)," + @"(?<quad4>\d+)," + @"(?<port1>\d+)," + @"(?<port2>\d+)");
            if (!m.Success || m.Groups.Count != 7)
            {
                throw new FtpException("Malformed PASV response: " + reply.Message);
            }

            // Instruct source server to open a connection to the destination Server

            if (!(reply = sourceClient.Execute($"PORT {m.Value}")).Success)
            {
                throw new FtpCommandException(reply);
            }

            // the FXP session stores the active connections used for this FXP transfer
            return(new FtpFxpSession {
                SourceServer = sourceClient,
                TargetServer = destinationClient,
                ProgressServer = progressClient,
            });
        }