/*
 * Copyright (c) 2013, 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.rcache;

import java.io.IOException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.SeekableByteChannel;
import java.nio.charset.StandardCharsets;
import java.util.StringTokenizer;

The class represents an old style replay cache entry. It is only used in a dfl file.
Author:Sun/Oracle, Yanni Zhang
/** * The class represents an old style replay cache entry. It is only used in * a dfl file. * * @author Sun/Oracle * @author Yanni Zhang */
public class AuthTime { final int ctime; final int cusec; final String client; final String server;
Constructs an AuthTime.
/** * Constructs an <code>AuthTime</code>. */
public AuthTime(String client, String server, int ctime, int cusec) { this.ctime = ctime; this.cusec = cusec; this.client = client; this.server = server; } @Override public String toString() { return String.format("%d/%06d/----/%s", ctime, cusec, client); } // Methods used when saved in a dfl file. See DflCache.java
Reads an LC style string from a channel, which is a int32 length plus a UTF-8 encoded string possibly ends with \0.
Throws:
/** * Reads an LC style string from a channel, which is a int32 length * plus a UTF-8 encoded string possibly ends with \0. * @throws IOException if there is a format error * @throws BufferUnderflowException if goes beyond the end */
private static String readStringWithLength(SeekableByteChannel chan) throws IOException { ByteBuffer bb = ByteBuffer.allocate(4); bb.order(ByteOrder.nativeOrder()); chan.read(bb); bb.flip(); int len = bb.getInt(); if (len > 1024) { // Memory attack? The string should be fairly short. throw new IOException("Invalid string length"); } bb = ByteBuffer.allocate(len); if (chan.read(bb) != len) { throw new IOException("Not enough string"); } byte[] data = bb.array(); return (data[len-1] == 0)? new String(data, 0, len-1, StandardCharsets.UTF_8): new String(data, StandardCharsets.UTF_8); }
Reads an AuthTime or AuthTimeWithHash object from a channel.
Throws:
/** * Reads an AuthTime or AuthTimeWithHash object from a channel. * @throws IOException if there is a format error * @throws BufferUnderflowException if goes beyond the end */
public static AuthTime readFrom(SeekableByteChannel chan) throws IOException { String client = readStringWithLength(chan); String server = readStringWithLength(chan); ByteBuffer bb = ByteBuffer.allocate(8); chan.read(bb); bb.order(ByteOrder.nativeOrder()); int cusec = bb.getInt(0); int ctime = bb.getInt(4); if (client.isEmpty()) { StringTokenizer st = new StringTokenizer(server, " :"); if (st.countTokens() != 6) { throw new IOException("Incorrect rcache style"); } String hashAlg = st.nextToken(); String hash = st.nextToken(); st.nextToken(); client = st.nextToken(); st.nextToken(); server = st.nextToken(); return new AuthTimeWithHash( client, server, ctime, cusec, hashAlg, hash); } else { return new AuthTime( client, server, ctime, cusec); } }
Encodes to be used in a dfl file
/** * Encodes to be used in a dfl file */
protected byte[] encode0(String cstring, String sstring) { byte[] c = cstring.getBytes(StandardCharsets.UTF_8);; byte[] s = sstring.getBytes(StandardCharsets.UTF_8);; byte[] zero = new byte[1]; int len = 4 + c.length + 1 + 4 + s.length + 1 + 4 + 4; ByteBuffer bb = ByteBuffer.allocate(len) .order(ByteOrder.nativeOrder()); bb.putInt(c.length+1).put(c).put(zero) .putInt(s.length+1).put(s).put(zero) .putInt(cusec).putInt(ctime); return bb.array(); }
Encodes to be used in a dfl file
Params:
  • withHash – useless here
/** * Encodes to be used in a dfl file * @param withHash useless here */
public byte[] encode(boolean withHash) { return encode0(client, server); } }