Fix aesgcm http file up/download bugs

This commit is contained in:
fiaxh 2018-11-27 18:28:28 +01:00
parent 141db9e40a
commit 7c1d580e17
4 changed files with 52 additions and 30 deletions

View file

@ -143,17 +143,23 @@ public class FileManager : StreamInteractionModule, Object {
private async void handle_incomming_file(FileProvider file_provider, FileTransfer file_transfer, Conversation conversation) { private async void handle_incomming_file(FileProvider file_provider, FileTransfer file_transfer, Conversation conversation) {
if (!is_sender_trustworthy(file_transfer, conversation)) return; if (!is_sender_trustworthy(file_transfer, conversation)) return;
string filename = Random.next_int().to_string("%x") + "_" + file_transfer.file_name; if (file_transfer.size == -1) {
File file = File.new_for_path(Path.build_filename(get_storage_dir(), filename)); file_provider.get_meta_info(file_transfer);
yield file_provider.download(file_transfer, file); }
try { if (file_transfer.size >= 0 && file_transfer.size < 5000000) {
FileInfo file_info = file_transfer.get_file().query_info("*", FileQueryInfoFlags.NONE); string filename = Random.next_int().to_string("%x") + "_" + file_transfer.file_name;
file_transfer.mime_type = file_info.get_content_type(); File file = File.new_for_path(Path.build_filename(get_storage_dir(), filename));
} catch (Error e) { } yield file_provider.download(file_transfer, file);
file_transfer.persist(db); try {
received_file(file_transfer, conversation); FileInfo file_info = file_transfer.get_file().query_info("*", FileQueryInfoFlags.NONE);
file_transfer.mime_type = file_info.get_content_type();
} catch (Error e) { }
file_transfer.persist(db);
received_file(file_transfer, conversation);
}
} }
private void save_file(FileTransfer file_transfer) { private void save_file(FileTransfer file_transfer) {
@ -175,6 +181,7 @@ public class FileManager : StreamInteractionModule, Object {
public interface FileProvider : Object { public interface FileProvider : Object {
public signal void file_incoming(FileTransfer file_transfer, Conversation conversation); public signal void file_incoming(FileTransfer file_transfer, Conversation conversation);
public abstract async void get_meta_info(FileTransfer file_transfer);
public abstract async void download(FileTransfer file_transfer, File file); public abstract async void download(FileTransfer file_transfer, File file);
} }

View file

@ -63,16 +63,18 @@ public class FileProvider : Dino.FileProvider, Object {
file_transfer.info = message.id.to_string(); file_transfer.info = message.id.to_string();
if (stream_interactor.get_module(FileManager.IDENTITY).is_sender_trustworthy(file_transfer, conversation)) { if (stream_interactor.get_module(FileManager.IDENTITY).is_sender_trustworthy(file_transfer, conversation)) {
ContentItem? content_item = stream_interactor.get_module(ContentItemStore.IDENTITY).get_item(conversation, 1, message.id);
if (content_item != null) {
stream_interactor.get_module(ContentItemStore.IDENTITY).set_item_hide(content_item, true);
}
yield get_meta_info(file_transfer); yield get_meta_info(file_transfer);
if (file_transfer.size >= 0 && file_transfer.size < 5000000) {
ContentItem? content_item = stream_interactor.get_module(ContentItemStore.IDENTITY).get_item(conversation, 1, message.id);
if (content_item != null) {
stream_interactor.get_module(ContentItemStore.IDENTITY).set_item_hide(content_item, true);
}
}
file_incoming(file_transfer, conversation); file_incoming(file_transfer, conversation);
} }
} }
private async void get_meta_info(FileTransfer file_transfer) { public async void get_meta_info(FileTransfer file_transfer) {
string url_body = dino_db.message.select({dino_db.message.body}).with(dino_db.message.id, "=", int.parse(file_transfer.info))[dino_db.message.body]; string url_body = dino_db.message.select({dino_db.message.body}).with(dino_db.message.id, "=", int.parse(file_transfer.info))[dino_db.message.body];
var session = new Soup.Session(); var session = new Soup.Session();
var head_message = new Soup.Message("HEAD", url_body); var head_message = new Soup.Message("HEAD", url_body);

View file

@ -65,36 +65,43 @@ public class FileProvider : Dino.FileProvider, Object {
file_transfer.info = message.id.to_string(); file_transfer.info = message.id.to_string();
if (stream_interactor.get_module(FileManager.IDENTITY).is_sender_trustworthy(file_transfer, conversation)) { if (stream_interactor.get_module(FileManager.IDENTITY).is_sender_trustworthy(file_transfer, conversation)) {
ContentItem? content_item = stream_interactor.get_module(ContentItemStore.IDENTITY).get_item(conversation, 1, message.id);
if (content_item != null) {
stream_interactor.get_module(ContentItemStore.IDENTITY).set_item_hide(content_item, true);
}
yield get_meta_info(file_transfer); yield get_meta_info(file_transfer);
if (file_transfer.size >= 0 && file_transfer.size < 5000000) {
ContentItem? content_item = stream_interactor.get_module(ContentItemStore.IDENTITY).get_item(conversation, 1, message.id);
if (content_item != null) {
stream_interactor.get_module(ContentItemStore.IDENTITY).set_item_hide(content_item, true);
}
}
file_incoming(file_transfer, conversation); file_incoming(file_transfer, conversation);
} }
} }
private async void get_meta_info(FileTransfer file_transfer) { public async void get_meta_info(FileTransfer file_transfer) {
string url_body = dino_db.message.select({dino_db.message.body}).with(dino_db.message.id, "=", int.parse(file_transfer.info))[dino_db.message.body]; string url_body = dino_db.message.select({dino_db.message.body}).with(dino_db.message.id, "=", int.parse(file_transfer.info))[dino_db.message.body];
string url = this.aesgcm_to_https_link(url_body);
var session = new Soup.Session(); var session = new Soup.Session();
var head_message = new Soup.Message("HEAD", url_body); var head_message = new Soup.Message("HEAD", url);
if (head_message != null) { if (head_message != null) {
yield session.send_async(head_message, null); yield session.send_async(head_message, null);
string? content_type = null, content_length = null; if (head_message.status_code >= 200 && head_message.status_code < 300) {
head_message.response_headers.foreach((name, val) => { string? content_type = null, content_length = null;
if (name == "Content-Type") content_type = val; head_message.response_headers.foreach((name, val) => {
if (name == "Content-Length") content_length = val; if (name == "Content-Type") content_type = val;
}); if (name == "Content-Length") content_length = val;
file_transfer.mime_type = content_type; });
file_transfer.size = int.parse(content_length); file_transfer.mime_type = content_type;
file_transfer.size = int.parse(content_length);
} else {
warning("HTTP HEAD download status code " + head_message.status_code.to_string());
}
} }
} }
public async void download(FileTransfer file_transfer, File file) { public async void download(FileTransfer file_transfer, File file) {
try { try {
string url_body = dino_db.message.select({dino_db.message.body}).with(dino_db.message.id, "=", int.parse(file_transfer.info))[dino_db.message.body]; string url_body = dino_db.message.select({dino_db.message.body}).with(dino_db.message.id, "=", int.parse(file_transfer.info))[dino_db.message.body];
string url = "https://" + url_body.substring(9); string url = this.aesgcm_to_https_link(url_body);
var session = new Soup.Session(); var session = new Soup.Session();
Soup.Request request = session.request(url); Soup.Request request = session.request(url);
@ -149,6 +156,12 @@ public class FileProvider : Dino.FileProvider, Object {
} }
return bin; return bin;
} }
private string aesgcm_to_https_link(string aesgcm_link) {
MatchInfo match_info;
this.url_regex.match(aesgcm_link, 0, out match_info);
return "https://" + match_info.fetch(1);
}
} }
} }

View file

@ -46,7 +46,7 @@ public class AesGcmFileSender : StreamInteractionModule, FileSender, Object {
foreach (uint8 byte in iv) iv_and_key += byte.to_string("%02x"); foreach (uint8 byte in iv) iv_and_key += byte.to_string("%02x");
foreach (uint8 byte in key) iv_and_key += byte.to_string("%02x"); foreach (uint8 byte in key) iv_and_key += byte.to_string("%02x");
stream_interactor.module_manager.get_module(file_transfer.account, Xmpp.Xep.HttpFileUpload.Module.IDENTITY).request_slot(stream, file_transfer.server_file_name, (int) data.length, file_transfer.mime_type, stream_interactor.module_manager.get_module(file_transfer.account, Xmpp.Xep.HttpFileUpload.Module.IDENTITY).request_slot(stream, file_transfer.server_file_name, (int) ciphertext.length, file_transfer.mime_type,
(stream, url_down, url_up) => { (stream, url_down, url_up) => {
Soup.Message message = new Soup.Message("PUT", url_up); Soup.Message message = new Soup.Message("PUT", url_up);
message.set_request(file_transfer.mime_type, Soup.MemoryUse.COPY, ciphertext); message.set_request(file_transfer.mime_type, Soup.MemoryUse.COPY, ciphertext);
@ -69,7 +69,7 @@ public class AesGcmFileSender : StreamInteractionModule, FileSender, Object {
stream_interactor.get_module(ContentItemStore.IDENTITY).set_item_hide(content_item, true); stream_interactor.get_module(ContentItemStore.IDENTITY).set_item_hide(content_item, true);
} }
} else { } else {
warning("HTTP status code " + message.status_code.to_string()); warning("HTTP upload status code " + message.status_code.to_string());
file_transfer.state = FileTransfer.State.FAILED; file_transfer.state = FileTransfer.State.FAILED;
} }
} catch (Error e) { } catch (Error e) {