/* * Copyright 1999-2006 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.ftp.extended; import java.io.InputStream; import java.io.BufferedInputStream; import java.io.IOException; import java.io.EOFException; import org.globus.gsi.gssapi.net.GssInputStream; import org.bouncycastle.util.encoders.Base64; import org.ietf.jgss.GSSContext; public class GridFTPInputStream extends GssInputStream { public GridFTPInputStream(InputStream in, GSSContext context) { super(new BufferedInputStream(in), context); } private String readLine() throws IOException { int c = this.in.read(); if (c == -1) { return null; } StringBuffer buf = new StringBuffer(); buf.append((char)c); while( (c = this.in.read()) != -1 ) { if (c == '\r') { c = this.in.read(); if (c == '\n' || c == -1) { break; } else { throw new IOException("bad format"); } } else { buf.append( (char)c); } } return buf.toString(); } public byte[] readHandshakeToken() throws IOException { String line = readLine(); if (line == null) { throw new EOFException(); } if (line.startsWith("335 ADAT=") || line.startsWith("334 ADAT=") ) { // TODO: this can be optimized return Base64.decode(line.substring(9).getBytes()); } else if ( line.startsWith("335 more data needed") ) { return new byte[0]; } else { throw new IOException(handleReply(line)); } } private String handleReply(String line) throws IOException { line = line.trim(); if (line.length() > 4 && line.charAt(3) == '-') { String lineSeparator = System.getProperty("line.separator"); String lastLineStarts = line.substring(0, 3) + ' '; StringBuffer buf = new StringBuffer(); buf.append(line); for (;;) { line = readLine(); if (line == null) { throw new EOFException(); } line = line.trim(); buf.append(lineSeparator).append(line); if (line.startsWith(lastLineStarts)) { break; } } return buf.toString(); } else { return line; } } protected void readMsg() throws IOException { String line = readLine(); if (line == null) { throw new EOFException(); } if (line.charAt(0) == '6') { this.buff = unwrap(Base64.decode(line.substring(4).getBytes())); this.index = 0; /** * This is a fix for messages that are not * \r\n terminated */ byte last = this.buff[this.buff.length-1]; if (last == 0) { // this is a bug in older gridftp servers // line should be terminated with \r\n0 if (this.buff[this.buff.length-2] != 10) { this.buff[this.buff.length-1] = 10; } } else if (last != 10) { byte [] newBuff = new byte[this.buff.length+1]; System.arraycopy(buff, 0, newBuff, 0, this.buff.length); newBuff[this.buff.length]=10; this.buff = newBuff; } } else { throw new IOException(line); } } }