/// <summary> /// Sends a command to the POP server. /// </summary> /// <param name="cmd">command to send to server</param> /// <returns>true if server responded "+OK"</returns> private PopCommandResponse SendCommand(string cmd) { PopCommandResponse response = PopCommandResponse.NullResponse; try { if (StreamWriter.BaseStream.CanWrite) { StreamWriter.WriteLine(cmd); StreamWriter.Flush(); response = PopCommandResponse.FromRawResponseString(StreamReader.ReadLine()); } } catch (Exception e) { if (e is IOException) { throw e; } else { string err = cmd + ":" + e.Message; Debug.WriteLine(e); throw new PopServerResponseErrException(err, e); } } return(response); }
/// <summary> /// Connect to the server. Requires that the Port and Host properties be set. /// </summary> public void Connect() { if (Connected) { throw new InvalidOperationException("PopClient is already connected."); } if (Host == null || Host == default(string)) { throw new InvalidOperationException("The Host property must be set."); } string host = Host; int port = Port; SslProtocols sslProtocol = SslProtocol; ClientSocket.Connect(host, port); Stream stream = ClientSocket.GetStream(); if (SslProtocols.None != sslProtocol) { if (SslNegotiationMode.Connect == SslNegotiationMode) { //Implements POP3S capability for SSL/TLS connections on an alternate port. //For POPS/Connect, we negotiate an SslStream immediately. stream = NegotiateSslStream(host, sslProtocol, stream); } else { //UNDONE: test STARTTLS. (Need an account on a compatible server.) //For STLS, we have to start out with plain text and then issue the STLS command and if the server says +OK //we can negotiate TLS. Have to do this without using a StreamReader or StreamWriter because we need to change //the stream from a NetworkStream to an SslStream. The stream inside of a StreamReader and StreamWriter can't //be changed and closing the StreamReader or StreamWriter will close the stream upon which the SslStream is based. string response; try { //don't close or dispose these StreamReader and StreamWriter objects of the stream will be closed. StreamWriter writer = new StreamWriter(stream); StreamReader reader = new StreamReader(stream); writer.WriteLine("STLS"); response = reader.ReadLine(); } catch (Exception ex) { if (null != stream) { try{ stream.Dispose(); } catch (ObjectDisposedException) {} } this.Disconnect(); throw new StartTlsNegotiationException("STARTTLS negotiation failed. Consider using SslNegotiationMode.Connect.", ex); } if (PopCommandResponse.IsResponseSuccess(response)) { stream = NegotiateSslStream(host, sslProtocol, stream); } else { if (null != stream) { try{ stream.Dispose(); } catch (ObjectDisposedException) {} } this.Disconnect(); throw new StartTlsNegotiationException(response); } } } StreamReader = new StreamReader(stream, Encoding.Default, true); StreamWriter = new StreamWriter(stream); StreamWriter.AutoFlush = true; PopCommandResponse popresponse = PopCommandResponse.FromRawResponseString(StreamReader.ReadLine()); if (popresponse.Success) { Match match = Regex.Match(popresponse.RawValue, @"^\+OK\s.+(<.+>$)"); if (match.Success) { ApopTimestamp = match.Groups[1].Value; } } else { this.Disconnect(); popresponse.ToException(); } }