NetworkExplorerpublic class NetworkExplorer extends HttpServlet 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. |
Fields Summary |
---|
private static jcifs.util.LogStream | log | private jcifs.util.MimeMap | mimeMap | private String | style | private NtlmSsp | ntlmSsp | private boolean | credentialsSupplied | private boolean | enableBasic | private boolean | insecureBasic | private String | realm | private String | defaultDomain |
Methods Summary |
---|
protected int | compareDates(SmbFile f1, java.lang.String f1name, SmbFile f2)
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 int | compareNames(SmbFile f1, java.lang.String f1name, SmbFile f2)
if( f1.isDirectory() != f2.isDirectory() ) {
return f1.isDirectory() ? -1 : 1;
}
return f1name.compareToIgnoreCase( f2.getName() );
| protected int | compareSizes(SmbFile f1, java.lang.String f1name, SmbFile f2)
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, java.lang.String f1name, SmbFile f2)
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 void | doDirectory(javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse resp, SmbFile dir)
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( "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">" );
out.println( "<html><head><title>Network Explorer</title>" );
out.println( "<meta HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">" );
out.println( "<style TYPE=\"text/css\">" );
out.println( style );
if( dirents.length < 200 ) {
out.println( " a:hover {" );
out.println( " background: #a2ff01;" );
out.println( " }" );
}
out.println( "</STYLE>" );
out.println( "</head><body>" );
out.print( "<a class=\"sort\" style=\"width: " + maxLen + ";\" href=\"?fmt=detail&sort=name\">Name</a>" );
out.println( "<a class=\"sort\" href=\"?fmt=detail&sort=size\">Size</a>" );
out.println( "<a class=\"sort\" href=\"?fmt=detail&sort=type\">Type</a>" );
out.println( "<a class=\"sort\" style=\"width: 180\" href=\"?fmt=detail&sort=date\">Modified</a><br clear='all'><p>" );
path = dir.getCanonicalPath();
if( path.length() < 7 ) {
out.println( "<b><big>smb://</big></b><br>" );
path = ".";
} else {
out.println( "<b><big>" + path + "</big></b><br>" );
path = "../";
}
out.println( (dirCount + fileCount) + " objects (" + dirCount + " directories, " + fileCount + " files)<br>" );
out.println( "<b><a class=\"plain\" href=\".\">normal</a> | <a class=\"plain\" href=\"?fmt=detail\">detailed</a></b>" );
out.println( "<p><table border='0' cellspacing='0' cellpadding='0'><tr><td>" );
out.print( "<A style=\"width: " + maxLen );
out.print( "; height: 18;\" HREF=\"" );
out.print( path );
out.println( "\"><b>↑</b></a>" );
if( fmt.equals( "detail" )) {
out.println( "<br clear='all'>" );
}
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( "<A style=\"width: " + maxLen );
out.print( "; height: 18;\" HREF=\"" );
out.print( path );
out.print( name );
if( f.isDirectory() ) {
out.print( "?fmt=detail\"><b>" );
out.print( name );
out.print( "</b></a>" );
} else {
out.print( "\"><b>" );
out.print( name );
out.print( "</b></a><div align='right'>" );
out.print( (f.length() / 1024) + " KB </div><div>" );
i = name.lastIndexOf( '." ) + 1;
if( i > 1 && (name.length() - i) < 6 ) {
out.print( name.substring( i ).toUpperCase() + "</div class='ext'>" );
} else {
out.print( " </div>" );
}
out.print( "<div style='width: 180'>" );
out.print( sdf.format( new Date( f.lastModified() )));
out.print( "</div>" );
}
out.println( "<br clear='all'>" );
} else {
out.print( "<A style=\"width: " + maxLen );
if( f.isDirectory() ) {
out.print( "; height: 18;\" HREF=\"" );
out.print( path );
out.print( name );
out.print( "\"><b>" );
out.print( name );
out.print( "</b></a>" );
} else {
out.print( ";\" HREF=\"" );
out.print( path );
out.print( name );
out.print( "\"><b>" );
out.print( name );
out.print( "</b><br><small>" );
out.print( (f.length() / 1024) + "KB <br>" );
out.print( sdf.format( new Date( f.lastModified() )));
out.print( "</small>" );
out.println( "</a>" );
}
}
}
out.println( "</td></tr></table>" );
out.println( "</BODY></HTML>" );
out.close();
| protected void | doFile(javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse resp, SmbFile file)
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 );
}
| public void | doGet(javax.servlet.http.HttpServletRequest req, javax.servlet.http.HttpServletResponse resp)
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;
}
| public void | init()
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 ) {
}
}
| private java.lang.String | parseServerAndShare(java.lang.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 );
|
|