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.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.text.SimpleDateFormat;
import java.net.UnknownHostException;
import jcifs.*;
import jcifs.http.*;
import jcifs.smb.*;
import jcifs.netbios.NbtAddress;
import jcifs.util.MimeMap;
import jcifs.util.Base64;
import jcifs.util.LogStream;
/**
* 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.
*/
public class NetworkExplorer extends HttpServlet {
private static LogStream log = LogStream.getInstance();
private MimeMap mimeMap;
private String style;
private NtlmSsp ntlmSsp;
private boolean credentialsSupplied;
private boolean enableBasic;
private boolean insecureBasic;
private String realm, defaultDomain;
public void init() throws ServletException {
InputStream is;
StringBuffer sb = new StringBuffer();
byte[] buf = new byte[1024];
int n, level;
String name;
Config.setProperty( "jcifs.smb.client.soTimeout", "600000" );
Config.setProperty( "jcifs.smb.client.attrExpirationPeriod", "300000" );
Enumeration e = getInitParameterNames();
while( e.hasMoreElements() ) {
name = (String)e.nextElement();
if( name.startsWith( "jcifs." )) {
Config.setProperty( name, getInitParameter( name ));
}
}
if( Config.getProperty( "jcifs.smb.client.username" ) == null ) {
ntlmSsp = new NtlmSsp();
} else {
credentialsSupplied = true;
}
try {
mimeMap = new MimeMap();
is = getClass().getClassLoader().getResourceAsStream( "jcifs/http/ne.css" );
while(( n = is.read( buf )) != -1 ) {
sb.append( new String( buf, 0, n, "ISO8859_1" ));
}
style = sb.toString();
} catch( IOException ioe ) {
throw new ServletException( ioe.getMessage() );
}
enableBasic = Config.getBoolean("jcifs.http.enableBasic", false );
insecureBasic = Config.getBoolean("jcifs.http.insecureBasic", false );
realm = Config.getProperty("jcifs.http.basicRealm");
if (realm == null) realm = "jCIFS";
defaultDomain = Config.getProperty("jcifs.smb.client.domain");
if(( level = Config.getInt( "jcifs.util.loglevel", -1 )) != -1 ) {
LogStream.setLevel( level );
}
if( log.level > 2 ) {
try {
Config.store( log, "JCIFS PROPERTIES" );
} catch( IOException ioe ) {
}
}
}
protected void doFile( HttpServletRequest req,
HttpServletResponse resp, SmbFile file ) throws IOException {
byte[] buf = new byte[8192];
SmbFileInputStream in;
ServletOutputStream out;
String url, type;
int n;
in = new SmbFileInputStream( file );
out = resp.getOutputStream();
url = file.getPath();
resp.setContentType( "text/plain" );
if(( n = url.lastIndexOf( '.' )) > 0 &&
( type = url.substring( n + 1 )) != null &&
type.length() > 1 && type.length() < 6 ) {
resp.setContentType( mimeMap.getMimeType( type ));
}
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;
}
protected void doDirectory( HttpServletRequest req, HttpServletResponse resp, SmbFile dir ) throws IOException {
PrintWriter out;
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.level > 2 )
log.println( 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() == SmbFile.TYPE_NAMED_PIPE ) {
continue;
}
} catch( SmbAuthException sae ) {
if( log.level > 2 )
sae.printStackTrace( log );
} catch( SmbException se ) {
if( log.level > 2 )
se.printStackTrace( log );
if( se.getNtStatus() != se.NT_STATUS_UNSUCCESSFUL ) {
throw se;
}
}
if( dirents[i].isDirectory() ) {
dirCount++;
} else {
fileCount++;
}
name = dirents[i].getName();
if( log.level > 3 )
log.println( 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, (SmbFile)iter.next() ) < 0 ) {
break;
}
} else if( sort == 1 ) {
if( compareSizes( dirents[i], name, (SmbFile)iter.next() ) < 0 ) {
break;
}
} else if( sort == 2 ) {
if( compareTypes( dirents[i], name, (SmbFile)iter.next() ) < 0 ) {
break;
}
} else if( sort == 3 ) {
if( compareDates( dirents[i], name, (SmbFile)iter.next() ) < 0 ) {
break;
}
}
}
sorted.add( j, dirents[i] );
}
if( maxLen > 50 ) {
maxLen = 50;
}
maxLen *= 9; /* convert to px */
out = resp.getWriter();
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.getCanonicalPath();
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() != SmbFile.TYPE_WORKGROUP ) {
path = "";
}
iter = sorted.listIterator();
while( iter.hasNext() ) {
f = (SmbFile)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 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 );
}
public void doGet( HttpServletRequest req,
HttpServletResponse resp ) throws IOException, ServletException {
UniAddress 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 = enableBasic && (insecureBasic || req.isSecure());
if( msg != null && (msg.startsWith( "NTLM " ) ||
(offerBasic && msg.startsWith("Basic ")))) {
if( msg.startsWith("NTLM ")) {
byte[] challenge;
if( pathInfo == null || server == null ) {
String mb = NbtAddress.getByName( NbtAddress.MASTER_BROWSER_NAME, 0x01, null ).getHostAddress();
dc = UniAddress.getByName( mb );
} else {
dc = UniAddress.getByName( server, possibleWorkgroup );
}
req.getSession(); /* ensure session id is set for cluster env. */
challenge = SmbSession.getChallenge( dc );
if(( ntlm = NtlmSsp.authenticate( 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) : defaultDomain;
user = (index != -1) ? user.substring(index + 1) : user;
ntlm = new NtlmPasswordAuthentication(domain, user, password);
}
req.getSession().setAttribute( "npa-" + server, ntlm );
} else if( !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=\"" + realm + "\"");
}
resp.setHeader( "Connection", "close" );
resp.setStatus( HttpServletResponse.SC_UNAUTHORIZED );
resp.flushBuffer();
return;
}
}
try {
SmbFile file;
if( ntlm != null ) {
file = new SmbFile( "smb:/" + pathInfo , ntlm );
} else if( server == null ) {
file = new SmbFile( "smb://" );
} else {
file = new SmbFile( "smb:/" + pathInfo );
}
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() == sae.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=\"" + realm + "\"");
}
resp.setHeader( "Connection", "close" );
resp.setStatus( HttpServletResponse.SC_UNAUTHORIZED );
resp.flushBuffer();
return;
} catch( DfsReferral dr ) {
StringBuffer redir = req.getRequestURL();
String qs = req.getQueryString();
redir = new StringBuffer( redir.substring( 0, redir.length() - req.getPathInfo().length() ));
redir.append( '/' );
redir.append(dr.server);
redir.append( '/' );
redir.append(dr.share);
redir.append( '/' );
if( qs != null ) {
redir.append( req.getQueryString() );
}
resp.sendRedirect( redir.toString() );
resp.flushBuffer();
return;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy