/* * Copyright 1999-2010 University of Chicago * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is * distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. * * See the License for the specific language governing permissions and limitations under the License. */ package org.globus.gsi.gssapi.net.impl; import java.io.InputStream; import java.io.IOException; import java.io.EOFException; import org.globus.gsi.gssapi.net.GssSocket; import org.globus.gsi.gssapi.net.GssInputStream; import org.globus.gsi.gssapi.SSLUtil; import org.ietf.jgss.GSSContext; public class GSIGssInputStream extends GssInputStream { // 32Mb private static final int MAX_LEN = 32 * 1024 * 1024; protected byte [] header; protected int mode; public GSIGssInputStream(InputStream in, GSSContext context) { super(in, context); this.header = new byte[5]; this.mode = -1; } protected void readMsg() throws IOException { do { byte [] token = readToken(); if (token == null) { this.buff = null; break; } this.buff = unwrap(token); } while (buff == null); this.index = 0; } public int getWrapMode() { return this.mode; } public byte[] readHandshakeToken() throws IOException { byte [] token = readToken(); if (token == null) { throw new EOFException(); } return token; } protected byte[] readToken() throws IOException { byte[] buf = null; if (SSLUtil.read(this.in, this.header, 0, this.header.length-1) < 0) { return null; } if (SSLUtil.isSSLv3Packet(this.header)) { this.mode = GssSocket.SSL_MODE; // read the second byte of packet length field if (SSLUtil.read(this.in, this.header, 4, 1) < 0) { return null; } int len = SSLUtil.toUnsignedShort(this.header[3], this.header[4]); buf = new byte[this.header.length + len]; System.arraycopy(this.header, 0, buf, 0, this.header.length); if (SSLUtil.read(this.in, buf, this.header.length, len) < 0) { return null; } } else if (SSLUtil.isSSLv2HelloPacket(this.header)) { this.mode = GssSocket.SSL_MODE; // SSLv2 - assume 2-byte header // read extra 2 bytes so subtract it from total len int len = (((header[0] & 0x7f) << 8) | (header[1] & 0xff)) - 2; buf = new byte[this.header.length-1 + len]; System.arraycopy(this.header, 0, buf, 0, this.header.length-1); if (SSLUtil.read(this.in, buf, this.header.length-1, len) < 0) { return null; } } else { this.mode = GssSocket.GSI_MODE; int len = SSLUtil.toInt(this.header, 0); if (len > MAX_LEN) { throw new IOException("Token length " + len + " > " + MAX_LEN); } else if (len < 0) { throw new IOException("Token length " + len + " < 0"); } buf = new byte[len]; if (SSLUtil.read(this.in, buf, 0, buf.length) < 0) { return null; } } return buf; } }