A new user interface for you! Read more...

File curl-7.15.5-CVE-2009-0037.patch of Package curl-centos5

diff -pruN curl-7.15.5.orig/docs/libcurl/curl_easy_setopt.3 curl-7.15.5/docs/libcurl/curl_easy_setopt.3
--- curl-7.15.5.orig/docs/libcurl/curl_easy_setopt.3	2006-08-02 11:33:32.000000000 +0200
+++ curl-7.15.5/docs/libcurl/curl_easy_setopt.3	2009-03-13 15:04:52.000000000 +0100
@@ -346,6 +346,26 @@ The string given to CURLOPT_URL must be 
 
 \fICURLOPT_URL\fP is the only option that \fBmust\fP be set before
 \fIcurl_easy_perform(3)\fP is called.
+
+\fICURLOPT_PROTOCOLS\fP can be used to limit what protocols libcurl will use
+for this transfer, independent of what libcurl has been compiled to
+support. That may be useful if you accept the URL from an external source and
+want to limit the accessibility.
+.IP CURLOPT_PROTOCOLS
+Pass a long that holds a bitmask of CURLPROTO_* defines. If used, this bitmask
+limits what protocols libcurl may use in the transfer. This allows you to have
+a libcurl built to support a wide range of protocols but still limit specific
+transfers to only be allowed to use a subset of them. By default libcurl will
+accept all protocols it supports. See also
+\fICURLOPT_REDIR_PROTOCOLS\fP. (Added in 7.19.4)
+.IP CURLOPT_REDIR_PROTOCOLS
+Pass a long that holds a bitmask of CURLPROTO_* defines. If used, this bitmask
+limits what protocols libcurl may use in a transfer that it follows to in a
+redirect when \fICURLOPT_FOLLOWLOCATION\fP is enabled. This allows you to
+limit specific transfers to only be allowed to use a subset of protocols in
+redirections. By default libcurl will allow all protocols except for FILE and
+SCP. This is a difference compared to pre-7.19.4 versions which
+unconditionally would follow to all protocols supported. (Added in 7.19.4)
 .IP CURLOPT_PROXY
 Set HTTP proxy to use. The parameter should be a char * to a zero terminated
 string holding the host name or dotted IP address. To specify port number in
@@ -574,6 +594,10 @@ This means that the library will re-send
 and follow new Location: headers all the way until no more such headers are
 returned. \fICURLOPT_MAXREDIRS\fP can be used to limit the number of redirects
 libcurl will follow.
+
+NOTE: since 7.19.4, libcurl can limit to what protocols it will automatically
+follow. The accepted protocols are set with \fICURLOPT_REDIR_PROTOCOLS\fP and
+it excludes the FILE protocol by default.
 .IP CURLOPT_UNRESTRICTED_AUTH
 A non-zero parameter tells the library it can continue to send authentication
 (user+password) when following locations, even when hostname changed. This
diff -pruN curl-7.15.5.orig/include/curl/curl.h curl-7.15.5/include/curl/curl.h
--- curl-7.15.5.orig/include/curl/curl.h	2006-08-06 22:45:34.000000000 +0200
+++ curl-7.15.5/include/curl/curl.h	2009-03-13 15:04:52.000000000 +0100
@@ -414,6 +414,19 @@ typedef enum {
   CURLFTPMETHOD_LAST       /* not an option, never use */
 } curl_ftpmethod;
 
+/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */
+#define CURLPROTO_HTTP   (1<<0)
+#define CURLPROTO_HTTPS  (1<<1)
+#define CURLPROTO_FTP    (1<<2)
+#define CURLPROTO_FTPS   (1<<3)
+#define CURLPROTO_TELNET (1<<6)
+#define CURLPROTO_LDAP   (1<<7)
+#define CURLPROTO_LDAPS  (1<<8)
+#define CURLPROTO_DICT   (1<<9)
+#define CURLPROTO_FILE   (1<<10)
+#define CURLPROTO_TFTP   (1<<11)
+#define CURLPROTO_ALL    (~0) /* enable everything */
+
 /* long may be 32 or 64 bits, but we should never depend on anything else
    but 32 */
 #define CURLOPTTYPE_LONG          0
@@ -982,6 +995,18 @@ typedef enum {
   /* Pointer to command string to send if USER/PASS fails. */
   CINIT(FTP_ALTERNATIVE_TO_USER, OBJECTPOINT, 147),
 
+  /* set the bitmask for the protocols that are allowed to be used for the
+     transfer, which thus helps the app which takes URLs from users or other
+     external inputs and want to restrict what protocol(s) to deal
+     with. Defaults to CURLPROTO_ALL. */
+  CINIT(PROTOCOLS, LONG, 181),
+
+  /* set the bitmask for the protocols that libcurl is allowed to follow to,
+     as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
+     to be set in both bitmasks to be allowed to get redirected to. Defaults
+     to CURLPROTO_ALL & ~CURLPROTO_FILE. */
+  CINIT(REDIR_PROTOCOLS, LONG, 182),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
diff -pruN curl-7.15.5.orig/lib/url.c curl-7.15.5/lib/url.c
--- curl-7.15.5.orig/lib/url.c	2006-08-02 20:08:06.000000000 +0200
+++ curl-7.15.5/lib/url.c	2009-03-13 15:04:52.000000000 +0100
@@ -367,6 +367,13 @@ CURLcode Curl_open(struct SessionHandle 
     data->set.httpauth = CURLAUTH_BASIC;  /* defaults to basic */
     data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic */
 
+    /* for the *protocols fields we don't use the CURLPROTO_ALL convenience
+       define since we internally only use the lower 16 bits for the passed
+       in bitmask to not conflict with the private bits */
+    data->set.allowed_protocols = PROT_EXTMASK;
+    data->set.redir_protocols =
+      (PROT_EXTMASK & ~CURLPROTO_FILE); /* not FILE */
+
     /* create an array with connection data struct pointers */
     data->state.numconnects = 5; /* hard-coded right now */
     data->state.connects = (struct connectdata **)
@@ -1551,6 +1558,22 @@ CURLcode Curl_setopt(struct SessionHandl
     data->set.ftp_alternative_to_user = va_arg(param, char *);
     break;
 
+  case CURLOPT_PROTOCOLS:
+    /* set the bitmask for the protocols that are allowed to be used for the
+       transfer, which thus helps the app which takes URLs from users or other
+       external inputs and want to restrict what protocol(s) to deal
+       with. Defaults to CURLPROTO_ALL. */
+    data->set.allowed_protocols = va_arg(param, long) & PROT_EXTMASK;
+    break;
+
+  case CURLOPT_REDIR_PROTOCOLS:
+    /* set the bitmask for the protocols that libcurl is allowed to follow to,
+       as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
+       to be set in both bitmasks to be allowed to get redirected to. Defaults
+       to CURLPROTO_ALL & ~CURLPROTO_FILE. */
+    data->set.redir_protocols = va_arg(param, long) & PROT_EXTMASK;
+    break;
+
   default:
     /* unknown tag and its companion, just ignore: */
     result = CURLE_FAILED_INIT; /* correct this */
@@ -3198,8 +3221,6 @@ static CURLcode CreateConnection(struct 
       result = Curl_Transfer(conn, -1, -1, FALSE, NULL, /* no download */
                              -1, NULL); /* no upload */
     }
-
-    return result;
 #else
     failf(data, LIBCURL_NAME
           " was built with FILE disabled!");
@@ -3249,6 +3270,17 @@ static CURLcode CreateConnection(struct 
     failf(data, "Unsupported protocol: %s", conn->protostr);
     return CURLE_UNSUPPORTED_PROTOCOL;
   }
+  /* Protocol found. Check if allowed */
+  if(!(data->set.allowed_protocols & conn->protocol) ||
+    /* it is allowed for "normal" request, now do an extra check if this is
+       the result of a redirect */
+      (data->state.this_is_a_follow &&
+      !(data->set.redir_protocols & conn->protocol))) {
+    failf(data, "Unsupported protocol: %s", conn->protostr);
+    return CURLE_UNSUPPORTED_PROTOCOL;
+  }
+  if (conn->protocol & PROT_FILE)
+    return result;
 
   if(data->change.proxy && *data->change.proxy) {
     /* If this is supposed to use a proxy, we need to figure out the proxy
diff -pruN curl-7.15.5.orig/lib/urldata.h curl-7.15.5/lib/urldata.h
--- curl-7.15.5.orig/lib/urldata.h	2006-07-26 00:46:38.000000000 +0200
+++ curl-7.15.5/lib/urldata.h	2009-03-13 15:04:52.000000000 +0100
@@ -563,17 +563,23 @@ struct connectdata {
                        struct has */
 
   long protocol; /* PROT_* flags concerning the protocol set */
-#define PROT_MISSING (1<<0)
-#define PROT_HTTP    (1<<2)
-#define PROT_HTTPS   (1<<3)
-#define PROT_FTP     (1<<4)
-#define PROT_TELNET  (1<<5)
-#define PROT_DICT    (1<<6)
-#define PROT_LDAP    (1<<7)
-#define PROT_FILE    (1<<8)
-#define PROT_TFTP    (1<<11)
-#define PROT_FTPS    (1<<9)
-#define PROT_SSL     (1<<10) /* protocol requires SSL */
+#define PROT_HTTP    CURLPROTO_HTTP
+#define PROT_HTTPS   CURLPROTO_HTTPS
+#define PROT_FTP     CURLPROTO_FTP
+#define PROT_TELNET  CURLPROTO_TELNET
+#define PROT_DICT    CURLPROTO_DICT
+#define PROT_LDAP    CURLPROTO_LDAP
+#define PROT_FILE    CURLPROTO_FILE
+#define PROT_FTPS    CURLPROTO_FTPS
+#define PROT_TFTP    CURLPROTO_TFTP
+/* CURLPROTO_TFTP (1<<11) is currently the highest used bit in the public
+   bitmask. We make sure we use "private bits" above the first 16 to make
+   things easier. */
+
+#define PROT_EXTMASK 0xfff
+
+#define PROT_SSL     (1<<22) /* protocol requires SSL */
+#define PROT_MISSING (1<<23)
 
   /* 'dns_entry' is the particular host we use. This points to an entry in the
      DNS cache and it will not get pruned while locked. It gets unlocked in
@@ -1147,6 +1153,8 @@ struct UserDefined {
   bool ftp_skip_ip;      /* skip the IP address the FTP server passes on to
                             us */
   bool connect_only;     /* make connection, let application use the socket */
+  long allowed_protocols;
+  long redir_protocols;
 };
 
 struct Names {
diff -pruN curl-7.15.5.orig/lib/easy.c curl-7.15.5/lib/easy.c
--- curl-7.15.5.orig/lib/easy.c	2006-07-25 20:39:22.000000000 +0200
+++ curl-7.15.5/lib/easy.c	2009-03-13 15:04:52.000000000 +0100
@@ -670,6 +670,13 @@ void curl_easy_reset(CURL *curl)
   data->set.httpauth = CURLAUTH_BASIC;  /* defaults to basic */
   data->set.proxyauth = CURLAUTH_BASIC; /* defaults to basic */
 
+  /* for the *protocols fields we don't use the CURLPROTO_ALL convenience
+     define since we internally only use the lower 16 bits for the passed
+     in bitmask to not conflict with the private bits */
+  data->set.allowed_protocols = PROT_EXTMASK;
+  data->set.redir_protocols =
+    (PROT_EXTMASK & ~CURLPROTO_FILE); /* not FILE */
+
   /*
    * libcurl 7.10 introduced SSL verification *by default*! This needs to be
    * switched off unless wanted.