I'm building a MATLAB application that authenticates a user's credentials. I want to read in his password, and I want to hide his typed credentials somehow.
Some constraints:
Here's what I've tried:
Straight-up GUIDE
Works, but not an option as the user is likely to be running matlab in -nodesktop
(or -nodisplay
) mode.
MATLAB + Java
console.readPassword. This messes up my terminal horribly.
system() calls
Essentially I call bash or dos scripts based on OS.
I have the following call for linux/mac:
[status cred] = system('stty -echo; read cred; stty echo;echo ""; echo "$cred"');
This is supposed to pick up the user credentials and dump that on to 'cred'. I've checked that it works in the regular terminal, but executing it in MATLAB causes nothing to be output, and a Ctrl-C is required to bring back the >>
prompt.
MATLAB Perl
The Windows MATLAB packages Perl, as pointed out in comments. I tried the following snippet:
use Term::ReadKey;
use Term::ReadLine;
ReadMode('noecho');
$yesnoline = Term::ReadLine->new("foo");
$pass = $yesnoline->readline();
printf "$pass";
ReadMode('restore');
And then called it as [result status] = perl('my_perl.pl')
. Works great on Linux.
On Windows:
res =
GetConsoleMode failed, LastError=|6| at ReadKey.pm line 264.
sta =
9
My searches so far suggest that it's a problem related to the packaged version of perl for windows.
Any idea what's happening in the above approaches?
I suggest that you detect Windows installation (ispc
), and handle them differently than Unix-like systems, by creating a MATLAB GUI or something similar..
Here is one possible solution for Windows using .NET Windows Forms from inside MATLAB:
function pass = getPasswordNET()
%# password return value
pass = '';
%# hidden figure used to wait for button press
fig = figure('Visible','off', ...
'IntegerHandle','off', 'HandleVisibility','off');
%# create and show the Windows Forms GUI
[handles,lh] = InitializeComponents();
handles.frm.Show();
%# block execution until figure is closed
waitfor(fig)
%# remove the listeners
delete(lh);
return;
%# create GUI
function [handles,lh] = InitializeComponents()
%# import assembly
NET.addAssembly('System.Windows.Forms');
%# form
frm = System.Windows.Forms.Form();
frm.SuspendLayout();
%# textbox
tb = System.Windows.Forms.TextBox();
tb.Dock = System.Windows.Forms.DockStyle.Fill;
tb.Text = '';
tb.PasswordChar = '*';
tb.MaxLength = 14;
%# button
bt = System.Windows.Forms.Button();
bt.Dock = System.Windows.Forms.DockStyle.Bottom;
bt.Text = 'Submit';
%# setup the form
frm.Text = 'Password';
frm.ClientSize = System.Drawing.Size(250, 40);
frm.Controls.Add(tb);
frm.Controls.Add(bt);
frm.ResumeLayout(false);
frm.PerformLayout();
%# add event listeners
lh(1) = addlistener(bt, 'Click', @onClick);
lh(2) = addlistener(frm, 'FormClosing', @onClose);
%# return handles structure
handles = struct('frm',frm, 'tb',tb, 'bt',bt);
end
%# event handlers
function onClick(~,~)
%# get password from textbox
pass = char(handles.tb.Text);
%# close form
handles.frm.Close();
end
function onClose(~,~)
%# delete hidden figure (to unblock and return from function)
close(fig)
end
end
I tested the above on my machine, and it worked even when MATLAB was started in headless mode:
matlab.exe -nodesktop -noFigureWindows
then called it as:
>> pass = getPasswordNET()
pass =
secret_password
It should be straightforward to do something similar in Java using Swing's JPasswordField