
jcifs.http.NetworkExplorer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jcifs Show documentation
Show all versions of jcifs Show documentation
JCIFS is an Open Source client library that implements the CIFS/SMB networking protocol in 100% Java
/* jcifs smb client library in Java
* Copyright (C) 2002 "Michael B. Allen"
*
* This library 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.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.http;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.GregorianCalendar;
import java.util.LinkedList;
import java.util.ListIterator;
import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.bouncycastle.util.encoders.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jcifs.Address;
import jcifs.CIFSContext;
import jcifs.CIFSException;
import jcifs.Config;
import jcifs.DfsReferralData;
import jcifs.NameServiceClient;
import jcifs.SmbConstants;
import jcifs.config.PropertyConfiguration;
import jcifs.context.BaseContext;
import jcifs.netbios.NbtAddress;
import jcifs.smb.DfsReferral;
import jcifs.smb.NtStatus;
import jcifs.smb.NtlmPasswordAuthentication;
import jcifs.smb.SmbAuthException;
import jcifs.smb.SmbException;
import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileInputStream;
/**
* This servlet may be used to "browse" the entire hierarchy of resources
* on an SMB network like one might with Network Neighborhood or Windows
* Explorer. The users credentials with be negotiated using NTLM SSP if
* the client is Microsoft Internet Explorer.
*
* @deprecated Unsupported
*/
@Deprecated
public class NetworkExplorer extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = -3847521461674504364L;
private static final Logger log = LoggerFactory.getLogger(NetworkExplorer.class);
private String style;
private boolean credentialsSupplied;
private boolean enableBasic;
private boolean insecureBasic;
private String realm, defaultDomain;
private CIFSContext transportContext;
@Override
public void init () throws ServletException {
StringBuffer sb = new StringBuffer();
byte[] buf = new byte[1024];
int n;
String name;
Properties p = new Properties();
p.putAll(System.getProperties());
p.setProperty("jcifs.smb.client.soTimeout", "600000");
p.setProperty("jcifs.smb.client.attrExpirationPeriod", "300000");
Enumeration e = getInitParameterNames();
while ( e.hasMoreElements() ) {
name = e.nextElement();
if ( name.startsWith("jcifs.") ) {
p.setProperty(name, getInitParameter(name));
}
}
try {
if ( p.getProperty("jcifs.smb.client.username") == null ) {
new NtlmSsp();
}
else {
this.credentialsSupplied = true;
}
try {
try ( InputStream is = getClass().getClassLoader().getResourceAsStream("jcifs/http/ne.css"); ) {
while ( ( n = is.read(buf) ) != -1 ) {
sb.append(new String(buf, 0, n, "ISO8859_1"));
}
this.style = sb.toString();
}
}
catch ( IOException ioe ) {
throw new ServletException(ioe.getMessage());
}
this.enableBasic = Config.getBoolean(p, "jcifs.http.enableBasic", false);
this.insecureBasic = Config.getBoolean(p, "jcifs.http.insecureBasic", false);
this.realm = p.getProperty("jcifs.http.basicRealm");
if ( this.realm == null )
this.realm = "jCIFS";
this.defaultDomain = p.getProperty("jcifs.smb.client.domain");
this.transportContext = new BaseContext(new PropertyConfiguration(p));
}
catch ( CIFSException ex ) {
throw new ServletException("Failed to initialize CIFS context", ex);
}
}
protected void doFile ( HttpServletRequest req, HttpServletResponse resp, SmbFile file ) throws IOException {
byte[] buf = new byte[8192];
@SuppressWarnings ( "resource" )
ServletOutputStream out = resp.getOutputStream();
String url;
int n;
try ( SmbFileInputStream in = new SmbFileInputStream(file) ) {
url = file.getLocator().getPath();
resp.setContentType("text/plain");
resp.setContentType(URLConnection.guessContentTypeFromName(url));
resp.setHeader("Content-Length", file.length() + "");
resp.setHeader("Accept-Ranges", "Bytes");
while ( ( n = in.read(buf) ) != -1 ) {
out.write(buf, 0, n);
}
}
}
protected int compareNames ( SmbFile f1, String f1name, SmbFile f2 ) throws IOException {
if ( f1.isDirectory() != f2.isDirectory() ) {
return f1.isDirectory() ? -1 : 1;
}
return f1name.compareToIgnoreCase(f2.getName());
}
protected int compareSizes ( SmbFile f1, String f1name, SmbFile f2 ) throws IOException {
long diff;
if ( f1.isDirectory() != f2.isDirectory() ) {
return f1.isDirectory() ? -1 : 1;
}
if ( f1.isDirectory() ) {
return f1name.compareToIgnoreCase(f2.getName());
}
diff = f1.length() - f2.length();
if ( diff == 0 ) {
return f1name.compareToIgnoreCase(f2.getName());
}
return diff > 0 ? -1 : 1;
}
protected int compareTypes ( SmbFile f1, String f1name, SmbFile f2 ) throws IOException {
String f2name, t1, t2;
int i;
if ( f1.isDirectory() != f2.isDirectory() ) {
return f1.isDirectory() ? -1 : 1;
}
f2name = f2.getName();
if ( f1.isDirectory() ) {
return f1name.compareToIgnoreCase(f2name);
}
i = f1name.lastIndexOf('.');
t1 = i == -1 ? "" : f1name.substring(i + 1);
i = f2name.lastIndexOf('.');
t2 = i == -1 ? "" : f2name.substring(i + 1);
i = t1.compareToIgnoreCase(t2);
if ( i == 0 ) {
return f1name.compareToIgnoreCase(f2name);
}
return i;
}
protected int compareDates ( SmbFile f1, String f1name, SmbFile f2 ) throws IOException {
if ( f1.isDirectory() != f2.isDirectory() ) {
return f1.isDirectory() ? -1 : 1;
}
if ( f1.isDirectory() ) {
return f1name.compareToIgnoreCase(f2.getName());
}
return f1.lastModified() > f2.lastModified() ? -1 : 1;
}
@SuppressWarnings ( "resource" )
protected void doDirectory ( HttpServletRequest req, HttpServletResponse resp, SmbFile dir ) throws IOException {
PrintWriter out = resp.getWriter();
SmbFile[] dirents;
SmbFile f;
int i, j, len, maxLen, dirCount, fileCount, sort;
String str, name, path, fmt;
LinkedList sorted;
ListIterator iter;
SimpleDateFormat sdf = new SimpleDateFormat("MM/d/yy h:mm a");
GregorianCalendar cal = new GregorianCalendar();
sdf.setCalendar(cal);
dirents = dir.listFiles();
if ( log.isDebugEnabled() ) {
log.debug(dirents.length + " items listed");
}
sorted = new LinkedList<>();
if ( ( fmt = req.getParameter("fmt") ) == null ) {
fmt = "col";
}
sort = 0;
if ( ( str = req.getParameter("sort") ) == null || str.equals("name") ) {
sort = 0;
}
else if ( str.equals("size") ) {
sort = 1;
}
else if ( str.equals("type") ) {
sort = 2;
}
else if ( str.equals("date") ) {
sort = 3;
}
dirCount = fileCount = 0;
maxLen = 28;
for ( i = 0; i < dirents.length; i++ ) {
try {
if ( dirents[ i ].getType() == SmbConstants.TYPE_NAMED_PIPE ) {
continue;
}
}
catch ( SmbAuthException sae ) {
log.warn("Auth failed", sae);
}
catch ( SmbException se ) {
log.warn("Connection failed", se);
if ( se.getNtStatus() != NtStatus.NT_STATUS_UNSUCCESSFUL ) {
throw se;
}
}
if ( dirents[ i ].isDirectory() ) {
dirCount++;
}
else {
fileCount++;
}
name = dirents[ i ].getName();
if ( log.isDebugEnabled() ) {
log.debug(i + ": " + name);
}
len = name.length();
if ( len > maxLen ) {
maxLen = len;
}
iter = sorted.listIterator();
for ( j = 0; iter.hasNext(); j++ ) {
if ( sort == 0 ) {
if ( compareNames(dirents[ i ], name, iter.next()) < 0 ) {
break;
}
}
else if ( sort == 1 ) {
if ( compareSizes(dirents[ i ], name, iter.next()) < 0 ) {
break;
}
}
else if ( sort == 2 ) {
if ( compareTypes(dirents[ i ], name, iter.next()) < 0 ) {
break;
}
}
else if ( sort == 3 ) {
if ( compareDates(dirents[ i ], name, iter.next()) < 0 ) {
break;
}
}
}
sorted.add(j, dirents[ i ]);
}
if ( maxLen > 50 ) {
maxLen = 50;
}
maxLen *= 9; /* convert to px */
resp.setContentType("text/html");
out.println("");
out.println("Network Explorer ");
out.println("");
out.println("");
out.println("");
out.print("Name");
out.println("Size");
out.println("Type");
out.println("Modified
");
path = dir.getLocator().getCanonicalURL();
if ( path.length() < 7 ) {
out.println("smb://
");
path = ".";
}
else {
out.println("" + path + "
");
path = "../";
}
out.println( ( dirCount + fileCount ) + " objects (" + dirCount + " directories, " + fileCount + " files)
");
out.println("normal | detailed");
out.println("
");
out.print("↑");
if ( fmt.equals("detail") ) {
out.println("
");
}
if ( path.length() == 1 || dir.getType() != SmbConstants.TYPE_WORKGROUP ) {
path = "";
}
iter = sorted.listIterator();
while ( iter.hasNext() ) {
f = iter.next();
name = f.getName();
if ( fmt.equals("detail") ) {
out.print("");
out.print(name);
out.print("");
}
else {
out.print("\">");
out.print(name);
out.print("");
out.print( ( f.length() / 1024 ) + " KB ");
i = name.lastIndexOf('.') + 1;
if ( i > 1 && ( name.length() - i ) < 6 ) {
out.print(name.substring(i).toUpperCase() + "");
}
else {
out.print(" ");
}
out.print("");
out.print(sdf.format(new Date(f.lastModified())));
out.print("");
}
out.println("
");
}
else {
out.print("");
out.print(name);
out.print("");
}
else {
out.print(";\" HREF=\"");
out.print(path);
out.print(name);
out.print("\">");
out.print(name);
out.print("
");
out.print( ( f.length() / 1024 ) + "KB
");
out.print(sdf.format(new Date(f.lastModified())));
out.print("");
out.println("");
}
}
}
out.println("
");
out.println("");
out.close();
}
private static String parseServerAndShare ( String pathInfo ) {
char[] out = new char[256];
char ch;
int len, p, i;
if ( pathInfo == null ) {
return null;
}
len = pathInfo.length();
p = i = 0;
while ( p < len && pathInfo.charAt(p) == '/' ) {
p++;
}
if ( p == len ) {
return null;
}
/* collect server name */
while ( p < len && ( ch = pathInfo.charAt(p) ) != '/' ) {
out[ i++ ] = ch;
p++;
}
while ( p < len && pathInfo.charAt(p) == '/' ) {
p++;
}
if ( p < len ) { /* then there must be a share */
out[ i++ ] = '/';
do { /* collect the share name */
out[ i++ ] = ( ch = pathInfo.charAt(p++) );
}
while ( p < len && ch != '/' );
}
return new String(out, 0, i);
}
@Override
public void doGet ( HttpServletRequest req, HttpServletResponse resp ) throws IOException, ServletException {
Address dc;
String msg, pathInfo, server = null;
boolean offerBasic, possibleWorkgroup = true;
NtlmPasswordAuthentication ntlm = null;
HttpSession ssn = req.getSession(false);
if ( ( pathInfo = req.getPathInfo() ) != null ) {
int i;
server = parseServerAndShare(pathInfo);
if ( server != null && ( i = server.indexOf('/') ) > 0 ) {
server = server.substring(0, i).toLowerCase();
possibleWorkgroup = false;
}
}
msg = req.getHeader("Authorization");
offerBasic = this.enableBasic && ( this.insecureBasic || req.isSecure() );
if ( msg != null && ( msg.startsWith("NTLM ") || ( offerBasic && msg.startsWith("Basic ") ) ) ) {
if ( msg.startsWith("NTLM ") ) {
byte[] challenge;
NameServiceClient nameServiceClient = getTransportContext().getNameServiceClient();
if ( pathInfo == null || server == null ) {
String mb = nameServiceClient.getNbtByName(NbtAddress.MASTER_BROWSER_NAME, 0x01, null).getHostAddress();
dc = nameServiceClient.getByName(mb);
}
else {
dc = nameServiceClient.getByName(server, possibleWorkgroup);
}
req.getSession(); /* ensure session id is set for cluster env. */
challenge = getTransportContext().getTransportPool().getChallenge(getTransportContext(), dc);
if ( ( ntlm = NtlmSsp.authenticate(getTransportContext(), req, resp, challenge) ) == null ) {
return;
}
}
else { /* Basic */
String auth = new String(Base64.decode(msg.substring(6)), "US-ASCII");
int index = auth.indexOf(':');
String user = ( index != -1 ) ? auth.substring(0, index) : auth;
String password = ( index != -1 ) ? auth.substring(index + 1) : "";
index = user.indexOf('\\');
if ( index == -1 )
index = user.indexOf('/');
String domain = ( index != -1 ) ? user.substring(0, index) : this.defaultDomain;
user = ( index != -1 ) ? user.substring(index + 1) : user;
ntlm = new NtlmPasswordAuthentication(getTransportContext(), domain, user, password);
}
req.getSession().setAttribute("npa-" + server, ntlm);
}
else if ( !this.credentialsSupplied ) {
if ( ssn != null ) {
ntlm = (NtlmPasswordAuthentication) ssn.getAttribute("npa-" + server);
}
if ( ntlm == null ) {
resp.setHeader("WWW-Authenticate", "NTLM");
if ( offerBasic ) {
resp.addHeader("WWW-Authenticate", "Basic realm=\"" + this.realm + "\"");
}
resp.setHeader("Connection", "close");
resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
resp.flushBuffer();
return;
}
}
try ( SmbFile file = openFile(pathInfo, server) ) {
if ( file.isDirectory() ) {
doDirectory(req, resp, file);
}
else {
doFile(req, resp, file);
}
}
catch ( SmbAuthException sae ) {
if ( ssn != null ) {
ssn.removeAttribute("npa-" + server);
}
if ( sae.getNtStatus() == NtStatus.NT_STATUS_ACCESS_VIOLATION ) {
/*
* Server challenge no longer valid for
* externally supplied password hashes.
*/
resp.sendRedirect(req.getRequestURL().toString());
return;
}
resp.setHeader("WWW-Authenticate", "NTLM");
if ( offerBasic ) {
resp.addHeader("WWW-Authenticate", "Basic realm=\"" + this.realm + "\"");
}
resp.setHeader("Connection", "close");
resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
resp.flushBuffer();
return;
}
catch ( DfsReferral dr ) {
StringBuffer redir = req.getRequestURL();
String qs = req.getQueryString();
DfsReferralData refdata = dr.getData();
redir = new StringBuffer(redir.substring(0, redir.length() - req.getPathInfo().length()));
redir.append('/');
redir.append(refdata.getServer());
redir.append('/');
redir.append(refdata.getShare());
redir.append('/');
if ( qs != null ) {
redir.append(req.getQueryString());
}
resp.sendRedirect(redir.toString());
resp.flushBuffer();
return;
}
}
/**
* @param pathInfo
* @param server
* @return
* @throws MalformedURLException
*/
private SmbFile openFile ( String pathInfo, String server ) throws MalformedURLException {
SmbFile file;
if ( server == null ) {
file = new SmbFile("smb://", getTransportContext());
}
else {
file = new SmbFile("smb:/" + pathInfo, getTransportContext());
}
return file;
}
/**
* @return
*/
private CIFSContext getTransportContext () {
return this.transportContext;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy