예제 #1
0
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();
    }
}
예제 #2
0
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]);
}