[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [help] how to develop multithread sshd


Hi Feng,

Your program seems fine, but I've never used servers in a thread so I'm
not sure where's the problem.
Could you tell us which version of libssh you're using, and also what's
the output when sessions are in debug mode as described
here:http://api.libssh.org/master/guided_tour.html

Thanks,

Aris

Le 15/09/10 10:53, Feng Yi a écrit :
> Dear Developers,
> 
> Our company is currently using libssh for developing server side
> softwares. Thanks for your wonderful work.
> 
> Here 's problem we met. When we are trying to develop multithread ssh
> server to serve clients (each client has its serving thread), the server
> only responses to the newly added client ! ie. the old connection is not
> responsing anymore after new client joins. And after the newly added
> client quits, the old connection recover again !!!
> 
> We search through the internet but find little help. Could you please
> give me a hint?.
> 
> Here's the sshd like code we use:
> 
> 
> #include <libssh/libssh.h>                                        
> #include <libssh/server.h>                                        
> #include <argp.h>                                                 
> #include <stdlib.h>                                               
> #include <string.h>                                               
> #include <stdio.h>                                                
> #include <unistd.h>                                               
> #include <string>                                                 
> #include <iostream>                                               
> #include <boost/thread.hpp>                                       
> 
> static int auth_password(char *user, char *password){
>     if(strcmp(user,"aris"))                         
>         return 0;                                   
>     if(strcmp(password,"lala"))                     
>         return 0;                                   
>     return 1; // authenticated                      
> }                                                   
> 
> class Console
> {           
> public:     
>     explicit Console(const std::string addr,
>                      const std::string port)
>        
> :addr_(addr),port_(port),SSH_HOST_DSA_KEY_PATH_("./ssh_host_dsa_key"),SSH_HOST_RSA_KEY_PATH_("./ssh_host_rsa_key"){}                                                                                                                     
> 
>    
> ~Console(){};                                                                                                       
> 
> 
> private:
>     Console(const Console&);
>     Console& operator=(const Console&);
> 
> private:
>     std::string addr_;
>     std::string port_;
>     std::string SSH_HOST_DSA_KEY_PATH_;
>     std::string SSH_HOST_RSA_KEY_PATH_;
>     //ssh_session session;            
>     ssh_bind sshbind;                 
>     //ssh_message message;            
>     //ssh_channel chan;               
>     //int i;                          
> 
> public:
>     int32_t Start() {
>         sshbind=ssh_bind_new();
> 
>         ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY,
> SSH_HOST_DSA_KEY_PATH_.c_str());
>         ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY,
> SSH_HOST_RSA_KEY_PATH_.c_str());
>         ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR,
> port_.c_str());          
>         //ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY,
> arg);                       
>         //ssh_bind_options_set(sshbind,
> SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3");             
>         ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR,
> addr_.c_str());              
> 
>         if (ssh_bind_listen(sshbind) < 0) {
>             std::cout << "ERROR: listening to socket: " <<
> ssh_get_error(sshbind) << std::endl;
>            
> ssh_bind_free(sshbind);                                                           
> 
>             return
> -1;                                                                        
>        
> }                                                                                     
> 
>         for(;;)
> {                                                                             
> 
>             ssh_session
> session=ssh_new();                                                    
>             if (ssh_bind_accept(sshbind,session) != SSH_ERROR) {
>                 // every client will use a thread running Session(...)
>                             
>                 boost::thread *t = new
> boost::thread(boost::bind(&Console::Session, this, session));
>                
> sleep(10);                                                                         
> 
>             }else
> {                                                                                
> 
>                 std::cout << "ERROR: accepting a connection: " <<
> ssh_get_error(sshbind) << std::endl;
>                
> ssh_bind_free(sshbind);                                                              
> 
>                
> ssh_free(session);                                                                   
> 
>                 return
> -1;                                                                           
> 
>            
> }                                                                                        
> 
>        
> }                                                                                            
> 
>    
> }                                                                                                
> 
> 
>     int32_t Session(ssh_session newSession) {
>         ssh_session session = newSession;   
>         ssh_channel chan = 0;               
>         ssh_message message;                
>         int auth = 0;                       
>         int sftp = 0;                       
>         if (ssh_handle_key_exchange(session)) {
>             std::cout << "ERROR: ssh_handle_key_exchange: " <<
> ssh_get_error(session) << std::endl;
>             return
> -1;                                                                            
> 
>        
> }                                                                                         
> 
>         do
> {                                                                                      
> 
>            
> message=ssh_message_get(session);                                                     
> 
>            
> if(!message)                                                                          
> 
>                
> break;                                                                            
> 
>            
> switch(ssh_message_type(message)){                                                    
> 
>             case
> SSH_REQUEST_AUTH:                                                                
> 
>                
> switch(ssh_message_subtype(message)){                                             
> 
>                 case
> SSH_AUTH_METHOD_PASSWORD:                                                    
> 
>                     std::cout << "User " <<
> ssh_message_auth_user(message) << " wants to auth with pass " <<
>                         ssh_message_auth_password(message) <<
> std::endl;                                   
>                    
> if(auth_password(ssh_message_auth_user(message),                                       
> 
>                                     
> ssh_message_auth_password(message))){                                 
>                        
> auth=1;                                                                            
> 
>                        
> ssh_message_auth_reply_success(message,0);                                         
> 
>                        
> break;                                                                             
> 
>                    
> }                                                                                      
> 
>                     // not authenticated, send default
> message                                             
>                 case
> SSH_AUTH_METHOD_NONE:                                                                 
> 
>                
> default:                                                                                   
> 
>                    
> ssh_message_auth_set_methods(message,SSH_AUTH_METHOD_PASSWORD);                        
> 
>                    
> ssh_message_reply_default(message);                                                    
> 
>                    
> break;                                                                                 
> 
>                
> }                                                                                          
> 
>                
> break;                                                                                     
> 
>            
> default:                                                                                       
> 
>                
> ssh_message_reply_default(message);                                                        
> 
>            
> }                                                                                              
> 
>            
> ssh_message_free(message);                                                                     
> 
>         } while
> (!auth);                                                                                   
> 
>        
> if(!auth){                                                                                         
> 
>             std::cout << "ERROR: auth error: " << ssh_get_error(session)
> << std::endl;                     
>            
> ssh_disconnect(session);                                                                       
> 
>             return
> -1;                                                                                     
> 
>        
> }                                                                                                  
> 
>         do
> {                                                                                               
> 
>            
> message=ssh_message_get(session);                                                              
> 
>            
> if(message){                                                                                   
> 
>                
> switch(ssh_message_type(message)){                                                         
> 
>                 case
> SSH_REQUEST_CHANNEL_OPEN:                                                             
> 
>                    
> if(ssh_message_subtype(message)==SSH_CHANNEL_SESSION){                                 
> 
>                        
> chan=ssh_message_channel_request_open_reply_accept(message);                       
> 
>                        
> break;                                                                             
> 
>                    
> }                                                                                      
> 
>                
> default:                                                                                   
> 
>                    
> ssh_message_reply_default(message);                                                    
> 
>                
> }                                                                                          
> 
>                
> ssh_message_free(message);                                                                 
> 
>            
> }                                                                                              
> 
>         } while(message &&
> !chan);                                                                         
> 
>        
> if(!chan){                                                                                         
> 
>             std::cout << "ERROR: " << ssh_get_error(session) <<
> std::endl;                                 
>             return
> -1;                                                                                     
> 
>        
> }                                                                                                  
> 
>         do
> {                                                                                               
> 
>            
> message=ssh_message_get(session);                                                              
> 
>             if(message && ssh_message_type(message)==SSH_REQUEST_CHANNEL
> &&                                
>               
> ssh_message_subtype(message)==SSH_CHANNEL_REQUEST_SHELL){                                   
> 
>                 //           
> if(!strcmp(ssh_message_channel_request_subsystem(message),"sftp")){          
> 
>                
> sftp=1;                                                                                    
> 
>                
> ssh_message_channel_request_reply_success(message);                                        
> 
>                
> break;                                                                                     
> 
>                 //          
> }                                                                             
> 
>            
> }                                                                                              
> 
>            
> if(!sftp){                                                                                     
> 
>                
> ssh_message_reply_default(message);                                                        
> 
>            
> }                                                                                              
> 
>             ssh_message_free(message);
>         } while (message && !sftp);
>         if(!sftp){
>             std::cout << "ERROR: " << ssh_get_error(session) << std::endl;
>             return -1;
>         }
>         printf("it works !\n");
>         char buf[2048];
>         int i = 0;
>         ssh_channel_write(chan, "#:", 2);
>         do{
>             i = ssh_channel_read(chan, buf, 2048, 0);
>             if (i > 0) {
>                 ssh_channel_write(chan, buf, i);
>                 if (buf[0] == 'q') {
>                     break;
>                 }
>                 if (buf[0] == '\r'|| buf[i] == '\r')
>                     ssh_channel_write(chan, "\r\nabcd\r\n#:", 10);
>                 if (write(1,buf,i) < 0) {
>                     printf("error writing to buffer\n");
>                     return 1;
>                 }
>             }
>         } while (i > 0);
>         ssh_disconnect(session);
>         ssh_channel_close(chan); //?
>         ssh_channel_free(chan); //?
>         ssh_free(session);
>         return 0;
>     }
>     int32_t Stop()
>     {
>         ssh_finalize();
>     }
> };
> 
> int main()
> {
>     Console c("127.0.0.1", "1200");
>     c.Start();
> 
>     return 0;
> }
> 
> 
> Thanks & Best Regards,
> FY
> 
> 


References:
[help] how to develop multithread sshdFeng Yi <yifengcn@xxxxxxxxx>
Archive administrator: postmaster@lists.cynapses.org