Coverage Report

Created: 2026-06-15 07:03

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