Page 1 of 1

Connecting and Uploading to FileZilla Server.

Posted: 2017-10-17 08:28
by PastorBurt
Hi. I’m failing to upload in C# anything to the FileZilla Server. I’ve been a developer for decade, and the C# code does and will work on a Windows FTP Server, but fails with the FileZilla Server:

Basically what I am showing you is a (a) C# class, (b) that calls an “UploadFile” function by passing to it 5 parameters: (1) a Local File path, (2) a Remote File Path, (3) the FTP url, in this case an IP Address, (4) the UserName, and (5) the account Password. In this case the local file to be Uploaded is in a local directory as “C:\PollofPolls\PollofPolls\App_Data\AdvertisementRates.xml”. The output URL on the remote server is this: “ftp://00.000.000.000//App_Data/AdvertisementRates.xml”. (This is an example. I did not use zeros. In a real test, this is the Server’s IP address.)

The function always fails in trying to establish communication with the FTP Server [ ftpStream = ftpRequest.GetRequestStream() ]. If ftpRequest.Passive is set to “true”, then the error message upon failure is “The remote server returned an error: (550) File unavailable (e.g., file not found, no access).”. If the ftpRequest.Passive is set to “false”, then the error message is “The remote server returned an error: 227 Entering Passive Mode (34,232,100,121,192,8)\r\n.”. The C# function which is not working with FileZila is this.

public bool UploadFile(string strLocalFile, string strRemoteFile, string strFTPHost, string strUserName, string strPassword)
{
// Output file to remote App Data directory
byte[] byteBuffer;
int intBufferSize = 2048; // Buffer size.
string strErrorMessage = ""; // Error Message upon failure.
FtpWebRequest ftpRequest = null; // FTP Request object.
Stream ftpStream = null; // FTP Stream
bool bolSuccess = true; // Assume "true" for success. If errors out, then "false" for failure.
int intWriteBytes = 0; // Bytes being written out

string strRemotePath = strFTPHost + "/" + strRemoteFile; // Becomes essentially: ftp://00.000.000.000//App_Data/AdvertisementRates.xml
System.IO.FileStream fsLocalStream;
try
{
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(strRemotePath); // Create an FTP Request to ftp://00.000.000.000//App_Data/AdvertisementRates.xml
ftpRequest.Credentials = new NetworkCredential(strUserName, strPassword); // Log in to the FTP Server with the User Name and Password Provided
ftpRequest.UseBinary = true; // When in doubt, use these options
ftpRequest.UsePassive = false; // POTENTIAL ERROR: Was = true. But to keep active changed to = false for FileZilla Server.
ftpRequest.KeepAlive = true;
ftpRequest.EnableSsl = false;
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile; // Specify the Type of FTP Request [ ERRORS OUT ]
ftpStream = ftpRequest.GetRequestStream(); // Establish Return Communication with the FTP Server
fsLocalStream = System.IO.File.OpenRead(strLocalFile); // Open a File Stream to Read the File for Upload, at
// C:\PollofPolls\PollofPolls\App_Data\AdvertisementRates.xml
byteBuffer = new byte[intBufferSize]; // Buffer for the Downloaded Data
intWriteBytes = fsLocalStream.Read(byteBuffer, 0, intBufferSize); // (1) Read in first bytes of the file.
try // Upload the File by Sending the Buffered Data Until the Transfer is Complete
{
while (intWriteBytes > 0)
{
ftpStream.Write(byteBuffer, 0, intWriteBytes); // Write out bytes from the prior Read (1) or (2) if looping through the file.
intWriteBytes = fsLocalStream.Read(byteBuffer, 0, intBufferSize); // (2) Read in next string of bytes, if any still exist
}
}
catch (Exception ex) // Discover errors in the reading and writing to the Upload directory.
{
strErrorMessage = ex.Message;
bolSuccess = false;
}
fsLocalStream.Close(); // (3) Resource Cleanup
ftpStream.Close();
ftpRequest = null;
}
catch (Exception ex) // Discover Errors upon connection.
{ // If .UsePassive = false (therefore Active = true) then produced error message is this:
bolSuccess = false; // "The remote server returned an error: 227 Entering Passive Mode (34,232,100,121,192,8)\r\n."
strErrorMessage = ex.Message; // If .UsePassive = true (therefore Active = false) then produced error message is this:
} // "The remote server returned an error: (550) File unavailable (e.g., file not found, no access)."
return bolSuccess; // Return Success or failure.
}

Please advise if there is any C# correction required for this function to run on FileZilla. I really need this to work.

Concerning environment, The Client is a Window 10 workstation. The failures occur with or without the Firewall on or off. The Host server is an Amazon AWS Windows Server 2012, using FileZilla Server version 0.9.44beta. Since I am new to both the FileZilla Server and Amazon AWS, there could be a setting errors. Here are the settings on AWS that I am aware of which could be affecting performance.

(1) Within the AWS Management Console, the Security Groups has within the Inbound tab, a Custom TCP Rule with the Port Range of 50000-51000 and Source set to 0.0.0.0/0.
(2) A second Custom TCP Rule is established for the Port Range of 20-21 and Source set to 0.0.0.0/0.
On the FileZilla Server, I have made the following settings:
(1) On the General Settings tap, I left the Listener on Port 21.
(2) Under “Passive Mode Settings”, I was advised to set the custom port range from 49152 to 65535.
(3) The FileZilla Server is set to the Elastic IP address of Server, which serves as the Public DNS IP address on the Passive Mode settings tab.
(4) I created within FileZilla Server a “Normal Users” group, and set up four users for my personal use.

Within the Windows Server 2012 Administrative Tools, under Windows Firewall and Advanced Security, I created two FTP Inbound Rules:
(1) The first rule following https://www.codeproject.com/Tips/404132 ... -Instances was for TCP for all programs within the local port range of 49152-65535, and then for All Remote ports.
(2) The second rule for Rule was for all programs for any remote or local using Port 21, applied to Domain, Privat or Public

Please advise if there are any corrections to the AWS Server Inbound Rules, FileZila Server settings, or Windows Firewall settings that would cause my C# function to fail.

The only thing I notices as strange came from the FileZilla Client. When using the Windows Server FTP, I always set each client account in FileZilla Client to the Transfer Mode of “Default”. However, now referencing the FileZilla FTP Server from the FileZilla FTP Client, I found that every user would fail to log in. The connect would always follow the normal string of commands and events, but the Directory Listing would fail, and eventually time out. Nothing fully connected. However, when I changed the Transfer Setting to “Active” for each of the Client users, then Directory Listing for each user from the FileZilla Client succeeded and listed the contents of the server’s directory. I don’t know if that means anything, because why would something strange in performance from the FileZilla FTP Client reveal why C# programming could not connect at all UNLESS THIS strange behavior identified a problem with the FileZilla Server which presently may be affecting BOTH clients. Please advise.

Please advise if there is any C# correction required for this function to run on FileZilla. For me to use the FileZilla Server, I have to be able to connect to the FileZilla server, and be able to both upload and download to it programmatically.

Sincerely,
Pastor Burt :roll:

Re: Connecting and Uploading to FileZilla Server.

Posted: 2017-10-17 09:47
by boco
I cannot comment on the code (as I'm not a coder). However, some things immediately catched my eye:

1. You defined a Passive port range of 49152-65535 (the complete ephemeral port range), yet you forwarded only 50000-51000. Both TCP port range settings must match. A request to a port not forwarded will not reach the server. Thus the Passive mode fails.

2. Forwarding port 20 is not required. That FTP DATA port is used, if at all, as an outgoing connection in Active mode. There won't be any incoming connection to this port.

3.
The output URL on the remote server is this: “ftp://00.000.000.000//App_Data/AdvertisementRates.xml
There's an excessive slash in the address that I marked red.

4.
If the ftpRequest.Passive is set to “false”, then the error message is “The remote server returned an error: 227 Entering Passive Mode (34,232,100,121,192,8)\r\n.”
Very strange, in Active mode, there should be NO Passive reply at all. Could be a fallback in the code or a bug.
And, you failed to mask the IP. :mrgreen:

5. Please update your FileZilla Server, we are at 0.9.60.2, currently. The version you're using has unpatched vulnerabilities.

We recommend the Passive mode over the Active one. Plus, you definitely should enable FTP over TLS, if possible. Otherwise, your password is sent in cleartext over a public channel.

Re: Connecting and Uploading to FileZilla Server.

Posted: 2017-10-18 00:13
by PastorBurt
ISSUE RESOLVED! Thank you. You were correct

The problem was the extra "/" in ftp://00.000.000.000//App_Data/AdvertisementRates.xml" of the Remote connection file string which was killing the Upload. Once that was removed, everything worked.

Good news: The code even worked whether the ftpRequest.UsePassive was marked "true" or "false". So I changed it to "true", as I have done in all prior coding, and as you suggested.

In life, it is the smallest of errors that always seem to kill you. I looked at this for hours, and I never saw that extra slash. Thank you. Other than this, if there is a good side to this issue, you now have a documented C# Upload to FileZilla Server from a FileZilla Client, hosted on Amazon AWS. There likely is that there is no such documentation of this anywhere else.

Thank you for your assistance. An Extra pair of eyes can help a lot.

This issue is resolved