Hallo Community,
Ich entwickele zur Zeit eine Konsolenanwendung die auf einem Raspberry läuft. Die gesamte Eingabe/Ausgang erfolgt somit über die Konsole.
Ich habe ein Thread erstellt welcher sich um die Eingabe kümmert realisiert mit einem Scanner. Funktioniert wunderbar nun ist es so das die Anwendung gegen unbefugten Benutzen geschützt sein soll. Daher hab ich ein Systempasswort mit einprogrammiert. Dieses muss der Nutzer wenn die Anwendung gestartet wird eingeben bevor er überhaupt auf das eigentlich Programm zugreifen kann.
Damit die Passworteingabe nicht sichtbar ist in der Konsole verwende ich die readPassword() Funktion aus der java.io.Console Klasse. Und da ist genau das Problem. Wenn die Anwendung startet greift die Software erst auf readPassword zu und der Scanner Thread läuft noch nicht es funktioniert alles wie es soll. Nutzt der Nutzer den "logout" Befehl wird er abgemeldet und der Scanner Thread kann ganz normal über ein Flag unterbrochen werden bevor der Scanner wieder bei scanner.hasNextLine() ankommt.
Nun jetzt könnte man ja vergessen sich mit "logout" abzumelden also hab ich noch ein Logout Timer hinzugefügt der nach X Minuten den Nutzer automatisch abmeldet. Und hier kommt das Problem, sobald der Logout Timer auslöst wird das Flag für den Scanner Thread gesetzt jedoch bleibt der Scanner Thread ja so lange aktiv bis er wieder eine neue Zeile bekommt und erst dann würde sich der Thread beenden.
Bedeutet also für mich das die readPassword() Funktion noch nicht greift und das Passwort beim eingeben sichtbar ist weil es vom Scanner Thread ausgewertet wird. Erst dann läuft die Anmeldung über die readPassword() Funktion weil der Scanner Thread beendet ist.
Ich muss den Scanner Thread vorher beenden bevor ich wieder eine Anmeldung erlaube. Eine Möglichkeit wäre es den InputStream vom Scanner zuschließen mit scanner.close() nur dann kann ich den InputStream nicht wieder öffnen weil es sich dabei um System.in handelt. Ich hab schon mehreres versucht mit einer eigenen InputStream Klasse die halt das close Überschreibt und nichts macht aber das führt nicht zum gewünschten Erfolg. Auch hab ich mit PipedInput/OutputStreams versucht ein Userinput per Code auszulösen. Aber da bräuchte wieder ein Thread der den System.in Stream ausliest und den PipedInputStream füttert ...
Aktuell bleibt mir da nur die Möglichkeit den Nutzer aufzufordern erst irgendwas einzugeben um den Scanner Thread zu beenden und dann das Passwort. Was aber meiner Meinung nach eine große Sicherheitslücke darstellen würde da der Nutzer dann das Passwort versehentlich direkt eingeben könnte und es somit sichtbar wäre was verhindert werden soll.
Hat jemand ne Ahnung oder Idee wie ich Scanner block von hasNextLine oder die read Funktionen vom InputStream unterbrechen kann?
Thread.stop() ist ja veraltet und wird nicht empfohlen zu verwenden. Funktioniert bei mir auch tatsächlich nicht immer habs getestet. Die available() Funktion vom InputStream abzufragen führt bei mir dazu das ich gar keine sichtbaren Eingaben in der Konsole machen kann und wird ja auch nicht empfohlen damit zu arbeiten. Das gleiche ja mit der ready() Funktion vom BufferedReader als alternative zum Scanner.
Mfg
Ich entwickele zur Zeit eine Konsolenanwendung die auf einem Raspberry läuft. Die gesamte Eingabe/Ausgang erfolgt somit über die Konsole.
Ich habe ein Thread erstellt welcher sich um die Eingabe kümmert realisiert mit einem Scanner. Funktioniert wunderbar nun ist es so das die Anwendung gegen unbefugten Benutzen geschützt sein soll. Daher hab ich ein Systempasswort mit einprogrammiert. Dieses muss der Nutzer wenn die Anwendung gestartet wird eingeben bevor er überhaupt auf das eigentlich Programm zugreifen kann.
Damit die Passworteingabe nicht sichtbar ist in der Konsole verwende ich die readPassword() Funktion aus der java.io.Console Klasse. Und da ist genau das Problem. Wenn die Anwendung startet greift die Software erst auf readPassword zu und der Scanner Thread läuft noch nicht es funktioniert alles wie es soll. Nutzt der Nutzer den "logout" Befehl wird er abgemeldet und der Scanner Thread kann ganz normal über ein Flag unterbrochen werden bevor der Scanner wieder bei scanner.hasNextLine() ankommt.
Nun jetzt könnte man ja vergessen sich mit "logout" abzumelden also hab ich noch ein Logout Timer hinzugefügt der nach X Minuten den Nutzer automatisch abmeldet. Und hier kommt das Problem, sobald der Logout Timer auslöst wird das Flag für den Scanner Thread gesetzt jedoch bleibt der Scanner Thread ja so lange aktiv bis er wieder eine neue Zeile bekommt und erst dann würde sich der Thread beenden.
Bedeutet also für mich das die readPassword() Funktion noch nicht greift und das Passwort beim eingeben sichtbar ist weil es vom Scanner Thread ausgewertet wird. Erst dann läuft die Anmeldung über die readPassword() Funktion weil der Scanner Thread beendet ist.
Ich muss den Scanner Thread vorher beenden bevor ich wieder eine Anmeldung erlaube. Eine Möglichkeit wäre es den InputStream vom Scanner zuschließen mit scanner.close() nur dann kann ich den InputStream nicht wieder öffnen weil es sich dabei um System.in handelt. Ich hab schon mehreres versucht mit einer eigenen InputStream Klasse die halt das close Überschreibt und nichts macht aber das führt nicht zum gewünschten Erfolg. Auch hab ich mit PipedInput/OutputStreams versucht ein Userinput per Code auszulösen. Aber da bräuchte wieder ein Thread der den System.in Stream ausliest und den PipedInputStream füttert ...
Aktuell bleibt mir da nur die Möglichkeit den Nutzer aufzufordern erst irgendwas einzugeben um den Scanner Thread zu beenden und dann das Passwort. Was aber meiner Meinung nach eine große Sicherheitslücke darstellen würde da der Nutzer dann das Passwort versehentlich direkt eingeben könnte und es somit sichtbar wäre was verhindert werden soll.
Hat jemand ne Ahnung oder Idee wie ich Scanner block von hasNextLine oder die read Funktionen vom InputStream unterbrechen kann?
Thread.stop() ist ja veraltet und wird nicht empfohlen zu verwenden. Funktioniert bei mir auch tatsächlich nicht immer habs getestet. Die available() Funktion vom InputStream abzufragen führt bei mir dazu das ich gar keine sichtbaren Eingaben in der Konsole machen kann und wird ja auch nicht empfohlen damit zu arbeiten. Das gleiche ja mit der ready() Funktion vom BufferedReader als alternative zum Scanner.
Code:
started = true;
scan = new Scanner(System.in);
thread = new Thread(new Runnable() {
@Override
public void run() {
if(newInputLine) sendNewInput(); //Initial input line
while(started) { //Run until thread is interrupted
try{
if(scan.hasNextLine()) { //Got a new line from User?
line = scan.nextLine(); //Get next line
String[] args = line.split(" "); //Split string at each space char
//If the logout timer is active we reset the timer here to avoid a logout
fw.system.getPasswordManager().getLogoutTimer().resetTimer();
//Check if args length is larger then 0 (No empty input)
if(args.length > 0 && (!line.isEmpty())) {
proceedCommand(line, args[0].toLowerCase());
}else{
sendUnrecognizedCommand();
}
}
}catch(IllegalStateException | NullPointerException e) {
if(e instanceof IllegalStateException) {
if(!e.getLocalizedMessage().contains("Scanner closed")) {
e.printStackTrace();
}
}
}
}
}
}, "User input Thread");
thread.start();
Mfg