Uh, is this going to get committed?

The Zope/Python XML-RPC people are fixing a similar defect in their
XML-RPC implementation; it would be good if Apache followed suit.

   http://lists.zope.org/pipermail/zope-dev/2002-August/017126.html
   http://lists.zope.org/pipermail/zope-dev/2002-August/017143.html

  - a


Adam Megacz <[EMAIL PROTECTED]> writes:
> XmlRpc.java does not provide adequate support to implement HTTP Basic
> Authentication. WebServer.java implements it incorrectly. This patch
> fixes both problems.
> 
> If an HTTP request requires authentication, the server MUST return a
> 401 Unauthorized:
> 
>   http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2
> 
> Without the 401, the client doesn't know which type of authentication
> to use. It can't assume Basic, because that would mean sending
> passwords in the clear even to Digest-capable servers (thereby
> rendering digest auth useless). It can't assume Digest, because the
> 401 contains the nonce (which is required to perform digest
> authentication).
> 
> Patch appended. This also fixes a bug whereby WebServer would return
> an HTTP/1.1 response without a Content-Length or chunked encoding,
> which is not allowed.
> 
>   - a
> 
> ------------------------------------------------------------------------------
> 
> Index: src/java/org/apache/xmlrpc/WebServer.java
> ===================================================================
> RCS file: /home/cvspublic/xml-rpc/src/java/org/apache/xmlrpc/WebServer.java,v
> retrieving revision 1.13
> diff -u -r1.13 WebServer.java
> --- src/java/org/apache/xmlrpc/WebServer.java 13 Aug 2002 22:27:16 -0000      1.13
> +++ src/java/org/apache/xmlrpc/WebServer.java 13 Aug 2002 23:53:40 -0000
> @@ -94,6 +94,7 @@
>      protected static final byte[] conclose = "Connection: close\r\n".getBytes();
>      protected static final byte[] ok = " 200 OK\r\n".getBytes();
>      protected static final byte[] server = "Server: Apache XML-RPC 
>1.0\r\n".getBytes();
> +    protected static final byte[] www_authenticate = "WWW-Authenticate: Basic 
>realm=XMLRPC\r\n".getBytes();
>  
>      private static final String HTTP_11 = "HTTP/1.1";
>      private static final String STAR = "*";
> @@ -584,29 +585,40 @@
>                      {
>                          ServerInputStream sin = new ServerInputStream(input,
>                                  contentLength);
> -                        byte result[] = xmlrpc.execute(sin, user, password);
> -                        output.write(httpversion.getBytes());
> -                        output.write(ok);
> -                        output.write(server);
> -                        if (keepalive)
> -                        {
> -                            output.write(conkeep);
> -                        }
> -                        else
> -                        {
> -                            output.write (conclose);
> +                        try {
> +                            byte result[] = xmlrpc.execute(sin, user, password);
> +                            output.write(httpversion.getBytes());
> +                            output.write(ok);
> +                            output.write(server);
> +                            if (keepalive)
> +                                {
> +                                    output.write(conkeep);
> +                                }
> +                            else
> +                                {
> +                                    output.write (conclose);
> +                                }
> +                            output.write(ctype);
> +                            output.write(clength);
> +                            output.write(Integer.toString(result.length)
> +                                         .getBytes());
> +                            output.write(doubleNewline);
> +                            output.write(result);
> +                        } catch (XmlRpcServer.AuthenticationRequiredException are) {
> +                            output.write("HTTP/1.0".getBytes());
> +                            output.write(" 401 Unauthorized\r\n".getBytes());
> +                            output.write(server);
> +                            output.write(www_authenticate);
> +                            output.write("\r\n".getBytes());
> +                            output.write(("Method " + method
> +                                          + " requires a username and 
>password").getBytes());
> +                            keepalive = false;
>                          }
> -                        output.write(ctype);
> -                        output.write(clength);
> -                        output.write(Integer.toString(result.length)
> -                                .getBytes());
> -                        output.write(doubleNewline);
> -                        output.write(result);
>                          output.flush();
>                      }
>                      else
>                      {
> -                        output.write(httpversion.getBytes());
> +                        output.write("HTTP/1.0".getBytes());
>                          output.write(" 400 Bad Request\r\n".getBytes());
>                          output.write(server);
>                          output.write("\r\n".getBytes());
> Index: src/java/org/apache/xmlrpc/XmlRpcServer.java
> ===================================================================
> RCS file: /home/cvspublic/xml-rpc/src/java/org/apache/xmlrpc/XmlRpcServer.java,v
> retrieving revision 1.28
> diff -u -r1.28 XmlRpcServer.java
> --- src/java/org/apache/xmlrpc/XmlRpcServer.java      9 Aug 2002 09:14:24 -0000      
> 1.28
> +++ src/java/org/apache/xmlrpc/XmlRpcServer.java      13 Aug 2002 23:53:40 -0000
> @@ -136,6 +136,7 @@
>       * since this is all packed into the response.
>       */
>      public byte[] execute(InputStream is)
> +        throws AuthenticationRequiredException
>      {
>          return execute(is, null, null);
>      }
> @@ -146,6 +147,7 @@
>       * use the credentials to authenticate the user.
>       */
>      public byte[] execute(InputStream is, String user, String password)
> +        throws AuthenticationRequiredException
>      {
>          Worker worker = getWorker();
>          byte[] retval = worker.execute(is, user, password);
> @@ -202,6 +204,7 @@
>           * Given a request for the server, generates a response.
>           */
>          public byte[] execute(InputStream is, String user, String password)
> +            throws AuthenticationRequiredException
>          {
>              try
>              {
> @@ -224,7 +227,7 @@
>           * @return
>           */
>          private byte[] executeInternal(InputStream is, String user,
> -                String password)
> +                String password) throws AuthenticationRequiredException
>          {
>              byte[] result;
>              long now = 0;
> @@ -284,6 +287,7 @@
>                  Object outParam;
>                  if (handler instanceof AuthenticatedXmlRpcHandler)
>                  {
> +                    if (user == null) throw new 
>XmlRpcServer.AuthenticationRequiredException();
>                      outParam =((AuthenticatedXmlRpcHandler) handler)
>                              .execute(methodName, inParams, user, password);
>                  }
> @@ -303,6 +307,9 @@
>              }
>              catch(Exception x)
>              {
> +                if (x instanceof XmlRpcServer.AuthenticationRequiredException)
> +                    throw (XmlRpcServer.AuthenticationRequiredException)x;
> +
>                  if (XmlRpc.debug)
>                  {
>                      x.printStackTrace();
> @@ -427,6 +434,11 @@
>              writer.endElement("methodResponse");
>          }
>      } // end of inner class Worker
> +
> +    public static class AuthenticationRequiredException extends IOException {
> +        AuthenticationRequiredException() { }
> +    }
> +
>  } // XmlRpcServer
>  
>  /**
> @@ -555,4 +567,6 @@
>          }
>          return returnValue;
>      }
> +
>  }
> +
> 

-- 
Sick of HTML user interfaces?
www.xwt.org

Reply via email to