geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rickmcgu...@apache.org
Subject svn commit: r946314 [4/5] - in /geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src: main/java/org/apache/geronimo/javamail/authentication/ main/java/org/apache/geronimo/javamail/store/imap/ main/java/org/apache/geronimo/ja...
Date Wed, 19 May 2010 18:01:55 GMT
Modified: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseStream.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseStream.java?rev=946314&r1=946313&r2=946314&view=diff
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseStream.java (original)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseStream.java Wed May 19 18:01:55 2010
@@ -20,62 +20,63 @@ package org.apache.geronimo.javamail.sto
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
 
-import javax.mail.MessagingException; 
-import javax.mail.event.FolderEvent; 
+import javax.mail.MessagingException;
+import javax.mail.event.FolderEvent;
 
 import org.apache.geronimo.javamail.store.imap.connection.IMAPResponseTokenizer.Token;
 import org.apache.geronimo.javamail.util.ConnectionException;
 
 public class IMAPResponseStream {
-    protected final int BUFFER_SIZE = 1024;   
-    
+    protected final int BUFFER_SIZE = 1024;
+
     // our source input stream
     protected InputStream in;
-    // The response buffer 
-    IMAPResponseBuffer out; 
-    // the buffer array 
-    protected byte[] buffer = new byte[BUFFER_SIZE]; 
-    // the current buffer position 
-    int position; 
-    // the current buffer read length 
-    int length; 
+    // The response buffer
+    IMAPResponseBuffer out;
+    // the buffer array
+    protected byte[] buffer = new byte[BUFFER_SIZE];
+    // the current buffer position
+    int position;
+    // the current buffer read length
+    int length;
 
     public IMAPResponseStream(InputStream in) {
         this.in = in;
         out = new IMAPResponseBuffer();
     }
-    
+
     public int read() throws IOException {
-        // if we can't read any more, that's an EOF condition. 
+        // if we can't read any more, that's an EOF condition.
         if (!fillBufferIfNeeded()) {
-            return -1; 
+            return -1;
         }
-        // just grab the next character 
-        return buffer[position++]; 
+        // just grab the next character
+        return buffer[position++];
     }
-    
+
     protected boolean fillBufferIfNeeded() throws IOException {
         // used up all of the data in the buffer?
         if (position >= length) {
-            int readLength = 0; 
-            // a read from a network connection can return 0 bytes, 
-            // so we need to be prepared to handle a spin loop.  
+            int readLength = 0;
+            // a read from a network connection can return 0 bytes,
+            // so we need to be prepared to handle a spin loop.
             while (readLength == 0) {
-                readLength = in.read(buffer, 0, buffer.length); 
+                readLength = in.read(buffer, 0, buffer.length);
             }
-            // we may have hit the EOF.  Indicate the read failure   
+            // we may have hit the EOF.  Indicate the read failure
             if (readLength == -1) {
-                return false; 
+                return false;
             }
-            // set our new buffer positions. 
-            position = 0; 
-            length = readLength; 
+            // set our new buffer positions.
+            position = 0;
+            length = readLength;
         }
-        return true; 
+        return true;
     }
 
 
@@ -86,180 +87,180 @@ public class IMAPResponseStream {
      * @return A parsed IMAPResponse item using the response data.
      * @exception MessagingException
      */
-    public IMAPResponse readResponse() throws MessagingException  
-      {  
-        // reset our accumulator 
-        out.reset(); 
+    public IMAPResponse readResponse() throws MessagingException
+      {
+        // reset our accumulator
+        out.reset();
         // now read a buffer of data
         byte[] data = readData();
-        
+
         // and create a tokenizer for parsing this down.
         IMAPResponseTokenizer tokenizer = new IMAPResponseTokenizer(data);
         // get the first token.
         Token token = tokenizer.next();
-        
-        int type = token.getType(); 
-        
-        // a continuation response.  This will terminate a response set. 
+
+        int type = token.getType();
+
+        // a continuation response.  This will terminate a response set.
         if (type == Token.CONTINUATION) {
-            return new IMAPContinuationResponse(data); 
+            return new IMAPContinuationResponse(data);
         }
-        // unsolicited response.  There are multiple forms of these, which might actually be 
-        // part of the response for the last issued command. 
+        // unsolicited response.  There are multiple forms of these, which might actually be
+        // part of the response for the last issued command.
         else if (type == Token.UNTAGGED) {
             // step to the next token, which will give us the type
-            token = tokenizer.next(); 
-            // if the token is numeric, then this is a size response in the 
+            token = tokenizer.next();
+            // if the token is numeric, then this is a size response in the
             // form "* nn type"
             if (token.isType(Token.NUMERIC)) {
-                int size = token.getInteger(); 
-                
-                token = tokenizer.next(); 
-                
-                String keyword = token.getValue(); 
-                
-                // FETCH responses require fairly complicated parsing.  Other 
-                // size/message updates are fairly generic. 
+                int size = token.getInteger();
+
+                token = tokenizer.next();
+
+                String keyword = token.getValue();
+
+                // FETCH responses require fairly complicated parsing.  Other
+                // size/message updates are fairly generic.
                 if (keyword.equals("FETCH")) {
-                    return new IMAPFetchResponse(size, data, tokenizer); 
+                    return new IMAPFetchResponse(size, data, tokenizer);
                 }
-                return new IMAPSizeResponse(keyword, size, data); 
+                return new IMAPSizeResponse(keyword, size, data);
             }
-            
-            // this needs to be an ATOM type, which will tell us what format this untagged 
-            // response is in.  There are many different untagged formats, some general, some 
-            // specific to particular command types. 
+
+            // this needs to be an ATOM type, which will tell us what format this untagged
+            // response is in.  There are many different untagged formats, some general, some
+            // specific to particular command types.
             if (token.getType() != Token.ATOM) {
-                throw new MessagingException("Unknown server response: " + new String(data)); 
+                throw new MessagingException("Unknown server response: " + new String(data, Charset.forName("ISO8859-1")));
             }
-            
-            String keyword = token.getValue(); 
-            // many response are in the form "* OK [keyword value] message". 
+
+            String keyword = token.getValue();
+            // many response are in the form "* OK [keyword value] message".
             if (keyword.equals("OK")) {
-                return parseUntaggedOkResponse(data, tokenizer); 
+                return parseUntaggedOkResponse(data, tokenizer);
             }
-            // preauth status response 
+            // preauth status response
             else if (keyword.equals("PREAUTH")) {
-                return new IMAPServerStatusResponse("PREAUTH", tokenizer.getRemainder(), data); 
+                return new IMAPServerStatusResponse("PREAUTH", tokenizer.getRemainder(), data);
             }
-            // preauth status response 
+            // preauth status response
             else if (keyword.equals("BYE")) {
-                return new IMAPServerStatusResponse("BYE", tokenizer.getRemainder(), data); 
+                return new IMAPServerStatusResponse("BYE", tokenizer.getRemainder(), data);
             }
             else if (keyword.equals("BAD")) {
-                // these are generally ignored. 
-                return new IMAPServerStatusResponse("BAD", tokenizer.getRemainder(), data); 
+                // these are generally ignored.
+                return new IMAPServerStatusResponse("BAD", tokenizer.getRemainder(), data);
             }
             else if (keyword.equals("NO")) {
-                // these are generally ignored. 
-                return new IMAPServerStatusResponse("NO", tokenizer.getRemainder(), data); 
+                // these are generally ignored.
+                return new IMAPServerStatusResponse("NO", tokenizer.getRemainder(), data);
             }
-            // a complex CAPABILITY response 
+            // a complex CAPABILITY response
             else if (keyword.equals("CAPABILITY")) {
-                return new IMAPCapabilityResponse(tokenizer, data); 
+                return new IMAPCapabilityResponse(tokenizer, data);
             }
-            // a complex LIST response 
+            // a complex LIST response
             else if (keyword.equals("LIST")) {
-                return new IMAPListResponse("LIST", data, tokenizer); 
+                return new IMAPListResponse("LIST", data, tokenizer);
             }
-            // a complex FLAGS response 
+            // a complex FLAGS response
             else if (keyword.equals("FLAGS")) {
-                // parse this into a flags set. 
-                return new IMAPFlagsResponse(data, tokenizer); 
+                // parse this into a flags set.
+                return new IMAPFlagsResponse(data, tokenizer);
             }
             // a complex LSUB response (identical in format to LIST)
             else if (keyword.equals("LSUB")) {
-                return new IMAPListResponse("LSUB", data, tokenizer); 
+                return new IMAPListResponse("LSUB", data, tokenizer);
             }
-            // a STATUS response, which will contain a list of elements 
+            // a STATUS response, which will contain a list of elements
             else if (keyword.equals("STATUS")) {
-                return new IMAPStatusResponse(data, tokenizer); 
+                return new IMAPStatusResponse(data, tokenizer);
             }
-            // SEARCH requests return an variable length list of message matches. 
+            // SEARCH requests return an variable length list of message matches.
             else if (keyword.equals("SEARCH")) {
-                return new IMAPSearchResponse(data, tokenizer); 
+                return new IMAPSearchResponse(data, tokenizer);
             }
-            // ACL requests return an variable length list of ACL values . 
+            // ACL requests return an variable length list of ACL values .
             else if (keyword.equals("ACL")) {
-                return new IMAPACLResponse(data, tokenizer); 
+                return new IMAPACLResponse(data, tokenizer);
             }
-            // LISTRIGHTS requests return a variable length list of RIGHTS values . 
+            // LISTRIGHTS requests return a variable length list of RIGHTS values .
             else if (keyword.equals("LISTRIGHTS")) {
-                return new IMAPListRightsResponse(data, tokenizer); 
+                return new IMAPListRightsResponse(data, tokenizer);
             }
-            // MYRIGHTS requests return a list of user rights for a mailbox name. 
+            // MYRIGHTS requests return a list of user rights for a mailbox name.
             else if (keyword.equals("MYRIGHTS")) {
-                return new IMAPMyRightsResponse(data, tokenizer); 
+                return new IMAPMyRightsResponse(data, tokenizer);
             }
-            // QUOTAROOT requests return a list of mailbox quota root names  
+            // QUOTAROOT requests return a list of mailbox quota root names
             else if (keyword.equals("QUOTAROOT")) {
-                return new IMAPQuotaRootResponse(data, tokenizer); 
+                return new IMAPQuotaRootResponse(data, tokenizer);
             }
-            // QUOTA requests return a list of quota values for a root name  
+            // QUOTA requests return a list of quota values for a root name
             else if (keyword.equals("QUOTA")) {
-                return new IMAPQuotaResponse(data, tokenizer); 
+                return new IMAPQuotaResponse(data, tokenizer);
             }
             else if (keyword.equals("NAMESPACE")) {
-                return new IMAPNamespaceResponse(data, tokenizer); 
+                return new IMAPNamespaceResponse(data, tokenizer);
             }
         }
-        // begins with a word, this should be the tagged response from the last command. 
+        // begins with a word, this should be the tagged response from the last command.
         else if (type == Token.ATOM) {
-            String tag = token.getValue(); 
-            token = tokenizer.next(); 
-            String status = token.getValue(); 
-            // primary information in one of these is the status field, which hopefully 
+            String tag = token.getValue();
+            token = tokenizer.next();
+            String status = token.getValue();
+            // primary information in one of these is the status field, which hopefully
             // is 'OK'
-            return new IMAPTaggedResponse(tag, status, tokenizer.getRemainder(), data); 
+            return new IMAPTaggedResponse(tag, status, tokenizer.getRemainder(), data);
         }
-        throw new MessagingException("Unknown server response: " + new String(data)); 
+        throw new MessagingException("Unknown server response: " + new String(data, Charset.forName("ISO8859-1")));
     }
-    
+
     /**
-     * Parse an unsolicited OK status response.  These 
+     * Parse an unsolicited OK status response.  These
      * responses are of the form:
-     * 
+     *
      * * OK [keyword arguments ...] message
-     * 
-     * The part in the brackets are optional, but 
+     *
+     * The part in the brackets are optional, but
      * most OK messages will have some sort of update.
-     * 
+     *
      * @param data      The raw message data
      * @param tokenizer The tokenizer being used for this message.
-     * 
-     * @return An IMAPResponse instance for this message. 
+     *
+     * @return An IMAPResponse instance for this message.
      */
     private IMAPResponse parseUntaggedOkResponse(byte [] data, IMAPResponseTokenizer tokenizer) throws MessagingException {
-        Token token = tokenizer.peek(); 
-        // we might have an optional value here 
+        Token token = tokenizer.peek();
+        // we might have an optional value here
         if (token.getType() != '[') {
-            // this has no tagging item, so there's nothing to be processed 
-            // later. 
-            return new IMAPOkResponse("OK", null, tokenizer.getRemainder(), data); 
+            // this has no tagging item, so there's nothing to be processed
+            // later.
+            return new IMAPOkResponse("OK", null, tokenizer.getRemainder(), data);
         }
         // skip over the "[" token
-        tokenizer.next(); 
-        token = tokenizer.next(); 
-        String keyword = token.getValue(); 
-        
-        // Permanent flags gets special handling 
+        tokenizer.next();
+        token = tokenizer.next();
+        String keyword = token.getValue();
+
+        // Permanent flags gets special handling
         if (keyword.equals("PERMANENTFLAGS")) {
-            return new IMAPPermanentFlagsResponse(data, tokenizer); 
+            return new IMAPPermanentFlagsResponse(data, tokenizer);
         }
-        
-        ArrayList arguments = new ArrayList(); 
-        
-        // strip off all of the argument tokens until the "]" list terminator. 
-        token = tokenizer.next(); 
+
+        ArrayList arguments = new ArrayList();
+
+        // strip off all of the argument tokens until the "]" list terminator.
+        token = tokenizer.next();
         while (token.getType() != ']') {
-            arguments.add(token); 
-            token = tokenizer.next(); 
+            arguments.add(token);
+            token = tokenizer.next();
         }
-        // this has a tagged keyword and arguments that will be processed later. 
-        return new IMAPOkResponse(keyword, arguments, tokenizer.getRemainder(), data); 
+        // this has a tagged keyword and arguments that will be processed later.
+        return new IMAPOkResponse(keyword, arguments, tokenizer.getRemainder(), data);
     }
 
-    
+
     /**
      * Read a "line" of server response data.  An individual line
      * may span multiple line breaks, depending on syntax implications.
@@ -322,7 +323,7 @@ public class IMAPResponseStream {
         try {
             // see if we have a literal length signature at the end.
             int length = out.getLiteralLength();
-            
+
             // -1 means no literal length, so we're done reading this particular response.
             if (length == -1) {
                 return;
@@ -341,11 +342,11 @@ public class IMAPResponseStream {
                 // The InputStream can return less than the requested length if it needs to block.
                 // This may take a couple iterations to get everything, particularly if it's long.
                 while (length > 0) {
-                    int read = -1; 
+                    int read = -1;
                     try {
                         read = in.read(bytes, offset, length);
                     } catch (IOException e) {
-                        throw new MessagingException("Unexpected read error on server connection", e); 
+                        throw new MessagingException("Unexpected read error on server connection", e);
                     }
                     // premature EOF we can't ignore.
                     if (read == -1) {
@@ -362,7 +363,7 @@ public class IMAPResponseStream {
             // additional literals).  Just recurse on the line reading logic.
             readBuffer();
         } catch (IOException e) {
-            e.printStackTrace(); 
+            e.printStackTrace();
             // this is a byte array output stream...should never happen
         }
     }

Modified: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java?rev=946314&r1=946313&r2=946314&view=diff
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java (original)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java Wed May 19 18:01:55 2010
@@ -19,6 +19,7 @@ package org.apache.geronimo.javamail.sto
 
 import java.io.ByteArrayOutputStream;
 import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
@@ -186,7 +187,7 @@ public class IMAPResponseTokenizer {
             return "";
         }
 
-        return new String(response, pos, response.length - pos);
+        return new String(response, pos, response.length - pos, Charset.forName("ISO8859-1"));
     }
 
 
@@ -236,7 +237,7 @@ public class IMAPResponseTokenizer {
         }
 
         // Numeric tokens we store as a different type.
-        String value = new String(response, start, pos - start);
+        String value = new String(response, start, pos - start, Charset.forName("ISO8859-1"));
         try {
             int intValue = Integer.parseInt(value);
             return new Token(Token.NUMERIC, value);
@@ -376,7 +377,7 @@ public class IMAPResponseTokenizer {
      */
     private Token readQuotedString() throws MessagingException {
 
-        String value = new String(readQuotedStringData());
+        String value = new String(readQuotedStringData(), Charset.forName("ISO8859-1"));
         return new Token(Token.QUOTEDSTRING, value);
     }
 
@@ -428,7 +429,7 @@ public class IMAPResponseTokenizer {
      * @exception ResponseFormatException
      */
     protected Token readLiteral() throws MessagingException {
-        String value = new String(readLiteralData());
+        String value = new String(readLiteralData(), Charset.forName("ISO8859-1"));
         return new Token(Token.LITERAL, value);
     }
 
@@ -480,7 +481,7 @@ public class IMAPResponseTokenizer {
      * @return A String extracted from the buffer.
      */
     protected String substring(int start, int end ) {
-        return new String(response, start, end - start);
+        return new String(response, start, end - start, Charset.forName("ISO8859-1"));
     }
 
 

Modified: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3Connection.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3Connection.java?rev=946314&r1=946313&r2=946314&view=diff
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3Connection.java (original)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/connection/POP3Connection.java Wed May 19 18:01:55 2010
@@ -22,6 +22,7 @@ import java.net.InetAddress;
 import java.net.Socket;
 import java.net.SocketException;
 import java.net.UnknownHostException;
+import java.nio.charset.Charset;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
@@ -35,48 +36,48 @@ import java.util.StringTokenizer;
 import javax.mail.MessagingException;
 import javax.mail.internet.InternetHeaders;
 
-import org.apache.geronimo.javamail.authentication.AuthenticatorFactory; 
+import org.apache.geronimo.javamail.authentication.AuthenticatorFactory;
 import org.apache.geronimo.javamail.authentication.ClientAuthenticator;
-import org.apache.geronimo.javamail.store.pop3.POP3Constants;         
-import org.apache.geronimo.javamail.util.CommandFailedException;      
-import org.apache.geronimo.javamail.util.InvalidCommandException;      
+import org.apache.geronimo.javamail.store.pop3.POP3Constants;
+import org.apache.geronimo.javamail.util.CommandFailedException;
+import org.apache.geronimo.javamail.util.InvalidCommandException;
 import org.apache.geronimo.javamail.util.MIMEInputReader;
-import org.apache.geronimo.javamail.util.MailConnection; 
-import org.apache.geronimo.javamail.util.ProtocolProperties; 
+import org.apache.geronimo.javamail.util.MailConnection;
+import org.apache.geronimo.javamail.util.ProtocolProperties;
 import org.apache.geronimo.mail.util.Base64;
 import org.apache.geronimo.mail.util.Hex;
 
 /**
- * Simple implementation of POP3 transport.  
+ * Simple implementation of POP3 transport.
  *
  * @version $Rev$ $Date$
  */
 public class POP3Connection extends MailConnection implements POP3Constants {
-    
-    static final protected String MAIL_APOP_ENABLED = "apop.enable"; 
-    static final protected String MAIL_AUTH_ENABLED = "auth.enable"; 
-    static final protected String MAIL_RESET_QUIT = "rsetbeforequit"; 
+
+    static final protected String MAIL_APOP_ENABLED = "apop.enable";
+    static final protected String MAIL_AUTH_ENABLED = "auth.enable";
+    static final protected String MAIL_RESET_QUIT = "rsetbeforequit";
     static final protected String MAIL_DISABLE_TOP = "disabletop";
-    static final protected String MAIL_FORGET_TOP = "forgettopheaders"; 
-    
-    // the initial greeting string, which might be required for APOP authentication. 
-    protected String greeting; 
-    // is use of the AUTH command enabled 
-    protected boolean authEnabled; 
-    // is use of APOP command enabled 
-    protected boolean apopEnabled; 
-    // input reader wrapped around the socket input stream 
-    protected BufferedReader reader; 
-    // output writer wrapped around the socket output stream. 
-    protected PrintWriter writer; 
+    static final protected String MAIL_FORGET_TOP = "forgettopheaders";
+
+    // the initial greeting string, which might be required for APOP authentication.
+    protected String greeting;
+    // is use of the AUTH command enabled
+    protected boolean authEnabled;
+    // is use of APOP command enabled
+    protected boolean apopEnabled;
+    // input reader wrapped around the socket input stream
+    protected BufferedReader reader;
+    // output writer wrapped around the socket output stream.
+    protected PrintWriter writer;
     // this connection was closed unexpectedly
     protected boolean closed;
-    // indicates whether this conneciton is currently logged in.  Once 
-    // we send a QUIT, we're finished. 
-    protected boolean loggedIn; 
-    // indicates whether we need to avoid using the TOP command 
+    // indicates whether this conneciton is currently logged in.  Once
+    // we send a QUIT, we're finished.
+    protected boolean loggedIn;
+    // indicates whether we need to avoid using the TOP command
     // when retrieving headers
-    protected boolean topDisabled = false; 
+    protected boolean topDisabled = false;
 
     /**
      * Normal constructor for an POP3Connection() object.
@@ -95,40 +96,40 @@ public class POP3Connection extends Mail
      */
     public POP3Connection(ProtocolProperties props) {
         super(props);
-        
-        // get our login properties flags 
-        authEnabled = props.getBooleanProperty(MAIL_AUTH_ENABLED, false); 
-        apopEnabled = props.getBooleanProperty(MAIL_APOP_ENABLED, false); 
-        topDisabled = props.getBooleanProperty(MAIL_DISABLE_TOP, false); 
+
+        // get our login properties flags
+        authEnabled = props.getBooleanProperty(MAIL_AUTH_ENABLED, false);
+        apopEnabled = props.getBooleanProperty(MAIL_APOP_ENABLED, false);
+        topDisabled = props.getBooleanProperty(MAIL_DISABLE_TOP, false);
     }
 
-                          
+
     /**
      * Connect to the server and do the initial handshaking.
      *
      * @exception MessagingException
      */
     public boolean protocolConnect(String host, int port, String authid, String realm, String username, String password) throws MessagingException {
-        this.serverHost = host; 
-        this.serverPort = port; 
-        this.realm = realm; 
-        this.authid = authid; 
-        this.username = username; 
-        this.password = password; 
-        
+        this.serverHost = host;
+        this.serverPort = port;
+        this.realm = realm;
+        this.authid = authid;
+        this.username = username;
+        this.password = password;
+
         try {
             // create socket and connect to server.
             getConnection();
-            // consume the welcome line 
-            getWelcome(); 
+            // consume the welcome line
+            getWelcome();
 
-            // go login with the server 
-            if (login())  
+            // go login with the server
+            if (login())
             {
-                loggedIn = true; 
+                loggedIn = true;
                 return true;
             }
-            return false; 
+            return false;
         } catch (IOException e) {
             if (debug) {
                 debugOut("I/O exception establishing connection", e);
@@ -147,23 +148,25 @@ public class POP3Connection extends Mail
     protected void getConnection() throws MessagingException
     {
         try {
-            // do all of the non-protocol specific set up.  This will get our socket established 
-            // and ready use. 
-            super.getConnection(); 
+            // do all of the non-protocol specific set up.  This will get our socket established
+            // and ready use.
+            super.getConnection();
         } catch (IOException e) {
-            throw new MessagingException("Unable to obtain a connection to the POP3 server", e); 
+            throw new MessagingException("Unable to obtain a connection to the POP3 server", e);
         }
-        
-        // The POp3 protocol is inherently a string-based protocol, so we get 
-        // string readers/writers for the connection streams 
-        reader = new BufferedReader(new InputStreamReader(inputStream));
-        writer = new PrintWriter(new BufferedOutputStream(outputStream));
+
+        // The POp3 protocol is inherently a string-based protocol, so we get
+        // string readers/writers for the connection streams.  Note that we explicitly
+        // set the encoding to ensure that an inappropriate native encoding is not picked up.
+        Charset iso88591 = Charset.forName("ISO8859-1");
+        reader = new BufferedReader(new InputStreamReader(inputStream, iso88591));
+        writer = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(outputStream), iso88591));
     }
-    
+
     protected void getWelcome() throws IOException {
-        // just read the line and consume it.  If debug is 
+        // just read the line and consume it.  If debug is
         // enabled, there I/O stream will be traced
-        greeting = reader.readLine(); 
+        greeting = reader.readLine();
     }
 
     public String toString() {
@@ -184,70 +187,70 @@ public class POP3Connection extends Mail
         }
         try {
             // say goodbye
-            logout();   
+            logout();
         } 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();
-            // get rid of our response processor too. 
-            reader = null; 
-            writer = null; 
+            // get rid of our response processor too.
+            reader = null;
+            writer = null;
         }
     }
 
-    
+
     /**
-     * Tag this connection as having been closed by the 
-     * server.  This will not be returned to the 
-     * connection pool. 
+     * Tag this connection as having been closed by the
+     * server.  This will not be returned to the
+     * connection pool.
      */
     public void setClosed() {
         closed = true;
     }
-    
+
     /**
      * Test if the connnection has been forcibly closed.
-     * 
+     *
      * @return True if the server disconnected the connection.
      */
     public boolean isClosed() {
-        return closed; 
+        return closed;
     }
-    
+
     protected POP3Response sendCommand(String cmd) throws MessagingException {
-        return sendCommand(cmd, false); 
+        return sendCommand(cmd, false);
     }
-    
+
     protected POP3Response sendMultiLineCommand(String cmd) throws MessagingException {
-        return sendCommand(cmd, true); 
+        return sendCommand(cmd, true);
     }
 
     protected synchronized POP3Response sendCommand(String cmd, boolean multiLine) throws MessagingException {
         if (socket.isConnected()) {
             {
-                // NOTE:  We don't use println() because it uses the platform concept of a newline rather 
-                // than using CRLF, which is required by the POP3 protocol.  
+                // NOTE:  We don't use println() because it uses the platform concept of a newline rather
+                // than using CRLF, which is required by the POP3 protocol.
                 writer.write(cmd);
-                writer.write("\r\n"); 
+                writer.write("\r\n");
                 writer.flush();
-                
-                POP3Response response = buildResponse(multiLine); 
+
+                POP3Response response = buildResponse(multiLine);
                 if (response.isError()) {
-                    throw new CommandFailedException("Error issuing POP3 command: " + cmd); 
+                    throw new CommandFailedException("Error issuing POP3 command: " + cmd);
                 }
-                return response; 
+                return response;
             }
         }
         throw new MessagingException("Connection to Mail Server is lost, connection " + this.toString());
     }
-    
+
     /**
      * Build a POP3Response item from the response stream.
-     * 
+     *
      * @param isMultiLineResponse
      *               If true, this command is expecting multiple lines back from the server.
-     * 
-     * @return A POP3Response item with all of the command response data. 
+     *
+     * @return A POP3Response item with all of the command response data.
      * @exception MessagingException
      */
     protected POP3Response buildResponse(boolean isMultiLineResponse) throws MessagingException {
@@ -255,18 +258,18 @@ public class POP3Connection extends Mail
         byte[] data = null;
 
         String line;
-        MIMEInputReader source = new MIMEInputReader(reader); 
-        
+        MIMEInputReader source = new MIMEInputReader(reader);
+
         try {
             line = reader.readLine();
         } catch (IOException e) {
             throw new MessagingException("Error in receving response");
         }
-        
+
         if (line == null || line.trim().equals("")) {
             throw new MessagingException("Empty Response");
         }
-        
+
         if (line.startsWith("+OK")) {
             status = OK;
             line = removeStatusField(line);
@@ -297,314 +300,314 @@ public class POP3Connection extends Mail
      */
     private byte[] getMultiLineResponse() throws MessagingException {
 
-        MIMEInputReader source = new MIMEInputReader(reader); 
-        
+        MIMEInputReader source = new MIMEInputReader(reader);
+
         ByteArrayOutputStream out = new ByteArrayOutputStream();
-        
-        // it's more efficient to do this a buffer at a time. 
-        // the MIMEInputReader takes care of the byte-stuffing and 
-        // ".\r\n" input terminator for us. 
-        OutputStreamWriter outWriter = new OutputStreamWriter(out); 
-        char buffer[] = new char[500]; 
+
+        // it's more efficient to do this a buffer at a time.
+        // the MIMEInputReader takes care of the byte-stuffing and
+        // ".\r\n" input terminator for us.
+        OutputStreamWriter outWriter = new OutputStreamWriter(out);
+        char buffer[] = new char[500];
         try {
             int charsRead = -1;
             while ((charsRead = source.read(buffer)) >= 0) {
                 outWriter.write(buffer, 0, charsRead);
             }
-            outWriter.flush(); 
+            outWriter.flush();
         } catch (IOException e) {
             throw new MessagingException("Error processing a multi-line response", e);
         }
-        
+
         return out.toByteArray();
     }
-    
-    
+
+
     /**
-     * Retrieve the raw message content from the POP3 
-     * server.  This is all of the message data, including 
-     * the header. 
-     * 
+     * Retrieve the raw message content from the POP3
+     * server.  This is all of the message data, including
+     * the header.
+     *
      * @param sequenceNumber
      *               The message sequence number.
-     * 
-     * @return A byte array containing all of the message data. 
+     *
+     * @return A byte array containing all of the message data.
      * @exception MessagingException
      */
     public byte[] retrieveMessageData(int sequenceNumber) throws MessagingException {
-        POP3Response msgResponse = sendMultiLineCommand("RETR " + sequenceNumber); 
-        // we want the data directly in this case. 
-        return msgResponse.getData();          
+        POP3Response msgResponse = sendMultiLineCommand("RETR " + sequenceNumber);
+        // we want the data directly in this case.
+        return msgResponse.getData();
     }
-    
+
     /**
-     * Retrieve the message header information for a given 
-     * message, returned as an input stream suitable 
+     * Retrieve the message header information for a given
+     * message, returned as an input stream suitable
      * for loading the message data.
-     * 
+     *
      * @param sequenceNumber
      *               The server sequence number for the message.
-     * 
-     * @return An inputstream that can be used to read the message 
+     *
+     * @return An inputstream that can be used to read the message
      *         data.
      * @exception MessagingException
      */
     public ByteArrayInputStream retrieveMessageHeaders(int sequenceNumber) throws MessagingException {
-        POP3Response msgResponse; 
-        
-        // some POP3 servers don't correctly implement TOP, so this can be disabled.  If 
-        // we can't use TOP, then use RETR and retrieve everything.  We can just hand back 
-        // the stream, as the header loading routine will stop at the first 
-        // null line. 
+        POP3Response msgResponse;
+
+        // some POP3 servers don't correctly implement TOP, so this can be disabled.  If
+        // we can't use TOP, then use RETR and retrieve everything.  We can just hand back
+        // the stream, as the header loading routine will stop at the first
+        // null line.
         if (topDisabled) {
-            msgResponse = sendMultiLineCommand("RETR " + sequenceNumber); 
+            msgResponse = sendMultiLineCommand("RETR " + sequenceNumber);
         }
         else {
-            msgResponse = sendMultiLineCommand("TOP " + sequenceNumber + " 0"); 
+            msgResponse = sendMultiLineCommand("TOP " + sequenceNumber + " 0");
         }
-        
-        // just load the returned message data as a set of headers 
+
+        // just load the returned message data as a set of headers
         return msgResponse.getContentStream();
     }
-    
+
     /**
-     * Retrieve the total message size from the mail 
-     * server.  This is the size of the headers plus 
-     * the size of the message content. 
-     * 
+     * Retrieve the total message size from the mail
+     * server.  This is the size of the headers plus
+     * the size of the message content.
+     *
      * @param sequenceNumber
      *               The message sequence number.
-     * 
+     *
      * @return The full size of the message.
      * @exception MessagingException
      */
     public int retrieveMessageSize(int sequenceNumber) throws MessagingException {
-        POP3Response msgResponse = sendCommand("LIST " + sequenceNumber); 
-        // Convert this into the parsed response type we need. 
-        POP3ListResponse list = new POP3ListResponse(msgResponse); 
-        // this returns the total message size 
-        return list.getSize(); 
+        POP3Response msgResponse = sendCommand("LIST " + sequenceNumber);
+        // Convert this into the parsed response type we need.
+        POP3ListResponse list = new POP3ListResponse(msgResponse);
+        // this returns the total message size
+        return list.getSize();
     }
-    
+
     /**
      * Retrieve the mail drop status information.
-     * 
-     * @return An object representing the returned mail drop status. 
+     *
+     * @return An object representing the returned mail drop status.
      * @exception MessagingException
      */
     public POP3StatusResponse retrieveMailboxStatus() throws MessagingException {
-        // issue the STAT command and return this into a status response 
-        return new POP3StatusResponse(sendCommand("STAT")); 
+        // issue the STAT command and return this into a status response
+        return new POP3StatusResponse(sendCommand("STAT"));
     }
-    
-    
+
+
     /**
      * Retrieve the UID for an individual message.
-     * 
+     *
      * @param sequenceNumber
      *               The target message sequence number.
-     * 
-     * @return The string UID maintained by the server. 
+     *
+     * @return The string UID maintained by the server.
      * @exception MessagingException
      */
     public String retrieveMessageUid(int sequenceNumber) throws MessagingException {
-        POP3Response msgResponse = sendCommand("UIDL " + sequenceNumber); 
-        
-        String message = msgResponse.getFirstLine(); 
-        // the UID is everything after the blank separating the message number and the UID. 
-        // there's not supposed to be anything else on the message, but trim it of whitespace 
-        // just to be on the safe side. 
-        return message.substring(message.indexOf(' ') + 1).trim(); 
+        POP3Response msgResponse = sendCommand("UIDL " + sequenceNumber);
+
+        String message = msgResponse.getFirstLine();
+        // the UID is everything after the blank separating the message number and the UID.
+        // there's not supposed to be anything else on the message, but trim it of whitespace
+        // just to be on the safe side.
+        return message.substring(message.indexOf(' ') + 1).trim();
     }
-    
-    
+
+
     /**
      * Delete a single message from the mail server.
-     * 
+     *
      * @param sequenceNumber
      *               The sequence number of the message to delete.
-     * 
+     *
      * @exception MessagingException
      */
     public void deleteMessage(int sequenceNumber) throws MessagingException {
-        // just issue the command...we ignore the command response 
-        sendCommand("DELE " + sequenceNumber); 
+        // just issue the command...we ignore the command response
+        sendCommand("DELE " + sequenceNumber);
     }
-    
+
     /**
-     * Logout from the mail server.  This sends a QUIT 
+     * Logout from the mail server.  This sends a QUIT
      * command, which will likely sever the mail connection.
-     * 
+     *
      * @exception MessagingException
      */
     public void logout() throws MessagingException {
         // we may have already sent the QUIT command
         if (!loggedIn) {
-            return; 
+            return;
         }
-        // just issue the command...we ignore the command response 
-        sendCommand("QUIT"); 
-        loggedIn = false; 
+        // just issue the command...we ignore the command response
+        sendCommand("QUIT");
+        loggedIn = false;
     }
-    
+
     /**
-     * Perform a reset on the mail server.                   
-     * 
+     * Perform a reset on the mail server.
+     *
      * @exception MessagingException
      */
     public void reset() throws MessagingException {
-        // some mail servers mark retrieved messages for deletion 
-        // automatically.  This will reset the read flags before 
-        // we go through normal cleanup. 
+        // some mail servers mark retrieved messages for deletion
+        // automatically.  This will reset the read flags before
+        // we go through normal cleanup.
         if (props.getBooleanProperty(MAIL_RESET_QUIT, false)) {
             // just send an RSET command first
-            sendCommand("RSET"); 
+            sendCommand("RSET");
         }
     }
-    
+
     /**
-     * Ping the mail server to see if we still have an active connection. 
-     * 
-     * @exception MessagingException thrown if we do not have an active connection. 
+     * Ping the mail server to see if we still have an active connection.
+     *
+     * @exception MessagingException thrown if we do not have an active connection.
      */
     public void pingServer() throws MessagingException {
-        // just issue the command...we ignore the command response 
-        sendCommand("NOOP"); 
+        // just issue the command...we ignore the command response
+        sendCommand("NOOP");
     }
-    
+
     /**
-     * Login to the mail server, using whichever method is 
-     * configured.  This will try multiple methods, if allowed, 
-     * in decreasing levels of security. 
-     * 
-     * @return true if the login was successful. 
+     * Login to the mail server, using whichever method is
+     * configured.  This will try multiple methods, if allowed,
+     * in decreasing levels of security.
+     *
+     * @return true if the login was successful.
      * @exception MessagingException
      */
     public synchronized boolean login() throws MessagingException {
         // permitted to use the AUTH command?
         if (authEnabled) {
             try {
-                // go do the SASL thing 
-                return processSaslAuthentication(); 
+                // go do the SASL thing
+                return processSaslAuthentication();
             } catch (MessagingException e) {
-                // Any error here means fall back to the next mechanism 
+                // Any error here means fall back to the next mechanism
             }
         }
-        
+
         if (apopEnabled) {
             try {
-                // go do the SASL thing 
-                return processAPOPAuthentication(); 
+                // go do the SASL thing
+                return processAPOPAuthentication();
             } catch (MessagingException e) {
-                // Any error here means fall back to the next mechanism 
+                // Any error here means fall back to the next mechanism
             }
         }
-        
+
         try {
-            // do the tried and true login processing. 
-            return processLogin(); 
+            // do the tried and true login processing.
+            return processLogin();
         } catch (MessagingException e) {
         }
-        // everything failed...can't get in 
-        return false; 
+        // everything failed...can't get in
+        return false;
     }
-    
-    
+
+
     /**
-     * Process a basic LOGIN operation, using the 
-     * plain test USER/PASS command combo. 
-     * 
-     * @return true if we logged successfully. 
+     * Process a basic LOGIN operation, using the
+     * plain test USER/PASS command combo.
+     *
+     * @return true if we logged successfully.
      * @exception MessagingException
      */
     public boolean processLogin() throws MessagingException {
-        // start by sending the USER command, followed by  
+        // start by sending the USER command, followed by
         // the PASS command
-        sendCommand("USER " + username); 
-        sendCommand("PASS " + password); 
-        return true;       // we're in 
-    }
-    
-    /**
-     * Process logging in using the APOP command.  Only 
-     * works on servers that give a timestamp value 
-     * in the welcome response. 
-     * 
-     * @return true if the login was accepted. 
+        sendCommand("USER " + username);
+        sendCommand("PASS " + password);
+        return true;       // we're in
+    }
+
+    /**
+     * Process logging in using the APOP command.  Only
+     * works on servers that give a timestamp value
+     * in the welcome response.
+     *
+     * @return true if the login was accepted.
      * @exception MessagingException
      */
     public boolean processAPOPAuthentication() throws MessagingException {
-        int timeStart = greeting.indexOf('<'); 
-        // if we didn't get an APOP challenge on the greeting, throw an exception 
-        // the main login processor will swallow that and fall back to the next 
-        // mechanism 
+        int timeStart = greeting.indexOf('<');
+        // if we didn't get an APOP challenge on the greeting, throw an exception
+        // the main login processor will swallow that and fall back to the next
+        // mechanism
         if (timeStart == -1) {
-            throw new MessagingException("POP3 Server does not support APOP"); 
+            throw new MessagingException("POP3 Server does not support APOP");
         }
-        int timeEnd = greeting.indexOf('>'); 
-        String timeStamp = greeting.substring(timeStart, timeEnd + 1); 
-        
-        // we create the digest password using the timestamp value sent to use 
-        // concatenated with the password. 
-        String digestPassword = timeStamp + password; 
-        
-        byte[] digest; 
-        
+        int timeEnd = greeting.indexOf('>');
+        String timeStamp = greeting.substring(timeStart, timeEnd + 1);
+
+        // we create the digest password using the timestamp value sent to use
+        // concatenated with the password.
+        String digestPassword = timeStamp + password;
+
+        byte[] digest;
+
         try {
-            // create a digest value from the password. 
-            MessageDigest md = MessageDigest.getInstance("MD5"); 
-            digest = md.digest(digestPassword.getBytes("iso-8859-1")); 
+            // create a digest value from the password.
+            MessageDigest md = MessageDigest.getInstance("MD5");
+            digest = md.digest(digestPassword.getBytes("iso-8859-1"));
         } catch (NoSuchAlgorithmException e) {
-            // this shouldn't happen, but if it does, we'll just try a plain 
-            // login. 
-            throw new MessagingException("Unable to create MD5 digest", e); 
+            // this shouldn't happen, but if it does, we'll just try a plain
+            // login.
+            throw new MessagingException("Unable to create MD5 digest", e);
         } catch (UnsupportedEncodingException e) {
-            // this shouldn't happen, but if it does, we'll just try a plain 
-            // login. 
-            throw new MessagingException("Unable to create MD5 digest", e); 
+            // this shouldn't happen, but if it does, we'll just try a plain
+            // login.
+            throw new MessagingException("Unable to create MD5 digest", e);
         }
         // this will throw an exception if it gives an error failure
-        sendCommand("APOP " + username + " " + Hex.encode(digest)); 
-        // no exception, we must have passed 
-        return true; 
+        sendCommand("APOP " + username + " " + Hex.encode(digest));
+        // no exception, we must have passed
+        return true;
     }
 
-    
+
     /**
      * Process SASL-type authentication.
-     * 
+     *
      * @return Returns true if the server support a SASL authentication mechanism and
      *         accepted reponse challenges.
      * @exception MessagingException
      */
     protected boolean processSaslAuthentication() throws MessagingException {
-        // if unable to get an appropriate authenticator, just fail it. 
-        ClientAuthenticator authenticator = getSaslAuthenticator(); 
+        // if unable to get an appropriate authenticator, just fail it.
+        ClientAuthenticator authenticator = getSaslAuthenticator();
         if (authenticator == null) {
-            throw new MessagingException("Unable to obtain SASL authenticator"); 
+            throw new MessagingException("Unable to obtain SASL authenticator");
         }
-        
+
         // go process the login.
         return processLogin(authenticator);
     }
-    
+
     /**
-     * Attempt to retrieve a SASL authenticator for this 
-     * protocol. 
-     * 
-     * @return A SASL authenticator, or null if a suitable one 
+     * 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); 
+        return AuthenticatorFactory.getAuthenticator(props, selectSaslMechanisms(), serverHost, username, password, authid, realm);
     }
 
 
     /**
      * Process a login using the provided authenticator object.
-     * 
-     * NB:  This method is synchronized because we have a multi-step process going on 
-     * here.  No other commands should be sent to the server until we complete. 
+     *
+     * NB:  This method is synchronized because we have a multi-step process going on
+     * here.  No other commands should be sent to the server until we complete.
      *
      * @return Returns true if the server support a SASL authentication mechanism and
      * accepted reponse challenges.
@@ -615,41 +618,44 @@ public class POP3Connection extends Mail
             debugOut("Authenticating for user: " + username + " using " + authenticator.getMechanismName());
         }
 
-        POP3Response response = sendCommand("AUTH " + authenticator.getMechanismName()); 
+        POP3Response response = sendCommand("AUTH " + authenticator.getMechanismName());
 
-        // now process the challenge sequence.  We get a continuation response back for each stage of the 
-        // authentication, and finally an OK when everything passes muster.     
+        // now process the challenge sequence.  We get a continuation response back for each stage of the
+        // authentication, and finally an OK when everything passes muster.
         while (true) {
             // this should be a continuation reply, if things are still good.
             if (response.isChallenge()) {
                 // we're passed back a challenge value, Base64 encoded.
                 byte[] challenge = response.decodeChallengeResponse();
-                
-                String responseString = new String(Base64.encode(authenticator.evaluateChallenge(challenge)));
 
-                // have the authenticator evaluate and send back the encoded response.
-                response = sendCommand(responseString);
+                try {
+                    String responseString = new String(Base64.encode(authenticator.evaluateChallenge(challenge)), "US_ASCII");
+
+                    // have the authenticator evaluate and send back the encoded response.
+                    response = sendCommand(responseString);
+                } catch (UnsupportedEncodingException ex) {
+                }
             }
             else {
-                // there are only two choices here, OK or a continuation.  OK means 
-                // we've passed muster and are in. 
-                return true; 
+                // there are only two choices here, OK or a continuation.  OK means
+                // we've passed muster and are in.
+                return true;
             }
         }
     }
-    
-    
+
+
     /**
-     * Merge the configured SASL mechanisms with the capabilities that the 
-     * server has indicated it supports, returning a merged list that can 
-     * be used for selecting a mechanism. 
-     * 
-     * @return A List representing the intersection of the configured list and the 
+     * Merge the configured SASL mechanisms with the capabilities that the
+     * server has indicated it supports, returning a merged list that can
+     * be used for selecting a mechanism.
+     *
+     * @return A List representing the intersection of the configured list and the
      *         capabilities list.
      */
     protected List selectSaslMechanisms() {
-        // just return the set that have been explicity permitted 
-        return getSaslMechanisms(); 
+        // just return the set that have been explicity permitted
+        return getSaslMechanisms();
     }
 }
 

Modified: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPConnection.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPConnection.java?rev=946314&r1=946313&r2=946314&view=diff
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPConnection.java (original)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/transport/nntp/NNTPConnection.java Wed May 19 18:01:55 2010
@@ -20,18 +20,20 @@
 package org.apache.geronimo.javamail.transport.nntp;
 
 import java.io.BufferedReader;
-import java.io.BufferedOutputStream; 
+import java.io.BufferedOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.PrintStream;
 import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.net.InetAddress;
 import java.net.Socket;
-import java.util.ArrayList; 
+import java.nio.charset.Charset;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.StringTokenizer;
@@ -40,17 +42,17 @@ import javax.mail.Message;
 import javax.mail.MessagingException;
 import javax.mail.Session;
 
-import org.apache.geronimo.javamail.authentication.ClientAuthenticator; 
-import org.apache.geronimo.javamail.authentication.AuthenticatorFactory; 
-import org.apache.geronimo.javamail.util.MailConnection; 
+import org.apache.geronimo.javamail.authentication.ClientAuthenticator;
+import org.apache.geronimo.javamail.authentication.AuthenticatorFactory;
+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.javamail.util.ProtocolProperties;
 import org.apache.geronimo.mail.util.Base64;
 import org.apache.geronimo.mail.util.SessionUtil;
 
 /**
  * Simple implementation of NNTP transport. Just does plain RFC977-ish delivery.
- * 
+ *
  * @version $Rev$ $Date$
  */
 public class NNTPConnection extends MailConnection {
@@ -68,53 +70,53 @@ public class NNTPConnection extends Mail
     protected static final int DEFAULT_NNTP_PORT = 119;
     // does the server support posting?
     protected boolean postingAllowed = true;
-    
-    // different authentication mechanisms 
-    protected boolean authInfoUserAllowed = false; 
-    protected boolean authInfoSaslAllowed = false; 
-    
+
+    // different authentication mechanisms
+    protected boolean authInfoUserAllowed = false;
+    protected boolean authInfoSaslAllowed = false;
+
     // the last response line received from the server.
     protected NNTPReply lastServerResponse = null;
 
     // the welcome string from the server.
     protected String welcomeString = null;
-    
-    // input reader wrapped around the socket input stream 
-    protected BufferedReader reader; 
-    // output writer wrapped around the socket output stream. 
-    protected PrintWriter writer; 
+
+    // input reader wrapped around the socket input stream
+    protected BufferedReader reader;
+    // output writer wrapped around the socket output stream.
+    protected PrintWriter writer;
 
     /**
      * Normal constructor for an NNTPConnection() object.
-     * 
+     *
      * @param props  The property bundle for this protocol instance.
      */
     public NNTPConnection(ProtocolProperties props) {
         super(props);
     }
-    
-    
+
+
     /**
      * 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 
+     *
+     * @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 {
-        super.protocolConnect(host, port, username, password); 
+        super.protocolConnect(host, port, username, password);
         // create socket and connect to server.
         getConnection();
 
         // receive welcoming message
         getWelcome();
-        
-        return true; 
+
+        return true;
     }
 
 
@@ -127,24 +129,26 @@ public class NNTPConnection extends Mail
     protected void getConnection() throws MessagingException
     {
         try {
-            // do all of the non-protocol specific set up.  This will get our socket established 
-            // and ready use. 
-            super.getConnection(); 
+            // do all of the non-protocol specific set up.  This will get our socket established
+            // and ready use.
+            super.getConnection();
         } catch (IOException e) {
-            throw new MessagingException("Unable to obtain a connection to the NNTP server", e); 
+            throw new MessagingException("Unable to obtain a connection to the NNTP server", e);
         }
-        
-        // The NNTP protocol is inherently a string-based protocol, so we get 
-        // string readers/writers for the connection streams 
-        reader = new BufferedReader(new InputStreamReader(inputStream));
+
+        // The NNTP protocol is inherently a string-based protocol, so we get
+        // string readers/writers for the connection streams.  Note that we explicitly
+        // set the encoding to ensure that an inappropriate native encoding is not picked up.
+        Charset iso88591 = Charset.forName("ISO8859-1");
+        reader = new BufferedReader(new InputStreamReader(inputStream, iso88591));
         writer = new PrintWriter(new BufferedOutputStream(outputStream));
     }
-    
+
 
     /**
      * 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 {
@@ -160,16 +164,16 @@ public class NNTPConnection extends Mail
             // make sure the connection
             // is shut down even if quit gets an error.
             closeServerConnection();
-            // get rid of our response processor too. 
-            reader = null; 
-            writer = null; 
+            // get rid of our response processor too.
+            reader = null;
+            writer = null;
         }
     }
 
     public String toString() {
         return "NNTPConnection host: " + serverHost + " port: " + serverPort;
     }
-    
+
 
     /**
      * Get the servers welcome blob from the wire....
@@ -196,32 +200,32 @@ public class NNTPConnection extends Mail
         getExtensions();
     }
 
-    
+
     /**
      * Sends the QUIT message and receieves the response
      */
     public void sendQuit() throws MessagingException {
         sendLine("QUIT");
     }
-    
+
 
     /**
      * Tell the server to switch to a named group.
-     * 
+     *
      * @param name
      *            The name of the target group.
-     * 
+     *
      * @return The server response to the GROUP command.
      */
     public NNTPReply selectGroup(String name) throws MessagingException {
         // send the GROUP command
         return sendCommand("GROUP " + name);
     }
-    
+
 
     /**
      * Ask the server what extensions it supports.
-     * 
+     *
      * @return True if the command was accepted ok, false for any errors.
      * @exception MessagingException
      */
@@ -237,7 +241,7 @@ public class NNTPConnection extends Mail
 
         // get a fresh extension mapping table.
         capabilities = new HashMap();
-        authentications = new ArrayList(); 
+        authentications = new ArrayList();
 
         // get the extension data lines.
         List extensions = reply.getData();
@@ -249,10 +253,10 @@ public class NNTPConnection extends Mail
         }
     }
 
-    
+
     /**
      * Process an extension string passed back as the LIST EXTENSIONS response.
-     * 
+     *
      * @param extension
      *            The string value of the extension (which will be of the form
      *            "NAME arguments").
@@ -272,18 +276,18 @@ public class NNTPConnection extends Mail
         // add this to the map so it can be tested later.
         capabilities.put(extensionName, argument);
 
-        // we need to determine which authentication mechanisms are supported here 
+        // we need to determine which authentication mechanisms are supported here
         if (extensionName.equals("AUTHINFO")) {
-            StringTokenizer tokenizer = new StringTokenizer(argument); 
-            
+            StringTokenizer tokenizer = new StringTokenizer(argument);
+
             while (tokenizer.hasMoreTokens()) {
-                // we only know how to do USER or SASL 
+                // we only know how to do USER or SASL
                 String mechanism = tokenizer.nextToken().toUpperCase();
                 if (mechanism.equals("SASL")) {
-                    authInfoSaslAllowed = true; 
+                    authInfoSaslAllowed = true;
                 }
                 else if (mechanism.equals("USER")) {
-                    authInfoUserAllowed = true; 
+                    authInfoUserAllowed = true;
                 }
             }
         }
@@ -298,15 +302,15 @@ public class NNTPConnection extends Mail
             }
         }
     }
-    
+
 
     /**
      * 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.
@@ -320,10 +324,10 @@ public class NNTPConnection extends Mail
 
     /**
      * 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.
@@ -333,7 +337,7 @@ public class NNTPConnection extends Mail
         return extensionParameter(name) != null;
     }
 
-    
+
     /**
      * 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
@@ -370,9 +374,9 @@ public class NNTPConnection extends Mail
             msg.writeTo(mimeOut);
 
             // now to finish, we send a CRLF sequence, followed by a ".".
-            mimeOut.writeSMTPTerminator();           
-            // and flush the data to send it along 
-            mimeOut.flush();   
+            mimeOut.writeSMTPTerminator();
+            // and flush the data to send it along
+            mimeOut.flush();
         } catch (IOException e) {
             throw new MessagingException("I/O error posting message", e);
         } catch (MessagingException e) {
@@ -392,13 +396,13 @@ public class NNTPConnection extends Mail
      * Issue a command and retrieve the response. If the given success indicator
      * is received, the command is returning a longer response, terminated by a
      * "crlf.crlf" sequence. These lines are attached to the reply.
-     * 
+     *
      * @param command
      *            The command to issue.
      * @param success
      *            The command reply that indicates additional data should be
      *            retrieved.
-     * 
+     *
      * @return The command reply.
      */
     public synchronized NNTPReply sendCommand(String command, int success) throws MessagingException {
@@ -412,10 +416,10 @@ public class NNTPConnection extends Mail
     /**
      * 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
      */
@@ -441,10 +445,10 @@ public class NNTPConnection extends Mail
     /**
      * 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
      */
@@ -461,7 +465,7 @@ public class NNTPConnection extends Mail
             throw new MessagingException("no connection");
         }
         try {
-            outputStream.write(data.getBytes());
+            outputStream.write(data.getBytes("ISO8859-1"));
             outputStream.write(CR);
             outputStream.write(LF);
             outputStream.flush();
@@ -472,7 +476,7 @@ public class NNTPConnection extends Mail
 
     /**
      * Get a reply line for an NNTP command.
-     * 
+     *
      * @return An NNTP reply object from the stream.
      */
     public NNTPReply getReply() throws MessagingException {
@@ -482,7 +486,7 @@ public class NNTPConnection extends Mail
 
     /**
      * Retrieve the last response received from the NNTP server.
-     * 
+     *
      * @return The raw response string (including the error code) returned from
      *         the NNTP server.
      */
@@ -496,7 +500,7 @@ public class NNTPConnection extends Mail
     /**
      * 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
      */
     public String receiveLine() throws MessagingException {
@@ -515,7 +519,7 @@ public class NNTPConnection extends Mail
         }
     }
 
-    
+
     /**
      * Authenticate with the server, if necessary (or possible).
      */
@@ -539,7 +543,7 @@ public class NNTPConnection extends Mail
     /**
      * Process an AUTHINFO SIMPLE command. Not widely used, but if the server
      * asks for it, we can respond.
-     * 
+     *
      * @exception MessagingException
      */
     protected void processAuthinfoSimple() throws MessagingException {
@@ -553,46 +557,46 @@ public class NNTPConnection extends Mail
         }
     }
 
-    
+
     /**
      * Process SASL-type authentication.
-     * 
+     *
      * @return Returns true if the server support a SASL authentication mechanism and
      *         accepted reponse challenges.
      * @exception MessagingException
      */
     protected boolean processSaslAuthentication() throws MessagingException {
-        // only do this if permitted 
+        // only do this if permitted
         if (!authInfoSaslAllowed) {
-            return false; 
+            return false;
         }
-        // if unable to get an appropriate authenticator, just fail it. 
-        ClientAuthenticator authenticator = getSaslAuthenticator(); 
+        // if unable to get an appropriate authenticator, just fail it.
+        ClientAuthenticator authenticator = getSaslAuthenticator();
         if (authenticator == null) {
-            throw new MessagingException("Unable to obtain SASL authenticator"); 
+            throw new MessagingException("Unable to obtain SASL authenticator");
         }
-        
+
         // go process the login.
         return processLogin(authenticator);
     }
-    
+
     /**
-     * Attempt to retrieve a SASL authenticator for this 
-     * protocol. 
-     * 
-     * @return A SASL authenticator, or null if a suitable one 
+     * 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); 
+        return AuthenticatorFactory.getAuthenticator(props, selectSaslMechanisms(), serverHost, username, password, authid, realm);
     }
 
 
     /**
      * Process a login using the provided authenticator object.
-     * 
-     * NB:  This method is synchronized because we have a multi-step process going on 
-     * here.  No other commands should be sent to the server until we complete. 
+     *
+     * NB:  This method is synchronized because we have a multi-step process going on
+     * here.  No other commands should be sent to the server until we complete.
      *
      * @return Returns true if the server support a SASL authentication mechanism and
      * accepted reponse challenges.
@@ -611,7 +615,10 @@ public class NNTPConnection extends Mail
             command.append(authenticator.getMechanismName());
             command.append(" ");
             // and append the response data
-            command.append(new String(Base64.encode(authenticator.evaluateChallenge(null))));
+            try {
+                command.append(new String(Base64.encode(authenticator.evaluateChallenge(null)), "US-ASCII"));
+            } catch (UnsupportedEncodingException e) {
+            }
             // send the command now
             sendLine(command.toString());
         }
@@ -650,11 +657,14 @@ public class NNTPConnection extends Mail
                 }
 
                 // we're passed back a challenge value, Base64 encoded.
-                byte[] challenge = Base64.decode(line.getMessage().getBytes());
+                try {
+                    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))));
+                    // 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
@@ -666,17 +676,17 @@ public class NNTPConnection extends Mail
         }
     }
 
-    
+
     /**
      * Process an AUTHINFO USER command. Most common form of NNTP
      * authentication.
-     * 
+     *
      * @exception MessagingException
      */
     protected void processAuthinfoUser() throws MessagingException {
-        // only do this if allowed by the server 
+        // only do this if allowed by the server
         if (!authInfoUserAllowed) {
-            return; 
+            return;
         }
         NNTPReply reply = sendAuthCommand("AUTHINFO USER " + username);
         // accepted without a password (uncommon, but allowed), we're done
@@ -694,10 +704,10 @@ public class NNTPConnection extends Mail
         }
     }
 
-    
+
     /**
      * Indicate whether posting is allowed for a given server.
-     * 
+     *
      * @return True if the server allows posting, false if the server is
      *         read-only.
      */
@@ -707,7 +717,7 @@ public class NNTPConnection extends Mail
 
     /**
      * Retrieve the welcome string sent back from the server.
-     * 
+     *
      * @return The server provided welcome string.
      */
     public String getWelcomeString() {



Mime
View raw message