Example #1
0
        /// <inheritdoc />
        public void Execute(XmppBase xmpp, Tag tag = null)
        {
            Features features;

            xmpp.ClientSocket.SetReadClear();

            Logger.Log(LogLevel.Debug, "Starting to parse features");
            switch (tag)
            {
            case Stream s when s.Version.StartsWith("1."):
                features = s.Features;

                break;

            case Features f:
                features = f;
                break;

            default:
                Logger.Log(LogLevel.Error, "Unexpected tag. Wrong state executed");
                return;
            }

            if (features.StartTls != null && (xmpp.UseSsl || features.FeatureCount == 1 || features.StartTls.Required))
            {
                Logger.Log(LogLevel.Debug, "SSL/TLS is required or it is supported and we want to use it");
                xmpp.State = new StartTlsState();
                xmpp.State.Execute(xmpp);
                return;
            }

            if (xmpp is XmppClient client && !client.Authenticated)
            {
                Logger.Log(LogLevel.Debug, "Starting authentication");
                client.SaslProcessor = SaslProcessor.CreateProcessor(
                    features.Mechanisms.SupportedTypes,
                    MechanismTypes.Default,
                    client);
                if (client.SaslProcessor is null)
                {
                    client.State = new DisconnectState();
                    client.State.Execute(client);
                    return;
                }

                client.ClientSocket.Send(client.SaslProcessor.Initialize(client.Id, client.Password));
                client.State = new SaslState();
            }
        }
Example #2
0
        /// <summary>
        ///     Authenticate a user with the server
        /// </summary>
        /// <param name="features">Current <see cref="Features"/> from the server</param>
        /// <param name="client">Current <see cref="XmppClient"/> instance</param>
        public static void AuthenticateUser(this Features features, XmppClient client)
        {
            client.SaslProcessor = SaslProcessor.CreateProcessor(
                features.Mechanisms.SupportedTypes,
                MechanismTypes.Default,
                client);
            if (client.SaslProcessor is null)
            {
                client.State = new DisconnectState();
                client.State.Execute(client);
                return;
            }

            client.ClientSocket.Send(client.SaslProcessor.Initialize(client.Id, client.Password));
            client.State = new SaslState();
        }
Example #3
0
        /// <summary>
        /// </summary>
        /// <param name="data">
        ///     A <see cref="Tag" />
        /// </param>
        public override void Execute(Tag data = null)
        {
            Features f;

            if (data is Stream)
            {
                var s = data as Stream;
                if (!s.Version.StartsWith("1."))
                {
                    ProtocolState.Events.Error(this, ErrorType.WrongProtocolVersion, ErrorSeverity.Fatal, "Didn't receive expected stream:features tag from 1.x compliant server.");
                    return;
                }
                f = s.Features;
            }
            else
            {
                f = data as Features;
            }

            if (f != null)
            {
                if (f.StartTls != null && ProtocolState.Settings.Ssl)
                {
                    ProtocolState.State = new StartTlsState();
                    var tls = TagRegistry.GetTag <StartTls>("starttls", Namespaces.StartTls);
                    ProtocolState.Socket.Write(tls);
                    return;
                }

                if (!ProtocolState.Authenticated)
                {
                    ProtocolState.Processor = SaslProcessor.CreateProcessor(f.StartSasl.SupportedTypes, ProtocolState.Settings.AuthenticationTypes);
                    if (ProtocolState.Processor == null)
                    {
                        ProtocolState.State = new DisconnectState();
                        ProtocolState.State.Execute();
                        return;
                    }
                    ProtocolState.Socket.Write(ProtocolState.Processor.Initialize(ProtocolState.Settings.Id, ProtocolState.Settings.Password));

                    ProtocolState.State = new SaslState();
                    return;
                }

                // Takes place after authentication according to XEP-0170
                if (!ProtocolState.Compressed && CompressionRegistry.AlgorithmsAvailable && !ProtocolState.Settings.Ssl &&
                    f.Compression != null)
                {
                    // Do we have a stream for any of the compressions supported by the server?
                    foreach (string algorithm in
                             f.Compression.Algorithms.Where(CompressionRegistry.SupportsAlgorithm))
                    {
                        var c = TagRegistry.GetTag <GenericTag>("compress", Namespaces.CompressionProtocol);
                        var m = TagRegistry.GetTag <GenericTag>("method", Namespaces.CompressionProtocol);

                        m.InnerText = ProtocolState.Algorithm = algorithm;
                        c.AddChildTag(m);
                        ProtocolState.Socket.Write(c);
                        ProtocolState.State = new CompressedState();
                        return;
                    }
                }
            }

            ProtocolState.State = new BindingState();
            ProtocolState.State.Execute();
        }
Example #4
0
        /// <summary>
        /// </summary>
        /// <param name="data">
        ///     A <see cref="Tag" />
        /// </param>
        public void Execute(Tag data = null)
        {
            Features features;

            var stream = data as Stream;

            if (stream != null)
            {
                var s = stream;
                if (!s.Version.StartsWith("1."))
                {
                    ProtocolState.Events.Error(this, ErrorType.WrongProtocolVersion, ErrorSeverity.Fatal,
                                               "Didn't receive expected stream:features tag from 1.x compliant server.");
                    return;
                }
                features = s.Features;
            }
            else
            {
                features = data as Features;
            }

            if (features != null)
            {
                // We have features available so make sure we have them set
                features.Update();

                // Should we use SSL and is it required
                if ((ProtocolState.Features.HasFlag(ProtocolFeatures.StartTls) && ProtocolState.Settings.Ssl) ||
                    (ProtocolState.Features.HasFlag(ProtocolFeatures.StartTls) &&
                     ProtocolState.Features.HasFlag(ProtocolFeatures.SslRequired)) && !ProtocolState.Encrypted)
                {
                    Log.Debug("Starting SSL...");
                    ProtocolState.State = new StartTlsState();
                    var tls = TagRegistry.GetTag <StartTls>("starttls", Namespaces.StartTls);
                    ProtocolState.Socket.Write(tls);
                    return;
                }

                if (!ProtocolState.Authenticated)
                {
                    Log.Debug("Starting Authentication...");
                    ProtocolState.Processor = SaslProcessor.CreateProcessor(features.StartSasl.SupportedTypes,
                                                                            ProtocolState.Settings.AuthenticationTypes);
                    if (ProtocolState.Processor == null)
                    {
                        ProtocolState.State = new DisconnectState();
                        ProtocolState.State.Execute();
                        return;
                    }
                    ProtocolState.Socket.Write(
                        ProtocolState.Processor.Initialize(ProtocolState.Settings.Id, ProtocolState.Settings.Password));

                    ProtocolState.State = new SaslState();
                    return;
                }

                // Takes place after authentication according to XEP-0170
                if (!ProtocolState.Compressed && CompressionRegistry.AlgorithmsAvailable &&
                    !ProtocolState.Settings.Ssl &&
                    features.Compression != null)
                {
                    Log.Debug("Starting Compression...");
                    // Do we have a stream for any of the compressions supported by the server?
                    foreach (var algorithm in
                             features.Compression.Algorithms.Where(CompressionRegistry.SupportsAlgorithm))
                    {
                        var c = TagRegistry.GetTag <GenericTag>("compress", Namespaces.CompressionProtocol);
                        var m = TagRegistry.GetTag <GenericTag>("method", Namespaces.CompressionProtocol);

                        m.InnerText = ProtocolState.Algorithm = algorithm;
                        c.AddChildTag(m);
                        ProtocolState.Socket.Write(c);
                        ProtocolState.State = new CompressedState();
                        return;
                    }
                }

                if (ProtocolState.Authenticated)
                {
                    Log.Debug("Switching to Binding state");
                    ProtocolState.State = new BindingState();
                    ProtocolState.State.Execute();
                }
            }
        }