[352] | 1 | /***************************************************************************
|
---|
| 2 | * _ _ ____ _
|
---|
| 3 | * Project ___| | | | _ \| |
|
---|
| 4 | * / __| | | | |_) | |
|
---|
| 5 | * | (__| |_| | _ <| |___
|
---|
| 6 | * \___|\___/|_| \_\_____|
|
---|
| 7 | *
|
---|
| 8 | * Copyright (C) 1998 - 2017, 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.haxx.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 | ***************************************************************************/
|
---|
| 22 | #include "tool_setup.h"
|
---|
| 23 |
|
---|
| 24 | #include "strcase.h"
|
---|
| 25 |
|
---|
| 26 | #define ENABLE_CURLX_PRINTF
|
---|
| 27 | /* use our own printf() functions */
|
---|
| 28 | #include "curlx.h"
|
---|
| 29 |
|
---|
| 30 | #include "tool_cfgable.h"
|
---|
| 31 | #include "tool_getparam.h"
|
---|
| 32 | #include "tool_getpass.h"
|
---|
| 33 | #include "tool_homedir.h"
|
---|
| 34 | #include "tool_msgs.h"
|
---|
| 35 | #include "tool_paramhlp.h"
|
---|
| 36 | #include "tool_version.h"
|
---|
| 37 |
|
---|
| 38 | #include "memdebug.h" /* keep this as LAST include */
|
---|
| 39 |
|
---|
| 40 | struct getout *new_getout(struct OperationConfig *config)
|
---|
| 41 | {
|
---|
| 42 | struct getout *node = calloc(1, sizeof(struct getout));
|
---|
| 43 | struct getout *last = config->url_last;
|
---|
| 44 | if(node) {
|
---|
| 45 | /* append this new node last in the list */
|
---|
| 46 | if(last)
|
---|
| 47 | last->next = node;
|
---|
| 48 | else
|
---|
| 49 | config->url_list = node; /* first node */
|
---|
| 50 |
|
---|
| 51 | /* move the last pointer */
|
---|
| 52 | config->url_last = node;
|
---|
| 53 |
|
---|
| 54 | node->flags = config->default_node_flags;
|
---|
| 55 | }
|
---|
| 56 | return node;
|
---|
| 57 | }
|
---|
| 58 |
|
---|
| 59 | ParameterError file2string(char **bufp, FILE *file)
|
---|
| 60 | {
|
---|
| 61 | char buffer[256];
|
---|
| 62 | char *ptr;
|
---|
| 63 | char *string = NULL;
|
---|
| 64 | size_t stringlen = 0;
|
---|
| 65 | size_t buflen;
|
---|
| 66 |
|
---|
| 67 | if(file) {
|
---|
| 68 | while(fgets(buffer, sizeof(buffer), file)) {
|
---|
| 69 | ptr = strchr(buffer, '\r');
|
---|
| 70 | if(ptr)
|
---|
| 71 | *ptr = '\0';
|
---|
| 72 | ptr = strchr(buffer, '\n');
|
---|
| 73 | if(ptr)
|
---|
| 74 | *ptr = '\0';
|
---|
| 75 | buflen = strlen(buffer);
|
---|
| 76 | ptr = realloc(string, stringlen + buflen + 1);
|
---|
| 77 | if(!ptr) {
|
---|
| 78 | Curl_safefree(string);
|
---|
| 79 | return PARAM_NO_MEM;
|
---|
| 80 | }
|
---|
| 81 | string = ptr;
|
---|
| 82 | strcpy(string + stringlen, buffer);
|
---|
| 83 | stringlen += buflen;
|
---|
| 84 | }
|
---|
| 85 | }
|
---|
| 86 | *bufp = string;
|
---|
| 87 | return PARAM_OK;
|
---|
| 88 | }
|
---|
| 89 |
|
---|
| 90 | ParameterError file2memory(char **bufp, size_t *size, FILE *file)
|
---|
| 91 | {
|
---|
| 92 | char *newbuf;
|
---|
| 93 | char *buffer = NULL;
|
---|
| 94 | size_t alloc = 512;
|
---|
| 95 | size_t nused = 0;
|
---|
| 96 | size_t nread;
|
---|
| 97 |
|
---|
| 98 | if(file) {
|
---|
| 99 | do {
|
---|
| 100 | if(!buffer || (alloc == nused)) {
|
---|
| 101 | /* size_t overflow detection for huge files */
|
---|
| 102 | if(alloc + 1 > ((size_t)-1)/2) {
|
---|
| 103 | Curl_safefree(buffer);
|
---|
| 104 | return PARAM_NO_MEM;
|
---|
| 105 | }
|
---|
| 106 | alloc *= 2;
|
---|
| 107 | /* allocate an extra char, reserved space, for null termination */
|
---|
| 108 | newbuf = realloc(buffer, alloc + 1);
|
---|
| 109 | if(!newbuf) {
|
---|
| 110 | Curl_safefree(buffer);
|
---|
| 111 | return PARAM_NO_MEM;
|
---|
| 112 | }
|
---|
| 113 | buffer = newbuf;
|
---|
| 114 | }
|
---|
| 115 | nread = fread(buffer + nused, 1, alloc-nused, file);
|
---|
| 116 | nused += nread;
|
---|
| 117 | } while(nread);
|
---|
| 118 | /* null terminate the buffer in case it's used as a string later */
|
---|
| 119 | buffer[nused] = '\0';
|
---|
| 120 | /* free trailing slack space, if possible */
|
---|
| 121 | if(alloc != nused) {
|
---|
| 122 | newbuf = realloc(buffer, nused + 1);
|
---|
| 123 | if(!newbuf) {
|
---|
| 124 | Curl_safefree(buffer);
|
---|
| 125 | return PARAM_NO_MEM;
|
---|
| 126 | }
|
---|
| 127 | buffer = newbuf;
|
---|
| 128 | }
|
---|
| 129 | /* discard buffer if nothing was read */
|
---|
| 130 | if(!nused) {
|
---|
| 131 | Curl_safefree(buffer); /* no string */
|
---|
| 132 | }
|
---|
| 133 | }
|
---|
| 134 | *size = nused;
|
---|
| 135 | *bufp = buffer;
|
---|
| 136 | return PARAM_OK;
|
---|
| 137 | }
|
---|
| 138 |
|
---|
| 139 | void cleanarg(char *str)
|
---|
| 140 | {
|
---|
| 141 | #ifdef HAVE_WRITABLE_ARGV
|
---|
| 142 | /* now that GetStr has copied the contents of nextarg, wipe the next
|
---|
| 143 | * argument out so that the username:password isn't displayed in the
|
---|
| 144 | * system process list */
|
---|
| 145 | if(str) {
|
---|
| 146 | size_t len = strlen(str);
|
---|
| 147 | memset(str, ' ', len);
|
---|
| 148 | }
|
---|
| 149 | #else
|
---|
| 150 | (void)str;
|
---|
| 151 | #endif
|
---|
| 152 | }
|
---|
| 153 |
|
---|
| 154 | /*
|
---|
| 155 | * Parse the string and write the long in the given address. Return PARAM_OK
|
---|
| 156 | * on success, otherwise a parameter specific error enum.
|
---|
| 157 | *
|
---|
| 158 | * Since this function gets called with the 'nextarg' pointer from within the
|
---|
| 159 | * getparameter a lot, we must check it for NULL before accessing the str
|
---|
| 160 | * data.
|
---|
| 161 | */
|
---|
| 162 |
|
---|
| 163 | ParameterError str2num(long *val, const char *str)
|
---|
| 164 | {
|
---|
| 165 | if(str) {
|
---|
| 166 | char *endptr;
|
---|
| 167 | long num;
|
---|
| 168 | errno = 0;
|
---|
| 169 | num = strtol(str, &endptr, 10);
|
---|
| 170 | if(errno == ERANGE)
|
---|
| 171 | return PARAM_NUMBER_TOO_LARGE;
|
---|
| 172 | if((endptr != str) && (endptr == str + strlen(str))) {
|
---|
| 173 | *val = num;
|
---|
| 174 | return PARAM_OK; /* Ok */
|
---|
| 175 | }
|
---|
| 176 | }
|
---|
| 177 | return PARAM_BAD_NUMERIC; /* badness */
|
---|
| 178 | }
|
---|
| 179 |
|
---|
| 180 | /*
|
---|
| 181 | * Parse the string and write the long in the given address. Return PARAM_OK
|
---|
| 182 | * on success, otherwise a parameter error enum. ONLY ACCEPTS POSITIVE NUMBERS!
|
---|
| 183 | *
|
---|
| 184 | * Since this function gets called with the 'nextarg' pointer from within the
|
---|
| 185 | * getparameter a lot, we must check it for NULL before accessing the str
|
---|
| 186 | * data.
|
---|
| 187 | */
|
---|
| 188 |
|
---|
| 189 | ParameterError str2unum(long *val, const char *str)
|
---|
| 190 | {
|
---|
| 191 | ParameterError result = str2num(val, str);
|
---|
| 192 | if(result != PARAM_OK)
|
---|
| 193 | return result;
|
---|
| 194 | if(*val < 0)
|
---|
| 195 | return PARAM_NEGATIVE_NUMERIC;
|
---|
| 196 |
|
---|
| 197 | return PARAM_OK;
|
---|
| 198 | }
|
---|
| 199 |
|
---|
| 200 | /*
|
---|
| 201 | * Parse the string and write the double in the given address. Return PARAM_OK
|
---|
| 202 | * on success, otherwise a parameter specific error enum.
|
---|
| 203 | *
|
---|
| 204 | * The 'max' argument is the maximum value allowed, as the numbers are often
|
---|
| 205 | * multiplied when later used.
|
---|
| 206 | *
|
---|
| 207 | * Since this function gets called with the 'nextarg' pointer from within the
|
---|
| 208 | * getparameter a lot, we must check it for NULL before accessing the str
|
---|
| 209 | * data.
|
---|
| 210 | */
|
---|
| 211 |
|
---|
| 212 | static ParameterError str2double(double *val, const char *str, long max)
|
---|
| 213 | {
|
---|
| 214 | if(str) {
|
---|
| 215 | char *endptr;
|
---|
| 216 | double num;
|
---|
| 217 | errno = 0;
|
---|
| 218 | num = strtod(str, &endptr);
|
---|
| 219 | if(errno == ERANGE)
|
---|
| 220 | return PARAM_NUMBER_TOO_LARGE;
|
---|
| 221 | if(num > max) {
|
---|
| 222 | /* too large */
|
---|
| 223 | return PARAM_NUMBER_TOO_LARGE;
|
---|
| 224 | }
|
---|
| 225 | if((endptr != str) && (endptr == str + strlen(str))) {
|
---|
| 226 | *val = num;
|
---|
| 227 | return PARAM_OK; /* Ok */
|
---|
| 228 | }
|
---|
| 229 | }
|
---|
| 230 | return PARAM_BAD_NUMERIC; /* badness */
|
---|
| 231 | }
|
---|
| 232 |
|
---|
| 233 | /*
|
---|
| 234 | * Parse the string and write the double in the given address. Return PARAM_OK
|
---|
| 235 | * on success, otherwise a parameter error enum. ONLY ACCEPTS POSITIVE NUMBERS!
|
---|
| 236 | *
|
---|
| 237 | * The 'max' argument is the maximum value allowed, as the numbers are often
|
---|
| 238 | * multiplied when later used.
|
---|
| 239 | *
|
---|
| 240 | * Since this function gets called with the 'nextarg' pointer from within the
|
---|
| 241 | * getparameter a lot, we must check it for NULL before accessing the str
|
---|
| 242 | * data.
|
---|
| 243 | */
|
---|
| 244 |
|
---|
| 245 | ParameterError str2udouble(double *valp, const char *str, long max)
|
---|
| 246 | {
|
---|
| 247 | double value;
|
---|
| 248 | ParameterError result = str2double(&value, str, max);
|
---|
| 249 | if(result != PARAM_OK)
|
---|
| 250 | return result;
|
---|
| 251 | if(value < 0)
|
---|
| 252 | return PARAM_NEGATIVE_NUMERIC;
|
---|
| 253 |
|
---|
| 254 | *valp = value;
|
---|
| 255 | return PARAM_OK;
|
---|
| 256 | }
|
---|
| 257 |
|
---|
| 258 | /*
|
---|
| 259 | * Parse the string and modify the long in the given address. Return
|
---|
| 260 | * non-zero on failure, zero on success.
|
---|
| 261 | *
|
---|
| 262 | * The string is a list of protocols
|
---|
| 263 | *
|
---|
| 264 | * Since this function gets called with the 'nextarg' pointer from within the
|
---|
| 265 | * getparameter a lot, we must check it for NULL before accessing the str
|
---|
| 266 | * data.
|
---|
| 267 | */
|
---|
| 268 |
|
---|
| 269 | long proto2num(struct OperationConfig *config, long *val, const char *str)
|
---|
| 270 | {
|
---|
| 271 | char *buffer;
|
---|
| 272 | const char *sep = ",";
|
---|
| 273 | char *token;
|
---|
| 274 |
|
---|
| 275 | static struct sprotos {
|
---|
| 276 | const char *name;
|
---|
| 277 | long bit;
|
---|
| 278 | } const protos[] = {
|
---|
| 279 | { "all", CURLPROTO_ALL },
|
---|
| 280 | { "http", CURLPROTO_HTTP },
|
---|
| 281 | { "https", CURLPROTO_HTTPS },
|
---|
| 282 | { "ftp", CURLPROTO_FTP },
|
---|
| 283 | { "ftps", CURLPROTO_FTPS },
|
---|
| 284 | { "scp", CURLPROTO_SCP },
|
---|
| 285 | { "sftp", CURLPROTO_SFTP },
|
---|
| 286 | { "telnet", CURLPROTO_TELNET },
|
---|
| 287 | { "ldap", CURLPROTO_LDAP },
|
---|
| 288 | { "ldaps", CURLPROTO_LDAPS },
|
---|
| 289 | { "dict", CURLPROTO_DICT },
|
---|
| 290 | { "file", CURLPROTO_FILE },
|
---|
| 291 | { "tftp", CURLPROTO_TFTP },
|
---|
| 292 | { "imap", CURLPROTO_IMAP },
|
---|
| 293 | { "imaps", CURLPROTO_IMAPS },
|
---|
| 294 | { "pop3", CURLPROTO_POP3 },
|
---|
| 295 | { "pop3s", CURLPROTO_POP3S },
|
---|
| 296 | { "smtp", CURLPROTO_SMTP },
|
---|
| 297 | { "smtps", CURLPROTO_SMTPS },
|
---|
| 298 | { "rtsp", CURLPROTO_RTSP },
|
---|
| 299 | { "gopher", CURLPROTO_GOPHER },
|
---|
| 300 | { "smb", CURLPROTO_SMB },
|
---|
| 301 | { "smbs", CURLPROTO_SMBS },
|
---|
| 302 | { NULL, 0 }
|
---|
| 303 | };
|
---|
| 304 |
|
---|
| 305 | if(!str)
|
---|
| 306 | return 1;
|
---|
| 307 |
|
---|
| 308 | buffer = strdup(str); /* because strtok corrupts it */
|
---|
| 309 | if(!buffer)
|
---|
| 310 | return 1;
|
---|
| 311 |
|
---|
| 312 | /* Allow strtok() here since this isn't used threaded */
|
---|
| 313 | /* !checksrc! disable BANNEDFUNC 2 */
|
---|
| 314 | for(token = strtok(buffer, sep);
|
---|
| 315 | token;
|
---|
| 316 | token = strtok(NULL, sep)) {
|
---|
| 317 | enum e_action { allow, deny, set } action = allow;
|
---|
| 318 |
|
---|
| 319 | struct sprotos const *pp;
|
---|
| 320 |
|
---|
| 321 | /* Process token modifiers */
|
---|
| 322 | while(!ISALNUM(*token)) { /* may be NULL if token is all modifiers */
|
---|
| 323 | switch (*token++) {
|
---|
| 324 | case '=':
|
---|
| 325 | action = set;
|
---|
| 326 | break;
|
---|
| 327 | case '-':
|
---|
| 328 | action = deny;
|
---|
| 329 | break;
|
---|
| 330 | case '+':
|
---|
| 331 | action = allow;
|
---|
| 332 | break;
|
---|
| 333 | default: /* Includes case of terminating NULL */
|
---|
| 334 | Curl_safefree(buffer);
|
---|
| 335 | return 1;
|
---|
| 336 | }
|
---|
| 337 | }
|
---|
| 338 |
|
---|
| 339 | for(pp = protos; pp->name; pp++) {
|
---|
| 340 | if(curl_strequal(token, pp->name)) {
|
---|
| 341 | switch(action) {
|
---|
| 342 | case deny:
|
---|
| 343 | *val &= ~(pp->bit);
|
---|
| 344 | break;
|
---|
| 345 | case allow:
|
---|
| 346 | *val |= pp->bit;
|
---|
| 347 | break;
|
---|
| 348 | case set:
|
---|
| 349 | *val = pp->bit;
|
---|
| 350 | break;
|
---|
| 351 | }
|
---|
| 352 | break;
|
---|
| 353 | }
|
---|
| 354 | }
|
---|
| 355 |
|
---|
| 356 | if(!(pp->name)) { /* unknown protocol */
|
---|
| 357 | /* If they have specified only this protocol, we say treat it as
|
---|
| 358 | if no protocols are allowed */
|
---|
| 359 | if(action == set)
|
---|
| 360 | *val = 0;
|
---|
| 361 | warnf(config->global, "unrecognized protocol '%s'\n", token);
|
---|
| 362 | }
|
---|
| 363 | }
|
---|
| 364 | Curl_safefree(buffer);
|
---|
| 365 | return 0;
|
---|
| 366 | }
|
---|
| 367 |
|
---|
| 368 | /**
|
---|
| 369 | * Check if the given string is a protocol supported by libcurl
|
---|
| 370 | *
|
---|
| 371 | * @param str the protocol name
|
---|
| 372 | * @return PARAM_OK protocol supported
|
---|
| 373 | * @return PARAM_LIBCURL_UNSUPPORTED_PROTOCOL protocol not supported
|
---|
| 374 | * @return PARAM_REQUIRES_PARAMETER missing parameter
|
---|
| 375 | */
|
---|
| 376 | int check_protocol(const char *str)
|
---|
| 377 | {
|
---|
| 378 | const char * const *pp;
|
---|
| 379 | const curl_version_info_data *curlinfo = curl_version_info(CURLVERSION_NOW);
|
---|
| 380 | if(!str)
|
---|
| 381 | return PARAM_REQUIRES_PARAMETER;
|
---|
| 382 | for(pp = curlinfo->protocols; *pp; pp++) {
|
---|
| 383 | if(curl_strequal(*pp, str))
|
---|
| 384 | return PARAM_OK;
|
---|
| 385 | }
|
---|
| 386 | return PARAM_LIBCURL_UNSUPPORTED_PROTOCOL;
|
---|
| 387 | }
|
---|
| 388 |
|
---|
| 389 | /**
|
---|
| 390 | * Parses the given string looking for an offset (which may be a
|
---|
| 391 | * larger-than-integer value). The offset CANNOT be negative!
|
---|
| 392 | *
|
---|
| 393 | * @param val the offset to populate
|
---|
| 394 | * @param str the buffer containing the offset
|
---|
| 395 | * @return PARAM_OK if successful, a parameter specific error enum if failure.
|
---|
| 396 | */
|
---|
| 397 | ParameterError str2offset(curl_off_t *val, const char *str)
|
---|
| 398 | {
|
---|
| 399 | char *endptr;
|
---|
| 400 | if(str[0] == '-')
|
---|
| 401 | /* offsets aren't negative, this indicates weird input */
|
---|
| 402 | return PARAM_NEGATIVE_NUMERIC;
|
---|
| 403 |
|
---|
| 404 | #if(SIZEOF_CURL_OFF_T > SIZEOF_LONG)
|
---|
| 405 | {
|
---|
| 406 | CURLofft offt = curlx_strtoofft(str, &endptr, 0, val);
|
---|
| 407 | if(CURL_OFFT_FLOW == offt)
|
---|
| 408 | return PARAM_NUMBER_TOO_LARGE;
|
---|
| 409 | else if(CURL_OFFT_INVAL == offt)
|
---|
| 410 | return PARAM_BAD_NUMERIC;
|
---|
| 411 | }
|
---|
| 412 | #else
|
---|
| 413 | errno = 0;
|
---|
| 414 | *val = strtol(str, &endptr, 0);
|
---|
| 415 | if((*val == LONG_MIN || *val == LONG_MAX) && errno == ERANGE)
|
---|
| 416 | return PARAM_NUMBER_TOO_LARGE;
|
---|
| 417 | #endif
|
---|
| 418 | if((endptr != str) && (endptr == str + strlen(str)))
|
---|
| 419 | return PARAM_OK;
|
---|
| 420 |
|
---|
| 421 | return PARAM_BAD_NUMERIC;
|
---|
| 422 | }
|
---|
| 423 |
|
---|
| 424 | static CURLcode checkpasswd(const char *kind, /* for what purpose */
|
---|
| 425 | const size_t i, /* operation index */
|
---|
| 426 | const bool last, /* TRUE if last operation */
|
---|
| 427 | char **userpwd) /* pointer to allocated string */
|
---|
| 428 | {
|
---|
| 429 | char *psep;
|
---|
| 430 | char *osep;
|
---|
| 431 |
|
---|
| 432 | if(!*userpwd)
|
---|
| 433 | return CURLE_OK;
|
---|
| 434 |
|
---|
| 435 | /* Attempt to find the password separator */
|
---|
| 436 | psep = strchr(*userpwd, ':');
|
---|
| 437 |
|
---|
| 438 | /* Attempt to find the options separator */
|
---|
| 439 | osep = strchr(*userpwd, ';');
|
---|
| 440 |
|
---|
| 441 | if(!psep && **userpwd != ';') {
|
---|
| 442 | /* no password present, prompt for one */
|
---|
| 443 | char passwd[256] = "";
|
---|
| 444 | char prompt[256];
|
---|
| 445 | size_t passwdlen;
|
---|
| 446 | size_t userlen = strlen(*userpwd);
|
---|
| 447 | char *passptr;
|
---|
| 448 |
|
---|
| 449 | if(osep)
|
---|
| 450 | *osep = '\0';
|
---|
| 451 |
|
---|
| 452 | /* build a nice-looking prompt */
|
---|
| 453 | if(!i && last)
|
---|
| 454 | curlx_msnprintf(prompt, sizeof(prompt),
|
---|
| 455 | "Enter %s password for user '%s':",
|
---|
| 456 | kind, *userpwd);
|
---|
| 457 | else
|
---|
| 458 | curlx_msnprintf(prompt, sizeof(prompt),
|
---|
| 459 | "Enter %s password for user '%s' on URL #%"
|
---|
| 460 | CURL_FORMAT_CURL_OFF_TU ":",
|
---|
| 461 | kind, *userpwd, (curl_off_t) (i + 1));
|
---|
| 462 |
|
---|
| 463 | /* get password */
|
---|
| 464 | getpass_r(prompt, passwd, sizeof(passwd));
|
---|
| 465 | passwdlen = strlen(passwd);
|
---|
| 466 |
|
---|
| 467 | if(osep)
|
---|
| 468 | *osep = ';';
|
---|
| 469 |
|
---|
| 470 | /* extend the allocated memory area to fit the password too */
|
---|
| 471 | passptr = realloc(*userpwd,
|
---|
| 472 | passwdlen + 1 + /* an extra for the colon */
|
---|
| 473 | userlen + 1); /* an extra for the zero */
|
---|
| 474 | if(!passptr)
|
---|
| 475 | return CURLE_OUT_OF_MEMORY;
|
---|
| 476 |
|
---|
| 477 | /* append the password separated with a colon */
|
---|
| 478 | passptr[userlen] = ':';
|
---|
| 479 | memcpy(&passptr[userlen + 1], passwd, passwdlen + 1);
|
---|
| 480 | *userpwd = passptr;
|
---|
| 481 | }
|
---|
| 482 |
|
---|
| 483 | return CURLE_OK;
|
---|
| 484 | }
|
---|
| 485 |
|
---|
| 486 | ParameterError add2list(struct curl_slist **list, const char *ptr)
|
---|
| 487 | {
|
---|
| 488 | struct curl_slist *newlist = curl_slist_append(*list, ptr);
|
---|
| 489 | if(newlist)
|
---|
| 490 | *list = newlist;
|
---|
| 491 | else
|
---|
| 492 | return PARAM_NO_MEM;
|
---|
| 493 |
|
---|
| 494 | return PARAM_OK;
|
---|
| 495 | }
|
---|
| 496 |
|
---|
| 497 | int ftpfilemethod(struct OperationConfig *config, const char *str)
|
---|
| 498 | {
|
---|
| 499 | if(curl_strequal("singlecwd", str))
|
---|
| 500 | return CURLFTPMETHOD_SINGLECWD;
|
---|
| 501 | if(curl_strequal("nocwd", str))
|
---|
| 502 | return CURLFTPMETHOD_NOCWD;
|
---|
| 503 | if(curl_strequal("multicwd", str))
|
---|
| 504 | return CURLFTPMETHOD_MULTICWD;
|
---|
| 505 |
|
---|
| 506 | warnf(config->global, "unrecognized ftp file method '%s', using default\n",
|
---|
| 507 | str);
|
---|
| 508 |
|
---|
| 509 | return CURLFTPMETHOD_MULTICWD;
|
---|
| 510 | }
|
---|
| 511 |
|
---|
| 512 | int ftpcccmethod(struct OperationConfig *config, const char *str)
|
---|
| 513 | {
|
---|
| 514 | if(curl_strequal("passive", str))
|
---|
| 515 | return CURLFTPSSL_CCC_PASSIVE;
|
---|
| 516 | if(curl_strequal("active", str))
|
---|
| 517 | return CURLFTPSSL_CCC_ACTIVE;
|
---|
| 518 |
|
---|
| 519 | warnf(config->global, "unrecognized ftp CCC method '%s', using default\n",
|
---|
| 520 | str);
|
---|
| 521 |
|
---|
| 522 | return CURLFTPSSL_CCC_PASSIVE;
|
---|
| 523 | }
|
---|
| 524 |
|
---|
| 525 | long delegation(struct OperationConfig *config, char *str)
|
---|
| 526 | {
|
---|
| 527 | if(curl_strequal("none", str))
|
---|
| 528 | return CURLGSSAPI_DELEGATION_NONE;
|
---|
| 529 | if(curl_strequal("policy", str))
|
---|
| 530 | return CURLGSSAPI_DELEGATION_POLICY_FLAG;
|
---|
| 531 | if(curl_strequal("always", str))
|
---|
| 532 | return CURLGSSAPI_DELEGATION_FLAG;
|
---|
| 533 |
|
---|
| 534 | warnf(config->global, "unrecognized delegation method '%s', using none\n",
|
---|
| 535 | str);
|
---|
| 536 |
|
---|
| 537 | return CURLGSSAPI_DELEGATION_NONE;
|
---|
| 538 | }
|
---|
| 539 |
|
---|
| 540 | /*
|
---|
| 541 | * my_useragent: returns allocated string with default user agent
|
---|
| 542 | */
|
---|
| 543 | static char *my_useragent(void)
|
---|
| 544 | {
|
---|
| 545 | return strdup(CURL_NAME "/" CURL_VERSION);
|
---|
| 546 | }
|
---|
| 547 |
|
---|
| 548 | CURLcode get_args(struct OperationConfig *config, const size_t i)
|
---|
| 549 | {
|
---|
| 550 | CURLcode result = CURLE_OK;
|
---|
| 551 | bool last = (config->next ? FALSE : TRUE);
|
---|
| 552 |
|
---|
| 553 | /* Check we have a password for the given host user */
|
---|
| 554 | if(config->userpwd && !config->oauth_bearer) {
|
---|
| 555 | result = checkpasswd("host", i, last, &config->userpwd);
|
---|
| 556 | if(result)
|
---|
| 557 | return result;
|
---|
| 558 | }
|
---|
| 559 |
|
---|
| 560 | /* Check we have a password for the given proxy user */
|
---|
| 561 | if(config->proxyuserpwd) {
|
---|
| 562 | result = checkpasswd("proxy", i, last, &config->proxyuserpwd);
|
---|
| 563 | if(result)
|
---|
| 564 | return result;
|
---|
| 565 | }
|
---|
| 566 |
|
---|
| 567 | /* Check we have a user agent */
|
---|
| 568 | if(!config->useragent) {
|
---|
| 569 | config->useragent = my_useragent();
|
---|
| 570 | if(!config->useragent) {
|
---|
| 571 | helpf(config->global->errors, "out of memory\n");
|
---|
| 572 | result = CURLE_OUT_OF_MEMORY;
|
---|
| 573 | }
|
---|
| 574 | }
|
---|
| 575 |
|
---|
| 576 | return result;
|
---|
| 577 | }
|
---|
| 578 |
|
---|
| 579 | /*
|
---|
| 580 | * Parse the string and modify ssl_version in the val argument. Return PARAM_OK
|
---|
| 581 | * on success, otherwise a parameter error enum. ONLY ACCEPTS POSITIVE NUMBERS!
|
---|
| 582 | *
|
---|
| 583 | * Since this function gets called with the 'nextarg' pointer from within the
|
---|
| 584 | * getparameter a lot, we must check it for NULL before accessing the str
|
---|
| 585 | * data.
|
---|
| 586 | */
|
---|
| 587 |
|
---|
| 588 | ParameterError str2tls_max(long *val, const char *str)
|
---|
| 589 | {
|
---|
| 590 | static struct s_tls_max {
|
---|
| 591 | const char *tls_max_str;
|
---|
| 592 | long tls_max;
|
---|
| 593 | } const tls_max_array[] = {
|
---|
| 594 | { "default", CURL_SSLVERSION_MAX_DEFAULT },
|
---|
| 595 | { "1.0", CURL_SSLVERSION_MAX_TLSv1_0 },
|
---|
| 596 | { "1.1", CURL_SSLVERSION_MAX_TLSv1_1 },
|
---|
| 597 | { "1.2", CURL_SSLVERSION_MAX_TLSv1_2 },
|
---|
| 598 | { "1.3", CURL_SSLVERSION_MAX_TLSv1_3 }
|
---|
| 599 | };
|
---|
| 600 | size_t i = 0;
|
---|
| 601 | if(!str)
|
---|
| 602 | return PARAM_REQUIRES_PARAMETER;
|
---|
| 603 | for(i = 0; i < sizeof(tls_max_array)/sizeof(tls_max_array[0]); i++) {
|
---|
| 604 | if(!strcmp(str, tls_max_array[i].tls_max_str)) {
|
---|
| 605 | *val = tls_max_array[i].tls_max;
|
---|
| 606 | return PARAM_OK;
|
---|
| 607 | }
|
---|
| 608 | }
|
---|
| 609 | return PARAM_BAD_USE;
|
---|
| 610 | }
|
---|