libssh 0.5.2
|
00001 /* 00002 * This file is part of the SSH Library 00003 * 00004 * Copyright (c) 2010 by Aris Adamantiadis 00005 * 00006 * The SSH Library is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU Lesser General Public License as published by 00008 * the Free Software Foundation; either version 2.1 of the License, or (at your 00009 * option) any later version. 00010 * 00011 * The SSH Library is distributed in the hope that it will be useful, but 00012 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 00013 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 00014 * License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public License 00017 * along with the SSH Library; see the file COPYING. If not, write to 00018 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, 00019 * MA 02111-1307, USA. 00020 */ 00021 00022 #ifndef LIBSSHPP_HPP_ 00023 #define LIBSSHPP_HPP_ 00024 00052 /* do not use deprecated functions */ 00053 #define LIBSSH_LEGACY_0_4 00054 00055 #include <libssh/libssh.h> 00056 #include <libssh/server.h> 00057 #include <stdlib.h> 00058 #include <stdarg.h> 00059 #include <stdio.h> 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 userauthAutopubkey(void){ 00181 int ret=ssh_userauth_autopubkey(c_session,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 } 00216 int userauthOfferPubkey(int type, ssh_string pubkey){ 00217 int ret=ssh_userauth_offer_pubkey(c_session,NULL,type,pubkey); 00218 ssh_throw(ret); 00219 return ret; 00220 } 00228 int userauthPubkey(ssh_string pubkey, ssh_private_key privkey){ 00229 int ret=ssh_userauth_pubkey(c_session,NULL,pubkey,privkey); 00230 ssh_throw(ret); 00231 return ret; 00232 } 00233 int userauthPubkey(ssh_private_key privkey){ 00234 int ret=ssh_userauth_pubkey(c_session,NULL,NULL,privkey); 00235 ssh_throw(ret); 00236 return ret; 00237 } 00238 int userauthPrivatekeyFile(const char *filename, 00239 const char *passphrase); 00245 int getAuthList(){ 00246 int ret=ssh_userauth_list(c_session, NULL); 00247 ssh_throw(ret); 00248 return ret; 00249 } 00253 void disconnect(){ 00254 ssh_disconnect(c_session); 00255 } 00260 const char *getDisconnectMessage(){ 00261 const char *msg=ssh_get_disconnect_message(c_session); 00262 return msg; 00263 } 00267 const char *getError(){ 00268 return ssh_get_error(c_session); 00269 } 00273 int getErrorCode(){ 00274 return ssh_get_error_code(c_session); 00275 } 00282 socket_t getSocket(){ 00283 return ssh_get_fd(c_session); 00284 } 00289 std::string getIssueBanner(){ 00290 char *banner=ssh_get_issue_banner(c_session); 00291 std::string ret= std::string(banner); 00292 ::free(banner); 00293 return ret; 00294 } 00299 int getOpensshVersion(){ 00300 return ssh_get_openssh_version(c_session); 00301 } 00306 int getVersion(){ 00307 return ssh_get_version(c_session); 00308 } 00315 int isServerKnown(){ 00316 int ret=ssh_is_server_known(c_session); 00317 ssh_throw(ret); 00318 return ret; 00319 } 00320 void log(int priority, const char *format, ...){ 00321 char buffer[1024]; 00322 va_list va; 00323 00324 va_start(va, format); 00325 vsnprintf(buffer, sizeof(buffer), format, va); 00326 va_end(va); 00327 ssh_log(c_session,priority, "%s", buffer); 00328 } 00329 00334 void_throwable optionsCopy(const Session &source){ 00335 ssh_throw(ssh_options_copy(source.c_session,&c_session)); 00336 return_throwable; 00337 } 00343 void_throwable optionsParseConfig(const char *file){ 00344 ssh_throw(ssh_options_parse_config(c_session,file)); 00345 return_throwable; 00346 } 00350 void silentDisconnect(){ 00351 ssh_silent_disconnect(c_session); 00352 } 00358 int writeKnownhost(){ 00359 int ret = ssh_write_knownhost(c_session); 00360 ssh_throw(ret); 00361 return ret; 00362 } 00363 00372 Channel *acceptForward(int timeout_ms); 00373 /* acceptForward is implemented later in this file */ 00374 00375 void_throwable cancelForward(const char *address, int port){ 00376 int err=ssh_forward_cancel(c_session, address, port); 00377 ssh_throw(err); 00378 return_throwable; 00379 } 00380 00381 void_throwable listenForward(const char *address, int port, 00382 int &boundport){ 00383 int err=ssh_forward_listen(c_session, address, port, &boundport); 00384 ssh_throw(err); 00385 return_throwable; 00386 } 00387 00388 private: 00389 ssh_session c_session; 00390 ssh_session getCSession(){ 00391 return c_session; 00392 } 00393 /* No copy constructor, no = operator */ 00394 Session(const Session &); 00395 Session& operator=(const Session &); 00396 }; 00397 00402 class Channel { 00403 friend class Session; 00404 public: 00405 Channel(Session &session){ 00406 channel=ssh_channel_new(session.getCSession()); 00407 this->session=&session; 00408 } 00409 ~Channel(){ 00410 ssh_channel_free(channel); 00411 channel=NULL; 00412 } 00413 00422 Channel *acceptX11(int timeout_ms){ 00423 ssh_channel x11chan = ssh_channel_accept_x11(channel,timeout_ms); 00424 ssh_throw_null(getCSession(),x11chan); 00425 Channel *newchan = new Channel(getSession(),x11chan); 00426 return newchan; 00427 } 00434 void_throwable changePtySize(int cols, int rows){ 00435 int err=ssh_channel_change_pty_size(channel,cols,rows); 00436 ssh_throw(err); 00437 return_throwable; 00438 } 00439 00444 void_throwable close(){ 00445 ssh_throw(ssh_channel_close(channel)); 00446 return_throwable; 00447 } 00448 00449 int getExitStatus(){ 00450 return ssh_channel_get_exit_status(channel); 00451 } 00452 Session &getSession(){ 00453 return *session; 00454 } 00458 bool isClosed(){ 00459 return ssh_channel_is_closed(channel) != 0; 00460 } 00464 bool isEof(){ 00465 return ssh_channel_is_eof(channel) != 0; 00466 } 00470 bool isOpen(){ 00471 return ssh_channel_is_open(channel) != 0; 00472 } 00473 int openForward(const char *remotehost, int remoteport, 00474 const char *sourcehost=NULL, int localport=0){ 00475 int err=ssh_channel_open_forward(channel,remotehost,remoteport, 00476 sourcehost, localport); 00477 ssh_throw(err); 00478 return err; 00479 } 00480 /* TODO: completely remove this ? */ 00481 void_throwable openSession(){ 00482 int err=ssh_channel_open_session(channel); 00483 ssh_throw(err); 00484 return_throwable; 00485 } 00486 int poll(bool is_stderr=false){ 00487 int err=ssh_channel_poll(channel,is_stderr); 00488 ssh_throw(err); 00489 return err; 00490 } 00491 int read(void *dest, size_t count, bool is_stderr=false){ 00492 int err; 00493 /* handle int overflow */ 00494 if(count > 0x7fffffff) 00495 count = 0x7fffffff; 00496 err=ssh_channel_read(channel,dest,count,is_stderr); 00497 ssh_throw(err); 00498 return err; 00499 } 00500 int readNonblocking(void *dest, size_t count, bool is_stderr=false){ 00501 int err; 00502 /* handle int overflow */ 00503 if(count > 0x7fffffff) 00504 count = 0x7fffffff; 00505 err=ssh_channel_read_nonblocking(channel,dest,count,is_stderr); 00506 ssh_throw(err); 00507 return err; 00508 } 00509 void_throwable requestEnv(const char *name, const char *value){ 00510 int err=ssh_channel_request_env(channel,name,value); 00511 ssh_throw(err); 00512 return_throwable; 00513 } 00514 00515 void_throwable requestExec(const char *cmd){ 00516 int err=ssh_channel_request_exec(channel,cmd); 00517 ssh_throw(err); 00518 return_throwable; 00519 } 00520 void_throwable requestPty(const char *term=NULL, int cols=0, int rows=0){ 00521 int err; 00522 if(term != NULL && cols != 0 && rows != 0) 00523 err=ssh_channel_request_pty_size(channel,term,cols,rows); 00524 else 00525 err=ssh_channel_request_pty(channel); 00526 ssh_throw(err); 00527 return_throwable; 00528 } 00529 00530 void_throwable requestShell(){ 00531 int err=ssh_channel_request_shell(channel); 00532 ssh_throw(err); 00533 return_throwable; 00534 } 00535 void_throwable requestSendSignal(const char *signum){ 00536 int err=ssh_channel_request_send_signal(channel, signum); 00537 ssh_throw(err); 00538 return_throwable; 00539 } 00540 void_throwable requestSubsystem(const char *subsystem){ 00541 int err=ssh_channel_request_subsystem(channel,subsystem); 00542 ssh_throw(err); 00543 return_throwable; 00544 } 00545 int requestX11(bool single_connection, 00546 const char *protocol, const char *cookie, int screen_number){ 00547 int err=ssh_channel_request_x11(channel,single_connection, 00548 protocol, cookie, screen_number); 00549 ssh_throw(err); 00550 return err; 00551 } 00552 void_throwable sendEof(){ 00553 int err=ssh_channel_send_eof(channel); 00554 ssh_throw(err); 00555 return_throwable; 00556 } 00566 int write(const void *data, size_t len, bool is_stderr=false){ 00567 int ret; 00568 if(is_stderr){ 00569 ret=ssh_channel_write_stderr(channel,data,len); 00570 } else { 00571 ret=ssh_channel_write(channel,data,len); 00572 } 00573 ssh_throw(ret); 00574 return ret; 00575 } 00576 private: 00577 ssh_session getCSession(){ 00578 return session->getCSession(); 00579 } 00580 Channel (Session &session, ssh_channel c_channel){ 00581 this->channel=c_channel; 00582 this->session=&session; 00583 } 00584 Session *session; 00585 ssh_channel channel; 00586 /* No copy and no = operator */ 00587 Channel(const Channel &); 00588 Channel &operator=(const Channel &); 00589 }; 00590 00591 00592 /* This code cannot be put inline due to references to Channel */ 00593 Channel *Session::acceptForward(int timeout_ms){ 00594 ssh_channel forward = ssh_forward_accept(c_session, 00595 timeout_ms); 00596 ssh_throw_null(c_session,forward); 00597 Channel *newchan = new Channel(*this,forward); 00598 return newchan; 00599 } 00600 00601 } // namespace ssh 00602 00604 #endif /* LIBSSHPP_HPP_ */