[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Regarding Putty is not connecting to lib SSH server - HMAC Error
[Thread Prev] | [Thread Next]
- Subject: Regarding Putty is not connecting to lib SSH server - HMAC Error
- From: Ashish Mangla <Ashish.Mangla@xxxxxxxxxxxxxx>
- Reply-to: libssh@xxxxxxxxxx
- Date: Wed, 19 Jun 2013 10:01:41 +0000
- To: "libssh@xxxxxxxxxx" <libssh@xxxxxxxxxx>
Hi We are using your LIBSSH server and customized it to meet our needs. Today I am trying to connect the server with putty but unfortunately I am getting the following error. To check this I have written one LIBSSH client and it seems that the LIBSSH server works fine with the custom client (which I wrote, with same kind of messages what putty is sending). Can you help us what is going wrong with putty. I am attaching both client and server code along with the keys (these keys I have collected from one my Linux server) used. Please find the error reported and corresponding putty log. [cid:image001.png@01CE6B85.DBA37C70] Server Log with custom client .., [3] Enabling POLLOUT for socket [3] ssh_handle_key_exchange: Actual state : 2 [3] Received banner: SSH-2.0-libssh-0.5.0 [1] SSH client banner: SSH-2.0-libssh-0.5.0 [1] Analyzing banner: SSH-2.0-libssh-0.5.0 [3] Writing on the wire a packet having 347 bytes before [3] 347 bytes after comp + 8 padding bytes = 356 bytes packet [3] Enabling POLLOUT for socket [3] ssh_handle_key_exchange: Actual state : 4 [3] ssh_handle_key_exchange: Actual state : 4 [3] Packet size decrypted: 148 (0x94) [3] Read a 148 bytes packet [3] 6 bytes padding, 147 bytes left in buffer [3] After padding, 141 bytes left in buffer [3] Final size 141 [3] Type 20 [3] Dispatching handler for packet type 20 [3] Set output algorithm aes256-ctr [3] Set input algorithm aes256-ctr [3] ssh_handle_key_exchange: Actual state : 6 [3] Packet size decrypted: 140 (0x8c) [3] Read a 140 bytes packet [3] 5 bytes padding, 139 bytes left in buffer [3] After padding, 134 bytes left in buffer [3] Final size 134 [3] Type 30 [3] Dispatching handler for packet type 30 [3] Received SSH_MSG_KEXDH_INIT [3] Writing on the wire a packet having 689 bytes before [3] 689 bytes after comp + 10 padding bytes = 700 bytes packet [3] Enabling POLLOUT for socket [3] Writing on the wire a packet having 1 bytes before [3] 1 bytes after comp + 10 padding bytes = 12 bytes packet [3] SSH_MSG_NEWKEYS sent [3] ssh_handle_key_exchange: Actual state : 6 [3] Packet size decrypted: 12 (0xc) [3] Read a 12 bytes packet [3] 10 bytes padding, 11 bytes left in buffer [3] After padding, 1 bytes left in buffer [3] Final size 1 [3] Type 21 [3] Dispatching handler for packet type 21 [2] Received SSH_MSG_NEWKEYS [3] Enabling POLLOUT for socket [3] ssh_handle_key_exchange: Actual state : 7 [3] Decrypting 16 bytes [3] Packet size decrypted: 28 (0x1c) [3] Read a 28 bytes packet [3] Decrypting 16 bytes [3] 10 bytes padding, 27 bytes left in buffer [3] After padding, 17 bytes left in buffer [3] Final size 17 [3] Type 5 [3] Dispatching handler for packet type 5 [3] Received a SERVICE_REQUEST for service ssh-userauth [3] Sending a SERVICE_ACCEPT for service ssh-userauth [3] Writing on the wire a packet having 17 bytes before [3] 17 bytes after comp + 10 padding bytes = 28 bytes packet [3] Encrypting packet with seq num: 3, len: 32 [3] Enabling POLLOUT for socket [3] Decrypting 16 bytes [3] Packet size decrypted: 44 (0x2c) [3] Read a 44 bytes packet [3] Decrypting 32 bytes [3] 19 bytes padding, 43 bytes left in buffer [3] After padding, 24 bytes left in buffer [3] Final size 24 [3] Type 90 [3] Dispatching handler for packet type 90 [3] Clients wants to open a session channel [3] Writing on the wire a packet having 17 bytes before [3] 17 bytes after comp + 10 padding bytes = 28 bytes packet [3] Encrypting packet with seq num: 4, len: 32 [3] Enabling POLLOUT for socket It seems it's fine with the custom client. /Ashish
Attachment:
putty.log
Description: putty.log
Attachment:
ssh_host_dsa_key
Description: ssh_host_dsa_key
Attachment:
ssh_host_dsa_key.pub
Description: ssh_host_dsa_key.pub
Attachment:
ssh_host_key.pub
Description: ssh_host_key.pub
Attachment:
ssh_host_rsa_key
Description: ssh_host_rsa_key
Attachment:
ssh_host_rsa_key.pub
Description: ssh_host_rsa_key.pub
/*
ebpsshd.c compile:
gcc -g -Wall -Wstrict-prototypes -O0 -o ebpsshd `pkg-config --cflags --libs glib-2.0` -I/home/jeetu/utils/libssh/libssh-project/include ebpsshd.c -L/home/jeetu/utils/libssh/libssh-project/build/src -lssh -L/home/jeetu/utils/libssh/libssh-project/build/src/threads -lssh_threads -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 "poll.h"
#include <sys/types.h>
//#include <sys/socket.h>
#include <WinSock2.h>
//#include <netdb.h>
#include <fcntl.h>
#pragma comment(lib, "ws2_32.lib")
//#include "key.h" //jeetu - temporary hardcoded key
#ifndef KEYS_FOLDER
#ifdef _WIN32
#define KEYS_FOLDER "C:\\Users\\inrasun3\\.ssh\\"
#define AUTHORIZED_KEYS "C:\\Users\\inrasun3\\.ssh\\ssh_host_dsa_key"
#else
#define KEYS_FOLDER "/home/jeetu/tmp/" //jeetu - temporary
#define AUTHORIZED_KEYS "/home/jeetu/tmp/authorized_keys"
#endif
#endif
typedef void* gpointer;
#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);
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 x11_conn_struct
{
ssh_session session;
int client_sock;
} x11data;
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 *socket);
int session_setup_x11fwd(ssh_session session,x11_session* x11session,int *socket);
int x11_create_display_inet(ssh_session session,unsigned int *display_numberp, int *sockets);
int wait_for_something(ssh_session session,int socket);
static gpointer server_thread(gpointer session_data);
int exec_command(const char *command,x11_session* x11session);
//static gpointer exec_command(gpointer data);
//static gpointer process_x11_channel_events_thread(gpointer x11conndata);
ssh_channel chan=0;
ssh_session *session;
x11data **x11conndata;
/* 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_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;
}
while(1)
{
session[session_count]=ssh_new();
ssh_options_getopt(session[session_count],&argc,argv);
r=ssh_bind_accept(sshbind,session[session_count]);
if(r==SSH_ERROR)
{
printf("error accepting a connection : %s\n",ssh_get_error(sshbind));
return 2;
}
ssh_options_set(session[session_count], SSH_OPTIONS_LOG_VERBOSITY, &verbosity );
if(ssh_handle_key_exchange(session[session_count]))
{
printf("ssh_handle_key_exchange: %s\n",ssh_get_error(session[session_count]));
return 3;
}
/* public key authentication */
auth = authenticate_user(session[session_count]);
if(!auth)
{
printf("auth error: %s\n",ssh_get_error(session[session_count]));
ssh_disconnect(session[session_count]);
return 4;
}
//g_thread_create(server_thread,session[session_count],FALSE,NULL);
session_count++;
}
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)
{
char header[100],key[300],footer[100];
int ret = 0;
FILE *fp;
fp = fopen(AUTHORIZED_KEYS,"r");
if(fp == NULL)
{
fprintf(stderr,"\nCould not open authorized_keys file %s\n",AUTHORIZED_KEYS);
return 0;
}
while(fgetc(fp) != EOF)
{
header[0] = '\0';
key[0] = '\0';
footer[0] = '\0';
fscanf(fp,"%s %s %s\n",header,key,footer);
printf("\nkey = %s\n",key);
if(strcmp(pk64,key) == 0)
{
ret = 1;
break;
}
}
fclose(fp);
return ret;
}
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;
x11_session x11session;
int socket;
do
{
message=ssh_message_get(session);
if(message)
{
message_type = ssh_message_type(message);
message_subtype = ssh_message_subtype(message);
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",message_subtype);
/*if(message_subtype == SSH_CHANNEL_REQUEST_X11)
{
printf("\nSSH_CHANNEL_REQUEST_X11");
if(session_x11_req(session,message,&x11session,&socket) != 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);
wait_for_something(session,socket);
ssh_disconnect(session);
return NULL; /* Aris's hack */
}
break;
default:
ssh_message_reply_default(message);
}
ssh_message_free(message);
}
} while(1);
return NULL;
}
/*
int session_x11_req(ssh_session session,ssh_message message,x11_session* x11session,int *socket)
{
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 = session_setup_x11fwd(session,x11session,socket);
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);
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 *socket)
{
int ret = 1;
ret = x11_create_display_inet(session,&x11session->display_number,socket);
if(ret == 0)
{
printf("\nx11_create_display_inet failed");
return 0;
}
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);
sprintf(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(ai->ai_family == AF_INET6)
// sock_set_v6only(sock);
// if(x11_use_localhost)
// channel_set_reuseaddr(sock);
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;
}
*/
/*
int wait_for_something(ssh_session session,int socket)
{
fd_set infds, testfds;
struct timeval tv = { 15, 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;
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
};
FD_ZERO(&infds);
FD_SET(socket, &infds);
printf("\nwait_for_something: socket = %d\n",socket);
maxfds = socket;
testfds = infds;
printf("\nwait_for_something: before select\n");
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(socket, &testfds))
{
printf("\nFD_ISSET\n");
cli_len = sizeof (cli_addr);
bzero((char *) &cli_addr, sizeof (cli_addr));
client_sock = accept(socket, (struct sockaddr *) &cli_addr, (socklen_t *) &cli_len);
printf("\nclient_sock = %d",client_sock);
chan_x11 = ssh_channel_new(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 0;
}
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 0;
}
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 0;
}
else
printf("\nAdded fd to event");
if(ssh_event_add_session(event, session) != SSH_OK)
{
printf("Couldn't add the session to the event\n");
return 0;
}
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);
}
}
printf("\nexiting wait_for_something\n");
return 1;
}
*/
static int copy_fd_to_chan(socket_t fd, int revents, void *userdata)
{
ssh_channel chan = (ssh_channel)userdata;
char buf[2048];
int sz = 0;
buf[0] = '\0';
if(!chan) {
close(fd);
return -1;
}
if(revents & POLLIN) {
sz = read(fd, buf, 2048);
if(sz == 0)
{
ssh_channel_close(chan);
close(fd);
sz = -1;
}
if(sz > 0) {
ssh_channel_write(chan, buf, sz);
}
}
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);
}
int exec_command(const char *command,x11_session* x11session)
//static gpointer exec_command(gpointer data)
{
FILE *fpcmd;
char str_exec[256]; //jeetu - buffer size sufficient?; command name may be larger; ideally not fixed
// char *env[256] = {"DISPLAY=:10",NULL};
// char *argv[256] = {"/bin/sh","-c","xcalc",NULL};
str_exec[0] = '\0';
// snprintf(str_exec,199,"%s -display :%d",command,x11session->display_number);
//snprintf(str_exec,256,"/bin/sh -c \"export DISPLAY=:%d;%s\"",x11session->display_number,command);
//sprintf(str_exec, "/bin/sh -c \"export DISPLAY=:%d;%s\"", x11session->display_number,command);
// fpcmd = popen(str_exec,"r");
if(fpcmd == NULL)
return 0;
// execve("/bin/sh",argv,env);
return 1;
// return NULL;
}
int wait_for_something(ssh_session session,int socket)
{
fd_set infds, testfds;
struct timeval tv = { 15, 0 };
int maxfds = 0;
int nready;
int x11datacount = 0;
int client_sock,cli_len;
struct sockaddr_in cli_addr;
x11conndata = malloc(sizeof(x11data)); //jeetu - memory to be freed
while(1)
{
FD_ZERO(&infds);
FD_SET(socket, &infds);
printf("\nwait_for_something: socket = %d\n",socket);
maxfds = socket;
testfds = infds;
printf("\nwait_for_something: before select\n");
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(socket, &testfds))
{
printf("\nFD_ISSET\n");
x11conndata[x11datacount] = malloc(sizeof(x11data));
cli_len = sizeof (cli_addr);
//bzero((char *) &cli_addr, sizeof (cli_addr));
client_sock = accept(socket, (struct sockaddr *) &cli_addr, &cli_len);
printf("\nclient_sock = %d",client_sock);
x11conndata[x11datacount]->session = session;
x11conndata[x11datacount]->client_sock = client_sock;
//g_thread_create(process_x11_channel_events_thread,x11conndata[x11datacount],FALSE,NULL);
x11datacount++;
}
}
}
printf("\nexiting wait_for_something\n");
return 1;
}
/*
static gpointer process_x11_channel_events_thread(gpointer x11conndata)
{
ssh_event event;
short events;
ssh_channel chan_x11=0;
int client_sock;
x11data *data = (x11data *) x11conndata;
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
};
client_sock = data->client_sock;
chan_x11 = ssh_channel_new(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);
return NULL;
}
*/#include <iostream>
using namespace std;
#include"libssh/libssh.h"
#include"libssh/server.h"
#include"libssh/callbacks.h"
#include"libssh/legacy.h"
#include"libssh/sftp.h"
#include"libssh/ssh2.h"
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <io.h>
//#include <unistd.h>
int verify_knownhost(ssh_session session);
char *getpass(char *data);
int interactive_shell_session(ssh_channel channel);
const int port = 2000;//22010;
int main(void)
{
ssh_session session;
int iError;
char *password;
ssh_channel channel;
iError = ssh_init();
if(iError == SSH_ERROR)
{
cout<<"Error Libssh init failed";
return 0;
}
session = ssh_new();
if(session == NULL)
{
cout<<"Session is null";
return 0;
}
ssh_options_set(session, SSH_OPTIONS_HOST, "127.0.0.1");
ssh_options_set(session, SSH_OPTIONS_PORT, &port);
if(iError < 0)
{
cout<<"ssh set options failed "<<ssh_get_error(session);
return 0;
}
iError = ssh_connect(session);
if(iError < 0 )
{
printf("Error while connecting to server at local host %s", ssh_get_error(session));
return 0;
}
//iError = verify_knownhost(session);
// Verify the server's identity
// For the source code of verify_knowhost(), check previous example
if (verify_knownhost(session) < 0)
{
ssh_disconnect(session);
ssh_free(session);
exit(-1);
}
//request for Service request
iError = ssh_service_request(session, "ssh-userauth");
if(iError == -1)
{
printf("Error while sending ssh_service_request %s", ssh_get_error(session));
return 0;
}
channel = ssh_channel_new(session);
if (channel == NULL)
return SSH_ERROR;
iError = ssh_channel_open_session(channel);
if (iError != SSH_OK)
{
ssh_channel_free(channel);
return iError;
}
//request a channel
interactive_shell_session(channel);
// Authenticate ourselves
password = getpass("Password: ");
iError = ssh_userauth_password(session, NULL, password);
if (iError != SSH_AUTH_SUCCESS)
{
fprintf(stderr, "Error authenticating with password: %s\n", ssh_get_error(session));
ssh_disconnect(session);
ssh_free(session);
exit(-1);
}
Sleep(10000);
ssh_disconnect(session);
ssh_free(session);
return 0;
}
int verify_knownhost(ssh_session session)
{
int state, hlen;
unsigned char *hash = NULL;
char *hexa;
char buf[10];
state = ssh_is_server_known(session);
hlen = ssh_get_pubkey_hash(session, &hash);
if (hlen < 0)
return -1;
switch (state)
{
case SSH_SERVER_KNOWN_OK:
break; /* ok */
case SSH_SERVER_KNOWN_CHANGED:
fprintf(stderr, "Host key for server changed: it is now:\n");
ssh_print_hexa("Public key hash", hash, hlen);
fprintf(stderr, "For security reasons, connection will be stopped\n");
free(hash);
return -1;
case SSH_SERVER_FOUND_OTHER:
fprintf(stderr, "The host key for this server was not found but an other"
"type of key exists.\n");
fprintf(stderr, "An attacker might change the default server key to"
"confuse your client into thinking the key does not exist\n");
free(hash);
return -1;
case SSH_SERVER_FILE_NOT_FOUND:
fprintf(stderr, "Could not find known host file.\n");
fprintf(stderr, "If you accept the host key here, the file will be"
"automatically created.\n");
/* fallback to SSH_SERVER_NOT_KNOWN behavior */
case SSH_SERVER_NOT_KNOWN:
hexa = ssh_get_hexa(hash, hlen);
fprintf(stderr,"The server is unknown. Do you trust the host key?\n");
fprintf(stderr, "Public key hash: %s\n", hexa);
free(hexa);
if (fgets(buf, sizeof(buf), stdin) == NULL)
{
free(hash);
return -1;
}
//if (strncasecmp(buf, "yes", 3) != 0)
//{
//free(hash);
//return -1;
//}
if (ssh_write_knownhost(session) < 0)
{
fprintf(stderr, "Error %s\n", strerror(errno));
free(hash);
return -1;
}
break;
case SSH_SERVER_ERROR:
fprintf(stderr, "Error %s", ssh_get_error(session));
free(hash);
return -1;
}
free(hash);
return 0;
}
char *getpass(char *data)
{
char *pData = new char[50];
//cout<<data;
gets(pData);
return pData;
}
int interactive_shell_session(ssh_channel channel)
{
int rc;
char buffer[256];
int nbytes;
rc = ssh_channel_request_pty(channel);
if (rc != SSH_OK)
return rc;
rc = ssh_channel_change_pty_size(channel, 80, 24);
if (rc != SSH_OK)
return rc;
rc = ssh_channel_request_shell(channel);
if (rc != SSH_OK)
return rc;
while (ssh_channel_is_open(channel) &&
!ssh_channel_is_eof(channel))
{
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
if (nbytes < 0)
return SSH_ERROR;
if (nbytes > 0)
write(1, buffer, nbytes);
}
return rc;
}
Archive administrator: postmaster@lists.cynapses.org
