diff --git a/examples/libsshpp.cpp b/examples/libsshpp.cpp index eb415d8c..f9bfe63d 100644 --- a/examples/libsshpp.cpp +++ b/examples/libsshpp.cpp @@ -1,10 +1,31 @@ +/* +Copyright 2010 Aris Adamantiadis +This file is part of the SSH Library + +You are free to copy this file, modify it in any way, consider it being public +domain. This does not apply to the rest of the library though, but it is +allowed to cut-and-paste working code from this file to any license of +program. +*/ + +/* This file demonstrates the use of the C++ wrapper to libssh */ + +#include #include int main(int argc, const char **argv){ ssh::Session session; - session.setOption(SSH_OPTIONS_HOST,"localhost"); - session.connect(); - session.userauthAutopubkey(); + try { + if(argc>1) + session.setOption(SSH_OPTIONS_HOST,argv[1]); + else + session.setOption(SSH_OPTIONS_HOST,"localhost"); + session.connect(); + session.userauthAutopubkey(); + } catch (ssh::SshException e){ + std::cout << "Error during connection : "; + std::cout << e.getError() << std::endl; + } return 0; } diff --git a/include/libssh/libsshpp.hpp b/include/libssh/libsshpp.hpp index ae841d72..de2d29c4 100644 --- a/include/libssh/libsshpp.hpp +++ b/include/libssh/libsshpp.hpp @@ -25,35 +25,96 @@ /** @defgroup ssh_cpp libssh C++ wrapper * @addtogroup ssh_cpp * @{ + * The C++ bindings for libssh are completely embedded in a single .hpp file, and + * this for two reasons: + * - C++ is hard to keep binary compatible, C is easy. We try to keep libssh C version + * as much as possible binary compatible between releases, while this would be hard for + * C++. If you compile your program with these headers, you will only link to the C version + * of libssh which will be kept ABI compatible. No need to recompile your C++ program + * each time a new binary-compatible version of libssh is out + * - Most of the functions in this file are really short and are probably worth the "inline" + * linking mode, which the compiler can decide to do in some case. There would be nearly no + * performance penalty of using the wrapper rather than native calls. */ #include - namespace ssh { + +/** @brief This class describes a SSH Exception object. This object can be throwed + * by several SSH functions that interact with the network, and may fail because of + * socket, protocol or memory errors. + */ +class SshException{ +public: + SshException(ssh_session csession){ + code=ssh_get_error_code(csession); + description=ssh_get_error(csession); + } + SshException(const SshException &e){ + code=e.code; + description=e.description; + } + /** @brief returns the Error code + * @returns SSH_FATAL Fatal error happened (not recoverable) + * @returns SSH_REQUEST_DENIED Request was denied by remote host + * @see ssh_get_error_code + */ + int getCode(){ + return code; + } + /** @brief returns the error message of the last exception + * @returns pointer to a c string containing the description of error + * @see ssh_get_error + */ + const char *getError(){ + return description; + } +private: + int code; + const char *description; +}; + +/** + * The ssh::Session class contains the state of a SSH connection. + */ class Session { + friend class Channel; public: Session(){ - session=ssh_new(); + c_session=ssh_new(); } ~Session(){ - ssh_free(session); - session=NULL; + ssh_free(c_session); + c_session=NULL; } void setOption(enum ssh_options_e type, const char *option){ - ssh_options_set(session,type,option); + ssh_options_set(c_session,type,option); } void setOption(enum ssh_options_e type, long int option){ - ssh_options_set(session,type,&option); + ssh_options_set(c_session,type,&option); } void setOption(enum ssh_options_e type, void *option){ - ssh_options_set(session,type,option); + ssh_options_set(c_session,type,option); } - int connect(){ - return ssh_connect(session); + /** @brief connects to the remote host + * @throws SshException on error + * @see ssh_connect + */ + void connect(){ + int ret=ssh_connect(c_session); + if(ret != SSH_OK){ + throw SshException(getCSession()); + } } int userauthAutopubkey(){ - return ssh_userauth_autopubkey(session,NULL); + return ssh_userauth_autopubkey(c_session,NULL); } + int userauthNone(); + int userauthPassword(const char *password); + int userauthOfferPubkey(ssh_string pubkey); + int userauthPubkey(ssh_string pubkey, ssh_private_key privkey); + int userauthPubkey(ssh_private_key privkey); + int userauthPrivatekeyFile(const char *filename, const char *passphrase); int getAuthList(); int disconnect(); const char *getDisconnectMessage(); @@ -64,13 +125,63 @@ public: int getOpensshVersion(); int getVersion(); int isServerKnown(); - + void log(int priority, const char *format, ...); + void optionsCopy(const Session &source); + void optionsParseConfig(const char *file); + void silentDisconnect(); + int writeKnownhost(); private: - ssh_session session; + ssh_session c_session; + ssh_session getCSession(){ + return c_session; + } }; -} +class Channel { +public: + Channel(Session &session){ + channel=channel_new(session.getCSession()); + this->session=&session; + } + ~Channel(){ + channel_free(channel); + channel=NULL; + } + int acceptX11(int timeout_ms); + int changePtySize(int cols, int rows); + int acceptForward(int timeout_ms); + int close(); + int cancelForward(const char *address, int port); + int listenForward(const char *address, int port, int &boundport); + int getExitStatus(); + Session &getSession(){ + return *session; + } + int isClosed(); + int isEof(); + int isOpen(); + int openForward(const char *remotehost, int remoteport, + const char *sourcehost=NULL, int localport=0); + int openSession(); + int poll(bool is_stderr=false); + int read(void *dest, size_t count, bool is_stderr=false); + int readNonblocking(void *dest, size_t count, bool is_stderr=false); + int requestEnv(const char *name, const char *value); + int requestExec(const char *cmd); + int requestPty(const char *term=NULL, int cols=0, int rows=0); + int requestShell(); + int requestSendSignal(const char *signum); + int requestSubsystem(const char *subsystem); + int requestX11(bool single_connection, const char *protocol, const char *cookie, + int screen_number); + int sendEof(); + int write(const void *data, size_t len, bool is_stderr=false); +private: + Session *session; + ssh_channel channel; +}; +} // namespace ssh /** @} */ #endif /* LIBSSHPP_HPP_ */ diff --git a/libssh/messages.c b/libssh/messages.c index 8cd9ab55..0d3620c0 100644 --- a/libssh/messages.c +++ b/libssh/messages.c @@ -444,6 +444,7 @@ end: return SSH_PACKET_USED; } +/* TODO: make this function accept a ssh_channel */ ssh_channel ssh_message_channel_request_open_reply_accept(ssh_message msg) { ssh_session session = msg->session; ssh_channel chan = NULL;