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