Problem
Facebook chat now requires a secure connection, so any apps that are using it are now broken until TLS is exposed through our TCP sockets.
Pull Request
https://github.com/appcelerator/titanium_mobile/pull/725
How to Test
Drop the following in an app.js. Look at the log. After some network traffic (~5 seconds) you should see the log message, "Socket secured!". (Note that around 10 seconds later, the connection will timeout and you'll be disconnected -- this is expected behavior.)
var win = Ti.UI.createWindow({
backgroundColor: '#fff'
});
var states = {
WAITING_FOR_FIRST_RESPONSE: 0,
WAITING_FOR_START_TLS: 1,
WAITING_FOR_PROCEED: 2,
WAITING_FOR_SECURED: 3,
DONE: 4,
ERRORED: 5
};
var currentState = Ti.Android ? states.WAITING_FOR_FIRST_RESPONSE : states.WAITING_FOR_START_TLS;
var socket = Ti.Network.Socket.createTCP({
host: 'chat.facebook.com', port: 5222,
connected: function (e) {
Ti.API.info('Socket opened!');
Ti.Stream.pump(e.socket, read, 1024, true);
socket.write(Ti.createBuffer({
value: '<stream:stream xmlns:stream="http://etherx.jabber.org/streams" version="1.0" \
xmlns="jabber:client" to="chat.facebook.com" xml:lang="en" \
xmlns:xml="http://www.w3.org/XML/1998/namespace">'
}));
},
secured: function (e) {
Ti.API.info('Socket secured!');
},
error: function (e) {
Ti.API.info('Error (' + e.errorCode + '): ' + e.error);
},
closed: function (e) {
Ti.API.info('Socket closed!');
}
});
socket.connect();
function write(msg) {
Ti.API.info('State: ' + currentState + ', Wrote: ' + msg);
socket.write(Ti.createBuffer({
value: msg
}));
}
function read(e) {
try {
if (e.buffer) {
var received = e.buffer.toString();
Ti.API.info('State: ' + currentState + ', Received: ' + received);
switch (currentState) {
case states.WAITING_FOR_FIRST_RESPONSE:
if (received.split('<?xml version="1.0"?><stream:stream ').length <= 1) {
Ti.API.error('Unexpected response from server while WAITING_FOR_FIRST_RESPONSE!');
return currentState = states.ERRORED;
}
return currentState = states.WAITING_FOR_START_TLS;
case states.WAITING_FOR_START_TLS:
if (received.split('<stream:features><starttls ').length <= 1) {
Ti.API.error('Unexpected response from server while WAITING_FOR_START_TLS!');
return currentState = states.ERRORED;
}
write('<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>');
if (!Ti.Android) {
// Note: iOS requires that startTLS be called right after sending the above XML.
// This is required because of how reads and writes are queued up before a secure handshake.
socket.startTLS();
return currentState = states.WAITING_FOR_SECURED;
}
return currentState = states.WAITING_FOR_PROCEED;
case states.WAITING_FOR_PROCEED:
if (received.split('<proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>').length <= 1) {
Ti.API.error('Unexpected response from server while WAITING_FOR_PROCEED!');
return currentState = states.ERRORED;
}
socket.startTLS();
return currentState = states.WAITING_FOR_SECURED;
case states.WAITING_FOR_SECURED:
write('<stream:stream xmlns:stream="http://etherx.jabber.org/streams" version="1.0" \
xmlns="jabber:client" to="chat.facebook.com" xml:lang="en" \
xmlns:xml="http://www.w3.org/XML/1998/namespace">');
return currentState = states.DONE;
}
}
else {
Ti.API.error('Error: no e.buffer!');
}
} catch (ex) {
Ti.API.error(ex);
}
}
win.open();
Related Tickets
iOS: [TIMOB-6211]
Android: [TIMOB-6212]
APIDoc: [TIMOB-6213]
Cloned off of [MOD-286]. Android and Doc tickets en route as well as pull requests for all of them.
Opened pull request https://github.com/appcelerator/titanium_mobile/pull/725
Revamped the description so that it is clear what this is addressing and how it can be tested.
Still nothing changed? Can somebody explain me how can I develop secure software using Titanium if features like this one are not provided?
[~sko] Are you actually creating a direct TCP socket, or just using a HTTPS connection? TLS is already supported in that context, see http://www.appcelerator.com/blog/2012/11/the-titanium-sdk-and-certificate-validation/.
Hi Ingo, yes I create a direct TCP connection to be more specific I have got my own module that provides connection using WebSocket protocol and this protocol works over TCP that unfortunately can't be encrypted... That's a big problem. This feature is not required only by me ,but several other people that mentioned this in Titanium Community Questions & Answers. // To be honest at this time every serious application uses encrypted connection (https, wss or directly TCP). I think this feature is quite important.
[~sko] is this a native module? How is it creating the TCP connection?
No it is not a native module. The TCP connection is created exactly in the same way as in the example above so using Ti.Network.Socket.createTCP
Ingo, please could you set higher priority for this issue? We are quite far with our application and we can't release it without encrypted connection. That's standard. Thank you a lot
[~sko] I currently cannot bump the priority. If you are interested, I believe you could take [~dtoth]'s PR and expand it.
i would need a secure socket for a chat app for ios and android - is there timeline or a workaround ? thanks
Hello to all Also in my work I find myself needing to create secure connections on TLS. Specifically for the creation of IoT app with proprietary protocol that require a minimum level of data transmission security.