1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2009, 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 http://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  * $Id: url.c,v 1.790 2009-03-02 23:05:31 bagder Exp $
22  ***************************************************************************/
23 
24 /* -- WIN32 approved -- */
25 
26 #include "setup.h"
27 
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdarg.h>
31 #include <stdlib.h>
32 #include <ctype.h>
33 #include <errno.h>
34 
35 #ifdef WIN32
36 #include <time.h>
37 #include <io.h>
38 #else
39 #ifdef HAVE_SYS_SOCKET_H
40 #include <sys/socket.h>
41 #endif
42 #ifdef HAVE_NETINET_IN_H
43 #include <netinet/in.h>
44 #endif
45 #ifdef HAVE_SYS_TIME_H
46 #include <sys/time.h>
47 #endif
48 #ifdef HAVE_UNISTD_H
49 #include <unistd.h>
50 #endif
51 #ifdef HAVE_NETDB_H
52 #include <netdb.h>
53 #endif
54 #ifdef HAVE_ARPA_INET_H
55 #include <arpa/inet.h>
56 #endif
57 #ifdef HAVE_NET_IF_H
58 #include <net/if.h>
59 #endif
60 #ifdef HAVE_SYS_IOCTL_H
61 #include <sys/ioctl.h>
62 #endif
63 
64 #ifdef HAVE_SYS_PARAM_H
65 #include <sys/param.h>
66 #endif
67 
68 #ifdef VMS
69 #include <in.h>
70 #include <inet.h>
71 #endif
72 
73 #ifndef HAVE_SOCKET
74 #error "We can't compile without socket() support!"
75 #endif
76 
77 #endif  /* WIN32 */
78 
79 #ifdef USE_LIBIDN
80 #include <idna.h>
81 #include <tld.h>
82 #include <stringprep.h>
83 #ifdef HAVE_IDN_FREE_H
84 #include <idn-free.h>
85 #else
86 void idn_free (void *ptr); /* prototype from idn-free.h, not provided by
87                               libidn 0.4.5's make install! */
88 #endif
89 #ifndef HAVE_IDN_FREE
90 /* if idn_free() was not found in this version of libidn, use plain free()
91    instead */
92 #define idn_free(x) (free)(x)
93 #endif
94 #endif  /* USE_LIBIDN */
95 
96 #include "urldata.h"
97 #include "netrc.h"
98 
99 #include "formdata.h"
100 #include "sslgen.h"
101 #include "hostip.h"
102 #include "transfer.h"
103 #include "sendf.h"
104 #include "progress.h"
105 #include "cookie.h"
106 #include "strequal.h"
107 #include "strerror.h"
108 #include "escape.h"
109 #include "strtok.h"
110 #include "share.h"
111 #include "content_encoding.h"
112 #include "http_digest.h"
113 #include "http_negotiate.h"
114 #include "select.h"
115 #include "multiif.h"
116 #include "easyif.h"
117 #include "speedcheck.h"
118 #include "rawstr.h"
119 
120 /* And now for the protocols */
121 #include "ftp.h"
122 #include "dict.h"
123 #include "telnet.h"
124 #include "tftp.h"
125 #include "http.h"
126 #include "file.h"
127 #include "curl_ldap.h"
128 #include "ssh.h"
129 #include "url.h"
130 #include "connect.h"
131 #include "inet_ntop.h"
132 #include "http_ntlm.h"
133 #include "socks.h"
134 
135 #define _MPRINTF_REPLACE /* use our functions only */
136 #include <curl/mprintf.h>
137 
138 #include "memory.h"
139 /* The last #include file should be: */
140 #include "memdebug.h"
141 
142 /* Local static prototypes */
143 static long ConnectionKillOne(struct SessionHandle *data);
144 static void conn_free(struct connectdata *conn);
145 static void signalPipeClose(struct curl_llist *pipeline);
146 
147 #ifdef CURL_DISABLE_VERBOSE_STRINGS
148 #define verboseconnect(x)  do { } while (0)
149 #endif
150 
151 
152 /*
153  * Protocol table.
154  */
155 
156 static const struct Curl_handler * const protocols[] = {
157 
158 #ifndef CURL_DISABLE_HTTP
159   &Curl_handler_http,
160 #endif
161 
162 #if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
163   &Curl_handler_https,
164 #endif
165 
166 #ifndef CURL_DISABLE_FTP
167   &Curl_handler_ftp,
168 #endif
169 
170 #if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)
171   &Curl_handler_ftps,
172 #endif
173 
174 #ifndef CURL_DISABLE_TELNET
175   &Curl_handler_telnet,
176 #endif
177 
178 #ifndef CURL_DISABLE_DICT
179   &Curl_handler_dict,
180 #endif
181 
182 #ifndef CURL_DISABLE_LDAP
183   &Curl_handler_ldap,
184 #endif
185 
186 #if !defined(CURL_DISABLE_LDAP) && defined(HAVE_LDAP_SSL)
187   &Curl_handler_ldaps,
188 #endif
189 
190 #ifndef CURL_DISABLE_FILE
191   &Curl_handler_file,
192 #endif
193 
194 #ifndef CURL_DISABLE_TFTP
195   &Curl_handler_tftp,
196 #endif
197 
198 #ifdef USE_LIBSSH2
199   &Curl_handler_scp,
200   &Curl_handler_sftp,
201 #endif
202 
203   (struct Curl_handler *) NULL
204 };
205 
206 /*
207  * Dummy handler for undefined protocol schemes.
208  */
209 
210 static const struct Curl_handler Curl_handler_dummy = {
211   "<no protocol>",                      /* scheme */
212   ZERO_NULL,                            /* setup_connection */
213   ZERO_NULL,                            /* do_it */
214   ZERO_NULL,                            /* done */
215   ZERO_NULL,                            /* do_more */
216   ZERO_NULL,                            /* connect_it */
217   ZERO_NULL,                            /* connecting */
218   ZERO_NULL,                            /* doing */
219   ZERO_NULL,                            /* proto_getsock */
220   ZERO_NULL,                            /* doing_getsock */
221   ZERO_NULL,                            /* perform_getsock */
222   ZERO_NULL,                            /* disconnect */
223   0,                                    /* defport */
224   0                                     /* protocol */
225 };
226 
Curl_safefree(void * ptr)227 void Curl_safefree(void *ptr)
228 {
229   if(ptr)
230     free(ptr);
231 }
232 
close_connections(struct SessionHandle * data)233 static void close_connections(struct SessionHandle *data)
234 {
235   /* Loop through all open connections and kill them one by one */
236   long i;
237   do {
238     i = ConnectionKillOne(data);
239   } while(i != -1L);
240 }
241 
Curl_freeset(struct SessionHandle * data)242 void Curl_freeset(struct SessionHandle * data)
243 {
244   /* Free all dynamic strings stored in the data->set substructure. */
245   enum dupstring i;
246   for(i=(enum dupstring)0; i < STRING_LAST; i++)
247     Curl_safefree(data->set.str[i]);
248 }
249 
setstropt(char ** charp,char * s)250 static CURLcode setstropt(char **charp, char * s)
251 {
252   /* Release the previous storage at `charp' and replace by a dynamic storage
253      copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */
254 
255   if(*charp) {
256     free(*charp);
257     *charp = (char *) NULL;
258   }
259 
260   if(s) {
261     s = strdup(s);
262 
263     if(!s)
264       return CURLE_OUT_OF_MEMORY;
265 
266     *charp = s;
267   }
268 
269   return CURLE_OK;
270 }
271 
setstropt_userpwd(char * option,char ** user_storage,char ** pwd_storage)272 static CURLcode setstropt_userpwd(char *option, char **user_storage,
273                                   char **pwd_storage)
274 {
275   char* separator;
276   CURLcode result = CURLE_OK;
277 
278   if(!option)
279     return result;
280 
281   separator = strchr(option, ':');
282   if (separator != NULL) {
283 
284     /* store username part of option */
285     char * p;
286     size_t username_len = (size_t)(separator-option);
287     p = malloc(username_len+1);
288     if(!p)
289       result = CURLE_OUT_OF_MEMORY;
290     else {
291       memcpy(p, option, username_len);
292       p[username_len] = '\0';
293       Curl_safefree(*user_storage);
294       *user_storage = p;
295     }
296 
297     /* store password part of option */
298     if (result == CURLE_OK) {
299       result = setstropt(pwd_storage, separator+1);
300     }
301   }
302   else {
303     result = setstropt(user_storage, option);
304   }
305   return result;
306 }
307 
Curl_dupset(struct SessionHandle * dst,struct SessionHandle * src)308 CURLcode Curl_dupset(struct SessionHandle * dst, struct SessionHandle * src)
309 {
310   CURLcode r = CURLE_OK;
311   enum dupstring i;
312 
313   /* Copy src->set into dst->set first, then deal with the strings
314      afterwards */
315   dst->set = src->set;
316 
317   /* clear all string pointers first */
318   memset(dst->set.str, 0, STRING_LAST * sizeof(char *));
319 
320   /* duplicate all strings */
321   for(i=(enum dupstring)0; i< STRING_LAST; i++) {
322     r = setstropt(&dst->set.str[i], src->set.str[i]);
323     if(r != CURLE_OK)
324       break;
325   }
326 
327   /* If a failure occurred, freeing has to be performed externally. */
328   return r;
329 }
330 
331 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
flush_cookies(struct SessionHandle * data,int cleanup)332 static void flush_cookies(struct SessionHandle *data, int cleanup)
333 {
334   if(data->set.str[STRING_COOKIEJAR]) {
335     if(data->change.cookielist) {
336       /* If there is a list of cookie files to read, do it first so that
337          we have all the told files read before we write the new jar.
338          Curl_cookie_loadfiles() LOCKS and UNLOCKS the share itself! */
339       Curl_cookie_loadfiles(data);
340     }
341 
342     Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
343 
344     /* if we have a destination file for all the cookies to get dumped to */
345     if(Curl_cookie_output(data->cookies, data->set.str[STRING_COOKIEJAR]))
346       infof(data, "WARNING: failed to save cookies in %s\n",
347             data->set.str[STRING_COOKIEJAR]);
348   }
349   else {
350     if(cleanup && data->change.cookielist)
351       /* since nothing is written, we can just free the list of cookie file
352          names */
353       curl_slist_free_all(data->change.cookielist); /* clean up list */
354     Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
355   }
356 
357   if(cleanup && (!data->share || (data->cookies != data->share->cookies))) {
358     Curl_cookie_cleanup(data->cookies);
359   }
360   Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
361 }
362 #endif
363 
364 /*
365  * This is the internal function curl_easy_cleanup() calls. This should
366  * cleanup and free all resources associated with this sessionhandle.
367  *
368  * NOTE: if we ever add something that attempts to write to a socket or
369  * similar here, we must ignore SIGPIPE first. It is currently only done
370  * when curl_easy_perform() is invoked.
371  */
372 
Curl_close(struct SessionHandle * data)373 CURLcode Curl_close(struct SessionHandle *data)
374 {
375   struct Curl_multi *m = data->multi;
376 
377 #ifdef CURLDEBUG
378   /* only for debugging, scan through all connections and see if there's a
379      pipe reference still identifying this handle */
380 
381   if(data->state.connc && data->state.connc->type == CONNCACHE_MULTI) {
382     struct conncache *c = data->state.connc;
383     long i;
384     struct curl_llist *pipeline;
385     struct curl_llist_element *curr;
386     struct connectdata *connptr;
387 
388     for(i=0; i< c->num; i++) {
389       connptr = c->connects[i];
390       if(!connptr)
391         continue;
392 
393       pipeline = connptr->send_pipe;
394       if(pipeline) {
395         for (curr = pipeline->head; curr; curr=curr->next) {
396           if(data == (struct SessionHandle *) curr->ptr) {
397             fprintf(stderr,
398                     "MAJOR problem we %p are still in send pipe for %p done %d\n",
399                     data, connptr, (int)connptr->bits.done);
400           }
401         }
402       }
403       pipeline = connptr->recv_pipe;
404       if(pipeline) {
405         for (curr = pipeline->head; curr; curr=curr->next) {
406           if(data == (struct SessionHandle *) curr->ptr) {
407             fprintf(stderr,
408                     "MAJOR problem we %p are still in recv pipe for %p done %d\n",
409                     data, connptr, (int)connptr->bits.done);
410           }
411         }
412       }
413       pipeline = connptr->pend_pipe;
414       if(pipeline) {
415         for (curr = pipeline->head; curr; curr=curr->next) {
416           if(data == (struct SessionHandle *) curr->ptr) {
417             fprintf(stderr,
418                     "MAJOR problem we %p are still in pend pipe for %p done %d\n",
419                     data, connptr, (int)connptr->bits.done);
420           }
421         }
422       }
423     }
424   }
425 #endif
426 
427   if(m)
428     /* This handle is still part of a multi handle, take care of this first
429        and detach this handle from there. */
430     Curl_multi_rmeasy(data->multi, data);
431 
432   data->magic = 0; /* force a clear AFTER the possibly enforced removal from
433                       the multi handle, since that function uses the magic
434                       field! */
435 
436   if(data->state.connc) {
437 
438     if(data->state.connc->type == CONNCACHE_PRIVATE) {
439       /* close all connections still alive that are in the private connection
440          cache, as we no longer have the pointer left to the shared one. */
441       close_connections(data);
442 
443       /* free the connection cache if allocated privately */
444       Curl_rm_connc(data->state.connc);
445     }
446   }
447 
448   if(data->state.shared_conn) {
449     /* marked to be used by a pending connection so we can't kill this handle
450        just yet */
451     data->state.closed = TRUE;
452     return CURLE_OK;
453   }
454 
455   if(data->dns.hostcachetype == HCACHE_PRIVATE) {
456     Curl_hash_destroy(data->dns.hostcache);
457     data->dns.hostcachetype = HCACHE_NONE;
458     data->dns.hostcache = NULL;
459   }
460 
461   if(data->state.rangestringalloc)
462     free(data->state.range);
463 
464   /* Free the pathbuffer */
465   Curl_safefree(data->state.pathbuffer);
466   Curl_safefree(data->state.proto.generic);
467 
468   /* Close down all open SSL info and sessions */
469   Curl_ssl_close_all(data);
470   Curl_safefree(data->state.first_host);
471   Curl_safefree(data->state.scratch);
472   Curl_ssl_free_certinfo(data);
473 
474   if(data->change.referer_alloc)
475     free(data->change.referer);
476 
477   if(data->change.url_alloc)
478     free(data->change.url);
479 
480   Curl_safefree(data->state.headerbuff);
481 
482 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
483   flush_cookies(data, 1);
484 #endif
485 
486   Curl_digest_cleanup(data);
487 
488   Curl_safefree(data->info.contenttype);
489   Curl_safefree(data->info.wouldredirect);
490 
491   /* this destroys the channel and we cannot use it anymore after this */
492   ares_destroy(data->state.areschannel);
493 
494 #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
495   /* close iconv conversion descriptors */
496   if(data->inbound_cd != (iconv_t)-1) {
497      iconv_close(data->inbound_cd);
498   }
499   if(data->outbound_cd != (iconv_t)-1) {
500      iconv_close(data->outbound_cd);
501   }
502   if(data->utf8_cd != (iconv_t)-1) {
503      iconv_close(data->utf8_cd);
504   }
505 #endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
506 
507   /* No longer a dirty share, if it exists */
508   if(data->share) {
509     Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
510     data->share->dirty--;
511     Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
512   }
513 
514   Curl_freeset(data);
515   free(data);
516   return CURLE_OK;
517 }
518 
519 /* create a connection cache of a private or multi type */
Curl_mk_connc(int type,long amount)520 struct conncache *Curl_mk_connc(int type,
521                                 long amount) /* set -1 to use default */
522 {
523   /* It is subject for debate how many default connections to have for a multi
524      connection cache... */
525 
526   struct conncache *c;
527   long default_amount;
528 
529   if(type == CONNCACHE_PRIVATE) {
530     default_amount = (amount < 0) ? 5 : amount;
531   }
532   else {
533     default_amount = (amount < 0) ? 10 : amount;
534   }
535 
536   c= calloc(sizeof(struct conncache), 1);
537   if(!c)
538     return NULL;
539 
540   if((size_t)(default_amount) > ((size_t)-1) / sizeof(struct connectdata *))
541     default_amount = ((size_t)-1) / sizeof(struct connectdata *);
542 
543   c->connects = calloc(sizeof(struct connectdata *), (size_t)default_amount);
544   if(!c->connects) {
545     free(c);
546     return NULL;
547   }
548 
549   c->num = default_amount;
550 
551   return c;
552 }
553 
554 /* Change number of entries of a connection cache */
Curl_ch_connc(struct SessionHandle * data,struct conncache * c,long newamount)555 CURLcode Curl_ch_connc(struct SessionHandle *data,
556                        struct conncache *c,
557                        long newamount)
558 {
559   long i;
560   struct connectdata **newptr;
561 
562   if(newamount < 1)
563     newamount = 1; /* we better have at least one entry */
564 
565   if(!c) {
566     /* we get a NULL pointer passed in as connection cache, which means that
567        there is no cache created for this SessionHandle just yet, we create a
568        brand new with the requested size.
569     */
570     data->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, newamount);
571     if(!data->state.connc)
572       return CURLE_OUT_OF_MEMORY;
573     return CURLE_OK;
574   }
575 
576   if(newamount < c->num) {
577     /* Since this number is *decreased* from the existing number, we must
578        close the possibly open connections that live on the indexes that
579        are being removed!
580 
581        NOTE: for conncache_multi cases we must make sure that we only
582        close handles not in use.
583     */
584     for(i=newamount; i< c->num; i++)
585       Curl_disconnect(c->connects[i]);
586 
587     /* If the most recent connection is no longer valid, mark it
588        invalid. */
589     if(data->state.lastconnect <= newamount)
590       data->state.lastconnect = -1;
591   }
592   if(newamount > 0) {
593     newptr = realloc(c->connects, sizeof(struct connectdata *) * newamount);
594     if(!newptr)
595       /* we closed a few connections in vain, but so what? */
596       return CURLE_OUT_OF_MEMORY;
597 
598     /* nullify the newly added pointers */
599     for(i=c->num; i<newamount; i++)
600       newptr[i] = NULL;
601 
602     c->connects = newptr;
603     c->num = newamount;
604   }
605   /* we no longer support less than 1 as size for the connection cache, and
606      I'm not sure it ever worked to set it to zero */
607   return CURLE_OK;
608 }
609 
610 /* Free a connection cache. This is called from Curl_close() and
611    curl_multi_cleanup(). */
Curl_rm_connc(struct conncache * c)612 void Curl_rm_connc(struct conncache *c)
613 {
614   if(c->connects) {
615     long i;
616     for(i = 0; i < c->num; ++i)
617       conn_free(c->connects[i]);
618 
619     free(c->connects);
620   }
621 
622   free(c);
623 }
624 
625 /*
626  * Initialize the UserDefined fields within a SessionHandle.
627  * This may be safely called on a new or existing SessionHandle.
628  */
Curl_init_userdefined(struct UserDefined * set)629 CURLcode Curl_init_userdefined(struct UserDefined *set)
630 {
631   CURLcode res = CURLE_OK;
632 
633   set->out = stdout; /* default output to stdout */
634   set->in  = stdin;  /* default input from stdin */
635   set->err  = stderr;  /* default stderr to stderr */
636 
637   /* use fwrite as default function to store output */
638   set->fwrite_func = (curl_write_callback)fwrite;
639 
640   /* use fread as default function to read input */
641   set->fread_func = (curl_read_callback)fread;
642 
643   set->seek_func = ZERO_NULL;
644   set->seek_client = ZERO_NULL;
645 
646   /* conversion callbacks for non-ASCII hosts */
647   set->convfromnetwork = ZERO_NULL;
648   set->convtonetwork   = ZERO_NULL;
649   set->convfromutf8    = ZERO_NULL;
650 
651   set->infilesize = -1;      /* we don't know any size */
652   set->postfieldsize = -1;   /* unknown size */
653   set->maxredirs = -1;       /* allow any amount by default */
654 
655   set->httpreq = HTTPREQ_GET; /* Default HTTP request */
656   set->ftp_use_epsv = TRUE;   /* FTP defaults to EPSV operations */
657   set->ftp_use_eprt = TRUE;   /* FTP defaults to EPRT operations */
658   set->ftp_filemethod = FTPFILE_MULTICWD;
659 
660   set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
661 
662   /* Set the default size of the SSL session ID cache */
663   set->ssl.numsessions = 5;
664 
665   set->proxyport = CURL_DEFAULT_PROXY_PORT; /* from url.h */
666   set->proxytype = CURLPROXY_HTTP; /* defaults to HTTP proxy */
667   set->httpauth = CURLAUTH_BASIC;  /* defaults to basic */
668   set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */
669 
670   /* make libcurl quiet by default: */
671   set->hide_progress = TRUE;  /* CURLOPT_NOPROGRESS changes these */
672 
673   /*
674    * libcurl 7.10 introduced SSL verification *by default*! This needs to be
675    * switched off unless wanted.
676    */
677   set->ssl.verifypeer = TRUE;
678   set->ssl.verifyhost = 2;
679   set->ssh_auth_types = CURLSSH_AUTH_DEFAULT; /* defaults to any auth
680                                                       type */
681   set->ssl.sessionid = TRUE; /* session ID caching enabled by default */
682 
683   set->new_file_perms = 0644;    /* Default permissions */
684   set->new_directory_perms = 0755; /* Default permissions */
685 
686   /* for the *protocols fields we don't use the CURLPROTO_ALL convenience
687      define since we internally only use the lower 16 bits for the passed
688      in bitmask to not conflict with the private bits */
689   set->allowed_protocols = PROT_EXTMASK;
690   set->redir_protocols =
691     PROT_EXTMASK & ~(CURLPROTO_FILE|CURLPROTO_SCP); /* not FILE or SCP */
692 
693 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
694   /*
695    * disallow unprotected protection negotiation NEC reference implementation
696    * seem not to follow rfc1961 section 4.3/4.4
697    */
698   set->socks5_gssapi_nec = FALSE;
699   /* set default gssapi service name */
700   res = setstropt(&set->str[STRING_SOCKS5_GSSAPI_SERVICE],
701                   (char *) CURL_DEFAULT_SOCKS5_GSSAPI_SERVICE);
702   if (res != CURLE_OK)
703     return res;
704 #endif
705 
706   /* This is our preferred CA cert bundle/path since install time */
707 #if defined(CURL_CA_BUNDLE)
708   res = setstropt(&set->str[STRING_SSL_CAFILE], (char *) CURL_CA_BUNDLE);
709 #elif defined(CURL_CA_PATH)
710   res = setstropt(&set->str[STRING_SSL_CAPATH], (char *) CURL_CA_PATH);
711 #endif
712 
713   return res;
714 }
715 
716 /**
717  * Curl_open()
718  *
719  * @param curl is a pointer to a sessionhandle pointer that gets set by this
720  * function.
721  * @return CURLcode
722  */
723 
Curl_open(struct SessionHandle ** curl)724 CURLcode Curl_open(struct SessionHandle **curl)
725 {
726   CURLcode res = CURLE_OK;
727   struct SessionHandle *data;
728 #ifdef USE_ARES
729   int status;
730 #endif
731 
732   /* Very simple start-up: alloc the struct, init it with zeroes and return */
733   data = calloc(1, sizeof(struct SessionHandle));
734   if(!data) {
735     /* this is a very serious error */
736     DEBUGF(fprintf(stderr, "Error: calloc of SessionHandle failed\n"));
737     return CURLE_OUT_OF_MEMORY;
738   }
739 
740   data->magic = CURLEASY_MAGIC_NUMBER;
741 
742 #ifdef USE_ARES
743   if((status = ares_init(&data->state.areschannel)) != ARES_SUCCESS) {
744     DEBUGF(fprintf(stderr, "Error: ares_init failed\n"));
745     free(data);
746     if(status == ARES_ENOMEM)
747       return CURLE_OUT_OF_MEMORY;
748     else
749       return CURLE_FAILED_INIT;
750   }
751   /* make sure that all other returns from this function should destroy the
752      ares channel before returning error! */
753 #endif
754 
755   /* We do some initial setup here, all those fields that can't be just 0 */
756 
757   data->state.headerbuff = malloc(HEADERSIZE);
758   if(!data->state.headerbuff) {
759     DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
760     res = CURLE_OUT_OF_MEMORY;
761   }
762   else {
763     Curl_easy_initHandleData(data);
764     res = Curl_init_userdefined(&data->set);
765 
766     data->state.headersize=HEADERSIZE;
767 
768 #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV)
769     /* conversion descriptors for iconv calls */
770     data->outbound_cd = (iconv_t)-1;
771     data->inbound_cd  = (iconv_t)-1;
772     data->utf8_cd     = (iconv_t)-1;
773 #endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */
774 
775     /* most recent connection is not yet defined */
776     data->state.lastconnect = -1;
777 
778     data->progress.flags |= PGRS_HIDE;
779     data->state.current_speed = -1; /* init to negative == impossible */
780 
781     /* This no longer creates a connection cache here. It is instead made on
782        the first call to curl_easy_perform() or when the handle is added to a
783        multi stack. */
784   }
785 
786   if(res) {
787     ares_destroy(data->state.areschannel);
788     if(data->state.headerbuff)
789       free(data->state.headerbuff);
790     Curl_freeset(data);
791     free(data);
792     data = NULL;
793   }
794   else
795     *curl = data;
796 
797   return res;
798 }
799 
Curl_setopt(struct SessionHandle * data,CURLoption option,va_list param)800 CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
801                      va_list param)
802 {
803   char *argptr;
804   CURLcode result = CURLE_OK;
805 #ifndef CURL_DISABLE_HTTP
806   curl_off_t bigsize;
807 #endif
808 
809   switch(option) {
810   case CURLOPT_DNS_CACHE_TIMEOUT:
811     data->set.dns_cache_timeout = va_arg(param, long);
812     break;
813   case CURLOPT_DNS_USE_GLOBAL_CACHE:
814   {
815     /* remember we want this enabled */
816     long use_cache = va_arg(param, long);
817     data->set.global_dns_cache = (bool)(0 != use_cache);
818   }
819   break;
820   case CURLOPT_SSL_CIPHER_LIST:
821     /* set a list of cipher we want to use in the SSL connection */
822     result = setstropt(&data->set.str[STRING_SSL_CIPHER_LIST],
823                        va_arg(param, char *));
824     break;
825 
826   case CURLOPT_RANDOM_FILE:
827     /*
828      * This is the path name to a file that contains random data to seed
829      * the random SSL stuff with. The file is only used for reading.
830      */
831     result = setstropt(&data->set.str[STRING_SSL_RANDOM_FILE],
832                        va_arg(param, char *));
833     break;
834   case CURLOPT_EGDSOCKET:
835     /*
836      * The Entropy Gathering Daemon socket pathname
837      */
838     result = setstropt(&data->set.str[STRING_SSL_EGDSOCKET],
839                        va_arg(param, char *));
840     break;
841   case CURLOPT_MAXCONNECTS:
842     /*
843      * Set the absolute number of maximum simultaneous alive connection that
844      * libcurl is allowed to have.
845      */
846     result = Curl_ch_connc(data, data->state.connc, va_arg(param, long));
847     break;
848   case CURLOPT_FORBID_REUSE:
849     /*
850      * When this transfer is done, it must not be left to be reused by a
851      * subsequent transfer but shall be closed immediately.
852      */
853     data->set.reuse_forbid = (bool)(0 != va_arg(param, long));
854     break;
855   case CURLOPT_FRESH_CONNECT:
856     /*
857      * This transfer shall not use a previously cached connection but
858      * should be made with a fresh new connect!
859      */
860     data->set.reuse_fresh = (bool)(0 != va_arg(param, long));
861     break;
862   case CURLOPT_VERBOSE:
863     /*
864      * Verbose means infof() calls that give a lot of information about
865      * the connection and transfer procedures as well as internal choices.
866      */
867     data->set.verbose = (bool)(0 != va_arg(param, long));
868     break;
869   case CURLOPT_HEADER:
870     /*
871      * Set to include the header in the general data output stream.
872      */
873     data->set.include_header = (bool)(0 != va_arg(param, long));
874     break;
875   case CURLOPT_NOPROGRESS:
876     /*
877      * Shut off the internal supported progress meter
878      */
879     data->set.hide_progress = (bool)(0 != va_arg(param, long));
880     if(data->set.hide_progress)
881       data->progress.flags |= PGRS_HIDE;
882     else
883       data->progress.flags &= ~PGRS_HIDE;
884     break;
885   case CURLOPT_NOBODY:
886     /*
887      * Do not include the body part in the output data stream.
888      */
889     data->set.opt_no_body = (bool)(0 != va_arg(param, long));
890 
891     /* in HTTP lingo, no body means using the HEAD request and if unset there
892        really is no perfect method that is the "opposite" of HEAD but in
893        reality most people probably think GET then. The important thing is
894        that we can't let it remain HEAD if the opt_no_body is set FALSE since
895        then we'll behave wrong when getting HTTP. */
896     data->set.httpreq = data->set.opt_no_body?HTTPREQ_HEAD:HTTPREQ_GET;
897     break;
898   case CURLOPT_FAILONERROR:
899     /*
900      * Don't output the >=300 error code HTML-page, but instead only
901      * return error.
902      */
903     data->set.http_fail_on_error = (bool)(0 != va_arg(param, long));
904     break;
905   case CURLOPT_UPLOAD:
906   case CURLOPT_PUT:
907     /*
908      * We want to sent data to the remote host. If this is HTTP, that equals
909      * using the PUT request.
910      */
911     data->set.upload = (bool)(0 != va_arg(param, long));
912     if(data->set.upload)
913       /* If this is HTTP, PUT is what's needed to "upload" */
914       data->set.httpreq = HTTPREQ_PUT;
915     else
916       /* In HTTP, the opposite of upload is either GET or a HEAD */
917       data->set.httpreq = data->set.opt_no_body?HTTPREQ_HEAD:HTTPREQ_GET;
918     break;
919   case CURLOPT_FILETIME:
920     /*
921      * Try to get the file time of the remote document. The time will
922      * later (possibly) become available using curl_easy_getinfo().
923      */
924     data->set.get_filetime = (bool)(0 != va_arg(param, long));
925     break;
926   case CURLOPT_FTP_CREATE_MISSING_DIRS:
927     /*
928      * An FTP option that modifies an upload to create missing directories on
929      * the server.
930      */
931     data->set.ftp_create_missing_dirs = (int)va_arg(param, long);
932     break;
933   case CURLOPT_FTP_RESPONSE_TIMEOUT:
934     /*
935      * An FTP option that specifies how quickly an FTP response must be
936      * obtained before it is considered failure.
937      */
938     data->set.ftp_response_timeout = va_arg( param , long ) * 1000;
939     break;
940   case CURLOPT_TFTP_BLKSIZE:
941     /*
942      * TFTP option that specifies the block size to use for data transmission
943      */
944     data->set.tftp_blksize = va_arg(param, long);
945     break;
946   case CURLOPT_DIRLISTONLY:
947     /*
948      * An option that changes the command to one that asks for a list
949      * only, no file info details.
950      */
951     data->set.ftp_list_only = (bool)(0 != va_arg(param, long));
952     break;
953   case CURLOPT_APPEND:
954     /*
955      * We want to upload and append to an existing file.
956      */
957     data->set.ftp_append = (bool)(0 != va_arg(param, long));
958     break;
959   case CURLOPT_FTP_FILEMETHOD:
960     /*
961      * How do access files over FTP.
962      */
963     data->set.ftp_filemethod = (curl_ftpfile)va_arg(param, long);
964     break;
965   case CURLOPT_NETRC:
966     /*
967      * Parse the $HOME/.netrc file
968      */
969     data->set.use_netrc = (enum CURL_NETRC_OPTION)va_arg(param, long);
970     break;
971   case CURLOPT_NETRC_FILE:
972     /*
973      * Use this file instead of the $HOME/.netrc file
974      */
975     result = setstropt(&data->set.str[STRING_NETRC_FILE],
976                        va_arg(param, char *));
977     break;
978   case CURLOPT_TRANSFERTEXT:
979     /*
980      * This option was previously named 'FTPASCII'. Renamed to work with
981      * more protocols than merely FTP.
982      *
983      * Transfer using ASCII (instead of BINARY).
984      */
985     data->set.prefer_ascii = (bool)(0 != va_arg(param, long));
986     break;
987   case CURLOPT_TIMECONDITION:
988     /*
989      * Set HTTP time condition. This must be one of the defines in the
990      * curl/curl.h header file.
991      */
992     data->set.timecondition = (curl_TimeCond)va_arg(param, long);
993     break;
994   case CURLOPT_TIMEVALUE:
995     /*
996      * This is the value to compare with the remote document with the
997      * method set with CURLOPT_TIMECONDITION
998      */
999     data->set.timevalue = (time_t)va_arg(param, long);
1000     break;
1001   case CURLOPT_SSLVERSION:
1002     /*
1003      * Set explicit SSL version to try to connect with, as some SSL
1004      * implementations are lame.
1005      */
1006     data->set.ssl.version = va_arg(param, long);
1007     break;
1008 
1009 #ifndef CURL_DISABLE_HTTP
1010   case CURLOPT_AUTOREFERER:
1011     /*
1012      * Switch on automatic referer that gets set if curl follows locations.
1013      */
1014     data->set.http_auto_referer = (bool)(0 != va_arg(param, long));
1015     break;
1016 
1017   case CURLOPT_ENCODING:
1018     /*
1019      * String to use at the value of Accept-Encoding header.
1020      *
1021      * If the encoding is set to "" we use an Accept-Encoding header that
1022      * encompasses all the encodings we support.
1023      * If the encoding is set to NULL we don't send an Accept-Encoding header
1024      * and ignore an received Content-Encoding header.
1025      *
1026      */
1027     argptr = va_arg(param, char *);
1028     result = setstropt(&data->set.str[STRING_ENCODING],
1029                        (argptr && !*argptr)?
1030                        (char *) ALL_CONTENT_ENCODINGS: argptr);
1031     break;
1032 
1033   case CURLOPT_FOLLOWLOCATION:
1034     /*
1035      * Follow Location: header hints on a HTTP-server.
1036      */
1037     data->set.http_follow_location = (bool)(0 != va_arg(param, long));
1038     break;
1039 
1040   case CURLOPT_UNRESTRICTED_AUTH:
1041     /*
1042      * Send authentication (user+password) when following locations, even when
1043      * hostname changed.
1044      */
1045     data->set.http_disable_hostname_check_before_authentication =
1046       (bool)(0 != va_arg(param, long));
1047     break;
1048 
1049   case CURLOPT_MAXREDIRS:
1050     /*
1051      * The maximum amount of hops you allow curl to follow Location:
1052      * headers. This should mostly be used to detect never-ending loops.
1053      */
1054     data->set.maxredirs = va_arg(param, long);
1055     break;
1056 
1057   case CURLOPT_POSTREDIR:
1058   {
1059     /*
1060      * Set the behaviour of POST when redirecting
1061      * CURL_REDIR_GET_ALL - POST is changed to GET after 301 and 302
1062      * CURL_REDIR_POST_301 - POST is kept as POST after 301
1063      * CURL_REDIR_POST_302 - POST is kept as POST after 302
1064      * CURL_REDIR_POST_ALL - POST is kept as POST after 301 and 302
1065      * other - POST is kept as POST after 301 and 302
1066      */
1067     long postRedir = va_arg(param, long);
1068     data->set.post301 = (bool)((postRedir & CURL_REDIR_POST_301)?TRUE:FALSE);
1069     data->set.post302 = (bool)((postRedir & CURL_REDIR_POST_302)?TRUE:FALSE);
1070   }
1071   break;
1072 
1073   case CURLOPT_POST:
1074     /* Does this option serve a purpose anymore? Yes it does, when
1075        CURLOPT_POSTFIELDS isn't used and the POST data is read off the
1076        callback! */
1077     if(va_arg(param, long)) {
1078       data->set.httpreq = HTTPREQ_POST;
1079       data->set.opt_no_body = FALSE; /* this is implied */
1080     }
1081     else
1082       data->set.httpreq = HTTPREQ_GET;
1083     break;
1084 
1085   case CURLOPT_COPYPOSTFIELDS:
1086     /*
1087      * A string with POST data. Makes curl HTTP POST. Even if it is NULL.
1088      * If needed, CURLOPT_POSTFIELDSIZE must have been set prior to
1089      *  CURLOPT_COPYPOSTFIELDS and not altered later.
1090      */
1091     argptr = va_arg(param, char *);
1092 
1093     if(!argptr || data->set.postfieldsize == -1)
1094       result = setstropt(&data->set.str[STRING_COPYPOSTFIELDS], argptr);
1095     else {
1096       /*
1097        *  Check that requested length does not overflow the size_t type.
1098        */
1099 
1100       if((data->set.postfieldsize < 0) ||
1101          ((sizeof(curl_off_t) != sizeof(size_t)) &&
1102           (data->set.postfieldsize > (curl_off_t)((size_t)-1))))
1103         result = CURLE_OUT_OF_MEMORY;
1104       else {
1105         char * p;
1106 
1107         (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1108 
1109         /* Allocate even when size == 0. This satisfies the need of possible
1110            later address compare to detect the COPYPOSTFIELDS mode, and
1111            to mark that postfields is used rather than read function or
1112            form data.
1113         */
1114         p = malloc((size_t)(data->set.postfieldsize?data->set.postfieldsize:1));
1115 
1116         if(!p)
1117           result = CURLE_OUT_OF_MEMORY;
1118         else {
1119           if(data->set.postfieldsize)
1120             memcpy(p, argptr, (size_t)data->set.postfieldsize);
1121 
1122           data->set.str[STRING_COPYPOSTFIELDS] = p;
1123         }
1124       }
1125     }
1126 
1127     data->set.postfields = data->set.str[STRING_COPYPOSTFIELDS];
1128     data->set.httpreq = HTTPREQ_POST;
1129     break;
1130 
1131   case CURLOPT_POSTFIELDS:
1132     /*
1133      * Like above, but use static data instead of copying it.
1134      */
1135     data->set.postfields = va_arg(param, void *);
1136     /* Release old copied data. */
1137     (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1138     data->set.httpreq = HTTPREQ_POST;
1139     break;
1140 
1141   case CURLOPT_POSTFIELDSIZE:
1142     /*
1143      * The size of the POSTFIELD data to prevent libcurl to do strlen() to
1144      * figure it out. Enables binary posts.
1145      */
1146     bigsize = va_arg(param, long);
1147 
1148     if(data->set.postfieldsize < bigsize &&
1149        data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
1150       /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
1151       (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1152       data->set.postfields = NULL;
1153     }
1154 
1155     data->set.postfieldsize = bigsize;
1156     break;
1157 
1158   case CURLOPT_POSTFIELDSIZE_LARGE:
1159     /*
1160      * The size of the POSTFIELD data to prevent libcurl to do strlen() to
1161      * figure it out. Enables binary posts.
1162      */
1163     bigsize = va_arg(param, curl_off_t);
1164 
1165     if(data->set.postfieldsize < bigsize &&
1166        data->set.postfields == data->set.str[STRING_COPYPOSTFIELDS]) {
1167       /* Previous CURLOPT_COPYPOSTFIELDS is no longer valid. */
1168       (void) setstropt(&data->set.str[STRING_COPYPOSTFIELDS], NULL);
1169       data->set.postfields = NULL;
1170     }
1171 
1172     data->set.postfieldsize = bigsize;
1173     break;
1174 
1175   case CURLOPT_HTTPPOST:
1176     /*
1177      * Set to make us do HTTP POST
1178      */
1179     data->set.httppost = va_arg(param, struct curl_httppost *);
1180     data->set.httpreq = HTTPREQ_POST_FORM;
1181     data->set.opt_no_body = FALSE; /* this is implied */
1182     break;
1183 
1184   case CURLOPT_REFERER:
1185     /*
1186      * String to set in the HTTP Referer: field.
1187      */
1188     if(data->change.referer_alloc) {
1189       free(data->change.referer);
1190       data->change.referer_alloc = FALSE;
1191     }
1192     result = setstropt(&data->set.str[STRING_SET_REFERER],
1193                        va_arg(param, char *));
1194     data->change.referer = data->set.str[STRING_SET_REFERER];
1195     break;
1196 
1197   case CURLOPT_USERAGENT:
1198     /*
1199      * String to use in the HTTP User-Agent field
1200      */
1201     result = setstropt(&data->set.str[STRING_USERAGENT],
1202                        va_arg(param, char *));
1203     break;
1204 
1205   case CURLOPT_HTTPHEADER:
1206     /*
1207      * Set a list with HTTP headers to use (or replace internals with)
1208      */
1209     data->set.headers = va_arg(param, struct curl_slist *);
1210     break;
1211 
1212   case CURLOPT_HTTP200ALIASES:
1213     /*
1214      * Set a list of aliases for HTTP 200 in response header
1215      */
1216     data->set.http200aliases = va_arg(param, struct curl_slist *);
1217     break;
1218 
1219 #if !defined(CURL_DISABLE_COOKIES)
1220   case CURLOPT_COOKIE:
1221     /*
1222      * Cookie string to send to the remote server in the request.
1223      */
1224     result = setstropt(&data->set.str[STRING_COOKIE],
1225                        va_arg(param, char *));
1226     break;
1227 
1228   case CURLOPT_COOKIEFILE:
1229     /*
1230      * Set cookie file to read and parse. Can be used multiple times.
1231      */
1232     argptr = (char *)va_arg(param, void *);
1233     if(argptr) {
1234       struct curl_slist *cl;
1235       /* append the cookie file name to the list of file names, and deal with
1236          them later */
1237       cl = curl_slist_append(data->change.cookielist, argptr);
1238 
1239       if(!cl)
1240         return CURLE_OUT_OF_MEMORY;
1241 
1242       data->change.cookielist = cl; /* store the list for later use */
1243     }
1244     break;
1245 
1246   case CURLOPT_COOKIEJAR:
1247     /*
1248      * Set cookie file name to dump all cookies to when we're done.
1249      */
1250     result = setstropt(&data->set.str[STRING_COOKIEJAR],
1251                        va_arg(param, char *));
1252 
1253     /*
1254      * Activate the cookie parser. This may or may not already
1255      * have been made.
1256      */
1257     data->cookies = Curl_cookie_init(data, NULL, data->cookies,
1258                                      data->set.cookiesession);
1259     break;
1260 
1261   case CURLOPT_COOKIESESSION:
1262     /*
1263      * Set this option to TRUE to start a new "cookie session". It will
1264      * prevent the forthcoming read-cookies-from-file actions to accept
1265      * cookies that are marked as being session cookies, as they belong to a
1266      * previous session.
1267      *
1268      * In the original Netscape cookie spec, "session cookies" are cookies
1269      * with no expire date set. RFC2109 describes the same action if no
1270      * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds
1271      * a 'Discard' action that can enforce the discard even for cookies that
1272      * have a Max-Age.
1273      *
1274      * We run mostly with the original cookie spec, as hardly anyone implements
1275      * anything else.
1276      */
1277     data->set.cookiesession = (bool)(0 != va_arg(param, long));
1278     break;
1279 
1280   case CURLOPT_COOKIELIST:
1281     argptr = va_arg(param, char *);
1282 
1283     if(argptr == NULL)
1284       break;
1285 
1286     if(Curl_raw_equal(argptr, "ALL")) {
1287       /* clear all cookies */
1288       Curl_cookie_clearall(data->cookies);
1289       break;
1290     }
1291     else if(Curl_raw_equal(argptr, "SESS")) {
1292       /* clear session cookies */
1293       Curl_cookie_clearsess(data->cookies);
1294       break;
1295     }
1296     else if(Curl_raw_equal(argptr, "FLUSH")) {
1297       /* flush cookies to file */
1298       flush_cookies(data, 0);
1299       break;
1300     }
1301 
1302     if(!data->cookies)
1303       /* if cookie engine was not running, activate it */
1304       data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE);
1305 
1306     argptr = strdup(argptr);
1307     if(!argptr) {
1308       result = CURLE_OUT_OF_MEMORY;
1309       break;
1310     }
1311 
1312     if(checkprefix("Set-Cookie:", argptr))
1313       /* HTTP Header format line */
1314       Curl_cookie_add(data, data->cookies, TRUE, argptr + 11, NULL, NULL);
1315 
1316     else
1317       /* Netscape format line */
1318       Curl_cookie_add(data, data->cookies, FALSE, argptr, NULL, NULL);
1319 
1320     free(argptr);
1321     break;
1322 #endif /* CURL_DISABLE_COOKIES */
1323 
1324   case CURLOPT_HTTPGET:
1325     /*
1326      * Set to force us do HTTP GET
1327      */
1328     if(va_arg(param, long)) {
1329       data->set.httpreq = HTTPREQ_GET;
1330       data->set.upload = FALSE; /* switch off upload */
1331       data->set.opt_no_body = FALSE; /* this is implied */
1332     }
1333     break;
1334 
1335   case CURLOPT_HTTP_VERSION:
1336     /*
1337      * This sets a requested HTTP version to be used. The value is one of
1338      * the listed enums in curl/curl.h.
1339      */
1340     data->set.httpversion = va_arg(param, long);
1341     break;
1342 
1343   case CURLOPT_CUSTOMREQUEST:
1344     /*
1345      * Set a custom string to use as request
1346      */
1347     result = setstropt(&data->set.str[STRING_CUSTOMREQUEST],
1348                        va_arg(param, char *));
1349 
1350     /* we don't set
1351        data->set.httpreq = HTTPREQ_CUSTOM;
1352        here, we continue as if we were using the already set type
1353        and this just changes the actual request keyword */
1354     break;
1355 
1356   case CURLOPT_HTTPAUTH:
1357     /*
1358      * Set HTTP Authentication type BITMASK.
1359      */
1360   {
1361     long auth = va_arg(param, long);
1362 
1363     /* the DIGEST_IE bit is only used to set a special marker, for all the
1364        rest we need to handle it as normal DIGEST */
1365     data->state.authhost.iestyle = (bool)((auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE);
1366 
1367     if(auth & CURLAUTH_DIGEST_IE) {
1368       auth |= CURLAUTH_DIGEST; /* set standard digest bit */
1369       auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
1370     }
1371 
1372     /* switch off bits we can't support */
1373 #ifndef USE_NTLM
1374     auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
1375 #endif
1376 #ifndef HAVE_GSSAPI
1377     auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
1378 #endif
1379     if(!auth)
1380       return CURLE_FAILED_INIT; /* no supported types left! */
1381 
1382     data->set.httpauth = auth;
1383   }
1384   break;
1385 
1386 #ifndef CURL_DISABLE_PROXY
1387   case CURLOPT_HTTPPROXYTUNNEL:
1388     /*
1389      * Tunnel operations through the proxy instead of normal proxy use
1390      */
1391     data->set.tunnel_thru_httpproxy = (bool)(0 != va_arg(param, long));
1392     break;
1393 
1394   case CURLOPT_PROXYPORT:
1395     /*
1396      * Explicitly set HTTP proxy port number.
1397      */
1398     data->set.proxyport = va_arg(param, long);
1399     break;
1400 
1401   case CURLOPT_PROXYAUTH:
1402     /*
1403      * Set HTTP Authentication type BITMASK.
1404      */
1405   {
1406     long auth = va_arg(param, long);
1407 
1408     /* the DIGEST_IE bit is only used to set a special marker, for all the
1409        rest we need to handle it as normal DIGEST */
1410     data->state.authproxy.iestyle = (bool)((auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE);
1411 
1412     if(auth & CURLAUTH_DIGEST_IE) {
1413       auth |= CURLAUTH_DIGEST; /* set standard digest bit */
1414       auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */
1415     }
1416     /* switch off bits we can't support */
1417 #ifndef USE_NTLM
1418     auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
1419 #endif
1420 #ifndef HAVE_GSSAPI
1421     auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI */
1422 #endif
1423     if(!auth)
1424       return CURLE_FAILED_INIT; /* no supported types left! */
1425 
1426     data->set.proxyauth = auth;
1427   }
1428   break;
1429 #endif   /* CURL_DISABLE_HTTP */
1430 
1431   case CURLOPT_PROXY:
1432     /*
1433      * Set proxy server:port to use as HTTP proxy.
1434      *
1435      * If the proxy is set to "" we explicitly say that we don't want to use a
1436      * proxy (even though there might be environment variables saying so).
1437      *
1438      * Setting it to NULL, means no proxy but allows the environment variables
1439      * to decide for us.
1440      */
1441     result = setstropt(&data->set.str[STRING_PROXY],
1442                        va_arg(param, char *));
1443     break;
1444 
1445   case CURLOPT_PROXYTYPE:
1446     /*
1447      * Set proxy type. HTTP/HTTP_1_0/SOCKS4/SOCKS4a/SOCKS5/SOCKS5_HOSTNAME
1448      */
1449     data->set.proxytype = (curl_proxytype)va_arg(param, long);
1450     break;
1451 
1452   case CURLOPT_PROXY_TRANSFER_MODE:
1453     /*
1454      * set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy
1455      */
1456     switch (va_arg(param, long)) {
1457     case 0:
1458       data->set.proxy_transfer_mode = FALSE;
1459       break;
1460     case 1:
1461       data->set.proxy_transfer_mode = TRUE;
1462       break;
1463     default:
1464       /* reserve other values for future use */
1465       result = CURLE_FAILED_INIT;
1466       break;
1467     }
1468     break;
1469 #endif
1470 
1471 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
1472   case CURLOPT_SOCKS5_GSSAPI_SERVICE:
1473     /*
1474      * Set gssapi service name
1475      */
1476     result = setstropt(&data->set.str[STRING_SOCKS5_GSSAPI_SERVICE],
1477                        va_arg(param, char *));
1478     break;
1479 
1480   case CURLOPT_SOCKS5_GSSAPI_NEC:
1481     /*
1482      * set flag for nec socks5 support
1483      */
1484     data->set.socks5_gssapi_nec = (bool)(0 != va_arg(param, long));
1485     break;
1486 #endif
1487 
1488   case CURLOPT_WRITEHEADER:
1489     /*
1490      * Custom pointer to pass the header write callback function
1491      */
1492     data->set.writeheader = (void *)va_arg(param, void *);
1493     break;
1494   case CURLOPT_ERRORBUFFER:
1495     /*
1496      * Error buffer provided by the caller to get the human readable
1497      * error string in.
1498      */
1499     data->set.errorbuffer = va_arg(param, char *);
1500     break;
1501   case CURLOPT_FILE:
1502     /*
1503      * FILE pointer to write to or include in the data write callback
1504      */
1505     data->set.out = va_arg(param, FILE *);
1506     break;
1507   case CURLOPT_FTPPORT:
1508     /*
1509      * Use FTP PORT, this also specifies which IP address to use
1510      */
1511     result = setstropt(&data->set.str[STRING_FTPPORT],
1512                        va_arg(param, char *));
1513     data->set.ftp_use_port = (bool)(NULL != data->set.str[STRING_FTPPORT]);
1514     break;
1515 
1516   case CURLOPT_FTP_USE_EPRT:
1517     data->set.ftp_use_eprt = (bool)(0 != va_arg(param, long));
1518     break;
1519 
1520   case CURLOPT_FTP_USE_EPSV:
1521     data->set.ftp_use_epsv = (bool)(0 != va_arg(param, long));
1522     break;
1523 
1524   case CURLOPT_FTP_SSL_CCC:
1525     data->set.ftp_ccc = (curl_ftpccc)va_arg(param, long);
1526     break;
1527 
1528   case CURLOPT_FTP_SKIP_PASV_IP:
1529     /*
1530      * Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the
1531      * bypass of the IP address in PASV responses.
1532      */
1533     data->set.ftp_skip_ip = (bool)(0 != va_arg(param, long));
1534     break;
1535 
1536   case CURLOPT_INFILE:
1537     /*
1538      * FILE pointer to read the file to be uploaded from. Or possibly
1539      * used as argument to the read callback.
1540      */
1541     data->set.in = va_arg(param, FILE *);
1542     break;
1543   case CURLOPT_INFILESIZE:
1544     /*
1545      * If known, this should inform curl about the file size of the
1546      * to-be-uploaded file.
1547      */
1548     data->set.infilesize = va_arg(param, long);
1549     break;
1550   case CURLOPT_INFILESIZE_LARGE:
1551     /*
1552      * If known, this should inform curl about the file size of the
1553      * to-be-uploaded file.
1554      */
1555     data->set.infilesize = va_arg(param, curl_off_t);
1556     break;
1557   case CURLOPT_LOW_SPEED_LIMIT:
1558     /*
1559      * The low speed limit that if transfers are below this for
1560      * CURLOPT_LOW_SPEED_TIME, the transfer is aborted.
1561      */
1562     data->set.low_speed_limit=va_arg(param, long);
1563     break;
1564   case CURLOPT_MAX_SEND_SPEED_LARGE:
1565     /*
1566      * When transfer uploads are faster then CURLOPT_MAX_SEND_SPEED_LARGE
1567      * bytes per second the transfer is throttled..
1568      */
1569     data->set.max_send_speed=va_arg(param, curl_off_t);
1570     break;
1571   case CURLOPT_MAX_RECV_SPEED_LARGE:
1572     /*
1573      * When receiving data faster than CURLOPT_MAX_RECV_SPEED_LARGE bytes per
1574      * second the transfer is throttled..
1575      */
1576     data->set.max_recv_speed=va_arg(param, curl_off_t);
1577     break;
1578   case CURLOPT_LOW_SPEED_TIME:
1579     /*
1580      * The low speed time that if transfers are below the set
1581      * CURLOPT_LOW_SPEED_LIMIT during this time, the transfer is aborted.
1582      */
1583     data->set.low_speed_time=va_arg(param, long);
1584     break;
1585   case CURLOPT_URL:
1586     /*
1587      * The URL to fetch.
1588      */
1589     if(data->change.url_alloc) {
1590       /* the already set URL is allocated, free it first! */
1591       free(data->change.url);
1592       data->change.url_alloc=FALSE;
1593     }
1594     result = setstropt(&data->set.str[STRING_SET_URL],
1595                        va_arg(param, char *));
1596     data->change.url = data->set.str[STRING_SET_URL];
1597     break;
1598   case CURLOPT_PORT:
1599     /*
1600      * The port number to use when getting the URL
1601      */
1602     data->set.use_port = va_arg(param, long);
1603     break;
1604   case CURLOPT_TIMEOUT:
1605     /*
1606      * The maximum time you allow curl to use for a single transfer
1607      * operation.
1608      */
1609     data->set.timeout = va_arg(param, long) * 1000L;
1610     break;
1611 
1612   case CURLOPT_TIMEOUT_MS:
1613     data->set.timeout = va_arg(param, long);
1614     break;
1615 
1616   case CURLOPT_CONNECTTIMEOUT:
1617     /*
1618      * The maximum time you allow curl to use to connect.
1619      */
1620     data->set.connecttimeout = va_arg(param, long) * 1000L;
1621     break;
1622 
1623   case CURLOPT_CONNECTTIMEOUT_MS:
1624     data->set.connecttimeout = va_arg(param, long);
1625     break;
1626 
1627   case CURLOPT_USERPWD:
1628     /*
1629      * user:password to use in the operation
1630      */
1631     result = setstropt_userpwd(va_arg(param, char *),
1632                                &data->set.str[STRING_USERNAME],
1633                                &data->set.str[STRING_PASSWORD]);
1634     break;
1635   case CURLOPT_USERNAME:
1636     /*
1637      * authentication user name to use in the operation
1638      */
1639     result = setstropt(&data->set.str[STRING_USERNAME],
1640                        va_arg(param, char *));
1641     break;
1642   case CURLOPT_PASSWORD:
1643     /*
1644      * authentication password to use in the operation
1645      */
1646     result = setstropt(&data->set.str[STRING_PASSWORD],
1647                        va_arg(param, char *));
1648     break;
1649   case CURLOPT_POSTQUOTE:
1650     /*
1651      * List of RAW FTP commands to use after a transfer
1652      */
1653     data->set.postquote = va_arg(param, struct curl_slist *);
1654     break;
1655   case CURLOPT_PREQUOTE:
1656     /*
1657      * List of RAW FTP commands to use prior to RETR (Wesley Laxton)
1658      */
1659     data->set.prequote = va_arg(param, struct curl_slist *);
1660     break;
1661   case CURLOPT_QUOTE:
1662     /*
1663      * List of RAW FTP commands to use before a transfer
1664      */
1665     data->set.quote = va_arg(param, struct curl_slist *);
1666     break;
1667   case CURLOPT_PROGRESSFUNCTION:
1668     /*
1669      * Progress callback function
1670      */
1671     data->set.fprogress = va_arg(param, curl_progress_callback);
1672     if(data->set.fprogress)
1673       data->progress.callback = TRUE; /* no longer internal */
1674     else
1675       data->progress.callback = FALSE; /* NULL enforces internal */
1676 
1677     break;
1678   case CURLOPT_PROGRESSDATA:
1679     /*
1680      * Custom client data to pass to the progress callback
1681      */
1682     data->set.progress_client = va_arg(param, void *);
1683     break;
1684 
1685 #ifndef CURL_DISABLE_PROXY
1686   case CURLOPT_PROXYUSERPWD:
1687     /*
1688      * user:password needed to use the proxy
1689      */
1690     result = setstropt_userpwd(va_arg(param, char *),
1691                                &data->set.str[STRING_PROXYUSERNAME],
1692                                &data->set.str[STRING_PROXYPASSWORD]);
1693     break;
1694   case CURLOPT_PROXYUSERNAME:
1695     /*
1696      * authentication user name to use in the operation
1697      */
1698     result = setstropt(&data->set.str[STRING_PROXYUSERNAME],
1699                        va_arg(param, char *));
1700     break;
1701   case CURLOPT_PROXYPASSWORD:
1702     /*
1703      * authentication password to use in the operation
1704      */
1705     result = setstropt(&data->set.str[STRING_PROXYPASSWORD],
1706                        va_arg(param, char *));
1707     break;
1708   case CURLOPT_NOPROXY:
1709     /*
1710      * proxy exception list
1711      */
1712     result = setstropt(&data->set.str[STRING_NOPROXY],
1713                        va_arg(param, char *));
1714     break;
1715 #endif
1716 
1717   case CURLOPT_RANGE:
1718     /*
1719      * What range of the file you want to transfer
1720      */
1721     result = setstropt(&data->set.str[STRING_SET_RANGE],
1722                        va_arg(param, char *));
1723     break;
1724   case CURLOPT_RESUME_FROM:
1725     /*
1726      * Resume transfer at the give file position
1727      */
1728     data->set.set_resume_from = va_arg(param, long);
1729     break;
1730   case CURLOPT_RESUME_FROM_LARGE:
1731     /*
1732      * Resume transfer at the give file position
1733      */
1734     data->set.set_resume_from = va_arg(param, curl_off_t);
1735     break;
1736   case CURLOPT_DEBUGFUNCTION:
1737     /*
1738      * stderr write callback.
1739      */
1740     data->set.fdebug = va_arg(param, curl_debug_callback);
1741     /*
1742      * if the callback provided is NULL, it'll use the default callback
1743      */
1744     break;
1745   case CURLOPT_DEBUGDATA:
1746     /*
1747      * Set to a void * that should receive all error writes. This
1748      * defaults to CURLOPT_STDERR for normal operations.
1749      */
1750     data->set.debugdata = va_arg(param, void *);
1751     break;
1752   case CURLOPT_STDERR:
1753     /*
1754      * Set to a FILE * that should receive all error writes. This
1755      * defaults to stderr for normal operations.
1756      */
1757     data->set.err = va_arg(param, FILE *);
1758     if(!data->set.err)
1759       data->set.err = stderr;
1760     break;
1761   case CURLOPT_HEADERFUNCTION:
1762     /*
1763      * Set header write callback
1764      */
1765     data->set.fwrite_header = va_arg(param, curl_write_callback);
1766     break;
1767   case CURLOPT_WRITEFUNCTION:
1768     /*
1769      * Set data write callback
1770      */
1771     data->set.fwrite_func = va_arg(param, curl_write_callback);
1772     if(!data->set.fwrite_func)
1773       /* When set to NULL, reset to our internal default function */
1774       data->set.fwrite_func = (curl_write_callback)fwrite;
1775     break;
1776   case CURLOPT_READFUNCTION:
1777     /*
1778      * Read data callback
1779      */
1780     data->set.fread_func = va_arg(param, curl_read_callback);
1781     if(!data->set.fread_func)
1782       /* When set to NULL, reset to our internal default function */
1783       data->set.fread_func = (curl_read_callback)fread;
1784     break;
1785   case CURLOPT_SEEKFUNCTION:
1786     /*
1787      * Seek callback. Might be NULL.
1788      */
1789     data->set.seek_func = va_arg(param, curl_seek_callback);
1790     break;
1791   case CURLOPT_SEEKDATA:
1792     /*
1793      * Seek control callback. Might be NULL.
1794      */
1795     data->set.seek_client = va_arg(param, void *);
1796     break;
1797   case CURLOPT_CONV_FROM_NETWORK_FUNCTION:
1798     /*
1799      * "Convert from network encoding" callback
1800      */
1801     data->set.convfromnetwork = va_arg(param, curl_conv_callback);
1802     break;
1803   case CURLOPT_CONV_TO_NETWORK_FUNCTION:
1804     /*
1805      * "Convert to network encoding" callback
1806      */
1807     data->set.convtonetwork = va_arg(param, curl_conv_callback);
1808     break;
1809   case CURLOPT_CONV_FROM_UTF8_FUNCTION:
1810     /*
1811      * "Convert from UTF-8 encoding" callback
1812      */
1813     data->set.convfromutf8 = va_arg(param, curl_conv_callback);
1814     break;
1815   case CURLOPT_IOCTLFUNCTION:
1816     /*
1817      * I/O control callback. Might be NULL.
1818      */
1819     data->set.ioctl_func = va_arg(param, curl_ioctl_callback);
1820     break;
1821   case CURLOPT_IOCTLDATA:
1822     /*
1823      * I/O control data pointer. Might be NULL.
1824      */
1825     data->set.ioctl_client = va_arg(param, void *);
1826     break;
1827   case CURLOPT_SSLCERT:
1828     /*
1829      * String that holds file name of the SSL certificate to use
1830      */
1831     result = setstropt(&data->set.str[STRING_CERT],
1832                        va_arg(param, char *));
1833     break;
1834   case CURLOPT_SSLCERTTYPE:
1835     /*
1836      * String that holds file type of the SSL certificate to use
1837      */
1838     result = setstropt(&data->set.str[STRING_CERT_TYPE],
1839                        va_arg(param, char *));
1840     break;
1841   case CURLOPT_SSLKEY:
1842     /*
1843      * String that holds file name of the SSL certificate to use
1844      */
1845     result = setstropt(&data->set.str[STRING_KEY],
1846                        va_arg(param, char *));
1847     break;
1848   case CURLOPT_SSLKEYTYPE:
1849     /*
1850      * String that holds file type of the SSL certificate to use
1851      */
1852     result = setstropt(&data->set.str[STRING_KEY_TYPE],
1853                        va_arg(param, char *));
1854     break;
1855   case CURLOPT_KEYPASSWD:
1856     /*
1857      * String that holds the SSL or SSH private key password.
1858      */
1859     result = setstropt(&data->set.str[STRING_KEY_PASSWD],
1860                        va_arg(param, char *));
1861     break;
1862   case CURLOPT_SSLENGINE:
1863     /*
1864      * String that holds the SSL crypto engine.
1865      */
1866     argptr = va_arg(param, char *);
1867     if(argptr && argptr[0])
1868       result = Curl_ssl_set_engine(data, argptr);
1869     break;
1870 
1871   case CURLOPT_SSLENGINE_DEFAULT:
1872     /*
1873      * flag to set engine as default.
1874      */
1875     result = Curl_ssl_set_engine_default(data);
1876     break;
1877   case CURLOPT_CRLF:
1878     /*
1879      * Kludgy option to enable CRLF conversions. Subject for removal.
1880      */
1881     data->set.crlf = (bool)(0 != va_arg(param, long));
1882     break;
1883 
1884   case CURLOPT_INTERFACE:
1885     /*
1886      * Set what interface or address/hostname to bind the socket to when
1887      * performing an operation and thus what from-IP your connection will use.
1888      */
1889     result = setstropt(&data->set.str[STRING_DEVICE],
1890                        va_arg(param, char *));
1891     break;
1892   case CURLOPT_LOCALPORT:
1893     /*
1894      * Set what local port to bind the socket to when performing an operation.
1895      */
1896     data->set.localport = (unsigned short) va_arg(param, long);
1897     break;
1898   case CURLOPT_LOCALPORTRANGE:
1899     /*
1900      * Set number of local ports to try, starting with CURLOPT_LOCALPORT.
1901      */
1902     data->set.localportrange = (int) va_arg(param, long);
1903     break;
1904   case CURLOPT_KRBLEVEL:
1905     /*
1906      * A string that defines the kerberos security level.
1907      */
1908     result = setstropt(&data->set.str[STRING_KRB_LEVEL],
1909                        va_arg(param, char *));
1910     data->set.krb = (bool)(NULL != data->set.str[STRING_KRB_LEVEL]);
1911     break;
1912   case CURLOPT_SSL_VERIFYPEER:
1913     /*
1914      * Enable peer SSL verifying.
1915      */
1916     data->set.ssl.verifypeer = va_arg(param, long);
1917     break;
1918   case CURLOPT_SSL_VERIFYHOST:
1919     /*
1920      * Enable verification of the CN contained in the peer certificate
1921      */
1922     data->set.ssl.verifyhost = va_arg(param, long);
1923     break;
1924 #ifdef USE_SSLEAY
1925     /* since these two options are only possible to use on an OpenSSL-
1926        powered libcurl we #ifdef them on this condition so that libcurls
1927        built against other SSL libs will return a proper error when trying
1928        to set this option! */
1929   case CURLOPT_SSL_CTX_FUNCTION:
1930     /*
1931      * Set a SSL_CTX callback
1932      */
1933     data->set.ssl.fsslctx = va_arg(param, curl_ssl_ctx_callback);
1934     break;
1935   case CURLOPT_SSL_CTX_DATA:
1936     /*
1937      * Set a SSL_CTX callback parameter pointer
1938      */
1939     data->set.ssl.fsslctxp = va_arg(param, void *);
1940     break;
1941   case CURLOPT_CERTINFO:
1942     data->set.ssl.certinfo = (bool)(0 != va_arg(param, long));
1943     break;
1944 #endif
1945   case CURLOPT_CAINFO:
1946     /*
1947      * Set CA info for SSL connection. Specify file name of the CA certificate
1948      */
1949     result = setstropt(&data->set.str[STRING_SSL_CAFILE],
1950                        va_arg(param, char *));
1951     break;
1952   case CURLOPT_CAPATH:
1953     /*
1954      * Set CA path info for SSL connection. Specify directory name of the CA
1955      * certificates which have been prepared using openssl c_rehash utility.
1956      */
1957     /* This does not work on windows. */
1958     result = setstropt(&data->set.str[STRING_SSL_CAPATH],
1959                        va_arg(param, char *));
1960     break;
1961   case CURLOPT_CRLFILE:
1962     /*
1963      * Set CRL file info for SSL connection. Specify file name of the CRL
1964      * to check certificates revocation
1965      */
1966     result = setstropt(&data->set.str[STRING_SSL_CRLFILE],
1967                        va_arg(param, char *));
1968     break;
1969   case CURLOPT_ISSUERCERT:
1970     /*
1971      * Set Issuer certificate file
1972      * to check certificates issuer
1973      */
1974     result = setstropt(&data->set.str[STRING_SSL_ISSUERCERT],
1975                        va_arg(param, char *));
1976     break;
1977   case CURLOPT_TELNETOPTIONS:
1978     /*
1979      * Set a linked list of telnet options
1980      */
1981     data->set.telnet_options = va_arg(param, struct curl_slist *);
1982     break;
1983 
1984   case CURLOPT_BUFFERSIZE:
1985     /*
1986      * The application kindly asks for a differently sized receive buffer.
1987      * If it seems reasonable, we'll use it.
1988      */
1989     data->set.buffer_size = va_arg(param, long);
1990 
1991     if((data->set.buffer_size> (BUFSIZE -1 )) ||
1992        (data->set.buffer_size < 1))
1993       data->set.buffer_size = 0; /* huge internal default */
1994 
1995     break;
1996 
1997   case CURLOPT_NOSIGNAL:
1998     /*
1999      * The application asks not to set any signal() or alarm() handlers,
2000      * even when using a timeout.
2001      */
2002     data->set.no_signal = (bool)(0 != va_arg(param, long));
2003     break;
2004 
2005   case CURLOPT_SHARE:
2006   {
2007     struct Curl_share *set;
2008     set = va_arg(param, struct Curl_share *);
2009 
2010     /* disconnect from old share, if any */
2011     if(data->share) {
2012       Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
2013 
2014       if(data->dns.hostcachetype == HCACHE_SHARED) {
2015         data->dns.hostcache = NULL;
2016         data->dns.hostcachetype = HCACHE_NONE;
2017       }
2018 
2019       if(data->share->cookies == data->cookies)
2020         data->cookies = NULL;
2021 
2022       data->share->dirty--;
2023 
2024       Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
2025       data->share = NULL;
2026     }
2027 
2028     /* use new share if it set */
2029     data->share = set;
2030     if(data->share) {
2031 
2032       Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE);
2033 
2034       data->share->dirty++;
2035 
2036       if(data->share->hostcache) {
2037         /* use shared host cache, first free the private one if any */
2038         if(data->dns.hostcachetype == HCACHE_PRIVATE)
2039           Curl_hash_destroy(data->dns.hostcache);
2040 
2041         data->dns.hostcache = data->share->hostcache;
2042         data->dns.hostcachetype = HCACHE_SHARED;
2043       }
2044 #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
2045       if(data->share->cookies) {
2046         /* use shared cookie list, first free own one if any */
2047         if(data->cookies)
2048           Curl_cookie_cleanup(data->cookies);
2049         /* enable cookies since we now use a share that uses cookies! */
2050         data->cookies = data->share->cookies;
2051       }
2052 #endif   /* CURL_DISABLE_HTTP */
2053       Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
2054 
2055     }
2056     /* check for host cache not needed,
2057      * it will be done by curl_easy_perform */
2058   }
2059   break;
2060 
2061   case CURLOPT_PRIVATE:
2062     /*
2063      * Set private data pointer.
2064      */
2065     data->set.private_data = va_arg(param, void *);
2066     break;
2067 
2068   case CURLOPT_MAXFILESIZE:
2069     /*
2070      * Set the maximum size of a file to download.
2071      */
2072     data->set.max_filesize = va_arg(param, long);
2073     break;
2074 
2075   case CURLOPT_USE_SSL:
2076     /*
2077      * Make transfers attempt to use SSL/TLS.
2078      */
2079     data->set.ftp_ssl = (curl_usessl)va_arg(param, long);
2080     break;
2081 
2082   case CURLOPT_FTPSSLAUTH:
2083     /*
2084      * Set a specific auth for FTP-SSL transfers.
2085      */
2086     data->set.ftpsslauth = (curl_ftpauth)va_arg(param, long);
2087     break;
2088 
2089   case CURLOPT_IPRESOLVE:
2090     data->set.ip_version = va_arg(param, long);
2091     break;
2092 
2093   case CURLOPT_MAXFILESIZE_LARGE:
2094     /*
2095      * Set the maximum size of a file to download.
2096      */
2097     data->set.max_filesize = va_arg(param, curl_off_t);
2098     break;
2099 
2100   case CURLOPT_TCP_NODELAY:
2101     /*
2102      * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
2103      * algorithm
2104      */
2105     data->set.tcp_nodelay = (bool)(0 != va_arg(param, long));
2106     break;
2107 
2108   case CURLOPT_FTP_ACCOUNT:
2109     result = setstropt(&data->set.str[STRING_FTP_ACCOUNT],
2110                        va_arg(param, char *));
2111     break;
2112 
2113   case CURLOPT_IGNORE_CONTENT_LENGTH:
2114     data->set.ignorecl = (bool)(0 != va_arg(param, long));
2115     break;
2116 
2117   case CURLOPT_CONNECT_ONLY:
2118     /*
2119      * No data transfer, set up connection and let application use the socket
2120      */
2121     data->set.connect_only = (bool)(0 != va_arg(param, long));
2122     break;
2123 
2124   case CURLOPT_FTP_ALTERNATIVE_TO_USER:
2125     result = setstropt(&data->set.str[STRING_FTP_ALTERNATIVE_TO_USER],
2126                        va_arg(param, char *));
2127     break;
2128 
2129   case CURLOPT_SOCKOPTFUNCTION:
2130     /*
2131      * socket callback function: called after socket() but before connect()
2132      */
2133     data->set.fsockopt = va_arg(param, curl_sockopt_callback);
2134     break;
2135 
2136   case CURLOPT_SOCKOPTDATA:
2137     /*
2138      * socket callback data pointer. Might be NULL.
2139      */
2140     data->set.sockopt_client = va_arg(param, void *);
2141     break;
2142 
2143   case CURLOPT_OPENSOCKETFUNCTION:
2144     /*
2145      * open/create socket callback function: called instead of socket(),
2146      * before connect()
2147      */
2148     data->set.fopensocket = va_arg(param, curl_opensocket_callback);
2149     break;
2150 
2151   case CURLOPT_OPENSOCKETDATA:
2152     /*
2153      * socket callback data pointer. Might be NULL.
2154      */
2155     data->set.opensocket_client = va_arg(param, void *);
2156     break;
2157 
2158   case CURLOPT_SSL_SESSIONID_CACHE:
2159     data->set.ssl.sessionid = (bool)(0 != va_arg(param, long));
2160     break;
2161 
2162   case CURLOPT_SSH_AUTH_TYPES:
2163     data->set.ssh_auth_types = va_arg(param, long);
2164     break;
2165 
2166   case CURLOPT_SSH_PUBLIC_KEYFILE:
2167     /*
2168      * Use this file instead of the $HOME/.ssh/id_dsa.pub file
2169      */
2170     result = setstropt(&data->set.str[STRING_SSH_PUBLIC_KEY],
2171                        va_arg(param, char *));
2172     break;
2173 
2174   case CURLOPT_SSH_PRIVATE_KEYFILE:
2175     /*
2176      * Use this file instead of the $HOME/.ssh/id_dsa file
2177      */
2178     result = setstropt(&data->set.str[STRING_SSH_PRIVATE_KEY],
2179                        va_arg(param, char *));
2180     break;
2181   case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
2182     /*
2183      * Option to allow for the MD5 of the host public key to be checked
2184      * for validation purposes.
2185      */
2186     result = setstropt(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5],
2187                        va_arg(param, char *));
2188     break;
2189   case CURLOPT_HTTP_TRANSFER_DECODING:
2190     /*
2191      * disable libcurl transfer encoding is used
2192      */
2193     data->set.http_te_skip = (bool)(0 == va_arg(param, long));
2194     break;
2195 
2196   case CURLOPT_HTTP_CONTENT_DECODING:
2197     /*
2198      * raw data passed to the application when content encoding is used
2199      */
2200     data->set.http_ce_skip = (bool)(0 == va_arg(param, long));
2201     break;
2202 
2203   case CURLOPT_NEW_FILE_PERMS:
2204     /*
2205      * Uses these permissions instead of 0644
2206      */
2207     data->set.new_file_perms = va_arg(param, long);
2208     break;
2209 
2210   case CURLOPT_NEW_DIRECTORY_PERMS:
2211     /*
2212      * Uses these permissions instead of 0755
2213      */
2214     data->set.new_directory_perms = va_arg(param, long);
2215     break;
2216 
2217   case CURLOPT_ADDRESS_SCOPE:
2218     /*
2219      * We always get longs when passed plain numericals, but for this value we
2220      * know that an unsigned int will always hold the value so we blindly
2221      * typecast to this type
2222      */
2223     data->set.scope = (unsigned int) va_arg(param, long);
2224     break;
2225 
2226   case CURLOPT_PROTOCOLS:
2227     /* set the bitmask for the protocols that are allowed to be used for the
2228        transfer, which thus helps the app which takes URLs from users or other
2229        external inputs and want to restrict what protocol(s) to deal
2230        with. Defaults to CURLPROTO_ALL. */
2231     data->set.allowed_protocols = va_arg(param, long) & PROT_EXTMASK;
2232     break;
2233 
2234   case CURLOPT_REDIR_PROTOCOLS:
2235     /* set the bitmask for the protocols that libcurl is allowed to follow to,
2236        as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
2237        to be set in both bitmasks to be allowed to get redirected to. Defaults
2238        to all protocols except FILE and SCP. */
2239     data->set.redir_protocols = va_arg(param, long) & PROT_EXTMASK;
2240     break;
2241 
2242   default:
2243     /* unknown tag and its companion, just ignore: */
2244     result = CURLE_FAILED_INIT; /* correct this */
2245     break;
2246   }
2247 
2248   return result;
2249 }
2250 
conn_free(struct connectdata * conn)2251 static void conn_free(struct connectdata *conn)
2252 {
2253   if(!conn)
2254     return;
2255 
2256   /* close possibly still open sockets */
2257   if(CURL_SOCKET_BAD != conn->sock[SECONDARYSOCKET])
2258     sclose(conn->sock[SECONDARYSOCKET]);
2259   if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
2260     sclose(conn->sock[FIRSTSOCKET]);
2261 
2262   Curl_safefree(conn->user);
2263   Curl_safefree(conn->passwd);
2264   Curl_safefree(conn->proxyuser);
2265   Curl_safefree(conn->proxypasswd);
2266   Curl_safefree(conn->allocptr.proxyuserpwd);
2267   Curl_safefree(conn->allocptr.uagent);
2268   Curl_safefree(conn->allocptr.userpwd);
2269   Curl_safefree(conn->allocptr.accept_encoding);
2270   Curl_safefree(conn->allocptr.rangeline);
2271   Curl_safefree(conn->allocptr.ref);
2272   Curl_safefree(conn->allocptr.host);
2273   Curl_safefree(conn->allocptr.cookiehost);
2274   Curl_safefree(conn->trailer);
2275   Curl_safefree(conn->host.rawalloc); /* host name buffer */
2276   Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */
2277   Curl_safefree(conn->master_buffer);
2278 
2279   Curl_llist_destroy(conn->send_pipe, NULL);
2280   Curl_llist_destroy(conn->recv_pipe, NULL);
2281   Curl_llist_destroy(conn->pend_pipe, NULL);
2282 
2283   /* possible left-overs from the async name resolvers */
2284 #if defined(USE_ARES)
2285   Curl_safefree(conn->async.hostname);
2286   Curl_safefree(conn->async.os_specific);
2287 #elif defined(CURLRES_THREADED)
2288   Curl_destroy_thread_data(&conn->async);
2289 #endif
2290 
2291   Curl_ssl_close(conn, FIRSTSOCKET);
2292   Curl_ssl_close(conn, SECONDARYSOCKET);
2293 
2294   Curl_free_ssl_config(&conn->ssl_config);
2295 
2296   free(conn); /* free all the connection oriented data */
2297 }
2298 
Curl_disconnect(struct connectdata * conn)2299 CURLcode Curl_disconnect(struct connectdata *conn)
2300 {
2301   struct SessionHandle *data;
2302   if(!conn)
2303     return CURLE_OK; /* this is closed and fine already */
2304   data = conn->data;
2305 
2306   if(!data) {
2307     DEBUGF(infof(data, "DISCONNECT without easy handle, ignoring\n"));
2308     return CURLE_OK;
2309   }
2310 
2311 #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST)
2312   /* scan for DNS cache entries still marked as in use */
2313   Curl_hash_apply(data->hostcache,
2314                   NULL, Curl_scan_cache_used);
2315 #endif
2316 
2317   Curl_expire(data, 0); /* shut off timers */
2318   Curl_hostcache_prune(data); /* kill old DNS cache entries */
2319 
2320   {
2321     int has_host_ntlm = (conn->ntlm.state != NTLMSTATE_NONE);
2322     int has_proxy_ntlm = (conn->proxyntlm.state != NTLMSTATE_NONE);
2323 
2324     /* Authentication data is a mix of connection-related and sessionhandle-
2325        related stuff. NTLM is connection-related so when we close the shop
2326        we shall forget. */
2327 
2328     if (has_host_ntlm) {
2329       data->state.authhost.done = FALSE;
2330       data->state.authhost.picked =
2331         data->state.authhost.want;
2332     }
2333 
2334     if (has_proxy_ntlm) {
2335       data->state.authproxy.done = FALSE;
2336       data->state.authproxy.picked =
2337         data->state.authproxy.want;
2338     }
2339 
2340     if (has_host_ntlm || has_proxy_ntlm) {
2341       data->state.authproblem = FALSE;
2342 
2343       Curl_ntlm_cleanup(conn);
2344     }
2345   }
2346 
2347   /* Cleanup possible redirect junk */
2348   if(data->req.newurl) {
2349     free(data->req.newurl);
2350     data->req.newurl = NULL;
2351   }
2352 
2353   if(conn->handler->disconnect)
2354     /* This is set if protocol-specific cleanups should be made */
2355     conn->handler->disconnect(conn);
2356 
2357   if(-1 != conn->connectindex) {
2358     /* unlink ourselves! */
2359     infof(data, "Closing connection #%ld\n", conn->connectindex);
2360     if(data->state.connc)
2361       /* only clear the table entry if we still know in which cache we
2362          used to be in */
2363       data->state.connc->connects[conn->connectindex] = NULL;
2364   }
2365 
2366 #ifdef USE_LIBIDN
2367   if(conn->host.encalloc)
2368     idn_free(conn->host.encalloc); /* encoded host name buffer, must be freed
2369                                       with idn_free() since this was allocated
2370                                       by libidn */
2371   if(conn->proxy.encalloc)
2372     idn_free(conn->proxy.encalloc); /* encoded proxy name buffer, must be
2373                                        freed with idn_free() since this was
2374                                        allocated by libidn */
2375 #endif
2376 
2377   Curl_ssl_close(conn, FIRSTSOCKET);
2378 
2379   /* Indicate to all handles on the pipe that we're dead */
2380   if(Curl_isPipeliningEnabled(data)) {
2381     signalPipeClose(conn->send_pipe);
2382     signalPipeClose(conn->recv_pipe);
2383     signalPipeClose(conn->pend_pipe);
2384   }
2385 
2386   conn_free(conn);
2387   data->state.current_conn = NULL;
2388 
2389   return CURLE_OK;
2390 }
2391 
2392 /*
2393  * This function should return TRUE if the socket is to be assumed to
2394  * be dead. Most commonly this happens when the server has closed the
2395  * connection due to inactivity.
2396  */
SocketIsDead(curl_socket_t sock)2397 static bool SocketIsDead(curl_socket_t sock)
2398 {
2399   int sval;
2400   bool ret_val = TRUE;
2401 
2402   sval = Curl_socket_ready(sock, CURL_SOCKET_BAD, 0);
2403   if(sval == 0)
2404     /* timeout */
2405     ret_val = FALSE;
2406 
2407   return ret_val;
2408 }
2409 
IsPipeliningPossible(const struct SessionHandle * handle)2410 static bool IsPipeliningPossible(const struct SessionHandle *handle)
2411 {
2412   if(handle->multi && Curl_multi_canPipeline(handle->multi) &&
2413       (handle->set.httpreq == HTTPREQ_GET ||
2414        handle->set.httpreq == HTTPREQ_HEAD) &&
2415       handle->set.httpversion != CURL_HTTP_VERSION_1_0)
2416     return TRUE;
2417 
2418   return FALSE;
2419 }
2420 
Curl_isPipeliningEnabled(const struct SessionHandle * handle)2421 bool Curl_isPipeliningEnabled(const struct SessionHandle *handle)
2422 {
2423   if(handle->multi && Curl_multi_canPipeline(handle->multi))
2424     return TRUE;
2425 
2426   return FALSE;
2427 }
2428 
Curl_addHandleToPipeline(struct SessionHandle * data,struct curl_llist * pipeline)2429 CURLcode Curl_addHandleToPipeline(struct SessionHandle *data,
2430                                   struct curl_llist *pipeline)
2431 {
2432 #ifdef CURLDEBUG
2433   if(!IsPipeliningPossible(data)) {
2434     /* when not pipelined, there MUST be no handle in the list already */
2435     if(pipeline->head)
2436       infof(data, "PIPE when no PIPE supposed!\n");
2437   }
2438 #endif
2439   if(!Curl_llist_insert_next(pipeline, pipeline->tail, data))
2440     return CURLE_OUT_OF_MEMORY;
2441   return CURLE_OK;
2442 }
2443 
Curl_removeHandleFromPipeline(struct SessionHandle * handle,struct curl_llist * pipeline)2444 int Curl_removeHandleFromPipeline(struct SessionHandle *handle,
2445                                   struct curl_llist *pipeline)
2446 {
2447   struct curl_llist_element *curr;
2448 
2449   curr = pipeline->head;
2450   while(curr) {
2451     if(curr->ptr == handle) {
2452       Curl_llist_remove(pipeline, curr, NULL);
2453       return 1; /* we removed a handle */
2454     }
2455     curr = curr->next;
2456   }
2457 
2458   return 0;
2459 }
2460 
2461 #if 0 /* this code is saved here as it is useful for debugging purposes */
2462 static void Curl_printPipeline(struct curl_llist *pipeline)
2463 {
2464   struct curl_llist_element *curr;
2465 
2466   curr = pipeline->head;
2467   while(curr) {
2468     struct SessionHandle *data = (struct SessionHandle *) curr->ptr;
2469     infof(data, "Handle in pipeline: %s\n", data->state.path);
2470     curr = curr->next;
2471   }
2472 }
2473 #endif
2474 
gethandleathead(struct curl_llist * pipeline)2475 static struct SessionHandle* gethandleathead(struct curl_llist *pipeline)
2476 {
2477   struct curl_llist_element *curr = pipeline->head;
2478   if(curr) {
2479     return (struct SessionHandle *) curr->ptr;
2480   }
2481 
2482   return NULL;
2483 }
2484 
2485 /* remove the specified connection from all (possible) pipelines and related
2486    queues */
Curl_getoff_all_pipelines(struct SessionHandle * data,struct connectdata * conn)2487 void Curl_getoff_all_pipelines(struct SessionHandle *data,
2488                                struct connectdata *conn)
2489 {
2490   bool recv_head = (bool)(conn->readchannel_inuse &&
2491     (gethandleathead(conn->recv_pipe) == data));
2492 
2493   bool send_head = (bool)(conn->writechannel_inuse &&
2494     (gethandleathead(conn->send_pipe) == data));
2495 
2496   if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && recv_head)
2497     conn->readchannel_inuse = FALSE;
2498   if(Curl_removeHandleFromPipeline(data, conn->send_pipe) && send_head)
2499     conn->writechannel_inuse = FALSE;
2500   Curl_removeHandleFromPipeline(data, conn->pend_pipe);
2501 }
2502 
signalPipeClose(struct curl_llist * pipeline)2503 static void signalPipeClose(struct curl_llist *pipeline)
2504 {
2505   struct curl_llist_element *curr;
2506 
2507   if(!pipeline)
2508     return;
2509 
2510   curr = pipeline->head;
2511   while(curr) {
2512     struct curl_llist_element *next = curr->next;
2513     struct SessionHandle *data = (struct SessionHandle *) curr->ptr;
2514 
2515 #ifdef CURLDEBUG /* debug-only code */
2516     if(data->magic != CURLEASY_MAGIC_NUMBER) {
2517       /* MAJOR BADNESS */
2518       infof(data, "signalPipeClose() found BAAD easy handle\n");
2519     }
2520 #endif
2521 
2522     data->state.pipe_broke = TRUE;
2523     Curl_multi_handlePipeBreak(data);
2524     Curl_llist_remove(pipeline, curr, NULL);
2525     curr = next;
2526   }
2527 }
2528 
2529 
2530 /*
2531  * Given one filled in connection struct (named needle), this function should
2532  * detect if there already is one that has all the significant details
2533  * exactly the same and thus should be used instead.
2534  *
2535  * If there is a match, this function returns TRUE - and has marked the
2536  * connection as 'in-use'. It must later be called with ConnectionDone() to
2537  * return back to 'idle' (unused) state.
2538  */
2539 static bool
ConnectionExists(struct SessionHandle * data,struct connectdata * needle,struct connectdata ** usethis)2540 ConnectionExists(struct SessionHandle *data,
2541                  struct connectdata *needle,
2542                  struct connectdata **usethis)
2543 {
2544   long i;
2545   struct connectdata *check;
2546   bool canPipeline = IsPipeliningPossible(data);
2547 
2548   for(i=0; i< data->state.connc->num; i++) {
2549     bool match = FALSE;
2550     size_t pipeLen = 0;
2551     /*
2552      * Note that if we use a HTTP proxy, we check connections to that
2553      * proxy and not to the actual remote server.
2554      */
2555     check = data->state.connc->connects[i];
2556     if(!check)
2557       /* NULL pointer means not filled-in entry */
2558       continue;
2559 
2560     pipeLen = check->send_pipe->size + check->recv_pipe->size;
2561 
2562     if(check->connectindex == -1) {
2563       check->connectindex = i; /* Set this appropriately since it might have
2564                                   been set to -1 when the easy was removed
2565                                   from the multi */
2566     }
2567 
2568     if(canPipeline) {
2569       /* Make sure the pipe has only GET requests */
2570       struct SessionHandle* sh = gethandleathead(check->send_pipe);
2571       struct SessionHandle* rh = gethandleathead(check->recv_pipe);
2572       if(sh) {
2573         if(!IsPipeliningPossible(sh))
2574           continue;
2575       }
2576       else if(rh) {
2577         if(!IsPipeliningPossible(rh))
2578           continue;
2579       }
2580 
2581 #ifdef CURLDEBUG
2582       if(pipeLen > MAX_PIPELINE_LENGTH) {
2583         infof(data, "BAD! Connection #%ld has too big pipeline!\n",
2584               check->connectindex);
2585       }
2586 #endif
2587     }
2588     else {
2589       if(pipeLen > 0) {
2590         /* can only happen within multi handles, and means that another easy
2591            handle is using this connection */
2592         continue;
2593       }
2594 
2595 #ifdef CURLRES_ASYNCH
2596       /* ip_addr_str[0] is NUL only if the resolving of the name hasn't
2597          completed yet and until then we don't re-use this connection */
2598       if(!check->ip_addr_str[0]) {
2599         infof(data,
2600               "Connection #%ld hasn't finished name resolve, can't reuse\n",
2601               check->connectindex);
2602         continue;
2603       }
2604 #endif
2605 
2606       if((check->sock[FIRSTSOCKET] == CURL_SOCKET_BAD) || check->bits.close) {
2607         /* Don't pick a connection that hasn't connected yet or that is going to
2608            get closed. */
2609         infof(data, "Connection #%ld isn't open enough, can't reuse\n",
2610               check->connectindex);
2611 #ifdef CURLDEBUG
2612         if(check->recv_pipe->size > 0) {
2613           infof(data, "BAD! Unconnected #%ld has a non-empty recv pipeline!\n",
2614                 check->connectindex);
2615         }
2616 #endif
2617         continue;
2618       }
2619     }
2620 
2621     if((needle->protocol&PROT_SSL) != (check->protocol&PROT_SSL))
2622       /* don't do mixed SSL and non-SSL connections */
2623       continue;
2624 
2625     if(needle->bits.proxy != check->bits.proxy)
2626       /* don't do mixed proxy and non-proxy connections */
2627       continue;
2628 
2629     if(!canPipeline && check->inuse)
2630       /* this request can't be pipelined but the checked connection is already
2631          in use so we skip it */
2632       continue;
2633 
2634     if(!needle->bits.httpproxy || needle->protocol&PROT_SSL ||
2635        (needle->bits.httpproxy && check->bits.httpproxy &&
2636         needle->bits.tunnel_proxy && check->bits.tunnel_proxy &&
2637         Curl_raw_equal(needle->proxy.name, check->proxy.name) &&
2638         (needle->port == check->port))) {
2639       /* The requested connection does not use a HTTP proxy or it uses SSL or
2640          it is a non-SSL protocol tunneled over the same http proxy name and
2641          port number */
2642 
2643       if(Curl_raw_equal(needle->protostr, check->protostr) &&
2644          Curl_raw_equal(needle->host.name, check->host.name) &&
2645          (needle->remote_port == check->remote_port) ) {
2646         if(needle->protocol & PROT_SSL) {
2647           /* This is SSL, verify that we're using the same
2648              ssl options as well */
2649           if(!Curl_ssl_config_matches(&needle->ssl_config,
2650                                       &check->ssl_config)) {
2651             DEBUGF(infof(data,
2652                          "Connection #%ld has different SSL parameters, "
2653                          "can't reuse\n",
2654                          check->connectindex));
2655             continue;
2656           }
2657           else if(check->ssl[FIRSTSOCKET].state != ssl_connection_complete) {
2658             DEBUGF(infof(data,
2659                          "Connection #%ld has not started ssl connect, "
2660                          "can't reuse\n",
2661                          check->connectindex));
2662             continue;
2663           }
2664         }
2665         if((needle->protocol & PROT_FTP) ||
2666            ((needle->protocol & PROT_HTTP) &&
2667             (data->state.authhost.want==CURLAUTH_NTLM))) {
2668           /* This is FTP or HTTP+NTLM, verify that we're using the same name
2669              and password as well */
2670           if(!strequal(needle->user, check->user) ||
2671              !strequal(needle->passwd, check->passwd)) {
2672             /* one of them was different */
2673             continue;
2674           }
2675         }
2676         match = TRUE;
2677       }
2678     }
2679     else { /* The requested needle connection is using a proxy,
2680               is the checked one using the same host, port and type? */
2681       if(check->bits.proxy &&
2682          (needle->proxytype == check->proxytype) &&
2683          Curl_raw_equal(needle->proxy.name, check->proxy.name) &&
2684          needle->port == check->port) {
2685         /* This is the same proxy connection, use it! */
2686         match = TRUE;
2687       }
2688     }
2689 
2690     if(match) {
2691       if(!pipeLen && !check->inuse) {
2692         /* The check for a dead socket makes sense only if there are no
2693            handles in pipeline and the connection isn't already marked in
2694            use */
2695         bool dead = SocketIsDead(check->sock[FIRSTSOCKET]);
2696         if(dead) {
2697           check->data = data;
2698           infof(data, "Connection #%d seems to be dead!\n", i);
2699 
2700           Curl_disconnect(check); /* disconnect resources */
2701           data->state.connc->connects[i]=NULL; /* nothing here */
2702 
2703           return FALSE;
2704         }
2705       }
2706 
2707       check->inuse = TRUE; /* mark this as being in use so that no other
2708                               handle in a multi stack may nick it */
2709 
2710       *usethis = check;
2711       return TRUE; /* yes, we found one to use! */
2712     }
2713   }
2714 
2715   return FALSE; /* no matching connecting exists */
2716 }
2717 
2718 
2719 
2720 /*
2721  * This function frees/closes a connection in the connection cache. This
2722  * should take the previously set policy into account when deciding which
2723  * of the connections to kill.
2724  */
2725 static long
ConnectionKillOne(struct SessionHandle * data)2726 ConnectionKillOne(struct SessionHandle *data)
2727 {
2728   long i;
2729   struct connectdata *conn;
2730   long highscore=-1;
2731   long connindex=-1;
2732   long score;
2733   struct timeval now;
2734 
2735   now = Curl_tvnow();
2736 
2737   for(i=0; data->state.connc && (i< data->state.connc->num); i++) {
2738     conn = data->state.connc->connects[i];
2739 
2740     if(!conn || conn->inuse)
2741       continue;
2742 
2743     /* Set higher score for the age passed since the connection was used */
2744     score = Curl_tvdiff(now, conn->now);
2745 
2746     if(score > highscore) {
2747       highscore = score;
2748       connindex = i;
2749     }
2750   }
2751   if(connindex >= 0) {
2752     /* Set the connection's owner correctly */
2753     conn = data->state.connc->connects[connindex];
2754     conn->data = data;
2755 
2756     /* the winner gets the honour of being disconnected */
2757     (void)Curl_disconnect(conn);
2758 
2759     /* clean the array entry */
2760     data->state.connc->connects[connindex] = NULL;
2761   }
2762 
2763   return connindex; /* return the available index or -1 */
2764 }
2765 
2766 /* this connection can now be marked 'idle' */
2767 static void
ConnectionDone(struct connectdata * conn)2768 ConnectionDone(struct connectdata *conn)
2769 {
2770   conn->inuse = FALSE;
2771 }
2772 
2773 /*
2774  * The given input connection struct pointer is to be stored. If the "cache"
2775  * is already full, we must clean out the most suitable using the previously
2776  * set policy.
2777  *
2778  * The given connection should be unique. That must've been checked prior to
2779  * this call.
2780  */
2781 static long
ConnectionStore(struct SessionHandle * data,struct connectdata * conn)2782 ConnectionStore(struct SessionHandle *data,
2783                 struct connectdata *conn)
2784 {
2785   long i;
2786   for(i=0; i< data->state.connc->num; i++) {
2787     if(!data->state.connc->connects[i])
2788       break;
2789   }
2790   if(i == data->state.connc->num) {
2791     /* there was no room available, kill one */
2792     i = ConnectionKillOne(data);
2793     if(-1 != i)
2794       infof(data, "Connection (#%d) was killed to make room (holds %d)\n",
2795             i, data->state.connc->num);
2796     else
2797       infof(data, "This connection did not fit in the connection cache\n");
2798   }
2799 
2800   conn->connectindex = i; /* Make the child know where the pointer to this
2801                              particular data is stored. But note that this -1
2802                              if this is not within the cache and this is
2803                              probably not checked for everywhere (yet). */
2804   conn->inuse = TRUE;
2805   if(-1 != i) {
2806     /* Only do this if a true index was returned, if -1 was returned there
2807        is no room in the cache for an unknown reason and we cannot store
2808        this there.
2809 
2810        TODO: make sure we really can work with more handles than positions in
2811        the cache, or possibly we should (allow to automatically) resize the
2812        connection cache when we add more easy handles to a multi handle!
2813     */
2814     data->state.connc->connects[i] = conn; /* fill in this */
2815     conn->data = data;
2816   }
2817 
2818   return i;
2819 }
2820 
ConnectPlease(struct SessionHandle * data,struct connectdata * conn,struct Curl_dns_entry * hostaddr,bool * connected)2821 static CURLcode ConnectPlease(struct SessionHandle *data,
2822                               struct connectdata *conn,
2823                               struct Curl_dns_entry *hostaddr,
2824                               bool *connected)
2825 {
2826   CURLcode result;
2827   Curl_addrinfo *addr;
2828 #ifndef CURL_DISABLE_VERBOSE_STRINGS
2829   char *hostname = conn->bits.proxy?conn->proxy.name:conn->host.name;
2830 
2831   infof(data, "About to connect() to %s%s port %d (#%d)\n",
2832         conn->bits.proxy?"proxy ":"",
2833         hostname, conn->port, conn->connectindex);
2834 #endif
2835 
2836   /*************************************************************
2837    * Connect to server/proxy
2838    *************************************************************/
2839   result= Curl_connecthost(conn,
2840                            hostaddr,
2841                            &conn->sock[FIRSTSOCKET],
2842                            &addr,
2843                            connected);
2844   if(CURLE_OK == result) {
2845     /* All is cool, then we store the current information */
2846     conn->dns_entry = hostaddr;
2847     conn->ip_addr = addr;
2848 
2849     switch(data->set.proxytype) {
2850 #ifndef CURL_DISABLE_PROXY
2851     case CURLPROXY_SOCKS5:
2852     case CURLPROXY_SOCKS5_HOSTNAME:
2853       result = Curl_SOCKS5(conn->proxyuser, conn->proxypasswd,
2854                            conn->host.name, conn->remote_port,
2855                            FIRSTSOCKET, conn);
2856       break;
2857     case CURLPROXY_SOCKS4:
2858       result = Curl_SOCKS4(conn->proxyuser, conn->host.name,
2859                            conn->remote_port, FIRSTSOCKET, conn, FALSE);
2860       break;
2861     case CURLPROXY_SOCKS4A:
2862       result = Curl_SOCKS4(conn->proxyuser, conn->host.name,
2863                            conn->remote_port, FIRSTSOCKET, conn, TRUE);
2864       break;
2865 #endif /* CURL_DISABLE_PROXY */
2866     case CURLPROXY_HTTP:
2867     case CURLPROXY_HTTP_1_0:
2868       /* do nothing here. handled later. */
2869       break;
2870     default:
2871       failf(data, "unknown proxytype option given");
2872       result = CURLE_COULDNT_CONNECT;
2873       break;
2874     } /* switch proxytype */
2875   } /* if result is ok */
2876 
2877   if(result)
2878     *connected = FALSE; /* mark it as not connected */
2879 
2880   return result;
2881 }
2882 
2883 /*
2884  * verboseconnect() displays verbose information after a connect
2885  */
2886 #ifndef CURL_DISABLE_VERBOSE_STRINGS
verboseconnect(struct connectdata * conn)2887 static void verboseconnect(struct connectdata *conn)
2888 {
2889   infof(conn->data, "Connected to %s (%s) port %d (#%d)\n",
2890         conn->bits.proxy ? conn->proxy.dispname : conn->host.dispname,
2891         conn->ip_addr_str, conn->port, conn->connectindex);
2892 }
2893 #endif
2894 
Curl_protocol_getsock(struct connectdata * conn,curl_socket_t * socks,int numsocks)2895 int Curl_protocol_getsock(struct connectdata *conn,
2896                           curl_socket_t *socks,
2897                           int numsocks)
2898 {
2899   if(conn->handler->proto_getsock)
2900     return conn->handler->proto_getsock(conn, socks, numsocks);
2901   return GETSOCK_BLANK;
2902 }
2903 
Curl_doing_getsock(struct connectdata * conn,curl_socket_t * socks,int numsocks)2904 int Curl_doing_getsock(struct connectdata *conn,
2905                        curl_socket_t *socks,
2906                        int numsocks)
2907 {
2908   if(conn && conn->handler->doing_getsock)
2909     return conn->handler->doing_getsock(conn, socks, numsocks);
2910   return GETSOCK_BLANK;
2911 }
2912 
2913 /*
2914  * We are doing protocol-specific connecting and this is being called over and
2915  * over from the multi interface until the connection phase is done on
2916  * protocol layer.
2917  */
2918 
Curl_protocol_connecting(struct connectdata * conn,bool * done)2919 CURLcode Curl_protocol_connecting(struct connectdata *conn,
2920                                   bool *done)
2921 {
2922   CURLcode result=CURLE_OK;
2923 
2924   if(conn && conn->handler->connecting) {
2925     *done = FALSE;
2926     result = conn->handler->connecting(conn, done);
2927   }
2928   else
2929     *done = TRUE;
2930 
2931   return result;
2932 }
2933 
2934 /*
2935  * We are DOING this is being called over and over from the multi interface
2936  * until the DOING phase is done on protocol layer.
2937  */
2938 
Curl_protocol_doing(struct connectdata * conn,bool * done)2939 CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
2940 {
2941   CURLcode result=CURLE_OK;
2942 
2943   if(conn && conn->handler->doing) {
2944     *done = FALSE;
2945     result = conn->handler->doing(conn, done);
2946   }
2947   else
2948     *done = TRUE;
2949 
2950   return result;
2951 }
2952 
2953 /*
2954  * We have discovered that the TCP connection has been successful, we can now
2955  * proceed with some action.
2956  *
2957  */
Curl_protocol_connect(struct connectdata * conn,bool * protocol_done)2958 CURLcode Curl_protocol_connect(struct connectdata *conn,
2959                                bool *protocol_done)
2960 {
2961   CURLcode result=CURLE_OK;
2962   struct SessionHandle *data = conn->data;
2963 
2964   *protocol_done = FALSE;
2965 
2966   if(conn->bits.tcpconnect && conn->bits.protoconnstart) {
2967     /* We already are connected, get back. This may happen when the connect
2968        worked fine in the first call, like when we connect to a local server
2969        or proxy. Note that we don't know if the protocol is actually done.
2970 
2971        Unless this protocol doesn't have any protocol-connect callback, as
2972        then we know we're done. */
2973     if(!conn->handler->connecting)
2974       *protocol_done = TRUE;
2975 
2976     return CURLE_OK;
2977   }
2978 
2979   if(!conn->bits.tcpconnect) {
2980 
2981     Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
2982 
2983     if(data->set.verbose)
2984       verboseconnect(conn);
2985   }
2986 
2987   if(!conn->bits.protoconnstart) {
2988     if(conn->handler->connect_it) {
2989       /* is there a protocol-specific connect() procedure? */
2990 
2991       /* Set start time here for timeout purposes in the connect procedure, it
2992          is later set again for the progress meter purpose */
2993       conn->now = Curl_tvnow();
2994 
2995       /* Call the protocol-specific connect function */
2996       result = conn->handler->connect_it(conn, protocol_done);
2997     }
2998     else
2999       *protocol_done = TRUE;
3000 
3001     /* it has started, possibly even completed but that knowledge isn't stored
3002        in this bit! */
3003     if(!result)
3004       conn->bits.protoconnstart = TRUE;
3005   }
3006 
3007   return result; /* pass back status */
3008 }
3009 
3010 /*
3011  * Helpers for IDNA convertions.
3012  */
3013 #ifdef USE_LIBIDN
is_ASCII_name(const char * hostname)3014 static bool is_ASCII_name(const char *hostname)
3015 {
3016   const unsigned char *ch = (const unsigned char*)hostname;
3017 
3018   while(*ch) {
3019     if(*ch++ & 0x80)
3020       return FALSE;
3021   }
3022   return TRUE;
3023 }
3024 
3025 /*
3026  * Check if characters in hostname is allowed in Top Level Domain.
3027  */
tld_check_name(struct SessionHandle * data,const char * ace_hostname)3028 static bool tld_check_name(struct SessionHandle *data,
3029                            const char *ace_hostname)
3030 {
3031   size_t err_pos;
3032   char *uc_name = NULL;
3033   int rc;
3034 #ifndef CURL_DISABLE_VERBOSE_STRINGS
3035   const char *tld_errmsg = "<no msg>";
3036 #else
3037   (void)data;
3038 #endif
3039 
3040   /* Convert (and downcase) ACE-name back into locale's character set */
3041   rc = idna_to_unicode_lzlz(ace_hostname, &uc_name, 0);
3042   if(rc != IDNA_SUCCESS)
3043     return (FALSE);
3044 
3045   rc = tld_check_lz(uc_name, &err_pos, NULL);
3046 #ifndef CURL_DISABLE_VERBOSE_STRINGS
3047 #ifdef HAVE_TLD_STRERROR
3048   if(rc != TLD_SUCCESS)
3049     tld_errmsg = tld_strerror((Tld_rc)rc);
3050 #endif
3051   if(rc == TLD_INVALID)
3052     infof(data, "WARNING: %s; pos %u = `%c'/0x%02X\n",
3053           tld_errmsg, err_pos, uc_name[err_pos],
3054           uc_name[err_pos] & 255);
3055   else if(rc != TLD_SUCCESS)
3056     infof(data, "WARNING: TLD check for %s failed; %s\n",
3057           uc_name, tld_errmsg);
3058 #endif /* CURL_DISABLE_VERBOSE_STRINGS */
3059   if(uc_name)
3060      idn_free(uc_name);
3061   return (bool)(rc == TLD_SUCCESS);
3062 }
3063 #endif
3064 
3065 /*
3066  * Perform any necessary IDN conversion of hostname
3067  */
fix_hostname(struct SessionHandle * data,struct connectdata * conn,struct hostname * host)3068 static void fix_hostname(struct SessionHandle *data,
3069                          struct connectdata *conn, struct hostname *host)
3070 {
3071 #ifndef USE_LIBIDN
3072   (void)data;
3073   (void)conn;
3074 #elif defined(CURL_DISABLE_VERBOSE_STRINGS)
3075   (void)conn;
3076 #endif
3077 
3078   /* set the name we use to display the host name */
3079   host->dispname = host->name;
3080 
3081 #ifdef USE_LIBIDN
3082   /*************************************************************
3083    * Check name for non-ASCII and convert hostname to ACE form.
3084    *************************************************************/
3085   if(!is_ASCII_name(host->name) &&
3086       stringprep_check_version(LIBIDN_REQUIRED_VERSION)) {
3087     char *ace_hostname = NULL;
3088     int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0);
3089     infof (data, "Input domain encoded as `%s'\n",
3090            stringprep_locale_charset ());
3091     if(rc != IDNA_SUCCESS)
3092       infof(data, "Failed to convert %s to ACE; %s\n",
3093             host->name, Curl_idn_strerror(conn,rc));
3094     else {
3095       /* tld_check_name() displays a warning if the host name contains
3096          "illegal" characters for this TLD */
3097       (void)tld_check_name(data, ace_hostname);
3098 
3099       host->encalloc = ace_hostname;
3100       /* change the name pointer to point to the encoded hostname */
3101       host->name = host->encalloc;
3102     }
3103   }
3104 #endif
3105 }
3106 
3107 /*
3108  * Allocate and initialize a new connectdata object.
3109  */
allocate_conn(void)3110 static struct connectdata *allocate_conn(void)
3111 {
3112   struct connectdata *conn;
3113 
3114   conn = calloc(1, sizeof(struct connectdata));
3115   if(!conn)
3116     return NULL;
3117 
3118   conn->handler = &Curl_handler_dummy;  /* Be sure we have a handler defined
3119                                            already from start to avoid NULL
3120                                            situations and checks */
3121 
3122   /* and we setup a few fields in case we end up actually using this struct */
3123 
3124   conn->sock[FIRSTSOCKET] = CURL_SOCKET_BAD;     /* no file descriptor */
3125   conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; /* no file descriptor */
3126   conn->connectindex = -1;    /* no index */
3127 
3128   /* Default protocol-independent behavior doesn't support persistent
3129      connections, so we set this to force-close. Protocols that support
3130      this need to set this to FALSE in their "curl_do" functions. */
3131   conn->bits.close = TRUE;
3132 
3133   /* Store creation time to help future close decision making */
3134   conn->created = Curl_tvnow();
3135 
3136   return conn;
3137 }
3138 
3139 /*
3140  * Parse URL and fill in the relevant members of the connection struct.
3141  */
ParseURLAndFillConnection(struct SessionHandle * data,struct connectdata * conn)3142 static CURLcode ParseURLAndFillConnection(struct SessionHandle *data,
3143                                           struct connectdata *conn)
3144 {
3145   char *at;
3146   char *tmp;
3147   char *path = data->state.path;
3148   int rc;
3149 
3150   /*************************************************************
3151    * Parse the URL.
3152    *
3153    * We need to parse the url even when using the proxy, because we will need
3154    * the hostname and port in case we are trying to SSL connect through the
3155    * proxy -- and we don't know if we will need to use SSL until we parse the
3156    * url ...
3157    ************************************************************/
3158   if((2 == sscanf(data->change.url, "%15[^:]:%[^\n]",
3159                   conn->protostr,
3160                   path)) && Curl_raw_equal(conn->protostr, "file")) {
3161     if(path[0] == '/' && path[1] == '/') {
3162       /* Allow omitted hostname (e.g. file:/<path>).  This is not strictly
3163        * speaking a valid file: URL by RFC 1738, but treating file:/<path> as
3164        * file://localhost/<path> is similar to how other schemes treat missing
3165        * hostnames.  See RFC 1808. */
3166 
3167       /* This cannot be done with strcpy() in a portable manner, since the
3168          memory areas overlap! */
3169       memmove(path, path + 2, strlen(path + 2)+1);
3170     }
3171     /*
3172      * we deal with file://<host>/<path> differently since it supports no
3173      * hostname other than "localhost" and "127.0.0.1", which is unique among
3174      * the URL protocols specified in RFC 1738
3175      */
3176     if(path[0] != '/') {
3177       /* the URL included a host name, we ignore host names in file:// URLs
3178          as the standards don't define what to do with them */
3179       char *ptr=strchr(path, '/');
3180       if(ptr) {
3181         /* there was a slash present
3182 
3183            RFC1738 (section 3.1, page 5) says:
3184 
3185            The rest of the locator consists of data specific to the scheme,
3186            and is known as the "url-path". It supplies the details of how the
3187            specified resource can be accessed. Note that the "/" between the
3188            host (or port) and the url-path is NOT part of the url-path.
3189 
3190            As most agents use file://localhost/foo to get '/foo' although the
3191            slash preceding foo is a separator and not a slash for the path,
3192            a URL as file://localhost//foo must be valid as well, to refer to
3193            the same file with an absolute path.
3194         */
3195 
3196         if(ptr[1] && ('/' == ptr[1]))
3197           /* if there was two slashes, we skip the first one as that is then
3198              used truly as a separator */
3199           ptr++;
3200 
3201         /* This cannot be made with strcpy, as the memory chunks overlap! */
3202         memmove(path, ptr, strlen(ptr)+1);
3203       }
3204     }
3205 
3206     strcpy(conn->protostr, "file"); /* store protocol string lowercase */
3207   }
3208   else {
3209     /* clear path */
3210     path[0]=0;
3211 
3212     if(2 > sscanf(data->change.url,
3213                    "%15[^\n:]://%[^\n/]%[^\n]",
3214                    conn->protostr,
3215                    conn->host.name, path)) {
3216 
3217       /*
3218        * The URL was badly formatted, let's try the browser-style _without_
3219        * protocol specified like 'http://'.
3220        */
3221       if(1 > (rc = sscanf(data->change.url, "%[^\n/]%[^\n]",
3222                           conn->host.name, path)) ) {
3223         /*
3224          * We couldn't even get this format.
3225          * djgpp 2.04 has a sscanf() bug where 'conn->host.name' is
3226          * assigned, but the return value is EOF!
3227          */
3228 #if defined(__DJGPP__) && (DJGPP_MINOR == 4)
3229         if (!(rc == -1 && *conn->host.name))
3230 #endif
3231         {
3232           failf(data, "<url> malformed");
3233           return CURLE_URL_MALFORMAT;
3234         }
3235       }
3236 
3237       /*
3238        * Since there was no protocol part specified, we guess what protocol it
3239        * is based on the first letters of the server name.
3240        */
3241 
3242       /* Note: if you add a new protocol, please update the list in
3243        * lib/version.c too! */
3244 
3245       if(checkprefix("FTP.", conn->host.name))
3246         strcpy(conn->protostr, "ftp");
3247       else if(checkprefix("DICT.", conn->host.name))
3248         strcpy(conn->protostr, "DICT");
3249       else if(checkprefix("LDAP.", conn->host.name))
3250         strcpy(conn->protostr, "LDAP");
3251       else {
3252         strcpy(conn->protostr, "http");
3253       }
3254 
3255       conn->protocol |= PROT_MISSING; /* not given in URL */
3256     }
3257   }
3258 
3259   /* We search for '?' in the host name (but only on the right side of a
3260    * @-letter to allow ?-letters in username and password) to handle things
3261    * like http://example.com?param= (notice the missing '/').
3262    */
3263   at = strchr(conn->host.name, '@');
3264   if(at)
3265     tmp = strchr(at+1, '?');
3266   else
3267     tmp = strchr(conn->host.name, '?');
3268 
3269   if(tmp) {
3270     /* We must insert a slash before the '?'-letter in the URL. If the URL had
3271        a slash after the '?', that is where the path currently begins and the
3272        '?string' is still part of the host name.
3273 
3274        We must move the trailing part from the host name and put it first in
3275        the path. And have it all prefixed with a slash.
3276     */
3277 
3278     size_t hostlen = strlen(tmp);
3279     size_t pathlen = strlen(path);
3280 
3281     /* move the existing path plus the zero byte forward, to make room for
3282        the host-name part */
3283     memmove(path+hostlen+1, path, pathlen+1);
3284 
3285      /* now copy the trailing host part in front of the existing path */
3286     memcpy(path+1, tmp, hostlen);
3287 
3288     path[0]='/'; /* prepend the missing slash */
3289 
3290     *tmp=0; /* now cut off the hostname at the ? */
3291   }
3292   else if(!path[0]) {
3293     /* if there's no path set, use a single slash */
3294     strcpy(path, "/");
3295   }
3296 
3297   /* If the URL is malformatted (missing a '/' after hostname before path) we
3298    * insert a slash here. The only letter except '/' we accept to start a path
3299    * is '?'.
3300    */
3301   if(path[0] == '?') {
3302     /* We need this function to deal with overlapping memory areas. We know
3303        that the memory area 'path' points to is 'urllen' bytes big and that
3304        is bigger than the path. Use +1 to move the zero byte too. */
3305     memmove(&path[1], path, strlen(path)+1);
3306     path[0] = '/';
3307   }
3308 
3309   if (conn->host.name[0] == '[') {
3310     /* This looks like an IPv6 address literal.  See if there is an address
3311        scope.  */
3312     char *percent = strstr (conn->host.name, "%25");
3313     if (percent) {
3314       char *endp;
3315       unsigned long scope = strtoul (percent + 3, &endp, 10);
3316       if (*endp == ']') {
3317         /* The address scope was well formed.  Knock it out of the hostname.  */
3318         memmove(percent, endp, strlen(endp)+1);
3319         if (!data->state.this_is_a_follow)
3320           /* Don't honour a scope given in a Location: header */
3321           conn->scope = (unsigned int)scope;
3322       } else
3323         infof(data, "Invalid IPv6 address format\n");
3324     }
3325   }
3326 
3327   if (data->set.scope)
3328     /* Override any scope that was set above.  */
3329     conn->scope = data->set.scope;
3330 
3331   /*
3332    * So if the URL was A://B/C,
3333    *   conn->protostr is A
3334    *   conn->host.name is B
3335    *   data->state.path is /C
3336    */
3337   (void)rc;
3338   return CURLE_OK;
3339 }
3340 
llist_dtor(void * user,void * element)3341 static void llist_dtor(void *user, void *element)
3342 {
3343   (void)user;
3344   (void)element;
3345   /* Do nothing */
3346 }
3347 
3348 /*
3349  * If we're doing a resumed transfer, we need to setup our stuff
3350  * properly.
3351  */
setup_range(struct SessionHandle * data)3352 static CURLcode setup_range(struct SessionHandle *data)
3353 {
3354   struct UrlState *s = &data->state;
3355   s->resume_from = data->set.set_resume_from;
3356   if(s->resume_from || data->set.str[STRING_SET_RANGE]) {
3357     if(s->rangestringalloc)
3358       free(s->range);
3359 
3360     if(s->resume_from)
3361       s->range = aprintf("%" FORMAT_OFF_TU "-", s->resume_from);
3362     else
3363       s->range = strdup(data->set.str[STRING_SET_RANGE]);
3364 
3365     s->rangestringalloc = (bool)(s->range?TRUE:FALSE);
3366 
3367     if(!s->range)
3368       return CURLE_OUT_OF_MEMORY;
3369 
3370     /* tell ourselves to fetch this range */
3371     s->use_range = TRUE;        /* enable range download */
3372   }
3373   else
3374     s->use_range = FALSE; /* disable range download */
3375 
3376   return CURLE_OK;
3377 }
3378 
3379 
3380 /***************************************************************
3381 * Setup connection internals specific to the requested protocol
3382 ***************************************************************/
setup_connection_internals(struct SessionHandle * data,struct connectdata * conn)3383 static CURLcode setup_connection_internals(struct SessionHandle *data,
3384                                            struct connectdata *conn)
3385 {
3386   const struct Curl_handler * const * pp;
3387   const struct Curl_handler * p;
3388   CURLcode result;
3389 
3390   conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
3391 
3392   /* Scan protocol handler table. */
3393 
3394   for (pp = protocols; (p = *pp) != NULL; pp++)
3395     if(Curl_raw_equal(p->scheme, conn->protostr)) {
3396       /* Protocol found in table. Check if allowed */
3397       if(!(data->set.allowed_protocols & p->protocol))
3398         /* nope, get out */
3399         break;
3400 
3401       /* it is allowed for "normal" request, now do an extra check if this is
3402          the result of a redirect */
3403       if(data->state.this_is_a_follow &&
3404          !(data->set.redir_protocols & p->protocol))
3405         /* nope, get out */
3406         break;
3407 
3408       /* Perform setup complement if some. */
3409       conn->handler = p;
3410 
3411       if(p->setup_connection) {
3412         result = (*p->setup_connection)(conn);
3413 
3414         if(result != CURLE_OK)
3415           return result;
3416 
3417         p = conn->handler;              /* May have changed. */
3418       }
3419 
3420       conn->port = p->defport;
3421       conn->remote_port = (unsigned short)p->defport;
3422       conn->protocol |= p->protocol;
3423       return CURLE_OK;
3424     }
3425 
3426   /* The protocol was not found in the table, but we don't have to assign it
3427      to anything since it is already assigned to a dummy-struct in the
3428      create_conn() function when the connectdata struct is allocated. */
3429   failf(data, "Protocol %s not supported or disabled in " LIBCURL_NAME,
3430         conn->protostr);
3431   return CURLE_UNSUPPORTED_PROTOCOL;
3432 }
3433 
3434 #ifndef CURL_DISABLE_PROXY
3435 /****************************************************************
3436 * Checks if the host is in the noproxy list. returns true if it matches
3437 * and therefore the proxy should NOT be used.
3438 ****************************************************************/
check_noproxy(const char * name,const char * no_proxy)3439 static bool check_noproxy(const char* name, const char* no_proxy)
3440 {
3441   /* no_proxy=domain1.dom,host.domain2.dom
3442    *   (a comma-separated list of hosts which should
3443    *   not be proxied, or an asterisk to override
3444    *   all proxy variables)
3445    */
3446   size_t tok_start;
3447   size_t tok_end;
3448   const char* separator = ", ";
3449   size_t no_proxy_len;
3450   size_t namelen;
3451   char *endptr;
3452 
3453   if(no_proxy && no_proxy[0]) {
3454     if(Curl_raw_equal("*", no_proxy)) {
3455       return TRUE;
3456     }
3457 
3458     /* NO_PROXY was specified and it wasn't just an asterisk */
3459 
3460     no_proxy_len = strlen(no_proxy);
3461     endptr = strchr(name, ':');
3462     if(endptr)
3463       namelen = endptr - name;
3464     else
3465       namelen = strlen(name);
3466 
3467     tok_start = 0;
3468     for (tok_start = 0; tok_start < no_proxy_len; tok_start = tok_end + 1) {
3469       while (tok_start < no_proxy_len &&
3470              strchr(separator, no_proxy[tok_start]) != NULL) {
3471         /* Look for the beginning of the token. */
3472         ++tok_start;
3473       }
3474 
3475       if(tok_start == no_proxy_len)
3476         break; /* It was all trailing separator chars, no more tokens. */
3477 
3478       for (tok_end = tok_start; tok_end < no_proxy_len &&
3479              strchr(separator, no_proxy[tok_end]) == NULL; ++tok_end) {
3480         /* Look for the end of the token. */
3481       }
3482 
3483       /* To match previous behaviour, where it was necessary to specify
3484        * ".local.com" to prevent matching "notlocal.com", we will leave
3485        * the '.' off.
3486        */
3487       if(no_proxy[tok_start] == '.')
3488         ++tok_start;
3489 
3490       if((tok_end - tok_start) <= namelen) {
3491         /* Match the last part of the name to the domain we are checking. */
3492         const char *checkn = name + namelen - (tok_end - tok_start);
3493         if(Curl_raw_nequal(no_proxy + tok_start, checkn, tok_end - tok_start)) {
3494           if((tok_end - tok_start) == namelen || *(checkn - 1) == '.') {
3495             /* We either have an exact match, or the previous character is a .
3496              * so it is within the same domain, so no proxy for this host.
3497              */
3498             return TRUE;
3499           }
3500         }
3501       } /* if((tok_end - tok_start) <= namelen) */
3502     } /* for (tok_start = 0; tok_start < no_proxy_len;
3503          tok_start = tok_end + 1) */
3504   } /* NO_PROXY was specified and it wasn't just an asterisk */
3505 
3506   return FALSE;
3507 }
3508 
3509 /****************************************************************
3510 * Detect what (if any) proxy to use. Remember that this selects a host
3511 * name and is not limited to HTTP proxies only.
3512 * The returned pointer must be freed by the caller (unless NULL)
3513 ****************************************************************/
detect_proxy(struct connectdata * conn)3514 static char *detect_proxy(struct connectdata *conn)
3515 {
3516   char *proxy = NULL;
3517 
3518 #ifndef CURL_DISABLE_HTTP
3519   /* If proxy was not specified, we check for default proxy environment
3520    * variables, to enable i.e Lynx compliance:
3521    *
3522    * http_proxy=http://some.server.dom:port/
3523    * https_proxy=http://some.server.dom:port/
3524    * ftp_proxy=http://some.server.dom:port/
3525    * no_proxy=domain1.dom,host.domain2.dom
3526    *   (a comma-separated list of hosts which should
3527    *   not be proxied, or an asterisk to override
3528    *   all proxy variables)
3529    * all_proxy=http://some.server.dom:port/
3530    *   (seems to exist for the CERN www lib. Probably
3531    *   the first to check for.)
3532    *
3533    * For compatibility, the all-uppercase versions of these variables are
3534    * checked if the lowercase versions don't exist.
3535    */
3536   char *no_proxy=NULL;
3537   char proxy_env[128];
3538 
3539   no_proxy=curl_getenv("no_proxy");
3540   if(!no_proxy)
3541     no_proxy=curl_getenv("NO_PROXY");
3542 
3543   if(!check_noproxy(conn->host.name, no_proxy)) {
3544     /* It was not listed as without proxy */
3545     char *protop = conn->protostr;
3546     char *envp = proxy_env;
3547     char *prox;
3548 
3549     /* Now, build <protocol>_proxy and check for such a one to use */
3550     while(*protop)
3551       *envp++ = (char)tolower((int)*protop++);
3552 
3553     /* append _proxy */
3554     strcpy(envp, "_proxy");
3555 
3556     /* read the protocol proxy: */
3557     prox=curl_getenv(proxy_env);
3558 
3559     /*
3560      * We don't try the uppercase version of HTTP_PROXY because of
3561      * security reasons:
3562      *
3563      * When curl is used in a webserver application
3564      * environment (cgi or php), this environment variable can
3565      * be controlled by the web server user by setting the
3566      * http header 'Proxy:' to some value.
3567      *
3568      * This can cause 'internal' http/ftp requests to be
3569      * arbitrarily redirected by any external attacker.
3570      */
3571     if(!prox && !Curl_raw_equal("http_proxy", proxy_env)) {
3572       /* There was no lowercase variable, try the uppercase version: */
3573       Curl_strntoupper(proxy_env, proxy_env, sizeof(proxy_env));
3574       prox=curl_getenv(proxy_env);
3575     }
3576 
3577     if(prox && *prox) { /* don't count "" strings */
3578       proxy = prox; /* use this */
3579     }
3580     else {
3581       proxy = curl_getenv("all_proxy"); /* default proxy to use */
3582       if(!proxy)
3583         proxy=curl_getenv("ALL_PROXY");
3584     }
3585   } /* if(!check_noproxy(conn->host.name, no_proxy)) - it wasn't specified
3586        non-proxy */
3587   if(no_proxy)
3588     free(no_proxy);
3589 
3590 #else /* !CURL_DISABLE_HTTP */
3591 
3592   (void)conn;
3593 #endif /* CURL_DISABLE_HTTP */
3594 
3595   return proxy;
3596 }
3597 
3598 /*
3599  * If this is supposed to use a proxy, we need to figure out the proxy
3600  * host name, so that we can re-use an existing connection
3601  * that may exist registered to the same proxy host.
3602  * proxy will be freed before this function returns.
3603  */
parse_proxy(struct SessionHandle * data,struct connectdata * conn,char * proxy)3604 static CURLcode parse_proxy(struct SessionHandle *data,
3605                             struct connectdata *conn, char *proxy)
3606 {
3607   char *prox_portno;
3608   char *endofprot;
3609 
3610   /* We use 'proxyptr' to point to the proxy name from now on... */
3611   char *proxyptr=proxy;
3612   char *portptr;
3613   char *atsign;
3614 
3615   /* We do the proxy host string parsing here. We want the host name and the
3616    * port name. Accept a protocol:// prefix, even though it should just be
3617    * ignored.
3618    */
3619 
3620   /* Skip the protocol part if present */
3621   endofprot=strstr(proxyptr, "://");
3622   if(endofprot)
3623     proxyptr = endofprot+3;
3624 
3625   /* Is there a username and password given in this proxy url? */
3626   atsign = strchr(proxyptr, '@');
3627   if(atsign) {
3628     char proxyuser[MAX_CURL_USER_LENGTH];
3629     char proxypasswd[MAX_CURL_PASSWORD_LENGTH];
3630     proxypasswd[0] = 0;
3631 
3632     if(1 <= sscanf(proxyptr,
3633                    "%" MAX_CURL_USER_LENGTH_TXT"[^:@]:"
3634                    "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
3635                    proxyuser, proxypasswd)) {
3636       CURLcode res = CURLE_OK;
3637 
3638       /* found user and password, rip them out.  note that we are
3639          unescaping them, as there is otherwise no way to have a
3640          username or password with reserved characters like ':' in
3641          them. */
3642       Curl_safefree(conn->proxyuser);
3643       conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
3644 
3645       if(!conn->proxyuser)
3646         res = CURLE_OUT_OF_MEMORY;
3647       else {
3648         Curl_safefree(conn->proxypasswd);
3649         conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
3650 
3651         if(!conn->proxypasswd)
3652           res = CURLE_OUT_OF_MEMORY;
3653       }
3654 
3655       if(CURLE_OK == res) {
3656         conn->bits.proxy_user_passwd = TRUE; /* enable it */
3657         atsign = strdup(atsign+1); /* the right side of the @-letter */
3658 
3659         if(atsign) {
3660           free(proxy); /* free the former proxy string */
3661           proxy = proxyptr = atsign; /* now use this instead */
3662         }
3663         else
3664           res = CURLE_OUT_OF_MEMORY;
3665       }
3666 
3667       if(res) {
3668         free(proxy); /* free the allocated proxy string */
3669         return res;
3670       }
3671     }
3672   }
3673 
3674   /* start scanning for port number at this point */
3675   portptr = proxyptr;
3676 
3677   /* detect and extract RFC2732-style IPv6-addresses */
3678   if(*proxyptr == '[') {
3679     char *ptr = ++proxyptr; /* advance beyond the initial bracket */
3680     while(*ptr && (ISXDIGIT(*ptr) || (*ptr == ':') || (*ptr == '%') || (*ptr == '.')))
3681       ptr++;
3682     if(*ptr == ']') {
3683       /* yeps, it ended nicely with a bracket as well */
3684       *ptr++ = 0;
3685     } else
3686       infof(data, "Invalid IPv6 address format\n");
3687     portptr = ptr;
3688     /* Note that if this didn't end with a bracket, we still advanced the
3689      * proxyptr first, but I can't see anything wrong with that as no host
3690      * name nor a numeric can legally start with a bracket.
3691      */
3692   }
3693 
3694   /* Get port number off proxy.server.com:1080 */
3695   prox_portno = strchr(portptr, ':');
3696   if(prox_portno) {
3697     *prox_portno = 0x0; /* cut off number from host name */
3698     prox_portno ++;
3699     /* now set the local port number */
3700     conn->port = atoi(prox_portno);
3701   }
3702   else {
3703     /* without a port number after the host name, some people seem to use
3704        a slash so we strip everything from the first slash */
3705     atsign = strchr(proxyptr, '/');
3706     if(atsign)
3707       *atsign = 0x0; /* cut off path part from host name */
3708 
3709     if(data->set.proxyport)
3710       /* None given in the proxy string, then get the default one if it is
3711          given */
3712       conn->port = data->set.proxyport;
3713   }
3714 
3715   /* now, clone the cleaned proxy host name */
3716   conn->proxy.rawalloc = strdup(proxyptr);
3717   conn->proxy.name = conn->proxy.rawalloc;
3718 
3719   free(proxy);
3720   if(!conn->proxy.rawalloc)
3721     return CURLE_OUT_OF_MEMORY;
3722 
3723   return CURLE_OK;
3724 }
3725 
3726 /*
3727  * Extract the user and password from the authentication string
3728  */
parse_proxy_auth(struct SessionHandle * data,struct connectdata * conn)3729 static CURLcode parse_proxy_auth(struct SessionHandle *data,
3730                                  struct connectdata *conn)
3731 {
3732   char proxyuser[MAX_CURL_USER_LENGTH]="";
3733   char proxypasswd[MAX_CURL_PASSWORD_LENGTH]="";
3734 
3735   if(data->set.str[STRING_PROXYUSERNAME] != NULL) {
3736     strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME],
3737             MAX_CURL_USER_LENGTH);
3738     proxyuser[MAX_CURL_USER_LENGTH-1] = '\0';   /*To be on safe side*/
3739   }
3740   if(data->set.str[STRING_PROXYPASSWORD] != NULL) {
3741     strncpy(proxypasswd, data->set.str[STRING_PROXYPASSWORD],
3742             MAX_CURL_PASSWORD_LENGTH);
3743     proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/
3744   }
3745 
3746   conn->proxyuser = curl_easy_unescape(data, proxyuser, 0, NULL);
3747   if(!conn->proxyuser)
3748     return CURLE_OUT_OF_MEMORY;
3749 
3750   conn->proxypasswd = curl_easy_unescape(data, proxypasswd, 0, NULL);
3751   if(!conn->proxypasswd)
3752     return CURLE_OUT_OF_MEMORY;
3753 
3754   return CURLE_OK;
3755 }
3756 #endif /* CURL_DISABLE_PROXY */
3757 
3758 /*
3759  *
3760  * Parse a user name and password in the URL and strip it out of the host name
3761  *
3762  * Inputs: data->set.use_netrc (CURLOPT_NETRC)
3763  *         conn->host.name
3764  *
3765  * Outputs: (almost :- all currently undefined)
3766  *          conn->bits.user_passwd  - non-zero if non-default passwords exist
3767  *          user                    - non-zero length if defined
3768  *          passwd                  -   ditto
3769  *          conn->host.name         - remove user name and password
3770  */
parse_url_userpass(struct SessionHandle * data,struct connectdata * conn,char * user,char * passwd)3771 static CURLcode parse_url_userpass(struct SessionHandle *data,
3772                                    struct connectdata *conn,
3773                                    char *user, char *passwd)
3774 {
3775   /* At this point, we're hoping all the other special cases have
3776    * been taken care of, so conn->host.name is at most
3777    *    [user[:password]]@]hostname
3778    *
3779    * We need somewhere to put the embedded details, so do that first.
3780    */
3781 
3782   user[0] =0;   /* to make everything well-defined */
3783   passwd[0]=0;
3784 
3785   if(conn->protocol & (PROT_FTP|PROT_HTTP|PROT_SCP|PROT_SFTP)) {
3786     /* This is a FTP, HTTP, SCP or SFTP URL, we will now try to extract the
3787      * possible user+password pair in a string like:
3788      * ftp://user:password@ftp.my.site:8021/README */
3789     char *ptr=strchr(conn->host.name, '@');
3790     char *userpass = conn->host.name;
3791     if(ptr != NULL) {
3792       /* there's a user+password given here, to the left of the @ */
3793 
3794       conn->host.name = ++ptr;
3795 
3796       /* So the hostname is sane.  Only bother interpreting the
3797        * results if we could care.  It could still be wasted
3798        * work because it might be overtaken by the programmatically
3799        * set user/passwd, but doing that first adds more cases here :-(
3800        */
3801 
3802       if(data->set.use_netrc != CURL_NETRC_REQUIRED) {
3803         /* We could use the one in the URL */
3804 
3805         conn->bits.user_passwd = 1; /* enable user+password */
3806 
3807         if(*userpass != ':') {
3808           /* the name is given, get user+password */
3809           sscanf(userpass, "%" MAX_CURL_USER_LENGTH_TXT "[^:@]:"
3810                  "%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
3811                  user, passwd);
3812         }
3813         else
3814           /* no name given, get the password only */
3815           sscanf(userpass, ":%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]", passwd);
3816 
3817         if(user[0]) {
3818           char *newname=curl_easy_unescape(data, user, 0, NULL);
3819           if(!newname)
3820             return CURLE_OUT_OF_MEMORY;
3821           if(strlen(newname) < MAX_CURL_USER_LENGTH)
3822             strcpy(user, newname);
3823 
3824           /* if the new name is longer than accepted, then just use
3825              the unconverted name, it'll be wrong but what the heck */
3826           free(newname);
3827         }
3828         if(passwd[0]) {
3829           /* we have a password found in the URL, decode it! */
3830           char *newpasswd=curl_easy_unescape(data, passwd, 0, NULL);
3831           if(!newpasswd)
3832             return CURLE_OUT_OF_MEMORY;
3833           if(strlen(newpasswd) < MAX_CURL_PASSWORD_LENGTH)
3834             strcpy(passwd, newpasswd);
3835 
3836           free(newpasswd);
3837         }
3838       }
3839     }
3840   }
3841   return CURLE_OK;
3842 }
3843 
3844 /*************************************************************
3845  * Figure out the remote port number and fix it in the URL
3846  *
3847  * No matter if we use a proxy or not, we have to figure out the remote
3848  * port number of various reasons.
3849  *
3850  * To be able to detect port number flawlessly, we must not confuse them
3851  * IPv6-specified addresses in the [0::1] style. (RFC2732)
3852  *
3853  * The conn->host.name is currently [user:passwd@]host[:port] where host
3854  * could be a hostname, IPv4 address or IPv6 address.
3855  *
3856  * The port number embedded in the URL is replaced, if necessary.
3857  *************************************************************/
parse_remote_port(struct SessionHandle * data,struct connectdata * conn)3858 static CURLcode parse_remote_port(struct SessionHandle *data,
3859                                   struct connectdata *conn)
3860 {
3861   char *portptr;
3862   char endbracket;
3863 
3864   /* Note that at this point, the IPv6 address cannot contain any scope
3865      suffix as that has already been removed in the ParseURLAndFillConnection()
3866      function */
3867   if((1 == sscanf(conn->host.name, "[%*45[0123456789abcdefABCDEF:.]%c",
3868                   &endbracket)) &&
3869      (']' == endbracket)) {
3870     /* this is a RFC2732-style specified IP-address */
3871     conn->bits.ipv6_ip = TRUE;
3872 
3873     conn->host.name++; /* skip over the starting bracket */
3874     portptr = strchr(conn->host.name, ']');
3875     *portptr++ = 0; /* zero terminate, killing the bracket */
3876     if(':' != *portptr)
3877       portptr = NULL; /* no port number available */
3878   }
3879   else
3880     portptr = strrchr(conn->host.name, ':');
3881 
3882   if(data->set.use_port && data->state.allow_port) {
3883     /* if set, we use this and ignore the port possibly given in the URL */
3884     conn->remote_port = (unsigned short)data->set.use_port;
3885     if(portptr)
3886       *portptr = '\0'; /* cut off the name there anyway - if there was a port
3887                       number - since the port number is to be ignored! */
3888     if(conn->bits.httpproxy) {
3889       /* we need to create new URL with the new port number */
3890       char *url;
3891       bool isftp = (bool)(Curl_raw_equal("ftp", conn->protostr) ||
3892                           Curl_raw_equal("ftps", conn->protostr));
3893 
3894       /*
3895        * This synthesized URL isn't always right--suffixes like ;type=A
3896        * are stripped off. It would be better to work directly from the
3897        * original URL and simply replace the port part of it.
3898        */
3899       url = aprintf("%s://%s%s%s:%d%s%s", conn->protostr,
3900              conn->bits.ipv6_ip?"[":"", conn->host.name,
3901              conn->bits.ipv6_ip?"]":"", conn->remote_port,
3902              isftp?"/":"", data->state.path);
3903       if(!url)
3904         return CURLE_OUT_OF_MEMORY;
3905 
3906       if(data->change.url_alloc)
3907         free(data->change.url);
3908 
3909       data->change.url = url;
3910       data->change.url_alloc = TRUE;
3911     }
3912   }
3913   else if(portptr) {
3914     /* no CURLOPT_PORT given, extract the one from the URL */
3915 
3916     char *rest;
3917     unsigned long port;
3918 
3919     port=strtoul(portptr+1, &rest, 10);  /* Port number must be decimal */
3920 
3921     if(rest != (portptr+1) && *rest == '\0') {
3922       /* The colon really did have only digits after it,
3923        * so it is either a port number or a mistake */
3924 
3925       if(port > 0xffff) {   /* Single unix standard says port numbers are
3926                               * 16 bits long */
3927         failf(data, "Port number too large: %lu", port);
3928         return CURLE_URL_MALFORMAT;
3929       }
3930 
3931       *portptr = '\0'; /* cut off the name there */
3932       conn->remote_port = (unsigned short)port;
3933     }
3934   }
3935   return CURLE_OK;
3936 }
3937 
3938 /*
3939  * Override a user name and password from the URL with that in the
3940  * CURLOPT_USERPWD option or a .netrc file, if applicable.
3941  */
override_userpass(struct SessionHandle * data,struct connectdata * conn,char * user,char * passwd)3942 static void override_userpass(struct SessionHandle *data,
3943                               struct connectdata *conn,
3944                               char *user, char *passwd)
3945 {
3946   if(data->set.str[STRING_USERNAME] != NULL) {
3947     strncpy(user, data->set.str[STRING_USERNAME], MAX_CURL_USER_LENGTH);
3948     user[MAX_CURL_USER_LENGTH-1] = '\0';   /*To be on safe side*/
3949   }
3950   if(data->set.str[STRING_PASSWORD] != NULL) {
3951     strncpy(passwd, data->set.str[STRING_PASSWORD], MAX_CURL_PASSWORD_LENGTH);
3952     passwd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/
3953   }
3954 
3955   conn->bits.netrc = FALSE;
3956   if(data->set.use_netrc != CURL_NETRC_IGNORED) {
3957     if(Curl_parsenetrc(conn->host.name,
3958                        user, passwd,
3959                        data->set.str[STRING_NETRC_FILE])) {
3960       infof(data, "Couldn't find host %s in the "
3961             DOT_CHAR "netrc file; using defaults\n",
3962             conn->host.name);
3963     }
3964     else {
3965       /* set bits.netrc TRUE to remember that we got the name from a .netrc
3966          file, so that it is safe to use even if we followed a Location: to a
3967          different host or similar. */
3968       conn->bits.netrc = TRUE;
3969 
3970       conn->bits.user_passwd = 1; /* enable user+password */
3971     }
3972   }
3973 }
3974 
3975 /*
3976  * Set password so it's available in the connection.
3977  */
set_userpass(struct connectdata * conn,const char * user,const char * passwd)3978 static CURLcode set_userpass(struct connectdata *conn,
3979                              const char *user, const char *passwd)
3980 {
3981   /* If our protocol needs a password and we have none, use the defaults */
3982   if( (conn->protocol & PROT_FTP) &&
3983        !conn->bits.user_passwd) {
3984 
3985     conn->user = strdup(CURL_DEFAULT_USER);
3986     conn->passwd = strdup(CURL_DEFAULT_PASSWORD);
3987     /* This is the default password, so DON'T set conn->bits.user_passwd */
3988   }
3989   else {
3990     /* store user + password, zero-length if not set */
3991     conn->user = strdup(user);
3992     conn->passwd = strdup(passwd);
3993   }
3994   if(!conn->user || !conn->passwd)
3995     return CURLE_OUT_OF_MEMORY;
3996 
3997   return CURLE_OK;
3998 }
3999 
4000 /*************************************************************
4001  * Resolve the address of the server or proxy
4002  *************************************************************/
resolve_server(struct SessionHandle * data,struct connectdata * conn,struct Curl_dns_entry ** addr,bool * async)4003 static CURLcode resolve_server(struct SessionHandle *data,
4004                                struct connectdata *conn,
4005                                struct Curl_dns_entry **addr,
4006                                bool *async)
4007 {
4008   CURLcode result=CURLE_OK;
4009   long shortest = 0; /* default to no timeout */
4010 
4011   /*************************************************************
4012    * Set timeout if that is being used
4013    *************************************************************/
4014   if(data->set.timeout || data->set.connecttimeout) {
4015 
4016     /* We set the timeout on the name resolving phase first, separately from
4017      * the download/upload part to allow a maximum time on everything. This is
4018      * a signal-based timeout, why it won't work and shouldn't be used in
4019      * multi-threaded environments. */
4020 
4021     shortest = data->set.timeout; /* default to this timeout value */
4022     if(shortest && data->set.connecttimeout &&
4023        (data->set.connecttimeout < shortest))
4024       /* if both are set, pick the shortest */
4025       shortest = data->set.connecttimeout;
4026     else if(!shortest)
4027       /* if timeout is not set, use the connect timeout */
4028       shortest = data->set.connecttimeout;
4029   /* We can expect the conn->created time to be "now", as that was just
4030      recently set in the beginning of this function and nothing slow
4031      has been done since then until now. */
4032   }
4033 
4034   /*************************************************************
4035    * Resolve the name of the server or proxy
4036    *************************************************************/
4037   if(conn->bits.reuse) {
4038     /* re-used connection, no resolving is necessary */
4039     *addr = NULL;
4040     /* we'll need to clear conn->dns_entry later in Curl_disconnect() */
4041 
4042     if(conn->bits.proxy)
4043       fix_hostname(data, conn, &conn->host);
4044   }
4045   else {
4046     /* this is a fresh connect */
4047     int rc;
4048     struct Curl_dns_entry *hostaddr;
4049 
4050     /* set a pointer to the hostname we display */
4051     fix_hostname(data, conn, &conn->host);
4052 
4053     if(!conn->proxy.name || !*conn->proxy.name) {
4054       /* If not connecting via a proxy, extract the port from the URL, if it is
4055        * there, thus overriding any defaults that might have been set above. */
4056       conn->port =  conn->remote_port; /* it is the same port */
4057 
4058       /* Resolve target host right on */
4059       rc = Curl_resolv_timeout(conn, conn->host.name, (int)conn->port,
4060                                &hostaddr, shortest);
4061       if(rc == CURLRESOLV_PENDING)
4062         *async = TRUE;
4063 
4064       else if (rc == CURLRESOLV_TIMEDOUT)
4065         result = CURLE_OPERATION_TIMEDOUT;
4066 
4067       else if(!hostaddr) {
4068         failf(data, "Couldn't resolve host '%s'", conn->host.dispname);
4069         result =  CURLE_COULDNT_RESOLVE_HOST;
4070         /* don't return yet, we need to clean up the timeout first */
4071       }
4072     }
4073     else {
4074       /* This is a proxy that hasn't been resolved yet. */
4075 
4076       /* IDN-fix the proxy name */
4077       fix_hostname(data, conn, &conn->proxy);
4078 
4079       /* resolve proxy */
4080       rc = Curl_resolv_timeout(conn, conn->proxy.name, (int)conn->port,
4081                                &hostaddr, shortest);
4082 
4083       if(rc == CURLRESOLV_PENDING)
4084         *async = TRUE;
4085 
4086       else if (rc == CURLRESOLV_TIMEDOUT)
4087         result = CURLE_OPERATION_TIMEDOUT;
4088 
4089       else if(!hostaddr) {
4090         failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname);
4091         result = CURLE_COULDNT_RESOLVE_PROXY;
4092         /* don't return yet, we need to clean up the timeout first */
4093       }
4094     }
4095     *addr = hostaddr;
4096   }
4097 
4098   return result;
4099 }
4100 
4101 /*
4102  * Cleanup the connection just allocated before we can move along and use the
4103  * previously existing one.  All relevant data is copied over and old_conn is
4104  * ready for freeing once this function returns.
4105  */
reuse_conn(struct connectdata * old_conn,struct connectdata * conn)4106 static void reuse_conn(struct connectdata *old_conn,
4107                        struct connectdata *conn)
4108 {
4109   if(old_conn->proxy.rawalloc)
4110     free(old_conn->proxy.rawalloc);
4111 
4112   /* free the SSL config struct from this connection struct as this was
4113      allocated in vain and is targeted for destruction */
4114   Curl_free_ssl_config(&old_conn->ssl_config);
4115 
4116   conn->data = old_conn->data;
4117 
4118   /* get the user+password information from the old_conn struct since it may
4119    * be new for this request even when we re-use an existing connection */
4120   conn->bits.user_passwd = old_conn->bits.user_passwd;
4121   if(conn->bits.user_passwd) {
4122     /* use the new user name and password though */
4123     Curl_safefree(conn->user);
4124     Curl_safefree(conn->passwd);
4125     conn->user = old_conn->user;
4126     conn->passwd = old_conn->passwd;
4127     old_conn->user = NULL;
4128     old_conn->passwd = NULL;
4129   }
4130 
4131   conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd;
4132   if(conn->bits.proxy_user_passwd) {
4133     /* use the new proxy user name and proxy password though */
4134     Curl_safefree(conn->proxyuser);
4135     Curl_safefree(conn->proxypasswd);
4136     conn->proxyuser = old_conn->proxyuser;
4137     conn->proxypasswd = old_conn->proxypasswd;
4138     old_conn->proxyuser = NULL;
4139     old_conn->proxypasswd = NULL;
4140   }
4141 
4142   /* host can change, when doing keepalive with a proxy ! */
4143   if(conn->bits.proxy) {
4144     free(conn->host.rawalloc);
4145     conn->host=old_conn->host;
4146   }
4147   else
4148     free(old_conn->host.rawalloc); /* free the newly allocated name buffer */
4149 
4150   /* re-use init */
4151   conn->bits.reuse = TRUE; /* yes, we're re-using here */
4152 
4153   Curl_safefree(old_conn->user);
4154   Curl_safefree(old_conn->passwd);
4155   Curl_safefree(old_conn->proxyuser);
4156   Curl_safefree(old_conn->proxypasswd);
4157   Curl_llist_destroy(old_conn->send_pipe, NULL);
4158   Curl_llist_destroy(old_conn->recv_pipe, NULL);
4159   Curl_llist_destroy(old_conn->pend_pipe, NULL);
4160   Curl_safefree(old_conn->master_buffer);
4161 }
4162 
4163 /**
4164  * create_conn() sets up a new connectdata struct, or re-uses an already
4165  * existing one, and resolves host name.
4166  *
4167  * if this function returns CURLE_OK and *async is set to TRUE, the resolve
4168  * response will be coming asynchronously. If *async is FALSE, the name is
4169  * already resolved.
4170  *
4171  * @param data The sessionhandle pointer
4172  * @param in_connect is set to the next connection data pointer
4173  * @param addr is set to the new dns entry for this connection. If this
4174  *        connection is re-used it will be NULL.
4175  * @param async is set TRUE/FALSE depending on the nature of this lookup
4176  * @return CURLcode
4177  * @see setup_conn()
4178  *
4179  * *NOTE* this function assigns the conn->data pointer!
4180  */
4181 
create_conn(struct SessionHandle * data,struct connectdata ** in_connect,struct Curl_dns_entry ** addr,bool * async)4182 static CURLcode create_conn(struct SessionHandle *data,
4183                             struct connectdata **in_connect,
4184                             struct Curl_dns_entry **addr,
4185                             bool *async)
4186 {
4187   CURLcode result=CURLE_OK;
4188   struct connectdata *conn;
4189   struct connectdata *conn_temp = NULL;
4190   size_t urllen;
4191   char user[MAX_CURL_USER_LENGTH];
4192   char passwd[MAX_CURL_PASSWORD_LENGTH];
4193   bool reuse;
4194   char *proxy = NULL;
4195 
4196   *addr = NULL; /* nothing yet */
4197   *async = FALSE;
4198 
4199   /*************************************************************
4200    * Check input data
4201    *************************************************************/
4202 
4203   if(!data->change.url)
4204     return CURLE_URL_MALFORMAT;
4205 
4206   /* First, split up the current URL in parts so that we can use the
4207      parts for checking against the already present connections. In order
4208      to not have to modify everything at once, we allocate a temporary
4209      connection data struct and fill in for comparison purposes. */
4210 
4211   conn = allocate_conn();
4212 
4213   /* We must set the return variable as soon as possible, so that our
4214      parent can cleanup any possible allocs we may have done before
4215      any failure */
4216   *in_connect = conn;
4217 
4218   if(!conn)
4219     return CURLE_OUT_OF_MEMORY;
4220 
4221   conn->data = data; /* Setup the association between this connection
4222                         and the SessionHandle */
4223 
4224   conn->proxytype = data->set.proxytype; /* type */
4225 
4226 #ifdef CURL_DISABLE_PROXY
4227 
4228   conn->bits.proxy = FALSE;
4229   conn->bits.httpproxy = FALSE;
4230   conn->bits.proxy_user_passwd = FALSE;
4231   conn->bits.tunnel_proxy = FALSE;
4232 
4233 #else /* CURL_DISABLE_PROXY */
4234 
4235   conn->bits.proxy = (bool)(data->set.str[STRING_PROXY] &&
4236                             *data->set.str[STRING_PROXY]);
4237   conn->bits.httpproxy = (bool)(conn->bits.proxy &&
4238                                 (conn->proxytype == CURLPROXY_HTTP ||
4239                                  conn->proxytype == CURLPROXY_HTTP_1_0));
4240   conn->bits.proxy_user_passwd =
4241     (bool)(NULL != data->set.str[STRING_PROXYUSERNAME]);
4242   conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
4243 
4244 #endif /* CURL_DISABLE_PROXY */
4245 
4246   conn->bits.user_passwd = (bool)(NULL != data->set.str[STRING_USERNAME]);
4247   conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
4248   conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
4249 
4250   if(data->multi && Curl_multi_canPipeline(data->multi) &&
4251       !conn->master_buffer) {
4252     /* Allocate master_buffer to be used for pipelining */
4253     conn->master_buffer = calloc(BUFSIZE, sizeof (char));
4254     if(!conn->master_buffer)
4255       return CURLE_OUT_OF_MEMORY;
4256   }
4257 
4258   /* Initialize the pipeline lists */
4259   conn->send_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
4260   conn->recv_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
4261   conn->pend_pipe = Curl_llist_alloc((curl_llist_dtor) llist_dtor);
4262   if(!conn->send_pipe || !conn->recv_pipe || !conn->pend_pipe)
4263     return CURLE_OUT_OF_MEMORY;
4264 
4265   /* This initing continues below, see the comment "Continue connectdata
4266    * initialization here" */
4267 
4268   /***********************************************************
4269    * We need to allocate memory to store the path in. We get the size of the
4270    * full URL to be sure, and we need to make it at least 256 bytes since
4271    * other parts of the code will rely on this fact
4272    ***********************************************************/
4273 #define LEAST_PATH_ALLOC 256
4274   urllen=strlen(data->change.url);
4275   if(urllen < LEAST_PATH_ALLOC)
4276     urllen=LEAST_PATH_ALLOC;
4277 
4278   /*
4279    * We malloc() the buffers below urllen+2 to make room for to possibilities:
4280    * 1 - an extra terminating zero
4281    * 2 - an extra slash (in case a syntax like "www.host.com?moo" is used)
4282    */
4283 
4284   Curl_safefree(data->state.pathbuffer);
4285   data->state.pathbuffer = malloc(urllen+2);
4286   if(NULL == data->state.pathbuffer)
4287     return CURLE_OUT_OF_MEMORY; /* really bad error */
4288   data->state.path = data->state.pathbuffer;
4289 
4290   conn->host.rawalloc = malloc(urllen+2);
4291   if(NULL == conn->host.rawalloc)
4292     return CURLE_OUT_OF_MEMORY;
4293 
4294   conn->host.name = conn->host.rawalloc;
4295   conn->host.name[0] = 0;
4296 
4297   result = ParseURLAndFillConnection(data, conn);
4298   if(result != CURLE_OK) {
4299       return result;
4300   }
4301 
4302 #ifndef CURL_DISABLE_PROXY
4303   /*************************************************************
4304    * Extract the user and password from the authentication string
4305    *************************************************************/
4306   if(conn->bits.proxy_user_passwd) {
4307     result = parse_proxy_auth(data, conn);
4308     if(result != CURLE_OK)
4309         return result;
4310   }
4311 
4312   /*************************************************************
4313    * Detect what (if any) proxy to use
4314    *************************************************************/
4315   if(data->set.str[STRING_PROXY]) {
4316     proxy = strdup(data->set.str[STRING_PROXY]);
4317     /* if global proxy is set, this is it */
4318     if(NULL == proxy) {
4319       failf(data, "memory shortage");
4320       return CURLE_OUT_OF_MEMORY;
4321     }
4322   }
4323 
4324   if(!proxy)
4325     proxy = detect_proxy(conn);
4326   else if(data->set.str[STRING_NOPROXY]) {
4327     if(check_noproxy(conn->host.name, data->set.str[STRING_NOPROXY])) {
4328       free(proxy);  /* proxy is in exception list */
4329       proxy = NULL;
4330     }
4331   }
4332   if(proxy && !*proxy) {
4333     free(proxy);  /* Don't bother with an empty proxy string */
4334     proxy = NULL;
4335   }
4336   /* proxy must be freed later unless NULL */
4337   if(proxy && *proxy) {
4338     long bits = conn->protocol & (PROT_HTTPS|PROT_SSL|PROT_MISSING);
4339 
4340     if((conn->proxytype == CURLPROXY_HTTP) ||
4341        (conn->proxytype == CURLPROXY_HTTP_1_0)) {
4342       /* force this connection's protocol to become HTTP */
4343       conn->protocol = PROT_HTTP | bits;
4344       conn->bits.httpproxy = TRUE;
4345     }
4346     conn->bits.proxy = TRUE;
4347   }
4348   else {
4349       /* we aren't using the proxy after all... */
4350       conn->bits.proxy = FALSE;
4351       conn->bits.httpproxy = FALSE;
4352       conn->bits.proxy_user_passwd = FALSE;
4353       conn->bits.tunnel_proxy = FALSE;
4354   }
4355 #endif /* CURL_DISABLE_PROXY */
4356 
4357   /*************************************************************
4358    * No protocol part in URL was used, add it!
4359    *************************************************************/
4360   if(conn->protocol&PROT_MISSING) {
4361     /* We're guessing prefixes here and if we're told to use a proxy or if
4362        we're gonna follow a Location: later or... then we need the protocol
4363        part added so that we have a valid URL. */
4364     char *reurl;
4365 
4366     reurl = aprintf("%s://%s", conn->protostr, data->change.url);
4367 
4368     if(!reurl) {
4369       Curl_safefree(proxy);
4370       return CURLE_OUT_OF_MEMORY;
4371     }
4372 
4373     data->change.url = reurl;
4374     data->change.url_alloc = TRUE; /* free this later */
4375     conn->protocol &= ~PROT_MISSING; /* switch that one off again */
4376   }
4377 
4378   /*************************************************************
4379    * Setup internals depending on protocol
4380    *************************************************************/
4381   result = setup_connection_internals(data, conn);
4382   if(result != CURLE_OK) {
4383     Curl_safefree(proxy);
4384     return result;
4385   }
4386 
4387 
4388 #ifndef CURL_DISABLE_PROXY
4389   /***********************************************************************
4390    * If this is supposed to use a proxy, we need to figure out the proxy
4391    * host name, so that we can re-use an existing connection
4392    * that may exist registered to the same proxy host.
4393    ***********************************************************************/
4394   if(proxy) {
4395     result = parse_proxy(data, conn, proxy);
4396     /* parse_proxy has freed the proxy string, so don't try to use it again */
4397     proxy = NULL;
4398     if(result != CURLE_OK)
4399       return result;
4400   }
4401 #endif /* CURL_DISABLE_PROXY */
4402 
4403   /***********************************************************************
4404    * file: is a special case in that it doesn't need a network connection
4405    ***********************************************************************/
4406 #ifndef CURL_DISABLE_FILE
4407   if(conn->protocol & PROT_FILE) {
4408     bool done;
4409     /* this is supposed to be the connect function so we better at least check
4410        that the file is present here! */
4411     DEBUGASSERT(conn->handler->connect_it);
4412     result = conn->handler->connect_it(conn, &done);
4413 
4414     /* Setup a "faked" transfer that'll do nothing */
4415     if(CURLE_OK == result) {
4416       conn->data = data;
4417       conn->bits.tcpconnect = TRUE; /* we are "connected */
4418 
4419       ConnectionStore(data, conn);
4420 
4421       /*
4422        * Setup whatever necessary for a resumed transfer
4423        */
4424       result = setup_range(data);
4425       if(result) {
4426         DEBUGASSERT(conn->handler->done);
4427         /* we ignore the return code for the protocol-specific DONE */
4428         (void)conn->handler->done(conn, result, FALSE);
4429         return result;
4430       }
4431 
4432       result = Curl_setup_transfer(conn, -1, -1, FALSE,
4433                                    NULL, /* no download */
4434                                    -1, NULL); /* no upload */
4435     }
4436 
4437     return result;
4438   }
4439 #endif
4440 
4441   /*************************************************************
4442    * If the protocol is using SSL and HTTP proxy is used, we set
4443    * the tunnel_proxy bit.
4444    *************************************************************/
4445   if((conn->protocol&PROT_SSL) && conn->bits.httpproxy)
4446     conn->bits.tunnel_proxy = TRUE;
4447 
4448   /*************************************************************
4449    * Parse a user name and password in the URL and strip it out
4450    * of the host name
4451    *************************************************************/
4452   result = parse_url_userpass(data, conn, user, passwd);
4453   if(result != CURLE_OK)
4454     return result;
4455 
4456   /*************************************************************
4457    * Figure out the remote port number and fix it in the URL
4458    *************************************************************/
4459   result = parse_remote_port(data, conn);
4460   if(result != CURLE_OK)
4461     return result;
4462 
4463   /*************************************************************
4464    * Check for an overridden user name and password, then set it
4465    * for use
4466    *************************************************************/
4467   override_userpass(data, conn, user, passwd);
4468   result = set_userpass(conn, user, passwd);
4469   if(result != CURLE_OK)
4470     return result;
4471 
4472   /*************************************************************
4473    * Check the current list of connections to see if we can
4474    * re-use an already existing one or if we have to create a
4475    * new one.
4476    *************************************************************/
4477 
4478   /* Get a cloned copy of the SSL config situation stored in the
4479      connection struct. But to get this going nicely, we must first make
4480      sure that the strings in the master copy are pointing to the correct
4481      strings in the session handle strings array!
4482 
4483      Keep in mind that the pointers in the master copy are pointing to strings
4484      that will be freed as part of the SessionHandle struct, but all cloned
4485      copies will be separately allocated.
4486   */
4487   data->set.ssl.CApath = data->set.str[STRING_SSL_CAPATH];
4488   data->set.ssl.CAfile = data->set.str[STRING_SSL_CAFILE];
4489   data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE];
4490   data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT];
4491   data->set.ssl.random_file = data->set.str[STRING_SSL_RANDOM_FILE];
4492   data->set.ssl.egdsocket = data->set.str[STRING_SSL_EGDSOCKET];
4493   data->set.ssl.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST];
4494 
4495   if(!Curl_clone_ssl_config(&data->set.ssl, &conn->ssl_config))
4496     return CURLE_OUT_OF_MEMORY;
4497 
4498   /* reuse_fresh is TRUE if we are told to use a new connection by force, but
4499      we only acknowledge this option if this is not a re-used connection
4500      already (which happens due to follow-location or during a HTTP
4501      authentication phase). */
4502   if(data->set.reuse_fresh && !data->state.this_is_a_follow)
4503     reuse = FALSE;
4504   else
4505     reuse = ConnectionExists(data, conn, &conn_temp);
4506 
4507   if(reuse) {
4508     /*
4509      * We already have a connection for this, we got the former connection
4510      * in the conn_temp variable and thus we need to cleanup the one we
4511      * just allocated before we can move along and use the previously
4512      * existing one.
4513      */
4514     reuse_conn(conn, conn_temp);
4515     free(conn);          /* we don't need this anymore */
4516     conn = conn_temp;
4517     *in_connect = conn;
4518     infof(data, "Re-using existing connection! (#%ld) with host %s\n",
4519           conn->connectindex,
4520           conn->proxy.name?conn->proxy.dispname:conn->host.dispname);
4521     /* copy this IP address to the common buffer for the easy handle so that
4522        the address can actually survice the removal of this connection. strcpy
4523        is safe since the target buffer is big enough to hold the largest
4524        possible IP address */
4525     strcpy(data->info.ip, conn->ip_addr_str);
4526 
4527   }
4528   else {
4529     /*
4530      * This is a brand new connection, so let's store it in the connection
4531      * cache of ours!
4532      */
4533     ConnectionStore(data, conn);
4534   }
4535 
4536   /*
4537    * Setup whatever necessary for a resumed transfer
4538    */
4539   result = setup_range(data);
4540   if(result)
4541     return result;
4542 
4543   /* Continue connectdata initialization here. */
4544 
4545   /*
4546    * Inherit the proper values from the urldata struct AFTER we have arranged
4547    * the persistent connection stuff
4548    */
4549   conn->fread_func = data->set.fread_func;
4550   conn->fread_in = data->set.in;
4551   conn->seek_func = data->set.seek_func;
4552   conn->seek_client = data->set.seek_client;
4553 
4554   /*************************************************************
4555    * Resolve the address of the server or proxy
4556    *************************************************************/
4557   result = resolve_server(data, conn, addr, async);
4558 
4559   return result;
4560 }
4561 
4562 /* setup_conn() is called after the name resolve initiated in
4563  * create_conn() is all done.
4564  *
4565  * NOTE: the argument 'hostaddr' is NULL when this function is called for a
4566  * re-used connection.
4567  *
4568  * conn->data MUST already have been setup fine (in create_conn)
4569  */
4570 
setup_conn(struct connectdata * conn,struct Curl_dns_entry * hostaddr,bool * protocol_done)4571 static CURLcode setup_conn(struct connectdata *conn,
4572                            struct Curl_dns_entry *hostaddr,
4573                            bool *protocol_done)
4574 {
4575   CURLcode result=CURLE_OK;
4576   struct SessionHandle *data = conn->data;
4577 
4578   Curl_pgrsTime(data, TIMER_NAMELOOKUP);
4579 
4580   if(conn->protocol & PROT_FILE) {
4581     /* There's nothing in this function to setup if we're only doing
4582        a file:// transfer */
4583     *protocol_done = TRUE;
4584     return result;
4585   }
4586   *protocol_done = FALSE; /* default to not done */
4587 
4588   /* set proxy_connect_closed to false unconditionally already here since it
4589      is used strictly to provide extra information to a parent function in the
4590      case of proxy CONNECT failures and we must make sure we don't have it
4591      lingering set from a previous invoke */
4592   conn->bits.proxy_connect_closed = FALSE;
4593 
4594   /*
4595    * Set user-agent. Used for HTTP, but since we can attempt to tunnel
4596    * basically anything through a http proxy we can't limit this based on
4597    * protocol.
4598    */
4599   if(data->set.str[STRING_USERAGENT]) {
4600     Curl_safefree(conn->allocptr.uagent);
4601     conn->allocptr.uagent =
4602       aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]);
4603     if(!conn->allocptr.uagent)
4604       return CURLE_OUT_OF_MEMORY;
4605   }
4606 
4607   data->req.headerbytecount = 0;
4608 
4609 #ifdef CURL_DO_LINEEND_CONV
4610   data->state.crlf_conversions = 0; /* reset CRLF conversion counter */
4611 #endif /* CURL_DO_LINEEND_CONV */
4612 
4613   for(;;) {
4614     /* loop for CURL_SERVER_CLOSED_CONNECTION */
4615 
4616     if(CURL_SOCKET_BAD == conn->sock[FIRSTSOCKET]) {
4617       bool connected = FALSE;
4618 
4619       /* Connect only if not already connected!
4620        *
4621        * NOTE: hostaddr can be NULL when passed to this function, but that is
4622        * only for the case where we re-use an existing connection and thus
4623        * this code section will not be reached with hostaddr == NULL.
4624        */
4625       result = ConnectPlease(data, conn, hostaddr, &connected);
4626 
4627       if(connected) {
4628         result = Curl_protocol_connect(conn, protocol_done);
4629         if(CURLE_OK == result)
4630           conn->bits.tcpconnect = TRUE;
4631       }
4632       else
4633         conn->bits.tcpconnect = FALSE;
4634 
4635       /* if the connection was closed by the server while exchanging
4636          authentication informations, retry with the new set
4637          authentication information */
4638       if(conn->bits.proxy_connect_closed) {
4639         /* reset the error buffer */
4640         if(data->set.errorbuffer)
4641           data->set.errorbuffer[0] = '\0';
4642         data->state.errorbuf = FALSE;
4643         continue;
4644       }
4645 
4646       if(CURLE_OK != result)
4647         return result;
4648     }
4649     else {
4650       Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
4651       Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */
4652       conn->bits.tcpconnect = TRUE;
4653       *protocol_done = TRUE;
4654       if(data->set.verbose)
4655         verboseconnect(conn);
4656     }
4657     /* Stop the loop now */
4658     break;
4659   }
4660 
4661   conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
4662                                set this here perhaps a second time */
4663 
4664 #ifdef __EMX__
4665   /*
4666    * This check is quite a hack. We're calling _fsetmode to fix the problem
4667    * with fwrite converting newline characters (you get mangled text files,
4668    * and corrupted binary files when you download to stdout and redirect it to
4669    * a file).
4670    */
4671 
4672   if((data->set.out)->_handle == NULL) {
4673     _fsetmode(stdout, "b");
4674   }
4675 #endif
4676 
4677   return result;
4678 }
4679 
Curl_connect(struct SessionHandle * data,struct connectdata ** in_connect,bool * asyncp,bool * protocol_done)4680 CURLcode Curl_connect(struct SessionHandle *data,
4681                       struct connectdata **in_connect,
4682                       bool *asyncp,
4683                       bool *protocol_done)
4684 {
4685   CURLcode code;
4686   struct Curl_dns_entry *dns;
4687 
4688   *asyncp = FALSE; /* assume synchronous resolves by default */
4689 
4690   /* call the stuff that needs to be called */
4691   code = create_conn(data, in_connect, &dns, asyncp);
4692 
4693   if(CURLE_OK == code) {
4694     /* no error */
4695     if((*in_connect)->send_pipe->size || (*in_connect)->recv_pipe->size)
4696       /* pipelining */
4697       *protocol_done = TRUE;
4698     else {
4699 
4700       if(dns || !*asyncp)
4701         /* If an address is available it means that we already have the name
4702            resolved, OR it isn't async. if this is a re-used connection 'dns'
4703            will be NULL here. Continue connecting from here */
4704         code = setup_conn(*in_connect, dns, protocol_done);
4705 
4706       if(dns && code) {
4707         /* We have the dns entry info already but failed to connect to the
4708          * host and thus we must make sure to unlock the dns entry again
4709          * before returning failure from here.
4710          */
4711         Curl_resolv_unlock(data, dns);
4712       }
4713     }
4714   }
4715 
4716   if(code && *in_connect) {
4717     /* We're not allowed to return failure with memory left allocated
4718        in the connectdata struct, free those here */
4719     Curl_disconnect(*in_connect); /* close the connection */
4720     *in_connect = NULL;           /* return a NULL */
4721   }
4722 
4723   return code;
4724 }
4725 
4726 /* Call this function after Curl_connect() has returned async=TRUE and
4727    then a successful name resolve has been received.
4728 
4729    Note: this function disconnects and frees the conn data in case of
4730    resolve failure */
Curl_async_resolved(struct connectdata * conn,bool * protocol_done)4731 CURLcode Curl_async_resolved(struct connectdata *conn,
4732                              bool *protocol_done)
4733 {
4734 #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \
4735     defined(USE_THREADING_GETADDRINFO)
4736   CURLcode code = setup_conn(conn, conn->async.dns, protocol_done);
4737 
4738   if(code)
4739     /* We're not allowed to return failure with memory left allocated
4740        in the connectdata struct, free those here */
4741     Curl_disconnect(conn); /* close the connection */
4742 
4743   return code;
4744 #else
4745   (void)conn;
4746   (void)protocol_done;
4747   return CURLE_OK;
4748 #endif
4749 }
4750 
4751 
Curl_done(struct connectdata ** connp,CURLcode status,bool premature)4752 CURLcode Curl_done(struct connectdata **connp,
4753                    CURLcode status,  /* an error if this is called after an
4754                                         error was detected */
4755                    bool premature)
4756 {
4757   CURLcode result;
4758   struct connectdata *conn;
4759   struct SessionHandle *data;
4760 
4761   DEBUGASSERT(*connp);
4762 
4763   conn = *connp;
4764   data = conn->data;
4765 
4766   Curl_expire(data, 0); /* stop timer */
4767 
4768   Curl_getoff_all_pipelines(data, conn);
4769 
4770   if(conn->bits.done ||
4771      (conn->send_pipe->size + conn->recv_pipe->size != 0 &&
4772       !data->set.reuse_forbid &&
4773       !conn->bits.close))
4774     /* Stop if Curl_done() has already been called or pipeline
4775        is not empty and we do not have to close connection. */
4776     return CURLE_OK;
4777 
4778   conn->bits.done = TRUE; /* called just now! */
4779 
4780   /* Cleanup possible redirect junk */
4781   if(data->req.newurl) {
4782     free(data->req.newurl);
4783     data->req.newurl = NULL;
4784   }
4785   if(data->req.location) {
4786     free(data->req.location);
4787     data->req.location = NULL;
4788   }
4789 
4790   if(conn->dns_entry) {
4791     Curl_resolv_unlock(data, conn->dns_entry); /* done with this */
4792     conn->dns_entry = NULL;
4793   }
4794 
4795   /* this calls the protocol-specific function pointer previously set */
4796   if(conn->handler->done)
4797     result = conn->handler->done(conn, status, premature);
4798   else
4799     result = CURLE_OK;
4800 
4801   Curl_pgrsDone(conn); /* done with the operation */
4802 
4803   /* if the transfer was completed in a paused state there can be buffered
4804      data left to write and then kill */
4805   if(data->state.tempwrite) {
4806     free(data->state.tempwrite);
4807     data->state.tempwrite = NULL;
4808   }
4809 
4810   /* for ares-using, make sure all possible outstanding requests are properly
4811      cancelled before we proceed */
4812   ares_cancel(data->state.areschannel);
4813 
4814   /* if data->set.reuse_forbid is TRUE, it means the libcurl client has
4815      forced us to close this no matter what we think.
4816 
4817      if conn->bits.close is TRUE, it means that the connection should be
4818      closed in spite of all our efforts to be nice, due to protocol
4819      restrictions in our or the server's end
4820 
4821      if premature is TRUE, it means this connection was said to be DONE before
4822      the entire request operation is complete and thus we can't know in what
4823      state it is for re-using, so we're forced to close it. In a perfect world
4824      we can add code that keep track of if we really must close it here or not,
4825      but currently we have no such detail knowledge.
4826 
4827      connectindex == -1 here means that the connection has no spot in the
4828      connection cache and thus we must disconnect it here.
4829   */
4830   if(data->set.reuse_forbid || conn->bits.close || premature ||
4831      (-1 == conn->connectindex)) {
4832     CURLcode res2 = Curl_disconnect(conn); /* close the connection */
4833 
4834     /* If we had an error already, make sure we return that one. But
4835        if we got a new error, return that. */
4836     if(!result && res2)
4837       result = res2;
4838   }
4839   else {
4840     ConnectionDone(conn); /* the connection is no longer in use */
4841 
4842     /* remember the most recently used connection */
4843     data->state.lastconnect = conn->connectindex;
4844 
4845     infof(data, "Connection #%ld to host %s left intact\n",
4846           conn->connectindex,
4847           conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname);
4848   }
4849 
4850   *connp = NULL; /* to make the caller of this function better detect that
4851                     this was either closed or handed over to the connection
4852                     cache here, and therefore cannot be used from this point on
4853                  */
4854 
4855   return result;
4856 }
4857 
4858 /*
4859  * do_init() inits the readwrite session. This is inited each time (in the DO
4860  * function before the protocol-specific DO functions are invoked) for a
4861  * transfer, sometimes multiple times on the same SessionHandle. Make sure
4862  * nothing in here depends on stuff that are setup dynamically for the
4863  * transfer.
4864  */
4865 
do_init(struct connectdata * conn)4866 static CURLcode do_init(struct connectdata *conn)
4867 {
4868   struct SessionHandle *data = conn->data;
4869   struct SingleRequest *k = &data->req;
4870 
4871   conn->bits.done = FALSE; /* Curl_done() is not called yet */
4872   conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */
4873   data->state.expect100header = FALSE;
4874 
4875   /* NB: the content encoding software depends on this initialization */
4876   Curl_easy_initHandleData(data);
4877 
4878   k->start = Curl_tvnow(); /* start time */
4879   k->now = k->start;   /* current time is now */
4880   k->header = TRUE; /* assume header */
4881 
4882   k->bytecount = 0;
4883 
4884   k->buf = data->state.buffer;
4885   k->uploadbuf = data->state.uploadbuffer;
4886   k->hbufp = data->state.headerbuff;
4887   k->ignorebody=FALSE;
4888 
4889   Curl_pgrsTime(data, TIMER_PRETRANSFER);
4890   Curl_speedinit(data);
4891 
4892   Curl_pgrsSetUploadCounter(data, 0);
4893   Curl_pgrsSetDownloadCounter(data, 0);
4894 
4895   return CURLE_OK;
4896 }
4897 
4898 /*
4899  * do_complete is called when the DO actions are complete.
4900  *
4901  * We init chunking and trailer bits to their default values here immediately
4902  * before receiving any header data for the current request in the pipeline.
4903  */
do_complete(struct connectdata * conn)4904 static void do_complete(struct connectdata *conn)
4905 {
4906   conn->data->req.chunk=FALSE;
4907   conn->data->req.trailerhdrpresent=FALSE;
4908 
4909   conn->data->req.maxfd = (conn->sockfd>conn->writesockfd?
4910                                conn->sockfd:conn->writesockfd)+1;
4911 }
4912 
Curl_do(struct connectdata ** connp,bool * done)4913 CURLcode Curl_do(struct connectdata **connp, bool *done)
4914 {
4915   CURLcode result=CURLE_OK;
4916   struct connectdata *conn = *connp;
4917   struct SessionHandle *data = conn->data;
4918 
4919   /* setup and init stuff before DO starts, in preparing for the transfer */
4920   do_init(conn);
4921 
4922   if(conn->handler->do_it) {
4923     /* generic protocol-specific function pointer set in curl_connect() */
4924     result = conn->handler->do_it(conn, done);
4925 
4926     /* This was formerly done in transfer.c, but we better do it here */
4927     if((CURLE_SEND_ERROR == result) && conn->bits.reuse) {
4928       /* This was a re-use of a connection and we got a write error in the
4929        * DO-phase. Then we DISCONNECT this connection and have another attempt
4930        * to CONNECT and then DO again! The retry cannot possibly find another
4931        * connection to re-use, since we only keep one possible connection for
4932        * each.  */
4933 
4934       infof(data, "Re-used connection seems dead, get a new one\n");
4935 
4936       conn->bits.close = TRUE; /* enforce close of this connection */
4937       result = Curl_done(&conn, result, FALSE); /* we are so done with this */
4938 
4939       /* conn may no longer be a good pointer */
4940 
4941       /*
4942        * According to bug report #1330310. We need to check for
4943        * CURLE_SEND_ERROR here as well. I figure this could happen when the
4944        * request failed on a FTP connection and thus Curl_done() itself tried
4945        * to use the connection (again). Slight Lack of feedback in the report,
4946        * but I don't think this extra check can do much harm.
4947        */
4948       if((CURLE_OK == result) || (CURLE_SEND_ERROR == result)) {
4949         bool async;
4950         bool protocol_done = TRUE;
4951 
4952         /* Now, redo the connect and get a new connection */
4953         result = Curl_connect(data, connp, &async, &protocol_done);
4954         if(CURLE_OK == result) {
4955           /* We have connected or sent away a name resolve query fine */
4956 
4957           conn = *connp; /* setup conn to again point to something nice */
4958           if(async) {
4959             /* Now, if async is TRUE here, we need to wait for the name
4960                to resolve */
4961             result = Curl_wait_for_resolv(conn, NULL);
4962             if(result)
4963               return result;
4964 
4965             /* Resolved, continue with the connection */
4966             result = Curl_async_resolved(conn, &protocol_done);
4967             if(result)
4968               return result;
4969           }
4970 
4971           /* ... finally back to actually retry the DO phase */
4972           result = conn->handler->do_it(conn, done);
4973         }
4974       }
4975     }
4976 
4977     if((result == CURLE_OK) && *done)
4978       /* do_complete must be called after the protocol-specific DO function */
4979       do_complete(conn);
4980   }
4981   return result;
4982 }
4983 
Curl_do_more(struct connectdata * conn)4984 CURLcode Curl_do_more(struct connectdata *conn)
4985 {
4986   CURLcode result=CURLE_OK;
4987 
4988   if(conn->handler->do_more)
4989     result = conn->handler->do_more(conn);
4990 
4991   if(result == CURLE_OK)
4992     /* do_complete must be called after the protocol-specific DO function */
4993     do_complete(conn);
4994 
4995   return result;
4996 }
4997 
4998 /* Called on connect, and if there's already a protocol-specific struct
4999    allocated for a different connection, this frees it that it can be setup
5000    properly later on. */
Curl_reset_reqproto(struct connectdata * conn)5001 void Curl_reset_reqproto(struct connectdata *conn)
5002 {
5003   struct SessionHandle *data = conn->data;
5004   if(data->state.proto.generic && data->state.current_conn != conn) {
5005     free(data->state.proto.generic);
5006     data->state.proto.generic = NULL;
5007   }
5008   data->state.current_conn = conn;
5009 }
5010