aboutsummaryrefslogtreecommitdiff
path: root/src/npassd/service.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/npassd/service.c')
-rw-r--r--src/npassd/service.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/npassd/service.c b/src/npassd/service.c
new file mode 100644
index 0000000..5628e45
--- /dev/null
+++ b/src/npassd/service.c
@@ -0,0 +1,77 @@
+#include <errno.h>
+#include <stdio.h>
+#include <systemd/sd-bus.h>
+
+#include "npassd/common.h"
+#include "npassd/service.h"
+#include "util.h"
+
+#define SERVICE_IFACE "org.freedesktop.Secret.Service"
+
+static int handle_open_session(sd_bus_message *msg, void *data,
+ sd_bus_error *ret_error);
+
+static const sd_bus_vtable service_vtable[] = {
+ SD_BUS_VTABLE_START(0),
+ SD_BUS_METHOD("OpenSession", "sv", "vo", handle_open_session,
+ SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_VTABLE_END,
+};
+
+static int handle_open_session(sd_bus_message *msg, void *data,
+ sd_bus_error *ret_error)
+{
+ struct service *service = data;
+ int ret, session_slot_no;
+ char *algo;
+
+ ret = sd_bus_message_read(msg, "s", &algo);
+ if (ret < 0)
+ return ret;
+
+ ret = strcmp(algo, "plain");
+ if (ret) {
+ sd_bus_error_set_const(ret_error, SD_BUS_ERROR_NOT_SUPPORTED,
+ "Unsupported encryption algorithm");
+ return -ENOTSUP;
+ }
+
+ session_slot_no = session_slot_available(service->session, MAX_SESSION);
+ if (session_slot_no < 0) {
+ print_err("No free slot available: %s",
+ strerror(-session_slot_no));
+ return ret;
+ }
+
+ ret = session_new(service->bus, &service->session[session_slot_no],
+ session_slot_no);
+ if (ret < 0)
+ return ret;
+
+ return sd_bus_reply_method_return(
+ msg, "vs", "s", "", service->session[session_slot_no].path);
+}
+
+void service_free(struct service *service)
+{
+ for (int i = 0; i < MAX_SESSION; i++)
+ session_free(&service->session[i]);
+
+ sd_bus_slot_unref(service->slot);
+}
+
+int service_init(sd_bus *bus, struct service *service)
+{
+ int ret;
+
+ service->bus = bus;
+ session_init(service->session, MAX_SESSION);
+
+ ret = sd_bus_add_object_vtable(service->bus, &service->slot,
+ DBUS_OBJECT_PATH, SERVICE_IFACE,
+ service_vtable, service);
+ if (ret < 0)
+ print_err("Failed to connect to bus: %s", strerror(-ret));
+
+ return ret;
+}