51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#define PORT 8000
-
#define _GNU_SOURCE
+
+#include <errno.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
-#include <microhttpd.h>
-#include <libpq-fe.h>
-#include <yubikey.h>
#include <time.h>
-#include <gcrypt.h>
+#include <sys/types.h>
#include <sys/select.h>
#include <arpa/inet.h>
#include <syslog.h>
+#include <pwd.h>
+#include <grp.h>
+#include <microhttpd.h>
+#include <libpq-fe.h>
+#include <yubikey.h>
+#include <gcrypt.h>
+
#include "util.h"
#include "config.h"
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 */
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;
PQfinish(db_conn);
return 0;
}
-