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