diff options
author | zeapo <mohamed@zenadi.com> | 2014-08-23 18:44:54 +0200 |
---|---|---|
committer | zeapo <mohamed@zenadi.com> | 2014-08-23 18:44:54 +0200 |
commit | 734988be283db33d68dfb610e51486a3ba07ad22 (patch) | |
tree | 6fb997358f3ee871bedcd0ef1c140f02b48e21df /app/src/main | |
parent | 196813022a694b0b2a3b75c9e785bfd04bbd0ca6 (diff) |
added ssh-key based authentication for clone
Diffstat (limited to 'app/src/main')
-rw-r--r-- | app/src/main/java/com/zeapo/pwdstore/GitHandler.java | 126 | ||||
-rw-r--r-- | app/src/main/java/com/zeapo/pwdstore/UserPreference.java | 20 | ||||
-rw-r--r-- | app/src/main/res/layout/activity_git_clone.xml | 8 | ||||
-rw-r--r-- | app/src/main/res/xml/preference.xml | 3 |
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"> |