Update check for Java GUI + Copy password on Android + Native scrypt for Android.
This commit is contained in:
parent
f47ff67ba9
commit
76280ac71c
@ -25,7 +25,9 @@
|
||||
<artifactId>android-maven-plugin</artifactId>
|
||||
|
||||
<configuration>
|
||||
<sdk>19</sdk>
|
||||
<sdk>
|
||||
<platform>19</platform>
|
||||
</sdk>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
@ -59,6 +61,15 @@
|
||||
<artifactId>android</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.lambdaworks</groupId>
|
||||
<artifactId>libscrypt</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<type>so</type>
|
||||
<classifier>android</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
@ -64,14 +64,16 @@
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="26sp" />
|
||||
|
||||
<TextView
|
||||
<Button
|
||||
android:id="@+id/sitePasswordField"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:background="@null"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="32sp"
|
||||
android:text="LuxdZozvDuma4[" />
|
||||
android:text="LuxdZozvDuma4["
|
||||
android:onClick="copySitePassword" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/typeField"
|
||||
|
@ -1,7 +1,9 @@
|
||||
package com.lyndir.masterpassword;
|
||||
|
||||
import static com.lyndir.lhunath.opal.system.util.StringUtils.strf;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.*;
|
||||
import android.graphics.Paint;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
@ -85,7 +87,8 @@ public class EmergencyActivity extends Activity {
|
||||
sitePasswordField.setTypeface( Res.sourceCodePro_Black );
|
||||
sitePasswordField.setPaintFlags( userNameField.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG );
|
||||
|
||||
typeField.setAdapter( new ArrayAdapter<>( this, R.layout.type_item, MPElementType.forClass( MPElementTypeClass.Generated ) ) );
|
||||
typeField.setAdapter(
|
||||
new ArrayAdapter<MPElementType>( 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 {
|
||||
|
||||
|
@ -26,6 +26,33 @@
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>buildnumber-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>validate</phase>
|
||||
<goals>
|
||||
<goal>create</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<doCheck>false</doCheck>
|
||||
<doUpdate>false</doUpdate>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifestEntries>
|
||||
<SCM-Revision>${buildNumber}</SCM-Revision>
|
||||
</manifestEntries>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user