/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 | | "smb", "smbs", "smtp", "smtps", "tftp", "ws", |
28 | | "wss", nullptr}; |
29 | | |
30 | | /** |
31 | | * Tests support against libcurl's authoritative runtime protocol list so a |
32 | | * dependency variant cannot poison the complete CURLOPT_PROTOCOLS_STR value. |
33 | | */ |
34 | | bool IsSupported(const char *candidate, |
35 | 31 | const char *const *supported_protocols) { |
36 | 31 | if (!supported_protocols) { |
37 | 0 | return false; |
38 | 0 | } |
39 | | |
40 | 482 | for (const char *const *protocol = supported_protocols; *protocol; |
41 | 472 | ++protocol) { |
42 | 472 | if (std::strcmp(candidate, *protocol) == 0) { |
43 | 21 | return true; |
44 | 21 | } |
45 | 472 | } |
46 | 10 | return false; |
47 | 31 | } |
48 | | |
49 | | } // namespace |
50 | | |
51 | 1 | std::string Build(const char *const *supported_protocols) { |
52 | 1 | std::string allowed; |
53 | 32 | for (const char *const *candidate = kIntendedProtocols; *candidate; |
54 | 31 | ++candidate) { |
55 | 31 | if (!IsSupported(*candidate, supported_protocols)) { |
56 | 10 | continue; |
57 | 10 | } |
58 | 21 | if (!allowed.empty()) { |
59 | 20 | allowed.push_back(','); |
60 | 20 | } |
61 | 21 | allowed.append(*candidate); |
62 | 21 | } |
63 | 1 | return allowed; |
64 | 1 | } |
65 | | |
66 | 5.10k | const std::string &ForCurrentCurl() { |
67 | 5.10k | static const std::string allowed = []() { |
68 | 1 | const curl_version_info_data *const info = |
69 | 1 | curl_version_info(CURLVERSION_NOW); |
70 | 1 | return Build(info ? info->protocols : nullptr); |
71 | 1 | }(); |
72 | 5.10k | return allowed; |
73 | 5.10k | } |
74 | | |
75 | | } // namespace legacy_protocol_allowlist |