/src/curl_fuzzer/legacy_protocol_allowlist.cc
Line | Count | Source |
1 | | /* |
2 | | * Copyright (C) Max Dymond, <cmeister2@gmail.com>, et al. |
3 | | * |
4 | | * SPDX-License-Identifier: curl |
5 | | */ |
6 | | |
7 | | #include "legacy_protocol_allowlist.h" |
8 | | |
9 | | #include <curl/curl.h> |
10 | | |
11 | | #include <cstring> |
12 | | |
13 | | namespace legacy_protocol_allowlist { |
14 | | namespace { |
15 | | |
16 | | /* |
17 | | * This is a harness safety policy, rather than a copy of libcurl's protocol |
18 | | * registry. In particular, TELNET remains exclusive to the proto fuzzer |
19 | | * because the legacy harness cannot prevent it from reading stdin. New curl |
20 | | * protocols must likewise be reviewed before being added here. |
21 | | */ |
22 | | const char *const kIntendedProtocols[] = { |
23 | | "dict", "file", "ftp", "ftps", "gopher", "gophers", |
24 | | "http", "https", "imap", "imaps", "mqtt", "pop3", |
25 | | "pop3s", "ldap", "ldaps", "rtmp", "rtmpe", "rtmps", |
26 | | "rtmpt", "rtmpte", "rtmpts", "scp", "sftp", "rtsp", |
27 | | "smtp", "smtps", "tftp", "ws", "wss", nullptr}; |
28 | | |
29 | | /** |
30 | | * Tests support against libcurl's authoritative runtime protocol list so a |
31 | | * dependency variant cannot poison the complete CURLOPT_PROTOCOLS_STR value. |
32 | | */ |
33 | | bool IsSupported(const char *candidate, |
34 | 29 | const char *const *supported_protocols) { |
35 | 29 | if (!supported_protocols) { |
36 | 0 | return false; |
37 | 0 | } |
38 | | |
39 | 434 | for (const char *const *protocol = supported_protocols; *protocol; |
40 | 426 | ++protocol) { |
41 | 426 | if (std::strcmp(candidate, *protocol) == 0) { |
42 | 21 | return true; |
43 | 21 | } |
44 | 426 | } |
45 | 8 | return false; |
46 | 29 | } |
47 | | |
48 | | } // namespace |
49 | | |
50 | 1 | std::string Build(const char *const *supported_protocols) { |
51 | 1 | std::string allowed; |
52 | 30 | for (const char *const *candidate = kIntendedProtocols; *candidate; |
53 | 29 | ++candidate) { |
54 | 29 | if (!IsSupported(*candidate, supported_protocols)) { |
55 | 8 | continue; |
56 | 8 | } |
57 | 21 | if (!allowed.empty()) { |
58 | 20 | allowed.push_back(','); |
59 | 20 | } |
60 | 21 | allowed.append(*candidate); |
61 | 21 | } |
62 | 1 | return allowed; |
63 | 1 | } |
64 | | |
65 | 22.3k | const std::string &ForCurrentCurl() { |
66 | 22.3k | static const std::string allowed = []() { |
67 | 1 | const curl_version_info_data *const info = |
68 | 1 | curl_version_info(CURLVERSION_NOW); |
69 | 1 | return Build(info ? info->protocols : nullptr); |
70 | 1 | }(); |
71 | 22.3k | return allowed; |
72 | 22.3k | } |
73 | | |
74 | | } // namespace legacy_protocol_allowlist |