//send peer credentials null byte //different platforms do this in different ways #if HAVE_CMSGCRED unsafe void WriteBsdCred () { //null credentials byte byte buf = 0; IOVector iov = new IOVector (); //iov.Base = (IntPtr)(&buf); iov.Base = &buf; iov.Length = 1; msghdr msg = new msghdr (); msg.msg_iov = &iov; msg.msg_iovlen = 1; cmsg cm = new cmsg (); msg.msg_control = (IntPtr)(&cm); msg.msg_controllen = (uint)sizeof (cmsg); cm.hdr.cmsg_len = (uint)sizeof (cmsg); cm.hdr.cmsg_level = 0xffff; //SOL_SOCKET cm.hdr.cmsg_type = 0x03; //SCM_CREDS int written = socket.SendMsg (&msg, 0); if (written != 1) throw new Exception ("Failed to write credentials"); }
//send peer credentials null byte //different platforms do this in different ways #if HAVE_CMSGCRED unsafe void WriteBsdCred() { //null credentials byte byte buf = 0; IOVector iov = new IOVector(); //iov.Base = (IntPtr)(&buf); iov.Base = &buf; iov.Length = 1; msghdr msg = new msghdr(); msg.msg_iov = &iov; msg.msg_iovlen = 1; cmsg cm = new cmsg(); msg.msg_control = (IntPtr)(&cm); msg.msg_controllen = (uint)sizeof(cmsg); cm.hdr.cmsg_len = (uint)sizeof(cmsg); cm.hdr.cmsg_level = 0xffff; //SOL_SOCKET cm.hdr.cmsg_type = 0x03; //SCM_CREDS int written = socket.SendMsg(&msg, 0); if (written != 1) { throw new Exception("Failed to write credentials"); } }
internal unsafe override int Read(byte[] buffer, int offset, int count, UnixFDArray fdArray) { if (!Connection.UnixFDSupported || fdArray == null) { return(base.Read(buffer, offset, count, fdArray)); } if (count < 0 || offset < 0 || count + offset < count || count + offset > buffer.Length) { throw new ArgumentException(); fixed(byte *ptr = buffer) { IOVector iov = new IOVector(); iov.Base = ptr + offset; iov.Length = count; msghdr msg = new msghdr(); msg.msg_iov = &iov; msg.msg_iovlen = 1; byte[] cmsg = new byte[CMSG_LEN((ulong)(sizeof(int) * UnixFDArray.MaxFDs))]; fixed(byte *cmsgPtr = cmsg) { msg.msg_control = (IntPtr)(cmsgPtr); msg.msg_controllen = (uint)cmsg.Length; int read = socket.RecvMsg(&msg, 0); for (cmsghdr *hdr = CMSG_FIRSTHDR(&msg); hdr != null; hdr = CMSG_NXTHDR(&msg, hdr)) { if (hdr->cmsg_level != 1) //SOL_SOCKET { continue; } if (hdr->cmsg_type != 0x01) //SCM_RIGHTS { continue; } int *data = (int *)CMSG_DATA(hdr); int fdCount = (int)(((ulong)hdr->cmsg_len - CMSG_LEN(0)) / sizeof(int)); for (int i = 0; i < fdCount; i++) { fdArray.FDs.Add(new UnixFD(data[i])); } } if ((msg.msg_flags & 0x08) != 0) // MSG_CTRUNC { throw new Exception("Control message truncated"); } return(read); } } }
// Send the two buffers and the FDs using sendmsg(), don't handle short writes // length1 + length2 must not be 0 public unsafe long SendmsgShort(byte[] buffer1, long offset1, long length1, byte[] buffer2, long offset2, long length2, DBus.Protocol.UnixFDArray fds) { //Console.WriteLine ("SendmsgShort (X, {0}, {1}, {2}, {3}, {4}, {5})", offset1, length1, buffer2 == null ? "-" : "Y", offset2, length2, fds == null ? "-" : "" + fds.FDs.Count); AssertValidBuffer(buffer1, offset1, length1); if (buffer2 == null) { if (length2 != 0) { throw new ArgumentOutOfRangeException("length2", "!= 0 while buffer2 == null"); } offset2 = 0; } else { AssertValidBuffer(buffer2, offset2, length2); } fixed(byte *ptr1 = buffer1, ptr2 = buffer2) { var iovecs = new IOVector[] { new IOVector { Base = (ptr1 + offset1), Length = (int)length1, }, new IOVector { Base = (ptr2 + offset2), Length = (int)length2, }, }; /* Simulate short writes * if (iovecs[0].iov_len == 0) { * iovecs[1].iov_len = Math.Min (iovecs[1].iov_len, 5); * } else { * iovecs[0].iov_len = Math.Min (iovecs[0].iov_len, 5); * iovecs[1].iov_len = 0; * } */ byte[] cmsg = null; // Create copy of FDs to prevent the user from Dispose()ing the // FDs in another thread between writing the FDs into the cmsg // buffer and calling sendmsg() fixed(IOVector *iovecPtr = iovecs) { using (var fds2 = fds == null ? null : fds.Clone()) { int fdCount = fds2 == null ? 0 : fds2.FDs.Count; if (fdCount != 0) { // Create one SCM_RIGHTS control message cmsg = new byte[CMSG_SPACE((uint)fdCount * sizeof(int))]; } fixed(byte *cmsgPtr = cmsg) { var msghdr = new msghdr { msg_iov = iovecPtr, msg_iovlen = length2 == 0 ? 1 : 2, msg_control = (IntPtr)cmsgPtr, msg_controllen = cmsg == null ? 0 : (uint)cmsg.Length, }; if (fdCount != 0) { var hdr = new cmsghdr { cmsg_len = (UIntPtr)CMSG_LEN((uint)fdCount * sizeof(int)), cmsg_level = 1, // SOL_SOCKET cmsg_type = 1, // SCM_RIGHTS }; *((cmsghdr *)cmsgPtr) = hdr; var data = CMSG_DATA((cmsghdr *)cmsgPtr); fixed(byte *ptr = cmsg) { for (int i = 0; i < fdCount; i++) { ((int *)data)[i] = fds2.FDs[i].Handle; } } } long r = socket.SendMsg(&msghdr, 0); if (r == 0) { throw new Exception("sendmsg() returned 0"); } return(r); } } } } }