~ubuntu-branches/ubuntu/lucid/curl/lucid-security

« back to all changes in this revision

Viewing changes to lib/socks.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Vogt
  • Date: 2009-04-29 11:10:29 UTC
  • mfrom: (3.2.3 sid)
  • Revision ID: james.westby@ubuntu.com-20090429111029-2j5eiyokfw2bw049
Tags: 7.19.4-1ubuntu1
* Merge from debian unstable, remaining changes:
  - Drop build dependencies: stunnel, libdb4.6-dev, libssh2-1-dev
  - Add build-dependency on openssh-server
  - Drop libssh2-1-dev from libcurl4-openssl-dev's Depends.
  - Call automake-1.9 with --add-missing --copy --force
* drop debian/patches/security_CVE-2009-0037.patch 
  - this patch is part of 7.19.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 *                            | (__| |_| |  _ <| |___
6
6
 *                             \___|\___/|_| \_\_____|
7
7
 *
8
 
 * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
 
8
 * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
9
9
 *
10
10
 * This software is licensed as described in the file COPYING, which
11
11
 * you should have received as part of this distribution. The terms
18
18
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19
19
 * KIND, either express or implied.
20
20
 *
21
 
 * $Id: socks.c,v 1.24 2008-02-11 22:03:31 bagder Exp $
 
21
 * $Id: socks.c,v 1.28 2009-01-28 21:34:16 bagder Exp $
22
22
 ***************************************************************************/
23
23
 
24
24
#include "setup.h"
25
25
 
 
26
#ifndef CURL_DISABLE_PROXY
26
27
#include <string.h>
27
28
 
28
29
#ifdef NEED_MALLOC_H
59
60
 * This is STUPID BLOCKING behaviour which we frown upon, but right now this
60
61
 * is what we have...
61
62
 */
62
 
static int blockread_all(struct connectdata *conn, /* connection data */
63
 
                         curl_socket_t sockfd,     /* read from this socket */
64
 
                         char *buf,                /* store read data here */
65
 
                         ssize_t buffersize,       /* max amount to read */
66
 
                         ssize_t *n,               /* amount bytes read */
67
 
                         long conn_timeout)        /* timeout for data wait
68
 
                                                      relative to
69
 
                                                      conn->created */
 
63
int Curl_blockread_all(struct connectdata *conn, /* connection data */
 
64
                       curl_socket_t sockfd,     /* read from this socket */
 
65
                       char *buf,                /* store read data here */
 
66
                       ssize_t buffersize,       /* max amount to read */
 
67
                       ssize_t *n,               /* amount bytes read */
 
68
                       long conn_timeout)        /* timeout for data wait
 
69
                                                    relative to
 
70
                                                    conn->created */
70
71
{
71
72
  ssize_t nread;
72
73
  ssize_t allread = 0;
88
89
      result = ~CURLE_OK;
89
90
      break;
90
91
    }
91
 
    result = Curl_read(conn, sockfd, buf, buffersize, &nread);
 
92
    result = Curl_read_plain(sockfd, buf, buffersize, &nread);
92
93
    if(result)
93
94
      break;
94
95
 
242
243
    }
243
244
 
244
245
    /* Send request */
245
 
    code = Curl_write(conn, sock, (char *)socksreq, packetsize + hostnamelen,
246
 
                      &written);
 
246
    code = Curl_write_plain(conn, sock, (char *)socksreq,
 
247
                            packetsize + hostnamelen,
 
248
                            &written);
247
249
    if((code != CURLE_OK) || (written != packetsize + hostnamelen)) {
248
250
      failf(data, "Failed to send SOCKS4 connect request.");
249
251
      return CURLE_COULDNT_CONNECT;
251
253
    if (protocol4a && hostnamelen == 0) {
252
254
      /* SOCKS4a with very long hostname - send that name separately */
253
255
      hostnamelen = (ssize_t)strlen(hostname) + 1;
254
 
      code = Curl_write(conn, sock, (char *)hostname, hostnamelen, &written);
 
256
      code = Curl_write_plain(conn, sock, (char *)hostname, hostnamelen,
 
257
                              &written);
255
258
      if((code != CURLE_OK) || (written != hostnamelen)) {
256
259
        failf(data, "Failed to send SOCKS4 connect request.");
257
260
        return CURLE_COULDNT_CONNECT;
261
264
    packetsize = 8; /* receive data size */
262
265
 
263
266
    /* Receive response */
264
 
    result = blockread_all(conn, sock, (char *)socksreq, packetsize,
 
267
    result = Curl_blockread_all(conn, sock, (char *)socksreq, packetsize,
265
268
                           &actualread, timeout);
266
269
    if((result != CURLE_OK) || (actualread != packetsize)) {
267
270
      failf(data, "Failed to receive SOCKS4 connect request ack.");
426
429
  }
427
430
 
428
431
  socksreq[0] = 5; /* version */
 
432
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
 
433
  socksreq[1] = (char)(proxy_name ? 3 : 2); /* number of methods (below) */
 
434
  socksreq[2] = 0; /* no authentication */
 
435
  socksreq[3] = 1; /* gssapi */
 
436
  socksreq[4] = 2; /* username/password */
 
437
#else
429
438
  socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */
430
439
  socksreq[2] = 0; /* no authentication */
431
440
  socksreq[3] = 2; /* username/password */
 
441
#endif
432
442
 
433
443
  Curl_nonblock(sock, FALSE);
434
444
 
435
 
  code = Curl_write(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
436
 
                      &written);
 
445
  code = Curl_write_plain(conn, sock, (char *)socksreq, (2 + (int)socksreq[1]),
 
446
                          &written);
437
447
  if((code != CURLE_OK) || (written != (2 + (int)socksreq[1]))) {
438
448
    failf(data, "Unable to send initial SOCKS5 request.");
439
449
    return CURLE_COULDNT_CONNECT;
459
469
 
460
470
  Curl_nonblock(sock, FALSE);
461
471
 
462
 
  result=blockread_all(conn, sock, (char *)socksreq, 2, &actualread, timeout);
 
472
  result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread,
 
473
                            timeout);
463
474
  if((result != CURLE_OK) || (actualread != 2)) {
464
475
    failf(data, "Unable to receive initial SOCKS5 response.");
465
476
    return CURLE_COULDNT_CONNECT;
473
484
    /* Nothing to do, no authentication needed */
474
485
    ;
475
486
  }
 
487
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
 
488
  else if(socksreq[1] == 1) {
 
489
    code = Curl_SOCKS5_gssapi_negotiate(sockindex, conn);
 
490
    if(code != CURLE_OK) {
 
491
      failf(data, "Unable to negotiate SOCKS5 gssapi context.");
 
492
      return CURLE_COULDNT_CONNECT;
 
493
    }
 
494
  }
 
495
#endif
476
496
  else if(socksreq[1] == 2) {
477
497
    /* Needs user name and password */
478
498
    size_t userlen, pwlen;
502
522
    memcpy(socksreq + len, proxy_password, (int) pwlen);
503
523
    len += pwlen;
504
524
 
505
 
    code = Curl_write(conn, sock, (char *)socksreq, len, &written);
 
525
    code = Curl_write_plain(conn, sock, (char *)socksreq, len, &written);
506
526
    if((code != CURLE_OK) || (len != written)) {
507
527
      failf(data, "Failed to send SOCKS5 sub-negotiation request.");
508
528
      return CURLE_COULDNT_CONNECT;
509
529
    }
510
530
 
511
 
    result=blockread_all(conn, sock, (char *)socksreq, 2, &actualread,
 
531
    result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread,
512
532
                         timeout);
513
533
    if((result != CURLE_OK) || (actualread != 2)) {
514
534
      failf(data, "Unable to receive SOCKS5 sub-negotiation response.");
526
546
  }
527
547
  else {
528
548
    /* error */
 
549
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
 
550
    if(socksreq[1] == 255) {
 
551
#else
529
552
    if(socksreq[1] == 1) {
530
553
      failf(data,
531
554
            "SOCKS5 GSSAPI per-message authentication is not supported.");
532
555
      return CURLE_COULDNT_CONNECT;
533
556
    }
534
557
    else if(socksreq[1] == 255) {
 
558
#endif
535
559
      if(!proxy_name || !*proxy_name) {
536
560
        failf(data,
537
561
              "No authentication method was acceptable. (It is quite likely"
613
637
    *((unsigned short*)&socksreq[8]) = htons((unsigned short)remote_port);
614
638
  }
615
639
 
616
 
  code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written);
 
640
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
 
641
  if(conn->socks5_gssapi_enctype) {
 
642
    failf(data, "SOCKS5 gssapi protection not yet implemented.");
 
643
  } else
 
644
#endif
 
645
  code = Curl_write_plain(conn, sock, (char *)socksreq, packetsize, &written);
617
646
  if((code != CURLE_OK) || (written != packetsize)) {
618
647
    failf(data, "Failed to send SOCKS5 connect request.");
619
648
    return CURLE_COULDNT_CONNECT;
621
650
 
622
651
  packetsize = 10; /* minimum packet size is 10 */
623
652
 
624
 
  result = blockread_all(conn, sock, (char *)socksreq, packetsize,
 
653
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
 
654
  if(conn->socks5_gssapi_enctype) {
 
655
    failf(data, "SOCKS5 gssapi protection not yet implemented.");
 
656
  } else
 
657
#endif
 
658
    result = Curl_blockread_all(conn, sock, (char *)socksreq, packetsize,
625
659
                           &actualread, timeout);
626
660
  if((result != CURLE_OK) || (actualread != packetsize)) {
627
661
    failf(data, "Failed to receive SOCKS5 connect request ack.");
671
705
  }
672
706
 
673
707
  /* At this point we already read first 10 bytes */
674
 
  if(packetsize > 10) {
675
 
    packetsize -= 10;
676
 
    result = blockread_all(conn, sock, (char *)&socksreq[10], packetsize,
677
 
                           &actualread, timeout);
678
 
    if((result != CURLE_OK) || (actualread != packetsize)) {
679
 
      failf(data, "Failed to receive SOCKS5 connect request ack.");
680
 
      return CURLE_COULDNT_CONNECT;
 
708
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
 
709
  if(!conn->socks5_gssapi_enctype) {
 
710
    /* decrypt_gssapi_blockread already read the whole packet */
 
711
#endif
 
712
    if(packetsize > 10) {
 
713
      packetsize -= 10;
 
714
      result = Curl_blockread_all(conn, sock, (char *)&socksreq[10],
 
715
                                  packetsize, &actualread, timeout);
 
716
      if((result != CURLE_OK) || (actualread != packetsize)) {
 
717
        failf(data, "Failed to receive SOCKS5 connect request ack.");
 
718
        return CURLE_COULDNT_CONNECT;
 
719
      }
681
720
    }
 
721
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
682
722
  }
 
723
#endif
683
724
 
684
725
  Curl_nonblock(sock, TRUE);
685
726
  return CURLE_OK; /* Proxy was successful! */
686
727
}
 
728
 
 
729
#endif /* CURL_DISABLE_PROXY */
 
730