Skip to content

Commit

Permalink
[timed] Add support for shared alarm events. Fixes JB#47635
Browse files Browse the repository at this point in the history
We need to be able to:
- Differentiate between private and shared alarm events
- Retain behavioral and dbus api backwards compatibility
- Access shared events on bootup, as any user, and without
  performing interactive tasks such as unlocking encrypted home
  partition
- Maintain uniqueness of cookies regardless of which user is
  considered as the active one

Add "Shared" event flag that can be modified via timed D-Bus
interface.

All already existing alarm events - or new ones created without
setting the shared flag - will behave just as before.

Shared event data is stored (outside possibly encrypted home
partition) under /var/lib/timed/shared_events directory. The
directory is owned by root:sailfish-alarms and has setgid bit
set - so that files created in there inherit group from
directory and remain readable and writable by all members of
"sailfish-alarms" group.

Shared events have cookie number with bit 30 set - which
effectively puts shared and private events in separate cookie
"namespaces."

Caveat: Reserving one cookie bit for shared/private
differentiation in practice cuts the number of possible cookies
from 2 billion down to just one billion - it is assumed that
this does not affect any users.

Signed-off-by: Simo Piiroinen <simo.piiroinen@jollamobile.com>
  • Loading branch information
spiiroin committed Nov 15, 2019
1 parent cd27129 commit 1cc6dae
Show file tree
Hide file tree
Showing 17 changed files with 283 additions and 68 deletions.
5 changes: 5 additions & 0 deletions rpm/timed-qt5.spec
Expand Up @@ -13,6 +13,7 @@ Requires: tzdata-timed
Requires: systemd
Requires: oneshot
Requires: statefs
Requires: sailfish-setup >= 0.1.7
%{_oneshot_groupadd_requires_pre}
%{_oneshot_requires_post}
%{_oneshot_groupadd_requires_post}
Expand All @@ -30,6 +31,7 @@ BuildRequires: libxslt
BuildRequires: oneshot
BuildRequires: pkgconfig(statefs-qt5)
BuildRequires: statefs-devel >= 0.3.21
BuildRequires: pkgconfig(sailfishaccesscontrol) >= 0.0.1

%description
The time daemon (%{name}) managing system time, time zone and settings,
Expand Down Expand Up @@ -92,6 +94,7 @@ chmod 755 %{buildroot}%{_oneshotdir}/setcaps-%{name}.sh
# Initial links are done in the post section
install -d %{buildroot}/var/lib/timed
touch %{buildroot}/var/lib/timed/localtime
install -d %{buildroot}/var/lib/timed/shared_events
# Make /etc/localtime a link to /var/lib/timed/localtime to make system time zone follow timed.
install -d %{buildroot}%{_sysconfdir}
ln -sf /var/lib/timed/localtime %{buildroot}%{_sysconfdir}/localtime
Expand Down Expand Up @@ -149,7 +152,9 @@ fi
%{_libdir}/systemd/user/pre-user-session.target.wants/%{name}.service
%{_oneshotdir}/setcaps-%{name}.sh
%dir %attr(0775,-,timed) /var/lib/timed
%dir %attr(02770,root,sailfish-alarms) /var/lib/timed/shared_events
%ghost /var/lib/timed/localtime
%ghost /var/lib/timed/shared_events/events.data

%files tests
%defattr(-,root,root,-)
Expand Down
3 changes: 3 additions & 0 deletions src/lib/event-declarations.h
Expand Up @@ -110,6 +110,9 @@ class Maemo::Timed::Event
void setReminderFlag() ;
bool reminderFlag() const ;
void clearReminderFlag() ;
void setSharedFlag();
bool sharedFlag() const;
void clearSharedFlag();
void setBootFlag() ;
bool bootFlag() const ;
void clearBootFlag() ;
Expand Down
19 changes: 17 additions & 2 deletions src/lib/event-pimple.cpp
Expand Up @@ -160,7 +160,7 @@ Maemo::Timed::Event::Action * Maemo::Timed::Event::getAction(event_action_pimple
throw Exception(__PRETTY_FUNCTION__, "invalid argument") ;

Maemo::Timed::Event::Action *ea = pa->ptr.get() ;

if(ea == NULL)
{
ea = new Maemo::Timed::Event::Action ;
Expand Down Expand Up @@ -216,7 +216,7 @@ Maemo::Timed::Event::Button * Maemo::Timed::Event::getButton(event_button_pimple
throw Exception(__PRETTY_FUNCTION__, "invalid argument") ;

Maemo::Timed::Event::Button *eb = pb->ptr.get() ;

if(eb == NULL)
{
eb = new Maemo::Timed::Event::Button ;
Expand Down Expand Up @@ -460,6 +460,21 @@ void Maemo::Timed::Event::clearReminderFlag()
p->eio.flags &= ~EventFlags::Reminder ;
}

void Maemo::Timed::Event::setSharedFlag()
{
p->eio.flags |= EventFlags::Shared;
}

bool Maemo::Timed::Event::sharedFlag() const
{
return p->eio.flags & EventFlags::Shared;
}

void Maemo::Timed::Event::clearSharedFlag()
{
p->eio.flags &= ~EventFlags::Shared;
}

void Maemo::Timed::Event::setBootFlag()
{
p->eio.flags |= EventFlags::Boot ;
Expand Down
2 changes: 1 addition & 1 deletion src/server/adaptor.h
Expand Up @@ -216,7 +216,7 @@ public slots:
{
Q_UNUSED(message);
log_notice("DBUS::com.nokia.time.ping() by %s", PEER) ;
iodata::record *r = timed->am->save(false) ; // false = not for backup
iodata::record *r = timed->am->save(false, machine_t::AllEvents); // false = not for backup
std::ostringstream s ;
s << *r ;
delete r ;
Expand Down
2 changes: 1 addition & 1 deletion src/server/backup.cpp
Expand Up @@ -119,7 +119,7 @@ void backup_t::clean_up()

bool backup_t::save_queue_as(const string &path)
{
iodata::record *r = timed->am->save(true) ;
iodata::record *r = timed->am->save(true, machine_t::AllEvents);
iodata::storage *backup = new iodata::storage ;

backup->set_primary_path(path) ;
Expand Down
1 change: 1 addition & 0 deletions src/server/config.type
Expand Up @@ -17,6 +17,7 @@ config_t =
{ name = "queue_threshold_long", type = $integer, value = 5000 },
{ name = "queue_threshold_short", type = $integer, value = 1000 },
{ name = "data_directory", type = $bytes, value = ".timed" },
{ name = "shared_events_directory", type = $bytes, value = "/var/lib/timed/shared_events" },
{ name = "settings_file", type = $bytes, value = "settings.data" },
{ name = "events_file", type = $bytes, value = "events.data" },

Expand Down
1 change: 1 addition & 0 deletions src/server/event.cpp
Expand Up @@ -321,6 +321,7 @@ void event_t::codec_initializer()
REG(event_t::codec, EventFlags, Empty_Recurring) ;
REG(event_t::codec, EventFlags, In_Dialog) ;
REG(event_t::codec, EventFlags, Missed) ;
REG(event_t::codec, EventFlags, Shared);

REG(action_t::codec, ActionFlags, Send_Cookie) ;
REG(action_t::codec, ActionFlags, Send_Event_Attributes) ;
Expand Down
3 changes: 2 additions & 1 deletion src/server/flags.h
Expand Up @@ -98,8 +98,9 @@ namespace WallOpcode
Backup = 1<<13,
Trigger_When_Adjusting = 1<<14,
Trigger_When_Settings_Changed= 1<<15,
Shared = 1<<16,

Last_Client_Flag = 1<<15,
Last_Client_Flag = 1<<16,
Client_Mask = (Last_Client_Flag<<1)-1,

Snoozing = Last_Client_Flag << 1,
Expand Down
22 changes: 19 additions & 3 deletions src/server/machine.cpp
Expand Up @@ -427,6 +427,16 @@ void machine_t::register_event(event_t *e)
{
if (not e->cookie.is_valid())
e->cookie = cookie_t(next_cookie++) ;

/* Remove Shared flag when it is not permitted */
if (e->flags & EventFlags::Shared) {
if (!timed->permissions_shared_events()) {
log_warning("rejecting Shared flag");
e->flags &= ~EventFlags::Shared;
}
}

e->cookie.setShared(e->flags & EventFlags::Shared);
events[e->cookie] = e ;
state_start->go_to(e) ;
}
Expand Down Expand Up @@ -672,7 +682,7 @@ uint32_t machine_t::attr(uint32_t mask)
return flags & mask ;
}

iodata::record *machine_t::save(bool for_backup)
iodata::record *machine_t::save(bool for_backup, EventTypes eventTypes)
{
iodata::record *r = new iodata::record ;
iodata::array *q = new iodata::array ;
Expand All @@ -682,18 +692,24 @@ iodata::record *machine_t::save(bool for_backup)
event_t *e = it->second ;
if(for_backup and not (e->flags & EventFlags::Backup))
continue ;
EventTypes eventType = e->cookie.shared() ? SharedEvents : PrivateEvents;
if (!(eventTypes & eventType))
continue;
q->add(e->save(for_backup)) ;
}

r->add("events", q) ;
if(not for_backup)
r->add("next_cookie", next_cookie) ;
r->add("next_cookie", next_cookie & cookie_t::ValueMask);
return r ;
}

void machine_t::load(const iodata::record *r)
{
next_cookie = r->get("next_cookie")->value() ;
int cookie = r->get("next_cookie")->value();
cookie &= cookie_t::ValueMask;
if (next_cookie < cookie)
next_cookie = cookie;
const iodata::array *a = r->get("events")->arr() ;
load_events(a, true, true) ;
}
Expand Down
7 changes: 6 additions & 1 deletion src/server/machine.h
Expand Up @@ -46,6 +46,11 @@ struct event_t ;

struct machine_t : public QObject
{
enum EventTypes {
PrivateEvents = 1 << 0,
SharedEvents = 1 << 1,
AllEvents = PrivateEvents | SharedEvents,
};
machine_t(const Timed *owner) ;
virtual ~machine_t() ;

Expand Down Expand Up @@ -112,7 +117,7 @@ struct machine_t : public QObject
void device_mode_detected(bool user_mode) ;
bool is_epoch_open() ;
void open_epoch() ;
iodata::record *save(bool for_backup) ;
iodata::record *save(bool for_backup, EventTypes eventTypes);
void load(const iodata::record *) ;
void load_events(const iodata::array *events_data, bool trusted_source, bool use_cookies) ;
void cancel_backup_events() ;
Expand Down
1 change: 1 addition & 0 deletions src/server/server.pro
Expand Up @@ -88,6 +88,7 @@ HEADERS += notification.h

CONFIG += link_pkgconfig
PKGCONFIG += libpcrecpp libsystemd-daemon
PKGCONFIG += sailfishaccesscontrol
equals(QT_MAJOR_VERSION, 4) {
CONFIG += iodata
PKGCONFIG += contextprovider-1.0
Expand Down
1 change: 1 addition & 0 deletions src/server/timed-qt5.rc
@@ -1,3 +1,4 @@
data_directory = ".timed",
shared_events_directory = "/var/lib/timed/shared_events",
events_file = "events.data",
settings_file = "settings.data" .

0 comments on commit 1cc6dae

Please sign in to comment.