libssh  0.7.2
include/libssh/libsshpp.hpp
00001 /*
00002  * This file is part of the SSH Library
00003  *
00004  * Copyright (c) 2010 by Aris Adamantiadis
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00019  */
00020 
00021 #ifndef LIBSSHPP_HPP_
00022 #define LIBSSHPP_HPP_
00023 
00051 /* do not use deprecated functions */
00052 #define LIBSSH_LEGACY_0_4
00053 
00054 #include <libssh/libssh.h>
00055 #include <libssh/server.h>
00056 #include <stdlib.h>
00057 #include <stdarg.h>
00058 #include <stdio.h>
00059 #include <string>
00060 
00061 namespace ssh {
00062 
00063 class Channel;
00068 #ifndef SSH_NO_CPP_EXCEPTIONS
00069 
00074 class SshException{
00075 public:
00076   SshException(ssh_session csession){
00077     code=ssh_get_error_code(csession);
00078     description=std::string(ssh_get_error(csession));
00079   }
00080   SshException(const SshException &e){
00081     code=e.code;
00082     description=e.description;
00083   }
00089   int getCode(){
00090     return code;
00091   }
00096   std::string getError(){
00097     return description;
00098   }
00099 private:
00100   int code;
00101   std::string description;
00102 };
00103 
00107 #define ssh_throw(x) if((x)==SSH_ERROR) throw SshException(getCSession())
00108 #define ssh_throw_null(CSession,x) if((x)==NULL) throw SshException(CSession)
00109 #define void_throwable void
00110 #define return_throwable return
00111 
00112 #else
00113 
00114 /* No exception at all. All functions will return an error code instead
00115  * of an exception
00116  */
00117 #define ssh_throw(x) if((x)==SSH_ERROR) return SSH_ERROR
00118 #define ssh_throw_null(CSession,x) if((x)==NULL) return NULL
00119 #define void_throwable int
00120 #define return_throwable return SSH_OK
00121 #endif
00122 
00126 class Session {
00127   friend class Channel;
00128 public:
00129   Session(){
00130     c_session=ssh_new();
00131   }
00132   ~Session(){
00133     ssh_free(c_session);
00134     c_session=NULL;
00135   }
00142   void_throwable setOption(enum ssh_options_e type, const char *option){
00143     ssh_throw(ssh_options_set(c_session,type,option));
00144     return_throwable;
00145   }
00152   void_throwable setOption(enum ssh_options_e type, long int option){
00153     ssh_throw(ssh_options_set(c_session,type,&option));
00154     return_throwable;
00155   }
00162   void_throwable setOption(enum ssh_options_e type, void *option){
00163     ssh_throw(ssh_options_set(c_session,type,option));
00164     return_throwable;
00165   }
00170   void_throwable connect(){
00171     int ret=ssh_connect(c_session);
00172     ssh_throw(ret);
00173     return_throwable;
00174   }
00180   int userauthPublickeyAuto(void){
00181     int ret=ssh_userauth_publickey_auto(c_session, NULL, NULL);
00182     ssh_throw(ret);
00183     return ret;
00184   }
00192   int userauthNone(){
00193     int ret=ssh_userauth_none(c_session,NULL);
00194     ssh_throw(ret);
00195     return ret;
00196   }
00203   int userauthPassword(const char *password){
00204     int ret=ssh_userauth_password(c_session,NULL,password);
00205     ssh_throw(ret);
00206     return ret;
00207   }
00215   int userauthTryPublickey(ssh_key pubkey){
00216     int ret=ssh_userauth_try_publickey(c_session, NULL, pubkey);
00217     ssh_throw(ret);
00218     return ret;
00219   }
00226   int userauthPublickey(ssh_key privkey){
00227     int ret=ssh_userauth_publickey(c_session, NULL, privkey);
00228     ssh_throw(ret);
00229     return ret;
00230   }
00231   int userauthPrivatekeyFile(const char *filename,
00232       const char *passphrase);
00238   int getAuthList(){
00239     int ret=ssh_userauth_list(c_session, NULL);
00240     ssh_throw(ret);
00241     return ret;
00242   }
00246   void disconnect(){
00247     ssh_disconnect(c_session);
00248   }
00253   const char *getDisconnectMessage(){
00254     const char *msg=ssh_get_disconnect_message(c_session);
00255     return msg;
00256   }
00260   const char *getError(){
00261     return ssh_get_error(c_session);
00262   }
00266   int getErrorCode(){
00267     return ssh_get_error_code(c_session);
00268   }
00275   socket_t getSocket(){
00276     return ssh_get_fd(c_session);
00277   }
00282   std::string getIssueBanner(){
00283     char *banner=ssh_get_issue_banner(c_session);
00284     std::string ret= std::string(banner);
00285     ::free(banner);
00286     return ret;
00287   }
00292   int getOpensshVersion(){
00293     return ssh_get_openssh_version(c_session);
00294   }
00299   int getVersion(){
00300     return ssh_get_version(c_session);
00301   }
00308   int isServerKnown(){
00309     int ret=ssh_is_server_known(c_session);
00310     ssh_throw(ret);
00311     return ret;
00312   }
00313   void log(int priority, const char *format, ...){
00314     char buffer[1024];
00315     va_list va;
00316 
00317     va_start(va, format);
00318     vsnprintf(buffer, sizeof(buffer), format, va);
00319     va_end(va);
00320     _ssh_log(priority, "libsshpp", "%s", buffer);
00321   }
00322 
00327   void_throwable optionsCopy(const Session &source){
00328     ssh_throw(ssh_options_copy(source.c_session,&c_session));
00329     return_throwable;
00330   }
00336   void_throwable optionsParseConfig(const char *file){
00337     ssh_throw(ssh_options_parse_config(c_session,file));
00338     return_throwable;
00339   }
00343   void silentDisconnect(){
00344     ssh_silent_disconnect(c_session);
00345   }
00351   int writeKnownhost(){
00352     int ret = ssh_write_knownhost(c_session);
00353     ssh_throw(ret);
00354     return ret;
00355   }
00356 
00365   inline Channel *acceptForward(int timeout_ms);
00366   /* implemented outside the class due Channel references */
00367 
00368   void_throwable cancelForward(const char *address, int port){
00369     int err=ssh_channel_cancel_forward(c_session, address, port);
00370     ssh_throw(err);
00371     return_throwable;
00372   }
00373 
00374   void_throwable listenForward(const char *address, int port,
00375       int &boundport){
00376     int err=ssh_channel_listen_forward(c_session, address, port, &boundport);
00377     ssh_throw(err);
00378     return_throwable;
00379   }
00380 
00381 private:
00382   ssh_session c_session;
00383   ssh_session getCSession(){
00384     return c_session;
00385   }
00386   /* No copy constructor, no = operator */
00387   Session(const Session &);
00388   Session& operator=(const Session &);
00389 };
00390 
00395 class Channel {
00396   friend class Session;
00397 public:
00398   Channel(Session &session){
00399     channel=ssh_channel_new(session.getCSession());
00400     this->session=&session;
00401   }
00402   ~Channel(){
00403     ssh_channel_free(channel);
00404     channel=NULL;
00405   }
00406 
00415   Channel *acceptX11(int timeout_ms){
00416     ssh_channel x11chan = ssh_channel_accept_x11(channel,timeout_ms);
00417     ssh_throw_null(getCSession(),x11chan);
00418     Channel *newchan = new Channel(getSession(),x11chan);
00419     return newchan;
00420   }
00427   void_throwable changePtySize(int cols, int rows){
00428     int err=ssh_channel_change_pty_size(channel,cols,rows);
00429     ssh_throw(err);
00430     return_throwable;
00431   }
00432 
00437   void_throwable close(){
00438     ssh_throw(ssh_channel_close(channel));
00439     return_throwable;
00440   }
00441 
00442   int getExitStatus(){
00443     return ssh_channel_get_exit_status(channel);
00444   }
00445   Session &getSession(){
00446     return *session;
00447   }
00451   bool isClosed(){
00452     return ssh_channel_is_closed(channel) != 0;
00453   }
00457   bool isEof(){
00458     return ssh_channel_is_eof(channel) != 0;
00459   }
00463   bool isOpen(){
00464     return ssh_channel_is_open(channel) != 0;
00465   }
00466   int openForward(const char *remotehost, int remoteport,
00467       const char *sourcehost=NULL, int localport=0){
00468     int err=ssh_channel_open_forward(channel,remotehost,remoteport,
00469         sourcehost, localport);
00470     ssh_throw(err);
00471     return err;
00472   }
00473   /* TODO: completely remove this ? */
00474   void_throwable openSession(){
00475     int err=ssh_channel_open_session(channel);
00476     ssh_throw(err);
00477     return_throwable;
00478   }
00479   int poll(bool is_stderr=false){
00480     int err=ssh_channel_poll(channel,is_stderr);
00481     ssh_throw(err);
00482     return err;
00483   }
00484   int read(void *dest, size_t count, bool is_stderr){
00485     int err;
00486     /* handle int overflow */
00487     if(count > 0x7fffffff)
00488       count = 0x7fffffff;
00489     err=ssh_channel_read_timeout(channel,dest,count,is_stderr,-1);
00490     ssh_throw(err);
00491     return err;
00492   }
00493   int read(void *dest, size_t count, int timeout){
00494     int err;
00495     /* handle int overflow */
00496     if(count > 0x7fffffff)
00497       count = 0x7fffffff;
00498     err=ssh_channel_read_timeout(channel,dest,count,false,timeout);
00499     ssh_throw(err);
00500     return err;
00501   }
00502   int read(void *dest, size_t count, bool is_stderr=false, int timeout=-1){
00503     int err;
00504     /* handle int overflow */
00505     if(count > 0x7fffffff)
00506       count = 0x7fffffff;
00507     err=ssh_channel_read_timeout(channel,dest,count,is_stderr,timeout);
00508     ssh_throw(err);
00509     return err;
00510   }
00511   int readNonblocking(void *dest, size_t count, bool is_stderr=false){
00512     int err;
00513     /* handle int overflow */
00514     if(count > 0x7fffffff)
00515       count = 0x7fffffff;
00516     err=ssh_channel_read_nonblocking(channel,dest,count,is_stderr);
00517     ssh_throw(err);
00518     return err;
00519   }
00520   void_throwable requestEnv(const char *name, const char *value){
00521     int err=ssh_channel_request_env(channel,name,value);
00522     ssh_throw(err);
00523     return_throwable;
00524   }
00525 
00526   void_throwable requestExec(const char *cmd){
00527     int err=ssh_channel_request_exec(channel,cmd);
00528     ssh_throw(err);
00529     return_throwable;
00530   }
00531   void_throwable requestPty(const char *term=NULL, int cols=0, int rows=0){
00532     int err;
00533     if(term != NULL && cols != 0 && rows != 0)
00534       err=ssh_channel_request_pty_size(channel,term,cols,rows);
00535     else
00536       err=ssh_channel_request_pty(channel);
00537     ssh_throw(err);
00538     return_throwable;
00539   }
00540 
00541   void_throwable requestShell(){
00542     int err=ssh_channel_request_shell(channel);
00543     ssh_throw(err);
00544     return_throwable;
00545   }
00546   void_throwable requestSendSignal(const char *signum){
00547     int err=ssh_channel_request_send_signal(channel, signum);
00548     ssh_throw(err);
00549     return_throwable;
00550   }
00551   void_throwable requestSubsystem(const char *subsystem){
00552     int err=ssh_channel_request_subsystem(channel,subsystem);
00553     ssh_throw(err);
00554     return_throwable;
00555   }
00556   int requestX11(bool single_connection,
00557       const char *protocol, const char *cookie, int screen_number){
00558     int err=ssh_channel_request_x11(channel,single_connection,
00559         protocol, cookie, screen_number);
00560     ssh_throw(err);
00561     return err;
00562   }
00563   void_throwable sendEof(){
00564     int err=ssh_channel_send_eof(channel);
00565     ssh_throw(err);
00566     return_throwable;
00567   }
00577   int write(const void *data, size_t len, bool is_stderr=false){
00578     int ret;
00579     if(is_stderr){
00580       ret=ssh_channel_write_stderr(channel,data,len);
00581     } else {
00582       ret=ssh_channel_write(channel,data,len);
00583     }
00584     ssh_throw(ret);
00585     return ret;
00586   }
00587 private:
00588   ssh_session getCSession(){
00589     return session->getCSession();
00590   }
00591   Channel (Session &session, ssh_channel c_channel){
00592     this->channel=c_channel;
00593     this->session=&session;
00594   }
00595   Session *session;
00596   ssh_channel channel;
00597   /* No copy and no = operator */
00598   Channel(const Channel &);
00599   Channel &operator=(const Channel &);
00600 };
00601 
00602 
00603 inline Channel *Session::acceptForward(int timeout_ms){
00604     ssh_channel forward =
00605         ssh_channel_accept_forward(c_session, timeout_ms, NULL);
00606     ssh_throw_null(c_session,forward);
00607     Channel *newchan = new Channel(*this,forward);
00608     return newchan;
00609   }
00610 
00611 } // namespace ssh
00612 
00614 #endif /* LIBSSHPP_HPP_ */