use Tor on http upload is account uses onion domain. fixes #3075

This commit is contained in:
Daniel Gultsch 2018-06-16 18:31:55 +02:00
parent 582178991b
commit b9bdb3df55
7 changed files with 22 additions and 21 deletions

View file

@ -15,6 +15,7 @@ import java.util.TimeZone;
import eu.siacs.conversations.Config; import eu.siacs.conversations.Config;
import eu.siacs.conversations.R; import eu.siacs.conversations.R;
import eu.siacs.conversations.crypto.axolotl.AxolotlService; import eu.siacs.conversations.crypto.axolotl.AxolotlService;
import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.utils.PhoneHelper; import eu.siacs.conversations.utils.PhoneHelper;
import eu.siacs.conversations.xml.Namespace; import eu.siacs.conversations.xml.Namespace;
@ -73,7 +74,7 @@ public abstract class AbstractGenerator {
return mXmppConnectionService.getString(R.string.app_name) + " " + getIdentityVersion(); return mXmppConnectionService.getString(R.string.app_name) + " " + getIdentityVersion();
} }
public String getIdentityType() { String getIdentityType() {
if ("chromium".equals(android.os.Build.BRAND)) { if ("chromium".equals(android.os.Build.BRAND)) {
return "pc"; return "pc";
} else { } else {
@ -81,9 +82,9 @@ public abstract class AbstractGenerator {
} }
} }
public String getCapHash() { String getCapHash(final Account account) {
StringBuilder s = new StringBuilder(); StringBuilder s = new StringBuilder();
s.append("client/" + getIdentityType() + "//" + getIdentityName() + "<"); s.append("client/").append(getIdentityType()).append("//").append(getIdentityName()).append('<');
MessageDigest md; MessageDigest md;
try { try {
md = MessageDigest.getInstance("SHA-1"); md = MessageDigest.getInstance("SHA-1");
@ -91,8 +92,8 @@ public abstract class AbstractGenerator {
return null; return null;
} }
for (String feature : getFeatures()) { for (String feature : getFeatures(account)) {
s.append(feature + "<"); s.append(feature).append('<');
} }
byte[] sha1 = md.digest(s.toString().getBytes()); byte[] sha1 = md.digest(s.toString().getBytes());
return new String(Base64.encode(sha1, Base64.DEFAULT)).trim(); return new String(Base64.encode(sha1, Base64.DEFAULT)).trim();
@ -103,9 +104,8 @@ public abstract class AbstractGenerator {
return DATE_FORMAT.format(time); return DATE_FORMAT.format(time);
} }
public List<String> getFeatures() { public List<String> getFeatures(Account account) {
ArrayList<String> features = new ArrayList<>(); ArrayList<String> features = new ArrayList<>(Arrays.asList(FEATURES));
features.addAll(Arrays.asList(FEATURES));
if (mXmppConnectionService.confirmMessages()) { if (mXmppConnectionService.confirmMessages()) {
features.addAll(Arrays.asList(MESSAGE_CONFIRMATION_FEATURES)); features.addAll(Arrays.asList(MESSAGE_CONFIRMATION_FEATURES));
} }
@ -115,7 +115,7 @@ public abstract class AbstractGenerator {
if (Config.supportOmemo()) { if (Config.supportOmemo()) {
features.add(AxolotlService.PEP_DEVICE_LIST_NOTIFY); features.add(AxolotlService.PEP_DEVICE_LIST_NOTIFY);
} }
if (!mXmppConnectionService.useTorToConnect()) { if (!mXmppConnectionService.useTorToConnect() && !account.isOnion()) {
features.addAll(Arrays.asList(PRIVACY_SENSITIVE)); features.addAll(Arrays.asList(PRIVACY_SENSITIVE));
} }
if (mXmppConnectionService.broadcastLastActivity()) { if (mXmppConnectionService.broadcastLastActivity()) {

View file

@ -41,7 +41,7 @@ public class IqGenerator extends AbstractGenerator {
super(service); super(service);
} }
public IqPacket discoResponse(final IqPacket request) { public IqPacket discoResponse(final Account account, final IqPacket request) {
final IqPacket packet = new IqPacket(IqPacket.TYPE.RESULT); final IqPacket packet = new IqPacket(IqPacket.TYPE.RESULT);
packet.setId(request.getId()); packet.setId(request.getId());
packet.setTo(request.getFrom()); packet.setTo(request.getFrom());
@ -51,7 +51,7 @@ public class IqGenerator extends AbstractGenerator {
identity.setAttribute("category", "client"); identity.setAttribute("category", "client");
identity.setAttribute("type", getIdentityType()); identity.setAttribute("type", getIdentityType());
identity.setAttribute("name", getIdentityName()); identity.setAttribute("name", getIdentityName());
for (final String feature : getFeatures()) { for (final String feature : getFeatures(account)) {
query.addChild("feature").setAttribute("var", feature); query.addChild("feature").setAttribute("var", feature);
} }
return packet; return packet;
@ -113,7 +113,7 @@ public class IqGenerator extends AbstractGenerator {
return publish(node, item, null); return publish(node, item, null);
} }
protected IqPacket retrieve(String node, Element item) { private IqPacket retrieve(String node, Element item) {
final IqPacket packet = new IqPacket(IqPacket.TYPE.GET); final IqPacket packet = new IqPacket(IqPacket.TYPE.GET);
final Element pubsub = packet.addChild("pubsub", Namespace.PUBSUB); final Element pubsub = packet.addChild("pubsub", Namespace.PUBSUB);
final Element items = pubsub.addChild("items"); final Element items = pubsub.addChild("items");

View file

@ -48,11 +48,11 @@ public class PresenceGenerator extends AbstractGenerator {
packet.addChild("show").setContent(status.toShowString()); packet.addChild("show").setContent(status.toShowString());
} }
packet.setFrom(account.getJid()); packet.setFrom(account.getJid());
String sig = account.getPgpSignature(); final String sig = account.getPgpSignature();
if (includePgpAnnouncement && sig != null && mXmppConnectionService.getPgpEngine() != null) { if (includePgpAnnouncement && sig != null && mXmppConnectionService.getPgpEngine() != null) {
packet.addChild("x", "jabber:x:signed").setContent(sig); packet.addChild("x", "jabber:x:signed").setContent(sig);
} }
String capHash = getCapHash(); final String capHash = getCapHash(account);
if (capHash != null) { if (capHash != null) {
Element cap = packet.addChild("c", Element cap = packet.addChild("c",
"http://jabber.org/protocol/caps"); "http://jabber.org/protocol/caps");

View file

@ -265,7 +265,7 @@ public class HttpDownloadConnection implements Transferable {
Log.d(Config.LOGTAG, "retrieve file size. interactive:" + String.valueOf(interactive)); Log.d(Config.LOGTAG, "retrieve file size. interactive:" + String.valueOf(interactive));
changeStatus(STATUS_CHECKING); changeStatus(STATUS_CHECKING);
HttpURLConnection connection; HttpURLConnection connection;
if (mUseTor) { if (mUseTor || message.getConversation().getAccount().isOnion()) {
connection = (HttpURLConnection) mUrl.openConnection(HttpConnectionManager.getProxy()); connection = (HttpURLConnection) mUrl.openConnection(HttpConnectionManager.getProxy());
} else { } else {
connection = (HttpURLConnection) mUrl.openConnection(); connection = (HttpURLConnection) mUrl.openConnection();
@ -348,7 +348,7 @@ public class HttpDownloadConnection implements Transferable {
PowerManager.WakeLock wakeLock = mHttpConnectionManager.createWakeLock("http_download_" + message.getUuid()); PowerManager.WakeLock wakeLock = mHttpConnectionManager.createWakeLock("http_download_" + message.getUuid());
try { try {
wakeLock.acquire(); wakeLock.acquire();
if (mUseTor) { if (mUseTor || message.getConversation().getAccount().isOnion()) {
connection = (HttpURLConnection) mUrl.openConnection(HttpConnectionManager.getProxy()); connection = (HttpURLConnection) mUrl.openConnection(HttpConnectionManager.getProxy());
} else { } else {
connection = (HttpURLConnection) mUrl.openConnection(); connection = (HttpURLConnection) mUrl.openConnection();

View file

@ -167,7 +167,7 @@ public class HttpUploadConnection implements Transferable {
final int readTimeout = (expectedFileSize / 2048) + Config.SOCKET_TIMEOUT; //assuming a minimum transfer speed of 16kbit/s final int readTimeout = (expectedFileSize / 2048) + Config.SOCKET_TIMEOUT; //assuming a minimum transfer speed of 16kbit/s
wakeLock.acquire(readTimeout); wakeLock.acquire(readTimeout);
Log.d(Config.LOGTAG, "uploading to " + slot.getPutUrl().toString()+ " w/ read timeout of "+readTimeout+"s"); Log.d(Config.LOGTAG, "uploading to " + slot.getPutUrl().toString()+ " w/ read timeout of "+readTimeout+"s");
if (mUseTor) { if (mUseTor || message.getConversation().getAccount().isOnion()) {
connection = (HttpURLConnection) slot.getPutUrl().openConnection(HttpConnectionManager.getProxy()); connection = (HttpURLConnection) slot.getPutUrl().openConnection(HttpConnectionManager.getProxy());
} else { } else {
connection = (HttpURLConnection) slot.getPutUrl().openConnection(); connection = (HttpURLConnection) slot.getPutUrl().openConnection();

View file

@ -285,7 +285,8 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived {
final boolean isGet = packet.getType() == IqPacket.TYPE.GET; final boolean isGet = packet.getType() == IqPacket.TYPE.GET;
if (packet.getType() == IqPacket.TYPE.ERROR || packet.getType() == IqPacket.TYPE.TIMEOUT) { if (packet.getType() == IqPacket.TYPE.ERROR || packet.getType() == IqPacket.TYPE.TIMEOUT) {
return; return;
} else if (packet.hasChild("query", Namespace.ROSTER) && packet.fromServer(account)) { }
if (packet.hasChild("query", Namespace.ROSTER) && packet.fromServer(account)) {
final Element query = packet.findChild("query"); final Element query = packet.findChild("query");
// If this is in response to a query for the whole roster: // If this is in response to a query for the whole roster:
if (packet.getType() == IqPacket.TYPE.RESULT) { if (packet.getType() == IqPacket.TYPE.RESULT) {
@ -362,7 +363,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived {
mXmppConnectionService.getJingleConnectionManager() mXmppConnectionService.getJingleConnectionManager()
.deliverIbbPacket(account, packet); .deliverIbbPacket(account, packet);
} else if (packet.hasChild("query", "http://jabber.org/protocol/disco#info")) { } else if (packet.hasChild("query", "http://jabber.org/protocol/disco#info")) {
final IqPacket response = mXmppConnectionService.getIqGenerator().discoResponse(packet); final IqPacket response = mXmppConnectionService.getIqGenerator().discoResponse(account, packet);
mXmppConnectionService.sendIqPacket(account, response, null); mXmppConnectionService.sendIqPacket(account, response, null);
} else if (packet.hasChild("query","jabber:iq:version") && isGet) { } else if (packet.hasChild("query","jabber:iq:version") && isGet) {
final IqPacket response = mXmppConnectionService.getIqGenerator().versionResponse(packet); final IqPacket response = mXmppConnectionService.getIqGenerator().versionResponse(packet);
@ -372,7 +373,7 @@ public class IqParser extends AbstractParser implements OnIqPacketReceived {
mXmppConnectionService.sendIqPacket(account, response, null); mXmppConnectionService.sendIqPacket(account, response, null);
} else if (packet.hasChild("time","urn:xmpp:time") && isGet) { } else if (packet.hasChild("time","urn:xmpp:time") && isGet) {
final IqPacket response; final IqPacket response;
if (mXmppConnectionService.useTorToConnect()) { if (mXmppConnectionService.useTorToConnect() || account.isOnion()) {
response = packet.generateResponse(IqPacket.TYPE.ERROR); response = packet.generateResponse(IqPacket.TYPE.ERROR);
final Element error = response.addChild("error"); final Element error = response.addChild("error");
error.setAttribute("type","cancel"); error.setAttribute("type","cancel");

View file

@ -260,7 +260,7 @@ public class XmppConnection implements Runnable {
if (useTor) { if (useTor) {
String destination; String destination;
if (account.getHostname().isEmpty()) { if (account.getHostname().isEmpty()) {
destination = account.getServer().toString(); destination = account.getServer();
} else { } else {
destination = account.getHostname(); destination = account.getHostname();
this.verifiedHostname = destination; this.verifiedHostname = destination;