Platforms to show: All Mac Windows Linux Cross-Platform
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 console
This example is the version from Sat, 19th Feb 2016.
Project "SSH console.xojo_binary_project"
Class App Inherits ConsoleApplication
EventHandler Function Run(args() as String) As Integer
// this example connects via SSH and runs commands with timer and thread
// please update login details in session method
// make a connection
dim e as integer = Connect
if e <> 0 then
return e // failed to connect
end if
// timer to make query every 10 seconds
dim t as new QueryTimer
t.Period = 10000
t.Mode = timer.ModeMultiple
// start main loop
print "Query date and disk space every 10 seconds."
do
app.DoEvents 10
loop until ende
// shutdown
session.Disconnect "Normal Shutdown, Thank you for playing"
session = nil
print "done"
End EventHandler
Function Connect() As integer
const Address = "localhost"
const username = "cs"
const password = "test"
const keyfile1 = ""
const keyfile2 = ""
dim hostAddr as string = System.Network.LookupIPAddress(Address)
print hostAddr
//* Create a session instance and start it up. This will trade welcome
//* banners, exchange keys, and setup crypto, compression, and MAC layers
dim session as new MySSH2SessionMBS(hostAddr, 22)
session.MyPassword = password
if session.Handle = 0 then
print "Failed to connect socket!"
Return 1
end if
session.SessionHandshake
if session.lasterror<>0 then
print "Failure establishing SSH session"
Return 9
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)
print "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
print "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
print "Authentication by password succeeded."
else
// failed
print "Authentication by password failed!"
Return 1
end if
elseif authKeyboardInteractive then
//* Or via keyboard-interactive */
session.UserAuthKeyboardInteractive username
if session.LastError <> 0 then
print "Authentication by keyboard-interactive failed!"
return 10
else
print "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
print "Authentication by public key failed!"
Return 4
else
print "Authentication by public key succeeded."
end if
else
print "No supported authentication methods found!"
Return 3
end if
self.session = session
return 0 // ok
End Function
Property Ende As Boolean
Property session As SSH2SessionMBS
End Class
Class MySSH2SessionMBS Inherits SSH2SessionMBS
EventHandler Sub KeyboardCallback(Name as string, Instruction as string, PromptCount as integer, Prompts() as SSH2UserAuthKeyboardInteractivePromptMBS, responses() as SSH2UserAuthKeyboardInteractiveResponseMBS)
'print "Name: "+Name
'print "Instruction: "+Instruction
'
'for each p as SSH2UserAuthKeyboardInteractivePromptMBS in Prompts
'print p.Text
'next
if PromptCount = 1 then
responses(0).Text = MyPassword
end if
End EventHandler
Property MyPassword As string
End Class
Class QueryThread Inherits Thread
EventHandler Sub Run()
dim Session as SSH2SessionMBS = app.session
//* Request a shell */
dim channel as SSH2ChannelMBS = session.OpenSession
if channel = nil then
print "Unable to open a session"
Return
end if
//* Some environment variables may be set,
//* It's up to the server which ones it'll allow though
'channel.SetEnv "FOO", "bar"
//* Request a terminal with 'vanilla' terminal emulation
//* See /etc/termcap for more options
'channel.RequestPTY "vanilla"
'if channel.LastError <> 0 then
'print "Failed requesting pty"
'Return
'end if
// Open a SHELL on that pty //
'channel.Shell
'if channel.LastError <> 0 then
'print "Unable to request shell on allocated pty"
'Return
'end if
channel.SetBlocking false
//* At this point the shell can be interacted with using
//* libssh2_channel_read()
//* libssh2_channel_read_stderr()
//* libssh2_channel_write()
//* libssh2_channel_write_stderr()
//*
//* Blocking mode may be (en|dis)abled with: libssh2_channel_set_blocking()
//* If the server send EOF, libssh2_channel_eof() will return non-0
//* To send EOF to the server use: libssh2_channel_send_eof()
//* A channel can be closed with: libssh2_channel_close()
//* A channel can be freed with: libssh2_channel_free()
app.YieldToNextThread
// read greetings
dim s as string = channel.Read(10000)
'print s
app.YieldToNextThread
dim commandline as string = "/bin/date"
call channel.Execute commandline
// wait until things are okay
while channel.LastError = -37
channel.execute commandline
'print "Lasterror: "+str(channel.LastError)
session.WaitSocket
wend
do
app.YieldToNextThread
s = channel.Read(10000)
if channel.LastError = session.kErrorEagain then
// no answer yet
Continue
else
print "Date: " + s
exit
end if
loop
app.YieldToNextThread
channel = nil
// start new channel
//* Request a shell */
channel = session.OpenSession
if channel = nil then
print "Unable to open a session"
Return
end if
commandline = "/bin/df"
call channel.Execute commandline
// wait until things are okay
while channel.LastError = -37
channel.execute commandline
'print "Lasterror: "+str(channel.LastError)
session.WaitSocket
wend
do
app.YieldToNextThread
s = channel.Read(10000)
if channel.LastError = session.kErrorEagain then
// no answer yet
Continue
else
s = ReplaceLineEndings(s, EndOfLine)
dim lines() as string = split(s, EndOfLine)
print "Disk space: "
for each line as string in lines
print line
next
print ""
exit
end if
loop
channel.Close
channel = nil
End EventHandler
End Class
Class QueryTimer Inherits Timer
EventHandler Sub Action()
counter = counter + 1
if counter = 11 then
print "10 times is okay, now quit"
app.ende = true
else
print "Timer: "+str(counter)
print ""
dim q as new QueryThread
q.run
end if
End EventHandler
Property counter As Integer
End Class
End Project
See also:
The items on this page are in the following plugins: MBS Network Plugin.