JarURLConnection.java (getCertificates): New method from Classpath.

* java/net/JarURLConnection.java (getCertificates): New method
	from Classpath.
	* java/net/URLClassLoader.java (URLClassLoader): Extends
	SecureClassLoader.
	(definePackage): New method from Classpath.
	(getPermissions): Likewise.
	(newInstance): Likewise.
	(findClass): Construct CodeSource for new class (from Classpath).
	* java/net/SocketImpl.java (shutdownInput, shutdownOutput): New
	methods.
	* java/net/URL.java (getUserInfo): New method.
	(set(String,String,int,String,String,String,String,String)): New
	method.
	* java/net/PlainSocketImpl.java (_Jv_SO_KEEPALIVE_): Define.
	(shutdownInput, shutdownOutput): Declare.
	* java/net/PlainDatagramSocketImpl.java (_Jv_SO_KEEPALIVE_):
	Define.
	* java/net/natPlainSocketImpl.cc (setOption): Handle keepalive.
	(getOption): Likewise.
	(shutdownInput): New method.
	(shutdownOutput): Likewise.
	* java/net/natPlainDatagramSocketImpl.cc (setOption): Handle
	keepalive.
	(getOption): Likewise.
	* java/net/SocketOptions.java (SO_KEEPALIVE): New constant.
	* java/net/Socket.java (setKeepAlive): New method.
	(getKeepAlive): Likewise.
	(shutdownInput, shutdownOutput): New methods.

From-SVN: r56685
This commit is contained in:
Tom Tromey 2002-08-30 18:16:00 +00:00 committed by Tom Tromey
parent 55f49e3d50
commit 4c322bff29
11 changed files with 392 additions and 15 deletions

View file

@ -1,4 +1,4 @@
/* Copyright (C) 1999, 2000 Free Software Foundation
/* Copyright (C) 1999, 2000, 2002 Free Software Foundation
This file is part of libgcj.
@ -12,11 +12,15 @@ import java.io.*;
import java.util.jar.*;
import java.util.Enumeration;
import java.util.Vector;
import java.security.CodeSource;
import java.security.SecureClassLoader;
import java.security.PermissionCollection;
import java.security.cert.Certificate;
/**
* @since 1.2
*/
public class URLClassLoader extends ClassLoader
public class URLClassLoader extends SecureClassLoader
{
// The URLStreamHandlerFactory
URLStreamHandlerFactory factory = null;
@ -228,12 +232,12 @@ public class URLClassLoader extends ClassLoader
try
{
URL u = getResource (name.replace ('.', '/') + ".class");
URL url = getResource (name.replace ('.', '/') + ".class");
if (u == null)
if (url == null)
throw new ClassNotFoundException (name);
URLConnection connection = u.openConnection ();
URLConnection connection = url.openConnection ();
InputStream is = connection.getInputStream ();
int len = connection.getContentLength ();
@ -250,12 +254,171 @@ public class URLClassLoader extends ClassLoader
off += c;
}
return defineClass (name, data, 0, len);
// Now construct the CodeSource (if loaded from a jar file)
CodeSource source = null;
if (url.getProtocol().equals("jar"))
{
Certificate[] certificates =
((JarURLConnection) connection).getCertificates();
String u = url.toExternalForm ();
u = u.substring (4); //skip "jar:"
int i = u.indexOf ('!');
if (i >= 0)
u = u.substring (0, i);
url = new URL("jar", "", u);
source = new CodeSource(url, certificates);
}
else if (url.getProtocol().equals("file"))
{
try
{
String u = url.toExternalForm();
// Skip "file:" and then get canonical directory name.
File f = new File(u.substring(5));
f = f.getCanonicalFile();
url = new URL("file", "", f.getParent());
source = new CodeSource (url, null);
}
catch (IOException ignore)
{
}
}
return defineClass (name, data, 0, len, source);
}
catch (java.io.IOException x)
{
throw new ClassNotFoundException(name);
}
}
}
/**
* Defines a Package based on the given name and the supplied manifest
* information. The manifest indicates the tile, version and
* vendor information of the specification and implementation and wheter the
* package is sealed. If the Manifest indicates that the package is sealed
* then the Package will be sealed with respect to the supplied URL.
*
* @exception IllegalArgumentException If this package name already exists
* in this class loader
* @param name The name of the package
* @param manifest The manifest describing the specification,
* implementation and sealing details of the package
* @param url the code source url to seal the package
* @return the defined Package
*/
protected Package definePackage(String name, Manifest manifest, URL url)
throws IllegalArgumentException
{
Attributes attr = manifest.getMainAttributes();
String specTitle =
attr.getValue(Attributes.Name.SPECIFICATION_TITLE);
String specVersion =
attr.getValue(Attributes.Name.SPECIFICATION_VERSION);
String specVendor =
attr.getValue(Attributes.Name.SPECIFICATION_VENDOR);
String implTitle =
attr.getValue(Attributes.Name.IMPLEMENTATION_TITLE);
String implVersion =
attr.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
String implVendor =
attr.getValue(Attributes.Name.IMPLEMENTATION_VENDOR);
// Look if the Manifest indicates that this package is sealed
// XXX - most likely not completely correct!
// Shouldn't we also check the sealed attribute of the complete jar?
// http://java.sun.com/products/jdk/1.3/docs/guide/extensions/spec.html#bundled
// But how do we get that jar manifest here?
String sealed = attr.getValue(Attributes.Name.SEALED);
if ("false".equals(sealed))
{
// Make sure that the URL is null so the package is not
// sealed.
url = null;
}
return definePackage(name, specTitle, specVersion, specVendor,
implTitle, implVersion, implVendor, url);
}
/**
* Returns the permissions needed to access a particular code source.
* These permissions includes those returned by
* <CODE>SecureClassLoader.getPermissions</CODE> and the actual permissions
* to access the objects referenced by the URL of the code source.
* The extra permissions added depend on the protocol and file portion of
* the URL in the code source. If the URL has the "file" protocol ends with
* a / character then it must be a directory and a file Permission to read
* everthing in that directory and all subdirectories is added. If the URL
* had the "file" protocol and doesn't end with a / character then it must
* be a normal file and a file permission to read that file is added. If the
* URL has any other protocol then a socket permission to connect and accept
* connections from the host portion of the URL is added.
* @param source The codesource that needs the permissions to be accessed
* @return the collection of permissions needed to access the code resource
* @see SecureClassLoader.getPermissions()
*/
protected PermissionCollection getPermissions(CodeSource source)
{
// XXX - This implementation does exactly as the Javadoc describes.
// But maybe we should/could use URLConnection.getPermissions()?
// First get the permissions that would normally be granted
PermissionCollection permissions = super.getPermissions(source);
// Now add the any extra permissions depending on the URL location
URL url = source.getLocation();
String protocol = url.getProtocol();
if (protocol.equals("file"))
{
String file = url.getFile();
// If the file end in / it must be an directory
if (file.endsWith("/"))
{
// Grant permission to read everything in that directory and
// all subdirectories
permissions.add(new FilePermission(file + "-", "read"));
}
else
{
// It is a 'normal' file
// Grant permission to access that file
permissions.add(new FilePermission(file, "read"));
}
}
else
{
// Grant permission to connect to and accept connections from host
String host = url.getHost();
permissions.add(new SocketPermission(host, "connect,accept"));
}
return permissions;
}
/**
* Creates a new instance of a URLClassLoader that gets classes from the
* supplied URLs. This class loader will have as parent the standard
* system class loader.
* @param urls the initial URLs used to resolve classes and resources
*/
public static URLClassLoader newInstance(URL urls[]) throws
SecurityException
{
return new URLClassLoader(urls);
}
/**
* Creates a new instance of a URLClassLoader that gets classes from the
* supplied URLs and with the supplied loader as parent class loader.
* @param urls the initial URLs used to resolve classes and resources
* @param parent the parent class loader
*/
public static URLClassLoader newInstance(URL urls[],
ClassLoader parent)
throws SecurityException
{
return new URLClassLoader(urls, parent);
}
}