提交 caa310e6 编写于 作者: A andrew

Merge

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