diff --git a/doc/toxic.conf.5.asc b/doc/toxic.conf.5.asc index 719ff3b..e0d2faa 100644 --- a/doc/toxic.conf.5.asc +++ b/doc/toxic.conf.5.asc @@ -123,6 +123,10 @@ OPTIONS *chatlogs_path*;; Default path for chatlogs. String value. Absolute path for chatlog files. + *password_eval*;; + Replace password prompt by running this command and using its output as + the password. + *sounds*:: Configuration related to notification sounds. Special value "silent" can be used to disable a specific notification. + diff --git a/src/settings.c b/src/settings.c index 95e20a6..e1b3e18 100644 --- a/src/settings.c +++ b/src/settings.c @@ -158,11 +158,13 @@ static const struct tox_strings { const char* download_path; const char* chatlogs_path; const char* avatar_path; + const char* password_eval; } tox_strings = { "tox", "download_path", "chatlogs_path", "avatar_path", + "password_eval", }; static void tox_defaults(struct user_settings* settings) @@ -170,6 +172,7 @@ static void tox_defaults(struct user_settings* settings) strcpy(settings->download_path, ""); strcpy(settings->chatlogs_path, ""); strcpy(settings->avatar_path, ""); + strcpy(settings->password_eval, ""); } #ifdef AUDIO @@ -359,6 +362,14 @@ int settings_load(struct user_settings *s, const char *patharg) if (len >= sizeof(s->avatar_path)) s->avatar_path[0] = '\0'; } + + if ( config_setting_lookup_string(setting, tox_strings.password_eval, &str) ) { + snprintf(s->password_eval, sizeof(s->password_eval), "%s", str); + int len = strlen(str); + + if (len >= sizeof(s->password_eval)) + s->password_eval[0] = '\0'; + } } /* keys */ diff --git a/src/settings.h b/src/settings.h index 1f5e7bd..5ed1c3e 100644 --- a/src/settings.h +++ b/src/settings.h @@ -30,6 +30,8 @@ /* Represents line_* hints max strlen */ #define LINE_HINT_MAX 3 +#define PASSWORD_EVAL_MAX 512 + /* holds user setting values */ struct user_settings { int autolog; /* boolean */ @@ -53,6 +55,7 @@ struct user_settings { char download_path[PATH_MAX]; char chatlogs_path[PATH_MAX]; char avatar_path[PATH_MAX]; + char password_eval[PASSWORD_EVAL_MAX]; int key_next_tab; int key_prev_tab; diff --git a/src/toxic.c b/src/toxic.c index 31765a0..bdf8f9e 100644 --- a/src/toxic.c +++ b/src/toxic.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -472,6 +473,45 @@ static int password_prompt(char *buf, int size) return len; } +/* Get the password from the eval command. + * return length of password on success, 0 on failure + */ +static int password_eval(char *buf, int size) +{ + buf[0] = '\0'; + + /* Run password_eval command */ + FILE *f = popen(user_settings->password_eval, "r"); + if (f == NULL) { + fprintf(stderr, "Executing password_eval failed\n"); + return 0; + } + + /* Get output from command */ + char *ret = fgets(buf, size, f); + if (ret == NULL) { + fprintf(stderr, "Reading password from password_eval command failed\n"); + pclose(f); + return 0; + } + + /* Get exit status */ + int status = pclose(f); + if (status != 0) { + fprintf(stderr, "password_eval command returned error %d\n", status); + return 0; + } + + /* Removez whitespace or \n at end */ + int i, len = strlen(buf); + for (i = len - 1; i > 0 && isspace(buf[i]); i--) { + buf[i] = 0; + len--; + } + + return len; +} + /* Ask user if they would like to encrypt the data file and set password */ static void first_time_encrypt(const char *msg) { @@ -693,14 +733,21 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, TOX_ERR_NEW user_password.data_is_encrypted = true; size_t pwlen = 0; - system("clear"); // TODO: is this portable? - printf("Enter password (q to quit) "); + int pweval = user_settings->password_eval[0]; + if (!pweval) { + system("clear"); // TODO: is this portable? + printf("Enter password (q to quit) "); + } size_t plain_len = len - TOX_PASS_ENCRYPTION_EXTRA_LENGTH; char plain[plain_len]; while (true) { - pwlen = password_prompt(user_password.pass, sizeof(user_password.pass)); + if (pweval) { + pwlen = password_eval(user_password.pass, sizeof(user_password.pass)); + } else { + pwlen = password_prompt(user_password.pass, sizeof(user_password.pass)); + } user_password.len = pwlen; if (strcasecmp(user_password.pass, "q") == 0) { @@ -712,6 +759,7 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, TOX_ERR_NEW system("clear"); sleep(1); printf("Invalid password. Try again. "); + pweval = 0; continue; } @@ -736,6 +784,7 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, TOX_ERR_NEW system("clear"); sleep(1); printf("Invalid password. Try again. "); + pweval = 0; } else { fclose(fp); exit_toxic_err("tox_pass_decrypt() failed", pwerr);