Browse Source

Merge branch 'Fix-Passive-Mode'

pull/26/head
Philipp Tölke 5 years ago
parent
commit
8032def548
  1. 75
      ftpd.c

75
ftpd.c

@ -187,7 +187,7 @@ static const char *month_table[12] = {
"Sep",
"Oct",
"Nov",
"Dez"
"Dec"
};
/*
@ -343,6 +343,7 @@ struct ftpd_msgstate {
vfs_t *vfs;
struct ip4_addr dataip;
u16_t dataport;
struct tcp_pcb *datalistenpcb;
struct tcp_pcb *datapcb;
struct ftpd_datastate *datafs;
int passive;
@ -368,6 +369,14 @@ static void ftpd_dataclose(struct tcp_pcb *pcb, struct ftpd_datastate *fsd)
tcp_arg(pcb, NULL);
tcp_sent(pcb, NULL);
tcp_recv(pcb, NULL);
if (fsd->msgfs->datalistenpcb) {
tcp_arg(fsd->msgfs->datalistenpcb, NULL);
tcp_accept(fsd->msgfs->datalistenpcb, NULL);
tcp_close(fsd->msgfs->datalistenpcb);
fsd->msgfs->datalistenpcb = NULL;
}
fsd->msgfs->datafs = NULL;
sfifo_close(&fsd->fifo);
free(fsd);
@ -664,15 +673,29 @@ static int open_dataconnection(struct tcp_pcb *pcb, struct ftpd_msgstate *fsm)
fsm->datafs = malloc(sizeof(struct ftpd_datastate));
if (fsm->datafs == NULL) {
dbg_printf("open_dataconnection: Out of memory\n");
send_msg(pcb, fsm, msg451);
return 1;
}
memset(fsm->datafs, 0, sizeof(struct ftpd_datastate));
fsm->datafs->msgfs = fsm;
fsm->datafs->msgpcb = pcb;
sfifo_init(&fsm->datafs->fifo, 2000);
if (sfifo_init(&fsm->datafs->fifo, 2000) != 0) {
free(fsm->datafs);
send_msg(pcb, fsm, msg451);
return 1;
}
fsm->datapcb = tcp_new();
if (fsm->datapcb == NULL) {
sfifo_close(&fsm->datafs->fifo);
free(fsm->datafs);
send_msg(pcb, fsm, msg451);
return 1;
}
/* Tell TCP that this is the structure we wish to be passed for our
callbacks. */
tcp_arg(fsm->datapcb, fsm->datafs);
@ -865,19 +888,26 @@ static void cmd_pasv(const char *arg, struct tcp_pcb *pcb, struct ftpd_msgstate
fsm->datafs = malloc(sizeof(struct ftpd_datastate));
if (fsm->datafs == NULL) {
dbg_printf("cmd_pasv: Out of memory\n");
send_msg(pcb, fsm, msg451);
return;
}
memset(fsm->datafs, 0, sizeof(struct ftpd_datastate));
fsm->datapcb = tcp_new();
if (!fsm->datapcb) {
if (sfifo_init(&fsm->datafs->fifo, 2000) != 0) {
free(fsm->datafs);
send_msg(pcb, fsm, msg451);
return;
}
sfifo_init(&fsm->datafs->fifo, 2000);
fsm->datalistenpcb = tcp_new();
if (fsm->datalistenpcb == NULL) {
free(fsm->datafs);
sfifo_close(&fsm->datafs->fifo);
send_msg(pcb, fsm, msg451);
return;
}
start_port = port;
@ -888,7 +918,7 @@ static void cmd_pasv(const char *arg, struct tcp_pcb *pcb, struct ftpd_msgstate
port = 4096;
fsm->dataport = port;
err = tcp_bind(fsm->datapcb, (ip_addr_t*)&pcb->local_ip, fsm->dataport);
err = tcp_bind(fsm->datalistenpcb, (ip_addr_t*)&pcb->local_ip, fsm->dataport);
if (err == ERR_OK)
break;
if (start_port == port)
@ -896,33 +926,32 @@ static void cmd_pasv(const char *arg, struct tcp_pcb *pcb, struct ftpd_msgstate
if (err == ERR_USE) {
continue;
} else {
ftpd_dataclose(fsm->datapcb, fsm->datafs);
fsm->datapcb = NULL;
ftpd_dataclose(fsm->datalistenpcb, fsm->datafs);
fsm->datalistenpcb = NULL;
fsm->datafs = NULL;
return;
}
}
fsm->datafs->msgfs = fsm;
temppcb = tcp_listen(fsm->datapcb);
temppcb = tcp_listen(fsm->datalistenpcb);
if (!temppcb) {
ftpd_dataclose(fsm->datapcb, fsm->datafs);
fsm->datapcb = NULL;
dbg_printf("cmd_pasv: tcp_listen failed\n");
ftpd_dataclose(fsm->datalistenpcb, fsm->datafs);
fsm->datalistenpcb = NULL;
fsm->datafs = NULL;
return;
}
fsm->datapcb = temppcb;
fsm->datalistenpcb = temppcb;
fsm->passive = 1;
fsm->datafs->connected = 0;
fsm->datafs->msgfs = fsm;
fsm->datafs->msgpcb = pcb;
/* Tell TCP that this is the structure we wish to be passed for our
callbacks. */
tcp_arg(fsm->datapcb, fsm->datafs);
tcp_accept(fsm->datapcb, ftpd_dataaccept);
tcp_arg(fsm->datalistenpcb, fsm->datafs);
tcp_accept(fsm->datalistenpcb, ftpd_dataaccept);
send_msg(pcb, fsm, msg227, ip4_addr1(ip_2_ip4(&pcb->local_ip)), ip4_addr2(ip_2_ip4(&pcb->local_ip)), ip4_addr3(ip_2_ip4(&pcb->local_ip)), ip4_addr4(ip_2_ip4(&pcb->local_ip)), (fsm->dataport >> 8) & 0xff, (fsm->dataport) & 0xff);
}
@ -932,7 +961,6 @@ static void cmd_abrt(const char *arg, struct tcp_pcb *pcb, struct ftpd_msgstate
tcp_arg(fsm->datapcb, NULL);
tcp_sent(fsm->datapcb, NULL);
tcp_recv(fsm->datapcb, NULL);
tcp_arg(fsm->datapcb, NULL);
tcp_abort(pcb);
sfifo_close(&fsm->datafs->fifo);
free(fsm->datafs);
@ -973,6 +1001,7 @@ static void cmd_rnfr(const char *arg, struct tcp_pcb *pcb, struct ftpd_msgstate
free(fsm->renamefrom);
fsm->renamefrom = malloc(strlen(arg) + 1);
if (fsm->renamefrom == NULL) {
dbg_printf("cmd_rnfr: Out of memory\n");
send_msg(pcb, fsm, msg451);
return;
}
@ -1104,7 +1133,7 @@ static struct ftpd_command ftpd_commands[] = {
{"RMD", cmd_rmd},
{"XRMD", cmd_rmd},
{"DELE", cmd_dele},
//{"PASV", cmd_pasv},
{"PASV", cmd_pasv},
{NULL, NULL}
};
@ -1314,10 +1343,14 @@ static err_t ftpd_msgaccept(void *arg, struct tcp_pcb *pcb, err_t err)
memset(fsm, 0, sizeof(struct ftpd_msgstate));
/* Initialize the structure. */
sfifo_init(&fsm->fifo, 2000);
if (sfifo_init(&fsm->fifo, 2000) != 0) {
free(fsm);
return ERR_MEM;
}
fsm->state = FTPD_IDLE;
fsm->vfs = vfs_openfs();
if (!fsm->vfs) {
if (fsm->vfs == NULL) {
sfifo_close(&fsm->fifo);
free(fsm);
return ERR_CLSD;
}

Loading…
Cancel
Save