/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.geronimo.javamail.transport.smtp;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;

import javax.mail.Address;
import javax.mail.AuthenticationFailedException;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimePart;
import javax.mail.Session;

import org.apache.geronimo.javamail.authentication.ClientAuthenticator;
import org.apache.geronimo.javamail.authentication.AuthenticatorFactory;
import org.apache.geronimo.javamail.util.CountingOutputStream;
import org.apache.geronimo.javamail.util.MailConnection;
import org.apache.geronimo.javamail.util.MIMEOutputStream;
import org.apache.geronimo.javamail.util.ProtocolProperties;
import org.apache.geronimo.mail.util.Base64;
import org.apache.geronimo.mail.util.XText;

/**
 * Simple implementation of SMTP transport. Just does plain RFC977-ish delivery.
 *
 * @version $Rev$ $Date$
 */
public class SMTPConnection extends MailConnection {
    protected static final String MAIL_SMTP_QUITWAIT = "quitwait";
    protected static final String MAIL_SMTP_EXTENSION = "mailextension";
    protected static final String MAIL_SMTP_EHLO = "ehlo";
    protected static final String MAIL_SMTP_ALLOW8BITMIME = "allow8bitmime";
    protected static final String MAIL_SMTP_REPORT_SUCCESS = "reportsuccess";
    protected static final String MAIL_SMTP_STARTTLS_ENABLE = "starttls.enable";
    protected static final String MAIL_SMTP_STARTTLS_REQUIRED = "starttls.required";
    protected static final String MAIL_SMTP_AUTH = "auth";
    protected static final String MAIL_SMTP_FROM = "from";
    protected static final String MAIL_SMTP_DSN_RET = "dsn.ret";
    protected static final String MAIL_SMTP_SUBMITTER = "submitter";

    /**
     * property keys for protocol properties.
     */
    protected static final int DEFAULT_NNTP_PORT = 119;

    // the last response line received from the server.
    protected SMTPReply lastServerResponse = null;

    // do we report success after completion of each mail send.
    protected boolean reportSuccess;
    // does the server support transport level security?
    protected boolean serverTLS = false;
    // is TLS enabled on our part?
    protected boolean useTLS = false;
    // is TLS required on our part?
    protected boolean requireTLS = false;
    // should we use 8BITMIME encoding if supported by the server?
    protected boolean use8bit = false;

    /**
     * Normal constructor for an SMTPConnection() object.
     *
     * @param props  The property bundle for this protocol instance.
     */
    public SMTPConnection(ProtocolProperties props) {
        super(props);

        // check to see if we need to throw an exception after a send operation.
        reportSuccess = props.getBooleanProperty(MAIL_SMTP_REPORT_SUCCESS, false);
        // and also check for TLS enablement.
        useTLS = props.getBooleanProperty(MAIL_SMTP_STARTTLS_ENABLE, false);
        // and also check if TLS is required.
        requireTLS = props.getBooleanProperty(MAIL_SMTP_STARTTLS_REQUIRED, false);
        // and also check for 8bitmime support
        use8bit = props.getBooleanProperty(MAIL_SMTP_ALLOW8BITMIME, false);
    }


    /**
     * Connect to the server and do the initial handshaking.
     *
     * @param host     The target host name.
     * @param port     The target port
     * @param username The connection username (can be null)
     * @param password The authentication password (can be null).
     *
     * @return true if we were able to obtain a connection and
     *         authenticate.
     * @exception MessagingException
     */
    public boolean protocolConnect(String host, int port, String username, String password) throws MessagingException {

        // now check to see if we need to authenticate. If we need this, then
        // we must have a username and
        // password specified. Failing this may result in a user prompt to
        // collect the information.
        boolean mustAuthenticate = props.getBooleanProperty(MAIL_SMTP_AUTH, false);

        // if we need to authenticate, and we don't have both a userid and
        // password, then we fail this
        // immediately. The Service.connect() method will try to obtain the user
        // information and retry the
        // connection one time.
        if (mustAuthenticate && (username == null || password == null)) {
            debugOut("Failing connection for missing authentication information");
            return false;
        }

        super.protocolConnect(host, port, username, password);

        try {
            // create socket and connect to server.
            getConnection();

            // receive welcoming message
            if (!getWelcome()) {
                debugOut("Error getting welcome message");
                throw new MessagingException("Error in getting welcome msg");
            }

            // say hello
            if (!sendHandshake()) {
                debugOut("Error getting processing handshake message");
                throw new MessagingException("Error in saying EHLO to server");
            }

            // authenticate with the server, if necessary
            if (!processAuthentication()) {
                debugOut("User authentication failure");
                throw new AuthenticationFailedException("Error authenticating with server");
            }
        } catch (IOException e) {
            debugOut("I/O exception establishing connection", e);
            throw new MessagingException("Connection error", e);
        }
        debugOut("Successful connection");
        return true;
    }


    /**
     * Close the connection. On completion, we'll be disconnected from the
     * server and unable to send more data.
     *
     * @exception MessagingException
     */
    public void close() throws MessagingException {
        // if we're already closed, get outta here.
        if (socket == null) {
            return;
        }
        try {
            // say goodbye
            sendQuit();
        } finally {
            // and close up the connection. We do this in a finally block to
            // make sure the connection
            // is shut down even if quit gets an error.
            closeServerConnection();
        }
    }

    public String toString() {
        return "SMTPConnection host: " + serverHost + " port: " + serverPort;
    }


    /**
     * Set the sender for this mail.
     *
     * @param message
     *                   The message we're sending.
     *
     * @return True if the command was accepted, false otherwise.
     * @exception MessagingException
     */
    protected boolean sendMailFrom(Message message) throws MessagingException {

        // need to sort the from value out from a variety of sources.
        String from = null;

        // first potential source is from the message itself, if it's an
        // instance of SMTPMessage.
        if (message instanceof SMTPMessage) {
            from = ((SMTPMessage) message).getEnvelopeFrom();
        }

        // if not available from the message, check the protocol property next
        if (from == null || from.length() == 0) {
            // the from value can be set explicitly as a property
            from = props.getProperty(MAIL_SMTP_FROM);
        }

        // if not there, see if we have something in the message header.
        if (from == null || from.length() == 0) {
            Address[] fromAddresses = message.getFrom();

            // if we have some addresses in the header, then take the first one
            // as our From: address
            if (fromAddresses != null && fromAddresses.length > 0) {
                from = ((InternetAddress) fromAddresses[0]).getAddress();
            }
            // get what the InternetAddress class believes to be the local
            // address.
            else {
                InternetAddress local = InternetAddress.getLocalAddress(session);
                if (local != null) {
                    from = local.getAddress();
                }
            }
        }

        if (from == null || from.length() == 0) {
            throw new MessagingException("no FROM address");
        }

        StringBuffer command = new StringBuffer();

        // start building up the command
        command.append("MAIL FROM: ");
        command.append(fixEmailAddress(from));

        // If the server supports the 8BITMIME extension, we might need to change the
        // transfer encoding for the content to allow for direct transmission of the
        // 8-bit codes.
        if (supportsExtension("8BITMIME")) {
            // we only do this if the capability was enabled via a property option or
            // by explicitly setting the property on the message object.
            if (use8bit || (message instanceof SMTPMessage && ((SMTPMessage)message).getAllow8bitMIME())) {
                // make sure we add the BODY= option to the FROM message.
                command.append(" BODY=8BITMIME");

                // go check the content and see if the can convert the transfer encoding to
                // allow direct 8-bit transmission.
                if (convertTransferEncoding((MimeMessage)message)) {
                    // if we changed the encoding on any of the parts, then we
                    // need to save the message again
                    message.saveChanges();
                }
            }
        }

        // some servers ask for a size estimate on the initial send
        if (supportsExtension("SIZE")) {
            int estimate = getSizeEstimate(message);
            if (estimate > 0) {
                command.append(" SIZE=" + estimate);
            }
        }

        // does this server support Delivery Status Notification? Then we may
        // need to add some extra to the command.
        if (supportsExtension("DSN")) {
            String returnNotification = null;

            // the return notification stuff might be set as value on the
            // message object itself.
            if (message instanceof SMTPMessage) {
                // we need to convert the option into a string value.
                switch (((SMTPMessage) message).getReturnOption()) {
                case SMTPMessage.RETURN_FULL:
                    returnNotification = "FULL";
                    break;

                case SMTPMessage.RETURN_HDRS:
                    returnNotification = "HDRS";
                    break;
                }
            }

            // if not obtained from the message object, it can also be set as a
            // property.
            if (returnNotification == null) {
                // the DSN value is set by yet another property.
                returnNotification = props.getProperty(MAIL_SMTP_DSN_RET);
            }

            // if we have a target, add the notification stuff to our FROM
            // command.
            if (returnNotification != null) {
                command.append(" RET=");
                command.append(returnNotification);
            }
        }

        // if this server supports AUTH and we have submitter information, then
        // we also add the
        // "AUTH=" keyword to the MAIL FROM command (see RFC 2554).

        if (supportsExtension("AUTH")) {
            String submitter = null;

            // another option that can be specified on the message object.
            if (message instanceof SMTPMessage) {
                submitter = ((SMTPMessage) message).getSubmitter();
            }
            // if not part of the object, try for a propery version.
            if (submitter == null) {
                // we only send the extra keyword is a submitter is specified.
                submitter = props.getProperty(MAIL_SMTP_SUBMITTER);
            }
            // we have one...add the keyword, plus the submitter info in xtext
            // format (defined by RFC 1891).
            if (submitter != null) {
                command.append(" AUTH=");
                try {
                    // add this encoded
                    command.append(new String(XText.encode(submitter.getBytes("US-ASCII")), "US-ASCII"));
                } catch (UnsupportedEncodingException e) {
                    throw new MessagingException("Invalid submitter value " + submitter);
                }
            }
        }

        String extension = null;

        // now see if we need to add any additional extension info to this
        // command. The extension is not
        // checked for validity. That's the reponsibility of the caller.
        if (message instanceof SMTPMessage) {
            extension = ((SMTPMessage) message).getMailExtension();
        }
        // this can come either from the object or from a set property.
        if (extension == null) {
            extension = props.getProperty(MAIL_SMTP_EXTENSION);
        }

        // have something real to add?
        if (extension != null && extension.length() != 0) {
            // tack this on the end with a blank delimiter.
            command.append(' ');
            command.append(extension);
        }

        // and finally send the command
        SMTPReply line = sendCommand(command.toString());

        // 250 response indicates success.
        return line.getCode() == SMTPReply.COMMAND_ACCEPTED;
    }


    /**
     * Check to see if a MIME body part can have its
     * encoding changed from quoted-printable or base64
     * encoding to 8bit encoding.  In order for this
     * to work, it must follow the rules laid out in
     * RFC 2045.  To qualify for conversion, the text
     * must be:
     *
     * 1)  No more than 998 bytes long
     * 2)  All lines are terminated with CRLF sequences
     * 3)  CR and LF characters only occur in properly
     * formed line separators
     * 4)  No null characters are allowed.
     *
     * The conversion will only be applied to text
     * elements, and this will recurse through the
     * different elements of MultiPart content.
     *
     * @param bodyPart The bodyPart to convert. Initially, this will be
     *                 the message itself.
     *
     * @return true if any conversion was performed, false if
     *         nothing was converted.
     */
    protected boolean convertTransferEncoding(MimePart bodyPart)
    {
        boolean converted = false;
        try {
            // if this is a multipart element, apply the conversion rules
            // to each of the parts.
            if (bodyPart.isMimeType("multipart/")) {
                MimeMultipart parts = (MimeMultipart)bodyPart.getContent();
                for (int i = 0; i < parts.getCount(); i++) {
                    // convert each body part, and accumulate the conversion result
                    converted = converted && convertTransferEncoding((MimePart)parts.getBodyPart(i));
                }
            }
            else {
                // we only do this if the encoding is quoted-printable or base64
                String encoding =  bodyPart.getEncoding();
                if (encoding != null) {
                    encoding = encoding.toLowerCase();
                    if (encoding.equals("quoted-printable") || encoding.equals("base64")) {
                        // this requires encoding.  Read the actual content to see if
                        // it conforms to the 8bit encoding rules.
                        if (isValid8bit(bodyPart.getInputStream())) {
                            // There's a huge hidden gotcha lurking under the covers here.
                            // If the content just exists as an encoded byte array, then just
                            // switching the transfer encoding will mess things up because the
                            // already encoded data gets transmitted in encoded form, but with
                            // and 8bit encoding style.  As a result, it doesn't get unencoded on
                            // the receiving end.  This is a nasty problem to debug.
                            //
                            // The solution is to get the content as it's object type, set it back
                            // on the the message in raw form.  Requesting the content will apply the
                            // current transfer encoding value to the data.  Once we have set the
                            // content value back, we can reset the transfer encoding.
                            bodyPart.setContent(bodyPart.getContent(), bodyPart.getContentType());

                            // it's valid, so change the transfer encoding to just
                            // pass the data through.
                            bodyPart.setHeader("Content-Transfer-Encoding", "8bit");
                            converted = true;   // we've changed something
                        }
                    }
                }
            }
        } catch (MessagingException e) {
        } catch (IOException e) {
        }
        return converted;
    }


    /**
     * Get the server's welcome blob from the wire....
     */
    protected boolean getWelcome() throws MessagingException {
        SMTPReply line = getReply();
        // just return the error status...we don't care about any of the
        // response information
        return !line.isError();
    }


    /**
     * Get an estimate of the transmission size for this
     * message.  This size is the complete message as it is
     * encoded and transmitted on the DATA command, not counting
     * the terminating ".CRLF".
     *
     * @param msg    The message we're sending.
     *
     * @return The count of bytes, if it can be calculated.
     */
    protected int getSizeEstimate(Message msg) {
        // now the data... I could look at the type, but
        try {
            CountingOutputStream outputStream = new CountingOutputStream();

            // the data content has two requirements we need to meet by
            // filtering the
            // output stream. Requirement 1 is to conicalize any line breaks.
            // All line
            // breaks will be transformed into properly formed CRLF sequences.
            //
            // Requirement 2 is to perform byte-stuff for any line that begins
            // with a "."
            // so that data is not confused with the end-of-data marker (a
            // "\r\n.\r\n" sequence.
            //
            // The MIME output stream performs those two functions on behalf of
            // the content
            // writer.
            MIMEOutputStream mimeOut = new MIMEOutputStream(outputStream);

            msg.writeTo(mimeOut);

            // now to finish, we make sure there's a line break at the end.
            mimeOut.forceTerminatingLineBreak();
            // and flush the data to send it along
            mimeOut.flush();

            return outputStream.getCount();
        } catch (IOException e) {
            return 0;     // can't get an estimate
        } catch (MessagingException e) {
            return 0;     // can't get an estimate
        }
    }


    /**
     * Sends the data in the message down the socket. This presumes the server
     * is in the right place and ready for getting the DATA message and the data
     * right place in the sequence
     */
    protected void sendData(MimeMessage msg) throws MessagingException {

        // send the DATA command
        SMTPReply line = sendCommand("DATA");

        if (line.isError()) {
            throw new MessagingException("Error issuing SMTP 'DATA' command: " + line);
        }

        // now the data... I could look at the type, but
        try {
            // the data content has two requirements we need to meet by
            // filtering the
            // output stream. Requirement 1 is to conicalize any line breaks.
            // All line
            // breaks will be transformed into properly formed CRLF sequences.
            //
            // Requirement 2 is to perform byte-stuff for any line that begins
            // with a "."
            // so that data is not confused with the end-of-data marker (a
            // "\r\n.\r\n" sequence.
            //
            // The MIME output stream performs those two functions on behalf of
            // the content
            // writer.
            MIMEOutputStream mimeOut = new MIMEOutputStream(outputStream);

            msg.writeTo(mimeOut, new String[] {"Bcc", "Content-Length"});

            // now to finish, we send a CRLF sequence, followed by a ".".
            mimeOut.writeSMTPTerminator();
            // and flush the data to send it along
            mimeOut.flush();
            this.outputStream.flush(); // most of the time MIMEOutputStream#flush does nothing so ensure we actually flush the data
        } catch (IOException e) {
            throw new MessagingException(e.toString());
        } catch (MessagingException e) {
            throw new MessagingException(e.toString());
        }

        // use a longer time out here to give the server time to process the
        // data.
        line = getReply(TIMEOUT * 2);

        if (line.isError()) {
            throw new MessagingException("Error issuing SMTP 'DATA' command: " + line);
        }
    }

    /**
     * Sends the QUIT message and receieves the response
     */
    protected void sendQuit() throws MessagingException {
        // there's yet another property that controls whether we should wait for
        // a reply for a QUIT command. If true, we're suppposed to wait for a response
        // from the QUIT command.  Otherwise we just send the QUIT and bail.  The default
        // is "false"
        if (props.getBooleanProperty(MAIL_SMTP_QUITWAIT, true)) {
            // handle as a real command...we're going to ignore the response.
            sendCommand("QUIT");
        } else {
            // just send the command without waiting for a response.
            sendLine("QUIT");
        }
    }

    /**
     * Sets a receiver address for the current message
     *
     * @param addr
     *            The target address.
     * @param dsn
     *            An optional DSN option appended to the RCPT TO command.
     *
     * @return The status for this particular send operation.
     * @exception MessagingException
     */
    public SendStatus sendRcptTo(InternetAddress addr, String dsn) throws MessagingException {
        // compose the command using the fixed up email address. Normally, this
        // involves adding
        // "<" and ">" around the address.

        StringBuffer command = new StringBuffer();

        // compose the first part of the command
        command.append("RCPT TO: ");
        command.append(fixEmailAddress(addr.getAddress()));

        // if we have DSN information, append it to the command.
        if (dsn != null) {
            command.append(" NOTIFY=");
            command.append(dsn);
        }

        // get a string version of this command.
        String commandString = command.toString();

        SMTPReply line = sendCommand(commandString);

        switch (line.getCode()) {
        // these two are both successful transmissions
        case SMTPReply.COMMAND_ACCEPTED:
        case SMTPReply.ADDRESS_NOT_LOCAL:
            // we get out of here with the status information.
            return new SendStatus(SendStatus.SUCCESS, addr, commandString, line);

        // these are considered invalid address errors
        case SMTPReply.PARAMETER_SYNTAX_ERROR:
        case SMTPReply.INVALID_COMMAND_SEQUENCE:
        case SMTPReply.MAILBOX_NOT_FOUND:
        case SMTPReply.INVALID_MAILBOX:
        case SMTPReply.USER_NOT_LOCAL:
            // we get out of here with the status information.
            return new SendStatus(SendStatus.INVALID_ADDRESS, addr, commandString, line);

        // the command was valid, but something went wrong in the server.
        case SMTPReply.SERVICE_NOT_AVAILABLE:
        case SMTPReply.MAILBOX_BUSY:
        case SMTPReply.PROCESSING_ERROR:
        case SMTPReply.INSUFFICIENT_STORAGE:
        case SMTPReply.MAILBOX_FULL:
            // we get out of here with the status information.
            return new SendStatus(SendStatus.SEND_FAILURE, addr, commandString, line);

        // everything else is considered really bad...
        default:
            // we get out of here with the status information.
            return new SendStatus(SendStatus.GENERAL_ERROR, addr, commandString, line);
        }
    }

    /**
     * Send a command to the server, returning the first response line back as a
     * reply.
     *
     * @param data
     *            The data to send.
     *
     * @return A reply object with the reply line.
     * @exception MessagingException
     */
    protected SMTPReply sendCommand(String data) throws MessagingException {
        sendLine(data);
        return getReply();
    }

    /**
     * Sends a message down the socket and terminates with the appropriate CRLF
     */
    protected void sendLine(String data) throws MessagingException {
        if (socket == null || !socket.isConnected()) {
            throw new MessagingException("no connection");
        }
        try { // don't write it in multiple times, ie build the data + "\r\n" string in memory to not get surprises on servers read() side
            outputStream.write((data + "\r\n").getBytes("ISO8859-1"));
            outputStream.flush();
        } catch (IOException e) {
            throw new MessagingException(e.toString());
        }
    }

    /**
     * Receives one line from the server. A line is a sequence of bytes
     * terminated by a CRLF
     *
     * @return the line from the server as String
     */
    protected String receiveLine() throws MessagingException {
        return receiveLine(TIMEOUT);
    }

    protected SMTPReply getReply() throws MessagingException {
        return getReply(TIMEOUT);
    }

    /**
     * Get a reply line for an SMTP command.
     *
     * @return An SMTP reply object from the stream.
     */
    protected SMTPReply getReply(int timeout) throws MessagingException {
        try {
            lastServerResponse = new SMTPReply(receiveLine(timeout));
            // if the first line we receive is a continuation, continue
            // reading lines until we reach the non-continued one.
            while (lastServerResponse.isContinued()) {
                lastServerResponse.addLine(receiveLine(timeout));
            }
        } catch (MalformedSMTPReplyException e) {
            throw new MessagingException(e.toString());
        }
        return lastServerResponse;
    }

    /**
     * Retrieve the last response received from the SMTP server.
     *
     * @return The raw response string (including the error code) returned from
     *         the SMTP server.
     */
    public SMTPReply getLastServerResponse() {
        return lastServerResponse;
    }


    /**
     * Receives one line from the server. A line is a sequence of bytes
     * terminated by a CRLF
     *
     * @return the line from the server as String
     */
    protected String receiveLine(int delayMillis) throws MessagingException {
        if (socket == null || !socket.isConnected()) {
            throw new MessagingException("no connection");
        }

        int timeout = 0;

        try {
            // for now, read byte for byte, looking for a CRLF
            timeout = socket.getSoTimeout();

            socket.setSoTimeout(delayMillis);

            StringBuffer buff = new StringBuffer();

            int c;
            boolean crFound = false, lfFound = false;

            while ((c = inputStream.read()) != -1 && crFound == false && lfFound == false) {
                // we're looking for a CRLF sequence, so mark each one as seen.
                // Any other
                // character gets appended to the end of the buffer.
                if (c == CR) {
                    crFound = true;
                } else if (c == LF) {
                    lfFound = true;
                } else {
                    buff.append((char) c);
                }
            }

            String line = buff.toString();
            return line;

        } catch (SocketException e) {
            throw new MessagingException(e.toString());
        } catch (IOException e) {
            throw new MessagingException(e.toString());
        } finally {
            try {
                socket.setSoTimeout(timeout);
            } catch (SocketException e) {
                // ignore - was just trying to do the decent thing...
            }
        }
    }

    /**
     * Convert an InternetAddress into a form sendable on an SMTP mail command.
     * InternetAddress.getAddress() generally returns just the address portion
     * of the full address, minus route address markers. We need to ensure we
     * have an address with '<' and '>' delimiters.
     *
     * @param mail
     *            The mail address returned from InternetAddress.getAddress().
     *
     * @return A string formatted for sending.
     */
    protected String fixEmailAddress(String mail) {
        if (mail.charAt(0) == '<') {
            return mail;
        }
        return "<" + mail + ">";
    }

    /**
     * Start the handshake process with the server, including setting up and
     * TLS-level work. At the completion of this task, we should be ready to
     * authenticate with the server, if needed.
     */
    protected boolean sendHandshake() throws MessagingException {
        // check to see what sort of initial handshake we need to make.
        boolean useEhlo = props.getBooleanProperty(MAIL_SMTP_EHLO, true);
        // if we're to use Ehlo, send it and then fall back to just a HELO
        // message if it fails.
        if (useEhlo) {
            if (!sendEhlo()) {
                sendHelo();
            }
        } else {
            // send the initial hello response.
            sendHelo();
        }

        if (useTLS || requireTLS) {
            // if we've been told to use TLS
            // if its not required and server does not support it we establish an unsecure connection
            //see GERONIMO-5873 and GERONIMO-5430
            if (requireTLS && !serverTLS) {
                // if we've been told to use TLS, and this server doesn't support
                // it, then this is a failure
                throw new MessagingException("Server doesn't support required transport level security");
            } else if (serverTLS){
                // if the server supports TLS, then use it for the connection.
                // on our connection.
                getConnectedTLSSocket();

                // some servers (gmail is one that I know of) only send a STARTTLS
                // extension message on the
                // first EHLO command. Now that we have the TLS handshaking
                // established, we need to send a
                // second EHLO message to retrieve the AUTH records from the server.
                if (!sendEhlo()) {
                    throw new MessagingException("Failure sending EHLO command to SMTP server");
                }
            } else {
                if (debug) {
                    debugOut("STARTTLS is enabled but not required and server does not support it. So we establish a connection without transport level security");
                }
            }
        }

        // this worked.
        return true;
    }


    /**
     * Switch the connection to using TLS level security, switching to an SSL
     * socket.
     */
    protected void getConnectedTLSSocket() throws MessagingException {
        debugOut("Attempting to negotiate STARTTLS with server " + serverHost);
        // tell the server of our intention to start a TLS session
        SMTPReply line = sendCommand("STARTTLS");

        if (line.getCode() != SMTPReply.SERVICE_READY) {
            debugOut("STARTTLS command rejected by SMTP server " + serverHost);
            throw new MessagingException("Unable to make TLS server connection");
        }

        debugOut("STARTTLS command accepted");

        // the base class handles the socket switch details
        super.getConnectedTLSSocket();
    }


    /**
     * Send the EHLO command to the SMTP server.
     *
     * @return True if the command was accepted ok, false for any errors.
     * @exception SMTPTransportException
     * @exception MalformedSMTPReplyException
     * @exception MessagingException
     */
    protected boolean sendEhlo() throws MessagingException {
        sendLine("EHLO " + getLocalHost());

        SMTPReply reply = getReply();

        // we get a 250 code back. The first line is just a greeting, and
        // extensions are identifed on
        // continuations. If this fails, then we'll try once more with HELO to
        // establish bona fides.
        if (reply.getCode() != SMTPReply.COMMAND_ACCEPTED) {
            return false;
        }

        // create a fresh mapping and authentications table
        capabilities = new HashMap();
        authentications = new ArrayList();

        List lines = reply.getLines();
        // process all of the continuation lines
        for (int i = 1; i < lines.size(); i++) {
            // go process the extention
            processExtension((String)lines.get(i));
        }
        return true;
    }

    /**
     * Send the HELO command to the SMTP server.
     *
     * @exception MessagingException
     */
    protected void sendHelo() throws MessagingException {
        // create a fresh mapping and authentications table
        // these will be empty, but it will prevent NPEs
        capabilities = new HashMap();
        authentications = new ArrayList();

        sendLine("HELO " + getLocalHost());

        SMTPReply line = getReply();

        // we get a 250 code back. The first line is just a greeting, and
        // extensions are identifed on
        // continuations. If this fails, then we'll try once more with HELO to
        // establish bona fides.
        if (line.getCode() != SMTPReply.COMMAND_ACCEPTED) {
            throw new MessagingException("Failure sending HELO command to SMTP server");
        }
    }

    /**
     * Return the current startTLS property.
     *
     * @return The current startTLS property.
     */
    public boolean getStartTLS() {
        return useTLS;
    }


    /**
     * Set a new value for the startTLS property.
     *
     * @param start
     *            The new setting.
     */
    public void setStartTLS(boolean start) {
        useTLS = start;
    }

    
    /**
     * Return the current requireTLS property.
     * 
     * @return The current requireTLS property.
     */
    public boolean getRequireTLS() {
        return requireTLS;
    }


    /**
     * Set a new value for the requireTLS property.
     * 
     * @param require
     *                  The new setting.
     */
    public void setRequireTLS(boolean require) {
        requireTLS = require;
    }


    /**
     * Process an extension string passed back as the EHLP response.
     *
     * @param extension
     *            The string value of the extension (which will be of the form
     *            "NAME arguments").
     */
    protected void processExtension(String extension) {
        debugOut("Processing extension " + extension);
        String extensionName = extension.toUpperCase();
        String argument = "";

        int delimiter = extension.indexOf(' ');
        // if we have a keyword with arguments, parse them out and add to the
        // argument map.
        if (delimiter != -1) {
            extensionName = extension.substring(0, delimiter).toUpperCase();
            argument = extension.substring(delimiter + 1);
        }

        // add this to the map so it can be tested later.
        capabilities.put(extensionName, argument);

        // process a few special ones that don't require extra parsing.
        // AUTH and AUTH=LOGIN are handled the same
        if (extensionName.equals("AUTH")) {
            // if we don't have an argument on AUTH, this means LOGIN.
            if (argument == null) {
                authentications.add("LOGIN");
            } else {
                // The security mechanisms are blank delimited tokens.
                StringTokenizer tokenizer = new StringTokenizer(argument);

                while (tokenizer.hasMoreTokens()) {
                    String mechanism = tokenizer.nextToken().toUpperCase();
                    authentications.add(mechanism);
                }
            }
        }
        // special case for some older servers.
        else if (extensionName.equals("AUTH=LOGIN")) {
            authentications.add("LOGIN");
        }
        // does this support transport level security?
        else if (extensionName.equals("STARTTLS")) {
            // flag this for later
            serverTLS = true;
        }
    }


    /**
     * Retrieve any argument information associated with a extension reported
     * back by the server on the EHLO command.
     *
     * @param name
     *            The name of the target server extension.
     *
     * @return Any argument passed on a server extension. Returns null if the
     *         extension did not include an argument or the extension was not
     *         supported.
     */
    public String extensionParameter(String name) {
        if (capabilities != null) {
            return (String)capabilities.get(name);
        }
        return null;
    }


    /**
     * Tests whether the target server supports a named extension.
     *
     * @param name
     *            The target extension name.
     *
     * @return true if the target server reported on the EHLO command that is
     *         supports the targer server, false if the extension was not
     *         supported.
     */
    public boolean supportsExtension(String name) {
        // this only returns null if we don't have this extension
        return extensionParameter(name) != null;
    }


    /**
     * Authenticate with the server, if necessary (or possible).
     *
     * @return true if we are ok to proceed, false for an authentication
     *         failures.
     */
    protected boolean processAuthentication() throws MessagingException {
        // no authentication defined?
        if (!props.getBooleanProperty(MAIL_SMTP_AUTH, false)) {
            return true;
        }

        // we need to authenticate, but we don't have userid/password
        // information...fail this
        // immediately.
        if (username == null || password == null) {
            return false;
        }

        // if unable to get an appropriate authenticator, just fail it.
        ClientAuthenticator authenticator = getSaslAuthenticator();
        if (authenticator == null) {
            throw new MessagingException("Unable to obtain SASL authenticator");
        }


        if (debug) {
            debugOut("Authenticating for user: " + username + " using " + authenticator.getMechanismName());
        }

        // if the authenticator has some initial data, we compose a command
        // containing the initial data.
        if (authenticator.hasInitialResponse()) {
            StringBuffer command = new StringBuffer();
            // the auth command initiates the handshaking.
            command.append("AUTH ");
            // and tell the server which mechanism we're using.
            command.append(authenticator.getMechanismName());
            command.append(" ");
            // and append the response data
            try {
                command.append(new String(Base64.encode(authenticator.evaluateChallenge(null)), "US-ASCII"));
            } catch (UnsupportedEncodingException e) {
            }
            // send the command now
            sendLine(command.toString());
        }
        // we just send an auth command with the command type.
        else {
            StringBuffer command = new StringBuffer();
            // the auth command initiates the handshaking.
            command.append("AUTH ");
            // and tell the server which mechanism we're using.
            command.append(authenticator.getMechanismName());
            // send the command now
            sendLine(command.toString());
        }

        // now process the challenge sequence. We get a 235 response back when
        // the server accepts the
        // authentication, and a 334 indicates we have an additional challenge.
        while (true) {
            // get the next line, and if it is an error response, return now.
            SMTPReply line;
            try {
                line = new SMTPReply(receiveLine());
            } catch (MalformedSMTPReplyException e) {
                throw new MessagingException(e.toString());
            } catch (MessagingException e) {
                throw e;
            }

            // if we get a completion return, we've passed muster, so give an
            // authentication response.
            if (line.getCode() == SMTPReply.AUTHENTICATION_COMPLETE) {
                debugOut("Successful SMTP authentication");
                return true;
            }
            // we have an additional challenge to process.
            else if (line.getCode() == SMTPReply.AUTHENTICATION_CHALLENGE) {
                // Does the authenticator think it is finished? We can't answer
                // an additional challenge,
                // so fail this.
                if (authenticator.isComplete()) {
                    return false;
                }

                try {
                    // we're passed back a challenge value, Base64 encoded.
                    byte[] challenge = Base64.decode(line.getMessage().getBytes("ISO8859-1"));

                    // have the authenticator evaluate and send back the encoded
                    // response.
                    sendLine(new String(Base64.encode(authenticator.evaluateChallenge(challenge)), "US-ASCII"));
                } catch (UnsupportedEncodingException e) {
                }
            }
            // completion or challenge are the only responses we know how to
            // handle. Anything else must
            // be a failure.
            else {
                if (debug) {
                    debugOut("Authentication failure " + line);
                }
                return false;
            }
        }
    }


    /**
     * Attempt to retrieve a SASL authenticator for this
     * protocol.
     *
     * @return A SASL authenticator, or null if a suitable one
     *         was not located.
     */
    protected ClientAuthenticator getSaslAuthenticator() {
        return AuthenticatorFactory.getAuthenticator(props, selectSaslMechanisms(), serverHost, username, password, authid, realm);
    }


    /**
     * Read the bytes in a stream a test to see if this
     * conforms to the RFC 2045 rules for 8bit encoding.
     *
     * 1)  No more than 998 bytes long
     * 2)  All lines are terminated with CRLF sequences
     * 3)  CR and LF characters only occur in properly
     * formed line separators
     * 4)  No null characters are allowed.
     *
     * @param inStream The source input stream.
     *
     * @return true if this can be transmitted successfully
     *         using 8bit encoding, false if an alternate encoding
     *         will be required.
     */
    protected boolean isValid8bit(InputStream inStream) {
        try {
            int ch;
            int lineLength = 0;
            while ((ch = inStream.read()) >= 0) {
                // nulls are decidedly not allowed
                if (ch == 0) {
                    return false;
                }
                // start of a CRLF sequence (potentially)
                else if (ch == '\r') {
                    // check the next character.  There must be one,
                    // and it must be a LF for this to be value
                    ch = inStream.read();
                    if (ch != '\n') {
                        return false;
                    }
                    // reset the line length
                    lineLength = 0;
                }
                else {
                    // a normal character
                    lineLength++;
                    // make sure the line is not too long
                    if (lineLength > 998) {
                        return false;
                    }
                }

            }
        } catch (IOException e) {
            return false;  // can't read this, don't try passing it
        }
        // this converted ok
        return true;
    }


    /**
     * Simple holder class for the address/send status duple, as we can have
     * mixed success for a set of addresses and a message
     */
    static public class SendStatus {
        public final static int SUCCESS = 0;

        public final static int INVALID_ADDRESS = 1;

        public final static int SEND_FAILURE = 2;

        public final static int GENERAL_ERROR = 3;

        // the status type of the send operation.
        int status;

        // the address associated with this status
        InternetAddress address;

        // the command string send to the server.
        String cmd;

        // the reply from the server.
        SMTPReply reply;

        /**
         * Constructor for a SendStatus item.
         *
         * @param s
         *            The status type.
         * @param a
         *            The address this is the status for.
         * @param c
         *            The command string associated with this status.
         * @param r
         *            The reply information from the server.
         */
        public SendStatus(int s, InternetAddress a, String c, SMTPReply r) {
            this.cmd = c;
            this.status = s;
            this.address = a;
            this.reply = r;
        }

        /**
         * Get the status information for this item.
         *
         * @return The current status code.
         */
        public int getStatus() {
            return this.status;
        }

        /**
         * Retrieve the InternetAddress object associated with this send
         * operation.
         *
         * @return The associated address object.
         */
        public InternetAddress getAddress() {
            return this.address;
        }

        /**
         * Retrieve the reply information associated with this send operati
         *
         * @return The SMTPReply object received for the operation.
         */
        public SMTPReply getReply() {
            return reply;
        }

        /**
         * Get the command string sent for this send operation.
         *
         * @return The command string for the MAIL TO command sent to the
         *         server.
         */
        public String getCommand() {
            return cmd;
        }

        /**
         * Get an exception object associated with this send operation. There is
         * a mechanism for reporting send success via a send operation, so this
         * will be either a success or failure exception.
         *
         * @param reportSuccess
         *            Indicates if we want success operations too.
         *
         * @return A newly constructed exception object.
         */
        public MessagingException getException(boolean reportSuccess) {
            if (status != SUCCESS) {
                return new SMTPAddressFailedException(address, cmd, reply.getCode(), reply.getMessage());
            } else {
                if (reportSuccess) {
                    return new SMTPAddressSucceededException(address, cmd, reply.getCode(), reply.getMessage());
                }
            }
            return null;
        }
    }


    /**
     * Reset the server connection after an error.
     *
     * @exception MessagingException
     */
    public void resetConnection() throws MessagingException {
        // we want the caller to retrieve the last response responsbile for
        // requiring the reset, so save and
        // restore that info around the reset.
        SMTPReply last = lastServerResponse;

        // send a reset command.
        SMTPReply line = sendCommand("RSET");

        // if this did not reset ok, just close the connection
        if (line.getCode() != SMTPReply.COMMAND_ACCEPTED) {
            close();
        }
        // restore this.
        lastServerResponse = last;
    }


    /**
     * Return the current reportSuccess property.
     *
     * @return The current reportSuccess property.
     */
    public boolean getReportSuccess() {
        return reportSuccess;
    }

    /**
     * Set a new value for the reportSuccess property.
     *
     * @param report
     *            The new setting.
     */
    public void setReportSuccess(boolean report) {
        reportSuccess = report;
    }
}

