rippled
Loading...
Searching...
No Matches
Roles_test.cpp
1#include <test/jtx.h>
2#include <test/jtx/WSClient.h>
3
4#include <xrpl/beast/unit_test.h>
5
6#include <string>
7#include <unordered_map>
8
9namespace ripple {
10
11namespace test {
12
14{
15 bool
17 {
18 boost::system::error_code ec;
19 boost::asio::ip::make_address(addr, ec);
20 return !ec.failed();
21 }
22
23 void
25 {
26 using namespace test::jtx;
27
28 {
29 Env env(*this);
30
31 BEAST_EXPECT(env.rpc("ping")["result"]["role"] == "admin");
32 BEAST_EXPECT(makeWSClient(env.app().config())
33 ->invoke("ping")["result"]["unlimited"]
34 .asBool());
35 }
36 {
37 Env env{*this, envconfig(no_admin)};
38
39 BEAST_EXPECT(!env.rpc("ping")["result"].isMember("role"));
40 auto wsRes =
41 makeWSClient(env.app().config())->invoke("ping")["result"];
42 BEAST_EXPECT(
43 !wsRes.isMember("unlimited") || !wsRes["unlimited"].asBool());
44 }
45 {
46 Env env{*this, envconfig(secure_gateway)};
47
48 BEAST_EXPECT(env.rpc("ping")["result"]["role"] == "proxied");
49 auto wsRes =
50 makeWSClient(env.app().config())->invoke("ping")["result"];
51 BEAST_EXPECT(
52 !wsRes.isMember("unlimited") || !wsRes["unlimited"].asBool());
53
55 Json::Value rpcRes;
56
57 // IPv4 tests.
58 headers["X-Forwarded-For"] = "12.34.56.78";
59 rpcRes = env.rpc(headers, "ping")["result"];
60 BEAST_EXPECT(rpcRes["role"] == "proxied");
61 BEAST_EXPECT(rpcRes["ip"] == "12.34.56.78");
62 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
63
64 headers["X-Forwarded-For"] = "87.65.43.21, 44.33.22.11";
65 rpcRes = env.rpc(headers, "ping")["result"];
66 BEAST_EXPECT(rpcRes["ip"] == "87.65.43.21");
67 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
68
69 headers["X-Forwarded-For"] = "87.65.43.21:47011, 44.33.22.11";
70 rpcRes = env.rpc(headers, "ping")["result"];
71 BEAST_EXPECT(rpcRes["ip"] == "87.65.43.21");
72 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
73
74 headers = {};
75 headers["Forwarded"] = "for=88.77.66.55";
76 rpcRes = env.rpc(headers, "ping")["result"];
77 BEAST_EXPECT(rpcRes["ip"] == "88.77.66.55");
78 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
79
80 headers["Forwarded"] =
81 "what=where;for=55.66.77.88;for=nobody;"
82 "who=3";
83 rpcRes = env.rpc(headers, "ping")["result"];
84 BEAST_EXPECT(rpcRes["ip"] == "55.66.77.88");
85 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
86
87 headers["Forwarded"] =
88 "what=where; for=55.66.77.88, for=99.00.11.22;"
89 "who=3";
90 rpcRes = env.rpc(headers, "ping")["result"];
91 BEAST_EXPECT(rpcRes["ip"] == "55.66.77.88");
92 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
93
94 headers["Forwarded"] =
95 "what=where; For=99.88.77.66, for=55.66.77.88;"
96 "who=3";
97 rpcRes = env.rpc(headers, "ping")["result"];
98 BEAST_EXPECT(rpcRes["ip"] == "99.88.77.66");
99 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
100
101 headers["Forwarded"] =
102 "what=where; for=\"55.66.77.88:47011\";"
103 "who=3";
104 rpcRes = env.rpc(headers, "ping")["result"];
105 BEAST_EXPECT(rpcRes["ip"] == "55.66.77.88");
106 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
107
108 headers["Forwarded"] =
109 "what=where; For= \" 99.88.77.66 \" ,for=11.22.33.44;"
110 "who=3";
111 rpcRes = env.rpc(headers, "ping")["result"];
112 BEAST_EXPECT(rpcRes["ip"] == "99.88.77.66");
113 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
114
115 wsRes = makeWSClient(env.app().config(), true, 2, headers)
116 ->invoke("ping")["result"];
117 BEAST_EXPECT(
118 !wsRes.isMember("unlimited") || !wsRes["unlimited"].asBool());
119
120 std::string const name = "xrposhi";
121 headers["X-User"] = name;
122 rpcRes = env.rpc(headers, "ping")["result"];
123 BEAST_EXPECT(rpcRes["role"] == "identified");
124 BEAST_EXPECT(rpcRes["username"] == name);
125 BEAST_EXPECT(rpcRes["ip"] == "99.88.77.66");
126 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
127 wsRes = makeWSClient(env.app().config(), true, 2, headers)
128 ->invoke("ping")["result"];
129 BEAST_EXPECT(wsRes["unlimited"].asBool());
130
131 // IPv6 tests.
132 headers = {};
133 headers["X-Forwarded-For"] =
134 "2001:db8:3333:4444:5555:6666:7777:8888";
135 rpcRes = env.rpc(headers, "ping")["result"];
136 BEAST_EXPECT(rpcRes["role"] == "proxied");
137 BEAST_EXPECT(
138 rpcRes["ip"] == "2001:db8:3333:4444:5555:6666:7777:8888");
139 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
140
141 headers["X-Forwarded-For"] =
142 "2001:db8:3333:4444:5555:6666:7777:9999, a:b:c:d:e:f, "
143 "g:h:i:j:k:l";
144 rpcRes = env.rpc(headers, "ping")["result"];
145 BEAST_EXPECT(rpcRes["role"] == "proxied");
146 BEAST_EXPECT(
147 rpcRes["ip"] == "2001:db8:3333:4444:5555:6666:7777:9999");
148 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
149
150 headers["X-Forwarded-For"] =
151 "[2001:db8:3333:4444:5555:6666:7777:8888]";
152 rpcRes = env.rpc(headers, "ping")["result"];
153 BEAST_EXPECT(rpcRes["role"] == "proxied");
154 BEAST_EXPECT(
155 rpcRes["ip"] == "2001:db8:3333:4444:5555:6666:7777:8888");
156 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
157
158 headers["X-Forwarded-For"] =
159 "[2001:db8:3333:4444:5555:6666:7777:9999], [a:b:c:d:e:f], "
160 "[g:h:i:j:k:l]";
161 rpcRes = env.rpc(headers, "ping")["result"];
162 BEAST_EXPECT(rpcRes["role"] == "proxied");
163 BEAST_EXPECT(
164 rpcRes["ip"] == "2001:db8:3333:4444:5555:6666:7777:9999");
165 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
166
167 headers = {};
168 headers["Forwarded"] =
169 "for=\"[2001:db8:3333:4444:5555:6666:7777:aaaa]\"";
170 rpcRes = env.rpc(headers, "ping")["result"];
171 BEAST_EXPECT(rpcRes["role"] == "proxied");
172 BEAST_EXPECT(
173 rpcRes["ip"] == "2001:db8:3333:4444:5555:6666:7777:aaaa");
174 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
175
176 headers["Forwarded"] =
177 "For=\"[2001:db8:bb:cc:dd:ee:ff::]:2345\", for=99.00.11.22";
178 rpcRes = env.rpc(headers, "ping")["result"];
179 BEAST_EXPECT(rpcRes["role"] == "proxied");
180 BEAST_EXPECT(rpcRes["ip"] == "2001:db8:bb:cc:dd:ee:ff::");
181 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
182
183 headers["Forwarded"] =
184 "proto=http;FOR=\"[2001:db8:11:22:33:44:55:66]\""
185 ";by=203.0.113.43";
186 rpcRes = env.rpc(headers, "ping")["result"];
187 BEAST_EXPECT(rpcRes["role"] == "proxied");
188 BEAST_EXPECT(rpcRes["ip"] == "2001:db8:11:22:33:44:55:66");
189 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
190
191 // IPv6 (dual) tests.
192 headers = {};
193 headers["X-Forwarded-For"] = "2001:db8:3333:4444:5555:6666:1.2.3.4";
194 rpcRes = env.rpc(headers, "ping")["result"];
195 BEAST_EXPECT(rpcRes["role"] == "proxied");
196 BEAST_EXPECT(
197 rpcRes["ip"] == "2001:db8:3333:4444:5555:6666:1.2.3.4");
198 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
199
200 headers["X-Forwarded-For"] =
201 "2001:db8:3333:4444:5555:6666:5.6.7.8, a:b:c:d:e:f, "
202 "g:h:i:j:k:l";
203 rpcRes = env.rpc(headers, "ping")["result"];
204 BEAST_EXPECT(rpcRes["role"] == "proxied");
205 BEAST_EXPECT(
206 rpcRes["ip"] == "2001:db8:3333:4444:5555:6666:5.6.7.8");
207 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
208
209 headers["X-Forwarded-For"] =
210 "[2001:db8:3333:4444:5555:6666:9.10.11.12]";
211 rpcRes = env.rpc(headers, "ping")["result"];
212 BEAST_EXPECT(rpcRes["role"] == "proxied");
213 BEAST_EXPECT(
214 rpcRes["ip"] == "2001:db8:3333:4444:5555:6666:9.10.11.12");
215 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
216
217 headers["X-Forwarded-For"] =
218 "[2001:db8:3333:4444:5555:6666:13.14.15.16], [a:b:c:d:e:f], "
219 "[g:h:i:j:k:l]";
220 rpcRes = env.rpc(headers, "ping")["result"];
221 BEAST_EXPECT(rpcRes["role"] == "proxied");
222 BEAST_EXPECT(
223 rpcRes["ip"] == "2001:db8:3333:4444:5555:6666:13.14.15.16");
224 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
225
226 headers = {};
227 headers["Forwarded"] =
228 "for=\"[2001:db8:3333:4444:5555:6666:20.19.18.17]\"";
229 rpcRes = env.rpc(headers, "ping")["result"];
230 BEAST_EXPECT(rpcRes["role"] == "proxied");
231 BEAST_EXPECT(
232 rpcRes["ip"] == "2001:db8:3333:4444:5555:6666:20.19.18.17");
233 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
234
235 headers["Forwarded"] =
236 "For=\"[2001:db8:bb:cc::24.23.22.21]\", for=99.00.11.22";
237 rpcRes = env.rpc(headers, "ping")["result"];
238 BEAST_EXPECT(rpcRes["role"] == "proxied");
239 BEAST_EXPECT(rpcRes["ip"] == "2001:db8:bb:cc::24.23.22.21");
240 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
241
242 headers["Forwarded"] =
243 "proto=http;FOR=\"[::11:22:33:44:45.55.65.75]:234\""
244 ";by=203.0.113.43";
245 rpcRes = env.rpc(headers, "ping")["result"];
246 BEAST_EXPECT(rpcRes["role"] == "proxied");
247 BEAST_EXPECT(rpcRes["ip"] == "::11:22:33:44:45.55.65.75");
248 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
249 }
250
251 {
252 Env env{*this, envconfig(admin_localnet)};
253 BEAST_EXPECT(env.rpc("ping")["result"]["role"] == "admin");
254 BEAST_EXPECT(makeWSClient(env.app().config())
255 ->invoke("ping")["result"]["unlimited"]
256 .asBool());
257 }
258
259 {
261 BEAST_EXPECT(env.rpc("ping")["result"]["role"] == "proxied");
262 auto wsRes =
263 makeWSClient(env.app().config())->invoke("ping")["result"];
264 BEAST_EXPECT(
265 !wsRes.isMember("unlimited") || !wsRes["unlimited"].asBool());
266
268 headers["X-Forwarded-For"] = "12.34.56.78";
269 Json::Value rpcRes = env.rpc(headers, "ping")["result"];
270 BEAST_EXPECT(rpcRes["role"] == "proxied");
271 BEAST_EXPECT(rpcRes["ip"] == "12.34.56.78");
272 BEAST_EXPECT(isValidIpAddress(rpcRes["ip"].asString()));
273 }
274 }
275
276 void
278 {
279 using namespace test::jtx;
280
281 {
282 Env env(*this);
283
285 Json::Value rpcRes;
286
287 // No "for=" in Forwarded.
288 headers["Forwarded"] = "for 88.77.66.55";
289 rpcRes = env.rpc(headers, "ping")["result"];
290 BEAST_EXPECT(rpcRes["role"] == "admin");
291 BEAST_EXPECT(!rpcRes.isMember("ip"));
292
293 headers["Forwarded"] = "by=88.77.66.55";
294 rpcRes = env.rpc(headers, "ping")["result"];
295 BEAST_EXPECT(rpcRes["role"] == "admin");
296 BEAST_EXPECT(!rpcRes.isMember("ip"));
297
298 // Empty field.
299 headers = {};
300 headers["Forwarded"] = "for=";
301 rpcRes = env.rpc(headers, "ping")["result"];
302 BEAST_EXPECT(rpcRes["role"] == "admin");
303 BEAST_EXPECT(!rpcRes.isMember("ip"));
304
305 headers = {};
306 headers["X-Forwarded-For"] = " ";
307 rpcRes = env.rpc(headers, "ping")["result"];
308 BEAST_EXPECT(rpcRes["role"] == "admin");
309 BEAST_EXPECT(!rpcRes.isMember("ip"));
310
311 // Empty quotes.
312 headers = {};
313 headers["Forwarded"] = "for= \" \" ";
314 rpcRes = env.rpc(headers, "ping")["result"];
315 BEAST_EXPECT(rpcRes["role"] == "admin");
316 BEAST_EXPECT(!rpcRes.isMember("ip"));
317
318 headers = {};
319 headers["X-Forwarded-For"] = "\"\"";
320 rpcRes = env.rpc(headers, "ping")["result"];
321 BEAST_EXPECT(rpcRes["role"] == "admin");
322 BEAST_EXPECT(!rpcRes.isMember("ip"));
323
324 // Unbalanced outer quotes.
325 headers = {};
326 headers["X-Forwarded-For"] = "\"12.34.56.78 ";
327 rpcRes = env.rpc(headers, "ping")["result"];
328 BEAST_EXPECT(rpcRes["role"] == "admin");
329 BEAST_EXPECT(!rpcRes.isMember("ip"));
330
331 headers["X-Forwarded-For"] = "12.34.56.78\"";
332 rpcRes = env.rpc(headers, "ping")["result"];
333 BEAST_EXPECT(rpcRes["role"] == "admin");
334 BEAST_EXPECT(!rpcRes.isMember("ip"));
335
336 // Unbalanced square brackets for IPv6.
337 headers = {};
338 headers["Forwarded"] = "FOR=[2001:db8:bb:cc::";
339 rpcRes = env.rpc(headers, "ping")["result"];
340 BEAST_EXPECT(rpcRes["role"] == "admin");
341 BEAST_EXPECT(!rpcRes.isMember("ip"));
342
343 headers = {};
344 headers["X-Forwarded-For"] = "2001:db8:bb:cc::24.23.22.21]";
345 rpcRes = env.rpc(headers, "ping")["result"];
346 BEAST_EXPECT(rpcRes["role"] == "admin");
347 BEAST_EXPECT(!rpcRes.isMember("ip"));
348
349 // Empty square brackets.
350 headers = {};
351 headers["Forwarded"] = "FOR=[]";
352 rpcRes = env.rpc(headers, "ping")["result"];
353 BEAST_EXPECT(rpcRes["role"] == "admin");
354 BEAST_EXPECT(!rpcRes.isMember("ip"));
355
356 headers = {};
357 headers["X-Forwarded-For"] = "\" [ ] \"";
358 rpcRes = env.rpc(headers, "ping")["result"];
359 BEAST_EXPECT(rpcRes["role"] == "admin");
360 BEAST_EXPECT(!rpcRes.isMember("ip"));
361 }
362 }
363
364public:
365 void
366 run() override
367 {
368 testRoles();
370 }
371};
372
373BEAST_DEFINE_TESTSUITE(Roles, rpc, ripple);
374
375} // namespace test
376
377} // namespace ripple
Represents a JSON value.
Definition json_value.h:130
bool isMember(char const *key) const
Return true if the object has a member named key.
A testsuite class.
Definition suite.h:52
virtual Config & config()=0
bool isValidIpAddress(std::string const &addr)
void run() override
Runs the suite.
A transaction testing environment.
Definition Env.h:102
Application & app()
Definition Env.h:242
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
Definition Env.h:772
Set the expected result code for a JTx The test will fail if the code doesn't match.
Definition rpc.h:16
std::unique_ptr< Config > admin_localnet(std::unique_ptr< Config >)
Definition envconfig.cpp:74
std::unique_ptr< Config > secure_gateway(std::unique_ptr< Config >)
Definition envconfig.cpp:65
std::unique_ptr< Config > no_admin(std::unique_ptr< Config >)
adjust config so no admin ports are enabled
Definition envconfig.cpp:57
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition envconfig.h:35
std::unique_ptr< Config > secure_gateway_localnet(std::unique_ptr< Config >)
Definition envconfig.cpp:82
std::unique_ptr< WSClient > makeWSClient(Config const &cfg, bool v2, unsigned rpc_version, std::unordered_map< std::string, std::string > const &headers)
Returns a client operating through WebSockets/S.
Definition WSClient.cpp:304
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6