blob: 96c5316239af977028a456134a4407eb6c757495 [file] [log] [blame]
// Copyright 2020 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "pciguard/event_handler.h"
#include "pciguard/pciguard_utils.h"
namespace pciguard {
// TODO(b/176184431): Don't assume NO_USER_LOGGED_IN on init.
EventHandler::EventHandler()
: state_(NO_USER_LOGGED_IN), authorizer_(nullptr) {}
void EventHandler::LogEvent(const char ev[]) {
const char* states[] = {
[NO_USER_LOGGED_IN] = "NO_USER_LOGGED_IN",
[USER_LOGGED_IN_BUT_SCREEN_LOCKED] = "USER_LOGGED_IN_BUT_SCREEN_LOCKED",
[USER_LOGGED_IN_SCREEN_UNLOCKED] = "USER_LOGGED_IN_SCREEN_UNLOCKED",
};
LOG(INFO) << "CurrentState= " << states[state_] << ", received event=" << ev;
}
// In a multiuser login scenario, session manager sends session-starting once
// for every time a user is logged in. So this function could get called
// multiple times before a single call to OnUserLogout() logs out all the users.
void EventHandler::OnUserLogin() {
DCHECK(!authorizer_);
bool user_permission = UserPermissionOK();
std::lock_guard<std::mutex> lock(lock_);
LogEvent("User-Login");
LOG(INFO) << "User-Permission = " << user_permission;
// It is important to have this state check, whenever we go from a more
// restrictive state to a less restrictive state to ensure that we always
// err on the cautious side should the events arrive out of order or are
// processed out of order.
if (state_ == NO_USER_LOGGED_IN) {
state_ = USER_LOGGED_IN_SCREEN_UNLOCKED;
if (user_permission) {
authorizer_ = std::make_unique<Authorizer>();
authorizer_->SubmitJob(Authorizer::AUTHORIZE_ALL_DEVICES,
base::FilePath(""));
}
}
}
void EventHandler::OnUserLogout() {
std::lock_guard<std::mutex> lock(lock_);
LogEvent("User-Logout");
// Don't check for current state when going to a super restrictive state.
state_ = NO_USER_LOGGED_IN;
authorizer_.reset();
DeauthorizeAllDevices();
}
void EventHandler::OnScreenLocked() {
std::lock_guard<std::mutex> lock(lock_);
LogEvent("Screen-Locked");
// Check to ensure we only allow to go from less restrictive state to more
// restrictive state.
if (state_ == USER_LOGGED_IN_SCREEN_UNLOCKED)
state_ = USER_LOGGED_IN_BUT_SCREEN_LOCKED;
authorizer_.reset();
DenyNewDevices();
}
void EventHandler::OnScreenUnlocked() {
DCHECK(!authorizer_);
bool user_permission = UserPermissionOK();
std::lock_guard<std::mutex> lock(lock_);
LogEvent("Screen-Unlocked");
LOG(INFO) << "User-Permission = " << user_permission;
// It is important to have this state check, whenever we go from a more
// restrictive state to a less restrictive state to ensure that we always
// err on the cautious side should the events arrive or are processed out
// of order.
if (state_ == USER_LOGGED_IN_BUT_SCREEN_LOCKED) {
state_ = USER_LOGGED_IN_SCREEN_UNLOCKED;
if (user_permission) {
authorizer_ = std::make_unique<Authorizer>();
authorizer_->SubmitJob(Authorizer::AUTHORIZE_ALL_DEVICES,
base::FilePath(""));
}
}
}
void EventHandler::OnNewThunderboltDev(base::FilePath path) {
std::lock_guard<std::mutex> lock(lock_);
LogEvent("New-Thunderbolt-Dev");
LOG(INFO) << "path = " << path;
if (authorizer_)
authorizer_->SubmitJob(Authorizer::AUTHORIZE_1_DEVICE, path);
}
void EventHandler::OnUserPermissionChanged() {
bool user_permission = UserPermissionOK();
std::lock_guard<std::mutex> lock(lock_);
if (user_permission) {
LogEvent("User-Permission-Allowed");
// It is important to have this state check, whenever we go from a more
// restrictive state to a less restrictive state to ensure that we always
// err on the cautious side should the events arrive or are processed out
// of order.
if (state_ == USER_LOGGED_IN_SCREEN_UNLOCKED) {
if (!authorizer_) {
authorizer_ = std::make_unique<Authorizer>();
authorizer_->SubmitJob(Authorizer::AUTHORIZE_ALL_DEVICES,
base::FilePath(""));
}
}
} else {
LogEvent("User-Permission-Denied");
// No state check needed.
authorizer_.reset();
DeauthorizeAllDevices();
}
}
bool EventHandler::UserPermissionOK() {
// TODO(b/172397647): Actually talk to chrome to determine chrome flag value
// after chrome flag is implemented.
return true;
}
} // namespace pciguard