How to get a password with a CLI program? - c++

I am writing a Linux CLI program. I need to get a password from the user and, obviously, I don't want the password to be echoed to the console.
There are several solutions available here, but they are all for plain C.
C command-line password input
How to mask password in c?
Getting a password in C without using getpass (3)?
How can those be adapted for C++, using std::string instead of char[]?
What would be the most elegant C++ solution?

Use any of the plain C solutions:
std::string pass (100); // size the string at your max password size (minus one)
func_to_get_pass(&pass[0], pass.size());
// function takes a char* and the max size to write (including a null char)
pass.resize(pass.find('\0'));
cout << "Your password is " << pass << ".\n"; // oops! don't show it ;)

Linux itself is written (mostly) in C, so anything you could find in C++ would only be an abstraction around a single C routine. Better to call the routine yourself, converting the input and result.

Related

Overwrite std::cin read-buffer after reading password

After reading a password from std::cin
std::cout << "Password: ";
SecureString pw{}; // secure string, wipes automatically on destruction
SetConsoleEcho(false); // hide input in terminal
std::getline(std::cin, pw); // input the password
SetConsoleEcho(true); // switch echo back on
the password stays stored in the read buffer of cin (heap memory) until it is overwritten with new input and can easily be sniffed with tools like Process Hacker or would be written to disk in case of a memory dump.
Does anyone know how the std::cin.rdbuf() can be cleared/overwritten, ideally in a cross-platform way? Or is there a way how to avoid using the buffer in the first place?
The above code uses SecureString which is implemented using Crypto++'s AllocatorWithCleanup which wipes memory at destruction. SetConsoleEcho switches the console echo on/off in order to avoid seeing the plain text password on screen.
I realize this question is very similar to this one but it's been over 10 years and the accepted answer actually does not answer the question.
The linked post has all the answers you need and unfortunately there isn't a way to securely read and then clear the password with 0 risk of it being exposed. See
Even if you scribble over the buffer immediately, it's still possible the password is written to disk. A system i/o buffer might be paged to disk, as might the working memory which std::cin is in. I used to develop forensic software which sniffed out exactly these conditions.
Furthermore if a malicious actor has access to the PC a keylogger can just be used to extract the password.
Or is there a way how to avoid using the buffer in the first place?
I found a cross-platform way (Linux, Mac, Windows) how to avoid the read buffer of cin using a readline replacement library. I used replxx but other readline replacement libraries will likely do as well.
I created a simple wrapper class PasswordInput around replxx that clears its input buffer on every key stroke and stores the entered password in a secure string using Crypto++'s AllocatorWithCleanup. The secure string is automatically wiped after a password digest is created, thus leaving no copy of the plain password in process memory.
All this achieves is to avoid having the plain password in process memory for longer than needed. It does not guard against keyloggers nor against the possibility of leaking the password if the process crashes while calculating the digest nor against well timed sniffing attacks nor against any other possible attack vectors.
So far I've only tested on Windows and I only did basic memory sniffing tests using Process Hacker. These showed no trace of the plain password (contrary to using std::cin)
Header file:
using SecureString =
std::basic_string<char, std::char_traits<char>, CryptoPP::AllocatorWithCleanup<char>>;
class PasswordInput {
public:
PasswordInput();
void Read(const std::string& prompt);
inline const SecureString& Secret() const { return secret_; }
private:
void RxPwModifyCb(std::string& line, int& pos);
Replxx rx_;
SecureString secret_;
};
Implementation:
namespace ph = std::placeholders;
PasswordInput::PasswordInput() :
rx_{}
{
rx_.set_modify_callback(std::bind(&PasswordInput::RxPwModifyCb, this, ph::_1, ph::_2));
}
void PasswordInput::Read(const std::string& prompt)
{
char const* cinput{nullptr};
do
{
cinput = rx_.input(prompt);
} while ((cinput == nullptr) && (errno == EAGAIN));
}
void PasswordInput::RxPwModifyCb(std::string& line, int& pos)
{
if (!line.empty())
{
secret_.append(1, line[0]);
line.clear();
}
}
Usage:
PasswordInput pwi{}; // create password input handler
pwi.Read("Password: "); // read the password
std::cout << "\x1b[A" << "\33[2K\r"; // go one line up, delete line and go to beginning (does nothing in terms of security but looks cool)
CalculatePassphrase(pwi.Secret().c_str(), pwi.Secret().size()); // Scrypt, pbkdf2, etc..
Please note this is not complete code and it needs replxx and Crypto++ libraries linked

c++ password storage .txt file + masking input

I'm pretty new to programming - just starting out with C++. So I wanted to make an application - just for fun - which would mask user input with asterisks. I did some research and found exactly what I was looking for. As you can see inside the code below it works fine but only checks password from a char I put - "correct_password". I thought it'd be more challenging to extend options. The program would write two options out: 1. register - just put your login and password (without asterisks), then store it into a file (fstream I guess), 2. login - after putting login and password (with asterisks just the way it is in getpass) it would check the file for data if user is actually registered. Even thought maybe about encrypting data in that file, although I have no idea how to proceed. Well, it's just made up thing to learn some new stuff, I know it's not really a THING and there's no really a purpose to write such code - just messing around with C++. Maybe you got some ideas how to snap that? After I wrote this asterisk thing i don't really see where I should put those other options, storing in file and so on. Would love to go through some ideas and appreciate the input from more experienced coders :)
I tried using fstream inside getpass but didn't work out. Generally I'd like to extend this program with login and password input, storing them into .txt file and then program would check if user is registered and while logging with this data input would be masked with asterisks - just like my first idea of that program which is only masking password input. I don't really know how to split unmasked input with that inside getpass.
#include <iostream>
#include <string>
#include <windows.h>
using namespace std;
string getpass(const char *dat, bool s_asterisk=true)
{
const char BACKSPACE=8;
const char RETURN=13;
string password;
unsigned char ch=0;
cout << dat;
DWORD con_mode;
DWORD dwRead;
HANDLE hIn=GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode( hIn, &con_mode );
SetConsoleMode( hIn, con_mode & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT) );
while(ReadConsoleA( hIn, &ch, 1, &dwRead, NULL) && ch !=RETURN)
{
if(ch==BACKSPACE)
{
if(password.length()!=0)
{
if(s_asterisk)
cout <<"\b \b";
password.resize(password.length()-1);
}
}
else
{
password+=ch;
if(s_asterisk)
cout <<'*';
}
}
cout << endl;
return password;
}
int main()
{
const char *correct_password="fdsidfjsijdsf21128321873";
START:
string password=getpass("Enter the password: ",true);
if(password==correct_password){
cout <<"\nCorrect password."<<endl;
exit(1);
}else{
cout <<"\nIncorrect password. Try again.\n"<<endl;
goto START;
}
return 0;
}
Usually you don't want to store actual passwords in a file. Although encrypting them would help security (to at least some degree), it's still generally pretty insecure and better avoided.
What you usually want to do instead is salt the password, then hash the salted password with a cryptographic hash. Then you store the salt and the hash, rather than the password itself.
Then (for the simplest case) when the user wants to log in, you repeat the same process: retrieve the salt for their password, apply the salt to the password they enter, hash the result, and finally compare that result to the value you stored. If they match, you assume the user entered the correct password. If they don't match, you know they didn't.
Note that this is only reasonable for the user logging into your application locally (or at least over a secure connection). If they might log in over an insecure connection, you need to get considerably more sophisticated still.
Another major point though: nearly all of this should happen outside getpass. getpass should do exactly one thing: read in a password from the user. Salting, hashing, storing, and so on, should all happen separately from that.

C++ ifstream from linux to arduino

original code
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
ofstream arduino_output("/dev/ttyACM0");
ifstream arduino_input("/dev/ttyACM0");
int value;
string txt;
while(cin >> value){
arduino_output << value << endl;
arduino_input >> txt;//I never recieve the "OK" (Which I should get)
cout << txt;
}
arduino_input.close();
arduino_output.close();
return(0);
}
Here is the problem:
cin >> value;
arduino_output << value << endl;
arduino_input >> txt;//I never recieve the "OK" (Which I should get)
cout << txt;
but if I do this instead it works:
cin >> value;
arduino_output << value << endl;
for(int i=0;i<10000;++i)
for(int j=0;j<10000;++j){ //Waste a lot of time
++value;
--value;
}
arduino_input >> txt; //I always recieve the "OK"
cout << txt; //I can see the "OK"
So how do I make my fast computer able to read the slow output from the arduino? (Without using for-loops to waste time)
Here it says some things about callback http://www.cplusplus.com/reference/ios/ios_base/register_callback/ but I could never get it to work. It says it supports 3 events, and none of them are: "If input buffer is not empty, call this function".
Because the ultimate solution would be a callback function for whenever the input buffer is not empty.
An acceptable solution would be a c++ equivalent version of the arduino version "Serial.available()".
Another acceptable solution would be anything that forces me to not rely on two for-loops. 3 for-loops is not acceptable if that's what you're thinking.
EDIT1: Showed the original code
EDIT2: I am using linux(lubuntu)
EDIT3: Someone got confused where the code was written. Strange.
If your arduino board is connected -e.g. by some cable- to a Linux laptop and your C++
program is on the Linux side (so not running on the Arduino microcontroller, which you did program in free-standing C), you'll better use directly syscalls(2) and low-level IO (not C++ ifstream which adds some buffering) such as open(2) & read(2) & write(2) & close(2).
Read Advanced Linux Programming. Consider using termios(3) to perhaps set your tty (demystified here) in raw mode. Use poll(2) to multiplex (and wait for) input (or ability to output), e.g. like Serial.available() does inside the Arduino.
Some event loop libraries (e.g. libevent or libev) provide callbacks, but you can make your own event loop around poll.
To make some delay, use perhaps usleep(3) (but very probably, you need to poll instead).
PS. If your Linux application is a graphical one using some GUI toolkit like Qt or GTK, you should use the event loop provided by that toolkit (that loop is calling poll or select, etc...). BTW, your question is not really Arduino related, but serial port related (any other device plugged on the same serial port would give the same issues).
Your problem is weird. In general, the problem is that the slower party can't read what the faster party sends. So, it seems you have a more fundamental problem here.
If arduino_output is a representation of a serial port (UART), I suggest to use a platform specific way of accessing it. On Windows, there are UART functions, and on Linux there's termios (probably on most other POSIX-like, too). This will give you a way to control the parameters of communication, and get information and/or notification about events (including parity/framing errors).

Pass a wxString into a printf-style varargs function

I am learning to code in C using K&R II. I am tired of console apps and decided to get into a GUI environment. Decided to use Code Blocks and wxWidgets. All is installed properly and working. [Windows 7 x86, Code Blocks 13.12, wxWidgets 3.0.0]
I am following the Tutorials on WxWidgets. I am in Tutorial 9. I have it working, finally; there are mistakes in the instructions.
I modified my app to have 2 text boxes and a button vs one text box for the output and one combo box for the input.
Visual C++ environment is totally foreign to me.
For the Button click I would like instead of printing, "O brave new world!\n",
I would like to read what has been entered in textbox1 and print it into textbox2.
The instruction:
wxString Text = TextCtrl1->GetValue();
gets the string that has been entered in textbox1
I have a call to the function
void printg(char *fmt, ...);
I need to know how/what to change the ... argument to so it will passes the wxString Text in the form of an array, I think, to that printg function. I am sure the first thing I need to do is change the Text string to an array, or some way to pass the string itself.
UPDATE 01/08/13 3:35 PM
I cut the code from the Textbox Enter event and pasted it into the ButtonClick event and now I can get the text in Box one to box two.
Now, I need a way to pass the text from textbox 1 to one of my C files, do whatever the exercise is about and pass it back to the click event to be passed to the printg function.
NOTE: I see confusion about printg. I think it is a feature of wxWidgets that lets you print back to a GUI form rather than a console as printf does. It works.
I would put the code on here, but I do not know how. Tried before and get a message about it not being formatted properly.
Thanks for the replies.
Text.ToUTF8().data() gives you const char *
Also if you only want char* instead of const char * you can use const_cast<char *>(Text.ToUTF8().data())
The most convenient thing to do is to use wx equivalents of standard functions, i.e. wxPrintf() in this case, because they allow you to pass wxString (and also std::string, std::wstring, char* and wchar_t*) objects directly, without doing anything special. So you could simply write
wxString s = ...;
wxPrintf("My string is %s\n", s);
OTOH using either printf() or wxPrintf() is generally not very useful in GUI applications, you probably want wxLogMessage() or something similar.
If you have a string: char *str = {"this is my string"};
Then you can use printf() like this:
printf("%s\n", str);
Note, there is no printg() in the C language. And the prototype of the printf() statement allows for multiple arguments to be passed as long as there is a format specifier for each argument. For example, this shows 3 format specifiers, and three arguments:
printf("%s %d %f\n", str, 10, 13.5);
The "..." argument is called the ellipse argument. It's covered in the K&R book, section 7.3 (in my edition anyway). It can have 0 or more arguments in it, as described by the *fmt argument.
If you already have a string ready, just call it like this:
printf("%s",str);

How to input a char or a string without hitting the return key

I'm learning Objective C using Foundation and printing to the console. I would like to know (and how) if it is possible to input a char or string and it print out automatically without hitting the return key (or any key). Obviously the simple code below still requires the return key to be hit. I am aware this code is mixed between C & objC but I've been trying out differnet ideas. I am also trying to do this without using Ncurses. Thanks in advance.
char input [1];
NSLog(#"enter key:");
fgets(input, 1, stdin);
NSString *inputString = [[NSString alloc]initWithCString:input];
NSLog(#"Input = %s",input);
Ive just found a good answer as follows:
// Set terminal to raw mode
system("stty raw");
// Wait for single character
char input = getchar();
// Echo input:
// Reset terminal to normal "cooked" mode
system("stty cooked");
// And we're out of here
NSLog(#"INPUT = %c",input);
Read the manual for tcsetattr and tcgetattr. Look for the flags ICANON and IECHO, and check out the part about cfmakeraw. The documentation console_ioctl(4) and tty_ioctl(4) may be of further interest, for example to determine the size of the tty.
Have a look at http://pwilson.net/sample.html and search for kbhit.c . That function should work for you, though it's not been tested with Objective C.