This commit is contained in:
Chris Hegarty 2009-10-21 15:47:09 +01:00
commit ee00e01c67
31 changed files with 4384 additions and 869 deletions

View File

@ -45,8 +45,14 @@ FILES_java = \
sun/net/dns/ResolverConfiguration.java \
sun/net/dns/ResolverConfigurationImpl.java \
sun/net/ftp/FtpClient.java \
sun/net/ftp/FtpClientProvider.java \
sun/net/ftp/FtpDirEntry.java \
sun/net/ftp/FtpReplyCode.java \
sun/net/ftp/FtpDirParser.java \
sun/net/ftp/FtpLoginException.java \
sun/net/ftp/FtpProtocolException.java \
sun/net/ftp/impl/FtpClient.java \
sun/net/ftp/impl/DefaultFtpClientProvider.java \
sun/net/spi/DefaultProxySelector.java \
sun/net/spi/nameservice/NameServiceDescriptor.java \
sun/net/spi/nameservice/NameService.java \

View File

@ -2051,6 +2051,8 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
*
* @param n shift distance, in bits.
* @return {@code this << n}
* @throws ArithmeticException if the shift distance is {@code
* Integer.MIN_VALUE}.
* @see #shiftRight
*/
public BigInteger shiftLeft(int n) {
@ -2058,8 +2060,13 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
return ZERO;
if (n==0)
return this;
if (n<0)
return shiftRight(-n);
if (n<0) {
if (n == Integer.MIN_VALUE) {
throw new ArithmeticException("Shift distance of Integer.MIN_VALUE not supported.");
} else {
return shiftRight(-n);
}
}
int nInts = n >>> 5;
int nBits = n & 0x1f;
@ -2097,13 +2104,20 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
*
* @param n shift distance, in bits.
* @return {@code this >> n}
* @throws ArithmeticException if the shift distance is {@code
* Integer.MIN_VALUE}.
* @see #shiftLeft
*/
public BigInteger shiftRight(int n) {
if (n==0)
return this;
if (n<0)
return shiftLeft(-n);
if (n<0) {
if (n == Integer.MIN_VALUE) {
throw new ArithmeticException("Shift distance of Integer.MIN_VALUE not supported.");
} else {
return shiftLeft(-n);
}
}
int nInts = n >>> 5;
int nBits = n & 0x1f;

View File

@ -101,11 +101,21 @@ public abstract class CookieHandler {
* Gets all the applicable cookies from a cookie cache for the
* specified uri in the request header.
*
* HTTP protocol implementers should make sure that this method is
* called after all request headers related to choosing cookies
* are added, and before the request is sent.
* <P>The {@code URI} passed as an argument specifies the intended use for
* the cookies. In particular the scheme should reflect whether the cookies
* will be sent over http, https or used in another context like javascript.
* The host part should reflect either the destination of the cookies or
* their origin in the case of javascript.</P>
* <P>It is up to the implementation to take into account the {@code URI} and
* the cookies attributes and security settings to determine which ones
* should be returned.</P>
*
* @param uri a <code>URI</code> to send cookies to in a request
* <P>HTTP protocol implementers should make sure that this method is
* called after all request headers related to choosing cookies
* are added, and before the request is sent.</P>
*
* @param uri a <code>URI</code> representing the intended use for the
* cookies
* @param requestHeaders - a Map from request header
* field names to lists of field values representing
* the current request headers

View File

@ -218,6 +218,13 @@ public class CookieManager extends CookieHandler
// 'secure' cookies over unsecure links)
if (pathMatches(path, cookie.getPath()) &&
(secureLink || !cookie.getSecure())) {
// Enforce httponly attribute
if (cookie.isHttpOnly()) {
String s = uri.getScheme();
if (!"http".equalsIgnoreCase(s) && !"https".equalsIgnoreCase(s)) {
continue;
}
}
// Let's check the authorize port list if it exists
String ports = cookie.getPortlist();
if (ports != null && !ports.isEmpty()) {

View File

@ -1,5 +1,5 @@
/*
* Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -297,6 +297,7 @@ class JarFile extends ZipFile {
String name = names[i].toUpperCase(Locale.ENGLISH);
if (name.endsWith(".DSA") ||
name.endsWith(".RSA") ||
name.endsWith(".EC") ||
name.endsWith(".SF")) {
// Assume since we found a signature-related file
// that the jar is signed and that we therefore

View File

@ -1,5 +1,5 @@
/*
* Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -50,7 +50,7 @@ class JarVerifier {
private Hashtable verifiedSigners;
/* a table mapping names to code signers, for jar entries that have
passed the .SF/.DSA -> MANIFEST check */
passed the .SF/.DSA/.EC -> MANIFEST check */
private Hashtable sigFileSigners;
/* a hash table to hold .SF bytes */
@ -111,7 +111,7 @@ class JarVerifier {
/*
* Assumptions:
* 1. The manifest should be the first entry in the META-INF directory.
* 2. The .SF/.DSA files follow the manifest, before any normal entries
* 2. The .SF/.DSA/.EC files follow the manifest, before any normal entries
* 3. Any of the following will throw a SecurityException:
* a. digest mismatch between a manifest section and
* the SF section.
@ -129,7 +129,7 @@ class JarVerifier {
}
if (SignatureFileVerifier.isBlockOrSF(uname)) {
/* We parse only DSA or RSA PKCS7 blocks. */
/* We parse only DSA, RSA or EC PKCS7 blocks. */
parsingBlockOrSF = true;
baos.reset();
mev.setEntry(null, je);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,158 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.net.ftp;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ServiceConfigurationError;
//import sun.misc.Service;
/**
* Service provider class for FtpClient.
* Sub-classes of FtpClientProvider provide an implementation of {@link FtpClient}
* and associated classes. Applications do not normally use this class directly.
* See {@link #provider() } for how providers are found and loaded.
*
* @since 1.7
*/
public abstract class FtpClientProvider {
/**
* Creates a FtpClient from this provider.
*
* @return The created {@link FtpClient}.
*/
public abstract FtpClient createFtpClient();
private static final Object lock = new Object();
private static FtpClientProvider provider = null;
/**
* Initializes a new instance of this class.
*
* @throws SecurityException if a security manager is installed and it denies
* {@link RuntimePermission}<tt>("ftpClientProvider")</tt>
*/
protected FtpClientProvider() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("ftpClientProvider"));
}
}
private static boolean loadProviderFromProperty() {
String cm = System.getProperty("sun.net.ftpClientProvider");
if (cm == null) {
return false;
}
try {
Class c = Class.forName(cm, true, null);
provider = (FtpClientProvider) c.newInstance();
return true;
} catch (ClassNotFoundException x) {
throw new ServiceConfigurationError(x.toString());
} catch (IllegalAccessException x) {
throw new ServiceConfigurationError(x.toString());
} catch (InstantiationException x) {
throw new ServiceConfigurationError(x.toString());
} catch (SecurityException x) {
throw new ServiceConfigurationError(x.toString());
}
}
private static boolean loadProviderAsService() {
// Iterator i = Service.providers(FtpClientProvider.class,
// ClassLoader.getSystemClassLoader());
// while (i.hasNext()) {
// try {
// provider = (FtpClientProvider) i.next();
// return true;
// } catch (ServiceConfigurationError sce) {
// if (sce.getCause() instanceof SecurityException) {
// // Ignore, try next provider, if any
// continue;
// }
// throw sce;
// }
// }
return false;
}
/**
* Returns the system wide default FtpClientProvider for this invocation of
* the Java virtual machine.
*
* <p> The first invocation of this method locates the default provider
* object as follows: </p>
*
* <ol>
*
* <li><p> If the system property
* <tt>java.net.FtpClientProvider</tt> is defined then it is
* taken to be the fully-qualified name of a concrete provider class.
* The class is loaded and instantiated; if this process fails then an
* unspecified unchecked error or exception is thrown. </p></li>
*
* <li><p> If a provider class has been installed in a jar file that is
* visible to the system class loader, and that jar file contains a
* provider-configuration file named
* <tt>java.net.FtpClientProvider</tt> in the resource
* directory <tt>META-INF/services</tt>, then the first class name
* specified in that file is taken. The class is loaded and
* instantiated; if this process fails then an unspecified unchecked error or exception is
* thrown. </p></li>
*
* <li><p> Finally, if no provider has been specified by any of the above
* means then the system-default provider class is instantiated and the
* result is returned. </p></li>
*
* </ol>
*
* <p> Subsequent invocations of this method return the provider that was
* returned by the first invocation. </p>
*
* @return The system-wide default FtpClientProvider
*/
public static FtpClientProvider provider() {
synchronized (lock) {
if (provider != null) {
return provider;
}
return (FtpClientProvider) AccessController.doPrivileged(
new PrivilegedAction<Object>() {
public Object run() {
if (loadProviderFromProperty()) {
return provider;
}
if (loadProviderAsService()) {
return provider;
}
provider = new sun.net.ftp.impl.DefaultFtpClientProvider();
return provider;
}
});
}
}
}

View File

@ -0,0 +1,331 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.net.ftp;
import java.util.Date;
import java.util.HashMap;
/**
* A {@code FtpDirEntry} is a class agregating all the information that the FTP client
* can gather from the server by doing a {@code LST} (or {@code NLST}) command and
* parsing the output. It will typically contain the name, type, size, last modification
* time, owner and group of the file, although some of these could be unavailable
* due to specific FTP server limitations.
*
* @see sun.net.ftp.FtpDirParser
* @since 1.7
*/
public class FtpDirEntry {
public enum Type {
FILE, DIR, PDIR, CDIR, LINK
};
public enum Permission {
USER(0), GROUP(1), OTHERS(2);
int value;
Permission(int v) {
value = v;
}
};
private final String name;
private String user = null;
private String group = null;
private long size = -1;
private java.util.Date created = null;
private java.util.Date lastModified = null;
private Type type = Type.FILE;
private boolean[][] permissions = null;
private HashMap<String, String> facts = new HashMap<String, String>();
private FtpDirEntry() {
name = null;
}
/**
* Creates an FtpDirEntry instance with only the name being set.
*
* @param name The name of the file
*/
public FtpDirEntry(String name) {
this.name = name;
}
/**
* Returns the name of the remote file.
*
* @return a {@code String} containing the name of the remote file.
*/
public String getName() {
return name;
}
/**
* Returns the user name of the owner of the file as returned by the FTP
* server, if provided. This could be a name or a user id (number).
*
* @return a {@code String} containing the user name or
* {@code null} if that information is not available.
*/
public String getUser() {
return user;
}
/**
* Sets the user name of the owner of the file. Intended mostly to be
* used from inside a {@link java.net.FtpDirParser} implementation.
*
* @param user The user name of the owner of the file, or {@code null}
* if that information is not available.
* @return this FtpDirEntry
*/
public FtpDirEntry setUser(String user) {
this.user = user;
return this;
}
/**
* Returns the group name of the file as returned by the FTP
* server, if provided. This could be a name or a group id (number).
*
* @return a {@code String} containing the group name or
* {@code null} if that information is not available.
*/
public String getGroup() {
return group;
}
/**
* Sets the name of the group to which the file belong. Intended mostly to be
* used from inside a {@link java.net.FtpDirParser} implementation.
*
* @param group The name of the group to which the file belong, or {@code null}
* if that information is not available.
* @return this FtpDirEntry
*/
public FtpDirEntry setGroup(String group) {
this.group = group;
return this;
}
/**
* Returns the size of the remote file as it was returned by the FTP
* server, if provided.
*
* @return the size of the file or -1 if that information is not available.
*/
public long getSize() {
return size;
}
/**
* Sets the size of that file. Intended mostly to be used from inside an
* {@link java.net.FtpDirParser} implementation.
*
* @param size The size, in bytes, of that file. or -1 if unknown.
* @return this FtpDirEntry
*/
public FtpDirEntry setSize(long size) {
this.size = size;
return this;
}
/**
* Returns the type of the remote file as it was returned by the FTP
* server, if provided.
* It returns a FtpDirEntry.Type enum and the values can be:
* - FtpDirEntry.Type.FILE for a normal file
* - FtpDirEntry.Type.DIR for a directory
* - FtpDirEntry.Type.LINK for a symbolic link
*
* @return a {@code FtpDirEntry.Type} describing the type of the file
* or {@code null} if that information is not available.
*/
public Type getType() {
return type;
}
/**
* Sets the type of the file. Intended mostly to be used from inside an
* {@link java.net.FtpDirParser} implementation.
*
* @param type the type of this file or {@code null} if that information
* is not available.
* @return this FtpDirEntry
*/
public FtpDirEntry setType(Type type) {
this.type = type;
return this;
}
/**
* Returns the last modification time of the remote file as it was returned
* by the FTP server, if provided, {@code null} otherwise.
*
* @return a <code>Date</code> representing the last time the file was
* modified on the server, or {@code null} if that
* information is not available.
*/
public java.util.Date getLastModified() {
return this.lastModified;
}
/**
* Sets the last modification time of the file. Intended mostly to be used
* from inside an {@link java.net.FtpDirParser} implementation.
*
* @param lastModified The Date representing the last modification time, or
* {@code null} if that information is not available.
* @return this FtpDirEntry
*/
public FtpDirEntry setLastModified(Date lastModified) {
this.lastModified = lastModified;
return this;
}
/**
* Returns whether read access is granted for a specific permission.
*
* @param p the Permission (user, group, others) to check.
* @return {@code true} if read access is granted.
*/
public boolean canRead(Permission p) {
if (permissions != null) {
return permissions[p.value][0];
}
return false;
}
/**
* Returns whether write access is granted for a specific permission.
*
* @param p the Permission (user, group, others) to check.
* @return {@code true} if write access is granted.
*/
public boolean canWrite(Permission p) {
if (permissions != null) {
return permissions[p.value][1];
}
return false;
}
/**
* Returns whether execute access is granted for a specific permission.
*
* @param p the Permission (user, group, others) to check.
* @return {@code true} if execute access is granted.
*/
public boolean canExexcute(Permission p) {
if (permissions != null) {
return permissions[p.value][2];
}
return false;
}
/**
* Sets the permissions for that file. Intended mostly to be used
* from inside an {@link java.net.FtpDirParser} implementation.
* The permissions array is a 3x3 {@code boolean} array, the first index being
* the User, group or owner (0, 1 and 2 respectively) while the second
* index is read, write or execute (0, 1 and 2 respectively again).
* <p>E.G.: {@code permissions[1][2]} is the group/execute permission.</p>
*
* @param permissions a 3x3 {@code boolean} array
* @return this {@code FtpDirEntry}
*/
public FtpDirEntry setPermissions(boolean[][] permissions) {
this.permissions = permissions;
return this;
}
/**
* Adds a 'fact', as defined in RFC 3659, to the list of facts of this file.
* Intended mostly to be used from inside a {@link java.net.FtpDirParser}
* implementation.
*
* @param fact the name of the fact (e.g. "Media-Type"). It is not case-sensitive.
* @param value the value associated with this fact.
* @return this {@code FtpDirEntry}
*/
public FtpDirEntry addFact(String fact, String value) {
facts.put(fact.toLowerCase(), value);
return this;
}
/**
* Returns the requested 'fact', as defined in RFC 3659, if available.
*
* @param fact The name of the fact *e.g. "Media-Type"). It is not case sensitive.
* @return The value of the fact or, {@code null} if that fact wasn't
* provided by the server.
*/
public String getFact(String fact) {
return facts.get(fact.toLowerCase());
}
/**
* Returns the creation time of the file, when provided by the server.
*
* @return The Date representing the creation time, or {@code null}
* if the server didn't provide that information.
*/
public Date getCreated() {
return created;
}
/**
* Sets the creation time for that file. Intended mostly to be used from
* inside a {@link java.net.FtpDirParser} implementation.
*
* @param created the Date representing the creation time for that file, or
* {@code null} if that information is not available.
* @return this FtpDirEntry
*/
public FtpDirEntry setCreated(Date created) {
this.created = created;
return this;
}
/**
* Returns a string representation of the object.
* The {@code toString} method for class {@code FtpDirEntry}
* returns a string consisting of the name of the file, followed by its
* type between brackets, followed by the user and group between
* parenthesis, then size between '{', and, finally, the lastModified of last
* modification if it's available.
*
* @return a string representation of the object.
*/
@Override
public String toString() {
if (lastModified == null) {
return name + " [" + type + "] (" + user + " / " + group + ") " + size;
}
return name + " [" + type + "] (" + user + " / " + group + ") {" + size + "} " + java.text.DateFormat.getDateInstance().format(lastModified);
}
}

View File

@ -0,0 +1,49 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.net.ftp;
/**
* This interface describes a parser for the FtpClient class. Such a parser is
* used when listing a remote directory to transform text lines like:
* drwxr-xr-x 1 user01 ftp 512 Jan 29 23:32 prog
* into FtpDirEntry instances.
*
* @see java.net.FtpClient#setFileParser(FtpDirParser)
* @since 1.7
*/
public interface FtpDirParser {
/**
* Takes one line from a directory listing and returns an FtpDirEntry instance
* based on the information contained.
*
* @param line a <code>String</code>, a line sent by the FTP server as a
* result of the LST command.
* @return an <code>FtpDirEntry</code> instance.
* @see java.net.FtpDirEntry
*/
public FtpDirEntry parseLine(String line);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1994-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,7 +25,7 @@
package sun.net.ftp;
import java.io.*;
import java.io.IOException;
/**
* This exception is thrown when an error is encountered during an
@ -33,10 +33,10 @@ import java.io.*;
*
* @author Jonathan Payne
*/
public class FtpLoginException extends FtpProtocolException {
public class FtpLoginException extends IOException {
private static final long serialVersionUID = 2218162403237941536L;
FtpLoginException(String s) {
public FtpLoginException(String s) {
super(s);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1994-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -22,21 +22,49 @@
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.net.ftp;
import java.io.*;
/**
* This exeception is thrown when unexpected results are returned during
* an FTP session.
*
* Thrown to indicate that the FTP server reported an error.
* For instance that the requested file doesn't exist or
* that a command isn't supported.
* <p>The specific error code can be retreived with {@link #getReplyCode() }.</p>
* @author Jonathan Payne
*/
public class FtpProtocolException extends IOException {
public class FtpProtocolException extends Exception {
private static final long serialVersionUID = 5978077070276545054L;
private final FtpReplyCode code;
FtpProtocolException(String s) {
super(s);
/**
* Constructs a new {@code FtpProtocolException} from the
* specified detail message. The reply code is set to unknow error.
*
* @param detail the detail message.
*/
public FtpProtocolException(String detail) {
super(detail);
code = FtpReplyCode.UNKNOWN_ERROR;
}
/**
* Constructs a new {@code FtpProtocolException} from the
* specified response code and exception detail message
*
* @param detail the detail message.
* @param code The {@code FtpRelyCode} received from server.
*/
public FtpProtocolException(String detail, FtpReplyCode code) {
super(detail);
this.code = code;
}
/**
* Gets the reply code sent by the server that led to this exception
* being thrown.
*
* @return The {@link FtpReplyCode} associated with that exception.
*/
public FtpReplyCode getReplyCode() {
return code;
}
}

View File

@ -0,0 +1,248 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.net.ftp;
/**
* This class describes a FTP protocol reply code and associates a meaning
* to the numerical value according to the various RFCs (RFC 959 in
* particular).
*
*/
public enum FtpReplyCode {
RESTART_MARKER(110),
SERVICE_READY_IN(120),
DATA_CONNECTION_ALREADY_OPEN(125),
FILE_STATUS_OK(150),
COMMAND_OK(200),
NOT_IMPLEMENTED(202),
SYSTEM_STATUS(211),
DIRECTORY_STATUS(212),
FILE_STATUS(213),
HELP_MESSAGE(214),
NAME_SYSTEM_TYPE(215),
SERVICE_READY(220),
SERVICE_CLOSING(221),
DATA_CONNECTION_OPEN(225),
CLOSING_DATA_CONNECTION(226),
ENTERING_PASSIVE_MODE(227),
ENTERING_EXT_PASSIVE_MODE(229),
LOGGED_IN(230),
SECURELY_LOGGED_IN(232),
SECURITY_EXCHANGE_OK(234),
SECURITY_EXCHANGE_COMPLETE(235),
FILE_ACTION_OK(250),
PATHNAME_CREATED(257),
NEED_PASSWORD(331),
NEED_ACCOUNT(332),
NEED_ADAT(334),
NEED_MORE_ADAT(335),
FILE_ACTION_PENDING(350),
SERVICE_NOT_AVAILABLE(421),
CANT_OPEN_DATA_CONNECTION(425),
CONNECTION_CLOSED(426),
NEED_SECURITY_RESOURCE(431),
FILE_ACTION_NOT_TAKEN(450),
ACTION_ABORTED(451),
INSUFFICIENT_STORAGE(452),
COMMAND_UNRECOGNIZED(500),
INVALID_PARAMETER(501),
BAD_SEQUENCE(503),
NOT_IMPLEMENTED_FOR_PARAMETER(504),
NOT_LOGGED_IN(530),
NEED_ACCOUNT_FOR_STORING(532),
PROT_LEVEL_DENIED(533),
REQUEST_DENIED(534),
FAILED_SECURITY_CHECK(535),
UNSUPPORTED_PROT_LEVEL(536),
PROT_LEVEL_NOT_SUPPORTED_BY_SECURITY(537),
FILE_UNAVAILABLE(550),
PAGE_TYPE_UNKNOWN(551),
EXCEEDED_STORAGE(552),
FILE_NAME_NOT_ALLOWED(553),
PROTECTED_REPLY(631),
UNKNOWN_ERROR(999);
private final int value;
FtpReplyCode(int val) {
this.value = val;
}
/**
* Returns the numerical value of the code.
*
* @return the numerical value.
*/
public int getValue() {
return value;
}
/**
* Determines if the code is a Positive Preliminary response.
* This means beginning with a 1 (which means a value between 100 and 199)
*
* @return <code>true</code> if the reply code is a positive preliminary
* response.
*/
public boolean isPositivePreliminary() {
return value >= 100 && value < 200;
}
/**
* Determines if the code is a Positive Completion response.
* This means beginning with a 2 (which means a value between 200 and 299)
*
* @return <code>true</code> if the reply code is a positive completion
* response.
*/
public boolean isPositiveCompletion() {
return value >= 200 && value < 300;
}
/**
* Determines if the code is a positive internediate response.
* This means beginning with a 3 (which means a value between 300 and 399)
*
* @return <code>true</code> if the reply code is a positive intermediate
* response.
*/
public boolean isPositiveIntermediate() {
return value >= 300 && value < 400;
}
/**
* Determines if the code is a transient negative response.
* This means beginning with a 4 (which means a value between 400 and 499)
*
* @return <code>true</code> if the reply code is a transient negative
* response.
*/
public boolean isTransientNegative() {
return value >= 400 && value < 500;
}
/**
* Determines if the code is a permanent negative response.
* This means beginning with a 5 (which means a value between 500 and 599)
*
* @return <code>true</code> if the reply code is a permanent negative
* response.
*/
public boolean isPermanentNegative() {
return value >= 500 && value < 600;
}
/**
* Determines if the code is a protected reply response.
* This means beginning with a 6 (which means a value between 600 and 699)
*
* @return <code>true</code> if the reply code is a protected reply
* response.
*/
public boolean isProtectedReply() {
return value >= 600 && value < 700;
}
/**
* Determines if the code is a syntax related response.
* This means the second digit is a 0.
*
* @return <code>true</code> if the reply code is a syntax related
* response.
*/
public boolean isSyntax() {
return ((value / 10) - ((value / 100) * 10)) == 0;
}
/**
* Determines if the code is an information related response.
* This means the second digit is a 1.
*
* @return <code>true</code> if the reply code is an information related
* response.
*/
public boolean isInformation() {
return ((value / 10) - ((value / 100) * 10)) == 1;
}
/**
* Determines if the code is a connection related response.
* This means the second digit is a 2.
*
* @return <code>true</code> if the reply code is a connection related
* response.
*/
public boolean isConnection() {
return ((value / 10) - ((value / 100) * 10)) == 2;
}
/**
* Determines if the code is an authentication related response.
* This means the second digit is a 3.
*
* @return <code>true</code> if the reply code is an authentication related
* response.
*/
public boolean isAuthentication() {
return ((value / 10) - ((value / 100) * 10)) == 3;
}
/**
* Determines if the code is an unspecified type of response.
* This means the second digit is a 4.
*
* @return <code>true</code> if the reply code is an unspecified type of
* response.
*/
public boolean isUnspecified() {
return ((value / 10) - ((value / 100) * 10)) == 4;
}
/**
* Determines if the code is a file system related response.
* This means the second digit is a 5.
*
* @return <code>true</code> if the reply code is a file system related
* response.
*/
public boolean isFileSystem() {
return ((value / 10) - ((value / 100) * 10)) == 5;
}
/**
* Static utility method to convert a value into a FtpReplyCode.
*
* @param v the value to convert
* @return the <code>FtpReplyCode</code> associated with the value.
*/
public static FtpReplyCode find(int v) {
for (FtpReplyCode code : FtpReplyCode.values()) {
if (code.getValue() == v) {
return code;
}
}
return UNKNOWN_ERROR;
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.net.ftp.impl;
/**
* Default FtpClientProvider.
* Uses sun.net.ftp.FtpCLient.
*/
public class DefaultFtpClientProvider extends sun.net.ftp.FtpClientProvider {
@Override
public sun.net.ftp.FtpClient createFtpClient() {
return sun.net.ftp.impl.FtpClient.create();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* Copyright 1994-2008 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1994-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -37,10 +37,8 @@ import java.io.FilterInputStream;
import java.io.FilterOutputStream;
import java.io.FileNotFoundException;
import java.net.URL;
import java.net.URLStreamHandler;
import java.net.SocketPermission;
import java.net.UnknownHostException;
import java.net.MalformedURLException;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.Proxy;
@ -84,7 +82,6 @@ public class FtpURLConnection extends URLConnection {
// In case we have to use proxies, we use HttpURLConnection
HttpURLConnection http = null;
private Proxy instProxy;
Proxy proxy = null;
InputStream is = null;
OutputStream os = null;
@ -125,12 +122,11 @@ public class FtpURLConnection extends URLConnection {
ftp = cl;
}
@Override
public void close() throws IOException {
super.close();
try {
if (ftp != null)
ftp.closeServer();
} catch (IOException ex) {
if (ftp != null) {
ftp.close();
}
}
}
@ -149,12 +145,11 @@ public class FtpURLConnection extends URLConnection {
ftp = cl;
}
@Override
public void close() throws IOException {
super.close();
try {
if (ftp != null)
ftp.closeServer();
} catch (IOException ex) {
if (ftp != null) {
ftp.close();
}
}
}
@ -192,10 +187,12 @@ public class FtpURLConnection extends URLConnection {
private void setTimeouts() {
if (ftp != null) {
if (connectTimeout >= 0)
if (connectTimeout >= 0) {
ftp.setConnectTimeout(connectTimeout);
if (readTimeout >= 0)
}
if (readTimeout >= 0) {
ftp.setReadTimeout(readTimeout);
}
}
}
@ -218,21 +215,22 @@ public class FtpURLConnection extends URLConnection {
* Do we have to use a proxy?
*/
ProxySelector sel = java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<ProxySelector>() {
public ProxySelector run() {
return ProxySelector.getDefault();
}
});
new java.security.PrivilegedAction<ProxySelector>() {
public ProxySelector run() {
return ProxySelector.getDefault();
}
});
if (sel != null) {
URI uri = sun.net.www.ParseUtil.toURI(url);
Iterator<Proxy> it = sel.select(uri).iterator();
while (it.hasNext()) {
p = it.next();
if (p == null || p == Proxy.NO_PROXY ||
p.type() == Proxy.Type.SOCKS)
p.type() == Proxy.Type.SOCKS) {
break;
}
if (p.type() != Proxy.Type.HTTP ||
!(p.address() instanceof InetSocketAddress)) {
!(p.address() instanceof InetSocketAddress)) {
sel.connectFailed(uri, p.address(), new IOException("Wrong proxy type"));
continue;
}
@ -240,10 +238,14 @@ public class FtpURLConnection extends URLConnection {
InetSocketAddress paddr = (InetSocketAddress) p.address();
try {
http = new HttpURLConnection(url, p);
if (connectTimeout >= 0)
http.setDoInput(getDoInput());
http.setDoOutput(getDoOutput());
if (connectTimeout >= 0) {
http.setConnectTimeout(connectTimeout);
if (readTimeout >= 0)
}
if (readTimeout >= 0) {
http.setReadTimeout(readTimeout);
}
http.connect();
connected = true;
return;
@ -257,10 +259,14 @@ public class FtpURLConnection extends URLConnection {
p = instProxy;
if (p.type() == Proxy.Type.HTTP) {
http = new HttpURLConnection(url, instProxy);
if (connectTimeout >= 0)
http.setDoInput(getDoInput());
http.setDoOutput(getDoOutput());
if (connectTimeout >= 0) {
http.setConnectTimeout(connectTimeout);
if (readTimeout >= 0)
}
if (readTimeout >= 0) {
http.setReadTimeout(readTimeout);
}
http.connect();
connected = true;
return;
@ -270,31 +276,35 @@ public class FtpURLConnection extends URLConnection {
if (user == null) {
user = "anonymous";
String vers = java.security.AccessController.doPrivileged(
new GetPropertyAction("java.version"));
new GetPropertyAction("java.version"));
password = java.security.AccessController.doPrivileged(
new GetPropertyAction("ftp.protocol.user",
"Java" + vers +"@"));
new GetPropertyAction("ftp.protocol.user",
"Java" + vers + "@"));
}
try {
if (p != null)
ftp = new FtpClient(p);
else
ftp = new FtpClient();
ftp = FtpClient.create();
if (p != null) {
ftp.setProxy(p);
}
setTimeouts();
if (port != -1)
ftp.openServer(host, port);
else
ftp.openServer(host);
if (port != -1) {
ftp.connect(new InetSocketAddress(host, port));
} else {
ftp.connect(new InetSocketAddress(host, FtpClient.defaultPort()));
}
} catch (UnknownHostException e) {
// Maybe do something smart here, like use a proxy like iftp.
// Just keep throwing for now.
throw e;
} catch (FtpProtocolException fe) {
throw new IOException(fe);
}
try {
ftp.login(user, password);
} catch (sun.net.ftp.FtpLoginException e) {
ftp.closeServer();
throw e;
ftp.login(user, password.toCharArray());
} catch (sun.net.ftp.FtpProtocolException e) {
ftp.close();
// Backward compatibility
throw new sun.net.ftp.FtpLoginException("Invalid username/password");
}
connected = true;
}
@ -306,24 +316,29 @@ public class FtpURLConnection extends URLConnection {
private void decodePath(String path) {
int i = path.indexOf(";type=");
if (i >= 0) {
String s1 = path.substring(i+6, path.length());
if ("i".equalsIgnoreCase(s1))
String s1 = path.substring(i + 6, path.length());
if ("i".equalsIgnoreCase(s1)) {
type = BIN;
if ("a".equalsIgnoreCase(s1))
}
if ("a".equalsIgnoreCase(s1)) {
type = ASCII;
if ("d".equalsIgnoreCase(s1))
}
if ("d".equalsIgnoreCase(s1)) {
type = DIR;
}
path = path.substring(0, i);
}
if (path != null && path.length() > 1 &&
path.charAt(0) == '/')
path.charAt(0) == '/') {
path = path.substring(1);
if (path == null || path.length() == 0)
}
if (path == null || path.length() == 0) {
path = "./";
}
if (!path.endsWith("/")) {
i = path.lastIndexOf('/');
if (i > 0) {
filename = path.substring(i+1, path.length());
filename = path.substring(i + 1, path.length());
filename = ParseUtil.decode(filename);
pathname = path.substring(0, i);
} else {
@ -334,10 +349,11 @@ public class FtpURLConnection extends URLConnection {
pathname = path.substring(0, path.length() - 1);
filename = null;
}
if (pathname != null)
if (pathname != null) {
fullpath = pathname + "/" + (filename != null ? filename : "");
else
} else {
fullpath = filename;
}
}
/*
@ -346,18 +362,19 @@ public class FtpURLConnection extends URLConnection {
* This is because, '/' is not necessarly the directory delimiter
* on every systems.
*/
private void cd(String path) throws IOException {
if (path == null || "".equals(path))
private void cd(String path) throws FtpProtocolException, IOException {
if (path == null || path.isEmpty()) {
return;
}
if (path.indexOf('/') == -1) {
ftp.cd(ParseUtil.decode(path));
ftp.changeDirectory(ParseUtil.decode(path));
return;
}
StringTokenizer token = new StringTokenizer(path,"/");
while (token.hasMoreTokens())
ftp.cd(ParseUtil.decode(token.nextToken()));
StringTokenizer token = new StringTokenizer(path, "/");
while (token.hasMoreTokens()) {
ftp.changeDirectory(ParseUtil.decode(token.nextToken()));
}
}
/**
@ -369,16 +386,19 @@ public class FtpURLConnection extends URLConnection {
* @throws IOException if already opened for output
* @throws FtpProtocolException if errors occur during the transfert.
*/
@Override
public InputStream getInputStream() throws IOException {
if (!connected) {
connect();
}
if (http != null)
if (http != null) {
return http.getInputStream();
}
if (os != null)
if (os != null) {
throw new IOException("Already opened for output");
}
if (is != null) {
return is;
@ -386,82 +406,85 @@ public class FtpURLConnection extends URLConnection {
MessageHeader msgh = new MessageHeader();
boolean isAdir = false;
try {
decodePath(url.getPath());
if (filename == null || type == DIR) {
ftp.ascii();
ftp.setAsciiType();
cd(pathname);
if (filename == null)
is = new FtpInputStream(ftp, ftp.list());
else
if (filename == null) {
is = new FtpInputStream(ftp, ftp.list(null));
} else {
is = new FtpInputStream(ftp, ftp.nameList(filename));
}
} else {
if (type == ASCII)
ftp.ascii();
else
ftp.binary();
if (type == ASCII) {
ftp.setAsciiType();
} else {
ftp.setBinaryType();
}
cd(pathname);
is = new FtpInputStream(ftp, ftp.get(filename));
is = new FtpInputStream(ftp, ftp.getFileStream(filename));
}
/* Try to get the size of the file in bytes. If that is
successful, then create a MeteredStream. */
successful, then create a MeteredStream. */
try {
String response = ftp.getResponseString();
int offset;
long l = ftp.getLastTransferSize();
msgh.add("content-length", Long.toString(l));
if (l > 0) {
if ((offset = response.indexOf(" bytes)")) != -1) {
int i = offset;
int c;
// Wrap input stream with MeteredStream to ensure read() will always return -1
// at expected length.
while (--i >= 0 && ((c = response.charAt(i)) >= '0'
&& c <= '9'))
;
long l = Long.parseLong(response.substring(i + 1, offset));
msgh.add("content-length", Long.toString(l));
if (l > 0) {
// Check if URL should be metered
boolean meteredInput = ProgressMonitor.getDefault().shouldMeterInput(url, "GET");
ProgressSource pi = null;
// Wrap input stream with MeteredStream to ensure read() will always return -1
// at expected length.
// Check if URL should be metered
boolean meteredInput = ProgressMonitor.getDefault().shouldMeterInput(url, "GET");
ProgressSource pi = null;
if (meteredInput) {
pi = new ProgressSource(url, "GET", l);
pi.beginTracking();
}
is = new MeteredStream(is, pi, l);
if (meteredInput) {
pi = new ProgressSource(url, "GET", l);
pi.beginTracking();
}
is = new MeteredStream(is, pi, l);
}
} catch (Exception e) {
e.printStackTrace();
/* do nothing, since all we were doing was trying to
get the size in bytes of the file */
/* do nothing, since all we were doing was trying to
get the size in bytes of the file */
}
String type = guessContentTypeFromName(fullpath);
if (type == null && is.markSupported()) {
type = guessContentTypeFromStream(is);
}
if (type != null) {
msgh.add("content-type", type);
if (isAdir) {
msgh.add("content-type", "text/plain");
msgh.add("access-type", "directory");
} else {
msgh.add("access-type", "file");
String ftype = guessContentTypeFromName(fullpath);
if (ftype == null && is.markSupported()) {
ftype = guessContentTypeFromStream(is);
}
if (ftype != null) {
msgh.add("content-type", ftype);
}
}
} catch (FileNotFoundException e) {
try {
cd(fullpath);
/* if that worked, then make a directory listing
and build an html stream with all the files in
the directory */
ftp.ascii();
and build an html stream with all the files in
the directory */
ftp.setAsciiType();
is = new FtpInputStream(ftp, ftp.list());
is = new FtpInputStream(ftp, ftp.list(null));
msgh.add("content-type", "text/plain");
msgh.add("access-type", "directory");
} catch (IOException ex) {
throw new FileNotFoundException(fullpath);
} catch (FtpProtocolException ex2) {
throw new FileNotFoundException(fullpath);
}
} catch (FtpProtocolException ftpe) {
throw new IOException(ftpe);
}
setProperties(msgh);
return is;
@ -477,31 +500,45 @@ public class FtpURLConnection extends URLConnection {
* points to a directory
* @throws FtpProtocolException if errors occur during the transfert.
*/
@Override
public OutputStream getOutputStream() throws IOException {
if (!connected) {
connect();
}
if (http != null)
return http.getOutputStream();
if (http != null) {
OutputStream out = http.getOutputStream();
// getInputStream() is neccessary to force a writeRequests()
// on the http client.
http.getInputStream();
return out;
}
if (is != null)
if (is != null) {
throw new IOException("Already opened for input");
}
if (os != null) {
return os;
}
decodePath(url.getPath());
if (filename == null || filename.length() == 0)
if (filename == null || filename.length() == 0) {
throw new IOException("illegal filename for a PUT");
if (pathname != null)
cd(pathname);
if (type == ASCII)
ftp.ascii();
else
ftp.binary();
os = new FtpOutputStream(ftp, ftp.put(filename));
}
try {
if (pathname != null) {
cd(pathname);
}
if (type == ASCII) {
ftp.setAsciiType();
} else {
ftp.setBinaryType();
}
os = new FtpOutputStream(ftp, ftp.putFileStream(filename, false));
} catch (FtpProtocolException e) {
throw new IOException(e);
}
return os;
}
@ -514,12 +551,13 @@ public class FtpURLConnection extends URLConnection {
*
* @return The <code>Permission</code> object.
*/
@Override
public Permission getPermission() {
if (permission == null) {
int port = url.getPort();
port = port < 0 ? FtpClient.FTP_PORT : port;
String host = this.host + ":" + port;
permission = new SocketPermission(host, "connect");
int urlport = url.getPort();
urlport = urlport < 0 ? FtpClient.defaultPort() : urlport;
String urlhost = this.host + ":" + urlport;
permission = new SocketPermission(urlhost, "connect");
}
return permission;
}
@ -534,21 +572,22 @@ public class FtpURLConnection extends URLConnection {
* @throws IllegalStateException if already connected
* @see #getRequestProperty(java.lang.String)
*/
@Override
public void setRequestProperty(String key, String value) {
super.setRequestProperty (key, value);
if ("type".equals (key)) {
if ("i".equalsIgnoreCase(value))
super.setRequestProperty(key, value);
if ("type".equals(key)) {
if ("i".equalsIgnoreCase(value)) {
type = BIN;
else if ("a".equalsIgnoreCase(value))
} else if ("a".equalsIgnoreCase(value)) {
type = ASCII;
else
if ("d".equalsIgnoreCase(value))
type = DIR;
else
} else if ("d".equalsIgnoreCase(value)) {
type = DIR;
} else {
throw new IllegalArgumentException(
"Value of '" + key +
"' request property was '" + value +
"' when it must be either 'i', 'a' or 'd'");
"Value of '" + key +
"' request property was '" + value +
"' when it must be either 'i', 'a' or 'd'");
}
}
}
@ -562,33 +601,41 @@ public class FtpURLConnection extends URLConnection {
* @throws IllegalStateException if already connected
* @see #setRequestProperty(java.lang.String, java.lang.String)
*/
@Override
public String getRequestProperty(String key) {
String value = super.getRequestProperty (key);
String value = super.getRequestProperty(key);
if (value == null) {
if ("type".equals (key))
if ("type".equals(key)) {
value = (type == ASCII ? "a" : type == DIR ? "d" : "i");
}
}
return value;
}
@Override
public void setConnectTimeout(int timeout) {
if (timeout < 0)
if (timeout < 0) {
throw new IllegalArgumentException("timeouts can't be negative");
}
connectTimeout = timeout;
}
@Override
public int getConnectTimeout() {
return (connectTimeout < 0 ? 0 : connectTimeout);
}
@Override
public void setReadTimeout(int timeout) {
if (timeout < 0)
if (timeout < 0) {
throw new IllegalArgumentException("timeouts can't be negative");
}
readTimeout = timeout;
}
@Override
public int getReadTimeout() {
return readTimeout < 0 ? 0 : readTimeout;
}

View File

@ -277,14 +277,16 @@ class DigestAuthentication extends AuthenticationInfo {
params.setOpaque (p.findValue("opaque"));
params.setQop (p.findValue("qop"));
String uri;
String uri="";
String method;
if (type == PROXY_AUTHENTICATION &&
conn.tunnelState() == HttpURLConnection.TunnelState.SETUP) {
uri = HttpURLConnection.connectRequestURI(conn.getURL());
method = HTTP_CONNECT;
} else {
uri = conn.getRequestURI();
try {
uri = conn.getRequestURI();
} catch (IOException e) {}
method = conn.getMethod();
}

View File

@ -1552,7 +1552,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
* because ntlm does not support this feature.
*/
private AuthenticationInfo
resetProxyAuthentication(AuthenticationInfo proxyAuthentication, AuthenticationHeader auth) {
resetProxyAuthentication(AuthenticationInfo proxyAuthentication, AuthenticationHeader auth) throws IOException {
if ((proxyAuthentication != null )&&
proxyAuthentication.getAuthScheme() != NTLM) {
String raw = auth.raw();
@ -1776,7 +1776,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
/**
* Sets pre-emptive proxy authentication in header
*/
private void setPreemptiveProxyAuthentication(MessageHeader requests) {
private void setPreemptiveProxyAuthentication(MessageHeader requests) throws IOException {
AuthenticationInfo pauth
= AuthenticationInfo.getProxyAuth(http.getProxyHostUsed(),
http.getProxyPortUsed());
@ -2132,13 +2132,9 @@ public class HttpURLConnection extends java.net.HttpURLConnection {
String requestURI = null;
String getRequestURI() {
String getRequestURI() throws IOException {
if (requestURI == null) {
try {
requestURI = http.getURLFile();
} catch (IOException e) {
requestURI = "";
}
requestURI = http.getURLFile();
}
return requestURI;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -86,6 +86,9 @@ public class Providers {
private static final String[] jarVerificationProviders = {
"sun.security.provider.Sun",
"sun.security.rsa.SunRsaSign",
// Note: SunEC *is* in a signed JAR file, but it's not signed
// by EC itself. So it's still safe to be listed here.
"sun.security.ec.SunEC",
BACKUP_PROVIDER_CLASSNAME,
};

View File

@ -1,5 +1,5 @@
/*
* Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -286,8 +286,6 @@ public class SignerInfo implements DerEncoder {
}
String digestAlgname = getDigestAlgorithmId().getName();
if (digestAlgname.equalsIgnoreCase("SHA"))
digestAlgname = "SHA1";
byte[] dataSigned;
@ -337,9 +335,12 @@ public class SignerInfo implements DerEncoder {
String encryptionAlgname =
getDigestEncryptionAlgorithmId().getName();
if (encryptionAlgname.equalsIgnoreCase("SHA1withDSA"))
encryptionAlgname = "DSA";
String algname = digestAlgname + "with" + encryptionAlgname;
// Workaround: sometimes the encryptionAlgname is actually
// a signature name
String tmp = AlgorithmId.getEncAlgFromSigAlg(encryptionAlgname);
if (tmp != null) encryptionAlgname = tmp;
String algname = AlgorithmId.makeSigAlg(
digestAlgname, encryptionAlgname);
Signature sig = Signature.getInstance(algname);
X509Certificate cert = getCertificate(block);

View File

@ -1031,9 +1031,9 @@ public class JarSigner {
}
if (sigfile.length() > 8) {
sigfile = sigfile.substring(0, 8).toUpperCase();
sigfile = sigfile.substring(0, 8).toUpperCase(Locale.ENGLISH);
} else {
sigfile = sigfile.toUpperCase();
sigfile = sigfile.toUpperCase(Locale.ENGLISH);
}
StringBuilder tmpSigFile = new StringBuilder(sigfile.length());
@ -1083,8 +1083,8 @@ public class JarSigner {
ZipOutputStream zos = new ZipOutputStream(ps);
/* First guess at what they might be - we don't xclude RSA ones. */
String sfFilename = (META_INF + sigfile + ".SF").toUpperCase();
String bkFilename = (META_INF + sigfile + ".DSA").toUpperCase();
String sfFilename = (META_INF + sigfile + ".SF").toUpperCase(Locale.ENGLISH);
String bkFilename = (META_INF + sigfile + ".DSA").toUpperCase(Locale.ENGLISH);
Manifest manifest = new Manifest();
Map<String,Attributes> mfEntries = manifest.getEntries();
@ -1447,9 +1447,10 @@ public class JarSigner {
* . META-INF/*.SF
* . META-INF/*.DSA
* . META-INF/*.RSA
* . META-INF/*.EC
*/
private boolean signatureRelated(String name) {
String ucName = name.toUpperCase();
String ucName = name.toUpperCase(Locale.ENGLISH);
if (ucName.equals(JarFile.MANIFEST_NAME) ||
ucName.equals(META_INF) ||
(ucName.startsWith(SIG_PREFIX) &&
@ -1459,7 +1460,7 @@ public class JarSigner {
if (ucName.startsWith(META_INF) &&
SignatureFileVerifier.isBlockOrSF(ucName)) {
// .SF/.DSA/.RSA files in META-INF subdirs
// .SF/.DSA/.RSA/.EC files in META-INF subdirs
// are not considered signature-related
return (ucName.indexOf("/") == ucName.lastIndexOf("/"));
}
@ -2227,7 +2228,6 @@ class SignatureFile {
}
BigInteger serial = certChain[0].getSerialNumber();
String digestAlgorithm;
String signatureAlgorithm;
String keyAlgorithm = privateKey.getAlgorithm();
/*
@ -2237,22 +2237,24 @@ class SignatureFile {
if (sigalg == null) {
if (keyAlgorithm.equalsIgnoreCase("DSA"))
digestAlgorithm = "SHA1";
signatureAlgorithm = "SHA1withDSA";
else if (keyAlgorithm.equalsIgnoreCase("RSA"))
digestAlgorithm = "SHA256";
else {
signatureAlgorithm = "SHA256withRSA";
else if (keyAlgorithm.equalsIgnoreCase("EC"))
signatureAlgorithm = "SHA256withECDSA";
else
throw new RuntimeException("private key is not a DSA or "
+ "RSA key");
}
signatureAlgorithm = digestAlgorithm + "with" + keyAlgorithm;
} else {
signatureAlgorithm = sigalg;
}
// check common invalid key/signature algorithm combinations
String sigAlgUpperCase = signatureAlgorithm.toUpperCase();
String sigAlgUpperCase = signatureAlgorithm.toUpperCase(Locale.ENGLISH);
if ((sigAlgUpperCase.endsWith("WITHRSA") &&
!keyAlgorithm.equalsIgnoreCase("RSA")) ||
(sigAlgUpperCase.endsWith("WITHECDSA") &&
!keyAlgorithm.equalsIgnoreCase("EC")) ||
(sigAlgUpperCase.endsWith("WITHDSA") &&
!keyAlgorithm.equalsIgnoreCase("DSA"))) {
throw new SignatureException

View File

@ -1407,7 +1407,7 @@ public final class KeyTool {
} else if ("RSA".equalsIgnoreCase(keyAlgName)) {
return "SHA256WithRSA";
} else if ("EC".equalsIgnoreCase(keyAlgName)) {
return "SHA1withECDSA";
return "SHA256withECDSA";
} else {
throw new Exception(rb.getString
("Cannot derive signature algorithm"));

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved.
* Copyright (c) 2007-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -159,18 +159,10 @@ public final class TimestampedSigner extends ContentSigner {
// "<digest>with<encryption>"
// or "<digest>with<encryption>and<mgf>"
String signatureAlgorithm = parameters.getSignatureAlgorithm();
String digestAlgorithm = null;
String keyAlgorithm = null;
int with = signatureAlgorithm.indexOf("with");
if (with > 0) {
digestAlgorithm = signatureAlgorithm.substring(0, with);
int and = signatureAlgorithm.indexOf("and", with + 4);
if (and > 0) {
keyAlgorithm = signatureAlgorithm.substring(with + 4, and);
} else {
keyAlgorithm = signatureAlgorithm.substring(with + 4);
}
}
String keyAlgorithm =
AlgorithmId.getEncAlgFromSigAlg(signatureAlgorithm);
String digestAlgorithm =
AlgorithmId.getDigAlgFromSigAlg(signatureAlgorithm);
AlgorithmId digestAlgorithmId = AlgorithmId.get(digestAlgorithm);
// Examine signer's certificate

View File

@ -1,5 +1,5 @@
/*
* Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -54,14 +54,14 @@ public class SignatureFileVerifier {
("-DIGEST-" + ManifestDigester.MF_MAIN_ATTRS).toUpperCase
(Locale.ENGLISH);
/** the PKCS7 block for this .DSA/.RSA file */
/** the PKCS7 block for this .DSA/.RSA/.EC file */
private PKCS7 block;
/** the raw bytes of the .SF file */
private byte sfBytes[];
/** the name of the signature block file, uppercased and without
* the extension (.DSA/.RSA)
* the extension (.DSA/.RSA/.EC)
*/
private String name;
@ -80,7 +80,7 @@ public class SignatureFileVerifier {
/**
* Create the named SignatureFileVerifier.
*
* @param name the name of the signature block file (.DSA/.RSA)
* @param name the name of the signature block file (.DSA/.RSA/.EC)
*
* @param rawBytes the raw bytes of the signature block file
*/
@ -148,7 +148,8 @@ public class SignatureFileVerifier {
*/
public static boolean isBlockOrSF(String s) {
// we currently only support DSA and RSA PKCS7 blocks
if (s.endsWith(".SF") || s.endsWith(".DSA") || s.endsWith(".RSA")) {
if (s.endsWith(".SF") || s.endsWith(".DSA") ||
s.endsWith(".RSA") || s.endsWith(".EC")) {
return true;
}
return false;

View File

@ -883,4 +883,53 @@ public class AlgorithmId implements Serializable, DerEncoder {
nameTable.put(pbeWithSHA1AndDESede_oid, "PBEWithSHA1AndDESede");
nameTable.put(pbeWithSHA1AndRC2_40_oid, "PBEWithSHA1AndRC2_40");
}
/**
* Creates a signature algorithm name from a digest algorithm
* name and a encryption algorithm name.
*/
public static String makeSigAlg(String digAlg, String encAlg) {
digAlg = digAlg.replace("-", "").toUpperCase(Locale.ENGLISH);
if (digAlg.equalsIgnoreCase("SHA")) digAlg = "SHA1";
encAlg = encAlg.toUpperCase(Locale.ENGLISH);
if (encAlg.equals("EC")) encAlg = "ECDSA";
return digAlg + "with" + encAlg;
}
/**
* Extracts the encryption algorithm name from a signature
* algorithm name.
*/
public static String getEncAlgFromSigAlg(String signatureAlgorithm) {
signatureAlgorithm = signatureAlgorithm.toUpperCase(Locale.ENGLISH);
int with = signatureAlgorithm.indexOf("WITH");
String keyAlgorithm = null;
if (with > 0) {
int and = signatureAlgorithm.indexOf("AND", with + 4);
if (and > 0) {
keyAlgorithm = signatureAlgorithm.substring(with + 4, and);
} else {
keyAlgorithm = signatureAlgorithm.substring(with + 4);
}
if (keyAlgorithm.equalsIgnoreCase("ECDSA")) {
keyAlgorithm = "EC";
}
}
return keyAlgorithm;
}
/**
* Extracts the digest algorithm name from a signature
* algorithm name.
*/
public static String getDigAlgFromSigAlg(String signatureAlgorithm) {
signatureAlgorithm = signatureAlgorithm.toUpperCase(Locale.ENGLISH);
int with = signatureAlgorithm.indexOf("WITH");
if (with > 0) {
return signatureAlgorithm.substring(0, with);
}
return null;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 1996-2003 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -34,6 +34,7 @@ import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;
import sun.security.pkcs.*;
import sun.security.x509.AlgorithmId;
/**
* <p>A signature file as defined in the <a
@ -103,7 +104,7 @@ public class SignatureFile {
if (name.length() > 8 || name.indexOf('.') != -1) {
throw new JarException("invalid file name");
}
rawName = name.toUpperCase();
rawName = name.toUpperCase(Locale.ENGLISH);
}
}
@ -217,7 +218,8 @@ public class SignatureFile {
if (signatureBlock != null) {
SignerInfo info = signatureBlock.getSignerInfos()[0];
suffix = info.getDigestEncryptionAlgorithmId().getName();
suffix = suffix.substring(suffix.length() - 3);
String temp = AlgorithmId.getEncAlgFromSigAlg(suffix);
if (temp != null) suffix = temp;
}
return "META-INF/" + rawName + "." + suffix;
}

View File

@ -307,7 +307,7 @@ EOF
#The alternative would be to use /usr/bin/pargs [pid] to get
#all the args for a process, splice them back into one
#long string, then grep.
UU=`/usr/bin/id -un`
UU=`/usr/xpg4/bin/id -u -n`
psCmd="pgrep -f -l -U $UU"
else
ulimit -c 0

View File

@ -0,0 +1,48 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/*
* @test
* @bug 6371401
* @summary Tests of shiftLeft and shiftRight on Integer.MIN_VALUE
* @author Joseph D. Darcy
*/
import static java.math.BigInteger.*;
public class ExtremeShiftingTests {
public static void main(String... args) {
try {
ONE.shiftLeft(Integer.MIN_VALUE);
throw new RuntimeException("Should not reach here.");
} catch (ArithmeticException ae) {
; // Expected
}
try {
ONE.shiftRight(Integer.MIN_VALUE);
throw new RuntimeException("Should not reach here.");
} catch (ArithmeticException ae) {
; // Expected
}
}
}

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 6644726
* @bug 6644726 6873543
* @summary Cookie management issues
*/
@ -170,6 +170,28 @@ public class B6644726 {
if (isIn(clst, "myCookie8=")) {
fail("A cookie with an invalid port list was returned");
}
// Test httpOnly flag (CR# 6873543)
lst.clear();
map.clear();
cm.getCookieStore().removeAll();
lst.add("myCookie11=httpOnlyTest; httpOnly");
map.put("Set-Cookie", lst);
uri = new URI("http://www.sun.com/");
cm.put(uri, map);
m = cm.get(uri, emptyMap);
clst = m.get("Cookie");
// URI scheme was http: so we should get the cookie
if (!isIn(clst, "myCookie11=")) {
fail("Missing cookie with httpOnly flag");
}
uri = new URI("javascript://www.sun.com/");
m = cm.get(uri, emptyMap);
clst = m.get("Cookie");
// URI scheme was neither http or https so we shouldn't get the cookie
if (isIn(clst, "myCookie11=")) {
fail("Should get the cookie with httpOnly when scheme is javascript:");
}
}
private static boolean isIn(List<String> lst, String cookie) {

View File

@ -0,0 +1,68 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
/**
* @test
* @bug 6890349
* @run main/othervm B6890349
* @summary Light weight HTTP server
*/
import java.net.*;
import java.io.*;
public class B6890349 extends Thread {
public static final void main(String[] args) throws Exception {
try {
ServerSocket server = new ServerSocket (0);
int port = server.getLocalPort();
System.out.println ("listening on " + port);
B6890349 t = new B6890349 (server);
t.start();
URL u = new URL ("http://127.0.0.1:"+port+"/foo\nbar");
HttpURLConnection urlc = (HttpURLConnection)u.openConnection ();
InputStream is = urlc.getInputStream();
throw new RuntimeException ("Test failed");
} catch (IOException e) {
System.out.println ("OK");
}
}
ServerSocket server;
B6890349 (ServerSocket server) {
this.server = server;
}
String resp = "HTTP/1.1 200 Ok\r\nContent-length: 0\r\n\r\n";
public void run () {
try {
Socket s = server.accept ();
OutputStream os = s.getOutputStream();
os.write (resp.getBytes());
} catch (IOException e) {
System.out.println (e);
}
}
}

View File

@ -0,0 +1,73 @@
#
# Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 only, as
# published by the Free Software Foundation.
#
# This code 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 General Public License
# version 2 for more details (a copy is included in the LICENSE file that
# accompanied this code).
#
# You should have received a copy of the GNU General Public License version
# 2 along with this work; if not, write to the Free Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
#
# @test
# @bug 6870812
# @summary enhance security tools to use ECC algorithm
#
if [ "${TESTJAVA}" = "" ] ; then
JAVAC_CMD=`which javac`
TESTJAVA=`dirname $JAVAC_CMD`/..
fi
# set platform-dependent variables
OS=`uname -s`
case "$OS" in
Windows_* )
FS="\\"
;;
* )
FS="/"
;;
esac
KS=ec.jks
JFILE=ec.jar
KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS"
JAR=$TESTJAVA${FS}bin${FS}jar
JARSIGNER=$TESTJAVA${FS}bin${FS}jarsigner
rm $KS $JFILE
echo A > A
$JAR cvf $JFILE A
$KT -alias a -dname CN=a -keyalg ec -genkey -validity 300 || exit 11
$KT -alias b -dname CN=b -keyalg ec -genkey -validity 300 || exit 12
$KT -alias c -dname CN=c -keyalg ec -genkey -validity 300 || exit 13
$KT -alias x -dname CN=x -keyalg ec -genkey -validity 300 || exit 14
$JARSIGNER -keystore $KS -storepass changeit $JFILE a -debug -strict || exit 21
$JARSIGNER -keystore $KS -storepass changeit $JFILE b -debug -strict -sigalg SHA1withECDSA || exit 22
$JARSIGNER -keystore $KS -storepass changeit $JFILE c -debug -strict -sigalg SHA512withECDSA || exit 23
$JARSIGNER -keystore $KS -storepass changeit -verify $JFILE a -debug -strict || exit 31
$JARSIGNER -keystore $KS -storepass changeit -verify $JFILE b -debug -strict || exit 32
$JARSIGNER -keystore $KS -storepass changeit -verify $JFILE c -debug -strict || exit 33
# Not signed by x, should exit with non-zero
$JARSIGNER -keystore $KS -storepass changeit -verify $JFILE x -debug -strict && exit 34
exit 0