Xojo Conferences
MBSSep2018MunichDE
XDCMay2019MiamiUSA

Platforms to show: All Mac Windows Linux Cross-Platform

/Network/SSH/SSH console
Function:
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.rbp"
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:

Feedback, Comments & Corrections

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





Links
MBS FileMaker blog