#include #include #include #include #include #include #include #include "auth.h" #include "config.h" #include "utils.h" #define TOKEN_DIR "/tmp/trashbox_tokens" #define TOKEN_SALT "TrashBoxSecretSalt2024" // ============================================ // ПРОВЕРКА ПАРОЛЯ // ============================================ int check_folder_password(const char *folder_name, const char *password) { if (!password || !folder_name || password[0] == '\0') return 0; FILE *f = fopen(g_config.passwd_file, "r"); if (!f) { fprintf(stderr, "DEBUG: cannot open passwd file: %s\n", g_config.passwd_file); return 0; } char line[512]; while (fgets(line, sizeof(line), f)) { line[strcspn(line, "\r\n")] = 0; char *colon = strchr(line, ':'); if (!colon) continue; *colon = '\0'; char *folder = line; char *pass = colon + 1; const char *last_slash = strrchr(folder_name, '/'); const char *base_name = last_slash ? last_slash + 1 : folder_name; if (strcmp(folder, folder_name) == 0 || strcmp(folder, base_name) == 0) { fclose(f); return strcmp(pass, password) == 0; } } fclose(f); return 0; } int is_folder_protected(const char *folder_path) { if (!folder_path || folder_path[0] == '\0') return 0; FILE *f = fopen(g_config.passwd_file, "r"); if (!f) return 0; char line[512]; while (fgets(line, sizeof(line), f)) { line[strcspn(line, "\r\n")] = 0; char *colon = strchr(line, ':'); if (!colon) continue; *colon = '\0'; const char *last_slash = strrchr(folder_path, '/'); const char *folder_name = last_slash ? last_slash + 1 : folder_path; if (strcmp(line, folder_path) == 0 || strcmp(line, folder_name) == 0) { fclose(f); return 1; } } fclose(f); return 0; } // ============================================ // ЛИМИТ ПОПЫТОК // ============================================ void get_attempts_file(char *buf, size_t size, const char *folder_name, const char *ip) { char safe_folder[256]; strncpy(safe_folder, folder_name, sizeof(safe_folder) - 1); safe_folder[sizeof(safe_folder) - 1] = '\0'; for (char *p = safe_folder; *p; p++) { if (*p == '/' || *p == '\\' || *p == '.') *p = '_'; } snprintf(buf, size, "/tmp/trashbox_attempts_%s_%s", safe_folder, ip); } int check_attempts(const char *folder_name, const char *ip) { if (!folder_name || !ip) return 0; char attempts_file[256]; get_attempts_file(attempts_file, sizeof(attempts_file), folder_name, ip); FILE *f = fopen(attempts_file, "r"); if (!f) return 0; int attempts; time_t first_attempt_time; if (fscanf(f, "%d %ld", &attempts, &first_attempt_time) != 2) { fclose(f); return 0; } fclose(f); time_t now = time(NULL); if (now - first_attempt_time > g_config.block_time) { unlink(attempts_file); return 0; } return attempts >= g_config.max_attempts; } void add_attempt(const char *folder_name, const char *ip) { if (!folder_name || !ip) return; char attempts_file[256]; get_attempts_file(attempts_file, sizeof(attempts_file), folder_name, ip); int attempts = 0; time_t first_attempt_time = time(NULL); FILE *f = fopen(attempts_file, "r"); if (f) { fscanf(f, "%d %ld", &attempts, &first_attempt_time); fclose(f); attempts++; } else { attempts = 1; } f = fopen(attempts_file, "w"); if (f) { fprintf(f, "%d %ld\n", attempts, first_attempt_time); fclose(f); } } void clear_attempts(const char *folder_name, const char *ip) { if (!folder_name || !ip) return; char attempts_file[256]; get_attempts_file(attempts_file, sizeof(attempts_file), folder_name, ip); unlink(attempts_file); } // ============================================ // ТОКЕНЫ // ============================================ char* generate_token(const char *path) { // ============================================ // ФИНАЛЬНЫЙ ФИКС: очищаем путь от любых нежелательных символов // ============================================ char clean_path[1024]; strncpy(clean_path, path, sizeof(clean_path) - 1); clean_path[sizeof(clean_path) - 1] = '\0'; // Удаляем всё после '%' и другие нежелательные символы char *p = clean_path; while (*p) { if (*p == '%' || *p == '\n' || *p == '\r') { *p = '\0'; break; } p++; } // Если путь пустой — используем "default" if (clean_path[0] == '\0') { strcpy(clean_path, "default"); } mkdir(TOKEN_DIR, 0700); time_t now = time(NULL); char input[1024]; snprintf(input, sizeof(input), "%ld_%s_%s", now, clean_path, TOKEN_SALT); unsigned long hash = 0; for (int i = 0; input[i]; i++) { hash = hash * 31 + input[i]; } char token[256]; snprintf(token, sizeof(token), "%lx_%ld", hash, now); char token_file[512]; snprintf(token_file, sizeof(token_file), "%s/%s", TOKEN_DIR, token); FILE *f = fopen(token_file, "w"); if (!f) return NULL; fprintf(f, "%s", clean_path); fclose(f); return strdup(token); } int check_token(const char *token, char *path, size_t path_size) { if (!token || !token[0]) return 0; char token_file[512]; snprintf(token_file, sizeof(token_file), "%s/%s", TOKEN_DIR, token); FILE *f = fopen(token_file, "r"); if (!f) return 0; char stored_path[1024]; if (fgets(stored_path, sizeof(stored_path), f) == NULL) { fclose(f); return 0; } fclose(f); stored_path[strcspn(stored_path, "\n")] = '\0'; // Обрезаем % в конце char *pp = stored_path; while (*pp) { if (*pp == '%' || *pp == '\n' || *pp == '\r') { *pp = '\0'; break; } pp++; } struct stat st; if (stat(token_file, &st) != 0) return 0; time_t now = time(NULL); if (now - st.st_mtime > 3600) { unlink(token_file); return 0; } strncpy(path, stored_path, path_size - 1); path[path_size - 1] = '\0'; return 1; } void cleanup_old_tokens(void) { DIR *dir = opendir(TOKEN_DIR); if (!dir) return; struct dirent *entry; time_t now = time(NULL); while ((entry = readdir(dir)) != NULL) { if (entry->d_name[0] == '.') continue; char token_file[512]; snprintf(token_file, sizeof(token_file), "%s/%s", TOKEN_DIR, entry->d_name); struct stat st; if (stat(token_file, &st) == 0) { if (now - st.st_mtime > 3600) { unlink(token_file); } } } closedir(dir); }