implement publickey authentication in JavaFileStorage (not yet integrated in main app)

This commit is contained in:
Philipp Crocoll
2018-09-10 12:56:03 +02:00
parent 7e122529d2
commit fcf1214f80
4 changed files with 138 additions and 5 deletions

View File

@@ -2,7 +2,9 @@ package keepass2android.javafilestorage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
@@ -13,6 +15,7 @@ import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.ChannelSftp.LsEntry;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.KeyPair;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpATTRS;
import com.jcraft.jsch.SftpException;
@@ -21,6 +24,7 @@ import com.jcraft.jsch.UserInfo;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
public class SftpStorage extends JavaFileStorageBase {
@@ -320,14 +324,28 @@ public class SftpStorage extends JavaFileStorageBase {
jsch = new JSch();
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);
UserInfo ui = new SftpUserInfo(ci.password,_appContext);
session.setUserInfo(ui);
session.setConfig("PreferredAuthentications",
"password,publickey");
session.setConfig("PreferredAuthentications", "publickey,password");
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)
throws UnsupportedEncodingException {
ConnectionInfo ci = new ConnectionInfo();

View File

@@ -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>

View File

@@ -135,7 +135,12 @@ package com.crocoapps.javafilestoragetest;
import group.pals.android.lib.ui.filechooser.FileChooserActivity;
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.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
@@ -662,6 +667,20 @@ public class MainActivity extends Activity implements JavaFileStorage.FileStorag
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
public void performManualFileSelect(boolean isForSave, final int requestCode,
String protocolId)
@@ -669,6 +688,30 @@ public class MainActivity extends Activity implements JavaFileStorage.FileStorag
if (protocolId.equals("sftp"))
{
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)
.setView(view)
.setTitle("Enter SFTP credentials")

View File

@@ -15,7 +15,7 @@
android:layout_height="wrap_content"
android:singleLine="true"
android:inputType="textNoSuggestions"
android:text=""
android:text="philipp-gross"
android:hint="@string/hint_sftp_host" />
<TextView
android:id="@+id/portsep"
@@ -63,6 +63,9 @@
android:singleLine="true"
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>