Ejemplo n.º 1
0
        public IAsyncOperation<string> Connect() {
            var window = CoreWindow.GetForCurrentThread();

            return Task.Run<string>(async () =>
            {
                try
                {
                    var socket = this.socket = new Windows.Networking.Sockets.StreamSocket();

                    await socket.ConnectAsync(new HostName("talk.google.com"), "5222", SocketProtectionLevel.PlainSocket);

                    await log(window, "connected!");

                    reader = new DataReader(socket.InputStream);
                    writer = new DataWriter(socket.OutputStream);

                    reader.InputStreamOptions = InputStreamOptions.Partial;

                    Write("<?xml version='1.0'?>\n<stream:stream to='" + server + "' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>");

                    xmlStream = new XmlStream();
                    bool shouldRead = true;

                    xmlStream.SetCallback(async (promptRead, data) => {
                        await log(window, "data " + data);

                        if (promptRead)
                        {
                            if (shouldRead)
                            {
                                await log(window, "prompt read");

                                await reader.LoadAsync(4096);
                                var buffer = new byte[reader.UnconsumedBufferLength];
                                reader.ReadBytes(buffer);
                                await log(window, "in " + Encoding.UTF8.GetString(buffer, 0, buffer.Length));
                                xmlStream.Update(buffer, 0, buffer.Length);
                            }
                            else
                            {
                                await log(window, "read blocked");
                            }
                        }
                        else if (data.IndexOf("stream:features") != -1)
                        {
                            Write("<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls' />");
                        }
                        else if (data.IndexOf("proceed") != -1)
                        {
                            await log(window, "SSL Strength: " + socket.Information.ProtectionLevel);

                            writer.DetachStream();
                            reader.DetachStream();

                            shouldRead = false;

                            if (server == "gmail.com")
                            {
                                await socket.UpgradeToSslAsync(SocketProtectionLevel.Ssl, new Windows.Networking.HostName("gmail.com"));
                            }
                            else
                            {
                                await socket.UpgradeToSslAsync(SocketProtectionLevel.Ssl, new Windows.Networking.HostName("talk.google.com"));
                            }

                            writer = new DataWriter(socket.OutputStream);
                            reader = new DataReader(socket.InputStream);

                            reader.InputStreamOptions = InputStreamOptions.Partial;

                            await log(window, "upgraded!");
                            await log(window, "SSL Strength: " + socket.Information.ProtectionLevel);

                            Write("<?xml version='1.0'?>\n<stream:stream to='" + server + "' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>");

                            xmlStream.SetCallback(async (shouldRead2, data2) =>
                            {
                                await log(window, "data " + data2);

                                if (shouldRead2)
                                {
                                    await reader.LoadAsync(4096);
                                    var buffer = new byte[reader.UnconsumedBufferLength];
                                    reader.ReadBytes(buffer);
                                    await log(window, "in " + Encoding.UTF8.GetString(buffer, 0, buffer.Length));
                                    xmlStream.Update(buffer, 0, buffer.Length);
                                }
                                else if (data2.Contains("X-GOOGLE-TOKEN"))
                                {
                                    var token = Convert.ToBase64String(Encoding.UTF8.GetBytes('\x00' + this.username + '\x00' + this.auth));
                                    Write("<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='X-GOOGLE-TOKEN'>" + token + "</auth>");
                                }
                                else if (data2.Contains("failure"))
                                {
                                    if (Disconnect != null) Disconnect(this, "auth failure");
                                }
                                else if (data2.Contains("success"))
                                {
                                    var messageEvent = Message;

                                    xmlStream.SetCallback(async (shouldRead3, data3) =>
                                    {
                                        if (shouldRead3)
                                        {
                                            await reader.LoadAsync(4096);
                                            var buffer = new byte[reader.UnconsumedBufferLength];
                                            reader.ReadBytes(buffer);
                                            await log(window, "in " + Encoding.UTF8.GetString(buffer, 0, buffer.Length));
                                            xmlStream.Update(buffer, 0, buffer.Length);
                                        }
                                        else if (data3 == "</stream:stream>")
                                        {
                                            await disconnect(window, "end of stream");
                                        }
                                        else if (!data3.StartsWith("<stream:stream"))
                                        {
                                            await message(window, data3);
                                        }
                                    });

                                    Write("<?xml version='1.0'?>\n<stream:stream to='" + server + "' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>");
                                }
                                else if (!data2.StartsWith("<stream:stream"))
                                {
                                    await log(window, "Ummm not sure what to do with '" + data2 + "'. flee.");
                                    if (Disconnect != null) Disconnect(this, "protocol error");
                                }
                            });
                        }
                        else if (!data.StartsWith("<stream:stream"))
                        {
                            await log(window, "Ummm not sure what to do with '" + data + "'. flee.");
                            if (Disconnect != null) Disconnect(this, "protocol error");
                        }
                    });

                    return "ok";
                }
                catch (Exception e)
                {
                    return e.ToString();
                }
            }).AsAsyncOperation<string>();
        }