Etsushi Kato
ekato****@ees*****
2004年 2月 24日 (火) 20:32:09 JST
こんばんは。加藤です。 On Tue, Feb 17, 2004 at 11:52:34PM +0900, yusuk****@cheru***** wrote: > ちょっと考えて見たのですが、Linuxの場合にst_uidが0になってたら > rootに攻撃されているというどうしようもない状況なので、あまり > 気にせずに接続することにしようと思います。 > > 一応ダメ押しで、次のようなコードにするつもりです。 > stat(st); > st.st_uidが自分でなければ失敗 > connect(); > fstat(st); > st.st_uidが自分でなくて、rootでもなければ切断 > -- 少し調べてみましたが、getpeereid() を使えば、Unix ドメインソケットの uid をチェックできそうな感じがするのですがどうでしょう? openssh の ssh-agent を参考にしてみました。 OpenBSD, FreeBSD には getpeereid() がありますし、Linux では getsockopt() で SO_PEERCRED を使うような簡単なラッパーを作ればいいよう です。 ただ残念ながら、Mac OS X 10.3 では getpeereid() も SO_PEERCRED も使え ないようなのでソケットの認証はできなさそうですが、いちおう geteuid() を fallback としているようです。 NetBSD ではおそらく、setsockopt() に LOCAL_CREDS を使うようなコードが 必要みたいですが、試すことができないので ssh-agent と同様に fallback しています。どなたかコードを付け足してください。 ということで、uim-0.3.0.1 に対するパッチを作ってみました。 bsd-getpeereid.c はopenssh からほとんどそのまま持ってきたものです。 getpeereid() の使い方が正しいのか自信はありませんけど、とりあえず動い ているようには見えます。 -- Etsushi Kato ekato****@ees***** -------------- next part -------------- diff -uNr uim-0.3.0.1.orig/configure.ac uim-0.3.0.1/configure.ac --- uim-0.3.0.1.orig/configure.ac Mon Feb 23 06:33:08 2004 +++ uim-0.3.0.1/configure.ac Tue Feb 24 19:31:24 2004 @@ -125,6 +125,8 @@ AC_FUNC_SELECT_ARGTYPES AC_TYPE_SIGNAL +AC_CHECK_FUNCS(getpeereid) + SRCDIR=$srcdir AC_SUBST(SRCDIR) diff -uNr uim-0.3.0.1.orig/uim/Makefile.am uim-0.3.0.1/uim/Makefile.am --- uim-0.3.0.1.orig/uim/Makefile.am Mon Feb 23 04:22:19 2004 +++ uim-0.3.0.1/uim/Makefile.am Tue Feb 24 19:36:10 2004 @@ -15,7 +15,8 @@ skk-dic.c anthy.c \ prime.c canna.c \ slib.c sliba.c siod.h context.h gettext.h \ - uim-ipc.c uim-table.c + uim-ipc.c uim-table.c \ + bsd-getpeereid.c libuimincludedir = $(includedir)/uim diff -uNr uim-0.3.0.1.orig/uim/Makefile.in uim-0.3.0.1/uim/Makefile.in --- uim-0.3.0.1.orig/uim/Makefile.in Mon Feb 23 06:34:19 2004 +++ uim-0.3.0.1/uim/Makefile.in Tue Feb 24 19:40:50 2004 @@ -200,7 +200,8 @@ skk-dic.c anthy.c \ prime.c canna.c \ slib.c sliba.c siod.h context.h gettext.h \ - uim-ipc.c uim-table.c + uim-ipc.c uim-table.c \ + bsd-getpeereid.c libuimincludedir = $(includedir)/uim @@ -226,7 +227,8 @@ libuim_la_DEPENDENCIES = am_libuim_la_OBJECTS = uim.lo uim-func.lo uim-key.lo uim-util.lo \ uim-helper.lo uim-helper-client.lo skk-dic.lo anthy.lo prime.lo \ - canna.lo slib.lo sliba.lo uim-ipc.lo uim-table.lo + canna.lo slib.lo sliba.lo uim-ipc.lo uim-table.lo \ + bsd-getpeereid.lo libuim_la_OBJECTS = $(am_libuim_la_OBJECTS) bin_PROGRAMS = uim-helper-server$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) @@ -241,10 +243,11 @@ DEFAULT_INCLUDES = -I. -I$(srcdir) -I. depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles - @ AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/anthy.Plo ./$(DEPDIR)/canna.Plo \ - @ AMDEP_TRUE@ ./$(DEPDIR)/prime.Plo ./$(DEPDIR)/skk-dic.Plo \ - @ AMDEP_TRUE@ ./$(DEPDIR)/slib.Plo ./$(DEPDIR)/sliba.Plo \ - @ AMDEP_TRUE@ ./$(DEPDIR)/uim-func.Plo \ + @ AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/anthy.Plo \ + @ AMDEP_TRUE@ ./$(DEPDIR)/bsd-getpeereid.Plo \ + @ AMDEP_TRUE@ ./$(DEPDIR)/canna.Plo ./$(DEPDIR)/prime.Plo \ + @ AMDEP_TRUE@ ./$(DEPDIR)/skk-dic.Plo ./$(DEPDIR)/slib.Plo \ + @ AMDEP_TRUE@ ./$(DEPDIR)/sliba.Plo ./$(DEPDIR)/uim-func.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/uim-helper-client.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/uim-helper.Plo ./$(DEPDIR)/uim-ipc.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/uim-key.Plo ./$(DEPDIR)/uim-table.Plo \ @@ -362,6 +365,7 @@ -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote @ ./$(DEPDIR)/anthy.Plo @ am__quote@ + @ AMDEP_TRUE@@am__include@ @am__quote @ ./$(DEPDIR)/bsd-getpeereid.Plo @ am__quote@ @AMDEP_TRUE@@am__include@ @am__quote @ ./$(DEPDIR)/canna.Plo @ am__quote@ @AMDEP_TRUE@@am__include@ @am__quote @ ./$(DEPDIR)/prime.Plo @ am__quote@ @AMDEP_TRUE@@am__include@ @am__quote @ ./$(DEPDIR)/skk-dic.Plo @ am__quote@ diff -uNr uim-0.3.0.1.orig/uim/bsd-getpeereid.c uim-0.3.0.1/uim/bsd-getpeereid.c --- uim-0.3.0.1.orig/uim/bsd-getpeereid.c Thu Jan 1 09:00:00 1970 +++ uim-0.3.0.1/uim/bsd-getpeereid.c Tue Feb 24 18:41:33 2004 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2002 Damien Miller. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include <sys/types.h> +#include <sys/socket.h> + +#if !defined(HAVE_GETPEEREID) + +#if defined(SO_PEERCRED) +int +getpeereid(int s, uid_t *euid, gid_t *gid) +{ + struct ucred cred; + socklen_t len = sizeof(cred); + + if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cred, &len) < 0) + return (-1); + *euid = cred.uid; + *gid = cred.gid; + + return (0); +} +#else +int +getpeereid(int s, uid_t *euid, gid_t *gid) +{ + *euid = geteuid(); + *gid = getgid(); + + return (0); +} +#endif /* defined(SO_PEERCRED) */ + +#endif /* !defined(HAVE_GETPEEREID) */ diff -uNr uim-0.3.0.1.orig/uim/config.h.in uim-0.3.0.1/uim/config.h.in --- uim-0.3.0.1.orig/uim/config.h.in Mon Feb 23 06:34:22 2004 +++ uim-0.3.0.1/uim/config.h.in Tue Feb 24 19:02:28 2004 @@ -44,6 +44,9 @@ /* Define to 1 if you have the `getpagesize' function. */ #undef HAVE_GETPAGESIZE +/* Define to 1 if you have the `getpeereid' function. */ +#undef HAVE_GETPEEREID + /* Define if the GNU gettext() function is already present or preinstalled. */ #undef HAVE_GETTEXT diff -uNr uim-0.3.0.1.orig/uim/uim-helper-client.c uim-0.3.0.1/uim/uim-helper-client.c --- uim-0.3.0.1.orig/uim/uim-helper-client.c Mon Feb 23 04:21:34 2004 +++ uim-0.3.0.1/uim/uim-helper-client.c Tue Feb 24 18:30:50 2004 @@ -37,6 +37,8 @@ int fd; struct sockaddr_un server; char *path = uim_helper_get_pathname(); + uid_t euid; + gid_t egid; uim_fd = -1; @@ -55,15 +57,6 @@ return -1; } - if (fstat(fd, &fst) != 0) { - close(fd); - return -1; - } - if (fst.st_uid != getuid()) { - close(fd); - return -1; - } - if(connect(fd, (struct sockaddr *)&server,sizeof(server)) == -1){ int serv_pid = 0; FILE *serv_r = NULL, *serv_w = NULL; @@ -85,6 +78,17 @@ } } + if (getpeereid(fd, &euid, &egid) < 0) { + perror("getpeereid failed"); + close(fd); + return -1; + } + if ((euid != 0) && (euid != getuid())) { + fprintf(stderr, "uid mismatch\n", euid); + close(fd); + return -1; + } + uim_disconnect_cb = disconnect_cb; uim_read_buf_count = 0; uim_read_buf_error = 0;