classpath-inetlib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Classpath-inetlib] Re: IMAP and SMTP Issues


From: Phillip Smith
Subject: [Classpath-inetlib] Re: IMAP and SMTP Issues
Date: Mon, 24 May 2004 19:24:35 -0400
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040113

Responses Inline

Chris Burdess wrote:
Phillip Smith wrote:

I'm not sure if you're the right person for this information - but here goes.


Absolutely; I've taken the liberty of crossposting to classpath-inetlib
as well.


I run Courier-IMAP and Postfix; both which only allow DIGEST-MD5 and CRAM-MD5 authentication. After some code changes, I got it working so I wanted to share my experience so others would not have to go through what I did.

**** IMAP ****

1. The capability() method on gnu.inet.imap.IMAPConnection had to be modified to also parse the asyncResponses:

// The capability "list" is actually contained in the response
// text.
StringBuffer caps = new StringBuffer(response.getText());
Iterator it = asyncResponses.iterator();

it.next();

while (it.hasNext())
{
 caps.append(" ").append(((IMAPResponse)it.next()).getText());
}

String text = caps.toString();


Ouch - that's not what the specification describes. I'm happy to put
this in, if we can show that it won't result in erroneous data with
other servers.

Jus out of interest, what's the deal with the first next() - a spurious
entry?

The debug output shows this:

imap: > A1 CAPABILITY
imap: < * OK [CAPABILITY, IMAP4rev1, UIDPLUS, CHILDREN, NAMESPACE, THREAD=ORDEREDSUBJECT, THREAD=REFERENCES, SORT, QUOTA, AUTH=CRAM-MD5, IDLE] Courier-IMAP ready. Copyright 1998-2003 Double Precision,
 Inc.  See COPYING for distribution information.
imap: < * CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THREAD=REFERENCES SORT QUOTA AUTH=CRAM-MD5 IDLE
imap: < A1 OK CAPABILITY completed

The it.next() processes the first async response which is essentially a duplicate of the second async response. I suppose I should surround it with an if (it.hasNext()) just to be safe. Whether this applies to other configurations, I don't know - but if it already isn't spec I don't know how far you want to take it.



***SNIP***
   /*  GNU Code... replace below
   byte[] s = secret.getBytes(US_ASCII); // TODO encoding?
   byte[] c0 = response.getText().getBytes(US_ASCII);
   byte[] c1 = BASE64.decode(c0); // challenge
   byte[] digest = hmac_md5(s, c1);
   byte[] r0 = username.getBytes(US_ASCII); // username
   byte[] r1 = new byte[r0.length+digest.length+1]; // response
   System.arraycopy(r0, 0, r1, 0, r0.length); // add username
   r1[r0.length] = 0x20; // SPACE
   System.arraycopy(digest, 0, r1, r0.length+1, digest.length);
   byte[] r2 = BASE64.encode(r1);
   out.write(r2);
   out.writeln();
   out.flush();
   */
***SNIP***


These methods are obsolete, since current GNU-Crypto provides a better,
more modular system, and I don't want to regress.

You need a very up-to-date version of GNU-Crypto, like current CVS HEAD.
It shouldn't require any configuration as such, you simply ask for a
SASL provider by name (the javamail providers ask for the first
authentication mechanism in the capabilities list).

I notice GNU-Crypto has made another release in the meantime. If it's
failing now we should try to correct it there.

I declaratively added the provider via the
security.provider.1=gnu.crypto.jce.GnuCrypto
property in my java.security file and I also tried programmatically adding it. Nothing seemed to work - Although it is frustrating, I can accept that is something simple that I am not doing right.

ALSO... when I directly instantiated gnu.crypto.sasl.ClientFactory in the IMAPConnection's authenticate() method,

SaslClient sasl =
new gnu.crypto.sasl.ClientFactory().createSaslClient(m, null, "smtp",
                                              socket.getInetAddress().
                                              getHostName(), p, ch);

I received an InvalidKeyException with a "Key too short" message. It is thrown from gnu.crypto.mac.HMac on line 182.

// for HMACs used in key-derivation functions (e.g. PBKDF2) the key
// material need not be >= the (output) block size of the underlying
// algorithm
Boolean pkcs5 = (Boolean) attributes.get(USE_WITH_PKCS5_V2);
  if (pkcs5 == null) {
  pkcs5 = Boolean.FALSE;
}
if (K.length < macSize && !pkcs5.booleanValue()) {
  throw new InvalidKeyException("Key too short");  <-- line 182
}

I modified the createHMac() method in gnu.crypto.sasl.crammd5.CramMD5Util so the exception would not be thrown.

map.put(IMac.MAC_KEY_MATERIAL, km);
map.put(gnu.crypto.mac.HMac.USE_WITH_PKCS5_V2, Boolean.TRUE);  <-- add
mac.init(map);
mac.update(data, 0, data.length);
return mac.digest();

I'm not sure if the only reason I received the exception was because I didn't go through the framework or for some other reason.

At any rate, even with directly instantiating the SASL ClientFactory (and after making the change to CramMD5Util) authentication still failed.

***SNIP****

Now that I have something working, I'll move forward with that. If I can I'll circle back and debug sasl. I'll let you know the results.

Thanks,
Phillip




reply via email to

[Prev in Thread] Current Thread [Next in Thread]