Config.cc
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
17 #include "Config.hh"
18 #include "Config.ih"
19 
20 // Custom includes
21 #include <senf/Utils/membind.hh>
22 
23 //#include "Config.mpp"
24 #define prefix_
25 //-/////////////////////////////////////////////////////////////////////////////////////////////////
26 
27 //-/////////////////////////////////////////////////////////////////////////////////////////////////
28 // senf::console::detail::RestrictedExecutor
29 
30 prefix_ senf::console::detail::RestrictedExecutor::RestrictedExecutor(DirectoryNode & root)
31 {
32  executor_
33  .chroot(root)
34  .policy(senf::membind(&RestrictedExecutor::policyCallback, this));
35 }
36 
37 prefix_ void
38 senf::console::detail::RestrictedExecutor::execute(std::ostream & output,
39  ParseCommandInfo const & command)
40 {
41  executor_.execute(output, command);
42 }
43 
44 prefix_ void
45 senf::console::detail::RestrictedExecutor::operator()(std::ostream & output,
46  ParseCommandInfo const & command)
47 {
48  execute(output, command);
49 }
50 
52 senf::console::detail::RestrictedExecutor::getNode(ParseCommandInfo const & command)
53 {
54  return executor_.getNode(command);
55 }
56 
57 prefix_ bool senf::console::detail::RestrictedExecutor::parsed(GenericNode & node)
58  const
59 {
60  ParsedNodes::const_iterator i (parsedNodes_.begin());
61  ParsedNodes::const_iterator const i_end (parsedNodes_.end());
62  for (; i != i_end; ++i)
63  if ( ! i->expired() && node.isChildOf(*(i->lock())) )
64  return true;
65  return false;
66 }
67 
68 prefix_ void senf::console::detail::RestrictedExecutor::policyCallback(DirectoryNode & dir,
69  std::string const & name)
70 {
71  if (dir.hasChild(name)) {
72  GenericNode & item (dir.get(name));
73  if (restrict_ && ! item.isChildOf(*restrict_) && ! item.isDirectory())
74  throw Executor::IgnoreCommandException();
75  if (parsed(item))
76  throw Executor::IgnoreCommandException();
77  }
78  else if (restrict_ && ! dir.isChildOf(*restrict_))
79  throw Executor::IgnoreCommandException();
80 }
81 
82 namespace {
83  struct RemoveNodesFn
84  {
85  RemoveNodesFn(senf::console::DirectoryNode::ptr newNode) : newNode_ (newNode) {}
86 
87  bool operator()(senf::console::DirectoryNode::weak_ptr node) const
88  { return node.expired() || node.lock()->isChildOf(*newNode_); }
89 
91  };
92 }
93 
94 prefix_ void
95 senf::console::detail::RestrictedExecutor::insertParsedNode(DirectoryNode & node)
96 {
97  parsedNodes_.erase(
98  std::remove_if(parsedNodes_.begin(), parsedNodes_.end(), RemoveNodesFn(node.thisptr())),
99  parsedNodes_.end());
100  parsedNodes_.push_back(node.thisptr());
101 }
102 
103 //-/////////////////////////////////////////////////////////////////////////////////////////////////
104 // senf::console::ConfigBundle
105 
107 {
108  detail::RestrictedExecutor::RestrictGuard guard (executor_);
109  parseInternal();
110 }
111 
113 {
114  detail::RestrictedExecutor::RestrictGuard guard (executor_, restrict);
115  parseInternal();
116 }
117 
118 prefix_ void senf::console::ConfigBundle::parseInternal()
119 {
120  // It is valid to add additional sources at the end while parsing ...
121  for (Sources::const_iterator i (sources_.begin()); i != sources_.end(); ++i)
122  (*i)->parse(executor_);
123 }
124 
125 //-/////////////////////////////////////////////////////////////////////////////////////////////////
126 // senf::console::detail::RestrictedExecutor::RestrictGuard
127 
128 prefix_ senf::console::detail::RestrictedExecutor::RestrictGuard::
129 RestrictGuard(RestrictedExecutor & executor)
130  : executor_ (executor)
131 {
132  // This MUST BE root() not chroot() since restriction does NOT follow symlinks.
133  // Therefore, if chroot() is a directory of symlinks, restricting to it will
134  // execute NOTHING.
135  executor_.restrict_ = console::root().thisptr();
136 }
137 
138 prefix_ senf::console::detail::RestrictedExecutor::RestrictGuard::
139 RestrictGuard(RestrictedExecutor & executor, DirectoryNode & restrict)
140  : executor_ (executor)
141 {
142  executor_.restrict_ = restrict.thisptr();
143 }
144 
145 prefix_ senf::console::detail::RestrictedExecutor::RestrictGuard::~RestrictGuard()
146 {
147  if (! std::uncaught_exception())
148  executor_.insertParsedNode( *executor_.restrict_ );
149  executor_.restrict_ = console::root().thisptr();
150 }
151 
152 //-/////////////////////////////////////////////////////////////////////////////////////////////////
153 // senf::console::detail::ConfigSource
154 
155 prefix_ senf::console::detail::ConfigSource::~ConfigSource()
156 {}
157 
158 //-/////////////////////////////////////////////////////////////////////////////////////////////////
159 #undef prefix_
160 //#include "Config.mpp"
161 
162 
163 // Local Variables:
164 // mode: c++
165 // fill-column: 100
166 // comment-column: 40
167 // c-file-style: "senf"
168 // indent-tabs-mode: nil
169 // ispell-local-dictionary: "american"
170 // compile-command: "scons -u test"
171 // End:
Config public header.
boost::shared_ptr< DirectoryNode > ptr
Definition: Node.hh:414
Config/console tree directory node.
Definition: Node.hh:406
boost::function< R(Args)> membind(R(T::*fn)(Args), T *ob)
#define prefix_
Definition: Config.cc:24
DirectoryNode & root()
Get console root node.
Definition: Node.cc:26
void parse()
Parse config bundle.
Definition: Config.cc:106
unspecified_keyword_type name
Argument name.
boost::weak_ptr< DirectoryNode > weak_ptr
Definition: Node.hh:416
Config/console node tree base-class.
Definition: Node.hh:250