diff --git a/MasterPassword/Java/masterpassword-android/pom.xml b/MasterPassword/Java/masterpassword-android/pom.xml index 7a784064..f7fa1824 100644 --- a/MasterPassword/Java/masterpassword-android/pom.xml +++ b/MasterPassword/Java/masterpassword-android/pom.xml @@ -25,7 +25,9 @@ android-maven-plugin - 19 + + 19 + @@ -59,6 +61,15 @@ android + + com.lambdaworks + libscrypt + 1.4.0 + so + android + runtime + + diff --git a/MasterPassword/Java/masterpassword-android/res/layout/activity_emergency.xml b/MasterPassword/Java/masterpassword-android/res/layout/activity_emergency.xml index 132a7cc3..e04df047 100644 --- a/MasterPassword/Java/masterpassword-android/res/layout/activity_emergency.xml +++ b/MasterPassword/Java/masterpassword-android/res/layout/activity_emergency.xml @@ -64,14 +64,16 @@ android:textColor="#FFFFFF" android:textSize="26sp" /> - + android:text="LuxdZozvDuma4[" + android:onClick="copySitePassword" /> ( this, R.layout.type_item, MPElementType.forClass( MPElementTypeClass.Generated ) ) ); + typeField.setAdapter( + new ArrayAdapter( this, R.layout.type_item, MPElementType.forClass( MPElementTypeClass.Generated ) ) ); typeField.setSelection( MPElementType.GeneratedLong.ordinal() ); counterField.setMinValue( 1 ); @@ -144,7 +147,11 @@ public class EmergencyActivity extends Activity { public byte[] call() throws Exception { try { - return MasterPassword.keyForPassword( masterPassword, userName ); + long start = System.currentTimeMillis(); + byte[] masterKey = MasterPassword.keyForPassword( masterPassword, userName ); + logger.inf( "masterKey time: %d", System.currentTimeMillis() - start ); + + return masterKey; } catch (RuntimeException e) { sitePasswordField.setText( "" ); @@ -182,7 +189,9 @@ public class EmergencyActivity extends Activity { @Override public void run() { try { + long start = System.currentTimeMillis(); final String sitePassword = MasterPassword.generateContent( type, siteName, masterKeyFuture.get(), counter ); + logger.inf( "sitePassword time: %d", System.currentTimeMillis() - start ); runOnUiThread( new Runnable() { @Override @@ -212,6 +221,22 @@ public class EmergencyActivity extends Activity { } ); } + public void copySitePassword(View view) { + String sitePassword = sitePasswordField.getText().toString(); + if (sitePassword.isEmpty()) + return; + + ClipDescription description = new ClipDescription( strf( "Password for %s", siteNameField.getText() ), + new String[]{ ClipDescription.MIMETYPE_TEXT_PLAIN } ); + ((ClipboardManager) getSystemService( CLIPBOARD_SERVICE )).setPrimaryClip( + new ClipData( description, new ClipData.Item( sitePassword ) ) ); + + Intent startMain = new Intent(Intent.ACTION_MAIN); + startMain.addCategory(Intent.CATEGORY_HOME); + startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(startMain); + } + private abstract class ValueChangedListener implements TextWatcher, NumberPicker.OnValueChangeListener, AdapterView.OnItemSelectedListener, View.OnFocusChangeListener { diff --git a/MasterPassword/Java/masterpassword-gui/pom.xml b/MasterPassword/Java/masterpassword-gui/pom.xml index d9c9466e..8cd78f27 100644 --- a/MasterPassword/Java/masterpassword-gui/pom.xml +++ b/MasterPassword/Java/masterpassword-gui/pom.xml @@ -26,6 +26,33 @@ + + org.codehaus.mojo + buildnumber-maven-plugin + + + validate + + create + + + + + false + false + + + + org.apache.maven.plugins + maven-jar-plugin + + + + ${buildNumber} + + + + org.apache.maven.plugins maven-shade-plugin diff --git a/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/GUI.java b/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/GUI.java index 7a2b59de..ef66cbf9 100644 --- a/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/GUI.java +++ b/MasterPassword/Java/masterpassword-gui/src/main/java/com/lyndir/masterpassword/GUI.java @@ -13,10 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + + package com.lyndir.masterpassword; +import com.google.common.base.Charsets; +import com.google.common.io.ByteStreams; +import com.google.common.io.CharStreams; +import com.lyndir.lhunath.opal.system.CodeUtils; +import com.lyndir.lhunath.opal.system.MessageDigests; +import com.lyndir.lhunath.opal.system.logging.Logger; import com.lyndir.lhunath.opal.system.util.TypeUtils; -import java.io.IOException; +import java.io.*; +import java.net.URI; +import java.net.URL; import javax.swing.*; @@ -27,16 +37,39 @@ import javax.swing.*; */ public class GUI implements UnlockFrame.SignInCallback { + @SuppressWarnings("UnusedDeclaration") + private static final Logger logger = Logger.get( GUI.class ); + private UnlockFrame unlockFrame = new UnlockFrame( this ); private PasswordFrame passwordFrame; public static void main(final String[] args) throws IOException { + try { + byte[] manifest = ByteStreams.toByteArray( GUI.class.getClassLoader().getResourceAsStream( "META-INF/MANIFEST.MF" ) ); + String manifestHash = CodeUtils.encodeHex( CodeUtils.digest( MessageDigests.SHA1, manifest ) ); + InputStream upstream = URI.create( "http://masterpasswordapp.com/masterpassword-gui.jar.mf.sha1" ).toURL().openStream(); + String upstreamHash = CharStreams.toString( new InputStreamReader( upstream, Charsets.UTF_8 ) ); + logger.inf( "Local Manifest Hash: %s", manifestHash ); + logger.inf( "Upstream Manifest Hash: %s", upstreamHash ); + if (!manifestHash.equalsIgnoreCase( upstreamHash )) { + logger.wrn( "You are not running the current official version. Please update from:\n" + + "http://masterpasswordapp.com/masterpassword-gui.jar" ); + JOptionPane.showMessageDialog( null, "A new version of Master Password is available.\n" + + "Please download the latest version from http://masterpasswordapp.com", + "Update Available", JOptionPane.WARNING_MESSAGE ); + } + } + catch (IOException e) { + logger.wrn( e, "Couldn't check for version update." ); + } + GUI gui; try { gui = TypeUtils.newInstance( AppleGUI.class ); - } catch (RuntimeException e) { + } + catch (RuntimeException e) { gui = new GUI(); } gui.open();