-1

I am implementing FTP server,Here making winscp as a client.whenever client sends PASV command to me(server), i am giving reply with ip address and port to client,then client is sending LIST command, then i giving response to client as

150 Opening ASCII mode data connection for file list
-rwxrwxr-x 1 elmpc-162 elmpc-162 17608 Sep 16 12:13 a.out
226 File transfer completed...

These response i am send in second port.

like this but winscp is always showing "8failed to retrieve directory listings**"

but if i see in logs of winscp the data what ever i am sending to client is not present

you can see logs....

. 2020-09-17 16:02:54.408 Username prompt (no username provided)
. 2020-09-17 16:03:00.663 Connecting to 192.168.5.37:5005 ...
. 2020-09-17 16:03:00.663 Connected with 192.168.5.37:5005. Waiting for welcome message...
< 2020-09-17 16:03:00.663 220 Welcome to Alan's FTP site
> 2020-09-17 16:03:00.663 USER srihari
< 2020-09-17 16:03:00.663 331 Password required 
> 2020-09-17 16:03:04.064 PASS *****
< 2020-09-17 16:03:04.064 230 Public login sucessful 
> 2020-09-17 16:03:04.064 SYST
< 2020-09-17 16:03:04.064 215 AmigaOS 
> 2020-09-17 16:03:04.064 FEAT
< 2020-09-17 16:03:04.064 202 Command not implemented, superfluous at this site. 
. 2020-09-17 16:03:04.079 Connected
. 2020-09-17 16:03:04.079 --------------------------------------------------------------------------
. 2020-09-17 16:03:04.079 Using FTP protocol.
. 2020-09-17 16:03:04.079 Doing startup conversation with host.
> 2020-09-17 16:03:04.095 PWD
< 2020-09-17 16:03:04.095 257 "/home/elmpc-162/ftp_server" 
. 2020-09-17 16:03:04.095 Getting current directory name.
. 2020-09-17 16:03:04.142 Retrieving directory listing...
> 2020-09-17 16:03:04.142 TYPE A
< 2020-09-17 16:03:04.142 200 Switching to ASCII mode. 
> 2020-09-17 16:03:04.142 PASV
< 2020-09-17 16:03:04.142 227 Entering Passive Mode (192,168,5,37,23,112) 
> 2020-09-17 16:03:04.142 LIST -a
. 2020-09-17 16:03:04.142 Connecting to 192.168.5.37:6000 ...
. 2020-09-17 16:03:19.757 Timeout detected. (data connection)

But in server it is showing client is connected.

here i am not able to find out,why response for LIST is not going

Can any one help me

Here is my code

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> //Header file for sleep(). man 3 sleep for details. 
#include <pthread.h> 
#include <stdio.h> 
#include <netdb.h> 
#include <netinet/in.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <sys/types.h> 
#define MAX 80 
#define PORT1 5013
#define PORT2 6004
#define SA struct sockaddr 
#define SA struct sockaddr 

char read_buffer[200],write_buffer[200];
char check=0;
void call_second(void);
// A normal C function that is executed as a thread 
// when its name is specified in pthread_create() 
void *first_thread(void *vargp) 
{ 
    printf("in first thread.....\n");
    int sockfd, connfd, len; 
    struct sockaddr_in servaddr, cli; 

    // socket create and verification 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    if (sockfd == -1) { 
        printf("socket creation failed...\n"); 
        exit(0); 
    } 
    else
        printf("Socket successfully created..\n"); 
    bzero(&servaddr, sizeof(servaddr)); 

    // assign IP, PORT 
    servaddr.sin_family = AF_INET; 
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
    servaddr.sin_port = htons(PORT1); 

    // Binding newly created socket to given IP and verification 
    if ((bind(sockfd, (SA*)&servaddr, sizeof(servaddr))) != 0) { 
        printf("socket bind failed...\n"); 
        exit(0); 
    } 
    else
        printf("Socket successfully binded..\n"); 

    // Now server is ready to listen and verification 
    if ((listen(sockfd, 5)) != 0) { 
        printf("Listen failed...\n"); 
        exit(0); 
    } 
    else
        printf("Server listening..\n"); 
    len = sizeof(cli); 

    // Accept the data packet from client and verification 
    connfd = accept(sockfd, (SA*)&cli, &len); 
    if (connfd < 0) { 
        printf("server acccept failed...\n"); 
        exit(0); 
    } 
    else
        printf("server acccept the client...\n"); 

    //bzero(buffer, 0); 
        // sprintf(buffer,"\n220 Welcome to Alan's FTP site \r\n\n");
        
        //for (;;) 
        //write(sockfd, "welcome", sizeof("welcome")); 
    // Function for chatting between client and server 
    //printf("after writing into sockbuffer ...\n");
    //func(connfd); 

    int n,bytes; 
    // infinite loop for chat 
    for (;;) 
    { 
        
        //bzero(buff, MAX); 
        memset(read_buffer,0,200);
        memset(write_buffer,0,200);
        sprintf(write_buffer,"\n220 Welcome to Alan's FTP site\r\n\n");
         write(connfd, write_buffer, sizeof(write_buffer)); 
        printf("come inside..\n");
        // read the message from client and copy it in buffer 
        while(1)
        {
        //sleep(1);
        memset(read_buffer,0,200);
        memset(write_buffer,0,200);
        //printf("before reading....\n");
        bytes=read(connfd, read_buffer, sizeof(read_buffer)); 
        //printf("checking blocking or not..  %s\n",read_buffer);
        if(bytes>0)
        {
        printf("From client:%s%d\n", read_buffer,bytes);
        } 
        // if(strstr(buff,"AUTH TLS")||strstr(buff,"AUTH SSL"))
        // {
        //  sprintf(buffer,"\n502 Command not implemented\r\n\n");
        //  write(sockfd, buffer, sizeof(buffer)); 
        // }
        if (strstr(read_buffer,"USER"))
            {
                printf("Logging in \n");
                sprintf(write_buffer,"331 Password required \r\n");
                bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
                if (bytes < 0) break;
            }
        if (strncmp(read_buffer,"PASS",4)==0)
            {
                printf("Typing password (anything will do... \n");
                sprintf(write_buffer,"230 Public login sucessful \r\n");
                bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
                if (bytes < 0) break;
            }
        if (strncmp(read_buffer,"SYST",4)==0)
            {
                printf("215 AmigaOS \n");
                //sprintf(write_buffer,"215 AmigaOS \r\n");
                sprintf(write_buffer,"215 UNIX emulated by FileZilla \r\n");
                bytes = write(connfd, write_buffer, sizeof(write_buffer));
                memset(write_buffer,0,sizeof(write_buffer));
                
            }
        if (strncmp(read_buffer,"CLNT",4)==0)
            {
                printf("200 Don't care \n");
                sprintf(write_buffer,"200 Don't care \r\n");
                bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
                if (bytes < 0) break;
            }
        if (strncmp(read_buffer,"OPTS UTF8 ON",4)==0)
            {
                printf("202 UTF8 mode is always enabled. No need to send this command. \n");
                sprintf(write_buffer,"202 UTF8 mode is always enabled. No need to send this command. \r\n");
                bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
                if (bytes < 0) break;
            }
        if (strncmp(read_buffer,"FEAT",4)==0)
            {
               printf("211-Features:  \n");
                sprintf(write_buffer,"211-Features: \r\n");
                bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
                sprintf(write_buffer,"MDTM \r\n");
                bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
                memset(write_buffer,0,sizeof(write_buffer));
                sprintf(write_buffer,"REST STREAM \r\n");
                bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
                memset(write_buffer,0,sizeof(write_buffer));
                sprintf(write_buffer,"MLST type*;size*;modify*; \r\n");
                bytes = write(connfd, write_buffer, sizeof(write_buffer));  
                // memset(write_buffer,0,sizeof(write_buffer));
                // sprintf(write_buffer,"MLSD \r\n");
                // bytes = write(connfd, write_buffer, sizeof(write_buffer));   
                memset(write_buffer,0,sizeof(write_buffer));
                sprintf(write_buffer,"UTF8 \r\n");
                bytes = write(connfd, write_buffer, sizeof(write_buffer));  
                memset(write_buffer,0,sizeof(write_buffer));
                sprintf(write_buffer,"CLNT \r\n");
                bytes = write(connfd, write_buffer, sizeof(write_buffer));  
                memset(write_buffer,0,sizeof(write_buffer));
                sprintf(write_buffer,"MFMT \r\n");
                bytes = write(connfd, write_buffer, sizeof(write_buffer));  
                memset(write_buffer,0,sizeof(write_buffer));
                sprintf(write_buffer,"CLNT \r\n");
                bytes = write(connfd, write_buffer, sizeof(write_buffer));  
                memset(write_buffer,0,sizeof(write_buffer));
                sprintf(write_buffer,"EPSV \r\n");
                bytes = write(connfd, write_buffer, sizeof(write_buffer));  
                memset(write_buffer,0,sizeof(write_buffer));
                sprintf(write_buffer,"EPRT \r\n");
                bytes = write(connfd, write_buffer, sizeof(write_buffer));  
                memset(write_buffer,0,sizeof(write_buffer));
                sprintf(write_buffer,"211 End \r\n");
                bytes = write(connfd, write_buffer, sizeof(write_buffer));  
                memset(write_buffer,0,sizeof(write_buffer));
                printf("211 end:  \n");
               
            }
        if (strncmp(read_buffer,"PWD",3)==0)
            {
                printf("present working directory \n");
                //  FILE *fpipe;
                 char pwd[100],i=5;
                // char *command = "pwd";
                // char c = 0;

                // if (0 == (fpipe = (FILE*)popen(command, "r")))
                // {
                //  perror("popen() failed.");
                //  exit(EXIT_FAILURE);
                // }
                // strcat(pwd,"257 \"");
                // printf("%s\n",pwd);
                // while (fread(&c, sizeof c, 1, fpipe))
                // {
                //  //printf("%c", c);
                //  pwd[i++]=c;

                // }
                // strcat(pwd,"\" \r\n");
                memset(pwd,0,sizeof(pwd));
                // strcat(pwd,"257 \"/\"\r\n");
                strcat(pwd,"257 \"/home/elmpc-162/ftp_server\" ");
                printf("%s\n",pwd);

                //pclose(fpipe);
                // sprintf(write_buffer,"202 Command not implemented, superfluous at this site. \r\n");
                bytes = write(connfd, pwd, sizeof(pwd)); 
                if (bytes < 0) break;
            }
        if (strstr(read_buffer,"TYPE I"))
            {
                printf(" 200 Switching to Binary mode.\n");
                sprintf(write_buffer,"200 Switching to Binary mode. \r\n");
                bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
                if (bytes < 0) break;
            }
        if (strstr(read_buffer,"TYPE A"))
            {
                printf(" 200 Switching to ASCII mode.\n");
                sprintf(write_buffer,"200 Switching to ASCII mode. \r\n");
                bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
                if (bytes < 0) break;
            }
        if (strstr(read_buffer,"AUTH TLS"))
            {
                printf(" asking AUTHTLS\n");
                sprintf(write_buffer,"502 Explicit TLS authentication not allowed \r\n");
                bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
                if (bytes < 0) break;
            }
        if (strstr(read_buffer,"AUTH SSL"))
            {
                printf(" asking AUTHTLS\n");
                sprintf(write_buffer,"502 Explicit TLS authentication not allowed \r\n");
                bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
                if (bytes < 0) break;
            }
        if (strstr(read_buffer,"CDUP"))
            {
                printf(" got CDUP command \n");
                sprintf(write_buffer,"457 \"/home\" \r\n");
                bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
                if (bytes < 0) break;
            }
        if (strstr(read_buffer,"CWD"))
            {
                printf(" got CWD command \n");
                sprintf(write_buffer,"457 \"/home/elmpc-162/ftp_server\" \r\n");
                bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
                if (bytes < 0) break;
            }
        if (strncmp(read_buffer,"PASV",4)==0)
            {int a,b;
                //close(sockfd);
                a=PORT2/256;
                b=PORT2%256;
                printf("Entering into passvie mode \n");
                sprintf(write_buffer,"227 Entering Passive Mode (192,168,5,37,%d,%d) \r\n",a,b);
                bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
                if (bytes < 0) break; 
                // check =1;
                   //exit(0);             
            }
        if (strstr(read_buffer,"LIST")||strstr(read_buffer,"MLSD"))
            {
sprintf(write_buffer,"150 Transfering... \r\n");
                //printf("%s\n",write_buffer);
                bytes = write(connfd, write_buffer, sizeof(write_buffer)); 
                if (bytes < 0) break;


                memset(write_buffer,0,sizeof(write_buffer));
                //strcat(pwd,"-rwxrwxr-x 1 elmpc-162 elmpc-162 17608 Sep 16 12:13 a.out \r\n");
                // sprintf(write_buffer,"type=file;modify=20200902093315;size=302; a.cfg \r\n");
                // sprintf(write_buffer,"a.out \r\n");
                // sprintf(write_buffer,"%s",pwd);
                // write(connfd, write_buffer, sizeof(write_buffer)); 
                call_second();

                memset(write_buffer,0,sizeof(write_buffer));
                sprintf(write_buffer,"226 File transfer completed... \r\n");
                //printf("%s\n",write_buffer);
                write(connfd, write_buffer, sizeof(write_buffer)); 
                 printf("wrote==%d\n",n);
                memset(write_buffer,0,sizeof(write_buffer));


                check =1;
            }

        // // print buffer which contains the client contents 
        
        }
        
        n = 0; 
        
    
    }

    return NULL; 
} 
void *second_thread(void *vargp) 
{ 
    while(1)
    {
        //printf("dfjhdkfhdf\n");
        // if(check==1)
        // call_second();
    }
}
void call_second(void)
{
    int sockfd_c, connfd_c, len_c; 
    struct sockaddr_in servaddr_c, cli_c; 

    // socket create and verification 
    sockfd_c = socket(AF_INET, SOCK_STREAM, 0); 
    if (sockfd_c == -1) { 
        printf("socket creation failed...2\n"); 
        exit(0); 
    } 
    else
        printf("Socket successfully created..2\n"); 
    bzero(&servaddr_c, sizeof(servaddr_c)); 

    // assign IP, PORT 
    servaddr_c.sin_family = AF_INET; 
    servaddr_c.sin_addr.s_addr = htonl(INADDR_ANY); 
    servaddr_c.sin_port = htons(PORT2); 

    // if (connect(sockfd_c, (SA*)&servaddr_c, sizeof(servaddr_c)) != 0) { 
    //  printf("connection with the server failed...\n"); 
    //  exit(0); 
    // } 
    // else
    //  printf("connected to the server..\n"); 

    // Binding newly created socket to given IP and verification 
    if ((bind(sockfd_c, (SA*)&servaddr_c, sizeof(servaddr_c))) != 0) { 
        printf("socket bind failed...2\n"); 
        exit(0); 
    } 
    else
        printf("Socket successfully binded..2\n"); 

    // Now server is ready to listen and verification 
    if ((listen(sockfd_c, 5)) != 0) { 
        printf("Listen failed...2\n"); 
        exit(0); 
    } 
    else
        printf("Server listening..2\n"); 
    len_c = sizeof(cli_c); 

    // Accept the data packet from client and verification 
    connfd_c = accept(sockfd_c, (SA*)&cli_c, &len_c); 
    if (connfd_c < 0) { 
        printf("server acccept failed...2\n"); 
        exit(0); 
    } 
    else
        printf("server acccept the client...2\n"); 

    
    char buff[MAX]; 
    int n; 
    // infinite loop for chat 
    //while(1)
    {
     if(check==1)
    {
    
                
                check =1;

                FILE *fpipe;
                int k=0;
                 char pwd[1500];int i=0;

                char *command = "ls -l";
                char c = 0;
                memset(pwd,0,sizeof(pwd));
                 
                
                if (0 == (fpipe = (FILE*)popen(command, "r")))
                {
                    perror("popen() failed.");
                    exit(EXIT_FAILURE);
                }
                
                while (fread(&c, sizeof c, 1, fpipe))
                {
                    //printf("%c", c);
                    k++;
                    if(k>9)
                    pwd[i++]=c;

                }
                // printf("pwd==%s\n",pwd);
                k=0;

                                
                memset(write_buffer,0,sizeof(write_buffer));
                // strcat(pwd,"-rwxrwxr-x 1 elmpc-162 elmpc-162 17608 Sep 16 12:13 a.out1 \r\n");
                // strcat(pwd,"-rwxrwxr-x 1 elmpc-162 elmpc-162 17608 Sep 16 12:14 a.out2 \r\n");
                // strcat(pwd,"-rwxrwxr-x 1 elmpc-162 elmpc-162 17608 Sep 16 12:15 a.out3 \r\n");
                sprintf(write_buffer,"%s",pwd);
                write(connfd_c, write_buffer, sizeof(write_buffer)); 
                
                sleep(3);
                
     check=0; 
 
    }
    }
    // After chatting close the socket 
    close(sockfd_c);
    printf("closed second connection...\n"); 
}
    


int main() 
{ 
    pthread_t thread_id1,thread_id2; 
    printf("Before Thread\n"); 
    pthread_create(&thread_id1, NULL, first_thread, (void *)&thread_id1); 
    //pthread_join(thread_id1, NULL); 
    pthread_create(&thread_id2, NULL, second_thread, (void *)&thread_id2); 
    //pthread_join(thread_id2, NULL);
    printf("After Thread\n"); 
    pthread_exit(NULL); 
    //exit(0); 
}
Srihari
  • 3
  • 3

2 Answers2

0
. 2020-09-17 16:03:04.142 Connecting to 192.168.5.37:6000 ...
. 2020-09-17 16:03:19.757 Timeout detected. (data connection)

The client is unable to establish a data connection to the server. Given that the error is a Timeout and not a Connection refused I suspect that there is a firewall between client and server (or on the server) which is blocking the access (dropping the traffic). But, since there is nothing reproducible in your question (like code and server setup) this is only an educated guess.

Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • Here everything i am implementing locally, my server and client both are in local network. one more thing is starting control connection happened and exchanged commands also. – Srihari Sep 18 '20 at 02:47
  • 1
    @Srihari: local network does not exclude firewalls on the machine itself. And again - without any more details (code, server setup) one can only guess what is happening. – Steffen Ullrich Sep 18 '20 at 04:18
  • 1
    @Srihari: The server is not supposed to just send a reply to PASV on the control connection but to a actually listen on the given IP and port and expect a connection to the client (data connection). I'm irritated that you never mention this part so it might be that you simply don't implement it. And again - still no code. – Steffen Ullrich Sep 18 '20 at 05:55
0

Most FTP servers have a setting called IP masquerade that has to be configured to the public IP address if the FTP sever is sitting behind NAT.

this response "227 Entering Passive Mode (192,168,5,37,23,112) " should be sending the public IP address and the port forwarding on the server side has to be configured to establish the connection