1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-11-26 22:13:26 +01:00

implement data file encryption

This commit is contained in:
Jfreegman 2014-09-14 17:46:28 -04:00
parent 0a6ce62363
commit 51e274ea38
No known key found for this signature in database
GPG Key ID: 3627F3144076AE63
6 changed files with 134 additions and 32 deletions

View File

@ -999,7 +999,6 @@ static void friendlist_onAv(ToxWindow *self, ToxAv *av, int call_index)
{ {
int id = toxav_get_peer_id(av, call_index, 0); int id = toxav_get_peer_id(av, call_index, 0);
/*id++;*/
if ( id != ErrorInternal && id >= Friends.max_idx) if ( id != ErrorInternal && id >= Friends.max_idx)
return; return;

View File

@ -26,7 +26,6 @@
struct chatlog { struct chatlog {
FILE *file; FILE *file;
uint64_t lastwrite; uint64_t lastwrite;
int pos;
bool log_on; /* specific to current chat window */ bool log_on; /* specific to current chat window */
}; };

View File

@ -306,8 +306,8 @@ void bytes_convert_str(char *buf, int size, uint64_t bytes)
} }
/* checks if a file exists. Returns true or false */ /* checks if a file exists. Returns true or false */
bool file_exists(const char *fp) bool file_exists(const char *path)
{ {
struct stat s; struct stat s;
return stat(fp, &s) == 0; return stat(path, &s) == 0;
} }

View File

@ -110,6 +110,6 @@ int char_rfind(const char *s, char ch, int len);
void bytes_convert_str(char *buf, int size, uint64_t bytes); void bytes_convert_str(char *buf, int size, uint64_t bytes);
/* checks if a file exists. Returns true or false */ /* checks if a file exists. Returns true or false */
bool file_exists(const char *fp); bool file_exists(const char *path);
#endif /* #define _misc_tools_h */ #endif /* #define _misc_tools_h */

View File

@ -38,8 +38,10 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <unistd.h> #include <unistd.h>
#include <limits.h> #include <limits.h>
#include <termios.h>
#include <tox/tox.h> #include <tox/tox.h>
#include <tox/toxencryptsave.h>
#include "configdir.h" #include "configdir.h"
#include "toxic.h" #include "toxic.h"
@ -79,6 +81,15 @@ struct _cqueue_thread cqueue_thread;
struct arg_opts arg_opts; struct arg_opts arg_opts;
struct user_settings *user_settings_ = NULL; struct user_settings *user_settings_ = NULL;
#define MIN_PASSWORD_LEN 6
#define MAX_PASSWORD_LEN 256
static struct _user_password {
bool data_is_encrypted;
char pass[MAX_STR_SIZE];
int len;
} user_password;
static void catch_SIGINT(int sig) static void catch_SIGINT(int sig)
{ {
Winthread.sig_exit_toxic = true; Winthread.sig_exit_toxic = true;
@ -107,6 +118,7 @@ static void init_signal_catchers(void)
void exit_toxic_success(Tox *m) void exit_toxic_success(Tox *m)
{ {
store_data(m, DATA_FILE); store_data(m, DATA_FILE);
memset(&user_password, 0, sizeof(struct _user_password));
close_all_file_senders(m); close_all_file_senders(m);
kill_all_windows(m); kill_all_windows(m);
@ -459,6 +471,69 @@ static void load_friendlist(Tox *m)
sort_friendlist_index(); sort_friendlist_index();
} }
/* return length of password on success, 0 on failure */
static int password_prompt(char *buf, int size)
{
printf("> ");
/* disable terminal echo */
struct termios oflags, nflags;
tcgetattr(fileno(stdin), &oflags);
nflags = oflags;
nflags.c_lflag &= ~ECHO;
nflags.c_lflag |= ECHONL;
if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0)
return 0;
fgets(buf, size, stdin);
int len = strlen(buf);
if (len > 0)
buf[--len] = '\0'; /* rm newline char */
/* re-enable terminal echo */
if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0)
return 0;
return len;
}
/* Ask user if they would like to encrypt the data file on first usage */
static void first_time_running(void)
{
char ch[3] = {0};
do {
system("clear");
printf("Encrypt data file? Y/n \n");
if (!strcasecmp(ch, "y\n") || !strcasecmp(ch, "n\n"))
break;
} while (fgets(ch, sizeof(ch), stdin));
const char *msg = NULL;
int len = 0;
if (ch[0] == 'y') {
do {
printf("Enter a new password (must be at least %d characters)\n", MIN_PASSWORD_LEN);
len = password_prompt(user_password.pass, sizeof(user_password.pass));
user_password.len = len;
} while (len < MIN_PASSWORD_LEN || len > MAX_PASSWORD_LEN);
user_password.data_is_encrypted = true;
msg = "Data file has been encrypted";
} else {
user_password.data_is_encrypted = false;
msg = "Data file has not been encrypted";
}
system("clear");
queue_init_message(msg);
}
/* /*
* Store Messenger to given location * Store Messenger to given location
* Return 0 stored successfully or ignoring data file * Return 0 stored successfully or ignoring data file
@ -467,7 +542,7 @@ static void load_friendlist(Tox *m)
* Return -3 opening path failed * Return -3 opening path failed
* Return -4 fwrite failed * Return -4 fwrite failed
*/ */
int store_data(Tox *m, char *path) int store_data(Tox *m, const char *path)
{ {
if (arg_opts.ignore_data_file) if (arg_opts.ignore_data_file)
return 0; return 0;
@ -475,12 +550,16 @@ int store_data(Tox *m, char *path)
if (path == NULL) if (path == NULL)
return -1; return -1;
int len = tox_size(m); int len = user_password.data_is_encrypted ? tox_encrypted_size(m) : tox_size(m);
char *buf = malloc(len); char *buf = malloc(len);
if (buf == NULL) if (buf == NULL)
return -2; return -2;
if (user_password.data_is_encrypted)
tox_encrypted_save(m, (uint8_t *) buf, (uint8_t *) user_password.pass,
user_password.len);
else
tox_save(m, (uint8_t *) buf); tox_save(m, (uint8_t *) buf);
FILE *fd = fopen(path, "wb"); FILE *fd = fopen(path, "wb");
@ -526,7 +605,30 @@ static void load_data(Tox *m, char *path)
exit_toxic_err("failed in load_data", FATALERR_FREAD); exit_toxic_err("failed in load_data", FATALERR_FREAD);
} }
user_password.data_is_encrypted = tox_is_data_encrypted((uint8_t *) buf);
int pwlen = 0;
if (user_password.data_is_encrypted) {
system("clear");
printf("Enter password\n");
do {
pwlen = password_prompt(user_password.pass, sizeof(user_password.pass));
user_password.len = pwlen;
if (-1 != tox_encrypted_load(m, (uint8_t *) buf, len, (uint8_t *) user_password.pass, pwlen)) {
break;
} else {
sleep(2);
printf("Invalid password. Try again.\n");
}
} while (true);
system("clear");
} else {
tox_load(m, (uint8_t *) buf, len); tox_load(m, (uint8_t *) buf, len);
}
load_friendlist(m); load_friendlist(m);
load_blocklist(BLOCK_FILE); load_blocklist(BLOCK_FILE);
@ -738,7 +840,7 @@ static void parse_args(int argc, char *argv[])
#define DATANAME "data" #define DATANAME "data"
#define BLOCKNAME "data-blocklist" #define BLOCKNAME "data-blocklist"
static int init_data_files(void) static int init_default_data_files(void)
{ {
if (arg_opts.use_custom_data) if (arg_opts.use_custom_data)
return 0; return 0;
@ -746,7 +848,6 @@ static int init_data_files(void)
char *user_config_dir = get_user_config_dir(); char *user_config_dir = get_user_config_dir();
int config_err = create_user_config_dirs(user_config_dir); int config_err = create_user_config_dirs(user_config_dir);
if (DATA_FILE == NULL ) {
if (config_err) { if (config_err) {
DATA_FILE = strdup(DATANAME); DATA_FILE = strdup(DATANAME);
BLOCK_FILE = strdup(BLOCKNAME); BLOCK_FILE = strdup(BLOCKNAME);
@ -768,7 +869,6 @@ static int init_data_files(void)
strcat(BLOCK_FILE, CONFIGDIR); strcat(BLOCK_FILE, CONFIGDIR);
strcat(BLOCK_FILE, BLOCKNAME); strcat(BLOCK_FILE, BLOCKNAME);
} }
}
free(user_config_dir); free(user_config_dir);
return config_err; return config_err;
@ -800,7 +900,11 @@ int main(int argc, char *argv[])
/* Make sure all written files are read/writeable only by the current user. */ /* Make sure all written files are read/writeable only by the current user. */
umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
int config_err = init_data_files(); int config_err = init_default_data_files();
bool first_run = !file_exists(DATA_FILE);
if (first_run)
first_time_running();
/* init user_settings struct and load settings from conf file */ /* init user_settings struct and load settings from conf file */
user_settings_ = calloc(1, sizeof(struct user_settings)); user_settings_ = calloc(1, sizeof(struct user_settings));
@ -808,11 +912,10 @@ int main(int argc, char *argv[])
if (user_settings_ == NULL) if (user_settings_ == NULL)
exit_toxic_err("failed in main", FATALERR_MEMORY); exit_toxic_err("failed in main", FATALERR_MEMORY);
char *p = arg_opts.config_path[0] ? arg_opts.config_path : NULL; const char *p = arg_opts.config_path[0] ? arg_opts.config_path : NULL;
int settings_err = settings_load(user_settings_, p); int settings_err = settings_load(user_settings_, p);
Tox *m = init_tox(); Tox *m = init_tox();
init_term();
/* enable stderr for debugging */ /* enable stderr for debugging */
if (!arg_opts.debug) if (!arg_opts.debug)
@ -824,6 +927,7 @@ int main(int argc, char *argv[])
if (!arg_opts.ignore_data_file) if (!arg_opts.ignore_data_file)
load_data(m, DATA_FILE); load_data(m, DATA_FILE);
init_term();
prompt = init_windows(m); prompt = init_windows(m);
prompt_init_statusbar(prompt, m); prompt_init_statusbar(prompt, m);

View File

@ -88,7 +88,7 @@ typedef enum _FATAL_ERRS {
void exit_toxic_success(Tox *m); void exit_toxic_success(Tox *m);
void exit_toxic_err(const char *errmsg, int errcode); void exit_toxic_err(const char *errmsg, int errcode);
int store_data(Tox *m, char *path); int store_data(Tox *m, const char *path);
void on_request(Tox *m, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata); void on_request(Tox *m, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata);
void on_connectionchange(Tox *m, int32_t friendnumber, uint8_t status, void *userdata); void on_connectionchange(Tox *m, int32_t friendnumber, uint8_t status, void *userdata);