KIHARA Hideto
deton****@m1*****
2004年 2月 29日 (日) 00:56:04 JST
Fri, Feb 27, 2004 at 08:22:32PM +0900 において Etsushi Kato さん曰く: > > NetBSD ではおそらく、setsockopt() に LOCAL_CREDS を使うようなコードが > > 必要みたいですが、試すことができないので ssh-agent と同様に fallback ... > するセキュリティが保てますし、NetBSD でも少しの変更で問題ないと思いま > す (postresql の Unix ドメンインソケットの認証が参考にできると思います)。 NetBSDのLOCAL_CREDSを使うコードを追加してみました。 PostgreSQLのものをほとんどそのまま持ってきただけですが。 LOCAL_CREDSを使う場合は、相手から何かデータが送られてこないと駄目なので、 接続後にクライアントからリクエストを送って、 サーバからダミーのバイトを送ってもらうようにしています。 参考にしたソース: http://developer.postgresql.org/docs/pgsql/src/backend/libpq/hba.c http://freedesktop.org/Software/dbus/doc/api/html/dbus-sysdeps_8c-source.html http://www.cs.odu.edu/~cs779/stevens2nd/unixdomain/tfcred01.c Sat, Feb 28, 2004 at 10:41:58AM +0900 において Etsushi Kato さん曰く: > なるほど、openldap にも getpeereid() が OS に無い場合のコードがありま > すね。NetBSD でもこれならいけそうです。ただ、このコードだと、Mac OS X > 10.3 では -1 が戻ってしまい (SO_PEERCRED, LOCAL_PEERCRED, > msg_accrights のすべてがありません)、openssh のように geteuid() の msg_accrightsの代わりにmsg_controlがありませんか? 4.3BSDではmsg_accrightsで、 4.3BSD Renoからはmsg_controlに変更されたとのことなので[*]、 msg_controlを使うようにすればいいのではないかと思います。 * 『詳解UNIXプログラミング』,W・リチャード・スティーヴンス,p.471 『UNIXネットワークプログラミング〈Vol.1〉』,W・リチャード・スティーヴンス の方にもっと詳しく載っていると思いますが、今は手元にないので。 -- 木原 英人 / KIHARA, Hideto / deton****@m1***** http://www1.interq.or.jp/~deton/ diff -urp uim-0.3.0.1-credential/uim/bsd-getpeereid.c uim-0.3.0.1/uim/bsd-getpeereid.c --- uim-0.3.0.1-credential/uim/bsd-getpeereid.c 2004-02-28 14:22:35.000000000 +0900 +++ uim-0.3.0.1/uim/bsd-getpeereid.c 2004-02-28 14:13:42.000000000 +0900 @@ -17,6 +17,8 @@ #include "config.h" #include <sys/types.h> #include <sys/socket.h> +#include <sys/un.h> +#include <sys/param.h> #if !defined(HAVE_GETPEEREID) @@ -34,6 +36,80 @@ getpeereid(int s, uid_t *euid, gid_t *gi return (0); } +#elif defined(LOCAL_CREDS) /* NetBSD */ +int +getpeereid(int s, uid_t *euid, gid_t *gid) +{ +/* Credentials structure */ +#ifdef __NetBSD__ /* XXX: should use autoconf */ +#define HAVE_STRUCT_SOCKCRED +#endif +#if defined(HAVE_STRUCT_CMSGCRED) + typedef struct cmsgcred Cred; + +#define cruid cmcred_euid +#define crgid cmcred_groups[0] +#elif defined(HAVE_STRUCT_FCRED) + typedef struct fcred Cred; + +#define cruid fc_uid +#define crgid fc_gid +#elif defined(HAVE_STRUCT_SOCKCRED) + typedef struct sockcred Cred; + +#define cruid sc_euid +#define crgid sc_egid +#endif + Cred *cred; + + /* Compute size without padding */ + char cmsgmem[CMSG_SPACE(sizeof(Cred))]; /* for NetBSD */ + + /* Point to start of first structure */ + struct cmsghdr *cmsg = (struct cmsghdr *)cmsgmem; + + struct iovec iov; + char buf; + struct msghdr msg; + + /* Receive credentials on next message receipt, NetBSD. + * We need to set this before the peer sends the next packet. + */ + int on = 1; + + if (setsockopt(s, 0, LOCAL_CREDS, &on, sizeof(on)) < 0) { + return -1; + } + write(s, "get_credentials\n\n", 18); + + memset(&msg, 0, sizeof(msg)); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = (char *)cmsg; + msg.msg_controllen = sizeof(cmsgmem); + memset(cmsg, 0, sizeof(cmsgmem)); + + /* + * The one character which is received here is not meaningful; its + * purposes is only to make sure that recvmsg() blocks long enough for + * the other side to send its credentials. + */ + iov.iov_base = &buf; + iov.iov_len = 1; + + if (recvmsg(s, &msg, 0) < 0 || + cmsg->cmsg_len < sizeof(cmsgmem) || + cmsg->cmsg_type != SCM_CREDS) + { + return -1; + } + + cred = (Cred *)CMSG_DATA(cmsg); + *euid = cred->cruid; + *gid = cred->crgid; + + return 0; +} #else int getpeereid(int s, uid_t *euid, gid_t *gid) diff -urp uim-0.3.0.1-credential/uim/uim-helper-server.c uim-0.3.0.1/uim/uim-helper-server.c --- uim-0.3.0.1-credential/uim/uim-helper-server.c 2004-02-22 00:24:41.000000000 +0900 +++ uim-0.3.0.1/uim/uim-helper-server.c 2004-02-28 13:58:47.000000000 +0900 @@ -104,6 +104,14 @@ parse_content(char *content, struct clie { int i; +#ifdef LOCAL_CREDS /* for NetBSD */ + if (strcmp(content, "get_credentials\n\n") == 0) { + char buf[1] = { '\0' }; + write(cl->fd, buf, 1); + return; + } +#endif + for (i = 0; i < MAX_CLIENT; i ++){ if(clients[i].fd != -1 && clients[i].fd != cl->fd &&