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 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; }
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 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; }