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.