Platforms to show: All Mac Windows Linux Cross-Platform

/Network/SSH/SSH tunnel for database Desktop


Required plugins for this example: MBS Network Plugin

You find this example project in your Plugins Download as a Xojo project file within the examples folder: /Network/SSH/SSH tunnel for database Desktop

This example is the version from Fri, 4th Mar 2021.

Project "SSH tunnel for database Desktop.xojo_binary_project"
Class App Inherits Application
Const kEditClear = "&Delete"
Const kFileQuit = "&Quit"
Const kFileQuitShortcut = ""
End Class
Class MainWindow Inherits Window
Control List Inherits Listbox
ControlInstance List Inherits Listbox
End Control
Control StartTunnelButton Inherits PushButton
ControlInstance StartTunnelButton Inherits PushButton
EventHandler Sub Action() const Address = "192.168.1.123" const username = "xxx" const password = "xxx" const keyfile1 = "" const keyfile2 = "" dim hostAddr as string = System.Network.LookupIPAddress(Address) log hostAddr //* Create a session instance and start it up. This will trade welcome //* banners, exchange keys, and setup crypto, compression, and MAC layers session = new MySSH2SessionMBS(hostAddr, 22) session.MyPassword = password if session.Handle = 0 then log "Failed to connect socket!" Return end if session.SessionHandshake if session.lasterror<>0 then log "Failure establishing SSH session" Return end if //* At this point we havn't authenticated. The first thing to do is check //* the hostkey's fingerprint against our known hosts Your app may have it //* hard coded, may go to a file, may present it to the user, that's your //* call dim fingerprint as string = session.HostKeyHash(session.kHostKeyHashSHA1) log "Fingerprint: "+EncodeHex(fingerprint) //* check what authentication methods are available */ dim userauthlist as string = session.UserAuthList(username) dim authPassword as Boolean = false dim authKeyboardInteractive as Boolean = false dim authPublickey as Boolean = false log "Authentication methods: "+ userauthlist if instr(userauthlist, "password")>0 then authPassword = true end if if instr(userauthlist, "keyboard-interactive")>0 then authKeyboardInteractive = true end if if instr(userauthlist, "publickey")>0 then authPublickey = true end if if authPassword then //* We could authenticate via password */ session.UserAuthPassword(username, password) if session.LastError = 0 then // ok log "Authentication by password succeeded." else // failed log "Authentication by password failed!" Return end if elseif authKeyboardInteractive then //* Or via keyboard-interactive */ session.UserAuthKeyboardInteractive username if session.LastError <> 0 then log "Authentication by keyboard-interactive failed!" return else log "Authentication by keyboard-interactive succeeded." end if //* Or by public key */ elseif authPublickey then session.UserAuthPublicKeyFromFile(username, keyfile1, keyfile2, password) if session.LastError <> 0 then log "Authentication by public key failed!" Return else log "Authentication by public key succeeded." end if else log "No supported authentication methods found!" Return end if // here we are authorized //* Open tunnel */ tunnel = new SSH2TunnelMBS(session) tunnel.LocalAddress = "127.0.0.1" tunnel.LocalPort = 3307 tunnel.RemoteAddress = "127.0.0.1" tunnel.RemotePort = 3306 // avoid timeing out in Socket and SSH layers tunnel.KeepAlive = True session.ConfigureKeepAlive // run it tunnel.Run // while it runs, connect to database server // don't alter session while tunnel runs app.DoEvents(200) logMessages tunnel.Messages StopTunnelButton.Enabled = true StartTunnelButton.Enabled = false QueryButton.Enabled = false ConnectButton.Enabled = true DisconnectButton.Enabled = false End EventHandler
End Control
Control ConnectButton Inherits PushButton
ControlInstance ConnectButton Inherits PushButton
EventHandler Sub Action() // now use it, e.g. with MySQL via Xojo's plugin db = new MySQLCommunityServer db.Host = "127.0.0.1" db.DatabaseName = "xxx" db.UserName = "xxx" db.Password = "xxx" db.Port = 3307 if db.Connect then log "Connected" else log "Failed to connect: "+db.ErrorMessage Return end if QueryButton.Enabled = true ConnectButton.Enabled = false DisconnectButton.Enabled = true End EventHandler
End Control
Control StopTunnelButton Inherits PushButton
ControlInstance StopTunnelButton Inherits PushButton
EventHandler Sub Action() db = nil tunnel.Cancel = true // wait for shutdown do app.DoEvents 10 loop until not tunnel.Running logMessages tunnel.Messages session.Disconnect "Normal Shutdown, Thank you for playing" session = nil log "done" StopTunnelButton.Enabled = false StartTunnelButton.Enabled = true QueryButton.Enabled = false ConnectButton.Enabled = false DisconnectButton.Enabled = false End EventHandler
End Control
Control DisconnectButton Inherits PushButton
ControlInstance DisconnectButton Inherits PushButton
EventHandler Sub Action() db = nil QueryButton.Enabled = false ConnectButton.Enabled = true DisconnectButton.Enabled = false End EventHandler
End Control
Control QueryButton Inherits PushButton
ControlInstance QueryButton Inherits PushButton
EventHandler Sub Action() dim r as RecordSet = db.SQLSelect("SELECT VERSION();") if db.Error then MsgBox db.ErrorMessage else MsgBox "Version: "+r.IdxField(1).StringValue end if End EventHandler
End Control
Sub log(s as string) List.AddRow s List.ScrollPosition = List.ListCount End Sub
Sub logMessages(s as string) s = ReplaceLineEndings(s, EndOfLine) dim m() as string = split(s, EndOfLine) for each t as string in m log t next End Sub
Property db As MySQLCommunityServer
Property session As MySSH2SessionMBS
Property tunnel As SSH2TunnelMBS
End Class
MenuBar MainMenuBar
MenuItem FileMenu = "&File"
MenuItem FileQuit = "#App.kFileQuit"
MenuItem EditMenu = "&Edit"
MenuItem EditUndo = "&Undo"
MenuItem EditSeparator1 = "-"
MenuItem EditCut = "Cu&t"
MenuItem EditCopy = "&Copy"
MenuItem EditPaste = "&Paste"
MenuItem EditClear = "#App.kEditClear"
MenuItem EditSeparator2 = "-"
MenuItem EditSelectAll = "Select &All"
End MenuBar
Class MySSH2SessionMBS Inherits SSH2SessionMBS
EventHandler Sub KeyboardCallback(Name as string, Instruction as string, PromptCount as integer, Prompts() as SSH2UserAuthKeyboardInteractivePromptMBS, responses() as SSH2UserAuthKeyboardInteractiveResponseMBS) log "Name: "+Name log "Instruction: "+Instruction for each p as SSH2UserAuthKeyboardInteractivePromptMBS in Prompts log p.Text next if PromptCount = 1 then responses(0).Text = MyPassword end if End EventHandler
Sub log(s as string) MainWindow.log s End Sub
Property MyPassword As string
End Class
End Project

See also:

The items on this page are in the following plugins: MBS Network Plugin.


The biggest plugin in space...