diff options
author | Martin Willi <martin@strongswan.org> | 2008-05-08 10:58:04 +0000 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2008-05-08 10:58:04 +0000 |
commit | 25b12c696bf52b7ddb228458bba656d25a6222d4 (patch) | |
tree | 6c9fa89a5fc25ac3923415901aa94a2448295769 | |
parent | 97e820f5fdbd7987003cb086a02f7ee2f2a6ccee (diff) | |
download | strongswan-25b12c696bf52b7ddb228458bba656d25a6222d4.tar.bz2 strongswan-25b12c696bf52b7ddb228458bba656d25a6222d4.tar.xz |
replaced --with-gid/uid by --with-group/user
using named users, groups
fixed capability dropping in pluto
-rw-r--r-- | configure.in | 24 | ||||
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/charon/daemon.c | 63 | ||||
-rw-r--r-- | src/charon/daemon.h | 10 | ||||
-rw-r--r-- | src/charon/plugins/smp/smp.c | 2 | ||||
-rw-r--r-- | src/charon/plugins/stroke/stroke_socket.c | 2 | ||||
-rw-r--r-- | src/libstrongswan/utils/leak_detective.c | 2 | ||||
-rw-r--r-- | src/pluto/plutomain.c | 38 | ||||
-rw-r--r-- | src/starter/Makefile.am | 20 | ||||
-rw-r--r-- | src/starter/invokecharon.c | 30 | ||||
-rw-r--r-- | src/starter/invokepluto.c | 30 | ||||
-rw-r--r-- | src/starter/starter.c | 62 |
12 files changed, 190 insertions, 97 deletions
diff --git a/configure.in b/configure.in index d9473fd1c..b29ce3a8c 100644 --- a/configure.in +++ b/configure.in @@ -118,17 +118,25 @@ AC_ARG_WITH( ) AC_ARG_WITH( - [uid], - AS_HELP_STRING([--with-uid=uid],[change user of the daemons to UID after startup (default is 0).]), - [AC_DEFINE_UNQUOTED(IPSEC_UID, $withval) AC_SUBST(ipsecuid, "$withval")], - [AC_DEFINE_UNQUOTED(IPSEC_UID, 0) AC_SUBST(ipsecuid, "0")] + [uid],,[AC_MSG_ERROR([--with-uid is gone, use --with-user instead!])] ) AC_ARG_WITH( - [gid], - AS_HELP_STRING([--with-gid=gid],[change group of the daemons to GID after startup (default is 0).]), - [AC_DEFINE_UNQUOTED(IPSEC_GID, $withval) AC_SUBST(ipsecgid, "$withval")], - [AC_DEFINE_UNQUOTED(IPSEC_GID, 0) AC_SUBST(ipsecgid, "0")] + [gid],,[AC_MSG_ERROR([--with-gid is gone, use --with-group instead!])] +) + +AC_ARG_WITH( + [user], + AS_HELP_STRING([--with-user=user],[change user of the daemons to "user" after startup (default is 0).]), + [AC_DEFINE_UNQUOTED(IPSEC_USER, "$withval") AC_SUBST(ipsecuser, "$withval")], + [AC_SUBST(ipsecuser, "root")] +) + +AC_ARG_WITH( + [group], + AS_HELP_STRING([--with-group=group],[change group of the daemons to "group" after startup (default is 0).]), + [AC_DEFINE_UNQUOTED(IPSEC_GROUP, "$withval") AC_SUBST(ipsecgroup, "$withval")], + [AC_SUBST(ipsecgroup, "root")] ) AC_ARG_ENABLE( diff --git a/src/Makefile.am b/src/Makefile.am index 3ed61dfc7..1322dda28 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,5 +42,5 @@ endif EXTRA_DIST = strongswan.conf install-exec-local : - test -e "$(DESTDIR)${sysconfdir}" || $(MKDIR_P) "$(DESTDIR)$(sysconfdir)" - test -e "$(DESTDIR)$(sysconfdir)/strongswan.conf" || $(INSTALL) -m 600 strongswan.conf $(DESTDIR)$(sysconfdir)/strongswan.conf + test -e "$(DESTDIR)${sysconfdir}" || $(INSTALL) -d "$(DESTDIR)$(sysconfdir)" + test -e "$(DESTDIR)$(sysconfdir)/strongswan.conf" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -m 640 strongswan.conf $(DESTDIR)$(sysconfdir)/strongswan.conf diff --git a/src/charon/daemon.c b/src/charon/daemon.c index 0400a991d..ce12917aa 100644 --- a/src/charon/daemon.c +++ b/src/charon/daemon.c @@ -28,6 +28,8 @@ #include <string.h> #include <getopt.h> #include <errno.h> +#include <pwd.h> +#include <grp.h> #ifdef HAVE_BACKTRACE # include <execinfo.h> #endif /* HAVE_BACKTRACE */ @@ -207,11 +209,17 @@ static void destroy(private_daemon_t *this) static void kill_daemon(private_daemon_t *this, char *reason) { /* we send SIGTERM, so the daemon can cleanly shut down */ - DBG1(DBG_DMN, "killing daemon: %s", reason); + if (this->public.bus) + { + DBG1(DBG_DMN, "killing daemon: %s", reason); + } + else + { + fprintf(stderr, "killing daemon: %s\n", reason); + } if (this->main_thread_id == pthread_self()) { /* initialization failed, terminate daemon */ - destroy(this); unlink(PID_FILE); exit(-1); } @@ -237,18 +245,14 @@ static void drop_capabilities(private_daemon_t *this, bool full) if (full) { -# if IPSEC_GID - if (setgid(IPSEC_GID) != 0) + if (setgid(charon->gid) != 0) { - kill_daemon(this, "changing GID to unprivileged group failed"); + kill_daemon(this, "change to unprivileged group failed"); } -# endif -# if IPSEC_UID - if (setuid(IPSEC_UID) != 0) + if (setuid(charon->uid) != 0) { - kill_daemon(this, "changing UID to unprivileged user failed"); + kill_daemon(this, "change to unprivileged user failed"); } -# endif } else { @@ -283,6 +287,39 @@ static void drop_capabilities(private_daemon_t *this, bool full) } /** + * lookup UID and GID + */ +static void lookup_uid_gid(private_daemon_t *this) +{ +#ifdef IPSEC_USER + { + char buf[1024]; + struct passwd passwd, *pwp; + + if (getpwnam_r(IPSEC_USER, &passwd, buf, sizeof(buf), &pwp) != 0 || + pwp == NULL) + { + kill_daemon(this, "resolving user '"IPSEC_USER"' failed"); + } + charon->uid = pwp->pw_uid; + } +#endif +#ifdef IPSEC_GROUP + { + char buf[1024]; + struct group group, *grp; + + if (getgrnam_r(IPSEC_GROUP, &group, buf, sizeof(buf), &grp) != 0 || + grp == NULL) + { + kill_daemon(this, "reslvoing group '"IPSEC_GROUP"' failed"); + } + charon->gid = grp->gr_gid; + } +#endif +} + +/** * Initialize the daemon */ static bool initialize(private_daemon_t *this, bool syslog, level_t levels[]) @@ -428,6 +465,8 @@ private_daemon_t *daemon_create(void) this->public.outlog = NULL; this->public.syslog = NULL; this->public.authlog = NULL; + this->public.uid = 0; + this->public.gid = 0; this->main_thread_id = pthread_self(); @@ -496,6 +535,8 @@ int main(int argc, char *argv[]) private_charon = daemon_create(); charon = (daemon_t*)private_charon; + lookup_uid_gid(private_charon); + /* drop the capabilities we won't need for initialization */ prctl(PR_SET_KEEPCAPS, 1); drop_capabilities(private_charon, FALSE); @@ -571,7 +612,7 @@ int main(int argc, char *argv[]) if (pid_file) { fprintf(pid_file, "%d\n", getpid()); - fchown(fileno(pid_file), IPSEC_UID, IPSEC_GID); + fchown(fileno(pid_file), charon->uid, charon->gid); fclose(pid_file); } diff --git a/src/charon/daemon.h b/src/charon/daemon.h index 5d590754b..8399523ec 100644 --- a/src/charon/daemon.h +++ b/src/charon/daemon.h @@ -299,6 +299,16 @@ struct daemon_t { #endif /* ME */ /** + * User ID the daemon will user after initialization + */ + uid_t uid; + + /** + * Group ID the daemon will use after initialization + */ + gid_t gid; + + /** * Shut down the daemon. * * @param reason describtion why it will be killed diff --git a/src/charon/plugins/smp/smp.c b/src/charon/plugins/smp/smp.c index 93824518e..6380714e9 100644 --- a/src/charon/plugins/smp/smp.c +++ b/src/charon/plugins/smp/smp.c @@ -728,7 +728,7 @@ plugin_t *plugin_create() return NULL; } umask(old); - if (chown(unix_addr.sun_path, IPSEC_UID, IPSEC_GID) != 0) + if (chown(unix_addr.sun_path, charon->uid, charon->gid) != 0) { DBG1(DBG_CFG, "changing XML socket permissions failed: %s", strerror(errno)); } diff --git a/src/charon/plugins/stroke/stroke_socket.c b/src/charon/plugins/stroke/stroke_socket.c index 2ae22e447..abc14794a 100644 --- a/src/charon/plugins/stroke/stroke_socket.c +++ b/src/charon/plugins/stroke/stroke_socket.c @@ -537,7 +537,7 @@ static bool open_socket(private_stroke_socket_t *this) return FALSE; } umask(old); - if (chown(socket_addr.sun_path, IPSEC_UID, IPSEC_GID) != 0) + if (chown(socket_addr.sun_path, charon->uid, charon->gid) != 0) { DBG1(DBG_CFG, "changing stroke socket permissions failed: %s", strerror(errno)); diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c index b979c40a7..e64dc0ced 100644 --- a/src/libstrongswan/utils/leak_detective.c +++ b/src/libstrongswan/utils/leak_detective.c @@ -249,6 +249,8 @@ char *whitelist[] = { "getprotobynumber", "getservbyport", "getservbyname", + "getpwnam_r", + "getgrnam_r", "register_printf_function", "syslog", "vsyslog", diff --git a/src/pluto/plutomain.c b/src/pluto/plutomain.c index 49638a3d7..f1b31637a 100644 --- a/src/pluto/plutomain.c +++ b/src/pluto/plutomain.c @@ -31,6 +31,8 @@ #include <sys/queue.h> #include <linux/capability.h> #include <sys/prctl.h> +#include <pwd.h> +#include <grp.h> #include <freeswan.h> @@ -617,19 +619,43 @@ main(int argc, char **argv) init_fetch(); /* drop unneeded capabilities and change UID/GID */ +#ifdef _LINUX_CAPABILITY_VERSION_1 + hdr.version = _LINUX_CAPABILITY_VERSION_1; +#else hdr.version = _LINUX_CAPABILITY_VERSION; +#endif hdr.pid = 0; data.inheritable = data.effective = data.permitted = 1<<CAP_NET_ADMIN | 1<<CAP_NET_BIND_SERVICE; prctl(PR_SET_KEEPCAPS, 1); + +#ifdef IPSEC_GROUP + { + struct group group, *grp; + char buf[1024]; -# if IPSEC_GID - setgid(IPSEC_GID); -# endif -# if IPSEC_UID - setuid(IPSEC_UID); -# endif + if (getgrnam_r(IPSEC_GROUP, &group, buf, sizeof(buf), &grp) != 0 || + grp == NULL || setgid(grp->gr_gid) != 0) + { + plog("unable to change daemon group"); + abort(); + } + } +#endif +#ifdef IPSEC_USER + { + struct passwd passwd, *pwp; + char buf[1024]; + + if (getpwnam_r(IPSEC_USER, &passwd, buf, sizeof(buf), &pwp) != 0 || + pwp == NULL || setuid(pwp->pw_uid) != 0) + { + plog("unable to change daemon user"); + abort(); + } + } +#endif if (capset(&hdr, &data)) { plog("unable to drop root privileges"); diff --git a/src/starter/Makefile.am b/src/starter/Makefile.am index e3b7f0d2d..3a8a31390 100644 --- a/src/starter/Makefile.am +++ b/src/starter/Makefile.am @@ -31,14 +31,14 @@ defs.o: $(PLUTODIR)/defs.c $(PLUTODIR)/defs.h $(COMPILE) -c -o $@ $< install-exec-local : - test -e "$(DESTDIR)${sysconfdir}/ipsec.d" || $(MKDIR_P) "$(DESTDIR)$(sysconfdir)/ipsec.d" - test -e "$(DESTDIR)${sysconfdir}/ipsec.d/cacerts" || $(MKDIR_P) "$(DESTDIR)$(sysconfdir)/ipsec.d/cacerts" - test -e "$(DESTDIR)${sysconfdir}/ipsec.d/ocspcerts" || $(MKDIR_P) "$(DESTDIR)$(sysconfdir)/ipsec.d/ocspcerts" - test -e "$(DESTDIR)${sysconfdir}/ipsec.d/certs" || $(MKDIR_P) "$(DESTDIR)$(sysconfdir)/ipsec.d/certs" - test -e "$(DESTDIR)${sysconfdir}/ipsec.d/acerts" || $(MKDIR_P) "$(DESTDIR)$(sysconfdir)/ipsec.d/acerts" - test -e "$(DESTDIR)${sysconfdir}/ipsec.d/aacerts" || $(MKDIR_P) "$(DESTDIR)$(sysconfdir)/ipsec.d/aacerts" - test -e "$(DESTDIR)${sysconfdir}/ipsec.d/crls" || $(MKDIR_P) "$(DESTDIR)$(sysconfdir)/ipsec.d/crls" - test -e "$(DESTDIR)${sysconfdir}/ipsec.d/reqs" || $(MKDIR_P) "$(DESTDIR)$(sysconfdir)/ipsec.d/reqs" - test -e "$(DESTDIR)${sysconfdir}/ipsec.d/private" || $(MKDIR_P) -m 700 "$(DESTDIR)$(sysconfdir)/ipsec.d/private" - test -e "$(DESTDIR)$(sysconfdir)/ipsec.conf" || $(INSTALL) -m 644 ipsec.conf $(DESTDIR)$(sysconfdir)/ipsec.conf + test -e "$(DESTDIR)${sysconfdir}/ipsec.d" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d" + test -e "$(DESTDIR)${sysconfdir}/ipsec.d/cacerts" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d/cacerts" + test -e "$(DESTDIR)${sysconfdir}/ipsec.d/ocspcerts" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d/ocspcerts" + test -e "$(DESTDIR)${sysconfdir}/ipsec.d/certs" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d/certs" + test -e "$(DESTDIR)${sysconfdir}/ipsec.d/acerts" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d/acerts" + test -e "$(DESTDIR)${sysconfdir}/ipsec.d/aacerts" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d/aacerts" + test -e "$(DESTDIR)${sysconfdir}/ipsec.d/crls" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d/crls" + test -e "$(DESTDIR)${sysconfdir}/ipsec.d/reqs" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d "$(DESTDIR)$(sysconfdir)/ipsec.d/reqs" + test -e "$(DESTDIR)${sysconfdir}/ipsec.d/private" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -d -m 750 "$(DESTDIR)$(sysconfdir)/ipsec.d/private" + test -e "$(DESTDIR)$(sysconfdir)/ipsec.conf" || $(INSTALL) -o ${ipsecuser} -g ${ipsecgroup} -m 644 ipsec.conf $(DESTDIR)$(sysconfdir)/ipsec.conf diff --git a/src/starter/invokecharon.c b/src/starter/invokecharon.c index 477be1faa..ade71fc56 100644 --- a/src/starter/invokecharon.c +++ b/src/starter/invokecharon.c @@ -103,8 +103,8 @@ starter_stop_charon (void) int starter_start_charon (starter_config_t *cfg, bool debug) { - int pid, i; struct stat stb; + int pid, i; char buffer[BUF_LEN]; int argc = 1; char *arg[] = { @@ -159,34 +159,6 @@ starter_start_charon (starter_config_t *cfg, bool debug) unlink(CHARON_CTL_FILE); _stop_requested = 0; - /* if ipsec.secrets file is missing then generate RSA default key pair */ - if (stat(SECRETS_FILE, &stb) != 0) - { - mode_t oldmask; - FILE *f; - - plog("no %s file, generating RSA key", SECRETS_FILE); - seteuid(IPSEC_UID); - setegid(IPSEC_GID); - system("ipsec scepclient --out pkcs1 --out cert-self --quiet"); - seteuid(0); - setegid(0); - - /* ipsec.secrets is root readable only */ - oldmask = umask(0066); - - f = fopen(SECRETS_FILE, "w"); - if (f) - { - fprintf(f, "# /etc/ipsec.secrets - strongSwan IPsec secrets file\n"); - fprintf(f, "\n"); - fprintf(f, ": RSA myKey.der\n"); - fclose(f); - } - chown(SECRETS_FILE, IPSEC_UID, IPSEC_GID); - umask(oldmask); - } - pid = fork(); switch (pid) { diff --git a/src/starter/invokepluto.c b/src/starter/invokepluto.c index b3a8749f4..c2b9c737e 100644 --- a/src/starter/invokepluto.c +++ b/src/starter/invokepluto.c @@ -106,8 +106,8 @@ starter_stop_pluto (void) int starter_start_pluto (starter_config_t *cfg, bool debug) { - int i; struct stat stb; + int i; pid_t pid; char **l; int argc = 2; @@ -218,34 +218,6 @@ starter_start_pluto (starter_config_t *cfg, bool debug) if (cfg->setup.prepluto) system(cfg->setup.prepluto); - /* if ipsec.secrets file is missing then generate RSA default key pair */ - if (stat(SECRETS_FILE, &stb) != 0) - { - mode_t oldmask; - FILE *f; - - plog("no %s file, generating RSA key", SECRETS_FILE); - seteuid(IPSEC_UID); - setegid(IPSEC_GID); - system("ipsec scepclient --out pkcs1 --out cert-self --quiet"); - seteuid(0); - setegid(0); - - /* ipsec.secrets is root readable only */ - oldmask = umask(0066); - - f = fopen(SECRETS_FILE, "w"); - if (f) - { - fprintf(f, "# /etc/ipsec.secrets - strongSwan IPsec secrets file\n"); - fprintf(f, "\n"); - fprintf(f, ": RSA myKey.der\n"); - fclose(f); - } - chown(SECRETS_FILE, IPSEC_UID, IPSEC_GID); - umask(oldmask); - } - pid = fork(); switch (pid) { diff --git a/src/starter/starter.c b/src/starter/starter.c index c92b2bc59..ff042e246 100644 --- a/src/starter/starter.c +++ b/src/starter/starter.c @@ -26,6 +26,8 @@ #include <string.h> #include <errno.h> #include <fcntl.h> +#include <pwd.h> +#include <grp.h> #include <freeswan.h> @@ -139,6 +141,64 @@ fsig(int signal) } } +static void generate_selfcert() +{ + struct stat stb; + + /* if ipsec.secrets file is missing then generate RSA default key pair */ + if (stat(SECRETS_FILE, &stb) != 0) + { + mode_t oldmask; + FILE *f; + uid_t uid = 0; + gid_t gid = 0; + +#ifdef IPSEC_GROUP + { + char buf[1024]; + struct group group, *grp; + + if (getgrnam_r(IPSEC_GROUP, &group, buf, sizeof(buf), &grp) == 0 && + grp) + { + gid = grp->gr_gid; + } + } +#endif +#ifdef IPSEC_USER + { + char buf[1024]; + struct passwd passwd, *pwp; + + if (getpwnam_r(IPSEC_USER, &passwd, buf, sizeof(buf), &pwp) == 0 && + pwp) + { + uid = pwp->pw_uid; + } + } +#endif + setegid(gid); + seteuid(uid); + system("ipsec scepclient --out pkcs1 --out cert-self --quiet"); + seteuid(0); + setegid(0); + + /* ipsec.secrets is root readable only */ + oldmask = umask(0066); + + f = fopen(SECRETS_FILE, "w"); + if (f) + { + fprintf(f, "# /etc/ipsec.secrets - strongSwan IPsec secrets file\n"); + fprintf(f, "\n"); + fprintf(f, ": RSA myKey.der\n"); + fclose(f); + } + chown(SECRETS_FILE, uid, gid); + umask(oldmask); + } +} + static void usage(char *name) { @@ -274,6 +334,8 @@ int main (int argc, char **argv) plog("starter is already running (%s exists) -- no fork done", STARTER_PID_FILE); exit(LSB_RC_SUCCESS); } + + generate_selfcert(); /* fork if we're not debugging stuff */ if (!no_fork) |