I'd like to authenticate on ssh-server via BSD socket. I know how to initiate a connection but don't know how to actually authenticate. Thanks for your time when pointing me to the right direction.
Here is the source code:
//
#include <stdio.h> // printf()
#include <sys/types.h> // socket data types
#include <sys/socket.h> // socket(), connect(), send(), recv()
#include <arpa/inet.h> // sockaddr_in, inet_addr()
#include <stdlib.h> // free()
#include <unistd.h> // close()
int *ssh(char *host, int port, char *user, char *pass);
int main(void)
{
// create socket
int *ssh_socket = ssh("127.0.0.1", 22, "root", "password");
// close and free
close(*ssh_socket);
free(ssh_socket);
return 0;
}
int *ssh(char *host, int port, char *user, char *pass)
{
int *sock = calloc(sizeof(int), 1);
struct sockaddr_in addr = {.sin_family=AF_INET, \
.sin_port=htons(port), \
.sin_addr.s_addr=inet_addr(host)};
*sock=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // create socket
connect(*sock, (struct sockaddr *)&addr, sizeof(addr)); // init connection
// here is the problem
// how do I authenticate on this socket?
return sock;
}
Use libssh for adding SSH functionality to your program.
SSH is a quite complex protocol with several layers.
Before getting to the user authentication you have to initiate the protocol, check remote host credentials and start an encrypted connection.
And after that, there are several ways to authenticate an user you may want to support (public key, passwd, keyboard-interactive, etc.).
The Wikipedia page for SSH has links to all the related RFCs.
Really, use libssh or libssh2 or the code from OpenSSH!
Related
I'm new to socket programming. I want to send a UDP package to a specific port on another PC in the network. When I analysie my network traffic with Wireshark I see a different port number in the outgoing packages from what I specified in my code.
With port=10000 the actual port it gets send to is 4135. When I changed it to port=15000 (just to try something different) it got send to port 38970.
The port numbers wireshark shows must be true, as a receiving program set to listen on these ports (4135 or 38970) does react to sent packages, although the received data seems like garble (the console shows unknown characters, the debug console shows "1\355I\211\321^H\211...").
Any ideas why?
I'm running this on a Debian VM connected to other VMs in a virtual network. A very similar program using TCP worked just fine.
#include <sys/types.h> //Various types, including ssize_t
#include <sys/socket.h> //Types, macros and functions for sockets
#include <netinet/in.h> //Types, including sockaddr_in, macros
#include <arpa/inet.h> //Types and functions, including inet_aton()
#include <unistd.h> //Types, macros and functions for Unix/Posix
#include <stdlib.h> //GP types, macros and functions
#include <stdio.h> //IO operations (streams)
#include <string.h> //Functions for string operations
#define BC_ADDR "192.168.1.255"
int main(int argc, char** argv) {
int clientSocket;
const int setBroadcast = 1;
in_port_t port = 10000;
struct sockaddr_in broadcastAddr;
int broadcastAddrLen = sizeof(struct sockaddr_in);
const char* msg = "Hello World";
//Create a new UDP socket
clientSocket = socket(AF_INET, SOCK_DGRAM, 0);
if(clientSocket > 0) {
printf("Socket created successfully\n");
}
else {
printf("Failure during socket creation\n");
exit(EXIT_FAILURE);
}
//Set socket options to allow broadcasts
int setSockOptStatus = setsockopt(clientSocket, SOL_SOCKET,
SO_BROADCAST, &setBroadcast, sizeof(setBroadcast));
if(setSockOptStatus != 0) {
printf("Error setting socket options!");
close(clientSocket);
return EXIT_FAILURE;
}
//Form boradcast address structure
broadcastAddr.sin_family = AF_INET;
broadcastAddr.sin_port = port;
broadcastAddr.sin_addr.s_addr = inet_addr(BC_ADDR);
//Send broadcast message
sendto(clientSocket, msg, strlen(msg)+1, 0,
(struct sockaddr*) &broadcastAddr, broadcastAddrLen);
//Close socket and exit program
close(clientSocket);
return EXIT_SUCCESS;
}
The problem is how you're setting the port:
broadcastAddr.sin_port = port;
The IP address and port number stored in a struct sockaddr_in must both be in network byte order which is big-endian byte ordering, i.e. most significant byte first. Your machine apparently uses little-endian byte ordering, i.e. least significant byte first, so by assigning the port number directly to the sin_port member that conversion is not being done.
This is more apparent if you look at the hexadecimal representation of the expected and actual port numbers:
10000d = 2710h, 4135d = 1027h
15000d = 3a98h, 38970 = 983ah
You need to call the htons() function, which converts a 16-bit value from host byte order to network byte order:
broadcastAddr.sin_port = htons(port);
I'm trying to port my desktop app written in C and C++ to webassembly platform and am investigating if it is possible at all. One of important things the app does is communicate by sending and receiving UDP messages. I have implemented minimal UDP client which just creates UDP socket and sends packets to server (which is build natively and is running as separate executable at the same machine). socket, bind and sendto APIs return no error and everything looks working but no messages are receiving on server side and wireshark shows no activity on that port.
Is UDP socket just stubbed at webassembly libc port, or it is implemented on top of some web standard connection (e.g. WebRTC)?
The client code is below. I checked that native build is working properly.
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFLEN 512
#define NPACK 100
#define PORT 9930
void diep(char *s)
{
perror(s);
exit(1);
}
#define SRV_IP "127.0.0.1"
int main(void)
{
struct sockaddr_in si_other;
int s, i, slen=sizeof(si_other);
char buf[BUFLEN];
if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
diep("socket");
memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
if (inet_aton(SRV_IP, &si_other.sin_addr)==0) {
fprintf(stderr, "inet_aton() failed\n");
exit(1);
}
for (i=0; i<NPACK; i++) {
printf("Sending packet %d\n", i);
sprintf(buf, "This is packet %d\n", i);
if (sendto(s, buf, BUFLEN, 0, (struct sockaddr*)&si_other, slen)==-1)
diep("sendto()");
}
close(s);
return 0;
}
I followed instructions from http://webassembly.org/getting-started/developers-guide/ to build and run it.
Thanks in advance for any help or clues!
I found how UDP sockets are implemented at webassembly. Actually, they are emulated by websockets. It probably would work if both client and server were webassemblies, but my server is built natively. As wasm doesn't support dynamic linking, all the code (including libc implementation) is bundled to one JS file, were we can find UDP sendto implementation:
// if we're emulating a connection-less dgram socket and don't have
// a cached connection, queue the buffer to send upon connect and
// lie, saying the data was sent now.
if (sock.type === 2) {
if (!dest || dest.socket.readyState !== dest.socket.OPEN) {
// if we're not connected, open a new connection
if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
dest = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
}
dest.dgram_send_queue.push(data);
return length;
}
}
Anything that runs in the browser will not give you native socket access and I suspect that browser vendors would strongly object to any such access as it is a potential security violation.
Perhaps as more and more native applications move to the web as the performance difference shrinks due to webassembly and similar initiatives would make them change their stance, but until then, anything that wants direct socket control would have to remain a native app.
Following code is TCP server program just send back “HELLO!!” to client.
When I run server with port 80, bind() is returned Permission denied.
Port 12345 is OK.
How can I use port 80 for this server program?
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int
main(){
int sock0;
struct sockaddr_in addr;
struct sockaddr_in client;
int len;
int sock;
char *message;
message = "HELLO !!";
sock0 = socket(AF_INET,SOCK_STREAM,0);
addr.sin_family = AF_INET;
addr.sin_port = htons(80);
inet_pton(AF_INET,"127.0.0.1",&addr,sizeof(addr));
bind(sock0,(struct sockaddr *)&addr,sizeof(addr));
perror("bind");
len = sizeof(client);
sock = accept(sock0,(struct sockaddr *)&client,&len);
perror("accept");
write(sock,message,sizeof(message));
perror("write");
close(sock);
return 0;
}
Ports below 1024 are considered "privileged" and can only be bound to with an equally privileged user (read: root).
Anything above and including 1024 is "free to use" by anyone.
OT: you may know this already, but the port in your example is that for HTTP web servers. Anything listening to this port should speak HTTP, too. A simple "hello world" does not suffice. ;-)
Only the root user is allowed to bind to ports <= 1024. Every ports > 1024 can be bound to by normal users.
Try executing your program as root or with sudo.
you have to run your application with super user account (root)
Run your application with sudo command
I'm working on a real time project on my Debian Wheezy (with real-time patch), it needs a strong reactivity using TCP communication protocol.
When I send a request, the response time is too long (220us) and I don't understand why.
My problem is when I send a request, my application server answers too late for my needs.
So, I decided to write a short program using TCP socket to acquire my server's response time. (see code below)
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
int main(int argc, char* argv[])
{
char sendBuffer [] = "OK";
char buffer [10];
int socket1;
int workingSocket;
socklen_t len;
int nodelay = 1;
struct sockaddr_in sa1;
struct sockaddr sa2;
socket1 = 0;
workingSocket = 0;
len = sizeof(sa1);
memset(&sa1, 0, len);
sa1.sin_addr.s_addr = htonl (INADDR_ANY);
sa1.sin_family = AF_INET;
sa1.sin_port = htons(12345);
socket1 = socket(AF_INET, SOCK_STREAM, 0);
bind(socket1, (struct sockaddr *)&sa1, len);
listen(socket1, 10);
workingSocket = accept(socket1, &sa2, &len);
setsockopt (workingSocket, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay));
// receive and send message back
while (1)
{
recv(workingSocket, buffer, 5, MSG_WAITALL);
send(workingSocket, sendBuffer, 2, 0);
}
}
I check the response time doing the following procedure :
start a wireshark session to trace the network traffic
launch my C server.
send a TCP request for example : $echo 'abcde'|netcat 192.168.0.1 12345
I got a response time of around 200 µs between the moment the string is sent (abcde) and the moment when I receive the reponse on the socket (OK)
This time seems to be very high. I made the same experience on VxWorks and got a response time aproaching 10µs.
Is the Linux kernel really slow or is there a trick to increase the reactivity of the system ?
Thank you for your help and your advices.
I'm not a software person, but I could really use some advice.
I'm writing a C program (cut/paste below) to establish a TCP socket connection from my Mac Pro to a Windows XP-based test-instrument sitting next to it over LAN (Ethernet). The program compiles without any warnings or errors. But executing the code using GNU Debugger, I can see it exits at 'exit(2)' which is the "if(connect(MySocket" line. There's no timeout, it just exits immediately.
I compile using:
gcc -g -Wall talk2me.c -o talk2me
but I don't get any hints in the output nor when debugging at to what might be the issue.
I'm sure the 10.0.1.100 and port 5025 are correct (using Matlab code I can communicate fine using these parameters). Any idea where else I could look to debug?
Outside of the code itself, are there any other requirements (perhaps system-level) that need to be satisfied (like running the code from a certain directory, or setting a parameter in unix to allow connections, etc.)? It may be something obvious that I'm missing because I'm a hardware guy, so feel free to assume I'm doing something stupid. I can run a 'hello world' program fine, it that helps. Thanks in advance, ggk
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/tcp.h>
#include <netinet/in.h>
#include <arpa/inet.h> //for inet_addr
#include <unistd.h> // for function 'close'
int main(void)
{
int MySocket;
if((MySocket=socket(PF_INET,SOCK_STREAM,0))==-1) exit(1);
struct in_addr {
unsigned long s_addr;
};
struct sockaddr_in {
short int sin_family; // Address family
unsigned short int sin_port; // Port number
struct in_addr sin_addr; // Internet address
unsigned char sin_zero[8]; // Padding
};
struct sockaddr_in MyAddress;
// Initialize the whole structure to zero
memset(&MyAddress,0,sizeof(struct sockaddr_in));
// Then set the individual fields
MyAddress.sin_family=PF_INET; // IPv4
MyAddress.sin_port=htons(5025); // Port number used by instrument
MyAddress.sin_addr.s_addr=inet_addr("10.0.1.100"); // IP Address
if(connect(MySocket,(struct sockaddr *) &MyAddress,
sizeof(struct sockaddr_in))==-1) exit(2);
// Send SCPI command
if(send(MySocket,"*IDN?\n",6,0)==-1) exit(3);
// Read response
char buffer[200];
int actual;
if((actual=recv(MySocket,&buffer[0],200,0))==-1) exit(4);
buffer[actual]=0; // Add zero character (C string)
printf("Instrument ID: %s\n",buffer);
// Close socket
if(close(MySocket)==-1) exit(99);
return 0;
}
You have defined struct in_addr and struct sockaddr_in yourself at the top of main. Do not do that, these are types found in header files(netinet/in.h), you have to use those, not your own versions.
Try connection with telnet from your mac box to 10.0.1.100 port 5025 , does that work ?
replace that exit(2); with {perror("connect"); exit(2); } to get a description of what is wrong.