diff --git a/apps/mosquitto_passwd/CMakeLists.txt b/apps/mosquitto_passwd/CMakeLists.txt index 86f023cc..13a7d826 100644 --- a/apps/mosquitto_passwd/CMakeLists.txt +++ b/apps/mosquitto_passwd/CMakeLists.txt @@ -5,6 +5,7 @@ include_directories(${mosquitto_SOURCE_DIR} ${mosquitto_SOURCE_DIR}/include if (WITH_TLS) add_executable(mosquitto_passwd mosquitto_passwd.c + get_password.c get_password.h ../../lib/memory_mosq.c ../../lib/memory_mosq.h ../../src/memory_public.c ../../lib/misc_mosq.c diff --git a/apps/mosquitto_passwd/Makefile b/apps/mosquitto_passwd/Makefile index 1c8381fd..3238cf3e 100644 --- a/apps/mosquitto_passwd/Makefile +++ b/apps/mosquitto_passwd/Makefile @@ -3,6 +3,7 @@ include ../../config.mk .PHONY: all install uninstall clean reallyclean OBJS= mosquitto_passwd.o \ + get_password.o \ memory_mosq.o \ memory_public.o \ misc_mosq.o \ @@ -20,6 +21,9 @@ mosquitto_passwd : ${OBJS} mosquitto_passwd.o : mosquitto_passwd.c ${CROSS_COMPILE}${CC} $(APP_CPPFLAGS) $(APP_CFLAGS) -c $< -o $@ +get_password.o : get_password.c + ${CROSS_COMPILE}${CC} $(APP_CPPFLAGS) $(APP_CFLAGS) -c $< -o $@ + memory_mosq.o : ../../lib/memory_mosq.c ${CROSS_COMPILE}${CC} $(APP_CPPFLAGS) $(APP_CFLAGS) -c $< -o $@ diff --git a/apps/mosquitto_passwd/get_password.c b/apps/mosquitto_passwd/get_password.c new file mode 100644 index 00000000..67fe9cda --- /dev/null +++ b/apps/mosquitto_passwd/get_password.c @@ -0,0 +1,135 @@ +/* +Copyright (c) 2012-2020 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#include "config.h" + +#include +#include +#include + +#ifdef WIN32 +# include +# include +# define snprintf sprintf_s +# include +# include +#else +# include +# include +# include +#endif + +#define MAX_BUFFER_LEN 65536 +#define SALT_LEN 12 + +void get_password__reset_term(void) +{ +#ifndef WIN32 + struct termios ts; + + tcgetattr(0, &ts); + ts.c_lflag |= ECHO | ICANON; + tcsetattr(0, TCSANOW, &ts); +#endif +} + + +static int gets_quiet(char *s, int len) +{ +#ifdef WIN32 + HANDLE h; + DWORD con_orig, con_quiet = 0; + DWORD read_len = 0; + + memset(s, 0, len); + h = GetStdHandle(STD_INPUT_HANDLE); + GetConsoleMode(h, &con_orig); + con_quiet = con_orig; + con_quiet &= ~ENABLE_ECHO_INPUT; + con_quiet |= ENABLE_LINE_INPUT; + SetConsoleMode(h, con_quiet); + if(!ReadConsole(h, s, len, &read_len, NULL)){ + SetConsoleMode(h, con_orig); + return 1; + } + while(s[strlen(s)-1] == 10 || s[strlen(s)-1] == 13){ + s[strlen(s)-1] = 0; + } + if(strlen(s) == 0){ + return 1; + } + SetConsoleMode(h, con_orig); + + return 0; +#else + struct termios ts_quiet, ts_orig; + char *rs; + + memset(s, 0, (size_t)len); + tcgetattr(0, &ts_orig); + ts_quiet = ts_orig; + ts_quiet.c_lflag &= (unsigned int)(~(ECHO | ICANON)); + tcsetattr(0, TCSANOW, &ts_quiet); + + rs = fgets(s, len, stdin); + tcsetattr(0, TCSANOW, &ts_orig); + + if(!rs){ + return 1; + }else{ + while(s[strlen(s)-1] == 10 || s[strlen(s)-1] == 13){ + s[strlen(s)-1] = 0; + } + if(strlen(s) == 0){ + return 1; + } + } + return 0; +#endif +} + +int get_password(const char *prompt, const char *verify_prompt, char *password, size_t len) +{ + char pw1[MAX_BUFFER_LEN], pw2[MAX_BUFFER_LEN]; + size_t minLen; + minLen = len < MAX_BUFFER_LEN ? len : MAX_BUFFER_LEN; + + printf("%s", prompt); + fflush(stdout); + if(gets_quiet(pw1, (int)minLen)){ + fprintf(stderr, "Error: Empty password.\n"); + return 1; + } + printf("\n"); + + if(verify_prompt){ + printf("%s", verify_prompt); + fflush(stdout); + if(gets_quiet(pw2, (int)minLen)){ + fprintf(stderr, "Error: Empty password.\n"); + return 1; + } + printf("\n"); + + if(strcmp(pw1, pw2)){ + fprintf(stderr, "Error: Passwords do not match.\n"); + return 1; + } + } + + strncpy(password, pw1, minLen); + return 0; +} diff --git a/apps/mosquitto_passwd/get_password.h b/apps/mosquitto_passwd/get_password.h new file mode 100644 index 00000000..7e116125 --- /dev/null +++ b/apps/mosquitto_passwd/get_password.h @@ -0,0 +1,22 @@ +#ifndef GET_PASSWORD_H +#define GET_PASSWORD_H +/* +Copyright (c) 2012-2020 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +void get_password__reset_term(void); +int get_password(const char *prompt, const char *verify_prompt, char *password, size_t len); + +#endif diff --git a/apps/mosquitto_passwd/mosquitto_passwd.c b/apps/mosquitto_passwd/mosquitto_passwd.c index 827047de..3a1f0c89 100644 --- a/apps/mosquitto_passwd/mosquitto_passwd.c +++ b/apps/mosquitto_passwd/mosquitto_passwd.c @@ -24,6 +24,7 @@ Contributors: #include #include +#include "get_password.h" #include "password_mosq.h" #ifdef WIN32 @@ -312,91 +313,6 @@ int update_pwuser(FILE *fptr, FILE *ftmp, const char *username, const char *pass } -int gets_quiet(char *s, int len) -{ -#ifdef WIN32 - HANDLE h; - DWORD con_orig, con_quiet = 0; - DWORD read_len = 0; - - memset(s, 0, len); - h = GetStdHandle(STD_INPUT_HANDLE); - GetConsoleMode(h, &con_orig); - con_quiet = con_orig; - con_quiet &= ~ENABLE_ECHO_INPUT; - con_quiet |= ENABLE_LINE_INPUT; - SetConsoleMode(h, con_quiet); - if(!ReadConsole(h, s, len, &read_len, NULL)){ - SetConsoleMode(h, con_orig); - return 1; - } - while(s[strlen(s)-1] == 10 || s[strlen(s)-1] == 13){ - s[strlen(s)-1] = 0; - } - if(strlen(s) == 0){ - return 1; - } - SetConsoleMode(h, con_orig); - - return 0; -#else - struct termios ts_quiet, ts_orig; - char *rs; - - memset(s, 0, (size_t)len); - tcgetattr(0, &ts_orig); - ts_quiet = ts_orig; - ts_quiet.c_lflag &= (unsigned int)(~(ECHO | ICANON)); - tcsetattr(0, TCSANOW, &ts_quiet); - - rs = fgets(s, len, stdin); - tcsetattr(0, TCSANOW, &ts_orig); - - if(!rs){ - return 1; - }else{ - while(s[strlen(s)-1] == 10 || s[strlen(s)-1] == 13){ - s[strlen(s)-1] = 0; - } - if(strlen(s) == 0){ - return 1; - } - } - return 0; -#endif -} - -int get_password(char *password, size_t len) -{ - char pw1[MAX_BUFFER_LEN], pw2[MAX_BUFFER_LEN]; - size_t minLen; - minLen = len < MAX_BUFFER_LEN ? len : MAX_BUFFER_LEN; - - printf("Password: "); - fflush(stdout); - if(gets_quiet(pw1, (int)minLen)){ - fprintf(stderr, "Error: Empty password.\n"); - return 1; - } - printf("\n"); - - printf("Reenter password: "); - fflush(stdout); - if(gets_quiet(pw2, (int)minLen)){ - fprintf(stderr, "Error: Empty password.\n"); - return 1; - } - printf("\n"); - - if(strcmp(pw1, pw2)){ - fprintf(stderr, "Error: Passwords do not match.\n"); - return 1; - } - - strncpy(password, pw1, minLen); - return 0; -} - int copy_contents(FILE *src, FILE *dest) { char buf[MAX_BUFFER_LEN]; @@ -442,15 +358,10 @@ int create_backup(const char *backup_file, FILE *fptr) rewind(fptr); return 0; } + void handle_sigint(int signal) { -#ifndef WIN32 - struct termios ts; - - tcgetattr(0, &ts); - ts.c_lflag |= ECHO | ICANON; - tcsetattr(0, TCSANOW, &ts); -#endif + get_password__reset_term(); UNUSED(signal); @@ -630,7 +541,7 @@ int main(int argc, char *argv[]) if(create_new){ if(batch_mode == false){ - rc = get_password(password, MAX_BUFFER_LEN); + rc = get_password("Password: ", "Reenter password: ", password, MAX_BUFFER_LEN); if(rc){ free(password_file); return rc; @@ -687,7 +598,7 @@ int main(int argc, char *argv[]) /* Update password for individual user */ rc = update_pwuser(fptr, ftmp, username, password_cmd, iterations); }else{ - rc = get_password(password, MAX_BUFFER_LEN); + rc = get_password("Password: ", "Reenter password: ", password, MAX_BUFFER_LEN); if(rc){ fclose(fptr); fclose(ftmp);