summaryrefslogtreecommitdiffstats
path: root/meta/recipes-support/curl/curl/CVE-2023-27535.patch
blob: e38390a57c56d40571a6c06fc5213dbca3116f6b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
From 8f4608468b890dce2dad9f91d5607ee7e9c1aba1 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 9 Mar 2023 17:47:06 +0100
Subject: [PATCH] ftp: add more conditions for connection reuse

Reported-by: Harry Sintonen
Closes #10730

Upstream-Status: Backport [import from ubuntu https://git.launchpad.net/ubuntu/+source/curl/tree/debian/patches/CVE-2023-27535.patch?h=ubuntu/focal-security
Upstream commit https://github.com/curl/curl/commit/8f4608468b890dce2dad9f91d5607ee7e9c1aba1]
CVE: CVE-2023-27535
Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
---
 lib/ftp.c     | 30 ++++++++++++++++++++++++++++--
 lib/ftp.h     |  5 +++++
 lib/setopt.c  |  2 +-
 lib/url.c     | 16 +++++++++++++++-
 lib/urldata.h |  4 ++--
 5 files changed, 51 insertions(+), 6 deletions(-)

diff --git a/lib/ftp.c b/lib/ftp.c
index 31a34e8..7a82a74 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -4059,6 +4059,10 @@ static CURLcode ftp_disconnect(struct connectdata *conn, bool dead_connection)
   }
 
   freedirs(ftpc);
+  free(ftpc->account);
+  ftpc->account = NULL;
+  free(ftpc->alternative_to_user);
+  ftpc->alternative_to_user = NULL;
   free(ftpc->prevpath);
   ftpc->prevpath = NULL;
   free(ftpc->server_os);
@@ -4326,11 +4330,31 @@ static CURLcode ftp_setup_connection(struct connectdata *conn)
   struct Curl_easy *data = conn->data;
   char *type;
   struct FTP *ftp;
+  struct ftp_conn *ftpc = &conn->proto.ftpc;
 
-  conn->data->req.protop = ftp = calloc(sizeof(struct FTP), 1);
+  ftp = calloc(sizeof(struct FTP), 1);
   if(NULL == ftp)
     return CURLE_OUT_OF_MEMORY;
 
+  /* clone connection related data that is FTP specific */
+  if(data->set.str[STRING_FTP_ACCOUNT]) {
+    ftpc->account = strdup(data->set.str[STRING_FTP_ACCOUNT]);
+    if(!ftpc->account) {
+      free(ftp);
+      return CURLE_OUT_OF_MEMORY;
+    }
+  }
+  if(data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]) {
+    ftpc->alternative_to_user =
+      strdup(data->set.str[STRING_FTP_ALTERNATIVE_TO_USER]);
+    if(!ftpc->alternative_to_user) {
+      Curl_safefree(ftpc->account);
+      free(ftp);
+      return CURLE_OUT_OF_MEMORY;
+    }
+  }
+  conn->data->req.protop = ftp;
+
   ftp->path = &data->state.up.path[1]; /* don't include the initial slash */
 
   /* FTP URLs support an extension like ";type=<typecode>" that
@@ -4366,7 +4390,9 @@ static CURLcode ftp_setup_connection(struct connectdata *conn)
   /* get some initial data into the ftp struct */
   ftp->transfer = FTPTRANSFER_BODY;
   ftp->downloadsize = 0;
-  conn->proto.ftpc.known_filesize = -1; /* unknown size for now */
+  ftpc->known_filesize = -1; /* unknown size for now */
+  ftpc->use_ssl = data->set.use_ssl;
+  ftpc->ccc = data->set.ftp_ccc;
 
   return CURLE_OK;
 }
diff --git a/lib/ftp.h b/lib/ftp.h
index 984347f..163dcb3 100644
--- a/lib/ftp.h
+++ b/lib/ftp.h
@@ -116,6 +116,8 @@ struct FTP {
    struct */
 struct ftp_conn {
   struct pingpong pp;
+  char *account;
+  char *alternative_to_user;
   char *entrypath; /* the PWD reply when we logged on */
   char **dirs;   /* realloc()ed array for path components */
   int dirdepth;  /* number of entries used in the 'dirs' array */
@@ -141,6 +143,9 @@ struct ftp_conn {
   ftpstate state; /* always use ftp.c:state() to change state! */
   ftpstate state_saved; /* transfer type saved to be reloaded after
                            data connection is established */
+  unsigned char use_ssl;   /* if AUTH TLS is to be attempted etc, for FTP or
+                              IMAP or POP3 or others! (type: curl_usessl)*/
+  unsigned char ccc;       /* ccc level for this connection */
   curl_off_t retr_size_saved; /* Size of retrieved file saved */
   char *server_os;     /* The target server operating system. */
   curl_off_t known_filesize; /* file size is different from -1, if wildcard
diff --git a/lib/setopt.c b/lib/setopt.c
index 4d96f6b..a91bb70 100644
--- a/lib/setopt.c
+++ b/lib/setopt.c
@@ -2126,7 +2126,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
     arg = va_arg(param, long);
     if((arg < CURLUSESSL_NONE) || (arg >= CURLUSESSL_LAST))
       return CURLE_BAD_FUNCTION_ARGUMENT;
-    data->set.use_ssl = (curl_usessl)arg;
+    data->set.use_ssl = (unsigned char)arg;
     break;
 
   case CURLOPT_SSL_OPTIONS:
diff --git a/lib/url.c b/lib/url.c
index dfbde3b..f84375c 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -1257,10 +1257,24 @@ ConnectionExists(struct Curl_easy *data,
         }
       }
 
-      if(get_protocol_family(needle->handler->protocol) & PROTO_FAMILY_SSH) {
+#ifdef USE_SSH
+      else if(get_protocol_family(needle->handler->protocol) & PROTO_FAMILY_SSH) {
         if(!ssh_config_matches(needle, check))
           continue;
       }
+#endif
+#ifndef CURL_DISABLE_FTP
+      else if(get_protocol_family(needle->handler->protocol) & PROTO_FAMILY_FTP) {
+        /* Also match ACCOUNT, ALTERNATIVE-TO-USER, USE_SSL and CCC options */
+        if(Curl_timestrcmp(needle->proto.ftpc.account,
+                           check->proto.ftpc.account) ||
+           Curl_timestrcmp(needle->proto.ftpc.alternative_to_user,
+                           check->proto.ftpc.alternative_to_user) ||
+           (needle->proto.ftpc.use_ssl != check->proto.ftpc.use_ssl) ||
+           (needle->proto.ftpc.ccc != check->proto.ftpc.ccc))
+          continue;
+      }
+#endif
 
       if(!needle->bits.httpproxy || (needle->handler->flags&PROTOPT_SSL) ||
          needle->bits.tunnel_proxy) {
diff --git a/lib/urldata.h b/lib/urldata.h
index 168f874..51b793b 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1730,8 +1730,6 @@ struct UserDefined {
   void *ssh_keyfunc_userp;         /* custom pointer to callback */
   enum CURL_NETRC_OPTION
        use_netrc;        /* defined in include/curl.h */
-  curl_usessl use_ssl;   /* if AUTH TLS is to be attempted etc, for FTP or
-                            IMAP or POP3 or others! */
   long new_file_perms;    /* Permissions to use when creating remote files */
   long new_directory_perms; /* Permissions to use when creating remote dirs */
   long ssh_auth_types;   /* allowed SSH auth types */
@@ -1851,6 +1849,8 @@ struct UserDefined {
   BIT(http09_allowed); /* allow HTTP/0.9 responses */
   BIT(mail_rcpt_allowfails); /* allow RCPT TO command to fail for some
                                 recipients */
+  unsigned char use_ssl;   /* if AUTH TLS is to be attempted etc, for FTP or
+                              IMAP or POP3 or others! (type: curl_usessl)*/
 };
 
 struct Names {
-- 
2.25.1