/// <summary> /// Stores specified message header + specified lines of body to the specified stream. /// </summary> /// <param name="sequenceNumber">Message 1 based sequence number.</param> /// <param name="stream">Stream where to store data.</param> /// <param name="lineCount">Number of lines of message body to get.</param> internal void GetTopOfMessage(int sequenceNumber, Stream stream, int lineCount) { TcpStream.WriteLine("TOP " + sequenceNumber + " " + lineCount); // Read first line of reply, check if it's ok. string line = ReadLine(); if (line.StartsWith("+OK")) { SmartStream.ReadPeriodTerminatedAsyncOP readTermOP = new SmartStream.ReadPeriodTerminatedAsyncOP(stream, 999999999, SizeExceededAction.ThrowException); TcpStream.ReadPeriodTerminated(readTermOP, false); if (readTermOP.Error != null) { throw readTermOP.Error; } LogAddWrite(readTermOP.BytesStored, readTermOP.BytesStored + " bytes read."); } else { throw new POP3_ClientException(line); } }
/// <summary> /// Sends and logs specified line to connected host. /// </summary> /// <param name="line">Line to send.</param> protected void WriteLine(string line) { if (line == null) { throw new ArgumentNullException("line"); } int countWritten = TcpStream.WriteLine(line); LogAddWrite(countWritten, line); }
/// <summary> /// Authenticates user. /// </summary> /// <param name="userName">User login name.</param> /// <param name="password">Password.</param> /// <param name="tryApop"> If true and POP3 server supports APOP, then APOP is used, otherwise normal login used.</param> /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and this method is accessed.</exception> /// <exception cref="InvalidOperationException">Is raised when POP3 client is not connected or is already authenticated.</exception> /// <exception cref="POP3_ClientException">Is raised when POP3 server returns error.</exception> public void Authenticate(string userName, string password, bool tryApop) { if (IsDisposed) { throw new ObjectDisposedException(GetType().Name); } if (!IsConnected) { throw new InvalidOperationException("You must connect first."); } if (IsAuthenticated) { throw new InvalidOperationException("Session is already authenticated."); } // Supports APOP, use it. if (tryApop && m_ApopHashKey.Length > 0) { string hexHash = Core.ComputeMd5(m_ApopHashKey + password, true); int countWritten = TcpStream.WriteLine("APOP " + userName + " " + hexHash); LogAddWrite(countWritten, "APOP " + userName + " " + hexHash); string line = ReadLine(); if (line.StartsWith("+OK")) { m_pAuthdUserIdentity = new GenericIdentity(userName, "apop"); } else { if (AuthFailed != null) { AuthFailed.Invoke(line); } throw new POP3_ClientException(line); } } // Use normal LOGIN, don't support APOP. else { int countWritten = TcpStream.WriteLine("USER " + userName); LogAddWrite(countWritten, "USER " + userName); string line = ReadLine(); if (line.StartsWith("+OK")) { countWritten = TcpStream.WriteLine("PASS " + password); LogAddWrite(countWritten, "PASS <***REMOVED***>"); line = ReadLine(); if (line.StartsWith("+OK")) { m_pAuthdUserIdentity = new GenericIdentity(userName, "pop3-user/pass"); } else { if (AuthFailed != null) { AuthFailed.Invoke(line); } throw new POP3_ClientException(line); } } else { if (AuthFailed != null) { AuthFailed.Invoke(line); } throw new POP3_ClientException(line); } } if (IsAuthenticated) { if (AuthSucceed != null) { AuthSucceed.Invoke(); } FillMessages(); } }