From 877f04fed50172751a9beb3172286f1cecceddfa Mon Sep 17 00:00:00 2001 From: Jochen Topf Date: Mon, 17 May 2021 16:04:48 +0200 Subject: [PATCH] Modernize the password prompt code Note that this hasn't been tested on anything but a Linux system. --- src/CMakeLists.txt | 1 - src/options.cpp | 7 +- src/sprompt.cpp | 187 --------------------------------------------- src/sprompt.hpp | 15 ---- src/util.cpp | 40 ++++++++++ src/util.hpp | 2 + 6 files changed, 44 insertions(+), 208 deletions(-) delete mode 100644 src/sprompt.cpp delete mode 100644 src/sprompt.hpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dd44a7ed5..c863c3171 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -25,7 +25,6 @@ set(osm2pgsql_lib_SOURCES pgsql-helper.cpp progress-display.cpp reprojection.cpp - sprompt.cpp table.cpp taginfo.cpp tagtransform-c.cpp diff --git a/src/options.cpp b/src/options.cpp index d3e47fa7d..93757f4d1 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -12,7 +12,7 @@ #include "logging.hpp" #include "options.hpp" #include "reprojection.hpp" -#include "sprompt.hpp" +#include "util.hpp" #include "version.hpp" #include @@ -639,10 +639,7 @@ options_t::options_t(int argc, char *argv[]) : options_t() check_options(); if (pass_prompt) { - char const *prompt = simple_prompt("Password:", 100, 0); - if (prompt != nullptr) { - database_options.password = prompt; - } + database_options.password = util::get_password(); } } diff --git a/src/sprompt.cpp b/src/sprompt.cpp deleted file mode 100644 index ee9459e3f..000000000 --- a/src/sprompt.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/*------------------------------------------------------------------------- - * - * sprompt.c - * simple_prompt() routine - * - * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * $PostgreSQL: pgsql/src/port/sprompt.c,v 1.18 2006/10/04 00:30:14 momjian Exp $ - * - *------------------------------------------------------------------------- - * - * PostgreSQL Database Management System - * (formerly known as Postgres, then as Postgres95) - * - * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group - * - * Portions Copyright (c) 1994, The Regents of the University of California - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without a written agreement - * is hereby granted, provided that the above copyright notice and this - * paragraph and the following two paragraphs appear in all copies. - * - * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING - * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS - * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - */ - -/* - * simple_prompt - * - * Generalized function especially intended for reading in usernames and - * password interactively. Reads from /dev/tty or stdin/stderr. - * - * prompt: The prompt to print - * maxlen: How many characters to accept - * echo: Set to false if you want to hide what is entered (for passwords) - * - * Returns a malloc()'ed string with the input (w/o trailing newline). - */ - -#define DEVTTY "/dev/tty" - -#include -#include -#include -#include - -#include "config.h" - -#ifdef HAVE_TERMIOS_H -#include -#endif - -#ifdef _WIN32 -#include -#endif - -char *simple_prompt(const char *prompt, int maxlen, int echo) -{ - size_t length; - char *destination; - FILE *termin, *termout; - -#ifdef HAVE_TERMIOS_H - struct termios t_orig, t; -#else -#ifdef _WIN32 - HANDLE t = NULL; - DWORD t_orig; -#endif -#endif - - destination = static_cast(malloc(maxlen + 1)); - if (!destination) { - return NULL; - } - - /* - * Do not try to collapse these into one "w+" mode file. Doesn't work on - * some platforms (eg, HPUX 10.20). - */ - termin = fopen(DEVTTY, "r"); - termout = fopen(DEVTTY, "w"); - if (!termin || - !termout -#ifdef _WIN32 - /* See DEVTTY comment for msys */ - || (getenv("OSTYPE") && strcmp(getenv("OSTYPE"), "msys") == 0) -#endif - ) { - if (termin) { - fclose(termin); - } - if (termout) { - fclose(termout); - } - termin = stdin; - termout = stderr; - } - -#ifdef HAVE_TERMIOS_H - if (!echo) { - tcgetattr(fileno(termin), &t); - t_orig = t; - t.c_lflag &= ~ECHO; - tcsetattr(fileno(termin), TCSAFLUSH, &t); - } -#else -#ifdef _WIN32 - if (!echo) { - /* get a new handle to turn echo off */ - t = GetStdHandle(STD_INPUT_HANDLE); - - /* save the old configuration first */ - GetConsoleMode(t, &t_orig); - - /* set to the new mode */ - SetConsoleMode(t, ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT); - } -#endif -#endif - - if (prompt) { - fputs(prompt, termout); - fflush(termout); - } - - if (fgets(destination, maxlen + 1, termin) == NULL) { - destination[0] = '\0'; - } - - length = strlen(destination); - if (length > 0 && destination[length - 1] != '\n') { - /* eat rest of the line */ - char buf[128]; - size_t buflen; - - do { - if (fgets(buf, sizeof(buf), termin) == NULL) { - break; - } - buflen = strlen(buf); - } while (buflen > 0 && buf[buflen - 1] != '\n'); - } - - if (length > 0 && destination[length - 1] == '\n') { - /* remove trailing newline */ - destination[length - 1] = '\0'; - } - -#ifdef HAVE_TERMIOS_H - if (!echo) { - tcsetattr(fileno(termin), TCSAFLUSH, &t_orig); - fputs("\n", termout); - fflush(termout); - } -#else -#ifdef _WIN32 - if (!echo) { - /* reset to the original console mode */ - SetConsoleMode(t, t_orig); - fputs("\n", termout); - fflush(termout); - } -#endif -#endif - - if (termin != stdin) { - fclose(termin); - fclose(termout); - } - - return destination; -} diff --git a/src/sprompt.hpp b/src/sprompt.hpp deleted file mode 100644 index 2ca8ee35e..000000000 --- a/src/sprompt.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef OSM2PGSQL_SPROMPT_HPP -#define OSM2PGSQL_SPROMPT_HPP - -/** - * SPDX-License-Identifier: GPL-2.0-or-later - * - * This file is part of osm2pgsql (https://osm2pgsql.org/). - * - * Copyright (C) 2006-2021 by the osm2pgsql developer community. - * For a full list of authors see the git log. - */ - -char *simple_prompt(const char *prompt, int maxlen, int echo); - -#endif // OSM2PGSQL_SPROMPT_HPP diff --git a/src/util.cpp b/src/util.cpp index 46bb3fbe9..134abbc5c 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -7,8 +7,19 @@ * For a full list of authors see the git log. */ +#include "config.h" + #include "util.hpp" +#include + +#ifdef _WIN32 +#include +#elif defined(HAVE_TERMIOS_H) +#include +#include +#endif + namespace util { void string_id_list_t::add(osmid_t id) @@ -44,4 +55,33 @@ std::string human_readable_duration(std::chrono::milliseconds ms) std::chrono::duration_cast(ms).count())); } +std::string get_password() +{ +#ifdef _WIN32 + HANDLE const handle_stdin = GetStdHandle(STD_INPUT_HANDLE); + DWORD mode = 0; + GetConsoleMode(handle_stdin, &mode); + SetConsoleMode(handle_stdin, mode & (~ENABLE_ECHO_INPUT)); +#elif defined(HAVE_TERMIOS_H) + termios orig_flags; + tcgetattr(STDIN_FILENO, &orig_flags); + termios flags = orig_flags; + flags.c_lflag &= ~static_cast(ECHO); + tcsetattr(STDIN_FILENO, TCSANOW, &flags); +#endif + + std::string password; + std::cout << "Password:"; + std::getline(std::cin, password); + std::cout << "\n"; + +#ifdef _WIN32 + SetConsoleMode(handle_stdin, mode); +#elif defined(HAVE_TERMIOS_H) + tcsetattr(STDIN_FILENO, TCSANOW, &orig_flags); +#endif + + return password; +} + } // namespace util diff --git a/src/util.hpp b/src/util.hpp index c5fd015eb..64c7d1224 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -126,6 +126,8 @@ std::string human_readable_duration(uint64_t seconds); std::string human_readable_duration(std::chrono::milliseconds ms); +std::string get_password(); + } // namespace util #endif // OSM2PGSQL_UTIL_HPP