File indexing completed on 2024-06-23 05:14:14

0001 /* -*- mode: c++; c-basic-offset:4 -*-
0002     uiserver/uiserver_unix.cpp
0003 
0004     This file is part of Kleopatra, the KDE keymanager
0005     SPDX-FileCopyrightText: 2007 Klarälvdalens Datakonsult AB
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include <config-kleopatra.h>
0011 
0012 #include "uiserver_p.h"
0013 
0014 #include <Libkleo/GnuPG>
0015 
0016 #include <KLocalizedString>
0017 
0018 #include <stdexcept>
0019 
0020 #include <cerrno>
0021 #include <cstdio>
0022 #include <cstring>
0023 #include <sys/socket.h>
0024 #include <sys/types.h>
0025 #include <sys/un.h>
0026 
0027 using namespace Kleo;
0028 
0029 QString UiServer::Private::systemErrorString()
0030 {
0031     return QString::fromLocal8Bit(strerror(errno));
0032 }
0033 
0034 void UiServer::Private::doMakeListeningSocket(const QByteArray &encodedFileName)
0035 {
0036     // Create a Unix Domain Socket:
0037     const assuan_fd_t sock = assuan_sock_new(AF_UNIX, SOCK_STREAM, 0);
0038     if (sock == ASSUAN_INVALID_FD) {
0039         throw_<std::runtime_error>(i18n("Could not create socket: %1", systemErrorString()));
0040     }
0041 
0042     try {
0043         // Bind
0044         struct sockaddr_un sa;
0045         std::memset(&sa, 0, sizeof(sa));
0046         sa.sun_family = AF_UNIX;
0047         std::strncpy(sa.sun_path, encodedFileName.constData(), sizeof(sa.sun_path) - 1);
0048         if (assuan_sock_bind(sock, (struct sockaddr *)&sa, sizeof(sa)))
0049             throw_<std::runtime_error>(i18n("Could not bind to socket: %1", systemErrorString()));
0050 
0051         // ### TODO: permissions?
0052 
0053         if (assuan_sock_get_nonce((struct sockaddr *)&sa, sizeof(sa), &nonce)) {
0054             throw_<std::runtime_error>(i18n("Could not get socket nonce: %1", systemErrorString()));
0055         }
0056 
0057         // Listen
0058         if (::listen(sock, SOMAXCONN)) {
0059             throw_<std::runtime_error>(i18n("Could not listen to socket: %1", systemErrorString()));
0060         }
0061 
0062         if (!setSocketDescriptor(sock)) {
0063             throw_<std::runtime_error>(i18n("Could not pass socket to Qt: %1. This should not happen, please report this bug.", errorString()));
0064         }
0065 
0066     } catch (...) {
0067         ::close(sock);
0068         throw;
0069     }
0070 }