1 19 20 package jcifs.dcerpc; 21 22 import java.io.*; 23 import java.net.*; 24 import java.security.Principal ; 25 26 import jcifs.smb.NtlmPasswordAuthentication; 27 import jcifs.util.Hexdump; 28 import jcifs.dcerpc.ndr.NdrBuffer; 29 30 public abstract class DcerpcHandle implements DcerpcConstants { 31 32 46 protected static DcerpcBinding parseBinding(String str) throws DcerpcException { 47 int state, mark, si; 48 char[] arr = str.toCharArray(); 49 String proto = null, key = null; 50 DcerpcBinding binding = null; 51 52 state = mark = si = 0; 53 do { 54 char ch = arr[si]; 55 56 switch (state) { 57 case 0: 58 if (ch == ':') { 59 proto = str.substring(mark, si); 60 mark = si + 1; 61 state = 1; 62 } 63 break; 64 case 1: 65 if (ch == '\\') { 66 mark = si + 1; 67 break; 68 } 69 state = 2; 70 case 2: 71 if (ch == '[') { 72 String server = str.substring(mark, si).trim(); 73 if (server.length() == 0) 74 server = "127.0.0.1"; 75 binding = new DcerpcBinding(proto, str.substring(mark, si)); 76 mark = si + 1; 77 state = 5; 78 } 79 break; 80 case 5: 81 if (ch == '=') { 82 key = str.substring(mark, si).trim(); 83 mark = si + 1; 84 } else if (ch == ',' || ch == ']') { 85 String val = str.substring(mark, si).trim(); 86 if (key == null) 87 key = "endpoint"; 88 binding.setOption(key, val); 89 key = null; 90 } 91 break; 92 default: 93 si = arr.length; 94 } 95 96 si++; 97 } while (si < arr.length); 98 99 if (binding == null || binding.endpoint == null) 100 throw new DcerpcException("Invalid binding URL: " + str); 101 102 return binding; 103 } 104 105 protected DcerpcBinding binding; 106 protected int max_xmit = 4280; 107 protected int max_recv = max_xmit; 108 protected int state = 0; 109 private static int call_id = 1; 110 111 public static DcerpcHandle getHandle(String url, 112 NtlmPasswordAuthentication auth) 113 throws UnknownHostException, MalformedURLException, DcerpcException { 114 if (url.startsWith("ncacn_np:")) { 115 return new DcerpcPipeHandle(url, auth); 116 } 117 throw new DcerpcException("DCERPC transport not supported: " + url); 118 } 119 120 public void sendrecv(DcerpcMessage msg) throws DcerpcException, IOException { 121 byte[] stub, frag; 122 NdrBuffer buf, fbuf; 123 boolean isLast, isDirect; 124 DcerpcException de; 125 126 if (state == 0) { 127 state = 1; 128 DcerpcMessage bind = new DcerpcBind(binding, this); 129 sendrecv(bind); 130 } 131 132 isDirect = msg instanceof DcerpcBind; 133 134 stub = jcifs.smb.BufferCache.getBuffer(); 135 try { 136 int off, tot, n; 137 138 buf = new NdrBuffer(stub, 0); 139 140 msg.flags = DCERPC_FIRST_FRAG | DCERPC_LAST_FRAG; 141 msg.call_id = call_id; 142 143 msg.encode(buf); 144 145 tot = buf.getLength(); 146 off = 0; 147 while (off < tot) { 148 msg.call_id = call_id++; 149 150 if ((tot - off) > max_xmit) { 151 159 throw new DcerpcException("Fragmented request PDUs currently not supported"); 160 } else { 161 n = tot - off; 162 } 163 164 doSendFragment(stub, off, n, isDirect); 165 off += n; 166 } 167 168 doReceiveFragment(stub, isDirect); 169 buf.reset(); 170 msg.decode_header(buf); 171 172 off = 24; 173 if (msg.ptype == 2 && msg.isFlagSet(DCERPC_LAST_FRAG) == false) 174 off = msg.length; 175 176 frag = null; 177 fbuf = null; 178 while (msg.isFlagSet(DCERPC_LAST_FRAG) == false) { 179 int stub_frag_len; 180 181 if (frag == null) { 182 frag = new byte[max_recv]; 183 fbuf = new NdrBuffer(frag, 0); 184 } 185 186 doReceiveFragment(frag, isDirect); 187 fbuf.reset(); 188 msg.decode_header(fbuf); 189 stub_frag_len = msg.length - 24; 190 191 if ((off + stub_frag_len) > stub.length) { 192 byte[] tmp = new byte[off + stub_frag_len]; 194 System.arraycopy(stub, 0, tmp, 0, off); 195 stub = tmp; 196 } 197 198 System.arraycopy(frag, 24, stub, off, stub_frag_len); 199 off += stub_frag_len; 200 } 201 202 buf.reset(); 203 msg.decode(buf); 204 } finally { 205 jcifs.smb.BufferCache.releaseBuffer(stub); 206 } 207 208 if ((de = msg.getResult()) != null) 209 throw de; 210 } 211 212 public String getServer() { 213 if (this instanceof DcerpcPipeHandle) 214 return ((DcerpcPipeHandle)this).pipe.getServer(); 215 return null; 216 } 217 public Principal getPrincipal() { 218 if (this instanceof DcerpcPipeHandle) 219 return ((DcerpcPipeHandle)this).pipe.getPrincipal(); 220 return null; 221 } 222 public String toString() { 223 return binding.toString(); 224 } 225 226 protected abstract void doSendFragment(byte[] buf, 227 int off, 228 int length, 229 boolean isDirect) throws IOException; 230 protected abstract void doReceiveFragment(byte[] buf, boolean isDirect) throws IOException; 231 public abstract void close() throws IOException; 232 } 233 | Popular Tags |