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 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 jcifs.Config;
038: import jcifs.UniAddress;
039:
040: import jcifs.smb.NtlmPasswordAuthentication;
041: import jcifs.smb.SmbAuthException;
042: import jcifs.smb.SmbSession;
043:
044: import jcifs.util.Base64;
045:
046: import 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: */
059:
060: public abstract class NtlmServlet extends HttpServlet {
061:
062: private String defaultDomain;
063:
064: private String domainController;
065:
066: private boolean loadBalance;
067:
068: private boolean enableBasic;
069:
070: private boolean insecureBasic;
071:
072: private String realm;
073:
074: public void init(ServletConfig config) throws ServletException {
075: super .init(config);
076:
077: /* Set jcifs properties we know we want; soTimeout and cachePolicy to 10min.
078: */
079: Config.setProperty("jcifs.smb.client.soTimeout", "300000");
080: Config.setProperty("jcifs.netbios.cachePolicy", "600");
081:
082: Enumeration e = config.getInitParameterNames();
083: String name;
084: while (e.hasMoreElements()) {
085: name = (String) e.nextElement();
086: if (name.startsWith("jcifs.")) {
087: Config.setProperty(name, config.getInitParameter(name));
088: }
089: }
090: defaultDomain = Config.getProperty("jcifs.smb.client.domain");
091: domainController = Config
092: .getProperty("jcifs.http.domainController");
093: if (domainController == null) {
094: domainController = defaultDomain;
095: loadBalance = Config.getBoolean("jcifs.http.loadBalance",
096: true);
097: }
098: enableBasic = Boolean.valueOf(
099: Config.getProperty("jcifs.http.enableBasic"))
100: .booleanValue();
101: insecureBasic = Boolean.valueOf(
102: Config.getProperty("jcifs.http.insecureBasic"))
103: .booleanValue();
104: realm = Config.getProperty("jcifs.http.basicRealm");
105: if (realm == null)
106: realm = "jCIFS";
107: }
108:
109: protected void service(HttpServletRequest request,
110: HttpServletResponse response) throws ServletException,
111: IOException {
112: UniAddress dc;
113: boolean offerBasic = enableBasic
114: && (insecureBasic || request.isSecure());
115: String msg = request.getHeader("Authorization");
116: if (msg != null
117: && (msg.startsWith("NTLM ") || (offerBasic && msg
118: .startsWith("Basic ")))) {
119: if (loadBalance) {
120: dc = new UniAddress(NbtAddress.getByName(
121: domainController, 0x1C, null));
122: } else {
123: dc = UniAddress.getByName(domainController, true);
124: }
125: NtlmPasswordAuthentication ntlm;
126: if (msg.startsWith("NTLM ")) {
127: byte[] challenge = SmbSession.getChallenge(dc);
128: ntlm = NtlmSsp.authenticate(request, response,
129: challenge);
130: if (ntlm == null)
131: return;
132: } else {
133: String auth = new String(Base64
134: .decode(msg.substring(6)), "US-ASCII");
135: int index = auth.indexOf(':');
136: String user = (index != -1) ? auth.substring(0, index)
137: : auth;
138: String password = (index != -1) ? auth
139: .substring(index + 1) : "";
140: index = user.indexOf('\\');
141: if (index == -1)
142: index = user.indexOf('/');
143: String domain = (index != -1) ? user
144: .substring(0, index) : defaultDomain;
145: user = (index != -1) ? user.substring(index + 1) : user;
146: ntlm = new NtlmPasswordAuthentication(domain, user,
147: password);
148: }
149: try {
150: SmbSession.logon(dc, ntlm);
151: } catch (SmbAuthException sae) {
152: response.setHeader("WWW-Authenticate", "NTLM");
153: if (offerBasic) {
154: response.addHeader("WWW-Authenticate",
155: "Basic realm=\"" + realm + "\"");
156: }
157: response.setHeader("Connection", "close");
158: response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
159: response.flushBuffer();
160: return;
161: }
162: HttpSession ssn = request.getSession();
163: ssn.setAttribute("NtlmHttpAuth", ntlm);
164: ssn.setAttribute("ntlmdomain", ntlm.getDomain());
165: ssn.setAttribute("ntlmuser", ntlm.getUsername());
166: } else {
167: HttpSession ssn = request.getSession(false);
168: if (ssn == null || ssn.getAttribute("NtlmHttpAuth") == null) {
169: response.setHeader("WWW-Authenticate", "NTLM");
170: if (offerBasic) {
171: response.addHeader("WWW-Authenticate",
172: "Basic realm=\"" + realm + "\"");
173: }
174: response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
175: response.flushBuffer();
176: return;
177: }
178: }
179: super.service(request, response);
180: }
181: }
|