Robin Rodricks
Robin Rodricks

Reputation: 113976

How do I disable encryption with the SslStream class?

I'm connecting to an FTPS server via TLS/SSL using the SslStream class. Everything is going fine. However I need to support a command called "CCC" which basically disables encryption. If I simply do:

SendCommand("CCC");
sslStream.Close();
netStream.Write("...<futher FTP commands>...")

Then the FTP server responds with seemingly garbage data (about 30 bytes), and then does not respond to any command after that (timeout).

The FTP logs are as follows:

# Connect()
Status:   Connecting to ***:21
Response: 220-IPv6 connections are also welcome on this server.
Command:  AUTH TLS
Response: 234 AUTH TLS OK.
Status:   FTPS Authentication Successful
Command:  USER ***
Response: 331 User *** OK. Password required
Command:  PASS ***
Response: 230 OK. Current restricted directory is /
Command:  PBSZ 0
Response: 200 PBSZ=0
Command:  PROT P
Response: 200 Data protection level set to "private"
Status:   Text encoding: System.Text.UTF8Encoding
Command:  OPTS UTF8 ON
Response: 200 OK, UTF-8 enabled
Command:  SYST
Response: 215 UNIX Type: L8
Command:  CCC
Response: 200 Control connection unencrypted
Status:   The stale data was: ************

As you can see the FTP server sends back "200 Control connection unencrypted" which means the command was successful. Its also important to note that the response was sent in encrypted format.

So I need to probably continue to use the SslStream while disabling encryption. Probably the "block mode" communication is still required while the encryption algorithm is disabled. Does anyone have any idea how I can do this?

Upvotes: 1

Views: 816

Answers (2)

Robin Rodricks
Robin Rodricks

Reputation: 113976

The FixedSslStream class worked for me. When you call Close() on it it sends an SSL close_notify alert! Then you can continue sending plaintext data to the base stream.

Upvotes: 1

President James K. Polk
President James K. Polk

Reputation: 41967

What is the difference between "closing the secure connection" and dropping it?

"Closing the secure connection" refers to sending a TLS close_notify alert without closing the underlying TCP connection. This feature is supported by the SslStream class, through use of the constructors that take a bool innerStreamOpen argument. Normally, when you call SslStream.Close() the peers securely close the TLS connection with an exchange of TLS close_notify messages and then the underlying TCP connection is immediately closed. However, if you use an SslStream constructor with the leaveInnerStreamOpen argument set to true, the TCP connection is not closed, and further unsecured data may be sent on it. For example,

var tcpClient = new TcpClient("127.0.0.1", 9876);
var tcpStream = tcpClient.GetStream();
var sslStream = new SslStream(tcpStream, true);
sslStream.AuthenticateAsClient("127.0.0.1");
sslStream.Write(....);  // use the secure connection.
sslStream.Close();   // close the TLS connection: the tcp stream is still viable
tcpStream.Write(...) // use the unsecured TCP connection
tcpStream.Close();  // now the TCP connection is terminated.

Now actually implementing an FTP over SSL client manually seems pretty tricky. Personally I would look for an existing mature implementation before attempting to write my own.

Upvotes: 2

Related Questions