Remove MPW_COLOR from core, safer decryption, more standard password input & curses dialog.
This commit is contained in:
@@ -28,18 +28,21 @@
|
||||
#include <errno.h>
|
||||
#include <sysexits.h>
|
||||
|
||||
#define MPW_MAX_INPUT 60
|
||||
|
||||
#if MPW_COLOR
|
||||
#include <curses.h>
|
||||
#include <term.h>
|
||||
#endif
|
||||
|
||||
#include "mpw-util.h"
|
||||
|
||||
/** Read the value of an environment variable.
|
||||
* @return A newly allocated string or NULL if the variable doesn't exist. */
|
||||
const char *mpw_getenv(const char *variableName) {
|
||||
|
||||
char *envBuf = getenv( variableName );
|
||||
return envBuf? mpw_strdup( envBuf ): NULL;
|
||||
}
|
||||
|
||||
/** Use the askpass program to prompt the user.
|
||||
* @return A newly allocated string or NULL if askpass is not supported or an error occurred. */
|
||||
char *mpw_askpass(const char *prompt) {
|
||||
|
||||
const char *askpass = mpw_getenv( MP_ENV_askpass );
|
||||
@@ -91,15 +94,59 @@ char *mpw_askpass(const char *prompt) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Ask the user a question.
|
||||
* @return A newly allocated string or NULL if an error occurred trying to read from the user. */
|
||||
const char *mpw_getline(const char *prompt) {
|
||||
static const char *_mpw_getline(const char *prompt, bool silent) {
|
||||
|
||||
// Get answer from askpass.
|
||||
char *answer = mpw_askpass( prompt );
|
||||
if (answer)
|
||||
return answer;
|
||||
|
||||
#if MPW_COLOR
|
||||
// Initialize a curses screen.
|
||||
initscr();
|
||||
start_color();
|
||||
init_pair( 1, COLOR_WHITE, COLOR_BLUE );
|
||||
init_pair( 2, COLOR_BLACK, COLOR_WHITE );
|
||||
int rows, cols;
|
||||
getmaxyx( stdscr, rows, cols );
|
||||
|
||||
// Display a dialog box.
|
||||
int width = max( prompt? (int)strlen( prompt ): 0, MPW_MAX_INPUT ) + 6;
|
||||
char *version = "mpw v" stringify_def( MP_VERSION );
|
||||
mvprintw( rows - 1, (cols - (int)strlen( version )) / 2, "%s", version );
|
||||
attron( A_BOLD );
|
||||
color_set( 2, NULL );
|
||||
mvprintw( rows / 2 - 1, (cols - width) / 2, "%s%*s%s", "*", width - 2, "", "*" );
|
||||
mvprintw( rows / 2 - 1, (cols - (int)strlen( prompt )) / 2, "%s", prompt );
|
||||
color_set( 1, NULL );
|
||||
mvprintw( rows / 2 + 0, (cols - width) / 2, "%s%*s%s", "|", width - 2, "", "|" );
|
||||
mvprintw( rows / 2 + 1, (cols - width) / 2, "%s%*s%s", "|", width - 2, "", "|" );
|
||||
mvprintw( rows / 2 + 2, (cols - width) / 2, "%s%*s%s", "|", width - 2, "", "|" );
|
||||
|
||||
// Read response.
|
||||
color_set( 2, NULL );
|
||||
attron( A_STANDOUT );
|
||||
int result = ERR;
|
||||
char str[MPW_MAX_INPUT + 1];
|
||||
if (silent) {
|
||||
mvprintw( rows / 2 + 1, (cols - 5) / 2, "[ * ]" );
|
||||
refresh();
|
||||
|
||||
noecho();
|
||||
result = mvgetnstr( rows / 2 + 1, (cols - 1) / 2, str, MPW_MAX_INPUT );
|
||||
echo();
|
||||
} else {
|
||||
mvprintw( rows / 2 + 1, (cols - (MPW_MAX_INPUT + 2)) / 2, "%*s", MPW_MAX_INPUT + 2, "" );
|
||||
refresh();
|
||||
|
||||
echo();
|
||||
result = mvgetnstr( rows / 2 + 1, (cols - MPW_MAX_INPUT) / 2, str, MPW_MAX_INPUT );
|
||||
}
|
||||
attrset( 0 );
|
||||
endwin();
|
||||
|
||||
return result == ERR? NULL: mpw_strndup( str, MPW_MAX_INPUT );
|
||||
#else
|
||||
// Get password from terminal.
|
||||
fprintf( stderr, "%s ", prompt );
|
||||
|
||||
@@ -113,31 +160,19 @@ const char *mpw_getline(const char *prompt) {
|
||||
// Remove trailing newline.
|
||||
answer[lineSize - 1] = '\0';
|
||||
return answer;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *mpw_getline(const char *prompt) {
|
||||
|
||||
return _mpw_getline( prompt, false );
|
||||
}
|
||||
|
||||
/** Ask the user for a password.
|
||||
* @return A newly allocated string or NULL if an error occurred trying to read from the user. */
|
||||
const char *mpw_getpass(const char *prompt) {
|
||||
|
||||
// Get password from askpass.
|
||||
const char *password = mpw_askpass( prompt );
|
||||
if (password)
|
||||
return password;
|
||||
|
||||
// Get password from terminal.
|
||||
char *answer = getpass( prompt );
|
||||
if (!answer)
|
||||
return NULL;
|
||||
|
||||
password = mpw_strdup( answer );
|
||||
mpw_zero( answer, strlen( answer ) );
|
||||
return password;
|
||||
return _mpw_getline( prompt, true );
|
||||
}
|
||||
|
||||
/** Get the absolute path to the mpw configuration file with the given prefix name and file extension.
|
||||
* Resolves the file <prefix.extension> as located in the <.mpw.d> directory inside the user's home directory
|
||||
* or current directory if it couldn't be resolved.
|
||||
* @return A newly allocated string. */
|
||||
const char *mpw_path(const char *prefix, const char *extension) {
|
||||
|
||||
// Resolve user's home directory.
|
||||
@@ -180,8 +215,6 @@ const char *mpw_path(const char *prefix, const char *extension) {
|
||||
return path;
|
||||
}
|
||||
|
||||
/** mkdir all the directories up to the directory of the given file path.
|
||||
* @return true if the file's path exists. */
|
||||
bool mpw_mkdirs(const char *filePath) {
|
||||
|
||||
if (!filePath)
|
||||
@@ -215,8 +248,6 @@ bool mpw_mkdirs(const char *filePath) {
|
||||
return success;
|
||||
}
|
||||
|
||||
/** Read until EOF from the given file descriptor.
|
||||
* @return A newly allocated string or NULL if the read buffer couldn't be allocated or an error occurred. */
|
||||
char *mpw_read_fd(int fd) {
|
||||
|
||||
char *buf = NULL;
|
||||
@@ -230,8 +261,6 @@ char *mpw_read_fd(int fd) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
/** Read the file contents of a given file.
|
||||
* @return A newly allocated string or NULL if the read buffer couldn't be allocated. */
|
||||
char *mpw_read_file(FILE *file) {
|
||||
|
||||
if (!file)
|
||||
@@ -245,3 +274,73 @@ char *mpw_read_file(FILE *file) {
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
#if MPW_COLOR
|
||||
static char *str_tputs;
|
||||
static int str_tputs_cursor;
|
||||
static const int str_tputs_max = 256;
|
||||
|
||||
static bool mpw_setupterm() {
|
||||
|
||||
if (!isatty( STDERR_FILENO ))
|
||||
return false;
|
||||
|
||||
static bool termsetup;
|
||||
if (!termsetup) {
|
||||
int errret;
|
||||
if (!(termsetup = (setupterm( NULL, STDERR_FILENO, &errret ) == OK))) {
|
||||
wrn( "Terminal doesn't support color (setupterm errret %d).\n", errret );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int mpw_tputc(int c) {
|
||||
|
||||
if (++str_tputs_cursor < str_tputs_max) {
|
||||
str_tputs[str_tputs_cursor] = (char)c;
|
||||
return OK;
|
||||
}
|
||||
|
||||
return ERR;
|
||||
}
|
||||
|
||||
static char *mpw_tputs(const char *str, int affcnt) {
|
||||
|
||||
if (str_tputs)
|
||||
mpw_free( &str_tputs, str_tputs_max );
|
||||
str_tputs = calloc( str_tputs_max, sizeof( char ) );
|
||||
str_tputs_cursor = -1;
|
||||
|
||||
char *result = tputs( str, affcnt, mpw_tputc ) == ERR? NULL: mpw_strndup( str_tputs, str_tputs_max );
|
||||
if (str_tputs)
|
||||
mpw_free( &str_tputs, str_tputs_max );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
const char *mpw_identicon_str(MPIdenticon identicon) {
|
||||
|
||||
char *colorString, *resetString;
|
||||
#ifdef MPW_COLOR
|
||||
if (mpw_setupterm()) {
|
||||
colorString = mpw_tputs( tparm( tgetstr( "AF", NULL ), identicon.color ), 1 );
|
||||
resetString = mpw_tputs( tgetstr( "me", NULL ), 1 );
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
colorString = calloc( 1, sizeof( char ) );
|
||||
resetString = calloc( 1, sizeof( char ) );
|
||||
}
|
||||
|
||||
const char *str = mpw_str( "%s%s%s%s%s%s",
|
||||
colorString, identicon.leftArm, identicon.body, identicon.rightArm, identicon.accessory, resetString );
|
||||
mpw_free_strings( &colorString, &resetString, NULL );
|
||||
|
||||
return mpw_strdup( str );
|
||||
}
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "mpw-types.h"
|
||||
|
||||
#ifndef MP_VERSION
|
||||
#define MP_VERSION ?
|
||||
@@ -62,3 +63,7 @@ char *mpw_read_fd(int fd);
|
||||
/** Read the file contents of a given file.
|
||||
* @return A newly allocated string or NULL the read buffer couldn't be allocated. */
|
||||
char *mpw_read_file(FILE *file);
|
||||
|
||||
/** Encode a visual fingerprint for a user.
|
||||
* @return A newly allocated string. */
|
||||
const char *mpw_identicon_str(MPIdenticon identicon);
|
||||
|
@@ -564,7 +564,7 @@ void cli_question(Arguments __unused *args, Operation *operation) {
|
||||
|
||||
void cli_operation(Arguments __unused *args, Operation *operation) {
|
||||
|
||||
operation->identicon = mpw_identicon( operation->user->fullName, operation->user->masterPassword );
|
||||
operation->identicon = mpw_identicon_str( mpw_identicon( operation->user->fullName, operation->user->masterPassword ) );
|
||||
|
||||
if (!operation->site)
|
||||
abort();
|
||||
|
Reference in New Issue
Block a user