mirror of
https://github.com/seregonwar/zftpd.git
synced 2026-10-22 03:32:24 -05:00
Introduce pal_resilient_accept to handle accept() failures by recreating, rebinding and relistening the server socket (with retries and logs), and send a notification when the server resumes. Add public header and implementation (include/pal_resilient_server.h, src/pal_resilient_server.c), wire it into the server accept loop (src/ftp_server.c) replacing the direct PAL_ACCEPT call, and add the new source to the build (Makefile). Also enable FTP_PORT_ALLOW_FOREIGN_IP in test builds and update tests/test_security.c to use 127.0.0.1 instead of 10.0.0.2.
87 lines
1.9 KiB
C
87 lines
1.9 KiB
C
#include "ftp_session.h"
|
|
#include "ftp_commands.h"
|
|
#include <arpa/inet.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <sys/socket.h>
|
|
#include <unistd.h>
|
|
|
|
static int read_reply_code(int fd)
|
|
{
|
|
char buf[256];
|
|
ssize_t n = recv(fd, buf, sizeof(buf) - 1U, 0);
|
|
if (n <= 0) {
|
|
return -1;
|
|
}
|
|
buf[n] = '\0';
|
|
if (n < 3) {
|
|
return -1;
|
|
}
|
|
return (buf[0] - '0') * 100 + (buf[1] - '0') * 10 + (buf[2] - '0');
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
int sv[2];
|
|
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) != 0) {
|
|
return 2;
|
|
}
|
|
|
|
struct sockaddr_in client_addr;
|
|
memset(&client_addr, 0, sizeof(client_addr));
|
|
client_addr.sin_family = AF_INET;
|
|
(void)inet_pton(AF_INET, "127.0.0.1", &client_addr.sin_addr);
|
|
client_addr.sin_port = htons(12345);
|
|
|
|
ftp_session_t session;
|
|
ftp_error_t init_err = ftp_session_init(&session, sv[0], &client_addr, 1U, "/");
|
|
if (init_err != FTP_OK) {
|
|
return 3;
|
|
}
|
|
|
|
(void)ftp_session_process_command(&session, "PWD");
|
|
int code = read_reply_code(sv[1]);
|
|
if (code != 530) {
|
|
return 4;
|
|
}
|
|
|
|
session.authenticated = 1U;
|
|
ftp_error_t port_err = cmd_PORT(&session, "127,0,0,1,0,21");
|
|
if (port_err != FTP_OK) {
|
|
return 5;
|
|
}
|
|
code = read_reply_code(sv[1]);
|
|
if (code != 200) {
|
|
return 6;
|
|
}
|
|
|
|
session.authenticated = 0U;
|
|
session.user_ok = 0U;
|
|
session.auth_attempts = 0U;
|
|
|
|
ftp_error_t u1 = cmd_USER(&session, "nope");
|
|
if (u1 != FTP_OK) {
|
|
return 7;
|
|
}
|
|
(void)read_reply_code(sv[1]);
|
|
|
|
ftp_error_t u2 = cmd_USER(&session, "nope");
|
|
if (u2 != FTP_OK) {
|
|
return 8;
|
|
}
|
|
(void)read_reply_code(sv[1]);
|
|
|
|
ftp_error_t u3 = cmd_USER(&session, "nope");
|
|
if (u3 != FTP_OK) {
|
|
return 9;
|
|
}
|
|
code = read_reply_code(sv[1]);
|
|
if (code != 230) {
|
|
return 10;
|
|
}
|
|
|
|
ftp_session_cleanup(&session);
|
|
close(sv[1]);
|
|
return 0;
|
|
}
|