parent
f31846719a
commit
34931efd9b
@ -0,0 +1,169 @@
|
|||||||
|
From be17dc9d31e805c03372b690dde67838b3bfc12d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Daniel Stenberg <daniel@haxx.se>
|
||||||
|
Date: Wed, 24 May 2023 16:34:11 +0200
|
||||||
|
Subject: [PATCH] libssh: when keyboard-interactive auth fails, try password
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
The state machine had a mistake in that it would not carry on to that
|
||||||
|
next step.
|
||||||
|
|
||||||
|
This also adds a verbose output what methods that are available from the
|
||||||
|
server and renames the macros that change to the next auth methods to
|
||||||
|
try.
|
||||||
|
|
||||||
|
Reported-by: 左潇峰
|
||||||
|
Fixes #11196
|
||||||
|
Closes #11197
|
||||||
|
---
|
||||||
|
lib/ssh-libssh.c | 43 +++++++++++++++++++++++++++----------------
|
||||||
|
1 file changed, 27 insertions(+), 16 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/ssh-libssh.c b/lib/ssh-libssh.c
|
||||||
|
index 7ebe61321419f..1cecb649cb623 100644
|
||||||
|
--- a/lib/ssh-libssh.c
|
||||||
|
+++ b/lib/ssh-libssh.c
|
||||||
|
@@ -442,7 +442,7 @@ static int myssh_is_known(struct Curl_easy *data)
|
||||||
|
break; \
|
||||||
|
}
|
||||||
|
|
||||||
|
-#define MOVE_TO_LAST_AUTH \
|
||||||
|
+#define MOVE_TO_PASSWD_AUTH \
|
||||||
|
if(sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD) { \
|
||||||
|
rc = SSH_OK; \
|
||||||
|
state(conn, SSH_AUTH_PASS_INIT); \
|
||||||
|
@@ -452,25 +452,25 @@ static int myssh_is_known(struct Curl_easy *data)
|
||||||
|
MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED); \
|
||||||
|
}
|
||||||
|
|
||||||
|
-#define MOVE_TO_TERTIARY_AUTH \
|
||||||
|
+#define MOVE_TO_KEY_AUTH \
|
||||||
|
if(sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE) { \
|
||||||
|
rc = SSH_OK; \
|
||||||
|
state(conn, SSH_AUTH_KEY_INIT); \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
else { \
|
||||||
|
- MOVE_TO_LAST_AUTH; \
|
||||||
|
+ MOVE_TO_PASSWD_AUTH; \
|
||||||
|
}
|
||||||
|
|
||||||
|
-#define MOVE_TO_SECONDARY_AUTH \
|
||||||
|
+#define MOVE_TO_GSSAPI_AUTH \
|
||||||
|
if(sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC) { \
|
||||||
|
rc = SSH_OK; \
|
||||||
|
state(conn, SSH_AUTH_GSSAPI); \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
else { \
|
||||||
|
- MOVE_TO_TERTIARY_AUTH; \
|
||||||
|
+ MOVE_TO_KEY_AUTH; \
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int myssh_auth_interactive(struct connectdata *conn)
|
||||||
|
@@ -617,6 +617,16 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
|
||||||
|
}
|
||||||
|
|
||||||
|
sshc->auth_methods = ssh_userauth_list(sshc->ssh_session, NULL);
|
||||||
|
+ if(sshc->auth_methods)
|
||||||
|
+ infof(data, "SSH authentication methods available: %s%s%s%s",
|
||||||
|
+ sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY ?
|
||||||
|
+ "public key, ": "",
|
||||||
|
+ sshc->auth_methods & SSH_AUTH_METHOD_GSSAPI_MIC ?
|
||||||
|
+ "GSSAPI, " : "",
|
||||||
|
+ sshc->auth_methods & SSH_AUTH_METHOD_INTERACTIVE ?
|
||||||
|
+ "keyboard-interactive, " : "",
|
||||||
|
+ sshc->auth_methods & SSH_AUTH_METHOD_PASSWORD ?
|
||||||
|
+ "password": "");
|
||||||
|
if(sshc->auth_methods & SSH_AUTH_METHOD_PUBLICKEY) {
|
||||||
|
state(conn, SSH_AUTH_PKEY_INIT);
|
||||||
|
infof(data, "Authentication using SSH public key file\n");
|
||||||
|
@@ -761,8 +761,8 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
|
||||||
|
}
|
||||||
|
case SSH_AUTH_PKEY_INIT:
|
||||||
|
if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY)) {
|
||||||
|
- MOVE_TO_SECONDARY_AUTH;
|
||||||
|
+ MOVE_TO_GSSAPI_AUTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Two choices, (1) private key was given on CMD,
|
||||||
|
* (2) use the "default" keys. */
|
||||||
|
@@ -776,7 +776,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rc != SSH_OK) {
|
||||||
|
- MOVE_TO_SECONDARY_AUTH;
|
||||||
|
+ MOVE_TO_GSSAPI_AUTH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -826,7 +836,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- MOVE_TO_SECONDARY_AUTH;
|
||||||
|
+ MOVE_TO_GSSAPI_AUTH;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SSH_AUTH_PKEY:
|
||||||
|
@@ -828,13 +828,13 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
infof(data, "Failed public key authentication (rc: %d)\n", rc);
|
||||||
|
- MOVE_TO_SECONDARY_AUTH;
|
||||||
|
+ MOVE_TO_GSSAPI_AUTH;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SSH_AUTH_GSSAPI:
|
||||||
|
if(!(data->set.ssh_auth_types & CURLSSH_AUTH_GSSAPI)) {
|
||||||
|
- MOVE_TO_TERTIARY_AUTH;
|
||||||
|
+ MOVE_TO_KEY_AUTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_userauth_gssapi(sshc->ssh_session);
|
||||||
|
@@ -851,7 +851,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- MOVE_TO_TERTIARY_AUTH;
|
||||||
|
+ MOVE_TO_KEY_AUTH;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SSH_AUTH_KEY_INIT:
|
||||||
|
@@ -736,13 +736,12 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
|
||||||
|
state(conn, SSH_AUTH_KEY);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
- MOVE_TO_LAST_AUTH;
|
||||||
|
+ MOVE_TO_PASSWD_AUTH;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SSH_AUTH_KEY:
|
||||||
|
-
|
||||||
|
- /* Authentication failed. Continue with keyboard-interactive now. */
|
||||||
|
+ /* keyboard-interactive authentication */
|
||||||
|
rc = myssh_auth_interactive(conn);
|
||||||
|
if(rc == SSH_AGAIN) {
|
||||||
|
break;
|
||||||
|
@@ -759,13 +759,15 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
|
||||||
|
if(rc == SSH_OK) {
|
||||||
|
sshc->authed = TRUE;
|
||||||
|
infof(data, "completed keyboard interactive authentication\n");
|
||||||
|
+ state(conn, SSH_AUTH_DONE);
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ MOVE_TO_PASSWD_AUTH;
|
||||||
|
}
|
||||||
|
- state(conn, SSH_AUTH_DONE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SSH_AUTH_PASS_INIT:
|
||||||
|
if(!(data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD)) {
|
||||||
|
- /* Host key authentication is intentionally not implemented */
|
||||||
|
MOVE_TO_ERROR_STATE(CURLE_LOGIN_DENIED);
|
||||||
|
}
|
||||||
|
state(conn, SSH_AUTH_PASS);
|
@ -0,0 +1,124 @@
|
|||||||
|
From 61275672b46d9abb3285740467b882e22ed75da8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Daniel Stenberg <daniel@haxx.se>
|
||||||
|
Date: Thu, 14 Sep 2023 23:28:32 +0200
|
||||||
|
Subject: [PATCH] cookie: remove unnecessary struct fields
|
||||||
|
|
||||||
|
Plus: reduce the hash table size from 256 to 63. It seems unlikely to
|
||||||
|
make much of a speed difference for most use cases but saves 1.5KB of
|
||||||
|
data per instance.
|
||||||
|
|
||||||
|
Closes #11862
|
||||||
|
---
|
||||||
|
lib/cookie.c | 13 +------------
|
||||||
|
lib/cookie.h | 13 ++++---------
|
||||||
|
lib/easy.c | 4 +---
|
||||||
|
3 files changed, 6 insertions(+), 24 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/cookie.c b/lib/cookie.c
|
||||||
|
index 4345a84c6fd9d..e39c89a94a960 100644
|
||||||
|
--- a/lib/cookie.c
|
||||||
|
+++ b/lib/cookie.c
|
||||||
|
@@ -119,7 +119,6 @@ static void freecookie(struct Cookie *co)
|
||||||
|
free(co->name);
|
||||||
|
free(co->value);
|
||||||
|
free(co->maxage);
|
||||||
|
- free(co->version);
|
||||||
|
free(co);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -717,11 +716,7 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(strcasecompare("version", name)) {
|
||||||
|
- strstore(&co->version, whatptr);
|
||||||
|
- if(!co->version) {
|
||||||
|
- badcookie = TRUE;
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
+ /* just ignore */
|
||||||
|
}
|
||||||
|
else if(strcasecompare("max-age", name)) {
|
||||||
|
/* Defined in RFC2109:
|
||||||
|
@@ -1159,7 +1154,6 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||||
|
free(clist->path);
|
||||||
|
free(clist->spath);
|
||||||
|
free(clist->expirestr);
|
||||||
|
- free(clist->version);
|
||||||
|
free(clist->maxage);
|
||||||
|
|
||||||
|
*clist = *co; /* then store all the new data */
|
||||||
|
@@ -1223,9 +1217,6 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
|
||||||
|
c = calloc(1, sizeof(struct CookieInfo));
|
||||||
|
if(!c)
|
||||||
|
return NULL; /* failed to get memory */
|
||||||
|
- c->filename = strdup(file?file:"none"); /* copy the name just in case */
|
||||||
|
- if(!c->filename)
|
||||||
|
- goto fail; /* failed to get memory */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* we got an already existing one, use that */
|
||||||
|
@@ -1378,7 +1369,6 @@ static struct Cookie *dup_cookie(struct Cookie *src)
|
||||||
|
CLONE(name);
|
||||||
|
CLONE(value);
|
||||||
|
CLONE(maxage);
|
||||||
|
- CLONE(version);
|
||||||
|
d->expires = src->expires;
|
||||||
|
d->tailmatch = src->tailmatch;
|
||||||
|
d->secure = src->secure;
|
||||||
|
@@ -1595,7 +1585,6 @@ void Curl_cookie_cleanup(struct CookieInfo *c)
|
||||||
|
{
|
||||||
|
if(c) {
|
||||||
|
unsigned int i;
|
||||||
|
- free(c->filename);
|
||||||
|
for(i = 0; i < COOKIE_HASH_SIZE; i++)
|
||||||
|
Curl_cookie_freelist(c->cookies[i]);
|
||||||
|
free(c); /* free the base struct as well */
|
||||||
|
diff --git a/lib/cookie.h b/lib/cookie.h
|
||||||
|
index b3c0063b2cfb2..41e9e7a6914e0 100644
|
||||||
|
--- a/lib/cookie.h
|
||||||
|
+++ b/lib/cookie.h
|
||||||
|
@@ -36,11 +36,7 @@ struct Cookie {
|
||||||
|
curl_off_t expires; /* expires = <this> */
|
||||||
|
char *expirestr; /* the plain text version */
|
||||||
|
bool tailmatch; /* whether we do tail-matching of the domain name */
|
||||||
|
-
|
||||||
|
- /* RFC 2109 keywords. Version=1 means 2109-compliant cookie sending */
|
||||||
|
- char *version; /* Version = <value> */
|
||||||
|
char *maxage; /* Max-Age = <value> */
|
||||||
|
-
|
||||||
|
bool secure; /* whether the 'secure' keyword was used */
|
||||||
|
bool livecookie; /* updated from a server, not a stored file */
|
||||||
|
bool httponly; /* true if the httponly directive is present */
|
||||||
|
@@ -56,15 +52,14 @@ struct Cookie {
|
||||||
|
int creationtime; /* time when the cookie was written */
|
||||||
|
};
|
||||||
|
|
||||||
|
-#define COOKIE_HASH_SIZE 256
|
||||||
|
+#define COOKIE_HASH_SIZE 63
|
||||||
|
|
||||||
|
struct CookieInfo {
|
||||||
|
/* linked list of cookies we know of */
|
||||||
|
struct Cookie *cookies[COOKIE_HASH_SIZE];
|
||||||
|
|
||||||
|
- char *filename; /* file we read from/write to */
|
||||||
|
bool running; /* state info, for cookie adding information */
|
||||||
|
- long numcookies; /* number of cookies in the "jar" */
|
||||||
|
+ int numcookies; /* number of cookies in the "jar" */
|
||||||
|
bool newsession; /* new session, discard session cookies on load */
|
||||||
|
int lastct; /* last creation-time used in the jar */
|
||||||
|
};
|
||||||
|
diff --git a/lib/easy.c b/lib/easy.c
|
||||||
|
index 16bbd35251d40..03195481f9780 100644
|
||||||
|
--- a/lib/easy.c
|
||||||
|
+++ b/lib/easy.c
|
||||||
|
@@ -925,9 +925,7 @@ struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
|
||||||
|
if(data->cookies) {
|
||||||
|
/* If cookies are enabled in the parent handle, we enable them
|
||||||
|
in the clone as well! */
|
||||||
|
- outcurl->cookies = Curl_cookie_init(data,
|
||||||
|
- data->cookies->filename,
|
||||||
|
- outcurl->cookies,
|
||||||
|
+ outcurl->cookies = Curl_cookie_init(data, NULL, outcurl->cookies,
|
||||||
|
data->set.cookiesession);
|
||||||
|
if(!outcurl->cookies)
|
||||||
|
goto fail;
|
@ -0,0 +1,388 @@
|
|||||||
|
From 47f0d37bfc008c088416f3dcca802c9e087d9bf1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Daniel Stenberg <daniel@haxx.se>
|
||||||
|
Date: Tue, 25 Apr 2023 08:28:01 +0200
|
||||||
|
Subject: [PATCH] lib: unify the upload/method handling
|
||||||
|
|
||||||
|
By making sure we set state.upload based on the set.method value and not
|
||||||
|
independently as set.upload, we reduce confusion and mixup risks, both
|
||||||
|
internally and externally.
|
||||||
|
---
|
||||||
|
lib/curl_rtmp.c | 4 ++--
|
||||||
|
lib/file.c | 4 ++--
|
||||||
|
lib/ftp.c | 8 ++++----
|
||||||
|
lib/http.c | 4 ++--
|
||||||
|
lib/imap.c | 6 +++---
|
||||||
|
lib/rtsp.c | 4 ++--
|
||||||
|
lib/setopt.c | 6 ++----
|
||||||
|
lib/smb.c | 6 +++---
|
||||||
|
lib/smtp.c | 4 ++--
|
||||||
|
lib/tftp.c | 8 ++++----
|
||||||
|
lib/transfer.c | 4 ++--
|
||||||
|
lib/urldata.h | 2 +-
|
||||||
|
lib/ssh-libssh.c | 6 +++---
|
||||||
|
lib/ssh.c | 6 +++---
|
||||||
|
14 files changed, 36 insertions(+), 38 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/curl_rtmp.c b/lib/curl_rtmp.c
|
||||||
|
index 2679a2cdc1afe..406fb42ac0f44 100644
|
||||||
|
--- a/lib/curl_rtmp.c
|
||||||
|
+++ b/lib/curl_rtmp.c
|
||||||
|
@@ -231,7 +231,7 @@ static CURLcode rtmp_connect(struct Curl_easy *data, bool *done)
|
||||||
|
/* We have to know if it's a write before we send the
|
||||||
|
* connect request packet
|
||||||
|
*/
|
||||||
|
- if(conn->data->set.upload)
|
||||||
|
+ if(conn->data->state.upload)
|
||||||
|
r->Link.protocol |= RTMP_FEATURE_WRITE;
|
||||||
|
|
||||||
|
/* For plain streams, use the buffer toggle trick to keep data flowing */
|
||||||
|
@@ -263,7 +263,7 @@ static CURLcode rtmp_do(struct Curl_easy *data, bool *done)
|
||||||
|
if(!RTMP_ConnectStream(r, 0))
|
||||||
|
return CURLE_FAILED_INIT;
|
||||||
|
|
||||||
|
- if(conn->data->set.upload) {
|
||||||
|
+ if(conn->data->state.upload) {
|
||||||
|
Curl_pgrsSetUploadSize(conn->data, conn->data->state.infilesize);
|
||||||
|
Curl_setup_transfer(conn, -1, -1, FALSE, NULL, FIRSTSOCKET, NULL);
|
||||||
|
}
|
||||||
|
diff --git a/lib/file.c b/lib/file.c
|
||||||
|
index 51c5d07ce40ab..c751e8861a99b 100644
|
||||||
|
--- a/lib/file.c
|
||||||
|
+++ b/lib/file.c
|
||||||
|
@@ -240,7 +240,7 @@ static CURLcode file_connect(struct Curl_easy *data, bool *done)
|
||||||
|
file->freepath = real_path; /* free this when done */
|
||||||
|
|
||||||
|
file->fd = fd;
|
||||||
|
- if(!data->set.upload && (fd == -1)) {
|
||||||
|
+ if(!data->state.upload && (fd == -1)) {
|
||||||
|
failf(data, "Couldn't open file %s", data->state.path);
|
||||||
|
file_done(conn, CURLE_FILE_COULDNT_READ_FILE, FALSE);
|
||||||
|
return CURLE_FILE_COULDNT_READ_FILE;
|
||||||
|
@@ -422,7 +422,7 @@ static CURLcode file_do(struct Curl_easy *data, bool *done)
|
||||||
|
|
||||||
|
Curl_pgrsStartNow(data);
|
||||||
|
|
||||||
|
- if(data->set.upload)
|
||||||
|
+ if(data->state.upload)
|
||||||
|
return file_upload(conn);
|
||||||
|
|
||||||
|
file = conn->data->req.protop;
|
||||||
|
diff --git a/lib/ftp.c b/lib/ftp.c
|
||||||
|
index f50d7baf622f8..4ff68cc454cbc 100644
|
||||||
|
--- a/lib/ftp.c
|
||||||
|
+++ b/lib/ftp.c
|
||||||
|
@@ -1381,7 +1381,7 @@ static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data)
|
||||||
|
data->set.str[STRING_CUSTOMREQUEST]:
|
||||||
|
(data->set.ftp_list_only?"NLST":"LIST"));
|
||||||
|
}
|
||||||
|
- else if(data->set.upload) {
|
||||||
|
+ else if(data->state.upload) {
|
||||||
|
PPSENDF(&conn->proto.ftpc.pp, "PRET STOR %s", conn->proto.ftpc.file);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
@@ -3368,7 +3368,7 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status,
|
||||||
|
/* the response code from the transfer showed an error already so no
|
||||||
|
use checking further */
|
||||||
|
;
|
||||||
|
- else if(data->set.upload) {
|
||||||
|
+ else if(data->state.upload) {
|
||||||
|
if((-1 != data->state.infilesize) &&
|
||||||
|
(data->state.infilesize != *ftp->bytecountp) &&
|
||||||
|
!data->set.crlf &&
|
||||||
|
@@ -3640,7 +3640,7 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
|
||||||
|
connected back to us */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- else if(data->set.upload) {
|
||||||
|
+ else if(data->state.upload) {
|
||||||
|
result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_STOR_TYPE);
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
|
@@ -4217,7 +4217,7 @@ CURLcode ftp_parse_url_path(struct Curl_easy *data)
|
||||||
|
ftpc->file = NULL; /* instead of point to a zero byte, we make it a NULL
|
||||||
|
pointer */
|
||||||
|
|
||||||
|
- if(data->set.upload && !ftpc->file && (ftp->transfer == FTPTRANSFER_BODY)) {
|
||||||
|
+ if(data->state.upload && !ftpc->file && (ftp->transfer == FTPTRANSFER_BODY)) {
|
||||||
|
/* We need a file name when uploading. Return error! */
|
||||||
|
failf(data, "Uploading to a URL without a file name!");
|
||||||
|
return CURLE_URL_MALFORMAT;
|
||||||
|
diff --git a/lib/http.c b/lib/http.c
|
||||||
|
index 80e43f6f361e8..bffdd3468536d 100644
|
||||||
|
--- a/lib/http.c
|
||||||
|
+++ b/lib/http.c
|
||||||
|
@@ -2112,7 +2112,7 @@ void Curl_http_method(struct Curl_easy *data, struct connectdata *conn,
|
||||||
|
http->writebytecount = http->readbytecount = 0;
|
||||||
|
|
||||||
|
if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) &&
|
||||||
|
- data->set.upload) {
|
||||||
|
+ data->state.upload) {
|
||||||
|
httpreq = HTTPREQ_PUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2423,7 +2423,7 @@ CURLcode Curl_http_body(struct Curl_easy *data, struct connectdata *conn,
|
||||||
|
if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
|
||||||
|
(((httpreq == HTTPREQ_POST_MIME || httpreq == HTTPREQ_POST_FORM) &&
|
||||||
|
http->postsize < 0) ||
|
||||||
|
- (data->set.upload && data->state.infilesize == -1))) {
|
||||||
|
+ (data->state.upload && data->state.infilesize == -1))) {
|
||||||
|
if(conn->bits.authneg)
|
||||||
|
/* don't enable chunked during auth neg */
|
||||||
|
;
|
||||||
|
diff --git a/lib/imap.c b/lib/imap.c
|
||||||
|
index c2f675d4b2618..1952e66a1efcd 100644
|
||||||
|
--- a/lib/imap.c
|
||||||
|
+++ b/lib/imap.c
|
||||||
|
@@ -1511,10 +1511,10 @@ static CURLcode imap_done(struct Curl_easy *data, CURLcode status,
|
||||||
|
result = status; /* use the already set error code */
|
||||||
|
}
|
||||||
|
else if(!data->set.connect_only && !imap->custom &&
|
||||||
|
- (imap->uid || data->set.upload ||
|
||||||
|
+ (imap->uid || data->state.upload ||
|
||||||
|
data->set.mimepost.kind != MIMEKIND_NONE)) {
|
||||||
|
/* Handle responses after FETCH or APPEND transfer has finished */
|
||||||
|
- if(!data->set.upload && data->set.mimepost.kind == MIMEKIND_NONE)
|
||||||
|
+ if(!data->state.upload && data->set.mimepost.kind == MIMEKIND_NONE)
|
||||||
|
state(conn, IMAP_FETCH_FINAL);
|
||||||
|
else {
|
||||||
|
/* End the APPEND command first by sending an empty line */
|
||||||
|
@@ -1581,7 +1581,7 @@ static CURLcode imap_perform(struct Curl_easy *data, bool *connected,
|
||||||
|
selected = TRUE;
|
||||||
|
|
||||||
|
/* Start the first command in the DO phase */
|
||||||
|
- if(conn->data->set.upload || data->set.mimepost.kind != MIMEKIND_NONE)
|
||||||
|
+ if(conn->data->state.upload || data->set.mimepost.kind != MIMEKIND_NONE)
|
||||||
|
/* APPEND can be executed directly */
|
||||||
|
result = imap_perform_append(conn);
|
||||||
|
else if(imap->custom && (selected || !imap->mailbox))
|
||||||
|
index ea99d720ec4eb..ccd7264b00e74 100644
|
||||||
|
--- a/lib/rtsp.c
|
||||||
|
+++ b/lib/rtsp.c
|
||||||
|
@@ -493,7 +493,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
||||||
|
rtspreq == RTSPREQ_SET_PARAMETER ||
|
||||||
|
rtspreq == RTSPREQ_GET_PARAMETER) {
|
||||||
|
|
||||||
|
- if(data->set.upload) {
|
||||||
|
+ if(data->state.upload) {
|
||||||
|
putsize = data->state.infilesize;
|
||||||
|
data->set.httpreq = HTTPREQ_PUT;
|
||||||
|
|
||||||
|
@@ -512,7 +512,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
|
||||||
|
if(!Curl_checkheaders(conn, "Content-Length")) {
|
||||||
|
result = Curl_add_bufferf(req_buffer,
|
||||||
|
"Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n",
|
||||||
|
- (data->set.upload ? putsize : postsize));
|
||||||
|
+ (data->state.upload ? putsize : postsize));
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
diff --git a/lib/setopt.c b/lib/setopt.c
|
||||||
|
index 38f5711e44191..0c3b9634d1192 100644
|
||||||
|
--- a/lib/setopt.c
|
||||||
|
+++ b/lib/setopt.c
|
||||||
|
@@ -333,8 +333,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
|
||||||
|
* We want to sent data to the remote host. If this is HTTP, that equals
|
||||||
|
* using the PUT request.
|
||||||
|
*/
|
||||||
|
- data->set.upload = (0 != va_arg(param, long)) ? TRUE : FALSE;
|
||||||
|
- if(data->set.upload) {
|
||||||
|
+ arg = va_arg(param, long);
|
||||||
|
+ if(arg) {
|
||||||
|
/* If this is HTTP, PUT is what's needed to "upload" */
|
||||||
|
data->set.httpreq = HTTPREQ_PUT;
|
||||||
|
data->set.opt_no_body = FALSE; /* this is implied */
|
||||||
|
@@ -888,7 +887,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
|
||||||
|
*/
|
||||||
|
if(va_arg(param, long)) {
|
||||||
|
data->set.httpreq = HTTPREQ_GET;
|
||||||
|
- data->set.upload = FALSE; /* switch off upload */
|
||||||
|
data->set.opt_no_body = FALSE; /* this is implied */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
diff --git a/lib/smb.c b/lib/smb.c
|
||||||
|
index a1e444ee6b97e..d6822213529bc 100644
|
||||||
|
--- a/lib/smb.c
|
||||||
|
+++ b/lib/smb.c
|
||||||
|
@@ -530,7 +530,7 @@ static CURLcode smb_send_open(struct Curl_easy *data)
|
||||||
|
byte_count = strlen(req->path);
|
||||||
|
msg.name_length = smb_swap16((unsigned short)byte_count);
|
||||||
|
msg.share_access = smb_swap32(SMB_FILE_SHARE_ALL);
|
||||||
|
- if(conn->data->set.upload) {
|
||||||
|
+ if(conn->data->state.upload) {
|
||||||
|
msg.access = smb_swap32(SMB_GENERIC_READ | SMB_GENERIC_WRITE);
|
||||||
|
msg.create_disposition = smb_swap32(SMB_FILE_OVERWRITE_IF);
|
||||||
|
}
|
||||||
|
@@ -813,7 +813,7 @@ static CURLcode smb_request_state(struct Curl_easy *data, bool *done)
|
||||||
|
smb_m = (const struct smb_nt_create_response*) msg;
|
||||||
|
req->fid = smb_swap16(smb_m->fid);
|
||||||
|
conn->data->req.offset = 0;
|
||||||
|
- if(conn->data->set.upload) {
|
||||||
|
+ if(conn->data->state.upload) {
|
||||||
|
conn->data->req.size = conn->data->state.infilesize;
|
||||||
|
Curl_pgrsSetUploadSize(conn->data, conn->data->req.size);
|
||||||
|
next_state = SMB_UPLOAD;
|
||||||
|
diff --git a/lib/smtp.c b/lib/smtp.c
|
||||||
|
index 7a030308d4689..c182cace742d7 100644
|
||||||
|
--- a/lib/smtp.c
|
||||||
|
+++ b/lib/smtp.c
|
||||||
|
@@ -1419,7 +1419,7 @@ static CURLcode smtp_done(struct Curl_easy *data, CURLcode status,
|
||||||
|
result = status; /* use the already set error code */
|
||||||
|
}
|
||||||
|
else if(!data->set.connect_only && data->set.mail_rcpt &&
|
||||||
|
- (data->set.upload || data->set.mimepost.kind)) {
|
||||||
|
+ (data->state.upload || data->set.mimepost.kind)) {
|
||||||
|
/* Calculate the EOB taking into account any terminating CRLF from the
|
||||||
|
previous line of the email or the CRLF of the DATA command when there
|
||||||
|
is "no mail data". RFC-5321, sect. 4.1.1.4.
|
||||||
|
@@ -1511,7 +1511,7 @@ static CURLcode smtp_perform(struct Curl_easy *data, bool *connected,
|
||||||
|
smtp->eob = 2;
|
||||||
|
|
||||||
|
/* Start the first command in the DO phase */
|
||||||
|
- if((data->set.upload || data->set.mimepost.kind) && data->set.mail_rcpt)
|
||||||
|
+ if((data->state.upload || data->set.mimepost.kind) && data->set.mail_rcpt)
|
||||||
|
/* MAIL transfer */
|
||||||
|
result = smtp_perform_mail(conn);
|
||||||
|
else
|
||||||
|
diff --git a/lib/tftp.c b/lib/tftp.c
|
||||||
|
index 164d3c723c5b9..8ed1b887b4d21 100644
|
||||||
|
--- a/lib/tftp.c
|
||||||
|
+++ b/lib/tftp.c
|
||||||
|
@@ -370,7 +370,7 @@ static CURLcode tftp_parse_option_ack(struct tftp_state_data *state,
|
||||||
|
|
||||||
|
/* tsize should be ignored on upload: Who cares about the size of the
|
||||||
|
remote file? */
|
||||||
|
- if(!data->set.upload) {
|
||||||
|
+ if(!data->state.upload) {
|
||||||
|
if(!tsize) {
|
||||||
|
failf(data, "invalid tsize -:%s:- value in OACK packet", value);
|
||||||
|
return CURLE_TFTP_ILLEGAL;
|
||||||
|
@@ -451,7 +451,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state,
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if(data->set.upload) {
|
||||||
|
+ if(data->state.upload) {
|
||||||
|
/* If we are uploading, send an WRQ */
|
||||||
|
setpacketevent(&state->spacket, TFTP_EVENT_WRQ);
|
||||||
|
state->conn->data->req.upload_fromhere =
|
||||||
|
@@ -486,7 +486,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state,
|
||||||
|
if(!data->set.tftp_no_options) {
|
||||||
|
char buf[64];
|
||||||
|
/* add tsize option */
|
||||||
|
- if(data->set.upload && (data->state.infilesize != -1))
|
||||||
|
+ if(data->state.upload && (data->state.infilesize != -1))
|
||||||
|
snprintf(buf, sizeof(buf), "%" CURL_FORMAT_CURL_OFF_T,
|
||||||
|
data->state.infilesize);
|
||||||
|
else
|
||||||
|
@@ -540,7 +540,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state,
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TFTP_EVENT_OACK:
|
||||||
|
- if(data->set.upload) {
|
||||||
|
+ if(data->state.upload) {
|
||||||
|
result = tftp_connect_for_tx(state, event);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
diff --git a/lib/transfer.c b/lib/transfer.c
|
||||||
|
index e9ab8fbf09510..cb69f3365855a 100644
|
||||||
|
--- a/lib/transfer.c
|
||||||
|
+++ b/lib/transfer.c
|
||||||
|
@@ -1293,6 +1293,7 @@ void Curl_init_CONNECT(struct Curl_easy *data)
|
||||||
|
{
|
||||||
|
data->state.fread_func = data->set.fread_func_set;
|
||||||
|
data->state.in = data->set.in_set;
|
||||||
|
+ data->state.upload = (data->set.httpreq == HTTPREQ_PUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -1770,7 +1770,7 @@ CURLcode Curl_retry_request(struct Curl_easy *data, char **url)
|
||||||
|
|
||||||
|
/* if we're talking upload, we can't do the checks below, unless the protocol
|
||||||
|
is HTTP as when uploading over HTTP we will still get a response */
|
||||||
|
- if(data->set.upload &&
|
||||||
|
+ if(data->state.upload &&
|
||||||
|
!(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)))
|
||||||
|
return CURLE_OK;
|
||||||
|
|
||||||
|
diff --git a/lib/urldata.h b/lib/urldata.h
|
||||||
|
index cca992a0295aa..a8580bdb66fe8 100644
|
||||||
|
--- a/lib/urldata.h
|
||||||
|
+++ b/lib/urldata.h
|
||||||
|
@@ -1494,6 +1494,7 @@ struct UrlState {
|
||||||
|
#ifdef CURLDEBUG
|
||||||
|
bool conncache_lock;
|
||||||
|
#endif
|
||||||
|
+ bool upload; /* upload request */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1838,7 +1839,6 @@ struct UserDefined {
|
||||||
|
bool http_set_referer; /* is a custom referer used */
|
||||||
|
bool http_auto_referer; /* set "correct" referer when following location: */
|
||||||
|
bool opt_no_body; /* as set with CURLOPT_NOBODY */
|
||||||
|
- bool upload; /* upload request */
|
||||||
|
enum CURL_NETRC_OPTION
|
||||||
|
use_netrc; /* defined in include/curl.h */
|
||||||
|
bool verbose; /* output verbosity */
|
||||||
|
diff --git a/lib/ssh-libssh.c b/lib/ssh-libssh.c
|
||||||
|
index b31f741ba9492..d60edaa303642 100644
|
||||||
|
--- a/lib/ssh-libssh.c
|
||||||
|
+++ b/lib/ssh-libssh.c
|
||||||
|
@@ -1209,7 +1209,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
|
||||||
|
}
|
||||||
|
|
||||||
|
case SSH_SFTP_TRANS_INIT:
|
||||||
|
- if(data->set.upload)
|
||||||
|
+ if(data->state.upload)
|
||||||
|
state(conn, SSH_SFTP_UPLOAD_INIT);
|
||||||
|
else {
|
||||||
|
if(protop->path[strlen(protop->path)-1] == '/')
|
||||||
|
@@ -1802,7 +1802,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
|
||||||
|
/* Functions from the SCP subsystem cannot handle/return SSH_AGAIN */
|
||||||
|
ssh_set_blocking(sshc->ssh_session, 1);
|
||||||
|
|
||||||
|
- if(data->set.upload) {
|
||||||
|
+ if(data->state.upload) {
|
||||||
|
if(data->state.infilesize < 0) {
|
||||||
|
failf(data, "SCP requires a known file size for upload");
|
||||||
|
sshc->actualcode = CURLE_UPLOAD_FAILED;
|
||||||
|
@@ -1907,7 +1907,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SSH_SCP_DONE:
|
||||||
|
- if(data->set.upload)
|
||||||
|
+ if(data->state.upload)
|
||||||
|
state(conn, SSH_SCP_SEND_EOF);
|
||||||
|
else
|
||||||
|
state(conn, SSH_SCP_CHANNEL_FREE);
|
||||||
|
diff --git a/lib/ssh.c b/lib/ssh.c
|
||||||
|
index f1154dc47a74e..f2e5352d1fd3a 100644
|
||||||
|
--- a/lib/ssh.c
|
||||||
|
+++ b/lib/ssh.c
|
||||||
|
@@ -2019,7 +2019,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
|
||||||
|
}
|
||||||
|
|
||||||
|
case SSH_SFTP_TRANS_INIT:
|
||||||
|
- if(data->set.upload)
|
||||||
|
+ if(data->state.upload)
|
||||||
|
state(conn, SSH_SFTP_UPLOAD_INIT);
|
||||||
|
else {
|
||||||
|
if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
|
||||||
|
@@ -2691,7 +2691,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if(data->set.upload) {
|
||||||
|
+ if(data->state.upload) {
|
||||||
|
if(data->state.infilesize < 0) {
|
||||||
|
failf(data, "SCP requires a known file size for upload");
|
||||||
|
sshc->actualcode = CURLE_UPLOAD_FAILED;
|
||||||
|
@@ -2831,7 +2831,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SSH_SCP_DONE:
|
||||||
|
- if(data->set.upload)
|
||||||
|
+ if(data->state.upload)
|
||||||
|
state(conn, SSH_SCP_SEND_EOF);
|
||||||
|
else
|
||||||
|
state(conn, SSH_SCP_CHANNEL_FREE);
|
@ -0,0 +1,193 @@
|
|||||||
|
diff -up curl-7.61.1/lib/http2.c.25a25f45 curl-7.61.1/lib/http2.c
|
||||||
|
--- curl-7.61.1/lib/http2.c.25a25f45 2023-08-07 14:03:42.043463284 +0200
|
||||||
|
+++ curl-7.61.1/lib/http2.c 2023-08-07 14:10:24.769489855 +0200
|
||||||
|
@@ -1202,7 +1202,7 @@ CURLcode Curl_http2_request_upgrade(Curl
|
||||||
|
binlen = nghttp2_pack_settings_payload(binsettings, H2_BINSETTINGS_LEN,
|
||||||
|
httpc->local_settings,
|
||||||
|
httpc->local_settings_num);
|
||||||
|
- if(!binlen) {
|
||||||
|
+ if(binlen <= 0) {
|
||||||
|
failf(conn->data, "nghttp2 unexpectedly failed on pack_settings_payload");
|
||||||
|
Curl_add_buffer_free(req);
|
||||||
|
return CURLE_FAILED_INIT;
|
||||||
|
@@ -1285,6 +1285,14 @@ static int h2_process_pending_input(stru
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if(nghttp2_session_check_request_allowed(httpc->h2) == 0) {
|
||||||
|
+ /* No more requests are allowed in the current session, so
|
||||||
|
+ the connection may not be reused. This is set when a
|
||||||
|
+ GOAWAY frame has been received or when the limit of stream
|
||||||
|
+ identifiers has been reached. */
|
||||||
|
+ connclose(conn, "http/2: No new requests allowed");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if(should_close_session(httpc)) {
|
||||||
|
H2BUGF(infof(data,
|
||||||
|
"h2_process_pending_input: nothing to do in this session\n"));
|
||||||
|
@@ -1297,7 +1305,6 @@ static int h2_process_pending_input(stru
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1455,8 +1462,6 @@ static int h2_session_send(struct Curl_e
|
||||||
|
static ssize_t http2_recv(struct connectdata *conn, int sockindex,
|
||||||
|
char *mem, size_t len, CURLcode *err)
|
||||||
|
{
|
||||||
|
- CURLcode result = CURLE_OK;
|
||||||
|
- ssize_t rv;
|
||||||
|
ssize_t nread;
|
||||||
|
struct http_conn *httpc = &conn->proto.httpc;
|
||||||
|
struct Curl_easy *data = conn->data;
|
||||||
|
@@ -1519,8 +1524,7 @@ static ssize_t http2_recv(struct connect
|
||||||
|
/* We have paused nghttp2, but we have no pause data (see
|
||||||
|
on_data_chunk_recv). */
|
||||||
|
httpc->pause_stream_id = 0;
|
||||||
|
- if(h2_process_pending_input(conn, httpc, &result) != 0) {
|
||||||
|
- *err = result;
|
||||||
|
+ if(h2_process_pending_input(conn, httpc, err) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1549,8 +1553,7 @@ static ssize_t http2_recv(struct connect
|
||||||
|
frames, then we have to call it again with 0-length data.
|
||||||
|
Without this, on_stream_close callback will not be called,
|
||||||
|
and stream could be hanged. */
|
||||||
|
- if(h2_process_pending_input(conn, httpc, &result) != 0) {
|
||||||
|
- *err = result;
|
||||||
|
+ if(h2_process_pending_input(conn, httpc, err) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1573,7 +1576,6 @@ static ssize_t http2_recv(struct connect
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
- char *inbuf;
|
||||||
|
/* remember where to store incoming data for this stream and how big the
|
||||||
|
buffer is */
|
||||||
|
stream->mem = mem;
|
||||||
|
@@ -1582,16 +1584,15 @@ static ssize_t http2_recv(struct connect
|
||||||
|
|
||||||
|
if(httpc->inbuflen == 0) {
|
||||||
|
nread = ((Curl_recv *)httpc->recv_underlying)(
|
||||||
|
- conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, &result);
|
||||||
|
+ conn, FIRSTSOCKET, httpc->inbuf, H2_BUFSIZE, err);
|
||||||
|
|
||||||
|
if(nread == -1) {
|
||||||
|
- if(result != CURLE_AGAIN)
|
||||||
|
+ if(*err != CURLE_AGAIN)
|
||||||
|
failf(data, "Failed receiving HTTP2 data");
|
||||||
|
else if(stream->closed)
|
||||||
|
/* received when the stream was already closed! */
|
||||||
|
return http2_handle_stream_close(conn, data, stream, err);
|
||||||
|
|
||||||
|
- *err = result;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1604,47 +1605,17 @@ static ssize_t http2_recv(struct connect
|
||||||
|
H2BUGF(infof(data, "nread=%zd\n", nread));
|
||||||
|
|
||||||
|
httpc->inbuflen = nread;
|
||||||
|
- inbuf = httpc->inbuf;
|
||||||
|
+
|
||||||
|
+ DEBUGASSERT(httpc->nread_inbuf == 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nread = httpc->inbuflen - httpc->nread_inbuf;
|
||||||
|
- inbuf = httpc->inbuf + httpc->nread_inbuf;
|
||||||
|
-
|
||||||
|
+ (void)nread; /* silence warning, used in debug */
|
||||||
|
H2BUGF(infof(data, "Use data left in connection buffer, nread=%zd\n",
|
||||||
|
nread));
|
||||||
|
}
|
||||||
|
- rv = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)inbuf, nread);
|
||||||
|
-
|
||||||
|
- if(nghttp2_is_fatal((int)rv)) {
|
||||||
|
- failf(data, "nghttp2_session_mem_recv() returned %zd:%s\n",
|
||||||
|
- rv, nghttp2_strerror((int)rv));
|
||||||
|
- *err = CURLE_RECV_ERROR;
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
- H2BUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", rv));
|
||||||
|
- if(nread == rv) {
|
||||||
|
- H2BUGF(infof(data, "All data in connection buffer processed\n"));
|
||||||
|
- httpc->inbuflen = 0;
|
||||||
|
- httpc->nread_inbuf = 0;
|
||||||
|
- }
|
||||||
|
- else {
|
||||||
|
- httpc->nread_inbuf += rv;
|
||||||
|
- H2BUGF(infof(data, "%zu bytes left in connection buffer\n",
|
||||||
|
- httpc->inbuflen - httpc->nread_inbuf));
|
||||||
|
- }
|
||||||
|
- /* Always send pending frames in nghttp2 session, because
|
||||||
|
- nghttp2_session_mem_recv() may queue new frame */
|
||||||
|
- rv = h2_session_send(data, httpc->h2);
|
||||||
|
- if(rv != 0) {
|
||||||
|
- *err = CURLE_SEND_ERROR;
|
||||||
|
- return -1;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if(should_close_session(httpc)) {
|
||||||
|
- H2BUGF(infof(data, "http2_recv: nothing to do in this session\n"));
|
||||||
|
- *err = CURLE_HTTP2;
|
||||||
|
+ if(h2_process_pending_input(conn, httpc, err) != 0)
|
||||||
|
return -1;
|
||||||
|
- }
|
||||||
|
}
|
||||||
|
if(stream->memlen) {
|
||||||
|
ssize_t retlen = stream->memlen;
|
||||||
|
@@ -2108,7 +2079,6 @@ CURLcode Curl_http2_switched(struct conn
|
||||||
|
CURLcode result;
|
||||||
|
struct http_conn *httpc = &conn->proto.httpc;
|
||||||
|
int rv;
|
||||||
|
- ssize_t nproc;
|
||||||
|
struct Curl_easy *data = conn->data;
|
||||||
|
struct HTTP *stream = conn->data->req.protop;
|
||||||
|
|
||||||
|
@@ -2186,39 +2156,10 @@ CURLcode Curl_http2_switched(struct conn
|
||||||
|
memcpy(httpc->inbuf, mem, nread);
|
||||||
|
httpc->inbuflen = nread;
|
||||||
|
|
||||||
|
- nproc = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)httpc->inbuf,
|
||||||
|
- httpc->inbuflen);
|
||||||
|
+ DEBUGASSERT(httpc->nread_inbuf == 0);
|
||||||
|
|
||||||
|
- if(nghttp2_is_fatal((int)nproc)) {
|
||||||
|
- failf(data, "nghttp2_session_mem_recv() failed: %s(%d)",
|
||||||
|
- nghttp2_strerror((int)nproc), (int)nproc);
|
||||||
|
+ if(-1 == h2_process_pending_input(conn, httpc, &result))
|
||||||
|
return CURLE_HTTP2;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- H2BUGF(infof(data, "nghttp2_session_mem_recv() returns %zd\n", nproc));
|
||||||
|
-
|
||||||
|
- if((ssize_t)nread == nproc) {
|
||||||
|
- httpc->inbuflen = 0;
|
||||||
|
- httpc->nread_inbuf = 0;
|
||||||
|
- }
|
||||||
|
- else {
|
||||||
|
- httpc->nread_inbuf += nproc;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- /* Try to send some frames since we may read SETTINGS already. */
|
||||||
|
- rv = h2_session_send(data, httpc->h2);
|
||||||
|
-
|
||||||
|
- if(rv != 0) {
|
||||||
|
- failf(data, "nghttp2_session_send() failed: %s(%d)",
|
||||||
|
- nghttp2_strerror(rv), rv);
|
||||||
|
- return CURLE_HTTP2;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if(should_close_session(httpc)) {
|
||||||
|
- H2BUGF(infof(data,
|
||||||
|
- "nghttp2_session_send(): nothing to do in this session\n"));
|
||||||
|
- return CURLE_HTTP2;
|
||||||
|
- }
|
||||||
|
|
||||||
|
return CURLE_OK;
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
diff -up curl-7.61.1/lib/http2.c.c1b6a384 curl-7.61.1/lib/http2.c
|
||||||
|
--- curl-7.61.1/lib/http2.c.c1b6a384 2023-08-07 13:59:18.482137005 +0200
|
||||||
|
+++ curl-7.61.1/lib/http2.c 2023-08-07 14:03:42.043463284 +0200
|
||||||
|
@@ -1467,6 +1467,11 @@ static ssize_t http2_recv(struct connect
|
||||||
|
if(should_close_session(httpc)) {
|
||||||
|
H2BUGF(infof(data,
|
||||||
|
"http2_recv: nothing to do in this session\n"));
|
||||||
|
+ if(conn->bits.close) {
|
||||||
|
+ /* already marked for closure, return OK and we're done */
|
||||||
|
+ *err = CURLE_OK;
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
*err = CURLE_HTTP2;
|
||||||
|
return -1;
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
From 2b0994c29a721c91c572cff7808c572a24d251eb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Daniel Stenberg <daniel@haxx.se>
|
||||||
|
Date: Thu, 23 Nov 2023 08:15:47 +0100
|
||||||
|
Subject: [PATCH] cookie: lowercase the domain names before PSL checks
|
||||||
|
|
||||||
|
Reported-by: Harry Sintonen
|
||||||
|
|
||||||
|
Closes #12387
|
||||||
|
---
|
||||||
|
lib/cookie.c | 24 ++++++++++++++++--------
|
||||||
|
1 file changed, 16 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/cookie.c b/lib/cookie.c
|
||||||
|
index 568cf537ad1b1f..9095cea3e97f22 100644
|
||||||
|
--- a/lib/cookie.c
|
||||||
|
+++ b/lib/cookie.c
|
||||||
|
@@ -1027,15 +1027,23 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||||
|
#ifdef USE_LIBPSL
|
||||||
|
/* Check if the domain is a Public Suffix and if yes, ignore the cookie. */
|
||||||
|
if(domain && co->domain && !isip(co->domain)) {
|
||||||
|
- const psl_ctx_t *psl = Curl_psl_use(data);
|
||||||
|
- int acceptable;
|
||||||
|
-
|
||||||
|
- if(psl) {
|
||||||
|
- acceptable = psl_is_cookie_domain_acceptable(psl, domain, co->domain);
|
||||||
|
- Curl_psl_release(data);
|
||||||
|
+ bool acceptable = FALSE;
|
||||||
|
+ char lcase[256];
|
||||||
|
+ char lcookie[256];
|
||||||
|
+ size_t dlen = strlen(domain);
|
||||||
|
+ size_t clen = strlen(co->domain);
|
||||||
|
+ if((dlen < sizeof(lcase)) && (clen < sizeof(lcookie))) {
|
||||||
|
+ const psl_ctx_t *psl = Curl_psl_use(data);
|
||||||
|
+ if(psl) {
|
||||||
|
+ /* the PSL check requires lowercase domain name and pattern */
|
||||||
|
+ Curl_strntolower(lcase, domain, dlen + 1);
|
||||||
|
+ Curl_strntolower(lcookie, co->domain, clen + 1);
|
||||||
|
+ acceptable = psl_is_cookie_domain_acceptable(psl, lcase, lcookie);
|
||||||
|
+ Curl_psl_release(data);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ acceptable = !bad_domain(domain);
|
||||||
|
}
|
||||||
|
- else
|
||||||
|
- acceptable = !bad_domain(domain);
|
||||||
|
|
||||||
|
if(!acceptable) {
|
||||||
|
infof(data, "cookie '%s' dropped, domain '%s' must not "
|
@ -0,0 +1,136 @@
|
|||||||
|
From 0023fce38d3bd6ee0e9b6ff8708fee1195057846 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Barry Pollard <barry_pollard@hotmail.com>
|
||||||
|
Date: Sun, 22 Sep 2019 21:17:12 +0100
|
||||||
|
Subject: [PATCH] http: lowercase headernames for HTTP/2 and HTTP/3
|
||||||
|
|
||||||
|
Closes #4401
|
||||||
|
Fixes #4400
|
||||||
|
---
|
||||||
|
lib/strcase.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
lib/strcase.h | 2 ++
|
||||||
|
5 files changed, 95 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/strcase.c b/lib/strcase.c
|
||||||
|
index 24bcca932..098cec7a8 100644
|
||||||
|
--- a/lib/strcase.c
|
||||||
|
+++ b/lib/strcase.c
|
||||||
|
@@ -93,6 +93,75 @@ char Curl_raw_toupper(char in)
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
|
+
|
||||||
|
+/* Portable, consistent tolower (remember EBCDIC). Do not use tolower() because
|
||||||
|
+ its behavior is altered by the current locale. */
|
||||||
|
+char Curl_raw_tolower(char in)
|
||||||
|
+{
|
||||||
|
+#if !defined(CURL_DOES_CONVERSIONS)
|
||||||
|
+ if(in >= 'A' && in <= 'Z')
|
||||||
|
+ return (char)('a' + in - 'A');
|
||||||
|
+#else
|
||||||
|
+ switch(in) {
|
||||||
|
+ case 'A':
|
||||||
|
+ return 'a';
|
||||||
|
+ case 'B':
|
||||||
|
+ return 'b';
|
||||||
|
+ case 'C':
|
||||||
|
+ return 'c';
|
||||||
|
+ case 'D':
|
||||||
|
+ return 'd';
|
||||||
|
+ case 'E':
|
||||||
|
+ return 'e';
|
||||||
|
+ case 'F':
|
||||||
|
+ return 'f';
|
||||||
|
+ case 'G':
|
||||||
|
+ return 'g';
|
||||||
|
+ case 'H':
|
||||||
|
+ return 'h';
|
||||||
|
+ case 'I':
|
||||||
|
+ return 'i';
|
||||||
|
+ case 'J':
|
||||||
|
+ return 'j';
|
||||||
|
+ case 'K':
|
||||||
|
+ return 'k';
|
||||||
|
+ case 'L':
|
||||||
|
+ return 'l';
|
||||||
|
+ case 'M':
|
||||||
|
+ return 'm';
|
||||||
|
+ case 'N':
|
||||||
|
+ return 'n';
|
||||||
|
+ case 'O':
|
||||||
|
+ return 'o';
|
||||||
|
+ case 'P':
|
||||||
|
+ return 'p';
|
||||||
|
+ case 'Q':
|
||||||
|
+ return 'q';
|
||||||
|
+ case 'R':
|
||||||
|
+ return 'r';
|
||||||
|
+ case 'S':
|
||||||
|
+ return 's';
|
||||||
|
+ case 'T':
|
||||||
|
+ return 't';
|
||||||
|
+ case 'U':
|
||||||
|
+ return 'u';
|
||||||
|
+ case 'V':
|
||||||
|
+ return 'v';
|
||||||
|
+ case 'W':
|
||||||
|
+ return 'w';
|
||||||
|
+ case 'X':
|
||||||
|
+ return 'X';
|
||||||
|
+ case 'Y':
|
||||||
|
+ return 'y';
|
||||||
|
+ case 'Z':
|
||||||
|
+ return 'z';
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ return in;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* Curl_strcasecompare() is for doing "raw" case insensitive strings. This is
|
||||||
|
* meant to be locale independent and only compare strings we know are safe
|
||||||
|
@@ -234,6 +303,21 @@ void Curl_strntoupper(char *dest, const char *src, size_t n)
|
||||||
|
} while(*src++ && --n);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Copy a lower case version of the string from src to dest. The
|
||||||
|
+ * strings may overlap. No more than n characters of the string are copied
|
||||||
|
+ * (including any NUL) and the destination string will NOT be
|
||||||
|
+ * NUL-terminated if that limit is reached.
|
||||||
|
+ */
|
||||||
|
+void Curl_strntolower(char *dest, const char *src, size_t n)
|
||||||
|
+{
|
||||||
|
+ if(n < 1)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ do {
|
||||||
|
+ *dest++ = Curl_raw_tolower(*src);
|
||||||
|
+ } while(*src++ && --n);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Compare case-sensitive NUL-terminated strings, taking care of possible
|
||||||
|
* null pointers. Return true if arguments match.
|
||||||
|
*/
|
||||||
|
diff --git a/lib/strcase.h b/lib/strcase.h
|
||||||
|
index 6fee3840e..2f07a74c9 100644
|
||||||
|
--- a/lib/strcase.h
|
||||||
|
+++ b/lib/strcase.h
|
||||||
|
@@ -40,12 +40,14 @@ int Curl_safe_strcasecompare(const char *first, const char *second);
|
||||||
|
int Curl_strncasecompare(const char *first, const char *second, size_t max);
|
||||||
|
|
||||||
|
char Curl_raw_toupper(char in);
|
||||||
|
+char Curl_raw_tolower(char in);
|
||||||
|
|
||||||
|
/* checkprefix() is a shorter version of the above, used when the first
|
||||||
|
argument is zero-byte terminated */
|
||||||
|
#define checkprefix(a,b) curl_strnequal(a,b,strlen(a))
|
||||||
|
|
||||||
|
void Curl_strntoupper(char *dest, const char *src, size_t n);
|
||||||
|
+void Curl_strntolower(char *dest, const char *src, size_t n);
|
||||||
|
|
||||||
|
bool Curl_safecmp(char *a, char *b);
|
||||||
|
int Curl_timestrcmp(const char *first, const char *second);
|
||||||
|
--
|
||||||
|
2.43.0
|
||||||
|
|
@ -0,0 +1,31 @@
|
|||||||
|
From 35eb2614d86316ba9f5a6806ce64f56680fa1e97 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jakub Jelen <jjelen@redhat.com>
|
||||||
|
Date: Tue, 5 Sep 2023 17:33:41 +0200
|
||||||
|
Subject: [PATCH] libssh: cap SFTP packet size sent
|
||||||
|
|
||||||
|
Due to libssh limitations
|
||||||
|
|
||||||
|
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
|
||||||
|
|
||||||
|
Closes #11804
|
||||||
|
---
|
||||||
|
lib/ssh-libssh.c | 6 ++++++
|
||||||
|
1 file changed, 6 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/lib/ssh-libssh.c b/lib/ssh-libssh.c
|
||||||
|
index dea0084575859..7c6a2e53f338f 100644
|
||||||
|
--- a/lib/ssh-libssh.c
|
||||||
|
+++ b/lib/ssh-libssh.c
|
||||||
|
@@ -2412,6 +2412,12 @@ static ssize_t sftp_send(struct Curl_easy *data, int sockindex,
|
||||||
|
ssize_t nwrite;
|
||||||
|
(void)sockindex;
|
||||||
|
|
||||||
|
+ /* limit the writes to the maximum specified in Section 3 of
|
||||||
|
+ * https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02
|
||||||
|
+ */
|
||||||
|
+ if(len > 32768)
|
||||||
|
+ len = 32768;
|
||||||
|
+
|
||||||
|
nwrite = sftp_write(conn->proto.sshc.sftp_file, mem, len);
|
||||||
|
|
||||||
|
myssh_block2waitfor(conn, FALSE);
|
Loading…
Reference in new issue