[#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-19 17:40:33 UTC
List: ruby-core #8295
On Tuesday 18 July 2006 15:52, Eric Hodel wrote:

> > +    if (uid < 0 || gid < 0)
> > +        rb_raise(rb_eSocket, "Invalid credentials: uid %d, gid %
> > d", uid, gid);
>
> Negative UID and GID are valid on some operating systems.

Are negative values allowed on Linux? AFAICT, if the credentials aren't 
available on Linux, say when I check a TCPServer socket's credentials
after accepting a connection from another host, the system call returns
0 but sets the uid & gid to -1:

   ruby -rsocket -e 'p TCPServer.new(ARGV.shift).accept.peer_cred' 5670
   {:ruid=>nil, :rgid=>nil, :uid=>-1, :gid=>-1, :euid=>-1, :egid=>-1}

If negative values are allowed, I really don't know what to do, otherwise,
I can raise an exception. I can also just leave it to the user to raise an
execption if e.g. Etc.getpwuid(creds[:uid]) fails.

Attached is the latest patch.

Questions/comments welcome.

Jim

Attachments (1)

ruby-sock-cred-02.patch (4.89 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	Tue Jun  6 22:40:22 2006
+++ ruby-1.8.5-preview1.mod/ext/socket/extconf.rb	Wed Jul 19 12:23:10 2006
@@ -226,6 +226,13 @@
 EOS
 end
 
+have_func("getpeerucred")
+have_func("getpeereid")
+
+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	Wed Jun 21 16:19:07 2006
+++ ruby-1.8.5-preview1.mod/ext/socket/socket.c	Wed Jul 19 10:51:42 2006
@@ -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
@@ -1643,7 +1650,121 @@
     return ipaddr((struct sockaddr*)&addr);
 }
 
+/*
+ * Document-method: peer_cred
+ * call-seq: socket.peer_cred => hash
+ *      hash[:uid]  => ruid || euid
+ *      hash[:gid]  => rgid || egid 
+ *      hash[:ruid] => ruid
+ *      hash[:euid] => euid
+ *      hash[:rgid] => rgid
+ *      hash[:egid] => egid
+ * }
+ *
+ * Returns a hash 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
+bsock_peer_cred(sock)
+    VALUE sock;
+{
+    char buf[1024];
+    socklen_t len = sizeof buf;
+    OpenFile *fptr;
+    VALUE kuid, kgid, kruid, krgid, keuid, kegid, ahash, hashval;
+/*    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;
+#elif defined(HAVE_GETPEEREID)
+    int euid, egid;
+#else
+    rb_raise(rb_eSocket, "peer_cred not implemented on this platform");
+#endif
+
+    GetOpenFile(sock, fptr);
+
+    kuid = rb_str_intern(rb_str_new2("uid"));
+    kgid = rb_str_intern(rb_str_new2("gid"));
+    kruid = rb_str_intern(rb_str_new2("ruid"));
+    krgid = rb_str_intern(rb_str_new2("rgid"));
+    keuid = rb_str_intern(rb_str_new2("euid"));
+    kegid = rb_str_intern(rb_str_new2("egid"));
+
+    ahash = rb_hash_new();
+
+    rb_hash_aset(ahash, kuid, Qnil);
+    rb_hash_aset(ahash, kgid, Qnil);
+    rb_hash_aset(ahash, kruid, Qnil);
+    rb_hash_aset(ahash, krgid, Qnil);
+    rb_hash_aset(ahash, keuid, Qnil);
+    rb_hash_aset(ahash, kegid, Qnil);
+
+#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)");
+
+    rb_hash_aset(ahash, kuid, INT2FIX(ucred_getruid(creds)));
+    rb_hash_aset(ahash, kgid, INT2FIX(ucred_getrgid(creds)));
+    rb_hash_aset(ahash, kruid, INT2FIX(ucred_getruid(creds)));
+    rb_hash_aset(ahash, krgid, INT2FIX(ucred_getrgid(creds)));
+    rb_hash_aset(ahash, keuid, INT2FIX(ucred_geteuid(creds)));
+    rb_hash_aset(ahash, kegid, INT2FIX(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");
+
+    rb_hash_aset(ahash, kuid, INT2FIX(creds.uid));
+    rb_hash_aset(ahash, kgid, INT2FIX(creds.gid));
+    rb_hash_aset(ahash, keuid, INT2FIX(creds.uid));
+    rb_hash_aset(ahash, kegid, INT2FIX(creds.gid));
+
+#elif defined(HAVE_GETPEEREID)
+    if (getpeereid(fileno(fptr->f), &euid, &egid) < 0)
+        rb_sys_fail("getpeereid");
+
+    rb_hash_aset(ahash, kuid, INT2FIX(euid));
+    rb_hash_aset(ahash, kgid, INT2FIX(egid));
+    rb_hash_aset(ahash, keuid, INT2FIX(euid));
+    rb_hash_aset(ahash, kegid, INT2FIX(egid));
+
+#endif
+
+    if ((hashval = rb_hash_aref(ahash, kuid)) == Qnil) 
+        rb_raise(rb_eSocket, "Invalid credentials: uid is nil");
+
+    if ((hashval = rb_hash_aref(ahash, kgid)) == Qnil)
+        rb_raise(rb_eSocket, "Invalid credentials: gid is nil");
+
+    return ahash;
+        
+}
+
+static VALUE
 ip_recvfrom(argc, argv, sock)
     int argc;
     VALUE *argv;
@@ -3864,6 +3985,8 @@
     rb_define_method(rb_cBasicSocket, "recv", bsock_recv, -1);
     rb_define_method(rb_cBasicSocket, "recv_nonblock", bsock_recv_nonblock, -1);
 
+    rb_define_method(rb_cBasicSocket, "peer_cred", bsock_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