Hi devs,
I'm thinking about ways to implement SSSD KCM notification that something has changed (i.e. user called kinit/kdestroy) [1]. The main use case is to notify Gnome Online Accounts (which is a daemon running under logged-in user) when something has changed and it is already a D-Bus service.
The basic idea is that we would use D-Bus signals that would be emitted by SSSD KCM responder (sssd_kcm process). Signals are broadcasted messages that are delivered to client that chose to listen to them.
The problem is that we 1) can't connect to specific user's session bus because KCM runs as root/sssd and connecting to other user's bus is not allowed 2) can't specify which user is allowed to get the signal 3) therefore we can't send the signal only to specific user
So the solution is that KCM connects to system bus and sends org.sssd.kcm.Changed(uid) signal where uid is uid of the user which ccache has changed so the receiver can know which user is affected. This signal is broadcasted to everyone who listens to it.
It is perfectly usable, however the question is whether we can broadcast this information (that user A run kinit/kdestroy/other modification of ccache) or it is a security leak that we must avoid and we should seek other solution.
I asked this secalert and they reply that there is no security concern "but":
After looking at this issue, honestly I dont see an attack vector here, but i am afraid something like this could be used with some other security flaw to maybe gain privesc? For example a flaw which is some component which can be triggered only when kinit is run? where precise timing is required.
So in conclusion if there is another "better" solution than it should be preferred. Or in worse case atleast have an option to disable this somehow via some config, so that such situations can be avoided.
I don't think a precise timing is necessary and we can send the signal few miliseconds or a second later. That should eliminate this concern (I asked this, waiting for an answer).
I can think of two more solutions currently:
1) Have client connect to KCM socket and await signal there. This however would mean that connection between client and KCM need to be always established and KCM responder would be running all the time (currently it is only short-lived socket activated process).
2) Create a temporary file in a directory owned by user. User can then setup inotify watch to the file and sssd would write to the file on changes. Since it is in directory owned by user, other users would not be able to setup the watch.
Note that it is possile to setup inotify watch on FILE ccache (keeping distro settings out of the question the default ccache is FILE:/tmp/krb5cc_%{uid} as per krb5.conf manpage) so perhaps we really don't have to care about broadcasting this information.
Thanks, Pavel.
On Thu, 2020-02-20 at 11:18 +0100, Pavel Březina wrote:
Hi devs,
I'm thinking about ways to implement SSSD KCM notification that something has changed (i.e. user called kinit/kdestroy) [1]. The main use case is to notify Gnome Online Accounts (which is a daemon running under logged-in user) when something has changed and it is already a D-Bus service.
The basic idea is that we would use D-Bus signals that would be emitted by SSSD KCM responder (sssd_kcm process). Signals are broadcasted messages that are delivered to client that chose to listen to them.
The problem is that we
- can't connect to specific user's session bus because KCM runs as
root/sssd and connecting to other user's bus is not allowed 2) can't specify which user is allowed to get the signal
Can you explain what this means?
- therefore we can't send the signal only to specific user
Why not? We definitely should be able to know what user is listening on the other side of a bus, so we could simply only send back info related to that same user? Or are we blinded to which user is interacting with us?
So the solution is that KCM connects to system bus and sends org.sssd.kcm.Changed(uid) signal where uid is uid of the user which ccache has changed so the receiver can know which user is affected. This signal is broadcasted to everyone who listens to it.
This means users can monitor each other, sounds bad.
It is perfectly usable, however the question is whether we can broadcast this information (that user A run kinit/kdestroy/other modification of ccache) or it is a security leak that we must avoid and we should seek other solution.
Looks quite bad, why do we need to broadcast to everyone? Isn't there an interface where a specific user can initiate a listening channel and we send back only info related to that user?
I asked this secalert and they reply that there is no security concern "but":
After looking at this issue, honestly I dont see an attack vector here, but i am afraid something like this could be used with some other security flaw to maybe gain privesc? For example a flaw which is some component which can be triggered only when kinit is run? where precise timing is required.
So in conclusion if there is another "better" solution than it should be preferred. Or in worse case atleast have an option to disable this somehow via some config, so that such situations can be avoided.
I don't think a precise timing is necessary and we can send the signal few miliseconds or a second later. That should eliminate this concern (I asked this, waiting for an answer).
It's more of a privacy reason to me, if we can find other ways that do not broadcast this to everyone I think it would be better.
I can think of two more solutions currently:
- Have client connect to KCM socket and await signal there. This
however would mean that connection between client and KCM need to be always established and KCM responder would be running all the time (currently it is only short-lived socket activated process).
Is this (shortlivedness) why we can't use a listener ?
- Create a temporary file in a directory owned by user. User can then
setup inotify watch to the file and sssd would write to the file on changes. Since it is in directory owned by user, other users would not be able to setup the watch.
But how will the daemon be able to do this? At the very least the file would need to be in /run/user because home directories could be on NFS where root can't write, and besides this is really temporary state and has no business in home directories.
Note that it is possile to setup inotify watch on FILE ccache (keeping distro settings out of the question the default ccache is FILE:/tmp/krb5cc_%{uid} as per krb5.conf manpage) so perhaps we really don't have to care about broadcasting this information.
That is a good point, I still dislike actively broadcasting around I wonder if it is possible to just reconnect to the system bus and learn who is listening and just target those listeners as appropriate.
Is the system bus stateful? Do clients have to reconnect whenever a daemon restarts?
Thanks, Pavel.
On 2/20/20 6:27 PM, Simo Sorce wrote:
On Thu, 2020-02-20 at 11:18 +0100, Pavel Březina wrote:
Hi devs,
I'm thinking about ways to implement SSSD KCM notification that something has changed (i.e. user called kinit/kdestroy) [1]. The main use case is to notify Gnome Online Accounts (which is a daemon running under logged-in user) when something has changed and it is already a D-Bus service.
The basic idea is that we would use D-Bus signals that would be emitted by SSSD KCM responder (sssd_kcm process). Signals are broadcasted messages that are delivered to client that chose to listen to them.
The problem is that we
- can't connect to specific user's session bus because KCM runs as
root/sssd and connecting to other user's bus is not allowed 2) can't specify which user is allowed to get the signal
Can you explain what this means?
See below.
- therefore we can't send the signal only to specific user
Why not? We definitely should be able to know what user is listening on the other side of a bus, so we could simply only send back info related to that same user? Or are we blinded to which user is interacting with us?
We need to distinguish method calls and signals. Method calls are (usually) unicast - client send method call to message bus and it is routed to the destination. In this case the destination knows who the sender was.
Signals are broadcasted messages and do not have destination. They are emitted by the sender and message bus resend it to anyone who is listening. The sender does not know who received it.
See: https://dbus.freedesktop.org/doc/dbus-tutorial.html#signalprocedure
In theory, it is possible to send signal to a particular destination: https://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-routing but we would have to know the destination name. But I am not aware of any way to obtain list of listeners.
But perhaps, we could create a dedicated message bus with our sbus that would be publicly available. It could be able to emit the signal only for connections with particular uid. Clients could still use standard dbus api.
So the solution is that KCM connects to system bus and sends org.sssd.kcm.Changed(uid) signal where uid is uid of the user which ccache has changed so the receiver can know which user is affected. This signal is broadcasted to everyone who listens to it.
This means users can monitor each other, sounds bad.
It is perfectly usable, however the question is whether we can broadcast this information (that user A run kinit/kdestroy/other modification of ccache) or it is a security leak that we must avoid and we should seek other solution.
Looks quite bad, why do we need to broadcast to everyone? Isn't there an interface where a specific user can initiate a listening channel and we send back only info related to that user?
I am not aware of such interface.
I asked this secalert and they reply that there is no security concern "but":
After looking at this issue, honestly I dont see an attack vector here, but i am afraid something like this could be used with some other security flaw to maybe gain privesc? For example a flaw which is some component which can be triggered only when kinit is run? where precise timing is required.
So in conclusion if there is another "better" solution than it should be preferred. Or in worse case atleast have an option to disable this somehow via some config, so that such situations can be avoided.
I don't think a precise timing is necessary and we can send the signal few miliseconds or a second later. That should eliminate this concern (I asked this, waiting for an answer).
It's more of a privacy reason to me, if we can find other ways that do not broadcast this to everyone I think it would be better.
Yes, I agree.
I can think of two more solutions currently:
- Have client connect to KCM socket and await signal there. This
however would mean that connection between client and KCM need to be always established and KCM responder would be running all the time (currently it is only short-lived socket activated process).
Is this (shortlivedness) why we can't use a listener ?
Pretty much yes. KCM is currently stateless responder that stops once it is idle.
(*) Perhaps we could make clients to send their name to kcm if they want to receive kcm signals and store this information in cache. UID can be associated with name. I'm not yet sure if we can tell if the name is still available but this could be doable.
- Create a temporary file in a directory owned by user. User can then
setup inotify watch to the file and sssd would write to the file on changes. Since it is in directory owned by user, other users would not be able to setup the watch.
But how will the daemon be able to do this? At the very least the file would need to be in /run/user because home directories could be on NFS where root can't write, and besides this is really temporary state and has no business in home directories.
AFAIK KCM runs as root. So we could created /var/lib/sss/kcm/$uid directory accessible only by $uid and store files there. But it is certainly not ideal.
Note that it is possile to setup inotify watch on FILE ccache (keeping distro settings out of the question the default ccache is FILE:/tmp/krb5cc_%{uid} as per krb5.conf manpage) so perhaps we really don't have to care about broadcasting this information.
That is a good point, I still dislike actively broadcasting around I wonder if it is possible to just reconnect to the system bus and learn who is listening and just target those listeners as appropriate.
I am not aware of such thing. There is only AddMatch/RemoveMatch to start/stop listening but we can't get the list of listeners AFAIK. But we could perhaps implement it ourselves (*)
Is the system bus stateful? Do clients have to reconnect whenever a daemon restarts?
daemon means dbus daemon? AFAIK if it drops clients need to reconnect. At least that is what we do in SSSD.
Thanks, Pavel.
On Fri, 2020-02-21 at 11:22 +0100, Pavel Březina wrote:
On 2/20/20 6:27 PM, Simo Sorce wrote:
On Thu, 2020-02-20 at 11:18 +0100, Pavel Březina wrote:
Hi devs,
I'm thinking about ways to implement SSSD KCM notification that something has changed (i.e. user called kinit/kdestroy) [1]. The main use case is to notify Gnome Online Accounts (which is a daemon running under logged-in user) when something has changed and it is already a D-Bus service.
The basic idea is that we would use D-Bus signals that would be emitted by SSSD KCM responder (sssd_kcm process). Signals are broadcasted messages that are delivered to client that chose to listen to them.
The problem is that we
- can't connect to specific user's session bus because KCM runs as
root/sssd and connecting to other user's bus is not allowed 2) can't specify which user is allowed to get the signal
Can you explain what this means?
See below.
- therefore we can't send the signal only to specific user
Why not? We definitely should be able to know what user is listening on the other side of a bus, so we could simply only send back info related to that same user? Or are we blinded to which user is interacting with us?
We need to distinguish method calls and signals. Method calls are (usually) unicast - client send method call to message bus and it is routed to the destination. In this case the destination knows who the sender was.
Signals are broadcasted messages and do not have destination. They are emitted by the sender and message bus resend it to anyone who is listening. The sender does not know who received it.
See: https://dbus.freedesktop.org/doc/dbus-tutorial.html#signalprocedure
In theory, it is possible to send signal to a particular destination: https://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-routing but we would have to know the destination name. But I am not aware of any way to obtain list of listeners.
But perhaps, we could create a dedicated message bus with our sbus that would be publicly available. It could be able to emit the signal only for connections with particular uid. Clients could still use standard dbus api.
Do we actually have to send a signal?
I was thinking if it is possible for client instead to create a service with the username in it. Then KCM could be their "client" and call a method to pass data (which ccache was updated ?) to the service. No signal involved.
The only problem is that I guess there is no way to restrict paths wo we would still need to double check that the service name whatever- whatever-<uid number> is really owned by <uid number> before sending data.
Can a user create a service on the system bus? Or does it require privileges ?
So the solution is that KCM connects to system bus and sends org.sssd.kcm.Changed(uid) signal where uid is uid of the user which ccache has changed so the receiver can know which user is affected. This signal is broadcasted to everyone who listens to it.
This means users can monitor each other, sounds bad.
It is perfectly usable, however the question is whether we can broadcast this information (that user A run kinit/kdestroy/other modification of ccache) or it is a security leak that we must avoid and we should seek other solution.
Looks quite bad, why do we need to broadcast to everyone? Isn't there an interface where a specific user can initiate a listening channel and we send back only info related to that user?
I am not aware of such interface.
Se above what I mean, it is about reversing the client-server paradigm, where KCM is the system bus client, and interested parties are actual "services" ? I guess one issue is that you can only have on service doing this, but that one service could be a gnome component that then can rebroadcast the information on the session bus via a signal?
I asked this secalert and they reply that there is no security concern "but":
After looking at this issue, honestly I dont see an attack vector here, but i am afraid something like this could be used with some other security flaw to maybe gain privesc? For example a flaw which is some component which can be triggered only when kinit is run? where precise timing is required.
So in conclusion if there is another "better" solution than it should be preferred. Or in worse case atleast have an option to disable this somehow via some config, so that such situations can be avoided.
I don't think a precise timing is necessary and we can send the signal few miliseconds or a second later. That should eliminate this concern (I asked this, waiting for an answer).
It's more of a privacy reason to me, if we can find other ways that do not broadcast this to everyone I think it would be better.
Yes, I agree.
I can think of two more solutions currently:
- Have client connect to KCM socket and await signal there. This
however would mean that connection between client and KCM need to be always established and KCM responder would be running all the time (currently it is only short-lived socket activated process).
Is this (shortlivedness) why we can't use a listener ?
Pretty much yes. KCM is currently stateless responder that stops once it is idle.
(*) Perhaps we could make clients to send their name to kcm if they want to receive kcm signals and store this information in cache. UID can be associated with name. I'm not yet sure if we can tell if the name is still available but this could be doable.
This is potentially an idea, are you hinting here at something like what I proposed above ?
- Create a temporary file in a directory owned by user. User can then
setup inotify watch to the file and sssd would write to the file on changes. Since it is in directory owned by user, other users would not be able to setup the watch.
But how will the daemon be able to do this? At the very least the file would need to be in /run/user because home directories could be on NFS where root can't write, and besides this is really temporary state and has no business in home directories.
AFAIK KCM runs as root. So we could created /var/lib/sss/kcm/$uid directory accessible only by $uid and store files there. But it is certainly not ideal.
I thought about this as well but definitely not ideal, unless we do this only if the interested daemon has somehow signaled explicitly that notifications are wanted, so that we do not litter the directory with useless notification files. However I would still use a file like: /run/user/<uid number>/.kcm-ccache-notify or similar But not in /var/lib/sss, /run/user files are removed dynamically when the user logs out and the session is terminated and won't persist on a system after reboots and such.
Note that it is possile to setup inotify watch on FILE ccache (keeping distro settings out of the question the default ccache is FILE:/tmp/krb5cc_%{uid} as per krb5.conf manpage) so perhaps we really don't have to care about broadcasting this information.
That is a good point, I still dislike actively broadcasting around I wonder if it is possible to just reconnect to the system bus and learn who is listening and just target those listeners as appropriate.
I am not aware of such thing. There is only AddMatch/RemoveMatch to start/stop listening but we can't get the list of listeners AFAIK. But we could perhaps implement it ourselves (*)
Sounds like too much work, we should try to find a mechanism that requires as little implementation as possible.
Is the system bus stateful? Do clients have to reconnect whenever a daemon restarts?
daemon means dbus daemon? AFAIK if it drops clients need to reconnect. At least that is what we do in SSSD.
No, by daemon I meant the service offering services on the system bus (KCM?), however if we can reverse the service/client direction as I mention above, this is not really important anymore.
Simo.
On 2/21/20 6:12 PM, Simo Sorce wrote:
On Fri, 2020-02-21 at 11:22 +0100, Pavel Březina wrote:
On 2/20/20 6:27 PM, Simo Sorce wrote:
On Thu, 2020-02-20 at 11:18 +0100, Pavel Březina wrote:
Hi devs,
I'm thinking about ways to implement SSSD KCM notification that something has changed (i.e. user called kinit/kdestroy) [1]. The main use case is to notify Gnome Online Accounts (which is a daemon running under logged-in user) when something has changed and it is already a D-Bus service.
The basic idea is that we would use D-Bus signals that would be emitted by SSSD KCM responder (sssd_kcm process). Signals are broadcasted messages that are delivered to client that chose to listen to them.
The problem is that we
- can't connect to specific user's session bus because KCM runs as
root/sssd and connecting to other user's bus is not allowed 2) can't specify which user is allowed to get the signal
Can you explain what this means?
See below.
- therefore we can't send the signal only to specific user
Why not? We definitely should be able to know what user is listening on the other side of a bus, so we could simply only send back info related to that same user? Or are we blinded to which user is interacting with us?
We need to distinguish method calls and signals. Method calls are (usually) unicast - client send method call to message bus and it is routed to the destination. In this case the destination knows who the sender was.
Signals are broadcasted messages and do not have destination. They are emitted by the sender and message bus resend it to anyone who is listening. The sender does not know who received it.
See: https://dbus.freedesktop.org/doc/dbus-tutorial.html#signalprocedure
In theory, it is possible to send signal to a particular destination: https://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-routing but we would have to know the destination name. But I am not aware of any way to obtain list of listeners.
But perhaps, we could create a dedicated message bus with our sbus that would be publicly available. It could be able to emit the signal only for connections with particular uid. Clients could still use standard dbus api.
Do we actually have to send a signal?
I was thinking if it is possible for client instead to create a service with the username in it. Then KCM could be their "client" and call a method to pass data (which ccache was updated ?) to the service. No signal involved.
The only problem is that I guess there is no way to restrict paths wo we would still need to double check that the service name whatever- whatever-<uid number> is really owned by <uid number> before sending data.
Can a user create a service on the system bus? Or does it require privileges ?
So the solution is that KCM connects to system bus and sends org.sssd.kcm.Changed(uid) signal where uid is uid of the user which ccache has changed so the receiver can know which user is affected. This signal is broadcasted to everyone who listens to it.
This means users can monitor each other, sounds bad.
It is perfectly usable, however the question is whether we can broadcast this information (that user A run kinit/kdestroy/other modification of ccache) or it is a security leak that we must avoid and we should seek other solution.
Looks quite bad, why do we need to broadcast to everyone? Isn't there an interface where a specific user can initiate a listening channel and we send back only info related to that user?
I am not aware of such interface.
Se above what I mean, it is about reversing the client-server paradigm, where KCM is the system bus client, and interested parties are actual "services" ? I guess one issue is that you can only have on service doing this, but that one service could be a gnome component that then can rebroadcast the information on the session bus via a signal?
I asked this secalert and they reply that there is no security concern "but":
After looking at this issue, honestly I dont see an attack vector here, but i am afraid something like this could be used with some other security flaw to maybe gain privesc? For example a flaw which is some component which can be triggered only when kinit is run? where precise timing is required.
So in conclusion if there is another "better" solution than it should be preferred. Or in worse case atleast have an option to disable this somehow via some config, so that such situations can be avoided.
I don't think a precise timing is necessary and we can send the signal few miliseconds or a second later. That should eliminate this concern (I asked this, waiting for an answer).
It's more of a privacy reason to me, if we can find other ways that do not broadcast this to everyone I think it would be better.
Yes, I agree.
I can think of two more solutions currently:
- Have client connect to KCM socket and await signal there. This
however would mean that connection between client and KCM need to be always established and KCM responder would be running all the time (currently it is only short-lived socket activated process).
Is this (shortlivedness) why we can't use a listener ?
Pretty much yes. KCM is currently stateless responder that stops once it is idle.
(*) Perhaps we could make clients to send their name to kcm if they want to receive kcm signals and store this information in cache. UID can be associated with name. I'm not yet sure if we can tell if the name is still available but this could be doable.
This is potentially an idea, are you hinting here at something like what I proposed above ?
Yes, I think we are proposing the same thing. It is possible, we would just need to maintain list of recipients ourselves.
- Create a temporary file in a directory owned by user. User can then
setup inotify watch to the file and sssd would write to the file on changes. Since it is in directory owned by user, other users would not be able to setup the watch.
But how will the daemon be able to do this? At the very least the file would need to be in /run/user because home directories could be on NFS where root can't write, and besides this is really temporary state and has no business in home directories.
AFAIK KCM runs as root. So we could created /var/lib/sss/kcm/$uid directory accessible only by $uid and store files there. But it is certainly not ideal.
I thought about this as well but definitely not ideal, unless we do this only if the interested daemon has somehow signaled explicitly that notifications are wanted, so that we do not litter the directory with useless notification files. However I would still use a file like: /run/user/<uid number>/.kcm-ccache-notify or similar But not in /var/lib/sss, /run/user files are removed dynamically when the user logs out and the session is terminated and won't persist on a system after reboots and such.
Note that it is possile to setup inotify watch on FILE ccache (keeping distro settings out of the question the default ccache is FILE:/tmp/krb5cc_%{uid} as per krb5.conf manpage) so perhaps we really don't have to care about broadcasting this information.
That is a good point, I still dislike actively broadcasting around I wonder if it is possible to just reconnect to the system bus and learn who is listening and just target those listeners as appropriate.
I am not aware of such thing. There is only AddMatch/RemoveMatch to start/stop listening but we can't get the list of listeners AFAIK. But we could perhaps implement it ourselves (*)
Sounds like too much work, we should try to find a mechanism that requires as little implementation as possible.
Is the system bus stateful? Do clients have to reconnect whenever a daemon restarts?
daemon means dbus daemon? AFAIK if it drops clients need to reconnect. At least that is what we do in SSSD.
No, by daemon I meant the service offering services on the system bus (KCM?), however if we can reverse the service/client direction as I mention above, this is not really important anymore.
Simo.
On Thu, Feb 20, 2020 at 12:27:23PM -0500, Simo Sorce wrote:
On Thu, 2020-02-20 at 11:18 +0100, Pavel Březina wrote:
Hi devs,
I'm thinking about ways to implement SSSD KCM notification that something has changed (i.e. user called kinit/kdestroy) [1]. The main use case is to notify Gnome Online Accounts (which is a daemon running under logged-in user) when something has changed and it is already a D-Bus service.
The basic idea is that we would use D-Bus signals that would be emitted by SSSD KCM responder (sssd_kcm process). Signals are broadcasted messages that are delivered to client that chose to listen to them.
The problem is that we
- can't connect to specific user's session bus because KCM runs as
root/sssd and connecting to other user's bus is not allowed 2) can't specify which user is allowed to get the signal
Can you explain what this means?
- therefore we can't send the signal only to specific user
Why not? We definitely should be able to know what user is listening on the other side of a bus, so we could simply only send back info related to that same user? Or are we blinded to which user is interacting with us?
So the solution is that KCM connects to system bus and sends org.sssd.kcm.Changed(uid) signal where uid is uid of the user which ccache has changed so the receiver can know which user is affected. This signal is broadcasted to everyone who listens to it.
This means users can monitor each other, sounds bad.
It is perfectly usable, however the question is whether we can broadcast this information (that user A run kinit/kdestroy/other modification of ccache) or it is a security leak that we must avoid and we should seek other solution.
Looks quite bad, why do we need to broadcast to everyone? Isn't there an interface where a specific user can initiate a listening channel and we send back only info related to that user?
I asked this secalert and they reply that there is no security concern "but":
After looking at this issue, honestly I dont see an attack vector here, but i am afraid something like this could be used with some other security flaw to maybe gain privesc? For example a flaw which is some component which can be triggered only when kinit is run? where precise timing is required.
So in conclusion if there is another "better" solution than it should be preferred. Or in worse case atleast have an option to disable this somehow via some config, so that such situations can be avoided.
I don't think a precise timing is necessary and we can send the signal few miliseconds or a second later. That should eliminate this concern (I asked this, waiting for an answer).
It's more of a privacy reason to me, if we can find other ways that do not broadcast this to everyone I think it would be better.
I can think of two more solutions currently:
- Have client connect to KCM socket and await signal there. This
however would mean that connection between client and KCM need to be always established and KCM responder would be running all the time (currently it is only short-lived socket activated process).
Is this (shortlivedness) why we can't use a listener ?
- Create a temporary file in a directory owned by user. User can then
setup inotify watch to the file and sssd would write to the file on changes. Since it is in directory owned by user, other users would not be able to setup the watch.
But how will the daemon be able to do this? At the very least the file would need to be in /run/user because home directories could be on NFS where root can't write, and besides this is really temporary state and has no business in home directories.
Note that it is possile to setup inotify watch on FILE ccache (keeping distro settings out of the question the default ccache is FILE:/tmp/krb5cc_%{uid} as per krb5.conf manpage) so perhaps we really don't have to care about broadcasting this information.
That is a good point, I still dislike actively broadcasting around I
Hi,
I'd also prefer the file/inotify based version. It would be also easier for Gnome-Online-Accounts (GOA) to implement this since that already do inotify on the FILE ccache.
However, this is a quite specific fix just for GOA I'm not sure if there are other use cases as well.
Going back to the original issue, the constant activity/load which is caused by GOA polling the KCM ccache state in regular, short intervals. Iirc Simo suggested in the related ticket to implement a rate-limitation. So if we detect a too many request in a short time from a single PID we can just delay the response. This would not require changes on the GOA side and might be useful in other cases as well. But there is a drawback, KCM will still run constantly. With the file/inotify solution KCM can shutdown itself when there is no activity.
So if GOA team agrees with the needed changes on the GOA side the file/inotify solution might be better.
bye, Sumit
wonder if it is possible to just reconnect to the system bus and learn who is listening and just target those listeners as appropriate.
Is the system bus stateful? Do clients have to reconnect whenever a daemon restarts?
Thanks, Pavel.
-- Simo Sorce RHEL Crypto Team Red Hat, Inc
On Fri, 2020-02-21 at 11:28 +0100, Sumit Bose wrote:
On Thu, Feb 20, 2020 at 12:27:23PM -0500, Simo Sorce wrote:
On Thu, 2020-02-20 at 11:18 +0100, Pavel Březina wrote:
Hi devs,
I'm thinking about ways to implement SSSD KCM notification that something has changed (i.e. user called kinit/kdestroy) [1]. The main use case is to notify Gnome Online Accounts (which is a daemon running under logged-in user) when something has changed and it is already a D-Bus service.
The basic idea is that we would use D-Bus signals that would be emitted by SSSD KCM responder (sssd_kcm process). Signals are broadcasted messages that are delivered to client that chose to listen to them.
The problem is that we
- can't connect to specific user's session bus because KCM runs as
root/sssd and connecting to other user's bus is not allowed 2) can't specify which user is allowed to get the signal
Can you explain what this means?
- therefore we can't send the signal only to specific user
Why not? We definitely should be able to know what user is listening on the other side of a bus, so we could simply only send back info related to that same user? Or are we blinded to which user is interacting with us?
So the solution is that KCM connects to system bus and sends org.sssd.kcm.Changed(uid) signal where uid is uid of the user which ccache has changed so the receiver can know which user is affected. This signal is broadcasted to everyone who listens to it.
This means users can monitor each other, sounds bad.
It is perfectly usable, however the question is whether we can broadcast this information (that user A run kinit/kdestroy/other modification of ccache) or it is a security leak that we must avoid and we should seek other solution.
Looks quite bad, why do we need to broadcast to everyone? Isn't there an interface where a specific user can initiate a listening channel and we send back only info related to that user?
I asked this secalert and they reply that there is no security concern "but":
After looking at this issue, honestly I dont see an attack vector here, but i am afraid something like this could be used with some other security flaw to maybe gain privesc? For example a flaw which is some component which can be triggered only when kinit is run? where precise timing is required.
So in conclusion if there is another "better" solution than it should be preferred. Or in worse case atleast have an option to disable this somehow via some config, so that such situations can be avoided.
I don't think a precise timing is necessary and we can send the signal few miliseconds or a second later. That should eliminate this concern (I asked this, waiting for an answer).
It's more of a privacy reason to me, if we can find other ways that do not broadcast this to everyone I think it would be better.
I can think of two more solutions currently:
- Have client connect to KCM socket and await signal there. This
however would mean that connection between client and KCM need to be always established and KCM responder would be running all the time (currently it is only short-lived socket activated process).
Is this (shortlivedness) why we can't use a listener ?
- Create a temporary file in a directory owned by user. User can then
setup inotify watch to the file and sssd would write to the file on changes. Since it is in directory owned by user, other users would not be able to setup the watch.
But how will the daemon be able to do this? At the very least the file would need to be in /run/user because home directories could be on NFS where root can't write, and besides this is really temporary state and has no business in home directories.
Note that it is possile to setup inotify watch on FILE ccache (keeping distro settings out of the question the default ccache is FILE:/tmp/krb5cc_%{uid} as per krb5.conf manpage) so perhaps we really don't have to care about broadcasting this information.
That is a good point, I still dislike actively broadcasting around I
Hi,
I'd also prefer the file/inotify based version. It would be also easier for Gnome-Online-Accounts (GOA) to implement this since that already do inotify on the FILE ccache.
However, this is a quite specific fix just for GOA I'm not sure if there are other use cases as well.
Going back to the original issue, the constant activity/load which is caused by GOA polling the KCM ccache state in regular, short intervals. Iirc Simo suggested in the related ticket to implement a rate-limitation. So if we detect a too many request in a short time from a single PID we can just delay the response. This would not require changes on the GOA side and might be useful in other cases as well. But there is a drawback, KCM will still run constantly. With the file/inotify solution KCM can shutdown itself when there is no activity.
So if GOA team agrees with the needed changes on the GOA side the file/inotify solution might be better.
The more I think of this idea of using files the more a file in /run/user/<uid number>/ sounds like a quite decent idea.
Two limitations come to mind here, but they are probably ok for now:
1) I wonder if /run/user/<uid number> is always guaranteed to exist when KCM operations for a specific user happen, if not though it is unlikely that anything is wanting to get notified anyway, so it probably does not matter. (The directory will definitely not be there during initial authentication, because KEYRING and KCM were created in part to overcome the fact this directory is created only after the first successful authentication, but this is not important, no user process will listen before the user is authenticated)
2) One reason to use KCM is that the socket protocol can be proxied, both across container boundaries and across even the network (I tested doing that over a SSH connection), in both cases the filesystem that KCM sees is not the filesystem the clients see. And the same can happen if /run/user get namespaced in the future. But this is a limitation we can deal with for now, it does not affect the primary use case (GOA).
Both point 1 and 2 make me think we may want to create notification files only "on demand" ie a client would have to use a new kcm API call to set up notifications.
If a client asks we respond with a payload that tells the client which file they should monitor (this way in future we can change notification mechanism by simply changing what we return), for example: FILE:/run/user/1000/.kcm-notify
Internally we store a KCM entry that tells if notifications for that ccache/user have been requested and we touch the file only if that entry exists, this will avoid touching a lot of files all over the place on machines where there are a lot of users but none of them cares about notifications like an SSH bastion host. The tricky part is to avoid unnecessary persistence of the notification mechanism, ie after a reboot KCM should not recreate/touch the notification file unless a client asked for it. Perhaps the notification request triggers the creation of the file and we only touch the file if it already exists. If someone removes the file it will be the equivalent of requesting notifications stop. GOA can have a behavior to ask again for notifications if the file goes away (and the cache still exists).
Sumit Bose sbose@redhat.com writes:
On Thu, Feb 20, 2020 at 12:27:23PM -0500, Simo Sorce wrote:
On Thu, 2020-02-20 at 11:18 +0100, Pavel Březina wrote:
Hi devs,
I'm thinking about ways to implement SSSD KCM notification that something has changed (i.e. user called kinit/kdestroy) [1]. The main use case is to notify Gnome Online Accounts (which is a daemon running under logged-in user) when something has changed and it is already a D-Bus service.
The basic idea is that we would use D-Bus signals that would be emitted by SSSD KCM responder (sssd_kcm process). Signals are broadcasted messages that are delivered to client that chose to listen to them.
The problem is that we
- can't connect to specific user's session bus because KCM runs as
root/sssd and connecting to other user's bus is not allowed 2) can't specify which user is allowed to get the signal
Can you explain what this means?
- therefore we can't send the signal only to specific user
Why not? We definitely should be able to know what user is listening on the other side of a bus, so we could simply only send back info related to that same user? Or are we blinded to which user is interacting with us?
So the solution is that KCM connects to system bus and sends org.sssd.kcm.Changed(uid) signal where uid is uid of the user which ccache has changed so the receiver can know which user is affected. This signal is broadcasted to everyone who listens to it.
This means users can monitor each other, sounds bad.
It is perfectly usable, however the question is whether we can broadcast this information (that user A run kinit/kdestroy/other modification of ccache) or it is a security leak that we must avoid and we should seek other solution.
Looks quite bad, why do we need to broadcast to everyone? Isn't there an interface where a specific user can initiate a listening channel and we send back only info related to that user?
I asked this secalert and they reply that there is no security concern "but":
After looking at this issue, honestly I dont see an attack vector here, but i am afraid something like this could be used with some other security flaw to maybe gain privesc? For example a flaw which is some component which can be triggered only when kinit is run? where precise timing is required.
So in conclusion if there is another "better" solution than it should be preferred. Or in worse case atleast have an option to disable this somehow via some config, so that such situations can be avoided.
I don't think a precise timing is necessary and we can send the signal few miliseconds or a second later. That should eliminate this concern (I asked this, waiting for an answer).
It's more of a privacy reason to me, if we can find other ways that do not broadcast this to everyone I think it would be better.
I can think of two more solutions currently:
- Have client connect to KCM socket and await signal there. This
however would mean that connection between client and KCM need to be always established and KCM responder would be running all the time (currently it is only short-lived socket activated process).
Is this (shortlivedness) why we can't use a listener ?
- Create a temporary file in a directory owned by user. User can then
setup inotify watch to the file and sssd would write to the file on changes. Since it is in directory owned by user, other users would not be able to setup the watch.
But how will the daemon be able to do this? At the very least the file would need to be in /run/user because home directories could be on NFS where root can't write, and besides this is really temporary state and has no business in home directories.
Note that it is possile to setup inotify watch on FILE ccache (keeping distro settings out of the question the default ccache is FILE:/tmp/krb5cc_%{uid} as per krb5.conf manpage) so perhaps we really don't have to care about broadcasting this information.
That is a good point, I still dislike actively broadcasting around I
Hi,
I'd also prefer the file/inotify based version. It would be also easier for Gnome-Online-Accounts (GOA) to implement this since that already do inotify on the FILE ccache.
However, this is a quite specific fix just for GOA I'm not sure if there are other use cases as well.
Going back to the original issue, the constant activity/load which is caused by GOA polling the KCM ccache state in regular, short intervals. Iirc Simo suggested in the related ticket to implement a rate-limitation. So if we detect a too many request in a short time from a single PID we can just delay the response. This would not require changes on the GOA side and might be useful in other cases as well. But there is a drawback, KCM will still run constantly. With the file/inotify solution KCM can shutdown itself when there is no activity.
So if GOA team agrees with the needed changes on the GOA side the file/inotify solution might be better.
CCing some GOA folks. I believe their preference was for the inotify approach.
Moreover, I'd like to provide a consistent interface to all of the ccaches from krb5. I'm not going to be able to do that if dbus becomes involved (for a variety of reasons).
Thanks, --Robbie
bye, Sumit
wonder if it is possible to just reconnect to the system bus and learn who is listening and just target those listeners as appropriate.
Is the system bus stateful? Do clients have to reconnect whenever a daemon restarts?
Thanks, Pavel.
-- Simo Sorce RHEL Crypto Team Red Hat, Inc
On 2/21/20 7:26 PM, Robbie Harwood wrote:
Sumit Bose sbose@redhat.com writes:
On Thu, Feb 20, 2020 at 12:27:23PM -0500, Simo Sorce wrote:
On Thu, 2020-02-20 at 11:18 +0100, Pavel Březina wrote:
Hi devs,
I'm thinking about ways to implement SSSD KCM notification that something has changed (i.e. user called kinit/kdestroy) [1]. The main use case is to notify Gnome Online Accounts (which is a daemon running under logged-in user) when something has changed and it is already a D-Bus service.
The basic idea is that we would use D-Bus signals that would be emitted by SSSD KCM responder (sssd_kcm process). Signals are broadcasted messages that are delivered to client that chose to listen to them.
The problem is that we
- can't connect to specific user's session bus because KCM runs as
root/sssd and connecting to other user's bus is not allowed 2) can't specify which user is allowed to get the signal
Can you explain what this means?
- therefore we can't send the signal only to specific user
Why not? We definitely should be able to know what user is listening on the other side of a bus, so we could simply only send back info related to that same user? Or are we blinded to which user is interacting with us?
So the solution is that KCM connects to system bus and sends org.sssd.kcm.Changed(uid) signal where uid is uid of the user which ccache has changed so the receiver can know which user is affected. This signal is broadcasted to everyone who listens to it.
This means users can monitor each other, sounds bad.
It is perfectly usable, however the question is whether we can broadcast this information (that user A run kinit/kdestroy/other modification of ccache) or it is a security leak that we must avoid and we should seek other solution.
Looks quite bad, why do we need to broadcast to everyone? Isn't there an interface where a specific user can initiate a listening channel and we send back only info related to that user?
I asked this secalert and they reply that there is no security concern "but":
After looking at this issue, honestly I dont see an attack vector here, but i am afraid something like this could be used with some other security flaw to maybe gain privesc? For example a flaw which is some component which can be triggered only when kinit is run? where precise timing is required.
So in conclusion if there is another "better" solution than it should be preferred. Or in worse case atleast have an option to disable this somehow via some config, so that such situations can be avoided.
I don't think a precise timing is necessary and we can send the signal few miliseconds or a second later. That should eliminate this concern (I asked this, waiting for an answer).
It's more of a privacy reason to me, if we can find other ways that do not broadcast this to everyone I think it would be better.
I can think of two more solutions currently:
- Have client connect to KCM socket and await signal there. This
however would mean that connection between client and KCM need to be always established and KCM responder would be running all the time (currently it is only short-lived socket activated process).
Is this (shortlivedness) why we can't use a listener ?
- Create a temporary file in a directory owned by user. User can then
setup inotify watch to the file and sssd would write to the file on changes. Since it is in directory owned by user, other users would not be able to setup the watch.
But how will the daemon be able to do this? At the very least the file would need to be in /run/user because home directories could be on NFS where root can't write, and besides this is really temporary state and has no business in home directories.
Note that it is possile to setup inotify watch on FILE ccache (keeping distro settings out of the question the default ccache is FILE:/tmp/krb5cc_%{uid} as per krb5.conf manpage) so perhaps we really don't have to care about broadcasting this information.
That is a good point, I still dislike actively broadcasting around I
Hi,
I'd also prefer the file/inotify based version. It would be also easier for Gnome-Online-Accounts (GOA) to implement this since that already do inotify on the FILE ccache.
However, this is a quite specific fix just for GOA I'm not sure if there are other use cases as well.
Going back to the original issue, the constant activity/load which is caused by GOA polling the KCM ccache state in regular, short intervals. Iirc Simo suggested in the related ticket to implement a rate-limitation. So if we detect a too many request in a short time from a single PID we can just delay the response. This would not require changes on the GOA side and might be useful in other cases as well. But there is a drawback, KCM will still run constantly. With the file/inotify solution KCM can shutdown itself when there is no activity.
So if GOA team agrees with the needed changes on the GOA side the file/inotify solution might be better.
CCing some GOA folks. I believe their preference was for the inotify approach.
Moreover, I'd like to provide a consistent interface to all of the ccaches from krb5. I'm not going to be able to do that if dbus becomes involved (for a variety of reasons).
Is there some kerberos api that can be used to register client for notifications?
Thanks, --Robbie
bye, Sumit
wonder if it is possible to just reconnect to the system bus and learn who is listening and just target those listeners as appropriate.
Is the system bus stateful? Do clients have to reconnect whenever a daemon restarts?
Thanks, Pavel.
-- Simo Sorce RHEL Crypto Team Red Hat, Inc
Pavel Březina pbrezina@redhat.com writes:
On 2/21/20 7:26 PM, Robbie Harwood wrote:
Sumit Bose sbose@redhat.com writes:
So if GOA team agrees with the needed changes on the GOA side the file/inotify solution might be better.
CCing some GOA folks. I believe their preference was for the inotify approach.
Moreover, I'd like to provide a consistent interface to all of the ccaches from krb5. I'm not going to be able to do that if dbus becomes involved (for a variety of reasons).
Is there some kerberos api that can be used to register client for notifications?
No, the idea would be to add one. For the most part, we can move the GOA logic into krb5 so long as it's suitable. Ray and I had discussed a possible interface in https://projects.engineering.redhat.com/browse/IDMAFS-1
This is not a definite thing, though - it's possible that only GOA wants this functionality and it's not worth adding a krb5 API for.
Thanks, --Robbie
On Thu, Feb 20, 2020 at 11:18:59AM +0100, Pavel Březina wrote:
Hi devs,
I'm thinking about ways to implement SSSD KCM notification that something has changed (i.e. user called kinit/kdestroy) [1]. The main use case is to notify Gnome Online Accounts (which is a daemon running under logged-in user) when something has changed and it is already a D-Bus service.
The basic idea is that we would use D-Bus signals that would be emitted by SSSD KCM responder (sssd_kcm process). Signals are broadcasted messages that are delivered to client that chose to listen to them.
The problem is that we
- can't connect to specific user's session bus because KCM runs as
root/sssd and connecting to other user's bus is not allowed 2) can't specify which user is allowed to get the signal 3) therefore we can't send the signal only to specific user
So the solution is that KCM connects to system bus and sends org.sssd.kcm.Changed(uid) signal where uid is uid of the user which ccache has changed so the receiver can know which user is affected. This signal is broadcasted to everyone who listens to it.
It is perfectly usable, however the question is whether we can broadcast this information (that user A run kinit/kdestroy/other modification of ccache) or it is a security leak that we must avoid and we should seek other solution.
IIRC with D-Bus you know who the peer is, can't you just filter out messages to be send about the same user as the peer? Or is gnome-online-accounts running as a different UID?
On 2/21/20 10:25 AM, Jakub Hrozek wrote:
On Thu, Feb 20, 2020 at 11:18:59AM +0100, Pavel Březina wrote:
Hi devs,
I'm thinking about ways to implement SSSD KCM notification that something has changed (i.e. user called kinit/kdestroy) [1]. The main use case is to notify Gnome Online Accounts (which is a daemon running under logged-in user) when something has changed and it is already a D-Bus service.
The basic idea is that we would use D-Bus signals that would be emitted by SSSD KCM responder (sssd_kcm process). Signals are broadcasted messages that are delivered to client that chose to listen to them.
The problem is that we
- can't connect to specific user's session bus because KCM runs as
root/sssd and connecting to other user's bus is not allowed 2) can't specify which user is allowed to get the signal 3) therefore we can't send the signal only to specific user
So the solution is that KCM connects to system bus and sends org.sssd.kcm.Changed(uid) signal where uid is uid of the user which ccache has changed so the receiver can know which user is affected. This signal is broadcasted to everyone who listens to it.
It is perfectly usable, however the question is whether we can broadcast this information (that user A run kinit/kdestroy/other modification of ccache) or it is a security leak that we must avoid and we should seek other solution.
IIRC with D-Bus you know who the peer is, can't you just filter out messages to be send about the same user as the peer? Or is gnome-online-accounts running as a different UID?
If you receive method, you know who send it. If you are emitting signals it is broadcasted by message bus to whoever listens. We do not know who receives it. But perhaps this can be implemented if we use sbus server instead of system message bus.
On Thu, Feb 20, 2020 at 11:19 AM Pavel Březina pbrezina@redhat.com wrote:
Hi devs,
I'm thinking about ways to implement SSSD KCM notification that something has changed (i.e. user called kinit/kdestroy) [1]. The main use case is to notify Gnome Online Accounts (which is a daemon running under logged-in user) when something has changed and it is already a D-Bus service.
The basic idea is that we would use D-Bus signals that would be emitted by SSSD KCM responder (sssd_kcm process). Signals are broadcasted messages that are delivered to client that chose to listen to them.
The problem is that we
- can't connect to specific user's session bus because KCM runs as
root/sssd and connecting to other user's bus is not allowed
Why? https://lists.freedesktop.org/archives/dbus/2010-May/012757.html
- can't specify which user is allowed to get the signal
- therefore we can't send the signal only to specific user
So the solution is that KCM connects to system bus and sends org.sssd.kcm.Changed(uid) signal where uid is uid of the user which ccache has changed so the receiver can know which user is affected. This signal is broadcasted to everyone who listens to it.
It is perfectly usable, however the question is whether we can broadcast this information (that user A run kinit/kdestroy/other modification of ccache) or it is a security leak that we must avoid and we should seek other solution.
I asked this secalert and they reply that there is no security concern "but":
After looking at this issue, honestly I dont see an attack vector here, but i am afraid something like this could be used with some other security flaw to maybe gain privesc? For example a flaw which is some component which can be triggered only when kinit is run? where precise timing is required.
So in conclusion if there is another "better" solution than it should be preferred. Or in worse case atleast have an option to disable this somehow via some config, so that such situations can be avoided.
I don't think a precise timing is necessary and we can send the signal few miliseconds or a second later. That should eliminate this concern (I asked this, waiting for an answer).
I can think of two more solutions currently:
- Have client connect to KCM socket and await signal there. This
however would mean that connection between client and KCM need to be always established and KCM responder would be running all the time (currently it is only short-lived socket activated process).
- Create a temporary file in a directory owned by user. User can then
setup inotify watch to the file and sssd would write to the file on changes. Since it is in directory owned by user, other users would not be able to setup the watch.
Note that it is possile to setup inotify watch on FILE ccache (keeping distro settings out of the question the default ccache is FILE:/tmp/krb5cc_%{uid} as per krb5.conf manpage) so perhaps we really don't have to care about broadcasting this information.
Thanks, Pavel.
[1] https://pagure.io/SSSD/sssd/issue/3568 _______________________________________________ sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org To unsubscribe send an email to sssd-devel-leave@lists.fedorahosted.org Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedorahosted.org/archives/list/sssd-devel@lists.fedorahosted.o...
On 2/21/20 11:04 AM, Alexey Tikhonov wrote:
On Thu, Feb 20, 2020 at 11:19 AM Pavel Březina pbrezina@redhat.com wrote:
Hi devs,
I'm thinking about ways to implement SSSD KCM notification that something has changed (i.e. user called kinit/kdestroy) [1]. The main use case is to notify Gnome Online Accounts (which is a daemon running under logged-in user) when something has changed and it is already a D-Bus service.
The basic idea is that we would use D-Bus signals that would be emitted by SSSD KCM responder (sssd_kcm process). Signals are broadcasted messages that are delivered to client that chose to listen to them.
The problem is that we
- can't connect to specific user's session bus because KCM runs as
root/sssd and connecting to other user's bus is not allowed
Why? https://lists.freedesktop.org/archives/dbus/2010-May/012757.html
We can't use seteuid directly in kcm due to its asynchronous nature. We can call it only for synchronous piece of code... but perhaps we could create a child process for that... i.e. create child process that would call seteuid, connect to the bus and send the notification then quit.
sssd-devel@lists.fedorahosted.org