00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef LIBSSHPP_HPP_
00022 #define LIBSSHPP_HPP_
00023
00051
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
00115
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
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
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
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
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
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
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
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
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 }
00612
00614 #endif