|
libssh
0.7.2
|
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_ */
1.7.5.1