FTP: remove krb4 support
[platform/upstream/curl.git] / lib / sendf.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2013, 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  ***************************************************************************/
22
23 #include "curl_setup.h"
24
25 #include <curl/curl.h>
26
27 #include "urldata.h"
28 #include "sendf.h"
29 #include "connect.h"
30 #include "sslgen.h"
31 #include "ssh.h"
32 #include "multiif.h"
33 #include "non-ascii.h"
34
35 #define _MPRINTF_REPLACE /* use the internal *printf() functions */
36 #include <curl/mprintf.h>
37
38 #include "curl_memory.h"
39 #include "strerror.h"
40
41 /* The last #include file should be: */
42 #include "memdebug.h"
43
44 #ifdef CURL_DO_LINEEND_CONV
45 /*
46  * convert_lineends() changes CRLF (\r\n) end-of-line markers to a single LF
47  * (\n), with special processing for CRLF sequences that are split between two
48  * blocks of data.  Remaining, bare CRs are changed to LFs.  The possibly new
49  * size of the data is returned.
50  */
51 static size_t convert_lineends(struct SessionHandle *data,
52                                char *startPtr, size_t size)
53 {
54   char *inPtr, *outPtr;
55
56   /* sanity check */
57   if((startPtr == NULL) || (size < 1)) {
58     return(size);
59   }
60
61   if(data->state.prev_block_had_trailing_cr) {
62     /* The previous block of incoming data
63        had a trailing CR, which was turned into a LF. */
64     if(*startPtr == '\n') {
65       /* This block of incoming data starts with the
66          previous block's LF so get rid of it */
67       memmove(startPtr, startPtr+1, size-1);
68       size--;
69       /* and it wasn't a bare CR but a CRLF conversion instead */
70       data->state.crlf_conversions++;
71     }
72     data->state.prev_block_had_trailing_cr = FALSE; /* reset the flag */
73   }
74
75   /* find 1st CR, if any */
76   inPtr = outPtr = memchr(startPtr, '\r', size);
77   if(inPtr) {
78     /* at least one CR, now look for CRLF */
79     while(inPtr < (startPtr+size-1)) {
80       /* note that it's size-1, so we'll never look past the last byte */
81       if(memcmp(inPtr, "\r\n", 2) == 0) {
82         /* CRLF found, bump past the CR and copy the NL */
83         inPtr++;
84         *outPtr = *inPtr;
85         /* keep track of how many CRLFs we converted */
86         data->state.crlf_conversions++;
87       }
88       else {
89         if(*inPtr == '\r') {
90           /* lone CR, move LF instead */
91           *outPtr = '\n';
92         }
93         else {
94           /* not a CRLF nor a CR, just copy whatever it is */
95           *outPtr = *inPtr;
96         }
97       }
98       outPtr++;
99       inPtr++;
100     } /* end of while loop */
101
102     if(inPtr < startPtr+size) {
103       /* handle last byte */
104       if(*inPtr == '\r') {
105         /* deal with a CR at the end of the buffer */
106         *outPtr = '\n'; /* copy a NL instead */
107         /* note that a CRLF might be split across two blocks */
108         data->state.prev_block_had_trailing_cr = TRUE;
109       }
110       else {
111         /* copy last byte */
112         *outPtr = *inPtr;
113       }
114       outPtr++;
115     }
116     if(outPtr < startPtr+size)
117       /* tidy up by null terminating the now shorter data */
118       *outPtr = '\0';
119
120     return(outPtr - startPtr);
121   }
122   return(size);
123 }
124 #endif /* CURL_DO_LINEEND_CONV */
125
126 /* Curl_infof() is for info message along the way */
127
128 void Curl_infof(struct SessionHandle *data, const char *fmt, ...)
129 {
130   if(data && data->set.verbose) {
131     va_list ap;
132     size_t len;
133     char print_buffer[2048 + 1];
134     va_start(ap, fmt);
135     vsnprintf(print_buffer, sizeof(print_buffer), fmt, ap);
136     va_end(ap);
137     len = strlen(print_buffer);
138     Curl_debug(data, CURLINFO_TEXT, print_buffer, len, NULL);
139   }
140 }
141
142 /* Curl_failf() is for messages stating why we failed.
143  * The message SHALL NOT include any LF or CR.
144  */
145
146 void Curl_failf(struct SessionHandle *data, const char *fmt, ...)
147 {
148   va_list ap;
149   size_t len;
150   va_start(ap, fmt);
151
152   vsnprintf(data->state.buffer, BUFSIZE, fmt, ap);
153
154   if(data->set.errorbuffer && !data->state.errorbuf) {
155     snprintf(data->set.errorbuffer, CURL_ERROR_SIZE, "%s", data->state.buffer);
156     data->state.errorbuf = TRUE; /* wrote error string */
157   }
158   if(data->set.verbose) {
159     len = strlen(data->state.buffer);
160     if(len < BUFSIZE - 1) {
161       data->state.buffer[len] = '\n';
162       data->state.buffer[++len] = '\0';
163     }
164     Curl_debug(data, CURLINFO_TEXT, data->state.buffer, len, NULL);
165   }
166
167   va_end(ap);
168 }
169
170 /* Curl_sendf() sends formated data to the server */
171 CURLcode Curl_sendf(curl_socket_t sockfd, struct connectdata *conn,
172                     const char *fmt, ...)
173 {
174   struct SessionHandle *data = conn->data;
175   ssize_t bytes_written;
176   size_t write_len;
177   CURLcode res = CURLE_OK;
178   char *s;
179   char *sptr;
180   va_list ap;
181   va_start(ap, fmt);
182   s = vaprintf(fmt, ap); /* returns an allocated string */
183   va_end(ap);
184   if(!s)
185     return CURLE_OUT_OF_MEMORY; /* failure */
186
187   bytes_written=0;
188   write_len = strlen(s);
189   sptr = s;
190
191   for(;;) {
192     /* Write the buffer to the socket */
193     res = Curl_write(conn, sockfd, sptr, write_len, &bytes_written);
194
195     if(CURLE_OK != res)
196       break;
197
198     if(data->set.verbose)
199       Curl_debug(data, CURLINFO_DATA_OUT, sptr, (size_t)bytes_written, conn);
200
201     if((size_t)bytes_written != write_len) {
202       /* if not all was written at once, we must advance the pointer, decrease
203          the size left and try again! */
204       write_len -= bytes_written;
205       sptr += bytes_written;
206     }
207     else
208       break;
209   }
210
211   free(s); /* free the output string */
212
213   return res;
214 }
215
216 /*
217  * Curl_write() is an internal write function that sends data to the
218  * server. Works with plain sockets, SCP, SSL or kerberos.
219  *
220  * If the write would block (CURLE_AGAIN), we return CURLE_OK and
221  * (*written == 0). Otherwise we return regular CURLcode value.
222  */
223 CURLcode Curl_write(struct connectdata *conn,
224                     curl_socket_t sockfd,
225                     const void *mem,
226                     size_t len,
227                     ssize_t *written)
228 {
229   ssize_t bytes_written;
230   CURLcode curlcode = CURLE_OK;
231   int num = (sockfd == conn->sock[SECONDARYSOCKET]);
232
233   bytes_written = conn->send[num](conn, num, mem, len, &curlcode);
234
235   *written = bytes_written;
236   if(bytes_written >= 0)
237     /* we completely ignore the curlcode value when subzero is not returned */
238     return CURLE_OK;
239
240   /* handle CURLE_AGAIN or a send failure */
241   switch(curlcode) {
242   case CURLE_AGAIN:
243     *written = 0;
244     return CURLE_OK;
245
246   case CURLE_OK:
247     /* general send failure */
248     return CURLE_SEND_ERROR;
249
250   default:
251     /* we got a specific curlcode, forward it */
252     return curlcode;
253   }
254 }
255
256 ssize_t Curl_send_plain(struct connectdata *conn, int num,
257                         const void *mem, size_t len, CURLcode *code)
258 {
259   curl_socket_t sockfd = conn->sock[num];
260   ssize_t bytes_written = swrite(sockfd, mem, len);
261
262   *code = CURLE_OK;
263   if(-1 == bytes_written) {
264     int err = SOCKERRNO;
265
266     if(
267 #ifdef WSAEWOULDBLOCK
268       /* This is how Windows does it */
269       (WSAEWOULDBLOCK == err)
270 #else
271       /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
272          due to its inability to send off data without blocking. We therefor
273          treat both error codes the same here */
274       (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
275 #endif
276       ) {
277       /* this is just a case of EWOULDBLOCK */
278       bytes_written=0;
279       *code = CURLE_AGAIN;
280     }
281     else {
282       failf(conn->data, "Send failure: %s",
283             Curl_strerror(conn, err));
284       conn->data->state.os_errno = err;
285       *code = CURLE_SEND_ERROR;
286     }
287   }
288   return bytes_written;
289 }
290
291 /*
292  * Curl_write_plain() is an internal write function that sends data to the
293  * server using plain sockets only. Otherwise meant to have the exact same
294  * proto as Curl_write()
295  */
296 CURLcode Curl_write_plain(struct connectdata *conn,
297                           curl_socket_t sockfd,
298                           const void *mem,
299                           size_t len,
300                           ssize_t *written)
301 {
302   ssize_t bytes_written;
303   CURLcode retcode;
304   int num = (sockfd == conn->sock[SECONDARYSOCKET]);
305
306   bytes_written = Curl_send_plain(conn, num, mem, len, &retcode);
307
308   *written = bytes_written;
309
310   return retcode;
311 }
312
313 ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
314                         size_t len, CURLcode *code)
315 {
316   curl_socket_t sockfd = conn->sock[num];
317   ssize_t nread = sread(sockfd, buf, len);
318
319   *code = CURLE_OK;
320   if(-1 == nread) {
321     int err = SOCKERRNO;
322
323     if(
324 #ifdef WSAEWOULDBLOCK
325       /* This is how Windows does it */
326       (WSAEWOULDBLOCK == err)
327 #else
328       /* errno may be EWOULDBLOCK or on some systems EAGAIN when it returned
329          due to its inability to send off data without blocking. We therefor
330          treat both error codes the same here */
331       (EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err)
332 #endif
333       ) {
334       /* this is just a case of EWOULDBLOCK */
335       *code = CURLE_AGAIN;
336     }
337     else {
338       failf(conn->data, "Recv failure: %s",
339             Curl_strerror(conn, err));
340       conn->data->state.os_errno = err;
341       *code = CURLE_RECV_ERROR;
342     }
343   }
344   return nread;
345 }
346
347 static CURLcode pausewrite(struct SessionHandle *data,
348                            int type, /* what type of data */
349                            const char *ptr,
350                            size_t len)
351 {
352   /* signalled to pause sending on this connection, but since we have data
353      we want to send we need to dup it to save a copy for when the sending
354      is again enabled */
355   struct SingleRequest *k = &data->req;
356   char *dupl = malloc(len);
357   if(!dupl)
358     return CURLE_OUT_OF_MEMORY;
359
360   memcpy(dupl, ptr, len);
361
362   /* store this information in the state struct for later use */
363   data->state.tempwrite = dupl;
364   data->state.tempwritesize = len;
365   data->state.tempwritetype = type;
366
367   /* mark the connection as RECV paused */
368   k->keepon |= KEEP_RECV_PAUSE;
369
370   DEBUGF(infof(data, "Pausing with %zu bytes in buffer for type %02x\n",
371                len, type));
372
373   return CURLE_OK;
374 }
375
376
377 /* Curl_client_write() sends data to the write callback(s)
378
379    The bit pattern defines to what "streams" to write to. Body and/or header.
380    The defines are in sendf.h of course.
381
382    If CURL_DO_LINEEND_CONV is enabled, data is converted IN PLACE to the
383    local character encoding.  This is a problem and should be changed in
384    the future to leave the original data alone.
385  */
386 CURLcode Curl_client_write(struct connectdata *conn,
387                            int type,
388                            char *ptr,
389                            size_t len)
390 {
391   struct SessionHandle *data = conn->data;
392   size_t wrote;
393
394   if(0 == len)
395     len = strlen(ptr);
396
397   /* If reading is actually paused, we're forced to append this chunk of data
398      to the already held data, but only if it is the same type as otherwise it
399      can't work and it'll return error instead. */
400   if(data->req.keepon & KEEP_RECV_PAUSE) {
401     size_t newlen;
402     char *newptr;
403     if(type != data->state.tempwritetype)
404       /* major internal confusion */
405       return CURLE_RECV_ERROR;
406
407     DEBUGASSERT(data->state.tempwrite);
408
409     /* figure out the new size of the data to save */
410     newlen = len + data->state.tempwritesize;
411     /* allocate the new memory area */
412     newptr = realloc(data->state.tempwrite, newlen);
413     if(!newptr)
414       return CURLE_OUT_OF_MEMORY;
415     /* copy the new data to the end of the new area */
416     memcpy(newptr + data->state.tempwritesize, ptr, len);
417     /* update the pointer and the size */
418     data->state.tempwrite = newptr;
419     data->state.tempwritesize = newlen;
420
421     return CURLE_OK;
422   }
423
424   if(type & CLIENTWRITE_BODY) {
425     if((conn->handler->protocol&CURLPROTO_FTP) &&
426        conn->proto.ftpc.transfertype == 'A') {
427       /* convert from the network encoding */
428       CURLcode rc = Curl_convert_from_network(data, ptr, len);
429       /* Curl_convert_from_network calls failf if unsuccessful */
430       if(rc)
431         return rc;
432
433 #ifdef CURL_DO_LINEEND_CONV
434       /* convert end-of-line markers */
435       len = convert_lineends(data, ptr, len);
436 #endif /* CURL_DO_LINEEND_CONV */
437     }
438     /* If the previous block of data ended with CR and this block of data is
439        just a NL, then the length might be zero */
440     if(len) {
441       wrote = data->set.fwrite_func(ptr, 1, len, data->set.out);
442     }
443     else {
444       wrote = len;
445     }
446
447     if(CURL_WRITEFUNC_PAUSE == wrote)
448       return pausewrite(data, type, ptr, len);
449
450     if(wrote != len) {
451       failf(data, "Failed writing body (%zu != %zu)", wrote, len);
452       return CURLE_WRITE_ERROR;
453     }
454   }
455
456   if((type & CLIENTWRITE_HEADER) &&
457      (data->set.fwrite_header || data->set.writeheader) ) {
458     /*
459      * Write headers to the same callback or to the especially setup
460      * header callback function (added after version 7.7.1).
461      */
462     curl_write_callback writeit=
463       data->set.fwrite_header?data->set.fwrite_header:data->set.fwrite_func;
464
465     /* Note: The header is in the host encoding
466        regardless of the ftp transfer mode (ASCII/Image) */
467
468     wrote = writeit(ptr, 1, len, data->set.writeheader);
469     if(CURL_WRITEFUNC_PAUSE == wrote)
470       /* here we pass in the HEADER bit only since if this was body as well
471          then it was passed already and clearly that didn't trigger the pause,
472          so this is saved for later with the HEADER bit only */
473       return pausewrite(data, CLIENTWRITE_HEADER, ptr, len);
474
475     if(wrote != len) {
476       failf (data, "Failed writing header");
477       return CURLE_WRITE_ERROR;
478     }
479   }
480
481   return CURLE_OK;
482 }
483
484 CURLcode Curl_read_plain(curl_socket_t sockfd,
485                          char *buf,
486                          size_t bytesfromsocket,
487                          ssize_t *n)
488 {
489   ssize_t nread = sread(sockfd, buf, bytesfromsocket);
490
491   if(-1 == nread) {
492     int err = SOCKERRNO;
493 #ifdef USE_WINSOCK
494     if(WSAEWOULDBLOCK == err)
495 #else
496     if((EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err))
497 #endif
498       return CURLE_AGAIN;
499     else
500       return CURLE_RECV_ERROR;
501   }
502
503   /* we only return number of bytes read when we return OK */
504   *n = nread;
505   return CURLE_OK;
506 }
507
508 /*
509  * Internal read-from-socket function. This is meant to deal with plain
510  * sockets, SSL sockets and kerberos sockets.
511  *
512  * Returns a regular CURLcode value.
513  */
514 CURLcode Curl_read(struct connectdata *conn, /* connection data */
515                    curl_socket_t sockfd,     /* read from this socket */
516                    char *buf,                /* store read data here */
517                    size_t sizerequested,     /* max amount to read */
518                    ssize_t *n)               /* amount bytes read */
519 {
520   CURLcode curlcode = CURLE_RECV_ERROR;
521   ssize_t nread = 0;
522   size_t bytesfromsocket = 0;
523   char *buffertofill = NULL;
524   bool pipelining = Curl_multi_pipeline_enabled(conn->data->multi);
525
526   /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
527      If it is the second socket, we set num to 1. Otherwise to 0. This lets
528      us use the correct ssl handle. */
529   int num = (sockfd == conn->sock[SECONDARYSOCKET]);
530
531   *n=0; /* reset amount to zero */
532
533   /* If session can pipeline, check connection buffer  */
534   if(pipelining) {
535     size_t bytestocopy = CURLMIN(conn->buf_len - conn->read_pos,
536                                  sizerequested);
537
538     /* Copy from our master buffer first if we have some unread data there*/
539     if(bytestocopy > 0) {
540       memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
541       conn->read_pos += bytestocopy;
542       conn->bits.stream_was_rewound = FALSE;
543
544       *n = (ssize_t)bytestocopy;
545       return CURLE_OK;
546     }
547     /* If we come here, it means that there is no data to read from the buffer,
548      * so we read from the socket */
549     bytesfromsocket = CURLMIN(sizerequested, BUFSIZE * sizeof (char));
550     buffertofill = conn->master_buffer;
551   }
552   else {
553     bytesfromsocket = CURLMIN((long)sizerequested,
554                               conn->data->set.buffer_size ?
555                               conn->data->set.buffer_size : BUFSIZE);
556     buffertofill = buf;
557   }
558
559   nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &curlcode);
560   if(nread < 0)
561     return curlcode;
562
563   if(pipelining) {
564     memcpy(buf, conn->master_buffer, nread);
565     conn->buf_len = nread;
566     conn->read_pos = nread;
567   }
568
569   *n += nread;
570
571   return CURLE_OK;
572 }
573
574 /* return 0 on success */
575 static int showit(struct SessionHandle *data, curl_infotype type,
576                   char *ptr, size_t size)
577 {
578   static const char s_infotype[CURLINFO_END][3] = {
579     "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
580
581 #ifdef CURL_DOES_CONVERSIONS
582   char buf[BUFSIZE+1];
583   size_t conv_size = 0;
584
585   switch(type) {
586   case CURLINFO_HEADER_OUT:
587     /* assume output headers are ASCII */
588     /* copy the data into my buffer so the original is unchanged */
589     if(size > BUFSIZE) {
590       size = BUFSIZE; /* truncate if necessary */
591       buf[BUFSIZE] = '\0';
592     }
593     conv_size = size;
594     memcpy(buf, ptr, size);
595     /* Special processing is needed for this block if it
596      * contains both headers and data (separated by CRLFCRLF).
597      * We want to convert just the headers, leaving the data as-is.
598      */
599     if(size > 4) {
600       size_t i;
601       for(i = 0; i < size-4; i++) {
602         if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) {
603           /* convert everything through this CRLFCRLF but no further */
604           conv_size = i + 4;
605           break;
606         }
607       }
608     }
609
610     Curl_convert_from_network(data, buf, conv_size);
611     /* Curl_convert_from_network calls failf if unsuccessful */
612     /* we might as well continue even if it fails...   */
613     ptr = buf; /* switch pointer to use my buffer instead */
614     break;
615   default:
616     /* leave everything else as-is */
617     break;
618   }
619 #endif /* CURL_DOES_CONVERSIONS */
620
621   if(data->set.fdebug)
622     return (*data->set.fdebug)(data, type, ptr, size,
623                                data->set.debugdata);
624
625   switch(type) {
626   case CURLINFO_TEXT:
627   case CURLINFO_HEADER_OUT:
628   case CURLINFO_HEADER_IN:
629     fwrite(s_infotype[type], 2, 1, data->set.err);
630     fwrite(ptr, size, 1, data->set.err);
631 #ifdef CURL_DOES_CONVERSIONS
632     if(size != conv_size) {
633       /* we had untranslated data so we need an explicit newline */
634       fwrite("\n", 1, 1, data->set.err);
635     }
636 #endif
637     break;
638   default: /* nada */
639     break;
640   }
641   return 0;
642 }
643
644 int Curl_debug(struct SessionHandle *data, curl_infotype type,
645                char *ptr, size_t size,
646                struct connectdata *conn)
647 {
648   int rc;
649   if(data->set.printhost && conn && conn->host.dispname) {
650     char buffer[160];
651     const char *t=NULL;
652     const char *w="Data";
653     switch (type) {
654     case CURLINFO_HEADER_IN:
655       w = "Header";
656     case CURLINFO_DATA_IN:
657       t = "from";
658       break;
659     case CURLINFO_HEADER_OUT:
660       w = "Header";
661     case CURLINFO_DATA_OUT:
662       t = "to";
663       break;
664     default:
665       break;
666     }
667
668     if(t) {
669       snprintf(buffer, sizeof(buffer), "[%s %s %s]", w, t,
670                conn->host.dispname);
671       rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer));
672       if(rc)
673         return rc;
674     }
675   }
676   rc = showit(data, type, ptr, size);
677   return rc;
678 }