feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
@@ -0,0 +1,416 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal.ccache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import sun.misc.IOUtils;
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.krb5.internal.util.KrbDataInputStream;
|
||||
|
||||
/**
|
||||
* This class extends KrbDataInputStream. It is used for parsing FCC-format
|
||||
* data from file to memory.
|
||||
*
|
||||
* @author Yanni Zhang
|
||||
*
|
||||
*/
|
||||
public class CCacheInputStream extends KrbDataInputStream implements FileCCacheConstants {
|
||||
|
||||
/*
|
||||
* FCC version 2 contains type information for principals. FCC
|
||||
* version 1 does not.
|
||||
*
|
||||
* FCC version 3 contains keyblock encryption type information, and is
|
||||
* architecture independent. Previous versions are not.
|
||||
*
|
||||
* The code will accept version 1, 2, and 3 ccaches, and depending
|
||||
* what KRB5_FCC_DEFAULT_FVNO is set to, it will create version 1, 2,
|
||||
* or 3 FCC caches.
|
||||
*
|
||||
* The default credentials cache should be type 3 for now (see
|
||||
* init_ctx.c).
|
||||
*/
|
||||
/* V4 of the credentials cache format allows for header tags */
|
||||
|
||||
private static boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
public CCacheInputStream(InputStream is){
|
||||
super(is);
|
||||
}
|
||||
|
||||
/* Read tag field introduced in KRB5_FCC_FVNO_4 */
|
||||
// this needs to be public for Kinit.
|
||||
public Tag readTag() throws IOException {
|
||||
char[] buf = new char[1024];
|
||||
int len;
|
||||
int tag = -1;
|
||||
int taglen;
|
||||
Integer time_offset = null;
|
||||
Integer usec_offset = null;
|
||||
|
||||
len = read(2);
|
||||
if (len < 0) {
|
||||
throw new IOException("stop.");
|
||||
}
|
||||
if (len > buf.length) {
|
||||
throw new IOException("Invalid tag length.");
|
||||
}
|
||||
while (len > 0) {
|
||||
tag = read(2);
|
||||
taglen = read(2);
|
||||
switch (tag) {
|
||||
case FCC_TAG_DELTATIME:
|
||||
time_offset = new Integer(read(4));
|
||||
usec_offset = new Integer(read(4));
|
||||
break;
|
||||
default:
|
||||
}
|
||||
len = len - (4 + taglen);
|
||||
}
|
||||
return new Tag(len, tag, time_offset, usec_offset);
|
||||
}
|
||||
/*
|
||||
* In file-based credential cache, the realm name is stored as part of
|
||||
* principal name at the first place.
|
||||
*/
|
||||
// made public for KinitOptions to call directly
|
||||
public PrincipalName readPrincipal(int version) throws IOException, RealmException {
|
||||
int type, length, namelength, kret;
|
||||
String[] pname = null;
|
||||
String realm;
|
||||
/* Read principal type */
|
||||
if (version == KRB5_FCC_FVNO_1) {
|
||||
type = KRB5_NT_UNKNOWN;
|
||||
} else {
|
||||
type = read(4);
|
||||
}
|
||||
length = readLength4();
|
||||
List<String> result = new ArrayList<String>();
|
||||
/*
|
||||
* DCE includes the principal's realm in the count; the new format
|
||||
* does not.
|
||||
*/
|
||||
if (version == KRB5_FCC_FVNO_1)
|
||||
length--;
|
||||
for (int i = 0; i <= length; i++) {
|
||||
namelength = readLength4();
|
||||
byte[] bytes = IOUtils.readExactlyNBytes(this, namelength);
|
||||
result.add(new String(bytes));
|
||||
}
|
||||
if (result.isEmpty()) {
|
||||
throw new IOException("No realm or principal");
|
||||
}
|
||||
if (isRealm(result.get(0))) {
|
||||
realm = result.remove(0);
|
||||
if (result.isEmpty()) {
|
||||
throw new IOException("No principal name components");
|
||||
}
|
||||
return new PrincipalName(
|
||||
type,
|
||||
result.toArray(new String[result.size()]),
|
||||
new Realm(realm));
|
||||
}
|
||||
try {
|
||||
return new PrincipalName(
|
||||
type,
|
||||
result.toArray(new String[result.size()]),
|
||||
Realm.getDefault());
|
||||
} catch (RealmException re) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* In practice, a realm is named by uppercasing the DNS domain name. we currently
|
||||
* rely on this to determine if the string within the principal identifier is realm
|
||||
* name.
|
||||
*
|
||||
*/
|
||||
boolean isRealm(String str) {
|
||||
try {
|
||||
Realm r = new Realm(str);
|
||||
}
|
||||
catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
StringTokenizer st = new StringTokenizer(str, ".");
|
||||
String s;
|
||||
while (st.hasMoreTokens()) {
|
||||
s = st.nextToken();
|
||||
for (int i = 0; i < s.length(); i++) {
|
||||
if (s.charAt(i) >= 141) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
EncryptionKey readKey(int version) throws IOException {
|
||||
int keyType, keyLen;
|
||||
keyType = read(2);
|
||||
if (version == KRB5_FCC_FVNO_3)
|
||||
read(2); /* keytype recorded twice in fvno 3 */
|
||||
keyLen = readLength4();
|
||||
byte[] bytes = IOUtils.readExactlyNBytes(this, keyLen);
|
||||
return new EncryptionKey(bytes, keyType, new Integer(version));
|
||||
}
|
||||
|
||||
long[] readTimes() throws IOException {
|
||||
long[] times = new long[4];
|
||||
times[0] = (long)read(4) * 1000;
|
||||
times[1] = (long)read(4) * 1000;
|
||||
times[2] = (long)read(4) * 1000;
|
||||
times[3] = (long)read(4) * 1000;
|
||||
return times;
|
||||
}
|
||||
|
||||
boolean readskey() throws IOException {
|
||||
if (read() == 0) {
|
||||
return false;
|
||||
}
|
||||
else return true;
|
||||
}
|
||||
|
||||
HostAddress[] readAddr() throws IOException, KrbApErrException {
|
||||
int numAddrs, addrType, addrLength;
|
||||
numAddrs = readLength4();
|
||||
if (numAddrs > 0) {
|
||||
List<HostAddress> addrs = new ArrayList<>();
|
||||
for (int i = 0; i < numAddrs; i++) {
|
||||
addrType = read(2);
|
||||
addrLength = readLength4();
|
||||
if (!(addrLength == 4 || addrLength == 16)) {
|
||||
if (DEBUG) {
|
||||
System.out.println("Incorrect address format.");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
byte[] result = new byte[addrLength];
|
||||
for (int j = 0; j < addrLength; j++)
|
||||
result[j] = (byte)read(1);
|
||||
addrs.add(new HostAddress(addrType, result));
|
||||
}
|
||||
return addrs.toArray(new HostAddress[addrs.size()]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
AuthorizationDataEntry[] readAuth() throws IOException {
|
||||
int num, adtype, adlength;
|
||||
num = readLength4();
|
||||
if (num > 0) {
|
||||
List<AuthorizationDataEntry> auData = new ArrayList<>();
|
||||
byte[] data = null;
|
||||
for (int i = 0; i < num; i++) {
|
||||
adtype = read(2);
|
||||
adlength = readLength4();
|
||||
data = IOUtils.readExactlyNBytes(this, adlength);
|
||||
auData.add(new AuthorizationDataEntry(adtype, data));
|
||||
}
|
||||
return auData.toArray(new AuthorizationDataEntry[auData.size()]);
|
||||
}
|
||||
else return null;
|
||||
}
|
||||
|
||||
byte[] readData() throws IOException {
|
||||
int length;
|
||||
length = readLength4();
|
||||
if (length == 0) {
|
||||
return null;
|
||||
} else {
|
||||
return IOUtils.readExactlyNBytes(this, length);
|
||||
}
|
||||
}
|
||||
|
||||
boolean[] readFlags() throws IOException {
|
||||
boolean[] flags = new boolean[Krb5.TKT_OPTS_MAX+1];
|
||||
int ticketFlags;
|
||||
ticketFlags = read(4);
|
||||
if ((ticketFlags & 0x40000000) == TKT_FLG_FORWARDABLE)
|
||||
flags[1] = true;
|
||||
if ((ticketFlags & 0x20000000) == TKT_FLG_FORWARDED)
|
||||
flags[2] = true;
|
||||
if ((ticketFlags & 0x10000000) == TKT_FLG_PROXIABLE)
|
||||
flags[3] = true;
|
||||
if ((ticketFlags & 0x08000000) == TKT_FLG_PROXY)
|
||||
flags[4] = true;
|
||||
if ((ticketFlags & 0x04000000) == TKT_FLG_MAY_POSTDATE)
|
||||
flags[5] = true;
|
||||
if ((ticketFlags & 0x02000000) == TKT_FLG_POSTDATED)
|
||||
flags[6] = true;
|
||||
if ((ticketFlags & 0x01000000) == TKT_FLG_INVALID)
|
||||
flags[7] = true;
|
||||
if ((ticketFlags & 0x00800000) == TKT_FLG_RENEWABLE)
|
||||
flags[8] = true;
|
||||
if ((ticketFlags & 0x00400000) == TKT_FLG_INITIAL)
|
||||
flags[9] = true;
|
||||
if ((ticketFlags & 0x00200000) == TKT_FLG_PRE_AUTH)
|
||||
flags[10] = true;
|
||||
if ((ticketFlags & 0x00100000) == TKT_FLG_HW_AUTH)
|
||||
flags[11] = true;
|
||||
if (DEBUG) {
|
||||
String msg = ">>> CCacheInputStream: readFlags() ";
|
||||
if (flags[1] == true) {
|
||||
msg += " FORWARDABLE;";
|
||||
}
|
||||
if (flags[2] == true) {
|
||||
msg += " FORWARDED;";
|
||||
}
|
||||
if (flags[3] == true) {
|
||||
msg += " PROXIABLE;";
|
||||
}
|
||||
if (flags[4] == true) {
|
||||
msg += " PROXY;";
|
||||
}
|
||||
if (flags[5] == true) {
|
||||
msg += " MAY_POSTDATE;";
|
||||
}
|
||||
if (flags[6] == true) {
|
||||
msg += " POSTDATED;";
|
||||
}
|
||||
if (flags[7] == true) {
|
||||
msg += " INVALID;";
|
||||
}
|
||||
if (flags[8] == true) {
|
||||
msg += " RENEWABLE;";
|
||||
}
|
||||
|
||||
if (flags[9] == true) {
|
||||
msg += " INITIAL;";
|
||||
}
|
||||
if (flags[10] == true) {
|
||||
msg += " PRE_AUTH;";
|
||||
}
|
||||
if (flags[11] == true) {
|
||||
msg += " HW_AUTH;";
|
||||
}
|
||||
System.out.println(msg);
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the next cred or config entry in stream.
|
||||
* @return the next cred or config entry, null if data unparseable.
|
||||
*
|
||||
* When data is unparseable, this method makes sure the correct number of
|
||||
* bytes are consumed so it's safe to start reading the next element.
|
||||
*/
|
||||
Object readCred(int version) throws IOException,RealmException, KrbApErrException, Asn1Exception {
|
||||
PrincipalName cpname = null;
|
||||
try {
|
||||
cpname = readPrincipal(version);
|
||||
} catch (Exception e) {
|
||||
// Do not return here. All data for this cred should be fully
|
||||
// consumed so that we can read the next one.
|
||||
}
|
||||
if (DEBUG) {
|
||||
System.out.println(">>>DEBUG <CCacheInputStream> client principal is " + cpname);
|
||||
}
|
||||
PrincipalName spname = null;
|
||||
try {
|
||||
spname = readPrincipal(version);
|
||||
} catch (Exception e) {
|
||||
// same as above
|
||||
}
|
||||
if (DEBUG) {
|
||||
System.out.println(">>>DEBUG <CCacheInputStream> server principal is " + spname);
|
||||
}
|
||||
EncryptionKey key = readKey(version);
|
||||
if (DEBUG) {
|
||||
System.out.println(">>>DEBUG <CCacheInputStream> key type: " + key.getEType());
|
||||
}
|
||||
long times[] = readTimes();
|
||||
KerberosTime authtime = new KerberosTime(times[0]);
|
||||
KerberosTime starttime =
|
||||
(times[1]==0) ? null : new KerberosTime(times[1]);
|
||||
KerberosTime endtime = new KerberosTime(times[2]);
|
||||
KerberosTime renewTill =
|
||||
(times[3]==0) ? null : new KerberosTime(times[3]);
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println(">>>DEBUG <CCacheInputStream> auth time: " + authtime.toDate().toString());
|
||||
System.out.println(">>>DEBUG <CCacheInputStream> start time: " +
|
||||
((starttime==null)?"null":starttime.toDate().toString()));
|
||||
System.out.println(">>>DEBUG <CCacheInputStream> end time: " + endtime.toDate().toString());
|
||||
System.out.println(">>>DEBUG <CCacheInputStream> renew_till time: " +
|
||||
((renewTill==null)?"null":renewTill.toDate().toString()));
|
||||
}
|
||||
boolean skey = readskey();
|
||||
boolean flags[] = readFlags();
|
||||
TicketFlags tFlags = new TicketFlags(flags);
|
||||
HostAddress addr[] = readAddr();
|
||||
HostAddresses addrs = null;
|
||||
if (addr != null) {
|
||||
addrs = new HostAddresses(addr);
|
||||
}
|
||||
AuthorizationDataEntry[] auDataEntry = readAuth();
|
||||
AuthorizationData auData = null;
|
||||
if (auDataEntry != null) {
|
||||
auData = new AuthorizationData(auDataEntry);
|
||||
}
|
||||
byte[] ticketData = readData();
|
||||
byte[] ticketData2 = readData();
|
||||
|
||||
// Skip this cred if either cpname or spname isn't created.
|
||||
if (cpname == null || spname == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
if (spname.getRealmString().equals("X-CACHECONF:")) {
|
||||
String[] nameParts = spname.getNameStrings();
|
||||
if (nameParts[0].equals("krb5_ccache_conf_data")) {
|
||||
return new CredentialsCache.ConfigEntry(nameParts[1],
|
||||
nameParts.length > 2 ? new PrincipalName(nameParts[2]) : null,
|
||||
ticketData);
|
||||
}
|
||||
}
|
||||
return new Credentials(cpname, spname, key, authtime, starttime,
|
||||
endtime, renewTill, skey, tFlags,
|
||||
addrs, auData,
|
||||
ticketData != null ? new Ticket(ticketData) : null,
|
||||
ticketData2 != null ? new Ticket(ticketData2) : null);
|
||||
} catch (Exception e) { // If any of new Ticket(*) fails.
|
||||
if (DEBUG) {
|
||||
e.printStackTrace(System.out);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal.ccache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import sun.security.krb5.internal.util.KrbDataOutputStream;
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.krb5.internal.*;
|
||||
|
||||
/**
|
||||
* This class implements a buffered output stream. It provides functions to write FCC-format data to a disk file.
|
||||
*
|
||||
* @author Yanni Zhang
|
||||
*
|
||||
*/
|
||||
public class CCacheOutputStream extends KrbDataOutputStream implements FileCCacheConstants {
|
||||
public CCacheOutputStream(OutputStream os) {
|
||||
super(os);
|
||||
}
|
||||
|
||||
public void writeHeader(PrincipalName p, int version) throws IOException {
|
||||
write((version & 0xff00) >> 8);
|
||||
write(version & 0x00ff);
|
||||
p.writePrincipal(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a credentials in FCC format to this cache output stream.
|
||||
*
|
||||
* @param creds the credentials to be written to the output stream.
|
||||
* @exception IOException if an I/O exception occurs.
|
||||
* @exception Asn1Exception if an Asn1Exception occurs.
|
||||
*/
|
||||
/*For object data fields which themselves have multiple data fields, such as PrincipalName, EncryptionKey
|
||||
HostAddresses, AuthorizationData, I created corresponding write methods (writePrincipal,
|
||||
writeKey,...) in each class, since converting the object into FCC format data stream
|
||||
should be encapsulated in object itself.
|
||||
*/
|
||||
public void addCreds(Credentials creds) throws IOException, Asn1Exception {
|
||||
creds.cname.writePrincipal(this);
|
||||
creds.sname.writePrincipal(this);
|
||||
creds.key.writeKey(this);
|
||||
write32((int)(creds.authtime.getTime()/1000));
|
||||
if (creds.starttime != null)
|
||||
write32((int)(creds.starttime.getTime()/1000));
|
||||
else write32(0);
|
||||
write32((int)(creds.endtime.getTime()/1000));
|
||||
if (creds.renewTill != null)
|
||||
write32((int)(creds.renewTill.getTime()/1000));
|
||||
|
||||
else write32(0);
|
||||
if (creds.isEncInSKey) {
|
||||
write8(1);
|
||||
}
|
||||
else write8(0);
|
||||
writeFlags(creds.flags);
|
||||
if (creds.caddr == null)
|
||||
write32(0);
|
||||
else
|
||||
creds.caddr.writeAddrs(this);
|
||||
|
||||
if (creds.authorizationData == null) {
|
||||
write32(0);
|
||||
}
|
||||
else
|
||||
creds.authorizationData.writeAuth(this);
|
||||
writeTicket(creds.ticket);
|
||||
writeTicket(creds.secondTicket);
|
||||
}
|
||||
|
||||
public void addConfigEntry(PrincipalName cname, CredentialsCache.ConfigEntry e)
|
||||
throws IOException {
|
||||
cname.writePrincipal(this);
|
||||
e.getSName().writePrincipal(this);
|
||||
write16(0); write16(0); write32(0);
|
||||
write32(0); write32(0); write32(0); write32(0);
|
||||
write8(0);
|
||||
write32(0);
|
||||
write32(0);
|
||||
write32(0);
|
||||
write32(e.getData().length);
|
||||
write(e.getData());
|
||||
write32(0);
|
||||
}
|
||||
|
||||
void writeTicket(Ticket t) throws IOException, Asn1Exception {
|
||||
if (t == null) {
|
||||
write32(0);
|
||||
}
|
||||
else {
|
||||
byte[] bytes = t.asn1Encode();
|
||||
write32(bytes.length);
|
||||
write(bytes, 0, bytes.length);
|
||||
}
|
||||
}
|
||||
|
||||
void writeFlags(TicketFlags flags) throws IOException {
|
||||
int tFlags = 0;
|
||||
boolean[] f = flags.toBooleanArray();
|
||||
if (f[1] == true) {
|
||||
tFlags |= TKT_FLG_FORWARDABLE;
|
||||
}
|
||||
if (f[2] == true) {
|
||||
tFlags |= TKT_FLG_FORWARDED;
|
||||
}
|
||||
if (f[3] == true) {
|
||||
tFlags |= TKT_FLG_PROXIABLE;
|
||||
}
|
||||
if (f[4] == true) {
|
||||
tFlags |= TKT_FLG_PROXY;
|
||||
}
|
||||
if (f[5] == true) {
|
||||
tFlags |= TKT_FLG_MAY_POSTDATE;
|
||||
}
|
||||
if (f[6] == true) {
|
||||
tFlags |= TKT_FLG_POSTDATED;
|
||||
}
|
||||
if (f[7] == true) {
|
||||
tFlags |= TKT_FLG_INVALID;
|
||||
}
|
||||
if (f[8] == true) {
|
||||
tFlags |= TKT_FLG_RENEWABLE;
|
||||
}
|
||||
if (f[9] == true) {
|
||||
tFlags |= TKT_FLG_INITIAL;
|
||||
}
|
||||
if (f[10] == true) {
|
||||
tFlags |= TKT_FLG_PRE_AUTH;
|
||||
}
|
||||
if (f[11] == true) {
|
||||
tFlags |= TKT_FLG_HW_AUTH;
|
||||
}
|
||||
write32(tFlags);
|
||||
|
||||
}
|
||||
}
|
||||
235
jdkSrc/jdk8/sun/security/krb5/internal/ccache/Credentials.java
Normal file
235
jdkSrc/jdk8/sun/security/krb5/internal/ccache/Credentials.java
Normal file
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal.ccache;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.krb5.internal.*;
|
||||
|
||||
public class Credentials {
|
||||
|
||||
PrincipalName cname;
|
||||
PrincipalName sname;
|
||||
EncryptionKey key;
|
||||
KerberosTime authtime;
|
||||
KerberosTime starttime;//optional
|
||||
KerberosTime endtime;
|
||||
KerberosTime renewTill; //optional
|
||||
HostAddresses caddr; //optional; for proxied tickets only
|
||||
AuthorizationData authorizationData; //optional, not being actually used
|
||||
public boolean isEncInSKey; // true if ticket is encrypted in another ticket's skey
|
||||
TicketFlags flags;
|
||||
Ticket ticket;
|
||||
Ticket secondTicket; //optional
|
||||
private boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
public Credentials(
|
||||
PrincipalName new_cname,
|
||||
PrincipalName new_sname,
|
||||
EncryptionKey new_key,
|
||||
KerberosTime new_authtime,
|
||||
KerberosTime new_starttime,
|
||||
KerberosTime new_endtime,
|
||||
KerberosTime new_renewTill,
|
||||
boolean new_isEncInSKey,
|
||||
TicketFlags new_flags,
|
||||
HostAddresses new_caddr,
|
||||
AuthorizationData new_authData,
|
||||
Ticket new_ticket,
|
||||
Ticket new_secondTicket) {
|
||||
cname = (PrincipalName) new_cname.clone();
|
||||
sname = (PrincipalName) new_sname.clone();
|
||||
key = (EncryptionKey) new_key.clone();
|
||||
|
||||
authtime = new_authtime;
|
||||
starttime = new_starttime;
|
||||
endtime = new_endtime;
|
||||
renewTill = new_renewTill;
|
||||
|
||||
if (new_caddr != null) {
|
||||
caddr = (HostAddresses) new_caddr.clone();
|
||||
}
|
||||
if (new_authData != null) {
|
||||
authorizationData = (AuthorizationData) new_authData.clone();
|
||||
}
|
||||
|
||||
isEncInSKey = new_isEncInSKey;
|
||||
flags = (TicketFlags) new_flags.clone();
|
||||
ticket = (Ticket) (new_ticket.clone());
|
||||
if (new_secondTicket != null) {
|
||||
secondTicket = (Ticket) new_secondTicket.clone();
|
||||
}
|
||||
}
|
||||
|
||||
public Credentials(
|
||||
KDCRep kdcRep,
|
||||
Ticket new_secondTicket,
|
||||
AuthorizationData new_authorizationData,
|
||||
boolean new_isEncInSKey) {
|
||||
if (kdcRep.encKDCRepPart == null) //can't store while encrypted
|
||||
{
|
||||
return;
|
||||
}
|
||||
cname = (PrincipalName) kdcRep.cname.clone();
|
||||
ticket = (Ticket) kdcRep.ticket.clone();
|
||||
key = (EncryptionKey) kdcRep.encKDCRepPart.key.clone();
|
||||
flags = (TicketFlags) kdcRep.encKDCRepPart.flags.clone();
|
||||
authtime = kdcRep.encKDCRepPart.authtime;
|
||||
starttime = kdcRep.encKDCRepPart.starttime;
|
||||
endtime = kdcRep.encKDCRepPart.endtime;
|
||||
renewTill = kdcRep.encKDCRepPart.renewTill;
|
||||
|
||||
sname = (PrincipalName) kdcRep.encKDCRepPart.sname.clone();
|
||||
caddr = (HostAddresses) kdcRep.encKDCRepPart.caddr.clone();
|
||||
secondTicket = (Ticket) new_secondTicket.clone();
|
||||
authorizationData =
|
||||
(AuthorizationData) new_authorizationData.clone();
|
||||
isEncInSKey = new_isEncInSKey;
|
||||
}
|
||||
|
||||
public Credentials(KDCRep kdcRep) {
|
||||
this(kdcRep, null);
|
||||
}
|
||||
|
||||
public Credentials(KDCRep kdcRep, Ticket new_ticket) {
|
||||
sname = (PrincipalName) kdcRep.encKDCRepPart.sname.clone();
|
||||
cname = (PrincipalName) kdcRep.cname.clone();
|
||||
key = (EncryptionKey) kdcRep.encKDCRepPart.key.clone();
|
||||
authtime = kdcRep.encKDCRepPart.authtime;
|
||||
starttime = kdcRep.encKDCRepPart.starttime;
|
||||
endtime = kdcRep.encKDCRepPart.endtime;
|
||||
renewTill = kdcRep.encKDCRepPart.renewTill;
|
||||
// if (kdcRep.msgType == Krb5.KRB_AS_REP) {
|
||||
// isEncInSKey = false;
|
||||
// secondTicket = null;
|
||||
// }
|
||||
flags = kdcRep.encKDCRepPart.flags;
|
||||
if (kdcRep.encKDCRepPart.caddr != null) {
|
||||
caddr = (HostAddresses) kdcRep.encKDCRepPart.caddr.clone();
|
||||
} else {
|
||||
caddr = null;
|
||||
}
|
||||
ticket = (Ticket) kdcRep.ticket.clone();
|
||||
if (new_ticket != null) {
|
||||
secondTicket = (Ticket) new_ticket.clone();
|
||||
isEncInSKey = true;
|
||||
} else {
|
||||
secondTicket = null;
|
||||
isEncInSKey = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this credential is expired
|
||||
*/
|
||||
public boolean isValid() {
|
||||
boolean valid = true;
|
||||
if (endtime.getTime() < System.currentTimeMillis()) {
|
||||
valid = false;
|
||||
} else if (starttime != null) {
|
||||
if (starttime.getTime() > System.currentTimeMillis()) {
|
||||
valid = false;
|
||||
}
|
||||
} else {
|
||||
if (authtime.getTime() > System.currentTimeMillis()) {
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
public PrincipalName getServicePrincipal() throws RealmException {
|
||||
return sname;
|
||||
}
|
||||
|
||||
public Ticket getTicket() throws RealmException {
|
||||
return ticket;
|
||||
}
|
||||
|
||||
public PrincipalName getServicePrincipal2() throws RealmException {
|
||||
return secondTicket == null ? null : secondTicket.sname;
|
||||
}
|
||||
|
||||
public PrincipalName getClientPrincipal() throws RealmException {
|
||||
return cname;
|
||||
}
|
||||
|
||||
public sun.security.krb5.Credentials setKrbCreds() {
|
||||
// Note: We will not pass authorizationData to s.s.k.Credentials. The
|
||||
// field in that class will be passed to Krb5Context as the return
|
||||
// value of ExtendedGSSContext.inquireSecContext(KRB5_GET_AUTHZ_DATA),
|
||||
// which is documented as the authData in the service ticket. That
|
||||
// is on the acceptor side.
|
||||
//
|
||||
// This class is for the initiator side. Also, authdata inside a ccache
|
||||
// is most likely to be the one in Authenticator in PA-TGS-REQ encoded
|
||||
// in TGS-REQ, therefore only stored with a service ticket. Currently
|
||||
// in Java, we only reads TGTs.
|
||||
return new sun.security.krb5.Credentials(ticket, cname, null, sname,
|
||||
null, key, flags, authtime, starttime, endtime, renewTill,
|
||||
caddr);
|
||||
}
|
||||
|
||||
public KerberosTime getStartTime() {
|
||||
return starttime;
|
||||
}
|
||||
|
||||
public KerberosTime getAuthTime() {
|
||||
return authtime;
|
||||
}
|
||||
|
||||
public KerberosTime getEndTime() {
|
||||
return endtime;
|
||||
}
|
||||
|
||||
public KerberosTime getRenewTill() {
|
||||
return renewTill;
|
||||
}
|
||||
|
||||
public TicketFlags getTicketFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
public int getEType() {
|
||||
return key.getEType();
|
||||
}
|
||||
|
||||
public EncryptionKey getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public int getTktEType() {
|
||||
return ticket.encPart.getEType();
|
||||
}
|
||||
|
||||
public int getTktEType2() {
|
||||
return (secondTicket == null) ? 0 : secondTicket.encPart.getEType();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal.ccache;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.krb5.internal.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* CredentialsCache stores credentials(tickets, session keys, etc) in a semi-permanent store
|
||||
* for later use by different program.
|
||||
*
|
||||
* @author Yanni Zhang
|
||||
*/
|
||||
public abstract class CredentialsCache {
|
||||
static CredentialsCache singleton = null;
|
||||
static String cacheName;
|
||||
private static boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
public static CredentialsCache getInstance(PrincipalName principal) {
|
||||
return FileCredentialsCache.acquireInstance(principal, null);
|
||||
}
|
||||
|
||||
public static CredentialsCache getInstance(String cache) {
|
||||
if ((cache.length() >= 5) && cache.substring(0, 5).equalsIgnoreCase("FILE:")) {
|
||||
return FileCredentialsCache.acquireInstance(null, cache.substring(5));
|
||||
}
|
||||
// XXX else, memory credential cache
|
||||
// default is file credential cache.
|
||||
return FileCredentialsCache.acquireInstance(null, cache);
|
||||
}
|
||||
|
||||
public static CredentialsCache getInstance(PrincipalName principal,
|
||||
String cache) {
|
||||
|
||||
// XXX Modify this to use URL framework of the JDK
|
||||
if (cache != null &&
|
||||
(cache.length() >= 5) &&
|
||||
cache.regionMatches(true, 0, "FILE:", 0, 5)) {
|
||||
return FileCredentialsCache.acquireInstance(principal,
|
||||
cache.substring(5));
|
||||
}
|
||||
|
||||
// When cache is null, read the default cache.
|
||||
// XXX else ..we haven't provided support for memory credential cache
|
||||
// yet. (supported in native code)
|
||||
// default is file credentials cache.
|
||||
return FileCredentialsCache.acquireInstance(principal, cache);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default credentials cache.
|
||||
*/
|
||||
public static CredentialsCache getInstance() {
|
||||
// Default credentials cache is file-based.
|
||||
return FileCredentialsCache.acquireInstance();
|
||||
}
|
||||
|
||||
public static CredentialsCache create(PrincipalName principal, String name) {
|
||||
if (name == null) {
|
||||
throw new RuntimeException("cache name error");
|
||||
}
|
||||
if ((name.length() >= 5)
|
||||
&& name.regionMatches(true, 0, "FILE:", 0, 5)) {
|
||||
name = name.substring(5);
|
||||
return (FileCredentialsCache.New(principal, name));
|
||||
}
|
||||
// else return file credentials cache
|
||||
// default is file credentials cache.
|
||||
return (FileCredentialsCache.New(principal, name));
|
||||
}
|
||||
|
||||
public static CredentialsCache create(PrincipalName principal) {
|
||||
// create a default credentials cache for a specified principal
|
||||
return (FileCredentialsCache.New(principal));
|
||||
}
|
||||
|
||||
public static String cacheName() {
|
||||
return cacheName;
|
||||
}
|
||||
|
||||
public abstract PrincipalName getPrimaryPrincipal();
|
||||
public abstract void update(Credentials c);
|
||||
public abstract void save() throws IOException, KrbException;
|
||||
public abstract Credentials[] getCredsList();
|
||||
public abstract Credentials getDefaultCreds();
|
||||
public abstract sun.security.krb5.Credentials getInitialCreds();
|
||||
public abstract Credentials getCreds(PrincipalName sname);
|
||||
public abstract Credentials getCreds(LoginOptions options, PrincipalName sname);
|
||||
public abstract void addConfigEntry(ConfigEntry e);
|
||||
public abstract List<ConfigEntry> getConfigEntries();
|
||||
|
||||
public ConfigEntry getConfigEntry(String name) {
|
||||
List<ConfigEntry> entries = getConfigEntries();
|
||||
if (entries != null) {
|
||||
for (ConfigEntry e : entries) {
|
||||
if (e.getName().equals(name)) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static class ConfigEntry {
|
||||
|
||||
public ConfigEntry(String name, PrincipalName princ, byte[] data) {
|
||||
this.name = name;
|
||||
this.princ = princ;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
private final String name;
|
||||
private final PrincipalName princ;
|
||||
private final byte[] data; // not worth cloning
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public PrincipalName getPrinc() {
|
||||
return princ;
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name + (princ != null ? ("." + princ) : "")
|
||||
+ ": " + new String(data);
|
||||
}
|
||||
|
||||
public PrincipalName getSName() {
|
||||
try {
|
||||
return new PrincipalName("krb5_ccache_conf_data/" + name
|
||||
+ (princ != null ? ("/" + princ) : "")
|
||||
+ "@X-CACHECONF:");
|
||||
} catch (RealmException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal.ccache;
|
||||
|
||||
/**
|
||||
* Constants used by file-based credential cache classes.
|
||||
*
|
||||
* @author Yanni Zhang
|
||||
*
|
||||
*/
|
||||
public interface FileCCacheConstants {
|
||||
/*
|
||||
* FCC version 2 contains type information for principals. FCC
|
||||
* version 1 does not.
|
||||
*
|
||||
* FCC version 3 contains keyblock encryption type information, and is
|
||||
* architecture independent. Previous versions are not. */
|
||||
public final int KRB5_FCC_FVNO_1 = 0x501;
|
||||
public final int KRB5_FCC_FVNO_2 = 0x502;
|
||||
public final int KRB5_FCC_FVNO_3 = 0x503;
|
||||
public final int KRB5_FCC_FVNO_4 = 0x504;
|
||||
public final int FCC_TAG_DELTATIME = 1;
|
||||
public final int KRB5_NT_UNKNOWN = 0;
|
||||
public final int TKT_FLG_FORWARDABLE = 0x40000000;
|
||||
public final int TKT_FLG_FORWARDED = 0x20000000;
|
||||
public final int TKT_FLG_PROXIABLE = 0x10000000;
|
||||
public final int TKT_FLG_PROXY = 0x08000000;
|
||||
public final int TKT_FLG_MAY_POSTDATE = 0x04000000;
|
||||
public final int TKT_FLG_POSTDATED = 0x02000000;
|
||||
public final int TKT_FLG_INVALID = 0x01000000;
|
||||
public final int TKT_FLG_RENEWABLE = 0x00800000;
|
||||
public final int TKT_FLG_INITIAL = 0x00400000;
|
||||
public final int TKT_FLG_PRE_AUTH = 0x00200000;
|
||||
public final int TKT_FLG_HW_AUTH = 0x00100000;
|
||||
}
|
||||
@@ -0,0 +1,643 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ===========================================================================
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
*
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
* ===========================================================================
|
||||
*
|
||||
*/
|
||||
package sun.security.krb5.internal.ccache;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.krb5.internal.*;
|
||||
import sun.security.util.SecurityProperties;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.Vector;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.*;
|
||||
|
||||
/**
|
||||
* CredentialsCache stores credentials(tickets, session keys, etc) in a
|
||||
* semi-permanent store
|
||||
* for later use by different program.
|
||||
*
|
||||
* @author Yanni Zhang
|
||||
* @author Ram Marti
|
||||
*/
|
||||
|
||||
public class FileCredentialsCache extends CredentialsCache
|
||||
implements FileCCacheConstants {
|
||||
public int version;
|
||||
public Tag tag; // optional
|
||||
public PrincipalName primaryPrincipal;
|
||||
private Vector<Credentials> credentialsList;
|
||||
private static String dir;
|
||||
private static boolean DEBUG = Krb5.DEBUG;
|
||||
|
||||
public static synchronized FileCredentialsCache acquireInstance(
|
||||
PrincipalName principal, String cache) {
|
||||
try {
|
||||
FileCredentialsCache fcc = new FileCredentialsCache();
|
||||
if (cache == null) {
|
||||
cacheName = FileCredentialsCache.getDefaultCacheName();
|
||||
} else {
|
||||
cacheName = FileCredentialsCache.checkValidation(cache);
|
||||
}
|
||||
if ((cacheName == null) || !(new File(cacheName)).exists()) {
|
||||
// invalid cache name or the file doesn't exist
|
||||
return null;
|
||||
}
|
||||
if (principal != null) {
|
||||
fcc.primaryPrincipal = principal;
|
||||
}
|
||||
fcc.load(cacheName);
|
||||
return fcc;
|
||||
} catch (IOException e) {
|
||||
// we don't handle it now, instead we return a null at the end.
|
||||
if (DEBUG) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (KrbException e) {
|
||||
// we don't handle it now, instead we return a null at the end.
|
||||
if (DEBUG) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static FileCredentialsCache acquireInstance() {
|
||||
return acquireInstance(null, null);
|
||||
}
|
||||
|
||||
static synchronized FileCredentialsCache New(PrincipalName principal,
|
||||
String name) {
|
||||
try {
|
||||
FileCredentialsCache fcc = new FileCredentialsCache();
|
||||
cacheName = FileCredentialsCache.checkValidation(name);
|
||||
if (cacheName == null) {
|
||||
// invalid cache name or the file doesn't exist
|
||||
return null;
|
||||
}
|
||||
fcc.init(principal, cacheName);
|
||||
return fcc;
|
||||
}
|
||||
catch (IOException e) {
|
||||
}
|
||||
catch (KrbException e) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static synchronized FileCredentialsCache New(PrincipalName principal) {
|
||||
try {
|
||||
FileCredentialsCache fcc = new FileCredentialsCache();
|
||||
cacheName = FileCredentialsCache.getDefaultCacheName();
|
||||
fcc.init(principal, cacheName);
|
||||
return fcc;
|
||||
}
|
||||
catch (IOException e) {
|
||||
if (DEBUG) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (KrbException e) {
|
||||
if (DEBUG) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private FileCredentialsCache() {
|
||||
}
|
||||
|
||||
boolean exists(String cache) {
|
||||
File file = new File(cache);
|
||||
if (file.exists()) {
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
|
||||
synchronized void init(PrincipalName principal, String name)
|
||||
throws IOException, KrbException {
|
||||
primaryPrincipal = principal;
|
||||
try (FileOutputStream fos = new FileOutputStream(name);
|
||||
CCacheOutputStream cos = new CCacheOutputStream(fos)) {
|
||||
version = KRB5_FCC_FVNO_3;
|
||||
cos.writeHeader(primaryPrincipal, version);
|
||||
}
|
||||
load(name);
|
||||
}
|
||||
|
||||
synchronized void load(String name) throws IOException, KrbException {
|
||||
PrincipalName p;
|
||||
try (FileInputStream fis = new FileInputStream(name);
|
||||
CCacheInputStream cis = new CCacheInputStream(fis)) {
|
||||
version = cis.readVersion();
|
||||
if (version == KRB5_FCC_FVNO_4) {
|
||||
tag = cis.readTag();
|
||||
} else {
|
||||
tag = null;
|
||||
if (version == KRB5_FCC_FVNO_1 || version == KRB5_FCC_FVNO_2) {
|
||||
cis.setNativeByteOrder();
|
||||
}
|
||||
}
|
||||
p = cis.readPrincipal(version);
|
||||
|
||||
if (primaryPrincipal != null) {
|
||||
if (!(primaryPrincipal.match(p))) {
|
||||
throw new IOException("Primary principals don't match.");
|
||||
}
|
||||
} else
|
||||
primaryPrincipal = p;
|
||||
credentialsList = new Vector<Credentials>();
|
||||
while (cis.available() > 0) {
|
||||
Object cred = cis.readCred(version);
|
||||
if (cred != null) {
|
||||
if (cred instanceof Credentials) {
|
||||
credentialsList.addElement((Credentials)cred);
|
||||
} else {
|
||||
addConfigEntry((CredentialsCache.ConfigEntry)cred);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the credentials list. If the specified credentials for the
|
||||
* service is new, add it to the list. If there is an entry in the list,
|
||||
* replace the old credentials with the new one.
|
||||
* @param c the credentials.
|
||||
*/
|
||||
|
||||
public synchronized void update(Credentials c) {
|
||||
if (credentialsList != null) {
|
||||
if (credentialsList.isEmpty()) {
|
||||
credentialsList.addElement(c);
|
||||
} else {
|
||||
Credentials tmp = null;
|
||||
boolean matched = false;
|
||||
|
||||
for (int i = 0; i < credentialsList.size(); i++) {
|
||||
tmp = credentialsList.elementAt(i);
|
||||
if (match(c.sname.getNameStrings(),
|
||||
tmp.sname.getNameStrings()) &&
|
||||
((c.sname.getRealmString()).equalsIgnoreCase(
|
||||
tmp.sname.getRealmString()))) {
|
||||
matched = true;
|
||||
if (c.endtime.getTime() >= tmp.endtime.getTime()) {
|
||||
if (DEBUG) {
|
||||
System.out.println(" >>> FileCredentialsCache "
|
||||
+ "Ticket matched, overwrite "
|
||||
+ "the old one.");
|
||||
}
|
||||
credentialsList.removeElementAt(i);
|
||||
credentialsList.addElement(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (matched == false) {
|
||||
if (DEBUG) {
|
||||
System.out.println(" >>> FileCredentialsCache Ticket "
|
||||
+ "not exactly matched, "
|
||||
+ "add new one into cache.");
|
||||
}
|
||||
|
||||
credentialsList.addElement(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized PrincipalName getPrimaryPrincipal() {
|
||||
return primaryPrincipal;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Saves the credentials cache file to the disk.
|
||||
*/
|
||||
public synchronized void save() throws IOException, Asn1Exception {
|
||||
try (FileOutputStream fos = new FileOutputStream(cacheName);
|
||||
CCacheOutputStream cos = new CCacheOutputStream(fos)) {
|
||||
cos.writeHeader(primaryPrincipal, version);
|
||||
Credentials[] tmp = null;
|
||||
if ((tmp = getCredsList()) != null) {
|
||||
for (int i = 0; i < tmp.length; i++) {
|
||||
cos.addCreds(tmp[i]);
|
||||
}
|
||||
}
|
||||
for (ConfigEntry e : getConfigEntries()) {
|
||||
cos.addConfigEntry(primaryPrincipal, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean match(String[] s1, String[] s2) {
|
||||
if (s1.length != s2.length) {
|
||||
return false;
|
||||
} else {
|
||||
for (int i = 0; i < s1.length; i++) {
|
||||
if (!(s1[i].equalsIgnoreCase(s2[i]))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of credentials entries in the cache file.
|
||||
*/
|
||||
public synchronized Credentials[] getCredsList() {
|
||||
if ((credentialsList == null) || (credentialsList.isEmpty())) {
|
||||
return null;
|
||||
} else {
|
||||
Credentials[] tmp = new Credentials[credentialsList.size()];
|
||||
for (int i = 0; i < credentialsList.size(); i++) {
|
||||
tmp[i] = credentialsList.elementAt(i);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Credentials getCreds(LoginOptions options, PrincipalName sname) {
|
||||
if (options == null) {
|
||||
return getCreds(sname);
|
||||
} else {
|
||||
Credentials[] list = getCredsList();
|
||||
if (list == null) {
|
||||
return null;
|
||||
} else {
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
if (sname.match(list[i].sname)) {
|
||||
if (list[i].flags.match(options)) {
|
||||
return list[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private List<ConfigEntry> configEntries = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void addConfigEntry(ConfigEntry e) {
|
||||
configEntries.add(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ConfigEntry> getConfigEntries() {
|
||||
return Collections.unmodifiableList(configEntries);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a credentials for a specified service.
|
||||
* @param sname service principal name.
|
||||
*/
|
||||
public Credentials getCreds(PrincipalName sname) {
|
||||
Credentials[] list = getCredsList();
|
||||
if (list == null) {
|
||||
return null;
|
||||
} else {
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
if (sname.match(list[i].sname)) {
|
||||
return list[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public sun.security.krb5.Credentials getInitialCreds() {
|
||||
|
||||
Credentials defaultCreds = getDefaultCreds();
|
||||
if (defaultCreds == null) {
|
||||
return null;
|
||||
}
|
||||
sun.security.krb5.Credentials tgt = defaultCreds.setKrbCreds();
|
||||
|
||||
CredentialsCache.ConfigEntry entry = getConfigEntry("proxy_impersonator");
|
||||
if (entry == null) {
|
||||
if (DEBUG) {
|
||||
System.out.println("get normal credential");
|
||||
}
|
||||
return tgt;
|
||||
}
|
||||
|
||||
boolean force;
|
||||
String prop = SecurityProperties.privilegedGetOverridable(
|
||||
"jdk.security.krb5.default.initiate.credential");
|
||||
if (prop == null) {
|
||||
prop = "always-impersonate";
|
||||
}
|
||||
switch (prop) {
|
||||
case "no-impersonate": // never try impersonation
|
||||
if (DEBUG) {
|
||||
System.out.println("get normal credential");
|
||||
}
|
||||
return tgt;
|
||||
case "try-impersonate":
|
||||
force = false;
|
||||
break;
|
||||
case "always-impersonate":
|
||||
force = true;
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(
|
||||
"Invalid jdk.security.krb5.default.initiate.credential");
|
||||
}
|
||||
|
||||
try {
|
||||
PrincipalName service = new PrincipalName(
|
||||
new String(entry.getData(), StandardCharsets.UTF_8));
|
||||
if (!tgt.getClient().equals(service)) {
|
||||
if (DEBUG) {
|
||||
System.out.println("proxy_impersonator does not match service name");
|
||||
}
|
||||
return force ? null : tgt;
|
||||
}
|
||||
PrincipalName client = getPrimaryPrincipal();
|
||||
Credentials proxy = null;
|
||||
for (Credentials c : getCredsList()) {
|
||||
if (c.getClientPrincipal().equals(client)
|
||||
&& c.getServicePrincipal().equals(service)) {
|
||||
proxy = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (proxy == null) {
|
||||
if (DEBUG) {
|
||||
System.out.println("Cannot find evidence ticket in ccache");
|
||||
}
|
||||
return force ? null : tgt;
|
||||
}
|
||||
if (DEBUG) {
|
||||
System.out.println("Get proxied credential");
|
||||
}
|
||||
return tgt.setProxy(proxy.setKrbCreds());
|
||||
} catch (KrbException e) {
|
||||
if (DEBUG) {
|
||||
System.out.println("Impersonation with ccache failed");
|
||||
}
|
||||
return force ? null : tgt;
|
||||
}
|
||||
}
|
||||
|
||||
public Credentials getDefaultCreds() {
|
||||
Credentials[] list = getCredsList();
|
||||
if (list == null) {
|
||||
return null;
|
||||
} else {
|
||||
for (int i = list.length-1; i >= 0; i--) {
|
||||
if (list[i].sname.toString().startsWith("krbtgt")) {
|
||||
String[] nameStrings = list[i].sname.getNameStrings();
|
||||
// find the TGT for the current realm krbtgt/realm@realm
|
||||
if (nameStrings[1].equals(list[i].sname.getRealm().toString())) {
|
||||
return list[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns path name of the credentials cache file.
|
||||
* The path name is searched in the following order:
|
||||
*
|
||||
* 1. KRB5CCNAME (bare file name without FILE:)
|
||||
* 2. /tmp/krb5cc_<uid> on unix systems
|
||||
* 3. <user.home>/krb5cc_<user.name>
|
||||
* 4. <user.home>/krb5cc (if can't get <user.name>)
|
||||
*/
|
||||
|
||||
public static String getDefaultCacheName() {
|
||||
|
||||
String stdCacheNameComponent = "krb5cc";
|
||||
String name;
|
||||
|
||||
// The env var can start with TYPE:, we only support FILE: here.
|
||||
// https://docs.oracle.com/cd/E19082-01/819-2252/6n4i8rtr3/index.html
|
||||
name = java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<String>() {
|
||||
@Override
|
||||
public String run() {
|
||||
String cache = System.getenv("KRB5CCNAME");
|
||||
if (cache != null &&
|
||||
(cache.length() >= 5) &&
|
||||
cache.regionMatches(true, 0, "FILE:", 0, 5)) {
|
||||
cache = cache.substring(5);
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
});
|
||||
if (name != null) {
|
||||
if (DEBUG) {
|
||||
System.out.println(">>>KinitOptions cache name is " + name);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
// get cache name from system.property
|
||||
String osname =
|
||||
java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction("os.name"));
|
||||
|
||||
/*
|
||||
* For Unix platforms we use the default cache name to be
|
||||
* /tmp/krbcc_uid ; for all other platforms we use
|
||||
* {user_home}/krb5_cc{user_name}
|
||||
* Please note that for Windows 2K we will use LSA to get
|
||||
* the TGT from the the default cache even before we come here;
|
||||
* however when we create cache we will create a cache under
|
||||
* {user_home}/krb5_cc{user_name} for non-Unix platforms including
|
||||
* Windows 2K.
|
||||
*/
|
||||
|
||||
if (osname != null) {
|
||||
String cmd = null;
|
||||
String uidStr = null;
|
||||
long uid = 0;
|
||||
|
||||
if (!osname.startsWith("Windows")) {
|
||||
try {
|
||||
Class<?> c = Class.forName
|
||||
("com.sun.security.auth.module.UnixSystem");
|
||||
Constructor<?> constructor = c.getConstructor();
|
||||
Object obj = constructor.newInstance();
|
||||
Method method = c.getMethod("getUid");
|
||||
uid = ((Long)method.invoke(obj)).longValue();
|
||||
name = File.separator + "tmp" +
|
||||
File.separator + stdCacheNameComponent + "_" + uid;
|
||||
if (DEBUG) {
|
||||
System.out.println(">>>KinitOptions cache name is " +
|
||||
name);
|
||||
}
|
||||
return name;
|
||||
} catch (Exception e) {
|
||||
if (DEBUG) {
|
||||
System.out.println("Exception in obtaining uid " +
|
||||
"for Unix platforms " +
|
||||
"Using user's home directory");
|
||||
|
||||
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we did not get the uid;
|
||||
|
||||
|
||||
String user_name =
|
||||
java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction("user.name"));
|
||||
|
||||
String user_home =
|
||||
java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction("user.home"));
|
||||
|
||||
if (user_home == null) {
|
||||
user_home =
|
||||
java.security.AccessController.doPrivileged(
|
||||
new sun.security.action.GetPropertyAction("user.dir"));
|
||||
}
|
||||
|
||||
if (user_name != null) {
|
||||
name = user_home + File.separator +
|
||||
stdCacheNameComponent + "_" + user_name;
|
||||
} else {
|
||||
name = user_home + File.separator + stdCacheNameComponent;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
System.out.println(">>>KinitOptions cache name is " + name);
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
public static String checkValidation(String name) {
|
||||
String fullname = null;
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
// get full path name
|
||||
fullname = (new File(name)).getCanonicalPath();
|
||||
File fCheck = new File(fullname);
|
||||
if (!(fCheck.exists())) {
|
||||
// get absolute directory
|
||||
File temp = new File(fCheck.getParent());
|
||||
// test if the directory exists
|
||||
if (!(temp.isDirectory()))
|
||||
fullname = null;
|
||||
temp = null;
|
||||
}
|
||||
fCheck = null;
|
||||
|
||||
} catch (IOException e) {
|
||||
fullname = null; // invalid name
|
||||
}
|
||||
return fullname;
|
||||
}
|
||||
|
||||
|
||||
private static String exec(String c) {
|
||||
StringTokenizer st = new StringTokenizer(c);
|
||||
Vector<String> v = new Vector<>();
|
||||
while (st.hasMoreTokens()) {
|
||||
v.addElement(st.nextToken());
|
||||
}
|
||||
final String[] command = new String[v.size()];
|
||||
v.copyInto(command);
|
||||
try {
|
||||
|
||||
Process p =
|
||||
java.security.AccessController.doPrivileged
|
||||
(new java.security.PrivilegedAction<Process> () {
|
||||
public Process run() {
|
||||
try {
|
||||
return (Runtime.getRuntime().exec(command));
|
||||
} catch (java.io.IOException e) {
|
||||
if (DEBUG) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (p == null) {
|
||||
// exception occurred during executing the command
|
||||
return null;
|
||||
}
|
||||
|
||||
BufferedReader commandResult =
|
||||
new BufferedReader
|
||||
(new InputStreamReader(p.getInputStream(), "8859_1"));
|
||||
String s1 = null;
|
||||
if ((command.length == 1) &&
|
||||
(command[0].equals("/usr/bin/env"))) {
|
||||
while ((s1 = commandResult.readLine()) != null) {
|
||||
if (s1.length() >= 11) {
|
||||
if ((s1.substring(0, 11)).equalsIgnoreCase
|
||||
("KRB5CCNAME=")) {
|
||||
s1 = s1.substring(11);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else s1 = commandResult.readLine();
|
||||
commandResult.close();
|
||||
return s1;
|
||||
} catch (Exception e) {
|
||||
if (DEBUG) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal.ccache;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.krb5.internal.*;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
|
||||
//Windows supports the "API: cache" type, which is a shared memory cache. This is
|
||||
//implemented by krbcc32.dll as part of the MIT Kerberos for Win32 distribution.
|
||||
//MemoryCredentialsCache will provide future functions to access shared memeory cache on
|
||||
//Windows platform. Native code implementation may be necessary.
|
||||
/**
|
||||
* This class extends CredentialsCache. It is used for accessing data in shared memory
|
||||
* cache on Windows platforms.
|
||||
*
|
||||
* @author Yanni Zhang
|
||||
*/
|
||||
public abstract class MemoryCredentialsCache extends CredentialsCache {
|
||||
|
||||
private static CredentialsCache getCCacheInstance(PrincipalName p) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static CredentialsCache getCCacheInstance(PrincipalName p, File cacheFile) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public abstract boolean exists(String cache);
|
||||
|
||||
public abstract void update(Credentials c);
|
||||
|
||||
public abstract void save() throws IOException, KrbException;
|
||||
|
||||
public abstract Credentials[] getCredsList();
|
||||
|
||||
public abstract Credentials getCreds(PrincipalName sname) ;
|
||||
|
||||
public abstract PrincipalName getPrimaryPrincipal();
|
||||
|
||||
}
|
||||
73
jdkSrc/jdk8/sun/security/krb5/internal/ccache/Tag.java
Normal file
73
jdkSrc/jdk8/sun/security/krb5/internal/ccache/Tag.java
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* (C) Copyright IBM Corp. 1999 All Rights Reserved.
|
||||
* Copyright 1997 The Open Group Research Institute. All rights reserved.
|
||||
*/
|
||||
|
||||
package sun.security.krb5.internal.ccache;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
/**
|
||||
* tag field introduced in KRB5_FCC_FVNO_4
|
||||
*
|
||||
* @author Yanni Zhang
|
||||
*/
|
||||
public class Tag{
|
||||
int length;
|
||||
int tag;
|
||||
int tagLen;
|
||||
Integer time_offset;
|
||||
Integer usec_offset;
|
||||
|
||||
public Tag(int len, int new_tag, Integer new_time, Integer new_usec) {
|
||||
tag = new_tag;
|
||||
tagLen = 8;
|
||||
time_offset = new_time;
|
||||
usec_offset = new_usec;
|
||||
length = 4 + tagLen;
|
||||
}
|
||||
public Tag(int new_tag) {
|
||||
tag = new_tag;
|
||||
tagLen = 0;
|
||||
length = 4 + tagLen;
|
||||
}
|
||||
public byte[] toByteArray() {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
os.write(length);
|
||||
os.write(tag);
|
||||
os.write(tagLen);
|
||||
if (time_offset != null) {
|
||||
os.write(time_offset.intValue());
|
||||
}
|
||||
if (usec_offset != null) {
|
||||
os.write(usec_offset.intValue());
|
||||
}
|
||||
return os.toByteArray();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user