Hello, I needed an Authentication mechanism that also does client ip checking.
I've included a patch against the latest 2.0 cvs version that makes this happen by changing the execute(String method, Vector params, String user, String pass) in the AuthenticatedXmlRpcHandler interface to execute(String method, Vector params, XmlRpcContext context) I have added an extra method InetAddress getInetAddress() on the XmlRpcContext interface and changes all implementing classes to the new interfaces. Furthermore I ran into a NullPointerException in WebServer in the parseAuth method. Which was silently ignored by try { ... } catch(Throwable ignore) {} This is also fixed in the AddClientip.patch file. I added an extra patch with only the fixed NullPointerException which doesn't change any interfaces. Robbert-Jan
Index: AuthDemo.java =================================================================== RCS file: /home/cvspublic/xml-rpc/src/java/org/apache/xmlrpc/AuthDemo.java,v retrieving revision 1.2 diff -u -r1.2 AuthDemo.java --- AuthDemo.java 20 Mar 2002 15:11:03 -0000 1.2 +++ AuthDemo.java 13 May 2003 10:07:16 -0000 @@ -67,13 +67,15 @@ /** * */ - public Object execute(String method, Vector v, String user, String password) + public Object execute(String method, Vector v, XmlRpcContext context) throws Exception { + String user = context.getUserName(); + // our simplistic authentication guidelines never fail ;) if (user == null || user.startsWith("bad")) { - throw new XmlRpcException(5, "Sorry, you're not allowed in here!"); + throw new XmlRpcException(5, "Sorry, you're not allowed in here!"); } return ("Hello " + user); Index: AuthenticatedXmlRpcHandler.java =================================================================== RCS file: /home/cvspublic/xml-rpc/src/java/org/apache/xmlrpc/AuthenticatedXmlRpcHandler.java,v retrieving revision 1.5 diff -u -r1.5 AuthenticatedXmlRpcHandler.java --- AuthenticatedXmlRpcHandler.java 27 Sep 2002 17:17:01 -0000 1.5 +++ AuthenticatedXmlRpcHandler.java 13 May 2003 10:07:17 -0000 @@ -70,15 +70,13 @@ * * @param method The name of the XML-RPC method to invoke. * @param params The parameters to the XML-RPC method. - * @param user The user name. - * @param password The password of <code>user</code>. + * @param context The context this request will occur in. * @return The response. * * @throws AuthenticationFailed If authentication fails, an * exception of this type must be thrown. * @see org.apache.xmlrpc.AuthenticationFailed */ - public Object execute(String method, Vector params, String user, - String password) + public Object execute(String method, Vector params, XmlRpcContext context ) throws Exception; } Index: DefaultXmlRpcContext.java =================================================================== RCS file: /home/cvspublic/xml-rpc/src/java/org/apache/xmlrpc/DefaultXmlRpcContext.java,v retrieving revision 1.1 diff -u -r1.1 DefaultXmlRpcContext.java --- DefaultXmlRpcContext.java 21 Oct 2002 13:08:50 -0000 1.1 +++ DefaultXmlRpcContext.java 13 May 2003 10:07:17 -0000 @@ -55,6 +55,8 @@ * <http://www.apache.org/>. */ +import java.net.InetAddress; + /** * A basic context object that stores the userName, password and * handler mapping. @@ -67,12 +69,15 @@ implements XmlRpcContext { protected String userName, password; + protected InetAddress inetAddress; protected XmlRpcHandlerMapping handlerMapping; - public DefaultXmlRpcContext(String userName, String password, XmlRpcHandlerMapping handlerMapping) + public DefaultXmlRpcContext(String userName, String password, + InetAddress inetAddress, XmlRpcHandlerMapping handlerMapping) { this.userName = userName; this.password = password; + this.inetAddress = inetAddress; this.handlerMapping = handlerMapping; } @@ -84,6 +89,11 @@ public String getPassword() { return password; + } + + public InetAddress getInetAddress() + { + return inetAddress; } public XmlRpcHandlerMapping getHandlerMapping() Index: WebServer.java =================================================================== RCS file: /home/cvspublic/xml-rpc/src/java/org/apache/xmlrpc/WebServer.java,v retrieving revision 1.23 diff -u -r1.23 WebServer.java --- WebServer.java 1 May 2003 16:53:15 -0000 1.23 +++ WebServer.java 13 May 2003 10:07:20 -0000 @@ -70,6 +70,7 @@ import java.util.StringTokenizer; import java.util.Vector; import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.DecoderException; /** * A minimal web server that exclusively handles XML-RPC requests. @@ -703,6 +704,7 @@ this.socket = socket; input = new BufferedInputStream(socket.getInputStream()); output = new BufferedOutputStream(socket.getOutputStream()); + base64Codec = new Base64(); } /** @@ -772,7 +774,8 @@ contentLength); try { - byte[] result = xmlrpc.execute(sin, user, password); + byte[] result = xmlrpc.execute(sin, user, password, + socket.getInetAddress()); writeResponse(result, httpVersion, keepAlive); } catch (AuthenticationFailed unauthorized) @@ -859,7 +862,7 @@ user = str.substring(0, col); password = str.substring(col + 1); } - catch (Throwable ignore) + catch(DecoderException ignore) { } } Index: XmlRpcContext.java =================================================================== RCS file: /home/cvspublic/xml-rpc/src/java/org/apache/xmlrpc/XmlRpcContext.java,v retrieving revision 1.1 diff -u -r1.1 XmlRpcContext.java --- XmlRpcContext.java 21 Oct 2002 13:08:50 -0000 1.1 +++ XmlRpcContext.java 13 May 2003 10:07:22 -0000 @@ -55,6 +55,8 @@ * <http://www.apache.org/>. */ +import java.net.InetAddress; + /** * The minimal context that an XML-RPC request will occur in. * @@ -77,6 +79,13 @@ * @returns the password (may be null). */ public String getPassword(); + + /** + * Get the address this request came from. + * + * @return the inetadress of the requesting client. + */ + public InetAddress getInetAddress(); /** * Get the XML-RPC handler mapping for the server handling the request. Index: XmlRpcServer.java =================================================================== RCS file: /home/cvspublic/xml-rpc/src/java/org/apache/xmlrpc/XmlRpcServer.java,v retrieving revision 1.35 diff -u -r1.35 XmlRpcServer.java --- XmlRpcServer.java 21 Oct 2002 13:08:50 -0000 1.35 +++ XmlRpcServer.java 13 May 2003 10:07:22 -0000 @@ -57,6 +57,7 @@ import java.io.IOException; import java.io.InputStream; +import java.net.InetAddress; import java.util.EmptyStackException; import java.util.Stack; @@ -125,7 +126,8 @@ */ public byte[] execute(InputStream is) { - return execute(is, new DefaultXmlRpcContext(null, null, getHandlerMapping())); + return execute(is, new DefaultXmlRpcContext(null, null, + null, getHandlerMapping())); } /** @@ -134,9 +136,11 @@ * use the credentials to authenticate the user. No context information * is passed. */ - public byte[] execute(InputStream is, String user, String password) + public byte[] execute(InputStream is, String user, String password, + InetAddress inetAddress) { - return execute(is, new DefaultXmlRpcContext(user, password, getHandlerMapping())); + return execute(is, new DefaultXmlRpcContext(user, password, + inetAddress, getHandlerMapping())); } /** Index: XmlRpcWorker.java =================================================================== RCS file: /home/cvspublic/xml-rpc/src/java/org/apache/xmlrpc/XmlRpcWorker.java,v retrieving revision 1.5 diff -u -r1.5 XmlRpcWorker.java --- XmlRpcWorker.java 5 Dec 2002 08:49:24 -0000 1.5 +++ XmlRpcWorker.java 13 May 2003 10:07:23 -0000 @@ -57,6 +57,7 @@ import java.io.InputStream; import java.io.IOException; +import java.net.InetAddress; /** * Tie together the XmlRequestProcessor and XmlResponseProcessor to handle @@ -127,7 +128,7 @@ { return ((AuthenticatedXmlRpcHandler) handler) .execute(request.getMethodName(), request.getParameters(), - context.getUserName(), context.getPassword()); + context); } else { @@ -150,9 +151,9 @@ * Decode, process and encode the response or exception for an XML-RPC * request. This method executes the handler method with the default context. */ - public byte[] execute(InputStream is, String user, String password) + public byte[] execute(InputStream is, String user, String password, InetAddress inetAddress) { - return execute(is, defaultContext(user, password)); + return execute(is, defaultContext(user, password, inetAddress)); } /** @@ -221,8 +222,10 @@ * @param password the password of the user making the request. * @return XmlRpcContext the context for the reqeust. */ - protected XmlRpcContext defaultContext(String user, String password) + protected XmlRpcContext defaultContext(String user, String password, + InetAddress inetAddress) { - return new DefaultXmlRpcContext(user, password, handlerMapping); + return new DefaultXmlRpcContext(user, password, inetAddress, + handlerMapping); } }
Index: WebServer.java =================================================================== RCS file: /home/cvspublic/xml-rpc/src/java/org/apache/xmlrpc/WebServer.java,v retrieving revision 1.23 diff -u -r1.23 WebServer.java --- WebServer.java 1 May 2003 16:53:15 -0000 1.23 +++ WebServer.java 12 May 2003 23:41:18 -0000 @@ -70,6 +70,7 @@ import java.util.StringTokenizer; import java.util.Vector; import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.DecoderException; /** * A minimal web server that exclusively handles XML-RPC requests. @@ -703,6 +704,7 @@ this.socket = socket; input = new BufferedInputStream(socket.getInputStream()); output = new BufferedOutputStream(socket.getOutputStream()); + base64Codec = new Base64(); } /** @@ -859,7 +861,7 @@ user = str.substring(0, col); password = str.substring(col + 1); } - catch (Throwable ignore) + catch(DecoderException ignore) { } }