diff --git a/reference/SFtpGet/SFtpGet.cpp b/reference/SFtpGet/SFtpGet.cpp deleted file mode 100644 index a571d3f54..000000000 --- a/reference/SFtpGet/SFtpGet.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include - -using namespace Upp; - -CONSOLE_APP_MAIN -{ - StdLogSetup(LOG_COUT|LOG_FILE); -// Ssh::Trace(); - - const char *file = "/pub/example/readme.txt"; - - SshSession session; - if(session.Timeout(30000).Connect("demo:password@test.rebex.net:22")) { - SFtp sftp = session.CreateSFtp(); - String out = sftp.LoadFile(file); - LOG((!sftp.IsError() ? out : sftp.GetErrorDesc())); - } - else - LOG(session.GetErrorDesc()); -} diff --git a/reference/SFtpGet/SFtpGet.upp b/reference/SFtpGet/SFtpGet.upp deleted file mode 100644 index 5b0ea368e..000000000 --- a/reference/SFtpGet/SFtpGet.upp +++ /dev/null @@ -1,13 +0,0 @@ -description "Demonstrates basic SFtp file download in blocking mode.\377"; - -uses - Core, - Core/SSH, - Core/SSL; - -file - SFtpGet.cpp; - -mainconfig - "" = ""; - diff --git a/reference/SshBasics/Exec.cpp b/reference/SshBasics/Exec.cpp new file mode 100644 index 000000000..21ec78635 --- /dev/null +++ b/reference/SshBasics/Exec.cpp @@ -0,0 +1,20 @@ +#include "SshBasics.h" + +// ExecListDir: +// Demonstrates a remote command execution. + +void ExecListDir(SshSession& session) +{ + const char *cmdline = "ls -l /pub/example"; + + SshExec exec(session); + String cout, cerr; + int exit_code = exec(cmdline, cout, cerr); + if(!exec.IsError()) { + DUMP(exit_code); + LOG("Stdout:\n" << cout); + LOG("Stderr:\n" << cerr); + return; + } + LOG(exec.GetErrorDesc()); +} \ No newline at end of file diff --git a/reference/SshBasics/PickSemantics.cpp b/reference/SshBasics/PickSemantics.cpp new file mode 100644 index 000000000..db9992a03 --- /dev/null +++ b/reference/SshBasics/PickSemantics.cpp @@ -0,0 +1,12 @@ +#include "SshBasics.h" + +// SshPick: +// Demonstrates the pick (move) semantics for ssh objects. + +void SshPick(SshSession& session) +{ + SshSession psession = pick(session); // All Ssh-based objects are pickable. + if(!session) + LOG("SshSession object is picked."); + SFtpGet(psession); +} \ No newline at end of file diff --git a/reference/SshBasics/SFtp.cpp b/reference/SshBasics/SFtp.cpp new file mode 100644 index 000000000..a7013ef6f --- /dev/null +++ b/reference/SshBasics/SFtp.cpp @@ -0,0 +1,13 @@ +#include "SshBasics.h" + +// SFtpGet: +// Demonstrates a file download, using sftp. + +void SFtpGet(SshSession& session) +{ + const char *path = "/readme.txt"; + + SFtp sftp(session); + String file = sftp.LoadFile(path); + LOG((!sftp.IsError() ? file : sftp.GetErrorDesc())); +} \ No newline at end of file diff --git a/reference/SshBasics/SFtpStream.cpp b/reference/SshBasics/SFtpStream.cpp new file mode 100644 index 000000000..5b3128ba9 --- /dev/null +++ b/reference/SshBasics/SFtpStream.cpp @@ -0,0 +1,21 @@ +#include "SshBasics.h" + +// SFtpStreamGet: +// Demonstrates a basic stream operation on an sftp remote file object. + +void SFtpStreamGet(SshSession& session) +{ + const char *path = "/readme.txt"; + + SFtp sftp(session); + SFtpFileIn fi(sftp, path); + while(!fi.IsEof()) { + int64 pos = fi.GetPos(); + String line = fi.GetLine(); + if(!line.IsEmpty()) + LOG(Format("Offset: %3d, Line: [%s]", pos, line)); + } + if(fi.IsError()) + LOG(fi.GetErrorText()); + +} \ No newline at end of file diff --git a/reference/SshBasics/Scp.cpp b/reference/SshBasics/Scp.cpp new file mode 100644 index 000000000..fa5e77ef7 --- /dev/null +++ b/reference/SshBasics/Scp.cpp @@ -0,0 +1,13 @@ +#include "SshBasics.h" + +// ScpGet: +// Demonstrates a file download using scp. + +void ScpGet(SshSession& session) +{ + const char *path = "the/full/path/of/the/file/to/downlad"; + + Scp scp(session); + String file = scp.LoadFile(path); + LOG((!scp.IsError() ? file : scp.GetErrorDesc())); +} \ No newline at end of file diff --git a/reference/SshBasics/Shell.cpp b/reference/SshBasics/Shell.cpp new file mode 100644 index 000000000..bfd356a62 --- /dev/null +++ b/reference/SshBasics/Shell.cpp @@ -0,0 +1,12 @@ +#include "SshBasics.h" + +// ShellConsole: +// Demonstrates an interactive shell in console mode. + +void ShellConsole(SshSession& session) +{ + SshShell shell(session); + shell.Timeout(Null); + if(!shell.Console("ansi")) + LOG(shell.GetErrorDesc()); +} \ No newline at end of file diff --git a/reference/SshBasics/SshBasics.h b/reference/SshBasics/SshBasics.h new file mode 100644 index 000000000..9f8cfe80d --- /dev/null +++ b/reference/SshBasics/SshBasics.h @@ -0,0 +1,19 @@ +#ifndef _SshBasic_SshBasic_h +#define _SshBasic_SshBasic_h + +#include +#include + +using namespace Upp; + +void SFtpGet(SshSession& session); +void SFtpStreamGet(SshSession& session); +void ExecListDir(SshSession& session); +void ShellConsole(SshSession& session); +void ScpGet(SshSession& session); +void ForwardTcpIp(SshSession& session); +void X11Forwarding(SshSession& session); +void SshPick(SshSession& session); +void TraceVerbose(); + +#endif diff --git a/reference/SshBasics/SshBasics.upp b/reference/SshBasics/SshBasics.upp new file mode 100644 index 000000000..e088d1423 --- /dev/null +++ b/reference/SshBasics/SshBasics.upp @@ -0,0 +1,24 @@ +description "Demonstrates the basic capabilities of the SSH package.\377"; + +uses + Core, + Core/SSH; + +file + SshBasics.h, + main.cpp, + "Core examples" readonly separator, + SFtp.cpp, + SFtpStream.cpp, + Exec.cpp, + Scp.cpp, + Shell.cpp, + X11Shell.cpp, + Tunnel.cpp, + "Misc. examples" readonly separator, + PickSemantics.cpp, + VerboseLogging.cpp; + +mainconfig + "" = ""; + diff --git a/reference/SshBasics/Tunnel.cpp b/reference/SshBasics/Tunnel.cpp new file mode 100644 index 000000000..978b54ede --- /dev/null +++ b/reference/SshBasics/Tunnel.cpp @@ -0,0 +1,44 @@ +#include "SshBasics.h" + +// OpenTcpTunnel: +// Demonstrates tcp-ip and port forwarding feature of the ssh protocol. + +// This example requires upp/reference/SocketServer and upp/reference/SocketClient examples. +// SocketClient: Set the port number to 3215. + +bool ServerSendRecv(SshSession& session, String& data) +{ + // SshTunnel <-> SocketServer + SshTunnel tunnel(session); + if(!tunnel.Connect("127.0.0.1", 3214)) { + LOG("ServerSendRecv(): " << tunnel.GetErrorDesc()); + return false; + } + tunnel.Put(data + '\n'); + data = tunnel.GetLine(); + return !data.IsEmpty(); +} + +void ForwardTcpIp(SshSession& session) +{ + SshTunnel listener(session); + if(!listener.Listen(3215, 5)) { + LOG("ForwardTcpIp(): " << listener.GetErrorDesc()); + return; + } + LOG("SSH tunnel (server mode): Waiting for the requests to be tunneled..."); + for(;;) { + SshTunnel tunnel(session); + if(!tunnel.Accept(listener)) { + LOG("ForwardTcpIp(): " << tunnel.GetErrorDesc()); + return; + } + // SocketClient <-> SshTunnel + String data = tunnel.GetLine(); + LOG("Tunneled Request: " << data); + if(!data.IsEmpty() && ServerSendRecv(session, data)) { + LOG("Tunneled Response: " << data); + tunnel.Put(data + '\n'); + } + } +} diff --git a/reference/SshBasics/VerboseLogging.cpp b/reference/SshBasics/VerboseLogging.cpp new file mode 100644 index 000000000..5bc688eb9 --- /dev/null +++ b/reference/SshBasics/VerboseLogging.cpp @@ -0,0 +1,19 @@ +#include "SshBasics.h" + +// TraceVerbose: +// To activate verbose logging, you need to set the LIBSSH2TRACE flag via +// TheIDE->Main Configuration settings. + +void TraceVerbose() +{ + Ssh::TraceVerbose( +// LIBSSH2_TRACE_SOCKET | +// LIBSSH2_TRACE_KEX | + LIBSSH2_TRACE_AUTH | + LIBSSH2_TRACE_CONN | +// LIBSSH2_TRACE_SCP | +// LIBSSH2_TRACE_SFTP | +// LIBSSH2_TRACE_PUBLICKEY | + LIBSSH2_TRACE_ERROR + ); +} \ No newline at end of file diff --git a/reference/SshBasics/X11Shell.cpp b/reference/SshBasics/X11Shell.cpp new file mode 100644 index 000000000..3ffa511f3 --- /dev/null +++ b/reference/SshBasics/X11Shell.cpp @@ -0,0 +1,19 @@ +#include "SshBasics.h" + +// X11Forwarding: +// Demonstrates an interactive shell with X11 forwarding, in console mode. + +// This example requires a running X server. + +void X11Forwarding(SshSession& session) +{ + SshShell x11shell(session); + x11shell.Timeout(Null); + session.WhenX11 = [&x11shell](SshX11Handle xhandle) + { + x11shell.AcceptX11(xhandle); + + }; + if(!x11shell.ForwardX11().Console("ansi")) + LOG(x11shell.GetErrorDesc()); +} \ No newline at end of file diff --git a/reference/SshBasics/main.cpp b/reference/SshBasics/main.cpp new file mode 100644 index 000000000..d7c8492cb --- /dev/null +++ b/reference/SshBasics/main.cpp @@ -0,0 +1,57 @@ +#include "SshBasics.h" + +//#define SSH_KBAUTH // Enables ssh keyboard authentication method. + +#define SSH_SFTP + +// Important note: The scp, X11 forwarding and tcp-ip/port forwarding (tunnel) examples will not +// work with the public ssh test server used in this reference example (test.rebex.net). In order +// to run these examples you can set up an easy-to-use ssh server (e.g. OpenSSH) on a local +// machine for testing purposes. + +CONSOLE_APP_MAIN +{ + StdLogSetup(LOG_COUT|LOG_FILE); +#ifdef flagLIBSSH2TRACE + VerboseLogging(); +#else +// Ssh::Trace(); +#endif + + SshSession session; +#if defined(SSH_KBAUTH) + session.KeyboardAuth(); + session.WhenKeyboard = [](String title, String instructions, String prompt) + { + // Title and insctructions are optional and might be empty. + if(!IsNull(title)) + LOG(title); + if(!IsNull(instructions)) + LOG(instructions); + + Cout() << prompt; + return ReadSecret(); // "password" + }; +#endif + if(session.Timeout(30000).Connect("demo:password@test.rebex.net:22")) { +#if defined(SSH_SFTP) + SFtpGet(session); +#elif defined(SSH_SFTP_STREAM) + SFtpStreamGet(session); +#elif defined(SSH_EXEC) + ExecListDir(session); +#elif defined(SSH_SCP) + ScpGet(session); +#elif defined(SSH_SHELL) + ShellConsole(session); +#elif defined(SSH_SHELL_X11) + X11Forwarding(session); +#elif defined(SSH_TUNNEL) + ForwardTcpIp(session); +#elif defined(SSH_PICK_SEMANTICS) + SshPick(session); +#endif + return; + } + LOG(session.GetErrorDesc()); +} diff --git a/reference/SshExec/SshExec.cpp b/reference/SshExec/SshExec.cpp deleted file mode 100644 index 60923a0d9..000000000 --- a/reference/SshExec/SshExec.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include - -using namespace Upp; - -CONSOLE_APP_MAIN -{ - StdLogSetup(LOG_COUT|LOG_FILE); -// Ssh::Trace(); - - const char *cmd = "ls -l /pub/example"; - String cout, cerr; - - SshSession session; - if(session.Timeout(30000).Connect("demo:password@test.rebex.net:22")) { - SshExec exec = session.CreateExec(); - if(exec(cmd, cout, cerr) >= 0) { - LOG("Stdout:\n" << cout); - LOG("Stderr:\n" << cerr); - LOG("Exit code: " << exec.GetExitCode()); - } - else - LOG(exec.GetErrorDesc()); - } - else - LOG(session.GetErrorDesc()); -} diff --git a/reference/SshExec/SshExec.upp b/reference/SshExec/SshExec.upp deleted file mode 100644 index f68084d35..000000000 --- a/reference/SshExec/SshExec.upp +++ /dev/null @@ -1,12 +0,0 @@ -description "Demonstrates basic SSH remote command execution .\377"; - -uses - Core, - Core/SSH; - -file - SshExec.cpp; - -mainconfig - "" = ""; -