Coverage Report

Created: 2023-12-08 06:48

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