LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Simple sockets program question (https://www.linuxquestions.org/questions/programming-9/simple-sockets-program-question-647863/)

default5 06-08-2008 03:58 PM

Simple sockets program question
 
Hello,

I am a relatively new c programmer and I have just started looking at unix sockets. To test out what I learned, I decided to write a program that forwarded data through to sshd on port 22. Here it is. (I know I didn't do all the error-checking ;)
Code:

/* Simple Tunnel
 *
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>

#define MYPORT 4545
#define BACKLOG 10
 
int main(int argc, char *argv[])
{
        int listenerfd, connectionfd, localfd;
        struct sockaddr_in myaddr, localaddr, theiraddr;
        char msg[256];
        int charsread;
        int port;
        int sin_size;
       
        if(argc > 2)
        {
                printf("Usage: ./stunnel[port]\n");
                return 1;
        }
        else if(argc == 2)
                port = atoi(argv[1]);
        else
                port = MYPORT;
       
        /*Create connection to remote host*/
        if((listenerfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
        {
                perror("socket");
                return 1;
        }
       
        myaddr.sin_family = AF_INET;
        myaddr.sin_port = htons(port);
        myaddr.sin_addr.s_addr = INADDR_ANY;
        memset(myaddr.sin_zero, '\0', sizeof myaddr.sin_zero);
       
        bind(listenerfd, (struct sockaddr *)&myaddr, sizeof myaddr);
       
        listen(listenerfd, BACKLOG);
       
        sin_size = sizeof theiraddr;
        connectionfd = accept(listenerfd, (struct sockaddr *)&theiraddr, &sin_size);
       
        close(listenerfd);
       
        /*Create connection to local service*/
        if((localfd = socket(PF_INET, SOCK_STREAM, 0)) == -1)
        {
                perror("socket2");
                return 1;
        }
       
        localaddr.sin_family = AF_INET;
        localaddr.sin_port = htons(22);
        localaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
        memset(myaddr.sin_zero, '\0', sizeof myaddr.sin_zero);
       
        if(connect(localfd, (struct sockaddr *)&localaddr, sizeof localaddr) == -1)
        {
                perror("connect");
                return 1;
        }
       
        /*Main Loop*/
        while(charsread != 0)
        {
                charsread = recv(connectionfd, msg, 256, 0);
                if(charsread == 0)
                        break;
                send(localfd, msg, charsread, 0);
                charsread = recv(localfd, msg, 256, 0);
                send(connectionfd, msg, charsread, 0);
        }
       

        printf("Connection closed\n");
       
        close(localfd);
       
        return 0;
}

I start it like "./stunnel 4545" in one window. When I run "telnet 127.0.0.1 4545" in another window I get
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
(I press enter)
SSH-2.0-OpenSSH_4.7
(I press enter)
Protocol mismatch.
(I press enter)
Connection closed by foreign host.

When I run "ssh -p4545 127.0.0.1" I get
ssh: connect to host 127.0.0.1 port 4545: Connection refused

Why does telnet open a connection and ssh doesn't?

pinniped 06-09-2008 01:24 AM

To communicate with SSH you need to use something like the OpenSSL library (plus you need to adhere to the SSH specification). There are numerous negotiations which go on, such as: are you required to prove who you are, what SSL/TLS version you agree to use, what encryption to use on connection, etc. One option you have is to create an SSH 'tunnel' which will allow you to send unencrypted data to a specific port, and the data will magically be relayed via ssh. There are numerous instructions on how to do this on the internet.

irishbitte 06-09-2008 01:32 AM

If I may suggeat that you look at the possibilities to wrap your code in code tags, that will make it easier to read your code! Don't forget to comment your code, to explain what you are doing...

My :twocents:, ;)

default5 06-09-2008 12:41 PM

Sorry about the confusion what my program (stunnel) does (hopefully) is forward all the traffic coming in on port 4545 (or whatever you give it at the command line) to another port and reroute that ports replies back through port 4545 to the remote host (see poorly draw diagram below). To test this I used port 22 because I have sshd running on port 22. However, I obviuosly didn't do something right because sshing to port 4545 didn't work. I showed the output of sshing and telneting to port 4545 above. I hope this clarifies it a little.

Code:

.........................................................
|--------| stunnel:4545 --------> telnet or ssh|-------|.
|........|...........|.........................|remote.|.
|.Server.|...........|.........................|.host..|.
|........|...........|.........................|.......|.
|--------| sshd:22 <--.........................|-------|.
.........................................................


pinniped 06-10-2008 07:14 AM

Ah, OK, I misunderstood your original post.

There are a number of fundamental flaws in your logic for bridging the data.
Try turning your sockets into nonblocking types. You must also check the return values all the time to ensure that you only attempt to relay data when there is data to send. With any luck that should work (even though it will be rather inefficient).

To make a file descriptor non-blocking you need code that's something like this:

#include <unistd.h>
#include <fcntl.h>

int flags = fcntl(my_socket_fd, F_GETFL);
fcntl(my_socket_fd, F_SETFL, flags|O_NONBLOCK);

Of course you need to check the return value of 'fcntl' for validity.

irishbitte 06-10-2008 09:13 AM

Another interesting thing is that telnet will work on any specified port, but sshd on the receiving machine, in this case the remote host, will only accept data on port 22, as per the RFC governing ssh. Anything else is viewed as hostile!

Hko 06-10-2008 10:32 AM

Quote:

Originally Posted by irishbitte (Post 3180419)
Another interesting thing is that telnet will work on any specified port, but sshd on the receiving machine, in this case the remote host, will only accept data on port 22, as per the RFC governing ssh. Anything else is viewed as hostile!

Are you sure?
I am sure I have connected to ssh-server listening on other ports than 22. Some people even recommend running sshd listening on different port than to keep the brute force ssh-ringers from trying you box.

And I could not find anything about that in the man pages of sshd_config, ssh and sshd...

I did not read the RFC though, the actual implementation I deal with in practice matters more to me in this sort of cases.

default5 06-10-2008 04:45 PM

Quote:

Originally Posted by irishbitte (Post 3180419)
Another interesting thing is that telnet will work on any specified port, but sshd on the receiving machine, in this case the remote host, will only accept data on port 22, as per the RFC governing ssh. Anything else is viewed as hostile!

Do you mean the client connection must originate from port 22, or sshd must be listening on port 22? Also, thank you pinniped for pointing out my error, I forgot about blocking.

chrism01 06-10-2008 05:54 PM

You can bind any server to any port. The list of 'approved' ports in /etc/services is just the expected arrangement.
Of course, most systems go with the default because it makes life simpler.
As for ssh, you can only (sensibly) connect to it if you have a client that can understand the ssh protocol.
You can only use telnet to debug servers that are plain text based eg smtp, http; not ssh, https.

default5 06-10-2008 09:10 PM

Quote:

Originally Posted by chrism01 (Post 3180834)
You can only use telnet to debug servers that are plain text based eg smtp, http; not ssh, https.

Yes,I understand this. I simply used telnet to see if my program was passing any information at all since ssh only said it couldn't connect.

pinniped 06-11-2008 08:15 AM

Have you tried making your sockets non-blocking and see if your program worked then?


All times are GMT -5. The time now is 12:23 AM.