discover file extension in original filename from pgp

This commit is contained in:
Daniel Gultsch 2018-01-29 01:40:02 +01:00
parent 2f1f9f2c2c
commit bcd00bb517
5 changed files with 75 additions and 43 deletions

View File

@ -2,7 +2,9 @@ package eu.siacs.conversations.crypto;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Intent; import android.content.Intent;
import android.util.Log;
import org.openintents.openpgp.OpenPgpMetadata;
import org.openintents.openpgp.util.OpenPgpApi; import org.openintents.openpgp.util.OpenPgpApi;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
@ -17,11 +19,13 @@ import java.util.ArrayDeque;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import eu.siacs.conversations.Config;
import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.DownloadableFile; import eu.siacs.conversations.entities.DownloadableFile;
import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.http.HttpConnectionManager; import eu.siacs.conversations.http.HttpConnectionManager;
import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.utils.MimeUtils;
public class PgpDecryptionService { public class PgpDecryptionService {
@ -176,13 +180,31 @@ public class PgpDecryptionService {
try { try {
final DownloadableFile inputFile = mXmppConnectionService.getFileBackend().getFile(message, false); final DownloadableFile inputFile = mXmppConnectionService.getFileBackend().getFile(message, false);
final DownloadableFile outputFile = mXmppConnectionService.getFileBackend().getFile(message, true); final DownloadableFile outputFile = mXmppConnectionService.getFileBackend().getFile(message, true);
outputFile.getParentFile().mkdirs(); if (outputFile.getParentFile().mkdirs()) {
Log.d(Config.LOGTAG,"created parent directories for "+outputFile.getAbsolutePath());
}
outputFile.createNewFile(); outputFile.createNewFile();
InputStream is = new FileInputStream(inputFile); InputStream is = new FileInputStream(inputFile);
OutputStream os = new FileOutputStream(outputFile); OutputStream os = new FileOutputStream(outputFile);
Intent result = getOpenPgpApi().executeApi(params, is, os); Intent result = getOpenPgpApi().executeApi(params, is, os);
switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) { switch (result.getIntExtra(OpenPgpApi.RESULT_CODE, OpenPgpApi.RESULT_CODE_ERROR)) {
case OpenPgpApi.RESULT_CODE_SUCCESS: case OpenPgpApi.RESULT_CODE_SUCCESS:
OpenPgpMetadata openPgpMetadata = result.getParcelableExtra(OpenPgpApi.RESULT_METADATA);
String originalFilename = openPgpMetadata.getFilename();
String originalExtension = originalFilename == null ? null : MimeUtils.extractRelevantExtension(originalFilename);
if (originalExtension != null && MimeUtils.extractRelevantExtension(outputFile.getName()) == null) {
Log.d(Config.LOGTAG,"detected original filename during pgp decryption");
String mime = MimeUtils.guessMimeTypeFromExtension(originalExtension);
String path = outputFile.getName()+"."+originalExtension;
DownloadableFile fixedFile = mXmppConnectionService.getFileBackend().getFileForPath(path,mime);
if (fixedFile.getParentFile().mkdirs()) {
Log.d(Config.LOGTAG,"created parent directories for "+fixedFile.getAbsolutePath());
}
if (outputFile.renameTo(fixedFile)) {
Log.d(Config.LOGTAG, "renamed " + outputFile.getAbsolutePath() + " to " + fixedFile.getAbsolutePath());
message.setRelativeFilePath(path);
}
}
URL url = message.getFileParams().url; URL url = message.getFileParams().url;
mXmppConnectionService.getFileBackend().updateFileParams(message, url); mXmppConnectionService.getFileBackend().updateFileParams(message, url);
message.setEncryption(Message.ENCRYPTION_DECRYPTED); message.setEncryption(Message.ENCRYPTION_DECRYPTED);

View File

@ -680,46 +680,19 @@ public class Message extends AbstractEntity {
this.oob = isOob; this.oob = isOob;
} }
private static String extractRelevantExtension(URL url) {
String path = url.getPath();
return extractRelevantExtension(path);
}
private static String extractRelevantExtension(String path) {
if (path == null || path.isEmpty()) {
return null;
}
String filename = path.substring(path.lastIndexOf('/') + 1).toLowerCase();
int dotPosition = filename.lastIndexOf(".");
if (dotPosition != -1) {
String extension = filename.substring(dotPosition + 1);
// we want the real file extension, not the crypto one
if (Transferable.VALID_CRYPTO_EXTENSIONS.contains(extension)) {
return extractRelevantExtension(filename.substring(0,dotPosition));
} else {
return extension;
}
}
return null;
}
public String getMimeType() { public String getMimeType() {
String extension;
if (relativeFilePath != null) { if (relativeFilePath != null) {
int start = relativeFilePath.lastIndexOf('.') + 1; extension = MimeUtils.extractRelevantExtension(relativeFilePath);
if (start < relativeFilePath.length()) {
return MimeUtils.guessMimeTypeFromExtension(relativeFilePath.substring(start));
} else {
return null;
}
} else { } else {
try { try {
return MimeUtils.guessMimeTypeFromExtension(extractRelevantExtension(new URL(body.trim()))); final URL url = new URL(body.split("\n")[0]);
extension = MimeUtils.extractRelevantExtension(url);
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
return null; return null;
} }
} }
return MimeUtils.guessMimeTypeFromExtension(extension);
} }
public synchronized boolean treatAsDownloadable() { public synchronized boolean treatAsDownloadable() {

View File

@ -89,7 +89,7 @@ public class HttpDownloadConnection implements Transferable {
} else { } else {
extension = lastPart; extension = lastPart;
} }
message.setRelativeFilePath(message.getUuid() + "." + extension); message.setRelativeFilePath(message.getUuid() + (extension != null ? ("." + extension) : ""));
this.file = mXmppConnectionService.getFileBackend().getFile(message, false); this.file = mXmppConnectionService.getFileBackend().getFile(message, false);
final String reference = mUrl.getRef(); final String reference = mUrl.getRef();
if (reference != null && AesGcmURLStreamHandler.IV_KEY.matcher(reference).matches()) { if (reference != null && AesGcmURLStreamHandler.IV_KEY.matcher(reference).matches()) {

View File

@ -110,19 +110,11 @@ public class FileBackend {
return getFile(message, true); return getFile(message, true);
} }
public DownloadableFile getFile(Message message, boolean decrypted) { public DownloadableFile getFileForPath(String path, String mime) {
final boolean encrypted = !decrypted
&& (message.getEncryption() == Message.ENCRYPTION_PGP
|| message.getEncryption() == Message.ENCRYPTION_DECRYPTED);
final DownloadableFile file; final DownloadableFile file;
String path = message.getRelativeFilePath();
if (path == null) {
path = message.getUuid();
}
if (path.startsWith("/")) { if (path.startsWith("/")) {
file = new DownloadableFile(path); file = new DownloadableFile(path);
} else { } else {
String mime = message.getMimeType();
if (mime != null && mime.startsWith("image/")) { if (mime != null && mime.startsWith("image/")) {
file = new DownloadableFile(getConversationsDirectory("Images") + path); file = new DownloadableFile(getConversationsDirectory("Images") + path);
} else if (mime != null && mime.startsWith("video/")) { } else if (mime != null && mime.startsWith("video/")) {
@ -131,6 +123,18 @@ public class FileBackend {
file = new DownloadableFile(getConversationsDirectory("Files") + path); file = new DownloadableFile(getConversationsDirectory("Files") + path);
} }
} }
return file;
}
public DownloadableFile getFile(Message message, boolean decrypted) {
final boolean encrypted = !decrypted
&& (message.getEncryption() == Message.ENCRYPTION_PGP
|| message.getEncryption() == Message.ENCRYPTION_DECRYPTED);
String path = message.getRelativeFilePath();
if (path == null) {
path = message.getUuid();
}
final DownloadableFile file = getFileForPath(path, message.getMimeType());
if (encrypted) { if (encrypted) {
return new DownloadableFile(getConversationsDirectory("Files") + file.getName() + ".pgp"); return new DownloadableFile(getConversationsDirectory("Files") + file.getName() + ".pgp");
} else { } else {

View File

@ -21,9 +21,13 @@ import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import eu.siacs.conversations.entities.Transferable;
/** /**
* Utilities for dealing with MIME types. * Utilities for dealing with MIME types.
* Used to implement java.net.URLConnection and android.webkit.MimeTypeMap. * Used to implement java.net.URLConnection and android.webkit.MimeTypeMap.
@ -510,4 +514,33 @@ public final class MimeUtils {
} }
return mimeType; return mimeType;
} }
public static String extractRelevantExtension(URL url) {
String path = url.getPath();
return extractRelevantExtension(path, true);
}
public static String extractRelevantExtension(final String path) {
return extractRelevantExtension(path, false);
}
public static String extractRelevantExtension(final String path, final boolean ignoreCryptoExtension) {
if (path == null || path.isEmpty()) {
return null;
}
String filename = path.substring(path.lastIndexOf('/') + 1).toLowerCase();
int dotPosition = filename.lastIndexOf(".");
if (dotPosition != -1) {
String extension = filename.substring(dotPosition + 1);
// we want the real file extension, not the crypto one
if (ignoreCryptoExtension && Transferable.VALID_CRYPTO_EXTENSIONS.contains(extension)) {
return extractRelevantExtension(filename.substring(0,dotPosition));
} else {
return extension;
}
}
return null;
}
} }