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: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019:
020: package com.knowgate.jcifs.http;
021:
022: import java.io.IOException;
023:
024: import java.net.UnknownHostException;
025:
026: import java.util.Enumeration;
027:
028: import javax.servlet.ServletConfig;
029: import javax.servlet.ServletException;
030: import javax.servlet.UnavailableException;
031:
032: import javax.servlet.http.HttpSession;
033: import javax.servlet.http.HttpServlet;
034: import javax.servlet.http.HttpServletRequest;
035: import javax.servlet.http.HttpServletResponse;
036:
037: import com.knowgate.jcifs.Config;
038: import com.knowgate.jcifs.UniAddress;
039:
040: import com.knowgate.jcifs.smb.NtlmPasswordAuthentication;
041: import com.knowgate.jcifs.smb.SmbAuthException;
042: import com.knowgate.jcifs.smb.SmbSession;
043:
044: import com.knowgate.misc.Base64Decoder;
045:
046: import com.knowgate.jcifs.netbios.NbtAddress;
047:
048: /**
049: * This servlet may be used with pre-2.3 servlet containers
050: * to protect content with NTLM HTTP Authentication. Servlets that
051: * extend this abstract base class may be authenticatied against an SMB
052: * server or domain controller depending on how the
053: * <tt>jcifs.smb.client.domain</tt> or <tt>jcifs.http.domainController</tt>
054: * properties are be specified. <b>With later containers the
055: * <tt>NtlmHttpFilter</tt> should be used/b>. For custom NTLM HTTP Authentication schemes the <tt>NtlmSsp</tt> may be used.
056: * <p>
057: * Read <a href="../../../ntlmhttpauth.html">jCIFS NTLM HTTP Authentication and the Network Explorer Servlet</a> related information.
058: * @version 0.9.1
059: */
060:
061: public abstract class NtlmServlet extends HttpServlet {
062:
063: private String defaultDomain;
064:
065: private String domainController;
066:
067: private boolean loadBalance;
068:
069: private boolean enableBasic;
070:
071: private boolean insecureBasic;
072:
073: private String realm;
074:
075: public void init(ServletConfig config) throws ServletException {
076: super .init(config);
077:
078: /* Set jcifs properties we know we want; soTimeout and cachePolicy to 10min.
079: */
080: Config.setProperty("jcifs.smb.client.soTimeout", "300000");
081: Config.setProperty("jcifs.netbios.cachePolicy", "600");
082:
083: Enumeration e = config.getInitParameterNames();
084: String name;
085: while (e.hasMoreElements()) {
086: name = (String) e.nextElement();
087: if (name.startsWith("jcifs.")) {
088: Config.setProperty(name, config.getInitParameter(name));
089: }
090: }
091: defaultDomain = Config.getProperty("jcifs.smb.client.domain");
092: domainController = Config
093: .getProperty("jcifs.http.domainController");
094: if (domainController == null) {
095: domainController = defaultDomain;
096: loadBalance = Config.getBoolean("jcifs.http.loadBalance",
097: true);
098: }
099: enableBasic = Boolean.valueOf(
100: Config.getProperty("jcifs.http.enableBasic"))
101: .booleanValue();
102: insecureBasic = Boolean.valueOf(
103: Config.getProperty("jcifs.http.insecureBasic"))
104: .booleanValue();
105: realm = Config.getProperty("jcifs.http.basicRealm");
106: if (realm == null)
107: realm = "jCIFS";
108: }
109:
110: protected void service(HttpServletRequest request,
111: HttpServletResponse response) throws ServletException,
112: IOException {
113: UniAddress dc;
114: boolean offerBasic = enableBasic
115: && (insecureBasic || request.isSecure());
116: String msg = request.getHeader("Authorization");
117: if (msg != null
118: && (msg.startsWith("NTLM ") || (offerBasic && msg
119: .startsWith("Basic ")))) {
120: if (loadBalance) {
121: dc = new UniAddress(NbtAddress.getByName(
122: domainController, 0x1C, null));
123: } else {
124: dc = UniAddress.getByName(domainController, true);
125: }
126: NtlmPasswordAuthentication ntlm;
127: if (msg.startsWith("NTLM ")) {
128: byte[] challenge = SmbSession.getChallenge(dc);
129: ntlm = NtlmSsp.authenticate(request, response,
130: challenge);
131: if (ntlm == null)
132: return;
133: } else {
134: String auth = new String(Base64Decoder
135: .decodeToBytes(msg.substring(6)), "US-ASCII");
136: int index = auth.indexOf(':');
137: String user = (index != -1) ? auth.substring(0, index)
138: : auth;
139: String password = (index != -1) ? auth
140: .substring(index + 1) : "";
141: index = user.indexOf('\\');
142: if (index == -1)
143: index = user.indexOf('/');
144: String domain = (index != -1) ? user
145: .substring(0, index) : defaultDomain;
146: user = (index != -1) ? user.substring(index + 1) : user;
147: ntlm = new NtlmPasswordAuthentication(domain, user,
148: password);
149: }
150: try {
151: SmbSession.logon(dc, ntlm);
152: } catch (SmbAuthException sae) {
153: response.setHeader("WWW-Authenticate", "NTLM");
154: if (offerBasic) {
155: response.addHeader("WWW-Authenticate",
156: "Basic realm=\"" + realm + "\"");
157: }
158: response.setHeader("Connection", "close");
159: response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
160: response.flushBuffer();
161: return;
162: }
163: HttpSession ssn = request.getSession();
164: ssn.setAttribute("NtlmHttpAuth", ntlm);
165: ssn.setAttribute("ntlmdomain", ntlm.getDomain());
166: ssn.setAttribute("ntlmuser", ntlm.getUsername());
167: } else {
168: HttpSession ssn = request.getSession(false);
169: if (ssn == null || ssn.getAttribute("NtlmHttpAuth") == null) {
170: response.setHeader("WWW-Authenticate", "NTLM");
171: if (offerBasic) {
172: response.addHeader("WWW-Authenticate",
173: "Basic realm=\"" + realm + "\"");
174: }
175: response.setHeader("Connection", "close");
176: response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
177: response.flushBuffer();
178: return;
179: }
180: }
181: super.service(request, response);
182: }
183: }
|