2
0

Reformat to code style.

This commit is contained in:
Maarten Billemont 2018-04-26 13:05:45 -04:00
parent 10698284d2
commit 9c8566b537
38 changed files with 142 additions and 132 deletions

View File

@ -5,7 +5,7 @@ plugins {
description = 'Master Password Algorithm Implementation' description = 'Master Password Algorithm Implementation'
dependencies { dependencies {
compile (group: 'com.lyndir.lhunath.opal', name: 'opal-system', version: '1.6-p11') { compile( group: 'com.lyndir.lhunath.opal', name: 'opal-system', version: '1.6-p11' ) {
exclude( module: 'joda-time' ) exclude( module: 'joda-time' )
} }
compile group: 'com.lyndir.lhunath.opal', name: 'opal-crypto', version: '1.6-p11' compile group: 'com.lyndir.lhunath.opal', name: 'opal-crypto', version: '1.6-p11'

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<!-- PROJECT METADATA --> <!-- PROJECT METADATA -->

View File

@ -24,9 +24,8 @@ import javax.annotation.Nullable;
/** /**
* @see MPMasterKey.Version#V1
*
* @author lhunath, 2014-08-30 * @author lhunath, 2014-08-30
* @see MPMasterKey.Version#V1
*/ */
public class MPAlgorithmV1 extends MPAlgorithmV0 { public class MPAlgorithmV1 extends MPAlgorithmV0 {
@ -37,20 +36,21 @@ public class MPAlgorithmV1 extends MPAlgorithmV0 {
} }
@Override @Override
public String sitePasswordFromTemplate(final byte[] masterKey, final byte[] siteKey, final MPResultType resultType, @Nullable final String resultParam) { public String sitePasswordFromTemplate(final byte[] masterKey, final byte[] siteKey, final MPResultType resultType,
@Nullable final String resultParam) {
// Determine the template. // Determine the template.
Preconditions.checkState( siteKey.length > 0 ); Preconditions.checkState( siteKey.length > 0 );
int templateIndex = UnsignedBytes.toInt( siteKey[0] ); int templateIndex = UnsignedBytes.toInt( siteKey[0] );
MPTemplate template = resultType.getTemplateAtRollingIndex( templateIndex ); MPTemplate template = resultType.getTemplateAtRollingIndex( templateIndex );
logger.trc( "template: %d => %s", templateIndex, template.getTemplateString() ); logger.trc( "template: %d => %s", templateIndex, template.getTemplateString() );
// Encode the password from the seed using the template. // Encode the password from the seed using the template.
StringBuilder password = new StringBuilder( template.length() ); StringBuilder password = new StringBuilder( template.length() );
for (int i = 0; i < template.length(); ++i) { for (int i = 0; i < template.length(); ++i) {
int characterIndex = UnsignedBytes.toInt( siteKey[i + 1] ); int characterIndex = UnsignedBytes.toInt( siteKey[i + 1] );
MPTemplateCharacterClass characterClass = template.getCharacterClassAtIndex( i ); MPTemplateCharacterClass characterClass = template.getCharacterClassAtIndex( i );
char passwordCharacter = characterClass.getCharacterAtRollingIndex( characterIndex ); char passwordCharacter = characterClass.getCharacterAtRollingIndex( characterIndex );
logger.trc( " - class: %c, index: %3d (0x%2H) => character: %c", logger.trc( " - class: %c, index: %3d (0x%2H) => character: %c",
characterClass.getIdentifier(), characterIndex, siteKey[i + 1], passwordCharacter ); characterClass.getIdentifier(), characterIndex, siteKey[i + 1], passwordCharacter );

View File

@ -25,9 +25,8 @@ import javax.annotation.Nullable;
/** /**
* @see MPMasterKey.Version#V2
*
* @author lhunath, 2014-08-30 * @author lhunath, 2014-08-30
* @see MPMasterKey.Version#V2
*/ */
public class MPAlgorithmV2 extends MPAlgorithmV1 { public class MPAlgorithmV2 extends MPAlgorithmV1 {
@ -39,7 +38,7 @@ public class MPAlgorithmV2 extends MPAlgorithmV1 {
@Override @Override
public byte[] siteKey(final byte[] masterKey, final String siteName, UnsignedInteger siteCounter, final MPKeyPurpose keyPurpose, public byte[] siteKey(final byte[] masterKey, final String siteName, UnsignedInteger siteCounter, final MPKeyPurpose keyPurpose,
@Nullable final String keyContext) { @Nullable final String keyContext) {
String keyScope = keyPurpose.getScope(); String keyScope = keyPurpose.getScope();
logger.trc( "keyScope: %s", keyScope ); logger.trc( "keyScope: %s", keyScope );
@ -49,10 +48,10 @@ public class MPAlgorithmV2 extends MPAlgorithmV1 {
siteCounter = UnsignedInteger.valueOf( (System.currentTimeMillis() / (mpw_otp_window * 1000)) * mpw_otp_window ); siteCounter = UnsignedInteger.valueOf( (System.currentTimeMillis() / (mpw_otp_window * 1000)) * mpw_otp_window );
// Calculate the site seed. // Calculate the site seed.
byte[] siteNameBytes = siteName.getBytes( mpw_charset ); byte[] siteNameBytes = siteName.getBytes( mpw_charset );
byte[] siteNameLengthBytes = toBytes( siteNameBytes.length ); byte[] siteNameLengthBytes = toBytes( siteNameBytes.length );
byte[] siteCounterBytes = toBytes( siteCounter ); byte[] siteCounterBytes = toBytes( siteCounter );
byte[] keyContextBytes = ((keyContext == null) || keyContext.isEmpty())? null: keyContext.getBytes( mpw_charset ); byte[] keyContextBytes = ((keyContext == null) || keyContext.isEmpty())? null: keyContext.getBytes( mpw_charset );
byte[] keyContextLengthBytes = (keyContextBytes == null)? null: toBytes( keyContextBytes.length ); byte[] keyContextLengthBytes = (keyContextBytes == null)? null: toBytes( keyContextBytes.length );
logger.trc( "siteSalt: keyScope=%s | #siteName=%s | siteName=%s | siteCounter=%s | #keyContext=%s | keyContext=%s", logger.trc( "siteSalt: keyScope=%s | #siteName=%s | siteName=%s | siteCounter=%s | #keyContext=%s | keyContext=%s",
keyScope, CodeUtils.encodeHex( siteNameLengthBytes ), siteName, CodeUtils.encodeHex( siteCounterBytes ), keyScope, CodeUtils.encodeHex( siteNameLengthBytes ), siteName, CodeUtils.encodeHex( siteCounterBytes ),

View File

@ -24,9 +24,8 @@ import java.util.Arrays;
/** /**
* @see MPMasterKey.Version#V3
*
* @author lhunath, 2014-08-30 * @author lhunath, 2014-08-30
* @see MPMasterKey.Version#V3
*/ */
public class MPAlgorithmV3 extends MPAlgorithmV2 { public class MPAlgorithmV3 extends MPAlgorithmV2 {
@ -39,7 +38,7 @@ public class MPAlgorithmV3 extends MPAlgorithmV2 {
@Override @Override
public byte[] masterKey(final String fullName, final char[] masterPassword) { public byte[] masterKey(final String fullName, final char[] masterPassword) {
byte[] fullNameBytes = fullName.getBytes( mpw_charset ); byte[] fullNameBytes = fullName.getBytes( mpw_charset );
byte[] fullNameLengthBytes = toBytes( fullNameBytes.length ); byte[] fullNameLengthBytes = toBytes( fullNameBytes.length );
String keyScope = MPKeyPurpose.Authentication.getScope(); String keyScope = MPKeyPurpose.Authentication.getScope();
@ -54,7 +53,7 @@ public class MPAlgorithmV3 extends MPAlgorithmV2 {
// Calculate the master key. // Calculate the master key.
logger.trc( "masterKey: scrypt( masterPassword, masterKeySalt, N=%d, r=%d, p=%d )", logger.trc( "masterKey: scrypt( masterPassword, masterKeySalt, N=%d, r=%d, p=%d )",
scrypt_N, scrypt_r, scrypt_p ); scrypt_N, scrypt_r, scrypt_p );
byte[] mpBytes = toBytes( masterPassword ); byte[] mpBytes = toBytes( masterPassword );
byte[] masterKey = scrypt( masterKeySalt, mpBytes ); byte[] masterKey = scrypt( masterKeySalt, mpBytes );
Arrays.fill( masterKeySalt, (byte) 0 ); Arrays.fill( masterKeySalt, (byte) 0 );
Arrays.fill( mpBytes, (byte) 0 ); Arrays.fill( mpBytes, (byte) 0 );

View File

@ -37,8 +37,8 @@ public class MPMasterKey {
private static final Logger logger = Logger.get( MPMasterKey.class ); private static final Logger logger = Logger.get( MPMasterKey.class );
private final EnumMap<Version, byte[]> keyByVersion = new EnumMap<>( Version.class ); private final EnumMap<Version, byte[]> keyByVersion = new EnumMap<>( Version.class );
private final String fullName; private final String fullName;
private final char[] masterPassword; private final char[] masterPassword;
private boolean invalidated; private boolean invalidated;
@ -118,7 +118,7 @@ public class MPMasterKey {
throws MPInvalidatedException { throws MPInvalidatedException {
byte[] masterKey = masterKey( algorithmVersion ); byte[] masterKey = masterKey( algorithmVersion );
byte[] siteKey = siteKey( siteName, siteCounter, keyPurpose, keyContext, algorithmVersion ); byte[] siteKey = siteKey( siteName, siteCounter, keyPurpose, keyContext, algorithmVersion );
logger.trc( "-- mpw_siteResult (algorithm: %d)", algorithmVersion.toInt() ); logger.trc( "-- mpw_siteResult (algorithm: %d)", algorithmVersion.toInt() );
logger.trc( "resultType: %d (%s)", resultType.getType(), resultType.getShortName() ); logger.trc( "resultType: %d (%s)", resultType.getType(), resultType.getShortName() );
@ -150,7 +150,7 @@ public class MPMasterKey {
Preconditions.checkArgument( !resultParam.isEmpty() ); Preconditions.checkArgument( !resultParam.isEmpty() );
byte[] masterKey = masterKey( algorithmVersion ); byte[] masterKey = masterKey( algorithmVersion );
byte[] siteKey = siteKey( siteName, siteCounter, keyPurpose, keyContext, algorithmVersion ); byte[] siteKey = siteKey( siteName, siteCounter, keyPurpose, keyContext, algorithmVersion );
logger.trc( "-- mpw_siteState (algorithm: %d)", algorithmVersion.toInt() ); logger.trc( "-- mpw_siteState (algorithm: %d)", algorithmVersion.toInt() );
logger.trc( "resultType: %d (%s)", resultType.getType(), resultType.getShortName() ); logger.trc( "resultType: %d (%s)", resultType.getType(), resultType.getShortName() );

View File

@ -124,8 +124,8 @@ public enum MPResultType {
* Derive a unique binary key. * Derive a unique binary key.
*/ */
DeriveKey( "key", "Encryption key.", // DeriveKey( "key", "Encryption key.", //
ImmutableList.<MPTemplate>of(), // ImmutableList.<MPTemplate>of(), //
MPResultTypeClass.Derive, 0x0, MPSiteFeature.Alternative ); MPResultTypeClass.Derive, 0x0, MPSiteFeature.Alternative );
static final Logger logger = Logger.get( MPResultType.class ); static final Logger logger = Logger.get( MPResultType.class );

View File

@ -36,7 +36,7 @@ public class MPTemplate extends MetaObject implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final String templateString; private final String templateString;
private final List<MPTemplateCharacterClass> template; private final List<MPTemplateCharacterClass> template;
MPTemplate(@NonNls final String templateString) { MPTemplate(@NonNls final String templateString) {

View File

@ -17,11 +17,10 @@
//============================================================================== //==============================================================================
/** /**
*
* @author lhunath, 15-02-04 * @author lhunath, 15-02-04
*/ */
@ParametersAreNonnullByDefault
@ParametersAreNonnullByDefault package com.lyndir.masterpassword; package com.lyndir.masterpassword;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;

View File

@ -6,13 +6,13 @@ plugins {
description = 'Master Password Site Model' description = 'Master Password Site Model'
dependencies { dependencies {
compile project(':masterpassword-algorithm') compile project( ':masterpassword-algorithm' )
compile group: 'joda-time', name: 'joda-time', version:'2.4' compile group: 'joda-time', name: 'joda-time', version: '2.4'
compileOnly group: 'com.google.auto.value', name: 'auto-value', version: '1.2' compileOnly group: 'com.google.auto.value', name: 'auto-value', version: '1.2'
apt group: 'com.google.auto.value', name: 'auto-value', version: '1.2' apt group: 'com.google.auto.value', name: 'auto-value', version: '1.2'
testCompile group: 'org.testng', name: 'testng', version:'6.8.5' testCompile group: 'org.testng', name: 'testng', version: '6.8.5'
testCompile group: 'ch.qos.logback', name: 'logback-classic', version:'1.1.2' testCompile group: 'ch.qos.logback', name: 'logback-classic', version: '1.1.2'
} }
test.useTestNG() test.useTestNG()

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<!-- PROJECT METADATA --> <!-- PROJECT METADATA -->
@ -32,10 +33,10 @@
<artifactId>joda-time</artifactId> <artifactId>joda-time</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.google.auto.value</groupId> <groupId>com.google.auto.value</groupId>
<artifactId>auto-value</artifactId> <artifactId>auto-value</artifactId>
<version>1.0-rc1</version> <version>1.0-rc1</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!-- TESTING --> <!-- TESTING -->

View File

@ -180,7 +180,8 @@ public class MPFileSite extends MPSite {
this.loginContent = null; this.loginContent = null;
else else
this.loginContent = masterKey.siteState( this.loginContent = masterKey.siteState(
siteName, MPAlgorithm.mpw_default_counter, MPKeyPurpose.Identification, null, this.loginType, result, algorithmVersion ); siteName, MPAlgorithm.mpw_default_counter, MPKeyPurpose.Identification, null, this.loginType, result,
algorithmVersion );
} }
@Nullable @Nullable

View File

@ -58,7 +58,7 @@ public class MPFlatMarshaller implements MPMarshaller {
for (final MPFileSite site : user.getSites()) { for (final MPFileSite site : user.getSites()) {
String loginName = site.getLoginContent(); String loginName = site.getLoginContent();
String password = site.getSiteContent(); String password = site.getSiteContent();
if (!contentMode.isRedacted()) { if (!contentMode.isRedacted()) {
loginName = site.loginFor( masterKey ); loginName = site.loginFor( masterKey );
password = site.resultFor( masterKey ); password = site.resultFor( masterKey );

View File

@ -37,7 +37,7 @@ import org.joda.time.DateTime;
*/ */
public class MPFlatUnmarshaller implements MPUnmarshaller { public class MPFlatUnmarshaller implements MPUnmarshaller {
private static final Logger logger = Logger.get( MPFlatUnmarshaller.class ); private static final Logger logger = Logger.get( MPFlatUnmarshaller.class );
private static final Pattern[] unmarshallFormats = { private static final Pattern[] unmarshallFormats = {
Pattern.compile( "^([^ ]+) +(\\d+) +(\\d+)(:\\d+)? +([^\t]+)\t(.*)" ), Pattern.compile( "^([^ ]+) +(\\d+) +(\\d+)(:\\d+)? +([^\t]+)\t(.*)" ),
Pattern.compile( "^([^ ]+) +(\\d+) +(\\d+)(:\\d+)?(:\\d+)? +([^\t]*)\t *([^\t]+)\t(.*)" ) }; Pattern.compile( "^([^ ]+) +(\\d+) +(\\d+)(:\\d+)?(:\\d+)? +([^\t]*)\t *([^\t]+)\t(.*)" ) };
@ -73,7 +73,8 @@ public class MPFlatUnmarshaller implements MPUnmarshaller {
headerStarted = true; headerStarted = true;
else else
// Ends the header. // Ends the header.
user = new MPFileUser( fullName, keyID, MPMasterKey.Version.fromInt( mpVersion ), avatar, defaultType, new DateTime( 0 ), MPMarshalFormat.Flat ); user = new MPFileUser( fullName, keyID, MPMasterKey.Version.fromInt( mpVersion ), avatar, defaultType,
new DateTime( 0 ), MPMarshalFormat.Flat );
// Comment. // Comment.
else if (line.startsWith( "#" )) { else if (line.startsWith( "#" )) {
@ -116,7 +117,7 @@ public class MPFlatUnmarshaller implements MPUnmarshaller {
user.getAlgorithmVersion().getAlgorithm().mpw_default_counter, user.getAlgorithmVersion().getAlgorithm().mpw_default_counter,
MPResultType.forType( ConversionUtils.toIntegerNN( siteMatcher.group( 3 ) ) ), MPResultType.forType( ConversionUtils.toIntegerNN( siteMatcher.group( 3 ) ) ),
MPMasterKey.Version.fromInt( ConversionUtils.toIntegerNN( MPMasterKey.Version.fromInt( ConversionUtils.toIntegerNN(
colon.matcher( siteMatcher.group( 4 ) ).replaceAll( "" ) ) ), colon.matcher( siteMatcher.group( 4 ) ).replaceAll( "" ) ) ),
null, null, null, ConversionUtils.toIntegerNN( siteMatcher.group( 2 ) ), null, null, null, ConversionUtils.toIntegerNN( siteMatcher.group( 2 ) ),
MPConstant.dateTimeFormatter.parseDateTime( siteMatcher.group( 1 ) ).toInstant() ); MPConstant.dateTimeFormatter.parseDateTime( siteMatcher.group( 1 ) ).toInstant() );
break; break;
@ -127,7 +128,7 @@ public class MPFlatUnmarshaller implements MPUnmarshaller {
UnsignedInteger.valueOf( colon.matcher( siteMatcher.group( 5 ) ).replaceAll( "" ) ), UnsignedInteger.valueOf( colon.matcher( siteMatcher.group( 5 ) ).replaceAll( "" ) ),
MPResultType.forType( ConversionUtils.toIntegerNN( siteMatcher.group( 3 ) ) ), MPResultType.forType( ConversionUtils.toIntegerNN( siteMatcher.group( 3 ) ) ),
MPMasterKey.Version.fromInt( ConversionUtils.toIntegerNN( MPMasterKey.Version.fromInt( ConversionUtils.toIntegerNN(
colon.matcher( siteMatcher.group( 4 ) ).replaceAll( "" ) ) ), colon.matcher( siteMatcher.group( 4 ) ).replaceAll( "" ) ) ),
siteMatcher.group( 6 ), MPResultType.GeneratedName, null, siteMatcher.group( 6 ), MPResultType.GeneratedName, null,
ConversionUtils.toIntegerNN( siteMatcher.group( 2 ) ), ConversionUtils.toIntegerNN( siteMatcher.group( 2 ) ),
MPConstant.dateTimeFormatter.parseDateTime( siteMatcher.group( 1 ) ).toInstant() ); MPConstant.dateTimeFormatter.parseDateTime( siteMatcher.group( 1 ) ).toInstant() );

View File

@ -38,7 +38,7 @@ public class MPJSONUnmarshaller implements MPUnmarshaller {
@Nonnull @Nonnull
@Override @Override
public MPFileUser unmarshall(@Nonnull final String content) public MPFileUser unmarshall(@Nonnull final String content)
throws MPMarshalException{ throws MPMarshalException {
throw new MPMarshalException( "Not yet implemented" ); throw new MPMarshalException( "Not yet implemented" );
} }
} }

View File

@ -36,8 +36,8 @@ public interface MPMarshaller {
PROTECTED( "Export of site names and stored passwords (unless device-private) encrypted with the master key." ), PROTECTED( "Export of site names and stored passwords (unless device-private) encrypted with the master key." ),
VISIBLE( "Export of site names and passwords in clear-text." ); VISIBLE( "Export of site names and passwords in clear-text." );
private final String description; private final String description;
private boolean redacted; private boolean redacted;
ContentMode(final String description) { ContentMode(final String description) {
this.description = description; this.description = description;

View File

@ -59,7 +59,8 @@ public abstract class MPSite {
throws MPInvalidatedException { throws MPInvalidatedException {
return masterKey.siteResult( return masterKey.siteResult(
getSiteName(), MPAlgorithm.mpw_default_counter, MPKeyPurpose.Identification, null, loginType, loginContent, getAlgorithmVersion() ); getSiteName(), MPAlgorithm.mpw_default_counter, MPKeyPurpose.Identification, null, loginType, loginContent,
getAlgorithmVersion() );
} }
@Override @Override

View File

@ -29,7 +29,7 @@ import java.util.*;
public abstract class MPUserManager { public abstract class MPUserManager {
private final Map<String, MPFileUser> usersByName = Maps.newHashMap(); private final Map<String, MPFileUser> usersByName = Maps.newHashMap();
static MPUserManager instance; static MPUserManager instance;
public static MPUserManager get() { public static MPUserManager get() {
return instance; return instance;

View File

@ -17,7 +17,6 @@
//============================================================================== //==============================================================================
/** /**
*
* @author lhunath, 15-02-04 * @author lhunath, 15-02-04
*/ */

View File

@ -5,9 +5,9 @@ plugins {
description = 'Master Password Test Suite' description = 'Master Password Test Suite'
dependencies { dependencies {
compile project(':masterpassword-algorithm') compile project( ':masterpassword-algorithm' )
testCompile group: 'org.testng', name: 'testng', version:'6.8.5' testCompile group: 'org.testng', name: 'testng', version: '6.8.5'
testCompile group: 'ch.qos.logback', name: 'logback-classic', version:'1.1.2' testCompile group: 'ch.qos.logback', name: 'logback-classic', version: '1.1.2'
} }
test.useTestNG() test.useTestNG()

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<!-- PROJECT METADATA --> <!-- PROJECT METADATA -->

View File

@ -1,5 +1,6 @@
#Thu Apr 26 12:52:02 EDT 2018
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-4.3-all.zip

View File

@ -36,11 +36,11 @@ android {
} }
dependencies { dependencies {
compile project( ':masterpassword-algorithm' ) compile project( ':masterpassword-algorithm' )
compile project( ':masterpassword-tests' ) compile project( ':masterpassword-tests' )
compile group: 'org.slf4j', name: 'slf4j-android', version:'1.7.13-underscore' compile group: 'org.slf4j', name: 'slf4j-android', version: '1.7.13-underscore'
compile group: 'com.jakewharton', name: 'butterknife', version:'8.5.1' compile group: 'com.jakewharton', name: 'butterknife', version: '8.5.1'
annotationProcessor group: 'com.jakewharton', name: 'butterknife-compiler', version:'8.5.1' annotationProcessor group: 'com.jakewharton', name: 'butterknife-compiler', version: '8.5.1'
compile files( 'libs/scrypt-1.4.0-native.jar' ) compile files( 'libs/scrypt-1.4.0-native.jar' )
} }

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<!-- PROJECT METADATA --> <!-- PROJECT METADATA -->
@ -86,8 +87,10 @@
<keypass>${env.PASSWORD}</keypass> <keypass>${env.PASSWORD}</keypass>
<alias>masterpassword-android</alias> <alias>masterpassword-android</alias>
<arguments> <arguments>
<argument>-sigalg</argument><argument>MD5withRSA</argument> <argument>-sigalg</argument>
<argument>-digestalg</argument><argument>SHA1</argument> <argument>MD5withRSA</argument>
<argument>-digestalg</argument>
<argument>SHA1</argument>
</arguments> </arguments>
</configuration> </configuration>
</execution> </execution>

View File

@ -49,11 +49,13 @@ public class EmergencyActivity extends Activity {
private static final Logger logger = Logger.get( EmergencyActivity.class ); private static final Logger logger = Logger.get( EmergencyActivity.class );
private static final ClipData EMPTY_CLIP = new ClipData( new ClipDescription( "", new String[0] ), new ClipData.Item( "" ) ); private static final ClipData EMPTY_CLIP = new ClipData( new ClipDescription( "", new String[0] ), new ClipData.Item( "" ) );
private static final int PASSWORD_NOTIFICATION = 0; private static final int PASSWORD_NOTIFICATION = 0;
public static final int CLIPBOARD_CLEAR_DELAY = 20 /* s */ * MPConstant.MS_PER_S; public static final int CLIPBOARD_CLEAR_DELAY = 20 /* s */ * MPConstant.MS_PER_S;
private final Preferences preferences = Preferences.get( this ); private final Preferences preferences = Preferences.get( this );
private final ListeningExecutorService executor = MoreExecutors.listeningDecorator( Executors.newSingleThreadExecutor() ); private final ListeningExecutorService executor = MoreExecutors.listeningDecorator(
private final ImmutableList<MPResultType> allResultTypes = ImmutableList.copyOf( MPResultType.forClass( MPResultTypeClass.Template ) ); Executors.newSingleThreadExecutor() );
private final ImmutableList<MPResultType> allResultTypes = ImmutableList.copyOf(
MPResultType.forClass( MPResultTypeClass.Template ) );
private final ImmutableList<MPMasterKey.Version> allVersions = ImmutableList.copyOf( MPMasterKey.Version.values() ); private final ImmutableList<MPMasterKey.Version> allVersions = ImmutableList.copyOf( MPMasterKey.Version.values() );
private MPMasterKey masterKey; private MPMasterKey masterKey;
@ -211,7 +213,7 @@ public class EmergencyActivity extends Activity {
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
// FIXME: MasterKey.setAllowNativeByDefault( preferences.isAllowNativeKDF() ); // FIXME: MasterKey.setAllowNativeByDefault( preferences.isAllowNativeKDF() );
fullNameField.setText( preferences.getFullName() ); fullNameField.setText( preferences.getFullName() );
rememberFullNameField.setChecked( preferences.isRememberFullName() ); rememberFullNameField.setChecked( preferences.isRememberFullName() );
@ -254,7 +256,7 @@ public class EmergencyActivity extends Activity {
} }
private synchronized void updateMasterKey() { private synchronized void updateMasterKey() {
final String fullName = fullNameField.getText().toString(); final String fullName = fullNameField.getText().toString();
final char[] masterPassword = masterPasswordField.getText().toString().toCharArray(); final char[] masterPassword = masterPasswordField.getText().toString().toCharArray();
if ((id_userName == fullName.hashCode()) if ((id_userName == fullName.hashCode())
&& (id_masterPassword == Arrays.hashCode( masterPassword ))) && (id_masterPassword == Arrays.hashCode( masterPassword )))
@ -336,10 +338,10 @@ public class EmergencyActivity extends Activity {
if (TextUtils.isEmpty( currentSitePassword )) if (TextUtils.isEmpty( currentSitePassword ))
return; return;
final ClipboardManager clipboardManager = (ClipboardManager) getSystemService( CLIPBOARD_SERVICE ); final ClipboardManager clipboardManager = (ClipboardManager) getSystemService( CLIPBOARD_SERVICE );
final NotificationManager notificationManager = (NotificationManager) getSystemService( Context.NOTIFICATION_SERVICE ); final NotificationManager notificationManager = (NotificationManager) getSystemService( Context.NOTIFICATION_SERVICE );
String title = strf( "Password for %s", siteNameField.getText() ); String title = strf( "Password for %s", siteNameField.getText() );
ClipDescription description = new ClipDescription( title, new String[]{ ClipDescription.MIMETYPE_TEXT_PLAIN } ); ClipDescription description = new ClipDescription( title, new String[]{ ClipDescription.MIMETYPE_TEXT_PLAIN } );
clipboardManager.setPrimaryClip( new ClipData( description, new ClipData.Item( currentSitePassword ) ) ); clipboardManager.setPrimaryClip( new ClipData( description, new ClipData.Item( currentSitePassword ) ) );

View File

@ -33,7 +33,7 @@ public class MainThreadExecutor extends AbstractExecutorService {
private final Handler mHandler = new Handler( Looper.getMainLooper() ); private final Handler mHandler = new Handler( Looper.getMainLooper() );
private final Set<Runnable> commands = Sets.newLinkedHashSet(); private final Set<Runnable> commands = Sets.newLinkedHashSet();
private boolean shutdown; private boolean shutdown;
@Override @Override
public void execute(final Runnable command) { public void execute(final Runnable command) {

View File

@ -32,15 +32,15 @@ import javax.annotation.Nullable;
*/ */
public final class Preferences { public final class Preferences {
private static final String PREF_TESTS_PASSED = "integrityTestsPassed"; private static final String PREF_TESTS_PASSED = "integrityTestsPassed";
private static final String PREF_NATIVE_KDF = "nativeKDF"; private static final String PREF_NATIVE_KDF = "nativeKDF";
private static final String PREF_REMEMBER_FULL_NAME = "rememberFullName"; private static final String PREF_REMEMBER_FULL_NAME = "rememberFullName";
private static final String PREF_FORGET_PASSWORD = "forgetPassword"; private static final String PREF_FORGET_PASSWORD = "forgetPassword";
private static final String PREF_MASK_PASSWORD = "maskPassword"; private static final String PREF_MASK_PASSWORD = "maskPassword";
private static final String PREF_FULL_NAME = "fullName"; private static final String PREF_FULL_NAME = "fullName";
private static final String PREF_RESULT_TYPE = "resultType"; private static final String PREF_RESULT_TYPE = "resultType";
private static final String PREF_ALGORITHM_VERSION = "algorithmVersion"; private static final String PREF_ALGORITHM_VERSION = "algorithmVersion";
private static Preferences instance; private static Preferences instance;
private Context context; private Context context;
@Nullable @Nullable

View File

@ -8,10 +8,10 @@ description = 'Master Password GUI'
mainClassName = 'com.lyndir.masterpassword.gui.GUI' mainClassName = 'com.lyndir.masterpassword.gui.GUI'
dependencies { dependencies {
compile project(':masterpassword-model') compile project( ':masterpassword-model' )
compile group: 'ch.qos.logback', name: 'logback-classic', version:'1.1.2' compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.1.2'
compile group: 'com.yuvimasory', name: 'orange-extensions', version:'1.3.0' compile group: 'com.yuvimasory', name: 'orange-extensions', version: '1.3.0'
} }
run { run {

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<!-- PROJECT METADATA --> <!-- PROJECT METADATA -->
@ -116,8 +117,10 @@
<keypass>${env.PASSWORD}</keypass> <keypass>${env.PASSWORD}</keypass>
<alias>masterpassword-desktop</alias> <alias>masterpassword-desktop</alias>
<arguments> <arguments>
<argument>-sigalg</argument><argument>MD5withRSA</argument> <argument>-sigalg</argument>
<argument>-digestalg</argument><argument>SHA1</argument> <argument>MD5withRSA</argument>
<argument>-digestalg</argument>
<argument>SHA1</argument>
</arguments> </arguments>
</configuration> </configuration>
</execution> </execution>

View File

@ -16,7 +16,6 @@
// LICENSE file. Alternatively, see <http://www.gnu.org/licenses/>. // LICENSE file. Alternatively, see <http://www.gnu.org/licenses/>.
//============================================================================== //==============================================================================
package com.lyndir.masterpassword.gui; package com.lyndir.masterpassword.gui;
import com.google.common.base.*; import com.google.common.base.*;
@ -45,8 +44,8 @@ public class GUI implements UnlockFrame.SignInCallback {
@SuppressWarnings("UnusedDeclaration") @SuppressWarnings("UnusedDeclaration")
private static final Logger logger = Logger.get( GUI.class ); private static final Logger logger = Logger.get( GUI.class );
private final UnlockFrame unlockFrame = new UnlockFrame( this ); private final UnlockFrame unlockFrame = new UnlockFrame( this );
private PasswordFrame<?, ?> passwordFrame; private PasswordFrame<?, ?> passwordFrame;
public static void main(final String... args) { public static void main(final String... args) {
if (Config.get().checkForUpdates()) if (Config.get().checkForUpdates())
@ -54,7 +53,7 @@ public class GUI implements UnlockFrame.SignInCallback {
// Try and set the system look & feel, if available. // Try and set the system look & feel, if available.
try { try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
} }
catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException | IllegalAccessException ignored) { catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException | IllegalAccessException ignored) {
} }
@ -67,7 +66,8 @@ public class GUI implements UnlockFrame.SignInCallback {
else // No special platform handling. else // No special platform handling.
new GUI().open(); new GUI().open();
} catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) { }
catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
throw logger.bug( e ); throw logger.bug( e );
} }
} }
@ -77,14 +77,14 @@ public class GUI implements UnlockFrame.SignInCallback {
Enumeration<URL> manifestURLs = Thread.currentThread().getContextClassLoader().getResources( JarFile.MANIFEST_NAME ); Enumeration<URL> manifestURLs = Thread.currentThread().getContextClassLoader().getResources( JarFile.MANIFEST_NAME );
while (manifestURLs.hasMoreElements()) { while (manifestURLs.hasMoreElements()) {
InputStream manifestStream = manifestURLs.nextElement().openStream(); InputStream manifestStream = manifestURLs.nextElement().openStream();
Attributes attributes = new Manifest( manifestStream ).getMainAttributes(); Attributes attributes = new Manifest( manifestStream ).getMainAttributes();
if (!GUI.class.getCanonicalName().equals( attributes.getValue( Attributes.Name.MAIN_CLASS ) )) if (!GUI.class.getCanonicalName().equals( attributes.getValue( Attributes.Name.MAIN_CLASS ) ))
continue; continue;
String manifestRevision = attributes.getValue( Attributes.Name.IMPLEMENTATION_VERSION ); String manifestRevision = attributes.getValue( Attributes.Name.IMPLEMENTATION_VERSION );
String upstreamRevisionURL = "https://masterpasswordapp.com/masterpassword-gui.jar.rev"; String upstreamRevisionURL = "https://masterpasswordapp.com/masterpassword-gui.jar.rev";
CharSource upstream = Resources.asCharSource( URI.create( upstreamRevisionURL ).toURL(), Charsets.UTF_8 ); CharSource upstream = Resources.asCharSource( URI.create( upstreamRevisionURL ).toURL(), Charsets.UTF_8 );
String upstreamRevision = upstream.readFirstLine(); String upstreamRevision = upstream.readFirstLine();
if ((manifestRevision != null) && (upstreamRevision != null) && !manifestRevision.equalsIgnoreCase( upstreamRevision )) { if ((manifestRevision != null) && (upstreamRevision != null) && !manifestRevision.equalsIgnoreCase( upstreamRevision )) {
logger.inf( "Local Revision: <%s>", manifestRevision ); logger.inf( "Local Revision: <%s>", manifestRevision );
logger.inf( "Upstream Revision: <%s>", upstreamRevision ); logger.inf( "Upstream Revision: <%s>", upstreamRevision );

View File

@ -50,10 +50,10 @@ import org.jetbrains.annotations.NonNls;
@SuppressWarnings("HardcodedFileSeparator") @SuppressWarnings("HardcodedFileSeparator")
public abstract class Res { public abstract class Res {
private static final int AVATAR_COUNT = 19; private static final int AVATAR_COUNT = 19;
private static final Map<Window, ScheduledExecutorService> executorByWindow = new WeakHashMap<>(); private static final Map<Window, ScheduledExecutorService> executorByWindow = new WeakHashMap<>();
private static final Logger logger = Logger.get( Res.class ); private static final Logger logger = Logger.get( Res.class );
private static final Colors colors = new Colors(); private static final Colors colors = new Colors();
public static Future<?> execute(final Window host, final Runnable job) { public static Future<?> execute(final Window host, final Runnable job) {
return schedule( host, job, 0, TimeUnit.MILLISECONDS ); return schedule( host, job, 0, TimeUnit.MILLISECONDS );
@ -203,8 +203,8 @@ public abstract class Res {
private static Font font(@NonNls final String fontResourceName) { private static Font font(@NonNls final String fontResourceName) {
Map<String, SoftReference<Font>> fontsByResourceName = Maps.newHashMap(); Map<String, SoftReference<Font>> fontsByResourceName = Maps.newHashMap();
SoftReference<Font> fontRef = fontsByResourceName.get( fontResourceName ); SoftReference<Font> fontRef = fontsByResourceName.get( fontResourceName );
Font font = (fontRef == null)? null: fontRef.get(); Font font = (fontRef == null)? null: fontRef.get();
if (font == null) if (font == null)
try { try {
fontsByResourceName.put( fontResourceName, new SoftReference<>( fontsByResourceName.put( fontResourceName, new SoftReference<>(
@ -223,8 +223,8 @@ public abstract class Res {
private static final class RetinaIcon extends ImageIcon { private static final class RetinaIcon extends ImageIcon {
private static final Pattern scalePattern = Pattern.compile( ".*@(\\d+)x.[^.]+$" ); private static final Pattern scalePattern = Pattern.compile( ".*@(\\d+)x.[^.]+$" );
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final float scale; private final float scale;
@ -265,10 +265,10 @@ public abstract class Res {
public synchronized void paintIcon(final Component c, final Graphics g, final int x, final int y) { public synchronized void paintIcon(final Component c, final Graphics g, final int x, final int y) {
ImageObserver observer = ifNotNullElse( getImageObserver(), c ); ImageObserver observer = ifNotNullElse( getImageObserver(), c );
Image image = getImage(); Image image = getImage();
int width = image.getWidth( observer ); int width = image.getWidth( observer );
int height = image.getHeight( observer ); int height = image.getHeight( observer );
Graphics2D g2d = (Graphics2D) g.create( x, y, width, height ); Graphics2D g2d = (Graphics2D) g.create( x, y, width, height );
g2d.scale( 1 / scale, 1 / scale ); g2d.scale( 1 / scale, 1 / scale );
g2d.drawImage( image, 0, 0, observer ); g2d.drawImage( image, 0, 0, observer );

View File

@ -17,7 +17,6 @@
//============================================================================== //==============================================================================
/** /**
*
* @author lhunath, 15-02-04 * @author lhunath, 15-02-04
*/ */

View File

@ -17,7 +17,6 @@
//============================================================================== //==============================================================================
/** /**
*
* @author lhunath, 15-02-04 * @author lhunath, 15-02-04
*/ */

View File

@ -117,8 +117,8 @@ public abstract class Components {
} }
public static Component stud() { public static Component stud() {
Dimension studDimension = new Dimension( 8, 8 ); Dimension studDimension = new Dimension( 8, 8 );
Box.Filler rigidArea = new Box.Filler( studDimension, studDimension, studDimension ); Box.Filler rigidArea = new Box.Filler( studDimension, studDimension, studDimension );
rigidArea.setAlignmentX( Component.LEFT_ALIGNMENT ); rigidArea.setAlignmentX( Component.LEFT_ALIGNMENT );
rigidArea.setAlignmentY( Component.BOTTOM_ALIGNMENT ); rigidArea.setAlignmentY( Component.BOTTOM_ALIGNMENT );
rigidArea.setBackground( Color.red ); rigidArea.setBackground( Color.red );

View File

@ -17,7 +17,6 @@
//============================================================================== //==============================================================================
/** /**
*
* @author lhunath, 15-02-04 * @author lhunath, 15-02-04
*/ */

View File

@ -81,7 +81,7 @@ public class IncognitoAuthenticationPanel extends AuthenticationPanel<IncognitoU
@Override @Override
public PasswordFrame<IncognitoUser, ?> newPasswordFrame() { public PasswordFrame<IncognitoUser, ?> newPasswordFrame() {
return new PasswordFrame<IncognitoUser, IncognitoSite>(getSelectedUser()) { return new PasswordFrame<IncognitoUser, IncognitoSite>( getSelectedUser() ) {
@Override @Override
protected IncognitoSite createSite(final IncognitoUser user, final String siteName, final UnsignedInteger siteCounter, protected IncognitoSite createSite(final IncognitoUser user, final String siteName, final UnsignedInteger siteCounter,
final MPResultType resultType, final MPResultType resultType,

View File

@ -43,12 +43,12 @@ import javax.swing.plaf.metal.MetalComboBoxEditor;
public class ModelAuthenticationPanel extends AuthenticationPanel<MPFileUser> implements ItemListener, ActionListener, DocumentListener { public class ModelAuthenticationPanel extends AuthenticationPanel<MPFileUser> implements ItemListener, ActionListener, DocumentListener {
@SuppressWarnings("UnusedDeclaration") @SuppressWarnings("UnusedDeclaration")
private static final Logger logger = Logger.get( ModelAuthenticationPanel.class ); private static final Logger logger = Logger.get( ModelAuthenticationPanel.class );
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final JComboBox<MPFileUser> userField; private final JComboBox<MPFileUser> userField;
private final JLabel masterPasswordLabel; private final JLabel masterPasswordLabel;
private final JPasswordField masterPasswordField; private final JPasswordField masterPasswordField;
public ModelAuthenticationPanel(final UnlockFrame unlockFrame) { public ModelAuthenticationPanel(final UnlockFrame unlockFrame) {
super( unlockFrame ); super( unlockFrame );
@ -170,9 +170,10 @@ public class ModelAuthenticationPanel extends AuthenticationPanel<MPFileUser> im
return; return;
if (JOptionPane.showConfirmDialog( ModelAuthenticationPanel.this, // if (JOptionPane.showConfirmDialog( ModelAuthenticationPanel.this, //
strf( "Are you sure you want to delete the user and sites remembered for:\n%s.", strf( "Are you sure you want to delete the user and sites remembered for:\n%s.",
deleteUser.getFullName() ), // deleteUser.getFullName() ), //
"Delete User", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE ) == JOptionPane.CANCEL_OPTION) "Delete User", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE )
== JOptionPane.CANCEL_OPTION)
return; return;
MPFileUserManager.get().deleteUser( deleteUser ); MPFileUserManager.get().deleteUser( deleteUser );
@ -205,9 +206,10 @@ public class ModelAuthenticationPanel extends AuthenticationPanel<MPFileUser> im
@Override @Override
public PasswordFrame<MPFileUser, MPFileSite> newPasswordFrame() { public PasswordFrame<MPFileUser, MPFileSite> newPasswordFrame() {
return new PasswordFrame<MPFileUser, MPFileSite>(getSelectedUser()) { return new PasswordFrame<MPFileUser, MPFileSite>( getSelectedUser() ) {
@Override @Override
protected MPFileSite createSite(final MPFileUser user, final String siteName, final UnsignedInteger siteCounter, final MPResultType resultType, protected MPFileSite createSite(final MPFileUser user, final String siteName, final UnsignedInteger siteCounter,
final MPResultType resultType,
final MPMasterKey.Version algorithmVersion) { final MPMasterKey.Version algorithmVersion) {
return new MPFileSite( user, siteName, siteCounter, resultType, algorithmVersion ); return new MPFileSite( user, siteName, siteCounter, resultType, algorithmVersion );
} }

View File

@ -44,10 +44,10 @@ public class UnlockFrame extends JFrame {
private final JLabel identiconLabel; private final JLabel identiconLabel;
private final JButton signInButton; private final JButton signInButton;
private final JPanel authenticationContainer; private final JPanel authenticationContainer;
private AuthenticationPanel<?> authenticationPanel; private AuthenticationPanel<?> authenticationPanel;
private Future<?> identiconFuture; private Future<?> identiconFuture;
private boolean incognito; private boolean incognito;
private MPUser<?> user; private MPUser<?> user;
public UnlockFrame(final SignInCallback signInCallback) { public UnlockFrame(final SignInCallback signInCallback) {
super( "Unlock Master Password" ); super( "Unlock Master Password" );
@ -170,7 +170,7 @@ public class UnlockFrame extends JFrame {
SwingUtilities.invokeLater( new Runnable() { SwingUtilities.invokeLater( new Runnable() {
@Override @Override
public void run() { public void run() {
String fullName = (user == null)? "": user.getFullName(); String fullName = (user == null)? "": user.getFullName();
char[] masterPassword = authenticationPanel.getMasterPassword(); char[] masterPassword = authenticationPanel.getMasterPassword();
if (fullName.isEmpty() || (masterPassword.length == 0)) { if (fullName.isEmpty() || (masterPassword.length == 0)) {
@ -187,9 +187,9 @@ public class UnlockFrame extends JFrame {
} }
}, 300, TimeUnit.MILLISECONDS ); }, 300, TimeUnit.MILLISECONDS );
String fullName = (user == null)? "": user.getFullName(); String fullName = (user == null)? "": user.getFullName();
char[] masterPassword = authenticationPanel.getMasterPassword(); char[] masterPassword = authenticationPanel.getMasterPassword();
boolean enabled = !fullName.isEmpty() && (masterPassword.length > 0); boolean enabled = !fullName.isEmpty() && (masterPassword.length > 0);
signInButton.setEnabled( enabled ); signInButton.setEnabled( enabled );
return enabled; return enabled;