mirror of
https://github.com/Tha14/toxic.git
synced 2024-11-13 02:33:03 +01:00
implement data file encryption
This commit is contained in:
parent
0a6ce62363
commit
51e274ea38
@ -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);
|
||||
|
||||
/*id++;*/
|
||||
if ( id != ErrorInternal && id >= Friends.max_idx)
|
||||
return;
|
||||
|
||||
|
@ -26,7 +26,6 @@
|
||||
struct chatlog {
|
||||
FILE *file;
|
||||
uint64_t lastwrite;
|
||||
int pos;
|
||||
bool log_on; /* specific to current chat window */
|
||||
};
|
||||
|
||||
|
@ -306,8 +306,8 @@ void bytes_convert_str(char *buf, int size, uint64_t bytes)
|
||||
}
|
||||
|
||||
/* checks if a file exists. Returns true or false */
|
||||
bool file_exists(const char *fp)
|
||||
bool file_exists(const char *path)
|
||||
{
|
||||
struct stat s;
|
||||
return stat(fp, &s) == 0;
|
||||
return stat(path, &s) == 0;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
/* 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 */
|
||||
|
156
src/toxic.c
156
src/toxic.c
@ -38,8 +38,10 @@
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include <tox/tox.h>
|
||||
#include <tox/toxencryptsave.h>
|
||||
|
||||
#include "configdir.h"
|
||||
#include "toxic.h"
|
||||
@ -79,6 +81,15 @@ struct _cqueue_thread cqueue_thread;
|
||||
struct arg_opts arg_opts;
|
||||
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)
|
||||
{
|
||||
Winthread.sig_exit_toxic = true;
|
||||
@ -107,6 +118,7 @@ static void init_signal_catchers(void)
|
||||
void exit_toxic_success(Tox *m)
|
||||
{
|
||||
store_data(m, DATA_FILE);
|
||||
memset(&user_password, 0, sizeof(struct _user_password));
|
||||
close_all_file_senders(m);
|
||||
kill_all_windows(m);
|
||||
|
||||
@ -459,6 +471,69 @@ static void load_friendlist(Tox *m)
|
||||
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
|
||||
* Return 0 stored successfully or ignoring data file
|
||||
@ -467,7 +542,7 @@ static void load_friendlist(Tox *m)
|
||||
* Return -3 opening path 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)
|
||||
return 0;
|
||||
@ -475,13 +550,17 @@ int store_data(Tox *m, char *path)
|
||||
if (path == NULL)
|
||||
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);
|
||||
|
||||
if (buf == NULL)
|
||||
return -2;
|
||||
|
||||
tox_save(m, (uint8_t *) buf);
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
tox_load(m, (uint8_t *) buf, len);
|
||||
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);
|
||||
}
|
||||
|
||||
load_friendlist(m);
|
||||
load_blocklist(BLOCK_FILE);
|
||||
|
||||
@ -738,7 +840,7 @@ static void parse_args(int argc, char *argv[])
|
||||
|
||||
#define DATANAME "data"
|
||||
#define BLOCKNAME "data-blocklist"
|
||||
static int init_data_files(void)
|
||||
static int init_default_data_files(void)
|
||||
{
|
||||
if (arg_opts.use_custom_data)
|
||||
return 0;
|
||||
@ -746,28 +848,26 @@ static int init_data_files(void)
|
||||
char *user_config_dir = get_user_config_dir();
|
||||
int config_err = create_user_config_dirs(user_config_dir);
|
||||
|
||||
if (DATA_FILE == NULL ) {
|
||||
if (config_err) {
|
||||
DATA_FILE = strdup(DATANAME);
|
||||
BLOCK_FILE = strdup(BLOCKNAME);
|
||||
if (config_err) {
|
||||
DATA_FILE = strdup(DATANAME);
|
||||
BLOCK_FILE = strdup(BLOCKNAME);
|
||||
|
||||
if (DATA_FILE == NULL || BLOCK_FILE == NULL)
|
||||
exit_toxic_err("failed in load_data_structures", FATALERR_MEMORY);
|
||||
} else {
|
||||
DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(DATANAME) + 1);
|
||||
BLOCK_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(BLOCKNAME) + 1);
|
||||
if (DATA_FILE == NULL || BLOCK_FILE == NULL)
|
||||
exit_toxic_err("failed in load_data_structures", FATALERR_MEMORY);
|
||||
} else {
|
||||
DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(DATANAME) + 1);
|
||||
BLOCK_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(BLOCKNAME) + 1);
|
||||
|
||||
if (DATA_FILE == NULL || BLOCK_FILE == NULL)
|
||||
exit_toxic_err("failed in load_data_structures", FATALERR_MEMORY);
|
||||
if (DATA_FILE == NULL || BLOCK_FILE == NULL)
|
||||
exit_toxic_err("failed in load_data_structures", FATALERR_MEMORY);
|
||||
|
||||
strcpy(DATA_FILE, user_config_dir);
|
||||
strcat(DATA_FILE, CONFIGDIR);
|
||||
strcat(DATA_FILE, DATANAME);
|
||||
strcpy(DATA_FILE, user_config_dir);
|
||||
strcat(DATA_FILE, CONFIGDIR);
|
||||
strcat(DATA_FILE, DATANAME);
|
||||
|
||||
strcpy(BLOCK_FILE, user_config_dir);
|
||||
strcat(BLOCK_FILE, CONFIGDIR);
|
||||
strcat(BLOCK_FILE, BLOCKNAME);
|
||||
}
|
||||
strcpy(BLOCK_FILE, user_config_dir);
|
||||
strcat(BLOCK_FILE, CONFIGDIR);
|
||||
strcat(BLOCK_FILE, BLOCKNAME);
|
||||
}
|
||||
|
||||
free(user_config_dir);
|
||||
@ -800,7 +900,11 @@ int main(int argc, char *argv[])
|
||||
|
||||
/* Make sure all written files are read/writeable only by the current user. */
|
||||
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 */
|
||||
user_settings_ = calloc(1, sizeof(struct user_settings));
|
||||
@ -808,11 +912,10 @@ int main(int argc, char *argv[])
|
||||
if (user_settings_ == NULL)
|
||||
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);
|
||||
|
||||
Tox *m = init_tox();
|
||||
init_term();
|
||||
|
||||
/* enable stderr for debugging */
|
||||
if (!arg_opts.debug)
|
||||
@ -824,6 +927,7 @@ int main(int argc, char *argv[])
|
||||
if (!arg_opts.ignore_data_file)
|
||||
load_data(m, DATA_FILE);
|
||||
|
||||
init_term();
|
||||
prompt = init_windows(m);
|
||||
prompt_init_statusbar(prompt, m);
|
||||
|
||||
|
@ -88,7 +88,7 @@ typedef enum _FATAL_ERRS {
|
||||
void exit_toxic_success(Tox *m);
|
||||
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_connectionchange(Tox *m, int32_t friendnumber, uint8_t status, void *userdata);
|
||||
|
Loading…
Reference in New Issue
Block a user