Digest Authentication bug in org.apache.catalina.realm.RealmBase

2003-01-03 Thread Peter Costello
I apologize in advance if I am sending this bug report/fix to the
wrong group or if the fix has already been implemented.

Using JDK1.3.01 and Tomcat 4.1.12, and sun.net.HttpURLConnection,
Digest Authentication does not work.  The sun.net.HttpURLConnection
class responds to WWW-Authenticate challenge with a Http Authorization
header that contains no 'nc', 'nonce' or 'qop' parameters. Although this
may not be very efficient, as best as I can tell from the spec, this is
a legal response.

org.apache.catalina.realm.RealmBase (line 373) calculates:
   String serverDigestValue = md5a1 + : + nOnce + : + nc + :
+ cnonce + : + qop + : + md5a2;

These null parameters get added to the string as :null and the MD5
encoded result 'serverDigest' does not match the 'clientDigest' and
authentication fails.

Replacing the 'serverDigestValue' with the following fixes the problem:
String serverDigestValue = md5a1 + : + nOnce;
if (nc!=null) serverDigestValue += : + nc;
if (cnonce!=null) serverDigestValue += : + cnonce;
if (qop!=null) serverDigestValue += : + qop;
serverDigestValue += : + md5a2;


==
To reproduce the problem:
1) Start with a Tomcat 4.1.12 site with some pages requiring digest
authentication.
   Assume username,password = myName,myPassword

2) Define authenticator
public class AuthImpl extends Authenticator {
// Authentication Method
protected PasswordAuthentication getPasswordAuthentication() {
return new 
PasswordAuthentication(myName,myPassword.toCharArray());
}
}

3) Access the pages with the following
Authenticator.setDefault(new AuthImpl());
URL url = new URL(http://localhost/foo.html;);
HttpURLConnection uc = url.openConnection();
InputStream in = uc.getInputStream();
byte buf[] = new byte[4096];
int readNum;
while ((readNum=in.read(buf,0,4096))0) {
// if (out!=null) out.write(buf,0,readNum);
}
int status = ((HttpURLConnection)uc).getResponseCode();

Authentication will fail until corrected as described above.


--
To unsubscribe, e-mail:   mailto:[EMAIL PROTECTED]
For additional commands, e-mail: mailto:[EMAIL PROTECTED]




8 Patches for Win2k, Forte2.0 JDK1.3.0_01

2001-05-23 Thread Peter Costello

The following patches were made to get
jakarta-tomcat4.0-b5 to
compile and work properly in an environment using
Win2000, 
JDK1.3.0_01 and Forte2.0 IDE.

Could an active developer please review and check
out/in the changes?

===
1) org.apache.catalina.authenticator.FormAuthenticate

   The following enhancement allows the IE5.0 browser
to maintain the
   correct URL in its history list.  For example, if
browser fetches
   'index.jsp' and tomcat returns 'login.jsp', then
when browser submits
   username and password it sends a 'POST
j_security_check'.  Method
   'authenticate()' does its work and then restores
the original request
   and returns. However, now the browser thinks that
page 'GET index.jsp'
   is 'POST j_security_check' and using the
back/forward on the browser
   will result in an error when we get back to the
'POST'.
   
   My fix was to send a redirect to the original page
after authenticate
   does its work.  
   
   
/**
 * Authenticate the user making this request,
based on the specified
 * login configuration.  Return codetrue/code
if any specified
 * constraint has been satisfied, or
codefalse/code if we have
 * created a response challenge already.
 *
 * @param request Request we are processing
 * @param response Response we are creating
 * @param login Login configuration describing how
authentication
 *  should be performed
 *
 * @exception IOException if an input/output error
occurs
 */
public boolean authenticate(HttpRequest request,
HttpResponse response,
LoginConfig config)
throws IOException {
  
. UNCHANGED .

if (restoreRequest(request, session)) {
if (debug = 1)
log(Proceed to restored request);

/* Added code */
// If we merely serve the original
request, then IE5 browser
// shows POST j_security_check in
address field, and future
// back submits the POST rather than the
original GET.
// ToDo: the 'restoreRequest' above does
some extra/unnecessary
// work that could be cleaned up.
String uri =
hreq.getRequestURI()+?+hreq.getQueryString();
hres.sendRedirect(uri);
/* End added code */

return (true);// Perform
the original request
} else {
if (debug = 1)
log(Restore of original request
failed);
   
hres.sendError(HttpServletResponse.SC_BAD_REQUEST);
//hres.flushBuffer();
return (false);
}

===
2) org.apache.catalina.core.ApplicationDispatcher

This implementation of RequestDispatcher makes a
call to the protected
service method of the servlet.  I'm not sure why
it is doing that, but
as a servlet developer, I know I'm expecting
service calls to come
through the public method.

This change is needed to get Forte2.0 to compile
the file.

private void invoke(ServletRequest request,
ServletResponse response)
throws IOException,
ServletException {

 UNCHANGED    
  
// Call the service() method for the allocated
servlet instance
try {
if (servlet != null) {
  /* REMOVED CODE ... */
/* The call to 'protected void
service(HttpServletRequest,HttpServletResponse)'
will not compile. This is a
protected method, so calls to service should go
through the public method.
Changed 5/17/01 to get it to compile. 
if ((servlet instanceof
HttpServlet) 
(hrequest != null) 
(hresponse != null)) {
(HttpServlet
servlet).service(hrequest,hresponse);
} else {
servlet.service(request,
response);
} */
  /* END REMOVED CODE */
  
  /* added CODE */
 servlet.service(request,
response);
  /* END Added CODE */
   
}
} catch (IOException e) {
   
log(sm.getString(applicationDispatcher.serviceException,
 wrapper.getName()), e);
ioException = e;
} catch (UnavailableException e) {
 
 UNCHANGED    
  

===
3) org.apache.catalina.startup.Catalina

   This is an enhancement.  Currently, usage is
reported if any of the 
   arguments are not defined, but at least one
argument is required
   (eg run), and there is no usage call if no
arguments are supplied

protected boolean