aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsinanmohd <sinan@sinanmohd.com>2024-04-21 15:30:07 +0530
committersinanmohd <sinan@sinanmohd.com>2024-04-21 15:31:16 +0530
commit6f0fb6644fbb9fe2c05f1719e619ce4d0073728d (patch)
tree4a364053068b79c78a50e21989771a5e9ddf5902
parentc58a8abf4403fcdf7c453c75d7fce41cdd14bcdf (diff)
npassd/session: free session when owner service disconnects from the bus
-rw-r--r--include/npassd/session.h5
-rw-r--r--src/npassd/service.c4
-rw-r--r--src/npassd/session.c64
3 files changed, 63 insertions, 10 deletions
diff --git a/include/npassd/session.h b/include/npassd/session.h
index 6763c6a..a3aa705 100644
--- a/include/npassd/session.h
+++ b/include/npassd/session.h
@@ -4,11 +4,13 @@
#include "npassd/common.h"
#define SESSION_IFACE "org.freedesktop.Secret.Session"
+#define MAX_OWNER_LEN 64
/* reusable slots */
struct session {
bool isactive;
sd_bus_slot *slot;
+ char owner[MAX_OWNER_LEN];
/* +32 for snprintf("/session/%d") */
char path[sizeof(DBUS_OBJECT_PATH) + 32];
};
@@ -16,4 +18,5 @@ struct session {
void session_init(struct session *s, size_t n);
int session_slot_available(struct session *s, size_t n);
int session_free(struct session *s);
-int session_new(sd_bus *bus, struct session *s, unsigned slot_no);
+int session_new(sd_bus *bus, struct session *session, unsigned session_no,
+ const char *owner);
diff --git a/src/npassd/service.c b/src/npassd/service.c
index 60e458b..c93073a 100644
--- a/src/npassd/service.c
+++ b/src/npassd/service.c
@@ -23,6 +23,7 @@ static int handle_open_session(sd_bus_message *msg, void *data,
{
struct service *service = data;
int ret, session_slot_no;
+ const char *sender;
char *algo;
ret = sd_bus_message_read(msg, "s", &algo);
@@ -43,8 +44,9 @@ static int handle_open_session(sd_bus_message *msg, void *data,
return ret;
}
+ sender = sd_bus_message_get_sender(msg);
ret = session_new(service->bus, &service->session[session_slot_no],
- session_slot_no);
+ session_slot_no, sender);
if (ret < 0)
return ret;
diff --git a/src/npassd/session.c b/src/npassd/session.c
index e674bb7..7190aec 100644
--- a/src/npassd/session.c
+++ b/src/npassd/session.c
@@ -11,6 +11,9 @@
static int handle_close(__attribute__((unused)) sd_bus_message *msg, void *data,
__attribute__((unused)) sd_bus_error *ret_error);
+static int handle_nameownerchanged(sd_bus_message *msg, void *data,
+ __attribute__((unused))
+ sd_bus_error *ret_error);
static const sd_bus_vtable session_vtable[] = {
SD_BUS_VTABLE_START(0),
@@ -19,6 +22,28 @@ static const sd_bus_vtable session_vtable[] = {
SD_BUS_VTABLE_END,
};
+static int handle_nameownerchanged(sd_bus_message *msg, void *data,
+ __attribute__((unused))
+ sd_bus_error *ret_error)
+{
+ struct session *session = data;
+ const char *name;
+ int ret;
+
+ ret = sd_bus_message_read(msg, "ss", NULL, &name);
+ if (ret < 0) {
+ print_err("%s", strerror(-ret));
+ return ret;
+ }
+
+ ret = strcmp(session->owner, name);
+ if (ret)
+ return 0;
+
+ session_free(session);
+ return 0;
+}
+
static int handle_close(__attribute__((unused)) sd_bus_message *msg, void *data,
__attribute__((unused)) sd_bus_error *ret_error)
{
@@ -28,7 +53,7 @@ static int handle_close(__attribute__((unused)) sd_bus_message *msg, void *data,
if (ret < 0)
print_err("Failed to free session: %s", strerror(-ret));
- return ret;
+ return sd_bus_reply_method_return(msg, "");
}
int session_slot_available(struct session *s, size_t n)
@@ -47,25 +72,48 @@ int session_slot_available(struct session *s, size_t n)
return -ENOMEM;
}
-int session_new(sd_bus *bus, struct session *session, unsigned session_no)
+int session_new(sd_bus *bus, struct session *session, unsigned session_no,
+ const char *owner)
{
int ret;
- snprintf(session->path, sizeof(session->path),
- DBUS_OBJECT_PATH "/session/%d", session_no);
+ ret = snprintf(session->path, sizeof(session->path),
+ DBUS_OBJECT_PATH "/session/%d", session_no);
+ if (ret < 0 || (size_t)ret > sizeof(session->path)) {
+ print_err("%s", "Failed to create session path");
+ return -ENOMEM;
+ }
+
+ ret = snprintf(session->owner, sizeof(session->owner), "%s", owner);
+ if (ret < 0 || (size_t)ret > sizeof(session->owner)) {
+ print_err("%s", "Failed to set session owner");
+ return -ENOMEM;
+ }
+
ret = sd_bus_add_object_vtable(bus, &session->slot, session->path,
SESSION_IFACE, session_vtable, session);
- if (ret < 0)
+ if (ret < 0) {
print_err("Failed to create session: %s", strerror(-ret));
- else
- session->isactive = true;
+ return ret;
+ }
+ session->isactive = true;
+
+ ret = sd_bus_match_signal(bus, NULL, "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus", "NameOwnerChanged",
+ handle_nameownerchanged, session);
+ if (ret < 0) {
+ session_free(session);
+ print_err("%s", strerror(-ret));
+ return ret;
+ }
return ret;
}
int session_free(struct session *s)
{
- if (!s->isactive)
+ if (s->isactive == false)
return -EINVAL;
s->isactive = false;