public void TestApopCredentialNotFound() { server.EnqueueResponse("+OK POP3 server ready <*****@*****.**>\r\n"); using (var session = new PopSession(host, port)) { Assert.IsTrue(session.ApopAvailable); Assert.IsFalse((bool)session.Apop(new NullCredential())); Assert.IsFalse((bool)session.Apop(new NullCredential(),"user")); } }
protected PopSession Connect(string timestamp) { if (string.IsNullOrEmpty(timestamp)) server.EnqueueResponse("+OK POP3 server ready\r\n"); else server.EnqueueResponse(string.Format("+OK POP3 server ready {0}\r\n", timestamp)); var session = new PopSession(host, port); Assert.AreEqual(PopSessionState.Authorization, session.State); Assert.AreEqual(authority, session.Authority); return session; }
public void TestApop() { server.EnqueueResponse("+OK POP3 server ready <*****@*****.**>\r\n"); using (var session = new PopSession(host, port)) { Assert.IsTrue(session.ApopAvailable); server.EnqueueResponse("+OK maildrop has 1 message (369 octets)\r\n"); Assert.IsTrue((bool)session.Apop(new NetworkCredential("mrose", "tanstaaf"))); StringAssert.AreEqualIgnoringCase("APOP mrose c4c9334bac560ecc979e58001b3e22fb\r\n", server.DequeueRequest()); Assert.AreEqual(PopSessionState.Transaction, session.State); Assert.AreEqual(new Uri(string.Format("pop://mrose;AUTH=+APOP@{0}:{1}/", host, port)), session.Authority); } }
public void TestApopSelectAppropriateCredentialNotFound() { server.EnqueueResponse("+OK POP3 server ready <*****@*****.**>\r\n"); using (var session = new PopSession(host, port)) { var credentials = new CredentialCache(); credentials.Add("pop.example.net", 110, "LOGIN", new NetworkCredential("user", "pass1")); credentials.Add(server.Host, server.Port, "LOGIN", new NetworkCredential("user", "pass2")); credentials.Add(server.Host, server.Port, "+APOP", new NetworkCredential("user", "pass3")); credentials.Add(server.Host, server.Port, string.Empty, new NetworkCredential("user", "pass4")); var result = session.Apop(credentials, "xxxx"); Assert.IsFalse((bool)result); Assert.AreEqual(PopCommandResultCode.RequestError, result.Code); Assert.AreEqual(PopSessionState.Authorization, session.State); } }
public void TestConnectSocketError() { try { using (var session = new PopSession("pop.invalid", 110)) { Assert.Fail("PopConnectionException not thrown"); } } catch (PopConnectionException ex) { var socketException = ex.InnerException as System.Net.Sockets.SocketException; Assert.IsNotNull(socketException); } }
private PopSession GetSession(out PopCommandResult noopResult) { noopResult = null; var s = sessionManager.GetExistSession(requestUri); if (s != null) { if (s.IsDisposed) { s = null; } else if (s.IsTransactionProceeding) { throw new WebException("another transaction proceeding", WebExceptionStatus.Pending); } else { try { // check connected if (s.State != PopSessionState.NotConnected) noopResult = s.NoOp(); } catch { // ignore exception } // disconnected if (s.IsDisposed || s.State == PopSessionState.NotConnected) { sessionManager.UnregisterSession(requestUri); s = null; noopResult = null; } } } if (s == null) { var session = PopSessionManager.CreateSession(this); if (keepAlive) sessionManager.RegisterSession(requestUri, session); s = session; } this.session = s; return s; }
private static PopCommandResult AuthenticateAsAnonymous(PopSession session, string username, bool canFallback) { PopCommandResult result = null; if (string.IsNullOrEmpty(username)) username = "******"; if (session.ServerCapabilities.IsCapable(PopAuthenticationMechanism.Anonymous)) // try AUTH ANONYUMOUS result = session.Auth(new NetworkCredential(username, string.Empty), null, PopAuthenticationMechanism.Anonymous); if (result == null || (result.Failed && canFallback)) // try anonymous LOGIN result = session.Login(new NetworkCredential("anonymous", username), null); return result; }
private void SetSession(PopSession session) { this.session = session; lock (((System.Collections.ICollection)messages).SyncRoot) { messages.Clear(); } }
private void CloseSession() { sessionManager.UnregisterSession(requestUri); try { session.Disconnect(true); } catch { // ignore exceptions } session = null; }
private void ApopSelectAppropriateCredential(bool specifyUsername) { server.EnqueueResponse("+OK POP3 server ready <timestamp>\r\n"); using (var session = new PopSession(host, port)) { server.EnqueueResponse("+OK done\r\n"); var credentials = new CredentialCache(); credentials.Add("pop.example.net", 110, "LOGIN", new NetworkCredential("user", "pass1")); credentials.Add(server.Host, server.Port, "LOGIN", new NetworkCredential("user", "pass2")); credentials.Add(server.Host, server.Port, "+APOP", new NetworkCredential("user", "pass3")); credentials.Add(server.Host, server.Port, string.Empty, new NetworkCredential("user", "pass4")); server.EnqueueResponse("+OK done\r\n"); if (specifyUsername) Assert.IsTrue((bool)session.Apop(credentials, "user")); else Assert.IsTrue((bool)session.Apop(credentials)); StringAssert.AreEqualIgnoringCase("APOP user 80455cef894e28a3589d57c72e788afd\r\n", server.DequeueRequest()); Assert.AreEqual(PopSessionState.Transaction, session.State); Assert.AreEqual(new Uri(string.Format("pop://user;+APOP@{0}:{1}/", host, port)), session.Authority); } }
private static PopSession ConnectCore(ConnectParams @params) { PopSession session = null; try { session = PopSessionCreator.CreateSession(@params.Profile, @params.AuthMechanism, @params.CreateSslStreamCallback ?? PopConnection.CreateSslStream); } finally { @params.Profile.SetCredentials(null); } return session; }
public void TestConnectInvalidResponse() { server.EnqueueResponse("* OK pseudo IMAP server ready\r\n"); try { using (var session = new PopSession(host, port)) { Assert.Fail("PopConnectionException not thrown"); } } catch (PopConnectionException ex) { Assert.IsNull(ex.InnerException); StringAssert.Contains("unexpected response", ex.Message); } }
private static PopCommandResult AuthenticateWithAppropriateMechanism(PopSession session, bool allowInsecureMechanism, ICredentialsByHost credentials, string username, IEnumerable<string> usingSaslMechanisms) { PopCommandResult result = null; foreach (var mechanism in usingSaslMechanisms) { if (!allowInsecureMechanism && SaslClientMechanism.IsMechanismPlainText(mechanism)) // disallow plain text mechanism continue; if (string.Equals(mechanism, SaslMechanisms.Anonymous, StringComparison.OrdinalIgnoreCase)) // disallow 'ANONYMOUS' mechanism continue; var authMechanism = PopAuthenticationMechanism.GetKnownOrCreate(mechanism); if (session.ServerCapabilities.IsCapable(authMechanism)) { result = session.Auth(credentials, username, authMechanism); if (result.Succeeded) break; } } if ((result == null || result.Failed) && allowInsecureMechanism) { if (session.ApopAvailable) result = session.Apop(credentials, username); } if ((result == null || result.Failed) && allowInsecureMechanism) result = session.Login(credentials, username); return result; }
public void TestConnectErr() { server.EnqueueResponse("-ERR try again\r\n"); try { using (var session = new PopSession(host, port)) { Assert.Fail("PopConnectionException not thrown"); } } catch (PopConnectionException ex) { Assert.IsNull(ex.InnerException); StringAssert.Contains("try again", ex.Message); } }
public void TestConnect() { server.EnqueueResponse("+OK PopPseudoServer ready\r\n"); using (var session = new PopSession(host, port)) { Assert.IsFalse(session.ApopAvailable); Assert.IsTrue(string.IsNullOrEmpty(session.Timestamp)); Assert.AreEqual(PopSessionState.Authorization, session.State); Assert.AreEqual(new Uri(string.Format("pop://{0}:{1}/", host, port)), session.Authority); Assert.AreEqual(0, session.ServerCapabilities.Count); } }
public static void Log(PopSession session, string format, params object[] args) { Info("CID:{0} {1}", session.Id.HasValue ? session.Id.Value.ToString() : "-", args == null ? format : string.Format(format, args)); }
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; }
private static PopCommandResult AuthenticateWithSuppliedMechanism(PopSession session, ICredentialsByHost credentials, string username, PopAuthenticationMechanism authMechanism) { /* * http://tools.ietf.org/html/rfc2384 * 4. POP User Name and Authentication Mechanism * * An authentication mechanism can be expressed by adding ";AUTH=<enc- * auth-type>" to the end of the user name. If the authentication * mechanism name is not preceded by a "+", it is a SASL POP [SASL] * mechanism. If it is preceded by a "+", it is either "APOP" or an * extension mechanism. * * When an <enc-auth-type> is specified, the client SHOULD request * appropriate credentials from that mechanism and use the "AUTH", * "APOP", or extension command instead of the "USER" command. If no * user name is specified, one SHOULD be obtained from the mechanism or * requested from the user as appropriate. * * * If an <enc-auth-type> other than ";AUTH=*" is specified, the client * SHOULD NOT use a different mechanism without explicit user * permission. */ return session.Auth(credentials, username, authMechanism); }
private void ApopCredentialPropertyNull(ICredentialsByHost credential) { server.EnqueueResponse("+OK POP3 server ready <*****@*****.**>\r\n"); using (var session = new PopSession(host, port)) { Assert.IsFalse((bool)session.Apop(credential)); } }
public void TestConnectSsl() { server.EnqueueResponse("+OK PopPseudoServer ready\r\n"); var streamUpgraded = false; using (var session = new PopSession(host, port, delegate(ConnectionBase connection, Stream baseStream) { streamUpgraded = true; return baseStream; // TODO: return SslStream })) { Assert.IsFalse(session.ApopAvailable); Assert.IsTrue(string.IsNullOrEmpty(session.Timestamp)); Assert.AreEqual(PopSessionState.Authorization, session.State); Assert.AreEqual(new Uri(string.Format("pops://{0}:{1}/", host, port)), session.Authority); Assert.AreEqual(0, session.ServerCapabilities.Count); Assert.IsTrue(streamUpgraded, "stream upgraded"); Assert.IsTrue(session.IsSecureConnection); } }
public void TestApopNoWithInUseResponseCode() { server.EnqueueResponse("+OK POP3 server ready <*****@*****.**>\r\n"); using (var session = new PopSession(host, port)) { Assert.IsTrue(session.ApopAvailable); server.EnqueueResponse("-ERR [IN-USE] Do you have another POP session running?\r\n"); var result = session.Apop(new NetworkCredential("mrose", "tanstaaf")); Assert.IsTrue(result.Failed); Assert.IsNotNull(result.GetResponseCode(PopResponseCode.InUse)); StringAssert.AreEqualIgnoringCase("APOP mrose c4c9334bac560ecc979e58001b3e22fb\r\n", server.DequeueRequest()); Assert.AreEqual(PopSessionState.Authorization, session.State); Assert.AreEqual(new Uri(string.Format("pop://{0}:{1}/", host, port)), session.Authority); } }
public void TestConnectSslExceptionWhileUpgrading() { server.EnqueueResponse("+OK PopPseudoServer ready\r\n"); try { using (var session = new PopSession(host, port, delegate(ConnectionBase connection, Stream baseStream) { throw new System.Security.Authentication.AuthenticationException(); })) { Assert.Fail("connected"); } } catch (PopUpgradeConnectionException ex) { Assert.IsNotNull(ex.InnerException); Assert.IsInstanceOfType(typeof(System.Security.Authentication.AuthenticationException), ex.InnerException); } }
private void Disconnect(bool logout, bool checkAsyncConnectRunning) { if (checkAsyncConnectRunning) ThrowIfAsyncConnectRunning(); if (session != null) session.Disconnect(logout); session = null; lock (((System.Collections.ICollection)messages).SyncRoot) { foreach (var message in messages.Values) { message.Client = null; } messages.Clear(); } }
public void TestConnectTransactionTimeout() { server.Stop(); try { using (var session = new PopSession(host, port, 500)) { Assert.Fail("PopConnectionException not thrown"); } } catch (PopConnectionException ex) { var timeoutException = ex.InnerException as TimeoutException; Assert.IsNotNull(timeoutException); } }
private void Callback(IAsyncResult asyncResult) { PopSession ret = null; lock (asyncResultLockObject) { try { ret = ((ConnectProc)innerAsyncResult.AsyncDelegate).EndInvoke(innerAsyncResult); if (!OwnerDisposed) createdSession = ret; } catch (Exception ex) { exception = ex; } } if (asyncCallback != null) asyncCallback(this); if (OwnerDisposed && ret != null) ret.Disconnect(false); // ignore exceptions }
public void TestDisconnect() { server.EnqueueResponse("+OK PopPseudoServer ready\r\n"); var session = new PopSession(host, port); session.Disconnect(false); Assert.IsTrue(session.IsDisposed); try { session.NoOp(); Assert.Fail("ObjectDisposedException not thrown"); } catch (ObjectDisposedException) { } }
private PopWebResponse GetResponseProc() { try { PopCommandResult noopResult; GetSession(out noopResult); PopWebResponse response; try { try { if (string.Equals(Method, PopWebRequestMethods.NoOp, StringComparison.OrdinalIgnoreCase)) { if (noopResult == null) response = GetNoOpResponse(); else response = new PopWebResponse(noopResult); } else { response = InternalGetResponse(); } } catch (TimeoutException ex) { throw new WebException("timed out", ex, WebExceptionStatus.Timeout, null); } catch (PopException ex) { if (ex is PopProtocolViolationException) throw new ProtocolViolationException(ex.Message); else if (ex is PopIncapableException) throw new ProtocolViolationException(ex.Message); else throw new WebException("unexpected error", ex, WebExceptionStatus.UnknownError, null); } response.SetSessionInfo(session); } finally { if (!KeepAlive) CloseSession(); } if (response.ResponseUri == null) response.SetResponseUri(requestUri); if (response.Result.Succeeded) // succeeded return response; if (expectedErrorResponseCodes != null && response.ResponseCode != null) { foreach (var code in expectedErrorResponseCodes) { if (response.ResponseCode == code) // expected error return response; } } // unexpected error throw new WebException(response.ResponseDescription, null, WebExceptionStatus.ProtocolError, response); } finally { session = null; } }
public void TestGreetingWithTimestamp() { server.EnqueueResponse("+OK POP3 server ready <*****@*****.**>\r\n"); using (var session = new PopSession(host, port)) { Assert.IsTrue(session.ApopAvailable); Assert.AreEqual("<*****@*****.**>", session.Timestamp); Assert.AreEqual(PopSessionState.Authorization, session.State); Assert.AreEqual(new Uri(string.Format("pop://{0}:{1}/", host, port)), session.Authority); Assert.AreEqual(0, session.ServerCapabilities.Count); } }
internal void SetSessionInfo(PopSession session) { ServerCapabilities = new PopCapabilityList(true, session.ServerCapabilities); }
private static PopCommandResult Authenticate(PopSession session, IPopSessionProfile profile) { var authority = profile.Authority; var username = PopStyleUriParser.GetUser(authority); var authMechanism = PopStyleUriParser.GetAuthType(authority); /* * http://tools.ietf.org/html/rfc2384 * 4. POP User Name and Authentication Mechanism * * The string ";AUTH=*" indicates that the client SHOULD select an * appropriate authentication mechanism. It MAY use any mechanism * supported by the POP server. * * If a user name is included with no authentication mechanism, then * ";AUTH=*" is assumed. */ var canFallback = false; if (authMechanism == null) { if (string.IsNullOrEmpty(username)) { authMechanism = PopAuthenticationMechanism.Anonymous; canFallback = true; } else { authMechanism = PopAuthenticationMechanism.SelectAppropriate; } } if (authMechanism == PopAuthenticationMechanism.SelectAppropriate) { var allowInsecureMechanism = session.IsSecureConnection || profile.AllowInsecureLogin; return AuthenticateWithAppropriateMechanism(session, allowInsecureMechanism, profile.Credentials, username, GetUsingSaslMechanisms(profile.UsingSaslMechanisms ?? new string[0])); } else if (authMechanism == PopAuthenticationMechanism.Anonymous) { return AuthenticateAsAnonymous(session, username, canFallback); } else { return AuthenticateWithSuppliedMechanism(session, profile.Credentials, username, authMechanism); } }