aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Willi <martin@strongswan.org>2008-05-08 10:58:04 +0000
committerMartin Willi <martin@strongswan.org>2008-05-08 10:58:04 +0000
commit25b12c696bf52b7ddb228458bba656d25a6222d4 (patch)
tree6c9fa89a5fc25ac3923415901aa94a2448295769
parent97e820f5fdbd7987003cb086a02f7ee2f2a6ccee (diff)
downloadstrongswan-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.in24
-rw-r--r--src/Makefile.am4
-rw-r--r--src/charon/daemon.c63
-rw-r--r--src/charon/daemon.h10
-rw-r--r--src/charon/plugins/smp/smp.c2
-rw-r--r--src/charon/plugins/stroke/stroke_socket.c2
-rw-r--r--src/libstrongswan/utils/leak_detective.c2
-rw-r--r--src/pluto/plutomain.c38
-rw-r--r--src/starter/Makefile.am20
-rw-r--r--src/starter/invokecharon.c30
-rw-r--r--src/starter/invokepluto.c30
-rw-r--r--src/starter/starter.c62
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)