KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jcifs > dcerpc > DcerpcHandle


1 /* jcifs msrpc client library in Java
2  * Copyright (C) 2006 "Michael B. Allen" <jcifs at samba dot org>
3  * "Eric Glass" <jcifs at samba dot org>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

19
20 package jcifs.dcerpc;
21
22 import java.io.*;
23 import java.net.*;
24 import java.security.Principal JavaDoc;
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     /* Bindings are in the form:
33      * proto:\\server[key1=val1,key2=val2]
34      * or
35      * proto:server[key1=val1,key2=val2]
36      * or
37      * proto:[key1=val1,key2=val2]
38      *
39      * If a key is absent it is assumed to be 'endpoint'. Thus the
40      * following are equivalent:
41      * proto:\\ts0.win.net[endpoint=\pipe\srvsvc]
42      * proto:ts0.win.net[\pipe\srvsvc]
43      *
44      * If the server is absent it is set to "127.0.0.1"
45      */

46     protected static DcerpcBinding parseBinding(String JavaDoc str) throws DcerpcException {
47         int state, mark, si;
48         char[] arr = str.toCharArray();
49         String JavaDoc 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 JavaDoc 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 JavaDoc 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 JavaDoc 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                     /* Multiple fragments. Need to set flags and length
152                      * and re-encode header
153                     msg.length = n = max_xmit;
154                     msg.flags &= ~DCERPC_LAST_FRAG;
155                     buf.start = off;
156                     buf.reset();
157                     msg.encode_header(buf);
158                      */

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                     // shouldn't happen if alloc_hint is correct or greater
193
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 JavaDoc getServer() {
213         if (this instanceof DcerpcPipeHandle)
214             return ((DcerpcPipeHandle)this).pipe.getServer();
215         return null;
216     }
217     public Principal JavaDoc getPrincipal() {
218         if (this instanceof DcerpcPipeHandle)
219             return ((DcerpcPipeHandle)this).pipe.getPrincipal();
220         return null;
221     }
222     public String JavaDoc 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