Imports Bitvise
Imports Bitvise.FlowSshNet


Public Enum ExitCodes
    Success = 0
    UsageError = 1
    SessionError = 2
    FatalError = 3
End Enum


Public Class MyClient
    Inherits Client

    Public Sub New()
        AddHandler OnHostKey, AddressOf Me.OnMyHostKey
        AddHandler OnForwardingLog, AddressOf Me.OnMyForwardingLog
    End Sub

    Public Function OnMyHostKey(ByVal sender As Object, ByVal publicKey As PublicKey) As Boolean
        Console.WriteLine("Received the following host key: ")
        Console.WriteLine("  MD5 Fingerprint: {0}", publicKey.GetMd5())
        Console.WriteLine("  Bubble-Babble: {0}", publicKey.GetBubbleBabble())
        Console.WriteLine("  SHA-256: {0}", publicKey.GetSha256())
        Console.Write("Type 'yes' to accept the key, any other input to exit: ")
        Return Console.ReadLine() = "yes"
    End Function
    Public Sub OnMyForwardingLog(ByVal sender As Object, ByVal log As ForwardingLog)
        Console.WriteLine(log.Desc)
    End Sub
End Class


Module FlowSshNet_VbTnl

    Sub OnUncaughtExceptionInEvent(ByVal sender As Object, ByVal fatal As Boolean, ByVal e As System.Exception)
        Console.WriteLine("Error: {0}", e.ToString())
        System.Environment.Exit(ExitCodes.FatalError)
    End Sub

    Function Main() As Integer
        Try
            ' Register delegate for uncaught exceptions in user-defined events.
            ' Example: If there is an uncaught exception in MyClient.OnMyHostKey, 
            '          then this is reported in OnUncaughtExceptionInEvent.
            AddHandler SshNet.OnExceptionInEvent, AddressOf OnUncaughtExceptionInEvent

            ' For use in deployed applications where Bitvise SSH Client might not be installed, 
            ' provide an activation code using SetActCode to ensure that FlowSsh does not  
            ' display an evaluation dialog. On computers with Bitvise SSH Client, use of 
            ' FlowSsh is permitted under the same terms as the Client; in this case, there 
            ' will be no evaluation dialog, and SetActCode does not have to be called.
            '
            'SshNet.SetActCode("Enter Your Activation Code Here")

            Dim client As MyClient = New MyClient
            client.SetAppName("FlowSshNet_VbTnl")
            client.SetHost("localhost")
            client.SetPort(22)
            client.SetUserName("testuser")
            client.SetPassword("testpass")

            Dim progress As ProgressHandler = New ProgressHandler
            client.Connect(progress)
            progress.WaitDone()

            If Not progress.Success() Then
                Dim connectStep As UInt32 = progress.GetTaskSpecificStep()
                Dim auxInfo As String = progress.GetAuxInfo()
                Dim connErr As String = ProgressHandler.DescribeConnectError(connectStep, auxInfo)
                Console.WriteLine("{0}", connErr)
            Else

                Dim rule As ForwardingRule = New ForwardingRule
                rule.ClientToServer = True
                rule.ListInterface = "127.0.0.1"
                rule.ListPort = 22123
                rule.DestHost = "127.0.0.1" ' "/tmp/demo.unixsocket"
                rule.DestPort = 22          ' ForwardingRuleRef.Port_UnixSocket

                Dim addForwardingHandler As ForwardingHandler = New ForwardingHandler
                client.AddForwarding(rule, addForwardingHandler)

                Dim proxy As ProxyForwarding = New ProxyForwarding
                proxy.ListInterface = "127.0.0.1"
                proxy.ListPort = 1080

                Dim enableProxyHandler As ForwardingHandler = New ForwardingHandler
                client.EnableProxyForwarding(proxy, enableProxyHandler)

                addForwardingHandler.WaitDone()
                If (addForwardingHandler.Success() And addForwardingHandler.GetListPort() = ForwardingRuleRef.Port_UnixSocket) Then
                    Console.WriteLine("Forwarding rule added on Unix socket.")
                ElseIf (addForwardingHandler.Success()) Then
                    Console.WriteLine("Forwarding rule added, listening port: {0}", addForwardingHandler.GetListPort().ToString())
                Else
                    Console.WriteLine("Error adding forwarding rule: {0}", addForwardingHandler.GetError().Desc)
                End If

                enableProxyHandler.WaitDone()
                If (enableProxyHandler.Success()) Then
                    Console.WriteLine("Proxy forwarding enabled, listening port: {0}", enableProxyHandler.GetListPort().ToString())
                Else
                    Console.WriteLine("Error enabling proxy forwarding: {0}", enableProxyHandler.GetError().Desc)
                End If

                Console.WriteLine("Press Esc to stop forwarding")
                While Console.ReadKey(True).Key <> ConsoleKey.Escape
                End While

                If (addForwardingHandler.Success()) Then
                    Dim handler As ForwardingHandler = New ForwardingHandler
                    client.CancelForwarding(rule, handler)

                    handler.WaitDone()
                    If (handler.Success()) Then
                        Console.WriteLine("Forwarding rule canceled")
                    Else
                        Console.WriteLine("Error canceling forwarding rule: {0}", handler.GetError().Desc)
                    End If
                End If

                If (enableProxyHandler.Success()) Then
                    Dim handler As ForwardingHandler = New ForwardingHandler
                    client.DisableProxyForwarding(handler)

                    handler.WaitDone()
                    If (handler.Success()) Then
                        Console.WriteLine("Proxy forwarding disabled")
                    Else
                        Console.WriteLine("Error disabling proxy forwarding: {0}", handler.GetError().Desc)
                    End If
                End If

                client.Disconnect(New ProgressHandler)

                Console.WriteLine("Press Esc to exit")
                While Console.ReadKey(True).Key <> ConsoleKey.Escape
                End While

            End If

        Catch e As System.Exception
            Console.WriteLine(e.Message)
            Return ExitCodes.FatalError
        Finally
            SshNet.Shutdown()
        End Try

        Return ExitCodes.Success
    End Function

End Module
