MATLAB to read in a password

1.5k views Asked by At

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:

  • I have to account for windows as well as linux/mac users.
  • I can't be assured of any programs (perl/python/VBS) in the user system.

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?

2

There are 2 answers

5
Amro On BEST ANSWER

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

screenshot

It should be straightforward to do something similar in Java using Swing's JPasswordField

12
jmetz On

Java getPassword

I haven't yet managed to get the getPassword approach to return the console to the normal state - I'm assuming your code looks something like:

import java.lang.*
cs = System.console()
a = cs.readPassword()

Could you confirm this?

Python solution

If the solution has to be multi-platform, and you don't mind Python being a dependency, I would suggest writing a very simple python script and using this with a Matlab system call, something like

file: usergetpass.py

import getpass
import os
os.sys.stdout.write(getpass.getpass())

then in matlab

[status,pass] = system('python usergetpass.py');

You would then have to (trivially) parse pass though, the actual password is contained on line 3 of pass.

So you could put the above into your own mini matlab function,

function out = getpass()
[status, pass] = system('python usergetpass.py');
out = pass(13:end-1);

Note: I can use this because the password always occurs at that point in the pass variable.