28 import java.io.BufferedInputStream;
29 import java.io.BufferedOutputStream;
30 import java.io.InterruptedIOException;
31 import java.io.IOException;
32 import java.io.OutputStream;
33 import java.io.InputStream;
34 import java.net.InetSocketAddress;
35 import java.net.Socket;
36 import javax.net.ssl.SSLSocket;
37
38 import javax.naming.CommunicationException;
39 import javax.naming.ServiceUnavailableException;
40 import javax.naming.NamingException;
41 import javax.naming.InterruptedNamingException;
42
43 import javax.naming.ldap.Control;
44
45 import java.lang.reflect.Method;
46 import java.lang.reflect.InvocationTargetException;
47 import java.util.Arrays;
48 import sun.misc.IOUtils;
49 import javax.net.SocketFactory;
50
51 /**
52 * A thread that creates a connection to an LDAP server.
53 * After the connection, the thread reads from the connection.
54 * A caller can invoke methods on the instance to read LDAP responses
55 * and to send LDAP requests.
56 * <p>
57 * There is a one-to-one correspondence between an LdapClient and
58 * a Connection. Access to Connection and its methods is only via
59 * LdapClient with two exceptions: SASL authentication and StartTLS.
60 * SASL needs to access Connection's socket IO streams (in order to do encryption
61 * of the security layer). StartTLS needs to do replace IO streams
62 * and close the IO streams on nonfatal close. The code for SASL
63 * authentication can be treated as being the same as from LdapClient
64 * because the SASL code is only ever called from LdapClient, from
65 * inside LdapClient's synchronized authenticate() method. StartTLS is called
66 * directly by the application but should only occur when the underlying
67 * connection is quiet.
68 * <p>
845 if (br < 0) {
846 eos = true;
847 break; // EOF
848 }
849 bytesread += br;
850 }
851
852 // end-of-stream reached before length bytes are read
853 if (eos)
854 break; // EOF
855
856 // Add contents of length bytes to determine length
857 seqlen = 0;
858 for( int i = 0; i < seqlenlen; i++) {
859 seqlen = (seqlen << 8) + (inbuf[offset+i] & 0xff);
860 }
861 offset += bytesread;
862 }
863
864 // read in seqlen bytes
865 byte[] left = IOUtils.readFully(in, seqlen, false);
866 inbuf = Arrays.copyOf(inbuf, offset + left.length);
867 System.arraycopy(left, 0, inbuf, offset, left.length);
868 offset += left.length;
869 /*
870 if (dump > 0) {
871 System.err.println("seqlen: " + seqlen);
872 System.err.println("bufsize: " + offset);
873 System.err.println("bytesleft: " + bytesleft);
874 System.err.println("bytesread: " + bytesread);
875 }
876 */
877
878
879 try {
880 retBer = new BerDecoder(inbuf, 0, offset);
881
882 if (traceFile != null) {
883 Ber.dumpBER(traceFile, traceTagIn, inbuf, 0, offset);
884 }
885
940 }
941 }
942
943 if (debug) {
944 System.err.println("Connection: end-of-stream detected: "
945 + in);
946 }
947 } catch (IOException ex) {
948 if (debug) {
949 System.err.println("Connection: Caught " + ex);
950 }
951 closureReason = ex;
952 } finally {
953 cleanup(null, true); // cleanup
954 }
955 if (debug) {
956 System.err.println("Connection: Thread Exiting");
957 }
958 }
959
960
961 // This code must be uncommented to run the LdapAbandonTest.
962 /*public void sendSearchReqs(String dn, int numReqs) {
963 int i;
964 String attrs[] = null;
965 for(i = 1; i <= numReqs; i++) {
966 BerEncoder ber = new BerEncoder(2048);
967
968 try {
969 ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
970 ber.encodeInt(i);
971 ber.beginSeq(LdapClient.LDAP_REQ_SEARCH);
972 ber.encodeString(dn == null ? "" : dn);
973 ber.encodeInt(0, LdapClient.LBER_ENUMERATED);
974 ber.encodeInt(3, LdapClient.LBER_ENUMERATED);
975 ber.encodeInt(0);
976 ber.encodeInt(0);
977 ber.encodeBoolean(true);
978 LdapClient.encodeFilter(ber, "");
979 ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
|
28 import java.io.BufferedInputStream;
29 import java.io.BufferedOutputStream;
30 import java.io.InterruptedIOException;
31 import java.io.IOException;
32 import java.io.OutputStream;
33 import java.io.InputStream;
34 import java.net.InetSocketAddress;
35 import java.net.Socket;
36 import javax.net.ssl.SSLSocket;
37
38 import javax.naming.CommunicationException;
39 import javax.naming.ServiceUnavailableException;
40 import javax.naming.NamingException;
41 import javax.naming.InterruptedNamingException;
42
43 import javax.naming.ldap.Control;
44
45 import java.lang.reflect.Method;
46 import java.lang.reflect.InvocationTargetException;
47 import java.util.Arrays;
48 import javax.net.SocketFactory;
49
50 /**
51 * A thread that creates a connection to an LDAP server.
52 * After the connection, the thread reads from the connection.
53 * A caller can invoke methods on the instance to read LDAP responses
54 * and to send LDAP requests.
55 * <p>
56 * There is a one-to-one correspondence between an LdapClient and
57 * a Connection. Access to Connection and its methods is only via
58 * LdapClient with two exceptions: SASL authentication and StartTLS.
59 * SASL needs to access Connection's socket IO streams (in order to do encryption
60 * of the security layer). StartTLS needs to do replace IO streams
61 * and close the IO streams on nonfatal close. The code for SASL
62 * authentication can be treated as being the same as from LdapClient
63 * because the SASL code is only ever called from LdapClient, from
64 * inside LdapClient's synchronized authenticate() method. StartTLS is called
65 * directly by the application but should only occur when the underlying
66 * connection is quiet.
67 * <p>
844 if (br < 0) {
845 eos = true;
846 break; // EOF
847 }
848 bytesread += br;
849 }
850
851 // end-of-stream reached before length bytes are read
852 if (eos)
853 break; // EOF
854
855 // Add contents of length bytes to determine length
856 seqlen = 0;
857 for( int i = 0; i < seqlenlen; i++) {
858 seqlen = (seqlen << 8) + (inbuf[offset+i] & 0xff);
859 }
860 offset += bytesread;
861 }
862
863 // read in seqlen bytes
864 byte[] left = readFully(in, seqlen);
865 inbuf = Arrays.copyOf(inbuf, offset + left.length);
866 System.arraycopy(left, 0, inbuf, offset, left.length);
867 offset += left.length;
868 /*
869 if (dump > 0) {
870 System.err.println("seqlen: " + seqlen);
871 System.err.println("bufsize: " + offset);
872 System.err.println("bytesleft: " + bytesleft);
873 System.err.println("bytesread: " + bytesread);
874 }
875 */
876
877
878 try {
879 retBer = new BerDecoder(inbuf, 0, offset);
880
881 if (traceFile != null) {
882 Ber.dumpBER(traceFile, traceTagIn, inbuf, 0, offset);
883 }
884
939 }
940 }
941
942 if (debug) {
943 System.err.println("Connection: end-of-stream detected: "
944 + in);
945 }
946 } catch (IOException ex) {
947 if (debug) {
948 System.err.println("Connection: Caught " + ex);
949 }
950 closureReason = ex;
951 } finally {
952 cleanup(null, true); // cleanup
953 }
954 if (debug) {
955 System.err.println("Connection: Thread Exiting");
956 }
957 }
958
959 private static byte[] readFully(InputStream is, int length)
960 throws IOException
961 {
962 byte[] buf = new byte[Math.min(length, 8192)];
963 int nread = 0;
964 while (nread < length) {
965 int bytesToRead;
966 if (nread >= buf.length) { // need to allocate a larger buffer
967 bytesToRead = Math.min(length - nread, buf.length + 8192);
968 if (buf.length < nread + bytesToRead) {
969 buf = Arrays.copyOf(buf, nread + bytesToRead);
970 }
971 } else {
972 bytesToRead = buf.length - nread;
973 }
974 int count = is.read(buf, nread, bytesToRead);
975 if (count < 0) {
976 if (buf.length != nread)
977 buf = Arrays.copyOf(buf, nread);
978 break;
979 }
980 nread += count;
981 }
982 return buf;
983 }
984
985 // This code must be uncommented to run the LdapAbandonTest.
986 /*public void sendSearchReqs(String dn, int numReqs) {
987 int i;
988 String attrs[] = null;
989 for(i = 1; i <= numReqs; i++) {
990 BerEncoder ber = new BerEncoder(2048);
991
992 try {
993 ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
994 ber.encodeInt(i);
995 ber.beginSeq(LdapClient.LDAP_REQ_SEARCH);
996 ber.encodeString(dn == null ? "" : dn);
997 ber.encodeInt(0, LdapClient.LBER_ENUMERATED);
998 ber.encodeInt(3, LdapClient.LBER_ENUMERATED);
999 ber.encodeInt(0);
1000 ber.encodeInt(0);
1001 ber.encodeBoolean(true);
1002 LdapClient.encodeFilter(ber, "");
1003 ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
|