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

Merge tag 'jdk8u242-ga'

......@@ -1005,6 +1005,16 @@ c7a97c9b7e5932d651eda37c8a907311818491d7 jdk8u222-b07
60eca04567a6d214aa60dd16306f4854bd41b273 jdk8u232-b03
3ef3348195ffeb3c268af4a43928f2f09c5fa83a jdk8u232-b04
6d60b8cf1bd4a5fa371b1ddad9d186ff546b25f5 jdk8u232-b05
1e8cdf311133ecde0ccae37e6137e49adc6164fb jdk8u242-b00
5d57817931e1f5b6a460158342f132ea348e14ef jdk8u232-b06
3560e0ebe876ce658c5261070fe728e47994210f jdk8u232-b07
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.
--------------------------------------------------------------------------------
%% 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.
--- begin of LICENSE ---
Copyright (c) 2017 JRuby Team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
......
......@@ -4,7 +4,9 @@
*
* 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.
* 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
......
......@@ -4,7 +4,9 @@
*
* 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.
* 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
......
......@@ -4,7 +4,9 @@
*
* 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.
* 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
......
/*
* 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -48,8 +48,9 @@ public abstract class CGLSurfaceData extends OGLSurfaceData {
native void validate(int xoff, int yoff, int width, int height, boolean isOpaque);
private native void initOps(long pConfigInfo, long pPeerData, long layerPtr,
int xoff, int yoff, boolean isOpaque);
private native void initOps(OGLGraphicsConfig gc, long pConfigInfo,
long pPeerData, long layerPtr, int xoff,
int yoff, boolean isOpaque);
protected native boolean initPbuffer(long pData, long pConfigInfo,
boolean isOpaque, int width, int height);
......@@ -77,7 +78,7 @@ public abstract class CGLSurfaceData extends OGLSurfaceData {
pPeerData = pView.getAWTView();
isOpaque = pView.isOpaque();
}
initOps(pConfigInfo, pPeerData, 0, 0, 0, isOpaque);
initOps(gc, pConfigInfo, pPeerData, 0, 0, 0, isOpaque);
}
protected CGLSurfaceData(CGLLayer layer, CGLGraphicsConfig gc,
......@@ -93,7 +94,7 @@ public abstract class CGLSurfaceData extends OGLSurfaceData {
layerPtr = layer.getPointer();
isOpaque = layer.isOpaque();
}
initOps(pConfigInfo, 0, layerPtr, 0, 0, isOpaque);
initOps(gc, pConfigInfo, 0, layerPtr, 0, 0, isOpaque);
}
@Override //SurfaceData
......
......@@ -5,7 +5,9 @@
*
* 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.
* 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
......
/*
* 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -94,16 +94,18 @@ static CFMutableArrayRef getAllValidDisplayModes(jint displayID){
static CGDisplayModeRef getBestModeForParameters(CFArrayRef allModes, int w, int h, int bpp, int refrate) {
CGDisplayModeRef bestGuess = NULL;
CFIndex numModes = CFArrayGetCount(allModes), n;
int thisBpp = 0;
for(n = 0; n < numModes; n++ ) {
CGDisplayModeRef cRef = (CGDisplayModeRef) CFArrayGetValueAtIndex(allModes, n);
if(cRef == NULL) {
continue;
}
CFStringRef modeString = CGDisplayModeCopyPixelEncoding(cRef);
thisBpp = getBPPFromModeString(modeString);
int thisBpp = getBPPFromModeString(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
continue;
}
......@@ -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
// 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
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
bestGuess = cRef;
}
......
......@@ -144,31 +144,6 @@ JNF_COCOA_ENTER(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
* "scratch" surface. If there is a problem making the context current,
......@@ -411,7 +386,7 @@ extern DisposeFunc OGLSD_Dispose;
JNIEXPORT void JNICALL
Java_sun_java2d_opengl_CGLSurfaceData_initOps
(JNIEnv *env, jobject cglsd,
(JNIEnv *env, jobject cglsd, jobject gc,
jlong pConfigInfo, jlong pPeerData, jlong layerPtr,
jint xoff, jint yoff, jboolean isOpaque)
{
......@@ -419,8 +394,22 @@ Java_sun_java2d_opengl_CGLSurfaceData_initOps
J2dTraceLn1(J2D_TRACE_INFO, " pPeerData=%p", jlong_to_ptr(pPeerData));
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 *)
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));
if (cglsdo == NULL) {
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.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
......@@ -62,14 +62,16 @@ final class GHASH {
private static final int AES_BLOCK_SIZE = 16;
// Multiplies state0, state1 by V0, V1.
private void blockMult(long V0, long V1) {
// Multiplies state[0], state[1] by subkeyH[0], subkeyH[1].
private static void blockMult(long[] st, long[] subH) {
long Z0 = 0;
long Z1 = 0;
long V0 = subH[0];
long V1 = subH[1];
long X;
// Separate loops for processing state0 and state1.
X = state0;
// Separate loops for processing state[0] and state[1].
X = st[0];
for (int i = 0; i < 64; i++) {
// Zi+1 = Zi if bit i of x is 0
long mask = X >> 63;
......@@ -89,7 +91,7 @@ final class GHASH {
X <<= 1;
}
X = state1;
X = st[1];
for (int i = 64; i < 127; i++) {
// Zi+1 = Zi if bit i of x is 0
long mask = X >> 63;
......@@ -115,15 +117,18 @@ final class GHASH {
Z1 ^= V1 & mask;
// Save result.
state0 = Z0;
state1 = Z1;
st[0] = Z0;
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
private final long subkeyH0, subkeyH1;
private final long[] subkeyH;
// buffer for storing hash
private long state0, state1;
private final long[] state;
// variables for save/restore calls
private long stateSave0, stateSave1;
......@@ -141,8 +146,10 @@ final class GHASH {
if ((subkeyH == null) || subkeyH.length != AES_BLOCK_SIZE) {
throw new ProviderException("Internal error");
}
this.subkeyH0 = getLong(subkeyH, 0);
this.subkeyH1 = getLong(subkeyH, 8);
state = new long[2];
this.subkeyH = new long[2];
this.subkeyH[0] = getLong(subkeyH, 0);
this.subkeyH[1] = getLong(subkeyH, 8);
}
/**
......@@ -151,33 +158,30 @@ final class GHASH {
* this object for different data w/ the same H.
*/
void reset() {
state0 = 0;
state1 = 0;
state[0] = 0;
state[1] = 0;
}
/**
* Save the current snapshot of this GHASH object.
*/
void save() {
stateSave0 = state0;
stateSave1 = state1;
stateSave0 = state[0];
stateSave1 = state[1];
}
/**
* Restores this object using the saved snapshot.
*/
void restore() {
state0 = stateSave0;
state1 = stateSave1;
state[0] = stateSave0;
state[1] = stateSave1;
}
private void processBlock(byte[] data, int ofs) {
if (data.length - ofs < AES_BLOCK_SIZE) {
throw new RuntimeException("need complete block");
}
state0 ^= getLong(data, ofs);
state1 ^= getLong(data, ofs + 8);
blockMult(subkeyH0, subkeyH1);
private static void processBlock(byte[] data, int ofs, long[] st, long[] subH) {
st[0] ^= getLong(data, ofs);
st[1] ^= getLong(data, ofs + 8);
blockMult(st, subH);
}
void update(byte[] in) {
......@@ -185,22 +189,57 @@ final class GHASH {
}
void update(byte[] in, int inOfs, int inLen) {
if (inLen - inOfs > in.length) {
throw new RuntimeException("input length out of bound");
if (inLen == 0) {
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) {
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) {
processBlock(in, i);
// These two checks are for C2 checking
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[] result = new byte[AES_BLOCK_SIZE];
putLong(result, 0, state0);
putLong(result, 8, state1);
putLong(result, 0, state[0]);
putLong(result, 8, state[1]);
reset();
return result;
}
......
......@@ -43,6 +43,7 @@ import java.security.cert.CertificateFactory;
import java.security.cert.CertificateException;
import javax.crypto.SealedObject;
import sun.misc.IOUtils;
import sun.misc.ObjectInputFilter;
/**
......@@ -70,7 +71,7 @@ public final class JceKeyStore extends KeyStoreSpi {
private static final class PrivateKeyEntry {
Date date; // the creation date of this entry
byte[] protectedKey;
Certificate chain[];
Certificate[] chain;
};
// Secret key
......@@ -738,23 +739,11 @@ public final class JceKeyStore extends KeyStoreSpi {
entry.date = new Date(dis.readLong());
// read the private key
try {
entry.protectedKey = new byte[dis.readInt()];
} catch (OutOfMemoryError e) {
throw new IOException("Keysize too big");
}
dis.readFully(entry.protectedKey);
entry.protectedKey = IOUtils.readExactlyNBytes(dis, dis.readInt());
// read the certificate chain
int numOfCerts = dis.readInt();
try {
if (numOfCerts > 0) {
entry.chain = new Certificate[numOfCerts];
}
} catch (OutOfMemoryError e) {
throw new IOException("Too many certificates in "
+ "chain");
}
List<Certificate> tmpCerts = new ArrayList<>();
for (int j = 0; j < numOfCerts; j++) {
if (xVersion == 2) {
// read the certificate type, and instantiate a
......@@ -762,27 +751,24 @@ public final class JceKeyStore extends KeyStoreSpi {
// existing factory if possible)
String certType = dis.readUTF();
if (cfs.containsKey(certType)) {
// reuse certificate factory
// reuse certificate factory
cf = cfs.get(certType);
} else {
// create new certificate factory
// create new certificate factory
cf = CertificateFactory.getInstance(
certType);
// store the certificate factory so we can
// reuse it later
// store the certificate factory so we can
// reuse it later
cfs.put(certType, cf);
}
}
// instantiate the certificate
try {
encoded = new byte[dis.readInt()];
} catch (OutOfMemoryError e) {
throw new IOException("Certificate too big");
}
dis.readFully(encoded);
encoded = IOUtils.readExactlyNBytes(dis, dis.readInt());
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
entries.put(alias, entry);
......@@ -814,12 +800,7 @@ public final class JceKeyStore extends KeyStoreSpi {
cfs.put(certType, cf);
}
}
try {
encoded = new byte[dis.readInt()];
} catch (OutOfMemoryError e) {
throw new IOException("Certificate too big");
}
dis.readFully(encoded);
encoded = IOUtils.readExactlyNBytes(dis, dis.readInt());
bais = new ByteArrayInputStream(encoded);
entry.cert = cf.generateCertificate(bais);
......@@ -870,18 +851,14 @@ public final class JceKeyStore extends KeyStoreSpi {
* with
*/
if (password != null) {
byte computed[], actual[];
computed = md.digest();
actual = new byte[computed.length];
dis.readFully(actual);
for (int i = 0; i < computed.length; i++) {
if (computed[i] != actual[i]) {
throw new IOException(
byte[] computed = md.digest();
byte[] actual = IOUtils.readExactlyNBytes(dis, computed.length);
if (!MessageDigest.isEqual(computed, actual)) {
throw new IOException(
"Keystore was tampered with, or "
+ "password was incorrect",
new UnrecoverableKeyException(
"Password verification failed"));
}
new UnrecoverableKeyException(
"Password verification failed"));
}
}
} finally {
......
......@@ -123,6 +123,13 @@ class ClassReader {
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. */
private Entry checkTag(Entry e, byte tag) throws ClassFormatException {
if (e == null || !e.tagMatches(tag)) {
......@@ -225,6 +232,29 @@ class ClassReader {
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 {
int length = in.readUnsignedShort();
//System.err.println("reading CP, length="+length);
......@@ -233,7 +263,7 @@ class ClassReader {
int fptr = 0;
Entry[] cpMap = new Entry[length];
cpMap[0] = null;
cpMap[0] = INVALID_ENTRY;
for (int i = 1; i < length; i++) {
//System.err.println("reading CP elt, i="+i);
int tag = in.readByte();
......@@ -254,13 +284,13 @@ class ClassReader {
case CONSTANT_Long:
{
cpMap[i] = ConstantPool.getLiteralEntry(in.readLong());
cpMap[++i] = null;
cpMap[++i] = INVALID_ENTRY;
}
break;
case CONSTANT_Double:
{
cpMap[i] = ConstantPool.getLiteralEntry(in.readDouble());
cpMap[++i] = null;
cpMap[++i] = INVALID_ENTRY;
}
break;
......@@ -315,7 +345,7 @@ class ClassReader {
int ref2 = fixups[fi++];
if (verbose > 3)
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.
fixups[fptr++] = cpi;
fixups[fptr++] = tag;
......@@ -364,7 +394,6 @@ class ClassReader {
cls.cpMap = cpMap;
}
private /*non-static*/
class UnresolvedEntry extends Entry {
final Object[] refsOrIndexes;
......
......@@ -47,8 +47,6 @@ import javax.naming.ldap.Control;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
import sun.misc.IOUtils;
/**
* A thread that creates a connection to an LDAP server.
* After the connection, the thread reads from the connection.
......@@ -886,7 +884,7 @@ public final class Connection implements Runnable {
}
// read in seqlen bytes
byte[] left = IOUtils.readFully(in, seqlen, false);
byte[] left = readFully(in, seqlen);
inbuf = Arrays.copyOf(inbuf, offset + left.length);
System.arraycopy(left, 0, inbuf, offset, left.length);
offset += left.length;
......@@ -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.
/*public void sendSearchReqs(String dn, int numReqs) {
......
......@@ -123,8 +123,9 @@ import sun.misc.HexDumpEncoder;
* must also be set to true; Otherwise a configuration error will
* be returned.</dd>
* <dt><b><code>renewTGT</code></b>:</dt>
* <dd>Set this to true, if you want to renew
* the TGT. If this is set, <code>useTicketCache</code> must also be
* <dd>Set this to true, if you want to renew the TGT when it's more than
* 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>
* <dt><b><code>doNotPrompt</code></b>:</dt>
* <dd>Set this to true if you do not want to be
......@@ -665,22 +666,21 @@ public class Krb5LoginModule implements LoginModule {
(principal, ticketCacheName);
if (cred != null) {
// check to renew credentials
if (!isCurrent(cred)) {
if (renewTGT) {
Credentials newCred = renewCredentials(cred);
if (newCred != null) {
newCred.setProxy(cred.getProxy());
}
if (renewTGT && isOld(cred)) {
// renew if ticket is old.
Credentials newCred = renewCredentials(cred);
if (newCred != null) {
newCred.setProxy(cred.getProxy());
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) {
......@@ -988,7 +988,7 @@ public class Krb5LoginModule implements LoginModule {
}
}
private boolean isCurrent(Credentials creds)
private static boolean isCurrent(Credentials creds)
{
Date endTime = creds.getEndTime();
if (endTime != null) {
......@@ -997,6 +997,23 @@ public class Krb5LoginModule implements LoginModule {
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)
{
Credentials lcreds;
......@@ -1004,6 +1021,10 @@ public class Krb5LoginModule implements LoginModule {
if (!creds.isRenewable())
throw new RefreshFailedException("This ticket" +
" is not renewable");
if (creds.getRenewTill() == null) {
// Renewable ticket without renew-till. Illegal and ignored.
return creds;
}
if (System.currentTimeMillis() > cred.getRenewTill().getTime())
throw new RefreshFailedException("This ticket is past "
+ "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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -73,8 +73,12 @@ abstract class GssKrb5Base extends AbstractSaslImpl {
}
try {
MessageProp msgProp = new MessageProp(JGSS_QOP, privacy);
MessageProp msgProp = new MessageProp(JGSS_QOP, false);
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)) {
traceOutput(myClassName, "KRB501:Unwrap", "incoming: ",
incoming, start, len);
......@@ -128,4 +132,20 @@ abstract class GssKrb5Base extends AbstractSaslImpl {
protected void finalize() throws Throwable {
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -230,8 +230,10 @@ final class GssKrb5Client extends GssKrb5Base implements SaslClient {
// Received S1 (security layer, server max recv size)
MessageProp msgProp = new MessageProp(false);
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
// 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -250,8 +250,10 @@ final class GssKrb5Server extends GssKrb5Base implements SaslServer {
try {
// Expecting 4 octets from client selected protection
// and client's receive buffer size
MessageProp msgProp = new MessageProp(false);
byte[] gssOutToken = secCtx.unwrap(responseData, 0,
responseData.length, new MessageProp(0, false));
responseData.length, msgProp);
checkMessageProp("Handshake failure: ", msgProp);
if (logger.isLoggable(Level.FINER)) {
traceOutput(MY_CLASS_NAME, "doHandshake2",
......
......@@ -43,7 +43,9 @@ import sun.java2d.cmm.ProfileDataVerifier;
import sun.java2d.cmm.ProfileDeferralMgr;
import sun.java2d.cmm.ProfileDeferralInfo;
import sun.java2d.cmm.ProfileActivator;
import sun.misc.IOUtils;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
......@@ -1019,42 +1021,25 @@ public class ICC_Profile implements Serializable {
static byte[] getProfileDataFromStream(InputStream s) throws IOException {
byte profileData[];
int profileSize;
byte header[] = new byte[128];
int bytestoread = 128;
int bytesread = 0;
int n;
BufferedInputStream bis = new BufferedInputStream(s);
bis.mark(128);
while (bytestoread != 0) {
if ((n = s.read(header, bytesread, bytestoread)) < 0) {
return null;
}
bytesread += n;
bytestoread -= n;
}
byte[] header = IOUtils.readNBytes(bis, 128);
if (header[36] != 0x61 || header[37] != 0x63 ||
header[38] != 0x73 || header[39] != 0x70) {
return null; /* not a valid profile */
}
profileSize = ((header[0] & 0xff) << 24) |
((header[1] & 0xff) << 16) |
((header[2] & 0xff) << 8) |
(header[3] & 0xff);
profileData = new byte[profileSize];
System.arraycopy(header, 0, profileData, 0, 128);
bytestoread = profileSize - 128;
bytesread = 128;
while (bytestoread != 0) {
if ((n = s.read(profileData, bytesread, bytestoread)) < 0) {
return null;
}
bytesread += n;
bytestoread -= n;
int profileSize = ((header[0] & 0xff) << 24) |
((header[1] & 0xff) << 16) |
((header[2] & 0xff) << 8) |
(header[3] & 0xff);
bis.reset();
try {
return IOUtils.readNBytes(bis, profileSize);
} catch (OutOfMemoryError e) {
throw new IOException("Color profile is too big");
}
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -1024,18 +1024,8 @@ public class BeanContextSupport extends BeanContextChildSupport
int count = serializable;
while (count-- > 0) {
Object child = null;
BeanContextSupport.BCSChild bscc = null;
try {
child = ois.readObject();
bscc = (BeanContextSupport.BCSChild)ois.readObject();
} catch (IOException ioe) {
continue;
} catch (ClassNotFoundException cnfe) {
continue;
}
Object child = ois.readObject();
BCSChild bscc = (BCSChild) ois.readObject();
synchronized(child) {
BeanContextChild bcc = null;
......
......@@ -46,8 +46,11 @@ import sun.security.util.SecurityConstants;
* the file separator character, <code>File.separatorChar</code>) indicates
* all the files and directories contained in that directory. A pathname
* that ends with "/-" indicates (recursively) all files
* and subdirectories contained in that directory. A pathname consisting of
* the special token "&lt;&lt;ALL FILES&gt;&gt;" matches <b>any</b> file.
* and subdirectories contained in that directory. Such a pathname is called
* 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>
* Note: A pathname consisting of a single "*" indicates all the files
* in the current directory, while a pathname consisting of a single "-"
......@@ -80,7 +83,7 @@ import sun.security.util.SecurityConstants;
* <P>
* Be careful when granting FilePermissions. Think about the implications
* 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
* file system. One thing this effectively allows is replacement of the
* system binary, including the JVM runtime environment.
......@@ -156,6 +159,7 @@ public final class FilePermission extends Permission implements Serializable {
private transient String cpath;
private transient boolean allFiles; // whether this is <<ALL FILES>>
private transient boolean invalid; // whether input path is invalid
// static Strings used by init(int mask)
......@@ -207,6 +211,7 @@ public final class FilePermission extends Permission implements Serializable {
this.mask = mask;
if (cpath.equals("<<ALL FILES>>")) {
allFiles = true;
directory = true;
recursive = true;
cpath = "";
......@@ -335,6 +340,23 @@ public final class FilePermission extends Permission implements Serializable {
* "/tmp/*" encompasses all files in the "/tmp" directory,
* including the one named "foo".
* </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.
*
......@@ -366,9 +388,15 @@ public final class FilePermission extends Permission implements Serializable {
if (this == that) {
return true;
}
if (allFiles) {
return true;
}
if (this.invalid || that.invalid) {
return false;
}
if (that.allFiles) {
return false;
}
if (this.directory) {
if (this.recursive) {
// make sure that.path is longer then path so
......@@ -415,6 +443,10 @@ public final class FilePermission extends Permission implements Serializable {
* Checks two FilePermission objects for equality. Checks that <i>obj</i> is
* 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.
* @return <code>true</code> if obj is a FilePermission, and has the same
* pathname and actions as this FilePermission object,
......@@ -433,6 +465,7 @@ public final class FilePermission extends Permission implements Serializable {
return false;
}
return (this.mask == that.mask) &&
(this.allFiles == that.allFiles) &&
this.cpath.equals(that.cpath) &&
(this.directory == that.directory) &&
(this.recursive == that.recursive);
......
......@@ -419,16 +419,50 @@ public class ObjectInputStream
* @throws IOException Any of the usual Input/Output related exceptions.
*/
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
{
if (enableOverride) {
return readObjectOverride();
}
if (! (type == Object.class || type == String.class))
throw new AssertionError("internal error");
// if nested read, passHandle contains handle of enclosing object
int outerHandle = passHandle;
try {
Object obj = readObject0(false);
Object obj = readObject0(type, false);
handles.markDependency(outerHandle, passHandle);
ClassNotFoundException ex = handles.lookupException(passHandle);
if (ex != null) {
......@@ -518,7 +552,7 @@ public class ObjectInputStream
// if nested read, passHandle contains handle of enclosing object
int outerHandle = passHandle;
try {
Object obj = readObject0(true);
Object obj = readObject0(Object.class, true);
handles.markDependency(outerHandle, passHandle);
ClassNotFoundException ex = handles.lookupException(passHandle);
if (ex != null) {
......@@ -1517,8 +1551,10 @@ public class ObjectInputStream
/**
* 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();
if (oldMode) {
int remain = bin.currentBlockRemaining();
......@@ -1550,13 +1586,20 @@ public class ObjectInputStream
return readNull();
case TC_REFERENCE:
return readHandle(unshared);
// check the type of the existing object
return type.cast(readHandle(unshared));
case TC_CLASS:
if (type == String.class) {
throw new ClassCastException("Cannot cast a class to java.lang.String");
}
return readClass(unshared);
case TC_CLASSDESC:
case TC_PROXYCLASSDESC:
if (type == String.class) {
throw new ClassCastException("Cannot cast a class to java.lang.String");
}
return readClassDesc(unshared);
case TC_STRING:
......@@ -1564,15 +1607,27 @@ public class ObjectInputStream
return checkResolve(readString(unshared));
case TC_ARRAY:
if (type == String.class) {
throw new ClassCastException("Cannot cast an array to java.lang.String");
}
return checkResolve(readArray(unshared));
case TC_ENUM:
if (type == String.class) {
throw new ClassCastException("Cannot cast an enum to java.lang.String");
}
return checkResolve(readEnum(unshared));
case TC_OBJECT:
if (type == String.class) {
throw new ClassCastException("Cannot cast an object to java.lang.String");
}
return checkResolve(readOrdinaryObject(unshared));
case TC_EXCEPTION:
if (type == String.class) {
throw new ClassCastException("Cannot cast an exception to java.lang.String");
}
IOException ex = readFatalException();
throw new WriteAbortedException("writing aborted", ex);
......@@ -1947,7 +2002,7 @@ public class ObjectInputStream
if (ccl == null) {
for (int i = 0; i < len; i++) {
readObject0(false);
readObject0(Object.class, false);
}
} else if (ccl.isPrimitive()) {
if (ccl == Integer.TYPE) {
......@@ -1972,7 +2027,7 @@ public class ObjectInputStream
} else {
Object[] oa = (Object[]) array;
for (int i = 0; i < len; i++) {
oa[i] = readObject0(false);
oa[i] = readObject0(Object.class, false);
handles.markDependency(arrayHandle, passHandle);
}
}
......@@ -2250,7 +2305,7 @@ public class ObjectInputStream
return;
default:
readObject0(false);
readObject0(Object.class, false);
break;
}
}
......@@ -2284,7 +2339,7 @@ public class ObjectInputStream
int numPrimFields = fields.length - objVals.length;
for (int i = 0; i < objVals.length; i++) {
ObjectStreamField f = fields[numPrimFields + i];
objVals[i] = readObject0(f.isUnshared());
objVals[i] = readObject0(Object.class, f.isUnshared());
if (f.getField() != null) {
handles.markDependency(objHandle, passHandle);
}
......@@ -2305,7 +2360,7 @@ public class ObjectInputStream
throw new InternalError();
}
clear();
return (IOException) readObject0(false);
return (IOException) readObject0(Object.class, false);
}
/**
......@@ -2449,7 +2504,7 @@ public class ObjectInputStream
int numPrimFields = fields.length - objVals.length;
for (int i = 0; i < objVals.length; i++) {
objVals[i] =
readObject0(fields[numPrimFields + i].isUnshared());
readObject0(Object.class, fields[numPrimFields + i].isUnshared());
objHandles[i] = passHandle;
}
passHandle = oldHandle;
......@@ -3403,7 +3458,15 @@ public class ObjectInputStream
* utflen bytes.
*/
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) {
end = pos = 0;
}
......@@ -3918,5 +3981,6 @@ public class ObjectInputStream
}
static {
SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::setValidator);
SharedSecrets.setJavaObjectInputStreamReadString(ObjectInputStream::readString);
}
}
/*
* 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -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
// loader's delegation chain.
boolean isAncestor(ClassLoader cl) {
......@@ -1809,10 +1821,9 @@ public abstract class ClassLoader {
boolean isAbsolute) {
ClassLoader loader =
(fromClass == null) ? null : fromClass.getClassLoader();
if (sys_paths == null) {
usr_paths = initializePath("java.library.path");
sys_paths = initializePath("sun.boot.library.path");
}
assert sys_paths != null : "should be initialized at this point";
assert usr_paths != null : "should be initialized at this point";
if (isAbsolute) {
if (loadLibrary0(fromClass, new File(name))) {
return;
......@@ -1902,13 +1913,14 @@ public abstract class ClassLoader {
name +
" already loaded in another classloader");
}
/* If the library is being loaded (must be by the same thread,
* because Runtime.load and Runtime.loadLibrary are
* synchronous). The reason is can occur is that the JNI_OnLoad
* function can cause another loadLibrary invocation.
/*
* When a library is being loaded, JNI_OnLoad function can cause
* another loadLibrary invocation that should succeed.
*
* Thus we can use a static stack to hold the list of libraries
* we are loading.
* We use a static stack to hold the list of libraries we are
* 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
* immediately return success; otherwise, we raise
......
/*
* 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -797,7 +798,7 @@ public class Runtime {
load0(Reflection.getCallerClass(), filename);
}
synchronized void load0(Class<?> fromClass, String filename) {
void load0(Class<?> fromClass, String filename) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkLink(filename);
......@@ -858,14 +859,14 @@ public class Runtime {
loadLibrary0(Reflection.getCallerClass(), libname);
}
synchronized void loadLibrary0(Class<?> fromClass, String libname) {
void loadLibrary0(Class<?> fromClass, String libname) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkLink(libname);
}
if (libname.indexOf((int)File.separatorChar) != -1) {
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);
}
......
......@@ -44,6 +44,7 @@ import sun.reflect.Reflection;
import sun.security.util.SecurityConstants;
import sun.reflect.annotation.AnnotationType;
import jdk.internal.util.StaticProperty;
/**
* The <code>System</code> class contains several useful class fields
......@@ -1185,6 +1186,7 @@ public final class System {
lineSeparator = props.getProperty("line.separator");
StaticProperty.jdkSerialFilter(); // Load StaticProperty to cache the property values
sun.misc.Version.init();
FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
......@@ -1194,6 +1196,8 @@ public final class System {
setOut0(newPrintStream(fdOut, props.getProperty("sun.stdout.encoding")));
setErr0(newPrintStream(fdErr, props.getProperty("sun.stderr.encoding")));
ClassLoader.initLibraryPaths();
// Load the zip library now in order to keep java.util.zip.ZipFile
// from trying to use itself to load this library later.
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -588,22 +588,29 @@ public abstract class Executable extends AccessibleObject
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() {
if (declaredAnnotations == null) {
Executable root = getRoot();
if (root != null) {
declaredAnnotations = root.declaredAnnotations();
} else {
declaredAnnotations = AnnotationParser.parseAnnotations(
getAnnotationBytes(),
sun.misc.SharedSecrets.getJavaLangAccess().
getConstantPool(getDeclaringClass()),
getDeclaringClass());
private Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
Map<Class<? extends Annotation>, Annotation> declAnnos;
if ((declAnnos = declaredAnnotations) == null) {
synchronized (this) {
if ((declAnnos = declaredAnnotations) == null) {
Executable root = getRoot();
if (root != null) {
declAnnos = root.declaredAnnotations();
} else {
declAnnos = AnnotationParser.parseAnnotations(
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -1139,21 +1139,28 @@ class Field extends AccessibleObject implements Member {
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() {
if (declaredAnnotations == null) {
Field root = this.root;
if (root != null) {
declaredAnnotations = root.declaredAnnotations();
} else {
declaredAnnotations = AnnotationParser.parseAnnotations(
annotations,
sun.misc.SharedSecrets.getJavaLangAccess().getConstantPool(getDeclaringClass()),
getDeclaringClass());
private Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
Map<Class<? extends Annotation>, Annotation> declAnnos;
if ((declAnnos = declaredAnnotations) == null) {
synchronized (this) {
if ((declAnnos = declaredAnnotations) == null) {
Field root = this.root;
if (root != null) {
declAnnos = root.declaredAnnotations();
} else {
declAnnos = AnnotationParser.parseAnnotations(
annotations,
sun.misc.SharedSecrets.getJavaLangAccess()
.getConstantPool(getDeclaringClass()),
getDeclaringClass());
}
declaredAnnotations = declAnnos;
}
}
}
return declaredAnnotations;
return declAnnos;
}
private native byte[] getTypeAnnotationBytes0();
......
......@@ -33,6 +33,7 @@ import java.io.ObjectStreamField;
import java.io.ObjectInputStream.GetField;
import java.util.Hashtable;
import java.util.StringTokenizer;
import sun.misc.VM;
import sun.net.util.IPAddressUtil;
import sun.security.util.SecurityConstants;
......@@ -1423,7 +1424,9 @@ public final class URL implements java.io.Serializable {
}
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) {
......
......@@ -121,7 +121,7 @@ public abstract class SelectableChannel
// keySet, may be empty but is never null, typ. a tiny array
// boolean isRegistered, protected by key set
// 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
......
/*
* 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -26,7 +26,14 @@
package java.nio.channels.spi;
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
// Lock for registration and configureBlocking operations
private final Object regLock = new Object();
// Blocking mode, protected by regLock
boolean blocking = true;
// True when non-blocking, need regLock to change;
private volatile boolean nonBlocking;
/**
* Initializes a new instance of this class.
......@@ -197,7 +204,7 @@ public abstract class AbstractSelectableChannel
throw new ClosedChannelException();
if ((ops & ~validOps()) != 0)
throw new IllegalArgumentException();
if (blocking)
if (isBlocking())
throw new IllegalBlockingModeException();
SelectionKey k = findKey(sel);
if (k != null) {
......@@ -264,9 +271,7 @@ public abstract class AbstractSelectableChannel
// -- Blocking --
public final boolean isBlocking() {
synchronized (regLock) {
return blocking;
}
return !nonBlocking;
}
public final Object blockingLock() {
......@@ -287,12 +292,13 @@ public abstract class AbstractSelectableChannel
synchronized (regLock) {
if (!isOpen())
throw new ClosedChannelException();
if (blocking == block)
return this;
if (block && haveValidKeys())
throw new IllegalBlockingModeException();
implConfigureBlocking(block);
blocking = block;
boolean blocking = !nonBlocking;
if (block != blocking) {
if (block && haveValidKeys())
throw new IllegalBlockingModeException();
implConfigureBlocking(block);
nonBlocking = !block;
}
}
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -29,6 +29,7 @@ import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.UnexpectedException;
import java.rmi.activation.Activatable;
import java.security.PrivilegedAction;
......@@ -224,6 +225,13 @@ public class RemoteObjectInvocationHandler
throw new IllegalArgumentException(
"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,
getMethodHash(method));
} catch (Exception e) {
......
......@@ -570,7 +570,7 @@ public class CodeSource implements java.io.Serializable {
cfs.put(certType, cf);
}
// parse the certificate
byte[] encoded = IOUtils.readNBytes(ois, ois.readInt());
byte[] encoded = IOUtils.readExactlyNBytes(ois, ois.readInt());
ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
try {
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -63,7 +63,7 @@ package java.security;
* </pre>
*
* 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>.
*
* <LI>A Format
......
......@@ -590,7 +590,7 @@ implements java.io.Serializable
cfs.put(certType, cf);
}
// parse the certificate
byte[] encoded = IOUtils.readNBytes(ois, ois.readInt());
byte[] encoded = IOUtils.readExactlyNBytes(ois, ois.readInt());
ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
try {
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -27,8 +27,8 @@ package java.security.cert;
/**
* The CRLReason enumeration specifies the reason that a certificate
* is revoked, as defined in <a href="http://www.ietf.org/rfc/rfc3280.txt">
* RFC 3280: Internet X.509 Public Key Infrastructure Certificate and CRL
* is revoked, as defined in <a href="http://tools.ietf.org/html/rfc5280">
* RFC 5280: Internet X.509 Public Key Infrastructure Certificate and CRL
* Profile</a>.
*
* @author Sean Mullan
......
......@@ -239,7 +239,7 @@ public class CertificateRevokedException extends CertificateException {
for (int i = 0; i < size; i++) {
String oid = (String) ois.readObject();
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
(new ObjectIdentifier(oid), critical, extVal);
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -28,7 +28,7 @@ package java.security.cert;
/**
* The {@code PKIXReason} enumerates the potential PKIX-specific reasons
* 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.
*
* @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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -78,7 +78,7 @@ public class TrustAnchor {
* The name constraints are specified as a byte array. This byte array
* should contain the DER encoded form of the name constraints, as they
* 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.
*
* <pre>{@code
......@@ -140,7 +140,7 @@ public class TrustAnchor {
* <p>
* The name constraints are specified as a byte array. This byte array
* 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
* documentation for
* {@link #TrustAnchor(X509Certificate, byte[])
......@@ -179,7 +179,7 @@ public class TrustAnchor {
* <p>
* The name constraints are specified as a byte array. This byte array
* 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
* documentation for
* {@link #TrustAnchor(X509Certificate, byte[])
......@@ -294,7 +294,7 @@ public class TrustAnchor {
* <p>
* The name constraints are returned as a byte array. This byte array
* 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
* documentation for
* {@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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -69,7 +69,7 @@ import sun.security.x509.X509CRLImpl;
* </pre>
* <p>
* 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>.
* <p>
* The ASN.1 definition of {@code tbsCertList} is:
......
......@@ -52,7 +52,7 @@ import sun.security.x509.X500Name;
* {@link CertStore#getCRLs CertStore.getCRLs} or some similar
* method.
* <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 definitions of the X.509 CRL fields and extensions mentioned below.
* <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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -65,7 +65,7 @@ import sun.security.x509.*;
* number. Other unique combinations include the issuer, subject,
* subjectKeyIdentifier and/or the subjectPublicKey criteria.
* <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
* definitions of the X.509 certificate extensions mentioned below.
* <p>
......@@ -728,7 +728,7 @@ public class X509CertSelector implements CertSelector {
* The name is provided in string format.
* <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
* 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
* as a series of nonnegative integers separated by periods. And
* directory names (distinguished names) are supplied in RFC 2253 format.
......@@ -746,7 +746,7 @@ public class X509CertSelector implements CertSelector {
* String form of some distinguished names.
*
* @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})
* @throws IOException if a parsing error occurs
*/
......@@ -770,7 +770,7 @@ public class X509CertSelector implements CertSelector {
* <p>
* 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
* 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
* with the name in the GeneralName structure. The ASN.1 definition of this
* structure appears below.
......@@ -806,7 +806,7 @@ public class X509CertSelector implements CertSelector {
* must contain the specified subjectAlternativeName.
*
* @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
* @throws IOException if a parsing error occurs
*/
......@@ -995,7 +995,7 @@ public class X509CertSelector implements CertSelector {
* <p>
* The name constraints are specified as a byte array. This byte array
* 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.
*
* <pre>{@code
......@@ -1197,7 +1197,7 @@ public class X509CertSelector implements CertSelector {
* <p>
* The name is provided in string format. RFC 822, DNS, and URI 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
* as a series of nonnegative integers separated by periods. And
* directory names (distinguished names) are supplied in RFC 2253 format.
......@@ -1214,7 +1214,7 @@ public class X509CertSelector implements CertSelector {
* String form of some distinguished names.
*
* @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
* @throws IOException if a parsing error occurs
*/
......@@ -1234,7 +1234,7 @@ public class X509CertSelector implements CertSelector {
* <p>
* 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
* 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
* {@link #addSubjectAlternativeName(int type, byte [] name)
* addSubjectAlternativeName(int type, byte [] name)}.
......@@ -1243,7 +1243,7 @@ public class X509CertSelector implements CertSelector {
* subsequent modifications.
*
* @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
* @throws IOException if a parsing error occurs
*/
......@@ -1258,7 +1258,7 @@ public class X509CertSelector implements CertSelector {
* the specified pathToName.
*
* @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
* @throws IOException if an encoding error occurs (incorrect form for DN)
*/
......@@ -1715,7 +1715,7 @@ public class X509CertSelector implements CertSelector {
* <p>
* The name constraints are returned as a byte array. This byte array
* 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
* documentation for
* {@link #setNameConstraints(byte [] bytes) setNameConstraints(byte [] bytes)}.
......@@ -2115,8 +2115,11 @@ public class X509CertSelector implements CertSelector {
if (certSubjectKeyID == null ||
!Arrays.equals(subjectKeyID, certSubjectKeyID)) {
if (debug != null) {
debug.println("X509CertSelector.match: "
+ "subject key IDs don't match");
debug.println("X509CertSelector.match: subject key IDs " +
"don't match\nX509CertSelector.match: subjectKeyID: " +
Arrays.toString(subjectKeyID) +
"\nX509CertSelector.match: certSubjectKeyID: " +
Arrays.toString(certSubjectKeyID));
}
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -63,7 +63,7 @@ import sun.security.x509.X509CertImpl;
* CA such as a "root" CA.
* <p>
* 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>.
* <p>
* The ASN.1 definition of {@code tbsCertificate} is:
......@@ -408,7 +408,7 @@ implements X509Extension {
* Gets the {@code issuerUniqueID} value from the certificate.
* The issuer unique identifier is present in the certificate
* 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.
* Applications conforming to that profile should be capable of
* parsing unique identifiers and making comparisons.
......@@ -459,7 +459,7 @@ implements X509Extension {
* encipherOnly (7),
* decipherOnly (8) }
* </pre>
* RFC 3280 recommends that when used, this be marked
* RFC 5280 recommends that when used, this be marked
* as a critical extension.
*
* @return the KeyUsage extension of this certificate, represented as
......@@ -572,7 +572,7 @@ implements X509Extension {
* <a href="http://www.ietf.org/rfc/rfc822.txt">RFC 822</a>, DNS, and URI
* names are returned as {@code String}s,
* 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
* in the form "a1:a2:...:a8", where a1-a8 are hexadecimal values
* representing the eight 16-bit pieces of the address. OID names are
......
......@@ -36,14 +36,14 @@ import java.io.IOException;
* For example, the following class prints out different representations of a
* stock's name depending on the flags and length constraints:
*
* {@code
* <pre> {@code
* import java.nio.CharBuffer;
* import java.util.Formatter;
* import java.util.Formattable;
* import java.util.Locale;
* import static java.util.FormattableFlags.*;
*
* ...
* ...
*
* public class StockName implements Formattable {
* private String symbol, companyName, frenchCompanyName;
......@@ -89,12 +89,12 @@ import java.io.IOException;
* return String.format("%s - %s", symbol, companyName);
* }
* }
* }
* }</pre>
*
* <p> When used in conjunction with the {@link java.util.Formatter}, the above
* class produces the following output for various format strings.
*
* {@code
* <pre> {@code
* Formatter fmt = new Formatter();
* StockName sn = new StockName("HUGE", "Huge Fruit, Inc.",
* "Fruit Titanesque, Inc.");
......@@ -104,7 +104,7 @@ import java.io.IOException;
* fmt.format("%-10.8s", sn); // -> "HUGE "
* fmt.format("%.12s", sn); // -> "Huge Fruit,*"
* fmt.format(Locale.FRANCE, "%25s", sn); // -> " Fruit Titanesque, Inc."
* }
* }</pre>
*
* <p> Formattables are not necessarily safe for multithreaded access. Thread
* safety is optional and may be enforced by classes that extend and implement
......
......@@ -422,7 +422,12 @@ class JarFile extends ZipFile {
*/
private byte[] getBytes(ZipEntry ze) throws IOException {
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
KeyTab ktab) {
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) {
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -80,6 +80,11 @@ public final class KerberosPrincipal
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 realm;
......
......@@ -194,6 +194,10 @@ public class KerberosTicket implements Destroyable, Refreshable,
private InetAddress[] clientAddresses;
transient KerberosPrincipal clientAlias = null;
transient KerberosPrincipal serverAlias = null;
/**
* Evidence ticket if proxy_impersonator. This field can be accessed
* by KerberosSecrets. It's serialized.
......@@ -308,11 +312,7 @@ public class KerberosTicket implements Destroyable, Refreshable,
} else
this.flags = new boolean[NUM_FLAGS];
if (this.flags[RENEWABLE_TICKET_FLAG]) {
if (renewTill == null)
throw new IllegalArgumentException("The renewable period "
+ "end time cannot be null for renewable tickets.");
if (this.flags[RENEWABLE_TICKET_FLAG] && renewTill != null) {
this.renewTill = new Date(renewTill.getTime());
}
......@@ -553,6 +553,11 @@ public class KerberosTicket implements Destroyable, Refreshable,
if (!isRenewable())
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())
throw new RefreshFailedException("This ticket is past "
+ "its last renewal time.");
......@@ -562,7 +567,11 @@ public class KerberosTicket implements Destroyable, Refreshable,
try {
krb5Creds = new sun.security.krb5.Credentials(asn1Encoding,
client.toString(),
(clientAlias != null ?
clientAlias.getName() : null),
server.toString(),
(serverAlias != null ?
serverAlias.getName() : null),
sessionKey.getEncoded(),
sessionKey.getKeyType(),
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -41,13 +41,13 @@ import sun.security.util.*;
* of the distinguished name, or by using the ASN.1 DER encoded byte
* representation of the distinguished name. The current specification
* 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
* 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
* 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>.
*
* <p> The string representation for this {@code X500Principal}
......@@ -108,7 +108,7 @@ public final class X500Principal implements Principal, java.io.Serializable {
* (and listed in {@link #getName(String format) getName(String format)}),
* as well as the T, DNQ or DNQUALIFIER, SURNAME, GIVENNAME, INITIALS,
* 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.
*
* <p>This implementation enforces a more restrictive OID syntax than
......@@ -456,7 +456,7 @@ public final class X500Principal implements Principal, java.io.Serializable {
* (obtained via the {@code getName(X500Principal.CANONICAL)} method)
* 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
* {@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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -31,15 +31,15 @@
* <h2>Package Specification</h2>
*
* <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>
* <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):
* UTF-8 String Representation of Distinguished Names</a></li>
* <li><a href="http://www.ietf.org/rfc/rfc3280.txt">
* RFC 3280: Internet X.509 Public Key Infrastructure
* <li><a href="http://tools.ietf.org/html/rfc5280">
* RFC 5280: Internet X.509 Public Key Infrastructure
* 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):
* Directory Information Models</a></li>
* </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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -28,6 +28,8 @@ package javax.swing;
import java.awt.event.*;
import java.awt.*;
import javax.swing.event.MenuKeyEvent;
import javax.swing.event.MenuKeyListener;
/**
* Manages all the <code>ToolTips</code> in the system.
......@@ -409,8 +411,14 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener
component.addMouseListener(this);
component.removeMouseMotionListener(moveBeforeEnterListener);
component.addMouseMotionListener(moveBeforeEnterListener);
component.removeKeyListener(accessibilityKeyListener);
component.addKeyListener(accessibilityKeyListener);
// use MenuKeyListener for menu items/elements
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
public void unregisterComponent(JComponent component) {
component.removeMouseListener(this);
component.removeMouseMotionListener(moveBeforeEnterListener);
component.removeKeyListener(accessibilityKeyListener);
if (component instanceof JMenuItem) {
((JMenuItem) component).removeMenuKeyListener((MenuKeyListener) accessibilityKeyListener);
} else {
component.removeKeyListener(accessibilityKeyListener);
}
}
// implements java.awt.event.MouseListener
......@@ -841,7 +853,7 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener
* Post Tip: 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) {
if (!e.isConsumed()) {
JComponent source = (JComponent) e.getComponent();
......@@ -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;
import java.net.MalformedURLException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.io.EOFException;
import java.io.File;
import java.io.FilePermission;
import java.io.IOException;
......@@ -333,7 +334,9 @@ public class AppletClassLoader extends URLClassLoader {
byte[] b;
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 {
in.close();
}
......
......@@ -27,6 +27,7 @@ package sun.java2d.opengl;
import java.awt.AlphaComposite;
import java.awt.Composite;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Transparency;
......@@ -598,16 +599,16 @@ public abstract class OGLSurfaceData extends SurfaceData
* (referenced by the pData parameter). This method is invoked from
* the native Dispose() method from the Disposer thread when the
* Java-level OGLSurfaceData object is about to go away. Note that we
* also pass a reference to the native GLX/WGLGraphicsConfigInfo
* (pConfigInfo) for the purposes of making a context current.
* also pass a reference to the OGLGraphicsConfig
* 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();
rq.lock();
try {
// make sure we have a current context before
// disposing the native resources (e.g. texture object)
OGLContext.setScratchSurface(pConfigInfo);
OGLContext.setScratchSurface(gc);
RenderBuffer buf = rq.getBuffer();
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -32,67 +32,282 @@ package sun.misc;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
public class IOUtils {
private static final int DEFAULT_BUFFER_SIZE = 8192;
/**
* Read up to {@code length} of bytes from {@code in}
* until EOF is detected.
* The maximum size of array to allocate.
* 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 length number of bytes to read, -1 or Integer.MAX_VALUE means
* 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
* @param length number of bytes to 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 {
byte[] output = {};
if (length == -1) length = Integer.MAX_VALUE;
int pos = 0;
while (pos < length) {
int bytesToRead;
if (pos >= output.length) { // Only expand when there's no room
bytesToRead = Math.min(length - pos, output.length + 1024);
if (output.length < pos + bytesToRead) {
output = Arrays.copyOf(output, pos + bytesToRead);
}
} else {
bytesToRead = output.length - pos;
if (length < 0) {
throw new IOException("length cannot be negative: " + length);
}
byte[] data = readNBytes(is, length);
if (data.length < length) {
throw new EOFException();
}
return data;
}
/**
* 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 (readAll && length != Integer.MAX_VALUE) {
throw new EOFException("Detect premature EOF");
if (nread > 0) {
if (MAX_BUFFER_SIZE - total < nread) {
throw new OutOfMemoryError("Required array size too large");
}
total += nread;
if (result == null) {
result = buf;
} else {
if (output.length != pos) {
output = Arrays.copyOf(output, pos);
if (bufs == null) {
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
* thrown if there are not enough bytes in the stream.
* Compatibility wrapper for third party users of
* {@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 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
* @throws IOException if any IO error or a premature EOF is detected, or
* if {@code length} is negative since this length is usually also
* read from {@code is}.
* @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[] readNBytes(InputStream is, int length) throws IOException {
public static byte[] readFully(InputStream is, int length, boolean readAll)
throws IOException {
if (length < 0) {
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;
import java.util.function.Function;
import sun.util.logging.PlatformLogger;
import jdk.internal.util.StaticProperty;
/**
* Filter classes, array lengths, and graph metrics during deserialization.
* If set on an {@link ObjectInputStream}, the {@link #checkInput checkInput(FilterInfo)}
......@@ -247,7 +249,7 @@ public interface ObjectInputFilter {
static {
configuredFilter = AccessController
.doPrivileged((PrivilegedAction<ObjectInputFilter>) () -> {
String props = System.getProperty(SERIAL_FILTER_PROPNAME);
String props = StaticProperty.jdkSerialFilter();
if (props == null) {
props = Security.getProperty(SERIAL_FILTER_PROPNAME);
}
......
......@@ -59,6 +59,7 @@ public class SharedSecrets {
private static JavaAWTAccess javaAWTAccess;
private static JavaOISAccess javaOISAccess;
private static JavaxCryptoSealedObjectAccess javaxCryptoSealedObjectAccess;
private static JavaObjectInputStreamReadString javaObjectInputStreamReadString;
private static JavaObjectInputStreamAccess javaObjectInputStreamAccess;
public static JavaUtilJarAccess javaUtilJarAccess() {
......@@ -202,8 +203,18 @@ public class SharedSecrets {
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) {
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -1229,10 +1229,15 @@ public class URLClassPath {
int i = 0;
while (st.hasMoreTokens()) {
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) {
urls[i] = url;
i++;
} else {
if (DEBUG_CP_URL_CHECK) {
System.err.println("Class-Path entry: \"" + path
+ "\" ignored in JAR file " + base);
}
}
}
if (i == 0) {
......@@ -1244,36 +1249,74 @@ public class URLClassPath {
return urls;
}
/*
* Return a URL for the given path resolved against the base URL, or
* null if the resulting URL is invalid.
static URL tryResolve(URL base, String input) throws MalformedURLException {
if ("file".equalsIgnoreCase(base.getProtocol())) {
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) {
String child = path.replace(File.separatorChar, '/');
try {
if (!URI.create(child).isAbsolute()) {
URL url = new URL(base, child);
if (base.getProtocol().equalsIgnoreCase("file")) {
return url;
} else {
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;
}
}
static URL tryResolveFile(URL base, String input) throws MalformedURLException {
int index = input.indexOf(':');
boolean isFile;
if (index >= 0) {
String scheme = input.substring(0, index);
isFile = "file".equalsIgnoreCase(scheme);
} else {
isFile = true;
}
return (isFile) ? new URL(base, input) : null;
}
/**
* Attempt to return a URL by resolving input against a base URL. Returns
* null if the resolved URL is not contained by the base 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;
}
/**
* 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 {
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
header. Also prints the RFC required blank line
at the end. Omits pairs with a null key. */
header. Also prints the RFC required blank line
at the end. Omits pairs with a null key. Omits
colon if key-value pair is the requestline. */
public synchronized void print(PrintStream p) {
for (int i = 0; i < nkeys; i++)
if (keys[i] != null) {
p.print(keys[i] +
(values[i] != null ? ": "+values[i]: "") + "\r\n");
StringBuilder sb = new StringBuilder(keys[i]);
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.flush();
......
......@@ -49,9 +49,6 @@ class DatagramChannelImpl
// Our file descriptor
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;
// The protocol family of the socket
......@@ -103,7 +100,6 @@ class DatagramChannelImpl
// -- End of fields protected by stateLock
public DatagramChannelImpl(SelectorProvider sp)
throws IOException
{
......@@ -138,16 +134,27 @@ class DatagramChannelImpl
throw new UnsupportedOperationException("IPv6 not available");
}
}
this.family = family;
this.fd = Net.socket(family, false);
this.fdVal = IOUtil.fdVal(fd);
this.state = ST_UNCONNECTED;
ResourceManager.beforeUdpCreate();
try {
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)
throws IOException
{
super(sp);
// increment UDP count to match decrement when closing
ResourceManager.beforeUdpCreate();
this.family = Net.isIPv6Available() ?
StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
this.fd = fd;
......@@ -742,10 +749,9 @@ class DatagramChannelImpl
localAddress = Net.localAddress(fd);
// flush any packets already received.
boolean blocking = false;
synchronized (blockingLock()) {
boolean blocking = isBlocking();
try {
blocking = isBlocking();
// remainder of each packet thrown away
ByteBuffer tmpBuf = ByteBuffer.allocate(1);
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,10 +25,22 @@
package sun.nio.ch;
import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
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.
......@@ -178,7 +190,6 @@ public class DatagramSocketAdaptor
dc.configureBlocking(false);
try {
int n;
SocketAddress sender;
if ((sender = dc.receive(bb)) != null)
return sender;
......@@ -188,19 +199,18 @@ public class DatagramSocketAdaptor
throw new ClosedChannelException();
long st = System.currentTimeMillis();
int result = dc.poll(Net.POLLIN, to);
if (result > 0 &&
((result & Net.POLLIN) != 0)) {
if (result > 0 && ((result & Net.POLLIN) != 0)) {
if ((sender = dc.receive(bb)) != null)
return sender;
}
to -= System.currentTimeMillis() - st;
if (to <= 0)
throw new SocketTimeoutException();
}
} finally {
if (dc.isOpen())
try {
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,9 +25,20 @@
package sun.nio.ch;
import java.io.*;
import java.net.*;
import java.nio.channels.*;
import java.io.IOException;
import java.net.InetAddress;
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.
......@@ -37,7 +48,7 @@ import java.nio.channels.*;
// class.
//
public class ServerSocketAdaptor // package-private
class ServerSocketAdaptor // package-private
extends ServerSocket
{
......@@ -97,12 +108,16 @@ public class ServerSocketAdaptor // package-private
throw new IllegalBlockingModeException();
try {
if (timeout == 0) {
// for compatibility reasons: accept connection if available
// when configured non-blocking
SocketChannel sc = ssc.accept();
if (sc == null && !ssc.isBlocking())
throw new IllegalBlockingModeException();
return sc.socket();
}
if (!ssc.isBlocking())
throw new IllegalBlockingModeException();
ssc.configureBlocking(false);
try {
SocketChannel sc;
......@@ -121,10 +136,10 @@ public class ServerSocketAdaptor // package-private
throw new SocketTimeoutException();
}
} finally {
if (ssc.isOpen())
try {
ssc.configureBlocking(true);
} catch (ClosedChannelException e) { }
}
} catch (Exception x) {
Net.translateException(x);
assert false;
......@@ -178,8 +193,7 @@ public class ServerSocketAdaptor // package-private
if (!isBound())
return "ServerSocket[unbound]";
return "ServerSocket[addr=" + getInetAddress() +
// ",port=" + getPort() +
",localport=" + getLocalPort() + "]";
",localport=" + getLocalPort() + "]";
}
public void setReceiveBufferSize(int size) throws SocketException {
......
......@@ -48,10 +48,7 @@ class ServerSocketChannelImpl
// Our file descriptor
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 int fdVal;
private final int fdVal;
// ID of native thread currently blocked in this channel, for signalling
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,11 +25,23 @@
package sun.nio.ch;
import java.io.*;
import java.lang.ref.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
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.PrivilegedExceptionAction;
import java.util.*;
......@@ -47,7 +59,7 @@ import java.util.*;
// java.net.Socket so as to simplify tracking future changes to that class.
//
public class SocketAdaptor
class SocketAdaptor
extends Socket
{
......@@ -91,7 +103,6 @@ public class SocketAdaptor
throw new IllegalBlockingModeException();
try {
if (timeout == 0) {
sc.connect(remote);
return;
......@@ -119,8 +130,9 @@ public class SocketAdaptor
}
}
} finally {
if (sc.isOpen())
try {
sc.configureBlocking(true);
} catch (ClosedChannelException e) { }
}
} catch (Exception x) {
......@@ -188,10 +200,11 @@ public class SocketAdaptor
synchronized (sc.blockingLock()) {
if (!sc.isBlocking())
throw new IllegalBlockingModeException();
if (timeout == 0)
return sc.read(bb);
sc.configureBlocking(false);
sc.configureBlocking(false);
try {
int n;
if ((n = sc.read(bb)) != 0)
......@@ -211,10 +224,10 @@ public class SocketAdaptor
throw new SocketTimeoutException();
}
} finally {
if (sc.isOpen())
try {
sc.configureBlocking(true);
} catch (ClosedChannelException e) { }
}
}
}
}
......
......@@ -50,9 +50,6 @@ class SocketChannelImpl
// Our file descriptor object
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;
// IDs of native threads doing reads and writes, for signalling
......
......@@ -25,6 +25,7 @@
package sun.reflect.misc;
import java.io.EOFException;
import java.security.AllPermission;
import java.security.AccessController;
import java.security.PermissionCollection;
......@@ -42,8 +43,8 @@ import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import sun.misc.IOUtils;
import sun.misc.IOUtils;
class Trampoline {
static {
......@@ -382,15 +383,12 @@ public final class MethodUtil extends SecureClassLoader {
}
}
int len = uc.getContentLength();
InputStream in = new BufferedInputStream(uc.getInputStream());
byte[] b;
try {
b = IOUtils.readFully(in, len, true);
} finally {
in.close();
try (InputStream in = new BufferedInputStream(uc.getInputStream())) {
byte[] b = IOUtils.readAllBytes(in);
if (len != -1 && b.length != len)
throw new EOFException("Expected:" + len + ", read:" + b.length);
return b;
}
return b;
}
......
......@@ -27,7 +27,9 @@
package sun.rmi.registry;
import java.io.IOException;
import java.io.ObjectInputStream;
import sun.misc.SharedSecrets;
import sun.rmi.transport.StreamRemoteCall;
/**
......@@ -83,8 +85,9 @@ public final class RegistryImpl_Skel
java.lang.String $param_String_1;
java.rmi.Remote $param_Remote_2;
try {
java.io.ObjectInput in = call.getInputStream();
$param_String_1 = (java.lang.String) in.readObject();
ObjectInputStream in = (ObjectInputStream)call.getInputStream();
$param_String_1 =
SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
$param_Remote_2 = (java.rmi.Remote) in.readObject();
} catch (ClassCastException | IOException | ClassNotFoundException e) {
call.discardPendingRefs();
......@@ -118,9 +121,10 @@ public final class RegistryImpl_Skel
{
java.lang.String $param_String_1;
try {
java.io.ObjectInput in = call.getInputStream();
$param_String_1 = (java.lang.String) in.readObject();
} catch (ClassCastException | IOException | ClassNotFoundException e) {
ObjectInputStream in = (ObjectInputStream)call.getInputStream();
$param_String_1 =
SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
} catch (ClassCastException | IOException e) {
call.discardPendingRefs();
throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
} finally {
......@@ -144,8 +148,9 @@ public final class RegistryImpl_Skel
java.lang.String $param_String_1;
java.rmi.Remote $param_Remote_2;
try {
java.io.ObjectInput in = call.getInputStream();
$param_String_1 = (java.lang.String) in.readObject();
ObjectInputStream in = (ObjectInputStream)call.getInputStream();
$param_String_1 =
SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
$param_Remote_2 = (java.rmi.Remote) in.readObject();
} catch (ClassCastException | IOException | java.lang.ClassNotFoundException e) {
call.discardPendingRefs();
......@@ -169,9 +174,10 @@ public final class RegistryImpl_Skel
java.lang.String $param_String_1;
try {
java.io.ObjectInput in = call.getInputStream();
$param_String_1 = (java.lang.String) in.readObject();
} catch (ClassCastException | IOException | ClassNotFoundException e) {
ObjectInputStream in = (ObjectInputStream)call.getInputStream();
$param_String_1 =
SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
} catch (ClassCastException | IOException e) {
call.discardPendingRefs();
throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
} finally {
......
......@@ -27,6 +27,7 @@ package sun.rmi.server;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.lang.reflect.Method;
import java.rmi.MarshalException;
......@@ -38,6 +39,8 @@ import java.rmi.server.RemoteCall;
import java.rmi.server.RemoteObject;
import java.rmi.server.RemoteRef;
import java.security.AccessController;
import sun.misc.SharedSecrets;
import sun.rmi.runtime.Log;
import sun.rmi.transport.Connection;
import sun.rmi.transport.LiveRef;
......@@ -318,6 +321,8 @@ public class UnicastRef implements RemoteRef {
} else {
throw new Error("Unrecognized primitive type: " + type);
}
} else if (type == String.class && in instanceof ObjectInputStream) {
return SharedSecrets.getJavaObjectInputStreamReadString().readString((ObjectInputStream)in);
} else {
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -29,6 +29,7 @@ import java.io.DataOutput;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.lang.reflect.Proxy;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
......@@ -553,6 +554,9 @@ public class TCPEndpoint implements Endpoint {
host = in.readUTF();
port = in.readInt();
csf = (RMIClientSocketFactory) in.readObject();
if (Proxy.isProxyClass(csf.getClass())) {
throw new IOException("Invalid SocketFactory");
}
break;
default:
......
......@@ -108,4 +108,27 @@ public class GetPropertyAction implements PrivilegedAction<String> {
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -44,6 +44,7 @@ import sun.security.krb5.internal.crypto.Des3;
import sun.security.krb5.internal.crypto.Aes128;
import sun.security.krb5.internal.crypto.Aes256;
import sun.security.krb5.internal.crypto.ArcFourHmac;
import sun.security.krb5.internal.crypto.EType;
class CipherHelper {
......@@ -77,10 +78,6 @@ class CipherHelper {
private int sgnAlg, sealAlg;
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 {
etype = key.getEType();
keybytes = key.getBytes();
......@@ -106,7 +103,6 @@ class CipherHelper {
case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96:
sgnAlg = -1;
sealAlg = -1;
proto = 1;
break;
default:
......@@ -123,8 +119,10 @@ class CipherHelper {
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() {
return proto;
return EType.isNewer(etype) ? 1 : 0;
}
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -29,6 +29,8 @@ import com.sun.security.jgss.AuthorizationDataEntry;
import org.ietf.jgss.*;
import java.io.InputStream;
import java.io.IOException;
import sun.security.action.GetPropertyAction;
import sun.security.krb5.*;
import java.net.InetAddress;
import sun.security.krb5.internal.AuthorizationData;
......@@ -36,6 +38,33 @@ import sun.security.krb5.internal.KerberosTime;
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;
/**
......@@ -79,7 +108,10 @@ class InitSecContextToken extends InitialToken {
context.setKey(Krb5Context.SESSION_KEY, serviceTicket.getSessionKey());
if (!mutualRequired)
context.resetPeerSequenceNumber(0);
context.resetPeerSequenceNumber(
ACCEPTOR_USE_INITIATOR_SEQNUM
? apReq.getSeqNumber().intValue()
: 0);
}
/**
......@@ -144,10 +176,12 @@ class InitSecContextToken extends InitialToken {
apReqSeqNumber.intValue() :
0);
context.resetPeerSequenceNumber(peerSeqNumber);
if (!context.getMutualAuthState())
// Use the same sequence number as the peer
// (Behaviour exhibited by the Windows SSPI server)
context.resetMySequenceNumber(peerSeqNumber);
if (!context.getMutualAuthState()) {
context.resetMySequenceNumber(
ACCEPTOR_USE_INITIATOR_SEQNUM
? peerSeqNumber
: 0);
}
context.setAuthTime(
new KerberosTime(apReq.getCreds().getAuthTime()).toString());
context.setTktFlags(apReq.getCreds().getFlags());
......
......@@ -713,14 +713,14 @@ class Krb5Context implements GSSContextSpi {
if (subject != null &&
!subject.isReadOnly()) {
/*
* Store the service credentials as
* javax.security.auth.kerberos.KerberosTicket in
* the Subject. We could wait till the context is
* succesfully established; however it is easier
* to do here and there is no harm indoing it here.
*/
* Store the service credentials as
* javax.security.auth.kerberos.KerberosTicket in
* the Subject. We could wait until the context is
* successfully established; however it is easier
* to do it here and there is no harm.
*/
final KerberosTicket kt =
Krb5Util.credsToTicket(serviceCreds);
Krb5Util.credsToTicket(serviceCreds);
AccessController.doPrivileged (
new java.security.PrivilegedAction<Void>() {
public Void run() {
......
......@@ -60,7 +60,9 @@ public class Krb5InitCredential
private Krb5InitCredential(Krb5NameElement name,
byte[] asn1Encoding,
KerberosPrincipal client,
KerberosPrincipal clientAlias,
KerberosPrincipal server,
KerberosPrincipal serverAlias,
byte[] sessionKey,
int keyType,
boolean[] flags,
......@@ -81,14 +83,21 @@ public class Krb5InitCredential
endTime,
renewTill,
clientAddresses);
KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
.kerberosTicketSetClientAlias(this, clientAlias);
KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
.kerberosTicketSetServerAlias(this, serverAlias);
this.name = name;
try {
// Cache this for later use by the sun.security.krb5 package.
krb5Credentials = new Credentials(asn1Encoding,
client.getName(),
(clientAlias != null ?
clientAlias.getName() : null),
server.getName(),
(serverAlias != null ?
serverAlias.getName() : null),
sessionKey,
keyType,
flags,
......@@ -111,7 +120,9 @@ public class Krb5InitCredential
Credentials delegatedCred,
byte[] asn1Encoding,
KerberosPrincipal client,
KerberosPrincipal clientAlias,
KerberosPrincipal server,
KerberosPrincipal serverAlias,
byte[] sessionKey,
int keyType,
boolean[] flags,
......@@ -132,7 +143,10 @@ public class Krb5InitCredential
endTime,
renewTill,
clientAddresses);
KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
.kerberosTicketSetClientAlias(this, clientAlias);
KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
.kerberosTicketSetServerAlias(this, serverAlias);
this.name = name;
// A delegated cred does not have all fields set. So do not try to
// creat new Credentials out of the delegatedCred.
......@@ -154,10 +168,18 @@ public class Krb5InitCredential
Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL);
}
KerberosPrincipal clientAlias = KerberosSecrets
.getJavaxSecurityAuthKerberosAccess()
.kerberosTicketGetClientAlias(tgt);
KerberosPrincipal serverAlias = KerberosSecrets
.getJavaxSecurityAuthKerberosAccess()
.kerberosTicketGetServerAlias(tgt);
Krb5InitCredential result = new Krb5InitCredential(name,
tgt.getEncoded(),
tgt.getClient(),
clientAlias,
tgt.getServer(),
serverAlias,
tgt.getSessionKey().getEncoded(),
tgt.getSessionKeyType(),
tgt.getFlags(),
......@@ -183,10 +205,14 @@ public class Krb5InitCredential
*/
PrincipalName cPrinc = delegatedCred.getClient();
PrincipalName cAPrinc = delegatedCred.getClientAlias();
PrincipalName sPrinc = delegatedCred.getServer();
PrincipalName sAPrinc = delegatedCred.getServerAlias();
KerberosPrincipal client = null;
KerberosPrincipal clientAlias = null;
KerberosPrincipal server = null;
KerberosPrincipal serverAlias = null;
Krb5NameElement credName = null;
......@@ -197,6 +223,10 @@ public class Krb5InitCredential
client = new KerberosPrincipal(fullName);
}
if (cAPrinc != null) {
clientAlias = new KerberosPrincipal(cAPrinc.getName());
}
// XXX Compare name to credName
if (sPrinc != null) {
......@@ -205,11 +235,17 @@ public class Krb5InitCredential
KerberosPrincipal.KRB_NT_SRV_INST);
}
if (sAPrinc != null) {
serverAlias = new KerberosPrincipal(sAPrinc.getName());
}
return new Krb5InitCredential(credName,
delegatedCred,
delegatedCred.getEncoded(),
client,
clientAlias,
server,
serverAlias,
sessionKey.getBytes(),
sessionKey.getEType(),
delegatedCred.getFlags(),
......
......@@ -228,7 +228,7 @@ public class Krb5Util {
public static KerberosTicket credsToTicket(Credentials serviceCreds) {
EncryptionKey sessionKey = serviceCreds.getSessionKey();
return new KerberosTicket(
KerberosTicket kt = new KerberosTicket(
serviceCreds.getEncoded(),
new KerberosPrincipal(serviceCreds.getClient().getName()),
new KerberosPrincipal(serviceCreds.getServer().getName(),
......@@ -241,14 +241,35 @@ public class Krb5Util {
serviceCreds.getEndTime(),
serviceCreds.getRenewTill(),
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)
throws KrbException, IOException {
KerberosPrincipal clientAlias = KerberosSecrets
.getJavaxSecurityAuthKerberosAccess()
.kerberosTicketGetClientAlias(kerbTicket);
KerberosPrincipal serverAlias = KerberosSecrets
.getJavaxSecurityAuthKerberosAccess()
.kerberosTicketGetServerAlias(kerbTicket);
return new Credentials(
kerbTicket.getEncoded(),
kerbTicket.getClient().getName(),
(clientAlias != null ? clientAlias.getName() : null),
kerbTicket.getServer().getName(),
(serverAlias != null ? serverAlias.getName() : null),
kerbTicket.getSessionKey().getEncoded(),
kerbTicket.getSessionKeyType(),
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -499,11 +499,11 @@ abstract class MessageToken_v2 extends Krb5Token {
*/
class MessageTokenHeader {
private int tokenId;
private byte[] bytes = new byte[TOKEN_HEADER_SIZE];
private int tokenId;
private byte[] bytes = new byte[TOKEN_HEADER_SIZE];
// Writes a new token header
public MessageTokenHeader(int tokenId, boolean conf) throws GSSException {
// Writes a new token header
public MessageTokenHeader(int tokenId, boolean conf) throws GSSException {
this.tokenId = tokenId;
......@@ -609,7 +609,7 @@ abstract class MessageToken_v2 extends Krb5Token {
prop.setQOP(0);
// 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -25,6 +25,8 @@
package sun.security.jgss.krb5;
import sun.security.krb5.KerberosSecrets;
import javax.security.auth.kerberos.KerberosTicket;
import javax.security.auth.kerberos.KerberosKey;
import javax.security.auth.Subject;
......@@ -182,24 +184,45 @@ class SubjectComber {
}
} else {
KerberosPrincipal serverAlias = KerberosSecrets
.getJavaxSecurityAuthKerberosAccess()
.kerberosTicketGetServerAlias(ticket);
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 ||
clientPrincipal.equals(
ticket.getClient().getName())) {
ticket.getClient().getName()) ||
(clientAlias != null &&
clientPrincipal.equals(
clientAlias.getName()))) {
if (oneOnly) {
return ticket;
} else {
// Record names so that tickets will
// all belong to same principals
if (clientPrincipal == null) {
clientPrincipal =
ticket.getClient().getName();
if (clientAlias == null) {
clientPrincipal =
ticket.getClient().getName();
} else {
clientPrincipal =
clientAlias.getName();
}
}
if (serverPrincipal == null) {
serverPrincipal =
ticket.getServer().getName();
if (serverAlias == null) {
serverPrincipal =
ticket.getServer().getName();
} else {
serverPrincipal =
serverAlias.getName();
}
}
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -69,6 +69,7 @@ public class Checksum {
// draft-brezak-win2k-krb-rc4-hmac-04.txt
public static final int CKSUMTYPE_HMAC_MD5_ARCFOUR = -138;
// default checksum type, -1 if not set
static int CKSUMTYPE_DEFAULT;
static int SAFECKSUMTYPE_DEFAULT;
......@@ -83,26 +84,19 @@ public class Checksum {
try {
cfg = Config.getInstance();
temp = cfg.get("libdefaults", "default_checksum");
if (temp != null)
{
CKSUMTYPE_DEFAULT = Config.getType(temp);
} else {
/*
* 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;
}
if (temp != null) {
CKSUMTYPE_DEFAULT = Config.getType(temp);
} else {
CKSUMTYPE_DEFAULT = -1;
}
} catch (Exception exc) {
if (DEBUG) {
System.out.println("Exception in getting default checksum "+
"value from the configuration " +
"Setting default checksum to be RSA-MD5");
"value from the configuration. " +
"No default checksum set.");
exc.printStackTrace();
}
CKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5;
CKSUMTYPE_DEFAULT = -1;
}
......@@ -112,97 +106,100 @@ public class Checksum {
{
SAFECKSUMTYPE_DEFAULT = Config.getType(temp);
} else {
SAFECKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5_DES;
SAFECKSUMTYPE_DEFAULT = -1;
}
} catch (Exception exc) {
if (DEBUG) {
System.out.println("Exception in getting safe default " +
"checksum value " +
"from the configuration Setting " +
"safe default checksum to be RSA-MD5");
"from the configuration Setting. " +
"No safe default checksum set.");
exc.printStackTrace();
}
SAFECKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5_DES;
SAFECKSUMTYPE_DEFAULT = -1;
}
}
/**
* 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.
* @new_cksumType the type of checksum.
*
*/
// used in InitialToken
public Checksum(byte[] data, int new_cksumType) {
cksumType = new_cksumType;
checksum = data;
}
/**
* Constructs a new Checksum by calculating the checksum 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.
* Constructs a new Checksum by calculating over the data using
* the specified checksum type. If the checksum is unkeyed, key
* and usage are ignored.
*
* @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)
throws KdcErrException, KrbCryptoException {
cksumType = new_cksumType;
CksumType cksumEngine = CksumType.getInstance(cksumType);
if (!cksumEngine.isSafe()) {
checksum = cksumEngine.calculateChecksum(data, data.length);
public Checksum(int new_cksumType, byte[] data,
EncryptionKey key, int usage)
throws KdcErrException, KrbApErrException, KrbCryptoException {
if (new_cksumType == -1) {
cksumType = EType.getInstance(key.getEType()).checksumType();
} 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
* 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.
* Verifies the keyed checksum over the data passed in.
*/
// KrbSafe, KrbTgsReq
public Checksum(int new_cksumType, byte[] data,
EncryptionKey key, int usage)
throws KdcErrException, KrbApErrException, KrbCryptoException {
cksumType = new_cksumType;
public boolean verifyKeyedChecksum(byte[] data, EncryptionKey key, int usage)
throws KdcErrException, KrbApErrException, KrbCryptoException {
CksumType cksumEngine = CksumType.getInstance(cksumType);
if (!cksumEngine.isSafe())
if (!cksumEngine.isKeyed()) {
throw new KrbApErrException(Krb5.KRB_AP_ERR_INAPP_CKSUM);
checksum =
cksumEngine.calculateKeyedChecksum(data,
data.length,
key.getBytes(),
usage);
} else {
return cksumEngine.verifyChecksum(
data, data.length, key.getBytes(), checksum, 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,
int usage)
throws KdcErrException, KrbApErrException, KrbCryptoException {
CksumType cksumEngine = CksumType.getInstance(cksumType);
if (!cksumEngine.isSafe())
throw new KrbApErrException(Krb5.KRB_AP_ERR_INAPP_CKSUM);
return cksumEngine.verifyKeyedChecksum(data,
data.length,
key.getBytes(),
checksum,
usage);
public boolean verifyAnyChecksum(byte[] data, EncryptionKey key, int usage)
throws KdcErrException, KrbCryptoException {
return CksumType.getInstance(cksumType).verifyChecksum(
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 {
if (cksumType != cksum.cksumType)
if (cksumType != cksum.cksumType) {
return false;
CksumType cksumEngine = CksumType.getInstance(cksumType);
}
return CksumType.isChecksumEqual(checksum, cksum.checksum);
}
......@@ -214,7 +211,7 @@ public class Checksum {
* @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;
if (encoding.getTag() != DerValue.tag_Sequence) {
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -30,25 +30,24 @@
*/
package sun.security.krb5;
import java.io.File;
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.io.*;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.List;
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.security.krb5.internal.crypto.EType;
import sun.security.krb5.internal.Krb5;
import sun.security.util.SecurityProperties;
/**
* This class maintains key-value pairs of Kerberos configurable constants
......@@ -57,6 +56,41 @@ import sun.security.krb5.internal.Krb5;
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.
*/
......@@ -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
* (See {@link #get})
*/
......@@ -267,6 +305,7 @@ public class Config {
StringBuilder sb = new StringBuilder();
boolean first = true;
for (String s: v) {
s = s.replaceAll("[\\s,]+", " ");
if (first) {
sb.append(s);
first = false;
......@@ -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.
* @param keys the keys
......
......@@ -48,7 +48,9 @@ public class Credentials {
Ticket ticket;
PrincipalName client;
PrincipalName clientAlias;
PrincipalName server;
PrincipalName serverAlias;
EncryptionKey key;
TicketFlags flags;
KerberosTime authTime;
......@@ -78,7 +80,9 @@ public class Credentials {
public Credentials(Ticket new_ticket,
PrincipalName new_client,
PrincipalName new_client_alias,
PrincipalName new_server,
PrincipalName new_server_alias,
EncryptionKey new_key,
TicketFlags new_flags,
KerberosTime authTime,
......@@ -87,14 +91,17 @@ public class Credentials {
KerberosTime renewTill,
HostAddresses cAddr,
AuthorizationData authzData) {
this(new_ticket, new_client, new_server, new_key, new_flags,
authTime, new_startTime, new_endTime, renewTill, cAddr);
this(new_ticket, new_client, new_client_alias, new_server,
new_server_alias, new_key, new_flags, authTime,
new_startTime, new_endTime, renewTill, cAddr);
this.authzData = authzData;
}
public Credentials(Ticket new_ticket,
PrincipalName new_client,
PrincipalName new_client_alias,
PrincipalName new_server,
PrincipalName new_server_alias,
EncryptionKey new_key,
TicketFlags new_flags,
KerberosTime authTime,
......@@ -104,7 +111,9 @@ public class Credentials {
HostAddresses cAddr) {
ticket = new_ticket;
client = new_client;
clientAlias = new_client_alias;
server = new_server;
serverAlias = new_server_alias;
key = new_key;
flags = new_flags;
this.authTime = authTime;
......@@ -116,7 +125,9 @@ public class Credentials {
public Credentials(byte[] encoding,
String client,
String clientAlias,
String server,
String serverAlias,
byte[] keyBytes,
int keyType,
boolean[] flags,
......@@ -127,7 +138,11 @@ public class Credentials {
InetAddress[] cAddrs) throws KrbException, IOException {
this(new Ticket(encoding),
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),
(serverAlias == null? null : new PrincipalName(serverAlias,
PrincipalName.KRB_NT_SRV_INST)),
new EncryptionKey(keyType, keyBytes),
(flags == null? null: new TicketFlags(flags)),
(authTime == null? null: new KerberosTime(authTime)),
......@@ -152,10 +167,18 @@ public class Credentials {
return client;
}
public final PrincipalName getClientAlias() {
return clientAlias;
}
public final PrincipalName getServer() {
return server;
}
public final PrincipalName getServerAlias() {
return serverAlias;
}
public final EncryptionKey getSessionKey() {
return key;
}
......@@ -271,6 +294,7 @@ public class Credentials {
return new KrbTgsReq(options,
this,
server,
serverAlias,
null, // from
null, // till
null, // rtime
......@@ -488,7 +512,11 @@ public class Credentials {
public static void printDebug(Credentials c) {
System.out.println(">>> DEBUG: ----Credentials----");
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());
if (c.serverAlias != null)
System.out.println("\tserver alias: " + c.serverAlias.toString());
System.out.println("\tticket: sname: " + c.ticket.sname.toString());
if (c.startTime != null) {
System.out.println("\tstartTime: " + c.startTime.getTime());
......@@ -516,7 +544,11 @@ public class Credentials {
public String toString() {
StringBuffer buffer = new StringBuffer("Credentials:");
buffer.append( "\n client=").append(client);
if (clientAlias != null)
buffer.append( "\n clientAlias=").append(clientAlias);
buffer.append( "\n server=").append(server);
if (serverAlias != null)
buffer.append( "\n serverAlias=").append(serverAlias);
if (authTime != null) {
buffer.append("\n authTime=").append(authTime);
}
......@@ -531,4 +563,23 @@ public class Credentials {
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 @@
package sun.security.krb5;
import javax.security.auth.kerberos.KerberosPrincipal;
import javax.security.auth.kerberos.KerberosTicket;
import javax.security.auth.kerberos.KeyTab;
......@@ -39,6 +40,14 @@ public interface JavaxSecurityAuthKerberosAccess {
public sun.security.krb5.internal.ktab.KeyTab keyTabTakeSnapshot(
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.
*/
......
/*
* 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -361,7 +361,9 @@ public class KrbApReq {
creds = new Credentials(
apReqMessg.ticket,
authenticator.cname,
null,
apReqMessg.ticket.sname,
null,
enc_ticketPart.key,
enc_ticketPart.flags,
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -118,7 +118,7 @@ class KrbAsRep extends KrbKdcRep {
"Cannot find key for type/kvno to decrypt AS REP - " +
EType.toString(encPartKeyType) + "/" + encPartKvno);
}
decrypt(dkey, asReq);
decrypt(dkey, asReq, cname);
}
/**
......@@ -136,7 +136,7 @@ class KrbAsRep extends KrbKdcRep {
password,
encPartKeyType,
PAData.getSaltAndParams(encPartKeyType, rep.pAData));
decrypt(dkey, asReq);
decrypt(dkey, asReq, cname);
}
/**
......@@ -144,7 +144,8 @@ class KrbAsRep extends KrbKdcRep {
* @param dkey the decryption key to use
* @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 {
byte[] enc_as_rep_bytes = rep.encPart.decrypt(dkey,
KeyUsage.KU_ENC_AS_REP_PART);
......@@ -155,12 +156,18 @@ class KrbAsRep extends KrbKdcRep {
rep.encKDCRepPart = enc_part;
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(
rep.ticket,
req.reqBody.cname,
rep.cname,
clientAlias,
enc_part.sname,
null, // No server alias expected in a TGT
enc_part.key,
enc_part.flags,
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -35,6 +35,8 @@ import sun.security.krb5.internal.*;
import sun.security.krb5.internal.crypto.Nonce;
import sun.security.krb5.internal.crypto.KeyUsage;
import java.io.IOException;
import java.time.Instant;
import java.util.Arrays;
/**
* This class encapsulates the KRB-AS-REQ message that the client
......@@ -57,14 +59,14 @@ public class KrbAsReq {
KerberosTime till, // ok, will use
KerberosTime rtime, // ok
int[] eTypes, // NO
HostAddresses addresses // ok
HostAddresses addresses, // ok
PAData[] extraPAs // ok
)
throws KrbException, IOException {
if (options == null) {
options = new KDCOptions();
}
// check if they are valid arguments. The optional fields should be
// consistent with settings in KDCOptions. Mar 17 2000
if (options.get(KDCOptions.FORWARDED) ||
......@@ -82,12 +84,6 @@ public class KrbAsReq {
} else {
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;
if (pakey != null) {
......@@ -99,6 +95,15 @@ public class KrbAsReq {
paData[0] = new PAData( Krb5.PA_ENC_TIMESTAMP,
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) {
throw new RealmException(Krb5.REALM_NULL,
......@@ -109,8 +114,10 @@ public class KrbAsReq {
System.out.println(">>> KrbAsReq creating message");
}
Config cfg = Config.getInstance();
// check to use addresses in tickets
if (addresses == null && Config.getInstance().useAddresses()) {
if (addresses == null && cfg.useAddresses()) {
addresses = HostAddresses.getLocalAddresses();
}
......@@ -120,7 +127,26 @@ public class KrbAsReq {
}
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
......
/*
* 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -68,6 +68,7 @@ public final class KrbAsReqBuilder {
// Common data for AS-REQ fields
private KDCOptions options;
private PrincipalName cname;
private PrincipalName refCname; // May be changed by referrals
private PrincipalName sname;
private KerberosTime from;
private KerberosTime till;
......@@ -100,6 +101,7 @@ public final class KrbAsReqBuilder {
private void init(PrincipalName cname)
throws KrbException {
this.cname = cname;
this.refCname = cname;
state = State.INIT;
}
......@@ -224,6 +226,16 @@ public final class KrbAsReqBuilder {
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
* for cname realm
......@@ -252,7 +264,9 @@ public final class KrbAsReqBuilder {
* @throws KrbException
* @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;
if (password != null) {
eTypes = EType.getDefaults("default_tkt_enctypes");
......@@ -262,15 +276,24 @@ public final class KrbAsReqBuilder {
ks);
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,
options,
cname,
refCname,
sname,
from,
till,
rtime,
eTypes,
addresses);
addresses,
extraPAs);
}
/**
......@@ -308,11 +331,15 @@ public final class KrbAsReqBuilder {
*/
private KrbAsReqBuilder send() throws KrbException, IOException {
boolean preAuthFailedOnce = false;
KdcComm comm = new KdcComm(cname.getRealmAsString());
KdcComm comm = null;
EncryptionKey pakey = null;
ReferralsState referralsState = new ReferralsState();
while (true) {
if (referralsState.refreshComm()) {
comm = new KdcComm(refCname.getRealmAsString());
}
try {
req = build(pakey);
req = build(pakey, referralsState);
rep = new KrbAsRep(comm.send(req.encoding()));
return this;
} catch (KrbException ke) {
......@@ -341,12 +368,71 @@ public final class KrbAsReqBuilder {
}
paList = kerr.getPA(); // Update current paList
} else {
if (referralsState.handleError(ke)) {
pakey = null;
preAuthFailedOnce = false;
continue;
}
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.
* 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -34,6 +34,7 @@ package sun.security.krb5;
import sun.security.krb5.internal.*;
import sun.security.krb5.internal.crypto.KeyUsage;
import java.io.IOException;
import sun.security.util.DerValue;
/**
......@@ -62,7 +63,6 @@ public class KrbCred {
PrincipalName client = tgt.getClient();
PrincipalName tgService = tgt.getServer();
PrincipalName server = serviceTicket.getServer();
if (!serviceTicket.getClient().equals(client))
throw new KrbException(Krb5.KRB_ERR_GENERIC,
"Client principal does not match");
......@@ -75,14 +75,10 @@ public class KrbCred {
options.set(KDCOptions.FORWARDED, 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,
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);
obuf = credMessg.asn1Encode();
......@@ -94,7 +90,6 @@ public class KrbCred {
EncryptionKey sessionKey
= delegatedCreds.getSessionKey();
PrincipalName princ = delegatedCreds.getClient();
Realm realm = princ.getRealm();
PrincipalName tgService = delegatedCreds.getServer();
KrbCredInfo credInfo = new KrbCredInfo(sessionKey,
......@@ -157,7 +152,7 @@ public class KrbCred {
+ " endtime=" + endtime
+ "renewTill=" + renewTill);
}
creds = new Credentials(ticket, pname, sname, credInfoKey,
creds = new Credentials(ticket, pname, null, sname, null, credInfoKey,
flags, authtime, starttime, endtime, renewTill, caddr);
}
......
......@@ -31,23 +31,41 @@
package sun.security.krb5;
import sun.security.krb5.internal.*;
import sun.security.krb5.internal.crypto.KeyUsage;
import sun.security.util.DerInputStream;
abstract class KrbKdcRep {
static void check(
boolean isAsReq,
KDCReq req,
KDCRep rep
KDCRep rep,
EncryptionKey replyKey
) 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();
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)) {
rep.encKDCRepPart.key.destroy();
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
String[] snameStrings = rep.encKDCRepPart.sname.getNameStrings();
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) {
......@@ -82,49 +100,84 @@ abstract class KrbKdcRep {
!rep.encKDCRepPart.flags.get(KDCOptions.RENEWABLE)) {
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
if ((rep.encKDCRepPart.starttime != null) &&
!rep.encKDCRepPart.starttime.inClockSkew()) {
!rep.encKDCRepPart.starttime.inClockSkew()) {
rep.encKDCRepPart.key.destroy();
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
if ((rep.encKDCRepPart.starttime != null) &&
!req.reqBody.from.equals(rep.encKDCRepPart.starttime)) {
!req.reqBody.from.equals(rep.encKDCRepPart.starttime)) {
rep.encKDCRepPart.key.destroy();
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
}
}
if (!req.reqBody.till.isZero() &&
rep.encKDCRepPart.endtime.greaterThan(req.reqBody.till)) {
rep.encKDCRepPart.endtime.greaterThan(req.reqBody.till)) {
rep.encKDCRepPart.key.destroy();
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
}
if (req.reqBody.kdcOptions.get(KDCOptions.RENEWABLE))
if (req.reqBody.rtime != null && !req.reqBody.rtime.isZero())
// verify this is required
if ((rep.encKDCRepPart.renewTill == null) ||
rep.encKDCRepPart.renewTill.greaterThan(req.reqBody.rtime)
) {
rep.encKDCRepPart.key.destroy();
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
// RFC 6806 - Section 11 mechanism check
if (rep.encKDCRepPart.flags.get(Krb5.TKT_OPTS_ENC_PA_REP) &&
req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE)) {
boolean reqPaReqEncPaRep = false;
boolean repPaReqEncPaRepValid = false;
// PA_REQ_ENC_PA_REP only required for AS requests
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) &&
rep.encKDCRepPart.flags.get(KDCOptions.RENEWABLE))
if (!req.reqBody.till.isZero())
// verify this is required
if (req.reqBody.kdcOptions.get(KDCOptions.RENEWABLE)) {
if (req.reqBody.rtime != null && !req.reqBody.rtime.isZero()) {
// verify this is required
if ((rep.encKDCRepPart.renewTill == null) ||
rep.encKDCRepPart.renewTill.greaterThan(req.reqBody.till)
) {
rep.encKDCRepPart.renewTill.greaterThan(req.reqBody.rtime)
) {
rep.encKDCRepPart.key.destroy();
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -84,11 +84,22 @@ public class KrbTgsRep extends KrbKdcRep {
EncTGSRepPart enc_part = new EncTGSRepPart(ref);
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,
rep.cname,
tgsReq.getClientAlias(),
enc_part.sname,
serverAlias,
enc_part.key,
enc_part.flags,
enc_part.authtime,
......@@ -111,4 +122,16 @@ public class KrbTgsRep extends KrbKdcRep {
sun.security.krb5.internal.ccache.Credentials setCredentials() {
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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -35,6 +35,7 @@ import sun.security.krb5.internal.*;
import sun.security.krb5.internal.crypto.*;
import java.io.IOException;
import java.net.UnknownHostException;
import java.time.Instant;
import java.util.Arrays;
/**
......@@ -44,7 +45,9 @@ import java.util.Arrays;
public class KrbTgsReq {
private PrincipalName princName;
private PrincipalName clientAlias;
private PrincipalName servName;
private PrincipalName serverAlias;
private TGSReq tgsReqMessg;
private KerberosTime ctime;
private Ticket secondTicket = null;
......@@ -57,59 +60,26 @@ public class KrbTgsReq {
private byte[] ibuf;
// Used in CredentialsUtil
public KrbTgsReq(Credentials asCreds,
PrincipalName sname)
public KrbTgsReq(KDCOptions options, Credentials asCreds,
PrincipalName cname, PrincipalName clientAlias,
PrincipalName sname, PrincipalName serverAlias,
Ticket[] additionalTickets, PAData[] extraPAs)
throws KrbException, IOException {
this(new KDCOptions(),
asCreds,
sname,
null, // KerberosTime from
null, // KerberosTime till
null, // KerberosTime rtime
null, // eTypes, // null, // int[] eTypes
null, // HostAddresses addresses
null, // AuthorizationData authorizationData
null, // Ticket[] additionalTickets
null); // EncryptionKey subSessionKey
}
// S4U2proxy
public KrbTgsReq(Credentials asCreds,
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
this(options,
asCreds,
cname,
clientAlias,
sname,
serverAlias,
null, // KerberosTime from
null, // KerberosTime till
null, // KerberosTime rtime
null, // int[] eTypes
null, // HostAddresses addresses
null, // AuthorizationData authorizationData
additionalTickets,
null, // EncryptionKey subKey
extraPAs);
}
// Called by Credentials, KrbCred
......@@ -117,6 +87,7 @@ public class KrbTgsReq {
KDCOptions options,
Credentials asCreds,
PrincipalName sname,
PrincipalName serverAlias,
KerberosTime from,
KerberosTime till,
KerberosTime rtime,
......@@ -125,16 +96,18 @@ public class KrbTgsReq {
AuthorizationData authorizationData,
Ticket[] additionalTickets,
EncryptionKey subKey) throws KrbException, IOException {
this(options, asCreds, asCreds.getClient(), sname,
from, till, rtime, eTypes, addresses,
authorizationData, additionalTickets, subKey, null);
this(options, asCreds, asCreds.getClient(), asCreds.getClientAlias(),
sname, serverAlias, from, till, rtime, eTypes,
addresses, authorizationData, additionalTickets, subKey, null);
}
private KrbTgsReq(
KDCOptions options,
Credentials asCreds,
PrincipalName cname,
PrincipalName clientAlias,
PrincipalName sname,
PrincipalName serverAlias,
KerberosTime from,
KerberosTime till,
KerberosTime rtime,
......@@ -143,10 +116,12 @@ public class KrbTgsReq {
AuthorizationData authorizationData,
Ticket[] additionalTickets,
EncryptionKey subKey,
PAData extraPA) throws KrbException, IOException {
PAData[] extraPAs) throws KrbException, IOException {
princName = cname;
this.clientAlias = clientAlias;
servName = sname;
this.serverAlias = serverAlias;
ctime = KerberosTime.now();
// check if they are valid arguments. The optional fields
......@@ -216,7 +191,7 @@ public class KrbTgsReq {
authorizationData,
additionalTickets,
subKey,
extraPA);
extraPAs);
obuf = tgsReqMessg.asn1Encode();
// XXX We need to revisit this to see if can't move it
......@@ -282,11 +257,16 @@ public class KrbTgsReq {
AuthorizationData authorizationData,
Ticket[] additionalTickets,
EncryptionKey subKey,
PAData extraPA)
PAData[] extraPAs)
throws IOException, KrbException, UnknownHostException {
KerberosTime req_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 {
req_till = till;
}
......@@ -340,26 +320,8 @@ public class KrbTgsReq {
byte[] temp = reqBody.asn1Encode(Krb5.KRB_TGS_REQ);
// if the checksum type is one of the keyed checksum types,
// use session key.
Checksum cksum;
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,
Checksum cksum = new Checksum(Checksum.CKSUMTYPE_DEFAULT, temp, key,
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
......@@ -375,11 +337,14 @@ public class KrbTgsReq {
null).getMessage();
PAData tgsPAData = new PAData(Krb5.PA_TGS_REQ, tgs_ap_req);
return new TGSReq(
extraPA != null ?
new PAData[] {extraPA, tgsPAData } :
new PAData[] {tgsPAData},
reqBody);
PAData[] pa;
if (extraPAs != null) {
pa = Arrays.copyOf(extraPAs, extraPAs.length + 1);
pa[extraPAs.length] = tgsPAData;
} else {
pa = new PAData[] {tgsPAData};
}
return new TGSReq(pa, reqBody);
}
TGSReq getMessage() {
......@@ -390,6 +355,14 @@ public class KrbTgsReq {
return secondTicket;
}
PrincipalName getClientAlias() {
return clientAlias;
}
PrincipalName getServerAlias() {
return serverAlias;
}
private static void debug(String 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.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -90,6 +90,11 @@ public class PrincipalName implements Cloneable {
*/
public static final int KRB_NT_UID = 5;
/**
* Enterprise name (alias)
*/
public static final int KRB_NT_ENTERPRISE = 10;
/**
* TGS Name
*/
......@@ -454,6 +459,7 @@ public class PrincipalName implements Cloneable {
case KRB_NT_SRV_INST:
case KRB_NT_SRV_XHST:
case KRB_NT_UID:
case KRB_NT_ENTERPRISE:
nameStrings = nameParts;
nameType = type;
if (realm != null) {
......@@ -547,7 +553,9 @@ public class PrincipalName implements Cloneable {
for (int i = 0; i < nameStrings.length; i++) {
if (i > 0)
str.append("/");
str.append(nameStrings[i]);
String n = nameStrings[i];
n = n.replace("@", "\\@");
str.append(n);
}
str.append("@");
str.append(nameRealm.toString());
......
......@@ -47,7 +47,8 @@ public class EncASRepPart extends EncKDCRepPart {
KerberosTime new_endtime,
KerberosTime new_renewTill,
PrincipalName new_sname,
HostAddresses new_caddr) {
HostAddresses new_caddr,
PAData[] new_pAData) {
super(
new_key,
new_lastReq,
......@@ -60,6 +61,7 @@ public class EncASRepPart extends EncKDCRepPart {
new_renewTill,
new_sname,
new_caddr,
new_pAData,
Krb5.KRB_ENC_AS_REP_PART
);
//may need to use Krb5.KRB_ENC_TGS_REP_PART to mimic
......
......@@ -46,7 +46,8 @@ public class EncTGSRepPart extends EncKDCRepPart {
KerberosTime new_endtime,
KerberosTime new_renewTill,
PrincipalName new_sname,
HostAddresses new_caddr) {
HostAddresses new_caddr,
PAData[] new_pAData) {
super(
new_key,
new_lastReq,
......@@ -59,6 +60,7 @@ public class EncTGSRepPart extends EncKDCRepPart {
new_renewTill,
new_sname,
new_caddr,
new_pAData,
Krb5.KRB_ENC_TGS_REP_PART);
}
......
......@@ -39,6 +39,7 @@ import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.UnknownHostException;
import java.io.IOException;
import java.util.Arrays;
/**
* Implements the ASN.1 HostAddress type.
......@@ -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 {
public static final int UNUSED10 = 10;
public static final int UNUSED11 = 11;
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 ENC_TKT_IN_SKEY = 28;
public static final int RENEW = 30;
......@@ -160,7 +161,8 @@ public class KDCOptions extends KerberosFlags {
"UNUSED11", //11;
null,null,
"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;
"ENC_TKT_IN_SKEY", //28;
null,
......
......@@ -38,6 +38,7 @@ import sun.security.util.DerOutputStream;
import sun.security.util.DerValue;
import java.io.IOException;
import java.time.Instant;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
......@@ -128,6 +129,14 @@ public class KerberosTime {
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()
* 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.
先完成此消息的编辑!
想要评论请 注册