001: /* jcifs smb client library in Java
002: * Copyright (C) 2002 "Michael B. Allen" <jcifs at samba dot org>
003: * "Eric Glass" <jcifs at samba dot org>
004: * "Jason Pugsley" <jcifs at samba dot org>
005: * "skeetz" <jcifs at samba dot org>
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */
021:
022: package com.knowgate.jcifs.http;
023:
024: import java.io.IOException;
025:
026: import javax.servlet.ServletException;
027:
028: import javax.servlet.http.HttpServletRequest;
029: import javax.servlet.http.HttpServletResponse;
030:
031: import com.knowgate.jcifs.smb.NtlmPasswordAuthentication;
032:
033: import com.knowgate.misc.Base64Decoder;
034: import com.knowgate.misc.Base64Encoder;
035:
036: import com.knowgate.jcifs.ntlmssp.NtlmFlags;
037: import com.knowgate.jcifs.ntlmssp.Type1Message;
038: import com.knowgate.jcifs.ntlmssp.Type2Message;
039: import com.knowgate.jcifs.ntlmssp.Type3Message;
040:
041: /**
042: * This class is used internally by <tt>NtlmHttpFilter</tt>,
043: * <tt>NtlmServlet</tt>, and <tt>NetworkExplorer</tt> to negiotiate password
044: * hashes via NTLM SSP with MSIE. It might also be used directly by servlet
045: * containers to incorporate similar functionality.
046: * <p>
047: * How NTLMSSP is used in conjunction with HTTP and MSIE clients is
048: * described in an <A HREF="http://www.innovation.ch/java/ntlm.html">NTLM
049: * Authentication Scheme for HTTP</A>. <p> Also, read <a
050: * href="../../../ntlmhttpauth.html">jCIFS NTLM HTTP Authentication and
051: * the Network Explorer Servlet</a> related information.
052: * @version 0.9.1
053: */
054:
055: public class NtlmSsp implements NtlmFlags {
056:
057: /**
058: * Calls the static {@link #authenticate(HttpServletRequest,
059: * HttpServletResponse, byte[])} method to perform NTLM authentication
060: * for the specified servlet request.
061: *
062: * @param req The request being serviced.
063: * @param resp The response.
064: * @param challenge The domain controller challenge.
065: * @throws IOException If an IO error occurs.
066: * @throws ServletException If an error occurs.
067: */
068: public NtlmPasswordAuthentication doAuthentication(
069: HttpServletRequest req, HttpServletResponse resp,
070: byte[] challenge) throws IOException, ServletException {
071: return authenticate(req, resp, challenge);
072: }
073:
074: /**
075: * Performs NTLM authentication for the servlet request.
076: *
077: * @param req The request being serviced.
078: * @param resp The response.
079: * @param challenge The domain controller challenge.
080: * @throws IOException If an IO error occurs.
081: * @throws ServletException If an error occurs.
082: */
083: public static NtlmPasswordAuthentication authenticate(
084: HttpServletRequest req, HttpServletResponse resp,
085: byte[] challenge) throws IOException, ServletException {
086: String msg = req.getHeader("Authorization");
087: if (msg != null && msg.startsWith("NTLM ")) {
088: byte[] src = Base64Decoder.decodeToBytes(msg.substring(5));
089: if (src[8] == 1) {
090: Type1Message type1 = new Type1Message(src);
091: Type2Message type2 = new Type2Message(type1, challenge,
092: null);
093: msg = Base64Encoder.encode(type2.toByteArray());
094: resp.setHeader("WWW-Authenticate", "NTLM " + msg);
095: } else if (src[8] == 3) {
096: Type3Message type3 = new Type3Message(src);
097: byte[] lmResponse = type3.getLMResponse();
098: if (lmResponse == null)
099: lmResponse = new byte[0];
100: byte[] ntResponse = type3.getNTResponse();
101: if (ntResponse == null)
102: ntResponse = new byte[0];
103: return new NtlmPasswordAuthentication(
104: type3.getDomain(), type3.getUser(), challenge,
105: lmResponse, ntResponse);
106: }
107: } else {
108: resp.setHeader("WWW-Authenticate", "NTLM");
109: resp.setHeader("Connection", "close");
110: }
111: resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
112: resp.setContentLength(0);
113: resp.flushBuffer();
114: return null;
115: }
116:
117: }
|