The following example demonstrates how to use an implicit SSL connection to securely connect to, log into, and disconnect from a secure FTP server using the FtpClient interface. We will handle the CertificateReceived event to validate the certificate received from the FTP server. For an explicit SSL connection demonstration, refer to the Quick Tour Sample. An example using the FtpConnection class follows below.
static void ImplicitSSLExample() { try { FtpClient ftp = new FtpClient(); //ftp.TraceWriter = Console.Out; // Subscribe to the CertificateReceived event ftp.CertificateReceived += new CertificateReceivedEventHandler( OnCertificateReceived ); // Pick an authentication method AuthenticationMethod authenticationMethod = AuthenticationMethod.Ssl; // Pick verification flags. If unsure, pick 'None'. VerificationFlags verificationFlags = VerificationFlags.None; // Supply a client certificate to submit to the server. This example doesn't use one Certificate clientCertificate = null; // Connect implicitly to the server using encryption. Notice the port number reserved for this // This form always enables encryption for the data channel (for file transfers) ftp.Connect( "localhost", 990, authenticationMethod, verificationFlags, clientCertificate ); try { // Login. The exchanged information will be encrypted ftp.Login( "username", "password" ); /* Perform your file transfers */ } finally { // Make sure we always disconnect ftp.Disconnect(); ftp.CertificateReceived -= new CertificateReceivedEventHandler( OnCertificateReceived ); } } catch( Exception exception ) { // Output some information about it Console.WriteLine( "-->{0}: {1}\n{2}", exception.GetType().Name, exception.Message, exception.StackTrace ); // Fetch the inner exception exception = exception.InnerException; // While there is an exception while( exception != null ) { // Output some information about it Console.WriteLine( "-->Inner exception: {0}: {1}\n{2}", exception.GetType().Name, exception.Message, exception.StackTrace ); // Fetch the inner exception exception = exception.InnerException; } } } static void OnCertificateReceived( object sender, CertificateReceivedEventArgs e ) { // The Status argument property tells you if the server certificate was accepted // based on the VerificationFlags provided in the call to Connect(). if( e.Status != VerificationStatus.ValidCertificate ) { Console.WriteLine( "The server certificate is invalid: {0}", e.Status.ToString() ); Console.WriteLine( e.ServerCertificate.ToString() ); // You have three choices here: // // 1) Refuse the certificate by setting e.Action to VerificationAction.Reject, // thus making the authentication fail. This is e.Action's default value // when the server certificate isn't valid. // // 2) Set e.Flags to less restrictive criterion and ask the library to // validate the certificate again by setting e.Action to // VerificationAction.VerifyAgain. // // 3) Force the library to accept this certificate by setting e.Action to // VerificationAction.Accept. // // We'll do #1 or #3, depending on the user's answer. Console.WriteLine( "Do you want to accept this certificate anyway? [Y/N]" ); int answer = Console.Read(); if( ( answer == 'y' ) || ( answer == 'Y' ) ) { e.Action = VerificationAction.Accept; } } else { // e.Action's default value is VerificationAction.Accept Console.WriteLine( "Valid certificate received from server." ); } }
Private Shared Sub ImplicitSSLExample() Try Dim ftp As New FtpClient() 'ftp.TraceWriter = Console.Out; ' Subscribe to the CertificateReceived event AddHandler ftp.CertificateReceived, AddressOf OnCertificateReceived ' Pick an authentication method Dim authenticationMethod As AuthenticationMethod = AuthenticationMethod.Ssl ' Pick verification flags. If unsure, pick 'None'. Dim verificationFlags As VerificationFlags = VerificationFlags.None ' Supply a client certificate to submit to the server. This example doesn't use one Dim clientCertificate As Certificate = Nothing ' Connect implicitly to the server using encryption. Notice the port number reserved for this ' This form always enables encryption for the data channel (for file transfers) ftp.Connect("localhost", 990, authenticationMethod, verificationFlags, clientCertificate) Try ' Login. The exchanged information will be encrypted ftp.Login("username", "password") ' Perform your file transfers Finally ' Make sure we always disconnect ftp.Disconnect() RemoveHandler ftp.CertificateReceived, AddressOf OnCertificateReceived End Try Catch exception As Exception ' Output some information about it Console.WriteLine("-->{0}: {1}" & Constants.vbLf & "{2}", exception.GetType().Name, exception.Message, exception.StackTrace) ' Fetch the inner exception exception = exception.InnerException ' While there is an exception Do While exception IsNot Nothing ' Output some information about it Console.WriteLine("-->Inner exception: {0}: {1}" & Constants.vbLf & "{2}", exception.GetType().Name, exception.Message, exception.StackTrace) ' Fetch the inner exception exception = exception.InnerException Loop End Try End Sub Private Shared Sub OnCertificateReceived(ByVal sender As Object, ByVal e As CertificateReceivedEventArgs) ' The Status argument property tells you if the server certificate was accepted ' based on the VerificationFlags provided in the call to Connect(). If e.Status <> VerificationStatus.ValidCertificate Then Console.WriteLine("The server certificate is invalid: {0}", e.Status.ToString()) Console.WriteLine(e.ServerCertificate.ToString()) ' You have three choices here: ' ' 1) Refuse the certificate by setting e.Action to VerificationAction.Reject, ' thus making the authentication fail. This is e.Action's default value ' when the server certificate isn't valid. ' ' 2) Set e.Flags to less restrictive criterion and ask the library to ' validate the certificate again by setting e.Action to ' VerificationAction.VerifyAgain. ' ' 3) Force the library to accept this certificate by setting e.Action to ' VerificationAction.Accept. ' ' We'll do #1 or #3, depending on the user's answer. Console.WriteLine("Do you want to accept this certificate anyway? [Y/N]") Dim answer As Integer = Console.Read() If (answer = AscW("y"c)) OrElse (answer = AscW("Y"c)) Then e.Action = VerificationAction.Accept End If Else ' e.Action's default value is VerificationAction.Accept Console.WriteLine("Valid certificate received from server.") End If End Sub