summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorParménides GV <parmegv@sdf.org>2014-05-05 16:06:53 +0200
committerParménides GV <parmegv@sdf.org>2014-05-05 16:06:53 +0200
commit230ae10fb3a0c08cbd16e91fce041133bdf5ae8e (patch)
tree37ab910d47817399301aed25374d5c9fd37cb22c
parent3ab74308e7ba1fda02d3427ec795eac397707199 (diff)
New menu option: signup.
There is some problem in the maths, because the server says it's ok but login doesn't work from Android app nor from webapp.
-rw-r--r--app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java9
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/Dashboard.java59
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java9
-rw-r--r--app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java150
-rw-r--r--app/src/main/res/menu/client_dashboard.xml13
-rw-r--r--app/src/main/res/values/strings.xml1
6 files changed, 228 insertions, 13 deletions
diff --git a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java
index f8895983..8678cc80 100644
--- a/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java
+++ b/app/src/debug/java/se/leap/bitmaskclient/ProviderAPI.java
@@ -214,27 +214,32 @@ public class ProviderAPI extends IntentService {
LeapSRPSession client = new LeapSRPSession(username, password, params);
byte[] salted_password = client.calculateSaltedPassword();
/* Calculate password verifier */
- BigInteger password_verifier = client.calculateV();
+ BigInteger password_verifier = client.calculateV(username, password, salted_password);
/* Send to the server */
try {
- sendNewUserDataToSRPServer(authentication_server, username, new BigInteger(salted_password).toString(), password_verifier.toString());
+ JSONObject result = sendNewUserDataToSRPServer(authentication_server, username, new BigInteger(salted_password).toString(16), password_verifier.toString());
+ Log.d(TAG, result.toString());
broadcast_progress(progress++);
} catch (ClientProtocolException e) {
// session_id_bundle.putBoolean(RESULT_KEY, false);
// session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_client_http_user_message));
// session_id_bundle.putString(LogInDialog.USERNAME, username);
+ e.printStackTrace();
} catch (IOException e) {
// session_id_bundle.putBoolean(RESULT_KEY, false);
// session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_io_exception_user_message));
// session_id_bundle.putString(LogInDialog.USERNAME, username);
+ e.printStackTrace();
} catch (JSONException e) {
// session_id_bundle.putBoolean(RESULT_KEY, false);
// session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_json_exception_user_message));
// session_id_bundle.putString(LogInDialog.USERNAME, username);
+ e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// session_id_bundle.putBoolean(RESULT_KEY, false);
// session_id_bundle.putString(getResources().getString(R.string.user_message), getResources().getString(R.string.error_no_such_algorithm_exception_user_message));
// session_id_bundle.putString(LogInDialog.USERNAME, username);
+ e.printStackTrace();
} catch (KeyManagementException e) {
// TODO Auto-generated catch block
e.printStackTrace();
diff --git a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java
index 3c17ebb8..241286bb 100644
--- a/app/src/main/java/se/leap/bitmaskclient/Dashboard.java
+++ b/app/src/main/java/se/leap/bitmaskclient/Dashboard.java
@@ -21,6 +21,7 @@ import org.json.JSONObject;
import se.leap.bitmaskclient.R;
import se.leap.bitmaskclient.ProviderAPIResultReceiver.Receiver;
+import se.leap.bitmaskclient.SignUpDialog;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.DialogFragment;
@@ -50,7 +51,7 @@ import android.widget.Toast;
* @author Sean Leonard <meanderingcode@aetherislands.net>
* @author parmegv
*/
-public class Dashboard extends Activity implements LogInDialog.LogInDialogInterface,Receiver {
+public class Dashboard extends Activity implements LogInDialog.LogInDialogInterface, SignUpDialog.SignUpDialogInterface, Receiver {
protected static final int CONFIGURE_LEAP = 0;
protected static final int SWITCH_PROVIDER = 1;
@@ -204,6 +205,7 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf
menu.findItem(R.id.login_button).setVisible(true);
menu.findItem(R.id.logout_button).setVisible(false);
}
+ menu.findItem(R.id.signup_button).setVisible(true);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
@@ -243,6 +245,9 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf
case R.id.logout_button:
logOut();
return true;
+ case R.id.signup_button:
+ signUpDialog(((ViewGroup)findViewById(android.R.id.content)).getChildAt(0), Bundle.EMPTY);
+ return true;
default:
return super.onOptionsItemSelected(item);
}
@@ -340,6 +345,58 @@ public class Dashboard extends Activity implements LogInDialog.LogInDialogInterf
newFragment.show(fragment_transaction, LogInDialog.TAG);
}
+ @Override
+ public void signUp(String username, String password) {
+ mProgressBar = (ProgressBar) findViewById(R.id.eipProgress);
+ eipStatus = (TextView) findViewById(R.id.eipStatus);
+
+ providerAPI_result_receiver = new ProviderAPIResultReceiver(new Handler());
+ providerAPI_result_receiver.setReceiver(this);
+
+ Intent provider_API_command = new Intent(this, ProviderAPI.class);
+
+ Bundle parameters = new Bundle();
+ parameters.putString(SignUpDialog.USERNAME, username);
+ parameters.putString(SignUpDialog.PASSWORD, password);
+
+ JSONObject provider_json;
+ try {
+ provider_json = new JSONObject(preferences.getString(Provider.KEY, ""));
+ parameters.putString(Provider.API_URL, provider_json.getString(Provider.API_URL) + "/" + provider_json.getString(Provider.API_VERSION));
+ } catch (JSONException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ provider_API_command.setAction(ProviderAPI.SRP_REGISTER);
+ provider_API_command.putExtra(ProviderAPI.PARAMETERS, parameters);
+ provider_API_command.putExtra(ProviderAPI.RECEIVER_KEY, providerAPI_result_receiver);
+
+ mProgressBar.setVisibility(ProgressBar.VISIBLE);
+ eipStatus.setText(R.string.authenticating_message);
+ //mProgressBar.setMax(4);
+ startService(provider_API_command);
+ }
+
+ /**
+ * Shows the sign up dialog.
+ * @param view from which the dialog is created.
+ */
+ public void signUpDialog(View view, Bundle resultData) {
+ FragmentTransaction fragment_transaction = getFragmentManager().beginTransaction();
+ Fragment previous_sign_up_dialog = getFragmentManager().findFragmentByTag(SignUpDialog.TAG);
+ if (previous_sign_up_dialog != null) {
+ fragment_transaction.remove(previous_sign_up_dialog);
+ }
+ fragment_transaction.addToBackStack(null);
+
+ DialogFragment newFragment = SignUpDialog.newInstance();
+ if(resultData != null && !resultData.isEmpty()) {
+ newFragment.setArguments(resultData);
+ }
+ newFragment.show(fragment_transaction, SignUpDialog.TAG);
+ }
+
/**
* Asks ProviderAPI to download an authenticated OpenVPN certificate.
* @param session_id cookie for the server to allow us to download the certificate.
diff --git a/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java b/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java
index db091300..8d95cdb8 100644
--- a/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java
+++ b/app/src/main/java/se/leap/bitmaskclient/LeapSRPSession.java
@@ -172,9 +172,11 @@ public class LeapSRPSession {
* Calculates the parameter V of the SRP-6a algorithm.
* @return the value of V
*/
- public BigInteger calculateV() {
+ public BigInteger calculateV(String username, String password, byte[] salt) {
String k_string = "bf66c44a428916cad64aa7c679f3fd897ad4c375e9bbb4cbf2f5de241d618ef0";
BigInteger k = new BigInteger(k_string, 16);
+ byte[] x_bytes = calculatePasswordHash(username, password, ConfigHelper.trim(salt));
+ x = new BigInteger(1, x_bytes);
BigInteger v = k.multiply(g.modPow(x, N)); // g^x % N
return v;
}
@@ -226,11 +228,8 @@ public class LeapSRPSession {
// Calculate x = H(s | H(U | ':' | password))
byte[] M1 = null;
if(new BigInteger(1, Bbytes).mod(new BigInteger(1, N_bytes)) != BigInteger.ZERO) {
- byte[] xb = calculatePasswordHash(username, password, ConfigHelper.trim(salt_bytes));
- this.x = new BigInteger(1, xb);
-
// Calculate v = kg^x mod N
- this.v = calculateV();
+ this.v = calculateV(username, password, salt_bytes);
// H(N)
byte[] digest_of_n = newDigest().digest(N_bytes);
diff --git a/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java b/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java
new file mode 100644
index 00000000..601df843
--- /dev/null
+++ b/app/src/main/java/se/leap/bitmaskclient/SignUpDialog.java
@@ -0,0 +1,150 @@
+/**
+ * Copyright (c) 2013 LEAP Encryption Access Project and contributers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+ package se.leap.bitmaskclient;
+
+import se.leap.bitmaskclient.R;
+import android.R.color;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.DialogFragment;
+import android.content.DialogInterface;
+import android.content.res.ColorStateList;
+import android.os.Bundle;
+import android.provider.CalendarContract.Colors;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.BounceInterpolator;
+import android.widget.EditText;
+import android.widget.TextView;
+
+/**
+ * Implements the sign up dialog, currently without progress dialog.
+ *
+ * It returns to the previous fragment when finished, and sends username and password to the registration method.
+ *
+ * It also notifies the user if the password is not valid.
+ *
+ * @author parmegv
+ *
+ */
+public class SignUpDialog extends DialogFragment {
+
+ final public static String TAG = "signUpDialog";
+ final public static String VERB = "log in";
+ final public static String USERNAME = "username";
+ final public static String PASSWORD = "password";
+ final public static String USERNAME_MISSING = "username missing";
+ final public static String PASSWORD_INVALID_LENGTH = "password_invalid_length";
+
+ private static boolean is_eip_pending = false;
+
+ public AlertDialog onCreateDialog(Bundle savedInstanceState) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ View log_in_dialog_view = inflater.inflate(R.layout.log_in_dialog, null);
+
+ final TextView user_message = (TextView)log_in_dialog_view.findViewById(R.id.user_message);
+ if(getArguments() != null && getArguments().containsKey(getResources().getString(R.string.user_message))) {
+ user_message.setText(getArguments().getString(getResources().getString(R.string.user_message)));
+ } else {
+ user_message.setVisibility(View.GONE);
+ }
+
+ final EditText username_field = (EditText)log_in_dialog_view.findViewById(R.id.username_entered);
+ if(getArguments() != null && getArguments().containsKey(USERNAME)) {
+ String username = getArguments().getString(USERNAME);
+ username_field.setText(username);
+ }
+ if (getArguments() != null && getArguments().containsKey(USERNAME_MISSING)) {
+ username_field.setError(getResources().getString(R.string.username_ask));
+ }
+
+ final EditText password_field = (EditText)log_in_dialog_view.findViewById(R.id.password_entered);
+ if(!username_field.getText().toString().isEmpty() && password_field.isFocusable()) {
+ password_field.requestFocus();
+ }
+ if (getArguments() != null && getArguments().containsKey(PASSWORD_INVALID_LENGTH)) {
+ password_field.setError(getResources().getString(R.string.error_not_valid_password_user_message));
+ }
+ if(getArguments() != null && getArguments().getBoolean(EipServiceFragment.IS_EIP_PENDING, false)) {
+ is_eip_pending = true;
+ }
+
+
+ builder.setView(log_in_dialog_view)
+ .setPositiveButton(R.string.signup_button, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ String username = username_field.getText().toString();
+ String password = password_field.getText().toString();
+ dialog.dismiss();
+ interface_with_Dashboard.signUp(username, password);
+ }
+ })
+ .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ dialog.cancel();
+ }
+ });
+
+ return builder.create();
+ }
+
+ /**
+ * Interface used to communicate SignUpDialog with Dashboard.
+ *
+ * @author parmegv
+ *
+ */
+ public interface SignUpDialogInterface {
+ /**
+ * Starts authentication process.
+ * @param username
+ * @param password
+ */
+ public void signUp(String username, String password);
+ public void cancelAuthedEipOn();
+ }
+
+ SignUpDialogInterface interface_with_Dashboard;
+
+ /**
+ * @return a new instance of this DialogFragment.
+ */
+ public static DialogFragment newInstance() {
+ SignUpDialog dialog_fragment = new SignUpDialog();
+ return dialog_fragment;
+ }
+
+ @Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ try {
+ interface_with_Dashboard = (SignUpDialogInterface) activity;
+ } catch (ClassCastException e) {
+ throw new ClassCastException(activity.toString()
+ + " must implement SignUpDialogListener");
+ }
+ }
+
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ if(is_eip_pending)
+ interface_with_Dashboard.cancelAuthedEipOn();
+ super.onCancel(dialog);
+ }
+}
diff --git a/app/src/main/res/menu/client_dashboard.xml b/app/src/main/res/menu/client_dashboard.xml
index 676c07c7..d4e9c879 100644
--- a/app/src/main/res/menu/client_dashboard.xml
+++ b/app/src/main/res/menu/client_dashboard.xml
@@ -6,18 +6,21 @@
<item
android:id="@+id/switch_provider"
android:orderInCategory="501"
- android:title="@string/switch_provider_menu_option"/>
+ android:title="@string/switch_provider_menu_option"/>
+ <item
+ android:id="@+id/signup_button"
+ android:showAsAction="ifRoom"
+ android:title="@string/signup_button"
+ android:visible="false"/>
<item
android:id="@+id/login_button"
android:showAsAction="ifRoom"
android:title="@string/login_button"
- android:visible="false">
- </item>
+ android:visible="false"/>
<item
android:id="@+id/logout_button"
android:showAsAction="ifRoom"
android:title="@string/logout_button"
- android:visible="false">
- </item>
+ android:visible="false"/>
</menu>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 492c48c7..5f0e2120 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -116,6 +116,7 @@
<string name="error_no_such_algorithm_exception_user_message">Update the app</string>
<string name="login_button">Log In</string>
<string name="logout_button">Log Out</string>
+ <string name="signup_button">Sign Up</string>
<string name="setup_error_title">Configuration Error</string>
<string name="setup_error_configure_button">Configure</string>
<string name="setup_error_close_button">Exit</string>