00001
00008 #include "myssh.hpp"
00009
00010 #include <QDebug>
00011
00012 using namespace std;
00013
00014 struct termios terminal;
00015
00016
00017
00018 #ifndef HAVE_CFMAKERAW
00019 static void cfmakeraw(struct termios *termios_p){
00020 termios_p->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
00021 termios_p->c_oflag &= ~OPOST;
00022 termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
00023 termios_p->c_cflag &= ~(CSIZE|PARENB);
00024 termios_p->c_cflag |= CS8;
00025 }
00026 #endif
00027
00031 void Myssh::_lock()
00032 {
00033 while(_isLocked) {}
00034 _isLocked = true;
00035 }
00039 void Myssh::_unlock()
00040 {
00041 _isLocked = false;
00042 }
00043
00049 QStringList Myssh::send_cmd(QString s)
00050 {
00051 QStringList outerr;
00052 const char * c = (s+"\n").toStdString().c_str();
00053 char * commande = (char*)malloc(s.length()+2);
00054 strncpy(commande, c, s.length()+2);
00055 int res = 0;
00056
00057 _lock();
00058
00059 res = channel_write(channel, commande, strlen(commande));
00060 sleep(1);
00061
00062 outerr.append(_getStdOut());
00063 outerr.append(_getStdErr());
00064
00065 _unlock();
00066
00067 return outerr;
00068 }
00069
00073 QString Myssh::_getStdOut()
00074 {
00075 QString _out;
00076 int res;
00077 char buf[MYSSH_BUFFER_SIZE];
00078
00079 _out = QString("");
00080
00081
00082 channel_request_exec(channel, "");
00083 buf[MYSSH_BUFFER_SIZE-1] = '\0';
00084 res = channel_read_nonblocking(channel, buf, MYSSH_BUFFER_SIZE-1, 0);
00085
00086 while (res > 0)
00087 {
00088 buf[res] = '\0';
00089 _out.append(buf);
00090 channel_request_exec(channel, "");
00091 res = channel_read_nonblocking(channel, buf, MYSSH_BUFFER_SIZE-1, 0);
00092 }
00093 return _out;
00094 }
00095
00099 QString Myssh::_getStdErr()
00100 {
00101 QString _err;
00102 int res;
00103 char buf[MYSSH_BUFFER_SIZE];
00104
00105 _err = QString("");
00106
00107
00108 channel_request_exec(channel, "");
00109 buf[MYSSH_BUFFER_SIZE-1] = '\0';
00110 res = channel_read_nonblocking(channel, buf, MYSSH_BUFFER_SIZE-1, 1);
00111 while (res > 0)
00112 {
00113 buf[res] = '\0';
00114 _err.append(buf);
00115 res = channel_read_nonblocking(channel, buf, MYSSH_BUFFER_SIZE-1, 1);
00116 }
00117 return _err;
00118 }
00119
00123 void Myssh::shell()
00124 {
00125 struct termios terminal_local;
00126 int interactive=isatty(0);
00127
00128 channel = channel_new(session);
00129
00130 if(interactive){
00131 tcgetattr(0,&terminal_local);
00132 memcpy(&terminal,&terminal_local,sizeof(struct termios));
00133 }
00134 if(channel_open_session(channel)){
00135 _errmsg = QString("Error opening channel: ")+ssh_get_error(session);
00136 return;
00137 }
00138
00139 if(interactive)
00140 channel_request_pty(channel);
00141
00142 if(channel_request_shell(channel)){
00143 _errmsg = QString("Requesting shell: ")+ssh_get_error(session);
00144 return;
00145 }
00146 if(interactive){
00147 cfmakeraw(&terminal_local);
00148 tcsetattr(0,TCSANOW,&terminal_local);
00149 }
00150 }
00151
00152
00153 int Myssh::auth_kbdint(){
00154 int err=ssh_userauth_kbdint(session,NULL,NULL);
00155 char *name,*instruction,*prompt,*ptr;
00156 char buffer[128];
00157 int i,n;
00158 char echo;
00159 while (err==SSH_AUTH_INFO){
00160 name=ssh_userauth_kbdint_getname(session);
00161 instruction=ssh_userauth_kbdint_getinstruction(session);
00162 n=ssh_userauth_kbdint_getnprompts(session);
00163 if(strlen(name)>0)
00164 printf("%s\n",name);
00165 if(strlen(instruction)>0)
00166 printf("%s\n",instruction);
00167 for(i=0;i<n;++i)
00168 {
00169 prompt=ssh_userauth_kbdint_getprompt(session,i,&echo);
00170 if(echo)
00171 {
00172 printf("%s",prompt);
00173 fgets(buffer,sizeof(buffer),stdin);
00174 buffer[sizeof(buffer)-1]=0;
00175 if((ptr=strchr(buffer,'\n')))
00176 *ptr=0;
00177 ssh_userauth_kbdint_setanswer(session,i,buffer);
00178 memset(buffer,0,strlen(buffer));
00179 } else {
00180 ptr=getpass(prompt);
00181 ssh_userauth_kbdint_setanswer(session,i,ptr);
00182 }
00183 }
00184 err=ssh_userauth_kbdint(session,NULL,NULL);
00185 }
00186 return err;
00187 }
00188
00192 void Myssh::disconnect_ssh()
00193 {
00194 ssh_disconnect(session);
00195 connected = false;
00196 }
00197
00205 int Myssh::connect_ssh(char * login,char * passwd,char * host)
00206 {
00207
00208 int auth=0;
00209 char *banner;
00210 connected=false;
00211
00212 _lock();
00213
00214 options=ssh_options_new();
00215
00216 ssh_options_set_username(options,login);
00217 ssh_options_set_host(options,host);
00218
00219 session=ssh_new();
00220 ssh_set_options(session,options);
00221 if(ssh_connect(session)){
00222 _errmsg = QString("Connection failed: ")+ ssh_get_error(session);
00223 ssh_disconnect(session);
00224 ssh_finalize();
00225 _unlock();
00226 return 1;
00227 }
00228
00229
00230 auth=ssh_userauth_autopubkey(session);
00231 qDebug() << "auth = " << auth;
00232 if(auth==SSH_AUTH_ERROR){
00233 _errmsg = QString("Authenticating with pubkey: ")+ssh_get_error(session);
00234 ssh_finalize();
00235 _unlock();
00236 return -1;
00237 }
00238
00239 banner=ssh_get_issue_banner(session);
00240 if(banner){
00241 printf("%s\n",banner);
00242 free(banner);
00243 }
00244
00245 if(auth!=SSH_AUTH_SUCCESS){
00246 auth=auth_kbdint();
00247 if(auth==SSH_AUTH_ERROR){
00248 _errmsg = QString("authenticating with keyb-interactive: ")+ssh_get_error(session);
00249 ssh_finalize();
00250 _unlock();
00251 return -1;
00252 }
00253 }
00254
00255 if(auth!=SSH_AUTH_SUCCESS){
00256 if(ssh_userauth_password(session,NULL,passwd) != SSH_AUTH_SUCCESS){
00257 _errmsg = QString("Authentication failed: ")+ssh_get_error(session);
00258 ssh_disconnect(session);
00259 ssh_finalize();
00260 _unlock();
00261 return -1;
00262 } else {
00263 connected = true;
00264 }
00265 }
00266
00267 shell();
00268
00269 _unlock();
00270
00271 return 0;
00272 }