Leosac  0.8.0
Open Source Access Control
WebServiceNotifier.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 "WebServiceNotifier.hpp"
21 #include "core/auth/Auth.hpp"
23 #include <curl/curl.h>
24 
25 using namespace Leosac;
26 using namespace Leosac::Module;
27 using namespace Leosac::Module::WSNotifier;
28 
29 WebServiceNotifier::WebServiceNotifier(zmqpp::context &ctx, zmqpp::socket *pipe,
30  const boost::property_tree::ptree &cfg,
31  CoreUtilsPtr utils)
32  : BaseModule(ctx, pipe, cfg, utils)
33  , bus_sub_(ctx, zmqpp::socket_type::sub)
34 {
35  int ret;
36  long flags = 0;
37 
38  if (config_.get<bool>("module_config.want_ssl", true))
39  flags |= CURL_GLOBAL_SSL;
40  if ((ret = curl_global_init(flags)) != 0)
41  {
42  throw std::runtime_error("Failed to initialize curl: return code: " +
43  std::to_string(ret));
44  }
45  bus_sub_.connect("inproc://zmq-bus-pub");
48 }
49 
51 {
52  curl_global_cleanup();
53 }
54 
56 {
57  zmqpp::message msg;
58  std::string src;
60  std::string card;
61  int bits;
62 
63  bus_sub_.receive(msg);
64  if (msg.parts() < 4)
65  {
66  WARN("Unexpected message content.");
67  return;
68  }
69  msg >> src >> type >> card >> bits;
71  {
72  INFO("WS-Notifier cannot handle this type of credential yet.");
73  return;
74  }
75 
76  send_card_info_to_remote(src, card, bits);
77 }
78 
80 {
81  for (auto &&itr : config_.get_child("module_config.sources"))
82  {
83  auto name = itr.second.get<std::string>("");
84  bus_sub_.subscribe("S_" + name);
85  }
86 
87  for (auto &&itr : config_.get_child("module_config.targets"))
88  {
89  TargetInfo target;
90  target.url_ = itr.second.get<std::string>("url");
91  target.connect_timeout_ = itr.second.get<int>("connect_timeout", 7000);
92  target.request_timeout_ = itr.second.get<int>("request_timeout", 7000);
93  target.verify_host_ = itr.second.get<bool>("verify_host", true);
94  target.verify_peer_ = itr.second.get<bool>("verify_peer", true);
95  target.CA_info_file_ = itr.second.get<std::string>("ca_file", "");
96 
97  INFO("WS-Notifier remote target: "
98  << Colorize::green(target.url_)
99  << " (connect_timeout: " << Colorize::green(target.connect_timeout_)
100  << ", request_timeout: " << Colorize::green(target.request_timeout_)
101  << ", verify_host: " << Colorize::green(target.verify_host_)
102  << ", verify_peer: " << Colorize::green(target.verify_peer_)
103  << ", ca_info: " << Colorize::green(target.CA_info_file_) << ")");
104  targets_.push_back(std::move(target));
105  }
106 }
107 
108 void WebServiceNotifier::send_card_info_to_remote(const std::string &auth_source,
109  const std::string &card_hex,
110  int nb_bits)
111 {
112  auto card = Cred::RFIDCard();
113  card.card_id(card_hex);
114  card.nb_bits(nb_bits);
115 
116  for (const auto &target : targets_)
117  {
118  auto curl = curl_easy_init();
119  if (curl)
120  {
121  if (!target.CA_info_file_.empty())
122  curl_easy_setopt(curl, CURLOPT_CAINFO, target.CA_info_file_.c_str());
123  if (!target.verify_host_)
124  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
125  if (!target.verify_peer_)
126  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
127  send_to_target(curl, auth_source, card, target);
128  curl_easy_cleanup(curl);
129  }
130  else
131  {
132  ERROR("Cannot initialize curl_easy.");
133  }
134  }
135 }
136 
142 static size_t write_callback(char * /*ptr*/, size_t size, size_t nmemb,
143  void * /*userdata*/)
144 {
145  return size * nmemb;
146 }
147 
149  void *curl, const std::string &auth_source, const Cred::RFIDCard &card,
150  const WebServiceNotifier::TargetInfo &target) noexcept
151 {
152  assert(curl);
153 
154  std::string post_fields =
155  fmt::format("card_id={}&auth_source={}&card_id_raw={}", card.to_int(),
156  auth_source, card.to_raw_int());
157 
158  curl_easy_setopt(curl, CURLOPT_URL, target.url_.c_str());
159  curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_fields.c_str());
160 
161  // timeouts
162  curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, target.connect_timeout_);
163  curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, target.request_timeout_);
164 
165  curl_easy_setopt(curl, CURLOPT_WRITEDATA, nullptr);
166  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_callback);
167 
168  auto res = curl_easy_perform(curl);
169  if (res != CURLE_OK)
170  {
171  WARN("curl_easy_perform() failed: " << curl_easy_strerror(res));
172  }
173 }
Leosac::Module::WSNotifier::WebServiceNotifier::TargetInfo::url_
std::string url_
Definition: WebServiceNotifier.hpp:69
Leosac::Module::WSNotifier::WebServiceNotifier::handle_msg_bus
void handle_msg_bus()
Process a message that was read on the bus.
Definition: WebServiceNotifier.cpp:55
Leosac::Module::BaseModule
Base class for module implementation.
Definition: BaseModule.hpp:110
WARN
@ WARN
Definition: log.hpp:33
zmqpp
Definition: CoreUtils.hpp:27
Leosac::Module::WSNotifier::WebServiceNotifier::TargetInfo::verify_peer_
bool verify_peer_
If SSL is enabled, do we perform certificate validation ?
Definition: WebServiceNotifier.hpp:79
ERROR
@ ERROR
Definition: log.hpp:32
Auth.hpp
Leosac::Module::WSNotifier::WebServiceNotifier::WebServiceNotifier
WebServiceNotifier(zmqpp::context &ctx, zmqpp::socket *pipe, const boost::property_tree::ptree &cfg, CoreUtilsPtr utils)
Definition: WebServiceNotifier.cpp:29
RFIDCard.hpp
INFO
@ INFO
Definition: log.hpp:34
Leosac::Module::WSNotifier::WebServiceNotifier::TargetInfo::request_timeout_
int request_timeout_
Definition: WebServiceNotifier.hpp:71
Leosac::Module::WSNotifier::WebServiceNotifier::~WebServiceNotifier
~WebServiceNotifier()
Definition: WebServiceNotifier.cpp:50
Leosac::Cred::RFIDCard
An RFID card credential.
Definition: RFIDCard.hpp:33
Leosac::Module
All modules that provides features to Leosac shall be in this namespace.
Leosac
This is the header file for a generated source file, GitSHA1.cpp.
Definition: APIStatusCode.hpp:22
Leosac::Module::WSNotifier::WebServiceNotifier::send_to_target
void send_to_target(void *curl, const std::string &auth_source, const Cred::RFIDCard &card, const TargetInfo &target) noexcept
Definition: WebServiceNotifier.cpp:148
Leosac::Module::WSNotifier::WebServiceNotifier::bus_sub_
zmqpp::socket bus_sub_
Read internal message bus.
Definition: WebServiceNotifier.hpp:62
Leosac::Module::BaseModule::config_
boost::property_tree::ptree config_
The configuration tree passed to the start_module function.
Definition: BaseModule.hpp:193
Leosac::Module::BaseModule::reactor_
zmqpp::reactor reactor_
The reactor object we poll() on in the main loop.
Definition: BaseModule.hpp:214
Leosac::Colorize::green
std::string green(const T &in)
Definition: Colorize.hpp:82
Leosac::Module::WSNotifier::WebServiceNotifier::targets_
std::vector< TargetInfo > targets_
Definition: WebServiceNotifier.hpp:86
Leosac::Module::WSNotifier::WebServiceNotifier::TargetInfo::connect_timeout_
int connect_timeout_
Definition: WebServiceNotifier.hpp:70
Leosac::Module::WSNotifier::WebServiceNotifier::TargetInfo
Some information for each webservice target.
Definition: WebServiceNotifier.hpp:67
Leosac::Colorize::detail::format
std::string format(const std::string &escape_code, const T &in)
Return a string containing the escape code, a string representation of T and the clear escape string.
Definition: Colorize.hpp:49
Leosac::Module::WSNotifier::WebServiceNotifier::process_config
void process_config()
Process the configuration file.
Definition: WebServiceNotifier.cpp:79
Leosac::Module::WSNotifier
Definition: WebServiceNotifier.hpp:30
WebServiceNotifier.hpp
Leosac::Module::WSNotifier::WebServiceNotifier::TargetInfo::CA_info_file_
std::string CA_info_file_
Path to a CA bundle file.
Definition: WebServiceNotifier.hpp:83
Leosac::Module::WSNotifier::WebServiceNotifier::TargetInfo::verify_host_
bool verify_host_
If SSL is enabled, do we perform certificate hostname validation ?
Definition: WebServiceNotifier.hpp:75
Leosac::Auth::SourceType
SourceType
Definition: Auth.hpp:29
Leosac::Module::WSNotifier::WebServiceNotifier::send_card_info_to_remote
void send_card_info_to_remote(const std::string &auth_source, const std::string &card, int nb_bits)
Send an HTTP request to the remote webservice to let it know a card was read.
Definition: WebServiceNotifier.cpp:108
Leosac::CoreUtilsPtr
std::shared_ptr< CoreUtils > CoreUtilsPtr
Definition: LeosacFwd.hpp:35
Leosac::Auth::SourceType::SIMPLE_WIEGAND
@ SIMPLE_WIEGAND
This define message formatting for data source SIMPLE_WIEGAND.