mirror of
https://github.com/Tha14/toxic.git
synced 2024-11-23 02:13:01 +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);
|
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;
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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 */
|
||||||
|
156
src/toxic.c
156
src/toxic.c
@ -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,13 +550,17 @@ 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;
|
||||||
|
|
||||||
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");
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
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_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,28 +848,26 @@ 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);
|
|
||||||
|
|
||||||
if (DATA_FILE == NULL || BLOCK_FILE == NULL)
|
if (DATA_FILE == NULL || BLOCK_FILE == NULL)
|
||||||
exit_toxic_err("failed in load_data_structures", FATALERR_MEMORY);
|
exit_toxic_err("failed in load_data_structures", FATALERR_MEMORY);
|
||||||
} else {
|
} else {
|
||||||
DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(DATANAME) + 1);
|
DATA_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(DATANAME) + 1);
|
||||||
BLOCK_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(BLOCKNAME) + 1);
|
BLOCK_FILE = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen(BLOCKNAME) + 1);
|
||||||
|
|
||||||
if (DATA_FILE == NULL || BLOCK_FILE == NULL)
|
if (DATA_FILE == NULL || BLOCK_FILE == NULL)
|
||||||
exit_toxic_err("failed in load_data_structures", FATALERR_MEMORY);
|
exit_toxic_err("failed in load_data_structures", FATALERR_MEMORY);
|
||||||
|
|
||||||
strcpy(DATA_FILE, user_config_dir);
|
strcpy(DATA_FILE, user_config_dir);
|
||||||
strcat(DATA_FILE, CONFIGDIR);
|
strcat(DATA_FILE, CONFIGDIR);
|
||||||
strcat(DATA_FILE, DATANAME);
|
strcat(DATA_FILE, DATANAME);
|
||||||
|
|
||||||
strcpy(BLOCK_FILE, user_config_dir);
|
strcpy(BLOCK_FILE, user_config_dir);
|
||||||
strcat(BLOCK_FILE, CONFIGDIR);
|
strcat(BLOCK_FILE, CONFIGDIR);
|
||||||
strcat(BLOCK_FILE, BLOCKNAME);
|
strcat(BLOCK_FILE, BLOCKNAME);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(user_config_dir);
|
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. */
|
/* 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);
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user