package asmack.org.jivesoftware.smackx.filetransfer; import asmack.org.jivesoftware.smack.Connection; import asmack.org.jivesoftware.smack.ConnectionListener; import asmack.org.jivesoftware.smack.PacketCollector; import asmack.org.jivesoftware.smack.XMPPException; import asmack.org.jivesoftware.smack.filter.PacketIDFilter; import asmack.org.jivesoftware.smack.packet.IQ; import asmack.org.jivesoftware.smack.packet.Packet; import asmack.org.jivesoftware.smack.packet.XMPPError; import asmack.org.jivesoftware.smackx.Form; import asmack.org.jivesoftware.smackx.FormField; import asmack.org.jivesoftware.smackx.ServiceDiscoveryManager; import asmack.org.jivesoftware.smackx.packet.DataForm; import asmack.org.jivesoftware.smackx.packet.StreamInitiation; import java.net.URLConnection; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.Map; import java.util.Random; import java.util.concurrent.ConcurrentHashMap; public class FileTransferNegotiator { public static final String BYTE_STREAM = "http://jabber.org/protocol/bytestreams"; public static boolean IBB_ONLY = false; public static final String INBAND_BYTE_STREAM = "http://jabber.org/protocol/ibb"; private static final String[] NAMESPACE = {"http://jabber.org/protocol/si/profile/file-transfer", "http://jabber.org/protocol/si", BYTE_STREAM, "http://jabber.org/protocol/ibb"}; private static final String[] PROTOCOLS = {BYTE_STREAM, "http://jabber.org/protocol/ibb"}; protected static final String STREAM_DATA_FIELD_NAME = "stream-method"; private static final String STREAM_INIT_PREFIX = "jsi_"; private static final Random randomGenerator = new Random(); private static final Map<Connection, FileTransferNegotiator> transferObject = new ConcurrentHashMap(); private final Socks5TransferNegotiatorManager byteStreamTransferManager; private final Connection connection; private final StreamNegotiator inbandTransferManager; private FileTransferNegotiator(Connection connection2) { configureConnection(connection2); this.connection = connection2; this.byteStreamTransferManager = new Socks5TransferNegotiatorManager(connection2); this.inbandTransferManager = new IBBTransferNegotiator(connection2); } /* access modifiers changed from: private */ /* access modifiers changed from: public */ private void cleanup(Connection connection2) { if (transferObject.remove(connection2) != null) { this.byteStreamTransferManager.cleanup(); this.inbandTransferManager.cleanup(); } } private void configureConnection(final Connection connection2) { connection2.addConnectionListener(new ConnectionListener() { /* class asmack.org.jivesoftware.smackx.filetransfer.FileTransferNegotiator.AnonymousClass2 */ @Override // asmack.org.jivesoftware.smack.ConnectionListener public void connectionClosed() { FileTransferNegotiator.this.cleanup(connection2); } @Override // asmack.org.jivesoftware.smack.ConnectionListener public void connectionClosedOnError(Exception exc) { FileTransferNegotiator.this.cleanup(connection2); } @Override // asmack.org.jivesoftware.smack.ConnectionListener public void reconnectingIn(int i) { } @Override // asmack.org.jivesoftware.smack.ConnectionListener public void reconnectionFailed(Exception exc) { } @Override // asmack.org.jivesoftware.smack.ConnectionListener public void reconnectionSuccessful() { } }); } private DataForm createDefaultInitiationForm() { DataForm dataForm = new DataForm(Form.TYPE_FORM); FormField formField = new FormField(STREAM_DATA_FIELD_NAME); formField.setType(FormField.TYPE_LIST_MULTI); if (!IBB_ONLY) { formField.addOption(new FormField.Option(BYTE_STREAM)); } formField.addOption(new FormField.Option("http://jabber.org/protocol/ibb")); dataForm.addField(formField); return dataForm; } public static IQ createIQ(String str, String str2, String str3, IQ.Type type) { AnonymousClass1 r0 = new IQ() { /* class asmack.org.jivesoftware.smackx.filetransfer.FileTransferNegotiator.AnonymousClass1 */ @Override // asmack.org.jivesoftware.smack.packet.IQ public String getChildElementXML() { return null; } }; r0.setPacketID(str); r0.setTo(str2); r0.setFrom(str3); r0.setType(type); return r0; } public static FileTransferNegotiator getInstanceFor(Connection connection2) { if (connection2 == null) { throw new IllegalArgumentException("Connection cannot be null"); } else if (!connection2.isConnected()) { return null; } else { if (transferObject.containsKey(connection2)) { return transferObject.get(connection2); } FileTransferNegotiator fileTransferNegotiator = new FileTransferNegotiator(connection2); setServiceEnabled(connection2, true); transferObject.put(connection2, fileTransferNegotiator); return fileTransferNegotiator; } } private StreamNegotiator getNegotiator(FormField formField) throws XMPPException { Iterator<FormField.Option> options = formField.getOptions(); boolean z = false; boolean z2 = false; while (options.hasNext()) { String value = options.next().getValue(); if (value.equals(BYTE_STREAM) && !IBB_ONLY) { z = true; } else if (value.equals("http://jabber.org/protocol/ibb")) { z2 = true; } } if (z || z2) { return (!z || !z2 || !formField.getType().equals(FormField.TYPE_LIST_MULTI)) ? z ? this.byteStreamTransferManager.createNegotiator() : this.inbandTransferManager : new FaultTolerantNegotiator(this.connection, this.byteStreamTransferManager.createNegotiator(), this.inbandTransferManager); } XMPPError xMPPError = new XMPPError(XMPPError.Condition.bad_request, "No acceptable transfer mechanism"); throw new XMPPException(xMPPError.getMessage(), xMPPError); } private StreamNegotiator getOutgoingNegotiator(FormField formField) throws XMPPException { Iterator<String> values = formField.getValues(); boolean z = false; boolean z2 = false; while (values.hasNext()) { String next = values.next(); if (next.equals(BYTE_STREAM) && !IBB_ONLY) { z = true; } else if (next.equals("http://jabber.org/protocol/ibb")) { z2 = true; } } if (z || z2) { return (!z || !z2) ? z ? this.byteStreamTransferManager.createNegotiator() : this.inbandTransferManager : new FaultTolerantNegotiator(this.connection, this.byteStreamTransferManager.createNegotiator(), this.inbandTransferManager); } XMPPError xMPPError = new XMPPError(XMPPError.Condition.bad_request, "No acceptable transfer mechanism"); throw new XMPPException(xMPPError.getMessage(), xMPPError); } private FormField getStreamMethodField(DataForm dataForm) { FormField formField; Iterator<FormField> fields = dataForm.getFields(); do { formField = null; if (!fields.hasNext()) { break; } formField = fields.next(); } while (!formField.getVariable().equals(STREAM_DATA_FIELD_NAME)); return formField; } public static Collection<String> getSupportedProtocols() { return Collections.unmodifiableList(Arrays.asList(PROTOCOLS)); } public static boolean isServiceEnabled(Connection connection2) { for (String str : NAMESPACE) { if (!ServiceDiscoveryManager.getInstanceFor(connection2).includesFeature(str)) { return false; } } return true; } public static void setServiceEnabled(Connection connection2, boolean z) { ServiceDiscoveryManager instanceFor = ServiceDiscoveryManager.getInstanceFor(connection2); String[] strArr = NAMESPACE; for (String str : strArr) { if (z) { instanceFor.addFeature(str); } else { instanceFor.removeFeature(str); } } } public String getNextStreamID() { return STREAM_INIT_PREFIX + Math.abs(randomGenerator.nextLong()); } public StreamNegotiator negotiateOutgoingTransfer(String str, String str2, String str3, long j, String str4, int i) throws XMPPException { StreamInitiation streamInitiation = new StreamInitiation(); streamInitiation.setSesssionID(str2); streamInitiation.setMimeType(URLConnection.guessContentTypeFromName(str3)); StreamInitiation.File file = new StreamInitiation.File(str3, j); file.setDesc(str4); streamInitiation.setFile(file); streamInitiation.setFeatureNegotiationForm(createDefaultInitiationForm()); streamInitiation.setFrom(this.connection.getUser()); streamInitiation.setTo(str); streamInitiation.setType(IQ.Type.SET); PacketCollector createPacketCollector = this.connection.createPacketCollector(new PacketIDFilter(streamInitiation.getPacketID())); this.connection.sendPacket(streamInitiation); Packet nextResult = createPacketCollector.nextResult((long) i); createPacketCollector.cancel(); if (!(nextResult instanceof IQ)) { return null; } IQ iq = (IQ) nextResult; if (iq.getType().equals(IQ.Type.RESULT)) { return getOutgoingNegotiator(getStreamMethodField(((StreamInitiation) nextResult).getFeatureNegotiationForm())); } if (iq.getType().equals(IQ.Type.ERROR)) { throw new XMPPException(iq.getError()); } throw new XMPPException("File transfer response unreadable"); } public void rejectStream(StreamInitiation streamInitiation) { XMPPError xMPPError = new XMPPError(XMPPError.Condition.forbidden, "Offer Declined"); IQ createIQ = createIQ(streamInitiation.getPacketID(), streamInitiation.getFrom(), streamInitiation.getTo(), IQ.Type.ERROR); createIQ.setError(xMPPError); this.connection.sendPacket(createIQ); } public StreamNegotiator selectStreamNegotiator(FileTransferRequest fileTransferRequest) throws XMPPException { StreamInitiation streamInitiation = fileTransferRequest.getStreamInitiation(); FormField streamMethodField = getStreamMethodField(streamInitiation.getFeatureNegotiationForm()); if (streamMethodField != null) { try { return getNegotiator(streamMethodField); } catch (XMPPException e2) { IQ createIQ = createIQ(streamInitiation.getPacketID(), streamInitiation.getFrom(), streamInitiation.getTo(), IQ.Type.ERROR); createIQ.setError(e2.getXMPPError()); this.connection.sendPacket(createIQ); throw e2; } } else { XMPPError xMPPError = new XMPPError(XMPPError.Condition.bad_request, "No stream methods contained in packet."); IQ createIQ2 = createIQ(streamInitiation.getPacketID(), streamInitiation.getFrom(), streamInitiation.getTo(), IQ.Type.ERROR); createIQ2.setError(xMPPError); this.connection.sendPacket(createIQ2); throw new XMPPException("No stream methods contained in packet.", xMPPError); } } }