Пример #1
0
        /// <summary>
        /// Authenticates a socket client using plain authentication.
        /// </summary>
        /// <returns>True if the client was successfully authenticated. False otherwise.</returns>
        private async Task <bool> AuthenticateByPlainAsync()
        {
            if (!IsConnected)
            {
                return(false);
            }

            SmtpResponse response = await Socket.Send("Auth Plain");

            if (!response.ContainsStatus(SmtpCode.WaitingForAuthentication))
            {
                return(false);
            }

            string lineAuthentication = string.Format("{0}\0{0}\0{1}", Username, Password);

            SmtpResponse responseAuth = await Socket.Send(Convert.ToBase64String(Encoding.UTF8.GetBytes(lineAuthentication)));

            if (!responseAuth.ContainsStatus(SmtpCode.AuthenticationSuccessful))
            {
                return(false);
            }

            return(true);
        }
Пример #2
0
        /// <summary>
        /// Connects to the server.
        /// </summary>
        /// <returns>True for successful connection. False otherwise.</returns>
        private async Task <bool> ConnectAsync()
        {
            try
            {
                if (IsConnected)
                {
                    Socket.Dispose();
                    IsConnected = false;
                }

                Socket = new SmtpSocket(Server, Port, SSL);

                SmtpResponse response = await Socket.EstablishConnection();

                if (response.ContainsStatus(SmtpCode.ServiceReady))
                {
                    IsConnected = true;

                    return(true);
                }
            }
            catch
            {
                return(false);
            }

            return(false);
        }
Пример #3
0
        /// <summary>
        /// Authenticates a socket client using login authentication.
        /// </summary>
        /// <returns>True if the client was successfully authenticated. False otherwise.</returns>
        private async Task <bool> AuthenticateByLoginAsync()
        {
            if (!IsConnected)
            {
                return(false);
            }

            SmtpResponse response = await Socket.Send("Auth Login");

            if (!response.ContainsStatus(SmtpCode.WaitingForAuthentication))
            {
                return(false);
            }

            SmtpResponse responseUsername = await Socket.Send(Convert.ToBase64String(Encoding.UTF8.GetBytes(Username)));

            if (!responseUsername.ContainsStatus(SmtpCode.WaitingForAuthentication))
            {
                return(false);
            }

            SmtpResponse responsePassword = await Socket.Send(Convert.ToBase64String(Encoding.UTF8.GetBytes(Password)));

            if (!responsePassword.ContainsStatus(SmtpCode.AuthenticationSuccessful))
            {
                return(false);
            }

            return(true);
        }
Пример #4
0
        /// <summary>
        /// Connects to the server.
        /// </summary>
        /// <returns>True for successful connection. False otherwise.</returns>
        public async Task <bool> Connect()
        {
            try
            {
                if (IsConnected)
                {
                    Socket.Close();
                    IsConnected = false;
                }

                Socket = new SmtpSocket(Server, Port, SSL, Username, Password);

                SmtpResponse response = await Socket.EstablishConnection();

                if (response.Contains(SmtpCode.ServiceReady))
                {
                    IsConnected = true;

                    return(true);
                }
            }
            catch
            {
                return(false);
            }

            return(false);
        }
Пример #5
0
        /// <summary>
        /// Sends the specified email message.
        /// </summary>
        /// <param name="message">The email message.</param>
        /// <returns>True if the email was sent successfully. False otherwise.</returns>
        public async Task <bool> SendMail(SmtpMessage message)
        {
            if (!IsConnected)
            {
                await Connect();
            }

            if (!IsConnected)
            {
                throw new Exception("Can't connect to the SMTP server.");
            }

            if (!IsAuthenticated)
            {
                await Authenticate();
            }

            SmtpResponse response = await Socket.Send(string.Format("Mail From:<{0}>", message.From.EmailAddress));

            if (!response.Contains(SmtpCode.RequestedMailActionCompleted))
            {
                return(false);
            }

            foreach (MailBox to in message.To)
            {
                SmtpResponse responseTo = await Socket.Send(String.Format("Rcpt To:<{0}>", to.EmailAddress));

                if (!responseTo.Contains(SmtpCode.RequestedMailActionCompleted))
                {
                    break;
                }
            }

            SmtpResponse responseData = await Socket.Send(String.Format("Data"));

            if (!responseData.Contains(SmtpCode.StartMailInput))
            {
                return(false);
            }

            SmtpResponse repsonseMessage = await Socket.Send(await message.CreateMessageBody());

            if (!repsonseMessage.Contains(SmtpCode.RequestedMailActionCompleted))
            {
                return(false);
            }

            SmtpResponse responseQuit = await Socket.Send("Quit");

            if (!responseQuit.Contains(SmtpCode.ServiceClosingTransmissionChannel))
            {
                return(false);
            }

            return(true);
        }
Пример #6
0
        /// <summary>
        /// Authenticates a socket client using the specified Username and Password.
        /// </summary>
        /// <returns>True if the client was successfully authenticated. False otherwise.</returns>
        private async Task <bool> AuthenticateAsync()
        {
            if (!IsConnected)
            {
                return(false);
            }

            // get the type of auth
            SmtpResponse response = await Socket.Send("EHLO " + Server);

            if (response.ContainsMessage("STARTTLS"))
            {
                SmtpResponse responseSSL = await Socket.Send("STARTTLS");

                if (responseSSL.ContainsStatus(SmtpCode.ServiceReady))
                {
                    await Socket.UpgradeToSslAsync();

                    return(await AuthenticateAsync());
                }
            }

            if (response.ContainsMessage("AUTH"))
            {
                if (response.ContainsMessage("LOGIN"))
                {
                    IsAuthenticated = await AuthenticateByLoginAsync();
                }
                else if (response.ContainsMessage("PLAIN"))
                {
                    IsAuthenticated = await AuthenticateByPlainAsync();
                }
            }
            else
            {
                await Socket.Send("EHLO " + Server);

                IsAuthenticated = true;
            }

            return(IsAuthenticated);
        }
Пример #7
0
        /// <summary>
        /// Authenticates a socket client using the specified Username and Password.
        /// </summary>
        /// <returns>True if the client was successfully authenticated. False otherwise.</returns>
        public async Task <bool> Authenticate()
        {
            if (!IsConnected)
            {
                throw new Exception("Client is not connected");
            }

            // get the type of auth
            SmtpResponse response = await Socket.Send("EHLO " + Server);

            if (response.Contains("STARTTLS"))
            {
                SmtpResponse responseSSL = await Socket.Send("STARTTLS");

                if (responseSSL.Contains(SmtpCode.ServiceReady))
                {
                    await Socket.UpgradeToSslAsync();

                    return(await Authenticate());
                }
            }

            if (response.Contains("AUTH"))
            {
                if (response.Contains("LOGIN"))
                {
                    IsAuthenticated = await AuthenticateByLogin();
                }
                else if (response.Contains("PLAIN"))
                {
                    IsAuthenticated = await AuthenticateByPlain();
                }
            }
            else
            {
                await Socket.Send("EHLO " + Server);

                IsAuthenticated = true;
            }

            return(IsAuthenticated);
        }
Пример #8
0
        private async Task <SmtpResponse> GetResponse(string from)
        {
            SmtpResponse  response       = new SmtpResponse();
            bool          isStartingLine = true;
            StringBuilder stringBuilder  = null;
            int           charLen        = 3;
            Boolean       endOfStream    = false;
            SmtpCode      code           = SmtpCode.None;
            string        codeStr        = string.Empty;

            try
            {
                stringBuilder = new StringBuilder();

                while (!endOfStream)
                {
                    // There is a Strange beahvior when the bufferLength is exactly the same size as the inputStream
                    await _reader.LoadAsync(BUFFER_LENGTH);

                    charLen = Math.Min((int)_reader.UnconsumedBufferLength, BUFFER_LENGTH);

                    if (charLen == 0)
                    {
                        endOfStream = true;
                        break;
                    }

                    // If charLen < bufferLength, it's end of stream
                    if (charLen < BUFFER_LENGTH)
                    {
                        endOfStream = true;
                    }

                    // get the current position
                    int charPos = 0;

                    // Read the buffer
                    byte[] buffer = new byte[charLen];
                    _reader.ReadBytes(buffer);

                    do
                    {
                        // get the character
                        char chr = (char)buffer[charPos];

                        // if it's starting point, we can read the first 3 chars.
                        if (isStartingLine)
                        {
                            codeStr += chr;

                            // Get the code
                            if (codeStr.Length == 3)
                            {
                                int codeInt;
                                if (int.TryParse(codeStr, out codeInt))
                                {
                                    code = (SmtpCode)codeInt;
                                }

                                // next
                                isStartingLine = false;
                            }
                        }
                        else if (chr == '\r' || chr == '\n')
                        {
                            // Advance 1 byte to get the '\n' if not at the end of the buffer
                            if (chr == '\r' && charPos < (charLen - 1))
                            {
                                charPos++;
                                chr = (char)buffer[charPos];
                            }
                            if (chr == '\n')
                            {
                                KeyValuePair <SmtpCode, String> r = new KeyValuePair <SmtpCode, string>
                                                                        (code, stringBuilder.ToString());

                                response.Values.Add(r);

                                Debug.WriteLine("{0}{1}", ((int)code).ToString(), stringBuilder.ToString());

                                stringBuilder  = new StringBuilder();
                                code           = SmtpCode.None;
                                codeStr        = string.Empty;
                                isStartingLine = true;
                            }
                        }
                        else
                        {
                            stringBuilder.Append(chr);
                        }

                        charPos++;
                    } while (charPos < charLen);
                }
            }
            catch
            {
                throw;
            }

            return(response);
        }
Пример #9
0
        private async Task<SmtpResponse> GetResponse(string from)
        {
            SmtpResponse response = new SmtpResponse();
            bool isStartingLine = true;
            StringBuilder stringBuilder = null;
            int charLen = 3;
            Boolean endOfStream = false;
            SmtpCode code = SmtpCode.None;
            string codeStr = string.Empty;

            try
            {
                stringBuilder = new StringBuilder();

                while (!endOfStream)
                {
                    // There is a Strange beahvior when the bufferLength is exactly the same size as the inputStream
                    await _reader.LoadAsync(BUFFER_LENGTH);

                    charLen = Math.Min((int)_reader.UnconsumedBufferLength, BUFFER_LENGTH);

                    if (charLen == 0)
                    {
                        endOfStream = true;
                        break;
                    }

                    // If charLen < bufferLength, it's end of stream
                    if (charLen < BUFFER_LENGTH)
                        endOfStream = true;

                    // get the current position
                    int charPos = 0;

                    // Read the buffer
                    byte[] buffer = new byte[charLen];
                    _reader.ReadBytes(buffer);

                    do
                    {
                        // get the character
                        char chr = (char)buffer[charPos];

                        // if it's starting point, we can read the first 3 chars.
                        if (isStartingLine)
                        {

                            codeStr += chr;

                            // Get the code
                            if (codeStr.Length == 3)
                            {
                                int codeInt;
                                if (int.TryParse(codeStr, out codeInt))
                                    code = (SmtpCode)codeInt;

                                // next 
                                isStartingLine = false;
                            }

                        }
                        else if (chr == '\r' || chr == '\n')
                        {
                            // Advance 1 byte to get the '\n' if not at the end of the buffer
                            if (chr == '\r' && charPos < (charLen - 1))
                            {
                                charPos++;
                                chr = (char)buffer[charPos];
                            }
                            if (chr == '\n')
                            {
                                KeyValuePair<SmtpCode, String> r = new KeyValuePair<SmtpCode, string>
                                    (code, stringBuilder.ToString());

                                response.Values.Add(r);

                                Debug.WriteLine("{0}{1}", ((int)code).ToString(), stringBuilder.ToString());

                                stringBuilder = new StringBuilder();
                                code = SmtpCode.None;
                                codeStr = string.Empty;
                                isStartingLine = true;
                            }
                        }
                        else
                        {
                            stringBuilder.Append(chr);
                        }

                        charPos++;

                    } while (charPos < charLen);
                }
            }
            catch
            {
                throw;
            }

            return response;
        }
Пример #10
0
        /// <summary>
        /// Sends the specified email message.
        /// </summary>
        /// <param name="message">The email message.</param>
        /// <returns>True if the email was sent successfully. False otherwise.</returns>
        public async Task <SmtpResult> SendMailAsync(EmailMessage message)
        {
            if (!IsConnected)
            {
                await ConnectAsync();
            }

            if (!IsConnected)
            {
                return(SmtpResult.ConnectionFailed);
            }

            if (!IsAuthenticated)
            {
                await AuthenticateAsync();
            }

            if (!IsAuthenticated)
            {
                return(SmtpResult.AuthenticationFailed);
            }

            SmtpResponse response = message.Sender != null && message.Sender.Address.Length != 0 ?
                                    await Socket.Send(string.Format("Mail From:<{0}>", message.Sender.Address)) :
                                    await Socket.Send(string.Format("Mail From:<{0}>", Username));

            if (!response.ContainsStatus(SmtpCode.RequestedMailActionCompleted))
            {
                return(SmtpResult.CouldNotCreateMail);
            }

            foreach (EmailRecipient to in message.To)
            {
                SmtpResponse responseTo = await Socket.Send(string.Format("Rcpt To:<{0}>", to.Address));

                if (!responseTo.ContainsStatus(SmtpCode.RequestedMailActionCompleted))
                {
                    break;
                }
            }

            foreach (EmailRecipient to in message.CC)
            {
                SmtpResponse responseTo = await Socket.Send(string.Format("Rcpt To:<{0}>", to.Address));

                if (!responseTo.ContainsStatus(SmtpCode.RequestedMailActionCompleted))
                {
                    break;
                }
            }

            foreach (EmailRecipient to in message.Bcc)
            {
                SmtpResponse responseTo = await Socket.Send(string.Format("Rcpt To:<{0}>", to.Address));

                if (!responseTo.ContainsStatus(SmtpCode.RequestedMailActionCompleted))
                {
                    break;
                }
            }

            SmtpResponse responseData = await Socket.Send(string.Format("Data"));

            if (!responseData.ContainsStatus(SmtpCode.StartMailInput))
            {
                return(SmtpResult.CouldNotCreateMail);
            }

            SmtpResponse repsonseMessage = await Socket.Send(await BuildSmtpMailInput(message));

            if (!repsonseMessage.ContainsStatus(SmtpCode.RequestedMailActionCompleted))
            {
                return(SmtpResult.CouldNotCreateMail);
            }

            SmtpResponse responseQuit = await Socket.Send("Quit");

            if (!responseQuit.ContainsStatus(SmtpCode.ServiceClosingTransmissionChannel))
            {
                return(SmtpResult.CouldNotCloseTransmissionChannel);
            }

            return(SmtpResult.OK);
        }