C中的套接字FTP:身份验证获得530"请用户登录并通过"匿名

时间:2014-10-27 16:31:36

标签: c sockets ftp

我正在尝试连接到服务器以下载POS(销售点)应用程序。现在,我正在尝试在PC上工作以适应POS。 (POS没有FTP API,只有套接字)

尝试连接ftp://ftp.inf.puc-rio.br/(139.82.16.194)。我也尝试了ftp.dca.fee.unicamp.br,结果相同。

我正在使用 sys / socket.h 。我明白了:

  

220 Bem Vindo ao Servidor做DI / PUC-Rio。

     

USER anonymous

     

回复:331请指定密码。

     

PASS 123

     

回复:530请用USER和PASS登录

我尝试了另一个像电子邮件,客人但没有成功的密码。 在 Filezilla 中,我使用相同的值(IP,用户,密码123和端口21),我得到了这个:

  

USER anonymous

     

回复:331请指定密码。

     

Comando:通过***

     

回复:230登录成功。

试图理解服务器不接受PASS命令的原因。

这是我的代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <errno.h>

#define SERVER_PORT_ID 21
#define CLIENT_PORT_ID 8015
#define SERVER_HOST_ADDR "139.82.16.194"
/* ftp.dca.fee.unicamp.br */
//ftp://ftp.inf.puc-rio.br/
#define MAXSIZE 256    

main(int argc,char *argv[]){           

    int sockid, newsockid,i,getfile,ack,msg,msg_2,c,len;
    int no_writen,start_xfer, num_blks,num_last_blk;
    struct sockaddr_in my_addr, server_addr;
    FILE *fp;
    char in_buf[MAXSIZE], buffer[MAXSIZE];       


    if ((sockid = socket(AF_INET,SOCK_STREAM,0)) < 0)
    {
        printf("client: socket error : %d\n", errno); exit(0);

    }

    printf("client: binding my local socket\n");
    bzero((char *) &my_addr,sizeof(my_addr));
    my_addr.sin_family = AF_INET;
    my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    my_addr.sin_port = htons(CLIENT_PORT_ID);
    if (bind(sockid ,(struct sockaddr *) &my_addr,sizeof(my_addr)) < 0)
    {
        printf("client: bind error :%d\n", errno); exit(0);

    }

    setsockopt(sockid,SOL_SOCKET, SO_KEEPALIVE, 0, MAXSIZE);

    //Try to connect
    printf("client: starting connect\n");
    bzero((char *) &server_addr,sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(SERVER_HOST_ADDR);
    server_addr.sin_port = htons(SERVER_PORT_ID);
    if (connect(sockid ,(struct sockaddr *) &server_addr,
    sizeof(server_addr)) < 0)
    {
        printf("client: connect error :%d\n", errno); exit(0);

    }

//Print the Welcome message
    do{
        memset((void*) buffer,0,MAXSIZE);
        if(read(sockid,buffer,MAXSIZE) < 0) 
        {
            printf("client: read error :%d\n", errno); exit(0);
        }       
        printf("%s \n", buffer);
    }while(strstr(buffer,"220 ") == NULL);

    printf("Mensagem Welcome recebida\n");

//Try to connect

    stpcpy(buffer,"USER anonymous\r\n");
    printf("%s", buffer);
    if(write(sockid,buffer,sizeof(buffer))< 0){
        printf("client: write error :%d\n", errno); exit(0);
    }
    if(read(sockid,buffer,MAXSIZE) < 0)   
    {
        printf("client: read error :%d\n", errno); exit(0);
    }
    printf("%s", buffer);

    memset((void*) buffer,0,MAXSIZE);
    stpcpy(buffer,"PASS 123\r\n");  
    printf("%s", buffer);
    if(write(sockid,buffer,sizeof(buffer))< 0){
        printf("client: write error :%d\n", errno); exit(0);
    }
    memset((void*) buffer,0,MAXSIZE);
    if(read(sockid,buffer,MAXSIZE) < 0) 
    {
        printf("client: read error :%d\n", errno); exit(0);
    }
    printf("%s \n", buffer);

    exit(0);
}

代码没有下载任何内容。我正试图改善第一个问题。一些包含和变量未被使用,因为属于FTP应用程序的例子,其他代码可供下载。

FTP Authentication

谢谢大家!

1 个答案:

答案 0 :(得分:2)

代码最核心的问题是write()的长度来自sizeof。如果您将其更改为strlen()的呼叫,则匿名登录会起作用。使用sizeof作为长度会向服务器发送256个字节。

至少我用(vsftpd)试过这个ftp服务器,不喜欢密码。我没有检查RFC以查看它是否是长度或使其发生冲突的零。对于开发,您可能还想在本地安装一些ftpd软件。我认为对你自己运行的服务器进行试验可能更为谨慎。

NIT:我不知道您正在编译该代码的系统,但在Linux / Posix系统上,它需要更多的包含。我添加了

#include <string.h> 
#include <stdlib.h>
#include <unistd.h>

我建议你使用clang编译器编译或使用标志 -Wall -Werror -Wextra 来gcc。

我还建议使用strerror()或类似内容,而不是仅在打印错误时打印错误。