void KWalletExecuter::execute() { //Preparing sockets, we will share them with kwalletd int toWalletPipe[2] = { -1, -1}; if (pipe(toWalletPipe) < 0) { qFatal("Couldn't craete pipes"); } int envSocket; if ((envSocket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { qFatal("Couldn't create socket"); } QByteArray sock = KStandardDirs::locateLocal("socket", QLatin1String("test.socket")).toLocal8Bit(); struct sockaddr_un local; local.sun_family = AF_UNIX; strcpy(local.sun_path, sock.constData()); unlink(local.sun_path);//Just in case it exists from a previous login int len; len = strlen(local.sun_path) + sizeof(local.sun_family); if (bind(envSocket, (struct sockaddr *)&local, len) == -1) { qFatal("Couldn't bind the socket"); } if (listen(envSocket, 5) == -1) { qFatal("Couldn't listen into the socket"); } qputenv("PAM_KWALLET_LOGIN", "1"); pid_t pid; switch (pid = fork ()) { case -1: qFatal("Couldn't fork to execv kwalletd"); //Child fork, will contain kwalletd case 0: execute_kwallet(toWalletPipe, envSocket); /* Should never be reached */ break; //Parent default: break; }; close(toWalletPipe[0]);//Read end of the pipe, we will only use the write QByteArray hash = QByteArray::fromHex("1f1e7736894243657ef4a5274211b9a62703494c286e1699418a36e7ecf31d37319644db63d9fb26eb57cd9b7fea3e88bc18312480ba54f4"); write(toWalletPipe[1], hash.constData(), 56); QLocalSocket *socket = new QLocalSocket(this); socket->connectToServer(sock); //No need to send any environment vars, the env is already ok socket->close(); if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.kwalletd")) { qDebug() << "AAAAAAAA"; QEventLoop loop; QDBusServiceWatcher *watcher = new QDBusServiceWatcher("org.kde.kwalletd", QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForRegistration); connect(watcher, SIGNAL(serviceRegistered(QString)), &loop, SLOT(quit())); loop.exec(); } }
static void start_kwallet(pam_handle_t *pamh, struct passwd *userInfo, const char *kwalletKey) { //Just in case we get broken pipe, do not break the pam process.. struct sigaction sigPipe, oldSigPipe; memset (&sigPipe, 0, sizeof (sigPipe)); memset (&oldSigPipe, 0, sizeof (oldSigPipe)); sigPipe.sa_handler = SIG_IGN; sigaction (SIGPIPE, &sigPipe, &oldSigPipe); int toWalletPipe[2] = { -1, -1}; if (pipe(toWalletPipe) < 0) { pam_syslog(pamh, LOG_ERR, "pam_kwallet: Couldn't create pipes"); } int envSocket; if ((envSocket = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { pam_syslog(pamh, LOG_ERR, "pam_kwallet: couldn't create socket"); return; } int len = strlen(socketPath) + strlen(userInfo->pw_name) + 9;// 9 = slash+.socket+null char *fullSocket = (char*) malloc(len); sprintf(fullSocket, "%s/%s%s", socketPath, userInfo->pw_name, ".socket"); int result = set_env(pamh, "PAM_KWALLET_LOGIN", fullSocket); if (result != PAM_SUCCESS) { pam_syslog(pamh, LOG_ERR, "pam_kwallet: Impossible to set PAM_KWALLET_LOGIN env, %s", pam_strerror(pamh, result)); return; } struct sockaddr_un local; local.sun_family = AF_UNIX; strcpy(local.sun_path, fullSocket); unlink(local.sun_path);//Just in case it exists from a previous login pam_syslog(pamh, LOG_INFO, "pam-kwallet: final socket path: %s", fullSocket); len = strlen(local.sun_path) + sizeof(local.sun_family); if (bind(envSocket, (struct sockaddr *)&local, len) == -1) { pam_syslog(pamh, LOG_INFO, "kwalletd: Couldn't bind to local file\n"); return; } if (listen(envSocket, 5) == -1) { pam_syslog(pamh, LOG_INFO, "kwalletd: Couldn't listen in socket\n"); return; } if (chown(fullSocket, userInfo->pw_uid, userInfo->pw_gid) == -1) { pam_syslog(pamh, LOG_INFO, "Couldn't change ownership of the socket"); return; } pid_t pid; switch (pid = fork ()) { case -1: pam_syslog(pamh, LOG_ERR, "pam_kwallet: Couldn't fork to execv kwalletd"); return; //Child fork, will contain kwalletd case 0: execute_kwallet(pamh, userInfo, toWalletPipe, envSocket); /* Should never be reached */ break; //Parent default: break; }; close(toWalletPipe[0]);//Read end of the pipe, we will only use the write if (better_write(toWalletPipe[1], kwalletKey, KWALLET_PAM_KEYSIZE) < 0) { pam_syslog(pamh, LOG_ERR, "pam_kwallet: Impossible to write walletKey to walletPipe"); return; } close(toWalletPipe[1]); }