Frames | No Frames |
1: /* 2: * SaslInputStream.java 3: * Copyright (C) 2002 The Free Software Foundation 4: * 5: * This file is part of GNU inetlib, a library. 6: * 7: * GNU inetlib is free software; you can redistribute it and/or modify 8: * it under the terms of the GNU General Public License as published by 9: * the Free Software Foundation; either version 2 of the License, or 10: * (at your option) any later version. 11: * 12: * GNU inetlib is distributed in the hope that it will be useful, 13: * but WITHOUT ANY WARRANTY; without even the implied warranty of 14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15: * GNU General Public License for more details. 16: * 17: * You should have received a copy of the GNU General Public License 18: * along with this library; if not, write to the Free Software 19: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20: * 21: * Linking this library statically or dynamically with other modules is 22: * making a combined work based on this library. Thus, the terms and 23: * conditions of the GNU General Public License cover the whole 24: * combination. 25: * 26: * As a special exception, the copyright holders of this library give you 27: * permission to link this library with independent modules to produce an 28: * executable, regardless of the license terms of these independent 29: * modules, and to copy and distribute the resulting executable under 30: * terms of your choice, provided that you also meet, for each linked 31: * independent module, the terms and conditions of the license of that 32: * module. An independent module is a module which is not derived from 33: * or based on this library. If you modify this library, you may extend 34: * this exception to your version of the library, but you are not 35: * obliged to do so. If you do not wish to do so, delete this 36: * exception statement from your version. 37: */ 38: 39: package gnu.inet.util; 40: 41: import java.io.FilterInputStream; 42: import java.io.InputStream; 43: import java.io.IOException; 44: 45: import javax.security.sasl.SaslClient; 46: 47: /** 48: * A filter input stream that decodes all its received input using a SASL 49: * client. 50: * 51: * @author <a href="mailto:dog@gnu.org">Chris Burdess</a> 52: */ 53: public class SaslInputStream 54: extends FilterInputStream 55: { 56: 57: /* 58: * The SASL client. 59: */ 60: private final SaslClient sasl; 61: 62: /* 63: * Overflow buffer. 64: */ 65: private byte[] buf; 66: 67: /* 68: * Offset in overflow buffer. 69: */ 70: private int pos; 71: 72: /** 73: * Constructor. 74: * @param sasl the SASL client 75: * @param in the underlying input stream 76: */ 77: public SaslInputStream(SaslClient sasl, InputStream in) 78: { 79: super(in); 80: this.sasl = sasl; 81: } 82: 83: /** 84: * Reads a single character. 85: */ 86: public int read() 87: throws IOException 88: { 89: if (buf != null) 90: { 91: // Return next characer in buffer 92: int c = (int) buf[pos++]; 93: if (pos == buf.length) 94: { 95: buf = null; 96: } 97: return c; 98: } 99: int c = super.read(); 100: if (c == -1) 101: { 102: return c; 103: } 104: byte[] bytes = new byte[1]; 105: byte[] unwrapped = sasl.unwrap(bytes, 0, 1); 106: // FIXME if we get 0 bytes, we have a problem 107: c = (int) unwrapped[0]; 108: if (unwrapped.length > 1) 109: { 110: // Store in overflow buffer 111: int l = unwrapped.length - 1; 112: buf = new byte[l]; 113: System.arraycopy(unwrapped, 1, buf, 0, l); 114: pos = 0; 115: } 116: return c; 117: } 118: 119: public int read(byte[] bytes) 120: throws IOException 121: { 122: return read(bytes, 0, bytes.length); 123: } 124: 125: /** 126: * Block read. 127: */ 128: public int read(byte[] bytes, int off, int len) 129: throws IOException 130: { 131: if (buf != null) 132: { 133: // Return bytes from buffer 134: int l = buf.length; 135: if (l - pos <= len) 136: { 137: System.arraycopy(buf, pos, bytes, off, l); 138: buf = null; 139: return l; 140: } 141: else 142: { 143: System.arraycopy(buf, pos, bytes, off, len); 144: pos += len; 145: return len; 146: } 147: } 148: int l = super.read(bytes, off, len); 149: if (l == -1) 150: { 151: return l; 152: } 153: byte[] unwrapped = sasl.unwrap(bytes, off, l); 154: int l2 = unwrapped.length; 155: if (l2 > len) 156: { 157: // Store excess bytes in buffer 158: int d = l2 - len; 159: buf = new byte[d]; 160: System.arraycopy(unwrapped, 0, bytes, off, len); 161: System.arraycopy(unwrapped, len, buf, 0, d); 162: pos = 0; 163: return len; 164: } 165: else 166: { 167: System.arraycopy(unwrapped, 0, bytes, off, l2); 168: // Zero bytes from l2..l to ensure none of the original 169: // bytes received can be read by the caller 170: for (int i = l2; i < l; i++) 171: { 172: bytes[off + l2] = 0; 173: } 174: return l2; 175: } 176: } 177: 178: }