/* * svc_ftp.c * FTP honeypot handler — banner + USER/PASS capture + tarpit. */ #include "sdkconfig.h" #ifdef CONFIG_MODULE_HONEYPOT #include #include "svc_common.h" void handle_ftp_client(int client_fd, const char *client_ip, uint16_t client_port, hp_svc_desc_t *svc) { char banner[128]; hp_config_get_banner("ftp", banner, sizeof(banner)); send(client_fd, banner, strlen(banner), 0); svc->connections++; event_send("SVC_CONNECT", "LOW", "00:00:00:00:00:00", client_ip, client_port, 21, "service=ftp", NULL); char user[64] = {0}, pass[64] = {0}; for (int round = 0; round < 4; round++) { char buf[MAX_CLIENT_BUF]; int n = recv(client_fd, buf, sizeof(buf) - 1, 0); if (n <= 0) break; buf[n] = '\0'; if (strncasecmp(buf, "USER ", 5) == 0) { strncpy(user, buf + 5, sizeof(user) - 1); user[sizeof(user) - 1] = '\0'; char *p = user; while (*p && *p != '\r' && *p != '\n') p++; *p = '\0'; const char *resp = "331 Password required\r\n"; send(client_fd, resp, strlen(resp), 0); } else if (strncasecmp(buf, "PASS ", 5) == 0) { strncpy(pass, buf + 5, sizeof(pass) - 1); pass[sizeof(pass) - 1] = '\0'; char *p = pass; while (*p && *p != '\r' && *p != '\n') p++; *p = '\0'; const char *resp = "530 Login incorrect\r\n"; send(client_fd, resp, strlen(resp), 0); break; } else if (strncasecmp(buf, "QUIT", 4) == 0) { const char *resp = "221 Goodbye\r\n"; send(client_fd, resp, strlen(resp), 0); break; } else { const char *resp = "500 Unknown command\r\n"; send(client_fd, resp, strlen(resp), 0); } } if (user[0] || pass[0]) { svc->auth_attempts++; char detail[192]; snprintf(detail, sizeof(detail), "service=ftp user='%.32s' pass='%.32s'", user, pass); event_send("SVC_AUTH_ATTEMPT", "HIGH", "00:00:00:00:00:00", client_ip, client_port, 21, detail, NULL); } int tarpit = hp_config_get_threshold("tarpit_ms"); if (tarpit > 0) vTaskDelay(pdMS_TO_TICKS(tarpit)); } #endif