• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef SRC_PERMISSION_FS_PERMISSION_H_
2 #define SRC_PERMISSION_FS_PERMISSION_H_
3 
4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5 
6 #include "v8.h"
7 
8 #include <unordered_map>
9 #include "permission/permission_base.h"
10 #include "util.h"
11 
12 namespace node {
13 
14 namespace permission {
15 
16 class FSPermission final : public PermissionBase {
17  public:
18   void Apply(const std::string& allow, PermissionScope scope) override;
19   bool is_granted(PermissionScope perm, const std::string_view& param) override;
20 
21   struct RadixTree {
22     struct Node {
23       std::string prefix;
24       std::unordered_map<char, Node*> children;
25       Node* wildcard_child;
26 
NodeRadixTree::Node27       explicit Node(const std::string& pre)
28           : prefix(pre), wildcard_child(nullptr) {}
29 
NodeRadixTree::Node30       Node() : wildcard_child(nullptr) {}
31 
CreateChildRadixTree::Node32       Node* CreateChild(std::string prefix) {
33         char label = prefix[0];
34 
35         Node* child = children[label];
36         if (child == nullptr) {
37           children[label] = new Node(prefix);
38           return children[label];
39         }
40 
41         // swap prefix
42         unsigned int i = 0;
43         unsigned int prefix_len = prefix.length();
44         for (; i < child->prefix.length(); ++i) {
45           if (i > prefix_len || prefix[i] != child->prefix[i]) {
46             std::string parent_prefix = child->prefix.substr(0, i);
47             std::string child_prefix = child->prefix.substr(i);
48 
49             child->prefix = child_prefix;
50             Node* split_child = new Node(parent_prefix);
51             split_child->children[child_prefix[0]] = child;
52             children[parent_prefix[0]] = split_child;
53 
54             return split_child->CreateChild(prefix.substr(i));
55           }
56         }
57         return child->CreateChild(prefix.substr(i));
58       }
59 
CreateWildcardChildRadixTree::Node60       Node* CreateWildcardChild() {
61         if (wildcard_child != nullptr) {
62           return wildcard_child;
63         }
64         wildcard_child = new Node();
65         return wildcard_child;
66       }
67 
NextNodeRadixTree::Node68       Node* NextNode(const std::string& path, unsigned int idx) {
69         if (idx >= path.length()) {
70           return nullptr;
71         }
72 
73         auto it = children.find(path[idx]);
74         if (it == children.end()) {
75           return nullptr;
76         }
77         auto child = it->second;
78         // match prefix
79         unsigned int prefix_len = child->prefix.length();
80         for (unsigned int i = 0; i < path.length(); ++i) {
81           if (i >= prefix_len || child->prefix[i] == '*') {
82             return child;
83           }
84 
85           // Handle optional trailing
86           // path = /home/subdirectory
87           // child = subdirectory/*
88           if (idx >= path.length() &&
89               child->prefix[i] == node::kPathSeparator) {
90             continue;
91           }
92 
93           if (path[idx++] != child->prefix[i]) {
94             return nullptr;
95           }
96         }
97         return child;
98       }
99 
100       // A node can be a *end* node and have children
101       // E.g: */slower*, */slown* are inserted:
102       // /slow
103       // ---> er
104       // ---> n
105       // If */slow* is inserted right after, it will create an
106       // empty node
107       // /slow
108       // ---> '\000' ASCII (0) || \0
109       // ---> er
110       // ---> n
IsEndNodeRadixTree::Node111       bool IsEndNode() {
112         if (children.size() == 0) {
113           return true;
114         }
115         return children['\0'] != nullptr;
116       }
117     };
118 
119     RadixTree();
120     ~RadixTree();
121     void Insert(const std::string& s);
LookupRadixTree122     bool Lookup(const std::string_view& s) { return Lookup(s, false); }
123     bool Lookup(const std::string_view& s, bool when_empty_return);
124 
125    private:
126     Node* root_node_;
127   };
128 
129  private:
130   void GrantAccess(PermissionScope scope, const std::string& param);
131   // fs granted on startup
132   RadixTree granted_in_fs_;
133   RadixTree granted_out_fs_;
134 
135   bool deny_all_in_ = true;
136   bool deny_all_out_ = true;
137 
138   bool allow_all_in_ = false;
139   bool allow_all_out_ = false;
140 };
141 
142 }  // namespace permission
143 
144 }  // namespace node
145 
146 #endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
147 #endif  // SRC_PERMISSION_FS_PERMISSION_H_
148