|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package com.sun.jndi.ldap.sasl; |
|
|
|
import javax.security.sasl.Sasl; |
|
import javax.security.sasl.SaslClient; |
|
import javax.security.sasl.SaslException; |
|
import java.io.IOException; |
|
import java.io.FilterOutputStream; |
|
import java.io.OutputStream; |
|
|
|
class SaslOutputStream extends FilterOutputStream { |
|
private static final boolean debug = false; |
|
|
|
private byte[] lenBuf = new byte[4]; |
|
private int rawSendSize = 65536; |
|
private SaslClient sc; |
|
|
|
SaslOutputStream(SaslClient sc, OutputStream out) throws SaslException { |
|
super(out); |
|
this.sc = sc; |
|
|
|
if (debug) { |
|
System.err.println("SaslOutputStream: " + out); |
|
} |
|
|
|
String str = (String) sc.getNegotiatedProperty(Sasl.RAW_SEND_SIZE); |
|
if (str != null) { |
|
try { |
|
rawSendSize = Integer.parseInt(str); |
|
} catch (NumberFormatException e) { |
|
throw new SaslException(Sasl.RAW_SEND_SIZE + |
|
" property must be numeric string: " + str); |
|
} |
|
} |
|
} |
|
|
|
// Override this method to call write(byte[], int, int) counterpart |
|
// super.write(int) simply calls out.write(int) |
|
|
|
public void write(int b) throws IOException { |
|
byte[] buffer = new byte[1]; |
|
buffer[0] = (byte)b; |
|
write(buffer, 0, 1); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
public void write(byte[] buffer, int offset, int total) throws IOException { |
|
int count; |
|
byte[] wrappedToken, saslBuffer; |
|
|
|
|
|
if (debug) { |
|
System.err.println("Total size: " + total); |
|
} |
|
|
|
for (int i = 0; i < total; i += rawSendSize) { |
|
|
|
|
|
count = (total - i) < rawSendSize ? (total - i) : rawSendSize; |
|
|
|
|
|
wrappedToken = sc.wrap(buffer, offset+i, count); |
|
|
|
|
|
intToNetworkByteOrder(wrappedToken.length, lenBuf, 0, 4); |
|
|
|
if (debug) { |
|
System.err.println("sending size: " + wrappedToken.length); |
|
} |
|
out.write(lenBuf, 0, 4); |
|
|
|
|
|
out.write(wrappedToken, 0, wrappedToken.length); |
|
} |
|
} |
|
|
|
public void close() throws IOException { |
|
SaslException save = null; |
|
try { |
|
sc.dispose(); |
|
} catch (SaslException e) { |
|
|
|
save = e; |
|
} |
|
super.close(); |
|
|
|
if (save != null) { |
|
throw save; |
|
} |
|
} |
|
|
|
// Copied from com.sun.security.sasl.util.SaslImpl |
|
|
|
|
|
|
|
*/ |
|
private static void intToNetworkByteOrder(int num, byte[] buf, int start, |
|
int count) { |
|
if (count > 4) { |
|
throw new IllegalArgumentException("Cannot handle more than 4 bytes"); |
|
} |
|
|
|
for (int i = count-1; i >= 0; i--) { |
|
buf[start+i] = (byte)(num & 0xff); |
|
num >>>= 8; |
|
} |
|
} |
|
} |