This commit is contained in:
Jesper Wilhelmsson 2021-07-22 00:46:18 +00:00
commit c36755dedf
33 changed files with 483 additions and 114 deletions

View file

@ -24,16 +24,36 @@
*/
package sun.net.ftp.impl;
import java.net.*;
import java.io.*;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.Closeable;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.text.DateFormat;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Calendar;
import java.util.Date;
@ -44,7 +64,11 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import sun.net.ftp.*;
import sun.net.ftp.FtpDirEntry;
import sun.net.ftp.FtpDirParser;
import sun.net.ftp.FtpProtocolException;
import sun.net.ftp.FtpReplyCode;
import sun.net.util.IPAddressUtil;
import sun.util.logging.PlatformLogger;
@ -107,13 +131,15 @@ public class FtpClient extends sun.net.ftp.FtpClient {
private static Pattern[] patterns;
private static Pattern linkp = Pattern.compile("(\\p{Print}+) \\-\\> (\\p{Print}+)$");
private DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, java.util.Locale.US);
private static final boolean acceptPasvAddressVal;
static {
final int vals[] = {0, 0};
final String acceptPasvAddress[] = {null};
@SuppressWarnings("removal")
final String enc = AccessController.doPrivileged(
new PrivilegedAction<String>() {
public String run() {
acceptPasvAddress[0] = System.getProperty("jdk.net.ftp.trustPasvAddress", "false");
vals[0] = Integer.getInteger("sun.net.client.defaultReadTimeout", 300_000).intValue();
vals[1] = Integer.getInteger("sun.net.client.defaultConnectTimeout", 300_000).intValue();
return System.getProperty("file.encoding", "ISO8859_1");
@ -144,6 +170,8 @@ public class FtpClient extends sun.net.ftp.FtpClient {
for (int i = 0; i < patStrings.length; i++) {
patterns[i] = Pattern.compile(patStrings[i]);
}
acceptPasvAddressVal = Boolean.parseBoolean(acceptPasvAddress[0]);
}
/**
@ -610,7 +638,6 @@ public class FtpClient extends sun.net.ftp.FtpClient {
//
// The regular expression is a bit more complex this time, because
// the parenthesis are optionals and we have to use 3 groups.
if (pasvPat == null) {
pasvPat = Pattern.compile("227 .* \\(?(\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3}),(\\d{1,3}),(\\d{1,3})\\)?");
}
@ -622,8 +649,15 @@ public class FtpClient extends sun.net.ftp.FtpClient {
port = Integer.parseInt(m.group(3)) + (Integer.parseInt(m.group(2)) << 8);
// IP address is simple
String s = m.group(1).replace(',', '.');
dest = new InetSocketAddress(s, port);
if (!IPAddressUtil.isIPv4LiteralAddress(s))
throw new FtpProtocolException("PASV failed : " + serverAnswer);
if (acceptPasvAddressVal) {
dest = new InetSocketAddress(s, port);
} else {
dest = validatePasvAddress(port, s, server.getInetAddress());
}
}
// Got everything, let's open the socket!
Socket s;
if (proxy != null) {
@ -678,6 +712,80 @@ public class FtpClient extends sun.net.ftp.FtpClient {
return s;
}
static final String ERROR_MSG = "Address should be the same as originating server";
/**
* Returns an InetSocketAddress, based on value of acceptPasvAddressVal
* and other conditions such as the server address returned by pasv
* is not a hostname, is a socks proxy, or the loopback. An exception
* is thrown if none of the valid conditions are met.
*/
private InetSocketAddress validatePasvAddress(int port, String s, InetAddress address)
throws FtpProtocolException
{
if (address == null) {
return InetSocketAddress.createUnresolved(serverAddr.getHostName(), port);
}
String serverAddress = address.getHostAddress();
if (serverAddress.equals(s)) {
return new InetSocketAddress(s, port);
} else if (address.isLoopbackAddress() && s.startsWith("127.")) { // can be 127.0
return new InetSocketAddress(s, port);
} else if (address.isLoopbackAddress()) {
if (privilegedLocalHost().getHostAddress().equals(s)) {
return new InetSocketAddress(s, port);
} else {
throw new FtpProtocolException(ERROR_MSG);
}
} else if (s.startsWith("127.")) {
if (privilegedLocalHost().equals(address)) {
return new InetSocketAddress(s, port);
} else {
throw new FtpProtocolException(ERROR_MSG);
}
}
String hostName = address.getHostName();
if (!(IPAddressUtil.isIPv4LiteralAddress(hostName) || IPAddressUtil.isIPv6LiteralAddress(hostName))) {
InetAddress[] names = privilegedGetAllByName(hostName);
String resAddress = Arrays
.stream(names)
.map(InetAddress::getHostAddress)
.filter(s::equalsIgnoreCase)
.findFirst()
.orElse(null);
if (resAddress != null) {
return new InetSocketAddress(s, port);
}
}
throw new FtpProtocolException(ERROR_MSG);
}
private static InetAddress privilegedLocalHost() throws FtpProtocolException {
PrivilegedExceptionAction<InetAddress> action = InetAddress::getLocalHost;
try {
@SuppressWarnings("removal")
var tmp = AccessController.doPrivileged(action);
return tmp;
} catch (Exception e) {
var ftpEx = new FtpProtocolException(ERROR_MSG);
ftpEx.initCause(e);
throw ftpEx;
}
}
private static InetAddress[] privilegedGetAllByName(String hostName) throws FtpProtocolException {
PrivilegedExceptionAction<InetAddress[]> pAction = () -> InetAddress.getAllByName(hostName);
try {
@SuppressWarnings("removal")
var tmp =AccessController.doPrivileged(pAction);
return tmp;
} catch (Exception e) {
var ftpEx = new FtpProtocolException(ERROR_MSG);
ftpEx.initCause(e);
throw ftpEx;
}
}
/**
* Opens a data connection with the server according to the set mode
* (ACTIVE or PASSIVE) then send the command passed as an argument.
@ -688,7 +796,6 @@ public class FtpClient extends sun.net.ftp.FtpClient {
*/
private Socket openDataConnection(String cmd) throws sun.net.ftp.FtpProtocolException, IOException {
Socket clientSocket;
if (passiveMode) {
try {
return openPassiveDataConnection(cmd);

View file

@ -331,7 +331,18 @@ public class SignerInfo implements DerEncoder {
throws NoSuchAlgorithmException, SignatureException {
try {
Timestamp timestamp = getTimestamp();
Timestamp timestamp = null;
try {
timestamp = getTimestamp();
} catch (Exception e) {
// Log exception and continue. This allows for the case
// where, if there are no other errors, the code is
// signed but w/o a timestamp.
if (debug != null) {
debug.println("Unexpected exception while getting" +
" timestamp: " + e);
}
}
ContentInfo content = block.getContentInfo();
if (data == null) {
@ -471,7 +482,7 @@ public class SignerInfo implements DerEncoder {
if (sig.verify(encryptedDigest)) {
return this;
}
} catch (IOException | CertificateException e) {
} catch (IOException e) {
throw new SignatureException("Error verifying signature", e);
}
return null;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. 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
@ -270,7 +270,7 @@ public class SignatureFileVerifier {
*
*/
public void process(Hashtable<String, CodeSigner[]> signers,
List<Object> manifestDigests)
List<Object> manifestDigests, String manifestName)
throws IOException, SignatureException, NoSuchAlgorithmException,
JarException, CertificateException
{
@ -279,7 +279,7 @@ public class SignatureFileVerifier {
Object obj = null;
try {
obj = Providers.startJarVerification();
processImpl(signers, manifestDigests);
processImpl(signers, manifestDigests, manifestName);
} finally {
Providers.stopJarVerification(obj);
}
@ -287,7 +287,7 @@ public class SignatureFileVerifier {
}
private void processImpl(Hashtable<String, CodeSigner[]> signers,
List<Object> manifestDigests)
List<Object> manifestDigests, String manifestName)
throws IOException, SignatureException, NoSuchAlgorithmException,
JarException, CertificateException
{
@ -368,7 +368,7 @@ public class SignatureFileVerifier {
}
// MANIFEST.MF is always regarded as signed
updateSigners(newSigners, signers, JarFile.MANIFEST_NAME);
updateSigners(newSigners, signers, manifestName);
}
/**