Fluent FTP Won't connect to FTP Server [duplicate] - c#

This question already has an answer here:
"The handshake failed due to an unexpected packet format" FluentFTP error when connecting to SFTP server
(1 answer)
Closed 1 year ago.
I'm trying to connect to an FTP Server using Fluent FTP.
I have no issue using Filezilla when I use Port 22 (SFTP).
However I can't connect to it using Fluent FTP.
var client = new FtpClient(Constants.FtpHost, Constants.FtpUsername, Constants.FtpPassword)
{
// DataConnectionType = FtpDataConnectionType.PASV,
// EncryptionMode = FtpEncryptionMode.Implicit,
// SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13,
Port = 22
};
Console.WriteLine("Connecting...");
client.Connect();
Console.WriteLine("Connected");
I Get the following error: Unable to read data from the transport connection: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
When I Uncomment DataConnectionType = FtpDataConnectionType.PASV Nothing changes.
When I Uncomment EncryptionMode = FtpEncryptionMode.Implicit I Get the following Error:
System.IO.IOException: Cannot determine the frame size or a corrupted frame was received.
Once again I have 0 issues with FileZilla or WinSCP.
Any help would be greatly appreciated.

From the official GitHub page:
SFTP is not supported as it is FTP over SSH, a completely different protocol (use SSH.NET for that)
You're trying to use an FTP library to connect to an SFTP server. They're two completely different protocols that have nothing in common, despite fulfulling the same goal. Use a proper SFTP library for that server.
Both FileZilla and WinSCP support both FTP and SFTP, that's why you have no problems with them.

Related

ADO.NET FirebirdSql.Data.FirebirdClient.FbException: "Unable to complete network request to host "

I have a pretty strange problem when trying to connect my C# program to an existing Firebird server.
First of all, this is reproducable with the default connection example from the Firebird documentation at https://github.com/FirebirdSQL/NETProvider/blob/master/Provider/docs/ado-net.md
using (var connection = new FBConnection("database=192.168.0.150:c:\\Data\\demo.fdb;user=sysdba;password=m#sterkey"))
{
connection.Open();
using (var transaction = connection.BeginTransaction())
{
using (var command = new FbCommand("select * from demo", connection, transaction))
{
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
var values = new object[reader.FieldCount];
reader.GetValues(values);
Console.WriteLine(string.Join("|", values));
}
}
}
}
}
It all works fine when I am on my machine, I also can connect to a Firebird server on my coworkers PC.
But I cannot connect to the Firebird server on my other development server. I found an answer in another question and want to tell you that the server does not have internet access.
https://stackoverflow.com/a/57569057/2785084
This is the exception I get:
FirebirdSql.Data.FirebirdClient.FbException: "Unable to complete
network request to host " No message for error code 335544721 found."
IscException: Unable to complete network request to host " No message
for error code 335544721 found. IOException: Unable to read data from
the transport connection: An existing connection was forcibly closed
by the remote host
I already updated to the latest stable Version of Firebird. I can guarantee that the server is running and no firewall is blocking my connection, because when I try to connect with our old Delphi program, everything works. I also can connect using the lightweight Firebird management tool Flamerobin from Flamerobin.org, which is written in C++, I think.
When I try to connect with DBeaver I get the following message:
[SQLState:28000, ISC error code:335544472] Your user name and
password are not defined. Ask your database administrator to set up a
Firebird login.
I'm pretty sure that the user and password are correct. I do not use the default password, but a password with an # sign in it, maybe it has something to do with that.
I now have 2 programs that can Connect (Delphi and C++), and two that cannot connect (C# and Java). Does anyone have any clue or tweak how to change the connection that I can connect to the server?
Thanks to Mark Rotteveel for the comment which got me to the solution.
I can connect with the default password "masterkey", so it is obvious that the srp user was created with the default credentials and therefore a connection with the other credentials is not possible.
I have to correct the users in my old server.
Thanks for the hint that ADO.NET only supports srp.

"The server response contains a null character" when connecting to FTP site on port 990 using SSH.NET

I'm trying to use Renci SSH.NET to connect to an FTP site and download files from my C# app. I can successfully connect to the host with FileZilla and WinSCP (on Windows 10 Pro 64), and through an HTTP connection (the host is running CrushFTP), but cannot figure out how to successfully connect from my C# app, using SSH.NET. I'm getting this error:
The server response contains a null character at position 0x00000004: 00000000 15 03 03 00....A server must not send a null character before the Protocol Version Exchange is complete.
My take on the documentation from here, is that this problem appears to be an expected error. I've read the information suggested by the documentation at https://www.rfc-editor.org/rfc/rfc4253#section-4.2 and I "think" I understand that to mean that the host that I'm trying to connect to may not be correctly configured. My question is, since I don't have the ability to change how the host is configured, whether there is a way around this error with the SSH.NET library or am I just at a dead end for using SSH.NET?
Here's my code - tried to simplify to bare minimum:
using System;
using Renci.SshNet;
namespace mysftp
{
class Program
{
static void Main(string[] args)
{
string host = "myftps.hostname.com";
string username = "myusername";
string password = "securepassword";
int port = 990;
string remoteFolder = "/";
using (SftpClient sftp = new SftpClient(host, port, username, password))
{
try
{
Console.WriteLine("Attempting to connect to " + host + " ...");
sftp.Connect();
Console.WriteLine(sftp.ConnectionInfo.ServerVersion);
sftp.Disconnect();
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
}
}
}
Here is the host information (Remote server info from WinSCP):
Remote system = UNIX Type: L8
File transfer protocol = FTP
Cryptographic protocol = TLS/SSL Implicit encryption, TLSv1.2
Encryption algorithm = TLSv1.2: ECDHE-RSA-AES256-GCM-SHA384, 2048 bit RSA, ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD
Compression = No
------------------------------------------------------------
Certificate fingerprint
<<fingerprint info redacted>>
------------------------------------------------------------
Can change permissions = Yes
Can change owner/group = No
Can execute arbitrary command = Protocol commands only
Can create symbolic/hard link = No/No
Can lookup user groups = No
Can duplicate remote files = No
Can check available space = No
Can calculate file checksum = Yes
Native text (ASCII) mode transfers = No
------------------------------------------------------------
Additional information
The server supports these FTP additional features:
AUTH TLS
AUTH SSL
SSCN
PBSZ
PROT
CCC
CLNT
EPSV
EPRT
MDTM
MDTM YYYYMMDDHHMMSS[+-TZ];filename
MFMT
SIZE
REST STREAM
MODE Z
LIST -Q
SITE UTIME
SITE MD5
XMD5
SITE MD5s
SITE RANDOMACCESS
MLST Type*;Size*;Modify*;Perm*;UNIX.owner*;UNIX.group*;
UTF8
Port 990 is used for FTP protocol over implicitly encrypted TLS/SSL connection (aka implicit FTPS). While SSH.NET is an SSH/SFTP library. FTPS and SFTP are completely different things. You cannot use SSH.NET for FTPS.
The implicit FTPS is obsolete thing. Not all FTP(S) libraries do support it. It's notable not supported by the built-in .NET FTP implementation, the FtpWebRequest.
For you will have to use a 3rd party library. See Does .NET FtpWebRequest Support both Implicit (FTPS) and explicit (FTPES)?
Though most FTP servers do support the standard explicit FTPS (over port 21). If your server does, use that, instead of the legacy port 990. See FTPS (FTP over SSL) in C#
If not, talk to the server administrator to enable it.
See also Difference between FTP/FTPS/SFTP - Configurable connection to any of them
A completely different problem that can lead to the same error message: Connecting with SSH.NET to OpenSSH 7.4p1 fails with "The server response contains a null character at position" but works in WinSCP.

SSH.NET timeout when connecting to AWS Managed SFTP server in C#

I'm having issues trying to establish a connection to an AWS Managed SFTP server. Using the credentials I have on hand, I'm able to connect to the server from my Windows command line using the sftp command. Here's my .NET code:
using (var client = new SshClient(new ConnectionInfo(baseHost, user,
new AuthenticationMethod[]{
new PrivateKeyAuthenticationMethod(user,new PrivateKeyFile[]{
new PrivateKeyFile(keyLocation, pkpassword)
}),
}
)))
{
client.Connect(); // Timeout here
}
The code above gets to the client.Connect() line, then times out after 30 seconds with a Renci.SshNet.Common.SshOperationTimeoutException exception. When I look at what's happening with Wireshark, I see that the protocol being used by the sftp command line utility is SSH, while the SSH.NET is using TCP, and the packet sizes are completely different.
Does anybody know what I might be missing here?
I'm running the sftp command-line utility on the same computer as the above code. The first Wireshark image below is from the C# code above. The second is from the sFTP utility:
When I attempt to connect to the server's port 22 using PuTTY in raw mode, I get no response.
Thanks, Jim
This is bug both in old versions of SSH.NET and on Amazon Managed SFTP server side.
According to RFC 4253 Section 4.2. Protocol Version Exchange:
When the connection has been established, both sides MUST send an identification string.
Both SSH.NET client and Amazon Managed SFTP server fail this requirement. Both first wait for the other side to send the identification string before sending its own. A deadlock is inevitable (interrupted only by a timeout). That also explains why Wireshark does not identify the session as SSH, as there's no data exchanged at all. Hence, there's nothing by which the protocol can be identified.
If you can modify SSH.NET source code, moving this line in Session.Connect:
SocketAbstraction.Send(_socket, Encoding.UTF8.GetBytes(string.Format(CultureInfo.InvariantCulture, "{0}\x0D\x0A", ClientVersion)));
... above this block:
Match versionMatch;
// Get server version from the server,
// ignore text lines which are sent before if any
while (true)
{
...
}
... should fix the problem.
Also consider reporting the bug to Amazon.
I have reported the bug to SSH.NET
including the needed change. The fix is included from SSH.NET 2020.0.0 up.
If you cannot change SSH.NET code, you will need to use another SFTP library.
For example my WinSCP .NET assembly is compatible with Amazon Managed SFTP server.
This is an equivalent of your code:
// Set up session options
SessionOptions sessionOptions = new SessionOptions
{
Protocol = Protocol.Sftp,
HostName = baseHost,
UserName = user,
SshHostKeyFingerprint = ...,
SshPrivateKeyPath = keyLocation,
PrivateKeyPassphrase = pkpassword,
};
using (Session session = new Session())
{
// Connect
session.Open(sessionOptions);
// Your code
}
WinSCP GUI can generate a code template like the one above for you.

SSH.NET - Message type 80 is not valid

I have the following piece of code that tries to connect to an SFTP Server built with OpenSSH (The server works because I've been able to successfully connect to this FTP via WinSCP client):
ConnectionInfo ConnNfo = new ConnectionInfo("127.0.0.1", 22, "usertest",
new AuthenticationMethod[]{
// Pasword based Authentication
new PasswordAuthenticationMethod("usertest","usertest"),
}
);
// Upload A File
using (var sftp = new SftpClient(ConnNfo))
{
sftp.Connect();
sftp.ChangeDirectory(#"/C:/IISFTP/");
using (var uplfileStream = File.OpenRead(uploadfn))
{
sftp.UploadFile(uplfileStream, uploadfn, true);
}
sftp.Disconnect();
}
When calling the sftp.Connect() line, it raises the following Exception:
Message type 80 is not valid
Why is this happening? How can I connect to my SFTP server with SSH.NET?
Thank you
The message 80 stands for SSH_MSG_GLOBAL_REQUEST.
Modern versions of OpenSSH server use this generic message for various proprietary extensions of the SSH protocol.
Most clients will/should silently ignore unrecognized messages. The SSH.NET does ignore the SSH_MSG_GLOBAL_REQUEST too, but it does not expect the message until an authentication completes.
Unfortunately it seems that OpenSSH sends some of these (maybe the hostkeys-prove-00#openssh.com) even before the authentication.
The problem has been fixed in SSH.NET 2016.0.0-beta1. See Issue #8 and Commit a1f46d4.
In older versions, go to the Session.cs and in the Session.Connect() method move the below line somewhat up, above the authentication code:
RegisterMessage("SSH_MSG_GLOBAL_REQUEST");
I'd put it, just below this line:
RegisterMessage("SSH_MSG_USERAUTH_BANNER");

FtpException when getting files

I'm successfully establishing an ftp connection and want to get files from FTP server.
This is my code:
ftp.GetFile(file.Name, path + file.Name, false);
where ftp is FtpConnection.
And for all the other files it went well. Now, for the first time I got it and the exception msg isn't clear to me at all. Here it is:
200 Type set to I
227 Entering Passive Mode (93,186,176,75,78,64).
213 21846
What does this mean?
Since FTP is a bidirectional protocol and you need 2 connections (server <-> client)
In active mode the client connect to the server and the server connects back to the client. This is usually a problem with firewalls. In passive mode the client creates both connections, one on the ftp port, the second one on another port.
This can be for high server load or bad firewall configuration.

Categories