[#8136] Confused exception handling in Continuation Context — "Robert Dober" <robert.dober@...>

Hi all

13 messages 2006/07/06

[#8248] One-Click Installer: MinGW? or VC2005? — "Curt Hibbs" <ml.chibbs@...>

I just posted this to ruby-talk. But I would also like to discuss this

33 messages 2006/07/18
[#8264] Re: One-Click Installer: MinGW? or VC2005? — Charlie Savage <cfis@...> 2006/07/19

From my experience using both tool chains on Windows (for the ruby-prof

[#8266] Re: One-Click Installer: MinGW? or VC2005? — "Curt Hibbs" <ml.chibbs@...> 2006/07/19

Tim, I'm going to top reply since your post was so long. I'm interested in

[#8267] Re: One-Click Installer: MinGW? or VC2005? — Charlie Savage <cfis@...> 2006/07/19

> Tim, I'm going to top reply since your post was so long. I'm interested in

[#8271] my sandboxing extension!! — why the lucky stiff <ruby-core@...>

I have (what feels like) very exciting news. I finally sat down to code up my

17 messages 2006/07/19

[#8430] Re: doc patch: weakref. — "Berger, Daniel" <Daniel.Berger@...>

> -----Original Message-----

19 messages 2006/07/28
[#8434] Re: doc patch: weakref. — Yukihiro Matsumoto <matz@...> 2006/07/29

Hi,

[#8436] Re: doc patch: weakref. — Daniel Berger <djberg96@...> 2006/07/29

Yukihiro Matsumoto wrote:

[#8437] Re: doc patch: weakref. — Mauricio Fernandez <mfp@...> 2006/07/29

On Sat, Jul 29, 2006 at 07:37:24PM +0900, Daniel Berger wrote:

[#8441] Inconsistency in scoping during module_eval? — "Charles O Nutter" <headius@...>

I have the following code:

18 messages 2006/07/30
[#8442] Re: Inconsistency in scoping during module_eval? — nobu@... 2006/07/30

Hi,

[#8443] Re: Inconsistency in scoping during module_eval? — "Charles O Nutter" <headius@...> 2006/07/30

Why does this:

[#8445] Re: Inconsistency in scoping during module_eval? — Yukihiro Matsumoto <matz@...> 2006/07/30

Hi,

[#8454] Re: Inconsistency in scoping during module_eval? — "Charles O Nutter" <headius@...> 2006/07/31

So to clarify...

Re: Patch for Unix socket peer credentials

From: "James F. Hranicky" <jfh@...>
Date: 2006-07-13 19:04:13 UTC
List: ruby-core #8212
On Tuesday 11 July 2006 00:10, Tanaka Akira wrote:
> In article <200607101352.16804.jfh@cise.ufl.edu>,
>
> I think it's good enough.

Ok. I changed it to a struct, and made it a method of BasicSock:

   ruby -rsocket -e 'p UNIXServer.new(ARGV.shift).accept.peer_cred' /tmp/sock
   #<struct Struct::SockCred uid=987, gid=10426, ruid=987, rgid=10426,
   euid=987, egid=10426>

Here's the patch. The method should throw an error if any of the system calls
fail or if (uid < 0 || gid < 0). 

Questions or comments welcome.

Jim

Attachments (1)

ruby-sock-cred.patch (4.34 KB, text/x-diff)
diff -ur ruby-1.8.5-preview1/ext/socket/extconf.rb ruby-1.8.5-preview1.mod/ext/socket/extconf.rb
--- ruby-1.8.5-preview1/ext/socket/extconf.rb	2006-06-06 22:40:22.000000000 -0400
+++ ruby-1.8.5-preview1.mod/ext/socket/extconf.rb	2006-07-11 16:51:55.717600000 -0400
@@ -226,6 +226,20 @@
 EOS
 end
 
+if have_library("c", "getpeerucred")
+  $defs << "-DHAVE_GETPEERUCRED "
+else
+   puts "no getpeerucred"
+end
+
+if have_library("c", "getpeereid")
+  $defs << "-DHAVE_GETPEEREID "
+end
+
+if have_macro("SO_PEERCRED", "sys/socket.h")
+  $defs <<  "-DHAVE_SO_PEERCRED "
+end
+
 case with_config("lookup-order-hack", "UNSPEC")
 when "INET"
   $defs << "-DLOOKUP_ORDER_HACK_INET"
diff -ur ruby-1.8.5-preview1/ext/socket/socket.c ruby-1.8.5-preview1.mod/ext/socket/socket.c
--- ruby-1.8.5-preview1/ext/socket/socket.c	2006-06-21 16:19:07.000000000 -0400
+++ ruby-1.8.5-preview1.mod/ext/socket/socket.c	2006-07-13 14:58:17.499317000 -0400
@@ -71,6 +71,13 @@
 #endif
 #include "sockport.h"
 
+#if defined(HAVE_GETPEERUCRED)
+#include <ucred.h>
+#elif defined(HAVE_GETPEEREID)
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
 #if defined(__vms)
 #include <tcp.h>
 #endif
@@ -89,6 +96,7 @@
 VALUE rb_cSocket;
 
 static VALUE rb_eSocket;
+static VALUE sSockCred;
 
 #ifdef SOCKS
 VALUE rb_cSOCKSSocket;
@@ -1643,6 +1651,101 @@
     return ipaddr((struct sockaddr*)&addr);
 }
 
+/*
+ * Document-method: peer_cred
+ * call-seq: socket.peer_cred => s
+ *      s.uid  => ruid || euid
+ *      s.gid  => rgid || egid 
+ *      s.ruid => ruid
+ *      s.euid => euid
+ *      s.rgid => rgid
+ *      s.egid => egid
+ * }
+ *
+ * Returns a struct containing the credentials of the peer socket for 
+ * Unix domain stream sockets
+ *
+ * === Example
+ * # Client example
+ *   require 'socket'
+ *   s = UNIXSocket.new("/path/to/socket")
+ *   puts "Peer uid is #{s.peer_cred.uid}"
+ *
+ * # Server example
+ *   require 'socket'
+ *   s = UNIXServer.new("/path/to/socket")
+ *   ns = s.accept
+ *   puts "Peer uid is #{ns.peer_cred.uid}"
+ *
+ */
+ 
+static VALUE
+unix_peer_cred(sock)
+    VALUE sock;
+{
+    char buf[1024];
+    socklen_t len = sizeof buf;
+    OpenFile *fptr;
+    int uid, gid, ruid, rgid, euid, egid;
+    uid = gid = ruid = rgid = euid = egid = -1;
+
+#if defined(HAVE_GETPEERUCRED)
+    ucred_t *creds;
+#elif defined(HAVE_SO_PEERCRED)
+    struct ucred creds;
+#else
+    rb_raise(rb_eSocket, "peer_cred not implemented on this platform");
+#endif
+
+    GetOpenFile(sock, fptr);
+
+#if defined(HAVE_GETPEERUCRED)
+    if ((creds = malloc(ucred_size())) == NULL)
+        rb_sys_fail("malloc");
+
+    if (getpeerucred(fileno(fptr->f), &creds) < 0)
+        rb_sys_fail("getpeerucred(2)");
+
+    uid  = ucred_getruid(creds);
+    gid  = ucred_getrgid(creds);
+    ruid = ucred_getruid(creds);
+    rgid = ucred_getrgid(creds);
+    euid = ucred_geteuid(creds);
+    egid = ucred_getegid(creds);
+
+    ucred_free(creds);
+
+#elif defined(HAVE_SO_PEERCRED)
+
+    if (getsockopt(fileno(fptr->f), SOL_SOCKET, SO_PEERCRED, &creds, &len) < 0)
+        rb_sys_fail("getsockopt");
+
+    uid = creds.uid;
+    gid = creds.gid;
+    euid = creds.uid;
+    egid = creds.gid;
+
+#elif defined(HAVE_GETPEEREID)
+    if (getpeereid(fileno(fptr->f), &euid, &egid) < 0)
+        rb_sys_fail("getpeereid");
+
+    uid = euid;
+    gid = egid;
+
+#endif
+
+    if (uid < 0 || gid < 0)
+        rb_raise(rb_eSocket, "Invalid credentials: uid %d, gid %d", uid, gid);
+
+    return rb_struct_new(sSockCred, INT2FIX(uid), 
+                                    INT2FIX(gid),
+                                    INT2FIX(ruid),
+                                    INT2FIX(rgid),
+                                    INT2FIX(euid),
+                                    INT2FIX(egid), 
+                                    0);
+}
+
 static VALUE
 ip_recvfrom(argc, argv, sock)
     int argc;
@@ -3864,6 +3967,10 @@
     rb_define_method(rb_cBasicSocket, "recv", bsock_recv, -1);
     rb_define_method(rb_cBasicSocket, "recv_nonblock", bsock_recv_nonblock, -1);
 
+    rb_global_variable(&sSockCred);
+    sSockCred = rb_struct_define("SockCred", "uid", "gid", "ruid", "rgid", "euid", "egid", NULL);
+    rb_define_method(rb_cBasicSocket, "peer_cred", unix_peer_cred, 0);
+
     rb_cIPSocket = rb_define_class("IPSocket", rb_cBasicSocket);
     rb_define_global_const("IPsocket", rb_cIPSocket);
     rb_define_method(rb_cIPSocket, "addr", ip_addr, 0);

In This Thread