implement publickey authentication in JavaFileStorage (not yet integrated in main app)
This commit is contained in:
@@ -2,7 +2,9 @@ package keepass2android.javafilestorage;
|
|||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -13,6 +15,7 @@ import com.jcraft.jsch.ChannelSftp;
|
|||||||
import com.jcraft.jsch.ChannelSftp.LsEntry;
|
import com.jcraft.jsch.ChannelSftp.LsEntry;
|
||||||
import com.jcraft.jsch.JSch;
|
import com.jcraft.jsch.JSch;
|
||||||
import com.jcraft.jsch.JSchException;
|
import com.jcraft.jsch.JSchException;
|
||||||
|
import com.jcraft.jsch.KeyPair;
|
||||||
import com.jcraft.jsch.Session;
|
import com.jcraft.jsch.Session;
|
||||||
import com.jcraft.jsch.SftpATTRS;
|
import com.jcraft.jsch.SftpATTRS;
|
||||||
import com.jcraft.jsch.SftpException;
|
import com.jcraft.jsch.SftpException;
|
||||||
@@ -21,6 +24,7 @@ import com.jcraft.jsch.UserInfo;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
public class SftpStorage extends JavaFileStorageBase {
|
public class SftpStorage extends JavaFileStorageBase {
|
||||||
|
|
||||||
@@ -320,14 +324,28 @@ public class SftpStorage extends JavaFileStorageBase {
|
|||||||
jsch = new JSch();
|
jsch = new JSch();
|
||||||
ConnectionInfo ci = splitStringToConnectionInfo(filename);
|
ConnectionInfo ci = splitStringToConnectionInfo(filename);
|
||||||
|
|
||||||
jsch.setKnownHosts(_appContext.getFilesDir().getAbsolutePath() + "/known_hosts");
|
String base_dir = getBaseDir();
|
||||||
|
jsch.setKnownHosts(base_dir + "/known_hosts");
|
||||||
|
|
||||||
|
String key_filename = getKeyFileName();
|
||||||
|
try{
|
||||||
|
createKeyPair(key_filename);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
System.out.println(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
jsch.addIdentity(key_filename);
|
||||||
|
} catch (java.lang.Exception e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Session session = jsch.getSession(ci.username, ci.host, ci.port);
|
Session session = jsch.getSession(ci.username, ci.host, ci.port);
|
||||||
UserInfo ui = new SftpUserInfo(ci.password,_appContext);
|
UserInfo ui = new SftpUserInfo(ci.password,_appContext);
|
||||||
session.setUserInfo(ui);
|
session.setUserInfo(ui);
|
||||||
|
|
||||||
session.setConfig("PreferredAuthentications",
|
session.setConfig("PreferredAuthentications", "publickey,password");
|
||||||
"password,publickey");
|
|
||||||
|
|
||||||
session.connect();
|
session.connect();
|
||||||
|
|
||||||
@@ -340,6 +358,37 @@ public class SftpStorage extends JavaFileStorageBase {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private String getBaseDir() {
|
||||||
|
return _appContext.getFilesDir().getAbsolutePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private String getKeyFileName() {
|
||||||
|
return getBaseDir() + "/id_kp2a_rsa";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String createKeyPair() throws IOException, JSchException {
|
||||||
|
return createKeyPair(getKeyFileName());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String createKeyPair(String key_filename) throws JSchException, IOException {
|
||||||
|
String public_key_filename = key_filename + ".pub";
|
||||||
|
File file = new File(key_filename);
|
||||||
|
if (file.exists())
|
||||||
|
return public_key_filename;
|
||||||
|
int type = KeyPair.RSA;
|
||||||
|
KeyPair kpair = KeyPair.genKeyPair(jsch, type, 2048);
|
||||||
|
kpair.writePrivateKey(key_filename);
|
||||||
|
|
||||||
|
kpair.writePublicKey(public_key_filename, "generated by Keepass2Android");
|
||||||
|
//ret = "Fingerprint: " + kpair.getFingerPrint();
|
||||||
|
kpair.dispose();
|
||||||
|
return public_key_filename;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public ConnectionInfo splitStringToConnectionInfo(String filename)
|
public ConnectionInfo splitStringToConnectionInfo(String filename)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
ConnectionInfo ci = new ConnectionInfo();
|
ConnectionInfo ci = new ConnectionInfo();
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:padding="10dp"
|
||||||
|
>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/prompt"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
/>
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/entry"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@android:drawable/editbox_background"
|
||||||
|
android:password="true"
|
||||||
|
/>
|
||||||
|
<LinearLayout
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
android:id="@+id/ok"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="OK"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
android:id="@+id/cancel"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Cancel"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
@@ -135,7 +135,12 @@ package com.crocoapps.javafilestoragetest;
|
|||||||
import group.pals.android.lib.ui.filechooser.FileChooserActivity;
|
import group.pals.android.lib.ui.filechooser.FileChooserActivity;
|
||||||
import group.pals.android.lib.ui.filechooser.providers.BaseFileProviderUtils;
|
import group.pals.android.lib.ui.filechooser.providers.BaseFileProviderUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -662,6 +667,20 @@ public class MainActivity extends Activity implements JavaFileStorage.FileStorag
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String readStream(InputStream is) {
|
||||||
|
StringBuilder sb = new StringBuilder(512);
|
||||||
|
try {
|
||||||
|
Reader r = new InputStreamReader(is, "UTF-8");
|
||||||
|
int c = 0;
|
||||||
|
while ((c = r.read()) != -1) {
|
||||||
|
sb.append((char) c);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void performManualFileSelect(boolean isForSave, final int requestCode,
|
public void performManualFileSelect(boolean isForSave, final int requestCode,
|
||||||
String protocolId)
|
String protocolId)
|
||||||
@@ -669,6 +688,30 @@ public class MainActivity extends Activity implements JavaFileStorage.FileStorag
|
|||||||
if (protocolId.equals("sftp"))
|
if (protocolId.equals("sftp"))
|
||||||
{
|
{
|
||||||
final View view = getLayoutInflater().inflate(R.layout.sftp_credentials, null);
|
final View view = getLayoutInflater().inflate(R.layout.sftp_credentials, null);
|
||||||
|
|
||||||
|
view.findViewById(R.id.send_public_key).setOnClickListener(v -> {
|
||||||
|
Intent sendIntent = new Intent();
|
||||||
|
|
||||||
|
|
||||||
|
SftpStorage sftpStorage = (SftpStorage)storageToTest;
|
||||||
|
try {
|
||||||
|
String pub_filename = sftpStorage.createKeyPair();
|
||||||
|
|
||||||
|
sendIntent.setAction(Intent.ACTION_SEND);
|
||||||
|
sendIntent.putExtra(Intent.EXTRA_TEXT, readStream(new FileInputStream(pub_filename)));
|
||||||
|
|
||||||
|
sendIntent.putExtra(Intent.EXTRA_SUBJECT, "Keepass2Android sftp public key");
|
||||||
|
sendIntent.setType("text/plain");
|
||||||
|
this.startActivity(Intent.createChooser(sendIntent, "Send public key to..."));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Toast.makeText(this,"Failed to create key pair: " + ex.getMessage(), Toast.LENGTH_LONG);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
new AlertDialog.Builder(this)
|
new AlertDialog.Builder(this)
|
||||||
.setView(view)
|
.setView(view)
|
||||||
.setTitle("Enter SFTP credentials")
|
.setTitle("Enter SFTP credentials")
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:inputType="textNoSuggestions"
|
android:inputType="textNoSuggestions"
|
||||||
android:text=""
|
android:text="philipp-gross"
|
||||||
android:hint="@string/hint_sftp_host" />
|
android:hint="@string/hint_sftp_host" />
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/portsep"
|
android:id="@+id/portsep"
|
||||||
@@ -63,6 +63,9 @@
|
|||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:text="/home/philipp"
|
android:text="/home/philipp"
|
||||||
/>
|
/>
|
||||||
|
<Button android:id="@+id/send_public_key"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="send public key" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
Reference in New Issue
Block a user