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
00060 namespace ssh {
00061
00062 class Channel;
00067 #ifndef SSH_NO_CPP_EXCEPTIONS
00068
00073 class SshException{
00074 public:
00075 SshException(ssh_session csession){
00076 code=ssh_get_error_code(csession);
00077 description=std::string(ssh_get_error(csession));
00078 }
00079 SshException(const SshException &e){
00080 code=e.code;
00081 description=e.description;
00082 }
00088 int getCode(){
00089 return code;
00090 }
00095 std::string getError(){
00096 return description;
00097 }
00098 private:
00099 int code;
00100 std::string description;
00101 };
00102
00106 #define ssh_throw(x) if((x)==SSH_ERROR) throw SshException(getCSession())
00107 #define ssh_throw_null(CSession,x) if((x)==NULL) throw SshException(CSession)
00108 #define void_throwable void
00109 #define return_throwable return
00110
00111 #else
00112
00113
00114
00115
00116 #define ssh_throw(x) if((x)==SSH_ERROR) return SSH_ERROR
00117 #define ssh_throw_null(CSession,x) if((x)==NULL) return NULL
00118 #define void_throwable int
00119 #define return_throwable return SSH_OK
00120 #endif
00121
00125 class Session {
00126 friend class Channel;
00127 public:
00128 Session(){
00129 c_session=ssh_new();
00130 }
00131 ~Session(){
00132 ssh_free(c_session);
00133 c_session=NULL;
00134 }
00141 void_throwable setOption(enum ssh_options_e type, const char *option){
00142 ssh_throw(ssh_options_set(c_session,type,option));
00143 return_throwable;
00144 }
00151 void_throwable setOption(enum ssh_options_e type, long int option){
00152 ssh_throw(ssh_options_set(c_session,type,&option));
00153 return_throwable;
00154 }
00161 void_throwable setOption(enum ssh_options_e type, void *option){
00162 ssh_throw(ssh_options_set(c_session,type,option));
00163 return_throwable;
00164 }
00169 void_throwable connect(){
00170 int ret=ssh_connect(c_session);
00171 ssh_throw(ret);
00172 return_throwable;
00173 }
00179 int userauthPublickeyAuto(void){
00180 int ret=ssh_userauth_publickey_auto(c_session, NULL, NULL);
00181 ssh_throw(ret);
00182 return ret;
00183 }
00191 int userauthNone(){
00192 int ret=ssh_userauth_none(c_session,NULL);
00193 ssh_throw(ret);
00194 return ret;
00195 }
00202 int userauthPassword(const char *password){
00203 int ret=ssh_userauth_password(c_session,NULL,password);
00204 ssh_throw(ret);
00205 return ret;
00206 }
00214 int userauthTryPublickey(ssh_key pubkey){
00215 int ret=ssh_userauth_try_publickey(c_session, NULL, pubkey);
00216 ssh_throw(ret);
00217 return ret;
00218 }
00225 int userauthPublickey(ssh_key privkey){
00226 int ret=ssh_userauth_publickey(c_session, NULL, privkey);
00227 ssh_throw(ret);
00228 return ret;
00229 }
00230 int userauthPrivatekeyFile(const char *filename,
00231 const char *passphrase);
00237 int getAuthList(){
00238 int ret=ssh_userauth_list(c_session, NULL);
00239 ssh_throw(ret);
00240 return ret;
00241 }
00245 void disconnect(){
00246 ssh_disconnect(c_session);
00247 }
00252 const char *getDisconnectMessage(){
00253 const char *msg=ssh_get_disconnect_message(c_session);
00254 return msg;
00255 }
00259 const char *getError(){
00260 return ssh_get_error(c_session);
00261 }
00265 int getErrorCode(){
00266 return ssh_get_error_code(c_session);
00267 }
00274 socket_t getSocket(){
00275 return ssh_get_fd(c_session);
00276 }
00281 std::string getIssueBanner(){
00282 char *banner=ssh_get_issue_banner(c_session);
00283 std::string ret= std::string(banner);
00284 ::free(banner);
00285 return ret;
00286 }
00291 int getOpensshVersion(){
00292 return ssh_get_openssh_version(c_session);
00293 }
00298 int getVersion(){
00299 return ssh_get_version(c_session);
00300 }
00307 int isServerKnown(){
00308 int ret=ssh_is_server_known(c_session);
00309 ssh_throw(ret);
00310 return ret;
00311 }
00312 void log(int priority, const char *format, ...){
00313 char buffer[1024];
00314 va_list va;
00315
00316 va_start(va, format);
00317 vsnprintf(buffer, sizeof(buffer), format, va);
00318 va_end(va);
00319 _ssh_log(priority, "libsshpp", "%s", buffer);
00320 }
00321
00326 void_throwable optionsCopy(const Session &source){
00327 ssh_throw(ssh_options_copy(source.c_session,&c_session));
00328 return_throwable;
00329 }
00335 void_throwable optionsParseConfig(const char *file){
00336 ssh_throw(ssh_options_parse_config(c_session,file));
00337 return_throwable;
00338 }
00342 void silentDisconnect(){
00343 ssh_silent_disconnect(c_session);
00344 }
00350 int writeKnownhost(){
00351 int ret = ssh_write_knownhost(c_session);
00352 ssh_throw(ret);
00353 return ret;
00354 }
00355
00364 inline Channel *acceptForward(int timeout_ms);
00365
00366
00367 void_throwable cancelForward(const char *address, int port){
00368 int err=ssh_forward_cancel(c_session, address, port);
00369 ssh_throw(err);
00370 return_throwable;
00371 }
00372
00373 void_throwable listenForward(const char *address, int port,
00374 int &boundport){
00375 int err=ssh_forward_listen(c_session, address, port, &boundport);
00376 ssh_throw(err);
00377 return_throwable;
00378 }
00379
00380 private:
00381 ssh_session c_session;
00382 ssh_session getCSession(){
00383 return c_session;
00384 }
00385
00386 Session(const Session &);
00387 Session& operator=(const Session &);
00388 };
00389
00394 class Channel {
00395 friend class Session;
00396 public:
00397 Channel(Session &session){
00398 channel=ssh_channel_new(session.getCSession());
00399 this->session=&session;
00400 }
00401 ~Channel(){
00402 ssh_channel_free(channel);
00403 channel=NULL;
00404 }
00405
00414 Channel *acceptX11(int timeout_ms){
00415 ssh_channel x11chan = ssh_channel_accept_x11(channel,timeout_ms);
00416 ssh_throw_null(getCSession(),x11chan);
00417 Channel *newchan = new Channel(getSession(),x11chan);
00418 return newchan;
00419 }
00426 void_throwable changePtySize(int cols, int rows){
00427 int err=ssh_channel_change_pty_size(channel,cols,rows);
00428 ssh_throw(err);
00429 return_throwable;
00430 }
00431
00436 void_throwable close(){
00437 ssh_throw(ssh_channel_close(channel));
00438 return_throwable;
00439 }
00440
00441 int getExitStatus(){
00442 return ssh_channel_get_exit_status(channel);
00443 }
00444 Session &getSession(){
00445 return *session;
00446 }
00450 bool isClosed(){
00451 return ssh_channel_is_closed(channel) != 0;
00452 }
00456 bool isEof(){
00457 return ssh_channel_is_eof(channel) != 0;
00458 }
00462 bool isOpen(){
00463 return ssh_channel_is_open(channel) != 0;
00464 }
00465 int openForward(const char *remotehost, int remoteport,
00466 const char *sourcehost=NULL, int localport=0){
00467 int err=ssh_channel_open_forward(channel,remotehost,remoteport,
00468 sourcehost, localport);
00469 ssh_throw(err);
00470 return err;
00471 }
00472
00473 void_throwable openSession(){
00474 int err=ssh_channel_open_session(channel);
00475 ssh_throw(err);
00476 return_throwable;
00477 }
00478 int poll(bool is_stderr=false){
00479 int err=ssh_channel_poll(channel,is_stderr);
00480 ssh_throw(err);
00481 return err;
00482 }
00483 int read(void *dest, size_t count, bool is_stderr){
00484 int err;
00485
00486 if(count > 0x7fffffff)
00487 count = 0x7fffffff;
00488 err=ssh_channel_read_timeout(channel,dest,count,is_stderr,-1);
00489 ssh_throw(err);
00490 return err;
00491 }
00492 int read(void *dest, size_t count, int timeout){
00493 int err;
00494
00495 if(count > 0x7fffffff)
00496 count = 0x7fffffff;
00497 err=ssh_channel_read_timeout(channel,dest,count,false,timeout);
00498 ssh_throw(err);
00499 return err;
00500 }
00501 int read(void *dest, size_t count, bool is_stderr=false, int timeout=-1){
00502 int err;
00503
00504 if(count > 0x7fffffff)
00505 count = 0x7fffffff;
00506 err=ssh_channel_read_timeout(channel,dest,count,is_stderr,timeout);
00507 ssh_throw(err);
00508 return err;
00509 }
00510 int readNonblocking(void *dest, size_t count, bool is_stderr=false){
00511 int err;
00512
00513 if(count > 0x7fffffff)
00514 count = 0x7fffffff;
00515 err=ssh_channel_read_nonblocking(channel,dest,count,is_stderr);
00516 ssh_throw(err);
00517 return err;
00518 }
00519 void_throwable requestEnv(const char *name, const char *value){
00520 int err=ssh_channel_request_env(channel,name,value);
00521 ssh_throw(err);
00522 return_throwable;
00523 }
00524
00525 void_throwable requestExec(const char *cmd){
00526 int err=ssh_channel_request_exec(channel,cmd);
00527 ssh_throw(err);
00528 return_throwable;
00529 }
00530 void_throwable requestPty(const char *term=NULL, int cols=0, int rows=0){
00531 int err;
00532 if(term != NULL && cols != 0 && rows != 0)
00533 err=ssh_channel_request_pty_size(channel,term,cols,rows);
00534 else
00535 err=ssh_channel_request_pty(channel);
00536 ssh_throw(err);
00537 return_throwable;
00538 }
00539
00540 void_throwable requestShell(){
00541 int err=ssh_channel_request_shell(channel);
00542 ssh_throw(err);
00543 return_throwable;
00544 }
00545 void_throwable requestSendSignal(const char *signum){
00546 int err=ssh_channel_request_send_signal(channel, signum);
00547 ssh_throw(err);
00548 return_throwable;
00549 }
00550 void_throwable requestSubsystem(const char *subsystem){
00551 int err=ssh_channel_request_subsystem(channel,subsystem);
00552 ssh_throw(err);
00553 return_throwable;
00554 }
00555 int requestX11(bool single_connection,
00556 const char *protocol, const char *cookie, int screen_number){
00557 int err=ssh_channel_request_x11(channel,single_connection,
00558 protocol, cookie, screen_number);
00559 ssh_throw(err);
00560 return err;
00561 }
00562 void_throwable sendEof(){
00563 int err=ssh_channel_send_eof(channel);
00564 ssh_throw(err);
00565 return_throwable;
00566 }
00576 int write(const void *data, size_t len, bool is_stderr=false){
00577 int ret;
00578 if(is_stderr){
00579 ret=ssh_channel_write_stderr(channel,data,len);
00580 } else {
00581 ret=ssh_channel_write(channel,data,len);
00582 }
00583 ssh_throw(ret);
00584 return ret;
00585 }
00586 private:
00587 ssh_session getCSession(){
00588 return session->getCSession();
00589 }
00590 Channel (Session &session, ssh_channel c_channel){
00591 this->channel=c_channel;
00592 this->session=&session;
00593 }
00594 Session *session;
00595 ssh_channel channel;
00596
00597 Channel(const Channel &);
00598 Channel &operator=(const Channel &);
00599 };
00600
00601
00602
00603 Channel *Session::acceptForward(int timeout_ms){
00604 ssh_channel forward = ssh_forward_accept(c_session,
00605 timeout_ms);
00606 ssh_throw_null(c_session,forward);
00607 Channel *newchan = new Channel(*this,forward);
00608 return newchan;
00609 }
00610
00611 }
00612
00614 #endif