mirror of
https://github.com/M66B/FairEmail.git
synced 2026-01-04 03:43:55 +01:00
Better encryption support
This commit is contained in:
1282
app/schemas/eu.faircode.email.DB/30.json
Normal file
1282
app/schemas/eu.faircode.email.DB/30.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1218,7 +1218,7 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
|
|||||||
// Find encrypted data
|
// Find encrypted data
|
||||||
List<EntityAttachment> attachments = db.attachment().getAttachments(id);
|
List<EntityAttachment> attachments = db.attachment().getAttachments(id);
|
||||||
for (EntityAttachment attachment : attachments)
|
for (EntityAttachment attachment : attachments)
|
||||||
if ("encrypted.asc".equals(attachment.name)) {
|
if (EntityAttachment.PGP_MESSAGE.equals(attachment.encryption)) {
|
||||||
if (!attachment.available)
|
if (!attachment.available)
|
||||||
throw new IllegalArgumentException(getString(R.string.title_attachments_missing));
|
throw new IllegalArgumentException(getString(R.string.title_attachments_missing));
|
||||||
|
|
||||||
@@ -1291,7 +1291,7 @@ public class ActivityView extends ActivityBilling implements FragmentManager.OnB
|
|||||||
|
|
||||||
// Remove previously decrypted attachments
|
// Remove previously decrypted attachments
|
||||||
for (EntityAttachment a : attachments)
|
for (EntityAttachment a : attachments)
|
||||||
if (!"encrypted.asc".equals(a.name))
|
if (a.encryption == null)
|
||||||
db.attachment().deleteAttachment(a.id);
|
db.attachment().deleteAttachment(a.id);
|
||||||
|
|
||||||
// Add decrypted attachments
|
// Add decrypted attachments
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ public class AdapterAttachment extends RecyclerView.Adapter<AdapterAttachment.Vi
|
|||||||
progressbar.setVisibility(
|
progressbar.setVisibility(
|
||||||
attachment.progress == null || attachment.available ? View.GONE : View.VISIBLE);
|
attachment.progress == null || attachment.available ? View.GONE : View.VISIBLE);
|
||||||
|
|
||||||
tvType.setText(attachment.type + " " + attachment.cid);
|
tvType.setText(attachment.type + " " + attachment.cid + " " + attachment.encryption);
|
||||||
tvType.setVisibility(debug ? View.VISIBLE : View.GONE);
|
tvType.setVisibility(debug ? View.VISIBLE : View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory;
|
|||||||
// https://developer.android.com/topic/libraries/architecture/room.html
|
// https://developer.android.com/topic/libraries/architecture/room.html
|
||||||
|
|
||||||
@Database(
|
@Database(
|
||||||
version = 29,
|
version = 30,
|
||||||
entities = {
|
entities = {
|
||||||
EntityIdentity.class,
|
EntityIdentity.class,
|
||||||
EntityAccount.class,
|
EntityAccount.class,
|
||||||
@@ -377,6 +377,14 @@ public abstract class DB extends RoomDatabase {
|
|||||||
db.execSQL("ALTER TABLE `folder` ADD COLUMN `last_sync` INTEGER");
|
db.execSQL("ALTER TABLE `folder` ADD COLUMN `last_sync` INTEGER");
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.addMigrations(new Migration(29, 30) {
|
||||||
|
@Override
|
||||||
|
public void migrate(SupportSQLiteDatabase db) {
|
||||||
|
Log.i("DB migration from version " + startVersion + " to " + endVersion);
|
||||||
|
db.execSQL("ALTER TABLE `attachment` ADD COLUMN `encryption` INTEGER");
|
||||||
|
db.execSQL("UPDATE attachment SET encryption = " + EntityAttachment.PGP_MESSAGE + " where name = 'encrypted.asc'");
|
||||||
|
}
|
||||||
|
})
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,9 @@ public class EntityAttachment {
|
|||||||
static final String TABLE_NAME = "attachment";
|
static final String TABLE_NAME = "attachment";
|
||||||
static final int ATTACHMENT_BUFFER_SIZE = 8192; // bytes
|
static final int ATTACHMENT_BUFFER_SIZE = 8192; // bytes
|
||||||
|
|
||||||
|
static final Integer PGP_MESSAGE = 1;
|
||||||
|
static final Integer PGP_SIGNATURE = 2;
|
||||||
|
|
||||||
@PrimaryKey(autoGenerate = true)
|
@PrimaryKey(autoGenerate = true)
|
||||||
public Long id;
|
public Long id;
|
||||||
@NonNull
|
@NonNull
|
||||||
@@ -67,8 +70,8 @@ public class EntityAttachment {
|
|||||||
@NonNull
|
@NonNull
|
||||||
public String type;
|
public String type;
|
||||||
public String cid; // Content-ID
|
public String cid; // Content-ID
|
||||||
|
public Integer encryption;
|
||||||
public Integer size;
|
public Integer size;
|
||||||
|
|
||||||
public Integer progress;
|
public Integer progress;
|
||||||
@NonNull
|
@NonNull
|
||||||
public Boolean available = false;
|
public Boolean available = false;
|
||||||
|
|||||||
@@ -785,7 +785,7 @@ public class FragmentCompose extends FragmentEx {
|
|||||||
EntityMessage message = db.message().getMessage(id);
|
EntityMessage message = db.message().getMessage(id);
|
||||||
List<EntityAttachment> attachments = db.attachment().getAttachments(id);
|
List<EntityAttachment> attachments = db.attachment().getAttachments(id);
|
||||||
for (EntityAttachment attachment : new ArrayList<>(attachments))
|
for (EntityAttachment attachment : new ArrayList<>(attachments))
|
||||||
if ("encrypted.asc".equals(attachment.name) || "signature.asc".equals(attachment.name))
|
if (attachment.encryption != null)
|
||||||
attachments.remove(attachment);
|
attachments.remove(attachment);
|
||||||
|
|
||||||
// Build message
|
// Build message
|
||||||
@@ -822,7 +822,7 @@ public class FragmentCompose extends FragmentEx {
|
|||||||
|
|
||||||
// Delete previously encrypted data
|
// Delete previously encrypted data
|
||||||
for (EntityAttachment attachment : db.attachment().getAttachments(id))
|
for (EntityAttachment attachment : db.attachment().getAttachments(id))
|
||||||
if ("encrypted.asc".equals(attachment.name) || "signature.asc".equals(attachment.name))
|
if (attachment.encryption != null)
|
||||||
db.attachment().deleteAttachment(attachment.id);
|
db.attachment().deleteAttachment(attachment.id);
|
||||||
|
|
||||||
int seq = db.attachment().getAttachmentSequence(id);
|
int seq = db.attachment().getAttachmentSequence(id);
|
||||||
@@ -832,6 +832,7 @@ public class FragmentCompose extends FragmentEx {
|
|||||||
attachment1.sequence = seq + 1;
|
attachment1.sequence = seq + 1;
|
||||||
attachment1.name = "encrypted.asc";
|
attachment1.name = "encrypted.asc";
|
||||||
attachment1.type = "application/octet-stream";
|
attachment1.type = "application/octet-stream";
|
||||||
|
attachment1.encryption = EntityAttachment.PGP_MESSAGE;
|
||||||
attachment1.id = db.attachment().insertAttachment(attachment1);
|
attachment1.id = db.attachment().insertAttachment(attachment1);
|
||||||
|
|
||||||
File file1 = EntityAttachment.getFile(context, attachment1.id);
|
File file1 = EntityAttachment.getFile(context, attachment1.id);
|
||||||
@@ -856,6 +857,7 @@ public class FragmentCompose extends FragmentEx {
|
|||||||
attachment2.sequence = seq + 2;
|
attachment2.sequence = seq + 2;
|
||||||
attachment2.name = "signature.asc";
|
attachment2.name = "signature.asc";
|
||||||
attachment2.type = "application/octet-stream";
|
attachment2.type = "application/octet-stream";
|
||||||
|
attachment2.encryption = EntityAttachment.PGP_SIGNATURE;
|
||||||
attachment2.id = db.attachment().insertAttachment(attachment2);
|
attachment2.id = db.attachment().insertAttachment(attachment2);
|
||||||
|
|
||||||
File file2 = EntityAttachment.getFile(context, attachment2.id);
|
File file2 = EntityAttachment.getFile(context, attachment2.id);
|
||||||
@@ -1435,6 +1437,7 @@ public class FragmentCompose extends FragmentEx {
|
|||||||
copy.name = attachment.name;
|
copy.name = attachment.name;
|
||||||
copy.type = attachment.type;
|
copy.type = attachment.type;
|
||||||
copy.cid = attachment.cid;
|
copy.cid = attachment.cid;
|
||||||
|
copy.encryption = attachment.encryption;
|
||||||
copy.size = attachment.size;
|
copy.size = attachment.size;
|
||||||
copy.progress = attachment.progress;
|
copy.progress = attachment.progress;
|
||||||
copy.available = attachment.available;
|
copy.available = attachment.available;
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ public class MessageHelper {
|
|||||||
|
|
||||||
if (message.from != null && message.from.length > 0)
|
if (message.from != null && message.from.length > 0)
|
||||||
for (EntityAttachment attachment : attachments)
|
for (EntityAttachment attachment : attachments)
|
||||||
if (attachment.available && "signature.asc".equals(attachment.name)) {
|
if (attachment.available && EntityAttachment.PGP_SIGNATURE.equals(attachment.encryption)) {
|
||||||
InternetAddress from = (InternetAddress) message.from[0];
|
InternetAddress from = (InternetAddress) message.from[0];
|
||||||
File file = EntityAttachment.getFile(context, attachment.id);
|
File file = EntityAttachment.getFile(context, attachment.id);
|
||||||
BufferedReader br = null;
|
BufferedReader br = null;
|
||||||
@@ -238,7 +238,7 @@ public class MessageHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (final EntityAttachment attachment : attachments)
|
for (final EntityAttachment attachment : attachments)
|
||||||
if (attachment.available && "encrypted.asc".equals(attachment.name)) {
|
if (attachment.available && EntityAttachment.PGP_MESSAGE.equals(attachment.encryption)) {
|
||||||
Multipart multipart = new MimeMultipart("encrypted; protocol=\"application/pgp-encrypted\"");
|
Multipart multipart = new MimeMultipart("encrypted; protocol=\"application/pgp-encrypted\"");
|
||||||
|
|
||||||
BodyPart pgp = new MimeBodyPart();
|
BodyPart pgp = new MimeBodyPart();
|
||||||
@@ -576,9 +576,15 @@ public class MessageHelper {
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
if (content instanceof Multipart) {
|
if (content instanceof Multipart) {
|
||||||
|
boolean pgp = false;
|
||||||
Multipart multipart = (Multipart) content;
|
Multipart multipart = (Multipart) content;
|
||||||
for (int i = 0; i < multipart.getCount(); i++)
|
for (int i = 0; i < multipart.getCount(); i++) {
|
||||||
result.addAll(getAttachments(multipart.getBodyPart(i)));
|
BodyPart part = multipart.getBodyPart(i);
|
||||||
|
result.addAll(getAttachments(part, pgp));
|
||||||
|
ContentType ct = new ContentType(part.getContentType());
|
||||||
|
if ("application/pgp-encrypted".equals(ct.getBaseType().toLowerCase()))
|
||||||
|
pgp = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
if (ex.getCause() instanceof MessagingException)
|
if (ex.getCause() instanceof MessagingException)
|
||||||
@@ -592,7 +598,7 @@ public class MessageHelper {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<EntityAttachment> getAttachments(BodyPart part) throws
|
private static List<EntityAttachment> getAttachments(BodyPart part, boolean pgp) throws
|
||||||
IOException, MessagingException {
|
IOException, MessagingException {
|
||||||
List<EntityAttachment> result = new ArrayList<>();
|
List<EntityAttachment> result = new ArrayList<>();
|
||||||
|
|
||||||
@@ -635,6 +641,7 @@ public class MessageHelper {
|
|||||||
attachment.type = ct.getBaseType().toLowerCase();
|
attachment.type = ct.getBaseType().toLowerCase();
|
||||||
attachment.size = part.getSize();
|
attachment.size = part.getSize();
|
||||||
attachment.cid = (cid == null || cid.length == 0 ? null : cid[0]);
|
attachment.cid = (cid == null || cid.length == 0 ? null : cid[0]);
|
||||||
|
attachment.encryption = (pgp ? EntityAttachment.PGP_MESSAGE : null);
|
||||||
attachment.part = part;
|
attachment.part = part;
|
||||||
|
|
||||||
// Try to guess a better content type
|
// Try to guess a better content type
|
||||||
@@ -658,8 +665,13 @@ public class MessageHelper {
|
|||||||
}
|
}
|
||||||
} else if (content instanceof Multipart) {
|
} else if (content instanceof Multipart) {
|
||||||
Multipart multipart = (Multipart) content;
|
Multipart multipart = (Multipart) content;
|
||||||
for (int i = 0; i < multipart.getCount(); i++)
|
for (int i = 0; i < multipart.getCount(); i++) {
|
||||||
result.addAll(getAttachments(multipart.getBodyPart(i)));
|
BodyPart cpart = multipart.getBodyPart(i);
|
||||||
|
result.addAll(getAttachments(cpart, pgp));
|
||||||
|
ContentType ct = new ContentType(cpart.getContentType());
|
||||||
|
if ("application/pgp-encrypted".equals(ct.getBaseType().toLowerCase()))
|
||||||
|
pgp = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -2436,7 +2436,8 @@ public class ServiceSynchronize extends LifecycleService {
|
|||||||
int sequence = 1;
|
int sequence = 1;
|
||||||
for (EntityAttachment attachment : helper.getAttachments()) {
|
for (EntityAttachment attachment : helper.getAttachments()) {
|
||||||
Log.i(folder.name + " attachment seq=" + sequence +
|
Log.i(folder.name + " attachment seq=" + sequence +
|
||||||
" name=" + attachment.name + " type=" + attachment.type + " cid=" + attachment.cid);
|
" name=" + attachment.name + " type=" + attachment.type +
|
||||||
|
" cid=" + attachment.cid + " pgp=" + attachment.encryption);
|
||||||
if (!TextUtils.isEmpty(attachment.cid) &&
|
if (!TextUtils.isEmpty(attachment.cid) &&
|
||||||
db.attachment().getAttachment(message.id, attachment.cid) != null) {
|
db.attachment().getAttachment(message.id, attachment.cid) != null) {
|
||||||
Log.i("Skipping duplicated CID");
|
Log.i("Skipping duplicated CID");
|
||||||
|
|||||||
Reference in New Issue
Block a user