src/ssh/myssh.cpp

Go to the documentation of this file.
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     //FIXME: should be: return (res == SSH_SUCCESS);
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     //FIXME: why do we have to do that???
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     //FIXME: why do we have to do that???
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     /* no ? you should :) */
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 }

Generated on Mon Mar 16 18:46:05 2009 for QCJM by  doxygen 1.5.4