Example #1
0
        /// <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);
        }
Example #2
0
        /// <summary>
        /// Get the sizes of all the messages.
        /// </summary>
        /// <returns>Size of each message</returns>
        public IEnumerable <PopStat> List()
        {
            if (!Connected)
            {
                throw new InvalidOperationException("You must be connected.");
            }

            List <PopStat>     sizes    = null;
            PopCommandResponse response = SendCommand("LIST");

            if (response.Success)
            {
                sizes = new List <PopStat>();
                string line;
                while (null != (line = StreamReader.ReadLine()) && "." != line)
                {
                    string[] s = line.Split(' ');
                    if (s.Length > 1)
                    {
                        PopStat stat = new PopStat();
                        int.TryParse(s[0], out stat.MessageNumber);
                        int.TryParse(s[1], out stat.Size);
                        sizes.Add(stat);
                    }
                }
            }
            return(new ReadOnlyCollection <PopStat>(sizes));
        }
Example #3
0
        /// <summary>
        /// Get a list of message numbers with a unique identifier for each message number.
        /// </summary>
        public IEnumerable <PopUid> GetMessageUids()
        {
            if (!Connected)
            {
                throw new InvalidOperationException("You must be connected.");
            }

            List <PopUid>      uids     = new List <PopUid>();
            PopCommandResponse response = SendCommand("UIDL");

            if (response.Success)
            {
                string line;
                while (null != (line = StreamReader.ReadLine()) && "." != line)
                {
                    string[] s = line.Split(' ');
                    if (s.Length > 1)
                    {
                        PopUid uid = new PopUid();
                        int.TryParse(s[0], out uid.MessageNumber);
                        uid.UniqueIdentifier = s[1];
                        uids.Add(uid);
                    }
                }
            }
            return(new ReadOnlyCollection <PopUid>(uids));
        }
Example #4
0
        /// <summary>
        /// Get max message number and mailbox size.
        /// </summary>
        /// <returns>PopStat object with the max message number and mailbox size.</returns>
        public PopStat SendStat()
        {
            PopCommandResponse response = SendCommand("STAT");
            PopStat            stat     = new PopStat();
            IList <int>        v        = response.IntValues();

            if (v.Count > 1)
            {
                stat.MessageNumber = v[0];
                stat.Size          = v[1];
            }
            return(stat);
        }
Example #5
0
        /// <summary>
        /// Get the size of a message
        /// </summary>
        /// <param name="intMessageNumber">message number</param>
        /// <returns>Size of message</returns>
        public PopStat List(int intMessageNumber)
        {
            if (!Connected)
            {
                throw new InvalidOperationException("You must be connected.");
            }

            PopCommandResponse response = SendCommand("LIST " + intMessageNumber.ToString());
            PopStat            stat     = new PopStat();
            IList <int>        v        = response.IntValues();

            stat.MessageNumber = v[0];
            stat.Size          = v[1];
            return(stat);
        }
Example #6
0
        /// <summary>
        /// Authenticate the user with APOP
        /// </summary>
        /// <param name="username">user name</param>
        /// <param name="password">password</param>
        private void SendApop(string username, string password)
        {
            PopCommandResponse response = SendCommand("APOP " + username + " " + ComputeHashAsHexString(password));

            if (!response.Success)
            {
                if (Regex.IsMatch(response.RawValue, "lock", RegexOptions.IgnoreCase))
                {
                    throw new MailboxLockedException("Mailbox locked by another client. Try again later.", response.ToException());
                }
                else
                {
                    throw new PopAuthenticationException("APOP Authentication: " + response.RawValue, response.ToException());
                }
            }
        }
Example #7
0
        /// <summary>
        /// Get unique identifier for the given message number.
        /// </summary>
        /// <param name="intMessageNumber">message number</param>
        public PopUid GetMessageUid(int intMessageNumber)
        {
            if (!Connected)
            {
                throw new InvalidOperationException("You must be connected.");
            }

            PopCommandResponse response = SendCommand("UIDL " + intMessageNumber.ToString());

            if (response.Success)
            {
                if (response.Parameters.Count > 1)
                {
                    PopUid uid = new PopUid();
                    int.TryParse(response.Parameters[0], out uid.MessageNumber);
                    uid.UniqueIdentifier = response.Parameters[1];
                }
            }
            throw new InvalidDataException("Server responded with invalid data: " + response.RawValue);
        }
Example #8
0
        /// <summary>
        /// Get the capabilities of the server.
        /// </summary>
        /// <returns></returns>
        public IEnumerable <string> Capabilities()
        {
            if (!Connected)
            {
                throw new InvalidOperationException("You must be connected.");
            }

            List <string>      caps     = new List <string>();
            PopCommandResponse response = SendCommand("CAPA");

            if (response.Success)
            {
                string line;
                while (null != (line = StreamReader.ReadLine()) && "." != line)
                {
                    caps.Add(line);
                }
            }

            return(new ReadOnlyCollection <string>(caps));
        }
Example #9
0
        /// <summary>
        /// fetches a message or a message header
        /// </summary>
        /// <param name="messageNumber">message number on the server</param>
        /// <param name="fetchHeaderOnly">Only return message header?</param>
        /// <returns>Stream of mime-encoded text data. Returns null of the command failed.</returns>
        private TextReader GetMessageReader(int messageNumber, bool fetchHeaderOnly)
        {
            string cmd;

            if (fetchHeaderOnly)
            {
                cmd = string.Format("TOP {0} 0", messageNumber.ToString());
            }
            else
            {
                cmd = string.Format("RETR {0}", messageNumber.ToString());
            }

            PopCommandResponse response = SendCommand(cmd);

            if (!response.Success)
            {
                response.Throw();
            }

            return(StreamReader);
        }
Example #10
0
        /// <summary>
        /// Authenticate the user with USER/PASS
        /// </summary>
        /// <param name="username">user name</param>
        /// <param name="password">password</param>
        private void SendUserPass(string username, string password)
        {
            PopCommandResponse response = SendCommand("USER " + username);

            if (!response.Success)
            {
                throw new PopAuthenticationException("USER/PASS Authentication: " + response.RawValue, response.ToException());
            }

            response = SendCommand("PASS " + password);
            if (!response.Success)
            {
                if (Regex.IsMatch(response.RawValue, "lock", RegexOptions.IgnoreCase))
                {
                    throw new MailboxLockedException("Mailbox locked by another client. Try again later.", response.ToException());
                }
                else
                {
                    throw new PopAuthenticationException("USER/PASS Authentication: " + response.RawValue, response.ToException());
                }
            }
        }
Example #11
0
 static PopCommandResponse()
 {
     NullResponse = new PopCommandResponse( null );
 }
Example #12
0
 static PopCommandResponse()
 {
     NullResponse = new PopCommandResponse(null);
 }
Example #13
0
        /// <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();
            }
        }