提交 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
......@@ -774,15 +763,12 @@ public final class JceKeyStore extends KeyStoreSpi {
}
}
// 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,12 +851,9 @@ 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]) {
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",
......@@ -883,7 +861,6 @@ public final class JceKeyStore extends KeyStoreSpi {
"Password verification failed"));
}
}
}
} finally {
if (ois != null) {
ois.close();
......
......@@ -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,15 +666,15 @@ public class Krb5LoginModule implements LoginModule {
(principal, ticketCacheName);
if (cred != null) {
// check to renew credentials
if (!isCurrent(cred)) {
if (renewTGT) {
if (renewTGT && isOld(cred)) {
// renew if ticket is old.
Credentials newCred = renewCredentials(cred);
if (newCred != null) {
newCred.setProxy(cred.getProxy());
}
cred = newCred;
} else {
}
}
if (!isCurrent(cred)) {
// credentials have expired
cred = null;
if (debug)
......@@ -681,7 +682,6 @@ public class Krb5LoginModule implements LoginModule {
" no longer valid");
}
}
}
if (cred != null) {
// get the principal name from the ticket cache
......@@ -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) |
int 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;
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,7 +859,7 @@ 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);
......
......@@ -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) {
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) {
declaredAnnotations = root.declaredAnnotations();
declAnnos = root.declaredAnnotations();
} else {
declaredAnnotations = AnnotationParser.parseAnnotations(
declAnnos = AnnotationParser.parseAnnotations(
getAnnotationBytes(),
sun.misc.SharedSecrets.getJavaLangAccess().
getConstantPool(getDeclaringClass()),
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) {
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) {
declaredAnnotations = root.declaredAnnotations();
declAnnos = root.declaredAnnotations();
} else {
declaredAnnotations = AnnotationParser.parseAnnotations(
declAnnos = AnnotationParser.parseAnnotations(
annotations,
sun.misc.SharedSecrets.getJavaLangAccess().getConstantPool(getDeclaringClass()),
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;
boolean blocking = !nonBlocking;
if (block != blocking) {
if (block && haveValidKeys())
throw new IllegalBlockingModeException();
implConfigureBlocking(block);
blocking = 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,7 +36,7 @@ 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;
......@@ -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,9 +411,15 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener
component.addMouseListener(this);
component.removeMouseMotionListener(moveBeforeEnterListener);
component.addMouseMotionListener(moveBeforeEnterListener);
// 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);
}
}
/**
* Removes a component from tooltip control.
......@@ -421,8 +429,12 @@ public class ToolTipManager extends MouseAdapter implements MouseMotionListener
public void unregisterComponent(JComponent component) {
component.removeMouseListener(this);
component.removeMouseMotionListener(moveBeforeEnterListener);
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);
if (length < 0) {
throw new IOException("length cannot be negative: " + length);
}
} else {
bytesToRead = output.length - pos;
byte[] data = readNBytes(is, length);
if (data.length < length) {
throw new EOFException();
}
return data;
}
int cc = is.read(output, pos, bytesToRead);
if (cc < 0) {
if (readAll && length != Integer.MAX_VALUE) {
throw new EOFException("Detect premature EOF");
/**
* 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;
}
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,6 +203,16 @@ 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() {
if (javaObjectInputStreamAccess == null) {
......
/*
* 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,18 +1249,50 @@ 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;
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('/');
......@@ -1267,12 +1304,18 @@ public class URLClassPath {
return url;
}
}
return null;
}
} catch (MalformedURLException | IllegalArgumentException e) {}
if (DEBUG_CP_URL_CHECK) {
System.err.println("Class-Path entry: \"" + path + "\" ignored in JAR file " + base);
/**
* 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;
}
return null;
}
}
......
......@@ -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. */
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");
}
}
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,7 +193,6 @@ public class ServerSocketAdaptor // package-private
if (!isBound())
return "ServerSocket[unbound]";
return "ServerSocket[addr=" + getInetAddress() +
// ",port=" + getPort() +
",localport=" + getLocalPort() + "]";
}
......
......@@ -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,16 +383,13 @@ 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;
}
}
protected PermissionCollection getPermissions(CodeSource codesource)
......
......@@ -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());
......
......@@ -715,9 +715,9 @@ class Krb5Context implements GSSContextSpi {
/*
* 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.
* 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);
......
......@@ -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
......@@ -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) {
if (clientAlias == null) {
clientPrincipal =
ticket.getClient().getName();
} else {
clientPrincipal =
clientAlias.getName();
}
}
if (serverPrincipal == null) {
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)
{
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;
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.
*/
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);
} else {
throw new KdcErrException(Krb5.KRB_AP_ERR_INAPP_CKSUM);
}
}
/**
* 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.
* 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
*/
// KrbSafe, KrbTgsReq
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 {
cksumType = new_cksumType;
CksumType cksumEngine = CksumType.getInstance(cksumType);
if (!cksumEngine.isSafe())
throw new KrbApErrException(Krb5.KRB_AP_ERR_INAPP_CKSUM);
checksum =
cksumEngine.calculateKeyedChecksum(data,
data.length,
key.getBytes(),
usage);
}
checksum = CksumType.getInstance(cksumType).calculateChecksum(
data, data.length, key.getBytes(), usage);
}
/**
* Verifies the keyed checksum over the data passed in.
*/
public boolean verifyKeyedChecksum(byte[] data, EncryptionKey key,
int usage)
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);
return cksumEngine.verifyKeyedChecksum(data,
data.length,
key.getBytes(),
checksum,
usage);
} else {
return cksumEngine.verifyChecksum(
data, data.length, key.getBytes(), checksum, usage);
}
/*
public Checksum(byte[] data) throws KdcErrException, KrbCryptoException {
this(Checksum.CKSUMTYPE_DEFAULT, data);
}
/**
* 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 verifyAnyChecksum(byte[] data, EncryptionKey key, int usage)
throws KdcErrException, KrbCryptoException {
return CksumType.getInstance(cksumType).verifyChecksum(
data, data.length, key.getBytes(), checksum, usage);
}
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,8 +127,27 @@ public class KrbAsReq {
}
if (till == null) {
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
KDCReqBody kdc_req_body = new KDCReqBody(options,
......
/*
* 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,24 +31,42 @@
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)) {
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) {
rep.encKDCRepPart.key.destroy();
......@@ -82,21 +100,24 @@ 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.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)) {
rep.encKDCRepPart.key.destroy();
throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED);
}
}
if (!req.reqBody.till.isZero() &&
rep.encKDCRepPart.endtime.greaterThan(req.reqBody.till)) {
......@@ -104,27 +125,59 @@ abstract class KrbKdcRep {
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();
// 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())
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(),
this(options,
asCreds,
cname,
clientAlias,
sname,
serverAlias,
null, // KerberosTime from
null, // KerberosTime till
null, // KerberosTime rtime
null, // eTypes, // null, // int[] 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
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
......
......@@ -31,7 +31,6 @@
package sun.security.krb5.internal;
import sun.security.krb5.*;
import sun.security.krb5.EncryptionKey;
import sun.security.util.*;
import java.util.Vector;
import java.io.IOException;
......@@ -53,7 +52,8 @@ import java.math.BigInteger;
* renew-till [8] KerberosTime OPTIONAL,
* srealm [9] Realm,
* sname [10] PrincipalName,
* caddr [11] HostAddresses OPTIONAL
* caddr [11] HostAddresses OPTIONAL,
* encrypted-pa-data [12] SEQUENCE OF PA-DATA OPTIONAL
* }
* </xmp>
*
......@@ -76,6 +76,7 @@ public class EncKDCRepPart {
public KerberosTime renewTill; //optional
public PrincipalName sname;
public HostAddresses caddr; //optional
public PAData[] pAData; //optional
public int msgType; //not included in sequence
public EncKDCRepPart(
......@@ -90,6 +91,7 @@ public class EncKDCRepPart {
KerberosTime new_renewTill,
PrincipalName new_sname,
HostAddresses new_caddr,
PAData[] new_pAData,
int new_msgType) {
key = new_key;
lastReq = new_lastReq;
......@@ -102,6 +104,7 @@ public class EncKDCRepPart {
renewTill = new_renewTill;
sname = new_sname;
caddr = new_caddr;
pAData = new_pAData;
msgType = new_msgType;
}
......@@ -160,6 +163,9 @@ public class EncKDCRepPart {
if (der.getData().available() > 0) {
caddr = HostAddresses.parse(der.getData(), (byte) 0x0B, true);
}
if (der.getData().available() > 0) {
pAData = PAData.parseSequence(der.getData(), (byte) 0x0C, true);
}
// We observe extra data from MSAD
/*if (der.getData().available() > 0) {
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
......@@ -175,47 +181,58 @@ public class EncKDCRepPart {
*/
public byte[] asn1Encode(int rep_type) throws Asn1Exception,
IOException {
DerOutputStream bytes;
DerOutputStream temp = new DerOutputStream();
DerOutputStream bytes = new DerOutputStream();
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
DerOutputStream out = new DerOutputStream();
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x00), key.asn1Encode());
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x01), lastReq.asn1Encode());
temp.putInteger(BigInteger.valueOf(nonce));
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x02), temp);
if (keyExpiration != null) {
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x03), keyExpiration.asn1Encode());
}
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x04), flags.asn1Encode());
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x05), authtime.asn1Encode());
if (starttime != null) {
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x06), starttime.asn1Encode());
}
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x07), endtime.asn1Encode());
if (renewTill != null) {
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x08), renewTill.asn1Encode());
}
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x09), sname.getRealm().asn1Encode());
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x0A), sname.asn1Encode());
if (caddr != null) {
bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT,
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x0B), caddr.asn1Encode());
}
if (pAData != null && pAData.length > 0) {
temp = new DerOutputStream();
for (int i = 0; i < pAData.length; i++) {
temp.write(pAData[i].asn1Encode());
}
bytes = new DerOutputStream();
bytes.write(DerValue.tag_SequenceOf, temp);
out.write(DerValue.createTag(DerValue.TAG_CONTEXT,
true, (byte) 0x0C), bytes);
}
//should use the rep_type to build the encoding
//but other implementations do not; it is ignored and
//the cached msgType is used instead
temp = new DerOutputStream();
temp.write(DerValue.tag_Sequence, bytes);
temp.write(DerValue.tag_Sequence, out);
bytes = new DerOutputStream();
bytes.write(DerValue.createTag(DerValue.TAG_APPLICATION,
true, (byte) msgType), temp);
......
......@@ -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,
......
......@@ -59,9 +59,9 @@ import java.math.BigInteger;
public class KDCReq {
public KDCReqBody reqBody;
public PAData[] pAData = null; //optional
private int pvno;
private int msgType;
private PAData[] pAData = null; //optional
public KDCReq(PAData[] new_pAData, KDCReqBody new_reqBody,
int req_type) throws IOException {
......@@ -144,23 +144,7 @@ public class KDCReq {
} else {
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
}
if ((der.getData().peekByte() & 0x1F) == 0x03) {
subDer = der.getData().getDerValue();
DerValue subsubDer = subDer.getData().getDerValue();
if (subsubDer.getTag() != DerValue.tag_SequenceOf) {
throw new Asn1Exception(Krb5.ASN1_BAD_ID);
}
Vector<PAData> v = new Vector<>();
while (subsubDer.getData().available() > 0) {
v.addElement(new PAData(subsubDer.getData().getDerValue()));
}
if (v.size() > 0) {
pAData = new PAData[v.size()];
v.copyInto(pAData);
}
} else {
pAData = null;
}
pAData = PAData.parseSequence(der.getData(), (byte) 0x03, true);
subDer = der.getData().getDerValue();
if ((subDer.getTag() & 0x01F) == 0x04) {
DerValue subsubDer = subDer.getData().getDerValue();
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册