Beispiel #1
0
        static void ProcessMailFromResponse(SmtpResponse response, MailboxAddress mailbox)
        {
            switch (response.StatusCode)
            {
            case SmtpStatusCode.Ok:
                break;

            case SmtpStatusCode.MailboxNameNotAllowed:
            case SmtpStatusCode.MailboxUnavailable:
                throw new SmtpCommandException(SmtpErrorCode.SenderNotAccepted, response.StatusCode, mailbox, response.Response);

            case SmtpStatusCode.AuthenticationRequired:
                throw new UnauthorizedAccessException(response.Response);

            default:
                throw new SmtpCommandException(SmtpErrorCode.UnexpectedStatusCode, response.StatusCode, response.Response);
            }
        }
Beispiel #2
0
        static void ProcessRcptToResponse(SmtpResponse response, MailboxAddress mailbox)
        {
            switch (response.StatusCode)
            {
            case SmtpStatusCode.UserNotLocalWillForward:
            case SmtpStatusCode.Ok:
                break;

            case SmtpStatusCode.UserNotLocalTryAlternatePath:
            case SmtpStatusCode.MailboxNameNotAllowed:
            case SmtpStatusCode.MailboxUnavailable:
            case SmtpStatusCode.MailboxBusy:
                throw new SmtpCommandException(SmtpErrorCode.RecipientNotAccepted, response.StatusCode, mailbox, response.Response);

            case SmtpStatusCode.AuthenticationRequired:
                throw new UnauthorizedAccessException(response.Response);

            default:
                throw new SmtpCommandException(SmtpErrorCode.UnexpectedStatusCode, response.StatusCode, response.Response);
            }
        }
Beispiel #3
0
 static void ProcessRcptToResponse(SmtpResponse response, MailboxAddress mailbox)
 {
     switch (response.StatusCode) {
     case SmtpStatusCode.UserNotLocalWillForward:
     case SmtpStatusCode.Ok:
         break;
     case SmtpStatusCode.UserNotLocalTryAlternatePath:
     case SmtpStatusCode.MailboxNameNotAllowed:
     case SmtpStatusCode.MailboxUnavailable:
     case SmtpStatusCode.MailboxBusy:
         throw new SmtpCommandException (SmtpErrorCode.RecipientNotAccepted, response.StatusCode, mailbox, response.Response);
     case SmtpStatusCode.AuthenticationRequired:
         throw new UnauthorizedAccessException (response.Response);
     default:
         throw new SmtpCommandException (SmtpErrorCode.UnexpectedStatusCode, response.StatusCode, response.Response);
     }
 }
Beispiel #4
0
 static void ProcessMailFromResponse(SmtpResponse response, MailboxAddress mailbox)
 {
     switch (response.StatusCode) {
     case SmtpStatusCode.Ok:
         break;
     case SmtpStatusCode.MailboxNameNotAllowed:
     case SmtpStatusCode.MailboxUnavailable:
         throw new SmtpCommandException (SmtpErrorCode.SenderNotAccepted, response.StatusCode, mailbox, response.Response);
     case SmtpStatusCode.AuthenticationRequired:
         throw new UnauthorizedAccessException (response.Response);
     default:
         throw new SmtpCommandException (SmtpErrorCode.UnexpectedStatusCode, response.StatusCode, response.Response);
     }
 }
Beispiel #5
0
		bool ProcessRcptToResponse (MimeMessage message, MailboxAddress mailbox, SmtpResponse response)
		{
			switch (response.StatusCode) {
			case SmtpStatusCode.UserNotLocalWillForward:
			case SmtpStatusCode.Ok:
				OnRecipientAccepted (message, mailbox, response);
				return true;
			case SmtpStatusCode.UserNotLocalTryAlternatePath:
			case SmtpStatusCode.MailboxNameNotAllowed:
			case SmtpStatusCode.MailboxUnavailable:
			case SmtpStatusCode.MailboxBusy:
				OnRecipientNotAccepted (message, mailbox, response);
				return false;
			case SmtpStatusCode.AuthenticationRequired:
				throw new ServiceNotAuthenticatedException (response.Response);
			default:
				throw new SmtpCommandException (SmtpErrorCode.UnexpectedStatusCode, response.StatusCode, response.Response);
			}
		}
Beispiel #6
0
		/// <summary>
		/// Invoked when a recipient is not accepted by the SMTP server.
		/// </summary>
		/// <remarks>
		/// The default implementation throws an appropriate <see cref="SmtpCommandException"/>.
		/// </remarks>
		/// <param name="message">The message being sent.</param>
		/// <param name="mailbox">The mailbox used in the <c>RCPT TO</c> command.</param>
		/// <param name="response">The response to the <c>RCPT TO</c> command.</param>
		protected virtual void OnRecipientNotAccepted (MimeMessage message, MailboxAddress mailbox, SmtpResponse response)
		{
			throw new SmtpCommandException (SmtpErrorCode.RecipientNotAccepted, response.StatusCode, mailbox, response.Response);
		}
Beispiel #7
0
		/// <summary>
		/// Invoked when a recipient is accepted by the SMTP server.
		/// </summary>
		/// <remarks>
		/// The default implementation does nothing.
		/// </remarks>
		/// <param name="message">The message being sent.</param>
		/// <param name="mailbox">The mailbox used in the <c>RCPT TO</c> command.</param>
		/// <param name="response">The response to the <c>RCPT TO</c> command.</param>
		protected virtual void OnRecipientAccepted (MimeMessage message, MailboxAddress mailbox, SmtpResponse response)
		{
		}
Beispiel #8
0
		void ProcessMailFromResponse (MimeMessage message, MailboxAddress mailbox, SmtpResponse response)
		{
			switch (response.StatusCode) {
			case SmtpStatusCode.Ok:
				OnSenderAccepted (message, mailbox, response);
				break;
			case SmtpStatusCode.MailboxNameNotAllowed:
			case SmtpStatusCode.MailboxUnavailable:
				OnSenderNotAccepted (message, mailbox, response);
				break;
			case SmtpStatusCode.AuthenticationRequired:
				throw new ServiceNotAuthenticatedException (response.Response);
			default:
				throw new SmtpCommandException (SmtpErrorCode.UnexpectedStatusCode, response.StatusCode, response.Response);
			}
		}
Beispiel #9
0
		/// <summary>
		/// Invoked when the sender is accepted by the SMTP server.
		/// </summary>
		/// <remarks>
		/// The default implementation does nothing.
		/// </remarks>
		/// <param name="message">The message being sent.</param>
		/// <param name="mailbox">The mailbox used in the <c>MAIL FROM</c> command.</param>
		/// <param name="response">The response to the <c>MAIL FROM</c> command.</param>
		protected virtual void OnSenderAccepted (MimeMessage message, MailboxAddress mailbox, SmtpResponse response)
		{
		}
Beispiel #10
0
        /// <summary>
        /// Establishes a connection to the specified SMTP server.
        /// </summary>
        /// <remarks>
        /// <para>Establishes a connection to an SMTP or SMTP/S server. If the schema
        /// in the uri is "smtp", a clear-text connection is made and defaults to using
        /// port 25 if no port is specified in the URI. However, if the schema in the
        /// uri is "smtps", an SSL connection is made using the
        /// <see cref="ClientCertificates"/> and defaults to port 465 unless a port
        /// is specified in the URI.</para>
        /// <para>It should be noted that when using a clear-text SMTP connection,
        /// if the server advertizes support for the STARTTLS extension, the client
        /// will automatically switch into TLS mode before authenticating unless the
        /// <paramref name="uri"/> contains a query string to disable it.</para>
        /// If a successful connection is made, the <see cref="AuthenticationMechanisms"/>
        /// and <see cref="Capabilities"/> properties will be populated.
        /// </remarks>
        /// <param name="uri">The server URI. The <see cref="System.Uri.Scheme"/> should either
        /// be "smtp" to make a clear-text connection or "smtps" to make an SSL connection.</param>
        /// <param name="cancellationToken">A cancellation token.</param>
        /// <exception cref="System.ArgumentNullException">
        /// <para>The <paramref name="uri"/> is <c>null</c>.</para>
        /// </exception>
        /// <exception cref="System.ArgumentException">
        /// The <paramref name="uri"/> is not an absolute URI.
        /// </exception>
        /// <exception cref="System.ObjectDisposedException">
        /// The <see cref="SmtpClient"/> has been disposed.
        /// </exception>
        /// <exception cref="System.InvalidOperationException">
        /// The <see cref="SmtpClient"/> is already connected.
        /// </exception>
        /// <exception cref="System.OperationCanceledException">
        /// The operation was canceled.
        /// </exception>
        /// <exception cref="System.IO.IOException">
        /// An I/O error occurred.
        /// </exception>
        /// <exception cref="SmtpCommandException">
        /// An SMTP command failed.
        /// </exception>
        /// <exception cref="SmtpProtocolException">
        /// An SMTP protocol error occurred.
        /// </exception>
        public void Connect(Uri uri, CancellationToken cancellationToken)
        {
            CheckDisposed();

            if (uri == null)
            {
                throw new ArgumentNullException("uri");
            }

            if (!uri.IsAbsoluteUri)
            {
                throw new ArgumentException("The uri must be absolute.", "uri");
            }

            if (IsConnected)
            {
                throw new InvalidOperationException("The SmtpClient is already connected.");
            }

            Capabilities = SmtpCapabilities.None;
            authmechs.Clear();
            MaxSize = 0;

            bool         smtps       = uri.Scheme.ToLowerInvariant() == "smtps";
            int          port        = uri.Port > 0 ? uri.Port : (smtps ? 465 : 25);
            var          ipAddresses = Dns.GetHostAddresses(uri.DnsSafeHost);
            var          query       = uri.ParsedQuery();
            SmtpResponse response    = null;
            Socket       socket      = null;
            string       value;

            var starttls = !smtps && (!query.TryGetValue("starttls", out value) || Convert.ToBoolean(value));

            for (int i = 0; i < ipAddresses.Length; i++)
            {
                socket = new Socket(ipAddresses[i].AddressFamily, SocketType.Stream, ProtocolType.Tcp);

                cancellationToken.ThrowIfCancellationRequested();

                try {
                    socket.Connect(ipAddresses[i], port);
                    localEndPoint = socket.LocalEndPoint;
                    break;
                } catch {
                    if (i + 1 == ipAddresses.Length)
                    {
                        throw;
                    }
                }
            }

            if (smtps)
            {
                var ssl = new SslStream(new NetworkStream(socket, true), false, ValidateRemoteCertificate);
                ssl.AuthenticateAsClient(uri.Host, ClientCertificates, SslProtocols.Default, true);
                stream = ssl;
            }
            else
            {
                stream = new NetworkStream(socket, true);
            }

            host = uri.Host;

            logger.LogConnect(uri);

            try {
                // read the greeting
                response = ReadResponse(cancellationToken);

                if (response.StatusCode != SmtpStatusCode.ServiceReady)
                {
                    throw new SmtpCommandException(SmtpErrorCode.UnexpectedStatusCode, response.StatusCode, response.Response);
                }

                // Send EHLO and get a list of supported extensions
                Ehlo(cancellationToken);

                if (starttls && (Capabilities & SmtpCapabilities.StartTLS) != 0)
                {
                    response = SendCommand("STARTTLS", cancellationToken);
                    if (response.StatusCode != SmtpStatusCode.ServiceReady)
                    {
                        throw new SmtpCommandException(SmtpErrorCode.UnexpectedStatusCode, response.StatusCode, response.Response);
                    }

                    var tls = new SslStream(stream, false, ValidateRemoteCertificate);
                    tls.AuthenticateAsClient(uri.Host, ClientCertificates, SslProtocols.Tls, true);
                    stream = tls;

                    // Send EHLO again and get the new list of supported extensions
                    Ehlo(cancellationToken);
                }

                IsConnected = true;
            } catch {
                stream.Dispose();
                stream = null;
                throw;
            }
        }