[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Pki-devel] [PATCH] patch to nuxwdog to add systemd support



The attached patch adds systemd support.  When the STARTED_BY_SYSTEMD
environment variable is set, nuxwdog will call "systemd-ask-password" to
get the password from systemd.

To get this to work, we needed to temporarily disable the signal handler
used to handle SIGCHLD so as not to interfere with the handling of the
response from systemd-ask-password.  Also fixed an error condition.

Please review,
Ade
 
Index: src/com/redhat/nuxwdog/watchdog.cpp
===================================================================
--- src/com/redhat/nuxwdog/watchdog.cpp	(revision 86)
+++ src/com/redhat/nuxwdog/watchdog.cpp	(working copy)
@@ -570,7 +570,9 @@
 				    watchdog_error(errstr);
 				    // _watchdog_death = 1; ???
 				}
-				rv = watchdog_pwd_save(prompt, serial, pwd_result);
+                                if (pwd_result != NULL) {
+				    rv = watchdog_pwd_save(prompt, serial, pwd_result);
+                                }
 				// check error code??
 			    }	// otherwise can fall through without prompting
 			}
Index: src/com/redhat/nuxwdog/wdpwd.cpp
===================================================================
--- src/com/redhat/nuxwdog/wdpwd.cpp	(revision 87)
+++ src/com/redhat/nuxwdog/wdpwd.cpp	(working copy)
@@ -20,7 +20,9 @@
 
 #include <stdlib.h>
 #include <unistd.h>
+#include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/wait.h>
 #include <stdio.h>
 #include <string.h>
 #include <termios.h>
@@ -27,6 +29,7 @@
 #include <errno.h>
 #include "config.h"
 #include "wdlog.h"
+#include "wdsignals.h"
 
 #ifdef USE_KEYRING
 #include <sys/types.h>
@@ -40,10 +43,10 @@
 static void echoOff(int fd)
 {
     if (isatty(fd)) {
-	struct termios tio;
-	tcgetattr(fd, &tio);
-	tio.c_lflag &= ~ECHO;
-	tcsetattr(fd, TCSAFLUSH, &tio);
+        struct termios tio;
+        tcgetattr(fd, &tio);
+        tio.c_lflag &= ~ECHO;
+        tcsetattr(fd, TCSAFLUSH, &tio);
     }
 }
 
@@ -50,10 +53,10 @@
 static void echoOn(int fd)
 {
     if (isatty(fd)) {
-	struct termios tio;
-	tcgetattr(fd, &tio);
-	tio.c_lflag |= ECHO;
-	tcsetattr(fd, TCSAFLUSH, &tio);
+        struct termios tio;
+        tcgetattr(fd, &tio);
+        tio.c_lflag |= ECHO;
+        tcsetattr(fd, TCSAFLUSH, &tio);
     }
 }
 
@@ -120,7 +123,7 @@
 watchdog_pwd_decrypt(pwdenc_t *pwdcrypt)
 {
     if (!pwdcrypt->ptr) {
-	return NULL;
+    	return NULL;
     }
     {
         char *buf;
@@ -331,6 +334,52 @@
 }
 #endif
 
+/*
+ * is systemd running
+ */
+bool
+check_systemd_running ()
+{
+  struct stat a, b;
+
+  /* We simply test whether the systemd cgroup hierarchy is
+   * mounted */
+
+  return (lstat("/sys/fs/cgroup", &a) == 0)
+     && (lstat("/sys/fs/cgroup/systemd", &b) == 0)
+     && (a.st_dev != b.st_dev);
+
+}
+
+static bool
+watchdog_get_passwd_systemd(const char *prompt, char *input, const int capacity)
+{
+    char *cmd, *ret;
+    FILE *ask_pass_fp = NULL;
+    bool retval = false;
+
+    /* temporarily disable SIGCHLD handler */
+    disable_sigchld_for_one_signal();
+
+    cmd = ret = NULL;
+    if (asprintf(&cmd, "systemd-ask-password \"%s\"", prompt) >= 0) {
+        ask_pass_fp = popen (cmd, "re");
+        free (cmd);
+    }
+
+    if (ask_pass_fp) {
+        ret = fgets(input, capacity, ask_pass_fp);
+        pclose(ask_pass_fp);
+    }
+
+    if (ret) {
+        int len = strlen(input);
+        if (input[len - 1] == '\n') input[len - 1] = '\0';
+        return true;
+    }
+    return false;
+}
+
 int
 watchdog_pwd_prompt(const char *prompt, int serial, char **pwdvalue)
 {
@@ -340,6 +389,25 @@
     int isTTY = isatty(infd);
     int plen;
 
+    char *started_by_systemd = getenv("STARTED_BY_SYSTEMD");
+
+    if (started_by_systemd) {
+        if (!check_systemd_running()) {
+            fprintf(stderr,
+                "STARTED_BY_SYSTEMD set indicating that nuxwdog has been started by systemd, but "
+                "systemd is not running.");
+            return -1;
+        }
+
+        char pvalue[512];
+        pvalue[0] = '\0'; 
+        if (watchdog_get_passwd_systemd(prompt, pvalue, 256)) {
+            *pwdvalue = strdup(pvalue);
+            return 0;
+        }
+        return -1;
+    }
+
     /* Turn off buffering to avoid leaving password in I/O buffer */
     setbuf(stdin, NULL);
 
@@ -400,4 +468,3 @@
 
     return 0;
 }
-
Index: src/com/redhat/nuxwdog/wdsignals.cpp
===================================================================
--- src/com/redhat/nuxwdog/wdsignals.cpp	(revision 85)
+++ src/com/redhat/nuxwdog/wdsignals.cpp	(working copy)
@@ -37,6 +37,8 @@
 
 static int watchdog_pending_signal = 0;
 
+static struct sigaction prev_sigchld_handler;
+
 static void
 sig_term(int sig)
 {
@@ -217,3 +219,25 @@
         sigsuspend(&holdset);
     }
 }
+
+static void
+temp_sig_chld(int sig)
+{
+    sigaction(SIGCHLD, &prev_sigchld_handler, NULL);
+}
+
+void
+disable_sigchld_for_one_signal()
+{
+    struct sigaction sa;
+    sa.sa_handler = temp_sig_chld;
+    sigemptyset(&sa.sa_mask);
+    sigaddset(&sa.sa_mask, SIGCHLD);
+#ifdef SA_NOCLDSTOP
+    sa.sa_flags = SA_NOCLDSTOP;
+#else
+    sa.sa_flags = 0;
+#endif /* SA_NOCLDSTOP */
+    sigaction(SIGCHLD, &sa, &prev_sigchld_handler);
+}
+
Index: src/com/redhat/nuxwdog/wdsignals.h
===================================================================
--- src/com/redhat/nuxwdog/wdsignals.h	(revision 85)
+++ src/com/redhat/nuxwdog/wdsignals.h	(working copy)
@@ -32,5 +32,6 @@
 void watchdog_create_signal_handlers(void);
 void watchdog_delete_signal_handlers(void);
 void watchdog_wait_signal(void);
+void disable_sigchld_for_one_signal(void);
 
 #endif /* _WDSIGNAL_H_ */

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]