提交 2acf165b 编写于 作者: C Chuansheng Lu

Merge tag 'jdk8u242-ga'

...@@ -1005,6 +1005,16 @@ c7a97c9b7e5932d651eda37c8a907311818491d7 jdk8u222-b07 ...@@ -1005,6 +1005,16 @@ c7a97c9b7e5932d651eda37c8a907311818491d7 jdk8u222-b07
60eca04567a6d214aa60dd16306f4854bd41b273 jdk8u232-b03 60eca04567a6d214aa60dd16306f4854bd41b273 jdk8u232-b03
3ef3348195ffeb3c268af4a43928f2f09c5fa83a jdk8u232-b04 3ef3348195ffeb3c268af4a43928f2f09c5fa83a jdk8u232-b04
6d60b8cf1bd4a5fa371b1ddad9d186ff546b25f5 jdk8u232-b05 6d60b8cf1bd4a5fa371b1ddad9d186ff546b25f5 jdk8u232-b05
1e8cdf311133ecde0ccae37e6137e49adc6164fb jdk8u242-b00
5d57817931e1f5b6a460158342f132ea348e14ef jdk8u232-b06 5d57817931e1f5b6a460158342f132ea348e14ef jdk8u232-b06
3560e0ebe876ce658c5261070fe728e47994210f jdk8u232-b07 3560e0ebe876ce658c5261070fe728e47994210f jdk8u232-b07
69c4f673b33e255599d2aa257fa50fd8b48b7b95 jdk8u232-b08 69c4f673b33e255599d2aa257fa50fd8b48b7b95 jdk8u232-b08
5456f24496f43f72b0cf4f0db3a73ea49c33f94f jdk8u232-b09
5456f24496f43f72b0cf4f0db3a73ea49c33f94f jdk8u232-ga
d32fc856e071ff49c8a4c94682caad57f6c6874f jdk8u242-b01
2b292ab0ed9af9aa8aab27b1a80daa3509a050ba jdk8u242-b02
2f564a16517d678f31a3fa7352e16702e48c417d jdk8u242-b03
8163e59959ed5462891f2b1db7bc0fa2af1de0a6 jdk8u242-b04
b2865f7f557fcaec84445b034b2de2b27456b6c5 jdk8u242-b05
0d27e60569f7cf85cbdb0a83436e772e9256b5b0 jdk8u242-b06
034a65a05bfbfb06e14d3d39efa0c9f27683573a jdk8u242-b07
...@@ -1334,11 +1334,13 @@ SUCH DAMAGE. ...@@ -1334,11 +1334,13 @@ SUCH DAMAGE.
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
%% This notice is provided with respect to Joni v1.1.9, which may be %% This notice is provided with respect to Joni v2.1.16, which may be
included with JRE 8, JDK 8, and OpenJDK 8. included with JRE 8, JDK 8, and OpenJDK 8.
--- begin of LICENSE --- --- begin of LICENSE ---
Copyright (c) 2017 JRuby Team
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
......
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
* *
* This code is free software; you can redistribute it and/or modify it * 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 * under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. * published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
* *
* This code is distributed in the hope that it will be useful, but WITHOUT * This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
......
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
* *
* This code is free software; you can redistribute it and/or modify it * 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 * under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. * published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
* *
* This code is distributed in the hope that it will be useful, but WITHOUT * This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
......
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
* *
* This code is free software; you can redistribute it and/or modify it * 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 * under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. * published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
* *
* This code is distributed in the hope that it will be useful, but WITHOUT * This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
......
/* /*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -48,8 +48,9 @@ public abstract class CGLSurfaceData extends OGLSurfaceData { ...@@ -48,8 +48,9 @@ public abstract class CGLSurfaceData extends OGLSurfaceData {
native void validate(int xoff, int yoff, int width, int height, boolean isOpaque); native void validate(int xoff, int yoff, int width, int height, boolean isOpaque);
private native void initOps(long pConfigInfo, long pPeerData, long layerPtr, private native void initOps(OGLGraphicsConfig gc, long pConfigInfo,
int xoff, int yoff, boolean isOpaque); long pPeerData, long layerPtr, int xoff,
int yoff, boolean isOpaque);
protected native boolean initPbuffer(long pData, long pConfigInfo, protected native boolean initPbuffer(long pData, long pConfigInfo,
boolean isOpaque, int width, int height); boolean isOpaque, int width, int height);
...@@ -77,7 +78,7 @@ public abstract class CGLSurfaceData extends OGLSurfaceData { ...@@ -77,7 +78,7 @@ public abstract class CGLSurfaceData extends OGLSurfaceData {
pPeerData = pView.getAWTView(); pPeerData = pView.getAWTView();
isOpaque = pView.isOpaque(); isOpaque = pView.isOpaque();
} }
initOps(pConfigInfo, pPeerData, 0, 0, 0, isOpaque); initOps(gc, pConfigInfo, pPeerData, 0, 0, 0, isOpaque);
} }
protected CGLSurfaceData(CGLLayer layer, CGLGraphicsConfig gc, protected CGLSurfaceData(CGLLayer layer, CGLGraphicsConfig gc,
...@@ -93,7 +94,7 @@ public abstract class CGLSurfaceData extends OGLSurfaceData { ...@@ -93,7 +94,7 @@ public abstract class CGLSurfaceData extends OGLSurfaceData {
layerPtr = layer.getPointer(); layerPtr = layer.getPointer();
isOpaque = layer.isOpaque(); isOpaque = layer.isOpaque();
} }
initOps(pConfigInfo, 0, layerPtr, 0, 0, isOpaque); initOps(gc, pConfigInfo, 0, layerPtr, 0, 0, isOpaque);
} }
@Override //SurfaceData @Override //SurfaceData
......
...@@ -5,7 +5,9 @@ ...@@ -5,7 +5,9 @@
* *
* This code is free software; you can redistribute it and/or modify it * 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 * under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. * published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
* *
* This code is distributed in the hope that it will be useful, but WITHOUT * This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
......
/* /*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -94,16 +94,18 @@ static CFMutableArrayRef getAllValidDisplayModes(jint displayID){ ...@@ -94,16 +94,18 @@ static CFMutableArrayRef getAllValidDisplayModes(jint displayID){
static CGDisplayModeRef getBestModeForParameters(CFArrayRef allModes, int w, int h, int bpp, int refrate) { static CGDisplayModeRef getBestModeForParameters(CFArrayRef allModes, int w, int h, int bpp, int refrate) {
CGDisplayModeRef bestGuess = NULL; CGDisplayModeRef bestGuess = NULL;
CFIndex numModes = CFArrayGetCount(allModes), n; CFIndex numModes = CFArrayGetCount(allModes), n;
int thisBpp = 0;
for(n = 0; n < numModes; n++ ) { for(n = 0; n < numModes; n++ ) {
CGDisplayModeRef cRef = (CGDisplayModeRef) CFArrayGetValueAtIndex(allModes, n); CGDisplayModeRef cRef = (CGDisplayModeRef) CFArrayGetValueAtIndex(allModes, n);
if(cRef == NULL) { if(cRef == NULL) {
continue; continue;
} }
CFStringRef modeString = CGDisplayModeCopyPixelEncoding(cRef); CFStringRef modeString = CGDisplayModeCopyPixelEncoding(cRef);
thisBpp = getBPPFromModeString(modeString); int thisBpp = getBPPFromModeString(modeString);
CFRelease(modeString); CFRelease(modeString);
if (thisBpp != bpp || (int)CGDisplayModeGetHeight(cRef) != h || (int)CGDisplayModeGetWidth(cRef) != w) { int thisH = (int)CGDisplayModeGetHeight(cRef);
int thisW = (int)CGDisplayModeGetWidth(cRef);
if (thisBpp != bpp || thisH != h || thisW != w) {
// One of the key parameters does not match // One of the key parameters does not match
continue; continue;
} }
...@@ -114,11 +116,12 @@ static CGDisplayModeRef getBestModeForParameters(CFArrayRef allModes, int w, int ...@@ -114,11 +116,12 @@ static CGDisplayModeRef getBestModeForParameters(CFArrayRef allModes, int w, int
// Refresh rate might be 0 in display mode and we ask for specific display rate // Refresh rate might be 0 in display mode and we ask for specific display rate
// but if we do not find exact match then 0 refresh rate might be just Ok // but if we do not find exact match then 0 refresh rate might be just Ok
if (CGDisplayModeGetRefreshRate(cRef) == refrate) { int thisRefrate = (int)CGDisplayModeGetRefreshRate(cRef);
if (thisRefrate == refrate) {
// Exact match // Exact match
return cRef; return cRef;
} }
if (CGDisplayModeGetRefreshRate(cRef) == 0) { if (thisRefrate == 0) {
// Not exactly what was asked for, but may fit our needs if we don't find an exact match // Not exactly what was asked for, but may fit our needs if we don't find an exact match
bestGuess = cRef; bestGuess = cRef;
} }
......
...@@ -144,31 +144,6 @@ JNF_COCOA_ENTER(env); ...@@ -144,31 +144,6 @@ JNF_COCOA_ENTER(env);
JNF_COCOA_EXIT(env); JNF_COCOA_EXIT(env);
} }
/**
* Returns a pointer (as a jlong) to the native CGLGraphicsConfigInfo
* associated with the given OGLSDOps. This method can be called from
* shared code to retrieve the native GraphicsConfig data in a platform-
* independent manner.
*/
jlong
OGLSD_GetNativeConfigInfo(OGLSDOps *oglsdo)
{
J2dTraceLn(J2D_TRACE_INFO, "OGLSD_GetNativeConfigInfo");
if (oglsdo == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_GetNativeConfigInfo: ops are null");
return 0L;
}
CGLSDOps *cglsdo = (CGLSDOps *)oglsdo->privOps;
if (cglsdo == NULL) {
J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_GetNativeConfigInfo: cgl ops are null");
return 0L;
}
return ptr_to_jlong(cglsdo->configInfo);
}
/** /**
* Makes the given GraphicsConfig's context current to its associated * Makes the given GraphicsConfig's context current to its associated
* "scratch" surface. If there is a problem making the context current, * "scratch" surface. If there is a problem making the context current,
...@@ -411,7 +386,7 @@ extern DisposeFunc OGLSD_Dispose; ...@@ -411,7 +386,7 @@ extern DisposeFunc OGLSD_Dispose;
JNIEXPORT void JNICALL JNIEXPORT void JNICALL
Java_sun_java2d_opengl_CGLSurfaceData_initOps Java_sun_java2d_opengl_CGLSurfaceData_initOps
(JNIEnv *env, jobject cglsd, (JNIEnv *env, jobject cglsd, jobject gc,
jlong pConfigInfo, jlong pPeerData, jlong layerPtr, jlong pConfigInfo, jlong pPeerData, jlong layerPtr,
jint xoff, jint yoff, jboolean isOpaque) jint xoff, jint yoff, jboolean isOpaque)
{ {
...@@ -419,8 +394,22 @@ Java_sun_java2d_opengl_CGLSurfaceData_initOps ...@@ -419,8 +394,22 @@ Java_sun_java2d_opengl_CGLSurfaceData_initOps
J2dTraceLn1(J2D_TRACE_INFO, " pPeerData=%p", jlong_to_ptr(pPeerData)); J2dTraceLn1(J2D_TRACE_INFO, " pPeerData=%p", jlong_to_ptr(pPeerData));
J2dTraceLn2(J2D_TRACE_INFO, " xoff=%d, yoff=%d", (int)xoff, (int)yoff); J2dTraceLn2(J2D_TRACE_INFO, " xoff=%d, yoff=%d", (int)xoff, (int)yoff);
gc = (*env)->NewGlobalRef(env, gc);
if (gc == NULL) {
JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");
return;
}
OGLSDOps *oglsdo = (OGLSDOps *) OGLSDOps *oglsdo = (OGLSDOps *)
SurfaceData_InitOps(env, cglsd, sizeof(OGLSDOps)); SurfaceData_InitOps(env, cglsd, sizeof(OGLSDOps));
if (oglsdo == NULL) {
(*env)->DeleteGlobalRef(env, gc);
JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");
return;
}
// later the graphicsConfig will be used for deallocation of oglsdo
oglsdo->graphicsConfig = gc;
CGLSDOps *cglsdo = (CGLSDOps *)malloc(sizeof(CGLSDOps)); CGLSDOps *cglsdo = (CGLSDOps *)malloc(sizeof(CGLSDOps));
if (cglsdo == NULL) { if (cglsdo == NULL) {
JNU_ThrowOutOfMemoryError(env, "creating native cgl ops"); JNU_ThrowOutOfMemoryError(env, "creating native cgl ops");
......
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015 Red Hat, Inc. * Copyright (c) 2015 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
...@@ -62,14 +62,16 @@ final class GHASH { ...@@ -62,14 +62,16 @@ final class GHASH {
private static final int AES_BLOCK_SIZE = 16; private static final int AES_BLOCK_SIZE = 16;
// Multiplies state0, state1 by V0, V1. // Multiplies state[0], state[1] by subkeyH[0], subkeyH[1].
private void blockMult(long V0, long V1) { private static void blockMult(long[] st, long[] subH) {
long Z0 = 0; long Z0 = 0;
long Z1 = 0; long Z1 = 0;
long V0 = subH[0];
long V1 = subH[1];
long X; long X;
// Separate loops for processing state0 and state1. // Separate loops for processing state[0] and state[1].
X = state0; X = st[0];
for (int i = 0; i < 64; i++) { for (int i = 0; i < 64; i++) {
// Zi+1 = Zi if bit i of x is 0 // Zi+1 = Zi if bit i of x is 0
long mask = X >> 63; long mask = X >> 63;
...@@ -89,7 +91,7 @@ final class GHASH { ...@@ -89,7 +91,7 @@ final class GHASH {
X <<= 1; X <<= 1;
} }
X = state1; X = st[1];
for (int i = 64; i < 127; i++) { for (int i = 64; i < 127; i++) {
// Zi+1 = Zi if bit i of x is 0 // Zi+1 = Zi if bit i of x is 0
long mask = X >> 63; long mask = X >> 63;
...@@ -115,15 +117,18 @@ final class GHASH { ...@@ -115,15 +117,18 @@ final class GHASH {
Z1 ^= V1 & mask; Z1 ^= V1 & mask;
// Save result. // Save result.
state0 = Z0; st[0] = Z0;
state1 = Z1; st[1] = Z1;
} }
/* subkeyH and state are stored in long[] for GHASH intrinsic use */
// hash subkey H; should not change after the object has been constructed // hash subkey H; should not change after the object has been constructed
private final long subkeyH0, subkeyH1; private final long[] subkeyH;
// buffer for storing hash // buffer for storing hash
private long state0, state1; private final long[] state;
// variables for save/restore calls // variables for save/restore calls
private long stateSave0, stateSave1; private long stateSave0, stateSave1;
...@@ -141,8 +146,10 @@ final class GHASH { ...@@ -141,8 +146,10 @@ final class GHASH {
if ((subkeyH == null) || subkeyH.length != AES_BLOCK_SIZE) { if ((subkeyH == null) || subkeyH.length != AES_BLOCK_SIZE) {
throw new ProviderException("Internal error"); throw new ProviderException("Internal error");
} }
this.subkeyH0 = getLong(subkeyH, 0); state = new long[2];
this.subkeyH1 = getLong(subkeyH, 8); this.subkeyH = new long[2];
this.subkeyH[0] = getLong(subkeyH, 0);
this.subkeyH[1] = getLong(subkeyH, 8);
} }
/** /**
...@@ -151,33 +158,30 @@ final class GHASH { ...@@ -151,33 +158,30 @@ final class GHASH {
* this object for different data w/ the same H. * this object for different data w/ the same H.
*/ */
void reset() { void reset() {
state0 = 0; state[0] = 0;
state1 = 0; state[1] = 0;
} }
/** /**
* Save the current snapshot of this GHASH object. * Save the current snapshot of this GHASH object.
*/ */
void save() { void save() {
stateSave0 = state0; stateSave0 = state[0];
stateSave1 = state1; stateSave1 = state[1];
} }
/** /**
* Restores this object using the saved snapshot. * Restores this object using the saved snapshot.
*/ */
void restore() { void restore() {
state0 = stateSave0; state[0] = stateSave0;
state1 = stateSave1; state[1] = stateSave1;
} }
private void processBlock(byte[] data, int ofs) { private static void processBlock(byte[] data, int ofs, long[] st, long[] subH) {
if (data.length - ofs < AES_BLOCK_SIZE) { st[0] ^= getLong(data, ofs);
throw new RuntimeException("need complete block"); st[1] ^= getLong(data, ofs + 8);
} blockMult(st, subH);
state0 ^= getLong(data, ofs);
state1 ^= getLong(data, ofs + 8);
blockMult(subkeyH0, subkeyH1);
} }
void update(byte[] in) { void update(byte[] in) {
...@@ -185,22 +189,57 @@ final class GHASH { ...@@ -185,22 +189,57 @@ final class GHASH {
} }
void update(byte[] in, int inOfs, int inLen) { void update(byte[] in, int inOfs, int inLen) {
if (inLen - inOfs > in.length) { if (inLen == 0) {
throw new RuntimeException("input length out of bound"); return;
}
ghashRangeCheck(in, inOfs, inLen, state, subkeyH);
processBlocks(in, inOfs, inLen/AES_BLOCK_SIZE, state, subkeyH);
}
private static void ghashRangeCheck(byte[] in, int inOfs, int inLen, long[] st, long[] subH) {
if (inLen < 0) {
throw new RuntimeException("invalid input length: " + inLen);
}
if (inOfs < 0) {
throw new RuntimeException("invalid offset: " + inOfs);
}
if (inLen > in.length - inOfs) {
throw new RuntimeException("input length out of bound: " +
inLen + " > " + (in.length - inOfs));
} }
if (inLen % AES_BLOCK_SIZE != 0) { if (inLen % AES_BLOCK_SIZE != 0) {
throw new RuntimeException("input length unsupported"); throw new RuntimeException("input length/block size mismatch: " +
inLen);
} }
for (int i = inOfs; i < (inOfs + inLen); i += AES_BLOCK_SIZE) { // These two checks are for C2 checking
processBlock(in, i); if (st.length != 2) {
throw new RuntimeException("internal state has invalid length: " +
st.length);
}
if (subH.length != 2) {
throw new RuntimeException("internal subkeyH has invalid length: " +
subH.length);
}
}
/*
* This is an intrinsified method. The method's argument list must match
* the hotspot signature. This method and methods called by it, cannot
* throw exceptions or allocate arrays as it will breaking intrinsics
*/
private static void processBlocks(byte[] data, int inOfs, int blocks, long[] st, long[] subH) {
int offset = inOfs;
while (blocks > 0) {
processBlock(data, offset, st, subH);
blocks--;
offset += AES_BLOCK_SIZE;
} }
} }
byte[] digest() { byte[] digest() {
byte[] result = new byte[AES_BLOCK_SIZE]; byte[] result = new byte[AES_BLOCK_SIZE];
putLong(result, 0, state0); putLong(result, 0, state[0]);
putLong(result, 8, state1); putLong(result, 8, state[1]);
reset(); reset();
return result; return result;
} }
......
...@@ -43,6 +43,7 @@ import java.security.cert.CertificateFactory; ...@@ -43,6 +43,7 @@ import java.security.cert.CertificateFactory;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import javax.crypto.SealedObject; import javax.crypto.SealedObject;
import sun.misc.IOUtils;
import sun.misc.ObjectInputFilter; import sun.misc.ObjectInputFilter;
/** /**
...@@ -70,7 +71,7 @@ public final class JceKeyStore extends KeyStoreSpi { ...@@ -70,7 +71,7 @@ public final class JceKeyStore extends KeyStoreSpi {
private static final class PrivateKeyEntry { private static final class PrivateKeyEntry {
Date date; // the creation date of this entry Date date; // the creation date of this entry
byte[] protectedKey; byte[] protectedKey;
Certificate chain[]; Certificate[] chain;
}; };
// Secret key // Secret key
...@@ -738,23 +739,11 @@ public final class JceKeyStore extends KeyStoreSpi { ...@@ -738,23 +739,11 @@ public final class JceKeyStore extends KeyStoreSpi {
entry.date = new Date(dis.readLong()); entry.date = new Date(dis.readLong());
// read the private key // read the private key
try { entry.protectedKey = IOUtils.readExactlyNBytes(dis, dis.readInt());
entry.protectedKey = new byte[dis.readInt()];
} catch (OutOfMemoryError e) {
throw new IOException("Keysize too big");
}
dis.readFully(entry.protectedKey);
// read the certificate chain // read the certificate chain
int numOfCerts = dis.readInt(); int numOfCerts = dis.readInt();
try { List<Certificate> tmpCerts = new ArrayList<>();
if (numOfCerts > 0) {
entry.chain = new Certificate[numOfCerts];
}
} catch (OutOfMemoryError e) {
throw new IOException("Too many certificates in "
+ "chain");
}
for (int j = 0; j < numOfCerts; j++) { for (int j = 0; j < numOfCerts; j++) {
if (xVersion == 2) { if (xVersion == 2) {
// read the certificate type, and instantiate a // read the certificate type, and instantiate a
...@@ -762,27 +751,24 @@ public final class JceKeyStore extends KeyStoreSpi { ...@@ -762,27 +751,24 @@ public final class JceKeyStore extends KeyStoreSpi {
// existing factory if possible) // existing factory if possible)
String certType = dis.readUTF(); String certType = dis.readUTF();
if (cfs.containsKey(certType)) { if (cfs.containsKey(certType)) {
// reuse certificate factory // reuse certificate factory
cf = cfs.get(certType); cf = cfs.get(certType);
} else { } else {
// create new certificate factory // create new certificate factory
cf = CertificateFactory.getInstance( cf = CertificateFactory.getInstance(
certType); certType);
// store the certificate factory so we can // store the certificate factory so we can
// reuse it later // reuse it later
cfs.put(certType, cf); cfs.put(certType, cf);
} }
} }
// instantiate the certificate // instantiate the certificate
try { encoded = IOUtils.readExactlyNBytes(dis, dis.readInt());
encoded = new byte[dis.readInt()];
} catch (OutOfMemoryError e) {
throw new IOException("Certificate too big");
}
dis.readFully(encoded);
bais = new ByteArrayInputStream(encoded); bais = new ByteArrayInputStream(encoded);
entry.chain[j] = cf.generateCertificate(bais); tmpCerts.add(cf.generateCertificate(bais));
} }
entry.chain = tmpCerts.toArray(
new Certificate[numOfCerts]);
// Add the entry to the list // Add the entry to the list
entries.put(alias, entry); entries.put(alias, entry);
...@@ -814,12 +800,7 @@ public final class JceKeyStore extends KeyStoreSpi { ...@@ -814,12 +800,7 @@ public final class JceKeyStore extends KeyStoreSpi {
cfs.put(certType, cf); cfs.put(certType, cf);
} }
} }
try { encoded = IOUtils.readExactlyNBytes(dis, dis.readInt());
encoded = new byte[dis.readInt()];
} catch (OutOfMemoryError e) {
throw new IOException("Certificate too big");
}
dis.readFully(encoded);
bais = new ByteArrayInputStream(encoded); bais = new ByteArrayInputStream(encoded);
entry.cert = cf.generateCertificate(bais); entry.cert = cf.generateCertificate(bais);
...@@ -870,18 +851,14 @@ public final class JceKeyStore extends KeyStoreSpi { ...@@ -870,18 +851,14 @@ public final class JceKeyStore extends KeyStoreSpi {
* with * with
*/ */
if (password != null) { if (password != null) {
byte computed[], actual[]; byte[] computed = md.digest();
computed = md.digest(); byte[] actual = IOUtils.readExactlyNBytes(dis, computed.length);
actual = new byte[computed.length]; if (!MessageDigest.isEqual(computed, actual)) {
dis.readFully(actual); throw new IOException(
for (int i = 0; i < computed.length; i++) {
if (computed[i] != actual[i]) {
throw new IOException(
"Keystore was tampered with, or " "Keystore was tampered with, or "
+ "password was incorrect", + "password was incorrect",
new UnrecoverableKeyException( new UnrecoverableKeyException(
"Password verification failed")); "Password verification failed"));
}
} }
} }
} finally { } finally {
......
...@@ -123,6 +123,13 @@ class ClassReader { ...@@ -123,6 +123,13 @@ class ClassReader {
return e; return e;
} }
private Entry checkValid(Entry e) {
if (e == INVALID_ENTRY) {
throw new IllegalStateException("Invalid constant pool reference");
}
return e;
}
/** Throw a ClassFormatException if the entry does not match the expected tag type. */ /** Throw a ClassFormatException if the entry does not match the expected tag type. */
private Entry checkTag(Entry e, byte tag) throws ClassFormatException { private Entry checkTag(Entry e, byte tag) throws ClassFormatException {
if (e == null || !e.tagMatches(tag)) { if (e == null || !e.tagMatches(tag)) {
...@@ -225,6 +232,29 @@ class ClassReader { ...@@ -225,6 +232,29 @@ class ClassReader {
return null; // OK return null; // OK
} }
// use this identity for invalid references
private static final Entry INVALID_ENTRY = new Entry((byte) -1) {
@Override
public boolean equals(Object o) {
throw new IllegalStateException("Should not call this");
}
@Override
protected int computeValueHash() {
throw new IllegalStateException("Should not call this");
}
@Override
public int compareTo(Object o) {
throw new IllegalStateException("Should not call this");
}
@Override
public String stringValue() {
throw new IllegalStateException("Should not call this");
}
};
void readConstantPool() throws IOException { void readConstantPool() throws IOException {
int length = in.readUnsignedShort(); int length = in.readUnsignedShort();
//System.err.println("reading CP, length="+length); //System.err.println("reading CP, length="+length);
...@@ -233,7 +263,7 @@ class ClassReader { ...@@ -233,7 +263,7 @@ class ClassReader {
int fptr = 0; int fptr = 0;
Entry[] cpMap = new Entry[length]; Entry[] cpMap = new Entry[length];
cpMap[0] = null; cpMap[0] = INVALID_ENTRY;
for (int i = 1; i < length; i++) { for (int i = 1; i < length; i++) {
//System.err.println("reading CP elt, i="+i); //System.err.println("reading CP elt, i="+i);
int tag = in.readByte(); int tag = in.readByte();
...@@ -254,13 +284,13 @@ class ClassReader { ...@@ -254,13 +284,13 @@ class ClassReader {
case CONSTANT_Long: case CONSTANT_Long:
{ {
cpMap[i] = ConstantPool.getLiteralEntry(in.readLong()); cpMap[i] = ConstantPool.getLiteralEntry(in.readLong());
cpMap[++i] = null; cpMap[++i] = INVALID_ENTRY;
} }
break; break;
case CONSTANT_Double: case CONSTANT_Double:
{ {
cpMap[i] = ConstantPool.getLiteralEntry(in.readDouble()); cpMap[i] = ConstantPool.getLiteralEntry(in.readDouble());
cpMap[++i] = null; cpMap[++i] = INVALID_ENTRY;
} }
break; break;
...@@ -315,7 +345,7 @@ class ClassReader { ...@@ -315,7 +345,7 @@ class ClassReader {
int ref2 = fixups[fi++]; int ref2 = fixups[fi++];
if (verbose > 3) if (verbose > 3)
Utils.log.fine(" cp["+cpi+"] = "+ConstantPool.tagName(tag)+"{"+ref+","+ref2+"}"); Utils.log.fine(" cp["+cpi+"] = "+ConstantPool.tagName(tag)+"{"+ref+","+ref2+"}");
if (ref >= 0 && cpMap[ref] == null || ref2 >= 0 && cpMap[ref2] == null) { if (ref >= 0 && checkValid(cpMap[ref]) == null || ref2 >= 0 && checkValid(cpMap[ref2]) == null) {
// Defer. // Defer.
fixups[fptr++] = cpi; fixups[fptr++] = cpi;
fixups[fptr++] = tag; fixups[fptr++] = tag;
...@@ -364,7 +394,6 @@ class ClassReader { ...@@ -364,7 +394,6 @@ class ClassReader {
cls.cpMap = cpMap; cls.cpMap = cpMap;
} }
private /*non-static*/ private /*non-static*/
class UnresolvedEntry extends Entry { class UnresolvedEntry extends Entry {
final Object[] refsOrIndexes; final Object[] refsOrIndexes;
......
...@@ -47,8 +47,6 @@ import javax.naming.ldap.Control; ...@@ -47,8 +47,6 @@ import javax.naming.ldap.Control;
import javax.net.ssl.SSLParameters; import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocket;
import sun.misc.IOUtils;
/** /**
* A thread that creates a connection to an LDAP server. * A thread that creates a connection to an LDAP server.
* After the connection, the thread reads from the connection. * After the connection, the thread reads from the connection.
...@@ -886,7 +884,7 @@ public final class Connection implements Runnable { ...@@ -886,7 +884,7 @@ public final class Connection implements Runnable {
} }
// read in seqlen bytes // read in seqlen bytes
byte[] left = IOUtils.readFully(in, seqlen, false); byte[] left = readFully(in, seqlen);
inbuf = Arrays.copyOf(inbuf, offset + left.length); inbuf = Arrays.copyOf(inbuf, offset + left.length);
System.arraycopy(left, 0, inbuf, offset, left.length); System.arraycopy(left, 0, inbuf, offset, left.length);
offset += left.length; offset += left.length;
...@@ -981,6 +979,31 @@ System.err.println("bytesread: " + bytesread); ...@@ -981,6 +979,31 @@ System.err.println("bytesread: " + bytesread);
} }
} }
private static byte[] readFully(InputStream is, int length)
throws IOException
{
byte[] buf = new byte[Math.min(length, 8192)];
int nread = 0;
while (nread < length) {
int bytesToRead;
if (nread >= buf.length) { // need to allocate a larger buffer
bytesToRead = Math.min(length - nread, buf.length + 8192);
if (buf.length < nread + bytesToRead) {
buf = Arrays.copyOf(buf, nread + bytesToRead);
}
} else {
bytesToRead = buf.length - nread;
}
int count = is.read(buf, nread, bytesToRead);
if (count < 0) {
if (buf.length != nread)
buf = Arrays.copyOf(buf, nread);
break;
}
nread += count;
}
return buf;
}
// This code must be uncommented to run the LdapAbandonTest. // This code must be uncommented to run the LdapAbandonTest.
/*public void sendSearchReqs(String dn, int numReqs) { /*public void sendSearchReqs(String dn, int numReqs) {
......
...@@ -123,8 +123,9 @@ import sun.misc.HexDumpEncoder; ...@@ -123,8 +123,9 @@ import sun.misc.HexDumpEncoder;
* must also be set to true; Otherwise a configuration error will * must also be set to true; Otherwise a configuration error will
* be returned.</dd> * be returned.</dd>
* <dt><b><code>renewTGT</code></b>:</dt> * <dt><b><code>renewTGT</code></b>:</dt>
* <dd>Set this to true, if you want to renew * <dd>Set this to true, if you want to renew the TGT when it's more than
* the TGT. If this is set, <code>useTicketCache</code> must also be * half-way expired (the time until expiration is less than the time
* since start time). If this is set, {@code useTicketCache} must also be
* set to true; otherwise a configuration error will be returned.</dd> * set to true; otherwise a configuration error will be returned.</dd>
* <dt><b><code>doNotPrompt</code></b>:</dt> * <dt><b><code>doNotPrompt</code></b>:</dt>
* <dd>Set this to true if you do not want to be * <dd>Set this to true if you do not want to be
...@@ -665,22 +666,21 @@ public class Krb5LoginModule implements LoginModule { ...@@ -665,22 +666,21 @@ public class Krb5LoginModule implements LoginModule {
(principal, ticketCacheName); (principal, ticketCacheName);
if (cred != null) { if (cred != null) {
// check to renew credentials if (renewTGT && isOld(cred)) {
if (!isCurrent(cred)) { // renew if ticket is old.
if (renewTGT) { Credentials newCred = renewCredentials(cred);
Credentials newCred = renewCredentials(cred); if (newCred != null) {
if (newCred != null) { newCred.setProxy(cred.getProxy());
newCred.setProxy(cred.getProxy());
}
cred = newCred; cred = newCred;
} else {
// credentials have expired
cred = null;
if (debug)
System.out.println("Credentials are" +
" no longer valid");
} }
} }
if (!isCurrent(cred)) {
// credentials have expired
cred = null;
if (debug)
System.out.println("Credentials are" +
" no longer valid");
}
} }
if (cred != null) { if (cred != null) {
...@@ -988,7 +988,7 @@ public class Krb5LoginModule implements LoginModule { ...@@ -988,7 +988,7 @@ public class Krb5LoginModule implements LoginModule {
} }
} }
private boolean isCurrent(Credentials creds) private static boolean isCurrent(Credentials creds)
{ {
Date endTime = creds.getEndTime(); Date endTime = creds.getEndTime();
if (endTime != null) { if (endTime != null) {
...@@ -997,6 +997,23 @@ public class Krb5LoginModule implements LoginModule { ...@@ -997,6 +997,23 @@ public class Krb5LoginModule implements LoginModule {
return true; return true;
} }
private static boolean isOld(Credentials creds)
{
Date endTime = creds.getEndTime();
if (endTime != null) {
Date authTime = creds.getAuthTime();
long now = System.currentTimeMillis();
if (authTime != null) {
// pass the mid between auth and end
return now - authTime.getTime() > endTime.getTime() - now;
} else {
// will expire in less than 2 hours
return now <= endTime.getTime() - 1000*3600*2L;
}
}
return false;
}
private Credentials renewCredentials(Credentials creds) private Credentials renewCredentials(Credentials creds)
{ {
Credentials lcreds; Credentials lcreds;
...@@ -1004,6 +1021,10 @@ public class Krb5LoginModule implements LoginModule { ...@@ -1004,6 +1021,10 @@ public class Krb5LoginModule implements LoginModule {
if (!creds.isRenewable()) if (!creds.isRenewable())
throw new RefreshFailedException("This ticket" + throw new RefreshFailedException("This ticket" +
" is not renewable"); " is not renewable");
if (creds.getRenewTill() == null) {
// Renewable ticket without renew-till. Illegal and ignored.
return creds;
}
if (System.currentTimeMillis() > cred.getRenewTill().getTime()) if (System.currentTimeMillis() > cred.getRenewTill().getTime())
throw new RefreshFailedException("This ticket is past " throw new RefreshFailedException("This ticket is past "
+ "its last renewal time."); + "its last renewal time.");
......
/* /*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -73,8 +73,12 @@ abstract class GssKrb5Base extends AbstractSaslImpl { ...@@ -73,8 +73,12 @@ abstract class GssKrb5Base extends AbstractSaslImpl {
} }
try { try {
MessageProp msgProp = new MessageProp(JGSS_QOP, privacy); MessageProp msgProp = new MessageProp(JGSS_QOP, false);
byte[] answer = secCtx.unwrap(incoming, start, len, msgProp); byte[] answer = secCtx.unwrap(incoming, start, len, msgProp);
if (privacy && !msgProp.getPrivacy()) {
throw new SaslException("Privacy not protected");
}
checkMessageProp("", msgProp);
if (logger.isLoggable(Level.FINEST)) { if (logger.isLoggable(Level.FINEST)) {
traceOutput(myClassName, "KRB501:Unwrap", "incoming: ", traceOutput(myClassName, "KRB501:Unwrap", "incoming: ",
incoming, start, len); incoming, start, len);
...@@ -128,4 +132,20 @@ abstract class GssKrb5Base extends AbstractSaslImpl { ...@@ -128,4 +132,20 @@ abstract class GssKrb5Base extends AbstractSaslImpl {
protected void finalize() throws Throwable { protected void finalize() throws Throwable {
dispose(); dispose();
} }
void checkMessageProp(String label, MessageProp msgProp)
throws SaslException {
if (msgProp.isDuplicateToken()) {
throw new SaslException(label + "Duplicate token");
}
if (msgProp.isGapToken()) {
throw new SaslException(label + "Gap token");
}
if (msgProp.isOldToken()) {
throw new SaslException(label + "Old token");
}
if (msgProp.isUnseqToken()) {
throw new SaslException(label + "Token not in sequence");
}
}
} }
/* /*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -230,8 +230,10 @@ final class GssKrb5Client extends GssKrb5Base implements SaslClient { ...@@ -230,8 +230,10 @@ final class GssKrb5Client extends GssKrb5Base implements SaslClient {
// Received S1 (security layer, server max recv size) // Received S1 (security layer, server max recv size)
MessageProp msgProp = new MessageProp(false);
byte[] gssOutToken = secCtx.unwrap(challengeData, 0, byte[] gssOutToken = secCtx.unwrap(challengeData, 0,
challengeData.length, new MessageProp(0, false)); challengeData.length, msgProp);
checkMessageProp("Handshake failure: ", msgProp);
// First octet is a bit-mask specifying the protections // First octet is a bit-mask specifying the protections
// supported by the server // supported by the server
......
/* /*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -250,8 +250,10 @@ final class GssKrb5Server extends GssKrb5Base implements SaslServer { ...@@ -250,8 +250,10 @@ final class GssKrb5Server extends GssKrb5Base implements SaslServer {
try { try {
// Expecting 4 octets from client selected protection // Expecting 4 octets from client selected protection
// and client's receive buffer size // and client's receive buffer size
MessageProp msgProp = new MessageProp(false);
byte[] gssOutToken = secCtx.unwrap(responseData, 0, byte[] gssOutToken = secCtx.unwrap(responseData, 0,
responseData.length, new MessageProp(0, false)); responseData.length, msgProp);
checkMessageProp("Handshake failure: ", msgProp);
if (logger.isLoggable(Level.FINER)) { if (logger.isLoggable(Level.FINER)) {
traceOutput(MY_CLASS_NAME, "doHandshake2", traceOutput(MY_CLASS_NAME, "doHandshake2",
......
...@@ -43,7 +43,9 @@ import sun.java2d.cmm.ProfileDataVerifier; ...@@ -43,7 +43,9 @@ import sun.java2d.cmm.ProfileDataVerifier;
import sun.java2d.cmm.ProfileDeferralMgr; import sun.java2d.cmm.ProfileDeferralMgr;
import sun.java2d.cmm.ProfileDeferralInfo; import sun.java2d.cmm.ProfileDeferralInfo;
import sun.java2d.cmm.ProfileActivator; import sun.java2d.cmm.ProfileActivator;
import sun.misc.IOUtils;
import java.io.BufferedInputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
...@@ -1019,42 +1021,25 @@ public class ICC_Profile implements Serializable { ...@@ -1019,42 +1021,25 @@ public class ICC_Profile implements Serializable {
static byte[] getProfileDataFromStream(InputStream s) throws IOException { static byte[] getProfileDataFromStream(InputStream s) throws IOException {
byte profileData[];
int profileSize;
byte header[] = new byte[128]; BufferedInputStream bis = new BufferedInputStream(s);
int bytestoread = 128; bis.mark(128);
int bytesread = 0;
int n;
while (bytestoread != 0) { byte[] header = IOUtils.readNBytes(bis, 128);
if ((n = s.read(header, bytesread, bytestoread)) < 0) {
return null;
}
bytesread += n;
bytestoread -= n;
}
if (header[36] != 0x61 || header[37] != 0x63 || if (header[36] != 0x61 || header[37] != 0x63 ||
header[38] != 0x73 || header[39] != 0x70) { header[38] != 0x73 || header[39] != 0x70) {
return null; /* not a valid profile */ return null; /* not a valid profile */
} }
profileSize = ((header[0] & 0xff) << 24) | int profileSize = ((header[0] & 0xff) << 24) |
((header[1] & 0xff) << 16) | ((header[1] & 0xff) << 16) |
((header[2] & 0xff) << 8) | ((header[2] & 0xff) << 8) |
(header[3] & 0xff); (header[3] & 0xff);
profileData = new byte[profileSize]; bis.reset();
System.arraycopy(header, 0, profileData, 0, 128); try {
bytestoread = profileSize - 128; return IOUtils.readNBytes(bis, profileSize);
bytesread = 128; } catch (OutOfMemoryError e) {
while (bytestoread != 0) { throw new IOException("Color profile is too big");
if ((n = s.read(profileData, bytesread, bytestoread)) < 0) {
return null;
}
bytesread += n;
bytestoread -= n;
} }
return profileData;
} }
......
/* /*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -1024,18 +1024,8 @@ public class BeanContextSupport extends BeanContextChildSupport ...@@ -1024,18 +1024,8 @@ public class BeanContextSupport extends BeanContextChildSupport
int count = serializable; int count = serializable;
while (count-- > 0) { while (count-- > 0) {
Object child = null; Object child = ois.readObject();
BeanContextSupport.BCSChild bscc = null; BCSChild bscc = (BCSChild) ois.readObject();
try {
child = ois.readObject();
bscc = (BeanContextSupport.BCSChild)ois.readObject();
} catch (IOException ioe) {
continue;
} catch (ClassNotFoundException cnfe) {
continue;
}
synchronized(child) { synchronized(child) {
BeanContextChild bcc = null; BeanContextChild bcc = null;
......
...@@ -46,8 +46,11 @@ import sun.security.util.SecurityConstants; ...@@ -46,8 +46,11 @@ import sun.security.util.SecurityConstants;
* the file separator character, <code>File.separatorChar</code>) indicates * the file separator character, <code>File.separatorChar</code>) indicates
* all the files and directories contained in that directory. A pathname * all the files and directories contained in that directory. A pathname
* that ends with "/-" indicates (recursively) all files * that ends with "/-" indicates (recursively) all files
* and subdirectories contained in that directory. A pathname consisting of * and subdirectories contained in that directory. Such a pathname is called
* the special token "&lt;&lt;ALL FILES&gt;&gt;" matches <b>any</b> file. * a wildcard pathname. Otherwise, it's a simple pathname.
* <P>
* A pathname consisting of the special token {@literal "<<ALL FILES>>"}
* matches <b>any</b> file.
* <P> * <P>
* Note: A pathname consisting of a single "*" indicates all the files * Note: A pathname consisting of a single "*" indicates all the files
* in the current directory, while a pathname consisting of a single "-" * in the current directory, while a pathname consisting of a single "-"
...@@ -80,7 +83,7 @@ import sun.security.util.SecurityConstants; ...@@ -80,7 +83,7 @@ import sun.security.util.SecurityConstants;
* <P> * <P>
* Be careful when granting FilePermissions. Think about the implications * Be careful when granting FilePermissions. Think about the implications
* of granting read and especially write access to various files and * of granting read and especially write access to various files and
* directories. The "&lt;&lt;ALL FILES&gt;&gt;" permission with write action is * directories. The {@literal "<<ALL FILES>>"} permission with write action is
* especially dangerous. This grants permission to write to the entire * especially dangerous. This grants permission to write to the entire
* file system. One thing this effectively allows is replacement of the * file system. One thing this effectively allows is replacement of the
* system binary, including the JVM runtime environment. * system binary, including the JVM runtime environment.
...@@ -156,6 +159,7 @@ public final class FilePermission extends Permission implements Serializable { ...@@ -156,6 +159,7 @@ public final class FilePermission extends Permission implements Serializable {
private transient String cpath; private transient String cpath;
private transient boolean allFiles; // whether this is <<ALL FILES>>
private transient boolean invalid; // whether input path is invalid private transient boolean invalid; // whether input path is invalid
// static Strings used by init(int mask) // static Strings used by init(int mask)
...@@ -207,6 +211,7 @@ public final class FilePermission extends Permission implements Serializable { ...@@ -207,6 +211,7 @@ public final class FilePermission extends Permission implements Serializable {
this.mask = mask; this.mask = mask;
if (cpath.equals("<<ALL FILES>>")) { if (cpath.equals("<<ALL FILES>>")) {
allFiles = true;
directory = true; directory = true;
recursive = true; recursive = true;
cpath = ""; cpath = "";
...@@ -335,6 +340,23 @@ public final class FilePermission extends Permission implements Serializable { ...@@ -335,6 +340,23 @@ public final class FilePermission extends Permission implements Serializable {
* "/tmp/*" encompasses all files in the "/tmp" directory, * "/tmp/*" encompasses all files in the "/tmp" directory,
* including the one named "foo". * including the one named "foo".
* </ul> * </ul>
* <P>
* Precisely, a simple pathname implies another simple pathname
* if and only if they are equal. A simple pathname never implies
* a wildcard pathname. A wildcard pathname implies another wildcard
* pathname if and only if all simple pathnames implied by the latter
* are implied by the former. A wildcard pathname implies a simple
* pathname if and only if
* <ul>
* <li>if the wildcard flag is "*", the simple pathname's path
* must be right inside the wildcard pathname's path.
* <li>if the wildcard flag is "-", the simple pathname's path
* must be recursively inside the wildcard pathname's path.
* </ul>
* <P>
* {@literal "<<ALL FILES>>"} implies every other pathname. No pathname,
* except for {@literal "<<ALL FILES>>"} itself, implies
* {@literal "<<ALL FILES>>"}.
* *
* @param p the permission to check against. * @param p the permission to check against.
* *
...@@ -366,9 +388,15 @@ public final class FilePermission extends Permission implements Serializable { ...@@ -366,9 +388,15 @@ public final class FilePermission extends Permission implements Serializable {
if (this == that) { if (this == that) {
return true; return true;
} }
if (allFiles) {
return true;
}
if (this.invalid || that.invalid) { if (this.invalid || that.invalid) {
return false; return false;
} }
if (that.allFiles) {
return false;
}
if (this.directory) { if (this.directory) {
if (this.recursive) { if (this.recursive) {
// make sure that.path is longer then path so // make sure that.path is longer then path so
...@@ -415,6 +443,10 @@ public final class FilePermission extends Permission implements Serializable { ...@@ -415,6 +443,10 @@ public final class FilePermission extends Permission implements Serializable {
* Checks two FilePermission objects for equality. Checks that <i>obj</i> is * Checks two FilePermission objects for equality. Checks that <i>obj</i> is
* a FilePermission, and has the same pathname and actions as this object. * a FilePermission, and has the same pathname and actions as this object.
* *
* @implNote More specifically, two pathnames are the same if and only if
* they have the same wildcard flag and their
* {@code npath} are equal. Or they are both {@literal "<<ALL FILES>>"}.
*
* @param obj the object we are testing for equality with this object. * @param obj the object we are testing for equality with this object.
* @return <code>true</code> if obj is a FilePermission, and has the same * @return <code>true</code> if obj is a FilePermission, and has the same
* pathname and actions as this FilePermission object, * pathname and actions as this FilePermission object,
...@@ -433,6 +465,7 @@ public final class FilePermission extends Permission implements Serializable { ...@@ -433,6 +465,7 @@ public final class FilePermission extends Permission implements Serializable {
return false; return false;
} }
return (this.mask == that.mask) && return (this.mask == that.mask) &&
(this.allFiles == that.allFiles) &&
this.cpath.equals(that.cpath) && this.cpath.equals(that.cpath) &&
(this.directory == that.directory) && (this.directory == that.directory) &&
(this.recursive == that.recursive); (this.recursive == that.recursive);
......
...@@ -419,16 +419,50 @@ public class ObjectInputStream ...@@ -419,16 +419,50 @@ public class ObjectInputStream
* @throws IOException Any of the usual Input/Output related exceptions. * @throws IOException Any of the usual Input/Output related exceptions.
*/ */
public final Object readObject() public final Object readObject()
throws IOException, ClassNotFoundException {
return readObject(Object.class);
}
/**
* Reads a String and only a string.
*
* @return the String read
* @throws EOFException If end of file is reached.
* @throws IOException If other I/O error has occurred.
*/
private String readString() throws IOException {
try {
return (String) readObject(String.class);
} catch (ClassNotFoundException cnf) {
throw new IllegalStateException(cnf);
}
}
/**
* Internal method to read an object from the ObjectInputStream of the expected type.
* Called only from {@code readObject()} and {@code readString()}.
* Only {@code Object.class} and {@code String.class} are supported.
*
* @param type the type expected; either Object.class or String.class
* @return an object of the type
* @throws IOException Any of the usual Input/Output related exceptions.
* @throws ClassNotFoundException Class of a serialized object cannot be
* found.
*/
private final Object readObject(Class<?> type)
throws IOException, ClassNotFoundException throws IOException, ClassNotFoundException
{ {
if (enableOverride) { if (enableOverride) {
return readObjectOverride(); return readObjectOverride();
} }
if (! (type == Object.class || type == String.class))
throw new AssertionError("internal error");
// if nested read, passHandle contains handle of enclosing object // if nested read, passHandle contains handle of enclosing object
int outerHandle = passHandle; int outerHandle = passHandle;
try { try {
Object obj = readObject0(false); Object obj = readObject0(type, false);
handles.markDependency(outerHandle, passHandle); handles.markDependency(outerHandle, passHandle);
ClassNotFoundException ex = handles.lookupException(passHandle); ClassNotFoundException ex = handles.lookupException(passHandle);
if (ex != null) { if (ex != null) {
...@@ -518,7 +552,7 @@ public class ObjectInputStream ...@@ -518,7 +552,7 @@ public class ObjectInputStream
// if nested read, passHandle contains handle of enclosing object // if nested read, passHandle contains handle of enclosing object
int outerHandle = passHandle; int outerHandle = passHandle;
try { try {
Object obj = readObject0(true); Object obj = readObject0(Object.class, true);
handles.markDependency(outerHandle, passHandle); handles.markDependency(outerHandle, passHandle);
ClassNotFoundException ex = handles.lookupException(passHandle); ClassNotFoundException ex = handles.lookupException(passHandle);
if (ex != null) { if (ex != null) {
...@@ -1517,8 +1551,10 @@ public class ObjectInputStream ...@@ -1517,8 +1551,10 @@ public class ObjectInputStream
/** /**
* Underlying readObject implementation. * Underlying readObject implementation.
* @param type a type expected to be deserialized; non-null
* @param unshared true if the object can not be a reference to a shared object, otherwise false
*/ */
private Object readObject0(boolean unshared) throws IOException { private Object readObject0(Class<?> type, boolean unshared) throws IOException {
boolean oldMode = bin.getBlockDataMode(); boolean oldMode = bin.getBlockDataMode();
if (oldMode) { if (oldMode) {
int remain = bin.currentBlockRemaining(); int remain = bin.currentBlockRemaining();
...@@ -1550,13 +1586,20 @@ public class ObjectInputStream ...@@ -1550,13 +1586,20 @@ public class ObjectInputStream
return readNull(); return readNull();
case TC_REFERENCE: case TC_REFERENCE:
return readHandle(unshared); // check the type of the existing object
return type.cast(readHandle(unshared));
case TC_CLASS: case TC_CLASS:
if (type == String.class) {
throw new ClassCastException("Cannot cast a class to java.lang.String");
}
return readClass(unshared); return readClass(unshared);
case TC_CLASSDESC: case TC_CLASSDESC:
case TC_PROXYCLASSDESC: case TC_PROXYCLASSDESC:
if (type == String.class) {
throw new ClassCastException("Cannot cast a class to java.lang.String");
}
return readClassDesc(unshared); return readClassDesc(unshared);
case TC_STRING: case TC_STRING:
...@@ -1564,15 +1607,27 @@ public class ObjectInputStream ...@@ -1564,15 +1607,27 @@ public class ObjectInputStream
return checkResolve(readString(unshared)); return checkResolve(readString(unshared));
case TC_ARRAY: case TC_ARRAY:
if (type == String.class) {
throw new ClassCastException("Cannot cast an array to java.lang.String");
}
return checkResolve(readArray(unshared)); return checkResolve(readArray(unshared));
case TC_ENUM: case TC_ENUM:
if (type == String.class) {
throw new ClassCastException("Cannot cast an enum to java.lang.String");
}
return checkResolve(readEnum(unshared)); return checkResolve(readEnum(unshared));
case TC_OBJECT: case TC_OBJECT:
if (type == String.class) {
throw new ClassCastException("Cannot cast an object to java.lang.String");
}
return checkResolve(readOrdinaryObject(unshared)); return checkResolve(readOrdinaryObject(unshared));
case TC_EXCEPTION: case TC_EXCEPTION:
if (type == String.class) {
throw new ClassCastException("Cannot cast an exception to java.lang.String");
}
IOException ex = readFatalException(); IOException ex = readFatalException();
throw new WriteAbortedException("writing aborted", ex); throw new WriteAbortedException("writing aborted", ex);
...@@ -1947,7 +2002,7 @@ public class ObjectInputStream ...@@ -1947,7 +2002,7 @@ public class ObjectInputStream
if (ccl == null) { if (ccl == null) {
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
readObject0(false); readObject0(Object.class, false);
} }
} else if (ccl.isPrimitive()) { } else if (ccl.isPrimitive()) {
if (ccl == Integer.TYPE) { if (ccl == Integer.TYPE) {
...@@ -1972,7 +2027,7 @@ public class ObjectInputStream ...@@ -1972,7 +2027,7 @@ public class ObjectInputStream
} else { } else {
Object[] oa = (Object[]) array; Object[] oa = (Object[]) array;
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
oa[i] = readObject0(false); oa[i] = readObject0(Object.class, false);
handles.markDependency(arrayHandle, passHandle); handles.markDependency(arrayHandle, passHandle);
} }
} }
...@@ -2250,7 +2305,7 @@ public class ObjectInputStream ...@@ -2250,7 +2305,7 @@ public class ObjectInputStream
return; return;
default: default:
readObject0(false); readObject0(Object.class, false);
break; break;
} }
} }
...@@ -2284,7 +2339,7 @@ public class ObjectInputStream ...@@ -2284,7 +2339,7 @@ public class ObjectInputStream
int numPrimFields = fields.length - objVals.length; int numPrimFields = fields.length - objVals.length;
for (int i = 0; i < objVals.length; i++) { for (int i = 0; i < objVals.length; i++) {
ObjectStreamField f = fields[numPrimFields + i]; ObjectStreamField f = fields[numPrimFields + i];
objVals[i] = readObject0(f.isUnshared()); objVals[i] = readObject0(Object.class, f.isUnshared());
if (f.getField() != null) { if (f.getField() != null) {
handles.markDependency(objHandle, passHandle); handles.markDependency(objHandle, passHandle);
} }
...@@ -2305,7 +2360,7 @@ public class ObjectInputStream ...@@ -2305,7 +2360,7 @@ public class ObjectInputStream
throw new InternalError(); throw new InternalError();
} }
clear(); clear();
return (IOException) readObject0(false); return (IOException) readObject0(Object.class, false);
} }
/** /**
...@@ -2449,7 +2504,7 @@ public class ObjectInputStream ...@@ -2449,7 +2504,7 @@ public class ObjectInputStream
int numPrimFields = fields.length - objVals.length; int numPrimFields = fields.length - objVals.length;
for (int i = 0; i < objVals.length; i++) { for (int i = 0; i < objVals.length; i++) {
objVals[i] = objVals[i] =
readObject0(fields[numPrimFields + i].isUnshared()); readObject0(Object.class, fields[numPrimFields + i].isUnshared());
objHandles[i] = passHandle; objHandles[i] = passHandle;
} }
passHandle = oldHandle; passHandle = oldHandle;
...@@ -3403,7 +3458,15 @@ public class ObjectInputStream ...@@ -3403,7 +3458,15 @@ public class ObjectInputStream
* utflen bytes. * utflen bytes.
*/ */
private String readUTFBody(long utflen) throws IOException { private String readUTFBody(long utflen) throws IOException {
StringBuilder sbuf = new StringBuilder(); StringBuilder sbuf;
if (utflen > 0 && utflen < Integer.MAX_VALUE) {
// a reasonable initial capacity based on the UTF length
int initialCapacity = Math.min((int)utflen, 0xFFFF);
sbuf = new StringBuilder(initialCapacity);
} else {
sbuf = new StringBuilder();
}
if (!blkmode) { if (!blkmode) {
end = pos = 0; end = pos = 0;
} }
...@@ -3918,5 +3981,6 @@ public class ObjectInputStream ...@@ -3918,5 +3981,6 @@ public class ObjectInputStream
} }
static { static {
SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::setValidator); SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::setValidator);
SharedSecrets.setJavaObjectInputStreamReadString(ObjectInputStream::readString);
} }
} }
/* /*
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, Azul Systems, Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -1467,6 +1468,17 @@ public abstract class ClassLoader { ...@@ -1467,6 +1468,17 @@ public abstract class ClassLoader {
} }
} }
/*
* Initialize default paths for native libraries search.
* Must be done early as JDK may load libraries during bootstrap.
*
* @see java.lang.System#initPhase1
*/
static void initLibraryPaths() {
usr_paths = initializePath("java.library.path");
sys_paths = initializePath("sun.boot.library.path");
}
// Returns true if the specified class loader can be found in this class // Returns true if the specified class loader can be found in this class
// loader's delegation chain. // loader's delegation chain.
boolean isAncestor(ClassLoader cl) { boolean isAncestor(ClassLoader cl) {
...@@ -1809,10 +1821,9 @@ public abstract class ClassLoader { ...@@ -1809,10 +1821,9 @@ public abstract class ClassLoader {
boolean isAbsolute) { boolean isAbsolute) {
ClassLoader loader = ClassLoader loader =
(fromClass == null) ? null : fromClass.getClassLoader(); (fromClass == null) ? null : fromClass.getClassLoader();
if (sys_paths == null) { assert sys_paths != null : "should be initialized at this point";
usr_paths = initializePath("java.library.path"); assert usr_paths != null : "should be initialized at this point";
sys_paths = initializePath("sun.boot.library.path");
}
if (isAbsolute) { if (isAbsolute) {
if (loadLibrary0(fromClass, new File(name))) { if (loadLibrary0(fromClass, new File(name))) {
return; return;
...@@ -1902,13 +1913,14 @@ public abstract class ClassLoader { ...@@ -1902,13 +1913,14 @@ public abstract class ClassLoader {
name + name +
" already loaded in another classloader"); " already loaded in another classloader");
} }
/* If the library is being loaded (must be by the same thread, /*
* because Runtime.load and Runtime.loadLibrary are * When a library is being loaded, JNI_OnLoad function can cause
* synchronous). The reason is can occur is that the JNI_OnLoad * another loadLibrary invocation that should succeed.
* function can cause another loadLibrary invocation.
* *
* Thus we can use a static stack to hold the list of libraries * We use a static stack to hold the list of libraries we are
* we are loading. * loading because this can happen only when called by the
* same thread because Runtime.load and Runtime.loadLibrary
* are synchronous.
* *
* If there is a pending load operation for the library, we * If there is a pending load operation for the library, we
* immediately return success; otherwise, we raise * immediately return success; otherwise, we raise
......
/* /*
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, Azul Systems, Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -797,7 +798,7 @@ public class Runtime { ...@@ -797,7 +798,7 @@ public class Runtime {
load0(Reflection.getCallerClass(), filename); load0(Reflection.getCallerClass(), filename);
} }
synchronized void load0(Class<?> fromClass, String filename) { void load0(Class<?> fromClass, String filename) {
SecurityManager security = System.getSecurityManager(); SecurityManager security = System.getSecurityManager();
if (security != null) { if (security != null) {
security.checkLink(filename); security.checkLink(filename);
...@@ -858,14 +859,14 @@ public class Runtime { ...@@ -858,14 +859,14 @@ public class Runtime {
loadLibrary0(Reflection.getCallerClass(), libname); loadLibrary0(Reflection.getCallerClass(), libname);
} }
synchronized void loadLibrary0(Class<?> fromClass, String libname) { void loadLibrary0(Class<?> fromClass, String libname) {
SecurityManager security = System.getSecurityManager(); SecurityManager security = System.getSecurityManager();
if (security != null) { if (security != null) {
security.checkLink(libname); security.checkLink(libname);
} }
if (libname.indexOf((int)File.separatorChar) != -1) { if (libname.indexOf((int)File.separatorChar) != -1) {
throw new UnsatisfiedLinkError( throw new UnsatisfiedLinkError(
"Directory separator should not appear in library name: " + libname); "Directory separator should not appear in library name: " + libname);
} }
ClassLoader.loadLibrary(fromClass, libname, false); ClassLoader.loadLibrary(fromClass, libname, false);
} }
......
...@@ -44,6 +44,7 @@ import sun.reflect.Reflection; ...@@ -44,6 +44,7 @@ import sun.reflect.Reflection;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
import sun.reflect.annotation.AnnotationType; import sun.reflect.annotation.AnnotationType;
import jdk.internal.util.StaticProperty;
/** /**
* The <code>System</code> class contains several useful class fields * The <code>System</code> class contains several useful class fields
...@@ -1185,6 +1186,7 @@ public final class System { ...@@ -1185,6 +1186,7 @@ public final class System {
lineSeparator = props.getProperty("line.separator"); lineSeparator = props.getProperty("line.separator");
StaticProperty.jdkSerialFilter(); // Load StaticProperty to cache the property values
sun.misc.Version.init(); sun.misc.Version.init();
FileInputStream fdIn = new FileInputStream(FileDescriptor.in); FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
...@@ -1194,6 +1196,8 @@ public final class System { ...@@ -1194,6 +1196,8 @@ public final class System {
setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding"))); setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));
setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding"))); setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding")));
ClassLoader.initLibraryPaths();
// Load the zip library now in order to keep java.util.zip.ZipFile // Load the zip library now in order to keep java.util.zip.ZipFile
// from trying to use itself to load this library later. // from trying to use itself to load this library later.
loadLibrary("zip"); loadLibrary("zip");
......
/* /*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -588,22 +588,29 @@ public abstract class Executable extends AccessibleObject ...@@ -588,22 +588,29 @@ public abstract class Executable extends AccessibleObject
return AnnotationParser.toArray(declaredAnnotations()); return AnnotationParser.toArray(declaredAnnotations());
} }
private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations; private transient volatile Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() { private Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
if (declaredAnnotations == null) { Map<Class<? extends Annotation>, Annotation> declAnnos;
Executable root = getRoot(); if ((declAnnos = declaredAnnotations) == null) {
if (root != null) { synchronized (this) {
declaredAnnotations = root.declaredAnnotations(); if ((declAnnos = declaredAnnotations) == null) {
} else { Executable root = getRoot();
declaredAnnotations = AnnotationParser.parseAnnotations( if (root != null) {
getAnnotationBytes(), declAnnos = root.declaredAnnotations();
sun.misc.SharedSecrets.getJavaLangAccess(). } else {
getConstantPool(getDeclaringClass()), declAnnos = AnnotationParser.parseAnnotations(
getDeclaringClass()); getAnnotationBytes(),
sun.misc.SharedSecrets.getJavaLangAccess().
getConstantPool(getDeclaringClass()),
getDeclaringClass()
);
}
declaredAnnotations = declAnnos;
}
} }
} }
return declaredAnnotations; return declAnnos;
} }
/** /**
......
/* /*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -1139,21 +1139,28 @@ class Field extends AccessibleObject implements Member { ...@@ -1139,21 +1139,28 @@ class Field extends AccessibleObject implements Member {
return AnnotationParser.toArray(declaredAnnotations()); return AnnotationParser.toArray(declaredAnnotations());
} }
private transient Map<Class<? extends Annotation>, Annotation> declaredAnnotations; private transient volatile Map<Class<? extends Annotation>, Annotation> declaredAnnotations;
private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() { private Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
if (declaredAnnotations == null) { Map<Class<? extends Annotation>, Annotation> declAnnos;
Field root = this.root; if ((declAnnos = declaredAnnotations) == null) {
if (root != null) { synchronized (this) {
declaredAnnotations = root.declaredAnnotations(); if ((declAnnos = declaredAnnotations) == null) {
} else { Field root = this.root;
declaredAnnotations = AnnotationParser.parseAnnotations( if (root != null) {
annotations, declAnnos = root.declaredAnnotations();
sun.misc.SharedSecrets.getJavaLangAccess().getConstantPool(getDeclaringClass()), } else {
getDeclaringClass()); declAnnos = AnnotationParser.parseAnnotations(
annotations,
sun.misc.SharedSecrets.getJavaLangAccess()
.getConstantPool(getDeclaringClass()),
getDeclaringClass());
}
declaredAnnotations = declAnnos;
}
} }
} }
return declaredAnnotations; return declAnnos;
} }
private native byte[] getTypeAnnotationBytes0(); private native byte[] getTypeAnnotationBytes0();
......
...@@ -33,6 +33,7 @@ import java.io.ObjectStreamField; ...@@ -33,6 +33,7 @@ import java.io.ObjectStreamField;
import java.io.ObjectInputStream.GetField; import java.io.ObjectInputStream.GetField;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import sun.misc.VM;
import sun.net.util.IPAddressUtil; import sun.net.util.IPAddressUtil;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
...@@ -1423,7 +1424,9 @@ public final class URL implements java.io.Serializable { ...@@ -1423,7 +1424,9 @@ public final class URL implements java.io.Serializable {
} }
boolean isBuiltinStreamHandler(URLStreamHandler handler) { boolean isBuiltinStreamHandler(URLStreamHandler handler) {
return isBuiltinStreamHandler(handler.getClass().getName()); Class<?> handlerClass = handler.getClass();
return isBuiltinStreamHandler(handlerClass.getName())
|| VM.isSystemDomainLoader(handlerClass.getClassLoader());
} }
private boolean isBuiltinStreamHandler(String handlerClassName) { private boolean isBuiltinStreamHandler(String handlerClassName) {
......
...@@ -121,7 +121,7 @@ public abstract class SelectableChannel ...@@ -121,7 +121,7 @@ public abstract class SelectableChannel
// keySet, may be empty but is never null, typ. a tiny array // keySet, may be empty but is never null, typ. a tiny array
// boolean isRegistered, protected by key set // boolean isRegistered, protected by key set
// regLock, lock object to prevent duplicate registrations // regLock, lock object to prevent duplicate registrations
// boolean isBlocking, protected by regLock // blocking mode, protected by regLock
/** /**
* Tells whether or not this channel is currently registered with any * Tells whether or not this channel is currently registered with any
......
/* /*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -26,7 +26,14 @@ ...@@ -26,7 +26,14 @@
package java.nio.channels.spi; package java.nio.channels.spi;
import java.io.IOException; import java.io.IOException;
import java.nio.channels.*; import java.nio.channels.CancelledKeyException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.ClosedSelectorException;
import java.nio.channels.IllegalBlockingModeException;
import java.nio.channels.IllegalSelectorException;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
/** /**
...@@ -67,8 +74,8 @@ public abstract class AbstractSelectableChannel ...@@ -67,8 +74,8 @@ public abstract class AbstractSelectableChannel
// Lock for registration and configureBlocking operations // Lock for registration and configureBlocking operations
private final Object regLock = new Object(); private final Object regLock = new Object();
// Blocking mode, protected by regLock // True when non-blocking, need regLock to change;
boolean blocking = true; private volatile boolean nonBlocking;
/** /**
* Initializes a new instance of this class. * Initializes a new instance of this class.
...@@ -197,7 +204,7 @@ public abstract class AbstractSelectableChannel ...@@ -197,7 +204,7 @@ public abstract class AbstractSelectableChannel
throw new ClosedChannelException(); throw new ClosedChannelException();
if ((ops & ~validOps()) != 0) if ((ops & ~validOps()) != 0)
throw new IllegalArgumentException(); throw new IllegalArgumentException();
if (blocking) if (isBlocking())
throw new IllegalBlockingModeException(); throw new IllegalBlockingModeException();
SelectionKey k = findKey(sel); SelectionKey k = findKey(sel);
if (k != null) { if (k != null) {
...@@ -264,9 +271,7 @@ public abstract class AbstractSelectableChannel ...@@ -264,9 +271,7 @@ public abstract class AbstractSelectableChannel
// -- Blocking -- // -- Blocking --
public final boolean isBlocking() { public final boolean isBlocking() {
synchronized (regLock) { return !nonBlocking;
return blocking;
}
} }
public final Object blockingLock() { public final Object blockingLock() {
...@@ -287,12 +292,13 @@ public abstract class AbstractSelectableChannel ...@@ -287,12 +292,13 @@ public abstract class AbstractSelectableChannel
synchronized (regLock) { synchronized (regLock) {
if (!isOpen()) if (!isOpen())
throw new ClosedChannelException(); throw new ClosedChannelException();
if (blocking == block) boolean blocking = !nonBlocking;
return this; if (block != blocking) {
if (block && haveValidKeys()) if (block && haveValidKeys())
throw new IllegalBlockingModeException(); throw new IllegalBlockingModeException();
implConfigureBlocking(block); implConfigureBlocking(block);
blocking = block; nonBlocking = !block;
}
} }
return this; return this;
} }
......
/* /*
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -29,6 +29,7 @@ import java.lang.reflect.InvocationHandler; ...@@ -29,6 +29,7 @@ import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.rmi.Remote; import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.UnexpectedException; import java.rmi.UnexpectedException;
import java.rmi.activation.Activatable; import java.rmi.activation.Activatable;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
...@@ -224,6 +225,13 @@ public class RemoteObjectInvocationHandler ...@@ -224,6 +225,13 @@ public class RemoteObjectInvocationHandler
throw new IllegalArgumentException( throw new IllegalArgumentException(
"proxy not Remote instance"); "proxy not Remote instance");
} }
// Verify that the method is declared on an interface that extends Remote
Class<?> decl = method.getDeclaringClass();
if (!Remote.class.isAssignableFrom(decl)) {
throw new RemoteException("Method is not Remote: " + decl + "::" + method);
}
return ref.invoke((Remote) proxy, method, args, return ref.invoke((Remote) proxy, method, args,
getMethodHash(method)); getMethodHash(method));
} catch (Exception e) { } catch (Exception e) {
......
...@@ -570,7 +570,7 @@ public class CodeSource implements java.io.Serializable { ...@@ -570,7 +570,7 @@ public class CodeSource implements java.io.Serializable {
cfs.put(certType, cf); cfs.put(certType, cf);
} }
// parse the certificate // parse the certificate
byte[] encoded = IOUtils.readNBytes(ois, ois.readInt()); byte[] encoded = IOUtils.readExactlyNBytes(ois, ois.readInt());
ByteArrayInputStream bais = new ByteArrayInputStream(encoded); ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
try { try {
certList.add(cf.generateCertificate(bais)); certList.add(cf.generateCertificate(bais));
......
/* /*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -63,7 +63,7 @@ package java.security; ...@@ -63,7 +63,7 @@ package java.security;
* </pre> * </pre>
* *
* For more information, see * For more information, see
* <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: * <a href="http://tools.ietf.org/html/rfc5280">RFC 5280:
* Internet X.509 Public Key Infrastructure Certificate and CRL Profile</a>. * Internet X.509 Public Key Infrastructure Certificate and CRL Profile</a>.
* *
* <LI>A Format * <LI>A Format
......
...@@ -590,7 +590,7 @@ implements java.io.Serializable ...@@ -590,7 +590,7 @@ implements java.io.Serializable
cfs.put(certType, cf); cfs.put(certType, cf);
} }
// parse the certificate // parse the certificate
byte[] encoded = IOUtils.readNBytes(ois, ois.readInt()); byte[] encoded = IOUtils.readExactlyNBytes(ois, ois.readInt());
ByteArrayInputStream bais = new ByteArrayInputStream(encoded); ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
try { try {
certList.add(cf.generateCertificate(bais)); certList.add(cf.generateCertificate(bais));
......
/* /*
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -27,8 +27,8 @@ package java.security.cert; ...@@ -27,8 +27,8 @@ package java.security.cert;
/** /**
* The CRLReason enumeration specifies the reason that a certificate * The CRLReason enumeration specifies the reason that a certificate
* is revoked, as defined in <a href="http://www.ietf.org/rfc/rfc3280.txt"> * is revoked, as defined in <a href="http://tools.ietf.org/html/rfc5280">
* RFC 3280: Internet X.509 Public Key Infrastructure Certificate and CRL * RFC 5280: Internet X.509 Public Key Infrastructure Certificate and CRL
* Profile</a>. * Profile</a>.
* *
* @author Sean Mullan * @author Sean Mullan
......
...@@ -239,7 +239,7 @@ public class CertificateRevokedException extends CertificateException { ...@@ -239,7 +239,7 @@ public class CertificateRevokedException extends CertificateException {
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
String oid = (String) ois.readObject(); String oid = (String) ois.readObject();
boolean critical = ois.readBoolean(); boolean critical = ois.readBoolean();
byte[] extVal = IOUtils.readNBytes(ois, ois.readInt()); byte[] extVal = IOUtils.readExactlyNBytes(ois, ois.readInt());
Extension ext = sun.security.x509.Extension.newExtension Extension ext = sun.security.x509.Extension.newExtension
(new ObjectIdentifier(oid), critical, extVal); (new ObjectIdentifier(oid), critical, extVal);
extensions.put(oid, ext); extensions.put(oid, ext);
......
/* /*
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -28,7 +28,7 @@ package java.security.cert; ...@@ -28,7 +28,7 @@ package java.security.cert;
/** /**
* The {@code PKIXReason} enumerates the potential PKIX-specific reasons * The {@code PKIXReason} enumerates the potential PKIX-specific reasons
* that an X.509 certification path may be invalid according to the PKIX * that an X.509 certification path may be invalid according to the PKIX
* (RFC 3280) standard. These reasons are in addition to those of the * (RFC 5280) standard. These reasons are in addition to those of the
* {@code CertPathValidatorException.BasicReason} enumeration. * {@code CertPathValidatorException.BasicReason} enumeration.
* *
* @since 1.7 * @since 1.7
......
/* /*
* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -78,7 +78,7 @@ public class TrustAnchor { ...@@ -78,7 +78,7 @@ public class TrustAnchor {
* The name constraints are specified as a byte array. This byte array * The name constraints are specified as a byte array. This byte array
* should contain the DER encoded form of the name constraints, as they * should contain the DER encoded form of the name constraints, as they
* would appear in the NameConstraints structure defined in * would appear in the NameConstraints structure defined in
* <a href="http://www.ietf.org/rfc/rfc3280">RFC 3280</a> * <a href="http://tools.ietf.org/html/rfc5280">RFC 5280</a>
* and X.509. The ASN.1 definition of this structure appears below. * and X.509. The ASN.1 definition of this structure appears below.
* *
* <pre>{@code * <pre>{@code
...@@ -140,7 +140,7 @@ public class TrustAnchor { ...@@ -140,7 +140,7 @@ public class TrustAnchor {
* <p> * <p>
* The name constraints are specified as a byte array. This byte array * The name constraints are specified as a byte array. This byte array
* contains the DER encoded form of the name constraints, as they * contains the DER encoded form of the name constraints, as they
* would appear in the NameConstraints structure defined in RFC 3280 * would appear in the NameConstraints structure defined in RFC 5280
* and X.509. The ASN.1 notation for this structure is supplied in the * and X.509. The ASN.1 notation for this structure is supplied in the
* documentation for * documentation for
* {@link #TrustAnchor(X509Certificate, byte[]) * {@link #TrustAnchor(X509Certificate, byte[])
...@@ -179,7 +179,7 @@ public class TrustAnchor { ...@@ -179,7 +179,7 @@ public class TrustAnchor {
* <p> * <p>
* The name constraints are specified as a byte array. This byte array * The name constraints are specified as a byte array. This byte array
* contains the DER encoded form of the name constraints, as they * contains the DER encoded form of the name constraints, as they
* would appear in the NameConstraints structure defined in RFC 3280 * would appear in the NameConstraints structure defined in RFC 5280
* and X.509. The ASN.1 notation for this structure is supplied in the * and X.509. The ASN.1 notation for this structure is supplied in the
* documentation for * documentation for
* {@link #TrustAnchor(X509Certificate, byte[]) * {@link #TrustAnchor(X509Certificate, byte[])
...@@ -294,7 +294,7 @@ public class TrustAnchor { ...@@ -294,7 +294,7 @@ public class TrustAnchor {
* <p> * <p>
* The name constraints are returned as a byte array. This byte array * The name constraints are returned as a byte array. This byte array
* contains the DER encoded form of the name constraints, as they * contains the DER encoded form of the name constraints, as they
* would appear in the NameConstraints structure defined in RFC 3280 * would appear in the NameConstraints structure defined in RFC 5280
* and X.509. The ASN.1 notation for this structure is supplied in the * and X.509. The ASN.1 notation for this structure is supplied in the
* documentation for * documentation for
* {@link #TrustAnchor(X509Certificate, byte[]) * {@link #TrustAnchor(X509Certificate, byte[])
......
/* /*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -69,7 +69,7 @@ import sun.security.x509.X509CRLImpl; ...@@ -69,7 +69,7 @@ import sun.security.x509.X509CRLImpl;
* </pre> * </pre>
* <p> * <p>
* More information can be found in * More information can be found in
* <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509 * <a href="http://tools.ietf.org/html/rfc5280">RFC 5280: Internet X.509
* Public Key Infrastructure Certificate and CRL Profile</a>. * Public Key Infrastructure Certificate and CRL Profile</a>.
* <p> * <p>
* The ASN.1 definition of {@code tbsCertList} is: * The ASN.1 definition of {@code tbsCertList} is:
......
...@@ -52,7 +52,7 @@ import sun.security.x509.X500Name; ...@@ -52,7 +52,7 @@ import sun.security.x509.X500Name;
* {@link CertStore#getCRLs CertStore.getCRLs} or some similar * {@link CertStore#getCRLs CertStore.getCRLs} or some similar
* method. * method.
* <p> * <p>
* Please refer to <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: * Please refer to <a href="http://tools.ietf.org/html/rfc5280">RFC 5280:
* Internet X.509 Public Key Infrastructure Certificate and CRL Profile</a> * Internet X.509 Public Key Infrastructure Certificate and CRL Profile</a>
* for definitions of the X.509 CRL fields and extensions mentioned below. * for definitions of the X.509 CRL fields and extensions mentioned below.
* <p> * <p>
......
/* /*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -65,7 +65,7 @@ import sun.security.x509.*; ...@@ -65,7 +65,7 @@ import sun.security.x509.*;
* number. Other unique combinations include the issuer, subject, * number. Other unique combinations include the issuer, subject,
* subjectKeyIdentifier and/or the subjectPublicKey criteria. * subjectKeyIdentifier and/or the subjectPublicKey criteria.
* <p> * <p>
* Please refer to <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: * Please refer to <a href="http://tools.ietf.org/html/rfc5280">RFC 5280:
* Internet X.509 Public Key Infrastructure Certificate and CRL Profile</a> for * Internet X.509 Public Key Infrastructure Certificate and CRL Profile</a> for
* definitions of the X.509 certificate extensions mentioned below. * definitions of the X.509 certificate extensions mentioned below.
* <p> * <p>
...@@ -728,7 +728,7 @@ public class X509CertSelector implements CertSelector { ...@@ -728,7 +728,7 @@ public class X509CertSelector implements CertSelector {
* The name is provided in string format. * The name is provided in string format.
* <a href="http://www.ietf.org/rfc/rfc822.txt">RFC 822</a>, DNS, and URI * <a href="http://www.ietf.org/rfc/rfc822.txt">RFC 822</a>, DNS, and URI
* names use the well-established string formats for those types (subject to * names use the well-established string formats for those types (subject to
* the restrictions included in RFC 3280). IPv4 address names are * the restrictions included in RFC 5280). IPv4 address names are
* supplied using dotted quad notation. OID address names are represented * supplied using dotted quad notation. OID address names are represented
* as a series of nonnegative integers separated by periods. And * as a series of nonnegative integers separated by periods. And
* directory names (distinguished names) are supplied in RFC 2253 format. * directory names (distinguished names) are supplied in RFC 2253 format.
...@@ -746,7 +746,7 @@ public class X509CertSelector implements CertSelector { ...@@ -746,7 +746,7 @@ public class X509CertSelector implements CertSelector {
* String form of some distinguished names. * String form of some distinguished names.
* *
* @param type the name type (0-8, as specified in * @param type the name type (0-8, as specified in
* RFC 3280, section 4.2.1.7) * RFC 5280, section 4.2.1.6)
* @param name the name in string form (not {@code null}) * @param name the name in string form (not {@code null})
* @throws IOException if a parsing error occurs * @throws IOException if a parsing error occurs
*/ */
...@@ -770,7 +770,7 @@ public class X509CertSelector implements CertSelector { ...@@ -770,7 +770,7 @@ public class X509CertSelector implements CertSelector {
* <p> * <p>
* The name is provided as a byte array. This byte array should contain * The name is provided as a byte array. This byte array should contain
* the DER encoded name, as it would appear in the GeneralName structure * the DER encoded name, as it would appear in the GeneralName structure
* defined in RFC 3280 and X.509. The encoded byte array should only contain * defined in RFC 5280 and X.509. The encoded byte array should only contain
* the encoded value of the name, and should not include the tag associated * the encoded value of the name, and should not include the tag associated
* with the name in the GeneralName structure. The ASN.1 definition of this * with the name in the GeneralName structure. The ASN.1 definition of this
* structure appears below. * structure appears below.
...@@ -806,7 +806,7 @@ public class X509CertSelector implements CertSelector { ...@@ -806,7 +806,7 @@ public class X509CertSelector implements CertSelector {
* must contain the specified subjectAlternativeName. * must contain the specified subjectAlternativeName.
* *
* @param type the name type (0-8, as specified in * @param type the name type (0-8, as specified in
* RFC 3280, section 4.2.1.7) * RFC 5280, section 4.2.1.6)
* @param name the name in string or byte array form * @param name the name in string or byte array form
* @throws IOException if a parsing error occurs * @throws IOException if a parsing error occurs
*/ */
...@@ -995,7 +995,7 @@ public class X509CertSelector implements CertSelector { ...@@ -995,7 +995,7 @@ public class X509CertSelector implements CertSelector {
* <p> * <p>
* The name constraints are specified as a byte array. This byte array * The name constraints are specified as a byte array. This byte array
* should contain the DER encoded form of the name constraints, as they * should contain the DER encoded form of the name constraints, as they
* would appear in the NameConstraints structure defined in RFC 3280 * would appear in the NameConstraints structure defined in RFC 5280
* and X.509. The ASN.1 definition of this structure appears below. * and X.509. The ASN.1 definition of this structure appears below.
* *
* <pre>{@code * <pre>{@code
...@@ -1197,7 +1197,7 @@ public class X509CertSelector implements CertSelector { ...@@ -1197,7 +1197,7 @@ public class X509CertSelector implements CertSelector {
* <p> * <p>
* The name is provided in string format. RFC 822, DNS, and URI names * The name is provided in string format. RFC 822, DNS, and URI names
* use the well-established string formats for those types (subject to * use the well-established string formats for those types (subject to
* the restrictions included in RFC 3280). IPv4 address names are * the restrictions included in RFC 5280). IPv4 address names are
* supplied using dotted quad notation. OID address names are represented * supplied using dotted quad notation. OID address names are represented
* as a series of nonnegative integers separated by periods. And * as a series of nonnegative integers separated by periods. And
* directory names (distinguished names) are supplied in RFC 2253 format. * directory names (distinguished names) are supplied in RFC 2253 format.
...@@ -1214,7 +1214,7 @@ public class X509CertSelector implements CertSelector { ...@@ -1214,7 +1214,7 @@ public class X509CertSelector implements CertSelector {
* String form of some distinguished names. * String form of some distinguished names.
* *
* @param type the name type (0-8, as specified in * @param type the name type (0-8, as specified in
* RFC 3280, section 4.2.1.7) * RFC 5280, section 4.2.1.6)
* @param name the name in string form * @param name the name in string form
* @throws IOException if a parsing error occurs * @throws IOException if a parsing error occurs
*/ */
...@@ -1234,7 +1234,7 @@ public class X509CertSelector implements CertSelector { ...@@ -1234,7 +1234,7 @@ public class X509CertSelector implements CertSelector {
* <p> * <p>
* The name is provided as a byte array. This byte array should contain * The name is provided as a byte array. This byte array should contain
* the DER encoded name, as it would appear in the GeneralName structure * the DER encoded name, as it would appear in the GeneralName structure
* defined in RFC 3280 and X.509. The ASN.1 definition of this structure * defined in RFC 5280 and X.509. The ASN.1 definition of this structure
* appears in the documentation for * appears in the documentation for
* {@link #addSubjectAlternativeName(int type, byte [] name) * {@link #addSubjectAlternativeName(int type, byte [] name)
* addSubjectAlternativeName(int type, byte [] name)}. * addSubjectAlternativeName(int type, byte [] name)}.
...@@ -1243,7 +1243,7 @@ public class X509CertSelector implements CertSelector { ...@@ -1243,7 +1243,7 @@ public class X509CertSelector implements CertSelector {
* subsequent modifications. * subsequent modifications.
* *
* @param type the name type (0-8, as specified in * @param type the name type (0-8, as specified in
* RFC 3280, section 4.2.1.7) * RFC 5280, section 4.2.1.6)
* @param name a byte array containing the name in ASN.1 DER encoded form * @param name a byte array containing the name in ASN.1 DER encoded form
* @throws IOException if a parsing error occurs * @throws IOException if a parsing error occurs
*/ */
...@@ -1258,7 +1258,7 @@ public class X509CertSelector implements CertSelector { ...@@ -1258,7 +1258,7 @@ public class X509CertSelector implements CertSelector {
* the specified pathToName. * the specified pathToName.
* *
* @param type the name type (0-8, as specified in * @param type the name type (0-8, as specified in
* RFC 3280, section 4.2.1.7) * RFC 5280, section 4.2.1.6)
* @param name the name in string or byte array form * @param name the name in string or byte array form
* @throws IOException if an encoding error occurs (incorrect form for DN) * @throws IOException if an encoding error occurs (incorrect form for DN)
*/ */
...@@ -1715,7 +1715,7 @@ public class X509CertSelector implements CertSelector { ...@@ -1715,7 +1715,7 @@ public class X509CertSelector implements CertSelector {
* <p> * <p>
* The name constraints are returned as a byte array. This byte array * The name constraints are returned as a byte array. This byte array
* contains the DER encoded form of the name constraints, as they * contains the DER encoded form of the name constraints, as they
* would appear in the NameConstraints structure defined in RFC 3280 * would appear in the NameConstraints structure defined in RFC 5280
* and X.509. The ASN.1 notation for this structure is supplied in the * and X.509. The ASN.1 notation for this structure is supplied in the
* documentation for * documentation for
* {@link #setNameConstraints(byte [] bytes) setNameConstraints(byte [] bytes)}. * {@link #setNameConstraints(byte [] bytes) setNameConstraints(byte [] bytes)}.
...@@ -2115,8 +2115,11 @@ public class X509CertSelector implements CertSelector { ...@@ -2115,8 +2115,11 @@ public class X509CertSelector implements CertSelector {
if (certSubjectKeyID == null || if (certSubjectKeyID == null ||
!Arrays.equals(subjectKeyID, certSubjectKeyID)) { !Arrays.equals(subjectKeyID, certSubjectKeyID)) {
if (debug != null) { if (debug != null) {
debug.println("X509CertSelector.match: " debug.println("X509CertSelector.match: subject key IDs " +
+ "subject key IDs don't match"); "don't match\nX509CertSelector.match: subjectKeyID: " +
Arrays.toString(subjectKeyID) +
"\nX509CertSelector.match: certSubjectKeyID: " +
Arrays.toString(certSubjectKeyID));
} }
return false; return false;
} }
......
/* /*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -63,7 +63,7 @@ import sun.security.x509.X509CertImpl; ...@@ -63,7 +63,7 @@ import sun.security.x509.X509CertImpl;
* CA such as a "root" CA. * CA such as a "root" CA.
* <p> * <p>
* More information can be found in * More information can be found in
* <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509 * <a href="http://tools.ietf.org/html/rfc5280">RFC 5280: Internet X.509
* Public Key Infrastructure Certificate and CRL Profile</a>. * Public Key Infrastructure Certificate and CRL Profile</a>.
* <p> * <p>
* The ASN.1 definition of {@code tbsCertificate} is: * The ASN.1 definition of {@code tbsCertificate} is:
...@@ -408,7 +408,7 @@ implements X509Extension { ...@@ -408,7 +408,7 @@ implements X509Extension {
* Gets the {@code issuerUniqueID} value from the certificate. * Gets the {@code issuerUniqueID} value from the certificate.
* The issuer unique identifier is present in the certificate * The issuer unique identifier is present in the certificate
* to handle the possibility of reuse of issuer names over time. * to handle the possibility of reuse of issuer names over time.
* RFC 3280 recommends that names not be reused and that * RFC 5280 recommends that names not be reused and that
* conforming certificates not make use of unique identifiers. * conforming certificates not make use of unique identifiers.
* Applications conforming to that profile should be capable of * Applications conforming to that profile should be capable of
* parsing unique identifiers and making comparisons. * parsing unique identifiers and making comparisons.
...@@ -459,7 +459,7 @@ implements X509Extension { ...@@ -459,7 +459,7 @@ implements X509Extension {
* encipherOnly (7), * encipherOnly (7),
* decipherOnly (8) } * decipherOnly (8) }
* </pre> * </pre>
* RFC 3280 recommends that when used, this be marked * RFC 5280 recommends that when used, this be marked
* as a critical extension. * as a critical extension.
* *
* @return the KeyUsage extension of this certificate, represented as * @return the KeyUsage extension of this certificate, represented as
...@@ -572,7 +572,7 @@ implements X509Extension { ...@@ -572,7 +572,7 @@ implements X509Extension {
* <a href="http://www.ietf.org/rfc/rfc822.txt">RFC 822</a>, DNS, and URI * <a href="http://www.ietf.org/rfc/rfc822.txt">RFC 822</a>, DNS, and URI
* names are returned as {@code String}s, * names are returned as {@code String}s,
* using the well-established string formats for those types (subject to * using the well-established string formats for those types (subject to
* the restrictions included in RFC 3280). IPv4 address names are * the restrictions included in RFC 5280). IPv4 address names are
* returned using dotted quad notation. IPv6 address names are returned * returned using dotted quad notation. IPv6 address names are returned
* in the form "a1:a2:...:a8", where a1-a8 are hexadecimal values * in the form "a1:a2:...:a8", where a1-a8 are hexadecimal values
* representing the eight 16-bit pieces of the address. OID names are * representing the eight 16-bit pieces of the address. OID names are
......
...@@ -36,14 +36,14 @@ import java.io.IOException; ...@@ -36,14 +36,14 @@ import java.io.IOException;
* For example, the following class prints out different representations of a * For example, the following class prints out different representations of a
* stock's name depending on the flags and length constraints: * stock's name depending on the flags and length constraints:
* *
* {@code * <pre> {@code
* import java.nio.CharBuffer; * import java.nio.CharBuffer;
* import java.util.Formatter; * import java.util.Formatter;
* import java.util.Formattable; * import java.util.Formattable;
* import java.util.Locale; * import java.util.Locale;
* import static java.util.FormattableFlags.*; * import static java.util.FormattableFlags.*;
* *
* ... * ...
* *
* public class StockName implements Formattable { * public class StockName implements Formattable {
* private String symbol, companyName, frenchCompanyName; * private String symbol, companyName, frenchCompanyName;
...@@ -89,12 +89,12 @@ import java.io.IOException; ...@@ -89,12 +89,12 @@ import java.io.IOException;
* return String.format("%s - %s", symbol, companyName); * return String.format("%s - %s", symbol, companyName);
* } * }
* } * }
* } * }</pre>
* *
* <p> When used in conjunction with the {@link java.util.Formatter}, the above * <p> When used in conjunction with the {@link java.util.Formatter}, the above
* class produces the following output for various format strings. * class produces the following output for various format strings.
* *
* {@code * <pre> {@code
* Formatter fmt = new Formatter(); * Formatter fmt = new Formatter();
* StockName sn = new StockName("HUGE", "Huge Fruit, Inc.", * StockName sn = new StockName("HUGE", "Huge Fruit, Inc.",
* "Fruit Titanesque, Inc."); * "Fruit Titanesque, Inc.");
...@@ -104,7 +104,7 @@ import java.io.IOException; ...@@ -104,7 +104,7 @@ import java.io.IOException;
* fmt.format("%-10.8s", sn); // -> "HUGE " * fmt.format("%-10.8s", sn); // -> "HUGE "
* fmt.format("%.12s", sn); // -> "Huge Fruit,*" * fmt.format("%.12s", sn); // -> "Huge Fruit,*"
* fmt.format(Locale.FRANCE, "%25s", sn); // -> " Fruit Titanesque, Inc." * fmt.format(Locale.FRANCE, "%25s", sn); // -> " Fruit Titanesque, Inc."
* } * }</pre>
* *
* <p> Formattables are not necessarily safe for multithreaded access. Thread * <p> Formattables are not necessarily safe for multithreaded access. Thread
* safety is optional and may be enforced by classes that extend and implement * safety is optional and may be enforced by classes that extend and implement
......
...@@ -422,7 +422,12 @@ class JarFile extends ZipFile { ...@@ -422,7 +422,12 @@ class JarFile extends ZipFile {
*/ */
private byte[] getBytes(ZipEntry ze) throws IOException { private byte[] getBytes(ZipEntry ze) throws IOException {
try (InputStream is = super.getInputStream(ze)) { try (InputStream is = super.getInputStream(ze)) {
return IOUtils.readFully(is, (int)ze.getSize(), true); int len = (int)ze.getSize();
byte[] b = IOUtils.readAllBytes(is);
if (len != -1 && b.length != len)
throw new EOFException("Expected:" + len + ", read:" + b.length);
return b;
} }
} }
......
...@@ -33,6 +33,22 @@ class JavaxSecurityAuthKerberosAccessImpl ...@@ -33,6 +33,22 @@ class JavaxSecurityAuthKerberosAccessImpl
KeyTab ktab) { KeyTab ktab) {
return ktab.takeSnapshot(); return ktab.takeSnapshot();
} }
public KerberosPrincipal kerberosTicketGetClientAlias(KerberosTicket t) {
return t.clientAlias;
}
public void kerberosTicketSetClientAlias(KerberosTicket t, KerberosPrincipal a) {
t.clientAlias = a;
}
public KerberosPrincipal kerberosTicketGetServerAlias(KerberosTicket t) {
return t.serverAlias;
}
public void kerberosTicketSetServerAlias(KerberosTicket t, KerberosPrincipal a) {
t.serverAlias = a;
}
public KerberosTicket kerberosTicketGetProxy(KerberosTicket t) { public KerberosTicket kerberosTicketGetProxy(KerberosTicket t) {
return t.proxy; return t.proxy;
} }
......
/* /*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -80,6 +80,11 @@ public final class KerberosPrincipal ...@@ -80,6 +80,11 @@ public final class KerberosPrincipal
public static final int KRB_NT_UID = 5; public static final int KRB_NT_UID = 5;
/**
* Enterprise name (alias)
*/
static final int KRB_NT_ENTERPRISE = 10;
private transient String fullName; private transient String fullName;
private transient String realm; private transient String realm;
......
...@@ -194,6 +194,10 @@ public class KerberosTicket implements Destroyable, Refreshable, ...@@ -194,6 +194,10 @@ public class KerberosTicket implements Destroyable, Refreshable,
private InetAddress[] clientAddresses; private InetAddress[] clientAddresses;
transient KerberosPrincipal clientAlias = null;
transient KerberosPrincipal serverAlias = null;
/** /**
* Evidence ticket if proxy_impersonator. This field can be accessed * Evidence ticket if proxy_impersonator. This field can be accessed
* by KerberosSecrets. It's serialized. * by KerberosSecrets. It's serialized.
...@@ -308,11 +312,7 @@ public class KerberosTicket implements Destroyable, Refreshable, ...@@ -308,11 +312,7 @@ public class KerberosTicket implements Destroyable, Refreshable,
} else } else
this.flags = new boolean[NUM_FLAGS]; this.flags = new boolean[NUM_FLAGS];
if (this.flags[RENEWABLE_TICKET_FLAG]) { if (this.flags[RENEWABLE_TICKET_FLAG] && renewTill != null) {
if (renewTill == null)
throw new IllegalArgumentException("The renewable period "
+ "end time cannot be null for renewable tickets.");
this.renewTill = new Date(renewTill.getTime()); this.renewTill = new Date(renewTill.getTime());
} }
...@@ -553,6 +553,11 @@ public class KerberosTicket implements Destroyable, Refreshable, ...@@ -553,6 +553,11 @@ public class KerberosTicket implements Destroyable, Refreshable,
if (!isRenewable()) if (!isRenewable())
throw new RefreshFailedException("This ticket is not renewable"); throw new RefreshFailedException("This ticket is not renewable");
if (getRenewTill() == null) {
// Renewable ticket without renew-till. Illegal and ignored.
return;
}
if (System.currentTimeMillis() > getRenewTill().getTime()) if (System.currentTimeMillis() > getRenewTill().getTime())
throw new RefreshFailedException("This ticket is past " throw new RefreshFailedException("This ticket is past "
+ "its last renewal time."); + "its last renewal time.");
...@@ -562,7 +567,11 @@ public class KerberosTicket implements Destroyable, Refreshable, ...@@ -562,7 +567,11 @@ public class KerberosTicket implements Destroyable, Refreshable,
try { try {
krb5Creds = new sun.security.krb5.Credentials(asn1Encoding, krb5Creds = new sun.security.krb5.Credentials(asn1Encoding,
client.toString(), client.toString(),
(clientAlias != null ?
clientAlias.getName() : null),
server.toString(), server.toString(),
(serverAlias != null ?
serverAlias.getName() : null),
sessionKey.getEncoded(), sessionKey.getEncoded(),
sessionKey.getKeyType(), sessionKey.getKeyType(),
flags, flags,
......
/* /*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -41,13 +41,13 @@ import sun.security.util.*; ...@@ -41,13 +41,13 @@ import sun.security.util.*;
* of the distinguished name, or by using the ASN.1 DER encoded byte * of the distinguished name, or by using the ASN.1 DER encoded byte
* representation of the distinguished name. The current specification * representation of the distinguished name. The current specification
* for the string representation of a distinguished name is defined in * for the string representation of a distinguished name is defined in
* <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253: Lightweight * <a href="http://tools.ietf.org/html/rfc2253">RFC 2253: Lightweight
* Directory Access Protocol (v3): UTF-8 String Representation of * Directory Access Protocol (v3): UTF-8 String Representation of
* Distinguished Names</a>. This class, however, accepts string formats from * Distinguished Names</a>. This class, however, accepts string formats from
* both RFC 2253 and <a href="http://www.ietf.org/rfc/rfc1779.txt">RFC 1779: * both RFC 2253 and <a href="http://tools.ietf.org/html/rfc1779">RFC 1779:
* A String Representation of Distinguished Names</a>, and also recognizes * A String Representation of Distinguished Names</a>, and also recognizes
* attribute type keywords whose OIDs (Object Identifiers) are defined in * attribute type keywords whose OIDs (Object Identifiers) are defined in
* <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509 * <a href="http://tools.ietf.org/html/rfc5280">RFC 5280: Internet X.509
* Public Key Infrastructure Certificate and CRL Profile</a>. * Public Key Infrastructure Certificate and CRL Profile</a>.
* *
* <p> The string representation for this {@code X500Principal} * <p> The string representation for this {@code X500Principal}
...@@ -108,7 +108,7 @@ public final class X500Principal implements Principal, java.io.Serializable { ...@@ -108,7 +108,7 @@ public final class X500Principal implements Principal, java.io.Serializable {
* (and listed in {@link #getName(String format) getName(String format)}), * (and listed in {@link #getName(String format) getName(String format)}),
* as well as the T, DNQ or DNQUALIFIER, SURNAME, GIVENNAME, INITIALS, * as well as the T, DNQ or DNQUALIFIER, SURNAME, GIVENNAME, INITIALS,
* GENERATION, EMAILADDRESS, and SERIALNUMBER keywords whose Object * GENERATION, EMAILADDRESS, and SERIALNUMBER keywords whose Object
* Identifiers (OIDs) are defined in RFC 3280 and its successor. * Identifiers (OIDs) are defined in RFC 5280.
* Any other attribute type must be specified as an OID. * Any other attribute type must be specified as an OID.
* *
* <p>This implementation enforces a more restrictive OID syntax than * <p>This implementation enforces a more restrictive OID syntax than
...@@ -456,7 +456,7 @@ public final class X500Principal implements Principal, java.io.Serializable { ...@@ -456,7 +456,7 @@ public final class X500Principal implements Principal, java.io.Serializable {
* (obtained via the {@code getName(X500Principal.CANONICAL)} method) * (obtained via the {@code getName(X500Principal.CANONICAL)} method)
* of this object and <i>o</i> are equal. * of this object and <i>o</i> are equal.
* *
* <p> This implementation is compliant with the requirements of RFC 3280. * <p> This implementation is compliant with the requirements of RFC 5280.
* *
* @param o Object to be compared for equality with this * @param o Object to be compared for equality with this
* {@code X500Principal} * {@code X500Principal}
......
/* /*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -31,15 +31,15 @@ ...@@ -31,15 +31,15 @@
* <h2>Package Specification</h2> * <h2>Package Specification</h2>
* *
* <ul> * <ul>
* <li><a href="http://www.ietf.org/rfc/rfc1779.txt"> * <li><a href="http://tools.ietf.org/html/rfc1779">
* RFC 1779: A String Representation of Distinguished Names</a></li> * RFC 1779: A String Representation of Distinguished Names</a></li>
* <li><a href="http://www.ietf.org/rfc/rfc2253.txt"> * <li><a href="http://tools.ietf.org/html/rfc2253">
* RFC 2253: Lightweight Directory Access Protocol (v3): * RFC 2253: Lightweight Directory Access Protocol (v3):
* UTF-8 String Representation of Distinguished Names</a></li> * UTF-8 String Representation of Distinguished Names</a></li>
* <li><a href="http://www.ietf.org/rfc/rfc3280.txt"> * <li><a href="http://tools.ietf.org/html/rfc5280">
* RFC 3280: Internet X.509 Public Key Infrastructure * RFC 5280: Internet X.509 Public Key Infrastructure
* Certificate and Certificate Revocation List (CRL) Profile</a></li> * Certificate and Certificate Revocation List (CRL) Profile</a></li>
* <li><a href="http://www.ietf.org/rfc/rfc4512.txt"> * <li><a href="http://tools.ietf.org/html/rfc4512">
* RFC 4512: Lightweight Directory Access Protocol (LDAP): * RFC 4512: Lightweight Directory Access Protocol (LDAP):
* Directory Information Models</a></li> * Directory Information Models</a></li>
* </ul> * </ul>
......
/* /*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -28,6 +28,8 @@ package javax.swing; ...@@ -28,6 +28,8 @@ package javax.swing;
import java.awt.event.*; import java.awt.event.*;
import java.awt.*; import java.awt.*;
import javax.swing.event.MenuKeyEvent;
import javax.swing.event.MenuKeyListener;
/** /**
* Manages all the <code>ToolTips</code> in the system. * Manages all the <code>ToolTips</code> in the system.
...@@ -409,8 +411,14 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener ...@@ -409,8 +411,14 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener
component.addMouseListener(this); component.addMouseListener(this);
component.removeMouseMotionListener(moveBeforeEnterListener); component.removeMouseMotionListener(moveBeforeEnterListener);
component.addMouseMotionListener(moveBeforeEnterListener); component.addMouseMotionListener(moveBeforeEnterListener);
component.removeKeyListener(accessibilityKeyListener); // use MenuKeyListener for menu items/elements
component.addKeyListener(accessibilityKeyListener); if (component instanceof JMenuItem) {
((JMenuItem) component).removeMenuKeyListener((MenuKeyListener) accessibilityKeyListener);
((JMenuItem) component).addMenuKeyListener((MenuKeyListener) accessibilityKeyListener);
} else {
component.removeKeyListener(accessibilityKeyListener);
component.addKeyListener(accessibilityKeyListener);
}
} }
/** /**
...@@ -421,7 +429,11 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener ...@@ -421,7 +429,11 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener
public void unregisterComponent(JComponent component) { public void unregisterComponent(JComponent component) {
component.removeMouseListener(this); component.removeMouseListener(this);
component.removeMouseMotionListener(moveBeforeEnterListener); component.removeMouseMotionListener(moveBeforeEnterListener);
component.removeKeyListener(accessibilityKeyListener); if (component instanceof JMenuItem) {
((JMenuItem) component).removeMenuKeyListener((MenuKeyListener) accessibilityKeyListener);
} else {
component.removeKeyListener(accessibilityKeyListener);
}
} }
// implements java.awt.event.MouseListener // implements java.awt.event.MouseListener
...@@ -841,7 +853,7 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener ...@@ -841,7 +853,7 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener
* Post Tip: Ctrl+F1 * Post Tip: Ctrl+F1
* Unpost Tip: Esc and Ctrl+F1 * Unpost Tip: Esc and Ctrl+F1
*/ */
private class AccessibilityKeyListener extends KeyAdapter { private class AccessibilityKeyListener extends KeyAdapter implements MenuKeyListener {
public void keyPressed(KeyEvent e) { public void keyPressed(KeyEvent e) {
if (!e.isConsumed()) { if (!e.isConsumed()) {
JComponent source = (JComponent) e.getComponent(); JComponent source = (JComponent) e.getComponent();
...@@ -858,5 +870,32 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener ...@@ -858,5 +870,32 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener
} }
} }
} }
@Override
public void menuKeyTyped(MenuKeyEvent e) {}
@Override
public void menuKeyPressed(MenuKeyEvent e) {
if (postTip.equals(KeyStroke.getKeyStrokeForEvent(e))) {
// get element for the event
MenuElement path[] = e.getPath();
MenuElement element = path[path.length - 1];
// retrieve currently highlighted element
MenuSelectionManager msm = e.getMenuSelectionManager();
MenuElement selectedPath[] = msm.getSelectedPath();
MenuElement selectedElement = selectedPath[selectedPath.length - 1];
if (element.equals(selectedElement)) {
// show/hide tooltip message
JComponent source = (JComponent) element.getComponent();
ToolTipManager.this.show(source);
e.consume();
}
}
}
@Override
public void menuKeyReleased(MenuKeyEvent e) {}
} }
} }
/*
* Copyright (c) 2018, 2019, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.internal.util;
/**
* System Property access for internal use only.
* Read-only access to System property values initialized during Phase 1
* are cached. Setting, clearing, or modifying the value using
* {@link System#setProperty) or {@link System#getProperties()} is ignored.
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
* in these access methods. The caller of these methods should take care to ensure
* that the returned property is not made accessible to untrusted code.</strong>
*/
public final class StaticProperty {
// The class static initialization is triggered to initialize these final
// fields during init Phase 1 and before a security manager is set.
private static final String JDK_SERIAL_FILTER = System.getProperty("jdk.serialFilter");
private StaticProperty() {}
/**
*
* Return the {@code jdk.serialFilter} system property.
*
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
* in this method. The caller of this method should take care to ensure
* that the returned property is not made accessible to untrusted code.</strong>
*
* @return the {@code user.name} system property
*/
public static String jdkSerialFilter() {
return JDK_SERIAL_FILTER;
}
}
...@@ -33,6 +33,7 @@ import java.net.URLConnection; ...@@ -33,6 +33,7 @@ import java.net.URLConnection;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.io.EOFException;
import java.io.File; import java.io.File;
import java.io.FilePermission; import java.io.FilePermission;
import java.io.IOException; import java.io.IOException;
...@@ -333,7 +334,9 @@ public class AppletClassLoader extends URLClassLoader { ...@@ -333,7 +334,9 @@ public class AppletClassLoader extends URLClassLoader {
byte[] b; byte[] b;
try { try {
b = IOUtils.readFully(in, len, true); b = IOUtils.readAllBytes(in);
if (len != -1 && b.length != len)
throw new EOFException("Expected:" + len + ", read:" + b.length);
} finally { } finally {
in.close(); in.close();
} }
......
...@@ -27,6 +27,7 @@ package sun.java2d.opengl; ...@@ -27,6 +27,7 @@ package sun.java2d.opengl;
import java.awt.AlphaComposite; import java.awt.AlphaComposite;
import java.awt.Composite; import java.awt.Composite;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment; import java.awt.GraphicsEnvironment;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.Transparency; import java.awt.Transparency;
...@@ -598,16 +599,16 @@ public abstract class OGLSurfaceData extends SurfaceData ...@@ -598,16 +599,16 @@ public abstract class OGLSurfaceData extends SurfaceData
* (referenced by the pData parameter). This method is invoked from * (referenced by the pData parameter). This method is invoked from
* the native Dispose() method from the Disposer thread when the * the native Dispose() method from the Disposer thread when the
* Java-level OGLSurfaceData object is about to go away. Note that we * Java-level OGLSurfaceData object is about to go away. Note that we
* also pass a reference to the native GLX/WGLGraphicsConfigInfo * also pass a reference to the OGLGraphicsConfig
* (pConfigInfo) for the purposes of making a context current. * for the purposes of making a context current.
*/ */
static void dispose(long pData, long pConfigInfo) { static void dispose(long pData, OGLGraphicsConfig gc) {
OGLRenderQueue rq = OGLRenderQueue.getInstance(); OGLRenderQueue rq = OGLRenderQueue.getInstance();
rq.lock(); rq.lock();
try { try {
// make sure we have a current context before // make sure we have a current context before
// disposing the native resources (e.g. texture object) // disposing the native resources (e.g. texture object)
OGLContext.setScratchSurface(pConfigInfo); OGLContext.setScratchSurface(gc);
RenderBuffer buf = rq.getBuffer(); RenderBuffer buf = rq.getBuffer();
rq.ensureCapacityAndAlignment(12, 4); rq.ensureCapacityAndAlignment(12, 4);
......
/* /*
* Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -32,67 +32,282 @@ package sun.misc; ...@@ -32,67 +32,282 @@ package sun.misc;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import java.util.Objects;
public class IOUtils { public class IOUtils {
private static final int DEFAULT_BUFFER_SIZE = 8192;
/** /**
* Read up to {@code length} of bytes from {@code in} * The maximum size of array to allocate.
* until EOF is detected. * Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
*/
private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
/**
* Read exactly {@code length} of bytes from {@code in}.
*
* <p> Note that this method is safe to be called with unknown large
* {@code length} argument. The memory used is proportional to the
* actual bytes available. An exception is thrown if there are not
* enough bytes in the stream.
*
* @param is input stream, must not be null * @param is input stream, must not be null
* @param length number of bytes to read, -1 or Integer.MAX_VALUE means * @param length number of bytes to read
* read as much as possible
* @param readAll if true, an EOFException will be thrown if not enough
* bytes are read. Ignored when length is -1 or Integer.MAX_VALUE
* @return bytes read * @return bytes read
* @throws IOException Any IO error or a premature EOF is detected * @throws EOFException if there are not enough bytes in the stream
* @throws IOException if an I/O error occurs or {@code length} is negative
* @throws OutOfMemoryError if an array of the required size cannot be
* allocated.
*/ */
public static byte[] readFully(InputStream is, int length, boolean readAll) public static byte[] readExactlyNBytes(InputStream is, int length)
throws IOException { throws IOException {
byte[] output = {}; if (length < 0) {
if (length == -1) length = Integer.MAX_VALUE; throw new IOException("length cannot be negative: " + length);
int pos = 0; }
while (pos < length) { byte[] data = readNBytes(is, length);
int bytesToRead; if (data.length < length) {
if (pos >= output.length) { // Only expand when there's no room throw new EOFException();
bytesToRead = Math.min(length - pos, output.length + 1024); }
if (output.length < pos + bytesToRead) { return data;
output = Arrays.copyOf(output, pos + bytesToRead); }
}
} else { /**
bytesToRead = output.length - pos; * Reads all remaining bytes from the input stream. This method blocks until
* all remaining bytes have been read and end of stream is detected, or an
* exception is thrown. This method does not close the input stream.
*
* <p> When this stream reaches end of stream, further invocations of this
* method will return an empty byte array.
*
* <p> Note that this method is intended for simple cases where it is
* convenient to read all bytes into a byte array. It is not intended for
* reading input streams with large amounts of data.
*
* <p> The behavior for the case where the input stream is <i>asynchronously
* closed</i>, or the thread interrupted during the read, is highly input
* stream specific, and therefore not specified.
*
* <p> If an I/O error occurs reading from the input stream, then it may do
* so after some, but not all, bytes have been read. Consequently the input
* stream may not be at end of stream and may be in an inconsistent state.
* It is strongly recommended that the stream be promptly closed if an I/O
* error occurs.
*
* @implSpec
* This method invokes {@link #readNBytes(int)} with a length of
* {@link Integer#MAX_VALUE}.
*
* @param is input stream, must not be null
* @return a byte array containing the bytes read from this input stream
* @throws IOException if an I/O error occurs
* @throws OutOfMemoryError if an array of the required size cannot be
* allocated.
*
* @since 1.9
*/
public static byte[] readAllBytes(InputStream is) throws IOException {
return readNBytes(is, Integer.MAX_VALUE);
}
/**
* Reads up to a specified number of bytes from the input stream. This
* method blocks until the requested number of bytes have been read, end
* of stream is detected, or an exception is thrown. This method does not
* close the input stream.
*
* <p> The length of the returned array equals the number of bytes read
* from the stream. If {@code len} is zero, then no bytes are read and
* an empty byte array is returned. Otherwise, up to {@code len} bytes
* are read from the stream. Fewer than {@code len} bytes may be read if
* end of stream is encountered.
*
* <p> When this stream reaches end of stream, further invocations of this
* method will return an empty byte array.
*
* <p> Note that this method is intended for simple cases where it is
* convenient to read the specified number of bytes into a byte array. The
* total amount of memory allocated by this method is proportional to the
* number of bytes read from the stream which is bounded by {@code len}.
* Therefore, the method may be safely called with very large values of
* {@code len} provided sufficient memory is available.
*
* <p> The behavior for the case where the input stream is <i>asynchronously
* closed</i>, or the thread interrupted during the read, is highly input
* stream specific, and therefore not specified.
*
* <p> If an I/O error occurs reading from the input stream, then it may do
* so after some, but not all, bytes have been read. Consequently the input
* stream may not be at end of stream and may be in an inconsistent state.
* It is strongly recommended that the stream be promptly closed if an I/O
* error occurs.
*
* @implNote
* The number of bytes allocated to read data from this stream and return
* the result is bounded by {@code 2*(long)len}, inclusive.
*
* @param is input stream, must not be null
* @param len the maximum number of bytes to read
* @return a byte array containing the bytes read from this input stream
* @throws IllegalArgumentException if {@code length} is negative
* @throws IOException if an I/O error occurs
* @throws OutOfMemoryError if an array of the required size cannot be
* allocated.
*
* @since 11
*/
public static byte[] readNBytes(InputStream is, int len) throws IOException {
if (len < 0) {
throw new IllegalArgumentException("len < 0");
}
List<byte[]> bufs = null;
byte[] result = null;
int total = 0;
int remaining = len;
int n;
do {
byte[] buf = new byte[Math.min(remaining, DEFAULT_BUFFER_SIZE)];
int nread = 0;
// read to EOF which may read more or less than buffer size
while ((n = is.read(buf, nread,
Math.min(buf.length - nread, remaining))) > 0) {
nread += n;
remaining -= n;
} }
int cc = is.read(output, pos, bytesToRead);
if (cc < 0) { if (nread > 0) {
if (readAll && length != Integer.MAX_VALUE) { if (MAX_BUFFER_SIZE - total < nread) {
throw new EOFException("Detect premature EOF"); throw new OutOfMemoryError("Required array size too large");
}
total += nread;
if (result == null) {
result = buf;
} else { } else {
if (output.length != pos) { if (bufs == null) {
output = Arrays.copyOf(output, pos); bufs = new ArrayList<>();
bufs.add(result);
} }
break; bufs.add(buf);
} }
} }
pos += cc; // if the last call to read returned -1 or the number of bytes
// requested have been read then break
} while (n >= 0 && remaining > 0);
if (bufs == null) {
if (result == null) {
return new byte[0];
}
return result.length == total ?
result : Arrays.copyOf(result, total);
}
result = new byte[total];
int offset = 0;
remaining = total;
for (byte[] b : bufs) {
int count = Math.min(b.length, remaining);
System.arraycopy(b, 0, result, offset, count);
offset += count;
remaining -= count;
}
return result;
}
/**
* Reads the requested number of bytes from the input stream into the given
* byte array. This method blocks until {@code len} bytes of input data have
* been read, end of stream is detected, or an exception is thrown. The
* number of bytes actually read, possibly zero, is returned. This method
* does not close the input stream.
*
* <p> In the case where end of stream is reached before {@code len} bytes
* have been read, then the actual number of bytes read will be returned.
* When this stream reaches end of stream, further invocations of this
* method will return zero.
*
* <p> If {@code len} is zero, then no bytes are read and {@code 0} is
* returned; otherwise, there is an attempt to read up to {@code len} bytes.
*
* <p> The first byte read is stored into element {@code b[off]}, the next
* one in to {@code b[off+1]}, and so on. The number of bytes read is, at
* most, equal to {@code len}. Let <i>k</i> be the number of bytes actually
* read; these bytes will be stored in elements {@code b[off]} through
* {@code b[off+}<i>k</i>{@code -1]}, leaving elements {@code b[off+}<i>k</i>
* {@code ]} through {@code b[off+len-1]} unaffected.
*
* <p> The behavior for the case where the input stream is <i>asynchronously
* closed</i>, or the thread interrupted during the read, is highly input
* stream specific, and therefore not specified.
*
* <p> If an I/O error occurs reading from the input stream, then it may do
* so after some, but not all, bytes of {@code b} have been updated with
* data from the input stream. Consequently the input stream and {@code b}
* may be in an inconsistent state. It is strongly recommended that the
* stream be promptly closed if an I/O error occurs.
*
* @param is input stream, must not be null
* @param b the byte array into which the data is read
* @param off the start offset in {@code b} at which the data is written
* @param len the maximum number of bytes to read
* @return the actual number of bytes read into the buffer
* @throws IOException if an I/O error occurs
* @throws NullPointerException if {@code b} is {@code null}
* @throws IndexOutOfBoundsException If {@code off} is negative, {@code len}
* is negative, or {@code len} is greater than {@code b.length - off}
*
* @since 1.9
*/
public static int readNBytes(InputStream is, byte[] b, int off, int len) throws IOException {
Objects.requireNonNull(b);
if (off < 0 || len < 0 || len > b.length - off)
throw new IndexOutOfBoundsException();
int n = 0;
while (n < len) {
int count = is.read(b, off + n, len - n);
if (count < 0)
break;
n += count;
} }
return output; return n;
} }
/** /**
* Read {@code length} of bytes from {@code in}. An exception is * Compatibility wrapper for third party users of
* thrown if there are not enough bytes in the stream. * {@code sun.misc.IOUtils.readFully} following its
* removal in JDK-8231139.
*
* Read up to {@code length} of bytes from {@code in}
* until EOF is detected.
* *
* @param is input stream, must not be null * @param is input stream, must not be null
* @param length number of bytes to read, must not be negative * @param length number of bytes to read
* @param readAll if true, an EOFException will be thrown if not enough
* bytes are read.
* @return bytes read * @return bytes read
* @throws IOException if any IO error or a premature EOF is detected, or * @throws EOFException if there are not enough bytes in the stream
* if {@code length} is negative since this length is usually also * @throws IOException if an I/O error occurs or {@code length} is negative
* read from {@code is}. * @throws OutOfMemoryError if an array of the required size cannot be
* allocated.
*/ */
public static byte[] readNBytes(InputStream is, int length) throws IOException { public static byte[] readFully(InputStream is, int length, boolean readAll)
throws IOException {
if (length < 0) { if (length < 0) {
throw new IOException("length cannot be negative: " + length); throw new IOException("length cannot be negative: " + length);
} }
return readFully(is, length, true); if (readAll) {
return readExactlyNBytes(is, length);
} else {
return readNBytes(is, length);
}
} }
} }
/*
* Copyright (c) 2019, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.misc;
import java.io.IOException;
import java.io.ObjectInputStream;
/**
* Interface to specify methods for accessing {@code ObjectInputStream}.
*/
@FunctionalInterface
public interface JavaObjectInputStreamReadString {
String readString(ObjectInputStream ois) throws IOException;
}
...@@ -37,6 +37,8 @@ import java.util.Optional; ...@@ -37,6 +37,8 @@ import java.util.Optional;
import java.util.function.Function; import java.util.function.Function;
import sun.util.logging.PlatformLogger; import sun.util.logging.PlatformLogger;
import jdk.internal.util.StaticProperty;
/** /**
* Filter classes, array lengths, and graph metrics during deserialization. * Filter classes, array lengths, and graph metrics during deserialization.
* If set on an {@link ObjectInputStream}, the {@link #checkInput checkInput(FilterInfo)} * If set on an {@link ObjectInputStream}, the {@link #checkInput checkInput(FilterInfo)}
...@@ -247,7 +249,7 @@ public interface ObjectInputFilter { ...@@ -247,7 +249,7 @@ public interface ObjectInputFilter {
static { static {
configuredFilter = AccessController configuredFilter = AccessController
.doPrivileged((PrivilegedAction<ObjectInputFilter>) () -> { .doPrivileged((PrivilegedAction<ObjectInputFilter>) () -> {
String props = System.getProperty(SERIAL_FILTER_PROPNAME); String props = StaticProperty.jdkSerialFilter();
if (props == null) { if (props == null) {
props = Security.getProperty(SERIAL_FILTER_PROPNAME); props = Security.getProperty(SERIAL_FILTER_PROPNAME);
} }
......
...@@ -59,6 +59,7 @@ public class SharedSecrets { ...@@ -59,6 +59,7 @@ public class SharedSecrets {
private static JavaAWTAccess javaAWTAccess; private static JavaAWTAccess javaAWTAccess;
private static JavaOISAccess javaOISAccess; private static JavaOISAccess javaOISAccess;
private static JavaxCryptoSealedObjectAccess javaxCryptoSealedObjectAccess; private static JavaxCryptoSealedObjectAccess javaxCryptoSealedObjectAccess;
private static JavaObjectInputStreamReadString javaObjectInputStreamReadString;
private static JavaObjectInputStreamAccess javaObjectInputStreamAccess; private static JavaObjectInputStreamAccess javaObjectInputStreamAccess;
public static JavaUtilJarAccess javaUtilJarAccess() { public static JavaUtilJarAccess javaUtilJarAccess() {
...@@ -202,8 +203,18 @@ public class SharedSecrets { ...@@ -202,8 +203,18 @@ public class SharedSecrets {
return javaAWTAccess; return javaAWTAccess;
} }
public static JavaObjectInputStreamReadString getJavaObjectInputStreamReadString() {
if (javaObjectInputStreamReadString == null) {
unsafe.ensureClassInitialized(ObjectInputStream.class);
}
return javaObjectInputStreamReadString;
}
public static void setJavaObjectInputStreamReadString(JavaObjectInputStreamReadString access) {
javaObjectInputStreamReadString = access;
}
public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() { public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() {
if (javaObjectInputStreamAccess == null) { if (javaObjectInputStreamAccess == null) {
unsafe.ensureClassInitialized(ObjectInputStream.class); unsafe.ensureClassInitialized(ObjectInputStream.class);
} }
......
/* /*
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -1229,10 +1229,15 @@ public class URLClassPath { ...@@ -1229,10 +1229,15 @@ public class URLClassPath {
int i = 0; int i = 0;
while (st.hasMoreTokens()) { while (st.hasMoreTokens()) {
String path = st.nextToken(); String path = st.nextToken();
URL url = DISABLE_CP_URL_CHECK ? new URL(base, path) : safeResolve(base, path); URL url = DISABLE_CP_URL_CHECK ? new URL(base, path) : tryResolve(base, path);
if (url != null) { if (url != null) {
urls[i] = url; urls[i] = url;
i++; i++;
} else {
if (DEBUG_CP_URL_CHECK) {
System.err.println("Class-Path entry: \"" + path
+ "\" ignored in JAR file " + base);
}
} }
} }
if (i == 0) { if (i == 0) {
...@@ -1244,36 +1249,74 @@ public class URLClassPath { ...@@ -1244,36 +1249,74 @@ public class URLClassPath {
return urls; return urls;
} }
/* static URL tryResolve(URL base, String input) throws MalformedURLException {
* Return a URL for the given path resolved against the base URL, or if ("file".equalsIgnoreCase(base.getProtocol())) {
* null if the resulting URL is invalid. return tryResolveFile(base, input);
} else {
return tryResolveNonFile(base, input);
}
}
/**
* Attempt to return a file URL by resolving input against a base file
* URL. The input is an absolute or relative file URL that encodes a
* file path.
*
* @apiNote Nonsensical input such as a Windows file path with a drive
* letter cannot be disambiguated from an absolute URL so will be rejected
* (by returning null) by this method.
*
* @return the resolved URL or null if the input is an absolute URL with
* a scheme other than file (ignoring case)
* @throws MalformedURLException
*/ */
static URL safeResolve(URL base, String path) { static URL tryResolveFile(URL base, String input) throws MalformedURLException {
String child = path.replace(File.separatorChar, '/'); int index = input.indexOf(':');
try { boolean isFile;
if (!URI.create(child).isAbsolute()) { if (index >= 0) {
URL url = new URL(base, child); String scheme = input.substring(0, index);
if (base.getProtocol().equalsIgnoreCase("file")) { isFile = "file".equalsIgnoreCase(scheme);
return url; } else {
} else { isFile = true;
String bp = base.getPath(); }
String urlp = url.getPath(); return (isFile) ? new URL(base, input) : null;
int pos = bp.lastIndexOf('/'); }
if (pos == -1) {
pos = bp.length() - 1; /**
} * Attempt to return a URL by resolving input against a base URL. Returns
if (urlp.regionMatches(0, bp, 0, pos + 1) * null if the resolved URL is not contained by the base URL.
&& urlp.indexOf("..", pos) == -1) { *
return url; * @return the resolved URL or null
} * @throws MalformedURLException
} */
static URL tryResolveNonFile(URL base, String input) throws MalformedURLException {
String child = input.replace(File.separatorChar, '/');
if (isRelative(child)) {
URL url = new URL(base, child);
String bp = base.getPath();
String urlp = url.getPath();
int pos = bp.lastIndexOf('/');
if (pos == -1) {
pos = bp.length() - 1;
}
if (urlp.regionMatches(0, bp, 0, pos + 1)
&& urlp.indexOf("..", pos) == -1) {
return url;
} }
} catch (MalformedURLException | IllegalArgumentException e) {}
if (DEBUG_CP_URL_CHECK) {
System.err.println("Class-Path entry: \"" + path + "\" ignored in JAR file " + base);
} }
return null; return null;
} }
/**
* Returns true if the given input is a relative URI.
*/
static boolean isRelative(String child) {
try {
return !URI.create(child).isAbsolute();
} catch (IllegalArgumentException e) {
return false;
}
}
} }
/* /*
......
...@@ -288,14 +288,44 @@ class MessageHeader { ...@@ -288,14 +288,44 @@ class MessageHeader {
return Collections.unmodifiableMap(m); return Collections.unmodifiableMap(m);
} }
/** Check if a line of message header looks like a request line.
* This method does not perform a full validation but simply
* returns false if the line does not end with 'HTTP/[1-9].[0-9]'
* @param line the line to check.
* @return true if the line might be a request line.
*/
private boolean isRequestline(String line) {
String k = line.trim();
int i = k.lastIndexOf(' ');
if (i <= 0) return false;
int len = k.length();
if (len - i < 9) return false;
char c1 = k.charAt(len-3);
char c2 = k.charAt(len-2);
char c3 = k.charAt(len-1);
if (c1 < '1' || c1 > '9') return false;
if (c2 != '.') return false;
if (c3 < '0' || c3 > '9') return false;
return (k.substring(i+1, len-3).equalsIgnoreCase("HTTP/"));
}
/** Prints the key-value pairs represented by this /** Prints the key-value pairs represented by this
header. Also prints the RFC required blank line header. Also prints the RFC required blank line
at the end. Omits pairs with a null key. */ at the end. Omits pairs with a null key. Omits
colon if key-value pair is the requestline. */
public synchronized void print(PrintStream p) { public synchronized void print(PrintStream p) {
for (int i = 0; i < nkeys; i++) for (int i = 0; i < nkeys; i++)
if (keys[i] != null) { if (keys[i] != null) {
p.print(keys[i] + StringBuilder sb = new StringBuilder(keys[i]);
(values[i] != null ? ": "+values[i]: "") + "\r\n"); if (values[i] != null) {
sb.append(": " + values[i]);
} else if (i != 0 || !isRequestline(keys[i])) {
sb.append(":");
}
p.print(sb.append("\r\n"));
} }
p.print("\r\n"); p.print("\r\n");
p.flush(); p.flush();
......
...@@ -49,9 +49,6 @@ class DatagramChannelImpl ...@@ -49,9 +49,6 @@ class DatagramChannelImpl
// Our file descriptor // Our file descriptor
private final FileDescriptor fd; private final FileDescriptor fd;
// fd value needed for dev/poll. This value will remain valid
// even after the value in the file descriptor object has been set to -1
private final int fdVal; private final int fdVal;
// The protocol family of the socket // The protocol family of the socket
...@@ -103,7 +100,6 @@ class DatagramChannelImpl ...@@ -103,7 +100,6 @@ class DatagramChannelImpl
// -- End of fields protected by stateLock // -- End of fields protected by stateLock
public DatagramChannelImpl(SelectorProvider sp) public DatagramChannelImpl(SelectorProvider sp)
throws IOException throws IOException
{ {
...@@ -138,16 +134,27 @@ class DatagramChannelImpl ...@@ -138,16 +134,27 @@ class DatagramChannelImpl
throw new UnsupportedOperationException("IPv6 not available"); throw new UnsupportedOperationException("IPv6 not available");
} }
} }
this.family = family;
this.fd = Net.socket(family, false); ResourceManager.beforeUdpCreate();
this.fdVal = IOUtil.fdVal(fd); try {
this.state = ST_UNCONNECTED; this.family = family;
this.fd = Net.socket(family, false);
this.fdVal = IOUtil.fdVal(fd);
this.state = ST_UNCONNECTED;
} catch (IOException ioe) {
ResourceManager.afterUdpClose();
throw ioe;
}
} }
public DatagramChannelImpl(SelectorProvider sp, FileDescriptor fd) public DatagramChannelImpl(SelectorProvider sp, FileDescriptor fd)
throws IOException throws IOException
{ {
super(sp); super(sp);
// increment UDP count to match decrement when closing
ResourceManager.beforeUdpCreate();
this.family = Net.isIPv6Available() ? this.family = Net.isIPv6Available() ?
StandardProtocolFamily.INET6 : StandardProtocolFamily.INET; StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
this.fd = fd; this.fd = fd;
...@@ -742,10 +749,9 @@ class DatagramChannelImpl ...@@ -742,10 +749,9 @@ class DatagramChannelImpl
localAddress = Net.localAddress(fd); localAddress = Net.localAddress(fd);
// flush any packets already received. // flush any packets already received.
boolean blocking = false;
synchronized (blockingLock()) { synchronized (blockingLock()) {
boolean blocking = isBlocking();
try { try {
blocking = isBlocking();
// remainder of each packet thrown away // remainder of each packet thrown away
ByteBuffer tmpBuf = ByteBuffer.allocate(1); ByteBuffer tmpBuf = ByteBuffer.allocate(1);
if (blocking) { if (blocking) {
......
/* /*
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,10 +25,22 @@ ...@@ -25,10 +25,22 @@
package sun.nio.ch; package sun.nio.ch;
import java.io.*; import java.io.IOException;
import java.net.*; import java.net.DatagramPacket;
import java.nio.*; import java.net.DatagramSocket;
import java.nio.channels.*; import java.net.DatagramSocketImpl;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.SocketOption;
import java.net.SocketTimeoutException;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.DatagramChannel;
import java.nio.channels.IllegalBlockingModeException;
// Make a datagram-socket channel look like a datagram socket. // Make a datagram-socket channel look like a datagram socket.
...@@ -178,7 +190,6 @@ public class DatagramSocketAdaptor ...@@ -178,7 +190,6 @@ public class DatagramSocketAdaptor
dc.configureBlocking(false); dc.configureBlocking(false);
try { try {
int n;
SocketAddress sender; SocketAddress sender;
if ((sender = dc.receive(bb)) != null) if ((sender = dc.receive(bb)) != null)
return sender; return sender;
...@@ -188,19 +199,18 @@ public class DatagramSocketAdaptor ...@@ -188,19 +199,18 @@ public class DatagramSocketAdaptor
throw new ClosedChannelException(); throw new ClosedChannelException();
long st = System.currentTimeMillis(); long st = System.currentTimeMillis();
int result = dc.poll(Net.POLLIN, to); int result = dc.poll(Net.POLLIN, to);
if (result > 0 && if (result > 0 && ((result & Net.POLLIN) != 0)) {
((result & Net.POLLIN) != 0)) {
if ((sender = dc.receive(bb)) != null) if ((sender = dc.receive(bb)) != null)
return sender; return sender;
} }
to -= System.currentTimeMillis() - st; to -= System.currentTimeMillis() - st;
if (to <= 0) if (to <= 0)
throw new SocketTimeoutException(); throw new SocketTimeoutException();
} }
} finally { } finally {
if (dc.isOpen()) try {
dc.configureBlocking(true); dc.configureBlocking(true);
} catch (ClosedChannelException e) { }
} }
} }
......
/* /*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,9 +25,20 @@ ...@@ -25,9 +25,20 @@
package sun.nio.ch; package sun.nio.ch;
import java.io.*; import java.io.IOException;
import java.net.*; import java.net.InetAddress;
import java.nio.channels.*; import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.StandardSocketOptions;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.IllegalBlockingModeException;
import java.nio.channels.NotYetBoundException;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
// Make a server-socket channel look like a server socket. // Make a server-socket channel look like a server socket.
...@@ -37,7 +48,7 @@ import java.nio.channels.*; ...@@ -37,7 +48,7 @@ import java.nio.channels.*;
// class. // class.
// //
public class ServerSocketAdaptor // package-private class ServerSocketAdaptor // package-private
extends ServerSocket extends ServerSocket
{ {
...@@ -97,12 +108,16 @@ public class ServerSocketAdaptor // package-private ...@@ -97,12 +108,16 @@ public class ServerSocketAdaptor // package-private
throw new IllegalBlockingModeException(); throw new IllegalBlockingModeException();
try { try {
if (timeout == 0) { if (timeout == 0) {
// for compatibility reasons: accept connection if available
// when configured non-blocking
SocketChannel sc = ssc.accept(); SocketChannel sc = ssc.accept();
if (sc == null && !ssc.isBlocking()) if (sc == null && !ssc.isBlocking())
throw new IllegalBlockingModeException(); throw new IllegalBlockingModeException();
return sc.socket(); return sc.socket();
} }
if (!ssc.isBlocking())
throw new IllegalBlockingModeException();
ssc.configureBlocking(false); ssc.configureBlocking(false);
try { try {
SocketChannel sc; SocketChannel sc;
...@@ -121,10 +136,10 @@ public class ServerSocketAdaptor // package-private ...@@ -121,10 +136,10 @@ public class ServerSocketAdaptor // package-private
throw new SocketTimeoutException(); throw new SocketTimeoutException();
} }
} finally { } finally {
if (ssc.isOpen()) try {
ssc.configureBlocking(true); ssc.configureBlocking(true);
} catch (ClosedChannelException e) { }
} }
} catch (Exception x) { } catch (Exception x) {
Net.translateException(x); Net.translateException(x);
assert false; assert false;
...@@ -178,8 +193,7 @@ public class ServerSocketAdaptor // package-private ...@@ -178,8 +193,7 @@ public class ServerSocketAdaptor // package-private
if (!isBound()) if (!isBound())
return "ServerSocket[unbound]"; return "ServerSocket[unbound]";
return "ServerSocket[addr=" + getInetAddress() + return "ServerSocket[addr=" + getInetAddress() +
// ",port=" + getPort() + ",localport=" + getLocalPort() + "]";
",localport=" + getLocalPort() + "]";
} }
public void setReceiveBufferSize(int size) throws SocketException { public void setReceiveBufferSize(int size) throws SocketException {
......
...@@ -48,10 +48,7 @@ class ServerSocketChannelImpl ...@@ -48,10 +48,7 @@ class ServerSocketChannelImpl
// Our file descriptor // Our file descriptor
private final FileDescriptor fd; private final FileDescriptor fd;
private final int fdVal;
// fd value needed for dev/poll. This value will remain valid
// even after the value in the file descriptor object has been set to -1
private int fdVal;
// ID of native thread currently blocked in this channel, for signalling // ID of native thread currently blocked in this channel, for signalling
private volatile long thread = 0; private volatile long thread = 0;
......
/* /*
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,11 +25,23 @@ ...@@ -25,11 +25,23 @@
package sun.nio.ch; package sun.nio.ch;
import java.io.*; import java.io.IOException;
import java.lang.ref.*; import java.io.InputStream;
import java.net.*; import java.io.OutputStream;
import java.nio.*; import java.net.InetAddress;
import java.nio.channels.*; import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.SocketImpl;
import java.net.SocketOption;
import java.net.SocketTimeoutException;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.IllegalBlockingModeException;
import java.nio.channels.SocketChannel;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedExceptionAction; import java.security.PrivilegedExceptionAction;
import java.util.*; import java.util.*;
...@@ -47,7 +59,7 @@ import java.util.*; ...@@ -47,7 +59,7 @@ import java.util.*;
// java.net.Socket so as to simplify tracking future changes to that class. // java.net.Socket so as to simplify tracking future changes to that class.
// //
public class SocketAdaptor class SocketAdaptor
extends Socket extends Socket
{ {
...@@ -91,7 +103,6 @@ public class SocketAdaptor ...@@ -91,7 +103,6 @@ public class SocketAdaptor
throw new IllegalBlockingModeException(); throw new IllegalBlockingModeException();
try { try {
if (timeout == 0) { if (timeout == 0) {
sc.connect(remote); sc.connect(remote);
return; return;
...@@ -119,8 +130,9 @@ public class SocketAdaptor ...@@ -119,8 +130,9 @@ public class SocketAdaptor
} }
} }
} finally { } finally {
if (sc.isOpen()) try {
sc.configureBlocking(true); sc.configureBlocking(true);
} catch (ClosedChannelException e) { }
} }
} catch (Exception x) { } catch (Exception x) {
...@@ -188,10 +200,11 @@ public class SocketAdaptor ...@@ -188,10 +200,11 @@ public class SocketAdaptor
synchronized (sc.blockingLock()) { synchronized (sc.blockingLock()) {
if (!sc.isBlocking()) if (!sc.isBlocking())
throw new IllegalBlockingModeException(); throw new IllegalBlockingModeException();
if (timeout == 0) if (timeout == 0)
return sc.read(bb); return sc.read(bb);
sc.configureBlocking(false);
sc.configureBlocking(false);
try { try {
int n; int n;
if ((n = sc.read(bb)) != 0) if ((n = sc.read(bb)) != 0)
...@@ -211,10 +224,10 @@ public class SocketAdaptor ...@@ -211,10 +224,10 @@ public class SocketAdaptor
throw new SocketTimeoutException(); throw new SocketTimeoutException();
} }
} finally { } finally {
if (sc.isOpen()) try {
sc.configureBlocking(true); sc.configureBlocking(true);
} catch (ClosedChannelException e) { }
} }
} }
} }
} }
......
...@@ -50,9 +50,6 @@ class SocketChannelImpl ...@@ -50,9 +50,6 @@ class SocketChannelImpl
// Our file descriptor object // Our file descriptor object
private final FileDescriptor fd; private final FileDescriptor fd;
// fd value needed for dev/poll. This value will remain valid
// even after the value in the file descriptor object has been set to -1
private final int fdVal; private final int fdVal;
// IDs of native threads doing reads and writes, for signalling // IDs of native threads doing reads and writes, for signalling
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
package sun.reflect.misc; package sun.reflect.misc;
import java.io.EOFException;
import java.security.AllPermission; import java.security.AllPermission;
import java.security.AccessController; import java.security.AccessController;
import java.security.PermissionCollection; import java.security.PermissionCollection;
...@@ -42,8 +43,8 @@ import java.lang.reflect.AccessibleObject; ...@@ -42,8 +43,8 @@ import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import sun.misc.IOUtils;
import sun.misc.IOUtils;
class Trampoline { class Trampoline {
static { static {
...@@ -382,15 +383,12 @@ public final class MethodUtil extends SecureClassLoader { ...@@ -382,15 +383,12 @@ public final class MethodUtil extends SecureClassLoader {
} }
} }
int len = uc.getContentLength(); int len = uc.getContentLength();
InputStream in = new BufferedInputStream(uc.getInputStream()); try (InputStream in = new BufferedInputStream(uc.getInputStream())) {
byte[] b = IOUtils.readAllBytes(in);
byte[] b; if (len != -1 && b.length != len)
try { throw new EOFException("Expected:" + len + ", read:" + b.length);
b = IOUtils.readFully(in, len, true); return b;
} finally {
in.close();
} }
return b;
} }
......
...@@ -27,7 +27,9 @@ ...@@ -27,7 +27,9 @@
package sun.rmi.registry; package sun.rmi.registry;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInputStream;
import sun.misc.SharedSecrets;
import sun.rmi.transport.StreamRemoteCall; import sun.rmi.transport.StreamRemoteCall;
/** /**
...@@ -83,8 +85,9 @@ public final class RegistryImpl_Skel ...@@ -83,8 +85,9 @@ public final class RegistryImpl_Skel
java.lang.String $param_String_1; java.lang.String $param_String_1;
java.rmi.Remote $param_Remote_2; java.rmi.Remote $param_Remote_2;
try { try {
java.io.ObjectInput in = call.getInputStream(); ObjectInputStream in = (ObjectInputStream)call.getInputStream();
$param_String_1 = (java.lang.String) in.readObject(); $param_String_1 =
SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
$param_Remote_2 = (java.rmi.Remote) in.readObject(); $param_Remote_2 = (java.rmi.Remote) in.readObject();
} catch (ClassCastException | IOException | ClassNotFoundException e) { } catch (ClassCastException | IOException | ClassNotFoundException e) {
call.discardPendingRefs(); call.discardPendingRefs();
...@@ -118,9 +121,10 @@ public final class RegistryImpl_Skel ...@@ -118,9 +121,10 @@ public final class RegistryImpl_Skel
{ {
java.lang.String $param_String_1; java.lang.String $param_String_1;
try { try {
java.io.ObjectInput in = call.getInputStream(); ObjectInputStream in = (ObjectInputStream)call.getInputStream();
$param_String_1 = (java.lang.String) in.readObject(); $param_String_1 =
} catch (ClassCastException | IOException | ClassNotFoundException e) { SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
} catch (ClassCastException | IOException e) {
call.discardPendingRefs(); call.discardPendingRefs();
throw new java.rmi.UnmarshalException("error unmarshalling arguments", e); throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
} finally { } finally {
...@@ -144,8 +148,9 @@ public final class RegistryImpl_Skel ...@@ -144,8 +148,9 @@ public final class RegistryImpl_Skel
java.lang.String $param_String_1; java.lang.String $param_String_1;
java.rmi.Remote $param_Remote_2; java.rmi.Remote $param_Remote_2;
try { try {
java.io.ObjectInput in = call.getInputStream(); ObjectInputStream in = (ObjectInputStream)call.getInputStream();
$param_String_1 = (java.lang.String) in.readObject(); $param_String_1 =
SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
$param_Remote_2 = (java.rmi.Remote) in.readObject(); $param_Remote_2 = (java.rmi.Remote) in.readObject();
} catch (ClassCastException | IOException | java.lang.ClassNotFoundException e) { } catch (ClassCastException | IOException | java.lang.ClassNotFoundException e) {
call.discardPendingRefs(); call.discardPendingRefs();
...@@ -169,9 +174,10 @@ public final class RegistryImpl_Skel ...@@ -169,9 +174,10 @@ public final class RegistryImpl_Skel
java.lang.String $param_String_1; java.lang.String $param_String_1;
try { try {
java.io.ObjectInput in = call.getInputStream(); ObjectInputStream in = (ObjectInputStream)call.getInputStream();
$param_String_1 = (java.lang.String) in.readObject(); $param_String_1 =
} catch (ClassCastException | IOException | ClassNotFoundException e) { SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
} catch (ClassCastException | IOException e) {
call.discardPendingRefs(); call.discardPendingRefs();
throw new java.rmi.UnmarshalException("error unmarshalling arguments", e); throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
} finally { } finally {
......
...@@ -27,6 +27,7 @@ package sun.rmi.server; ...@@ -27,6 +27,7 @@ package sun.rmi.server;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInput; import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput; import java.io.ObjectOutput;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.rmi.MarshalException; import java.rmi.MarshalException;
...@@ -38,6 +39,8 @@ import java.rmi.server.RemoteCall; ...@@ -38,6 +39,8 @@ import java.rmi.server.RemoteCall;
import java.rmi.server.RemoteObject; import java.rmi.server.RemoteObject;
import java.rmi.server.RemoteRef; import java.rmi.server.RemoteRef;
import java.security.AccessController; import java.security.AccessController;
import sun.misc.SharedSecrets;
import sun.rmi.runtime.Log; import sun.rmi.runtime.Log;
import sun.rmi.transport.Connection; import sun.rmi.transport.Connection;
import sun.rmi.transport.LiveRef; import sun.rmi.transport.LiveRef;
...@@ -318,6 +321,8 @@ public class UnicastRef implements RemoteRef { ...@@ -318,6 +321,8 @@ public class UnicastRef implements RemoteRef {
} else { } else {
throw new Error("Unrecognized primitive type: " + type); throw new Error("Unrecognized primitive type: " + type);
} }
} else if (type == String.class && in instanceof ObjectInputStream) {
return SharedSecrets.getJavaObjectInputStreamReadString().readString((ObjectInputStream)in);
} else { } else {
return in.readObject(); return in.readObject();
} }
......
/* /*
* Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -29,6 +29,7 @@ import java.io.DataOutput; ...@@ -29,6 +29,7 @@ import java.io.DataOutput;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInput; import java.io.ObjectInput;
import java.io.ObjectOutput; import java.io.ObjectOutput;
import java.lang.reflect.Proxy;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
...@@ -553,6 +554,9 @@ public class TCPEndpoint implements Endpoint { ...@@ -553,6 +554,9 @@ public class TCPEndpoint implements Endpoint {
host = in.readUTF(); host = in.readUTF();
port = in.readInt(); port = in.readInt();
csf = (RMIClientSocketFactory) in.readObject(); csf = (RMIClientSocketFactory) in.readObject();
if (Proxy.isProxyClass(csf.getClass())) {
throw new IOException("Invalid SocketFactory");
}
break; break;
default: default:
......
...@@ -108,4 +108,27 @@ public class GetPropertyAction implements PrivilegedAction<String> { ...@@ -108,4 +108,27 @@ public class GetPropertyAction implements PrivilegedAction<String> {
new GetPropertyAction(theProp)); new GetPropertyAction(theProp));
} }
} }
/**
* Convenience method to get a property without going through doPrivileged
* if no security manager is present. This is unsafe for inclusion in a
* public API but allowable here since this class is now encapsulated.
*
* Note that this method performs a privileged action using caller-provided
* inputs. The caller of this method should take care to ensure that the
* inputs are not tainted and the returned property is not made accessible
* to untrusted code if it contains sensitive information.
*
* @param theProp the name of the system property.
* @param defaultVal the default value.
*/
public static String privilegedGetProperty(String theProp,
String defaultVal) {
if (System.getSecurityManager() == null) {
return System.getProperty(theProp, defaultVal);
} else {
return AccessController.doPrivileged(
new GetPropertyAction(theProp, defaultVal));
}
}
} }
/* /*
* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -44,6 +44,7 @@ import sun.security.krb5.internal.crypto.Des3; ...@@ -44,6 +44,7 @@ import sun.security.krb5.internal.crypto.Des3;
import sun.security.krb5.internal.crypto.Aes128; import sun.security.krb5.internal.crypto.Aes128;
import sun.security.krb5.internal.crypto.Aes256; import sun.security.krb5.internal.crypto.Aes256;
import sun.security.krb5.internal.crypto.ArcFourHmac; import sun.security.krb5.internal.crypto.ArcFourHmac;
import sun.security.krb5.internal.crypto.EType;
class CipherHelper { class CipherHelper {
...@@ -77,10 +78,6 @@ class CipherHelper { ...@@ -77,10 +78,6 @@ class CipherHelper {
private int sgnAlg, sealAlg; private int sgnAlg, sealAlg;
private byte[] keybytes; private byte[] keybytes;
// new token format from draft-ietf-krb-wg-gssapi-cfx-07
// proto is used to determine new GSS token format for "newer" etypes
private int proto = 0;
CipherHelper(EncryptionKey key) throws GSSException { CipherHelper(EncryptionKey key) throws GSSException {
etype = key.getEType(); etype = key.getEType();
keybytes = key.getBytes(); keybytes = key.getBytes();
...@@ -106,7 +103,6 @@ class CipherHelper { ...@@ -106,7 +103,6 @@ class CipherHelper {
case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96: case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96:
sgnAlg = -1; sgnAlg = -1;
sealAlg = -1; sealAlg = -1;
proto = 1;
break; break;
default: default:
...@@ -123,8 +119,10 @@ class CipherHelper { ...@@ -123,8 +119,10 @@ class CipherHelper {
return sealAlg; return sealAlg;
} }
// new token format from draft-ietf-krb-wg-gssapi-cfx-07
// proto is used to determine new GSS token format for "newer" etypes
int getProto() { int getProto() {
return proto; return EType.isNewer(etype) ? 1 : 0;
} }
int getEType() { int getEType() {
......
/* /*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -29,6 +29,8 @@ import com.sun.security.jgss.AuthorizationDataEntry; ...@@ -29,6 +29,8 @@ import com.sun.security.jgss.AuthorizationDataEntry;
import org.ietf.jgss.*; import org.ietf.jgss.*;
import java.io.InputStream; import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import sun.security.action.GetPropertyAction;
import sun.security.krb5.*; import sun.security.krb5.*;
import java.net.InetAddress; import java.net.InetAddress;
import sun.security.krb5.internal.AuthorizationData; import sun.security.krb5.internal.AuthorizationData;
...@@ -36,6 +38,33 @@ import sun.security.krb5.internal.KerberosTime; ...@@ -36,6 +38,33 @@ import sun.security.krb5.internal.KerberosTime;
class InitSecContextToken extends InitialToken { class InitSecContextToken extends InitialToken {
// If non-mutual authentication is requested, there is no AP-REP message.
// The acceptor thus has no chance to send the seq-number field to the
// initiator. In this case, the initiator and acceptor should has an
// agreement to derive acceptor's initial seq-number if the acceptor wishes
// to send messages to the initiator.
// If this flag is true, it will the same as the initiator's initial
// seq-number (as MIT krb5 and Windows SSPI do). Otherwise, it will be zero
// (as Heimdal does). The default value is true.
private static final boolean ACCEPTOR_USE_INITIATOR_SEQNUM;
static {
// The ACCEPTOR_USE_INITIATOR_SEQNUM value is determined by the system
// property "sun.security.krb5.acceptor.sequence.number.nonmutual",
// which can be set to "initiator", "zero" or "0".
String propName = "sun.security.krb5.acceptor.sequence.number.nonmutual";
String s = GetPropertyAction.privilegedGetProperty(propName, "initiator");
if (s.equals("initiator")) {
ACCEPTOR_USE_INITIATOR_SEQNUM = true;
} else if (s.equals("zero") || s.equals("0")) {
ACCEPTOR_USE_INITIATOR_SEQNUM = false;
} else {
throw new AssertionError("Unrecognized value for " + propName
+ ": " + s);
}
}
private KrbApReq apReq = null; private KrbApReq apReq = null;
/** /**
...@@ -79,7 +108,10 @@ class InitSecContextToken extends InitialToken { ...@@ -79,7 +108,10 @@ class InitSecContextToken extends InitialToken {
context.setKey(Krb5Context.SESSION_KEY, serviceTicket.getSessionKey()); context.setKey(Krb5Context.SESSION_KEY, serviceTicket.getSessionKey());
if (!mutualRequired) if (!mutualRequired)
context.resetPeerSequenceNumber(0); context.resetPeerSequenceNumber(
ACCEPTOR_USE_INITIATOR_SEQNUM
? apReq.getSeqNumber().intValue()
: 0);
} }
/** /**
...@@ -144,10 +176,12 @@ class InitSecContextToken extends InitialToken { ...@@ -144,10 +176,12 @@ class InitSecContextToken extends InitialToken {
apReqSeqNumber.intValue() : apReqSeqNumber.intValue() :
0); 0);
context.resetPeerSequenceNumber(peerSeqNumber); context.resetPeerSequenceNumber(peerSeqNumber);
if (!context.getMutualAuthState()) if (!context.getMutualAuthState()) {
// Use the same sequence number as the peer context.resetMySequenceNumber(
// (Behaviour exhibited by the Windows SSPI server) ACCEPTOR_USE_INITIATOR_SEQNUM
context.resetMySequenceNumber(peerSeqNumber); ? peerSeqNumber
: 0);
}
context.setAuthTime( context.setAuthTime(
new KerberosTime(apReq.getCreds().getAuthTime()).toString()); new KerberosTime(apReq.getCreds().getAuthTime()).toString());
context.setTktFlags(apReq.getCreds().getFlags()); context.setTktFlags(apReq.getCreds().getFlags());
......
...@@ -713,14 +713,14 @@ class Krb5Context implements GSSContextSpi { ...@@ -713,14 +713,14 @@ class Krb5Context implements GSSContextSpi {
if (subject != null && if (subject != null &&
!subject.isReadOnly()) { !subject.isReadOnly()) {
/* /*
* Store the service credentials as * Store the service credentials as
* javax.security.auth.kerberos.KerberosTicket in * javax.security.auth.kerberos.KerberosTicket in
* the Subject. We could wait till the context is * the Subject. We could wait until the context is
* succesfully established; however it is easier * successfully established; however it is easier
* to do here and there is no harm indoing it here. * to do it here and there is no harm.
*/ */
final KerberosTicket kt = final KerberosTicket kt =
Krb5Util.credsToTicket(serviceCreds); Krb5Util.credsToTicket(serviceCreds);
AccessController.doPrivileged ( AccessController.doPrivileged (
new java.security.PrivilegedAction<Void>() { new java.security.PrivilegedAction<Void>() {
public Void run() { public Void run() {
......
...@@ -60,7 +60,9 @@ public class Krb5InitCredential ...@@ -60,7 +60,9 @@ public class Krb5InitCredential
private Krb5InitCredential(Krb5NameElement name, private Krb5InitCredential(Krb5NameElement name,
byte[] asn1Encoding, byte[] asn1Encoding,
KerberosPrincipal client, KerberosPrincipal client,
KerberosPrincipal clientAlias,
KerberosPrincipal server, KerberosPrincipal server,
KerberosPrincipal serverAlias,
byte[] sessionKey, byte[] sessionKey,
int keyType, int keyType,
boolean[] flags, boolean[] flags,
...@@ -81,14 +83,21 @@ public class Krb5InitCredential ...@@ -81,14 +83,21 @@ public class Krb5InitCredential
endTime, endTime,
renewTill, renewTill,
clientAddresses); clientAddresses);
KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
.kerberosTicketSetClientAlias(this, clientAlias);
KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
.kerberosTicketSetServerAlias(this, serverAlias);
this.name = name; this.name = name;
try { try {
// Cache this for later use by the sun.security.krb5 package. // Cache this for later use by the sun.security.krb5 package.
krb5Credentials = new Credentials(asn1Encoding, krb5Credentials = new Credentials(asn1Encoding,
client.getName(), client.getName(),
(clientAlias != null ?
clientAlias.getName() : null),
server.getName(), server.getName(),
(serverAlias != null ?
serverAlias.getName() : null),
sessionKey, sessionKey,
keyType, keyType,
flags, flags,
...@@ -111,7 +120,9 @@ public class Krb5InitCredential ...@@ -111,7 +120,9 @@ public class Krb5InitCredential
Credentials delegatedCred, Credentials delegatedCred,
byte[] asn1Encoding, byte[] asn1Encoding,
KerberosPrincipal client, KerberosPrincipal client,
KerberosPrincipal clientAlias,
KerberosPrincipal server, KerberosPrincipal server,
KerberosPrincipal serverAlias,
byte[] sessionKey, byte[] sessionKey,
int keyType, int keyType,
boolean[] flags, boolean[] flags,
...@@ -132,7 +143,10 @@ public class Krb5InitCredential ...@@ -132,7 +143,10 @@ public class Krb5InitCredential
endTime, endTime,
renewTill, renewTill,
clientAddresses); clientAddresses);
KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
.kerberosTicketSetClientAlias(this, clientAlias);
KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
.kerberosTicketSetServerAlias(this, serverAlias);
this.name = name; this.name = name;
// A delegated cred does not have all fields set. So do not try to // A delegated cred does not have all fields set. So do not try to
// creat new Credentials out of the delegatedCred. // creat new Credentials out of the delegatedCred.
...@@ -154,10 +168,18 @@ public class Krb5InitCredential ...@@ -154,10 +168,18 @@ public class Krb5InitCredential
Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL); Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL);
} }
KerberosPrincipal clientAlias = KerberosSecrets
.getJavaxSecurityAuthKerberosAccess()
.kerberosTicketGetClientAlias(tgt);
KerberosPrincipal serverAlias = KerberosSecrets
.getJavaxSecurityAuthKerberosAccess()
.kerberosTicketGetServerAlias(tgt);
Krb5InitCredential result = new Krb5InitCredential(name, Krb5InitCredential result = new Krb5InitCredential(name,
tgt.getEncoded(), tgt.getEncoded(),
tgt.getClient(), tgt.getClient(),
clientAlias,
tgt.getServer(), tgt.getServer(),
serverAlias,
tgt.getSessionKey().getEncoded(), tgt.getSessionKey().getEncoded(),
tgt.getSessionKeyType(), tgt.getSessionKeyType(),
tgt.getFlags(), tgt.getFlags(),
...@@ -183,10 +205,14 @@ public class Krb5InitCredential ...@@ -183,10 +205,14 @@ public class Krb5InitCredential
*/ */
PrincipalName cPrinc = delegatedCred.getClient(); PrincipalName cPrinc = delegatedCred.getClient();
PrincipalName cAPrinc = delegatedCred.getClientAlias();
PrincipalName sPrinc = delegatedCred.getServer(); PrincipalName sPrinc = delegatedCred.getServer();
PrincipalName sAPrinc = delegatedCred.getServerAlias();
KerberosPrincipal client = null; KerberosPrincipal client = null;
KerberosPrincipal clientAlias = null;
KerberosPrincipal server = null; KerberosPrincipal server = null;
KerberosPrincipal serverAlias = null;
Krb5NameElement credName = null; Krb5NameElement credName = null;
...@@ -197,6 +223,10 @@ public class Krb5InitCredential ...@@ -197,6 +223,10 @@ public class Krb5InitCredential
client = new KerberosPrincipal(fullName); client = new KerberosPrincipal(fullName);
} }
if (cAPrinc != null) {
clientAlias = new KerberosPrincipal(cAPrinc.getName());
}
// XXX Compare name to credName // XXX Compare name to credName
if (sPrinc != null) { if (sPrinc != null) {
...@@ -205,11 +235,17 @@ public class Krb5InitCredential ...@@ -205,11 +235,17 @@ public class Krb5InitCredential
KerberosPrincipal.KRB_NT_SRV_INST); KerberosPrincipal.KRB_NT_SRV_INST);
} }
if (sAPrinc != null) {
serverAlias = new KerberosPrincipal(sAPrinc.getName());
}
return new Krb5InitCredential(credName, return new Krb5InitCredential(credName,
delegatedCred, delegatedCred,
delegatedCred.getEncoded(), delegatedCred.getEncoded(),
client, client,
clientAlias,
server, server,
serverAlias,
sessionKey.getBytes(), sessionKey.getBytes(),
sessionKey.getEType(), sessionKey.getEType(),
delegatedCred.getFlags(), delegatedCred.getFlags(),
......
...@@ -228,7 +228,7 @@ public class Krb5Util { ...@@ -228,7 +228,7 @@ public class Krb5Util {
public static KerberosTicket credsToTicket(Credentials serviceCreds) { public static KerberosTicket credsToTicket(Credentials serviceCreds) {
EncryptionKey sessionKey = serviceCreds.getSessionKey(); EncryptionKey sessionKey = serviceCreds.getSessionKey();
return new KerberosTicket( KerberosTicket kt = new KerberosTicket(
serviceCreds.getEncoded(), serviceCreds.getEncoded(),
new KerberosPrincipal(serviceCreds.getClient().getName()), new KerberosPrincipal(serviceCreds.getClient().getName()),
new KerberosPrincipal(serviceCreds.getServer().getName(), new KerberosPrincipal(serviceCreds.getServer().getName(),
...@@ -241,14 +241,35 @@ public class Krb5Util { ...@@ -241,14 +241,35 @@ public class Krb5Util {
serviceCreds.getEndTime(), serviceCreds.getEndTime(),
serviceCreds.getRenewTill(), serviceCreds.getRenewTill(),
serviceCreds.getClientAddresses()); serviceCreds.getClientAddresses());
PrincipalName clientAlias = serviceCreds.getClientAlias();
PrincipalName serverAlias = serviceCreds.getServerAlias();
if (clientAlias != null) {
KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
.kerberosTicketSetClientAlias(kt, new KerberosPrincipal(
clientAlias.getName(), clientAlias.getNameType()));
}
if (serverAlias != null) {
KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
.kerberosTicketSetServerAlias(kt, new KerberosPrincipal(
serverAlias.getName(), serverAlias.getNameType()));
}
return kt;
}; };
public static Credentials ticketToCreds(KerberosTicket kerbTicket) public static Credentials ticketToCreds(KerberosTicket kerbTicket)
throws KrbException, IOException { throws KrbException, IOException {
KerberosPrincipal clientAlias = KerberosSecrets
.getJavaxSecurityAuthKerberosAccess()
.kerberosTicketGetClientAlias(kerbTicket);
KerberosPrincipal serverAlias = KerberosSecrets
.getJavaxSecurityAuthKerberosAccess()
.kerberosTicketGetServerAlias(kerbTicket);
return new Credentials( return new Credentials(
kerbTicket.getEncoded(), kerbTicket.getEncoded(),
kerbTicket.getClient().getName(), kerbTicket.getClient().getName(),
(clientAlias != null ? clientAlias.getName() : null),
kerbTicket.getServer().getName(), kerbTicket.getServer().getName(),
(serverAlias != null ? serverAlias.getName() : null),
kerbTicket.getSessionKey().getEncoded(), kerbTicket.getSessionKey().getEncoded(),
kerbTicket.getSessionKeyType(), kerbTicket.getSessionKeyType(),
kerbTicket.getFlags(), kerbTicket.getFlags(),
......
/* /*
* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -499,11 +499,11 @@ abstract class MessageToken_v2 extends Krb5Token { ...@@ -499,11 +499,11 @@ abstract class MessageToken_v2 extends Krb5Token {
*/ */
class MessageTokenHeader { class MessageTokenHeader {
private int tokenId; private int tokenId;
private byte[] bytes = new byte[TOKEN_HEADER_SIZE]; private byte[] bytes = new byte[TOKEN_HEADER_SIZE];
// Writes a new token header // Writes a new token header
public MessageTokenHeader(int tokenId, boolean conf) throws GSSException { public MessageTokenHeader(int tokenId, boolean conf) throws GSSException {
this.tokenId = tokenId; this.tokenId = tokenId;
...@@ -609,7 +609,7 @@ abstract class MessageToken_v2 extends Krb5Token { ...@@ -609,7 +609,7 @@ abstract class MessageToken_v2 extends Krb5Token {
prop.setQOP(0); prop.setQOP(0);
// sequence number // sequence number
seqNumber = readBigEndian(bytes, 0, 8); seqNumber = readBigEndian(bytes, 12, 4);
} }
/** /**
......
/* /*
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
package sun.security.jgss.krb5; package sun.security.jgss.krb5;
import sun.security.krb5.KerberosSecrets;
import javax.security.auth.kerberos.KerberosTicket; import javax.security.auth.kerberos.KerberosTicket;
import javax.security.auth.kerberos.KerberosKey; import javax.security.auth.kerberos.KerberosKey;
import javax.security.auth.Subject; import javax.security.auth.Subject;
...@@ -182,24 +184,45 @@ class SubjectComber { ...@@ -182,24 +184,45 @@ class SubjectComber {
} }
} else { } else {
KerberosPrincipal serverAlias = KerberosSecrets
.getJavaxSecurityAuthKerberosAccess()
.kerberosTicketGetServerAlias(ticket);
if (serverPrincipal == null || if (serverPrincipal == null ||
ticket.getServer().getName().equals(serverPrincipal)) { ticket.getServer().getName().equals(serverPrincipal) ||
(serverAlias != null &&
serverPrincipal.equals(
serverAlias.getName()))) {
KerberosPrincipal clientAlias = KerberosSecrets
.getJavaxSecurityAuthKerberosAccess()
.kerberosTicketGetClientAlias(ticket);
if (clientPrincipal == null || if (clientPrincipal == null ||
clientPrincipal.equals( clientPrincipal.equals(
ticket.getClient().getName())) { ticket.getClient().getName()) ||
(clientAlias != null &&
clientPrincipal.equals(
clientAlias.getName()))) {
if (oneOnly) { if (oneOnly) {
return ticket; return ticket;
} else { } else {
// Record names so that tickets will // Record names so that tickets will
// all belong to same principals // all belong to same principals
if (clientPrincipal == null) { if (clientPrincipal == null) {
clientPrincipal = if (clientAlias == null) {
ticket.getClient().getName(); clientPrincipal =
ticket.getClient().getName();
} else {
clientPrincipal =
clientAlias.getName();
}
} }
if (serverPrincipal == null) { if (serverPrincipal == null) {
serverPrincipal = if (serverAlias == null) {
ticket.getServer().getName(); serverPrincipal =
ticket.getServer().getName();
} else {
serverPrincipal =
serverAlias.getName();
}
} }
answer.add(credClass.cast(ticket)); answer.add(credClass.cast(ticket));
} }
......
/* /*
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -69,6 +69,7 @@ public class Checksum { ...@@ -69,6 +69,7 @@ public class Checksum {
// draft-brezak-win2k-krb-rc4-hmac-04.txt // draft-brezak-win2k-krb-rc4-hmac-04.txt
public static final int CKSUMTYPE_HMAC_MD5_ARCFOUR = -138; public static final int CKSUMTYPE_HMAC_MD5_ARCFOUR = -138;
// default checksum type, -1 if not set
static int CKSUMTYPE_DEFAULT; static int CKSUMTYPE_DEFAULT;
static int SAFECKSUMTYPE_DEFAULT; static int SAFECKSUMTYPE_DEFAULT;
...@@ -83,26 +84,19 @@ public class Checksum { ...@@ -83,26 +84,19 @@ public class Checksum {
try { try {
cfg = Config.getInstance(); cfg = Config.getInstance();
temp = cfg.get("libdefaults", "default_checksum"); temp = cfg.get("libdefaults", "default_checksum");
if (temp != null) if (temp != null) {
{ CKSUMTYPE_DEFAULT = Config.getType(temp);
CKSUMTYPE_DEFAULT = Config.getType(temp); } else {
} else { CKSUMTYPE_DEFAULT = -1;
/* }
* If the default checksum is not
* specified in the configuration we
* set it to RSA_MD5. We follow the MIT and
* SEAM implementation.
*/
CKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5;
}
} catch (Exception exc) { } catch (Exception exc) {
if (DEBUG) { if (DEBUG) {
System.out.println("Exception in getting default checksum "+ System.out.println("Exception in getting default checksum "+
"value from the configuration " + "value from the configuration. " +
"Setting default checksum to be RSA-MD5"); "No default checksum set.");
exc.printStackTrace(); exc.printStackTrace();
} }
CKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5; CKSUMTYPE_DEFAULT = -1;
} }
...@@ -112,97 +106,100 @@ public class Checksum { ...@@ -112,97 +106,100 @@ public class Checksum {
{ {
SAFECKSUMTYPE_DEFAULT = Config.getType(temp); SAFECKSUMTYPE_DEFAULT = Config.getType(temp);
} else { } else {
SAFECKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5_DES; SAFECKSUMTYPE_DEFAULT = -1;
} }
} catch (Exception exc) { } catch (Exception exc) {
if (DEBUG) { if (DEBUG) {
System.out.println("Exception in getting safe default " + System.out.println("Exception in getting safe default " +
"checksum value " + "checksum value " +
"from the configuration Setting " + "from the configuration Setting. " +
"safe default checksum to be RSA-MD5"); "No safe default checksum set.");
exc.printStackTrace(); exc.printStackTrace();
} }
SAFECKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5_DES; SAFECKSUMTYPE_DEFAULT = -1;
} }
} }
/** /**
* Constructs a new Checksum using the raw data and type. * Constructs a new Checksum using the raw data and type.
*
* This constructor is only used by Authenticator Checksum
* {@link sun.security.jgss.krb5.InitialToken.OverloadedChecksum}
* where the checksum type must be 0x8003
* (see https://tools.ietf.org/html/rfc4121#section-4.1.1)
* and checksum field/value is used to convey service flags,
* channel bindings, and optional delegation information.
* This special type does NOT have a {@link CksumType} and has its
* own calculating and verification rules. It does has the same
* ASN.1 encoding though.
*
* @data the byte array of checksum. * @data the byte array of checksum.
* @new_cksumType the type of checksum. * @new_cksumType the type of checksum.
*
*/ */
// used in InitialToken
public Checksum(byte[] data, int new_cksumType) { public Checksum(byte[] data, int new_cksumType) {
cksumType = new_cksumType; cksumType = new_cksumType;
checksum = data; checksum = data;
} }
/** /**
* Constructs a new Checksum by calculating the checksum over the data * Constructs a new Checksum by calculating over the data using
* using specified checksum type. * the specified checksum type. If the checksum is unkeyed, key
* @new_cksumType the type of checksum. * and usage are ignored.
* @data the data that needs to be performed a checksum calculation on. *
* @param new_cksumType the type of checksum. If set to -1, the
* {@linkplain EType#checksumType() mandatory checksum type}
* for the encryption type of {@code key} will be used
* @param data the data that needs to be performed a checksum calculation on
* @param key the key used by a keyed checksum
* @param usage the usage used by a keyed checksum
*/ */
public Checksum(int new_cksumType, byte[] data) public Checksum(int new_cksumType, byte[] data,
throws KdcErrException, KrbCryptoException { EncryptionKey key, int usage)
throws KdcErrException, KrbApErrException, KrbCryptoException {
cksumType = new_cksumType; if (new_cksumType == -1) {
CksumType cksumEngine = CksumType.getInstance(cksumType); cksumType = EType.getInstance(key.getEType()).checksumType();
if (!cksumEngine.isSafe()) {
checksum = cksumEngine.calculateChecksum(data, data.length);
} else { } else {
throw new KdcErrException(Krb5.KRB_AP_ERR_INAPP_CKSUM); cksumType = new_cksumType;
} }
checksum = CksumType.getInstance(cksumType).calculateChecksum(
data, data.length, key.getBytes(), usage);
} }
/** /**
* Constructs a new Checksum by calculating the keyed checksum * Verifies the keyed checksum over the data passed in.
* over the data using specified checksum type.
* @new_cksumType the type of checksum.
* @data the data that needs to be performed a checksum calculation on.
*/ */
// KrbSafe, KrbTgsReq public boolean verifyKeyedChecksum(byte[] data, EncryptionKey key, int usage)
public Checksum(int new_cksumType, byte[] data, throws KdcErrException, KrbApErrException, KrbCryptoException {
EncryptionKey key, int usage)
throws KdcErrException, KrbApErrException, KrbCryptoException {
cksumType = new_cksumType;
CksumType cksumEngine = CksumType.getInstance(cksumType); CksumType cksumEngine = CksumType.getInstance(cksumType);
if (!cksumEngine.isSafe()) if (!cksumEngine.isKeyed()) {
throw new KrbApErrException(Krb5.KRB_AP_ERR_INAPP_CKSUM); throw new KrbApErrException(Krb5.KRB_AP_ERR_INAPP_CKSUM);
checksum = } else {
cksumEngine.calculateKeyedChecksum(data, return cksumEngine.verifyChecksum(
data.length, data, data.length, key.getBytes(), checksum, usage);
key.getBytes(), }
usage);
} }
/** /**
* Verifies the keyed checksum over the data passed in. * Verifies the checksum over the data passed in. The checksum might
* be a keyed or not.
*
* =============== ATTENTION! Use with care ==================
* According to https://tools.ietf.org/html/rfc3961#section-6.1,
* An unkeyed checksum should only be used "in limited circumstances
* where the lack of a key does not provide a window for an attack,
* preferably as part of an encrypted message".
*/ */
public boolean verifyKeyedChecksum(byte[] data, EncryptionKey key, public boolean verifyAnyChecksum(byte[] data, EncryptionKey key, int usage)
int usage) throws KdcErrException, KrbCryptoException {
throws KdcErrException, KrbApErrException, KrbCryptoException { return CksumType.getInstance(cksumType).verifyChecksum(
CksumType cksumEngine = CksumType.getInstance(cksumType); data, data.length, key.getBytes(), checksum, usage);
if (!cksumEngine.isSafe())
throw new KrbApErrException(Krb5.KRB_AP_ERR_INAPP_CKSUM);
return cksumEngine.verifyKeyedChecksum(data,
data.length,
key.getBytes(),
checksum,
usage);
} }
/*
public Checksum(byte[] data) throws KdcErrException, KrbCryptoException {
this(Checksum.CKSUMTYPE_DEFAULT, data);
}
*/
boolean isEqual(Checksum cksum) throws KdcErrException { boolean isEqual(Checksum cksum) throws KdcErrException {
if (cksumType != cksum.cksumType) if (cksumType != cksum.cksumType) {
return false; return false;
CksumType cksumEngine = CksumType.getInstance(cksumType); }
return CksumType.isChecksumEqual(checksum, cksum.checksum); return CksumType.isChecksumEqual(checksum, cksum.checksum);
} }
...@@ -214,7 +211,7 @@ public class Checksum { ...@@ -214,7 +211,7 @@ public class Checksum {
* @exception IOException if an I/O error occurs while reading encoded data. * @exception IOException if an I/O error occurs while reading encoded data.
* *
*/ */
private Checksum(DerValue encoding) throws Asn1Exception, IOException { public Checksum(DerValue encoding) throws Asn1Exception, IOException {
DerValue der; DerValue der;
if (encoding.getTag() != DerValue.tag_Sequence) { if (encoding.getTag() != DerValue.tag_Sequence) {
throw new Asn1Exception(Krb5.ASN1_BAD_ID); throw new Asn1Exception(Krb5.ASN1_BAD_ID);
......
/* /*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -30,25 +30,24 @@ ...@@ -30,25 +30,24 @@
*/ */
package sun.security.krb5; package sun.security.krb5;
import java.io.File; import java.io.*;
import java.io.FileInputStream;
import java.util.Hashtable;
import java.util.Vector;
import java.util.ArrayList;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedExceptionAction; import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Hashtable;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import sun.net.dns.ResolverConfiguration; import sun.net.dns.ResolverConfiguration;
import sun.security.krb5.internal.crypto.EType; import sun.security.krb5.internal.crypto.EType;
import sun.security.krb5.internal.Krb5; import sun.security.krb5.internal.Krb5;
import sun.security.util.SecurityProperties;
/** /**
* This class maintains key-value pairs of Kerberos configurable constants * This class maintains key-value pairs of Kerberos configurable constants
...@@ -57,6 +56,41 @@ import sun.security.krb5.internal.Krb5; ...@@ -57,6 +56,41 @@ import sun.security.krb5.internal.Krb5;
public class Config { public class Config {
/**
* {@systemProperty sun.security.krb5.disableReferrals} property
* indicating whether or not cross-realm referrals (RFC 6806) are
* enabled.
*/
public static final boolean DISABLE_REFERRALS;
/**
* {@systemProperty sun.security.krb5.maxReferrals} property
* indicating the maximum number of cross-realm referral
* hops allowed.
*/
public static final int MAX_REFERRALS;
static {
String disableReferralsProp =
SecurityProperties.privilegedGetOverridable(
"sun.security.krb5.disableReferrals");
if (disableReferralsProp != null) {
DISABLE_REFERRALS = "true".equalsIgnoreCase(disableReferralsProp);
} else {
DISABLE_REFERRALS = false;
}
int maxReferralsValue = 5;
String maxReferralsProp =
SecurityProperties.privilegedGetOverridable(
"sun.security.krb5.maxReferrals");
try {
maxReferralsValue = Integer.parseInt(maxReferralsProp);
} catch (NumberFormatException e) {
}
MAX_REFERRALS = maxReferralsValue;
}
/* /*
* Only allow a single instance of Config. * Only allow a single instance of Config.
*/ */
...@@ -257,7 +291,11 @@ public class Config { ...@@ -257,7 +291,11 @@ public class Config {
} }
/** /**
* Gets all values for the specified keys. * Gets all values (at least one) for the specified keys separated by
* a whitespace, or null if there is no such keys.
* The values can either be provided on a single line, or on multiple lines
* using the same key. When provided on a single line, the value can be
* comma or space separated.
* @throws IllegalArgumentException if any of the keys is illegal * @throws IllegalArgumentException if any of the keys is illegal
* (See {@link #get}) * (See {@link #get})
*/ */
...@@ -267,6 +305,7 @@ public class Config { ...@@ -267,6 +305,7 @@ public class Config {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
boolean first = true; boolean first = true;
for (String s: v) { for (String s: v) {
s = s.replaceAll("[\\s,]+", " ");
if (first) { if (first) {
sb.append(s); sb.append(s);
first = false; first = false;
...@@ -313,6 +352,72 @@ public class Config { ...@@ -313,6 +352,72 @@ public class Config {
} }
} }
/**
* Translates a duration value into seconds.
*
* The format can be one of "h:m[:s]", "NdNhNmNs", and "N". See
* http://web.mit.edu/kerberos/krb5-devel/doc/basic/date_format.html#duration
* for definitions.
*
* @param s the string duration
* @return time in seconds
* @throw KrbException if format is illegal
*/
public static int duration(String s) throws KrbException {
if (s.isEmpty()) {
throw new KrbException("Duration cannot be empty");
}
// N
if (s.matches("\\d+")) {
return Integer.parseInt(s);
}
// h:m[:s]
Matcher m = Pattern.compile("(\\d+):(\\d+)(:(\\d+))?").matcher(s);
if (m.matches()) {
int hr = Integer.parseInt(m.group(1));
int min = Integer.parseInt(m.group(2));
if (min >= 60) {
throw new KrbException("Illegal duration format " + s);
}
int result = hr * 3600 + min * 60;
if (m.group(4) != null) {
int sec = Integer.parseInt(m.group(4));
if (sec >= 60) {
throw new KrbException("Illegal duration format " + s);
}
result += sec;
}
return result;
}
// NdNhNmNs
// 120m allowed. Maybe 1h120m is not good, but still allowed
m = Pattern.compile(
"((\\d+)d)?\\s*((\\d+)h)?\\s*((\\d+)m)?\\s*((\\d+)s)?",
Pattern.CASE_INSENSITIVE).matcher(s);
if (m.matches()) {
int result = 0;
if (m.group(2) != null) {
result += 86400 * Integer.parseInt(m.group(2));
}
if (m.group(4) != null) {
result += 3600 * Integer.parseInt(m.group(4));
}
if (m.group(6) != null) {
result += 60 * Integer.parseInt(m.group(6));
}
if (m.group(8) != null) {
result += Integer.parseInt(m.group(8));
}
return result;
}
throw new KrbException("Illegal duration format " + s);
}
/** /**
* Gets the int value for the specified keys. * Gets the int value for the specified keys.
* @param keys the keys * @param keys the keys
......
...@@ -48,7 +48,9 @@ public class Credentials { ...@@ -48,7 +48,9 @@ public class Credentials {
Ticket ticket; Ticket ticket;
PrincipalName client; PrincipalName client;
PrincipalName clientAlias;
PrincipalName server; PrincipalName server;
PrincipalName serverAlias;
EncryptionKey key; EncryptionKey key;
TicketFlags flags; TicketFlags flags;
KerberosTime authTime; KerberosTime authTime;
...@@ -78,7 +80,9 @@ public class Credentials { ...@@ -78,7 +80,9 @@ public class Credentials {
public Credentials(Ticket new_ticket, public Credentials(Ticket new_ticket,
PrincipalName new_client, PrincipalName new_client,
PrincipalName new_client_alias,
PrincipalName new_server, PrincipalName new_server,
PrincipalName new_server_alias,
EncryptionKey new_key, EncryptionKey new_key,
TicketFlags new_flags, TicketFlags new_flags,
KerberosTime authTime, KerberosTime authTime,
...@@ -87,14 +91,17 @@ public class Credentials { ...@@ -87,14 +91,17 @@ public class Credentials {
KerberosTime renewTill, KerberosTime renewTill,
HostAddresses cAddr, HostAddresses cAddr,
AuthorizationData authzData) { AuthorizationData authzData) {
this(new_ticket, new_client, new_server, new_key, new_flags, this(new_ticket, new_client, new_client_alias, new_server,
authTime, new_startTime, new_endTime, renewTill, cAddr); new_server_alias, new_key, new_flags, authTime,
new_startTime, new_endTime, renewTill, cAddr);
this.authzData = authzData; this.authzData = authzData;
} }
public Credentials(Ticket new_ticket, public Credentials(Ticket new_ticket,
PrincipalName new_client, PrincipalName new_client,
PrincipalName new_client_alias,
PrincipalName new_server, PrincipalName new_server,
PrincipalName new_server_alias,
EncryptionKey new_key, EncryptionKey new_key,
TicketFlags new_flags, TicketFlags new_flags,
KerberosTime authTime, KerberosTime authTime,
...@@ -104,7 +111,9 @@ public class Credentials { ...@@ -104,7 +111,9 @@ public class Credentials {
HostAddresses cAddr) { HostAddresses cAddr) {
ticket = new_ticket; ticket = new_ticket;
client = new_client; client = new_client;
clientAlias = new_client_alias;
server = new_server; server = new_server;
serverAlias = new_server_alias;
key = new_key; key = new_key;
flags = new_flags; flags = new_flags;
this.authTime = authTime; this.authTime = authTime;
...@@ -116,7 +125,9 @@ public class Credentials { ...@@ -116,7 +125,9 @@ public class Credentials {
public Credentials(byte[] encoding, public Credentials(byte[] encoding,
String client, String client,
String clientAlias,
String server, String server,
String serverAlias,
byte[] keyBytes, byte[] keyBytes,
int keyType, int keyType,
boolean[] flags, boolean[] flags,
...@@ -127,7 +138,11 @@ public class Credentials { ...@@ -127,7 +138,11 @@ public class Credentials {
InetAddress[] cAddrs) throws KrbException, IOException { InetAddress[] cAddrs) throws KrbException, IOException {
this(new Ticket(encoding), this(new Ticket(encoding),
new PrincipalName(client, PrincipalName.KRB_NT_PRINCIPAL), new PrincipalName(client, PrincipalName.KRB_NT_PRINCIPAL),
(clientAlias == null? null : new PrincipalName(clientAlias,
PrincipalName.KRB_NT_PRINCIPAL)),
new PrincipalName(server, PrincipalName.KRB_NT_SRV_INST), new PrincipalName(server, PrincipalName.KRB_NT_SRV_INST),
(serverAlias == null? null : new PrincipalName(serverAlias,
PrincipalName.KRB_NT_SRV_INST)),
new EncryptionKey(keyType, keyBytes), new EncryptionKey(keyType, keyBytes),
(flags == null? null: new TicketFlags(flags)), (flags == null? null: new TicketFlags(flags)),
(authTime == null? null: new KerberosTime(authTime)), (authTime == null? null: new KerberosTime(authTime)),
...@@ -152,10 +167,18 @@ public class Credentials { ...@@ -152,10 +167,18 @@ public class Credentials {
return client; return client;
} }
public final PrincipalName getClientAlias() {
return clientAlias;
}
public final PrincipalName getServer() { public final PrincipalName getServer() {
return server; return server;
} }
public final PrincipalName getServerAlias() {
return serverAlias;
}
public final EncryptionKey getSessionKey() { public final EncryptionKey getSessionKey() {
return key; return key;
} }
...@@ -271,6 +294,7 @@ public class Credentials { ...@@ -271,6 +294,7 @@ public class Credentials {
return new KrbTgsReq(options, return new KrbTgsReq(options,
this, this,
server, server,
serverAlias,
null, // from null, // from
null, // till null, // till
null, // rtime null, // rtime
...@@ -488,7 +512,11 @@ public class Credentials { ...@@ -488,7 +512,11 @@ public class Credentials {
public static void printDebug(Credentials c) { public static void printDebug(Credentials c) {
System.out.println(">>> DEBUG: ----Credentials----"); System.out.println(">>> DEBUG: ----Credentials----");
System.out.println("\tclient: " + c.client.toString()); System.out.println("\tclient: " + c.client.toString());
if (c.clientAlias != null)
System.out.println("\tclient alias: " + c.clientAlias.toString());
System.out.println("\tserver: " + c.server.toString()); System.out.println("\tserver: " + c.server.toString());
if (c.serverAlias != null)
System.out.println("\tserver alias: " + c.serverAlias.toString());
System.out.println("\tticket: sname: " + c.ticket.sname.toString()); System.out.println("\tticket: sname: " + c.ticket.sname.toString());
if (c.startTime != null) { if (c.startTime != null) {
System.out.println("\tstartTime: " + c.startTime.getTime()); System.out.println("\tstartTime: " + c.startTime.getTime());
...@@ -516,7 +544,11 @@ public class Credentials { ...@@ -516,7 +544,11 @@ public class Credentials {
public String toString() { public String toString() {
StringBuffer buffer = new StringBuffer("Credentials:"); StringBuffer buffer = new StringBuffer("Credentials:");
buffer.append( "\n client=").append(client); buffer.append( "\n client=").append(client);
if (clientAlias != null)
buffer.append( "\n clientAlias=").append(clientAlias);
buffer.append( "\n server=").append(server); buffer.append( "\n server=").append(server);
if (serverAlias != null)
buffer.append( "\n serverAlias=").append(serverAlias);
if (authTime != null) { if (authTime != null) {
buffer.append("\n authTime=").append(authTime); buffer.append("\n authTime=").append(authTime);
} }
...@@ -531,4 +563,23 @@ public class Credentials { ...@@ -531,4 +563,23 @@ public class Credentials {
return buffer.toString(); return buffer.toString();
} }
public sun.security.krb5.internal.ccache.Credentials toCCacheCreds() {
return new sun.security.krb5.internal.ccache.Credentials(
getClient(), getServer(),
getSessionKey(),
date2kt(getAuthTime()),
date2kt(getStartTime()),
date2kt(getEndTime()),
date2kt(getRenewTill()),
false,
flags,
new HostAddresses(getClientAddresses()),
getAuthzData(),
getTicket(),
null);
}
private static KerberosTime date2kt(Date d) {
return d == null ? null : new KerberosTime(d);
}
} }
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
package sun.security.krb5; package sun.security.krb5;
import javax.security.auth.kerberos.KerberosPrincipal;
import javax.security.auth.kerberos.KerberosTicket; import javax.security.auth.kerberos.KerberosTicket;
import javax.security.auth.kerberos.KeyTab; import javax.security.auth.kerberos.KeyTab;
...@@ -39,6 +40,14 @@ public interface JavaxSecurityAuthKerberosAccess { ...@@ -39,6 +40,14 @@ public interface JavaxSecurityAuthKerberosAccess {
public sun.security.krb5.internal.ktab.KeyTab keyTabTakeSnapshot( public sun.security.krb5.internal.ktab.KeyTab keyTabTakeSnapshot(
KeyTab ktab); KeyTab ktab);
public KerberosPrincipal kerberosTicketGetClientAlias(KerberosTicket t);
public void kerberosTicketSetClientAlias(KerberosTicket t, KerberosPrincipal a);
public KerberosPrincipal kerberosTicketGetServerAlias(KerberosTicket t);
public void kerberosTicketSetServerAlias(KerberosTicket t, KerberosPrincipal a);
/** /**
* Returns the proxy for a KerberosTicket. * Returns the proxy for a KerberosTicket.
*/ */
......
/* /*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -361,7 +361,9 @@ public class KrbApReq { ...@@ -361,7 +361,9 @@ public class KrbApReq {
creds = new Credentials( creds = new Credentials(
apReqMessg.ticket, apReqMessg.ticket,
authenticator.cname, authenticator.cname,
null,
apReqMessg.ticket.sname, apReqMessg.ticket.sname,
null,
enc_ticketPart.key, enc_ticketPart.key,
enc_ticketPart.flags, enc_ticketPart.flags,
enc_ticketPart.authtime, enc_ticketPart.authtime,
......
/* /*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -118,7 +118,7 @@ class KrbAsRep extends KrbKdcRep { ...@@ -118,7 +118,7 @@ class KrbAsRep extends KrbKdcRep {
"Cannot find key for type/kvno to decrypt AS REP - " + "Cannot find key for type/kvno to decrypt AS REP - " +
EType.toString(encPartKeyType) + "/" + encPartKvno); EType.toString(encPartKeyType) + "/" + encPartKvno);
} }
decrypt(dkey, asReq); decrypt(dkey, asReq, cname);
} }
/** /**
...@@ -136,7 +136,7 @@ class KrbAsRep extends KrbKdcRep { ...@@ -136,7 +136,7 @@ class KrbAsRep extends KrbKdcRep {
password, password,
encPartKeyType, encPartKeyType,
PAData.getSaltAndParams(encPartKeyType, rep.pAData)); PAData.getSaltAndParams(encPartKeyType, rep.pAData));
decrypt(dkey, asReq); decrypt(dkey, asReq, cname);
} }
/** /**
...@@ -144,7 +144,8 @@ class KrbAsRep extends KrbKdcRep { ...@@ -144,7 +144,8 @@ class KrbAsRep extends KrbKdcRep {
* @param dkey the decryption key to use * @param dkey the decryption key to use
* @param asReq the original AS-REQ sent, used to validate AS-REP * @param asReq the original AS-REQ sent, used to validate AS-REP
*/ */
private void decrypt(EncryptionKey dkey, KrbAsReq asReq) private void decrypt(EncryptionKey dkey, KrbAsReq asReq,
PrincipalName cname)
throws KrbException, Asn1Exception, IOException { throws KrbException, Asn1Exception, IOException {
byte[] enc_as_rep_bytes = rep.encPart.decrypt(dkey, byte[] enc_as_rep_bytes = rep.encPart.decrypt(dkey,
KeyUsage.KU_ENC_AS_REP_PART); KeyUsage.KU_ENC_AS_REP_PART);
...@@ -155,12 +156,18 @@ class KrbAsRep extends KrbKdcRep { ...@@ -155,12 +156,18 @@ class KrbAsRep extends KrbKdcRep {
rep.encKDCRepPart = enc_part; rep.encKDCRepPart = enc_part;
ASReq req = asReq.getMessage(); ASReq req = asReq.getMessage();
check(true, req, rep); check(true, req, rep, dkey);
PrincipalName clientAlias = cname;
if (clientAlias.equals(rep.cname))
clientAlias = null;
creds = new Credentials( creds = new Credentials(
rep.ticket, rep.ticket,
req.reqBody.cname, rep.cname,
clientAlias,
enc_part.sname, enc_part.sname,
null, // No server alias expected in a TGT
enc_part.key, enc_part.key,
enc_part.flags, enc_part.flags,
enc_part.authtime, enc_part.authtime,
......
/* /*
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -35,6 +35,8 @@ import sun.security.krb5.internal.*; ...@@ -35,6 +35,8 @@ import sun.security.krb5.internal.*;
import sun.security.krb5.internal.crypto.Nonce; import sun.security.krb5.internal.crypto.Nonce;
import sun.security.krb5.internal.crypto.KeyUsage; import sun.security.krb5.internal.crypto.KeyUsage;
import java.io.IOException; import java.io.IOException;
import java.time.Instant;
import java.util.Arrays;
/** /**
* This class encapsulates the KRB-AS-REQ message that the client * This class encapsulates the KRB-AS-REQ message that the client
...@@ -57,14 +59,14 @@ public class KrbAsReq { ...@@ -57,14 +59,14 @@ public class KrbAsReq {
KerberosTime till, // ok, will use KerberosTime till, // ok, will use
KerberosTime rtime, // ok KerberosTime rtime, // ok
int[] eTypes, // NO int[] eTypes, // NO
HostAddresses addresses // ok HostAddresses addresses, // ok
PAData[] extraPAs // ok
) )
throws KrbException, IOException { throws KrbException, IOException {
if (options == null) { if (options == null) {
options = new KDCOptions(); options = new KDCOptions();
} }
// check if they are valid arguments. The optional fields should be // check if they are valid arguments. The optional fields should be
// consistent with settings in KDCOptions. Mar 17 2000 // consistent with settings in KDCOptions. Mar 17 2000
if (options.get(KDCOptions.FORWARDED) || if (options.get(KDCOptions.FORWARDED) ||
...@@ -82,12 +84,6 @@ public class KrbAsReq { ...@@ -82,12 +84,6 @@ public class KrbAsReq {
} else { } else {
if (from != null) from = null; if (from != null) from = null;
} }
if (options.get(KDCOptions.RENEWABLE)) {
// if (rtime == null)
// throw new KrbException(Krb5.KRB_AP_ERR_REQ_OPTIONS);
} else {
if (rtime != null) rtime = null;
}
PAData[] paData = null; PAData[] paData = null;
if (pakey != null) { if (pakey != null) {
...@@ -99,6 +95,15 @@ public class KrbAsReq { ...@@ -99,6 +95,15 @@ public class KrbAsReq {
paData[0] = new PAData( Krb5.PA_ENC_TIMESTAMP, paData[0] = new PAData( Krb5.PA_ENC_TIMESTAMP,
encTs.asn1Encode()); encTs.asn1Encode());
} }
if (extraPAs != null && extraPAs.length > 0) {
if (paData == null) {
paData = new PAData[extraPAs.length];
} else {
paData = Arrays.copyOf(paData, paData.length + extraPAs.length);
}
System.arraycopy(extraPAs, 0, paData,
paData.length - extraPAs.length, extraPAs.length);
}
if (cname.getRealm() == null) { if (cname.getRealm() == null) {
throw new RealmException(Krb5.REALM_NULL, throw new RealmException(Krb5.REALM_NULL,
...@@ -109,8 +114,10 @@ public class KrbAsReq { ...@@ -109,8 +114,10 @@ public class KrbAsReq {
System.out.println(">>> KrbAsReq creating message"); System.out.println(">>> KrbAsReq creating message");
} }
Config cfg = Config.getInstance();
// check to use addresses in tickets // check to use addresses in tickets
if (addresses == null && Config.getInstance().useAddresses()) { if (addresses == null && cfg.useAddresses()) {
addresses = HostAddresses.getLocalAddresses(); addresses = HostAddresses.getLocalAddresses();
} }
...@@ -120,7 +127,26 @@ public class KrbAsReq { ...@@ -120,7 +127,26 @@ public class KrbAsReq {
} }
if (till == null) { if (till == null) {
till = new KerberosTime(0); // Choose KDC maximum allowed String d = cfg.get("libdefaults", "ticket_lifetime");
if (d != null) {
till = new KerberosTime(Instant.now().plusSeconds(Config.duration(d)));
} else {
till = new KerberosTime(0); // Choose KDC maximum allowed
}
}
if (rtime == null) {
String d = cfg.get("libdefaults", "renew_lifetime");
if (d != null) {
rtime = new KerberosTime(Instant.now().plusSeconds(Config.duration(d)));
}
}
if (rtime != null) {
options.set(KDCOptions.RENEWABLE, true);
if (till.greaterThan(rtime)) {
rtime = till;
}
} }
// enc-authorization-data and additional-tickets never in AS-REQ // enc-authorization-data and additional-tickets never in AS-REQ
......
/* /*
* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -68,6 +68,7 @@ public final class KrbAsReqBuilder { ...@@ -68,6 +68,7 @@ public final class KrbAsReqBuilder {
// Common data for AS-REQ fields // Common data for AS-REQ fields
private KDCOptions options; private KDCOptions options;
private PrincipalName cname; private PrincipalName cname;
private PrincipalName refCname; // May be changed by referrals
private PrincipalName sname; private PrincipalName sname;
private KerberosTime from; private KerberosTime from;
private KerberosTime till; private KerberosTime till;
...@@ -100,6 +101,7 @@ public final class KrbAsReqBuilder { ...@@ -100,6 +101,7 @@ public final class KrbAsReqBuilder {
private void init(PrincipalName cname) private void init(PrincipalName cname)
throws KrbException { throws KrbException {
this.cname = cname; this.cname = cname;
this.refCname = cname;
state = State.INIT; state = State.INIT;
} }
...@@ -224,6 +226,16 @@ public final class KrbAsReqBuilder { ...@@ -224,6 +226,16 @@ public final class KrbAsReqBuilder {
this.options = options; this.options = options;
} }
public void setTill(KerberosTime till) {
checkState(State.INIT, "Cannot specify till");
this.till = till;
}
public void setRTime(KerberosTime rtime) {
checkState(State.INIT, "Cannot specify rtime");
this.rtime = rtime;
}
/** /**
* Sets or clears target. If cleared, KrbAsReq might choose krbtgt * Sets or clears target. If cleared, KrbAsReq might choose krbtgt
* for cname realm * for cname realm
...@@ -252,7 +264,9 @@ public final class KrbAsReqBuilder { ...@@ -252,7 +264,9 @@ public final class KrbAsReqBuilder {
* @throws KrbException * @throws KrbException
* @throws IOException * @throws IOException
*/ */
private KrbAsReq build(EncryptionKey key) throws KrbException, IOException { private KrbAsReq build(EncryptionKey key, ReferralsState referralsState)
throws KrbException, IOException {
PAData[] extraPAs = null;
int[] eTypes; int[] eTypes;
if (password != null) { if (password != null) {
eTypes = EType.getDefaults("default_tkt_enctypes"); eTypes = EType.getDefaults("default_tkt_enctypes");
...@@ -262,15 +276,24 @@ public final class KrbAsReqBuilder { ...@@ -262,15 +276,24 @@ public final class KrbAsReqBuilder {
ks); ks);
for (EncryptionKey k: ks) k.destroy(); for (EncryptionKey k: ks) k.destroy();
} }
options = (options == null) ? new KDCOptions() : options;
if (referralsState.isEnabled()) {
options.set(KDCOptions.CANONICALIZE, true);
extraPAs = new PAData[]{ new PAData(Krb5.PA_REQ_ENC_PA_REP,
new byte[]{}) };
} else {
options.set(KDCOptions.CANONICALIZE, false);
}
return new KrbAsReq(key, return new KrbAsReq(key,
options, options,
cname, refCname,
sname, sname,
from, from,
till, till,
rtime, rtime,
eTypes, eTypes,
addresses); addresses,
extraPAs);
} }
/** /**
...@@ -308,11 +331,15 @@ public final class KrbAsReqBuilder { ...@@ -308,11 +331,15 @@ public final class KrbAsReqBuilder {
*/ */
private KrbAsReqBuilder send() throws KrbException, IOException { private KrbAsReqBuilder send() throws KrbException, IOException {
boolean preAuthFailedOnce = false; boolean preAuthFailedOnce = false;
KdcComm comm = new KdcComm(cname.getRealmAsString()); KdcComm comm = null;
EncryptionKey pakey = null; EncryptionKey pakey = null;
ReferralsState referralsState = new ReferralsState();
while (true) { while (true) {
if (referralsState.refreshComm()) {
comm = new KdcComm(refCname.getRealmAsString());
}
try { try {
req = build(pakey); req = build(pakey, referralsState);
rep = new KrbAsRep(comm.send(req.encoding())); rep = new KrbAsRep(comm.send(req.encoding()));
return this; return this;
} catch (KrbException ke) { } catch (KrbException ke) {
...@@ -341,12 +368,71 @@ public final class KrbAsReqBuilder { ...@@ -341,12 +368,71 @@ public final class KrbAsReqBuilder {
} }
paList = kerr.getPA(); // Update current paList paList = kerr.getPA(); // Update current paList
} else { } else {
if (referralsState.handleError(ke)) {
pakey = null;
preAuthFailedOnce = false;
continue;
}
throw ke; throw ke;
} }
} }
} }
} }
private final class ReferralsState {
private boolean enabled;
private int count;
private boolean refreshComm;
ReferralsState() throws KrbException {
if (Config.DISABLE_REFERRALS) {
if (refCname.getNameType() == PrincipalName.KRB_NT_ENTERPRISE) {
throw new KrbException("NT-ENTERPRISE principals only allowed" +
" when referrals are enabled.");
}
enabled = false;
} else {
enabled = true;
}
refreshComm = true;
}
boolean handleError(KrbException ke) throws RealmException {
if (enabled) {
if (ke.returnCode() == Krb5.KRB_ERR_WRONG_REALM) {
Realm referredRealm = ke.getError().getClientRealm();
if (req.getMessage().reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) &&
referredRealm != null && referredRealm.toString().length() > 0 &&
count < Config.MAX_REFERRALS) {
refCname = new PrincipalName(refCname.getNameType(),
refCname.getNameStrings(), referredRealm);
refreshComm = true;
count++;
return true;
}
}
if (count < Config.MAX_REFERRALS &&
refCname.getNameType() != PrincipalName.KRB_NT_ENTERPRISE) {
// Server may raise an error if CANONICALIZE is true.
// Try CANONICALIZE false.
enabled = false;
return true;
}
}
return false;
}
boolean refreshComm() {
boolean retRefreshComm = refreshComm;
refreshComm = false;
return retRefreshComm;
}
boolean isEnabled() {
return enabled;
}
}
/** /**
* Performs AS-REQ send and AS-REP receive. * Performs AS-REQ send and AS-REP receive.
* Maybe a state is needed here, to divide prepare process and getCreds. * Maybe a state is needed here, to divide prepare process and getCreds.
......
/* /*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -34,6 +34,7 @@ package sun.security.krb5; ...@@ -34,6 +34,7 @@ package sun.security.krb5;
import sun.security.krb5.internal.*; import sun.security.krb5.internal.*;
import sun.security.krb5.internal.crypto.KeyUsage; import sun.security.krb5.internal.crypto.KeyUsage;
import java.io.IOException; import java.io.IOException;
import sun.security.util.DerValue; import sun.security.util.DerValue;
/** /**
...@@ -62,7 +63,6 @@ public class KrbCred { ...@@ -62,7 +63,6 @@ public class KrbCred {
PrincipalName client = tgt.getClient(); PrincipalName client = tgt.getClient();
PrincipalName tgService = tgt.getServer(); PrincipalName tgService = tgt.getServer();
PrincipalName server = serviceTicket.getServer();
if (!serviceTicket.getClient().equals(client)) if (!serviceTicket.getClient().equals(client))
throw new KrbException(Krb5.KRB_ERR_GENERIC, throw new KrbException(Krb5.KRB_ERR_GENERIC,
"Client principal does not match"); "Client principal does not match");
...@@ -75,14 +75,10 @@ public class KrbCred { ...@@ -75,14 +75,10 @@ public class KrbCred {
options.set(KDCOptions.FORWARDED, true); options.set(KDCOptions.FORWARDED, true);
options.set(KDCOptions.FORWARDABLE, true); options.set(KDCOptions.FORWARDABLE, true);
HostAddresses sAddrs = null;
// XXX Also NT_GSS_KRB5_PRINCIPAL can be a host based principal
// GSSName.NT_HOSTBASED_SERVICE should display with KRB_NT_SRV_HST
if (server.getNameType() == PrincipalName.KRB_NT_SRV_HST)
sAddrs= new HostAddresses(server);
KrbTgsReq tgsReq = new KrbTgsReq(options, tgt, tgService, KrbTgsReq tgsReq = new KrbTgsReq(options, tgt, tgService,
null, null, null, null, sAddrs, null, null, null); null, null, null, null, null,
null, // No easy way to get addresses right
null, null, null);
credMessg = createMessage(tgsReq.sendAndGetCreds(), key); credMessg = createMessage(tgsReq.sendAndGetCreds(), key);
obuf = credMessg.asn1Encode(); obuf = credMessg.asn1Encode();
...@@ -94,7 +90,6 @@ public class KrbCred { ...@@ -94,7 +90,6 @@ public class KrbCred {
EncryptionKey sessionKey EncryptionKey sessionKey
= delegatedCreds.getSessionKey(); = delegatedCreds.getSessionKey();
PrincipalName princ = delegatedCreds.getClient(); PrincipalName princ = delegatedCreds.getClient();
Realm realm = princ.getRealm();
PrincipalName tgService = delegatedCreds.getServer(); PrincipalName tgService = delegatedCreds.getServer();
KrbCredInfo credInfo = new KrbCredInfo(sessionKey, KrbCredInfo credInfo = new KrbCredInfo(sessionKey,
...@@ -157,7 +152,7 @@ public class KrbCred { ...@@ -157,7 +152,7 @@ public class KrbCred {
+ " endtime=" + endtime + " endtime=" + endtime
+ "renewTill=" + renewTill); + "renewTill=" + renewTill);
} }
creds = new Credentials(ticket, pname, sname, credInfoKey, creds = new Credentials(ticket, pname, null, sname, null, credInfoKey,
flags, authtime, starttime, endtime, renewTill, caddr); flags, authtime, starttime, endtime, renewTill, caddr);
} }
......
...@@ -31,23 +31,41 @@ ...@@ -31,23 +31,41 @@
package sun.security.krb5; package sun.security.krb5;
import sun.security.krb5.internal.*; import sun.security.krb5.internal.*;
import sun.security.krb5.internal.crypto.KeyUsage;
import sun.security.util.DerInputStream;
abstract class KrbKdcRep { abstract class KrbKdcRep {
static void check( static void check(
boolean isAsReq, boolean isAsReq,
KDCReq req, KDCReq req,
KDCRep rep KDCRep rep,
EncryptionKey replyKey
) throws KrbApErrException { ) throws KrbApErrException {
if (isAsReq && !req.reqBody.cname.equals(rep.cname)) { // cname change in AS-REP is allowed only if the client
// sent CANONICALIZE and the server supports RFC 6806 - Section 11
// FAST scheme (ENC-PA-REP flag).
if (isAsReq && !req.reqBody.cname.equals(rep.cname) &&
(!req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) ||
!rep.encKDCRepPart.flags.get(Krb5.TKT_OPTS_ENC_PA_REP))) {
rep.encKDCRepPart.key.destroy(); rep.encKDCRepPart.key.destroy();
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED); throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
} }
// sname change in TGS-REP is allowed only if client
// sent CANONICALIZE and new sname is a referral of
// the form krbtgt/TO-REALM.COM@FROM-REALM.COM.
if (!req.reqBody.sname.equals(rep.encKDCRepPart.sname)) { if (!req.reqBody.sname.equals(rep.encKDCRepPart.sname)) {
rep.encKDCRepPart.key.destroy(); String[] snameStrings = rep.encKDCRepPart.sname.getNameStrings();
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED); if (isAsReq || !req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) ||
snameStrings == null || snameStrings.length != 2 ||
!snameStrings[0].equals(PrincipalName.TGS_DEFAULT_SRV_NAME) ||
!rep.encKDCRepPart.sname.getRealmString().equals(
req.reqBody.sname.getRealmString())) {
rep.encKDCRepPart.key.destroy();
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
}
} }
if (req.reqBody.getNonce() != rep.encKDCRepPart.nonce) { if (req.reqBody.getNonce() != rep.encKDCRepPart.nonce) {
...@@ -82,49 +100,84 @@ abstract class KrbKdcRep { ...@@ -82,49 +100,84 @@ abstract class KrbKdcRep {
!rep.encKDCRepPart.flags.get(KDCOptions.RENEWABLE)) { !rep.encKDCRepPart.flags.get(KDCOptions.RENEWABLE)) {
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED); throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
} }
if ((req.reqBody.from == null) || req.reqBody.from.isZero())
if ((req.reqBody.from == null) || req.reqBody.from.isZero()) {
// verify this is allowed // verify this is allowed
if ((rep.encKDCRepPart.starttime != null) && if ((rep.encKDCRepPart.starttime != null) &&
!rep.encKDCRepPart.starttime.inClockSkew()) { !rep.encKDCRepPart.starttime.inClockSkew()) {
rep.encKDCRepPart.key.destroy(); rep.encKDCRepPart.key.destroy();
throw new KrbApErrException(Krb5.KRB_AP_ERR_SKEW); throw new KrbApErrException(Krb5.KRB_AP_ERR_SKEW);
} }
}
if ((req.reqBody.from != null) && !req.reqBody.from.isZero()) if ((req.reqBody.from != null) && !req.reqBody.from.isZero()) {
// verify this is allowed // verify this is allowed
if ((rep.encKDCRepPart.starttime != null) && if ((rep.encKDCRepPart.starttime != null) &&
!req.reqBody.from.equals(rep.encKDCRepPart.starttime)) { !req.reqBody.from.equals(rep.encKDCRepPart.starttime)) {
rep.encKDCRepPart.key.destroy(); rep.encKDCRepPart.key.destroy();
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED); throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
} }
}
if (!req.reqBody.till.isZero() && if (!req.reqBody.till.isZero() &&
rep.encKDCRepPart.endtime.greaterThan(req.reqBody.till)) { rep.encKDCRepPart.endtime.greaterThan(req.reqBody.till)) {
rep.encKDCRepPart.key.destroy(); rep.encKDCRepPart.key.destroy();
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED); throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
} }
if (req.reqBody.kdcOptions.get(KDCOptions.RENEWABLE)) // RFC 6806 - Section 11 mechanism check
if (req.reqBody.rtime != null && !req.reqBody.rtime.isZero()) if (rep.encKDCRepPart.flags.get(Krb5.TKT_OPTS_ENC_PA_REP) &&
// verify this is required req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE)) {
if ((rep.encKDCRepPart.renewTill == null) || boolean reqPaReqEncPaRep = false;
rep.encKDCRepPart.renewTill.greaterThan(req.reqBody.rtime) boolean repPaReqEncPaRepValid = false;
) {
rep.encKDCRepPart.key.destroy(); // PA_REQ_ENC_PA_REP only required for AS requests
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED); for (PAData pa : req.pAData) {
if (pa.getType() == Krb5.PA_REQ_ENC_PA_REP) {
reqPaReqEncPaRep = true;
break;
}
}
if (rep.encKDCRepPart.pAData != null) {
for (PAData pa : rep.encKDCRepPart.pAData) {
if (pa.getType() == Krb5.PA_REQ_ENC_PA_REP) {
try {
Checksum repCksum = new Checksum(
new DerInputStream(
pa.getValue()).getDerValue());
// The checksum is inside encKDCRepPart so we don't
// care if it's keyed or not.
repPaReqEncPaRepValid =
repCksum.verifyAnyChecksum(
req.asn1Encode(), replyKey,
KeyUsage.KU_AS_REQ);
} catch (Exception e) {
if (Krb5.DEBUG) {
e.printStackTrace();
}
}
break;
}
} }
}
if (reqPaReqEncPaRep && !repPaReqEncPaRepValid) {
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
}
}
if (req.reqBody.kdcOptions.get(KDCOptions.RENEWABLE_OK) && if (req.reqBody.kdcOptions.get(KDCOptions.RENEWABLE)) {
rep.encKDCRepPart.flags.get(KDCOptions.RENEWABLE)) if (req.reqBody.rtime != null && !req.reqBody.rtime.isZero()) {
if (!req.reqBody.till.isZero()) // verify this is required
// verify this is required
if ((rep.encKDCRepPart.renewTill == null) || if ((rep.encKDCRepPart.renewTill == null) ||
rep.encKDCRepPart.renewTill.greaterThan(req.reqBody.till) rep.encKDCRepPart.renewTill.greaterThan(req.reqBody.rtime)
) { ) {
rep.encKDCRepPart.key.destroy(); rep.encKDCRepPart.key.destroy();
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED); throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
} }
}
}
}
}
} }
/* /*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -84,11 +84,22 @@ public class KrbTgsRep extends KrbKdcRep { ...@@ -84,11 +84,22 @@ public class KrbTgsRep extends KrbKdcRep {
EncTGSRepPart enc_part = new EncTGSRepPart(ref); EncTGSRepPart enc_part = new EncTGSRepPart(ref);
rep.encKDCRepPart = enc_part; rep.encKDCRepPart = enc_part;
check(false, req, rep); check(false, req, rep, tgsReq.tgsReqKey);
PrincipalName serverAlias = tgsReq.getServerAlias();
if (serverAlias != null) {
PrincipalName repSname = enc_part.sname;
if (serverAlias.equals(repSname) ||
isReferralSname(repSname)) {
serverAlias = null;
}
}
this.creds = new Credentials(rep.ticket, this.creds = new Credentials(rep.ticket,
rep.cname, rep.cname,
tgsReq.getClientAlias(),
enc_part.sname, enc_part.sname,
serverAlias,
enc_part.key, enc_part.key,
enc_part.flags, enc_part.flags,
enc_part.authtime, enc_part.authtime,
...@@ -111,4 +122,16 @@ public class KrbTgsRep extends KrbKdcRep { ...@@ -111,4 +122,16 @@ public class KrbTgsRep extends KrbKdcRep {
sun.security.krb5.internal.ccache.Credentials setCredentials() { sun.security.krb5.internal.ccache.Credentials setCredentials() {
return new sun.security.krb5.internal.ccache.Credentials(rep, secondTicket); return new sun.security.krb5.internal.ccache.Credentials(rep, secondTicket);
} }
private static boolean isReferralSname(PrincipalName sname) {
if (sname != null) {
String[] snameStrings = sname.getNameStrings();
if (snameStrings.length == 2 &&
snameStrings[0].equals(
PrincipalName.TGS_DEFAULT_SRV_NAME)) {
return true;
}
}
return false;
}
} }
/* /*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -35,6 +35,7 @@ import sun.security.krb5.internal.*; ...@@ -35,6 +35,7 @@ import sun.security.krb5.internal.*;
import sun.security.krb5.internal.crypto.*; import sun.security.krb5.internal.crypto.*;
import java.io.IOException; import java.io.IOException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.time.Instant;
import java.util.Arrays; import java.util.Arrays;
/** /**
...@@ -44,7 +45,9 @@ import java.util.Arrays; ...@@ -44,7 +45,9 @@ import java.util.Arrays;
public class KrbTgsReq { public class KrbTgsReq {
private PrincipalName princName; private PrincipalName princName;
private PrincipalName clientAlias;
private PrincipalName servName; private PrincipalName servName;
private PrincipalName serverAlias;
private TGSReq tgsReqMessg; private TGSReq tgsReqMessg;
private KerberosTime ctime; private KerberosTime ctime;
private Ticket secondTicket = null; private Ticket secondTicket = null;
...@@ -57,59 +60,26 @@ public class KrbTgsReq { ...@@ -57,59 +60,26 @@ public class KrbTgsReq {
private byte[] ibuf; private byte[] ibuf;
// Used in CredentialsUtil // Used in CredentialsUtil
public KrbTgsReq(Credentials asCreds, public KrbTgsReq(KDCOptions options, Credentials asCreds,
PrincipalName sname) PrincipalName cname, PrincipalName clientAlias,
PrincipalName sname, PrincipalName serverAlias,
Ticket[] additionalTickets, PAData[] extraPAs)
throws KrbException, IOException { throws KrbException, IOException {
this(new KDCOptions(), this(options,
asCreds, asCreds,
sname, cname,
null, // KerberosTime from clientAlias,
null, // KerberosTime till sname,
null, // KerberosTime rtime serverAlias,
null, // eTypes, // null, // int[] eTypes null, // KerberosTime from
null, // HostAddresses addresses null, // KerberosTime till
null, // AuthorizationData authorizationData null, // KerberosTime rtime
null, // Ticket[] additionalTickets null, // int[] eTypes
null); // EncryptionKey subSessionKey null, // HostAddresses addresses
} null, // AuthorizationData authorizationData
additionalTickets,
// S4U2proxy null, // EncryptionKey subKey
public KrbTgsReq(Credentials asCreds, extraPAs);
Ticket second,
PrincipalName sname)
throws KrbException, IOException {
this(KDCOptions.with(KDCOptions.CNAME_IN_ADDL_TKT,
KDCOptions.FORWARDABLE),
asCreds,
sname,
null,
null,
null,
null,
null,
null,
new Ticket[] {second}, // the service ticket
null);
}
// S4U2user
public KrbTgsReq(Credentials asCreds,
PrincipalName sname,
PAData extraPA)
throws KrbException, IOException {
this(KDCOptions.with(KDCOptions.FORWARDABLE),
asCreds,
asCreds.getClient(),
sname,
null,
null,
null,
null,
null,
null,
null,
null,
extraPA); // the PA-FOR-USER
} }
// Called by Credentials, KrbCred // Called by Credentials, KrbCred
...@@ -117,6 +87,7 @@ public class KrbTgsReq { ...@@ -117,6 +87,7 @@ public class KrbTgsReq {
KDCOptions options, KDCOptions options,
Credentials asCreds, Credentials asCreds,
PrincipalName sname, PrincipalName sname,
PrincipalName serverAlias,
KerberosTime from, KerberosTime from,
KerberosTime till, KerberosTime till,
KerberosTime rtime, KerberosTime rtime,
...@@ -125,16 +96,18 @@ public class KrbTgsReq { ...@@ -125,16 +96,18 @@ public class KrbTgsReq {
AuthorizationData authorizationData, AuthorizationData authorizationData,
Ticket[] additionalTickets, Ticket[] additionalTickets,
EncryptionKey subKey) throws KrbException, IOException { EncryptionKey subKey) throws KrbException, IOException {
this(options, asCreds, asCreds.getClient(), sname, this(options, asCreds, asCreds.getClient(), asCreds.getClientAlias(),
from, till, rtime, eTypes, addresses, sname, serverAlias, from, till, rtime, eTypes,
authorizationData, additionalTickets, subKey, null); addresses, authorizationData, additionalTickets, subKey, null);
} }
private KrbTgsReq( private KrbTgsReq(
KDCOptions options, KDCOptions options,
Credentials asCreds, Credentials asCreds,
PrincipalName cname, PrincipalName cname,
PrincipalName clientAlias,
PrincipalName sname, PrincipalName sname,
PrincipalName serverAlias,
KerberosTime from, KerberosTime from,
KerberosTime till, KerberosTime till,
KerberosTime rtime, KerberosTime rtime,
...@@ -143,10 +116,12 @@ public class KrbTgsReq { ...@@ -143,10 +116,12 @@ public class KrbTgsReq {
AuthorizationData authorizationData, AuthorizationData authorizationData,
Ticket[] additionalTickets, Ticket[] additionalTickets,
EncryptionKey subKey, EncryptionKey subKey,
PAData extraPA) throws KrbException, IOException { PAData[] extraPAs) throws KrbException, IOException {
princName = cname; princName = cname;
this.clientAlias = clientAlias;
servName = sname; servName = sname;
this.serverAlias = serverAlias;
ctime = KerberosTime.now(); ctime = KerberosTime.now();
// check if they are valid arguments. The optional fields // check if they are valid arguments. The optional fields
...@@ -216,7 +191,7 @@ public class KrbTgsReq { ...@@ -216,7 +191,7 @@ public class KrbTgsReq {
authorizationData, authorizationData,
additionalTickets, additionalTickets,
subKey, subKey,
extraPA); extraPAs);
obuf = tgsReqMessg.asn1Encode(); obuf = tgsReqMessg.asn1Encode();
// XXX We need to revisit this to see if can't move it // XXX We need to revisit this to see if can't move it
...@@ -282,11 +257,16 @@ public class KrbTgsReq { ...@@ -282,11 +257,16 @@ public class KrbTgsReq {
AuthorizationData authorizationData, AuthorizationData authorizationData,
Ticket[] additionalTickets, Ticket[] additionalTickets,
EncryptionKey subKey, EncryptionKey subKey,
PAData extraPA) PAData[] extraPAs)
throws IOException, KrbException, UnknownHostException { throws IOException, KrbException, UnknownHostException {
KerberosTime req_till = null; KerberosTime req_till = null;
if (till == null) { if (till == null) {
req_till = new KerberosTime(0); String d = Config.getInstance().get("libdefaults", "ticket_lifetime");
if (d != null) {
req_till = new KerberosTime(Instant.now().plusSeconds(Config.duration(d)));
} else {
req_till = new KerberosTime(0); // Choose KDC maximum allowed
}
} else { } else {
req_till = till; req_till = till;
} }
...@@ -340,26 +320,8 @@ public class KrbTgsReq { ...@@ -340,26 +320,8 @@ public class KrbTgsReq {
byte[] temp = reqBody.asn1Encode(Krb5.KRB_TGS_REQ); byte[] temp = reqBody.asn1Encode(Krb5.KRB_TGS_REQ);
// if the checksum type is one of the keyed checksum types, // if the checksum type is one of the keyed checksum types,
// use session key. // use session key.
Checksum cksum; Checksum cksum = new Checksum(Checksum.CKSUMTYPE_DEFAULT, temp, key,
switch (Checksum.CKSUMTYPE_DEFAULT) {
case Checksum.CKSUMTYPE_RSA_MD4_DES:
case Checksum.CKSUMTYPE_DES_MAC:
case Checksum.CKSUMTYPE_DES_MAC_K:
case Checksum.CKSUMTYPE_RSA_MD4_DES_K:
case Checksum.CKSUMTYPE_RSA_MD5_DES:
case Checksum.CKSUMTYPE_HMAC_SHA1_DES3_KD:
case Checksum.CKSUMTYPE_HMAC_MD5_ARCFOUR:
case Checksum.CKSUMTYPE_HMAC_SHA1_96_AES128:
case Checksum.CKSUMTYPE_HMAC_SHA1_96_AES256:
cksum = new Checksum(Checksum.CKSUMTYPE_DEFAULT, temp, key,
KeyUsage.KU_PA_TGS_REQ_CKSUM); KeyUsage.KU_PA_TGS_REQ_CKSUM);
break;
case Checksum.CKSUMTYPE_CRC32:
case Checksum.CKSUMTYPE_RSA_MD4:
case Checksum.CKSUMTYPE_RSA_MD5:
default:
cksum = new Checksum(Checksum.CKSUMTYPE_DEFAULT, temp);
}
// Usage will be KeyUsage.KU_PA_TGS_REQ_AUTHENTICATOR // Usage will be KeyUsage.KU_PA_TGS_REQ_AUTHENTICATOR
...@@ -375,11 +337,14 @@ public class KrbTgsReq { ...@@ -375,11 +337,14 @@ public class KrbTgsReq {
null).getMessage(); null).getMessage();
PAData tgsPAData = new PAData(Krb5.PA_TGS_REQ, tgs_ap_req); PAData tgsPAData = new PAData(Krb5.PA_TGS_REQ, tgs_ap_req);
return new TGSReq( PAData[] pa;
extraPA != null ? if (extraPAs != null) {
new PAData[] {extraPA, tgsPAData } : pa = Arrays.copyOf(extraPAs, extraPAs.length + 1);
new PAData[] {tgsPAData}, pa[extraPAs.length] = tgsPAData;
reqBody); } else {
pa = new PAData[] {tgsPAData};
}
return new TGSReq(pa, reqBody);
} }
TGSReq getMessage() { TGSReq getMessage() {
...@@ -390,6 +355,14 @@ public class KrbTgsReq { ...@@ -390,6 +355,14 @@ public class KrbTgsReq {
return secondTicket; return secondTicket;
} }
PrincipalName getClientAlias() {
return clientAlias;
}
PrincipalName getServerAlias() {
return serverAlias;
}
private static void debug(String message) { private static void debug(String message) {
// System.err.println(">>> KrbTgsReq: " + message); // System.err.println(">>> KrbTgsReq: " + message);
} }
......
/* /*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -90,6 +90,11 @@ public class PrincipalName implements Cloneable { ...@@ -90,6 +90,11 @@ public class PrincipalName implements Cloneable {
*/ */
public static final int KRB_NT_UID = 5; public static final int KRB_NT_UID = 5;
/**
* Enterprise name (alias)
*/
public static final int KRB_NT_ENTERPRISE = 10;
/** /**
* TGS Name * TGS Name
*/ */
...@@ -454,6 +459,7 @@ public class PrincipalName implements Cloneable { ...@@ -454,6 +459,7 @@ public class PrincipalName implements Cloneable {
case KRB_NT_SRV_INST: case KRB_NT_SRV_INST:
case KRB_NT_SRV_XHST: case KRB_NT_SRV_XHST:
case KRB_NT_UID: case KRB_NT_UID:
case KRB_NT_ENTERPRISE:
nameStrings = nameParts; nameStrings = nameParts;
nameType = type; nameType = type;
if (realm != null) { if (realm != null) {
...@@ -547,7 +553,9 @@ public class PrincipalName implements Cloneable { ...@@ -547,7 +553,9 @@ public class PrincipalName implements Cloneable {
for (int i = 0; i < nameStrings.length; i++) { for (int i = 0; i < nameStrings.length; i++) {
if (i > 0) if (i > 0)
str.append("/"); str.append("/");
str.append(nameStrings[i]); String n = nameStrings[i];
n = n.replace("@", "\\@");
str.append(n);
} }
str.append("@"); str.append("@");
str.append(nameRealm.toString()); str.append(nameRealm.toString());
......
...@@ -47,7 +47,8 @@ public class EncASRepPart extends EncKDCRepPart { ...@@ -47,7 +47,8 @@ public class EncASRepPart extends EncKDCRepPart {
KerberosTime new_endtime, KerberosTime new_endtime,
KerberosTime new_renewTill, KerberosTime new_renewTill,
PrincipalName new_sname, PrincipalName new_sname,
HostAddresses new_caddr) { HostAddresses new_caddr,
PAData[] new_pAData) {
super( super(
new_key, new_key,
new_lastReq, new_lastReq,
...@@ -60,6 +61,7 @@ public class EncASRepPart extends EncKDCRepPart { ...@@ -60,6 +61,7 @@ public class EncASRepPart extends EncKDCRepPart {
new_renewTill, new_renewTill,
new_sname, new_sname,
new_caddr, new_caddr,
new_pAData,
Krb5.KRB_ENC_AS_REP_PART Krb5.KRB_ENC_AS_REP_PART
); );
//may need to use Krb5.KRB_ENC_TGS_REP_PART to mimic //may need to use Krb5.KRB_ENC_TGS_REP_PART to mimic
......
...@@ -46,7 +46,8 @@ public class EncTGSRepPart extends EncKDCRepPart { ...@@ -46,7 +46,8 @@ public class EncTGSRepPart extends EncKDCRepPart {
KerberosTime new_endtime, KerberosTime new_endtime,
KerberosTime new_renewTill, KerberosTime new_renewTill,
PrincipalName new_sname, PrincipalName new_sname,
HostAddresses new_caddr) { HostAddresses new_caddr,
PAData[] new_pAData) {
super( super(
new_key, new_key,
new_lastReq, new_lastReq,
...@@ -59,6 +60,7 @@ public class EncTGSRepPart extends EncKDCRepPart { ...@@ -59,6 +60,7 @@ public class EncTGSRepPart extends EncKDCRepPart {
new_renewTill, new_renewTill,
new_sname, new_sname,
new_caddr, new_caddr,
new_pAData,
Krb5.KRB_ENC_TGS_REP_PART); Krb5.KRB_ENC_TGS_REP_PART);
} }
......
...@@ -39,6 +39,7 @@ import java.net.Inet4Address; ...@@ -39,6 +39,7 @@ import java.net.Inet4Address;
import java.net.Inet6Address; import java.net.Inet6Address;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
/** /**
* Implements the ASN.1 HostAddress type. * Implements the ASN.1 HostAddress type.
...@@ -295,4 +296,11 @@ public class HostAddress implements Cloneable { ...@@ -295,4 +296,11 @@ public class HostAddress implements Cloneable {
} }
} }
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(Arrays.toString(address));
sb.append('(').append(addrType).append(')');
return sb.toString();
}
} }
...@@ -140,6 +140,7 @@ public class KDCOptions extends KerberosFlags { ...@@ -140,6 +140,7 @@ public class KDCOptions extends KerberosFlags {
public static final int UNUSED10 = 10; public static final int UNUSED10 = 10;
public static final int UNUSED11 = 11; public static final int UNUSED11 = 11;
public static final int CNAME_IN_ADDL_TKT = 14; public static final int CNAME_IN_ADDL_TKT = 14;
public static final int CANONICALIZE = 15;
public static final int RENEWABLE_OK = 27; public static final int RENEWABLE_OK = 27;
public static final int ENC_TKT_IN_SKEY = 28; public static final int ENC_TKT_IN_SKEY = 28;
public static final int RENEW = 30; public static final int RENEW = 30;
...@@ -160,7 +161,8 @@ public class KDCOptions extends KerberosFlags { ...@@ -160,7 +161,8 @@ public class KDCOptions extends KerberosFlags {
"UNUSED11", //11; "UNUSED11", //11;
null,null, null,null,
"CNAME_IN_ADDL_TKT",//14; "CNAME_IN_ADDL_TKT",//14;
null,null,null,null,null,null,null,null,null,null,null,null, "CANONICALIZE", //15;
null,null,null,null,null,null,null,null,null,null,null,
"RENEWABLE_OK", //27; "RENEWABLE_OK", //27;
"ENC_TKT_IN_SKEY", //28; "ENC_TKT_IN_SKEY", //28;
null, null,
......
...@@ -38,6 +38,7 @@ import sun.security.util.DerOutputStream; ...@@ -38,6 +38,7 @@ import sun.security.util.DerOutputStream;
import sun.security.util.DerValue; import sun.security.util.DerValue;
import java.io.IOException; import java.io.IOException;
import java.time.Instant;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.TimeZone; import java.util.TimeZone;
...@@ -128,6 +129,14 @@ public class KerberosTime { ...@@ -128,6 +129,14 @@ public class KerberosTime {
this(time.getTime(), 0); this(time.getTime(), 0);
} }
/**
* Creates a KerberosTime object from an Instant object
*/
public KerberosTime(Instant instant) {
this(instant.getEpochSecond()*1000 + instant.getNano()/1000000L,
instant.getNano()/1000%1000);
}
/** /**
* Creates a KerberosTime object for now. It uses System.nanoTime() * Creates a KerberosTime object for now. It uses System.nanoTime()
* to get a more precise time than "new Date()". * to get a more precise time than "new Date()".
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册