Coverage Report

Created: 2026-07-30 07:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/curl/lib/setopt.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
#ifdef HAVE_NETINET_IN_H
27
#include <netinet/in.h>
28
#endif
29
30
#ifdef HAVE_LINUX_TCP_H
31
#include <linux/tcp.h>
32
#elif defined(HAVE_NETINET_TCP_H)
33
#include <netinet/tcp.h>
34
#endif
35
36
#include "urldata.h"
37
#include "url.h"
38
#include "progress.h"
39
#include "content_encoding.h"
40
#include "strcase.h"
41
#include "curl_share.h"
42
#include "vtls/vtls.h"
43
#include "curl_trc.h"
44
#include "hostip.h"
45
#include "setopt.h"
46
#include "altsvc.h"
47
#include "hsts.h"
48
#include "tftp.h"
49
#include "curlx/strdup.h"
50
#include "escape.h"
51
#include "bufref.h"
52
#include "vauth/vauth.h"
53
54
static CURLcode setopt_set_timeout_sec(timediff_t *ptimeout_ms, long secs)
55
201k
{
56
201k
  if(secs < 0)
57
0
    return CURLE_BAD_FUNCTION_ARGUMENT;
58
201k
#if LONG_MAX > (TIMEDIFF_T_MAX / 1000)
59
201k
  if(secs > (TIMEDIFF_T_MAX / 1000)) {
60
0
    *ptimeout_ms = TIMEDIFF_T_MAX;
61
0
    return CURLE_OK;
62
0
  }
63
201k
#endif
64
201k
  *ptimeout_ms = (timediff_t)secs * 1000;
65
201k
  return CURLE_OK;
66
201k
}
67
68
static CURLcode setopt_set_timeout_ms(timediff_t *ptimeout_ms, long ms)
69
228k
{
70
228k
  if(ms < 0)
71
0
    return CURLE_BAD_FUNCTION_ARGUMENT;
72
#if LONG_MAX > TIMEDIFF_T_MAX
73
  if(ms > TIMEDIFF_T_MAX) {
74
    *ptimeout_ms = TIMEDIFF_T_MAX;
75
    return CURLE_OK;
76
  }
77
#endif
78
228k
  *ptimeout_ms = (timediff_t)ms;
79
228k
  return CURLE_OK;
80
228k
}
81
82
CURLcode Curl_setstropt(char **charp, const char *s)
83
1.83M
{
84
  /* Release the previous storage at `charp' and replace by a dynamic storage
85
     copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */
86
87
1.83M
  curlx_safefree(*charp);
88
89
1.83M
  if(s) {
90
1.83M
    if(strlen(s) > CURL_MAX_INPUT_LENGTH)
91
0
      return CURLE_BAD_FUNCTION_ARGUMENT;
92
93
1.83M
    *charp = curlx_strdup(s);
94
1.83M
    if(!*charp)
95
0
      return CURLE_OUT_OF_MEMORY;
96
1.83M
  }
97
98
1.83M
  return CURLE_OK;
99
1.83M
}
100
101
CURLcode Curl_setblobopt(struct curl_blob **blobp,
102
                         const struct curl_blob *blob)
103
0
{
104
  /* free the previous storage at `blobp' and replace by a dynamic storage
105
     copy of blob. If CURL_BLOB_COPY is set, the data is copied. */
106
107
0
  curlx_safefree(*blobp);
108
109
0
  if(blob) {
110
0
    struct curl_blob *nblob;
111
0
    if(!blob->data || !blob->len || (blob->len > CURL_MAX_INPUT_LENGTH))
112
0
      return CURLE_BAD_FUNCTION_ARGUMENT;
113
0
    nblob = (struct curl_blob *)
114
0
      curlx_malloc(sizeof(struct curl_blob) +
115
0
                   ((blob->flags & CURL_BLOB_COPY) ? blob->len : 0));
116
0
    if(!nblob)
117
0
      return CURLE_OUT_OF_MEMORY;
118
0
    *nblob = *blob;
119
0
    if(blob->flags & CURL_BLOB_COPY) {
120
      /* put the data after the blob struct in memory */
121
0
      nblob->data = (char *)nblob + sizeof(struct curl_blob);
122
0
      memcpy(nblob->data, blob->data, blob->len);
123
0
    }
124
125
0
    *blobp = nblob;
126
0
    return CURLE_OK;
127
0
  }
128
129
0
  return CURLE_OK;
130
0
}
131
132
static CURLcode setstropt_userpwd(const char *option, char **userp,
133
                                  char **passwdp)
134
3.84k
{
135
3.84k
  char *user = NULL;
136
3.84k
  char *passwd = NULL;
137
138
3.84k
  DEBUGASSERT(userp);
139
3.84k
  DEBUGASSERT(passwdp);
140
141
  /* Parse the login details if specified. If not, then we treat NULL as a
142
     hint to clear the existing data */
143
3.84k
  if(option) {
144
3.84k
    size_t len = strlen(option);
145
3.84k
    CURLcode result;
146
3.84k
    if(len > CURL_MAX_INPUT_LENGTH)
147
0
      return CURLE_BAD_FUNCTION_ARGUMENT;
148
149
3.84k
    result = Curl_parse_login_details(option, len, &user, &passwd, NULL);
150
3.84k
    if(result)
151
0
      return result;
152
3.84k
  }
153
154
3.84k
  curlx_free(*userp);
155
3.84k
  *userp = user;
156
157
3.84k
  curlx_strzero(*passwdp);
158
3.84k
  curlx_free(*passwdp);
159
3.84k
  *passwdp = passwd;
160
161
3.84k
  return CURLE_OK;
162
3.84k
}
163
164
static CURLcode setstropt_interface(char *option, char **devp,
165
                                    char **ifacep, char **hostp)
166
3.83k
{
167
3.83k
  char *dev = NULL;
168
3.83k
  char *iface = NULL;
169
3.83k
  char *host = NULL;
170
3.83k
  CURLcode result;
171
172
3.83k
  DEBUGASSERT(devp);
173
3.83k
  DEBUGASSERT(ifacep);
174
3.83k
  DEBUGASSERT(hostp);
175
176
3.83k
  if(option) {
177
    /* Parse the interface details if set, otherwise clear them all */
178
3.83k
    result = Curl_parse_interface(option, &dev, &iface, &host);
179
3.83k
    if(result)
180
107
      return result;
181
3.83k
  }
182
3.72k
  curlx_free(*devp);
183
3.72k
  *devp = dev;
184
185
3.72k
  curlx_free(*ifacep);
186
3.72k
  *ifacep = iface;
187
188
3.72k
  curlx_free(*hostp);
189
3.72k
  *hostp = host;
190
191
3.72k
  return CURLE_OK;
192
3.83k
}
193
194
#ifdef USE_SSL
195
879k
#define C_SSLVERSION_VALUE(x)     ((x) & 0xffff)
196
879k
#define C_SSLVERSION_MAX_VALUE(x) ((unsigned long)(x) & 0xffff0000)
197
#endif
198
199
static CURLcode protocol2num(const char *str, curl_prot_t *val)
200
217k
{
201
  /*
202
   * We are asked to cherry-pick protocols, so play it safe and disallow all
203
   * protocols to start with, and re-add the wanted ones back in.
204
   */
205
217k
  *val = 0;
206
207
217k
  if(!str)
208
0
    return CURLE_BAD_FUNCTION_ARGUMENT;
209
210
217k
  if(curl_strequal(str, "all")) {
211
1.63k
    *val = ~(curl_prot_t)0;
212
1.63k
    return CURLE_OK;
213
1.63k
  }
214
215
456k
  do {
216
456k
    const char *token = str;
217
456k
    size_t tlen;
218
219
456k
    str = strchr(str, ',');
220
456k
    tlen = str ? (size_t)(str - token) : strlen(token);
221
456k
    if(tlen) {
222
452k
      const struct Curl_scheme *h = Curl_getn_scheme(token, tlen);
223
224
452k
      if(!h || !h->run)
225
10.4k
        return CURLE_UNSUPPORTED_PROTOCOL;
226
227
442k
      *val |= h->protocol;
228
442k
    }
229
456k
  } while(str && str++);
230
231
205k
  if(!*val)
232
    /* no protocol listed */
233
171
    return CURLE_BAD_FUNCTION_ARGUMENT;
234
205k
  return CURLE_OK;
235
205k
}
236
237
#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_PROXY)
238
static CURLcode httpauth(struct Curl_easy *data, bool proxy,
239
                         unsigned long auth)
240
6.73k
{
241
6.73k
  if(auth != CURLAUTH_NONE) {
242
6.62k
    int bitcheck = 0;
243
6.62k
    bool authbits = FALSE;
244
6.62k
    if(auth & CURLAUTH_DIGEST_IE) {
245
1.74k
      auth |= CURLAUTH_DIGEST; /* set standard digest bit */
246
1.74k
      auth &= ~CURLAUTH_DIGEST_IE; /* drop the legacy bit */
247
1.74k
    }
248
249
    /* switch off bits we cannot support */
250
6.62k
#ifndef USE_NTLM
251
6.62k
    auth &= ~CURLAUTH_NTLM; /* no NTLM support */
252
6.62k
#endif
253
6.62k
#ifndef USE_SPNEGO
254
6.62k
    auth &= ~CURLAUTH_NEGOTIATE; /* no Negotiate (SPNEGO) auth without GSS-API
255
                                    or SSPI */
256
6.62k
#endif
257
258
    /* check if any auth bit lower than CURLAUTH_ONLY is still set */
259
37.6k
    while(bitcheck < 31) {
260
37.6k
      if(auth & (1UL << bitcheck++)) {
261
6.59k
        authbits = TRUE;
262
6.59k
        break;
263
6.59k
      }
264
37.6k
    }
265
6.62k
    if(!authbits)
266
31
      return CURLE_NOT_BUILT_IN; /* no supported types left! */
267
6.62k
  }
268
6.70k
  if(proxy)
269
1.36k
    data->set.proxyauth = (uint32_t)auth;
270
5.34k
  else
271
5.34k
    data->set.httpauth = (uint32_t)auth;
272
6.70k
  return CURLE_OK;
273
6.73k
}
274
#endif /* !CURL_DISABLE_HTTP || !CURL_DISABLE_PROXY */
275
276
#ifndef CURL_DISABLE_HTTP
277
static CURLcode setopt_HTTP_VERSION(struct Curl_easy *data, long arg)
278
30.4k
{
279
  /*
280
   * This sets a requested HTTP version to be used. The value is one of
281
   * the listed enums in curl/curl.h.
282
   */
283
30.4k
  switch(arg) {
284
1.29k
  case CURL_HTTP_VERSION_NONE:
285
    /* accepted */
286
1.29k
    break;
287
54
  case CURL_HTTP_VERSION_1_0:
288
103
  case CURL_HTTP_VERSION_1_1:
289
    /* accepted */
290
103
    break;
291
0
#ifdef USE_HTTP2
292
275
  case CURL_HTTP_VERSION_2_0:
293
9.84k
  case CURL_HTTP_VERSION_2TLS:
294
28.2k
  case CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE:
295
    /* accepted */
296
28.2k
    break;
297
0
#endif
298
#ifdef USE_HTTP3
299
  case CURL_HTTP_VERSION_3:
300
  case CURL_HTTP_VERSION_3ONLY:
301
    /* accepted */
302
    break;
303
#endif
304
730
  default:
305
    /* not accepted */
306
730
    if(arg < CURL_HTTP_VERSION_NONE)
307
132
      return CURLE_BAD_FUNCTION_ARGUMENT;
308
598
    return CURLE_UNSUPPORTED_PROTOCOL;
309
30.4k
  }
310
29.6k
  data->set.httpwant = (unsigned char)arg;
311
29.6k
  return CURLE_OK;
312
30.4k
}
313
#endif /* !CURL_DISABLE_HTTP */
314
315
#ifdef USE_SSL
316
CURLcode Curl_setopt_SSLVERSION(struct Curl_easy *data, CURLoption option,
317
                                long arg)
318
879k
{
319
  /*
320
   * Set explicit SSL version to try to connect with, as some SSL
321
   * implementations are lame.
322
   */
323
879k
  {
324
879k
    long version, version_max;
325
879k
    struct ssl_primary_config *primary = &data->set.ssl.primary;
326
879k
#ifndef CURL_DISABLE_PROXY
327
879k
    if(option != CURLOPT_SSLVERSION)
328
439k
      primary = &data->set.proxy_ssl.primary;
329
#else
330
    (void)option; /* unused */
331
#endif
332
879k
    version = C_SSLVERSION_VALUE(arg);
333
879k
    version_max = (long)C_SSLVERSION_MAX_VALUE(arg);
334
335
879k
    if(version < CURL_SSLVERSION_DEFAULT ||
336
879k
       version == CURL_SSLVERSION_SSLv2 ||
337
879k
       version == CURL_SSLVERSION_SSLv3 ||
338
879k
       version >= CURL_SSLVERSION_LAST ||
339
879k
       version_max < CURL_SSLVERSION_MAX_NONE ||
340
879k
       version_max >= CURL_SSLVERSION_MAX_LAST)
341
506
      return CURLE_BAD_FUNCTION_ARGUMENT;
342
879k
    if(version == CURL_SSLVERSION_DEFAULT)
343
878k
      version = CURL_SSLVERSION_TLSv1_2;
344
345
879k
    primary->version = (unsigned char)version;
346
879k
    primary->version_max = (unsigned int)version_max;
347
879k
  }
348
0
  return CURLE_OK;
349
879k
}
350
#endif /* !USE_SSL */
351
352
#ifndef CURL_DISABLE_RTSP
353
static CURLcode setopt_RTSP_REQUEST(struct Curl_easy *data, long arg)
354
2.50k
{
355
  /*
356
   * Set the RTSP request method (OPTIONS, SETUP, PLAY, etc...) Would this be
357
   * better if the RTSPREQ_* were moved into here?
358
   */
359
2.50k
  Curl_RtspReq rtspreq = RTSPREQ_NONE;
360
2.50k
  switch(arg) {
361
13
  case CURL_RTSPREQ_OPTIONS:
362
13
    rtspreq = RTSPREQ_OPTIONS;
363
13
    break;
364
1.65k
  case CURL_RTSPREQ_DESCRIBE:
365
1.65k
    rtspreq = RTSPREQ_DESCRIBE;
366
1.65k
    break;
367
229
  case CURL_RTSPREQ_ANNOUNCE:
368
229
    rtspreq = RTSPREQ_ANNOUNCE;
369
229
    break;
370
30
  case CURL_RTSPREQ_SETUP:
371
30
    rtspreq = RTSPREQ_SETUP;
372
30
    break;
373
38
  case CURL_RTSPREQ_PLAY:
374
38
    rtspreq = RTSPREQ_PLAY;
375
38
    break;
376
26
  case CURL_RTSPREQ_PAUSE:
377
26
    rtspreq = RTSPREQ_PAUSE;
378
26
    break;
379
13
  case CURL_RTSPREQ_TEARDOWN:
380
13
    rtspreq = RTSPREQ_TEARDOWN;
381
13
    break;
382
125
  case CURL_RTSPREQ_GET_PARAMETER:
383
125
    rtspreq = RTSPREQ_GET_PARAMETER;
384
125
    break;
385
57
  case CURL_RTSPREQ_SET_PARAMETER:
386
57
    rtspreq = RTSPREQ_SET_PARAMETER;
387
57
    break;
388
17
  case CURL_RTSPREQ_RECORD:
389
17
    rtspreq = RTSPREQ_RECORD;
390
17
    break;
391
29
  case CURL_RTSPREQ_RECEIVE:
392
29
    rtspreq = RTSPREQ_RECEIVE;
393
29
    break;
394
274
  default:
395
274
    return CURLE_BAD_FUNCTION_ARGUMENT;
396
2.50k
  }
397
398
2.22k
  data->set.rtspreq = rtspreq;
399
2.22k
  return CURLE_OK;
400
2.50k
}
401
#endif /* !CURL_DISABLE_RTSP */
402
403
static CURLcode setopt_long_bool(struct Curl_easy *data, CURLoption option,
404
                                 long arg)
405
657k
{
406
657k
  bool enabled = !!arg;
407
657k
  int ok = 1;
408
657k
  struct UserDefined *s = &data->set;
409
657k
  switch(option) {
410
139
  case CURLOPT_FORBID_REUSE:
411
    /*
412
     * When this transfer is done, it must not be left to be reused by a
413
     * subsequent transfer but shall be closed immediately.
414
     */
415
139
    s->reuse_forbid = enabled;
416
139
    break;
417
97
  case CURLOPT_FRESH_CONNECT:
418
    /*
419
     * This transfer shall not use a previously cached connection but
420
     * should be made with a fresh new connect!
421
     */
422
97
    s->reuse_fresh = enabled;
423
97
    break;
424
0
  case CURLOPT_VERBOSE:
425
    /*
426
     * Verbose means infof() calls that give a lot of information about
427
     * the connection and transfer procedures as well as internal choices.
428
     */
429
0
    s->verbose = enabled;
430
0
    break;
431
1.58k
  case CURLOPT_HEADER:
432
    /*
433
     * Set to include the header in the general data output stream.
434
     */
435
1.58k
    s->include_header = enabled;
436
1.58k
    break;
437
1.40k
  case CURLOPT_NOPROGRESS:
438
    /*
439
     * Shut off the internal supported progress meter
440
     */
441
1.40k
    data->progress.hide = enabled;
442
1.40k
    break;
443
10.9k
  case CURLOPT_NOBODY:
444
    /*
445
     * Do not include the body part in the output data stream.
446
     */
447
10.9k
    s->opt_no_body = enabled;
448
10.9k
#ifndef CURL_DISABLE_HTTP
449
10.9k
    if(s->opt_no_body)
450
      /* in HTTP lingo, no body means using the HEAD request... */
451
820
      s->method = HTTPREQ_HEAD;
452
10.1k
    else if(s->method == HTTPREQ_HEAD)
453
140
      s->method = HTTPREQ_GET;
454
10.9k
#endif
455
10.9k
    break;
456
1.01k
  case CURLOPT_FAILONERROR:
457
    /*
458
     * Do not output the >=400 error code HTML-page, but instead only
459
     * return error.
460
     */
461
1.01k
    s->http_fail_on_error = enabled;
462
1.01k
    break;
463
64
  case CURLOPT_KEEP_SENDING_ON_ERROR:
464
64
    s->http_keep_sending_on_error = enabled;
465
64
    break;
466
3.06k
  case CURLOPT_UPLOAD:
467
3.06k
  case CURLOPT_PUT:
468
    /*
469
     * We want to send data to the remote host. If this is HTTP, that equals
470
     * using the PUT request.
471
     */
472
3.06k
    if(enabled) {
473
      /* If this is HTTP, PUT is what's needed to "upload" */
474
2.33k
      s->method = HTTPREQ_PUT;
475
2.33k
      s->opt_no_body = FALSE; /* this is implied */
476
2.33k
    }
477
723
    else
478
      /* In HTTP, the opposite of upload is GET (unless NOBODY is true as
479
         then this can be changed to HEAD later on) */
480
723
      s->method = HTTPREQ_GET;
481
3.06k
    break;
482
133
  case CURLOPT_FILETIME:
483
    /*
484
     * Try to get the file time of the remote document. The time will
485
     * later (possibly) become available using curl_easy_getinfo().
486
     */
487
133
    s->get_filetime = enabled;
488
133
    break;
489
0
#ifndef CURL_DISABLE_HTTP
490
723
  case CURLOPT_HTTP09_ALLOWED:
491
723
    s->http09_allowed = enabled;
492
723
    break;
493
0
#ifndef CURL_DISABLE_COOKIES
494
49
  case CURLOPT_COOKIESESSION:
495
    /*
496
     * Set this option to TRUE to start a new "cookie session". It will
497
     * prevent the forthcoming read-cookies-from-file actions to accept
498
     * cookies that are marked as being session cookies, as they belong to a
499
     * previous session.
500
     */
501
49
    s->cookiesession = enabled;
502
49
    break;
503
0
#endif
504
1.42k
  case CURLOPT_AUTOREFERER:
505
    /*
506
     * Switch on automatic referer that gets set if curl follows locations.
507
     */
508
1.42k
    s->http_auto_referer = enabled;
509
1.42k
    break;
510
164
  case CURLOPT_TRANSFER_ENCODING:
511
164
    s->http_transfer_encoding = enabled;
512
164
    break;
513
246
  case CURLOPT_UNRESTRICTED_AUTH:
514
    /*
515
     * Send authentication (user+password) when following locations, even when
516
     * hostname changed.
517
     */
518
246
    s->allow_auth_to_other_hosts = enabled;
519
246
    break;
520
137
  case CURLOPT_HTTP_TRANSFER_DECODING:
521
    /*
522
     * disable libcurl transfer encoding is used
523
     */
524
137
    s->http_te_skip = !enabled; /* reversed */
525
137
    break;
526
71
  case CURLOPT_HTTP_CONTENT_DECODING:
527
    /*
528
     * raw data passed to the application when content encoding is used
529
     */
530
71
    s->http_ce_skip = !enabled; /* reversed */
531
71
    break;
532
2.74k
  case CURLOPT_HTTPGET:
533
    /*
534
     * Set to force us do HTTP GET
535
     */
536
2.74k
    if(enabled) {
537
208
      s->method = HTTPREQ_GET;
538
208
      s->opt_no_body = FALSE; /* this is implied */
539
208
    }
540
2.74k
    break;
541
3.97k
  case CURLOPT_POST:
542
    /* Does this option serve a purpose anymore? Yes it does, when
543
       CURLOPT_POSTFIELDS is not used and the POST data is read off the
544
       callback! */
545
3.97k
    if(enabled) {
546
992
      s->method = HTTPREQ_POST;
547
992
      s->opt_no_body = FALSE; /* this is implied */
548
992
    }
549
2.98k
    else
550
2.98k
      s->method = HTTPREQ_GET;
551
3.97k
    break;
552
0
#endif /* !CURL_DISABLE_HTTP */
553
0
#ifndef CURL_DISABLE_PROXY
554
76
  case CURLOPT_HTTPPROXYTUNNEL:
555
    /*
556
     * Tunnel operations through the proxy instead of normal proxy use
557
     */
558
76
    s->tunnel_thru_httpproxy = enabled;
559
76
    break;
560
105
  case CURLOPT_HAPROXYPROTOCOL:
561
    /*
562
     * Set to send the HAProxy Proxy Protocol header
563
     */
564
105
    s->haproxyprotocol = enabled;
565
105
    break;
566
280
  case CURLOPT_PROXY_SSL_VERIFYPEER:
567
    /*
568
     * Enable peer SSL verifying for proxy.
569
     */
570
280
    s->proxy_ssl.primary.verifypeer = enabled;
571
572
    /* Update the current connection proxy_ssl_config. */
573
280
    Curl_ssl_conn_config_update(data, TRUE);
574
280
    break;
575
243
  case CURLOPT_PROXY_SSL_VERIFYHOST:
576
    /*
577
     * Enable verification of the hostname in the peer certificate for proxy
578
     */
579
243
    s->proxy_ssl.primary.verifyhost = enabled;
580
243
    ok = 2;
581
    /* Update the current connection proxy_ssl_config. */
582
243
    Curl_ssl_conn_config_update(data, TRUE);
583
243
    break;
584
63
  case CURLOPT_PROXY_TRANSFER_MODE:
585
    /*
586
     * set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy
587
     */
588
63
    s->proxy_transfer_mode = enabled;
589
63
    break;
590
0
#endif /* !CURL_DISABLE_PROXY */
591
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
592
  case CURLOPT_SOCKS5_GSSAPI_NEC:
593
    /*
594
     * Set flag for NEC SOCKS5 support
595
     */
596
    s->socks5_gssapi_nec = enabled;
597
    break;
598
#endif
599
0
#ifdef CURL_LIST_ONLY_PROTOCOL
600
60
  case CURLOPT_DIRLISTONLY:
601
    /*
602
     * An option that changes the command to one that asks for a list only, no
603
     * file info details. Used for FTP, POP3 and SFTP.
604
     */
605
60
    s->list_only = enabled;
606
60
    break;
607
0
#endif
608
43
  case CURLOPT_APPEND:
609
    /*
610
     * We want to upload and append to an existing file. Used for FTP and
611
     * SFTP.
612
     */
613
43
    s->remote_append = enabled;
614
43
    break;
615
0
#ifndef CURL_DISABLE_FTP
616
78
  case CURLOPT_FTP_USE_EPRT:
617
78
    s->ftp_use_eprt = enabled;
618
78
    break;
619
55
  case CURLOPT_FTP_USE_EPSV:
620
55
    s->ftp_use_epsv = enabled;
621
55
    break;
622
79
  case CURLOPT_FTP_USE_PRET:
623
79
    s->ftp_use_pret = enabled;
624
79
    break;
625
53
  case CURLOPT_FTP_SKIP_PASV_IP:
626
    /*
627
     * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the
628
     * bypass of the IP address in PASV responses.
629
     */
630
53
    s->ftp_skip_ip = enabled;
631
53
    break;
632
775
  case CURLOPT_WILDCARDMATCH:
633
775
    s->wildcard_enabled = enabled;
634
775
    break;
635
0
#endif
636
0
  case CURLOPT_CRLF:
637
    /*
638
     * Kludgy option to enable CRLF conversions. Subject for removal.
639
     */
640
0
    s->crlf = enabled;
641
0
    break;
642
0
#ifndef CURL_DISABLE_TFTP
643
88
  case CURLOPT_TFTP_NO_OPTIONS:
644
    /*
645
     * Option that prevents libcurl from sending TFTP option requests to the
646
     * server.
647
     */
648
88
    s->tftp_no_options = enabled;
649
88
    break;
650
0
#endif /* !CURL_DISABLE_TFTP */
651
896
  case CURLOPT_TRANSFERTEXT:
652
    /*
653
     * This option was previously named 'FTPASCII'. Renamed to work with
654
     * more protocols than merely FTP.
655
     *
656
     * Transfer using ASCII (instead of BINARY).
657
     */
658
896
    s->prefer_ascii = enabled;
659
896
    break;
660
11.1k
  case CURLOPT_SSL_VERIFYPEER:
661
    /*
662
     * Enable peer SSL verifying.
663
     */
664
11.1k
    s->ssl.primary.verifypeer = enabled;
665
666
    /* Update the current connection ssl_config. */
667
11.1k
    Curl_ssl_conn_config_update(data, FALSE);
668
11.1k
    break;
669
0
#ifndef CURL_DISABLE_DOH
670
41
  case CURLOPT_DOH_SSL_VERIFYPEER:
671
    /*
672
     * Enable peer SSL verifying for DoH.
673
     */
674
41
    s->doh_verifypeer = enabled;
675
41
    break;
676
66
  case CURLOPT_DOH_SSL_VERIFYHOST:
677
    /*
678
     * Enable verification of the hostname in the peer certificate for DoH
679
     */
680
66
    s->doh_verifyhost = enabled;
681
66
    ok = 2;
682
66
    break;
683
78
  case CURLOPT_DOH_SSL_VERIFYSTATUS:
684
    /*
685
     * Enable certificate status verifying for DoH.
686
     */
687
78
    if(!Curl_ssl_cert_status_request())
688
0
      return CURLE_NOT_BUILT_IN;
689
690
78
    s->doh_verifystatus = enabled;
691
78
    ok = 2;
692
78
    break;
693
0
#endif /* !CURL_DISABLE_DOH */
694
9.65k
  case CURLOPT_SSL_VERIFYHOST:
695
    /*
696
     * Enable verification of the hostname in the peer certificate
697
     */
698
699
    /* Obviously people are not reading documentation and too many thought
700
       this argument took a boolean when it was not and misused it.
701
       Treat 1 and 2 the same */
702
9.65k
    s->ssl.primary.verifyhost = enabled;
703
9.65k
    ok = 2;
704
705
    /* Update the current connection ssl_config. */
706
9.65k
    Curl_ssl_conn_config_update(data, FALSE);
707
9.65k
    break;
708
9.64k
  case CURLOPT_SSL_VERIFYSTATUS:
709
    /*
710
     * Enable certificate status verifying.
711
     */
712
9.64k
    if(!Curl_ssl_cert_status_request())
713
0
      return CURLE_NOT_BUILT_IN;
714
715
9.64k
    s->ssl.primary.verifystatus = enabled;
716
717
    /* Update the current connection ssl_config. */
718
9.64k
    Curl_ssl_conn_config_update(data, FALSE);
719
9.64k
    break;
720
102
  case CURLOPT_CERTINFO:
721
102
#ifdef USE_SSL
722
102
    if(Curl_ssl_supports(data, SSLSUPP_CERTINFO))
723
102
      s->ssl.certinfo = enabled;
724
0
    else
725
0
#endif
726
0
      return CURLE_NOT_BUILT_IN;
727
102
    break;
728
216
  case CURLOPT_NOSIGNAL:
729
    /*
730
     * The application asks not to set any signal() or alarm() handlers,
731
     * even when using a timeout.
732
     */
733
216
    s->no_signal = enabled;
734
216
    break;
735
71
  case CURLOPT_TCP_NODELAY:
736
    /*
737
     * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
738
     * algorithm
739
     */
740
71
    s->tcp_nodelay = enabled;
741
71
    break;
742
85
  case CURLOPT_IGNORE_CONTENT_LENGTH:
743
85
    s->ignorecl = enabled;
744
85
    break;
745
61
  case CURLOPT_SSL_SESSIONID_CACHE:
746
61
    s->ssl.primary.cache_session = enabled;
747
61
#ifndef CURL_DISABLE_PROXY
748
61
    s->proxy_ssl.primary.cache_session = s->ssl.primary.cache_session;
749
61
#endif
750
61
    break;
751
#ifdef USE_SSH
752
  case CURLOPT_SSH_COMPRESSION:
753
    s->ssh_compression = enabled;
754
    break;
755
#endif /* !USE_SSH */
756
0
#ifndef CURL_DISABLE_SMTP
757
43
  case CURLOPT_MAIL_RCPT_ALLOWFAILS:
758
    /* allow RCPT TO command to fail for some recipients */
759
43
    s->mail_rcpt_allowfails = enabled;
760
43
    break;
761
0
#endif /* !CURL_DISABLE_SMTP */
762
215
  case CURLOPT_SASL_IR:
763
    /* Enable/disable SASL initial response */
764
215
    s->sasl_ir = enabled;
765
215
    break;
766
304
  case CURLOPT_TCP_KEEPALIVE:
767
304
    s->tcp_keepalive = enabled;
768
304
    break;
769
67
  case CURLOPT_TCP_FASTOPEN:
770
67
#if defined(CONNECT_DATA_IDEMPOTENT) || defined(MSG_FASTOPEN) || \
771
67
  defined(TCP_FASTOPEN_CONNECT)
772
67
    s->tcp_fastopen = enabled;
773
67
    break;
774
#else
775
    return CURLE_NOT_BUILT_IN;
776
#endif
777
151
  case CURLOPT_SSL_ENABLE_ALPN:
778
151
    s->ssl_enable_alpn = enabled;
779
151
    break;
780
423
  case CURLOPT_PATH_AS_IS:
781
423
    s->path_as_is = enabled;
782
423
    break;
783
9.60k
  case CURLOPT_PIPEWAIT:
784
9.60k
    s->pipewait = enabled;
785
9.60k
    break;
786
190
  case CURLOPT_SUPPRESS_CONNECT_HEADERS:
787
190
    s->suppress_connect_headers = enabled;
788
190
    break;
789
0
#ifndef CURL_DISABLE_SHUFFLE_DNS
790
188
  case CURLOPT_DNS_SHUFFLE_ADDRESSES:
791
188
    s->dns_shuffle_addresses = enabled;
792
188
    break;
793
0
#endif
794
67
  case CURLOPT_DISALLOW_USERNAME_IN_URL:
795
67
    s->disallow_username_in_url = enabled;
796
67
    break;
797
71
  case CURLOPT_QUICK_EXIT:
798
71
    s->quick_exit = enabled;
799
71
    break;
800
584k
  default:
801
584k
    return CURLE_UNKNOWN_OPTION;
802
657k
  }
803
73.3k
  if((arg > ok) || (arg < 0))
804
    /* reserve other values for future use */
805
9.17k
    infof(data, "boolean setopt(%d) got unsupported argument %ld,"
806
73.3k
          " treated as %d", (int)option, arg, enabled);
807
808
73.3k
  return CURLE_OK;
809
657k
}
810
811
static CURLcode value_range(long *value, long below_error, long min, long max)
812
17.5k
{
813
17.5k
  if(*value < below_error)
814
118
    return CURLE_BAD_FUNCTION_ARGUMENT;
815
17.3k
  else if(*value < min)
816
1.35k
    *value = min;
817
16.0k
  else if(*value > max)
818
5.67k
    *value = max;
819
17.3k
  return CURLE_OK;
820
17.5k
}
821
822
static CURLcode setopt_long_net(struct Curl_easy *data, CURLoption option,
823
                                long arg)
824
584k
{
825
584k
  CURLcode result = CURLE_OK;
826
584k
  struct UserDefined *s = &data->set;
827
828
584k
  switch(option) {
829
1.59k
  case CURLOPT_DNS_CACHE_TIMEOUT:
830
1.59k
    if(arg != -1)
831
1.59k
      return setopt_set_timeout_sec(&s->dns_cache_timeout_ms, arg);
832
0
    s->dns_cache_timeout_ms = -1;
833
0
    break;
834
866
  case CURLOPT_MAXCONNECTS:
835
866
    result = value_range(&arg, 0, 0, INT_MAX);
836
866
    if(!result)
837
866
      s->maxconnects = arg ? (uint32_t)arg : DEFAULT_CONNCACHE_SIZE;
838
866
    break;
839
196k
  case CURLOPT_SERVER_RESPONSE_TIMEOUT:
840
196k
    return setopt_set_timeout_sec(&s->server_response_timeout, arg);
841
415
  case CURLOPT_SERVER_RESPONSE_TIMEOUT_MS:
842
415
    return setopt_set_timeout_ms(&s->server_response_timeout, arg);
843
787
  case CURLOPT_LOW_SPEED_LIMIT:
844
787
    if(arg < 0)
845
0
      result = CURLE_BAD_FUNCTION_ARGUMENT;
846
787
    else
847
787
      s->low_speed_limit = arg;
848
787
    break;
849
1.32k
  case CURLOPT_LOW_SPEED_TIME:
850
1.32k
    result = value_range(&arg, 0, 0, USHRT_MAX);
851
1.32k
    if(!result)
852
1.32k
      s->low_speed_time = (uint16_t)arg;
853
1.32k
    break;
854
1.13k
  case CURLOPT_PORT:
855
1.13k
    if((arg < 0) || (arg > 65535))
856
494
      return CURLE_BAD_FUNCTION_ARGUMENT;
857
641
    s->use_port = (unsigned short)arg;
858
641
    break;
859
0
  case CURLOPT_TIMEOUT:
860
0
    return setopt_set_timeout_sec(&s->timeout, arg);
861
215k
  case CURLOPT_TIMEOUT_MS:
862
215k
    return setopt_set_timeout_ms(&s->timeout, arg);
863
1.83k
  case CURLOPT_CONNECTTIMEOUT:
864
1.83k
    return setopt_set_timeout_sec(&s->connecttimeout, arg);
865
11.6k
  case CURLOPT_CONNECTTIMEOUT_MS:
866
11.6k
    return setopt_set_timeout_ms(&s->connecttimeout, arg);
867
0
#ifndef CURL_DISABLE_BINDLOCAL
868
800
  case CURLOPT_LOCALPORT:
869
800
    if((arg < 0) || (arg > 65535))
870
237
      return CURLE_BAD_FUNCTION_ARGUMENT;
871
563
    s->localport = curlx_sltous(arg);
872
563
    break;
873
992
  case CURLOPT_LOCALPORTRANGE:
874
992
    if((arg < 0) || (arg > 65535))
875
488
      return CURLE_BAD_FUNCTION_ARGUMENT;
876
504
    s->localportrange = curlx_sltous(arg);
877
504
    break;
878
0
#endif
879
1.99k
  case CURLOPT_BUFFERSIZE:
880
1.99k
    result = value_range(&arg, 0, READBUFFER_MIN, READBUFFER_MAX);
881
1.99k
    if(!result)
882
1.99k
      s->buffer_size = (unsigned int)arg;
883
1.99k
    break;
884
2.19k
  case CURLOPT_UPLOAD_BUFFERSIZE:
885
2.19k
    result = value_range(&arg, 0, UPLOADBUFFER_MIN, UPLOADBUFFER_MAX);
886
2.19k
    if(!result)
887
2.19k
      s->upload_buffer_size = (unsigned int)arg;
888
2.19k
    break;
889
1.07k
  case CURLOPT_MAXFILESIZE:
890
1.07k
    if(arg < 0)
891
0
      result = CURLE_BAD_FUNCTION_ARGUMENT;
892
1.07k
    else
893
1.07k
      s->max_filesize = arg;
894
1.07k
    break;
895
776
  case CURLOPT_IPRESOLVE:
896
776
    if((arg < CURL_IPRESOLVE_WHATEVER) || (arg > CURL_IPRESOLVE_V6))
897
534
      result = CURLE_BAD_FUNCTION_ARGUMENT;
898
242
    else
899
242
      s->ipver = (unsigned char)arg;
900
776
    break;
901
23.7k
  case CURLOPT_CONNECT_ONLY:
902
23.7k
    if(arg < 0 || arg > 2)
903
845
      result = CURLE_BAD_FUNCTION_ARGUMENT;
904
22.9k
    else {
905
22.9k
      s->connect_only = !!arg;
906
22.9k
      s->connect_only_ws = (arg == 2);
907
22.9k
    }
908
23.7k
    break;
909
0
#ifdef USE_IPV6
910
2.96k
  case CURLOPT_ADDRESS_SCOPE:
911
2.96k
#if SIZEOF_LONG > 4
912
2.96k
    if((unsigned long)arg > UINT_MAX)
913
0
      result = CURLE_BAD_FUNCTION_ARGUMENT;
914
2.96k
    else
915
2.96k
#endif
916
2.96k
    s->scope_id = (unsigned int)arg;
917
2.96k
    break;
918
0
#endif
919
1.00k
  case CURLOPT_TCP_KEEPIDLE:
920
1.00k
    result = value_range(&arg, 0, 0, INT_MAX);
921
1.00k
    if(!result)
922
1.00k
      s->tcp_keepidle = (int)arg;
923
1.00k
    break;
924
1.05k
  case CURLOPT_TCP_KEEPINTVL:
925
1.05k
    result = value_range(&arg, 0, 0, INT_MAX);
926
1.05k
    if(!result)
927
1.05k
      s->tcp_keepintvl = (int)arg;
928
1.05k
    break;
929
950
  case CURLOPT_TCP_KEEPCNT:
930
950
    result = value_range(&arg, 0, 0, INT_MAX);
931
950
    if(!result)
932
950
      s->tcp_keepcnt = (int)arg;
933
950
    break;
934
106
  case CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS:
935
106
    return setopt_set_timeout_ms(&s->happy_eyeballs_timeout, arg);
936
506
  case CURLOPT_UPKEEP_INTERVAL_MS:
937
506
    return setopt_set_timeout_ms(&s->upkeep_interval_ms, arg);
938
790
  case CURLOPT_MAXAGE_CONN:
939
790
    return setopt_set_timeout_sec(&s->conn_max_idle_ms, arg);
940
780
  case CURLOPT_MAXLIFETIME_CONN:
941
780
    return setopt_set_timeout_sec(&s->conn_max_age_ms, arg);
942
0
  case CURLOPT_DNS_USE_GLOBAL_CACHE:
943
    /* deprecated */
944
0
    break;
945
113k
  default:
946
113k
    return CURLE_UNKNOWN_OPTION;
947
584k
  }
948
40.4k
  return result;
949
584k
}
950
951
static CURLcode setopt_long_ssl(struct Curl_easy *data, CURLoption option,
952
                                long arg)
953
45.5k
{
954
45.5k
#ifdef USE_SSL
955
45.5k
  CURLcode result = CURLE_OK;
956
45.5k
  struct UserDefined *s = &data->set;
957
45.5k
  switch(option) {
958
1.01k
  case CURLOPT_CA_CACHE_TIMEOUT:
959
1.01k
    if(Curl_ssl_supports(data, SSLSUPP_CA_CACHE)) {
960
1.01k
      result = value_range(&arg, -1, -1, INT_MAX);
961
1.01k
      if(!result)
962
1.01k
        s->general_ssl.ca_cache_timeout = (int)arg;
963
1.01k
    }
964
0
    else
965
0
      result = CURLE_NOT_BUILT_IN;
966
1.01k
    break;
967
923
  case CURLOPT_SSLVERSION:
968
923
#ifndef CURL_DISABLE_PROXY
969
1.47k
  case CURLOPT_PROXY_SSLVERSION:
970
1.47k
#endif
971
1.47k
    return Curl_setopt_SSLVERSION(data, option, arg);
972
16
  case CURLOPT_SSL_FALSESTART:
973
16
    result = CURLE_NOT_BUILT_IN;
974
16
    break;
975
722
  case CURLOPT_USE_SSL:
976
722
    if((arg < CURLUSESSL_NONE) || (arg >= CURLUSESSL_LAST))
977
570
      result = CURLE_BAD_FUNCTION_ARGUMENT;
978
152
    else
979
152
      s->use_ssl = (unsigned char)arg;
980
722
    break;
981
9.66k
  case CURLOPT_SSL_OPTIONS:
982
9.66k
    s->ssl.primary.ssl_options = (unsigned char)(arg & 0xff);
983
9.66k
    break;
984
0
#ifndef CURL_DISABLE_PROXY
985
55
  case CURLOPT_PROXY_SSL_OPTIONS:
986
55
    s->proxy_ssl.primary.ssl_options = (unsigned char)(arg & 0xff);
987
55
    break;
988
0
#endif
989
0
  case CURLOPT_SSL_ENABLE_NPN:
990
0
    break;
991
49
  case CURLOPT_SSLENGINE_DEFAULT:
992
49
    curlx_safefree(s->str[STRING_SSL_ENGINE]);
993
49
    result = Curl_ssl_set_engine_default(data);
994
49
    break;
995
32.5k
  default:
996
32.5k
    return CURLE_UNKNOWN_OPTION;
997
45.5k
  }
998
11.5k
  return result;
999
#else  /* USE_SSL */
1000
  (void)data;
1001
  (void)option;
1002
  (void)arg;
1003
  return CURLE_UNKNOWN_OPTION;
1004
#endif /* !USE_SSL */
1005
45.5k
}
1006
1007
#ifndef CURL_DISABLE_PROXY
1008
static void changeproxy(struct Curl_easy *data)
1009
34.8k
{
1010
34.8k
  Curl_auth_digest_cleanup(&data->state.proxydigest);
1011
34.8k
  memset(&data->state.authproxy, 0, sizeof(data->state.authproxy));
1012
34.8k
}
1013
1014
static CURLcode setopt_long_proxy(struct Curl_easy *data, CURLoption option,
1015
                                  long arg)
1016
60.3k
{
1017
60.3k
  struct UserDefined *s = &data->set;
1018
1019
60.3k
  switch(option) {
1020
993
  case CURLOPT_PROXYPORT:
1021
993
    if((arg < 0) || (arg > UINT16_MAX))
1022
470
      return CURLE_BAD_FUNCTION_ARGUMENT;
1023
523
    if(arg != s->proxyport)
1024
500
      changeproxy(data);
1025
523
    s->proxyport = (uint16_t)arg;
1026
523
    break;
1027
1.38k
  case CURLOPT_PROXYAUTH:
1028
1.38k
    return httpauth(data, TRUE, (unsigned long)arg);
1029
12.0k
  case CURLOPT_PROXYTYPE:
1030
12.0k
    if((arg < CURLPROXY_HTTP) || (arg > CURLPROXY_HTTPS3))
1031
539
      return CURLE_BAD_FUNCTION_ARGUMENT;
1032
11.5k
#ifndef USE_PROXY_HTTP3
1033
11.5k
    if(arg == CURLPROXY_HTTPS3)
1034
15
      return CURLE_NOT_BUILT_IN;
1035
11.5k
#endif
1036
11.5k
    s->proxytype = (unsigned char)arg;
1037
11.5k
    break;
1038
428
  case CURLOPT_SOCKS5_AUTH:
1039
428
    if(arg & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI))
1040
373
      return CURLE_NOT_BUILT_IN;
1041
55
    s->socks5auth = (unsigned char)arg;
1042
55
    break;
1043
45.5k
  default:
1044
45.5k
    return CURLE_UNKNOWN_OPTION;
1045
60.3k
  }
1046
12.0k
  return CURLE_OK;
1047
60.3k
}
1048
#else
1049
static CURLcode setopt_long_proxy(struct Curl_easy *data, CURLoption option,
1050
                                  long arg)
1051
{
1052
  (void)data;
1053
  (void)option;
1054
  (void)arg;
1055
  return CURLE_UNKNOWN_OPTION;
1056
}
1057
#endif
1058
1059
static CURLcode setopt_long_http(struct Curl_easy *data, CURLoption option,
1060
                                 long arg)
1061
113k
{
1062
113k
#ifndef CURL_DISABLE_HTTP
1063
113k
  CURLcode result = CURLE_OK;
1064
113k
  struct UserDefined *s = &data->set;
1065
1066
113k
  switch(option) {
1067
8.92k
  case CURLOPT_FOLLOWLOCATION:
1068
8.92k
    if((unsigned long)arg > 3)
1069
412
      result = CURLE_BAD_FUNCTION_ARGUMENT;
1070
8.51k
    else
1071
8.51k
      s->http_follow_mode = (unsigned char)arg;
1072
8.92k
    break;
1073
3.61k
  case CURLOPT_MAXREDIRS:
1074
3.61k
    result = value_range(&arg, -1, -1, 0x7fff);
1075
3.61k
    if(!result)
1076
3.49k
      s->maxredirs = (short)arg;
1077
3.61k
    break;
1078
538
  case CURLOPT_POSTREDIR:
1079
538
    if(arg < CURL_REDIR_GET_ALL)
1080
0
      result = CURLE_BAD_FUNCTION_ARGUMENT;
1081
538
    else {
1082
538
      s->post301 = !!(arg & CURL_REDIR_POST_301);
1083
538
      s->post302 = !!(arg & CURL_REDIR_POST_302);
1084
538
      s->post303 = !!(arg & CURL_REDIR_POST_303);
1085
538
    }
1086
538
    break;
1087
2.20k
  case CURLOPT_HEADEROPT:
1088
2.20k
    s->sep_headers = !!(arg & CURLHEADER_SEPARATE);
1089
2.20k
    break;
1090
5.35k
  case CURLOPT_HTTPAUTH:
1091
5.35k
    return httpauth(data, FALSE, (unsigned long)arg);
1092
30.4k
  case CURLOPT_HTTP_VERSION:
1093
30.4k
    return setopt_HTTP_VERSION(data, arg);
1094
785
  case CURLOPT_EXPECT_100_TIMEOUT_MS:
1095
785
    result = value_range(&arg, 0, 0, 0xffff);
1096
785
    if(!result)
1097
785
      s->expect_100_timeout = (unsigned short)arg;
1098
785
    break;
1099
1.03k
  case CURLOPT_STREAM_WEIGHT:
1100
1.03k
#if defined(USE_HTTP2) || defined(USE_HTTP3)
1101
1.03k
    if((arg >= 1) && (arg <= 256))
1102
245
      s->priority.weight = (int)arg;
1103
1.03k
    break;
1104
#else
1105
    result = CURLE_NOT_BUILT_IN;
1106
    break;
1107
#endif
1108
#ifndef CURL_DISABLE_HTTPSIG
1109
  case CURLOPT_HTTPSIG_ALGORITHM:
1110
    if(arg != CURLHTTPSIG_NONE &&
1111
       arg != CURLHTTPSIG_ED25519 &&
1112
       arg != CURLHTTPSIG_HMAC_SHA256)
1113
      return CURLE_BAD_FUNCTION_ARGUMENT;
1114
    s->httpsig_algorithm = (uint8_t)arg;
1115
    if(arg)
1116
      s->httpauth = (uint32_t)CURLAUTH_HTTPSIG;
1117
    else
1118
      s->httpauth &= ~(uint32_t)CURLAUTH_HTTPSIG;
1119
    break;
1120
#endif
1121
60.3k
  default:
1122
60.3k
    return CURLE_UNKNOWN_OPTION;
1123
113k
  }
1124
17.1k
  return result;
1125
#else
1126
  (void)data;
1127
  (void)option;
1128
  (void)arg;
1129
  return CURLE_UNKNOWN_OPTION;
1130
#endif
1131
113k
}
1132
1133
static CURLcode setopt_long_proto(struct Curl_easy *data, CURLoption option,
1134
                                  long arg)
1135
32.5k
{
1136
32.5k
  CURLcode result = CURLE_OK;
1137
32.5k
  struct UserDefined *s = &data->set;
1138
1139
32.5k
  switch(option) {
1140
0
#ifndef CURL_DISABLE_TFTP
1141
862
  case CURLOPT_TFTP_BLKSIZE:
1142
862
    result = value_range(&arg, 0, TFTP_BLKSIZE_MIN, TFTP_BLKSIZE_MAX);
1143
862
    if(!result)
1144
862
      s->tftp_blksize = (unsigned short)arg;
1145
862
    break;
1146
0
#endif
1147
0
#ifndef CURL_DISABLE_NETRC
1148
880
  case CURLOPT_NETRC:
1149
880
    if((arg < CURL_NETRC_IGNORED) || (arg >= CURL_NETRC_LAST))
1150
487
      result = CURLE_BAD_FUNCTION_ARGUMENT;
1151
393
    else
1152
393
      s->use_netrc = (unsigned char)arg;
1153
880
    break;
1154
0
#endif
1155
0
#ifndef CURL_DISABLE_FTP
1156
683
  case CURLOPT_FTP_FILEMETHOD:
1157
683
    if((arg < CURLFTPMETHOD_DEFAULT) || (arg >= CURLFTPMETHOD_LAST))
1158
619
      result = CURLE_BAD_FUNCTION_ARGUMENT;
1159
64
    else
1160
64
      s->ftp_filemethod = (unsigned char)arg;
1161
683
    break;
1162
508
  case CURLOPT_FTP_SSL_CCC:
1163
508
    if((arg < CURLFTPSSL_CCC_NONE) || (arg >= CURLFTPSSL_CCC_LAST))
1164
471
      result = CURLE_BAD_FUNCTION_ARGUMENT;
1165
37
    else
1166
37
      s->ftp_ccc = (unsigned char)arg;
1167
508
    break;
1168
581
  case CURLOPT_FTPSSLAUTH:
1169
581
    if((arg < CURLFTPAUTH_DEFAULT) || (arg >= CURLFTPAUTH_LAST))
1170
523
      result = CURLE_BAD_FUNCTION_ARGUMENT;
1171
58
    else
1172
58
      s->ftpsslauth = (unsigned char)arg;
1173
581
    break;
1174
464
  case CURLOPT_ACCEPTTIMEOUT_MS:
1175
464
    return setopt_set_timeout_ms(&s->accepttimeout, arg);
1176
0
#endif
1177
0
#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH)
1178
309
  case CURLOPT_FTP_CREATE_MISSING_DIRS:
1179
309
    if((arg < CURLFTP_CREATE_DIR_NONE) || (arg > CURLFTP_CREATE_DIR_RETRY))
1180
254
      result = CURLE_BAD_FUNCTION_ARGUMENT;
1181
55
    else
1182
55
      s->ftp_create_missing_dirs = (unsigned char)arg;
1183
309
    break;
1184
719
  case CURLOPT_NEW_FILE_PERMS:
1185
719
    if((arg < 0) || (arg > 0777))
1186
567
      result = CURLE_BAD_FUNCTION_ARGUMENT;
1187
152
    else
1188
152
      s->new_file_perms = (unsigned int)arg;
1189
719
    break;
1190
0
#endif
1191
0
#ifndef CURL_DISABLE_RTSP
1192
2.50k
  case CURLOPT_RTSP_REQUEST:
1193
2.50k
    return setopt_RTSP_REQUEST(data, arg);
1194
979
  case CURLOPT_RTSP_CLIENT_CSEQ:
1195
979
    result = value_range(&arg, 0, 0, INT_MAX);
1196
979
    if(!result)
1197
979
      data->state.rtsp_next_client_CSeq = (uint32_t)arg;
1198
979
    break;
1199
865
  case CURLOPT_RTSP_SERVER_CSEQ:
1200
865
    result = value_range(&arg, 0, 0, INT_MAX);
1201
865
    if(!result)
1202
865
      data->state.rtsp_next_server_CSeq = (uint32_t)arg;
1203
865
    break;
1204
0
#endif
1205
#ifdef USE_SSH
1206
  case CURLOPT_SSH_AUTH_TYPES:
1207
    s->ssh_auth_types = (uint32_t)arg;
1208
    break;
1209
  case CURLOPT_NEW_DIRECTORY_PERMS:
1210
    if((arg < 0) || (arg > 0777))
1211
      result = CURLE_BAD_FUNCTION_ARGUMENT;
1212
    else
1213
      s->new_directory_perms = (unsigned int)arg;
1214
    break;
1215
#endif
1216
9.52k
  case CURLOPT_PROTOCOLS:
1217
9.52k
    s->allowed_protocols = (curl_prot_t)arg;
1218
9.52k
    break;
1219
0
  case CURLOPT_REDIR_PROTOCOLS:
1220
0
    s->redir_protocols = (curl_prot_t)arg;
1221
0
    break;
1222
0
#ifndef CURL_DISABLE_WEBSOCKETS
1223
1.17k
  case CURLOPT_WS_OPTIONS:
1224
1.17k
    s->ws_raw_mode = (bool)(arg & CURLWS_RAW_MODE);
1225
1.17k
    s->ws_no_auto_pong = (bool)(arg & CURLWS_NOAUTOPONG);
1226
1.17k
    break;
1227
0
#endif
1228
12.4k
  default:
1229
12.4k
    return CURLE_UNKNOWN_OPTION;
1230
32.5k
  }
1231
17.0k
  return result;
1232
32.5k
}
1233
1234
static CURLcode setopt_long_misc(struct Curl_easy *data, CURLoption option,
1235
                                 long arg)
1236
12.4k
{
1237
12.4k
  struct UserDefined *s = &data->set;
1238
1239
12.4k
  switch(option) {
1240
932
  case CURLOPT_TIMECONDITION:
1241
932
    if((arg < CURL_TIMECOND_NONE) || (arg >= CURL_TIMECOND_LAST))
1242
582
      return CURLE_BAD_FUNCTION_ARGUMENT;
1243
350
    s->timecondition = (unsigned char)arg;
1244
350
    break;
1245
93
  case CURLOPT_TIMEVALUE:
1246
93
    s->timevalue = (time_t)arg;
1247
93
    break;
1248
9.52k
  case CURLOPT_POSTFIELDSIZE:
1249
9.52k
    if(arg < -1)
1250
0
      return CURLE_BAD_FUNCTION_ARGUMENT;
1251
9.52k
    if(s->postfieldsize < arg &&
1252
9.52k
       s->postfields == s->str[STRING_COPYPOSTFIELDS]) {
1253
0
      curlx_safefree(s->str[STRING_COPYPOSTFIELDS]);
1254
0
      s->postfields = NULL;
1255
0
    }
1256
9.52k
    s->postfieldsize = arg;
1257
9.52k
    break;
1258
0
  case CURLOPT_INFILESIZE:
1259
0
    if(arg < -1)
1260
0
      return CURLE_BAD_FUNCTION_ARGUMENT;
1261
0
    s->filesize = arg;
1262
0
    break;
1263
1.01k
  case CURLOPT_RESUME_FROM:
1264
1.01k
    if(arg < -1)
1265
0
      return CURLE_BAD_FUNCTION_ARGUMENT;
1266
1.01k
    s->set_resume_from = arg;
1267
1.01k
    break;
1268
0
  case CURLOPT_UPLOAD_FLAGS:
1269
0
    s->upload_flags = (unsigned char)arg;
1270
0
    break;
1271
0
#ifndef CURL_DISABLE_MIME
1272
165
  case CURLOPT_MIME_OPTIONS:
1273
165
    s->mime_formescape = !!(arg & CURLMIMEOPT_FORMESCAPE);
1274
165
    break;
1275
0
#endif
1276
0
#ifndef CURL_DISABLE_HSTS
1277
107
  case CURLOPT_HSTS_CTRL:
1278
107
    if(arg & CURLHSTS_ENABLE) {
1279
58
      if(!data->hsts) {
1280
58
        data->hsts = Curl_hsts_init();
1281
58
        if(!data->hsts)
1282
0
          return CURLE_OUT_OF_MEMORY;
1283
58
      }
1284
58
    }
1285
49
    else if(!data->share || !data->share->hsts) {
1286
      /* throw away the HSTS cache unless shared */
1287
49
      Curl_hsts_cleanup(&data->hsts);
1288
      /* flush all the entries */
1289
49
      curl_slist_free_all(data->state.hstslist);
1290
49
      data->state.hstslist = NULL;
1291
49
    }
1292
0
    else
1293
      /* detach from shared HSTS cache without freeing it */
1294
0
      data->hsts = NULL;
1295
107
    break;
1296
107
#endif
1297
107
#ifndef CURL_DISABLE_ALTSVC
1298
524
  case CURLOPT_ALTSVC_CTRL:
1299
524
    return Curl_altsvc_ctrl(data, arg);
1300
0
#endif
1301
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
1302
  case CURLOPT_GSSAPI_DELEGATION:
1303
    s->gssapi_delegation = (unsigned char)arg &
1304
      (CURLGSSAPI_DELEGATION_POLICY_FLAG | CURLGSSAPI_DELEGATION_FLAG);
1305
    break;
1306
#endif
1307
102
  default:
1308
102
    return CURLE_UNKNOWN_OPTION;
1309
12.4k
  }
1310
11.2k
  return CURLE_OK;
1311
12.4k
}
1312
1313
static CURLcode setopt_long(struct Curl_easy *data, CURLoption option,
1314
                            long arg)
1315
657k
{
1316
657k
  typedef CURLcode (*setoptfunc)(struct Curl_easy *data,
1317
657k
                                 CURLoption option, long arg);
1318
657k
  static const setoptfunc setopt_call[] = {
1319
657k
    setopt_long_bool,
1320
657k
    setopt_long_net,
1321
657k
    setopt_long_http,
1322
657k
    setopt_long_proxy,
1323
657k
    setopt_long_ssl,
1324
657k
    setopt_long_proto,
1325
657k
    setopt_long_misc
1326
657k
  };
1327
657k
  size_t i;
1328
1329
1.50M
  for(i = 0; i < CURL_ARRAYSIZE(setopt_call); i++) {
1330
1.50M
    CURLcode result = setopt_call[i](data, option, arg);
1331
1.50M
    if(result != CURLE_UNKNOWN_OPTION)
1332
657k
      return result;
1333
1.50M
  }
1334
102
  return CURLE_UNKNOWN_OPTION;
1335
657k
}
1336
1337
static CURLcode setopt_slist(struct Curl_easy *data, CURLoption option,
1338
                             struct curl_slist *slist)
1339
227k
{
1340
227k
  CURLcode result = CURLE_OK;
1341
227k
  struct UserDefined *s = &data->set;
1342
227k
  switch(option) {
1343
0
#ifndef CURL_DISABLE_PROXY
1344
0
  case CURLOPT_PROXYHEADER:
1345
    /*
1346
     * Set a list with proxy headers to use (or replace internals with)
1347
     *
1348
     * Since CURLOPT_HTTPHEADER was the only way to set HTTP headers for a
1349
     * long time we remain doing it this way until CURLOPT_PROXYHEADER is
1350
     * used. As soon as this option has been used, if set to anything but
1351
     * NULL, custom headers for proxies are only picked from this list.
1352
     *
1353
     * Set this option to NULL to restore the previous behavior.
1354
     */
1355
0
    s->proxyheaders = slist;
1356
0
    break;
1357
0
#endif
1358
0
#ifndef CURL_DISABLE_HTTP
1359
0
  case CURLOPT_HTTP200ALIASES:
1360
    /*
1361
     * Set a list of aliases for HTTP 200 in response header
1362
     */
1363
0
    s->http200aliases = slist;
1364
0
    break;
1365
0
#endif
1366
0
#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH)
1367
0
  case CURLOPT_POSTQUOTE:
1368
    /*
1369
     * List of RAW FTP commands to use after a transfer
1370
     */
1371
0
    s->postquote = slist;
1372
0
    break;
1373
0
  case CURLOPT_PREQUOTE:
1374
    /*
1375
     * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
1376
     */
1377
0
    s->prequote = slist;
1378
0
    break;
1379
0
  case CURLOPT_QUOTE:
1380
    /*
1381
     * List of RAW FTP commands to use before a transfer
1382
     */
1383
0
    s->quote = slist;
1384
0
    break;
1385
0
#endif
1386
0
  case CURLOPT_RESOLVE:
1387
    /*
1388
     * List of HOST:PORT:[addresses] strings to populate the DNS cache with
1389
     * Entries added this way will remain in the cache until explicitly
1390
     * removed or the handle is cleaned up.
1391
     *
1392
     * Prefix the HOST with plus sign (+) to have the entry expire like
1393
     * automatically added entries.
1394
     *
1395
     * Prefix the HOST with dash (-) to _remove_ the entry from the cache.
1396
     *
1397
     * This API can remove any entry from the DNS cache, but only entries
1398
     * that are not actually in use right now will be pruned immediately.
1399
     */
1400
0
    s->resolve = slist;
1401
0
    data->state.resolve = s->resolve;
1402
0
    break;
1403
0
#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_MIME)
1404
19.9k
  case CURLOPT_HTTPHEADER:
1405
    /*
1406
     * Set a list with HTTP headers to use (or replace internals with)
1407
     */
1408
19.9k
    s->headers = slist;
1409
19.9k
    break;
1410
0
#endif
1411
0
#ifndef CURL_DISABLE_TELNET
1412
0
  case CURLOPT_TELNETOPTIONS:
1413
    /*
1414
     * Set a linked list of telnet options
1415
     */
1416
0
    s->telnet_options = slist;
1417
0
    break;
1418
0
#endif
1419
0
#ifndef CURL_DISABLE_SMTP
1420
1.26k
  case CURLOPT_MAIL_RCPT:
1421
    /* Set the list of mail recipients */
1422
1.26k
    s->mail_rcpt = slist;
1423
1.26k
    break;
1424
0
#endif
1425
205k
  case CURLOPT_CONNECT_TO:
1426
205k
    s->connect_to = slist;
1427
205k
    break;
1428
0
  default:
1429
0
    return CURLE_UNKNOWN_OPTION;
1430
227k
  }
1431
227k
  return result;
1432
227k
}
1433
1434
#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_SMTP) ||       \
1435
  !defined(CURL_DISABLE_IMAP)
1436
#ifndef CURL_DISABLE_MIME
1437
static CURLcode setopt_mimepost(struct Curl_easy *data, curl_mime *mimep)
1438
4.81k
{
1439
  /*
1440
   * Set to make us do MIME POST
1441
   */
1442
4.81k
  CURLcode result;
1443
4.81k
  struct UserDefined *s = &data->set;
1444
4.81k
  if(!s->mimepostp) {
1445
4.81k
    s->mimepostp = curlx_malloc(sizeof(*s->mimepostp));
1446
4.81k
    if(!s->mimepostp)
1447
0
      return CURLE_OUT_OF_MEMORY;
1448
4.81k
    Curl_mime_initpart(s->mimepostp);
1449
4.81k
  }
1450
1451
4.81k
  result = Curl_mime_set_subparts(s->mimepostp, mimep, FALSE);
1452
4.81k
  if(!result) {
1453
4.81k
    s->method = HTTPREQ_POST_MIME;
1454
4.81k
    s->opt_no_body = FALSE; /* this is implied */
1455
4.81k
#ifndef CURL_DISABLE_FORM_API
1456
4.81k
    Curl_mime_cleanpart(data->state.formp);
1457
4.81k
    curlx_safefree(data->state.formp);
1458
4.81k
    data->state.mimepost = NULL;
1459
4.81k
#endif
1460
4.81k
  }
1461
4.81k
  return result;
1462
4.81k
}
1463
#endif /* !CURL_DISABLE_MIME */
1464
#endif /* !CURL_DISABLE_HTTP || !CURL_DISABLE_SMTP || !CURL_DISABLE_IMAP */
1465
1466
static CURLcode setopt_share(struct Curl_easy *data, struct Curl_share *set)
1467
9.52k
{
1468
9.52k
  CURLcode result;
1469
1470
9.52k
  if(data->conn) {
1471
    /* As this handle already has a connection attached, changing share now
1472
       would be complicated and error-prone */
1473
0
    infof(data, "Cannot change share object while in use");
1474
0
    result = CURLE_BAD_FUNCTION_ARGUMENT;
1475
0
  }
1476
9.52k
  else {
1477
    /* disconnect from old share, if any and possible */
1478
9.52k
    result = Curl_share_easy_unlink(data);
1479
9.52k
    if(!result && GOOD_SHARE_HANDLE(set))
1480
      /* use new share if it set */
1481
0
      result = Curl_share_easy_link(data, set);
1482
9.52k
  }
1483
9.52k
  return result;
1484
9.52k
}
1485
1486
/* assorted pointer type arguments */
1487
static CURLcode setopt_pointers(struct Curl_easy *data, CURLoption option,
1488
                                va_list param)
1489
16.5k
{
1490
16.5k
  CURLcode result = CURLE_OK;
1491
16.5k
  struct UserDefined *s = &data->set;
1492
16.5k
  switch(option) {
1493
0
  case CURLOPT_CURLU:
1494
    /*
1495
     * pass CURLU to set URL
1496
     */
1497
0
    Curl_bufref_free(&data->state.url);
1498
0
    curlx_safefree(s->str[STRING_SET_URL]);
1499
0
    s->uh = va_arg(param, CURLU *);
1500
0
    break;
1501
0
#ifndef CURL_DISABLE_HTTP
1502
0
#ifndef CURL_DISABLE_FORM_API
1503
2.20k
  case CURLOPT_HTTPPOST:
1504
    /*
1505
     * Set to make us do HTTP POST. Legacy API-style.
1506
     */
1507
2.20k
    s->httppost = va_arg(param, struct curl_httppost *);
1508
2.20k
    s->method = HTTPREQ_POST_FORM;
1509
2.20k
    s->opt_no_body = FALSE; /* this is implied */
1510
2.20k
    Curl_mime_cleanpart(data->state.formp);
1511
2.20k
    curlx_safefree(data->state.formp);
1512
2.20k
    data->state.mimepost = NULL;
1513
2.20k
    break;
1514
0
#endif /* !CURL_DISABLE_FORM_API */
1515
0
#endif /* !CURL_DISABLE_HTTP */
1516
0
#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_SMTP) ||       \
1517
0
  !defined(CURL_DISABLE_IMAP)
1518
0
#ifndef CURL_DISABLE_MIME
1519
4.81k
  case CURLOPT_MIMEPOST:
1520
4.81k
    result = setopt_mimepost(data, va_arg(param, curl_mime *));
1521
4.81k
    break;
1522
0
#endif /* !CURL_DISABLE_MIME */
1523
0
#endif /* !CURL_DISABLE_HTTP || !CURL_DISABLE_SMTP || !CURL_DISABLE_IMAP */
1524
0
  case CURLOPT_STDERR:
1525
    /*
1526
     * Set to a FILE * that should receive all error writes. This
1527
     * defaults to stderr for normal operations.
1528
     */
1529
0
    s->err = va_arg(param, FILE *);
1530
0
    if(!s->err)
1531
0
      s->err = stderr;
1532
0
    break;
1533
9.52k
  case CURLOPT_SHARE:
1534
9.52k
    return setopt_share(data, va_arg(param, struct Curl_share *));
1535
1536
0
  default:
1537
0
    return CURLE_UNKNOWN_OPTION;
1538
16.5k
  }
1539
7.02k
  return result;
1540
16.5k
}
1541
1542
#ifndef CURL_DISABLE_COOKIES
1543
static CURLcode cookielist(struct Curl_easy *data, const char *ptr)
1544
28.5k
{
1545
28.5k
  CURLcode result = CURLE_OK;
1546
28.5k
  if(!ptr)
1547
0
    return CURLE_OK;
1548
1549
28.5k
  if(curl_strequal(ptr, "ALL")) {
1550
    /* clear all cookies */
1551
15
    Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1552
15
    Curl_cookie_clearall(data->cookies);
1553
15
    Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1554
15
  }
1555
28.5k
  else if(curl_strequal(ptr, "SESS")) {
1556
    /* clear session cookies */
1557
15
    Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1558
15
    Curl_cookie_clearsess(data->cookies);
1559
15
    Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1560
15
  }
1561
28.4k
  else if(curl_strequal(ptr, "FLUSH")) {
1562
    /* flush cookies to file, takes care of the locking */
1563
29
    Curl_flush_cookies(data, FALSE);
1564
29
  }
1565
28.4k
  else if(curl_strequal(ptr, "RELOAD")) {
1566
    /* reload cookies from file */
1567
33
    return Curl_cookie_loadfiles(data);
1568
33
  }
1569
28.4k
  else {
1570
28.4k
    if(!data->cookies) {
1571
      /* if cookie engine was not running, activate it */
1572
28.4k
      data->cookies = Curl_cookie_init();
1573
28.4k
      if(!data->cookies)
1574
0
        return CURLE_OUT_OF_MEMORY;
1575
28.4k
      data->state.cookie_engine = TRUE;
1576
28.4k
    }
1577
1578
    /* general protection against mistakes and abuse */
1579
28.4k
    if(strlen(ptr) > CURL_MAX_INPUT_LENGTH)
1580
0
      return CURLE_BAD_FUNCTION_ARGUMENT;
1581
1582
28.4k
    Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
1583
28.4k
    if(checkprefix("Set-Cookie:", ptr))
1584
      /* HTTP Header format line */
1585
17.5k
      result = Curl_cookie_add(data, data->cookies, TRUE, FALSE, ptr + 11,
1586
17.5k
                               NULL, NULL, TRUE);
1587
10.9k
    else
1588
      /* Netscape format line */
1589
10.9k
      result = Curl_cookie_add(data, data->cookies, FALSE, FALSE, ptr, NULL,
1590
10.9k
                               NULL, TRUE);
1591
28.4k
    Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
1592
28.4k
  }
1593
28.4k
  return result;
1594
28.5k
}
1595
1596
static CURLcode cookiefile(struct Curl_easy *data, const char *ptr)
1597
196k
{
1598
  /*
1599
   * Set cookie file to read and parse. Can be used multiple times.
1600
   */
1601
196k
  if(ptr) {
1602
196k
    struct curl_slist *cl;
1603
    /* general protection against mistakes and abuse */
1604
196k
    if(strlen(ptr) > CURL_MAX_INPUT_LENGTH)
1605
0
      return CURLE_BAD_FUNCTION_ARGUMENT;
1606
    /* append the cookie filename to the list of filenames, and deal with
1607
       them later */
1608
196k
    cl = curl_slist_append(data->state.cookielist, ptr);
1609
196k
    if(!cl) {
1610
0
      curl_slist_free_all(data->state.cookielist);
1611
0
      data->state.cookielist = NULL;
1612
0
      return CURLE_OUT_OF_MEMORY;
1613
0
    }
1614
196k
    data->state.cookielist = cl; /* store the list for later use */
1615
196k
  }
1616
0
  else {
1617
    /* clear the list of cookie files */
1618
0
    curl_slist_free_all(data->state.cookielist);
1619
0
    data->state.cookielist = NULL;
1620
1621
0
    if(!data->share || !data->share->cookies) {
1622
      /* throw away all existing cookies if this is not a shared cookie
1623
         container */
1624
0
      Curl_cookie_clearall(data->cookies);
1625
0
      Curl_cookie_cleanup(data->cookies);
1626
0
    }
1627
    /* disable the cookie engine */
1628
0
    data->cookies = NULL;
1629
0
  }
1630
196k
  return CURLE_OK;
1631
196k
}
1632
#endif
1633
1634
#ifndef CURL_DISABLE_PROXY
1635
static CURLcode setproxy(struct Curl_easy *data, const char *proxy)
1636
34.3k
{
1637
34.3k
  if((data->set.str[STRING_PROXY] && proxy) &&
1638
     /* there was one set, is this a new one? */
1639
0
     !strcmp(data->set.str[STRING_PROXY], proxy))
1640
0
    return CURLE_OK; /* same one as before */
1641
1642
34.3k
  changeproxy(data);
1643
34.3k
  return Curl_setstropt(&data->set.str[STRING_PROXY], proxy);
1644
34.3k
}
1645
1646
static CURLcode setopt_cptr_proxy(struct Curl_easy *data, CURLoption option,
1647
                                  char *ptr)
1648
2.42M
{
1649
2.42M
  CURLcode result = CURLE_OK;
1650
2.42M
  struct UserDefined *s = &data->set;
1651
2.42M
  switch(option) {
1652
2.44k
  case CURLOPT_PROXYUSERPWD: {
1653
    /*
1654
     * user:password needed to use the proxy
1655
     */
1656
2.44k
    char *u = NULL;
1657
2.44k
    char *p = NULL;
1658
2.44k
    result = setstropt_userpwd(ptr, &u, &p);
1659
1660
    /* URL decode the components */
1661
2.44k
    if(!result) {
1662
2.44k
      curlx_safefree(s->str[STRING_PROXYUSERNAME]);
1663
2.44k
      curlx_safefree(s->str[STRING_PROXYPASSWORD]);
1664
2.44k
      if(u)
1665
2.44k
        result = Curl_urldecode(u, 0, &s->str[STRING_PROXYUSERNAME], NULL,
1666
2.44k
                                REJECT_ZERO);
1667
2.44k
    }
1668
2.44k
    if(!result && p)
1669
363
      result = Curl_urldecode(p, 0, &s->str[STRING_PROXYPASSWORD], NULL,
1670
363
                              REJECT_ZERO);
1671
2.44k
    curlx_free(u);
1672
2.44k
    curlx_strzero(p);
1673
2.44k
    curlx_free(p);
1674
2.44k
    break;
1675
0
  }
1676
100
  case CURLOPT_PROXYUSERNAME:
1677
    /*
1678
     * authentication username to use in the operation
1679
     */
1680
100
    return Curl_setstropt(&s->str[STRING_PROXYUSERNAME], ptr);
1681
1682
335
  case CURLOPT_PROXYPASSWORD:
1683
    /*
1684
     * authentication password to use in the operation
1685
     */
1686
335
    return Curl_setstropt(&s->str[STRING_PROXYPASSWORD], ptr);
1687
1688
3.26k
  case CURLOPT_NOPROXY:
1689
    /*
1690
     * proxy exception list
1691
     */
1692
3.26k
    return Curl_setstropt(&s->str[STRING_NOPROXY], ptr);
1693
378
  case CURLOPT_PROXY_SSLCERT:
1694
    /*
1695
     * String that holds filename of the SSL certificate to use for proxy
1696
     */
1697
378
    return Curl_setstropt(&s->str[STRING_CERT_PROXY], ptr);
1698
284
  case CURLOPT_PROXY_SSLCERTTYPE:
1699
    /*
1700
     * String that holds file type of the SSL certificate to use for proxy
1701
     */
1702
284
    return Curl_setstropt(&s->str[STRING_CERT_TYPE_PROXY], ptr);
1703
271
  case CURLOPT_PROXY_SSLKEY:
1704
    /*
1705
     * String that holds filename of the SSL key to use for proxy
1706
     */
1707
271
    return Curl_setstropt(&s->str[STRING_KEY_PROXY], ptr);
1708
215
  case CURLOPT_PROXY_KEYPASSWD:
1709
    /*
1710
     * String that holds the SSL private key password for proxy.
1711
     */
1712
215
    return Curl_setstropt(&s->str[STRING_KEY_PASSWD_PROXY], ptr);
1713
318
  case CURLOPT_PROXY_SSLKEYTYPE:
1714
    /*
1715
     * String that holds file type of the SSL key to use for proxy
1716
     */
1717
318
    return Curl_setstropt(&s->str[STRING_KEY_TYPE_PROXY], ptr);
1718
3.26k
  case CURLOPT_PROXY_SSL_CIPHER_LIST:
1719
3.26k
    if(Curl_ssl_supports(data, SSLSUPP_CIPHER_LIST)) {
1720
      /* set a list of cipher we want to use in the SSL connection for proxy */
1721
3.26k
      return Curl_setstropt(&s->str[STRING_SSL_CIPHER_LIST_PROXY], ptr);
1722
3.26k
    }
1723
0
    else
1724
0
      return CURLE_NOT_BUILT_IN;
1725
814
  case CURLOPT_PROXY_TLS13_CIPHERS:
1726
814
    if(Curl_ssl_supports(data, SSLSUPP_TLS13_CIPHERSUITES))
1727
      /* set preferred list of TLS 1.3 cipher suites for proxy */
1728
814
      return Curl_setstropt(&s->str[STRING_SSL_CIPHER13_LIST_PROXY], ptr);
1729
0
    else
1730
0
      return CURLE_NOT_BUILT_IN;
1731
34.3k
  case CURLOPT_PROXY:
1732
    /*
1733
     * Set proxy server:port to use as proxy.
1734
     *
1735
     * If the proxy is set to "" (and CURLOPT_PRE_PROXY is set to "" or NULL)
1736
     * we explicitly say that we do not want to use a proxy (even though there
1737
     * might be environment variables saying so).
1738
     *
1739
     * Setting it to NULL, means no proxy but allows the environment variables
1740
     * to decide for us (if CURLOPT_PRE_PROXY setting it to NULL).
1741
     */
1742
34.3k
    return setproxy(data, ptr);
1743
6.16k
  case CURLOPT_PRE_PROXY:
1744
    /*
1745
     * Set proxy server:port to use as SOCKS proxy.
1746
     *
1747
     * If the proxy is set to "" or NULL we explicitly say that we do not want
1748
     * to use the socks proxy.
1749
     */
1750
6.16k
    return Curl_setstropt(&s->str[STRING_PRE_PROXY], ptr);
1751
0
  case CURLOPT_SOCKS5_GSSAPI_SERVICE:
1752
254
  case CURLOPT_PROXY_SERVICE_NAME:
1753
    /*
1754
     * Set proxy authentication service name for Kerberos 5 and SPNEGO
1755
     */
1756
254
    return Curl_setstropt(&s->str[STRING_PROXY_SERVICE_NAME], ptr);
1757
243
  case CURLOPT_PROXY_PINNEDPUBLICKEY:
1758
    /*
1759
     * Set pinned public key for SSL connection.
1760
     * Specify filename of the public key in DER format.
1761
     */
1762
243
#ifdef USE_SSL
1763
243
    if(Curl_ssl_supports(data, SSLSUPP_PINNEDPUBKEY))
1764
243
      return Curl_setstropt(&s->str[STRING_SSL_PINNEDPUBLICKEY_PROXY], ptr);
1765
0
#endif
1766
0
    return CURLE_NOT_BUILT_IN;
1767
1768
527
  case CURLOPT_HAPROXY_CLIENT_IP:
1769
    /*
1770
     * Set the client IP to send through HAProxy PROXY protocol
1771
     */
1772
527
    result = Curl_setstropt(&s->str[STRING_HAPROXY_CLIENT_IP], ptr);
1773
1774
    /* enable the HAProxy protocol if an IP is provided */
1775
527
    s->haproxyprotocol = !!s->str[STRING_HAPROXY_CLIENT_IP];
1776
527
    break;
1777
465
  case CURLOPT_PROXY_CAINFO:
1778
    /*
1779
     * Set CA info SSL connection for proxy. Specify filename of the
1780
     * CA certificate
1781
     */
1782
465
    result = Curl_setstropt(&s->str[STRING_SSL_CAFILE_PROXY], ptr);
1783
465
    s->proxy_ssl.custom_cafile = !!s->str[STRING_SSL_CAFILE_PROXY];
1784
465
    return result;
1785
357
  case CURLOPT_PROXY_CRLFILE:
1786
    /*
1787
     * Set CRL file info for SSL connection for proxy. Specify filename of the
1788
     * CRL to check certificates revocation
1789
     */
1790
357
    if(Curl_ssl_supports(data, SSLSUPP_CRLFILE))
1791
357
      return Curl_setstropt(&s->str[STRING_SSL_CRLFILE_PROXY], ptr);
1792
0
    return CURLE_NOT_BUILT_IN;
1793
279
  case CURLOPT_PROXY_ISSUERCERT:
1794
    /*
1795
     * Set Issuer certificate file to check certificates issuer
1796
     */
1797
279
    if(Curl_ssl_supports(data, SSLSUPP_ISSUERCERT))
1798
279
      return Curl_setstropt(&s->str[STRING_SSL_ISSUERCERT_PROXY], ptr);
1799
0
    return CURLE_NOT_BUILT_IN;
1800
878
  case CURLOPT_PROXY_CAPATH:
1801
    /*
1802
     * Set CA path info for SSL connection proxy. Specify directory name of the
1803
     * CA certificates which have been prepared using openssl c_rehash utility.
1804
     */
1805
878
#ifdef USE_SSL
1806
878
    if(Curl_ssl_supports(data, SSLSUPP_CA_PATH)) {
1807
      /* This does not work on Windows. */
1808
878
      result = Curl_setstropt(&s->str[STRING_SSL_CAPATH_PROXY], ptr);
1809
878
      s->proxy_ssl.custom_capath = !!s->str[STRING_SSL_CAPATH_PROXY];
1810
878
      return result;
1811
878
    }
1812
0
#endif
1813
0
    return CURLE_NOT_BUILT_IN;
1814
2.37M
  default:
1815
2.37M
    return CURLE_UNKNOWN_OPTION;
1816
2.42M
  }
1817
2.97k
  return result;
1818
2.42M
}
1819
#endif
1820
1821
#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_MQTT)
1822
/*
1823
 * A string with POST data. Makes curl HTTP POST. Even if it is NULL. If
1824
 * needed, CURLOPT_POSTFIELDSIZE must have been set prior to
1825
 * CURLOPT_COPYPOSTFIELDS and not altered later.
1826
 */
1827
static CURLcode setopt_copypostfields(const char *ptr, struct UserDefined *s)
1828
0
{
1829
0
  CURLcode result = CURLE_OK;
1830
0
  if(s->postfieldsize < -1)
1831
0
    return CURLE_BAD_FUNCTION_ARGUMENT;
1832
0
  if(!ptr || s->postfieldsize == -1)
1833
0
    result = Curl_setstropt(&s->str[STRING_COPYPOSTFIELDS], ptr);
1834
0
  else {
1835
0
    size_t pflen = curlx_sotouz_range(s->postfieldsize, 0, SIZE_MAX);
1836
0
    if(pflen == SIZE_MAX)
1837
0
      return CURLE_OUT_OF_MEMORY;
1838
0
    else {
1839
      /* Allocate even when size == 0. This satisfies the need of possible
1840
         later address compare to detect the COPYPOSTFIELDS mode, and to mark
1841
         that postfields is used rather than read function or form data. */
1842
0
      char *p = curlx_memdup0(ptr, pflen);
1843
0
      if(!p)
1844
0
        return CURLE_OUT_OF_MEMORY;
1845
0
      else {
1846
0
        curlx_free(s->str[STRING_COPYPOSTFIELDS]);
1847
0
        s->str[STRING_COPYPOSTFIELDS] = p;
1848
0
      }
1849
0
    }
1850
0
  }
1851
1852
0
  s->postfields = s->str[STRING_COPYPOSTFIELDS];
1853
0
  s->method = HTTPREQ_POST;
1854
0
  return result;
1855
0
}
1856
#endif
1857
1858
#ifdef USE_ECH
1859
static CURLcode setopt_ech(struct Curl_easy *data, const char *ptr)
1860
{
1861
  struct UserDefined *s = &data->set;
1862
  CURLcode result = CURLE_OK;
1863
1864
  if(!ptr || !strcmp(ptr, "false"))
1865
    s->tls_ech = CURLECH_DISABLE;
1866
  else {
1867
    size_t plen = strlen(ptr);
1868
    if(plen > CURL_MAX_INPUT_LENGTH)
1869
      result = CURLE_BAD_FUNCTION_ARGUMENT;
1870
    else {
1871
      if(!strcmp(ptr, "grease"))
1872
        s->tls_ech = CURLECH_GREASE;
1873
      else if(!strcmp(ptr, "true"))
1874
        s->tls_ech = CURLECH_ENABLE;
1875
      else if(!strcmp(ptr, "hard"))
1876
        s->tls_ech = CURLECH_HARD;
1877
      else if(plen > 4 && !strncmp(ptr, "ecl:", 4)) {
1878
        if(!s->tls_ech)
1879
          s->tls_ech = CURLECH_HARD;
1880
        result = Curl_setstropt(&s->str[STRING_ECH_CONFIG], ptr + 4);
1881
      }
1882
      else if(plen > 3 && !strncmp(ptr, "pn:", 3)) {
1883
        if(!s->tls_ech)
1884
          s->tls_ech = CURLECH_HARD;
1885
        result = Curl_setstropt(&s->str[STRING_ECH_PUBLIC], ptr + 3);
1886
      }
1887
      else
1888
        result = CURLE_BAD_FUNCTION_ARGUMENT;
1889
    }
1890
  }
1891
  return result;
1892
}
1893
#else
1894
19
#define setopt_ech(x,y) CURLE_NOT_BUILT_IN
1895
#endif
1896
1897
#if defined(USE_SSL) || defined(USE_SSH)
1898
/* One of the options is used for both TLS and SSH */
1899
static CURLcode setopt_cptr_ssl(struct Curl_easy *data, CURLoption option,
1900
                                char *ptr)
1901
2.37M
{
1902
2.37M
  CURLcode result = CURLE_OK;
1903
2.37M
  struct UserDefined *s = &data->set;
1904
1905
2.37M
  switch(option) {
1906
242
  case CURLOPT_KEYPASSWD:
1907
    /*
1908
     * String that holds the SSL or SSH private key password.
1909
     */
1910
242
    result = Curl_setstropt(&s->str[STRING_KEY_PASSWD], ptr);
1911
242
    break;
1912
0
#ifdef USE_SSL
1913
11.2k
  case CURLOPT_CAINFO:
1914
    /*
1915
     * Set CA info for SSL connection. Specify filename of the CA certificate
1916
     */
1917
11.2k
    result = Curl_setstropt(&s->str[STRING_SSL_CAFILE], ptr);
1918
11.2k
    s->ssl.custom_cafile = !!s->str[STRING_SSL_CAFILE];
1919
11.2k
    return result;
1920
10.9k
  case CURLOPT_CAPATH:
1921
    /*
1922
     * Set CA path info for SSL connection. Specify directory name of the CA
1923
     * certificates which have been prepared using openssl c_rehash utility.
1924
     */
1925
10.9k
    if(Curl_ssl_supports(data, SSLSUPP_CA_PATH)) {
1926
      /* This does not work on Windows. */
1927
10.9k
      result = Curl_setstropt(&s->str[STRING_SSL_CAPATH], ptr);
1928
10.9k
      s->ssl.custom_capath = !!s->str[STRING_SSL_CAPATH];
1929
10.9k
      return result;
1930
10.9k
    }
1931
0
    return CURLE_NOT_BUILT_IN;
1932
205k
  case CURLOPT_CRLFILE:
1933
    /*
1934
     * Set CRL file info for SSL connection. Specify filename of the CRL
1935
     * to check certificates revocation
1936
     */
1937
205k
    if(Curl_ssl_supports(data, SSLSUPP_CRLFILE))
1938
205k
      return Curl_setstropt(&s->str[STRING_SSL_CRLFILE], ptr);
1939
0
    return CURLE_NOT_BUILT_IN;
1940
6.38k
  case CURLOPT_SSL_CIPHER_LIST:
1941
6.38k
    if(Curl_ssl_supports(data, SSLSUPP_CIPHER_LIST))
1942
      /* set a list of cipher we want to use in the SSL connection */
1943
6.38k
      return Curl_setstropt(&s->str[STRING_SSL_CIPHER_LIST], ptr);
1944
0
    else
1945
0
      return CURLE_NOT_BUILT_IN;
1946
1.14k
  case CURLOPT_TLS13_CIPHERS:
1947
1.14k
    if(Curl_ssl_supports(data, SSLSUPP_TLS13_CIPHERSUITES))
1948
      /* set preferred list of TLS 1.3 cipher suites */
1949
1.14k
      return Curl_setstropt(&s->str[STRING_SSL_CIPHER13_LIST], ptr);
1950
0
    else
1951
0
      return CURLE_NOT_BUILT_IN;
1952
0
  case CURLOPT_RANDOM_FILE:
1953
0
    break;
1954
0
  case CURLOPT_EGDSOCKET:
1955
0
    break;
1956
0
  case CURLOPT_SSL_CTX_DATA:
1957
    /*
1958
     * Set an SSL_CTX callback parameter pointer
1959
     */
1960
0
    if(Curl_ssl_supports(data, SSLSUPP_SSL_CTX)) {
1961
0
      s->ssl.fsslctxp = ptr;
1962
0
      break;
1963
0
    }
1964
0
    else
1965
0
      return CURLE_NOT_BUILT_IN;
1966
426
  case CURLOPT_SSLCERT:
1967
    /*
1968
     * String that holds filename of the SSL certificate to use
1969
     */
1970
426
    return Curl_setstropt(&s->str[STRING_CERT], ptr);
1971
346
  case CURLOPT_SSLCERTTYPE:
1972
    /*
1973
     * String that holds file type of the SSL certificate to use
1974
     */
1975
346
    return Curl_setstropt(&s->str[STRING_CERT_TYPE], ptr);
1976
203
  case CURLOPT_SSLKEY:
1977
    /*
1978
     * String that holds filename of the SSL key to use
1979
     */
1980
203
    return Curl_setstropt(&s->str[STRING_KEY], ptr);
1981
350
  case CURLOPT_SSLKEYTYPE:
1982
    /*
1983
     * String that holds file type of the SSL key to use
1984
     */
1985
350
    return Curl_setstropt(&s->str[STRING_KEY_TYPE], ptr);
1986
10.2k
  case CURLOPT_SSLENGINE:
1987
    /*
1988
     * String that holds the SSL crypto engine.
1989
     */
1990
10.2k
    if(ptr && ptr[0]) {
1991
10.2k
      result = Curl_setstropt(&s->str[STRING_SSL_ENGINE], ptr);
1992
10.2k
      if(!result) {
1993
10.2k
        result = Curl_ssl_set_engine(data, ptr);
1994
10.2k
      }
1995
10.2k
    }
1996
10.2k
    break;
1997
242
  case CURLOPT_ISSUERCERT:
1998
    /*
1999
     * Set Issuer certificate file
2000
     * to check certificates issuer
2001
     */
2002
242
    if(Curl_ssl_supports(data, SSLSUPP_ISSUERCERT))
2003
242
      return Curl_setstropt(&s->str[STRING_SSL_ISSUERCERT], ptr);
2004
0
    return CURLE_NOT_BUILT_IN;
2005
5.77k
  case CURLOPT_SSL_EC_CURVES:
2006
    /*
2007
     * Set accepted curves in SSL connection setup.
2008
     * Specify colon-delimited list of curve algorithm names.
2009
     */
2010
5.77k
    if(Curl_ssl_supports(data, SSLSUPP_SSL_EC_CURVES))
2011
5.77k
      return Curl_setstropt(&s->str[STRING_SSL_EC_CURVES], ptr);
2012
0
    return CURLE_NOT_BUILT_IN;
2013
0
  case CURLOPT_SSL_SIGNATURE_ALGORITHMS:
2014
    /*
2015
     * Set accepted signature algorithms.
2016
     * Specify colon-delimited list of signature scheme names.
2017
     */
2018
0
    if(Curl_ssl_supports(data, SSLSUPP_SIGNATURE_ALGORITHMS))
2019
0
      return Curl_setstropt(&s->str[STRING_SSL_SIGNATURE_ALGORITHMS], ptr);
2020
0
    return CURLE_NOT_BUILT_IN;
2021
258
  case CURLOPT_PINNEDPUBLICKEY:
2022
    /*
2023
     * Set pinned public key for SSL connection.
2024
     * Specify filename of the public key in DER format.
2025
     */
2026
258
    if(Curl_ssl_supports(data, SSLSUPP_PINNEDPUBKEY))
2027
258
      return Curl_setstropt(&s->str[STRING_SSL_PINNEDPUBLICKEY], ptr);
2028
0
    return CURLE_NOT_BUILT_IN;
2029
19
  case CURLOPT_ECH:
2030
19
    return setopt_ech(data, ptr);
2031
0
#endif
2032
2.11M
  default:
2033
2.11M
    return CURLE_UNKNOWN_OPTION;
2034
2.37M
  }
2035
10.5k
  return result;
2036
2.37M
}
2037
#endif
2038
2039
#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_MQTT)
2040
static CURLcode setopt_cptr_http_mqtt(struct Curl_easy *data,
2041
                                      CURLoption option, char *ptr)
2042
2.11M
{
2043
2.11M
  CURLcode result = CURLE_OK;
2044
2.11M
  struct UserDefined *s = &data->set;
2045
2046
2.11M
  switch(option) {
2047
0
  case CURLOPT_COPYPOSTFIELDS:
2048
0
    return setopt_copypostfields(ptr, s);
2049
2050
14.0k
  case CURLOPT_POSTFIELDS:
2051
    /*
2052
     * Like above, but use static data instead of copying it.
2053
     */
2054
14.0k
    s->postfields = ptr;
2055
    /* Release old copied data. */
2056
14.0k
    curlx_safefree(s->str[STRING_COPYPOSTFIELDS]);
2057
14.0k
    s->method = HTTPREQ_POST;
2058
14.0k
    break;
2059
2060
0
#ifndef CURL_DISABLE_HTTP
2061
0
  case CURLOPT_TRAILERDATA:
2062
0
    s->trailer_data = ptr;
2063
0
    break;
2064
6.71k
  case CURLOPT_ACCEPT_ENCODING:
2065
    /*
2066
     * String to use at the value of Accept-Encoding header.
2067
     *
2068
     * If the encoding is set to "" we use an Accept-Encoding header that
2069
     * encompasses all the encodings we support.
2070
     * If the encoding is set to NULL we do not send an Accept-Encoding header
2071
     * and ignore any received Content-Encoding header.
2072
     *
2073
     */
2074
6.71k
    if(ptr && !*ptr) {
2075
4.79k
      ptr = Curl_get_content_encodings();
2076
4.79k
      if(ptr) {
2077
4.79k
        curlx_free(s->str[STRING_ENCODING]);
2078
4.79k
        s->str[STRING_ENCODING] = ptr;
2079
4.79k
      }
2080
0
      else
2081
0
        result = CURLE_OUT_OF_MEMORY;
2082
4.79k
      return result;
2083
4.79k
    }
2084
1.91k
    return Curl_setstropt(&s->str[STRING_ENCODING], ptr);
2085
2086
0
#ifndef CURL_DISABLE_AWS
2087
11.2k
  case CURLOPT_AWS_SIGV4:
2088
    /*
2089
     * String that is merged to some authentication
2090
     * parameters are used by the algorithm.
2091
     */
2092
11.2k
    result = Curl_setstropt(&s->str[STRING_AWS_SIGV4], ptr);
2093
    /*
2094
     * Basic has been set by default; it needs to be unset here.
2095
     */
2096
11.2k
    if(s->str[STRING_AWS_SIGV4])
2097
11.2k
      s->httpauth = CURLAUTH_AWS_SIGV4;
2098
11.2k
    break;
2099
0
#endif
2100
#ifndef CURL_DISABLE_HTTPSIG
2101
  case CURLOPT_HTTPSIG_KEY:
2102
    result = Curl_setstropt(&s->str[STRING_HTTPSIG_KEY], ptr);
2103
    break;
2104
  case CURLOPT_HTTPSIG_KEYID:
2105
    result = Curl_setstropt(&s->str[STRING_HTTPSIG_KEYID], ptr);
2106
    break;
2107
  case CURLOPT_HTTPSIG_HEADERS:
2108
    result = Curl_setstropt(&s->str[STRING_HTTPSIG_HEADERS], ptr);
2109
    break;
2110
#endif
2111
4.43k
  case CURLOPT_REFERER:
2112
    /*
2113
     * String to set in the HTTP Referer: field.
2114
     */
2115
4.43k
    Curl_bufref_free(&data->state.referer);
2116
4.43k
    result = Curl_setstropt(&s->str[STRING_SET_REFERER], ptr);
2117
4.43k
    break;
2118
2119
9.12k
  case CURLOPT_USERAGENT:
2120
    /*
2121
     * String to use in the HTTP User-Agent field
2122
     */
2123
9.12k
    return Curl_setstropt(&s->str[STRING_USERAGENT], ptr);
2124
2125
0
#ifndef CURL_DISABLE_COOKIES
2126
693
  case CURLOPT_COOKIE:
2127
    /*
2128
     * Cookie string to send to the remote server in the request.
2129
     */
2130
693
    return Curl_setstropt(&s->str[STRING_COOKIE], ptr);
2131
2132
196k
  case CURLOPT_COOKIEFILE:
2133
196k
    return cookiefile(data, ptr);
2134
2135
205k
  case CURLOPT_COOKIEJAR:
2136
    /*
2137
     * Set cookie filename to dump all cookies to when we are done.
2138
     */
2139
205k
    result = Curl_setstropt(&s->str[STRING_COOKIEJAR], ptr);
2140
205k
    if(!result) {
2141
      /*
2142
       * Activate the cookie parser. This may or may not already
2143
       * have been made.
2144
       */
2145
205k
      if(!data->cookies)
2146
178k
        data->cookies = Curl_cookie_init();
2147
205k
      if(!data->cookies)
2148
0
        result = CURLE_OUT_OF_MEMORY;
2149
205k
      else
2150
205k
        data->state.cookie_engine = TRUE;
2151
205k
    }
2152
205k
    break;
2153
2154
28.5k
  case CURLOPT_COOKIELIST:
2155
28.5k
    return cookielist(data, ptr);
2156
0
#endif /* !CURL_DISABLE_COOKIES */
2157
2158
0
#endif /* !CURL_DISABLE_HTTP */
2159
1.64M
  default:
2160
1.64M
    return CURLE_UNKNOWN_OPTION;
2161
2.11M
  }
2162
235k
  return result;
2163
2.11M
}
2164
#endif /* !CURL_DISABLE_HTTP || !CURL_DISABLE_MQTT */
2165
2166
#ifdef USE_SSH
2167
static CURLcode setopt_cptr_ssh(struct Curl_easy *data, CURLoption option,
2168
                                char *ptr)
2169
{
2170
  struct UserDefined *s = &data->set;
2171
  switch(option) {
2172
  case CURLOPT_SSH_PUBLIC_KEYFILE:
2173
    /*
2174
     * Use this file instead of the $HOME/.ssh/id_dsa.pub file
2175
     */
2176
    return Curl_setstropt(&s->str[STRING_SSH_PUBLIC_KEY], ptr);
2177
  case CURLOPT_SSH_PRIVATE_KEYFILE:
2178
    /*
2179
     * Use this file instead of the $HOME/.ssh/id_dsa file
2180
     */
2181
    return Curl_setstropt(&s->str[STRING_SSH_PRIVATE_KEY], ptr);
2182
  case CURLOPT_SSH_KEYDATA:
2183
    /*
2184
     * Custom client data to pass to the SSH keyfunc callback
2185
     */
2186
    s->ssh_keyfunc_userp = ptr;
2187
    break;
2188
  case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
2189
    /*
2190
     * Option to allow for the MD5 of the host public key to be checked
2191
     * for validation purposes.
2192
     */
2193
    return Curl_setstropt(&s->str[STRING_SSH_HOST_PUBLIC_KEY_MD5], ptr);
2194
  case CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256:
2195
    /*
2196
     * Option to allow for the SHA256 of the host public key to be checked
2197
     * for validation purposes.
2198
     */
2199
    return Curl_setstropt(&s->str[STRING_SSH_HOST_PUBLIC_KEY_SHA256], ptr);
2200
  case CURLOPT_SSH_KNOWNHOSTS:
2201
    /*
2202
     * Store the filename to read known hosts from.
2203
     */
2204
    return Curl_setstropt(&s->str[STRING_SSH_KNOWNHOSTS], ptr);
2205
#ifdef USE_LIBSSH2
2206
  case CURLOPT_SSH_HOSTKEYDATA:
2207
    /*
2208
     * Custom client data to pass to the SSH keyfunc callback
2209
     */
2210
    s->ssh_hostkeyfunc_userp = ptr;
2211
    break;
2212
#endif /* USE_LIBSSH2 */
2213
  default:
2214
    return CURLE_UNKNOWN_OPTION;
2215
  }
2216
  return CURLE_OK;
2217
}
2218
#endif /* USE_SSH */
2219
2220
#ifndef CURL_DISABLE_FTP
2221
static CURLcode setopt_cptr_ftp(struct Curl_easy *data, CURLoption option,
2222
                                char *ptr)
2223
2.11M
{
2224
2.11M
  CURLcode result = CURLE_OK;
2225
2.11M
  struct UserDefined *s = &data->set;
2226
2.11M
  switch(option) {
2227
157
  case CURLOPT_FTPPORT:
2228
    /*
2229
     * Use FTP PORT, this also specifies which IP address to use
2230
     */
2231
157
    result = Curl_setstropt(&s->str[STRING_FTPPORT], ptr);
2232
157
    s->ftp_use_port = !!(s->str[STRING_FTPPORT]);
2233
157
    break;
2234
2235
289
  case CURLOPT_FTP_ACCOUNT:
2236
289
    return Curl_setstropt(&s->str[STRING_FTP_ACCOUNT], ptr);
2237
2238
143
  case CURLOPT_FTP_ALTERNATIVE_TO_USER:
2239
143
    return Curl_setstropt(&s->str[STRING_FTP_ALTERNATIVE_TO_USER], ptr);
2240
2241
24
  case CURLOPT_KRBLEVEL:
2242
24
    return CURLE_NOT_BUILT_IN; /* removed in 8.17.0 */
2243
0
  case CURLOPT_CHUNK_DATA:
2244
0
    s->wildcardptr = ptr;
2245
0
    break;
2246
0
  case CURLOPT_FNMATCH_DATA:
2247
0
    s->fnmatch_data = ptr;
2248
0
    break;
2249
2.11M
  default:
2250
2.11M
    return CURLE_UNKNOWN_OPTION;
2251
2.11M
  }
2252
157
  return result;
2253
2.11M
}
2254
#endif /* !CURL_DISABLE_FTP */
2255
2256
static CURLcode setopt_cptr_net(struct Curl_easy *data, CURLoption option,
2257
                                char *ptr)
2258
1.64M
{
2259
1.64M
  struct UserDefined *s = &data->set;
2260
1.64M
  switch(option) {
2261
3.83k
  case CURLOPT_INTERFACE:
2262
    /*
2263
     * Set what interface or address/hostname to bind the socket to when
2264
     * performing an operation and thus what from-IP your connection will use.
2265
     */
2266
3.83k
    return setstropt_interface(ptr,
2267
3.83k
                               &s->str[STRING_DEVICE],
2268
3.83k
                               &s->str[STRING_INTERFACE],
2269
3.83k
                               &s->str[STRING_BINDHOST]);
2270
#ifdef USE_RESOLV_ARES
2271
  case CURLOPT_DNS_SERVERS:
2272
    return Curl_setstropt(&s->str[STRING_DNS_SERVERS], ptr);
2273
2274
  case CURLOPT_DNS_INTERFACE:
2275
    return Curl_setstropt(&s->str[STRING_DNS_INTERFACE], ptr);
2276
2277
  case CURLOPT_DNS_LOCAL_IP4:
2278
    return Curl_setstropt(&s->str[STRING_DNS_LOCAL_IP4], ptr);
2279
2280
  case CURLOPT_DNS_LOCAL_IP6:
2281
    return Curl_setstropt(&s->str[STRING_DNS_LOCAL_IP6], ptr);
2282
#endif
2283
0
#ifdef USE_UNIX_SOCKETS
2284
424
  case CURLOPT_UNIX_SOCKET_PATH:
2285
424
    s->abstract_unix_socket = FALSE;
2286
424
    return Curl_setstropt(&s->str[STRING_UNIX_SOCKET_PATH], ptr);
2287
2288
912
  case CURLOPT_ABSTRACT_UNIX_SOCKET:
2289
912
    s->abstract_unix_socket = TRUE;
2290
912
    return Curl_setstropt(&s->str[STRING_UNIX_SOCKET_PATH], ptr);
2291
0
#endif
2292
0
#ifndef CURL_DISABLE_DOH
2293
5.24k
  case CURLOPT_DOH_URL:
2294
5.24k
    {
2295
5.24k
      CURLcode result = Curl_setstropt(&s->str[STRING_DOH], ptr);
2296
5.24k
      s->doh = !!(s->str[STRING_DOH]);
2297
5.24k
      return result;
2298
0
    }
2299
0
#endif
2300
1.63M
  default:
2301
1.63M
    return CURLE_UNKNOWN_OPTION;
2302
1.64M
  }
2303
1.64M
}
2304
2305
static CURLcode setopt_cptr_misc(struct Curl_easy *data, CURLoption option,
2306
                                 char *ptr)
2307
1.63M
{
2308
1.63M
  CURLcode result = CURLE_OK;
2309
1.63M
  struct UserDefined *s = &data->set;
2310
2311
1.63M
  switch(option) {
2312
377
  case CURLOPT_REQUEST_TARGET:
2313
377
    return Curl_setstropt(&s->str[STRING_TARGET], ptr);
2314
0
#ifndef CURL_DISABLE_NETRC
2315
205k
  case CURLOPT_NETRC_FILE:
2316
205k
    return Curl_setstropt(&s->str[STRING_NETRC_FILE], ptr);
2317
0
#endif
2318
1.44k
  case CURLOPT_CUSTOMREQUEST:
2319
1.44k
    return Curl_setstropt(&s->str[STRING_CUSTOMREQUEST], ptr);
2320
2321
    /* we do not set s->method = HTTPREQ_CUSTOM; here, we continue as if we
2322
       were using the already set type and this changes the actual request
2323
       keyword */
2324
269
  case CURLOPT_SERVICE_NAME:
2325
269
    return Curl_setstropt(&s->str[STRING_SERVICE_NAME], ptr);
2326
2327
0
  case CURLOPT_HEADERDATA:
2328
0
    s->writeheader = ptr;
2329
0
    break;
2330
205k
  case CURLOPT_READDATA:
2331
205k
    s->in_set = ptr;
2332
205k
    break;
2333
208k
  case CURLOPT_WRITEDATA:
2334
208k
    s->out = ptr;
2335
208k
    break;
2336
0
  case CURLOPT_DEBUGDATA:
2337
0
    s->debugdata = ptr;
2338
0
    break;
2339
0
  case CURLOPT_PROGRESSDATA:
2340
0
    s->progress_client = ptr;
2341
0
    break;
2342
0
  case CURLOPT_SEEKDATA:
2343
0
    s->seek_client = ptr;
2344
0
    break;
2345
0
  case CURLOPT_IOCTLDATA:
2346
0
    s->ioctl_client = ptr;
2347
0
    break;
2348
0
  case CURLOPT_SOCKOPTDATA:
2349
0
    s->sockopt_client = ptr;
2350
0
    break;
2351
205k
  case CURLOPT_OPENSOCKETDATA:
2352
205k
    s->opensocket_client = ptr;
2353
205k
    break;
2354
0
  case CURLOPT_RESOLVER_START_DATA:
2355
0
    s->resolver_start_client = ptr;
2356
0
    break;
2357
0
  case CURLOPT_CLOSESOCKETDATA:
2358
0
    s->closesocket_client = ptr;
2359
0
    break;
2360
0
  case CURLOPT_PREREQDATA:
2361
0
    s->prereq_userp = ptr;
2362
0
    break;
2363
0
  case CURLOPT_ERRORBUFFER:
2364
0
    s->errorbuffer = ptr;
2365
0
    break;
2366
152k
  case CURLOPT_URL:
2367
152k
    result = Curl_setstropt(&s->str[STRING_SET_URL], ptr);
2368
152k
    Curl_bufref_set(&data->state.url, s->str[STRING_SET_URL], 0, NULL);
2369
152k
    break;
2370
2371
1.40k
  case CURLOPT_USERPWD:
2372
1.40k
    return setstropt_userpwd(ptr, &s->str[STRING_USERNAME],
2373
1.40k
                             &s->str[STRING_PASSWORD]);
2374
2375
1.74k
  case CURLOPT_USERNAME:
2376
1.74k
    return Curl_setstropt(&s->str[STRING_USERNAME], ptr);
2377
2378
1.53k
  case CURLOPT_PASSWORD:
2379
1.53k
    return Curl_setstropt(&s->str[STRING_PASSWORD], ptr);
2380
2381
470
  case CURLOPT_LOGIN_OPTIONS:
2382
470
    return Curl_setstropt(&s->str[STRING_OPTIONS], ptr);
2383
2384
734
  case CURLOPT_XOAUTH2_BEARER:
2385
734
    return Curl_setstropt(&s->str[STRING_BEARER], ptr);
2386
1.59k
  case CURLOPT_RANGE:
2387
1.59k
    return Curl_setstropt(&s->str[STRING_SET_RANGE], ptr);
2388
0
  case CURLOPT_PRIVATE:
2389
0
    s->private_data = ptr;
2390
0
    break;
2391
205k
  case CURLOPT_PROTOCOLS_STR:
2392
205k
    if(ptr) {
2393
205k
      curl_prot_t protos;
2394
205k
      result = protocol2num(ptr, &protos);
2395
205k
      if(!result)
2396
195k
        s->allowed_protocols = protos;
2397
205k
    }
2398
0
    else
2399
      /* make a NULL argument reset to default */
2400
0
      s->allowed_protocols = (curl_prot_t)CURLPROTO_64ALL;
2401
205k
    break;
2402
11.9k
  case CURLOPT_REDIR_PROTOCOLS_STR:
2403
11.9k
    if(ptr) {
2404
11.9k
      curl_prot_t protos;
2405
11.9k
      result = protocol2num(ptr, &protos);
2406
11.9k
      if(!result)
2407
11.4k
        s->redir_protocols = protos;
2408
11.9k
    }
2409
0
    else
2410
      /* make a NULL argument reset to default */
2411
0
      s->redir_protocols = (curl_prot_t)CURLPROTO_REDIR;
2412
11.9k
    break;
2413
11.2k
  case CURLOPT_DEFAULT_PROTOCOL:
2414
    /* Set the protocol to use when the URL does not include any protocol */
2415
11.2k
    return Curl_setstropt(&s->str[STRING_DEFAULT_PROTOCOL], ptr);
2416
0
#ifndef CURL_DISABLE_SMTP
2417
501
  case CURLOPT_MAIL_FROM:
2418
    /* Set the SMTP mail originator */
2419
501
    return Curl_setstropt(&s->str[STRING_MAIL_FROM], ptr);
2420
310
  case CURLOPT_MAIL_AUTH:
2421
    /* Set the SMTP auth originator */
2422
310
    return Curl_setstropt(&s->str[STRING_MAIL_AUTH], ptr);
2423
0
#endif
2424
368
  case CURLOPT_SASL_AUTHZID:
2425
    /* Authorization identity (identity to act as) */
2426
368
    return Curl_setstropt(&s->str[STRING_SASL_AUTHZID], ptr);
2427
0
#ifndef CURL_DISABLE_RTSP
2428
388
  case CURLOPT_RTSP_SESSION_ID:
2429
388
    return Curl_setstropt(&s->str[STRING_RTSP_SESSION_ID], ptr);
2430
257
  case CURLOPT_RTSP_STREAM_URI:
2431
257
    return Curl_setstropt(&s->str[STRING_RTSP_STREAM_URI], ptr);
2432
275
  case CURLOPT_RTSP_TRANSPORT:
2433
275
    return Curl_setstropt(&s->str[STRING_RTSP_TRANSPORT], ptr);
2434
0
  case CURLOPT_INTERLEAVEDATA:
2435
0
    s->rtp_out = ptr;
2436
0
    break;
2437
0
#endif /* !CURL_DISABLE_RTSP */
2438
17
  case CURLOPT_TLSAUTH_USERNAME:
2439
47
  case CURLOPT_TLSAUTH_PASSWORD:
2440
68
  case CURLOPT_TLSAUTH_TYPE:
2441
89
  case CURLOPT_PROXY_TLSAUTH_USERNAME:
2442
106
  case CURLOPT_PROXY_TLSAUTH_PASSWORD:
2443
128
  case CURLOPT_PROXY_TLSAUTH_TYPE:
2444
128
    return CURLE_NOT_BUILT_IN;
2445
0
#ifndef CURL_DISABLE_HSTS
2446
0
  case CURLOPT_HSTSREADDATA:
2447
0
    s->hsts_read_userp = ptr;
2448
0
    break;
2449
0
  case CURLOPT_HSTSWRITEDATA:
2450
0
    s->hsts_write_userp = ptr;
2451
0
    break;
2452
205k
  case CURLOPT_HSTS: {
2453
205k
    struct curl_slist *h;
2454
205k
    if(!data->hsts) {
2455
205k
      data->hsts = Curl_hsts_init();
2456
205k
      if(!data->hsts)
2457
0
        return CURLE_OUT_OF_MEMORY;
2458
205k
    }
2459
205k
    if(ptr) {
2460
205k
      result = Curl_setstropt(&s->str[STRING_HSTS], ptr);
2461
205k
      if(result)
2462
0
        return result;
2463
      /* this needs to build a list of filenames to read from, so that it can
2464
         read them later, as we might get a shared HSTS handle to load them
2465
         into */
2466
205k
      h = curl_slist_append(data->state.hstslist, ptr);
2467
205k
      if(!h) {
2468
0
        curl_slist_free_all(data->state.hstslist);
2469
0
        data->state.hstslist = NULL;
2470
0
        return CURLE_OUT_OF_MEMORY;
2471
0
      }
2472
205k
      data->state.hstslist = h; /* store the list for later use */
2473
205k
    }
2474
0
    else {
2475
      /* clear the list of HSTS files */
2476
0
      curl_slist_free_all(data->state.hstslist);
2477
0
      data->state.hstslist = NULL;
2478
0
      if(!data->share || !data->share->hsts)
2479
        /* throw away the HSTS cache unless shared */
2480
0
        Curl_hsts_cleanup(&data->hsts);
2481
0
    }
2482
205k
    break;
2483
205k
  }
2484
205k
#endif /* !CURL_DISABLE_HSTS */
2485
205k
#ifndef CURL_DISABLE_ALTSVC
2486
205k
  case CURLOPT_ALTSVC:
2487
205k
    if(!data->asi) {
2488
205k
      data->asi = Curl_altsvc_init();
2489
205k
      if(!data->asi)
2490
0
        return CURLE_OUT_OF_MEMORY;
2491
205k
    }
2492
205k
    result = Curl_setstropt(&s->str[STRING_ALTSVC], ptr);
2493
205k
    if(result)
2494
0
      break;
2495
205k
    if(ptr)
2496
205k
      return Curl_altsvc_load(data->asi, ptr);
2497
0
    break;
2498
0
#endif /* !CURL_DISABLE_ALTSVC */
2499
0
  case CURLOPT_ECH:
2500
0
    return setopt_ech(data, ptr);
2501
209
  default:
2502
209
    return CURLE_UNKNOWN_OPTION;
2503
1.63M
  }
2504
1.19M
  return result;
2505
1.63M
}
2506
2507
static CURLcode setopt_cptr(struct Curl_easy *data, CURLoption option,
2508
                            char *ptr)
2509
2.42M
{
2510
2.42M
  typedef CURLcode (*ptrfunc)(struct Curl_easy *data, CURLoption option,
2511
2.42M
                              char *ptr);
2512
2.42M
  static const ptrfunc setopt_call[] = {
2513
2.42M
#ifndef CURL_DISABLE_PROXY
2514
2.42M
    setopt_cptr_proxy,
2515
2.42M
#endif
2516
2.42M
#if defined(USE_SSL) || defined(USE_SSH)
2517
2.42M
    setopt_cptr_ssl,
2518
2.42M
#endif
2519
#ifdef USE_SSH
2520
    setopt_cptr_ssh,
2521
#endif
2522
2.42M
#ifndef CURL_DISABLE_FTP
2523
2.42M
    setopt_cptr_ftp,
2524
2.42M
#endif
2525
2.42M
#if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_MQTT)
2526
2.42M
    setopt_cptr_http_mqtt,
2527
2.42M
#endif
2528
2.42M
    setopt_cptr_net,
2529
2.42M
    setopt_cptr_misc,
2530
2.42M
  };
2531
2.42M
  size_t i;
2532
2533
12.3M
  for(i = 0; i < CURL_ARRAYSIZE(setopt_call); i++) {
2534
12.3M
    CURLcode result = setopt_call[i](data, option, ptr);
2535
12.3M
    if(result != CURLE_UNKNOWN_OPTION)
2536
2.42M
      return result;
2537
12.3M
  }
2538
209
  return CURLE_UNKNOWN_OPTION;
2539
2.42M
}
2540
2541
static CURLcode setopt_func(struct Curl_easy *data, CURLoption option,
2542
                            va_list param)
2543
847k
{
2544
847k
  struct UserDefined *s = &data->set;
2545
847k
  switch(option) {
2546
0
  case CURLOPT_PROGRESSFUNCTION:
2547
    /*
2548
     * Progress callback function
2549
     */
2550
0
    s->fprogress = va_arg(param, curl_progress_callback);
2551
0
    if(s->fprogress)
2552
0
      data->progress.callback = TRUE; /* no longer internal */
2553
0
    else
2554
0
      data->progress.callback = FALSE; /* NULL enforces internal */
2555
0
    break;
2556
2557
0
  case CURLOPT_XFERINFOFUNCTION:
2558
    /*
2559
     * Transfer info callback function
2560
     */
2561
0
    s->fxferinfo = va_arg(param, curl_xferinfo_callback);
2562
0
    if(s->fxferinfo)
2563
0
      data->progress.callback = TRUE; /* no longer internal */
2564
0
    else
2565
0
      data->progress.callback = FALSE; /* NULL enforces internal */
2566
2567
0
    break;
2568
0
  case CURLOPT_DEBUGFUNCTION:
2569
    /*
2570
     * stderr write callback.
2571
     */
2572
0
    s->fdebug = va_arg(param, curl_debug_callback);
2573
    /*
2574
     * if the callback provided is NULL, it will use the default callback
2575
     */
2576
0
    break;
2577
11.9k
  case CURLOPT_HEADERFUNCTION:
2578
    /*
2579
     * Set header write callback
2580
     */
2581
11.9k
    s->fwrite_header = va_arg(param, curl_write_callback);
2582
11.9k
    break;
2583
217k
  case CURLOPT_WRITEFUNCTION:
2584
    /*
2585
     * Set data write callback
2586
     */
2587
217k
    s->fwrite_func = va_arg(param, curl_write_callback);
2588
217k
    if(!s->fwrite_func)
2589
0
#if defined(__clang__) && __clang_major__ >= 16
2590
0
#pragma clang diagnostic push
2591
0
#pragma clang diagnostic ignored "-Wcast-function-type-strict"
2592
0
#endif
2593
      /* When set to NULL, reset to our internal default function */
2594
0
      s->fwrite_func = (curl_write_callback)fwrite;
2595
217k
#if defined(__clang__) && __clang_major__ >= 16
2596
217k
#pragma clang diagnostic pop
2597
217k
#endif
2598
217k
    break;
2599
205k
  case CURLOPT_READFUNCTION:
2600
    /*
2601
     * Read data callback
2602
     */
2603
205k
    s->fread_func_set = va_arg(param, curl_read_callback);
2604
205k
    if(!s->fread_func_set) {
2605
0
      s->is_fread_set = 0;
2606
0
#if defined(__clang__) && __clang_major__ >= 16
2607
0
#pragma clang diagnostic push
2608
0
#pragma clang diagnostic ignored "-Wcast-function-type-strict"
2609
0
#endif
2610
      /* When set to NULL, reset to our internal default function */
2611
0
      s->fread_func_set = (curl_read_callback)fread;
2612
0
#if defined(__clang__) && __clang_major__ >= 16
2613
0
#pragma clang diagnostic pop
2614
0
#endif
2615
0
    }
2616
205k
    else
2617
205k
      s->is_fread_set = 1;
2618
205k
    break;
2619
0
  case CURLOPT_SEEKFUNCTION:
2620
    /*
2621
     * Seek callback. Might be NULL.
2622
     */
2623
0
    s->seek_func = va_arg(param, curl_seek_callback);
2624
0
    break;
2625
0
  case CURLOPT_IOCTLFUNCTION:
2626
    /*
2627
     * I/O control callback. Might be NULL.
2628
     */
2629
0
    s->ioctl_func = va_arg(param, curl_ioctl_callback);
2630
0
    break;
2631
0
  case CURLOPT_SSL_CTX_FUNCTION:
2632
    /*
2633
     * Set an SSL_CTX callback
2634
     */
2635
0
#ifdef USE_SSL
2636
0
    if(Curl_ssl_supports(data, SSLSUPP_SSL_CTX)) {
2637
0
      s->ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
2638
0
      break;
2639
0
    }
2640
0
    else
2641
0
#endif
2642
0
      return CURLE_NOT_BUILT_IN;
2643
2644
205k
  case CURLOPT_SOCKOPTFUNCTION:
2645
    /*
2646
     * socket callback function: called after socket() but before connect()
2647
     */
2648
205k
    s->fsockopt = va_arg(param, curl_sockopt_callback);
2649
205k
    break;
2650
2651
205k
  case CURLOPT_OPENSOCKETFUNCTION:
2652
    /*
2653
     * open/create socket callback function: called instead of socket(),
2654
     * before connect()
2655
     */
2656
205k
    s->fopensocket = va_arg(param, curl_opensocket_callback);
2657
205k
    break;
2658
2659
0
  case CURLOPT_CLOSESOCKETFUNCTION:
2660
    /*
2661
     * close socket callback function: called instead of close()
2662
     * when shutting down a connection
2663
     */
2664
0
    s->fclosesocket = va_arg(param, curl_closesocket_callback);
2665
0
    break;
2666
2667
0
  case CURLOPT_RESOLVER_START_FUNCTION:
2668
    /*
2669
     * resolver start callback function: called before a new resolver request
2670
     * is started
2671
     */
2672
0
    s->resolver_start = va_arg(param, curl_resolver_start_callback);
2673
0
    break;
2674
2675
#ifdef USE_SSH
2676
#ifdef USE_LIBSSH2
2677
  case CURLOPT_SSH_HOSTKEYFUNCTION:
2678
    /* the callback to check the hostkey without the knownhost file */
2679
    s->ssh_hostkeyfunc = va_arg(param, curl_sshhostkeycallback);
2680
    break;
2681
#endif
2682
2683
  case CURLOPT_SSH_KEYFUNCTION:
2684
    /* setting to NULL is fine since the ssh.c functions themselves will
2685
       then revert to use the internal default */
2686
    s->ssh_keyfunc = va_arg(param, curl_sshkeycallback);
2687
    break;
2688
2689
#endif /* USE_SSH */
2690
2691
0
#ifndef CURL_DISABLE_RTSP
2692
0
  case CURLOPT_INTERLEAVEFUNCTION:
2693
    /* Set the user defined RTP write function */
2694
0
    s->fwrite_rtp = va_arg(param, curl_write_callback);
2695
0
    break;
2696
0
#endif
2697
0
#ifndef CURL_DISABLE_FTP
2698
0
  case CURLOPT_CHUNK_BGN_FUNCTION:
2699
0
    s->chunk_bgn = va_arg(param, curl_chunk_bgn_callback);
2700
0
    break;
2701
0
  case CURLOPT_CHUNK_END_FUNCTION:
2702
0
    s->chunk_end = va_arg(param, curl_chunk_end_callback);
2703
0
    break;
2704
0
  case CURLOPT_FNMATCH_FUNCTION:
2705
0
    s->fnmatch = va_arg(param, curl_fnmatch_callback);
2706
0
    break;
2707
0
#endif
2708
0
#ifndef CURL_DISABLE_HTTP
2709
0
  case CURLOPT_TRAILERFUNCTION:
2710
0
    s->trailer_callback = va_arg(param, curl_trailer_callback);
2711
0
    break;
2712
0
#endif
2713
0
#ifndef CURL_DISABLE_HSTS
2714
0
  case CURLOPT_HSTSREADFUNCTION:
2715
0
    s->hsts_read = va_arg(param, curl_hstsread_callback);
2716
0
    break;
2717
0
  case CURLOPT_HSTSWRITEFUNCTION:
2718
0
    s->hsts_write = va_arg(param, curl_hstswrite_callback);
2719
0
    break;
2720
0
#endif
2721
0
  case CURLOPT_PREREQFUNCTION:
2722
0
    s->fprereq = va_arg(param, curl_prereq_callback);
2723
0
    break;
2724
0
  default:
2725
0
    return CURLE_UNKNOWN_OPTION;
2726
847k
  }
2727
847k
  return CURLE_OK;
2728
847k
}
2729
2730
static CURLcode setopt_offt(struct Curl_easy *data, CURLoption option,
2731
                            curl_off_t offt)
2732
26.7k
{
2733
26.7k
  struct UserDefined *s = &data->set;
2734
26.7k
  switch(option) {
2735
139
  case CURLOPT_TIMEVALUE_LARGE:
2736
    /*
2737
     * This is the value to compare with the remote document with the
2738
     * method set with CURLOPT_TIMECONDITION
2739
     */
2740
139
    s->timevalue = (time_t)offt;
2741
139
    break;
2742
2743
    /* MQTT "borrows" some of the HTTP options */
2744
3.29k
  case CURLOPT_POSTFIELDSIZE_LARGE:
2745
    /*
2746
     * The size of the POSTFIELD data to prevent libcurl to do strlen() to
2747
     * figure it out. Enables binary posts.
2748
     */
2749
3.29k
    if(offt < -1)
2750
0
      return CURLE_BAD_FUNCTION_ARGUMENT;
2751
2752
3.29k
    if(s->postfieldsize < offt &&
2753
880
       s->postfields == s->str[STRING_COPYPOSTFIELDS]) {
2754
      /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
2755
358
      curlx_safefree(s->str[STRING_COPYPOSTFIELDS]);
2756
358
      s->postfields = NULL;
2757
358
    }
2758
3.29k
    s->postfieldsize = offt;
2759
3.29k
    break;
2760
2.54k
  case CURLOPT_INFILESIZE_LARGE:
2761
    /*
2762
     * If known, this should inform curl about the file size of the
2763
     * to-be-uploaded file.
2764
     */
2765
2.54k
    if(offt < -1)
2766
111
      return CURLE_BAD_FUNCTION_ARGUMENT;
2767
2.43k
    s->filesize = offt;
2768
2.43k
    break;
2769
2.22k
  case CURLOPT_MAX_SEND_SPEED_LARGE:
2770
    /*
2771
     * When transfer uploads are faster than CURLOPT_MAX_SEND_SPEED_LARGE
2772
     * bytes per second the transfer is throttled..
2773
     */
2774
2.22k
    if(offt < 0)
2775
0
      return CURLE_BAD_FUNCTION_ARGUMENT;
2776
2.22k
    s->max_send_speed = offt;
2777
    /* use minimal burst rate of 32k. some protocol batch IO */
2778
2.22k
    Curl_rlimit_init(&data->progress.ul.rlimit, offt,
2779
2.22k
                     CURLMAX(offt, (32 * 1024)),
2780
2.22k
                     Curl_pgrs_now(data));
2781
2.22k
    break;
2782
15.4k
  case CURLOPT_MAX_RECV_SPEED_LARGE:
2783
    /*
2784
     * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per
2785
     * second the transfer is throttled..
2786
     */
2787
15.4k
    if(offt < 0)
2788
0
      return CURLE_BAD_FUNCTION_ARGUMENT;
2789
15.4k
    s->max_recv_speed = offt;
2790
    /* use minimal burst rate of 32k. some protocol batch IO */
2791
15.4k
    Curl_rlimit_init(&data->progress.dl.rlimit, offt,
2792
15.4k
                     CURLMAX(offt, (32 * 1024)),
2793
15.4k
                     Curl_pgrs_now(data));
2794
15.4k
    break;
2795
1.83k
  case CURLOPT_RESUME_FROM_LARGE:
2796
    /*
2797
     * Resume transfer at the given file position
2798
     */
2799
1.83k
    if(offt < -1)
2800
0
      return CURLE_BAD_FUNCTION_ARGUMENT;
2801
1.83k
    s->set_resume_from = offt;
2802
1.83k
    break;
2803
1.24k
  case CURLOPT_MAXFILESIZE_LARGE:
2804
    /*
2805
     * Set the maximum size of a file to download.
2806
     */
2807
1.24k
    if(offt < 0)
2808
0
      return CURLE_BAD_FUNCTION_ARGUMENT;
2809
1.24k
    s->max_filesize = offt;
2810
1.24k
    break;
2811
2812
0
  default:
2813
0
    return CURLE_UNKNOWN_OPTION;
2814
26.7k
  }
2815
26.6k
  return CURLE_OK;
2816
26.7k
}
2817
2818
static CURLcode setopt_blob(struct Curl_easy *data, CURLoption option,
2819
                            struct curl_blob *blob)
2820
0
{
2821
0
  struct UserDefined *s = &data->set;
2822
0
  switch(option) {
2823
0
  case CURLOPT_SSLCERT_BLOB:
2824
    /*
2825
     * Blob that holds file content of the SSL certificate to use
2826
     */
2827
0
    return Curl_setblobopt(&s->blobs[BLOB_CERT], blob);
2828
0
#ifndef CURL_DISABLE_PROXY
2829
0
  case CURLOPT_PROXY_SSLCERT_BLOB:
2830
    /*
2831
     * Blob that holds file content of the SSL certificate to use for proxy
2832
     */
2833
0
    return Curl_setblobopt(&s->blobs[BLOB_CERT_PROXY], blob);
2834
0
  case CURLOPT_PROXY_SSLKEY_BLOB:
2835
    /*
2836
     * Blob that holds file content of the SSL key to use for proxy
2837
     */
2838
0
    return Curl_setblobopt(&s->blobs[BLOB_KEY_PROXY], blob);
2839
0
  case CURLOPT_PROXY_CAINFO_BLOB:
2840
    /*
2841
     * Blob that holds CA info for SSL connection proxy.
2842
     * Specify entire PEM of the CA certificate
2843
     */
2844
0
#ifdef USE_SSL
2845
0
    if(Curl_ssl_supports(data, SSLSUPP_CAINFO_BLOB)) {
2846
0
      CURLcode result = Curl_setblobopt(&s->blobs[BLOB_CAINFO_PROXY], blob);
2847
0
      s->proxy_ssl.custom_cablob = !!s->blobs[BLOB_CAINFO_PROXY];
2848
0
      return result;
2849
0
    }
2850
0
#endif
2851
0
    return CURLE_NOT_BUILT_IN;
2852
0
  case CURLOPT_PROXY_ISSUERCERT_BLOB:
2853
    /*
2854
     * Blob that holds Issuer certificate to check certificates issuer
2855
     */
2856
0
    if(Curl_ssl_supports(data, SSLSUPP_ISSUERCERT_BLOB))
2857
0
      return Curl_setblobopt(&s->blobs[BLOB_SSL_ISSUERCERT_PROXY], blob);
2858
0
    return CURLE_NOT_BUILT_IN;
2859
0
#endif
2860
0
  case CURLOPT_SSLKEY_BLOB:
2861
    /*
2862
     * Blob that holds file content of the SSL key to use
2863
     */
2864
0
    return Curl_setblobopt(&s->blobs[BLOB_KEY], blob);
2865
0
  case CURLOPT_CAINFO_BLOB:
2866
    /*
2867
     * Blob that holds CA info for SSL connection.
2868
     * Specify entire PEM of the CA certificate
2869
     */
2870
0
#ifdef USE_SSL
2871
0
    if(Curl_ssl_supports(data, SSLSUPP_CAINFO_BLOB)) {
2872
0
      CURLcode result = Curl_setblobopt(&s->blobs[BLOB_CAINFO], blob);
2873
0
      s->ssl.custom_cablob = !!s->blobs[BLOB_CAINFO];
2874
0
      return result;
2875
0
    }
2876
0
#endif
2877
0
    return CURLE_NOT_BUILT_IN;
2878
0
  case CURLOPT_ISSUERCERT_BLOB:
2879
    /*
2880
     * Blob that holds Issuer certificate to check certificates issuer
2881
     */
2882
0
    if(Curl_ssl_supports(data, SSLSUPP_ISSUERCERT_BLOB))
2883
0
      return Curl_setblobopt(&s->blobs[BLOB_SSL_ISSUERCERT], blob);
2884
0
    return CURLE_NOT_BUILT_IN;
2885
2886
0
  default:
2887
0
    return CURLE_UNKNOWN_OPTION;
2888
0
  }
2889
  /* unreachable */
2890
0
}
2891
2892
/*
2893
 * Do not make Curl_vsetopt() static: it is called from
2894
 * projects/OS400/ccsidcurl.c.
2895
 */
2896
CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
2897
4.20M
{
2898
4.20M
  if(option < CURLOPTTYPE_OBJECTPOINT)
2899
657k
    return setopt_long(data, option, va_arg(param, long));
2900
3.54M
  else if(option < CURLOPTTYPE_FUNCTIONPOINT) {
2901
    /* unfortunately, different pointer types cannot be identified any other
2902
       way than being listed explicitly */
2903
2.67M
    switch(option) {
2904
19.9k
    case CURLOPT_HTTPHEADER:
2905
19.9k
    case CURLOPT_QUOTE:
2906
19.9k
    case CURLOPT_POSTQUOTE:
2907
19.9k
    case CURLOPT_TELNETOPTIONS:
2908
19.9k
    case CURLOPT_PREQUOTE:
2909
19.9k
    case CURLOPT_HTTP200ALIASES:
2910
21.1k
    case CURLOPT_MAIL_RCPT:
2911
21.1k
    case CURLOPT_RESOLVE:
2912
21.1k
    case CURLOPT_PROXYHEADER:
2913
227k
    case CURLOPT_CONNECT_TO:
2914
227k
      return setopt_slist(data, option, va_arg(param, struct curl_slist *));
2915
2.20k
    case CURLOPT_HTTPPOST:         /* curl_httppost * */
2916
7.02k
    case CURLOPT_MIMEPOST:         /* curl_mime * */
2917
7.02k
    case CURLOPT_STDERR:           /* FILE * */
2918
16.5k
    case CURLOPT_SHARE:            /* CURLSH * */
2919
16.5k
    case CURLOPT_CURLU:            /* CURLU * */
2920
16.5k
      return setopt_pointers(data, option, param);
2921
0
    case CURLOPT_STREAM_DEPENDS:   /* CURL * */
2922
0
    case CURLOPT_STREAM_DEPENDS_E: /* CURL * */
2923
0
      return CURLE_OK;
2924
2.42M
    default:
2925
2.42M
      break;
2926
2.67M
    }
2927
    /* the char pointer options */
2928
2.42M
    return setopt_cptr(data, option, va_arg(param, char *));
2929
2.67M
  }
2930
874k
  else if(option < CURLOPTTYPE_OFF_T)
2931
847k
    return setopt_func(data, option, param);
2932
26.7k
  else if(option < CURLOPTTYPE_BLOB)
2933
26.7k
    return setopt_offt(data, option, va_arg(param, curl_off_t));
2934
0
  return setopt_blob(data, option, va_arg(param, struct curl_blob *));
2935
4.20M
}
2936
2937
/*
2938
 * curl_easy_setopt() is the external interface for setting options on an
2939
 * easy handle.
2940
 *
2941
 * NOTE: This is one of few API functions that are allowed to be called from
2942
 * within a callback.
2943
 */
2944
#undef curl_easy_setopt
2945
CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...)
2946
4.20M
{
2947
4.20M
  struct Curl_eapi_guard guard;
2948
4.20M
  CURLcode result;
2949
2950
4.20M
  if(CURL_EAPI_ENTER(&guard, curl, easy_setopt, &result)) {
2951
4.20M
    struct Curl_easy *data = curl;
2952
4.20M
    va_list arg;
2953
2954
4.20M
    va_start(arg, option);
2955
2956
4.20M
    result = Curl_vsetopt(data, option, arg);
2957
2958
4.20M
    va_end(arg);
2959
4.20M
    if(result == CURLE_BAD_FUNCTION_ARGUMENT)
2960
9.58k
      failf(data, "setopt 0x%x got bad argument", (unsigned int)option);
2961
4.20M
  }
2962
4.20M
  CURL_EAPI_LEAVE(&guard);
2963
4.20M
  return result;
2964
4.20M
}