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