I am using libssh to send a remote command to a computer. This command is real time so I am trying to get databack as it is generated. Basically I am hexdumping a mouse event and I want that data as it comes in. How can I make this return realtime results from my command?
#include <libssh/libssh.h>
#include <stdio.h>
#include <stdlib.h>
/*
* 1) Set ssh options
* 2) Connect
* 3) Authenticate
* 4) Set channels
* 5) Execute command
* */
int main()
{
//Initilization
ssh_session session;
int verbosity = SSH_LOG_PROTOCOL;
int port = 22;
char* password ="root";
int rc;
session = ssh_new();
if (session == NULL)
return(-1);
//Set options for SSH connection
ssh_options_set(session,SSH_OPTIONS_HOST,"90.12.34.44");
ssh_options_set(session,SSH_OPTIONS_LOG_VERBOSITY,&verbosity);
ssh_options_set(session,SSH_OPTIONS_PORT,&port);
ssh_options_set(session,SSH_OPTIONS_USER,"root");
//Connect to server
rc = ssh_connect(session);
if (rc != SSH_OK)
{
fprintf(stderr,"Error connecting to host %s\n",ssh_get_error(session));
ssh_free(session);
return(-1);
}
rc = ssh_userauth_password(session,NULL,password);
if ( rc == SSH_AUTH_SUCCESS)
{
printf("Authenticated correctly");
}
ssh_channel channel;
channel = ssh_channel_new(session);
if(channel == NULL) return SSH_ERROR;
rc = ssh_channel_open_session(channel);
if (rc != SSH_OK)
{
ssh_channel_free(channel);
return rc;
}
rc = ssh_channel_request_exec(channel,"hd /dev/input/event0");
if (rc != SSH_OK)
{
ssh_channel_close(channel);
ssh_channel_free(channel);
return rc;
}
char buffer[30];
unsigned int nbytes;
nbytes = ssh_channel_read(channel,buffer,sizeof(buffer),0);
while(nbytes > 0)
{
if(fwrite(buffer,1,nbytes,stdout));
{
ssh_channel_close(channel);
ssh_channel_free(channel);
return SSH_ERROR;
}
nbytes = ssh_channel_read(channel,buffer,sizeof(buffer),0);
if (nbytes < 0)
{
ssh_channel_close(channel);
ssh_channel_free(channel);
return SSH_ERROR;
}
return 0;
}
}
If you want to get asynchronous real-time responses from remote file being changed, you'd better try some special async I/O API, like libevent. You will have to write your own client and server, but it's quite simple.
Are you sure you need an encrypted connection? If you are, openSSL is supported by libevent too.
The Problem is in this line my friend
nbytes = ssh_channel_read(channel,buffer,sizeof(buffer),0);
The last parameters is (0) Zero . If you Change it to (1) one , function will fill the buffer with the result of your Command . :D That's it
Related
I'm trying to sniff all TCP SYN packets received by any of my network adapters and I treid doing so by using the free npcap library available online.
You can see my code below
pcap_if_t* allNetworkDevices;
std::vector<pcap_t*> networkInterfacesHandles;
std::vector<WSAEVENT> sniffEvents;
void packet_handler(u_char* user, const struct pcap_pkthdr* header, const u_char* packet) {
cout << "here" << endl;
}
BOOL openAllInterfaceHandles()
{
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t* curNetworkHandle;
if (pcap_findalldevs(&allNetworkDevices, errbuf) == -1) {
printf("Error in pcap_findalldevs: %s\n", errbuf);
return FALSE;
}
for (pcap_if_t* d = allNetworkDevices; d != NULL; d = d->next) {
//curNetworkHandle = pcap_open(d->name, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf);
printf("%s\n", d->description);
curNetworkHandle = pcap_open_live(d->name, BUFSIZ, 1, 1000, errbuf);
if (curNetworkHandle == NULL) {
printf("Couldn't open device %s: %s\n", d->name, errbuf);
continue;
}
networkInterfacesHandles.push_back(curNetworkHandle);
// Compile and set the filter
struct bpf_program fp;
char filter_exp[] = "(tcp[tcpflags] & tcp-syn) != 0";
if (pcap_compile(curNetworkHandle, &fp, filter_exp, 1, PCAP_NETMASK_UNKNOWN) < 0) {
printf("Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(curNetworkHandle));
continue;
}
if (pcap_setfilter(curNetworkHandle, &fp) == -1) {
printf("Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(curNetworkHandle));
continue;
}
// Create an event for the handle
sniffEvents.push_back(pcap_getevent(curNetworkHandle));
}
}
int main()
{
openAllInterfaceHandles();
while (TRUE)
{
DWORD result = WaitForMultipleObjects(sniffEvents.size(), sniffEvents.data(), FALSE, INFINITE);
if (result == WAIT_FAILED) {
printf("Error in WaitForMultipleObjects: %d\n", GetLastError());
break;
}
// Dispatch packets for the handle associated with the triggered event
int index = result - WAIT_OBJECT_0;
pcap_dispatch(networkInterfacesHandles[index], -1, &packet_handler, NULL);
if (cond)
{
cout << "done" << endl;
break;
}
}
while (!networkInterfacesHandles.empty())
{
pcap_close(networkInterfacesHandles.back());
networkInterfacesHandles.pop_back();
}
pcap_freealldevs(allNetworkDevices);
return 0;
}
cond is some condition I'm using which is irrelevant to the problem.
For some reason it won't go into the packet_handler even when I receive TCP SYN packets (which I check by using Wireshark) and I tried sending them either via the loopback and also from another PC in the same LAN.
Any help to find the problem would be greatly appreciated.
I found a SSL/TLS client example here, it works well.
#include <stdio.h>
#include <errno.h>
#include <malloc.h>
#include <string.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <openssl/err.h>
#include <openssl/pkcs12.h>
#include <openssl/ssl.h>
#include <openssl/conf.h>
void connect(const char* host, int port) {
BIO* sbio, * out;
int len;
char tmpbuf[1024];
SSL_CTX* ctx;
SSL* ssl;
char server[200];
snprintf(server, sizeof(server), "%s:%d", host, port);
/* XXX Seed the PRNG if needed. */
ctx = SSL_CTX_new(TLS_client_method());
/* XXX Set verify paths and mode here. */
sbio = BIO_new_ssl_connect(ctx);
BIO_get_ssl(sbio, &ssl);
if (ssl == NULL) {
fprintf(stderr, "Can't locate SSL pointer\n");
ERR_print_errors_fp(stderr);
exit(1);
}
/* Don't want any retries */
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
/* XXX We might want to do other things with ssl here */
/* An empty host part means the loopback address */
BIO_set_conn_hostname(sbio, server);
out = BIO_new_fp(stdout, BIO_NOCLOSE);
if (BIO_do_connect(sbio) <= 0) {
fprintf(stderr, "Error connecting to server\n");
ERR_print_errors_fp(stderr);
exit(1);
}
int ret = 0;
if ((ret = BIO_do_handshake(sbio)) <= 0) {
fprintf(stderr, "Error establishing SSL connection\n");
ERR_print_errors_fp(stderr);
exit(1);
}
/* XXX Could examine ssl here to get connection info */
BIO_puts(sbio, "Hi, this message is from client c++");
for (;;) {
len = BIO_read(sbio, tmpbuf, 1024);
if (len <= 0) {
break;
}
BIO_write(out, tmpbuf, len);
}
BIO_free_all(sbio);
BIO_free(out);
}
int main() {
connect("127.0.0.1", 5555);
}
but i need to set a timeout for this connection. then i found How to set connection timeout and operation timeout in OpenSSL.
so i change the codes
if (BIO_do_connect(sbio) <= 0) {
fprintf(stderr, "Error connecting to server\n");
ERR_print_errors_fp(stderr);
exit(1);
}
to
{
BIO_set_nbio(sbio, 1);
if (1 > BIO_do_connect(sbio)) {
if (!BIO_should_retry(sbio)) {
fprintf(stderr, "Error: should not retry\n");
ERR_print_errors_fp(stderr);
exit(1);
}
int fdSocket = 0;
if (BIO_get_fd(sbio, &fdSocket) < 0) {
fprintf(stderr, "Error: can not get socket\n");
ERR_print_errors_fp(stderr);
exit(1);
}
struct timeval timeout;
fd_set connectionfds;
FD_ZERO(&connectionfds);
FD_SET(fdSocket, &connectionfds);
timeout.tv_usec = 0;
timeout.tv_sec = 4;
if (0 == select(fdSocket + 1, NULL, &connectionfds, NULL, &timeout)) {
fprintf(stderr, "Error: timeout\n");
ERR_print_errors_fp(stderr);
exit(1);
}
}
}
now BIO_do_handshake returns -1 and the program exits.
How can i set a timeout correctly for my ssl connection?
Please give me some advice! help me!
I think you should set a timeout for handshake, not connection. in your code the connection has no problem because "select" returned non-zero value. in fact BIO_do_connect does handshake after connection is available. BIO_do_connect and BIO_do_handshake are the same in header file.
# define BIO_do_connect(b) BIO_do_handshake(b)
So i think this problem is handshake. eg. you connect to a server which uses a normal tcp socket without ssl. the server will not send "server_hallo" and certificate. then the client will wait for these "server_hallo" and certificate. BIO_do_handshake returns -1 if the handshake progress is still not finished.
maybe you can use BIO_set_ssl_renegotiate_timeout to set a timeout.
I would go about this in two steps:
I would deal with connection setup on my own. That way you can use non-blocking socket, connect(2) and select(2) and have complete control over timing of this part.
I would also implement by own BIO. You can use an existing BIO and only implement read, write and puts methods. This will allow you to control socket accesses.
With this in place you can have total control over how much time you spend. You can implement different timeouts for session setup, renegotiation, normal operation...
The problem with BIO_set_nbio is that you set I/O to non blocking mode. So you have to process further steps in non blocking mode.
I made an example how to process the request with sleep and non blocking mode. Maybe it is a bit ugly. But it worked for me.
#include <openssl/err.h>
#include <openssl/ssl.h>
#include <unistd.h>
#include <stdio.h>
void connect(const char* host, int port) {
const long timeout_nsec = 4 * (long)1000000000, dt_nsec = 100000;
char tmpbuf[1024];
char server[200];
snprintf(server, sizeof(server), "%s:%d", host, port);
struct timespec dt;
dt.tv_sec = 0;
dt.tv_nsec = dt_nsec;
/* XXX Seed the PRNG if needed. */
SSL_CTX *ctx = SSL_CTX_new(TLS_client_method());
/* XXX Set verify paths and mode here. */
BIO *sbio = BIO_new_ssl_connect(ctx);
SSL* ssl = nullptr;
BIO_get_ssl(sbio, &ssl);
if (ssl == NULL) {
fprintf(stderr, "Can't locate SSL pointer\n");
ERR_print_errors_fp(stderr);
exit(1);
}
/* Don't want any retries */
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
/* XXX We might want to do other things with ssl here */
/* An empty host part means the loopback address */
BIO_set_conn_hostname(sbio, server);
BIO *out = BIO_new_fp(stdout, BIO_NOCLOSE);
BIO_set_nbio(sbio, 1);
{
long time_remained = timeout_nsec;
while(1) {
int res = BIO_do_connect(sbio);
if (res <= 0 && BIO_should_retry(sbio)) {
clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &dt, NULL);
time_remained -= dt_nsec;
if (time_remained <= 0) {
fprintf(stderr, "Timeout\n");
exit(1);
}
continue;
}
if (res <= 0) {
fprintf(stderr, "BIO_do_connect error\n");
ERR_print_errors_fp(stderr);
exit(1);
}
break;
}
}
{
long time_remained = timeout_nsec;
while(1) {
int res = BIO_do_handshake(sbio);
if (res <= 0 && BIO_should_retry(sbio)) {
clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &dt, NULL);
time_remained -= dt_nsec;
if (time_remained <= 0) {
fprintf(stderr, "Timeout\n");
exit(1);
}
continue;
}
if (res <= 0) {
fprintf(stderr, "BIO_do_handshake error\n");
ERR_print_errors_fp(stderr);
exit(1);
}
break;
}
}
/* XXX Could examine ssl here to get connection info */
int a = BIO_puts(sbio, "Hi, this message is from client c++");
for (;;) {
int len = -1;
{
long time_remained = timeout_nsec;
while(1) {
len = BIO_read(sbio, tmpbuf, 1024);
if (len < 0 && BIO_should_retry(sbio)) {
clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &dt, NULL);
time_remained -= dt_nsec;
if (time_remained <= 0) {
fprintf(stderr, "Timeout\n");
exit(1);
}
continue;
}
if (len < 0) {
fprintf(stderr, "BIO_read error\n");
ERR_print_errors_fp(stderr);
exit(1);
}
break;
}
}
if (len == 0) {
break;
}
BIO_write(out, tmpbuf, len);
}
BIO_free_all(sbio);
BIO_free(out);
}
int main() {
connect("127.0.0.1", 5555);
}
I have a Python server communicating with a C++ client using a unix datagram socket connection. The following code set-ups a socket, and then sends and receives one message from the client. This script works in python 2.7, however, when testing it in python 3, the call to recv() times out waiting for messages from the client. The client, however, does receive messages from the server without issue. I've tested this in two separate machines using both 3.5.2 and 3.7.1 with the same results.
UPDATE: I added an ioloop (wrapper for asyncio event loop) to create a callback system for when the messages on the socket are ready. Messages from client appear when the server is run with Python 2.7, but using Python 3.7.1 nothing is ever received.
C++ Client Source:
// Socket Client
#include <stdio.h>
#include <stdlib.h>
#include <cerrno>
#include <vector>
#include <string>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <cstdarg>
using namespace std;
int sock;
bool await_connection = true;
vector<sockaddr_un> dest_addrs;
int max_msg_size = 2048;
string msg_buf;
string sock_name = "test.sock";
void receive_control_message()
{
char buf[4096]; // Should be enough for client->server messages
sockaddr_un srcaddr;
socklen_t srcaddr_len;
srcaddr_len = sizeof(srcaddr);
int len = recvfrom(sock, buf, sizeof(buf),
0, (sockaddr *) &srcaddr, &srcaddr_len);
if (len == -1)
{
fprintf(stderr,"Socket read error: %s\n", strerror(errno));
exit(-1);
}
printf("sockaddr_un sun_path: '%s'\n", srcaddr.sun_path);
dest_addrs.push_back(srcaddr);
string data(buf, len);
fprintf(stderr, "websocket: Received control message in %d byte.\n", (int) data.size());
printf("%s\n", data.c_str());
}
void finish_message()
{
if (msg_buf.size() == 0)
return;
const int initial_buf_size = msg_buf.size();
fprintf(stderr, "websocket: About to send %d bytes.\n", initial_buf_size);
if (sock_name.empty())
{
msg_buf.clear();
return;
}
msg_buf.append("\n");
const char* fragment_start = msg_buf.data();
const char* data_end = msg_buf.data() + msg_buf.size();
int fragments = 0;
while (fragment_start < data_end)
{
int fragment_size = data_end - fragment_start;
if (fragment_size > max_msg_size)
fragment_size = max_msg_size;
fragments++;
for (unsigned int i = 0; i < dest_addrs.size(); ++i)
{
int retries = 30;
ssize_t sent = 0;
while (sent < fragment_size)
{
ssize_t retval = sendto(sock, fragment_start + sent,
fragment_size - sent, 0, (sockaddr*) &dest_addrs[i],
sizeof(sockaddr_un));
fprintf(stderr, " trying to send fragment to client %d...\n", i);
if (retval <= 0)
{
const char *errmsg = retval == 0 ? "No bytes sent"
: strerror(errno);
if (--retries <= 0)
{
fprintf(stderr,"Socket write error: %s\n", errmsg );
exit(-1);
}
if (retval == 0 || errno == ENOBUFS || errno == EWOULDBLOCK
|| errno == EINTR || errno == EAGAIN)
{
// Wait for half a second at first (up to five), then
// try again.
const int sleep_time = retries > 25 ? 2 * 1000
: retries > 10 ? 500 * 1000
: 5000 * 1000;
fprintf(stderr, "failed (%s), sleeping for %dms.\n",
errmsg, sleep_time / 1000);
usleep(sleep_time);
}
else if (errno == ECONNREFUSED || errno == ENOENT)
{
// the other side is dead
fprintf(stderr, "failed (%s), breaking.\n", errmsg);
dest_addrs.erase(dest_addrs.begin() + i);
i--;
break;
}
else
{
fprintf(stderr,"Socket write error: %s\n", errmsg);
}
}
else
{
fprintf(stderr, "fragment size %d sent.\n", fragment_size);
sent += retval;
}
}
}
fragment_start += fragment_size;
}
msg_buf.clear();
fprintf(stderr, "websocket: Sent %d bytes in %d fragments.\n", initial_buf_size, fragments);
}
void send_message(const char *format, ...)
{
char buf[2048];
int len;
va_list argp;
va_start(argp, format);
if ((len = vsnprintf(buf, sizeof(buf), format, argp)) >= (int)sizeof(buf)
|| len == -1)
{
if (len == -1)
{
fprintf(stderr, "Webtiles message format error! (%s)", format);
exit(-1);
}
else
{
fprintf(stderr, "Webtiles message too long! (%d)", len);
exit(-1);
}
}
va_end(argp);
msg_buf.append(buf);
finish_message();
}
int main()
{
if (sock_name.empty()) return 0;
sock = socket(PF_UNIX, SOCK_DGRAM, 0);
if (sock < 0)
{
printf("Can't open the webtiles socket!\n");
exit(-1);
}
sockaddr_un addr;
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, sock_name.c_str());
if (::bind(sock, (sockaddr*) &addr, sizeof(sockaddr_un)))
{
printf("Can't bind the webtiles socket!\n");
exit(-1);
}
int bufsize = 64 * 1024;
if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(bufsize)))
{
printf("Can't set buffer size!\n");
exit(-1);
}
// Need small maximum message size to avoid crashes in OS X
max_msg_size = 2048;
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;
if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0)
{
printf("Can't set send timeout!\n");
exit(-1);
}
printf("Awaiting connection...\n");
if (await_connection)
{
while (dest_addrs.size() == 0) receive_control_message();
}
send_message("{\"foo\":\"grapes\",\"boo\":\"chicken\"}");
send_message("*{\"msg\":\"flush_messages\"}");
return 0;
}
Server Script
# Socket Server
import socket
import json
from datetime import datetime, timedelta
import warnings
import os,sys
from tornado.ioloop import IOLoop
crawl_socket = None
crawl_socketpath = 'test.sock'
socketpath = 'crawl_socket'
msg_buffer = None
ioloop = IOLoop.instance()
def json_encode(value):
return json.dumps(value).replace("</", "<\\/")
def close():
global crawl_socket
if crawl_socket:
print ("Closing socket...")
crawl_socket.close()
os.unlink(socketpath)
crawl_socket = None
def message_callback(data):
if len(data) > 0 and not data.startswith("*"):
print(json.loads(data))
elif data.startswith("*"):
print(json.loads(data[1:]))
def handle_data(data):
global msg_buffer
if msg_buffer is not None:
data = msg_buffer + data
if data[-1] != "\n":
# All messages from crawl end with \n.
# If this one doesn't, it's fragmented.
msg_buffer = data
else:
msg_buffer = None
message_callback(data)
def handle_read(fd, events):
if events & ioloop.READ:
data = crawl_socket.recv(128 * 1024, socket.MSG_DONTWAIT)
handle_data(data)
if events & ioloop.ERROR:
pass
try:
os.unlink(socketpath)
except OSError:
if os.path.exists(socketpath):
raise
if os.path.exists(crawl_socketpath) and not os.path.exists(socketpath):
crawl_socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
crawl_socket.settimeout(10)
crawl_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if (crawl_socket.getsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF) < 2048):
crawl_socket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 2048)
if (crawl_socket.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF) < 212992):
crawl_socket.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 212992)
msg = json_encode({ "msg": "attach", "primary": True })
with warnings.catch_warnings():
warnings.simplefilter("ignore")
crawl_socket.bind(socketpath)
try:
crawl_socket.sendto(msg.encode('utf-8'), crawl_socketpath)
except socket.timeout:
print("ERROR: in send_message() - Game socket send timeout")
close()
sys.exit(-1)
ioloop.add_handler(crawl_socket.fileno(),
handle_read,
ioloop.ERROR | ioloop.READ)
ioloop.start()
else:
print('%s does not exist' % crawl_socketpath)
I managed to solve this on my own, so here is the answer for anyone seeking insight on a similar problem in the future.
socket.recv() in Python 2 returns a str object representing the data received.
In Python 3, this has changed, and socket.recv() returns a bytes object.
So the following needed to be added to handle_data above:
if isinstance(data,bytes):
data = data.decode("utf-8")
I am writing a single chat program with GUI. I wanted to write a server that would accept many clients. Every client can connect successfuly. But there is a strange problem with sending and receiving data. I use select() and a thread to handle many sockets at the same time. If a client sends some data to server, it will receive it and send it back to that client (the client is especially written without "prediction"). But the server won't send it further to another clients (like every client had its own private conversation with the server). Here's my code:
// this is rewritten from the Beej's tutorial with a little and insignificant changes
/* in the thread */
fd_set mainfd;
fd_set readfd;
// sin-size, newfd, maxfd - int
while(TRUE)
{
readfd = mainfd;
if(select(maxfd+1, &readfd, NULL, NULL, NULL) == -1)
{
MessageBoxA(NULL, "Error while trying to accept incoming connections (select)", "Error", 16);
itoa(GetLastError(), buf, 10);
MessageBoxA(NULL, buf, buf, 0);
break;
}
for(int i = 0; i <= maxfd; i++)
{
char* psr;
char srMsg[256];
if(FD_ISSET(i, &readfd))
{
if(i == mainSocket)
{
sin_size = sizeof(their_addr);
newfd = accept(mainSocket, (struct sockaddr*)&their_addr, &sin_size);
if(newfd == SOCKET_ERROR)
{
AddTextToEdit(hStaticChat, "* Error: couldn't accept incoming connection.", TRUE);
}
else
{
FD_SET(newfd, &mainfd);
if(newfd > maxfd)
{
maxfd = newfd;
}
}
}
else
{
len = recv(i, srMsg, 256, 0);
if(len == 0 || len == SOCKET_ERROR)
{
AddTextToEdit(hStaticChat, "* Client has disconnected", TRUE);
close(i);
FD_CLR(i, &mainfd);
}
else
{
AddTextToEdit(hStaticChat, srMsg, TRUE);
for(int j = 0; j <= maxfd; j++)
{
if(FD_ISSET(j, &readfd))
{
send(j, srMsg, len, 0);
}
}
}
}
}
}
}
You are only sending data to the clients whos fd is in readfd, that is, only to that one which just communicated to you. Try to test FD_ISSET(j, mainfd) instead.
This code is not valid under WinSock. Windows does not deal with sockets using integer file descriptors like other platforms do. Sockets are represented using actual kernel objects instead, so you can't use loop counters as socket handles and such. There is also API differences (closesocket() instead of close(), maxfd is ignored by select(), FD_XXX() expect SOCKET handles instead of int, etc).
On Windows, you need to use something more like this instead:
fd_set mainfd;
SOCKET newfd;
int sin_size;
...
while(TRUE)
{
fd_set readfd = mainfd;
if (select(0, &readfd, NULL, NULL, NULL) == SOCKET_ERROR)
{
itoa(WSAGetLastError(), buf, 10);
MessageBoxA(NULL, "Error while trying to accept incoming connections (select)", "Error", 16);
MessageBoxA(NULL, buf, buf, 0);
break;
}
for(int i = 0; i < readfd.fd_count; i++)
{
if (readfd.fd_array[i] == mainSocket)
{
sin_size = sizeof(their_addr);
newfd = accept(mainSocket, (struct sockaddr*)&their_addr, &sin_size);
if (newfd == INVALID_SOCKET)
{
AddTextToEdit(hStaticChat, "* Error: couldn't accept incoming connection.", TRUE);
}
else
{
// Note that fd_set can only hold FD_SETSIZE (64) sockets as a time!
FD_SET(newfd, &mainfd);
}
}
else
{
char srMsg[257];
len = recv(readfd.fd_array[i], srMsg, 256, 0);
if (len < 1)
{
if (len == 0)
AddTextToEdit(hStaticChat, "* Client has disconnected", TRUE);
else
AddTextToEdit(hStaticChat, "* Error: couldn't read from a client connection.", TRUE);
closesocket(readfd.fd_array[i]);
FD_CLR(readfd.fd_array[i], &mainfd);
}
else
{
srMsg[len] = 0;
AddTextToEdit(hStaticChat, srMsg, TRUE);
for (int j = 0; j < mainfd.fd_count; j++)
{
if (mainfd.fd_array[i] != mainSocket)
send(mainfd.fd_array[j], srMsg, len, 0);
}
}
}
}
}
I'm trying to get the output of the command 'df' which I'll replace later, from a remote server:
#include <libssh/libssh.h>
#include <stdlib.h>
#include <stdio.h>
int main()
{
ssh_session my_ssh_session;
int rc;
ssh_channel channel;
char buffer[256];
int nbytes;
int port = 22;
my_ssh_session = ssh_new();
if (my_ssh_session == NULL)
exit(-1);
ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "192.168.2.2");
ssh_options_set(my_ssh_session, SSH_OPTIONS_PORT, &port);
rc = ssh_connect(my_ssh_session);
if (rc != SSH_OK)
{
fprintf(stderr, "Failed %s\n",
ssh_get_error(my_ssh_session));
exit(-1);
}
channel = ssh_channel_new(my_ssh_session);
if (channel == NULL)
return SSH_ERROR;
rc = ssh_channel_open_session(channel);
if (rc != SSH_OK)
{
ssh_channel_free(channel);
return rc;
}
rc = ssh_channel_request_exec(channel, "df");
if (rc != SSH_OK)
{
ssh_channel_close(channel);
ssh_channel_free(channel);
return rc;
}
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
while (nbytes > 0)
{
if (write(1, buffer, nbytes) != nbytes)
{
ssh_channel_close(channel);
ssh_channel_free(channel);
return SSH_ERROR;
}
nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0);
}
if (nbytes < 0)
{
ssh_channel_close(channel);
ssh_channel_free(channel);
return SSH_ERROR;
}
ssh_channel_send_eof(channel);
ssh_channel_close(channel);
ssh_channel_free(channel);
return SSH_OK;
ssh_disconnect(my_ssh_session);
ssh_free(my_ssh_session);
}
The compiler didn't show any errors,
but there were no results when I run the program,
I checked the syslog of the remote server and I found the following line:
sshd[12794]: dispatch_protocol_error: type 90 seq 3
Please advise what could be the problem,
Thank you.
It seems like you are trying to get to the remote server without functions of host authentification (e.g. checking information from /.ssh/known_hosts) and user authentificationa through public keys or password. You should place these two functions after the
if (rc != SSH_OK)
{
fprintf(stderr, "Failed %s\n", ssh_get_error(my_ssh_session));
exit(-1);
}
Look through the chapters 1 and 2 in libssh tutorial.