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

Re: Server woes - Bad packet length, corrupted MAC on input


Hi Jeetu,

took me a lot of time and head scratching, but I narrowed it down to a threading problem. Two of your threads are running ssh loops at the same time, and this cause races. The probability that the race causes problem can be high, because there's a trigger (data on socket) and both threads run almost the same code at the same time.

Thread 1:      message = ssh_message_get(session);
in server_thread()
Thread 2:                 ssh_event_dopoll(event, 1000);
in wait_for_something()

I hacked your example so the server_thread() functions leaves early. It doesn't remove the race but reduces its window. now it works for me, and I'm able to run an xterm with it. I strongly recommend that you refactor your code in a singlethread design, and that you move the x11 callbacks back in the server loop.

Let's discuss what libssh can do better to help you write better code.

Kr,

Aris
Le 09/11/11 12:38, jeetu.golani@xxxxxxxxx a écrit :
Hi Aris,

No probs and I completely understand and appreciate your interest in
looking into this....please let me know how I can help further :)

Bye for now

On Wed, Nov 9, 2011 at 3:32 PM, Aris Adamantiadis<aris@xxxxxxxxxxxx>  wrote:
Hi Jeetu,

I apologize, still had no time to check it. I'm pretty busy and all my
free time is swallowed by another project. I hope I can free myself an
hour or two next week to debug this.

kr,

Aris

Le 3/11/11 19:13, jeetu.golani@xxxxxxxxx a écrit :
Hi Aris,

Just wanted to check in if you've had a chance to try out the libssh
server code I've sent and reproduce the errors I've been seeing?

Thanks so much again for looking into this.

Bye for now

On Sat, Oct 22, 2011 at 2:20 PM, jeetu.golani@xxxxxxxxx
<jeetu.golani@xxxxxxxxx>  wrote:
Hi Aris,

I'm attaching my proof of concept server code
as.....ebpsshd-singlesession.c has compile instructions at the
beginning of the code. You will also need to generate a key.h file
that holds the public key of the user who will be connecting to this
server - this is tempoarary since as of now I'm not reading this info
from an authorized_keys or something similar.

Just create a key.h file in the same directory and put something like :

#define MY_PUB_KEY "[YOUR PUBLIC KEY WITHIN THESE QUOTES]"

Also as of now ebpsshd-singlesession listens in on port 2000. So ssh
should connect to that port.

I also have a libssh-project-wrapper script that allows me to try this
out without needing to install the libssh i've built. It basically has
the content:

#!/bin/sh

export LD_LIBRARY_PATH=/home/jeetu/utils/libssh/libssh-project/build/src:/home/jeetu/utils/libssh/libssh-project/build/src/threads
./$1

I have been testing this code with simple examples like xeyes and
xcalc. For some reason xcalc shows the problem much sooner than with
xeyes, maybe because of the volume of data being transmitted to and
fro?

This is proof of concept code with a lot of fiddling with buffer sizes
as I have been trying to study if any of that makes an impact however
please point out any way you think this can be improved on :)

I'm sorry to drop this in your lap especially if it turns out it was
some server side code issue, however I completely appreciate your help
on this. I would like to squash this bug regardless of where it lies
i.e. in my code or libssh, unfortunately my understanding of libssh
and the ssh protocol is a little limited. However I do not want to put
all of this load completely in your lap and if you share your thoughts
and there's something you would like me to look into then please let
me know.

Thanks,
Jeetu
ebrain.in | Beehive Computing
Discover and run software from any device around you - an open source
(GPL) project.


On Fri, Oct 21, 2011 at 11:22 PM, jeetu.golani@xxxxxxxxx
<jeetu.golani@xxxxxxxxx>  wrote:
Hi Aris,

I think I'll need a proof-of-concept code to debug this. Would you mind
sharing your code, or it's not possible (too much integration with
existing code).

No problem at all :) The code is an independent unit as of now since I
wanted to make it work before I integrate it within my open source
project (eBrainPool)

I'll mail this out to you tomm (not on the machine with the code right now :) )

Thanks so much for looking into this.....truly appreciate it :)

Bye for now


On Fri, Oct 21, 2011 at 7:26 PM, Aris Adamantiadis<aris@xxxxxxxxxxxx>  wrote:
Hi Jeetu,

By seeing your logs, I understand this:
Both side have a hmac error. The openssh client sees it first, sends a
disconnect (that works), then there's the error in the libssh log.

I think I'll need a proof-of-concept code to debug this. Would you mind
sharing your code, or it's not possible (too much integration with
existing code).

If so, do you think I can reproduce the problem by "fixing" samplesshd
to make new X11 channels connection connect to the local X11 unix socket ?

Thanks.

Aris


Le 18/10/11 20:34, jeetu.golani@xxxxxxxxx a écrit :
This is not a problem and shouldn't cause invalid MAC errors. I'm on
travel so I'll look at the log when i'm back.

Thanks so much Aris :)

On Tue, Oct 18, 2011 at 5:52 PM, Aris Adamantiadis<aris@xxxxxxxxxxxx>  wrote:
Hi,

This is not a problem and shouldn't cause invalid MAC errors. I'm on
travel so I'll look at the log when i'm back.

Aris

Le 18/10/11 12:30, u@xxxxxxxxxxxxx a écrit :
Hi all,

debug3: Incorrect RSA1 identifier
debug3: Could not load "/home/jeetu/.ssh/id_rsa" as a RSA1 public key
debug2: key_type_from_name: unknown key type '-----BEGIN'


On Tue, Oct 18, 2011 at 03:22:08PM +0500, jeetu.golani@xxxxxxxxx wrote:
Hi Aris,

I've attached a log of the libssh server
(log-1-ebpsshd-singlesession-18102011.txt) and the OpenSSH client
(log-ssh-1-18102011.txt).

Greetings
--
Stefan Kuttler ==*== nc.netbeisser.de












/* 

ebpsshd-singlesession.c compile:

gcc -g -Wall -Wstrict-prototypes -O0 -o ebpsshd-singlesession -I/home/jeetu/utils/libssh/libssh-project/include -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include/ ebpsshd-singlesession.c -L/home/jeetu/utils/libssh/libssh-project/build/src -lssh -L/home/jeetu/utils/libssh/libssh-project/build/src/threads -lssh_threads -lglib-2.0 -lgthread-2.0

*/


#include <libssh/libssh.h>
#include <libssh/server.h>
#include <libssh/callbacks.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <glib.h>
#include <stdlib.h>
#include <errno.h>
#include <poll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
//#include "key.h" //jeetu - temporary hardcoded key

#ifndef KEYS_FOLDER
#ifdef _WIN32
#define KEYS_FOLDER
#else
#define KEYS_FOLDER "./" //jeetu - temporary
#endif
#endif

#define MAX_X11_AUTH_PROTO_STR_SZ 18
#define MAX_X11_AUTH_COOKIE_STR_SZ 50

//jeetu - all hardcoded defines; should probably figure out how these values came to be in the orig openssh code
#define MAX_DISPLAYS 1000
#define NI_MAXSERV 32
#define NUM_SOCKS 10
#define SSH_LISTEN_BACKLOG 128


static int copy_chan_to_fd(ssh_session session,
                                           ssh_channel channel,
                                           void *data,
                                           uint32_t len,
                                           int is_stderr,
                                           void *userdata);

static void chan_close(ssh_session session, ssh_channel channel, void *userdata);
static int copy_fd_to_chan(socket_t fd, int revents, void *userdata);

/*
struct ssh_channel_callbacks_struct cb = {
	.channel_data_function = copy_chan_to_fd,
    .channel_eof_function = chan_close,
    .channel_close_function = chan_close,
	.userdata = NULL 
};
*/


typedef struct x11_session_struct
       {
       char *x11_auth_cookie;
       char *x11_auth_protocol;
       int screen_number;
       int single_connection;
       unsigned int display_number;
       } x11_session;

typedef struct {
               ssh_session session;
               int *sockets;
               } WaitThreadData;
               
static WaitThreadData * thread_data_new (void);
int authenticate_user(ssh_session session);
int pubkey_auth(char *pk64);
int server_loop(ssh_session session);
int session_x11_req(ssh_session session,ssh_message message,x11_session* x11session);
int session_setup_x11fwd(ssh_session session,x11_session* x11session);
int x11_create_display_inet(ssh_session session,unsigned int *display_numberp, int *sockets);
static gpointer wait_for_something(gpointer user_data);
static gpointer server_thread(gpointer session_data);
int exec_command(const char *command,x11_session* x11session);

//struct x11_session_struct x11session; //jeetu - may not need to be global
ssh_channel chan=0;
ssh_session session;
int finished=0;
/*static GMutex *mutex_for_copy_fd_to_chan = NULL;
static GMutex *mutex_for_copy_chan_to_fd = NULL;
*/

/* Return Values:
 * 0 - Success
 * 1 - ssh_bind_listen failed - error listening to socket
 * 2 - ssh_bind_accept failed - error accepting a connection
 * 3 - ssh_handle_key_change failed 
 * 4 - authenticate_user failed
 */
int main(int argc, char **argv)
{    
    ssh_bind sshbind;
    int auth=0;
    int r;
    int port = 2000;
    int verbosity = SSH_LOG_PACKET;
    int session_count = 0;

    g_thread_init(NULL);

    ssh_threads_set_callbacks(ssh_threads_get_pthread());
    if(ssh_init() == -1)
      {
      printf("\nError initializing ssh: ssh_init() failed");
      exit(1);
      }

    sshbind=ssh_bind_new();
    session = ssh_new();

    ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT,&port);
    ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, KEYS_FOLDER "ssh_host_dsa_key");
    ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, KEYS_FOLDER "ssh_host_rsa_key");

    if(ssh_bind_listen(sshbind)<0)
      {
      printf("Error listening to socket: %s\n",ssh_get_error(sshbind));
      return 1;
      }   
 
    ssh_options_getopt(session,&argc,argv);
    r=ssh_bind_accept(sshbind,session);
    if(r==SSH_ERROR)
      {
      printf("error accepting a connection : %s\n",ssh_get_error(sshbind));
      return 2;
      }
    ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity );
    if(ssh_handle_key_exchange(session))
      {
      printf("ssh_handle_key_exchange: %s\n",ssh_get_error(session));
      return 3;
      }
     
    /* public key authentication */
    auth = authenticate_user(session);
    if(!auth)
      {
      printf("auth error: %s\n",ssh_get_error(session));
      ssh_disconnect(session);
      return 4;
      }
    server_thread(session);

/*    if(x11session.x11_auth_protocol != NULL)
      free(x11session.x11_auth_protocol);
    if(x11session.x11_auth_cookie != NULL)
      free(x11session.x11_auth_cookie);
*/
  
//    ssh_disconnect(session[session_count]);    
    while(!finished){
        sleep(1);
    }
    ssh_bind_free(sshbind);
    ssh_finalize();
  
    return 0;
}

/* returns 1 for OK, 0 for KO */
int authenticate_user(ssh_session session) 
{
    ssh_message message;
    ssh_string pubkey = NULL;
    char *pk64 = NULL;
    int signature_state = SSH_PUBLICKEY_STATE_NONE;

    do 
     {
     message = ssh_message_get(session);
     if(!message) 
       return 0;

     switch(ssh_message_type(message)) 
           {
           case SSH_REQUEST_AUTH:
                switch(ssh_message_subtype(message)) 
                      {
                      case SSH_AUTH_METHOD_PUBLICKEY:
                           pubkey = publickey_to_string(ssh_message_auth_publickey(message));
			   pk64 = g_base64_encode((const guchar *)ssh_string_to_char(pubkey), ssh_string_len(pubkey));
			   signature_state = ssh_message_auth_publickey_state(message);
                           if(signature_state == SSH_PUBLICKEY_STATE_NONE) 
			     {
                             /* no signature */
                             ssh_message_auth_reply_pk_ok_simple(message);
                             break;
                             } 
                           else if(signature_state != SSH_PUBLICKEY_STATE_VALID) 
                             {
                             /* will be rejected later */
                             } 
                           else 
                             {
                             /* signature is good at that point */
                             if(pubkey_auth(pk64)) 
                               {
                               /* user is allowed */
                               ssh_message_auth_reply_success(message, 0);
                               ssh_message_free(message);
                               return 1;
                               }
                             }
                           /* the following is not necessary if we want only pubkey auth */
                           ssh_message_auth_set_methods(message,SSH_AUTH_METHOD_PUBLICKEY);
                           /* reject authentication */
                           ssh_message_reply_default(message);
                           break;
                      case SSH_AUTH_METHOD_PASSWORD:
                        /* handle password auth if needed */
                      default:
                           ssh_message_auth_set_methods(message,SSH_AUTH_METHOD_PUBLICKEY);
                           ssh_message_reply_default(message);
                      }
                break;
           default:
                ssh_message_reply_default(message);
           }
     ssh_message_free(message);
     }while(1);
    
     return 0;
}

int pubkey_auth(char* pk64)
{
     //if(strcmp(pk64,MY_PUB_KEY) == 0)
     //  return 1;
    return 1;
     //return 0;
}


static gpointer server_thread(gpointer session_data)
{
    ssh_message message;
    int message_subtype = 0;
    int message_type = 0;
    int ret = 0;
    ssh_session session = (ssh_session) session_data;
    struct ssh_message_struct *msg;
    x11_session x11session;

    do 
     {
     message=ssh_message_get(session);
     msg = message;
     if(message)
       {
       message_type = ssh_message_type(message);
       message_subtype = ssh_message_subtype(message);
//       printf("\nmessage_type = %d subtype = %d",message_type,message_subtype);
       switch(message_type)
             {		
	     case SSH_REQUEST_CHANNEL_OPEN:
                  if(message_subtype == SSH_CHANNEL_SESSION)
                    {
		    printf("\nSSH_CHANNEL_SESSION");
                    chan=ssh_message_channel_request_open_reply_accept(message);
                    }
		  break;
	     case SSH_REQUEST_CHANNEL:
		  printf("\nSSH_REQUEST_CHANNEL subtype = %d SSH_CHANNEL_REQUEST_X11 = %d",message_subtype,SSH_CHANNEL_REQUEST_X11);
		  if(message_subtype == SSH_CHANNEL_REQUEST_X11)
		    {
		    printf("\nSSH_CHANNEL_REQUEST_X11");
		    if(session_x11_req(session,message,&x11session) != 1)
                      {
                      printf("\nsession_x11_req error");
                      ssh_message_reply_default(message);
                      ssh_disconnect(session);
                      return NULL;
                      }
                    else {
		      ssh_message_channel_request_reply_success(message);
                    }
		    }
		  if(message_subtype == SSH_CHANNEL_REQUEST_ENV)
		    {		   
		    printf("\nSSH_CHANNEL_REQUEST_ENV");
		    ssh_message_channel_request_reply_success(message);
		    }
		  if(message_subtype == SSH_CHANNEL_REQUEST_EXEC)
		    {
		    printf("\nSSH_CHANNEL_REQUEST_EXEC command = %s\n",ssh_message_channel_request_command(message));
                    ret = exec_command(ssh_message_channel_request_command(message),&x11session);
                    if(ret == 0)
                      {
                      printf("\nserver_loop: unable to exec command\n");
                      }
                    ssh_message_channel_request_reply_success(message);
                    return NULL;

		    }
		  break;		    
	     default:
                  ssh_message_reply_default(message);
	     }
       ssh_message_free(message);
       }
     } while(1);

//    return 1;
     return NULL;
}


int session_x11_req(ssh_session session,ssh_message message,x11_session* x11session)
{
    int ret = 1;
    FILE* fpxauth;
    char xauth_path[] = "/usr/bin/xauth";
    char strxauth_exec[200]; //jeetu - buffer size sufficient?; xauth path name may be larger; ideally not fixed

    x11session->x11_auth_protocol = NULL;
    x11session->x11_auth_cookie = NULL;

    x11session->x11_auth_protocol = malloc(MAX_X11_AUTH_PROTO_STR_SZ+2);
    strncpy(x11session->x11_auth_protocol,ssh_message_channel_request_x11_auth_protocol(message),MAX_X11_AUTH_PROTO_STR_SZ+1);
    x11session->x11_auth_protocol[MAX_X11_AUTH_PROTO_STR_SZ] = '\0';
    if(strncmp(x11session->x11_auth_protocol,"MIT-MAGIC-COOKIE-1",MAX_X11_AUTH_PROTO_STR_SZ+1) == 0)
      { 
      x11session->x11_auth_cookie = malloc(MAX_X11_AUTH_COOKIE_STR_SZ+2);
      strncpy(x11session->x11_auth_cookie,ssh_message_channel_request_x11_auth_cookie(message),MAX_X11_AUTH_COOKIE_STR_SZ+1);
      x11session->x11_auth_cookie[MAX_X11_AUTH_COOKIE_STR_SZ] = '\0';
      x11session->screen_number = ssh_message_channel_request_x11_screen_number(message);
      x11session->single_connection = ssh_message_channel_request_x11_single_connection(message);
      }
    else
      return 0;
//    ret = execl("/usr/bin/xauth","/usr/bin/xauth","add","unix:10.0",x11session.x11_auth_protocol,x11session.x11_auth_cookie,(char *) NULL);

    ret = session_setup_x11fwd(session,x11session);
    if(ret == 0)
      {
      printf("\nsession_setup_x11fwd failed");
      return 0;
      }

    printf("\nx11_auth_protocol=%s\nx11_auth_cookie=%s\nscreen_number = %d\nsingle_connection =  %d\ndisplay_number = %d\n",x11session->x11_auth_protocol,x11session->x11_auth_cookie,x11session->screen_number,x11session->single_connection,x11session->display_number);

    snprintf(strxauth_exec,199,"%s remove :%d",xauth_path,x11session->display_number);
    printf("\nstrxauth_exec = %s",strxauth_exec);

    fpxauth = popen(strxauth_exec,"r");
    if(fpxauth == NULL)
      return 0;
    pclose(fpxauth);

    strxauth_exec[0] = '\0';
    snprintf(strxauth_exec,199,"%s add unix:%d %s %s",xauth_path,x11session->display_number,x11session->x11_auth_protocol,x11session->x11_auth_cookie);
//    snprintf(strxauth_exec,199,"%s add unix:10 %s %s",xauth_path,x11session.x11_auth_protocol,x11session.x11_auth_cookie);
    printf("\nstrxauth_exec = %s",strxauth_exec);

    fpxauth = popen(strxauth_exec,"r");
    if(fpxauth == NULL)
      return 0;
    pclose(fpxauth);

    return ret;
}



int session_setup_x11fwd(ssh_session session,x11_session* x11session)
{
    int ret = 1;
    WaitThreadData *waitdata;
    int *sockets; //jeetu - sufficient array size?

    sockets = malloc( (sizeof(int) * 10) );

    ret = x11_create_display_inet(session,&x11session->display_number,sockets);
    if(ret == 0)
      {
      printf("\nx11_create_display_inet failed");
      return 0;
      }

    printf("\nsockets[0] = %d",sockets[0]);
    waitdata = thread_data_new(); //jeetu - memory needs to be freed
    waitdata->session = session;
    waitdata->sockets = sockets;
    g_thread_create(wait_for_something,waitdata,FALSE,NULL);
//    wait_for_something(waitdata);

    //free(sockets);
    return ret;
}

int x11_create_display_inet(ssh_session session,unsigned int *display_numberp, int *sockets)
{
    int ret = 1;
    int display_num = 0,sock = 0,num_socks = 0;
    unsigned int port = 0;
    struct addrinfo hints, *ai, *aitop;
    char strport[NI_MAXSERV];
    int gaierr,n,socks[NUM_SOCKS];
    static int x11_display_offset = 10; //jeetu - temporarily hardcoded here

    printf("\nx11_create_display_inet: x11_display_offset = %d\n",x11_display_offset);    
    for(display_num = x11_display_offset; display_num < MAX_DISPLAYS; display_num++)
       {
       port = 6000 + display_num;
       hints.ai_family = AF_INET;
       hints.ai_flags = AI_NUMERICSERV | AI_PASSIVE;
       hints.ai_socktype = SOCK_STREAM;
       hints.ai_protocol = 0;
       snprintf(strport, sizeof strport, "%d", port);
       if((gaierr = getaddrinfo(NULL, strport, &hints, &aitop)) != 0)
	 {
         printf("\ngetaddrinfo: %s",gai_strerror(gaierr));
         return 0;
         }

       for(ai = aitop; ai; ai = ai->ai_next)
          {
	  if(ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
	    continue;
          sock = socket(ai->ai_family, ai->ai_socktype,ai->ai_protocol);
	  if(sock < 0)
            {
	    if((errno != EINVAL) && (errno != EAFNOSUPPORT))
              {
	      printf("\nsocket error: %s", strerror(errno));
	      freeaddrinfo(aitop);
	      return 0;
	      }
            else
              {
	      printf("\nx11_create_display_inet: Socket family %d not supported",ai->ai_family);
	      continue;
              }
            }
	  if(bind(sock, ai->ai_addr, ai->ai_addrlen) < 0)
            {
	    printf("bind port %d: %s", port, strerror(errno));
            close(sock);
            for(n = 0; n < num_socks; n++) 
               {
	       close(socks[n]);
	       }
            num_socks = 0;
            break;
            }
          socks[num_socks++] = sock;
	  if(num_socks == NUM_SOCKS)
	    break;
          }
       freeaddrinfo(aitop);
       if(num_socks > 0)
	 break;
       }    

    if(display_num >= MAX_DISPLAYS) 
      {
      printf("\nFailed to allocate internet-domain X11 display socket.");
      return 0;
      }
 
    /* Start listening for connections on the socket. */
    for(n = 0; n < num_socks; n++) 
       {
       sock = socks[n];
       *(sockets+n) = sock;
       if(listen(sock, SSH_LISTEN_BACKLOG) < 0) 
         {
	 printf("\nlisten: %s", strerror(errno));
	 close(sock);
	 return 0;
	 }
       }

    *display_numberp = display_num;
    x11_display_offset++;
    return ret;
}

static gpointer wait_for_something(gpointer user_data)
{
    fd_set infds, testfds;
    struct timeval tv = { 30, 0 };
    int maxfds = 0;
    int nready;
    int client_sock, cli_len;
    struct sockaddr_in cli_addr;
    ssh_event event;
    short events;
    ssh_channel chan_x11=0;
    WaitThreadData *data;
    struct ssh_channel_callbacks_struct cb = 
	{
    	.channel_data_function = copy_chan_to_fd,
    	.channel_eof_function = chan_close,
    	.channel_close_function = chan_close,
	.userdata = NULL 
	};
    
    data = user_data;

    FD_ZERO(&infds);
    FD_SET(data->sockets[0], &infds);
    printf("\ndata->sockets[0] = %d",data->sockets[0]);
    maxfds = data->sockets[0];
    while(1)
         {
	 testfds = infds;
         printf("\nwait_for_something: before select");
         tv.tv_sec = 15;
         nready = select(maxfds + 1, &testfds, NULL, NULL, &tv);
         if(nready == -1)
           {
           printf("\nselect error: %s\n",strerror(errno));
           }
         if(nready > 0)
           {
           printf("\nwait_for_something: nready > 0");
           if(FD_ISSET(data->sockets[0], &testfds))
             {
             printf("\nFD_ISSET\n");
             cli_len = sizeof (cli_addr);
	     bzero((char *) &cli_addr, sizeof (cli_addr));	
	     client_sock = accept(data->sockets[0], (struct sockaddr *) &cli_addr, (socklen_t *) &cli_len);
             printf("\nclient_sock = %d",client_sock);
             chan_x11 = ssh_channel_new(data->session);
//             printf("\nchan_x11 session = %x\n",data->session);         
             if(ssh_channel_open_x11(chan_x11,"127.0.0.1",client_sock) == SSH_ERROR)
               {
               printf("ssh_channel_open_x11 error : %s\n",ssh_get_error(chan_x11));
               return NULL;
               }
             else
               printf("\nssh_channel_open_x11\n");

             cb.userdata = &client_sock;
             ssh_callbacks_init(&cb);
             ssh_set_channel_callbacks(chan_x11, &cb);
	     events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
             event = ssh_event_new();
             if(event == NULL) 
               {
               printf("Couldn't get a event\n");
               return NULL;
               }
             else
               printf("\nevent != NULL");

             if(ssh_event_add_fd(event, client_sock, events, copy_fd_to_chan, chan_x11) != SSH_OK) 
               {
               printf("Couldn't add an fd to the event\n");
	       return NULL;
               }
             else
               printf("\nAdded fd to event");

             if(ssh_event_add_session(event, data->session) != SSH_OK) 
               {
               printf("Couldn't add the session to the event\n");
               return NULL;
               }
             else
               printf("\nadded the session to the event\n");
  
             do {
                ssh_event_dopoll(event, 1000);
                } while(!ssh_channel_is_closed(chan_x11));
             printf("\nssh_channel_open_x11: channel closed\n");
/*             ssh_event_remove_fd(event, client_sock);
             ssh_event_remove_session(event, data->session);
             ssh_event_free(event);*/
             break;
             }
           }
         }
    printf("\nexiting wait_for_something");
    finished = 1;
    return NULL;
}

static int copy_fd_to_chan(socket_t fd, int revents, void *userdata) 
{
    ssh_channel chan = (ssh_channel)userdata;
    char buf[40000];
    int sz = 0;
    buf[0] = '\0';    

    if(!chan) 
      {
      close(fd);
      return -1;
      }
    if(revents & POLLIN) 
      {
      sz = read(fd, buf, 39999);        
      if(sz == 0)
        {
        printf("\ncopy_fd_to_chan: sz == 0\n");
        ssh_channel_close(chan);
        close(fd);
        sz = -1;
        }
      if(sz > 0) 
        {
          printf("BEGIN ssh_channel_write\n");
        ssh_channel_write(chan, buf, sz);
          printf("END ssh_channel_write\n");
        }
      }
    if(revents & POLLHUP) 
      {
      ssh_channel_close(chan);
      sz = -1;
      }
    return sz;
}


static int copy_chan_to_fd(ssh_session session,
                                           ssh_channel channel,
                                           void *data,
                                           uint32_t len,
                                           int is_stderr,
                                           void *userdata) 
{
    int fd = *(int*)userdata;
    int sz;
    (void)session;
    (void)channel;
    (void)is_stderr;

    sz = write(fd, data, len);

    return sz;
}

static void chan_close(ssh_session session, ssh_channel channel, void *userdata) 
{
    int fd = *(int*)userdata;
    (void)session;
    (void)channel;

    close(fd);
}


static WaitThreadData * thread_data_new (void)
{
    WaitThreadData *data;

    data = g_new0 (WaitThreadData, 1);

    return data;
}


int exec_command(const char *command,x11_session* x11session)
{
    FILE *fpcmd;
    char str_exec[200]; //jeetu - buffer size sufficient?; command name may be larger; ideally not fixed

    printf("\nexec_command: x11session->display_number = %d\n",x11session->display_number);
    str_exec[0] = '\0';
    snprintf(str_exec,199,"%s -display :%d",command,x11session->display_number);
    fpcmd = popen(str_exec,"r");
    if(fpcmd == NULL)
      return 0;
    
    return 1;
}


Follow-Ups:
Re: Server woes - Bad packet length, corrupted MAC on input"jeetu.golani@xxxxxxxxx" <jeetu.golani@xxxxxxxxx>
References:
Re: Server woes - Bad packet length, corrupted MAC on input"jeetu.golani@xxxxxxxxx" <jeetu.golani@xxxxxxxxx>
Re: Server woes - Bad packet length, corrupted MAC on inputAris Adamantiadis <aris@xxxxxxxxxxxx>
Re: Server woes - Bad packet length, corrupted MAC on input"jeetu.golani@xxxxxxxxx" <jeetu.golani@xxxxxxxxx>
Archive administrator: postmaster@lists.cynapses.org