Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
UppHub
Status & Roadmap
FAQ
Authors & License
Forums
Funding U++
Search on this site











SourceForge.net Logo

SourceForge.net Logo

GitHub Logo

Discord Logo

SshBasics

 

Demonstrates the basic capabilities of SSH package.

 

 

SshBasics.h

 

#ifndef _SshBasic_SshBasic_h

#define _SshBasic_SshBasic_h

 

#include <Core/Core.h>

#include <Core/SSH/SSH.h>

 

using namespace Upp;

 

void SFtpGet(SshSession& session);

void SFtpStreamGet(SshSession& session);

void SFtpTransparency(SshSession& session);

void SFtpAsyncGet(SshSession& session);

void SFtpAsyncGet2(SshSession& session);

void ExecListDir(SshSession& session);

void ExecAsyncListDir(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

 

 

 

Shell.cpp

 

#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());

}

 

 

main.cpp

 

#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_SFTP_TRANSPARENCY)

        SFtpTransparency(session);

#elif defined(SSH_SFTP_MT)

        SFtpAsyncGet(session);

#elif defined(SSH_SFTP_MT_LOOP)

        SFtpAsyncGet2(session);

#elif defined(SSH_EXEC)

        ExecListDir(session);

#elif defined(SSH_EXEC_MT)

        ExecAsyncListDir(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());

}

 

 

 

SFtp.cpp

 

#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()));

}

 

 

SFtpStream.cpp

 

#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());

 

}

 

 

Exec.cpp

 

#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());

    

    // Or you can use one of the helper functions instead:

    // LOG("Stdout:\n" << SshExecute(session, cmdline));

}

 

 

Scp.cpp

 

#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()));

}

 

 

VerboseLogging.cpp

 

#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

    );

}

 

 

SFtpMT2.cpp

 

#include "SshBasics.h"

 

// SFtpAsyncGet2: Demonstrates multiple file downloads, using a parallelization loop.

 

 

void SFtpAsyncGet2(SshSession& session)

{

    const int MAXDOWNLOADS = 4;

    const char *path = "/pub/example/";

 

    SFtp::DirList ls;

    {

        // Get a remote dir listing.

        SFtp browser(session);

        if(!browser.ListDir(path, ls)) {

            RLOG(browser.GetErrorDesc());

            return;

        }

    }

 

    // Filter the dir list.

    auto files =  FilterRange(ls, [](const SFtp::DirEntry& e) { return e.IsFile() && e.GetSize() <= 65536; });

 

    // Loop over.

    CoFor(min(files.GetCount(), MAXDOWNLOADS), [&files, &path, &session](int i){

        const SFtp::DirEntry& e = files[i];

        String fpath = AppendFileName(path, e.GetName());

        RLOG("Downloading " << fpath);

        SFtp sftp(session);

        String file = sftp.LoadFile(fpath);

        if(sftp.IsError())

            RLOG(Format("Worker #%d: %s", sftp.GetId(), sftp.GetErrorDesc()));

        else

            RLOG("File " << e.GetName() << " is successfully downloaded.");

    });

}

 

 

 

PickSemantics.cpp

 

#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);

}

 

 

SFtpMT.cpp

 

#include "SshBasics.h"

 

// SFtpAsyncGet: DEmonstrates multiple file downloads, using worker threads.

 

AsyncWork<void> AsyncGet(SshSession& session, const String& path)

{

    auto worker = Upp::Async([=, &session] {

        LOG("Downloading " << path);

        SFtp sftp(session);

        String file = sftp.LoadFile(path);

        if(sftp.IsError())

            throw Ssh::Error(Format("Worker #%d: %s", sftp.GetId(), sftp.GetErrorDesc()));

        LOG("File " << GetFileName(path) << " is successfully downloaded.");

    });

    return pick(worker);

}

 

void CheckError(AsyncWork<void>& w)

{

    try {

        w.Get();

    }

    catch(const Ssh::Error& e) {

        LOG(e);

    }

}

 

void SFtpAsyncGet(SshSession& session)

{

    const int MAXDOWNLOADS = 4;

    const char *path = "/pub/example/";

    

    SFtp browser(session);

    SFtp::DirList ls;

    

    if(!browser.ListDir(path, ls)) { // Get a dir listing to extract file names on-the-fly.

        LOG(browser.GetErrorDesc());

        return;

    }

 

    Array<AsyncWork<void>> workers;

    

    for(const auto& e : ls) {

        if(!e.IsFile() || (e.GetSize() > 65535))

            continue;

        if(workers.GetCount() == MAXDOWNLOADS)

            break;

        workers.Add(AsyncGet(session, AppendFileName(path, e.GetName())));

    }

    

    while(!workers.IsEmpty()) {

        for(int i = 0; i < workers.GetCount(); i++) {

            auto& worker = workers[i];

            if(worker.IsFinished()) {

                CheckError(worker);

                workers.Remove(i);

                break;

            }

            Sleep(1);

        }

    }

}

 

 

 

ExecMT.cpp

 

#include "SshBasics.h"

 

// ExecAsyncListDir: Demonstrates remote command execution in worker threads.

 

AsyncWork<void> AsyncListDir(SshSession& session, const String& path)

{

    auto worker = Upp::Async([=, &session] {

        SshExec exec(session);

        String cout, cerr;

        int exit_code = exec("ls -l " + path, cout, cerr);

        if(exec.IsError())

            throw Ssh::Error(Format("Worker #%d: %s", exec.GetId(), exec.GetErrorDesc()));

        LOG("Directory: " << path);

        LOG("Exit code: " << exit_code);

        LOG("Stdout:\n" << cout);

        LOG("Stderr:\n" << cerr);

    });

    return pick(worker);

}

 

void GetResult(AsyncWork<void>& w)

{

    try {

        w.Get();

    }

    catch(const Ssh::Error& e) {

        LOG(e);

    }

}

 

void ExecAsyncListDir(SshSession& session)

{

    const char *path1 = "/";

    const char *path2 = "/pub/example/";

    

    auto worker1 = AsyncListDir(session, path1);

    auto worker2 = AsyncListDir(session, path2);

    

    GetResult(worker2);

    GetResult(worker1);

}

 

 

SFtpFileSystemInfo.cpp

 

#include "SshBasics.h"

 

// SFtpTransparency:

// Demonstrates  access to sftp directory hierarcy in a file-system-agnostic (transparent) way.

 

void ReadDirEntries(FileSystemInfo& fsi, const String& path)

{

    int maxentry = 5;

    for(FileSystemInfo::FileInfo entry : fsi.Find(path, maxentry)) {

        DUMP(entry.filename);

        DUMP(entry.is_folder);

        DUMP(entry.length);

        DUMP(entry.last_access_time);

        //...

    }

}

 

void SFtpTransparency(SshSession& session)

{

    LOG("Local file system objects----------------------------------------------------------");

    ReadDirEntries(StdFileSystemInfo(), GetCurrentDirectory());

 

    SFtp sftp(session);

    SFtpFileSystemInfo sfsi(sftp);

    

    LOG("Remote file system objects---------------------------------------------------------");

    ReadDirEntries((FileSystemInfo&) sfsi, "/pub/example/*.png");

    

    if(sftp.IsError())

        LOG(sftp.GetErrorDesc());

}

 

 

 

Tunnel.cpp

 

#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');

        }

    }

}

 

 

X11Shell.cpp

 

#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());

}

 

 

 

Do you want to contribute?