Esempio n. 1
0
		//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");
		}
Esempio n. 2
0
        //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);
                        }
                    }
                }
            }
        }