Example #1
0
        public AuthTransaction(PopConnection connection, SaslClientMechanism authMechanism)
            : base(connection)
        {
            if (authMechanism == null)
            throw new ArgumentNullException("authMechanism");

              this.saslMechanism = authMechanism;
              this.requiredCapability = null; // do not check capability
              this.disposeMechanism = false;
        }
        public AuthenticateTransaction(ImapConnection connection, SaslClientMechanism authMechanism, bool sendInitialResponse)
            : base(connection)
        {
            if (authMechanism == null)
            throw new ArgumentNullException("authMechanism");

              this.saslMechanism = authMechanism;
              this.sendInitialResponse = sendInitialResponse;
              this.disposeMechanism = false;
        }
Example #3
0
        public static PopSession CreateSession(IPopSessionProfile profile,
                                           SaslClientMechanism authMechanismSpecified,
                                           UpgradeConnectionStreamCallback createSslStreamCallback)
        {
            PopSession session;

              var result = CreateSession(profile, authMechanismSpecified, createSslStreamCallback, out session);

              if (result.Succeeded)
            return session;
              else
            throw new PopAuthenticationException(result);
        }
Example #4
0
        public void Connect(SaslClientMechanism authMechanism)
        {
            if (authMechanism == null)
            throw new ArgumentNullException("authMechanism");

              ThrowIfAlreadyConnectedOrAsyncConnectRunning();

              SetSession(ConnectCore(new ConnectParams(profile,
                                               authMechanism,
                                               null)));
        }
Example #5
0
 public IAsyncResult BeginConnect(SaslClientMechanism authMechanism,
                              UpgradeConnectionStreamCallback createSslStreamCallback,
                              AsyncCallback asyncCallback,
                              object asyncState)
 {
     return BeginConnect(new ConnectParams(profile,
                                     authMechanism,
                                     createSslStreamCallback),
                   asyncCallback,
                   asyncState);
 }
Example #6
0
 public IAsyncResult BeginConnect(SaslClientMechanism authMechanism,
                              AsyncCallback asyncCallback,
                              object asyncState)
 {
     return BeginConnect(authMechanism, null, asyncCallback, asyncState);
 }
Example #7
0
 public IAsyncResult BeginConnect(SaslClientMechanism authMechanism,
                              UpgradeConnectionStreamCallback createSslStreamCallback)
 {
     return BeginConnect(authMechanism, createSslStreamCallback, null, null);
 }
Example #8
0
 public IAsyncResult BeginConnect(SaslClientMechanism authMechanism)
 {
     return BeginConnect(authMechanism, null, null, null);
 }
 /// <summary>sends AUTHENTICATE command</summary>
 /// <remarks>valid in non-authenticated state</remarks>
 public ImapCommandResult Authenticate(SaslClientMechanism specificAuthenticationMechanism)
 {
     return Authenticate(specificAuthenticationMechanism, false);
 }
Example #10
0
        protected override ProcessTransactionDelegate Reset()
        {
            if (saslMechanism == null) {
            /*
             * create mechanism
             */
            #if DEBUG
            if (!RequestArguments.ContainsKey("mechanism"))
              return ProcessArgumentNotSetted;
            #endif
            try {
              saslMechanism = SaslClientMechanism.Create(RequestArguments["mechanism"]);
              saslMechanism.Credential = credential;

              // The service name specified by this protocol's profile of SASL
              // is "pop".
              saslMechanism.ServiceName = "pop";

              if (saslMechanism is NTLMMechanism)
            (saslMechanism as NTLMMechanism).TargetHost = Connection.Host;
            }
            catch (SaslMechanismNotSupportedException) {
              return ProcessUnsupported;
            }
              }
              else {
            /*
             * use supplied mechanism
             */
            saslMechanism.Initialize();

            RequestArguments["mechanism"] = saslMechanism.Name;
              }

              /*
               * The optional initial-response argument to the AUTH command is
               * used to save a round trip when using authentication mechanisms
               * that support an initial client response.
               */
              if (saslMechanism.ClientFirst) {
            byte[] initialClientResponse;

            if (saslMechanism.GetInitialResponse(out initialClientResponse) == SaslExchangeStatus.Failed || initialClientResponse == null)
              return ProcessInitialResponseError;

            RequestArguments["initial-response"] = Base64.GetEncodedString(initialClientResponse);
              }

              return ProcessAuth;
        }
        private void AuthSpecificMechanism(SaslClientMechanism authMechanism)
        {
            using (var session = Connect(null)) {
            session.HandlesIncapableAsException = true;

            if (!authMechanism.ClientFirst)
              server.EnqueueResponse("+ \r\n");
            server.EnqueueResponse("+ \r\n");
            server.EnqueueResponse("+OK\r\n");

            Assert.IsTrue((bool)session.Auth(authMechanism));

            if (authMechanism.ClientFirst) {
              StringAssert.AreEqualIgnoringCase("AUTH X-PSEUDO-MECHANISM c3RlcDA=\r\n",
                                            server.DequeueRequest());
              StringAssert.AreEqualIgnoringCase("c3RlcDE=\r\n",
                                            server.DequeueRequest());
            }
            else {
              StringAssert.AreEqualIgnoringCase("AUTH X-PSEUDO-MECHANISM\r\n",
                                            server.DequeueRequest());
              StringAssert.AreEqualIgnoringCase("c3RlcDA=\r\n",
                                            server.DequeueRequest());
              StringAssert.AreEqualIgnoringCase("c3RlcDE=\r\n",
                                            server.DequeueRequest());
            }

            // not disposed
            Assert.AreEqual(SaslExchangeStatus.Succeeded,
                        authMechanism.ExchangeStatus);

            Assert.AreEqual(new Uri(string.Format("pop://{0};AUTH=X-PSEUDO-MECHANISM@{1}:{2}/",
                                              (authMechanism.Credential == null) ? null : authMechanism.Credential.UserName,
                                              host,
                                              port)),
                        session.Authority);
              }
        }
        /// <summary>sends AUTH command</summary>
        /// <remarks>valid in authorization state</remarks>
        public PopCommandResult Auth(SaslClientMechanism specificAuthenticationMechanism)
        {
            if (specificAuthenticationMechanism == null)
            throw new ArgumentNullException("specificAuthenticationMechanism");

              var ret = RejectNonConnectedOrGetAuthenticatedResult();

              if (ret != null)
            return ret;

              using (var t = new AuthTransaction(connection, specificAuthenticationMechanism)) {
            if (ProcessTransaction(t).Succeeded) {
              var authMechanism = PopAuthenticationMechanism.GetKnownOrCreate(specificAuthenticationMechanism.Name);
              var username = specificAuthenticationMechanism.Credential == null
            ? null
            : specificAuthenticationMechanism.Credential.UserName;

              UpdateAuthority(username, authMechanism);
              TransitStateTo(PopSessionState.Transaction);
            }

            return t.Result;
              }
        }
Example #13
0
        public static PopCommandResult CreateSession(IPopSessionProfile profile,
                                                 SaslClientMechanism authMechanismSpecified,
                                                 UpgradeConnectionStreamCallback createSslStreamCallback,
                                                 out PopSession session)
        {
            if (profile == null)
            throw new ArgumentNullException("profile");

              var authority = profile.Authority;
              var securePort = string.Equals(authority.Scheme, PopUri.UriSchemePops, StringComparison.OrdinalIgnoreCase);

              if (securePort && createSslStreamCallback == null)
            throw new ArgumentNullException("createSslStreamCallback");

              PopCommandResult result;
              session = null;

              session = new PopSession(authority.Host,
                               authority.Port,
                               profile.Timeout,
                               securePort
                                 ? createSslStreamCallback
                                 : null);

              session.HandlesIncapableAsException = false;
              session.TransactionTimeout  = profile.Timeout;
              session.SendTimeout         = profile.SendTimeout;
              session.ReceiveTimeout      = profile.ReceiveTimeout;

              // try querying server capability (ignore error; POP3 Extension Mechanism might not supported)
              session.Capa();

              if (profile.UseTlsIfAvailable && session.ServerCapabilities.IsCapable(PopCapability.Stls) && !session.IsSecureConnection) {
            var r = session.Stls(createSslStreamCallback, false);

            if (r.Failed)
              throw new PopUpgradeConnectionException(r.ResultText);

            // try re-querying server capability (ignore error; POP3 Extension Mechanism might not supported)
            session.Capa();
              }

              if (authMechanismSpecified == null)
            result = Authenticate(session, profile);
              else
            result = session.Auth(authMechanismSpecified);

              if (result == null) {
            throw new PopAuthenticationException("appropriate authentication mechanism not found");
              }
              else if (result.Failed) {
            try {
              try {
            session.Disconnect(false);
              }
              catch (PopConnectionException) {
            // ignore
              }
            }
            finally {
              session = null;
            }
              }

              return result;
        }
Example #14
0
        public static ImapCommandResult CreateSession(IImapSessionProfile profile,
                                                  SaslClientMechanism authMechanismSpecified,
                                                  UpgradeConnectionStreamCallback createSslStreamCallback,
                                                  out ImapSession session)
        {
            if (profile == null)
            throw new ArgumentNullException("profile");

              var authority = profile.Authority;
              var securePort = string.Equals(authority.Scheme, ImapUri.UriSchemeImaps, StringComparison.OrdinalIgnoreCase);

              if (securePort && createSslStreamCallback == null)
            throw new ArgumentNullException("createSslStreamCallback");

              ImapCommandResult result;
              session = null;

              session = new ImapSession(authority.Host,
                                authority.Port,
                                true,
                                profile.Timeout,
                                securePort
                                  ? createSslStreamCallback
                                  : null);

              session.HandlesIncapableAsException = false;
              session.HandlesReferralAsException = false;
              session.TransactionTimeout  = profile.Timeout;
              session.SendTimeout         = profile.SendTimeout;
              session.ReceiveTimeout      = profile.ReceiveTimeout;

              if (session.ServerCapabilities.Count == 0)
            // try querying server capability (ignore error)
            session.Capability();

              if (!session.ServerCapabilities.Has(ImapCapability.Imap4Rev1))
            throw new ImapIncapableException(ImapCapability.Imap4Rev1);

              if (profile.UseTlsIfAvailable && session.ServerCapabilities.Has(ImapCapability.StartTls) && !session.IsSecureConnection) {
            var r = session.StartTls(createSslStreamCallback, true);

            if (r.Failed)
              throw new ImapSecureConnectionException(r.ResultText);
            else if (!session.ServerCapabilities.Has(ImapCapability.Imap4Rev1))
              throw new ImapIncapableException(ImapCapability.Imap4Rev1);
              }

              if (profile.UseDeflateIfAvailable && session.ServerCapabilities.Has(ImapCapability.CompressDeflate)) {
            var r = session.Compress(ImapCompressionMechanism.Deflate);

            if (r.Failed)
              throw new WebException(r.ResultText, null, WebExceptionStatus.RequestCanceled, null);
              }

              if (authMechanismSpecified == null)
            result = Authenticate(session, profile);
              else
            result = session.Authenticate(authMechanismSpecified);

              if (result == null) {
            throw new ImapAuthenticationException("appropriate authentication mechanism not found");
              }
              else if (result.Failed) {
            try {
              try {
            session.Disconnect(false);
              }
              catch (ImapConnectionException) {
            // ignore
              }
            }
            finally {
              session = null;
            }
              }

              return result;
        }
        private void AuthenticateSpecificMechanism(bool saslIRCapable, SaslClientMechanism authMechanism)
        {
            if (saslIRCapable)
            server.EnqueueResponse("* OK [CAPABILITY IMAP4rev1 SASL-IR] ImapSimulatedServer ready\r\n");
              else
            server.EnqueueResponse("* OK [CAPABILITY IMAP4rev1] ImapSimulatedServer ready\r\n");

              using (var session = new ImapSession(host, port)) {
            session.HandlesIncapableAsException = true;

            if (!saslIRCapable)
              server.EnqueueResponse("+ \r\n");
            server.EnqueueResponse("+ \r\n");
            server.EnqueueResponse("0000 OK done\r\n");

            Assert.IsTrue((bool)session.Authenticate(authMechanism));

            if (saslIRCapable) {
              Assert.AreEqual("0000 AUTHENTICATE X-PSEUDO-MECHANISM c3RlcDA=\r\n",
                          server.DequeueRequest());
              Assert.AreEqual("c3RlcDE=\r\n",
                          server.DequeueRequest());
            }
            else {
              Assert.AreEqual("0000 AUTHENTICATE X-PSEUDO-MECHANISM\r\n",
                          server.DequeueRequest());
              Assert.AreEqual("c3RlcDA=\r\n",
                          server.DequeueRequest());
              Assert.AreEqual("c3RlcDE=\r\n",
                          server.DequeueRequest());
            }

            // not disposed
            Assert.AreEqual(SaslExchangeStatus.Succeeded,
                        authMechanism.ExchangeStatus);

            Assert.AreEqual(new Uri(string.Format("imap://{0};AUTH=X-PSEUDO-MECHANISM@{1}:{2}/",
                                              (authMechanism.Credential == null) ? null : authMechanism.Credential.UserName,
                                              host,
                                              port)),
                        session.Authority);
              }
        }
Example #16
0
        public void Connect(SaslClientMechanism authMechanism, UpgradeConnectionStreamCallback createSslStreamCallback)
        {
            if (authMechanism == null)
            throw new ArgumentNullException("authMechanism");

              ThrowIfAlreadyConnectedOrAsyncConnectRunning();

              SetSession(ConnectCore(new ConnectParams(profile,
                                               authMechanism,
                                               createSslStreamCallback)));
        }
Example #17
0
 public ConnectParams(ImapClientProfile profile,
                SaslClientMechanism authMechanism,
                UpgradeConnectionStreamCallback createSslStreamCallback)
 {
     Profile = profile.Clone();
     AuthMechanism = authMechanism;
     CreateSslStreamCallback = createSslStreamCallback;
 }
Example #18
0
        public override void Dispose()
        {
            if (saslMechanism != null) {
            if (disposeMechanism)
              saslMechanism.Dispose();

            saslMechanism = null;
              }

              base.Dispose();
        }
        /// <summary>sends AUTHENTICATE command</summary>
        /// <remarks>valid in non-authenticated state</remarks>
        public ImapCommandResult Authenticate(SaslClientMechanism specificAuthenticationMechanism,
                                          bool reissueCapability)
        {
            var ret = RejectNonConnectedOrGetAuthenticatedResult();

              if (ret != null)
            return ret;

              if (specificAuthenticationMechanism == null)
            throw new ArgumentNullException("specificAuthenticationMechanism");

              using (var t = new AuthenticateTransaction(connection, specificAuthenticationMechanism, serverCapabilities.Has(ImapCapability.SaslIR))) {
            var authMechanism = ImapAuthenticationMechanism.GetKnownOrCreate(specificAuthenticationMechanism.Name);
            var username = specificAuthenticationMechanism.Credential == null
              ? null
              : specificAuthenticationMechanism.Credential.UserName;

            return AuthenticateInternal(t, username, authMechanism, reissueCapability);
              }
        }
        protected override ProcessTransactionDelegate Reset()
        {
            if (saslMechanism == null) {
            /*
             * create mechanism
             */
            #if DEBUG
            if (!RequestArguments.ContainsKey("authentication mechanism name"))
              return ProcessArgumentNotSetted;
            #endif
            try {
              saslMechanism = SaslClientMechanism.Create((string)RequestArguments["authentication mechanism name"]);
              saslMechanism.Credential = credential;

              // The service name specified by this protocol's profile of [SASL] is
              // "imap".
              saslMechanism.ServiceName = "imap";

              if (saslMechanism is NTLMMechanism)
            (saslMechanism as NTLMMechanism).TargetHost = Connection.Host;
            }
            catch (SaslMechanismNotSupportedException) {
              return ProcessUnsupported;
            }
              }
              else {
            /*
             * use supplied mechanism
             */
            saslMechanism.Initialize();

            RequestArguments["authentication mechanism name"] = saslMechanism.Name;
              }

              /*
               * http://tools.ietf.org/html/rfc4959
               * RFC 4959 - IMAP Extension for Simple Authentication and Security Layer (SASL) Initial Client Response
               * 3. IMAP Changes to the IMAP AUTHENTICATE Command
               *    Note: support and use of the initial client response is optional for
               *    both clients and servers.  Servers that implement this extension MUST
               *    support clients that omit the initial client response, and clients
               *    that implement this extension MUST NOT send an initial client
               *    response to servers that do not advertise the SASL-IR capability.
               */
              if (sendInitialResponse && saslMechanism.ClientFirst) {
            byte[] initialClientResponse;

            if (saslMechanism.GetInitialResponse(out initialClientResponse) == SaslExchangeStatus.Failed || initialClientResponse == null)
              return ProcessInitialResponseError;

            /*
             * http://tools.ietf.org/html/rfc4959
             * RFC 4959 - IMAP Extension for Simple Authentication and Security Layer (SASL) Initial Client Response
             * 3. IMAP Changes to the IMAP AUTHENTICATE Command
             *    This extension adds an optional second argument to the AUTHENTICATE
             *    command that is defined in Section 6.2.2 of [RFC3501].  If this
             *    second argument is present, it represents the contents of the
             *    "initial client response" defined in Section 5.1 of [RFC4422].
             */
            RequestArguments["initial client response"] = Base64.GetEncodedString(initialClientResponse);
              }

              return ProcessAuthenticate;
        }