diff options
-rw-r--r-- | main.c | 24 | ||||
-rw-r--r-- | portfolio.c | 81 | ||||
-rw-r--r-- | portfolio.h | 24 |
3 files changed, 108 insertions, 21 deletions
@@ -30,14 +30,6 @@ int main(int argc, char* argv[]) { return 0; } - // Convert legacy porfolio - if (argc == 2 && strcmp(argv[1], "convert") == 0) { - portfolio_legacy_convert(); - free((void*) portfolio_file); - fclose(fp); - return 0; - } - // Portfolio modify operation int modop = -1; @@ -45,10 +37,16 @@ int main(int argc, char* argv[]) { if (strcmp(cmd, "news") == 0) { if (argc == 3 && strlen(argv[2]) <= 32 && strlen(argv[2]) > 1) news_print_top_three(argv[2]); - else - printf("Invalid symbol.\n"); + else printf("Invalid symbol.\n"); } - + //Convert + else if (strcmp(cmd, "convert") == 0 && argc == 2) + portfolio_legacy_convert(); + //Encrypt/decrypt + else if (strcmp(argv[1], "encrypt") == 0 && argc == 2) + portfolio_encrypt_decrypt(ENCRYPT, fp); + else if (strcmp(argv[1], "decrypt") == 0 && argc == 2) + portfolio_encrypt_decrypt(DECRYPT, fp); // Check else if (strcmp(cmd, "check") == 0) { if (argc < 3) { @@ -75,9 +73,7 @@ int main(int argc, char* argv[]) { else if (strcmp(cmd, "set") == 0) modop = SET; - else { - printf("Invalid arguments. Type \"man tick\" for help.\n"); - } + else printf("Invalid arguments. Type \"man tick\" for help.\n"); // Portfolio Operations if (modop > -1) { diff --git a/portfolio.c b/portfolio.c index d95ac178d874..f1395c48f5db 100644 --- a/portfolio.c +++ b/portfolio.c @@ -11,10 +11,16 @@ void portfolio_file_init() { portfolio_file = path; } -char* portfolio_file_get_string(FILE* fp) { +char* portfolio_file_get_string(FILE* fp, size_t* len) { char* portfolio_string = calloc(65536, 1); + if (portfolio_string == NULL) { + fprintf(stderr, "calloc() failed\n"); + exit(EXIT_FAILURE); + } fseek(fp, 0, SEEK_END); size_t portfolio_size = (size_t) ftell(fp); + if (len != NULL) + *len = portfolio_size; fseek(fp, 0, SEEK_SET); if (fread(portfolio_string, sizeof(char), portfolio_size, fp) != portfolio_size) return NULL; @@ -30,7 +36,7 @@ void portfolio_modify(char* ticker_name_string, double quantity_shares, double u printf("You cannot add or remove values of 0.\n"); return; } - char* portfolio_string = portfolio_file_get_string(fp); + char* portfolio_string = portfolio_file_get_string(fp, NULL); if (portfolio_string == NULL) { fprintf(stderr, "malloc() failed\n"); return; @@ -109,7 +115,7 @@ void portfolio_modify(char* ticker_name_string, double quantity_shares, double u void portfolio_print_all(FILE* fp) { printf(" AMOUNT SYMBOL VALUE SPENT PROFIT (%%) 24H (%%)\n"); - char* portfolio_string = portfolio_file_get_string(fp); + char* portfolio_string = portfolio_file_get_string(fp, NULL); double* data, total_owned = 0, total_spent = 0, total_gain_1d = 0; if (strcmp(portfolio_string, "") == 0) return; @@ -147,7 +153,7 @@ double* portfolio_print_stock(char* ticker_name_string, FILE* fp, Json* current_ data[0] = json_object_get_double(json_object_object_get(current_index, "Shares")); data[1] = json_object_get_double(json_object_object_get(current_index, "USD_Spent")); } else { //if being called directly from main - portfolio_string = portfolio_file_get_string(fp); + portfolio_string = portfolio_file_get_string(fp, NULL); if (portfolio_string == NULL) { fprintf(stderr, "fread() failed\n"); free(data); @@ -214,7 +220,7 @@ char* portfolio_legacy_get_next_val(FILE* fp) { } void portfolio_legacy_convert() { - printf("Warning: this will overwrite your JSON formatted portfolio, which is stored at: \"$HOME/.tick_portfolio\". Continue? y/n\n"); + printf("Warning: this will overwrite your JSON formatted portfolio, which is stored at: \"$HOME/.tick_portfolio.json\". Continue? y/n\n"); char c = 0; while (c != 'y' && c != 'n') { if (scanf("%c", &c) < 0) @@ -225,7 +231,7 @@ void portfolio_legacy_convert() { return; } FILE* fp = fopen(portfolio_file, "w"); - char* pf = portfolio_file_get_string(fp); + char* pf = portfolio_file_get_string(fp, NULL); if (pf == NULL) { fprintf(stderr, "fread() failed\n"); exit(EXIT_FAILURE); @@ -259,4 +265,67 @@ void portfolio_legacy_convert() { printf("Successfully converted portfolio!\n"); fclose(fp_legacy); fclose(fp); +} + +char* portfolio_get_encrypt_string(char* input, size_t input_len, char* password) { + int keySchedule[256]; + rc4_key_exchange(keySchedule, password); + char* output = rc4_prga(keySchedule, input_len); + rc4_execute(output, input, input_len); + return output; +} + +void portfolio_encrypt_decrypt(int option, FILE* fp) { + size_t len; + char* ps = portfolio_file_get_string(fp, &len); + Json* jobj = json_tokener_parse(ps); + if (option == ENCRYPT && jobj == NULL) // If trying to encrypt an encrypted portfolio + printf("Your portfolio is already encrypted.\n"); + else if (option == DECRYPT && jobj != NULL) // If trying to decrypt an unencrypted portfolio + printf("Your portfolio isn't encrypted.\n"); + else { + char* password = rc4_getPassword(); + if (option == ENCRYPT) { // When encrypting, ask to enter pw twice to make sure + printf("You will be asked to enter your password again to make sure the entries match.\n"); + sleep(2); + char* passwordCheck = rc4_getPassword(); + if (strcmp(password, passwordCheck) != 0) { + printf("Passwords do not match!\n"); + free(password); + free(passwordCheck); + free(ps); + json_object_put(jobj); + return; + } + free(passwordCheck); + } + char* encrypted = portfolio_get_encrypt_string(ps, len, password); + if (option == DECRYPT) { + json_object_put(jobj); + encrypted = realloc(encrypted, len + 1);// Realloc to add null terminator for json parsing + if (encrypted == NULL) { // Dealing with len is annoying so it's easier to just realloc + fprintf(stderr, "malloc() failed\n"); + exit(EXIT_FAILURE); + } + encrypted[len] = '\0'; + jobj = json_tokener_parse(encrypted); + if (jobj == NULL) { // If after decrypting, the portfolio is not JSON formatted, + printf("Wrong password!\n"); // then it's the wrong password + free(encrypted); + free(password); + free(ps); + return; + } + } + remove(portfolio_file); // Remove existing file and use fputc to write + fp = fopen(portfolio_file, "w"); // fprintf %s won't work since there some chars are encoded to '\0', so it + for (int i = 0; i < len; i++) // will be null terminated several times in the middle + fputc(encrypted[i], fp); + fclose(fp); + free(encrypted); + free(password); + } + if (jobj != NULL) + json_object_put(jobj); + free(ps); }
\ No newline at end of file diff --git a/portfolio.h b/portfolio.h index ab9f02a45a8b..36b5b91a9d13 100644 --- a/portfolio.h +++ b/portfolio.h @@ -2,11 +2,15 @@ #define PORTFOLIO_H #include <math.h> +#include <unistd.h> #include "api.h" +#include "rc4.h" #define REMOVE 0 #define ADD 1 #define SET 2 +#define DECRYPT 0 +#define ENCRYPT 1 const char* portfolio_file; @@ -18,9 +22,11 @@ void portfolio_file_init(); /** * Stores the given file in a string and returns it * @param fp the file + * @param len sets *len to the size of the string -- used for decryption (some chars will be encrypted to '\0', so + * the returned string will be null terminated somewhere in the middle several times * @return the string containing the file */ -char* portfolio_file_get_string(FILE* fp); +char* portfolio_file_get_string(FILE* fp, size_t* len); /** * Adds quantity_shares of given symbol at given price to portfolio @@ -68,4 +74,20 @@ char* portfolio_legacy_get_next_val(FILE* fp); */ void portfolio_legacy_convert(); +/** + * Returns an either encrypted or decrypted string of the input + * @param input the string to encrypt or decrypt + * @param input_len the length of the string + * @param password the password to encrypt or decrypt with + * @return encrypted or decrypted string + */ +char* portfolio_get_encrypt_string(char* input, size_t input_len, char* password); + +/** + * Either encrypts or decrypts the portfolio file + * @param option ENCRYPT or DECRYPT + * @param fp portfolio file + */ +void portfolio_encrypt_decrypt(int option, FILE* fp); + #endif
\ No newline at end of file |