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.net.*;
23 import java.io.*;
24 
25 import jcifs.dcerpc.ndr.NdrBuffer;
26 import jcifs.smb.*;
27 import jcifs.util.*;
28 
29 public class DcerpcPipeHandle extends DcerpcHandle {
30 
31     SmbNamedPipe pipe;
32     SmbFileInputStream in = null;
33     SmbFileOutputStream out = null;
34     boolean isStart = true;
35 
DcerpcPipeHandle(String url, NtlmPasswordAuthentication auth)36     public DcerpcPipeHandle(String url,
37                 NtlmPasswordAuthentication auth)
38                 throws UnknownHostException, MalformedURLException, DcerpcException {
39         binding = DcerpcHandle.parseBinding(url);
40         url = "smb://" + binding.server + "/IPC$/" + binding.endpoint.substring(6);
41 
42         String params = "", server, address;
43         server = (String)binding.getOption("server");
44         if (server != null)
45             params += "&server=" + server;
46         address = (String)binding.getOption("address");
47         if (server != null)
48             params += "&address=" + address;
49         if (params.length() > 0)
50             url += "?" + params.substring(1);
51 
52         pipe = new SmbNamedPipe(url,
53                 /* This 0x20000 bit is going to get chopped! */
54                 (0x2019F << 16) | SmbNamedPipe.PIPE_TYPE_RDWR | SmbNamedPipe.PIPE_TYPE_DCE_TRANSACT,
55                 auth);
56     }
57 
doSendFragment(byte[] buf, int off, int length, boolean isDirect)58     protected void doSendFragment(byte[] buf,
59                     int off,
60                     int length,
61                     boolean isDirect) throws IOException {
62         if (out != null && out.isOpen() == false)
63             throw new IOException("DCERPC pipe is no longer open");
64 
65         if (in == null)
66             in = (SmbFileInputStream)pipe.getNamedPipeInputStream();
67         if (out == null)
68             out = (SmbFileOutputStream)pipe.getNamedPipeOutputStream();
69         if (isDirect) {
70             out.writeDirect( buf, off, length, 1 );
71             return;
72         }
73         out.write(buf, off, length);
74     }
doReceiveFragment(byte[] buf, boolean isDirect)75     protected void doReceiveFragment(byte[] buf, boolean isDirect) throws IOException {
76         int off, flags, length;
77 
78         if (buf.length < max_recv)
79             throw new IllegalArgumentException("buffer too small");
80 
81         if (isStart && !isDirect) { // start of new frag, do trans
82             off = in.read(buf, 0, 1024);
83         } else {
84             off = in.readDirect(buf, 0, buf.length);
85         }
86 
87         if (buf[0] != 5 && buf[1] != 0)
88             throw new IOException("Unexpected DCERPC PDU header");
89 
90         flags = buf[3] & 0xFF;
91         // next read is start of new frag
92         isStart = (flags & DCERPC_LAST_FRAG) == DCERPC_LAST_FRAG;
93 
94         length = Encdec.dec_uint16le(buf, 8);
95         if (length > max_recv)
96             throw new IOException("Unexpected fragment length: " + length);
97 
98         while (off < length) {
99             off += in.readDirect(buf, off, length - off);
100         }
101     }
close()102     public void close() throws IOException {
103         state = 0;
104         if (out != null)
105             out.close();
106     }
107 }
108 
109