/* * 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; import java.io.EOFException; import java.io.InputStream; import java.io.IOException; import org.globus.common.ChainedIOException; import org.globus.gsi.gssapi.ClosedGSSException; import org.ietf.jgss.GSSContext; import org.ietf.jgss.GSSException; public abstract class GssInputStream extends InputStream { protected InputStream in; protected GSSContext context; protected byte [] buff; protected int index; public GssInputStream(InputStream in, GSSContext context) { this.in = in; this.context = context; this.buff = new byte[0]; this.index = 0; } protected byte[] unwrap(byte [] msg) throws IOException { try { return this.context.unwrap(msg, 0, msg.length, null); } catch (ClosedGSSException e) { throw new EOFException("Remote host terminated connection"); } catch (GSSException e) { throw new ChainedIOException("unwrap failed", e); } } protected abstract void readMsg() throws IOException; public int read(byte [] data) throws IOException { return read(data, 0, data.length); } public int read(byte [] data, int off, int len) throws IOException { if (!hasData()) { return -1; } int max = (index + len > buff.length) ? buff.length - index : len; System.arraycopy(buff, index, data, off, max); index += max; return max; } public int read() throws IOException { if (!hasData()) { return -1; } return buff[index++] & 0xff; } protected boolean hasData() throws IOException { if (this.buff == null) { return false; } if (this.buff.length == this.index) { try { readMsg(); } catch (EOFException e) { return false; } } if (this.buff == null) { return false; } return (this.buff.length != this.index); } /* does not dispose of the context */ public void close() throws IOException { this.buff = null; in.close(); } public int available() throws IOException { if (this.buff == null) { return -1; } int avail = this.buff.length - this.index; return (avail == 0) ? in.available() : avail; } }