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

« back to all changes in this revision

Viewing changes to lib/http.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2005-12-12 15:04:52 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20051212150452-2ymlra67b2p7kjyy
Tags: 7.15.1-1ubuntu1
Resynchronise with Debian to get URL parser overflow fix from 7.15.1
(CVE-2005-4077).

Show diffs side-by-side

added added

removed removed

Lines of Context:
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: http.c,v 1.272 2005/05/11 09:52:59 bagder Exp $
 
21
 * $Id: http.c,v 1.275 2005/10/20 20:07:33 bagder Exp $
22
22
 ***************************************************************************/
23
23
 
24
24
#include "setup.h"
96
96
#include "memory.h"
97
97
#include "select.h"
98
98
#include "parsedate.h" /* for the week day and month names */
 
99
#include "strtoofft.h"
99
100
 
100
101
#define _MPRINTF_REPLACE /* use our functions only */
101
102
#include <curl/mprintf.h>
620
621
#endif
621
622
#ifndef CURL_DISABLE_CRYPTO_AUTH
622
623
      if(checkprefix("Digest", start)) {
623
 
        CURLdigest dig;
624
 
        *availp |= CURLAUTH_DIGEST;
625
 
        authp->avail |= CURLAUTH_DIGEST;
626
 
 
627
 
        /* We call this function on input Digest headers even if Digest
628
 
         * authentication isn't activated yet, as we need to store the
629
 
         * incoming data from this header in case we are gonna use Digest. */
630
 
        dig = Curl_input_digest(conn, (bool)(httpcode == 407), start);
631
 
 
632
 
        if(CURLDIGEST_FINE != dig) {
633
 
          infof(data, "Authentication problem. Ignoring this.\n");
634
 
          data->state.authproblem = TRUE;
 
624
        if((authp->avail & CURLAUTH_DIGEST) != 0) {
 
625
          infof(data, "Ignoring duplicate digest auth header.\n");
 
626
        }
 
627
        else {
 
628
          CURLdigest dig;
 
629
          *availp |= CURLAUTH_DIGEST;
 
630
          authp->avail |= CURLAUTH_DIGEST;
 
631
 
 
632
          /* We call this function on input Digest headers even if Digest
 
633
           * authentication isn't activated yet, as we need to store the
 
634
           * incoming data from this header in case we are gonna use Digest. */
 
635
          dig = Curl_input_digest(conn, (bool)(httpcode == 407), start);
 
636
 
 
637
          if(CURLDIGEST_FINE != dig) {
 
638
            infof(data, "Authentication problem. Ignoring this.\n");
 
639
            data->state.authproblem = TRUE;
 
640
          }
635
641
        }
636
642
      }
637
643
      else
1053
1059
}
1054
1060
 
1055
1061
/*
1056
 
 * ConnectHTTPProxyTunnel() requires that we're connected to a HTTP
1057
 
 * proxy. This function will issue the necessary commands to get a seamless
1058
 
 * tunnel through this proxy. After that, the socket can be used just as a
1059
 
 * normal socket.
 
1062
 * Curl_proxyCONNECT() requires that we're connected to a HTTP proxy. This
 
1063
 * function will issue the necessary commands to get a seamless tunnel through
 
1064
 * this proxy. After that, the socket can be used just as a normal socket.
1060
1065
 *
1061
1066
 * This badly needs to be rewritten. CONNECT should be sent and dealt with
1062
1067
 * like any ordinary HTTP request, and not specially crafted like this. This
1064
1069
 * much work to do at the moment.
1065
1070
 */
1066
1071
 
1067
 
CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
1068
 
                                     int sockindex,
1069
 
                                     char *hostname,
1070
 
                                     int remote_port)
 
1072
CURLcode Curl_proxyCONNECT(struct connectdata *conn,
 
1073
                           int sockindex,
 
1074
                           char *hostname,
 
1075
                           int remote_port)
1071
1076
{
1072
1077
  int subversion=0;
1073
1078
  struct SessionHandle *data=conn->data;
1076
1081
  int res;
1077
1082
  size_t nread;   /* total size read */
1078
1083
  int perline; /* count bytes per line */
1079
 
  bool keepon=TRUE;
 
1084
  int keepon=TRUE;
1080
1085
  ssize_t gotbytes;
1081
1086
  char *ptr;
1082
1087
  long timeout =
1085
1090
  char *host_port;
1086
1091
  curl_socket_t tunnelsocket = conn->sock[sockindex];
1087
1092
  send_buffer *req_buffer;
 
1093
  curl_off_t cl=0;
1088
1094
 
1089
1095
#define SELECT_OK      0
1090
1096
#define SELECT_ERROR   1
1215
1221
          int i;
1216
1222
 
1217
1223
          nread += gotbytes;
 
1224
 
 
1225
          if(keepon > TRUE) {
 
1226
            /* This means we are currently ignoring a response-body, so we
 
1227
               simply count down our counter and make sure to break out of the
 
1228
               loop when we're done! */
 
1229
            cl -= gotbytes;
 
1230
            if(cl<=0) {
 
1231
              keepon = FALSE;
 
1232
              break;
 
1233
            }
 
1234
          }
 
1235
          else
1218
1236
          for(i = 0; i < gotbytes; ptr++, i++) {
1219
1237
            perline++; /* amount of bytes in this line so far */
1220
1238
            if(*ptr=='\n') {
1242
1260
              if(('\r' == line_start[0]) ||
1243
1261
                 ('\n' == line_start[0])) {
1244
1262
                /* end of response-headers from the proxy */
1245
 
                keepon=FALSE;
 
1263
                if(cl && (407 == k->httpcode) && !data->state.authproblem) {
 
1264
                  /* If we get a 407 response code with content length when we
 
1265
                   * have no auth problem, we must ignore the whole
 
1266
                   * response-body */
 
1267
                  keepon = 2;
 
1268
                  infof(data, "Ignore %" FORMAT_OFF_T
 
1269
                        " bytes of response-body\n", cl);
 
1270
                  cl -= (gotbytes - i);/* remove the remaining chunk of what
 
1271
                                          we already read */
 
1272
                  if(cl<=0)
 
1273
                    /* if the whole thing was already read, we are done! */
 
1274
                    keepon=FALSE;
 
1275
                }
 
1276
                else
 
1277
                  keepon = FALSE;
1246
1278
                break; /* breaks out of for-loop, not switch() */
1247
1279
              }
1248
1280
 
1257
1289
                if(result)
1258
1290
                  return result;
1259
1291
              }
 
1292
              else if(checkprefix("Content-Length:", line_start)) {
 
1293
                cl = curlx_strtoofft(line_start + strlen("Content-Length:"),
 
1294
                                     NULL, 10);
 
1295
              }
1260
1296
              else if(2 == sscanf(line_start, "HTTP/1.%d %d",
1261
1297
                                  &subversion,
1262
1298
                                  &k->httpcode)) {
1323
1359
  if(conn->bits.tunnel_proxy) {
1324
1360
 
1325
1361
    /* either SSL over proxy, or explicitly asked for */
1326
 
    result = Curl_ConnectHTTPProxyTunnel(conn, FIRSTSOCKET,
1327
 
                                         conn->host.name,
1328
 
                                         conn->remote_port);
 
1362
    result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
 
1363
                               conn->host.name,
 
1364
                               conn->remote_port);
1329
1365
    if(CURLE_OK != result)
1330
1366
      return result;
1331
1367
  }