summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2021-04-30 11:28:05 +0200
committerSimon Rettberg2021-04-30 11:28:05 +0200
commit21e7ad34ea33ceb37b7877a0782e33775c295054 (patch)
tree04b6337482f2eaf3acd4fcc4d579110b124b22a2
parentconst (diff)
downloadprintergui-21e7ad34ea33ceb37b7877a0782e33775c295054.tar.gz
printergui-21e7ad34ea33ceb37b7877a0782e33775c295054.tar.xz
printergui-21e7ad34ea33ceb37b7877a0782e33775c295054.zip
Try to get password from pwdaemonv29r2v29r1v28r1
-rw-r--r--src/pwgui/main.cpp74
1 files changed, 73 insertions, 1 deletions
diff --git a/src/pwgui/main.cpp b/src/pwgui/main.cpp
index 2c8123b..264f0df 100644
--- a/src/pwgui/main.cpp
+++ b/src/pwgui/main.cpp
@@ -19,6 +19,8 @@
#include <pwd.h>
#include <grp.h>
#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
#include "../x11workaround.h"
@@ -60,7 +62,8 @@ static char *helper_urlencode(char *s, char *enc);
static int helper_cupsError(const int code);
static void helper_messageBox(const char *caption, const char *text, const bool error = false);
-static void demo();
+static void query_pwdaemon(int pfd, char *creds);
+
/*
* Note to the next HiWi who wants to refactor this to use something like boost::program_options:
* Don't do it unless you are certain that you understood the behaviour described here:
@@ -203,6 +206,7 @@ int main(int argc, char *argv[])
// Seems we need the dialog
int status;
char *pass = NULL;
+ int numRun = 0;
do {
@@ -219,6 +223,11 @@ int main(int argc, char *argv[])
close(pfd[0]);
helper_dropprivs();
helper_copyenv(NULL);
+ // .... but first, try pwdaemon
+ if (numRun == 0) {
+ query_pwdaemon(pfd[1], creds);
+ // if the function returned, nothing was queried and we should show the gui
+ }
QApplication a(argc, argv);
Backdrop *bg = new Backdrop;
bg->show();
@@ -232,6 +241,7 @@ int main(int argc, char *argv[])
exit(a.exec());
return CUPS_BACKEND_CANCEL;
}
+ numRun++;
// Main (Parent)
close(pfd[1]);
// Read from pipe
@@ -670,3 +680,65 @@ static void helper_messageBox(const char *caption, const char *text, const bool
// Wait for child to die
waitpid(pid, NULL, 0);
}
+
+static void query_pwdaemon(int pfd, char *creds)
+{
+ char homedir[NAMELEN];
+ char daemon_data[NAMELEN];
+ char *e = getenv("HOME");
+ if (e == NULL) {
+ struct passwd *p = getpwuid(getuid());
+ if (p != nullptr) {
+ e = p->pw_dir;
+ }
+ }
+ if (e == nullptr) {
+ return;
+ }
+ snprintf(homedir, NAMELEN, "%s/.pwsocket", e);
+ // KONNEKT
+ struct sockaddr_un remote;
+ struct timeval tv;
+ int fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ if (fd == -1) {
+ perror("Cannot create unix socket");
+ return;
+ }
+ memset(&remote, 0, sizeof(remote));
+ remote.sun_family = AF_UNIX;
+ strncpy(remote.sun_path, homedir, sizeof(remote.sun_path)-1);
+ tv.tv_sec = 2;
+ tv.tv_usec = 0;
+ setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
+ setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
+ if (connect(fd, (struct sockaddr*)&remote, sizeof(remote)) == -1) {
+ perror("Cannot connect to pw daemon");
+ close(fd);
+ return;
+ }
+ write(fd, "PW", 2);
+ ssize_t ret = read(fd, daemon_data, NAMELEN - 5);
+ if (ret == -1) {
+ perror("Cannot read reply from pwdaemon");
+ close(fd);
+ return;
+ }
+ if (ret == 0) {
+ fprintf(stderr, "pwdaemon is configured to not reveal pw\n");
+ close(fd);
+ return;
+ }
+ daemon_data[ret] = '\0';
+ char *ptr = daemon_data;
+ int i = strlen(creds);
+ while (++i < NAMELEN - 5) {
+ creds[i] = *ptr++;
+ if (creds[i] == '\0')
+ break;
+ }
+ creds[NAMELEN-1] = '\0';
+ close(fd);
+ ::write(pfd, creds, qMin(i+1, NAMELEN));
+ ::close(pfd);
+ exit(0);
+}