/// <summary> /// Attempts to authenticate the supplied stream. /// </summary> /// <param name="stream">The stream to authenticate</param> /// <param name="useSsl"></param> /// <param name="secureStream">the secure stream if the authentication was successful.</param> /// <returns>true if successful</returns> public bool TryAuthenticate(Stream stream, bool useSsl, out Stream secureStream) { secureStream = null; SslStream ssl = null; Stream stream2; byte[] certSignatures; if (useSsl) { if (!TryConnectSsl(stream, out ssl)) { return(false); } stream2 = ssl; certSignatures = SecureStream.ComputeCertificateChallenge(false, ssl); } else { stream2 = stream; certSignatures = new byte[0]; } try { try { if (TryResumeSession(ref secureStream, stream2, certSignatures)) { return(true); } } catch (FileNotFoundException ex) { Log.Publish(MessageLevel.Info, "Bouncy Castle dll is missing! Oh No!", null, null, ex); } if (InternalTryAuthenticate(stream2, certSignatures)) { if (stream2.ReadBoolean()) { m_resumeTicket = stream2.ReadBytes(stream2.ReadNextByte()); m_sessionSecret = stream2.ReadBytes(stream2.ReadNextByte()); } secureStream = stream2; return(true); } if (ssl != null) { ssl.Dispose(); } return(false); } catch (Exception ex) { Log.Publish(MessageLevel.Info, "Authentication Failed", null, null, ex); if (ssl != null) { ssl.Dispose(); } return(false); } }
/// <summary> /// Attempts to authenticate the stream /// </summary> /// <param name="stream">the base stream to authenticate</param> /// <param name="useSsl">gets if ssl should be used</param> /// <param name="secureStream">the secure stream that is valid if the function returns true.</param> /// <param name="token">the user's token assocated with what user created the stream</param> /// <returns>true if successful, false otherwise</returns> public bool TryAuthenticateAsServer(Stream stream, bool useSsl, out Stream secureStream, out T token) { token = default(T); secureStream = null; SslStream ssl = null; try { Stream stream2; byte[] certSignatures; if (useSsl) { if (!TryConnectSsl(stream, out ssl)) { return(false); } stream2 = ssl; certSignatures = SecureStream.ComputeCertificateChallenge(true, ssl); } else { certSignatures = new byte[0]; stream2 = stream; } TryAgain: State state = m_state; AuthenticationMode authenticationMode = (AuthenticationMode)stream2.ReadNextByte(); Guid userToken; switch (authenticationMode) { case AuthenticationMode.None: if (!state.ContainsDefaultCredentials) { stream2.Write(false); if (ssl != null) { ssl.Dispose(); } return(false); } stream2.Write(true); userToken = state.DefaultUserToken; break; //case AuthenticationMode.Srp: //SRP // m_srp.AuthenticateAsServer(ssl, certSignatures); // break; case AuthenticationMode.Integrated: //Integrated if (!m_integrated.TryAuthenticateAsServer(stream2, out userToken, certSignatures)) { if (ssl != null) { ssl.Dispose(); } return(false); } break; //case AuthenticationMode.Scram: //Scram // m_scram.AuthenticateAsServer(ssl, certSignatures); // break; //case AuthenticationMode.Certificate: //Certificate // m_cert.AuthenticateAsServer(ssl); // break; case AuthenticationMode.ResumeSession: if (TryResumeSession(stream2, certSignatures, out userToken)) { lock (m_syncRoot) { m_userTokens.TryGetValue(userToken, out token); } secureStream = stream2; return(true); } goto TryAgain; default: Log.Publish(MessageLevel.Info, "Invalid Authentication Method", authenticationMode.ToString()); return(false); } stream2.Write(false); stream2.Flush(); //ToDo: Support resume tickets //byte[] ticket; //byte[] secret; //CreateResumeTicket(userToken, out ticket, out secret); //stream2.WriteByte((byte)ticket.Length); //stream2.Write(ticket); //stream2.WriteByte((byte)secret.Length); //stream2.Write(secret); //stream2.Flush(); lock (m_syncRoot) { m_userTokens.TryGetValue(userToken, out token); } secureStream = stream2; return(true); } catch (Exception ex) { Log.Publish(MessageLevel.Info, "Authentication Failed: Unknown Exception", null, null, ex); if (ssl != null) { ssl.Dispose(); } return(false); } }