1/***************************************************************************
2 *                                  _   _ ____  _
3 *  Project                     ___| | | |  _ \| |
4 *                             / __| | | | |_) | |
5 *                            | (__| |_| |  _ <| |___
6 *                             \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 1998 - 2014, 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 "vtls/vtls.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 */
51static 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
128void 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
146void 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 */
171CURLcode 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 */
223CURLcode 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
256ssize_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 */
296CURLcode 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
313ssize_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
347static 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 */
386CURLcode 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&PROTO_FAMILY_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      if(conn->handler->flags & PROTOPT_NONETWORK) {
449        /* Protocols that work without network cannot be paused. This is
450           actually only FILE:// just now, and it can't pause since the
451           transfer isn't done using the "normal" procedure. */
452        failf(data, "Write callback asked for PAUSE when not supported!");
453        return CURLE_WRITE_ERROR;
454      }
455      else
456        return pausewrite(data, type, ptr, len);
457    }
458    else if(wrote != len) {
459      failf(data, "Failed writing body (%zu != %zu)", wrote, len);
460      return CURLE_WRITE_ERROR;
461    }
462  }
463
464  if((type & CLIENTWRITE_HEADER) &&
465     (data->set.fwrite_header || data->set.writeheader) ) {
466    /*
467     * Write headers to the same callback or to the especially setup
468     * header callback function (added after version 7.7.1).
469     */
470    curl_write_callback writeit=
471      data->set.fwrite_header?data->set.fwrite_header:data->set.fwrite_func;
472
473    /* Note: The header is in the host encoding
474       regardless of the ftp transfer mode (ASCII/Image) */
475
476    wrote = writeit(ptr, 1, len, data->set.writeheader);
477    if(CURL_WRITEFUNC_PAUSE == wrote)
478      /* here we pass in the HEADER bit only since if this was body as well
479         then it was passed already and clearly that didn't trigger the pause,
480         so this is saved for later with the HEADER bit only */
481      return pausewrite(data, CLIENTWRITE_HEADER, ptr, len);
482
483    if(wrote != len) {
484      failf (data, "Failed writing header");
485      return CURLE_WRITE_ERROR;
486    }
487  }
488
489  return CURLE_OK;
490}
491
492CURLcode Curl_read_plain(curl_socket_t sockfd,
493                         char *buf,
494                         size_t bytesfromsocket,
495                         ssize_t *n)
496{
497  ssize_t nread = sread(sockfd, buf, bytesfromsocket);
498
499  if(-1 == nread) {
500    int err = SOCKERRNO;
501#ifdef USE_WINSOCK
502    if(WSAEWOULDBLOCK == err)
503#else
504    if((EWOULDBLOCK == err) || (EAGAIN == err) || (EINTR == err))
505#endif
506      return CURLE_AGAIN;
507    else
508      return CURLE_RECV_ERROR;
509  }
510
511  /* we only return number of bytes read when we return OK */
512  *n = nread;
513  return CURLE_OK;
514}
515
516/*
517 * Internal read-from-socket function. This is meant to deal with plain
518 * sockets, SSL sockets and kerberos sockets.
519 *
520 * Returns a regular CURLcode value.
521 */
522CURLcode Curl_read(struct connectdata *conn, /* connection data */
523                   curl_socket_t sockfd,     /* read from this socket */
524                   char *buf,                /* store read data here */
525                   size_t sizerequested,     /* max amount to read */
526                   ssize_t *n)               /* amount bytes read */
527{
528  CURLcode curlcode = CURLE_RECV_ERROR;
529  ssize_t nread = 0;
530  size_t bytesfromsocket = 0;
531  char *buffertofill = NULL;
532  bool pipelining = Curl_multi_pipeline_enabled(conn->data->multi);
533
534  /* Set 'num' to 0 or 1, depending on which socket that has been sent here.
535     If it is the second socket, we set num to 1. Otherwise to 0. This lets
536     us use the correct ssl handle. */
537  int num = (sockfd == conn->sock[SECONDARYSOCKET]);
538
539  *n=0; /* reset amount to zero */
540
541  /* If session can pipeline, check connection buffer  */
542  if(pipelining) {
543    size_t bytestocopy = CURLMIN(conn->buf_len - conn->read_pos,
544                                 sizerequested);
545
546    /* Copy from our master buffer first if we have some unread data there*/
547    if(bytestocopy > 0) {
548      memcpy(buf, conn->master_buffer + conn->read_pos, bytestocopy);
549      conn->read_pos += bytestocopy;
550      conn->bits.stream_was_rewound = FALSE;
551
552      *n = (ssize_t)bytestocopy;
553      return CURLE_OK;
554    }
555    /* If we come here, it means that there is no data to read from the buffer,
556     * so we read from the socket */
557    bytesfromsocket = CURLMIN(sizerequested, BUFSIZE * sizeof (char));
558    buffertofill = conn->master_buffer;
559  }
560  else {
561    bytesfromsocket = CURLMIN((long)sizerequested,
562                              conn->data->set.buffer_size ?
563                              conn->data->set.buffer_size : BUFSIZE);
564    buffertofill = buf;
565  }
566
567  nread = conn->recv[num](conn, num, buffertofill, bytesfromsocket, &curlcode);
568  if(nread < 0)
569    return curlcode;
570
571  if(pipelining) {
572    memcpy(buf, conn->master_buffer, nread);
573    conn->buf_len = nread;
574    conn->read_pos = nread;
575  }
576
577  *n += nread;
578
579  return CURLE_OK;
580}
581
582/* return 0 on success */
583static int showit(struct SessionHandle *data, curl_infotype type,
584                  char *ptr, size_t size)
585{
586  static const char s_infotype[CURLINFO_END][3] = {
587    "* ", "< ", "> ", "{ ", "} ", "{ ", "} " };
588
589#ifdef CURL_DOES_CONVERSIONS
590  char buf[BUFSIZE+1];
591  size_t conv_size = 0;
592
593  switch(type) {
594  case CURLINFO_HEADER_OUT:
595    /* assume output headers are ASCII */
596    /* copy the data into my buffer so the original is unchanged */
597    if(size > BUFSIZE) {
598      size = BUFSIZE; /* truncate if necessary */
599      buf[BUFSIZE] = '\0';
600    }
601    conv_size = size;
602    memcpy(buf, ptr, size);
603    /* Special processing is needed for this block if it
604     * contains both headers and data (separated by CRLFCRLF).
605     * We want to convert just the headers, leaving the data as-is.
606     */
607    if(size > 4) {
608      size_t i;
609      for(i = 0; i < size-4; i++) {
610        if(memcmp(&buf[i], "\x0d\x0a\x0d\x0a", 4) == 0) {
611          /* convert everything through this CRLFCRLF but no further */
612          conv_size = i + 4;
613          break;
614        }
615      }
616    }
617
618    Curl_convert_from_network(data, buf, conv_size);
619    /* Curl_convert_from_network calls failf if unsuccessful */
620    /* we might as well continue even if it fails...   */
621    ptr = buf; /* switch pointer to use my buffer instead */
622    break;
623  default:
624    /* leave everything else as-is */
625    break;
626  }
627#endif /* CURL_DOES_CONVERSIONS */
628
629  if(data->set.fdebug)
630    return (*data->set.fdebug)(data, type, ptr, size,
631                               data->set.debugdata);
632
633  switch(type) {
634  case CURLINFO_TEXT:
635  case CURLINFO_HEADER_OUT:
636  case CURLINFO_HEADER_IN:
637    fwrite(s_infotype[type], 2, 1, data->set.err);
638    fwrite(ptr, size, 1, data->set.err);
639#ifdef CURL_DOES_CONVERSIONS
640    if(size != conv_size) {
641      /* we had untranslated data so we need an explicit newline */
642      fwrite("\n", 1, 1, data->set.err);
643    }
644#endif
645    break;
646  default: /* nada */
647    break;
648  }
649  return 0;
650}
651
652int Curl_debug(struct SessionHandle *data, curl_infotype type,
653               char *ptr, size_t size,
654               struct connectdata *conn)
655{
656  int rc;
657  if(data->set.printhost && conn && conn->host.dispname) {
658    char buffer[160];
659    const char *t=NULL;
660    const char *w="Data";
661    switch (type) {
662    case CURLINFO_HEADER_IN:
663      w = "Header";
664    case CURLINFO_DATA_IN:
665      t = "from";
666      break;
667    case CURLINFO_HEADER_OUT:
668      w = "Header";
669    case CURLINFO_DATA_OUT:
670      t = "to";
671      break;
672    default:
673      break;
674    }
675
676    if(t) {
677      snprintf(buffer, sizeof(buffer), "[%s %s %s]", w, t,
678               conn->host.dispname);
679      rc = showit(data, CURLINFO_TEXT, buffer, strlen(buffer));
680      if(rc)
681        return rc;
682    }
683  }
684  rc = showit(data, type, ptr, size);
685  return rc;
686}
687