aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeapo <mohamed@zenadi.com>2014-08-23 18:44:54 +0200
committerzeapo <mohamed@zenadi.com>2014-08-23 18:44:54 +0200
commit734988be283db33d68dfb610e51486a3ba07ad22 (patch)
tree6fb997358f3ee871bedcd0ef1c140f02b48e21df
parent196813022a694b0b2a3b75c9e785bfd04bbd0ca6 (diff)
added ssh-key based authentication for clone
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/GitHandler.java126
-rw-r--r--app/src/main/java/com/zeapo/pwdstore/UserPreference.java20
-rw-r--r--app/src/main/res/layout/activity_git_clone.xml8
-rw-r--r--app/src/main/res/xml/preference.xml3
4 files changed, 139 insertions, 18 deletions
diff --git a/app/src/main/java/com/zeapo/pwdstore/GitHandler.java b/app/src/main/java/com/zeapo/pwdstore/GitHandler.java
index 7dc25567..21f3011e 100644
--- a/app/src/main/java/com/zeapo/pwdstore/GitHandler.java
+++ b/app/src/main/java/com/zeapo/pwdstore/GitHandler.java
@@ -26,6 +26,7 @@ import android.widget.TextView;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
+import com.jcraft.jsch.UserInfo;
import com.zeapo.pwdstore.crypto.PgpHandler;
import com.zeapo.pwdstore.utils.PasswordRepository;
@@ -36,10 +37,15 @@ import org.apache.commons.io.FileUtils;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.api.errors.TransportException;
+import org.eclipse.jgit.errors.UnsupportedCredentialItem;
import org.eclipse.jgit.merge.MergeStrategy;
+import org.eclipse.jgit.transport.CredentialItem;
+import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.transport.CredentialsProviderUserInfo;
import org.eclipse.jgit.transport.JschConfigSessionFactory;
import org.eclipse.jgit.transport.OpenSshConfig;
import org.eclipse.jgit.transport.SshSessionFactory;
+import org.eclipse.jgit.transport.URIish;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.eclipse.jgit.util.FS;
@@ -128,21 +134,6 @@ public class GitHandler extends Activity {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
String selection = ((Spinner) findViewById(R.id.connection_mode)).getSelectedItem().toString();
-
- if (selection.equalsIgnoreCase("ssh-key (not yet implemented)")) {
- new AlertDialog.Builder(activity)
- .setMessage("Authentication method not implemented yet")
- .setPositiveButton("OK",
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- dialog.cancel();
- }
- }
- ).show();
- ((Button) findViewById(R.id.clone_button)).setEnabled(false);
- } else {
- ((Button) findViewById(R.id.clone_button)).setEnabled(true);
- }
connectionMode = selection;
}
@@ -506,7 +497,112 @@ public class GitHandler extends Activity {
private void invokeWithAuthentication(final GitHandler activity, final Method method) {
if (connectionMode.equalsIgnoreCase("ssh-key")) {
+ final File sshKey = new File(getFilesDir() + "/.ssh_key");
+ if (!sshKey.exists()) {
+ new AlertDialog.Builder(this)
+ .setMessage("Please import your SSH key file in the preferences")
+ .setTitle("No SSH key")
+ .setPositiveButton("OK", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int id) {
+ try {
+ Intent intent = new Intent(getApplicationContext(), UserPreference.class);
+ startActivity(intent);
+ } catch (Exception e) {
+ System.out.println("Exception caught :(");
+ e.printStackTrace();
+ }
+ }
+ }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int id) {
+ // Do nothing...
+ }
+ }).show();
+ } else {
+ final EditText passphrase = new EditText(activity);
+ passphrase.setHint("Passphrase");
+ passphrase.setWidth(LinearLayout.LayoutParams.MATCH_PARENT);
+ passphrase.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
+
+ new AlertDialog.Builder(activity)
+ .setTitle("Authenticate")
+ .setMessage("Please provide the passphrase for your SSH key. Leave it empty if there is no passphrase.")
+ .setView(passphrase)
+ .setPositiveButton("OK", new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+
+ SshSessionFactory.setInstance(new GitConfigSessionFactory());
+ try {
+
+ JschConfigSessionFactory sessionFactory = new JschConfigSessionFactory() {
+
+ @Override
+ protected JSch
+ getJSch(final OpenSshConfig.Host hc, FS fs) throws JSchException {
+ JSch jsch = super.getJSch(hc, fs);
+ jsch.removeAllIdentity();
+ jsch.addIdentity(sshKey.getAbsolutePath());
+ return jsch;
+ }
+
+ @Override
+ protected void configure(OpenSshConfig.Host hc, Session session) {
+ session.setConfig("StrictHostKeyChecking", "no");
+ CredentialsProvider provider = new CredentialsProvider() {
+ @Override
+ public boolean isInteractive() {
+ return false;
+ }
+
+ @Override
+ public boolean supports(CredentialItem... items) {
+ return true;
+ }
+
+ @Override
+ public boolean get(URIish uri, CredentialItem... items) throws UnsupportedCredentialItem {
+ for (CredentialItem item : items) {
+ if (item instanceof CredentialItem.Username) {
+ ((CredentialItem.Username) item).setValue(settings.getString("git_remote_username", "git"));
+ continue;
+ }
+ if (item instanceof CredentialItem.StringType) {
+ ((CredentialItem.StringType) item).setValue(passphrase.getText().toString());
+ }
+ }
+ return true;
+ }
+ };
+ UserInfo userInfo = new CredentialsProviderUserInfo(session, provider);
+ session.setUserInfo(userInfo);
+ }
+ };
+
+ SshSessionFactory.setInstance(sessionFactory);
+
+
+ CloneCommand cmd = Git.cloneRepository()
+ .setDirectory(localDir)
+ .setURI(hostname)
+ .setBare(false)
+ .setNoCheckout(false)
+ .setCloneAllBranches(true);
+
+ new CloneTask(activity).execute(cmd);
+
+ } catch (Exception e){
+ e.printStackTrace();
+ }
+
+ }
+ }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ // Do nothing.
+ }
+ }).show();
+ }
} else {
if (protocol.equals("ssh://")) {
final EditText password = new EditText(activity);
diff --git a/app/src/main/java/com/zeapo/pwdstore/UserPreference.java b/app/src/main/java/com/zeapo/pwdstore/UserPreference.java
index 35b0d922..49709169 100644
--- a/app/src/main/java/com/zeapo/pwdstore/UserPreference.java
+++ b/app/src/main/java/com/zeapo/pwdstore/UserPreference.java
@@ -1,9 +1,13 @@
package com.zeapo.pwdstore;
import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.Uri;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceActivity;
+import android.preference.PreferenceManager;
+import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
@@ -12,6 +16,9 @@ import com.zeapo.pwdstore.utils.PasswordRepository;
import org.apache.commons.io.FileUtils;
+import java.io.File;
+import java.net.URI;
+
public class UserPreference extends PreferenceActivity implements Preference.OnPreferenceClickListener {
@Override
@@ -19,6 +26,7 @@ public class UserPreference extends PreferenceActivity implements Preference.OnP
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preference);
findPreference("openpgp_key_id").setOnPreferenceClickListener(this);
+ findPreference("ssh_key").setOnPreferenceClickListener(this);
getActionBar().setDisplayHomeAsUpEnabled(true);
}
@@ -46,6 +54,10 @@ public class UserPreference extends PreferenceActivity implements Preference.OnP
Intent intent = new Intent(this, PgpHandler.class);
intent.putExtra("Operation", "GET_KEY_ID");
startActivityForResult(intent, 0);
+ } else if (pref.getKey().equals("ssh_key")) {
+ Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
+ intent.setType("file/*");
+ startActivityForResult(intent, 1);
}
return true;
}
@@ -53,6 +65,14 @@ public class UserPreference extends PreferenceActivity implements Preference.OnP
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (resultCode == RESULT_OK) {
+ if (requestCode == 1) {
+ Uri sshFile = data.getData();
+ try {
+ FileUtils.copyFile(new File(sshFile.getPath()), new File(getFilesDir() + "/.ssh_key"));
+ } catch (Exception e) {
+
+ }
+ }
}
}
}
diff --git a/app/src/main/res/layout/activity_git_clone.xml b/app/src/main/res/layout/activity_git_clone.xml
index d4ccbc8a..f8e76cf4 100644
--- a/app/src/main/res/layout/activity_git_clone.xml
+++ b/app/src/main/res/layout/activity_git_clone.xml
@@ -15,7 +15,8 @@
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
- android:layout_height="wrap_content">
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
<Spinner
android:id="@+id/clone_protocol"
android:layout_width="wrap_content"
@@ -24,8 +25,9 @@
android:hint="Repository URI"
android:id="@+id/clone_uri"
android:layout_width="match_parent"
- android:layout_height="wrap_content" />
- </LinearLayout>
+ android:layout_height="wrap_content"
+ android:inputType="textUri"/>
+ </LinearLayout>
<Spinner
android:layout_width="match_parent"
diff --git a/app/src/main/res/xml/preference.xml b/app/src/main/res/xml/preference.xml
index d0abd8d1..849be86a 100644
--- a/app/src/main/res/xml/preference.xml
+++ b/app/src/main/res/xml/preference.xml
@@ -10,6 +10,9 @@
<EditTextPreference android:title="Username"
android:key="git_remote_username"
android:hint="username"/>
+ <Preference
+ android:title="SSH Key"
+ android:key="ssh_key"/>
</PreferenceCategory>
<PreferenceCategory android:title="Crypto">