I've downloaded and compiled libssh 0.6.1 from libSSH .
I also linked the ssh.lib,ssh.dll to a visual c++ project .
The library with code below compiles and run fine ,
but when calling ssh_connect() , it return -1 : Timeout .
I used the option :
ssh_options_set(my_ssh_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
to print the logging , and it says :
ssh_connect : socket connecting now waiting for callbacks to work.
ssh_connect : Timeout connecting to local host.
On my laptop i installed FreeSSHd server and connecting to it using putty works .
My code, until the error :
int _tmain(int argc, _TCHAR* argv[])
{
ssh_session my_ssh_session;
int verbosity = SSH_LOG_PROTOCOL;
int port = 22;
int rc;
char *password;
// Open session and set options
my_ssh_session = ssh_new();
if (my_ssh_session == NULL)
exit(-1);
ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "localhost");
ssh_options_set(my_ssh_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
ssh_options_set(my_ssh_session, SSH_OPTIONS_PORT, &port);
// Connect to server
rc = ssh_connect(my_ssh_session);
if (rc != SSH_OK)
{
fprintf(stderr, "Error connecting to localhost: %s\n",
ssh_get_error(my_ssh_session));
ssh_free(my_ssh_session);
exit(-1);
}
This code example is copied from the A typical SSH session Exmple site .
libssh doesn't support "localhost" as a parameter as said in the website instead , define :
char* host="127.0.0.1";
Related
I'm trying to write a demo server/client program in C++. I first ran my server program on my Macbook, with ngrok on and forwarding a public address on the Internet to a local address on my machine. I'm seeing something that I don't understand when I try to run my client program to connect to the server:
If the client tries to connect to localhost at the local port defined in the server program, the server accepts as expected and the client successfully connects,
If the client tries to connect to the ngrok server address at port 80 (default for ngrok), then the client connects, but the server is still blocked at the accept call. (This I don't understand!)
If I send an HTTP GET request to the ngrok server address, the server successfully accepts the connection.
Why do I see these? In the ideal case, I want my server to accept connections from my client program, not just respond to the HTTP GET request.
Here's my code if that helps: For the client,
#include "helpers.hh"
#include <cstdio>
#include <netdb.h>
// usage: -h [host] -p [port]
int main(int argc, char** argv) {
const char* host = "x.xx.xx.xx"; // use the server's ip here.
const char* port = "80";
// parse arguments
int opt;
while ((opt = getopt(argc, argv, "h:p:")) >= 0) {
if (opt == 'h') {
host = optarg;
} else if (opt == 'p') {
port = optarg;
}
}
// look up host and port
struct addrinfo hints, *ais;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6
hints.ai_socktype = SOCK_STREAM; // use TCP
hints.ai_flags = AI_NUMERICSERV;
if (strcmp(host, "ngrok") == 0) {
host = "xxxx-xxxx-xxxx-1011-2006-00-27b9.ngrok.io";
}
int r = getaddrinfo(host, port, &hints, &ais);
if (r != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(r));
exit(1);
}
// connect to server
int fd = -1;
for (auto ai = ais; ai && fd < 0; ai = ai->ai_next) {
fd = socket(ai->ai_family, ai->ai_socktype, 0);
if (fd < 0) {
perror("socket");
exit(1);
}
r = connect(fd, ai->ai_addr, ai->ai_addrlen);
if (r < 0) {
close(fd);
fd = -1;
}
}
if (fd < 0) {
perror("connect");
exit(1);
}
freeaddrinfo(ais);
//
printf("Connection established at fd %d\n", fd);
FILE* f = fdopen(fd, "a+");
fwrite("!", 1, 1, f);
fclose(f);
while (true) {
}
}
And for the server:
#include "helpers.hh"
void handle_connection(int cfd, std::string remote) {
(void) remote;
printf("Received incoming connection at cfd: %d\n", cfd);
usleep(1000000);
printf("Exiting\n");
}
int main(int argc, char** argv) {
int port = 6162;
if (argc >= 2) {
port = strtol(argv[1], nullptr, 0);
assert(port > 0 && port <= 65535);
}
// Prepare listening socket
int fd = open_listen_socket(port);
assert(fd >= 0);
fprintf(stderr, "Listening on port %d...\n", port);
while (true) {
struct sockaddr addr;
socklen_t addrlen = sizeof(addr);
// Accept connection on listening socket
int cfd = accept(fd, &addr, &addrlen);
if (cfd < 0) {
perror("accept");
exit(1);
}
// Handle connection
handle_connection(cfd, unparse_sockaddr(&addr, addrlen));
}
}
Contrary to the typical port forwarding done in the local router, ngrok is not a port forwarder at the transport level (TCP) but it is a request forwarder at the HTTP level.
Thus if the client does a TCP connect to the external ngrok server nothing will be forwarded yet. Only after the client has send the HTTP request the destination will be determined and then this request will be send to the ngrok connector on the internal machine, which then will initiate the connection to the internal server and forward the request.
Hey guys I am trying to write a program which can upload files from my computer to a online server.. I have started with a socket programming client side.....
I have written a code which successfully makes a connection to a server and i can send a message to a server also and can get a reply from it...
Have a look..
#include<stdio.h>
#include<winsock2.h>
#include<bits/stdc++.h>
#include<strings.h>
#pragma comment(lib,"ws2_32.lib") //Winsock Library
int main(int argc , char *argv[])
{
struct sockaddr_in server;
WSADATA wsa;
SOCKET s;
char *message , server_reply[2000];
int recv_size;
printf("\nInitialising Winsock...");
if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
{
printf("Failed. Error Code : %d",WSAGetLastError());
return 1;
}
printf("Initialised.\n");
if((s = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET)
{
printf("Could not create socket : %d" , WSAGetLastError());
}
printf("Socket created.\n");
server.sin_addr.s_addr = inet_addr("172.217.24.238");
server.sin_family = AF_INET;
server.sin_port = htons(80);
//Connect to remote server
if (connect(s , (struct sockaddr *)&server , sizeof(server)) < 0)
{
puts("connect error");
return 1;
}
puts("Connected");
//Send some data
message = "GET / HTTP/1.1\r\n\r\n";
if( send(s , message , strlen(message) , 0) < 0)
{
puts("Send failed");
return 1;
}
puts("Data Send\n");
//Receive a reply from the server
if((recv_size = recv(s , server_reply , 2000 , 0)) == SOCKET_ERROR)
{
puts("recv failed");
}
puts("Reply received\n");
//Add a NULL terminating character to make it a proper string before printing
server_reply[recv_size] = '\0';
puts(server_reply);
return 0;
}
Please suggest me how can i modify this to upload a file from my computer to a server whose IP address and port number is known to me.....
PS: I am new to socket programming ....
Please help....
Actual:code which successfully makes a connection to a server and i can send a message to a server also and can get a reply from it...
Expected: Modify to upload some file on server whose ip address and port number is known...
You need to read a bit more from HTTP RFC about posting data to the server.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST
You can get the correct example to learn how to POST the content as the body of HTTP request to the server.
I am writing an application which will allow user to login to the app using LDAP settings.
Sample program without Start TLS/LDAPS support:
#include <windows.h>
#include <winldap.h>
int main(){
LDAP *ldap =NULL;
int returnCode = -1;
int version = LDAP_VERSION3;
ldap = ldap_init(hostName, PORT);
if (ldap == NULL) {
printf("Failed to init LDAP connection");
return FALSE;
}
returnCode = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, (void*)&version);
if (returnCode != LDAP_SUCCESS) {
cout<<"LDAP: Could not set options. Error: "<< returnCode <<" "<< ldap_err2string(returnCode);
ldap_unbind(ldap);
return FALSE;
}
returnCode = ldap_connect(ldap, NULL);
if (returnCode != LDAP_SUCCESS) {
printf("LDAP: Could not establish connection. Error: %d %s", returnCode, ldap_err2string(returnCode));
ldap_unbind(ldap);
return FALSE;
}
returnCode = ldap_bind_s(ldap, binddn, bindpwd, LDAP_AUTH_SIMPLE);
if (returnCode != LDAP_SUCCESS) {
printf("LDAP: Could not establish connection. Error: %d %s", returnCode, ldap_err2string(returnCode));
ldap_unbind(ldap);
return FALSE;
}
}
StartTLS can be implemented using ldap_start_tls_s function. But I want to verify the certificate before allowing the connections. Any suggestions?
The StarTLS is an extended LDAP operation and must be sent after you have established the connection. However, the server and/or client certificates verifications are part of the TLS protocol. So when you use ldap_start_tls_s function, it will be performed automatically.
If you want to verify the server certificate at the time of the connection, you should use LDAP over SSL, and connect to the LDAPS port. You can use the ldap_sslinit() method for that.
I have 2 Computers. My Server is running on the Debian one while my Client is running on the Windows PC.
The IP of my Server is 192.168.2.113, the one of my Client is 192.168.2.122.
When I telnet 127.0.0.1 or 192.168.2.113 on the Server Machine there is no problem.
The Problem is that I cant connect to the Server from my Client.
I opened the port 50002 via iptables with the comment:
sudo iptables -A INPUT -p tcp --dport 50002 --jump ACCEPT
The main.cpp of my Server:
#include<stdio.h>
#include<string.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h> //write
int main(int argc , char *argv[])
{
int socket_desc , client_sock , c , read_size;
struct sockaddr_in server , client;
char client_message[2000];
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
puts("Socket created");
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 50002 );
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
//print the error message
perror("bind failed. Error");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
//accept connection from an incoming client
client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
if (client_sock < 0)
{
perror("accept failed");
return 1;
}
puts("Connection accepted");
//Receive a message from client
while( (read_size = recv(client_sock , client_message , 2000 , 0)) > 0 )
{
//Send the message back to client
write(client_sock , client_message , strlen(client_message));
}
if(read_size == 0)
{
puts("Client disconnected");
fflush(stdout);
}
else if(read_size == -1)
{
perror("recv failed");
}
return 0;
}
Something strange i noticed is that I can connect to www.google.com in firefox but not in telnet (on my client pc):
telnet>o www.google.com 80
I only get 400-badrequest error
help is very appriciated.
Suggestions:
Step 1) establish that you can ping your server from windows. This way we eliminate potential network configuration issues. Make changes to your firewall if needed.
ping 192.168.2.113
Step 2) Ping from server to access windows. Windows firewall can prevent communication as well.
ping 192.168.2.112
Step 3) I compiled your server program and run om Debian server.
Your program works as expected.
First I connected with telnet on same server to test the program. All good
Step 4) I used telnet from Windows 10 to connect to your server. It connected as well, sending encoded data back.
Step 5) I used PuTTY telnet from Windows that worked good as expected.
Step 6) Conclusion that you have network configuration problem on your system that is not your program related. It can be firewall as well. start with step 1 and 2. Then if needed troubleshoot your network. Regards Bogdan.
I inherited a C++/Windows project where we have an SNMP extension agent (loaded by SNMP service). Inside the agent, we are creating a simple TCP server to which our client applications connect and provide it with data for SNMP queries/traps etc. This all seems to work fine on Windows Server 2008. However, on Windows Server 2012, the client can no longer connect to the server running inside the agent (in SNMP service). The connect() fails with error 10013.
My server code looks something like this:
fd_set master_set;
fd_set readfds;
SOCKET listener;
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR)
{
OutputDebugStringA("WSAStartup failed\n");
return -1;
}
FD_ZERO(&master_set);
FD_ZERO(&readfds);
//----------------------
// Create a SOCKET for listening for
// incoming connection requests.
listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (listener == INVALID_SOCKET) {
OutputDebugStringA("socket failed with error:\n");
return -1;
}
int reuse_addr = 1;
setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, (char*)&reuse_addr, sizeof(reuse_addr));
//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port for the socket that is being bound.
sockaddr_in service = { 0 };
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr("127.0.0.1");
service.sin_port = htons(27015);
if (bind(listener, (SOCKADDR *)& service, sizeof(service)) == SOCKET_ERROR)
{
printf("bind failed with error: %d \n", WSAGetLastError());
closesocket(listener);
return -1;
}
if (listen(listener, 5) == SOCKET_ERROR)
{
OutputDebugStringA("listen failed with error\n");
closesocket(listener);
return -1;
}
u_long NonBlock = 1;
if (ioctlsocket(listener, FIONBIO, &NonBlock) == SOCKET_ERROR)
{
OutputDebugStringA("ioctlsocket() failed with error\n");
return -1;
}
FD_SET(listener, &master_set);
timeval timeout;
timeout.tv_sec = 3;
timeout.tv_usec = 0;
printf("Started Server on port %d\n", 27015);
for (;;)
{
readfds = master_set;
int ret = select(0, &readfds, NULL, NULL, &timeout);
if (ret == 0)
{
// Time out // Check if we need to shutdown
continue;
}
if (ret < 0)
{
printf("Error in Socket select\n");
return -1;
}
for (int i = 0; i < readfds.fd_count; i++)
{
SOCKET xfd = readfds.fd_array[i];
if (xfd == listener)
{
// New Connection.
SOCKET new_fd = HandleNewConnection(listener);
if (new_fd == -1)
{
printf("Error Accepting new connection");
continue;
}
FD_SET(new_fd, &master_set);
printf("Accepted new Connection\n");
continue;
}
else
{
if (!HandleIncomingData(xfd))
{
closesocket(xfd);
FD_CLR(xfd, &master_set);
continue;
}
}
}
}
SOCKET HandleNewConnection(SOCKET listener)
{
SOCKET newfd = accept(listener, (sockaddr*)NULL, (int*)NULL);
u_long NonBlock = 1;
ioctlsocket(newfd, FIONBIO, &NonBlock);
return newfd;
}
bool HandleIncomingData(SOCKET fd)
{
char buffer[16] = { 0 };
int recv_bytes = -1;
if ((recv_bytes = recv(fd, buffer, 16, 0)) <= 0)
{
printf("Connection Closed/ Error in Recieving");
return false;
}
printf("recieved %d bytes\n", recv_bytes);
return true;
}
The select continues to timeout every 3 seconds without any connection getting accepted.
Here's all that I have tried (none worked):
Tried to run the service in a specific user account.
The server is run in a separate thread, I provided a SECURITY_ATTRIBUTE with NULL DACL to see if it's a security problem.
Tried different ports.
Tried same server code in a separate normal application. The client can connect to this application.
Sample server application when launched from the agent, the client cannot connect to it.
Windows firewall is turned off and I don't have any anti virus software installed which would block such connections.
Checked connection from outside and observed in Wireshark that the TCP SYN packet does arrive but there's no response to it.
Observed in Process Explorer TCP/IP properties that the SNMP service does have a TCP socket listening on 127.0.0.1:27015.
For quick tests I am just doing telnet to port 27015.
Is there something obviously wrong with the server code which I am missing?
Is there some security restriction in Windows Server 2012 which don't allow a service to accept such TCP connections?
Any other hints, comments, inputs?
I solved the problem. The issue was due to Windows Service Hardening which did not allow any TCP communication from snmp service (and extensions). This is enforced even if the firewall is turned off.
https://support.microsoft.com/en-us/kb/2771908
I could solve it following these steps (found in http://www-01.ibm.com/support/docview.wss?uid=nas7ba16117761f1f93b86257f73000cff77)
Log on the system as Administrator and open Registry by issuing regedit in the command prompt.
Navigate to [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\RestrictedServices\Static\System].
Find the values which meet the following points:
a. “Name” string starts with “SNMP-”.
b. “Data” string contains “syswow64\snmp.exe”.
c. “Data” string contains “Action=Block”.
Change the “Action=Block” to “Action=Allow” of those entries.
Restart the “Windows Firewall” service by issuing net stop MPSSVC and net start MPSSVC .
Restart the “SNMP Service” service by using net stop SNMP and net start SNMP .