acl.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #ifndef ACL_ACL_H
  15. #define ACL_ACL_H
  16. #include "check.h"
  17. #include <vector>
  18. #include <boost/shared_ptr.hpp>
  19. #include <boost/noncopyable.hpp>
  20. namespace isc {
  21. namespace acl {
  22. /**
  23. * \brief Default actions an ACL could perform.
  24. *
  25. * This is the default for the ACL class. It is possible to specify any other
  26. * data type, as the ACL class does nothing about them, but these look
  27. * reasonable, so they are provided for convenience. It is not specified what
  28. * exactly these mean and it's up to whoever uses them.
  29. */
  30. enum BasicAction {
  31. ACCEPT,
  32. REJECT,
  33. DROP
  34. };
  35. /**
  36. * \brief The ACL itself.
  37. *
  38. * It holds bunch of ordered entries, each one consisting of a check (
  39. * of any kind, it might be even compound) and an action that is returned
  40. * whenever the action matches. They are tested in the order and first
  41. * match counts.
  42. *
  43. * This is non-copyable. It seems that there's no need to copy them (even
  44. * when it would be technically possible), so we forbid it just to prevent
  45. * copying it by accident. If there really is legitimate use, this restriction
  46. * can be removed.
  47. *
  48. * The class is template. It is possible to specify on which context the checks
  49. * match and which actions it returns. The actions must be copyable
  50. * for this to work and it is expected to be something small, usually an enum
  51. * (but other objects are also possible).
  52. *
  53. * \note There are protected functions. In fact, you should consider them
  54. * private, they are protected so tests can get inside. This class
  55. * is not expected to be subclassed in real applications.
  56. */
  57. template<typename Context, typename Action = BasicAction> class ACL :
  58. public boost::noncopyable {
  59. public:
  60. /**
  61. * \brief Constructor.
  62. *
  63. * \param default_action It is the action that is returned when the checked
  64. * things "falls off" the end of the list (when no rule matched).
  65. */
  66. ACL(const Action& default_action) : default_action_(default_action)
  67. {}
  68. /**
  69. * \brief Pointer to the check.
  70. *
  71. * We use the shared pointer, because we are not able to copy the checks.
  72. * However, we might need to copy the entries (when we concatenate ACLs
  73. * together in future).
  74. */
  75. typedef boost::shared_ptr<const Check<Context> > ConstCheckPtr;
  76. /**
  77. * \brief The actual main function that decides.
  78. *
  79. * This is the function that takes the entries one by one, checks
  80. * the context against conditions and if it matches, returns the
  81. * action that belongs to the first matched entry or default action
  82. * if nothing matches.
  83. * \param context The thing that should be checked. It is directly
  84. * passed to the checks.
  85. */
  86. const Action& execute(const Context& context) const {
  87. const typename Entries::const_iterator end(entries_.end());
  88. for (typename Entries::const_iterator i(entries_.begin()); i != end;
  89. ++i) {
  90. if (i->first->matches(context)) {
  91. return (i->second);
  92. }
  93. }
  94. return (default_action_);
  95. }
  96. /**
  97. * \brief Add new entry at the end of the list.
  98. *
  99. * \note We currently allow only adding at the end. This is enough for now,
  100. * but we may need more when we start implementing some kind optimisations,
  101. * including replacements, reorderings and removals.
  102. *
  103. * \param check The check to test if the thing matches.
  104. * \param action The action to return when the thing matches this check.
  105. */
  106. void append(ConstCheckPtr check, const Action& action) {
  107. entries_.push_back(Entry(check, action));
  108. }
  109. private:
  110. // Just type abbreviations.
  111. typedef std::pair<ConstCheckPtr, Action> Entry;
  112. typedef std::vector<Entry> Entries;
  113. /// \brief The default action, when nothing mathes.
  114. const Action default_action_;
  115. /// \brief The entries we have.
  116. Entries entries_;
  117. protected:
  118. /**
  119. * \brief Get the default action.
  120. *
  121. * This is for testing purposes only.
  122. */
  123. const Action& getDefaultAction() const {
  124. return (default_action_);
  125. }
  126. };
  127. }
  128. }
  129. #endif