Just dispose on close and scope executors to a window, clean up on window hide.
This commit is contained in:
parent
80f507b4cc
commit
d1649f3c33
@ -116,9 +116,6 @@ public class GUI implements UnlockFrame.SignInCallback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected PasswordFrame newPasswordFrame(final User user) {
|
protected PasswordFrame newPasswordFrame(final User user) {
|
||||||
PasswordFrame frame = new PasswordFrame( user );
|
return new PasswordFrame( user );
|
||||||
frame.setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );
|
|
||||||
|
|
||||||
return frame;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,8 @@ public class ModelUser extends User {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset() {
|
public void reset() {
|
||||||
|
super.reset();
|
||||||
|
|
||||||
masterPassword = null;
|
masterPassword = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,7 +217,7 @@ public class PasswordFrame extends JFrame implements DocumentListener {
|
|||||||
site.setSiteCounter( siteCounter );
|
site.setSiteCounter( siteCounter );
|
||||||
}
|
}
|
||||||
|
|
||||||
ListenableFuture<String> passwordFuture = Res.execute( new Callable<String>() {
|
ListenableFuture<String> passwordFuture = Res.execute( this, new Callable<String>() {
|
||||||
@Override
|
@Override
|
||||||
public String call()
|
public String call()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
@ -8,9 +8,11 @@ import com.google.common.io.Resources;
|
|||||||
import com.google.common.util.concurrent.*;
|
import com.google.common.util.concurrent.*;
|
||||||
import com.lyndir.lhunath.opal.system.logging.Logger;
|
import com.lyndir.lhunath.opal.system.logging.Logger;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
import java.awt.image.ImageObserver;
|
import java.awt.image.ImageObserver;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
@ -22,7 +24,7 @@ import javax.swing.*;
|
|||||||
*/
|
*/
|
||||||
public abstract class Res {
|
public abstract class Res {
|
||||||
|
|
||||||
private static final ExecutorService executor = Executors.newSingleThreadExecutor();
|
private static final WeakHashMap<Window, ExecutorService> executorByWindow = new WeakHashMap<>();
|
||||||
private static final Logger logger = Logger.get( Res.class );
|
private static final Logger logger = Logger.get( Res.class );
|
||||||
|
|
||||||
private static Font sourceCodeProRegular;
|
private static Font sourceCodeProRegular;
|
||||||
@ -32,8 +34,8 @@ public abstract class Res {
|
|||||||
private static Font exoRegular;
|
private static Font exoRegular;
|
||||||
private static Font exoThin;
|
private static Font exoThin;
|
||||||
|
|
||||||
public static Future<?> execute(final Runnable job) {
|
public static Future<?> execute(final Window host, final Runnable job) {
|
||||||
return executor.submit( new Runnable() {
|
return getExecutor( host ).submit( new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
@ -46,7 +48,8 @@ public abstract class Res {
|
|||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <V> ListenableFuture<V> execute(final Callable<V> job) {
|
public static <V> ListenableFuture<V> execute(final Window host, final Callable<V> job) {
|
||||||
|
ExecutorService executor = getExecutor( host );
|
||||||
return JdkFutureAdapters.listenInPoolThread( executor.submit( new Callable<V>() {
|
return JdkFutureAdapters.listenInPoolThread( executor.submit( new Callable<V>() {
|
||||||
@Override
|
@Override
|
||||||
public V call()
|
public V call()
|
||||||
@ -62,6 +65,25 @@ public abstract class Res {
|
|||||||
} ), executor );
|
} ), executor );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ExecutorService getExecutor(final Window host) {
|
||||||
|
ExecutorService executor = executorByWindow.get( host );
|
||||||
|
|
||||||
|
if (executor == null) {
|
||||||
|
executorByWindow.put( host, executor = Executors.newSingleThreadExecutor() );
|
||||||
|
|
||||||
|
host.addWindowListener( new WindowAdapter() {
|
||||||
|
@Override
|
||||||
|
public void windowClosing(final WindowEvent e) {
|
||||||
|
ExecutorService executor = executorByWindow.remove( host );
|
||||||
|
if (executor != null)
|
||||||
|
executor.shutdownNow();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
return executor;
|
||||||
|
}
|
||||||
|
|
||||||
public static Icon iconAdd() {
|
public static Icon iconAdd() {
|
||||||
return new RetinaIcon( Resources.getResource( "media/icon_add@2x.png" ) );
|
return new RetinaIcon( Resources.getResource( "media/icon_add@2x.png" ) );
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,7 @@ public class UnlockFrame extends JFrame {
|
|||||||
signInButton.setEnabled( false );
|
signInButton.setEnabled( false );
|
||||||
signInButton.setText( "Signing In..." );
|
signInButton.setText( "Signing In..." );
|
||||||
|
|
||||||
Res.execute( new Runnable() {
|
Res.execute( this, new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
final boolean success = signInCallback.signedIn( user );
|
final boolean success = signInCallback.signedIn( user );
|
||||||
|
@ -101,6 +101,7 @@
|
|||||||
<p>Another strategy is by "encoding" something you already know. This can seem like a good way to make memorable passwords, but recalling the "encoding" you used two years later can be tricky. This also makes it much easier for attackers that know you to find your password.</p>
|
<p>Another strategy is by "encoding" something you already know. This can seem like a good way to make memorable passwords, but recalling the "encoding" you used two years later can be tricky. This also makes it much easier for attackers that know you to find your password.</p>
|
||||||
<p>Master Password itself generates very random passwords that look semi-legible, for instance <code>Togu3]ToxiBuzb</code>. Such passwords have been found to be very memorable while also being very high in entropy (hard to guess).</p>
|
<p>Master Password itself generates very random passwords that look semi-legible, for instance <code>Togu3]ToxiBuzb</code>. Such passwords have been found to be very memorable while also being very high in entropy (hard to guess).</p>
|
||||||
<p>A strategy that's gaining traction lately is that of combining words into a sentence. Some claim it's best for the sentence to make no grammatical sense, others dispute these claims. It's a fact, though, that if your attacker doesn't expect such a password, they're nearly impossible to defeat.</p>
|
<p>A strategy that's gaining traction lately is that of combining words into a sentence. Some claim it's best for the sentence to make no grammatical sense, others dispute these claims. It's a fact, though, that if your attacker doesn't expect such a password, they're nearly impossible to defeat.</p>
|
||||||
|
<p><iframe width="420" height="315" src="//www.youtube.com/embed/MSyIhapMdI8?start=109" frameborder="0" allowfullscreen></iframe></p>
|
||||||
<p>Let's sum these strategies up in a table, note that this type of comparison is very subjective.</p>
|
<p>Let's sum these strategies up in a table, note that this type of comparison is very subjective.</p>
|
||||||
<table>
|
<table>
|
||||||
<caption>Time to crack a master password</caption>
|
<caption>Time to crack a master password</caption>
|
||||||
|
Loading…
Reference in New Issue
Block a user