use of eu.siacs.conversations.xmpp.jingle.stanzas.IbbTransportInfo in project Conversations by siacs.
the class JingleFileTransferConnection method receiveAccept.
private void receiveAccept(JinglePacket packet) {
if (responding()) {
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": received out of order session-accept (we were responding)");
respondToIqWithOutOfOrder(packet);
return;
}
if (this.mJingleStatus != JINGLE_STATUS_INITIATED) {
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": received out of order session-accept");
respondToIqWithOutOfOrder(packet);
return;
}
this.mJingleStatus = JINGLE_STATUS_ACCEPTED;
xmppConnectionService.markMessage(message, Message.STATUS_UNSEND);
final Content content = packet.getJingleContent();
final GenericTransportInfo transportInfo = content.getTransport();
// TODO we want to fail if transportInfo doesn’t match our intialTransport and/or our id
if (transportInfo instanceof S5BTransportInfo) {
final S5BTransportInfo s5BTransportInfo = (S5BTransportInfo) transportInfo;
respondToIq(packet, true);
// TODO calling merge is probably a bug because that might eliminate candidates of the other party and lead to us not sending accept/deny
// TODO: we probably just want to call add
mergeCandidates(s5BTransportInfo.getCandidates());
this.connectNextCandidate();
} else if (transportInfo instanceof IbbTransportInfo) {
final IbbTransportInfo ibbTransportInfo = (IbbTransportInfo) transportInfo;
final int remoteBlockSize = ibbTransportInfo.getBlockSize();
if (remoteBlockSize > 0) {
this.ibbBlockSize = Math.min(ibbBlockSize, remoteBlockSize);
}
respondToIq(packet, true);
this.transport = new JingleInBandTransport(this, this.transportId, this.ibbBlockSize);
this.transport.connect(onIbbTransportConnected);
} else {
respondToIq(packet, false);
}
}
use of eu.siacs.conversations.xmpp.jingle.stanzas.IbbTransportInfo in project Conversations by siacs.
the class JingleFileTransferConnection method sendInitRequest.
private void sendInitRequest() {
final JinglePacket packet = this.bootstrapPacket(JinglePacket.Action.SESSION_INITIATE);
final Content content = new Content(this.contentCreator, this.contentName);
content.setSenders(this.contentSenders);
if (message.getEncryption() == Message.ENCRYPTION_AXOLOTL && remoteSupportsOmemoJet) {
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": remote announced support for JET");
final Element security = new Element("security", Namespace.JINGLE_ENCRYPTED_TRANSPORT);
security.setAttribute("name", this.contentName);
security.setAttribute("cipher", JET_OMEMO_CIPHER);
security.setAttribute("type", AxolotlService.PEP_PREFIX);
security.addChild(mXmppAxolotlMessage.toElement());
content.addChild(security);
}
content.setDescription(this.description);
message.resetFileParams();
try {
this.mFileInputStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
fail(e.getMessage());
return;
}
if (this.initialTransport == IbbTransportInfo.class) {
content.setTransport(new IbbTransportInfo(this.transportId, this.ibbBlockSize));
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": sending IBB offer");
} else {
final Collection<JingleCandidate> candidates = getOurCandidates();
content.setTransport(new S5BTransportInfo(this.transportId, candidates));
Log.d(Config.LOGTAG, String.format("%s: sending S5B offer with %d candidates", id.account.getJid().asBareJid(), candidates.size()));
}
packet.addJingleContent(content);
this.sendJinglePacket(packet, (account, response) -> {
if (response.getType() == IqPacket.TYPE.RESULT) {
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": other party received offer");
if (mJingleStatus == JINGLE_STATUS_OFFERED) {
mJingleStatus = JINGLE_STATUS_INITIATED;
xmppConnectionService.markMessage(message, Message.STATUS_OFFERED);
} else {
Log.d(Config.LOGTAG, "received ack for offer when status was " + mJingleStatus);
}
} else {
fail(IqParser.extractErrorMessage(response));
}
});
}
use of eu.siacs.conversations.xmpp.jingle.stanzas.IbbTransportInfo in project Conversations by siacs.
the class JingleFileTransferConnection method sendAcceptIbb.
private void sendAcceptIbb() {
this.transport = new JingleInBandTransport(this, this.transportId, this.ibbBlockSize);
final JinglePacket packet = bootstrapPacket(JinglePacket.Action.SESSION_ACCEPT);
final Content content = new Content(contentCreator, contentName);
content.setSenders(this.contentSenders);
content.setDescription(this.description);
content.setTransport(new IbbTransportInfo(this.transportId, this.ibbBlockSize));
packet.addJingleContent(content);
this.transport.receive(file, onFileTransmissionStatusChanged);
this.sendJinglePacket(packet);
}
use of eu.siacs.conversations.xmpp.jingle.stanzas.IbbTransportInfo in project Conversations by siacs.
the class JingleFileTransferConnection method receiveTransportAccept.
private void receiveTransportAccept(JinglePacket packet) {
if (responding()) {
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": received out of order transport-accept (we were responding)");
respondToIqWithOutOfOrder(packet);
return;
}
final boolean validState = mJingleStatus == JINGLE_STATUS_ACCEPTED || (proxyActivationFailed && mJingleStatus == JINGLE_STATUS_TRANSMITTING);
if (!validState) {
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": received out of order transport-accept");
respondToIqWithOutOfOrder(packet);
return;
}
// fallback accepted; now we no longer need to accept another one;
this.proxyActivationFailed = false;
final Content content = packet.getJingleContent();
final GenericTransportInfo transportInfo = content == null ? null : content.getTransport();
if (transportInfo instanceof IbbTransportInfo) {
final IbbTransportInfo ibbTransportInfo = (IbbTransportInfo) transportInfo;
final int remoteBlockSize = ibbTransportInfo.getBlockSize();
if (remoteBlockSize > 0) {
this.ibbBlockSize = Math.min(MAX_IBB_BLOCK_SIZE, remoteBlockSize);
}
final String sid = ibbTransportInfo.getTransportId();
this.transport = new JingleInBandTransport(this, this.transportId, this.ibbBlockSize);
if (sid == null || !sid.equals(this.transportId)) {
Log.w(Config.LOGTAG, String.format("%s: sid in transport-accept (%s) did not match our sid (%s) ", id.account.getJid().asBareJid(), sid, transportId));
}
respondToIq(packet, true);
// might be receive instead if we are not initiating
if (isInitiator()) {
this.transport.connect(onIbbTransportConnected);
}
} else {
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": received invalid transport-accept");
respondToIq(packet, false);
}
}
use of eu.siacs.conversations.xmpp.jingle.stanzas.IbbTransportInfo in project Conversations by siacs.
the class JingleFileTransferConnection method init.
private void init(JinglePacket packet) {
// should move to deliverPacket
// TODO if not 'OFFERED' reply with out-of-order
this.mJingleStatus = JINGLE_STATUS_INITIATED;
final Conversation conversation = this.xmppConnectionService.findOrCreateConversation(id.account, id.with.asBareJid(), false, false);
this.message = new Message(conversation, "", Message.ENCRYPTION_NONE);
this.message.setStatus(Message.STATUS_RECEIVED);
this.mStatus = Transferable.STATUS_OFFER;
this.message.setTransferable(this);
this.message.setCounterpart(this.id.with);
this.responder = this.id.account.getJid();
final Content content = packet.getJingleContent();
final GenericTransportInfo transportInfo = content.getTransport();
this.contentCreator = content.getCreator();
Content.Senders senders;
try {
senders = content.getSenders();
} catch (final Exception e) {
senders = Content.Senders.INITIATOR;
}
this.contentSenders = senders;
this.contentName = content.getAttribute("name");
if (transportInfo instanceof S5BTransportInfo) {
final S5BTransportInfo s5BTransportInfo = (S5BTransportInfo) transportInfo;
this.transportId = s5BTransportInfo.getTransportId();
this.initialTransport = s5BTransportInfo.getClass();
this.mergeCandidates(s5BTransportInfo.getCandidates());
} else if (transportInfo instanceof IbbTransportInfo) {
final IbbTransportInfo ibbTransportInfo = (IbbTransportInfo) transportInfo;
this.initialTransport = ibbTransportInfo.getClass();
this.transportId = ibbTransportInfo.getTransportId();
final int remoteBlockSize = ibbTransportInfo.getBlockSize();
if (remoteBlockSize <= 0) {
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": remote party requested invalid ibb block size");
respondToIq(packet, false);
this.fail();
}
this.ibbBlockSize = Math.min(MAX_IBB_BLOCK_SIZE, ibbTransportInfo.getBlockSize());
} else {
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": remote tried to use unknown transport " + transportInfo.getNamespace());
respondToIq(packet, false);
this.fail();
return;
}
this.description = (FileTransferDescription) content.getDescription();
final Element fileOffer = this.description.getFileOffer();
if (fileOffer != null) {
boolean remoteIsUsingJet = false;
Element encrypted = fileOffer.findChild("encrypted", AxolotlService.PEP_PREFIX);
if (encrypted == null) {
final Element security = content.findChild("security", Namespace.JINGLE_ENCRYPTED_TRANSPORT);
if (security != null && AxolotlService.PEP_PREFIX.equals(security.getAttribute("type"))) {
Log.d(Config.LOGTAG, id.account.getJid().asBareJid() + ": received jingle file offer with JET");
encrypted = security.findChild("encrypted", AxolotlService.PEP_PREFIX);
remoteIsUsingJet = true;
}
}
if (encrypted != null) {
this.mXmppAxolotlMessage = XmppAxolotlMessage.fromElement(encrypted, packet.getFrom().asBareJid());
}
Element fileSize = fileOffer.findChild("size");
final String path = fileOffer.findChildContent("name");
if (path != null) {
AbstractConnectionManager.Extension extension = AbstractConnectionManager.Extension.of(path);
if (VALID_IMAGE_EXTENSIONS.contains(extension.main)) {
message.setType(Message.TYPE_IMAGE);
message.setRelativeFilePath(message.getUuid() + "." + extension.main);
} else if (VALID_CRYPTO_EXTENSIONS.contains(extension.main)) {
if (VALID_IMAGE_EXTENSIONS.contains(extension.secondary)) {
message.setType(Message.TYPE_IMAGE);
message.setRelativeFilePath(message.getUuid() + "." + extension.secondary);
} else {
message.setType(Message.TYPE_FILE);
message.setRelativeFilePath(message.getUuid() + (extension.secondary != null ? ("." + extension.secondary) : ""));
}
message.setEncryption(Message.ENCRYPTION_PGP);
} else {
message.setType(Message.TYPE_FILE);
message.setRelativeFilePath(message.getUuid() + (extension.main != null ? ("." + extension.main) : ""));
}
long size = parseLong(fileSize, 0);
message.setBody(Long.toString(size));
conversation.add(message);
jingleConnectionManager.updateConversationUi(true);
this.file = this.xmppConnectionService.getFileBackend().getFile(message, false);
if (mXmppAxolotlMessage != null) {
XmppAxolotlMessage.XmppAxolotlKeyTransportMessage transportMessage = id.account.getAxolotlService().processReceivingKeyTransportMessage(mXmppAxolotlMessage, false);
if (transportMessage != null) {
message.setEncryption(Message.ENCRYPTION_AXOLOTL);
this.file.setKey(transportMessage.getKey());
this.file.setIv(transportMessage.getIv());
message.setFingerprint(transportMessage.getFingerprint());
} else {
Log.d(Config.LOGTAG, "could not process KeyTransportMessage");
}
}
message.resetFileParams();
// legacy OMEMO encrypted file transfers reported the file size after encryption
// JET reports the plain text size. however lower levels of our receiving code still
// expect the cipher text size. so we just + 16 bytes (auth tag size) here
this.file.setExpectedSize(size + (remoteIsUsingJet ? 16 : 0));
respondToIq(packet, true);
if (id.account.getRoster().getContact(id.with).showInContactList() && jingleConnectionManager.hasStoragePermission() && size < this.jingleConnectionManager.getAutoAcceptFileSize() && xmppConnectionService.isDataSaverDisabled()) {
Log.d(Config.LOGTAG, "auto accepting file from " + id.with);
this.acceptedAutomatically = true;
this.sendAccept();
} else {
message.markUnread();
Log.d(Config.LOGTAG, "not auto accepting new file offer with size: " + size + " allowed size:" + this.jingleConnectionManager.getAutoAcceptFileSize());
this.xmppConnectionService.getNotificationService().push(message);
}
Log.d(Config.LOGTAG, "receiving file: expecting size of " + this.file.getExpectedSize());
return;
}
respondToIq(packet, false);
}
}
Aggregations