From 18c183a7676e24fa3141a50f628688a0a690f259 Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 23 Apr 2014 21:19:56 +0200 Subject: [PATCH] deny files with unknown file types --- .../persistance/FileBackend.java | 1 + .../services/XmppConnectionService.java | 1 + .../xmpp/jingle/JingleConnection.java | 86 ++++++++++++++----- .../xmpp/jingle/JingleSocks5Transport.java | 9 ++ 4 files changed, 76 insertions(+), 21 deletions(-) diff --git a/src/eu/siacs/conversations/persistance/FileBackend.java b/src/eu/siacs/conversations/persistance/FileBackend.java index d830652df..3032f3754 100644 --- a/src/eu/siacs/conversations/persistance/FileBackend.java +++ b/src/eu/siacs/conversations/persistance/FileBackend.java @@ -72,6 +72,7 @@ public class FileBackend { public JingleFile copyImageToPrivateStorage(Message message, Uri image) { try { + Log.d("xmppService","copying file: "+image.toString()+ " to internal storage"); InputStream is = context.getContentResolver() .openInputStream(image); JingleFile file = getJingleFile(message); diff --git a/src/eu/siacs/conversations/services/XmppConnectionService.java b/src/eu/siacs/conversations/services/XmppConnectionService.java index a58d80d53..b6930219f 100644 --- a/src/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/eu/siacs/conversations/services/XmppConnectionService.java @@ -423,6 +423,7 @@ public class XmppConnectionService extends Service { convChangedListener.onConversationListChanged(); } getFileBackend().copyImageToPrivateStorage(message, uri); + databaseBackend.createMessage(message); message.setStatus(Message.STATUS_OFFERED); if (convChangedListener!=null) { convChangedListener.onConversationListChanged(); diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java index f58aa30ce..0959031bf 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java +++ b/src/eu/siacs/conversations/xmpp/jingle/JingleConnection.java @@ -1,6 +1,7 @@ package eu.siacs.conversations.xmpp.jingle; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -21,6 +22,9 @@ import eu.siacs.conversations.xmpp.stanzas.IqPacket; public class JingleConnection { + private final String[] extensions = {"webp","jpeg","jpg","png"}; + private final String[] cryptoExtensions = {"pgp","gpg"}; + private JingleConnectionManager mJingleConnectionManager; private XmppConnectionService mXmppConnectionService; @@ -74,9 +78,9 @@ public class JingleConnection { if (acceptedAutomatically) { message.markUnread(); } + mXmppConnectionService.databaseBackend.createMessage(message); mXmppConnectionService.markMessage(message, Message.STATUS_RECIEVED); } - mXmppConnectionService.databaseBackend.createMessage(message); Log.d("xmppService","sucessfully transmitted file. sha1:"+file.getSha1Sum()); } }; @@ -123,13 +127,13 @@ public class JingleConnection { Reason reason = packet.getReason(); if (reason!=null) { if (reason.hasChild("cancel")) { - this.cancel(); + this.receiveCancel(); } else if (reason.hasChild("success")) { - this.finish(); + this.receiveSuccess(); } } else { Log.d("xmppService","remote terminated for no reason"); - this.cancel(); + this.receiveCancel(); } } else if (packet.isAction("session-accept")) { receiveAccept(packet); @@ -210,22 +214,42 @@ public class JingleConnection { if (fileOffer!=null) { this.file = this.mXmppConnectionService.getFileBackend().getJingleFile(message); Element fileSize = fileOffer.findChild("size"); - Element fileName = fileOffer.findChild("name"); - this.file.setExpectedSize(Long.parseLong(fileSize.getContent())); - conversation.getMessages().add(message); - if (this.file.getExpectedSize()<=this.mJingleConnectionManager.getAutoAcceptFileSize()) { - Log.d("xmppService","auto accepting file from "+packet.getFrom()); - this.acceptedAutomatically = true; - this.sendAccept(); - } else { - message.markUnread(); - Log.d("xmppService","not auto accepting new file offer with size: "+this.file.getExpectedSize()+" allowed size:"+this.mJingleConnectionManager.getAutoAcceptFileSize()); - if (this.mXmppConnectionService.convChangedListener!=null) { - this.mXmppConnectionService.convChangedListener.onConversationListChanged(); + Element fileNameElement = fileOffer.findChild("name"); + if (fileNameElement!=null) { + boolean supportedFile = false; + String[] filename = fileNameElement.getContent().toLowerCase().split("\\."); + if (Arrays.asList(this.extensions).contains(filename[filename.length - 1])) { + supportedFile = true; + } else if (Arrays.asList(this.cryptoExtensions).contains(filename[filename.length - 1])) { + if (filename.length == 3) { + if (Arrays.asList(this.extensions).contains(filename[filename.length -2])) { + supportedFile = true; + this.message.setEncryption(Message.ENCRYPTION_PGP); + } + } } + if (supportedFile) { + this.file.setExpectedSize(Long.parseLong(fileSize.getContent())); + conversation.getMessages().add(message); + if (this.file.getExpectedSize()<=this.mJingleConnectionManager.getAutoAcceptFileSize()) { + Log.d("xmppService","auto accepting file from "+packet.getFrom()); + this.acceptedAutomatically = true; + this.sendAccept(); + } else { + message.markUnread(); + Log.d("xmppService","not auto accepting new file offer with size: "+this.file.getExpectedSize()+" allowed size:"+this.mJingleConnectionManager.getAutoAcceptFileSize()); + if (this.mXmppConnectionService.convChangedListener!=null) { + this.mXmppConnectionService.convChangedListener.onConversationListChanged(); + } + } + } else { + this.sendCancel(); + } + } else { + this.sendCancel(); } } else { - Log.d("xmppService","no file offer was attached. aborting"); + this.sendCancel(); } } @@ -331,7 +355,19 @@ public class JingleConnection { Content content = packet.getJingleContent(); if (content.hasSocks5Transport()) { if (content.socks5transport().hasChild("activated")) { - onProxyActivated.success(); + if ((this.transport!=null)&&(this.transport instanceof JingleSocks5Transport)) { + onProxyActivated.success(); + } else { + String cid = content.socks5transport().findChild("activated").getAttribute("cid"); + Log.d("xmppService","received proxy activated ("+cid+")prior to choosing our own transport"); + JingleSocks5Transport connection = this.connections.get(cid); + if (connection!=null) { + connection.setActivated(true); + } else { + Log.d("xmppService","activated connection not found"); + this.sendCancel(); + } + } } else if (content.socks5transport().hasChild("activated")) { onProxyActivated.failed(); } else if (content.socks5transport().hasChild("candidate-error")) { @@ -375,7 +411,7 @@ public class JingleConnection { } } else { this.status = STATUS_TRANSMITTING; - if (connection.isProxy()) { + if (connection.needsActivation()) { if (connection.getCandidate().isOurs()) { Log.d("xmppService","candidate "+connection.getCandidate().getCid()+" was our proxy and needs activation"); IqPacket activation = new IqPacket(IqPacket.TYPE_SET); @@ -507,17 +543,25 @@ public class JingleConnection { } } - private void finish() { + private void receiveSuccess() { this.status = STATUS_FINISHED; this.mXmppConnectionService.markMessage(this.message, Message.STATUS_SEND); this.disconnect(); } - public void cancel() { + private void receiveCancel() { this.disconnect(); this.status = STATUS_CANCELED; this.mXmppConnectionService.markMessage(this.message, Message.STATUS_SEND_REJECTED); } + + private void sendCancel() { + JinglePacket packet = bootstrapPacket("session-terminate"); + Reason reason = new Reason(); + reason.addChild("cancel"); + packet.setReason(reason); + this.sendJinglePacket(packet); + } private void connectNextCandidate() { for(JingleCandidate candidate : this.candidates) { diff --git a/src/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java b/src/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java index f37d5a717..ea5d7285f 100644 --- a/src/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java +++ b/src/eu/siacs/conversations/xmpp/jingle/JingleSocks5Transport.java @@ -24,6 +24,7 @@ public class JingleSocks5Transport extends JingleTransport { private OutputStream outputStream; private InputStream inputStream; private boolean isEstablished = false; + private boolean activated = false; protected Socket socket; public JingleSocks5Transport(JingleConnection jingleConnection, JingleCandidate candidate) { @@ -184,6 +185,10 @@ public class JingleSocks5Transport extends JingleTransport { public boolean isProxy() { return this.candidate.getType() == JingleCandidate.TYPE_PROXY; } + + public boolean needsActivation() { + return (this.isProxy() && !this.activated); + } public void disconnect() { if (this.socket!=null) { @@ -203,4 +208,8 @@ public class JingleSocks5Transport extends JingleTransport { public JingleCandidate getCandidate() { return this.candidate; } + + public void setActivated(boolean activated) { + this.activated = activated; + } }