1
// Copyright 2006 Alp Toker <alp@atoker.com>
2
// This software is made available under the MIT License
3
// See COPYING for details
5
//We send BSD-style credentials on all platforms
6
//Doesn't seem to break Linux (but is redundant there)
7
//This may turn out to be a bad idea
13
using System.Runtime.InteropServices;
16
namespace NDesk.DBus.Transports
18
class UnixNativeTransport : UnixTransport
20
//protected UnixSocket socket;
21
internal UnixSocket socket;
23
public override string AuthString ()
25
long uid = UnixUid.GetEUID ();
26
return uid.ToString ();
29
public override void Open (string path, bool @abstract)
31
if (String.IsNullOrEmpty (path))
32
throw new ArgumentException ("path");
35
socket = OpenAbstractUnix (path);
37
socket = OpenUnix (path);
39
//socket.Blocking = true;
40
SocketHandle = (long)socket.Handle;
41
//Stream = new UnixStream ((int)socket.Handle);
42
Stream = new UnixStream (socket);
45
//send peer credentials null byte
46
//different platforms do this in different ways
48
unsafe void WriteBsdCred ()
50
//null credentials byte
53
IOVector iov = new IOVector ();
54
//iov.Base = (IntPtr)(&buf);
58
msghdr msg = new msghdr ();
62
cmsg cm = new cmsg ();
63
msg.msg_control = (IntPtr)(&cm);
64
msg.msg_controllen = (uint)sizeof (cmsg);
65
cm.hdr.cmsg_len = (uint)sizeof (cmsg);
66
cm.hdr.cmsg_level = 0xffff; //SOL_SOCKET
67
cm.hdr.cmsg_type = 0x03; //SCM_CREDS
69
int written = socket.SendMsg (&msg, 0);
71
throw new Exception ("Failed to write credentials");
75
public override void WriteCred ()
83
Console.Error.WriteLine ("Warning: WriteBsdCred() failed; falling back to ordinary WriteCred()");
86
//null credentials byte
88
Stream.WriteByte (buf);
91
public static byte[] GetSockAddr (string path)
93
byte[] p = Encoding.Default.GetBytes (path);
95
byte[] sa = new byte[2 + p.Length + 1];
97
//we use BitConverter to stay endian-safe
98
byte[] afData = BitConverter.GetBytes (UnixSocket.AF_UNIX);
102
for (int i = 0 ; i != p.Length ; i++)
104
sa[2 + p.Length] = 0; //null suffix for domain socket addresses, see unix(7)
109
public static byte[] GetSockAddrAbstract (string path)
111
byte[] p = Encoding.Default.GetBytes (path);
113
byte[] sa = new byte[2 + 1 + p.Length];
115
//we use BitConverter to stay endian-safe
116
byte[] afData = BitConverter.GetBytes (UnixSocket.AF_UNIX);
120
sa[2] = 0; //null prefix for abstract domain socket addresses, see unix(7)
121
for (int i = 0 ; i != p.Length ; i++)
127
internal UnixSocket OpenUnix (string path)
129
byte[] sa = GetSockAddr (path);
130
UnixSocket client = new UnixSocket ();
135
internal UnixSocket OpenAbstractUnix (string path)
137
byte[] sa = GetSockAddrAbstract (path);
138
UnixSocket client = new UnixSocket ();
148
public IntPtr msg_next;
149
public long msg_type;
150
public ushort msg_ts;
158
public IntPtr msg_name; //optional address
159
public uint msg_namelen; //size of address
160
public IOVector *msg_iov; //scatter/gather array
161
public int msg_iovlen; //# elements in msg_iov
162
public IntPtr msg_control; //ancillary data, see below
163
public uint msg_controllen; //ancillary data buffer len
164
public int msg_flags; //flags on received message
169
public uint cmsg_len; //data byte count, including header
170
public int cmsg_level; //originating protocol
171
public int cmsg_type; //protocol-specific type
174
unsafe struct cmsgcred
176
const int CMGROUP_MAX = 16;
178
public int cmcred_pid; //PID of sending process
179
public uint cmcred_uid; //real UID of sending process
180
public uint cmcred_euid; //effective UID of sending process
181
public uint cmcred_gid; //real GID of sending process
182
public short cmcred_ngroups; //number or groups
183
public fixed uint cmcred_groups[CMGROUP_MAX]; //groups
189
public cmsgcred cred;