Leosac  0.8.0
Open Source Access Control
AuthFileInstance.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014-2016 Leosac
3 
4  This file is part of Leosac.
5 
6  Leosac is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Affero General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Leosac is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Affero General Public License for more details.
15 
16  You should have received a copy of the GNU Affero General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "AuthFileInstance.hpp"
21 #include "FileAuthSourceMapper.hpp"
22 #include "core/CoreUtils.hpp"
23 #include "core/Scheduler.hpp"
24 #include "core/SecurityContext.hpp"
25 #include "core/auth/Auth.hpp"
27 #include "core/auth/User.hpp"
30 #include "tools/Colorize.hpp"
31 #include "tools/log.hpp"
32 #include <boost/algorithm/string/join.hpp>
33 
34 using namespace Leosac::Module::Auth;
35 using namespace Leosac::Auth;
36 
38  std::string const &auth_ctx_name,
39  const std::list<std::string> &auth_sources_names,
40  std::string const &auth_target_name,
41  std::string const &input_file,
42  CoreUtilsPtr core_utils)
43  : mapper_(std::make_shared<FileAuthSourceMapper>(input_file))
44  , bus_push_(ctx, zmqpp::socket_type::push)
45  , bus_sub_(ctx, zmqpp::socket_type::sub)
46  , name_(auth_ctx_name)
47  , target_name_(auth_target_name)
48  , file_path_(input_file)
49  , core_utils_(core_utils)
50 {
51  bus_push_.connect("inproc://zmq-bus-pull");
52  bus_sub_.connect("inproc://zmq-bus-pub");
53 
54  bus_sub_.subscribe("KERNEL");
55 
56  INFO("Auth instance (" << auth_ctx_name << ") subscribe to "
57  << boost::algorithm::join(auth_sources_names, ", "));
58  for (const auto &auth_source : auth_sources_names)
59  bus_sub_.subscribe("S_" + auth_source);
60 }
61 
63 {
64  INFO("AuthFileInstance down");
65 }
66 
68 {
69  using namespace Colorize;
70  zmqpp::message msg;
71  zmqpp::message auth_result_msg;
72 
73  bus_sub_.receive(msg);
74  if (handle_kernel_message(msg))
75  return;
76 
77  auth_result_msg << ("S_" + name_);
78  auto auth_result = handle_auth(&msg);
79 
80  std::string log_user;
81  // output user id if available.
82  if (auth_result.user)
83  log_user = Colorize::green(auth_result.user->username());
84  else
85  log_user = Colorize::red("UNKNOWN_USER");
86 
87  if (auth_result.success)
88  {
89  auth_result_msg << Leosac::Auth::AccessStatus::GRANTED;
91  << " " << Colorize::green("GRANTED") << " access to target "
92  << Colorize::underline(target_name_) << " for " << log_user);
93  }
94  else
95  {
96  auth_result_msg << Leosac::Auth::AccessStatus::DENIED;
98  << " " << Colorize::red("DENIED") << " access to target "
99  << Colorize::underline(target_name_) << " for " << log_user);
100  }
101  bus_push_.send(auth_result_msg);
102 }
103 
105 {
106  return bus_sub_;
107 }
108 
109 AuthResult AuthFileInstance::handle_auth(zmqpp::message *msg) noexcept
110 {
111  try
112  {
113  std::lock_guard<std::mutex> guard(mutex_);
114 
115  AuthSourceBuilder build;
116  Cred::ICredentialPtr auth_source = build.create(msg);
117  DEBUG("Auth source OK... will map");
118  mapper_->mapToUser(auth_source);
119  DEBUG("Mapping done");
120  assert(auth_source);
121 
123  *auth_source, SystemSecurityContext::instance());
124  INFO("Using Credential: " << cred_serialized);
125  auto profile = mapper_->buildProfile(auth_source);
126 
127  if (!profile)
128  {
129  INFO("No profile was created from this auth source message.");
130  // assert(auth_source->owner() == nullptr);
131  return {false, nullptr, nullptr};
132  }
133  if (target_name_.empty())
134  {
135  // check against default target
136  return {
137  profile->isAccessGranted(std::chrono::system_clock::now(), nullptr),
138  profile, auth_source->owner().get_eager()};
139  }
140  else
141  {
143  return {profile->isAccessGranted(std::chrono::system_clock::now(), t),
144  profile, auth_source->owner().get_eager()};
145  }
146  }
147  catch (std::exception &e)
148  {
149  WARN("Exception when handling authentication request.");
150  log_exception(e);
151  }
152  return {false, nullptr, nullptr};
153 }
154 
156 {
157  std::ifstream t(file_path_);
158  std::stringstream buffer;
159  buffer << t.rdbuf();
160 
161  return buffer.str();
162 }
163 
164 const std::string &AuthFileInstance::auth_file_name() const
165 {
166  return file_path_;
167 }
168 
170 {
171  // The idea is to build a new mapper in an other thread
172  // and swap it with the current mapper once it is built.
173  // This is because building a new mapper can take a while.
174 
175  // We keep a shared_ptr to "this" in order to avoid dangling pointer to
176  // a non-existent instance (for example if the module was shutdown between
177  // the scheduling of the task and its execution).
178  auto self = shared_from_this();
179  auto file_path = file_path_;
180  auto task = Tasks::GenericTask::build([self, file_path]() {
181  try
182  {
183  auto mapper = std::make_shared<FileAuthSourceMapper>(file_path);
184  {
185  std::lock_guard<std::mutex> guard(self->mutex_);
186  self->mapper_ = mapper;
187  INFO("AuthFileInstance config reloaded.");
188  }
189  return true;
190  }
191  catch (const std::exception &e)
192  {
193  WARN("Problem when reloading AuthFileInstance configuration: "
194  << e.what());
195  return false;
196  }
197  });
198  core_utils_->scheduler().enqueue(task, TargetThread::POOL);
199 }
200 
201 bool AuthFileInstance::handle_kernel_message(const zmqpp::message &msg)
202 {
203  auto cp = msg.copy();
204  std::string tmp;
205  cp >> tmp;
206 
207  if (tmp == "KERNEL")
208  {
209  cp >> tmp;
210  if (tmp == "SIGHUP")
211  {
213  }
214  return true;
215  }
216  return false;
217 }
Leosac::Auth
Holds classes relevant to the Authentication and Authorization subsystem.
Definition: AccessPoint.hpp:27
Leosac::Auth::AuthTarget
Represent an object that we are authorizing against (a door).
Definition: AuthTarget.hpp:37
Leosac::Module::Auth::AuthFileInstance::reload_auth_config
void reload_auth_config()
Schedule an asynchronous reload of the module configuration file.
Definition: AuthFileInstance.cpp:169
Leosac::SystemSecurityContext::instance
static SecurityContext & instance()
Definition: SecurityContext.cpp:64
Leosac::Module::Auth::AuthResult
Definition: AuthFileInstance.hpp:39
Leosac::Auth::AuthSourceBuilder::create
virtual Cred::ICredentialPtr create(zmqpp::message *msg)
Create a Credential object from a message.
Definition: AuthSourceBuilder.cpp:52
Leosac::Module::Auth::AuthFileInstance::auth_file_name
const std::string & auth_file_name() const
Return the name of the file associated with the authenticator.
Definition: AuthFileInstance.cpp:164
Leosac::Module::Auth::AuthFileInstance::mapper_
FileAuthSourceMapperPtr mapper_
Authentication config file parser.
Definition: AuthFileInstance.hpp:153
Leosac::Module::Auth::AuthFileInstance::target_name_
std::string target_name_
Name of the target we auth against.
Definition: AuthFileInstance.hpp:173
WARN
@ WARN
Definition: log.hpp:33
zmqpp
Definition: CoreUtils.hpp:27
PolymorphicCredentialSerializer.hpp
Leosac::Module::Auth::AuthFileInstance::bus_push_
zmqpp::socket bus_push_
Socket to write to the bus.
Definition: AuthFileInstance.hpp:158
Leosac::Module::Auth::AuthFileInstance::file_path_
std::string file_path_
Path to the auth data file.
Definition: AuthFileInstance.hpp:178
Leosac::log_exception
void log_exception(const std::exception &e, int level=0)
Recursively log exceptions using the logging macro.
Definition: ExceptionsTools.cpp:62
Leosac::PolymorphicCredentialJSONStringSerializer::serialize
static std::string serialize(const Cred::ICredential &in, const SecurityContext &sc)
Definition: PolymorphicCredentialSerializer.cpp:102
DEBUG
@ DEBUG
Definition: log.hpp:35
Auth.hpp
AuthSourceBuilder.hpp
User.hpp
INFO
@ INFO
Definition: log.hpp:34
ExceptionsTools.hpp
Colorize.hpp
Scheduler.hpp
Leosac::Colorize::underline
std::string underline(const T &in)
Definition: Colorize.hpp:64
Leosac::Module::Auth::AuthFileInstance::core_utils_
CoreUtilsPtr core_utils_
Definition: AuthFileInstance.hpp:180
Leosac::Module::Auth::AuthFileInstance::auth_file_content
std::string auth_file_content() const
Return the content of the configuration file use for user/group and permission mapping.
Definition: AuthFileInstance.cpp:155
Leosac::Auth::AccessStatus::GRANTED
@ GRANTED
Leosac::Auth::AuthTargetPtr
std::shared_ptr< AuthTarget > AuthTargetPtr
Definition: AuthFwd.hpp:93
SecurityContext.hpp
Leosac::Module::Auth::AuthFileInstance::handle_kernel_message
bool handle_kernel_message(const zmqpp::message &msg)
Handle the message if its from Leosac's kernel, or does nothing.
Definition: AuthFileInstance.cpp:201
FileAuthSourceMapper.hpp
Leosac::Colorize::bold
std::string bold(const T &in)
Definition: Colorize.hpp:58
Leosac::Auth::AuthSourceBuilder
This class is some kind of factory to create IAuthenticationSource object from a zmqpp::message sent ...
Definition: AuthSourceBuilder.hpp:37
Leosac::Module::Auth::AuthFileInstance::mutex_
std::mutex mutex_
A mutex used only internally.
Definition: AuthFileInstance.hpp:148
Leosac::Module::Auth::AuthFileInstance::AuthFileInstance
AuthFileInstance(zmqpp::context &ctx, const std::string &auth_ctx_name, const std::list< std::string > &auth_sources_names, const std::string &auth_target_name, const std::string &input_file, CoreUtilsPtr core_utils)
Create a new Authenticator that watch a device and emit authentication message.
Definition: AuthFileInstance.cpp:37
Leosac::Colorize::green
std::string green(const T &in)
Definition: Colorize.hpp:82
Leosac::Tasks::GenericTask::build
static TaskPtr build(const Callable &callable)
Definition: GenericTask.hpp:41
Leosac::Module::Auth::AuthFileInstance::bus_sub
zmqpp::socket & bus_sub()
Returns the socket subscribed to the message bus.
Definition: AuthFileInstance.cpp:104
Leosac::Module::Auth::AuthFileInstance::handle_bus_msg
void handle_bus_msg()
Something happened on the bus that we have interest into.
Definition: AuthFileInstance.cpp:67
Leosac::Auth::AccessStatus::DENIED
@ DENIED
Leosac::Module::Auth::AuthFileInstance::handle_auth
AuthResult handle_auth(zmqpp::message *msg) noexcept
Prepare auth source object, map them to profile and check if access is granted.
Definition: AuthFileInstance.cpp:109
Leosac::Colorize::red
std::string red(const T &in)
Definition: Colorize.hpp:70
Leosac::Cred::ICredentialPtr
std::shared_ptr< ICredential > ICredentialPtr
Definition: CredentialFwd.hpp:32
Leosac::Module::Auth::AuthFileInstance::name_
std::string name_
Name of this auth context instance.
Definition: AuthFileInstance.hpp:168
log.hpp
CoreUtils.hpp
Leosac::Module::Auth::AuthFileInstance::~AuthFileInstance
~AuthFileInstance()
Definition: AuthFileInstance.cpp:62
Leosac::Module::Auth
Authentication backend modules live here.
Leosac::CoreUtilsPtr
std::shared_ptr< CoreUtils > CoreUtilsPtr
Definition: LeosacFwd.hpp:35
Leosac::Module::Auth::AuthFileInstance::bus_sub_
zmqpp::socket bus_sub_
Socket to read from the bus.
Definition: AuthFileInstance.hpp:163
Leosac::Module::Auth::FileAuthSourceMapper
Use a file to map auth source (card, PIN, etc) to user.
Definition: FileAuthSourceMapper.hpp:47
AuthFileInstance.hpp
Leosac::TargetThread::POOL
@ POOL