From: Wolfgang M. M. <wol...@us...> - 2004-04-23 13:14:10
|
Update of /cvsroot/exist/eXist-1.0/src/org/exist/http/servlets In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv3779/src/org/exist/http/servlets Added Files: Authenticator.java BasicAuthenticator.java WebDAVServlet.java DigestAuthenticator.java Log Message: New WebDAV module (initial check in) --- NEW FILE: BasicAuthenticator.java --- /* * eXist Open Source Native XML Database * Copyright (C) 2001-04 Wolfgang M. Meier * wol...@ex... * http://exist-db.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id: BasicAuthenticator.java,v 1.1 2004/04/23 13:14:02 wolfgang_m Exp $ */ package org.exist.http.servlets; import java.io.IOException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.xmlrpc.Base64; import org.exist.security.SecurityManager; import org.exist.security.User; import org.exist.storage.BrokerPool; /** * @author wolf */ public class BasicAuthenticator implements Authenticator { private BrokerPool pool; public BasicAuthenticator(BrokerPool pool) { this.pool = pool; } /* (non-Javadoc) * @see org.exist.http.servlets.Authenticator#authenticate(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ public User authenticate(HttpServletRequest request, HttpServletResponse response) throws IOException { String credentials = request.getHeader("Authorization"); if(credentials == null) { sendChallenge(request, response); return null; } byte[] c = Base64.decode(credentials.substring("Basic ".length()).getBytes()); String s = new String(c); int p = s.indexOf(':'); String username = s.substring(0, p); String password = s.substring(p + 1); SecurityManager secman = pool.getSecurityManager(); User user = secman.getUser(username); if(user == null) { response.sendError(HttpServletResponse.SC_UNAUTHORIZED); return null; } if (!user.validate(password)) { response.sendError(HttpServletResponse.SC_UNAUTHORIZED); return null; } return user; } /* (non-Javadoc) * @see org.exist.http.servlets.Authenticator#sendChallenge(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ public void sendChallenge(HttpServletRequest request, HttpServletResponse response) throws IOException { // TODO Auto-generated method stub } } --- NEW FILE: DigestAuthenticator.java --- /* * eXist Open Source Native XML Database * Copyright (C) 2001-04 Wolfgang M. Meier * wol...@ex... * http://exist-db.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id: DigestAuthenticator.java,v 1.1 2004/04/23 13:14:02 wolfgang_m Exp $ */ package org.exist.http.servlets; import java.io.IOException; import java.security.MessageDigest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.exist.security.MD5; import org.exist.security.SecurityManager; import org.exist.security.User; import org.exist.storage.BrokerPool; /** * @author wolf */ public class DigestAuthenticator implements Authenticator { private BrokerPool pool; public DigestAuthenticator(BrokerPool pool) { this.pool = pool; } public User authenticate(HttpServletRequest request, HttpServletResponse response) throws IOException { String credentials = request.getHeader("Authorization"); if(credentials == null) { sendChallenge(request, response); return null; } Digest digest = new Digest(request.getMethod()); parseCredentials(digest, credentials); SecurityManager secman = pool.getSecurityManager(); User user = secman.getUser(digest.username); if(user == null) { response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "User unknown"); return null; } if(!digest.check(user.getPassword())) { response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Password check failed"); return null; } return user; } public void sendChallenge(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setHeader("WWW-Authenticate", "Digest realm=\"exist\", " + "nonce=\"" + createNonce(request) + "\", " + "domain=\"" + request.getContextPath() + "\", " + "opaque=\"" + MD5.md(Integer.toString(hashCode(), 27)) + '"'); response.sendError(HttpServletResponse.SC_UNAUTHORIZED); } private String createNonce(HttpServletRequest request) { return MD5.md(request.getRemoteAddr() + ':' + Long.toString(System.currentTimeMillis()) + ':' + Integer.toString(hashCode())); } private static void parseCredentials(Digest digest, String credentials) { credentials = credentials.substring("Digest ".length()); StringBuffer current = new StringBuffer(); String name = null, value; boolean inQuotedString = false; for(int i = 0; i < credentials.length(); i++) { char ch = credentials.charAt(i); switch(ch) { case ' ': break; case '"': case '\'': if(inQuotedString) { value = current.toString(); current.setLength(0); inQuotedString = false; if("username".equalsIgnoreCase(name)) digest.username = value; else if("realm".equalsIgnoreCase(name)) digest.realm = value; else if("nonce".equalsIgnoreCase(name)) digest.nonce = value; else if("uri".equalsIgnoreCase(name)) digest.uri = value; else if("response".equalsIgnoreCase(name)) digest.response = value; } else { value = null; inQuotedString = true; } break; case ',': name = null; break; case '=': name = current.toString(); current.setLength(0); break; default: current.append(ch); break; } } } private static class Digest { String method=null; String username = null; String realm = null; String nonce = null; String uri = null; String response=null; public Digest(String method) { this.method = method; } public boolean check(String credentials) throws IOException { try{ MessageDigest md = MessageDigest.getInstance("MD5"); // calc A2 digest md.reset(); md.update(method.getBytes("ISO-8859-1")); md.update((byte)':'); md.update(uri.getBytes("ISO-8859-1")); byte[] ha2=md.digest(); // calc digest md.update(credentials.getBytes("ISO-8859-1")); md.update((byte)':'); md.update(nonce.getBytes("ISO-8859-1")); md.update((byte)':'); md.update(MD5.byteArrayToHex(ha2).getBytes("ISO-8859-1")); byte[] digest=md.digest(); // check digest System.out.println(MD5.byteArrayToHex(digest) + " = " + response); return (MD5.byteArrayToHex(digest).equalsIgnoreCase(response)); } catch (Exception e) { throw new IOException("Internal error while checking digest"); } } } } --- NEW FILE: Authenticator.java --- /* * eXist Open Source Native XML Database * Copyright (C) 2001-04 Wolfgang M. Meier * wol...@ex... * http://exist-db.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id: Authenticator.java,v 1.1 2004/04/23 13:14:02 wolfgang_m Exp $ */ package org.exist.http.servlets; import java.io.IOException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.exist.security.User; /** * @author wolf */ public interface Authenticator { public User authenticate(HttpServletRequest request, HttpServletResponse response) throws IOException; public void sendChallenge(HttpServletRequest request, HttpServletResponse response) throws IOException; } --- NEW FILE: WebDAVServlet.java --- /* * eXist Open Source Native XML Database * Copyright (C) 2001-04 Wolfgang M. Meier * wol...@ex... * http://exist-db.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id: WebDAVServlet.java,v 1.1 2004/04/23 13:14:02 wolfgang_m Exp $ */ package org.exist.http.servlets; import java.io.IOException; import java.util.Enumeration; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.exist.http.webdav.WebDAV; public class WebDAVServlet extends HttpServlet { private WebDAV webdav; /* (non-Javadoc) * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig) */ public void init(ServletConfig config) throws ServletException { super.init(config); webdav = new WebDAV(); } /* (non-Javadoc) * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { dumpHeaders(request); webdav.process(request, response); } private void dumpHeaders(HttpServletRequest request) { System.out.println("-------------------------------------------------------"); for(Enumeration e = request.getHeaderNames(); e.hasMoreElements(); ) { String header = (String)e.nextElement(); System.out.println(header + " = " + request.getHeader(header)); } } } |