40 |
* @author <a href="mailto:dog@gnu.org">Chris Burdess</a> |
* @author <a href="mailto:dog@gnu.org">Chris Burdess</a> |
41 |
* @version $Revision$ $Date$ |
* @version $Revision$ $Date$ |
42 |
*/ |
*/ |
43 |
public class SaslInputStream |
public class SaslInputStream extends FilterInputStream |
|
extends FilterInputStream |
|
44 |
{ |
{ |
45 |
|
|
46 |
/* |
/* |
47 |
* The SASL client. |
* The SASL client. |
48 |
*/ |
*/ |
49 |
private final SaslClient sasl; |
private final SaslClient sasl; |
50 |
|
|
51 |
/* |
/* |
52 |
* Overflow buffer. |
* Overflow buffer. |
53 |
*/ |
*/ |
54 |
private byte[] buf; |
private byte[] buf; |
55 |
|
|
56 |
/* |
/* |
57 |
* Offset in overflow buffer. |
* Offset in overflow buffer. |
58 |
*/ |
*/ |
59 |
private int pos; |
private int pos; |
60 |
|
|
61 |
/** |
/** |
62 |
* Constructor. |
* Constructor. |
65 |
*/ |
*/ |
66 |
public SaslInputStream(SaslClient sasl, InputStream in) |
public SaslInputStream(SaslClient sasl, InputStream in) |
67 |
{ |
{ |
68 |
super(in); |
super(in); |
69 |
this.sasl = sasl; |
this.sasl = sasl; |
70 |
} |
} |
71 |
|
|
72 |
/** |
/** |
73 |
* Reads a single character. |
* Reads a single character. |
74 |
*/ |
*/ |
75 |
public int read() |
public int read() throws IOException |
76 |
throws IOException |
{ |
77 |
{ |
if (buf != null) |
78 |
if (buf!=null) |
{ |
79 |
{ |
// Return next characer in buffer |
80 |
// Return next characer in buffer |
int c = (int) buf[pos++]; |
81 |
int c = (int)buf[pos++]; |
if (pos == buf.length) |
82 |
if (pos==buf.length) |
buf = null; |
83 |
buf = null; |
return c; |
84 |
return c; |
} |
85 |
} |
int c = super.read(); |
86 |
int c = super.read(); |
if (c == -1) |
87 |
if (c==-1) |
return c; |
88 |
return c; |
byte[]bytes = new byte[1]; |
89 |
byte[] bytes = new byte[1]; |
byte[]unwrapped = sasl.unwrap(bytes, 0, 1); |
90 |
byte[] unwrapped = sasl.unwrap(bytes, 0, 1); |
// FIXME if we get 0 bytes, we have a problem |
91 |
// FIXME if we get 0 bytes, we have a problem |
c = (int) unwrapped[0]; |
92 |
c = (int)unwrapped[0]; |
if (unwrapped.length > 1) |
93 |
if (unwrapped.length>1) |
{ |
94 |
{ |
// Store in overflow buffer |
95 |
// Store in overflow buffer |
int l = unwrapped.length - 1; |
96 |
int l = unwrapped.length-1; |
buf = new byte[l]; |
97 |
buf = new byte[l]; |
System.arraycopy(unwrapped, 1, buf, 0, l); |
98 |
System.arraycopy(unwrapped, 1, buf, 0, l); |
pos = 0; |
99 |
pos = 0; |
} |
100 |
} |
return c; |
101 |
return c; |
} |
102 |
} |
|
103 |
|
public int read(byte[]bytes) throws IOException |
104 |
public int read(byte[] bytes) |
{ |
105 |
throws IOException |
return read(bytes, 0, bytes.length); |
106 |
{ |
} |
|
return read(bytes, 0, bytes.length); |
|
|
} |
|
107 |
|
|
108 |
/** |
/** |
109 |
* Block read. |
* Block read. |
110 |
*/ |
*/ |
111 |
public int read(byte[] bytes, int off, int len) |
public int read(byte[]bytes, int off, int len) throws IOException |
112 |
throws IOException |
{ |
113 |
{ |
if (buf != null) |
114 |
if (buf!=null) |
{ |
115 |
{ |
// Return bytes from buffer |
116 |
// Return bytes from buffer |
int l = buf.length; |
117 |
int l = buf.length; |
if (l - pos <= len) |
118 |
if (l-pos<=len) |
{ |
119 |
{ |
System.arraycopy(buf, pos, bytes, off, l); |
120 |
System.arraycopy(buf, pos, bytes, off, l); |
buf = null; |
121 |
buf = null; |
return l; |
122 |
return l; |
} |
123 |
} |
else |
124 |
else |
{ |
125 |
{ |
System.arraycopy(buf, pos, bytes, off, len); |
126 |
System.arraycopy(buf, pos, bytes, off, len); |
pos += len; |
127 |
pos += len; |
return len; |
128 |
return len; |
} |
129 |
} |
} |
130 |
} |
int l = super.read(bytes, off, len); |
131 |
int l = super.read(bytes, off, len); |
if (l == -1) |
132 |
if (l==-1) |
return l; |
133 |
return l; |
byte[]unwrapped = sasl.unwrap(bytes, off, l); |
134 |
byte[] unwrapped = sasl.unwrap(bytes, off, l); |
int l2 = unwrapped.length; |
135 |
int l2 = unwrapped.length; |
if (l2 > len) |
136 |
if (l2>len) |
{ |
137 |
{ |
// Store excess bytes in buffer |
138 |
// Store excess bytes in buffer |
int d = l2 - len; |
139 |
int d = l2-len; |
buf = new byte[d]; |
140 |
buf = new byte[d]; |
System.arraycopy(unwrapped, 0, bytes, off, len); |
141 |
System.arraycopy(unwrapped, 0, bytes, off, len); |
System.arraycopy(unwrapped, len, buf, 0, d); |
142 |
System.arraycopy(unwrapped, len, buf, 0, d); |
pos = 0; |
143 |
pos = 0; |
return len; |
144 |
return len; |
} |
145 |
} |
else |
146 |
else |
{ |
147 |
{ |
System.arraycopy(unwrapped, 0, bytes, off, l2); |
148 |
System.arraycopy(unwrapped, 0, bytes, off, l2); |
// Zero bytes from l2..l to ensure none of the original |
149 |
// Zero bytes from l2..l to ensure none of the original |
// bytes received can be read by the caller |
150 |
// bytes received can be read by the caller |
for (int i = l2; i < l; i++) |
151 |
for (int i=l2; i<l; i++) |
bytes[off + l2] = 0; |
152 |
bytes[off+l2] = 0; |
return l2; |
153 |
return l2; |
} |
154 |
} |
} |
|
} |
|
155 |
|
|
156 |
} |
} |