From fa62fe2a40774807990325cf4c1fb00c9461f01f Mon Sep 17 00:00:00 2001 From: Tollef Fog Heen Date: Mon, 19 Oct 2009 16:20:24 +0200 Subject: [PATCH] Make this into a real daemon Misc fixes to make it setuid/setgid properly, add some rudimentary help, parsing of a config file and such --- src/main.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 144 insertions(+), 11 deletions(-) diff --git a/src/main.c b/src/main.c index 679d487..d21c60f 100644 --- a/src/main.c +++ b/src/main.c @@ -16,9 +16,9 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#define PORT 8000 - #define _GNU_SOURCE + +#include #include #include #include @@ -26,14 +26,18 @@ #include #include #include -#include -#include -#include #include -#include +#include #include #include #include +#include +#include +#include +#include +#include +#include + #include "util.h" #include "config.h" @@ -459,22 +463,126 @@ free_mem: return MHD_YES; } -int main(int UNUSED(argc), char ** UNUSED(argv)) +void print_usage() +{ + printf("yubikeyd [-c conffile] [-V] [-f] [-h]\n"); + printf("\n"); + printf("-c conffile - use configuration file\n"); + printf("-V - print version\n"); + printf("-f - keep in foreground\n"); + printf("-h - this help\n"); + exit(0); +} + +void print_version(void) +{ + printf("yubikeyd %s\n", VERSION); + exit(0); +} + +struct ykc_config { + char *pidfile; + char *user; + int uid; + char *group; + int gid; + char *dbdef; + int port; +}; + +int parse_config(const char *file, struct ykc_config *c) +{ + FILE *f; + char line[4096]; + char *key, *value; + + f = fopen(file, "r"); + + while (fgets(line, sizeof(line), f) != NULL) { + if (line[0] == '#' || line[0] == '\n') + continue; + if ((value = index(line, '\n')) != NULL) { + *value = '\0'; + } + if ((value = index(line, '=')) == NULL) { + /* XXX complain */ + continue; + } + key = line; + *value = '\0'; + value++; + + if (strcmp(key, "pidfile") == 0) { + c->pidfile = strdup(value); + continue; + } + if (strcmp(key, "user") == 0) { + struct passwd *p; + p = getpwnam(value); + c->user = strdup(value); + c->uid = p->pw_uid; + continue; + } + if (strcmp(key, "group") == 0) { + struct group *g; + g = getgrnam(value); + c->group = strdup(value); + c->gid = g->gr_gid; + continue; + } + if (strcmp(key, "dbdef") == 0) { + c->dbdef = strdup(value); + continue; + } + if (strcmp(key, "port") == 0) { + c->port = strtol(value, NULL, 0); + continue; + } + } + return 0; +} + +int main(int argc, char ** argv) { struct MHD_Daemon *d; + int opt; + const char *config; + int foreground = 0; + struct ykc_config conf; + FILE *pidfd; + + while ((opt = getopt(argc, argv, "c:p:vfh")) != -1) { + switch (opt) { + case 'c': + config = optarg; + break; + case 'f': + foreground = 1; + break; + case 'V': + print_version(); + break; + case 'h': + default: + print_usage(); + break; + } + } openlog("yubikeyd", LOG_PID, LOG_AUTHPRIV); syslog(LOG_NOTICE, "yubikeyd version %s starting up", VERSION); - /* XXX connect args should go in config file */ - db_conn = PQconnectdb("dbname=yubikey port=5433"); + /* XXX return value */ + parse_config(config, &conf); + + db_conn = PQconnectdb(conf.dbdef); if (PQstatus(db_conn) != CONNECTION_OK) { syslog(LOG_ERR, "connection to database failed: %s", PQerrorMessage(db_conn)); exit(1); } d = MHD_start_daemon(MHD_USE_DEBUG, - PORT, + conf.port, NULL, /* Access policy handler */ NULL, /* Data to access policy handler */ handle_request, /* default handler for all URIs */ @@ -482,8 +590,34 @@ int main(int UNUSED(argc), char ** UNUSED(argv)) MHD_OPTION_END); if (d == NULL) { syslog(LOG_ERR, "could not start daemon, unsure why\n"); + perror("Error starting yubikeyd"); exit(1); } + + /*XXX return value */ + if (setregid(conf.gid, conf.gid) < 0) { + perror("changing group id"); + exit(1); + } + if (setreuid(conf.uid, conf.uid) < 0) { + perror("changing group id"); + exit(1); + } + + if (!foreground) + daemon(0, 0); + + unlink(conf.pidfile); /* XXX ignore errors? */ + pidfd = fopen(conf.pidfile, "wx"); + if (! pidfd) { + perror("Error opening pid file"); + syslog(LOG_ERR, "could not open pid file: %s\n", + strerror(errno)); + exit(1); + } + fprintf(pidfd, "%d\n", getpid()); + fclose(pidfd); + while (1) { fd_set rs, ws, es; int max_fd = 0; @@ -517,4 +651,3 @@ int main(int UNUSED(argc), char ** UNUSED(argv)) PQfinish(db_conn); return 0; } - -- 2.39.5