Esempio n. 1
0
        /// <summary>
        /// Performs the session negotiation and authentication
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="compressionSelector"></param>
        /// <param name="encryptionSelector"></param>
        /// <param name="identity"></param>
        /// <param name="authenticator"></param>
        /// <param name="instance"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async static Task <Session> EstablishSessionAsync(this IClientChannel channel, Func <SessionCompression[], SessionCompression> compressionSelector,
                                                                 Func <SessionEncryption[], SessionEncryption> encryptionSelector, Identity identity, Func <AuthenticationScheme[], Authentication, Authentication> authenticator,
                                                                 string instance, CancellationToken cancellationToken)
        {
            if (channel == null)
            {
                throw new ArgumentNullException("channel");
            }

            if (authenticator == null)
            {
                throw new ArgumentNullException("authenticator");
            }

            var receivedSession = await channel.StartNewSessionAsync(cancellationToken).ConfigureAwait(false);

            // Session negotiation
            if (receivedSession.State == SessionState.Negotiating)
            {
                if (compressionSelector == null)
                {
                    throw new ArgumentNullException("compressionSelector");
                }

                if (encryptionSelector == null)
                {
                    throw new ArgumentNullException("encryptionSelector");
                }

                // Select options
                receivedSession = await channel.NegotiateSessionAsync(
                    compressionSelector(receivedSession.CompressionOptions),
                    encryptionSelector(receivedSession.EncryptionOptions),
                    cancellationToken).ConfigureAwait(false);

                if (receivedSession.State == SessionState.Negotiating)
                {
                    // Configure transport
                    if (receivedSession.Compression != channel.Transport.Compression)
                    {
                        await channel.Transport.SetCompressionAsync(receivedSession.Compression.Value, cancellationToken).ConfigureAwait(false);
                    }

                    if (receivedSession.Encryption != channel.Transport.Encryption)
                    {
                        await channel.Transport.SetEncryptionAsync(receivedSession.Encryption.Value, cancellationToken).ConfigureAwait(false);
                    }
                }

                // Await for authentication options
                receivedSession = await channel.ReceiveAuthenticatingSessionAsync(cancellationToken).ConfigureAwait(false);
            }

            // Session authentication
            if (receivedSession.State == SessionState.Authenticating)
            {
                do
                {
                    Authentication roundtrip = null;

                    receivedSession = await channel.AuthenticateSessionAsync(
                        identity,
                        authenticator(receivedSession.SchemeOptions, roundtrip),
                        instance,
                        cancellationToken).ConfigureAwait(false);

                    roundtrip = receivedSession.Authentication;
                } while (receivedSession.State == SessionState.Authenticating);
            }

            return(receivedSession);
        }