/src/CMake/Utilities/cmcurl/lib/protocol.c
Line | Count | Source |
1 | | /*************************************************************************** |
2 | | * _ _ ____ _ |
3 | | * Project ___| | | | _ \| | |
4 | | * / __| | | | |_) | | |
5 | | * | (__| |_| | _ <| |___ |
6 | | * \___|\___/|_| \_\_____| |
7 | | * |
8 | | * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. |
9 | | * |
10 | | * This software is licensed as described in the file COPYING, which |
11 | | * you should have received as part of this distribution. The terms |
12 | | * are also available at https://curl.se/docs/copyright.html. |
13 | | * |
14 | | * You may opt to use, copy, modify, merge, publish, distribute and/or sell |
15 | | * copies of the Software, and permit persons to whom the Software is |
16 | | * furnished to do so, under the terms of the COPYING file. |
17 | | * |
18 | | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
19 | | * KIND, either express or implied. |
20 | | * |
21 | | * SPDX-License-Identifier: curl |
22 | | * |
23 | | ***************************************************************************/ |
24 | | #include "curl_setup.h" |
25 | | |
26 | | #include "protocol.h" |
27 | | #include "strcase.h" |
28 | | |
29 | | #include "dict.h" |
30 | | #include "file.h" |
31 | | #include "ftp.h" |
32 | | #include "gopher.h" |
33 | | #include "http.h" |
34 | | #include "imap.h" |
35 | | #include "curl_ldap.h" |
36 | | #include "mqtt.h" |
37 | | #include "pop3.h" |
38 | | #include "rtsp.h" |
39 | | #include "smb.h" |
40 | | #include "smtp.h" |
41 | | #include "telnet.h" |
42 | | #include "tftp.h" |
43 | | #include "ws.h" |
44 | | #include "vssh/ssh.h" |
45 | | |
46 | | |
47 | | /* All URI schemes known to libcurl, but not necessarily implemented |
48 | | * by protocol handlers. */ |
49 | | const struct Curl_scheme Curl_scheme_dict = { |
50 | | "dict", /* scheme */ |
51 | | #ifdef CURL_DISABLE_DICT |
52 | | ZERO_NULL, |
53 | | #else |
54 | | &Curl_protocol_dict, |
55 | | #endif |
56 | | CURLPROTO_DICT, /* protocol */ |
57 | | CURLPROTO_DICT, /* family */ |
58 | | PROTOPT_NONE | PROTOPT_NOURLQUERY, /* flags */ |
59 | | PORT_DICT, /* defport */ |
60 | | }; |
61 | | |
62 | | const struct Curl_scheme Curl_scheme_file = { |
63 | | "file", /* scheme */ |
64 | | #ifdef CURL_DISABLE_FILE |
65 | | ZERO_NULL, |
66 | | #else |
67 | | &Curl_protocol_file, |
68 | | #endif |
69 | | CURLPROTO_FILE, /* protocol */ |
70 | | CURLPROTO_FILE, /* family */ |
71 | | PROTOPT_NONETWORK | PROTOPT_NOURLQUERY, /* flags */ |
72 | | 0 /* defport */ |
73 | | }; |
74 | | |
75 | | const struct Curl_scheme Curl_scheme_ftp = { |
76 | | "ftp", /* scheme */ |
77 | | #ifdef CURL_DISABLE_FTP |
78 | | ZERO_NULL, |
79 | | #else |
80 | | &Curl_protocol_ftp, |
81 | | #endif |
82 | | CURLPROTO_FTP, /* protocol */ |
83 | | CURLPROTO_FTP, /* family */ |
84 | | PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD | |
85 | | PROTOPT_NOURLQUERY | PROTOPT_PROXY_AS_HTTP | |
86 | | PROTOPT_WILDCARD | PROTOPT_SSL_REUSE | |
87 | | PROTOPT_CONN_REUSE, /* flags */ |
88 | | PORT_FTP, /* defport */ |
89 | | }; |
90 | | |
91 | | const struct Curl_scheme Curl_scheme_ftps = { |
92 | | "ftps", /* scheme */ |
93 | | #if defined(CURL_DISABLE_FTP) || !defined(USE_SSL) |
94 | | ZERO_NULL, |
95 | | #else |
96 | | &Curl_protocol_ftp, |
97 | | #endif |
98 | | CURLPROTO_FTPS, /* protocol */ |
99 | | CURLPROTO_FTP, /* family */ |
100 | | PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION | |
101 | | PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY | PROTOPT_WILDCARD | |
102 | | PROTOPT_CONN_REUSE, /* flags */ |
103 | | PORT_FTPS, /* defport */ |
104 | | }; |
105 | | |
106 | | const struct Curl_scheme Curl_scheme_gopher = { |
107 | | "gopher", /* scheme */ |
108 | | #ifdef CURL_DISABLE_GOPHER |
109 | | ZERO_NULL, |
110 | | #else |
111 | | &Curl_protocol_gopher, |
112 | | #endif |
113 | | CURLPROTO_GOPHER, /* protocol */ |
114 | | CURLPROTO_GOPHER, /* family */ |
115 | | PROTOPT_NONE, /* flags */ |
116 | | PORT_GOPHER, /* defport */ |
117 | | }; |
118 | | |
119 | | const struct Curl_scheme Curl_scheme_gophers = { |
120 | | "gophers", /* scheme */ |
121 | | #if defined(CURL_DISABLE_GOPHER) || !defined(USE_SSL) |
122 | | ZERO_NULL, |
123 | | #else |
124 | | &Curl_protocol_gophers, |
125 | | #endif |
126 | | CURLPROTO_GOPHERS, /* protocol */ |
127 | | CURLPROTO_GOPHER, /* family */ |
128 | | PROTOPT_SSL, /* flags */ |
129 | | PORT_GOPHER, /* defport */ |
130 | | }; |
131 | | |
132 | | const struct Curl_scheme Curl_scheme_http = { |
133 | | "http", /* scheme */ |
134 | | #ifdef CURL_DISABLE_HTTP |
135 | | ZERO_NULL, |
136 | | #else |
137 | | &Curl_protocol_http, |
138 | | #endif |
139 | | CURLPROTO_HTTP, /* protocol */ |
140 | | CURLPROTO_HTTP, /* family */ |
141 | | PROTOPT_CREDSPERREQUEST | /* flags */ |
142 | | PROTOPT_USERPWDCTRL | PROTOPT_CONN_REUSE, |
143 | | PORT_HTTP, /* defport */ |
144 | | }; |
145 | | |
146 | | const struct Curl_scheme Curl_scheme_https = { |
147 | | "https", /* scheme */ |
148 | | #if defined(CURL_DISABLE_HTTP) || !defined(USE_SSL) |
149 | | ZERO_NULL, |
150 | | #else |
151 | | &Curl_protocol_http, |
152 | | #endif |
153 | | CURLPROTO_HTTPS, /* protocol */ |
154 | | CURLPROTO_HTTP, /* family */ |
155 | | PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN | /* flags */ |
156 | | PROTOPT_USERPWDCTRL | PROTOPT_CONN_REUSE, |
157 | | PORT_HTTPS, /* defport */ |
158 | | }; |
159 | | |
160 | | const struct Curl_scheme Curl_scheme_imap = { |
161 | | "imap", /* scheme */ |
162 | | #ifdef CURL_DISABLE_IMAP |
163 | | ZERO_NULL, |
164 | | #else |
165 | | &Curl_protocol_imap, |
166 | | #endif |
167 | | CURLPROTO_IMAP, /* protocol */ |
168 | | CURLPROTO_IMAP, /* family */ |
169 | | PROTOPT_CLOSEACTION | /* flags */ |
170 | | PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE | |
171 | | PROTOPT_CONN_REUSE, |
172 | | PORT_IMAP, /* defport */ |
173 | | }; |
174 | | |
175 | | const struct Curl_scheme Curl_scheme_imaps = { |
176 | | "imaps", /* scheme */ |
177 | | #if defined(CURL_DISABLE_IMAP) || !defined(USE_SSL) |
178 | | ZERO_NULL, |
179 | | #else |
180 | | &Curl_protocol_imap, |
181 | | #endif |
182 | | CURLPROTO_IMAPS, /* protocol */ |
183 | | CURLPROTO_IMAP, /* family */ |
184 | | PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */ |
185 | | PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE, |
186 | | PORT_IMAPS, /* defport */ |
187 | | }; |
188 | | |
189 | | const struct Curl_scheme Curl_scheme_ldap = { |
190 | | "ldap", /* scheme */ |
191 | | #ifdef CURL_DISABLE_LDAP |
192 | | ZERO_NULL, |
193 | | #else |
194 | | &Curl_protocol_ldap, |
195 | | #endif |
196 | | CURLPROTO_LDAP, /* protocol */ |
197 | | CURLPROTO_LDAP, /* family */ |
198 | | PROTOPT_SSL_REUSE, /* flags */ |
199 | | PORT_LDAP, /* defport */ |
200 | | }; |
201 | | |
202 | | const struct Curl_scheme Curl_scheme_ldaps = { |
203 | | "ldaps", /* scheme */ |
204 | | #if defined(CURL_DISABLE_LDAP) || !defined(HAVE_LDAP_SSL) |
205 | | ZERO_NULL, |
206 | | #else |
207 | | &Curl_protocol_ldap, |
208 | | #endif |
209 | | CURLPROTO_LDAPS, /* protocol */ |
210 | | CURLPROTO_LDAP, /* family */ |
211 | | PROTOPT_SSL, /* flags */ |
212 | | PORT_LDAPS, /* defport */ |
213 | | }; |
214 | | |
215 | | const struct Curl_scheme Curl_scheme_mqtt = { |
216 | | "mqtt", /* scheme */ |
217 | | #ifdef CURL_DISABLE_MQTT |
218 | | ZERO_NULL, |
219 | | #else |
220 | | &Curl_protocol_mqtt, |
221 | | #endif |
222 | | CURLPROTO_MQTT, /* protocol */ |
223 | | CURLPROTO_MQTT, /* family */ |
224 | | PROTOPT_NONE, /* flags */ |
225 | | PORT_MQTT, /* defport */ |
226 | | }; |
227 | | |
228 | | const struct Curl_scheme Curl_scheme_mqtts = { |
229 | | "mqtts", /* scheme */ |
230 | | #if defined(CURL_DISABLE_MQTT) || !defined(USE_SSL) |
231 | | ZERO_NULL, |
232 | | #else |
233 | | &Curl_protocol_mqtts, |
234 | | #endif |
235 | | CURLPROTO_MQTTS, /* protocol */ |
236 | | CURLPROTO_MQTT, /* family */ |
237 | | PROTOPT_SSL, /* flags */ |
238 | | PORT_MQTTS, /* defport */ |
239 | | }; |
240 | | |
241 | | const struct Curl_scheme Curl_scheme_pop3 = { |
242 | | "pop3", /* scheme */ |
243 | | #ifdef CURL_DISABLE_POP3 |
244 | | ZERO_NULL, |
245 | | #else |
246 | | &Curl_protocol_pop3, |
247 | | #endif |
248 | | CURLPROTO_POP3, /* protocol */ |
249 | | CURLPROTO_POP3, /* family */ |
250 | | PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */ |
251 | | PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE | PROTOPT_CONN_REUSE, |
252 | | PORT_POP3, /* defport */ |
253 | | }; |
254 | | |
255 | | const struct Curl_scheme Curl_scheme_pop3s = { |
256 | | "pop3s", /* scheme */ |
257 | | #if defined(CURL_DISABLE_POP3) || !defined(USE_SSL) |
258 | | ZERO_NULL, |
259 | | #else |
260 | | &Curl_protocol_pop3, |
261 | | #endif |
262 | | CURLPROTO_POP3S, /* protocol */ |
263 | | CURLPROTO_POP3, /* family */ |
264 | | PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */ |
265 | | PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE, |
266 | | PORT_POP3S, /* defport */ |
267 | | }; |
268 | | |
269 | | const struct Curl_scheme Curl_scheme_rtsp = { |
270 | | "rtsp", /* scheme */ |
271 | | #ifdef CURL_DISABLE_RTSP |
272 | | ZERO_NULL, |
273 | | #else |
274 | | &Curl_protocol_rtsp, |
275 | | #endif |
276 | | CURLPROTO_RTSP, /* protocol */ |
277 | | CURLPROTO_RTSP, /* family */ |
278 | | PROTOPT_CONN_REUSE, /* flags */ |
279 | | PORT_RTSP, /* defport */ |
280 | | }; |
281 | | |
282 | | const struct Curl_scheme Curl_scheme_sftp = { |
283 | | "sftp", /* scheme */ |
284 | | #ifndef USE_SSH |
285 | | NULL, |
286 | | #else |
287 | | &Curl_protocol_sftp, |
288 | | #endif |
289 | | CURLPROTO_SFTP, /* protocol */ |
290 | | CURLPROTO_SFTP, /* family */ |
291 | | PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */ |
292 | | PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE, |
293 | | PORT_SSH /* defport */ |
294 | | }; |
295 | | |
296 | | const struct Curl_scheme Curl_scheme_scp = { |
297 | | "scp", /* scheme */ |
298 | | #ifndef USE_SSH |
299 | | NULL, |
300 | | #else |
301 | | &Curl_protocol_scp, |
302 | | #endif |
303 | | CURLPROTO_SCP, /* protocol */ |
304 | | CURLPROTO_SCP, /* family */ |
305 | | PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */ |
306 | | PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE, |
307 | | PORT_SSH, /* defport */ |
308 | | }; |
309 | | |
310 | | const struct Curl_scheme Curl_scheme_smb = { |
311 | | "smb", /* scheme */ |
312 | | #if defined(CURL_ENABLE_SMB) && defined(USE_CURL_NTLM_CORE) |
313 | | &Curl_protocol_smb, |
314 | | #else |
315 | | ZERO_NULL, |
316 | | #endif |
317 | | CURLPROTO_SMB, /* protocol */ |
318 | | CURLPROTO_SMB, /* family */ |
319 | | PROTOPT_NONE, /* flags */ |
320 | | PORT_SMB, /* defport */ |
321 | | }; |
322 | | |
323 | | const struct Curl_scheme Curl_scheme_smbs = { |
324 | | "smbs", /* scheme */ |
325 | | #if defined(CURL_ENABLE_SMB) && defined(USE_CURL_NTLM_CORE) && defined(USE_SSL) |
326 | | &Curl_protocol_smb, |
327 | | #else |
328 | | ZERO_NULL, |
329 | | #endif |
330 | | CURLPROTO_SMBS, /* protocol */ |
331 | | CURLPROTO_SMB, /* family */ |
332 | | PROTOPT_SSL, /* flags */ |
333 | | PORT_SMBS, /* defport */ |
334 | | }; |
335 | | |
336 | | const struct Curl_scheme Curl_scheme_smtp = { |
337 | | "smtp", /* scheme */ |
338 | | #ifdef CURL_DISABLE_SMTP |
339 | | ZERO_NULL, |
340 | | #else |
341 | | &Curl_protocol_smtp, |
342 | | #endif |
343 | | CURLPROTO_SMTP, /* protocol */ |
344 | | CURLPROTO_SMTP, /* family */ |
345 | | PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */ |
346 | | PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE | PROTOPT_CONN_REUSE, |
347 | | PORT_SMTP, /* defport */ |
348 | | }; |
349 | | |
350 | | const struct Curl_scheme Curl_scheme_smtps = { |
351 | | "smtps", /* scheme */ |
352 | | #if defined(CURL_DISABLE_SMTP) || !defined(USE_SSL) |
353 | | ZERO_NULL, |
354 | | #else |
355 | | &Curl_protocol_smtp, |
356 | | #endif |
357 | | CURLPROTO_SMTPS, /* protocol */ |
358 | | CURLPROTO_SMTP, /* family */ |
359 | | PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */ |
360 | | PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE, |
361 | | PORT_SMTPS, /* defport */ |
362 | | }; |
363 | | |
364 | | const struct Curl_scheme Curl_scheme_telnet = { |
365 | | "telnet", /* scheme */ |
366 | | #ifdef CURL_DISABLE_TELNET |
367 | | ZERO_NULL, |
368 | | #else |
369 | | &Curl_protocol_telnet, |
370 | | #endif |
371 | | CURLPROTO_TELNET, /* protocol */ |
372 | | CURLPROTO_TELNET, /* family */ |
373 | | PROTOPT_NONE | PROTOPT_NOURLQUERY, /* flags */ |
374 | | PORT_TELNET, /* defport */ |
375 | | }; |
376 | | |
377 | | const struct Curl_scheme Curl_scheme_tftp = { |
378 | | "tftp", /* scheme */ |
379 | | #ifdef CURL_DISABLE_TFTP |
380 | | ZERO_NULL, |
381 | | #else |
382 | | &Curl_protocol_tftp, |
383 | | #endif |
384 | | CURLPROTO_TFTP, /* protocol */ |
385 | | CURLPROTO_TFTP, /* family */ |
386 | | PROTOPT_NOTCPPROXY | PROTOPT_NOURLQUERY, /* flags */ |
387 | | PORT_TFTP, /* defport */ |
388 | | }; |
389 | | |
390 | | const struct Curl_scheme Curl_scheme_ws = { |
391 | | "ws", /* scheme */ |
392 | | #if defined(CURL_DISABLE_WEBSOCKETS) || defined(CURL_DISABLE_HTTP) |
393 | | ZERO_NULL, |
394 | | #else |
395 | | &Curl_protocol_ws, |
396 | | #endif |
397 | | CURLPROTO_WS, /* protocol */ |
398 | | CURLPROTO_HTTP, /* family */ |
399 | | PROTOPT_CREDSPERREQUEST | /* flags */ |
400 | | PROTOPT_USERPWDCTRL, |
401 | | PORT_HTTP /* defport */ |
402 | | }; |
403 | | |
404 | | const struct Curl_scheme Curl_scheme_wss = { |
405 | | "wss", /* scheme */ |
406 | | #if defined(CURL_DISABLE_WEBSOCKETS) || defined(CURL_DISABLE_HTTP) || \ |
407 | | !defined(USE_SSL) |
408 | | ZERO_NULL, |
409 | | #else |
410 | | &Curl_protocol_ws, |
411 | | #endif |
412 | | CURLPROTO_WSS, /* protocol */ |
413 | | CURLPROTO_HTTP, /* family */ |
414 | | PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | /* flags */ |
415 | | PROTOPT_USERPWDCTRL, |
416 | | PORT_HTTPS /* defport */ |
417 | | }; |
418 | | |
419 | | /* Returns a struct scheme pointer if the name is a known scheme. Check the |
420 | | ->run struct field for non-NULL to figure out if an implementation is |
421 | | present. */ |
422 | | const struct Curl_scheme *Curl_getn_scheme(const char *scheme, size_t len) |
423 | 0 | { |
424 | | /* table generated by schemetable.c: |
425 | | 1. gcc schemetable.c && ./a.out |
426 | | 2. check how small the table gets |
427 | | 3. tweak the hash algorithm, then rerun from 1 |
428 | | 4. when the table is good enough |
429 | | 5. copy the table into this source code |
430 | | 6. make sure this function uses the same hash function that worked for |
431 | | schemetable.c |
432 | | */ |
433 | 0 | static const struct Curl_scheme * const all_schemes[47] = { |
434 | 0 | &Curl_scheme_mqtt, |
435 | 0 | &Curl_scheme_smtp, |
436 | 0 | &Curl_scheme_tftp, |
437 | 0 | &Curl_scheme_imap, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
438 | 0 | &Curl_scheme_ldaps, |
439 | 0 | &Curl_scheme_dict, NULL, |
440 | 0 | &Curl_scheme_file, NULL, |
441 | 0 | &Curl_scheme_pop3s, |
442 | 0 | &Curl_scheme_ftp, |
443 | 0 | &Curl_scheme_scp, |
444 | 0 | &Curl_scheme_mqtts, |
445 | 0 | &Curl_scheme_imaps, |
446 | 0 | &Curl_scheme_ldap, |
447 | 0 | &Curl_scheme_http, |
448 | 0 | &Curl_scheme_smb, NULL, NULL, |
449 | 0 | &Curl_scheme_telnet, |
450 | 0 | &Curl_scheme_https, |
451 | 0 | &Curl_scheme_gopher, |
452 | 0 | &Curl_scheme_rtsp, NULL, NULL, |
453 | 0 | &Curl_scheme_wss, NULL, |
454 | 0 | &Curl_scheme_gophers, |
455 | 0 | &Curl_scheme_smtps, |
456 | 0 | &Curl_scheme_pop3, |
457 | 0 | &Curl_scheme_ws, NULL, NULL, |
458 | 0 | &Curl_scheme_sftp, |
459 | 0 | &Curl_scheme_ftps, NULL, |
460 | 0 | &Curl_scheme_smbs, NULL, |
461 | 0 | }; |
462 | |
|
463 | 0 | if(len && (len <= 7)) { |
464 | 0 | const char *s = scheme; |
465 | 0 | size_t l = len; |
466 | 0 | const struct Curl_scheme *h; |
467 | 0 | unsigned int c = 792; |
468 | 0 | while(l) { |
469 | 0 | c <<= 4; |
470 | 0 | c += (unsigned int)Curl_raw_tolower(*s); |
471 | 0 | s++; |
472 | 0 | l--; |
473 | 0 | } |
474 | |
|
475 | 0 | h = all_schemes[c % 47]; |
476 | 0 | if(h && curl_strnequal(scheme, h->name, len) && !h->name[len]) |
477 | 0 | return h; |
478 | 0 | } |
479 | 0 | return NULL; |
480 | 0 | } |
481 | | |
482 | | const struct Curl_scheme *Curl_get_scheme(const char *scheme) |
483 | 0 | { |
484 | 0 | return Curl_getn_scheme(scheme, strlen(scheme)); |
485 | 0 | } |