сортировка, переделана авторизация, изменен дизайн
This commit is contained in:
213
src/auth.c
213
src/auth.c
@@ -1,13 +1,29 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#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) return 1;
|
||||
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)) {
|
||||
@@ -19,13 +35,14 @@ int check_folder_password(const char *folder_name, const char *password) {
|
||||
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 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_folder_protected(const char *folder_path) {
|
||||
@@ -50,3 +67,195 @@ int is_folder_protected(const char *folder_path) {
|
||||
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);
|
||||
}
|
||||
Reference in New Issue
Block a user