Blob Blame History Raw
Index: src/com/redhat/nuxwdog/wdsignals.h
===================================================================
--- src/com/redhat/nuxwdog/wdsignals.h	(revision 87)
+++ src/com/redhat/nuxwdog/wdsignals.h	(revision 89)
@@ -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_ */
Index: src/com/redhat/nuxwdog/watchdog.cpp
===================================================================
--- src/com/redhat/nuxwdog/watchdog.cpp	(revision 87)
+++ src/com/redhat/nuxwdog/watchdog.cpp	(revision 89)
@@ -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	(revision 89)
@@ -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[256];
+        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 87)
+++ src/com/redhat/nuxwdog/wdsignals.cpp	(revision 89)
@@ -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);
+}
+