From b77a6897234c1871b4d7b11db68675719c4eb123 Mon Sep 17 00:00:00 2001 From: eabdullin Date: Tue, 7 Oct 2025 05:23:43 +0000 Subject: [PATCH] import UBI curl-7.61.1-34.el8_10.8 --- SOURCES/0051-curl-7.61.1-CVE-2023-28321.patch | 16 +- SOURCES/0064-curl-7.61.1-EBADF.patch | 283 +++++++++++++++ SOURCES/0065-md5-hex-key.patch | 338 ++++++++++++++++++ SOURCES/0066-crypto-initialization.patch | 44 +++ ...0067-curl-7.61.1-ntlm-force-http-1-1.patch | 42 +++ SPECS/curl.spec | 34 +- 6 files changed, 749 insertions(+), 8 deletions(-) create mode 100644 SOURCES/0064-curl-7.61.1-EBADF.patch create mode 100644 SOURCES/0065-md5-hex-key.patch create mode 100644 SOURCES/0066-crypto-initialization.patch create mode 100644 SOURCES/0067-curl-7.61.1-ntlm-force-http-1-1.patch diff --git a/SOURCES/0051-curl-7.61.1-CVE-2023-28321.patch b/SOURCES/0051-curl-7.61.1-CVE-2023-28321.patch index bd66821..e3909b3 100644 --- a/SOURCES/0051-curl-7.61.1-CVE-2023-28321.patch +++ b/SOURCES/0051-curl-7.61.1-CVE-2023-28321.patch @@ -41,7 +41,7 @@ index e827dc58f378c..d061c6356f97f 100644 /* * Match a hostname against a wildcard pattern. * E.g. -@@ -65,26 +76,27 @@ +@@ -65,26 +76,31 @@ static int hostmatch(char *hostname, char *pattern) { @@ -73,10 +73,14 @@ index e827dc58f378c..d061c6356f97f 100644 - if(pattern_wildcard == NULL) - return strcasecompare(pattern, hostname) ? - CURL_HOST_MATCH : CURL_HOST_NOMATCH; -+ if(hostname[hostlen-1]=='.') ++ if(hostname[hostlen-1]=='.') { + hostname[hostlen-1] = 0; -+ if(pattern[patternlen-1]=='.') ++ hostlen--; ++ } ++ if(pattern[patternlen-1]=='.') { + pattern[patternlen-1] = 0; ++ patternlen--; ++ } + + if(strncmp(pattern, "*.", 2)) + return pmatch(hostname, hostlen, pattern, patternlen); @@ -170,7 +174,7 @@ index 2f3d3aa4d09e1..3ae75618d5d10 100644 static CURLcode unit_setup(void) { return CURLE_OK; -@@ -30,50 +28,93 @@ static CURLcode unit_setup(void) +@@ -30,50 +28,91 @@ static CURLcode unit_setup(void) static void unit_stop(void) { @@ -281,9 +285,7 @@ index 2f3d3aa4d09e1..3ae75618d5d10 100644 + int i; + for(i = 0; tests[i].host; i++) { + if(tests[i].match != Curl_cert_hostcheck(tests[i].pattern, -+ strlen(tests[i].pattern), -+ tests[i].host, -+ strlen(tests[i].host))) { ++ tests[i].host)) { + fprintf(stderr, + "HOST: %s\n" + "PTRN: %s\n" diff --git a/SOURCES/0064-curl-7.61.1-EBADF.patch b/SOURCES/0064-curl-7.61.1-EBADF.patch new file mode 100644 index 0000000..46d9ea9 --- /dev/null +++ b/SOURCES/0064-curl-7.61.1-EBADF.patch @@ -0,0 +1,283 @@ +From 17d1e27d309f16da960fd3b9933e6e2b1db22b17 Mon Sep 17 00:00:00 2001 +From: Eric Wong +Date: Sat, 10 Aug 2019 21:20:23 +0000 +Subject: [PATCH] asyn-thread: issue CURL_POLL_REMOVE before closing socket + +This avoids EBADF errors from EPOLL_CTL_DEL operations in the +ephiperfifo.c example. EBADF is dangerous in multi-threaded +applications where I rely on epoll_ctl to operate on the same +epoll description from different threads. + +Follow-up to eb9a604f8d7db8 + +Bug: https://curl.haxx.se/mail/lib-2019-08/0026.html +Closes #4211 +--- + lib/asyn-thread.c | 25 ++++++++++++++++++++----- + 1 file changed, 20 insertions(+), 5 deletions(-) + +diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c +index 222e78d98..24da74885 100755 +--- a/lib/asyn-thread.c ++++ b/lib/asyn-thread.c +@@ -164,6 +164,7 @@ struct thread_sync_data { + duplicate */ + int port; + #ifdef HAVE_SOCKETPAIR ++ struct connectdata *conn; + curl_socket_t sock_pair[2]; /* socket pair */ + #endif + int sock_error; +@@ -201,11 +202,10 @@ void destroy_thread_sync_data(struct thread_sync_data * tsd) + Curl_freeaddrinfo(tsd->res); + + #ifdef HAVE_SOCKETPAIR +- /* close socket pair */ +- if(tsd->sock_pair[0] != CURL_SOCKET_BAD) { +- sclose(tsd->sock_pair[0]); +- } +- ++ /* ++ * close one end of the socket pair (may be done in resolver thread); ++ * the other end (for reading) is always closed in the parent thread. ++ */ + if(tsd->sock_pair[1] != CURL_SOCKET_BAD) { + sclose(tsd->sock_pair[1]); + } +@@ -382,6 +382,10 @@ static void destroy_async_data(struct Curl_async *async) + if(async->os_specific) { + struct thread_data *td = (struct thread_data*) async->os_specific; + int done; ++#ifdef HAVE_SOCKETPAIR ++ curl_socket_t sock_rd = td->tsd.sock_pair[0]; ++ struct connectdata *conn = td->tsd.conn; ++#endif + + /* + * if the thread is still blocking in the resolve syscall, detach it and +@@ -403,6 +407,15 @@ static void destroy_async_data(struct Curl_async *async) + + free(async->os_specific); + } ++#ifdef HAVE_SOCKETPAIR ++ /* ++ * ensure CURLMOPT_SOCKETFUNCTION fires CURL_POLL_REMOVE ++ * before the FD is invalidated to avoid EBADF on EPOLL_CTL_DEL ++ */ ++ if(conn) ++ Curl_multi_closed(conn->data, sock_rd); ++ sclose(sock_rd); ++#endif + } + async->os_specific = NULL; + +@@ -644,6 +657,8 @@ int Curl_resolver_getsock(struct connectdata *conn, + if(td) { + /* return read fd to client for polling the DNS resolution status */ + socks[0] = td->tsd.sock_pair[0]; ++ DEBUGASSERT(td->tsd.conn == conn || !td->tsd.conn); ++ td->tsd.conn = conn; + ret_val = GETSOCK_READSOCK(0); + } + else { +-- +2.49.0 + +From 041690aadb1357775ff06c5bf827a98585627c76 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 30 Jul 2019 10:29:54 +0200 +Subject: [PATCH] asyn-thread: removed unused variable + +Follow-up to eb9a604f. Mistake caused by me when I edited the commit +before push... +--- + lib/asyn-thread.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c +index f17638e44..e323cbe20 100755 +--- a/lib/asyn-thread.c ++++ b/lib/asyn-thread.c +@@ -636,11 +636,10 @@ int Curl_resolver_getsock(struct connectdata *conn, + struct resdata *reslv = (struct resdata *)data->state.resolver; + #ifdef HAVE_SOCKETPAIR + struct thread_data *td = (struct thread_data*)conn->async.os_specific; +- int loop_idx; + #else + (void)socks; +- (void)numsocks; + #endif ++ (void)numsocks; + + #ifdef HAVE_SOCKETPAIR + if(td) { +-- +2.49.0 + +From 060fb84a5a07388f099c7a3422e281ac64d623a5 Mon Sep 17 00:00:00 2001 +From: Xiang Xiao +Date: Tue, 24 Dec 2019 21:47:37 +0800 +Subject: [PATCH] lib: remove erroneous +x file permission on some c files + +Modified by commit eb9a604 accidentally. + +Closes https://github.com/curl/curl/pull/4756 +--- + lib/asyn-thread.c | 0 + lib/multi.c | 0 + 2 files changed, 0 insertions(+), 0 deletions(-) + mode change 100755 => 100644 lib/asyn-thread.c + mode change 100755 => 100644 lib/multi.c + +diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c +old mode 100755 +new mode 100644 +diff --git a/lib/multi.c b/lib/multi.c +old mode 100755 +new mode 100644 +-- +2.49.0 + +From e34ec7de5964baa214555115f5061ed199d0f7b4 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Wed, 11 Sep 2019 23:11:58 +0200 +Subject: [PATCH] asyn-thread: s/AF_LOCAL/AF_UNIX for Solaris + +Reported-by: Dagobert Michelsen +Fixes #4328 +Closes #4333 +--- + lib/asyn-thread.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c +index 24da74885..fcbf1305e 100755 +--- a/lib/asyn-thread.c ++++ b/lib/asyn-thread.c +@@ -244,8 +244,8 @@ int init_thread_sync_data(struct thread_data * td, + Curl_mutex_init(tsd->mtx); + + #ifdef HAVE_SOCKETPAIR +- /* create socket pair */ +- if(socketpair(AF_LOCAL, SOCK_STREAM, 0, &tsd->sock_pair[0]) < 0) { ++ /* create socket pair, avoid AF_LOCAL since it doesn't build on Solaris */ ++ if(socketpair(AF_UNIX, SOCK_STREAM, 0, &tsd->sock_pair[0]) < 0) { + tsd->sock_pair[0] = CURL_SOCKET_BAD; + tsd->sock_pair[1] = CURL_SOCKET_BAD; + goto err_exit; +-- +2.49.0 + +From 9c76f694de1765152e0b349cd55baad5a501f55b Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sat, 5 Oct 2019 15:41:09 +0200 +Subject: [PATCH] asyn-thread: make use of Curl_socketpair() where available + +--- + lib/asyn-thread.c | 26 ++++++++++++++------------ + 1 file changed, 14 insertions(+), 12 deletions(-) + +diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c +index fcbf1305e..8c552baa9 100755 +--- a/lib/asyn-thread.c ++++ b/lib/asyn-thread.c +@@ -163,7 +165,7 @@ struct thread_sync_data { + char *hostname; /* hostname to resolve, Curl_async.hostname + duplicate */ + int port; +-#ifdef HAVE_SOCKETPAIR ++#ifdef USE_SOCKETPAIR + struct connectdata *conn; + curl_socket_t sock_pair[2]; /* socket pair */ + #endif +@@ -201,7 +203,7 @@ void destroy_thread_sync_data(struct thread_sync_data * tsd) + if(tsd->res) + Curl_freeaddrinfo(tsd->res); + +-#ifdef HAVE_SOCKETPAIR ++#ifdef USE_SOCKETPAIR + /* + * close one end of the socket pair (may be done in resolver thread); + * the other end (for reading) is always closed in the parent thread. +@@ -243,9 +245,9 @@ int init_thread_sync_data(struct thread_data * td, + + Curl_mutex_init(tsd->mtx); + +-#ifdef HAVE_SOCKETPAIR ++#ifdef USE_SOCKETPAIR + /* create socket pair, avoid AF_LOCAL since it doesn't build on Solaris */ +- if(socketpair(AF_UNIX, SOCK_STREAM, 0, &tsd->sock_pair[0]) < 0) { ++ if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, &tsd->sock_pair[0]) < 0) { + tsd->sock_pair[0] = CURL_SOCKET_BAD; + tsd->sock_pair[1] = CURL_SOCKET_BAD; + goto err_exit; +@@ -297,7 +299,7 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg) + struct thread_data *td = tsd->td; + char service[12]; + int rc; +-#ifdef HAVE_SOCKETPAIR ++#ifdef USE_SOCKETPAIR + char buf[1]; + #endif + +@@ -322,11 +324,11 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg) + free(td); + } + else { +-#ifdef HAVE_SOCKETPAIR ++#ifdef USE_SOCKETPAIR + if(tsd->sock_pair[1] != CURL_SOCKET_BAD) { + /* DNS has been resolved, signal client task */ + buf[0] = 1; +- if(write(tsd->sock_pair[1], buf, sizeof(buf)) < 0) { ++ if(swrite(tsd->sock_pair[1], buf, sizeof(buf)) < 0) { + /* update sock_erro to errno */ + tsd->sock_error = SOCKERRNO; + } +@@ -382,7 +384,7 @@ static void destroy_async_data(struct Curl_async *async) + if(async->os_specific) { + struct thread_data *td = (struct thread_data*) async->os_specific; + int done; +-#ifdef HAVE_SOCKETPAIR ++#ifdef USE_SOCKETPAIR + curl_socket_t sock_rd = td->tsd.sock_pair[0]; + struct connectdata *conn = td->tsd.conn; + #endif +@@ -407,7 +409,7 @@ static void destroy_async_data(struct Curl_async *async) + + free(async->os_specific); + } +-#ifdef HAVE_SOCKETPAIR ++#ifdef USE_SOCKETPAIR + /* + * ensure CURLMOPT_SOCKETFUNCTION fires CURL_POLL_REMOVE + * before the FD is invalidated to avoid EBADF on EPOLL_CTL_DEL +@@ -649,14 +651,14 @@ int Curl_resolver_getsock(struct connectdata *conn, + timediff_t ms; + struct Curl_easy *data = conn->data; + struct resdata *reslv = (struct resdata *)data->state.resolver; +-#ifdef HAVE_SOCKETPAIR ++#ifdef USE_SOCKETPAIR + struct thread_data *td = (struct thread_data*)conn->async.os_specific; + #else + (void)socks; + #endif + (void)numsocks; + +-#ifdef HAVE_SOCKETPAIR ++#ifdef USE_SOCKETPAIR + if(td) { + /* return read fd to client for polling the DNS resolution status */ + socks[0] = td->tsd.sock_pair[0]; +@@ -673,7 +675,7 @@ int Curl_resolver_getsock(struct connectdata *conn, + else + milli = 200; + Curl_expire(data, milli, EXPIRE_ASYNC_NAME); +-#ifdef HAVE_SOCKETPAIR ++#ifdef USE_SOCKETPAIR + } + #endif + +-- +2.49.0 + diff --git a/SOURCES/0065-md5-hex-key.patch b/SOURCES/0065-md5-hex-key.patch new file mode 100644 index 0000000..eddbf7b --- /dev/null +++ b/SOURCES/0065-md5-hex-key.patch @@ -0,0 +1,338 @@ +From b1a049b4c024ea69ef571da8def3cc13889430f4 Mon Sep 17 00:00:00 2001 +From: Jay Satiro +Date: Sun, 23 Feb 2020 18:37:09 -0500 +Subject: [PATCH] libssh: Fix matching user-specified MD5 hex key + +Prior to this change a match would never be successful because it +was mistakenly coded to compare binary data from libssh to a +user-specified hex string (ie CURLOPT_SSH_HOST_PUBLIC_KEY_MD5). + +Reported-by: fds242@users.noreply.github.com + +Fixes https://github.com/curl/curl/issues/4971 +Closes https://github.com/curl/curl/pull/4974 +(cherry picked from commit 09aa807240b9dcde78a919ff712316a1daf0655e) +--- + lib/ssh-libssh.c | 20 ++++++++++++++++--- + tests/FILEFORMAT | 1 + + tests/data/Makefile.inc | 1 + + tests/data/test664 | 44 +++++++++++++++++++++++++++++++++++++++++ + tests/data/test665 | 44 +++++++++++++++++++++++++++++++++++++++++ + tests/runtests.pl | 24 ++++++++++++++++++++++ + tests/sshhelp.pm | 3 +++ + tests/sshserver.pl | 31 +++++++++++++++++++++++++---- + 8 files changed, 161 insertions(+), 7 deletions(-) + create mode 100644 tests/data/test664 + create mode 100644 tests/data/test665 + +diff --git a/lib/ssh-libssh.c b/lib/ssh-libssh.c +index 7d590891c..c203d6336 100644 +--- a/lib/ssh-libssh.c ++++ b/lib/ssh-libssh.c +@@ -327,13 +327,27 @@ static int myssh_is_known(struct connectdata *conn) + return rc; + + if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) { ++ int i; ++ char md5buffer[33]; ++ const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]; ++ + rc = ssh_get_publickey_hash(pubkey, SSH_PUBLICKEY_HASH_MD5, + &hash, &hlen); +- if(rc != SSH_OK) ++ if(rc != SSH_OK || hlen != 16) { ++ failf(data, ++ "Denied establishing ssh session: md5 fingerprint not available"); + goto cleanup; ++ } ++ ++ for(i = 0; i < 16; i++) ++ snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char)hash[i]); ++ ++ infof(data, "SSH MD5 fingerprint: %s\n", md5buffer); + +- if(hlen != strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) || +- memcmp(&data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5], hash, hlen)) { ++ if(!strcasecompare(md5buffer, pubkey_md5)) { ++ failf(data, ++ "Denied establishing ssh session: mismatch md5 fingerprint. " ++ "Remote %s is not equal to %s", md5buffer, pubkey_md5); + rc = SSH_ERROR; + goto cleanup; + } +diff --git a/tests/FILEFORMAT b/tests/FILEFORMAT +index 135ded6c1..6b79093ab 100644 +--- a/tests/FILEFORMAT ++++ b/tests/FILEFORMAT +@@ -368,6 +368,7 @@ Available substitute variables include: + %PWD - Current directory + %RTSP6PORT - IPv6 port number of the RTSP server + %RTSPPORT - Port number of the RTSP server ++%SSHSRVMD5 - MD5 of SSH server's public key + %SMTP6PORT - IPv6 port number of the SMTP server + %SMTPPORT - Port number of the SMTP server + %SOCKSPORT - Port number of the SOCKS4/5 server +diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc +index e0457486b..923b58a63 100644 +--- a/tests/data/Makefile.inc ++++ b/tests/data/Makefile.inc +@@ -84,6 +84,7 @@ test626 test627 test628 test629 test630 test631 test632 test633 test634 \ + test635 test636 test637 test638 test639 test640 test641 test642 \ + test643 test644 test645 test646 test647 test648 test649 test650 test651 \ + test652 test653 test654 test655 test656 \ ++test664 test665 \ + \ + test700 test701 test702 test703 test704 test705 test706 test707 test708 \ + test709 test710 test711 test712 test713 test714 test715 \ +diff --git a/tests/data/test664 b/tests/data/test664 +new file mode 100644 +index 000000000..cb73b248b +--- /dev/null ++++ b/tests/data/test664 +@@ -0,0 +1,44 @@ ++ ++ ++ ++SFTP ++server key check ++ ++ ++ ++# ++# Server-side ++ ++ ++test ++ ++ ++ ++# ++# Client-side ++ ++ ++sftp ++ ++ ++SFTP correct host key ++ ++ ++--hostpubmd5 %SSHSRVMD5 --key curl_client_key --pubkey curl_client_key.pub -u %USER: sftp://%HOSTIP:%SSHPORT%POSIX_PWD/log/file664.txt ++ ++ ++test ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++ ++0 ++ ++ ++disable ++ ++ ++ +diff --git a/tests/data/test665 b/tests/data/test665 +new file mode 100644 +index 000000000..830adb8f6 +--- /dev/null ++++ b/tests/data/test665 +@@ -0,0 +1,44 @@ ++ ++ ++ ++SCP ++server key check ++ ++ ++ ++# ++# Server-side ++ ++ ++test ++ ++ ++ ++# ++# Client-side ++ ++ ++scp ++ ++ ++SCP correct host key ++ ++ ++--hostpubmd5 %SSHSRVMD5 --key curl_client_key --pubkey curl_client_key.pub -u %USER: scp://%HOSTIP:%SSHPORT%POSIX_PWD/log/file665.txt ++ ++ ++test ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++ ++0 ++ ++ ++disable ++ ++ ++ +diff --git a/tests/runtests.pl b/tests/runtests.pl +index e12c1429a..4e2a19cf2 100755 +--- a/tests/runtests.pl ++++ b/tests/runtests.pl +@@ -150,6 +150,8 @@ my $SMBPORT; # SMB server port + my $SMBSPORT; # SMBS server port + my $NEGTELNETPORT; # TELNET server port with negotiation + ++my $SSHSRVMD5; # MD5 of ssh server public key ++ + my $srcdir = $ENV{'srcdir'} || '.'; + my $CURL="../src/curl".exe_ext(); # what curl executable to run on the tests + my $VCURL=$CURL; # what curl binary to use to verify the servers with +@@ -2181,6 +2183,18 @@ sub runsshserver { + return (0,0); + } + ++ my $hstpubmd5f = "curl_host_rsa_key.pub_md5"; ++ if(!open(PUBMD5FILE, "<", $hstpubmd5f) || ++ (read(PUBMD5FILE, $SSHSRVMD5, 32) != 32) || ++ !close(PUBMD5FILE) || ++ ($SSHSRVMD5 !~ /^[a-f0-9]{32}$/i)) ++ { ++ my $msg = "Fatal: $srvrname pubkey md5 missing : \"$hstpubmd5f\" : $!"; ++ logmsg "$msg\n"; ++ stopservers($verbose); ++ die $msg; ++ } ++ + if($verbose) { + logmsg "RUN: $srvrname server is now running PID $pid2\n"; + } +@@ -3205,6 +3219,16 @@ sub subVariables { + $$thing =~ s/%SRCDIR/$srcdir/g; + $$thing =~ s/%USER/$USER/g; + ++ if($$thing =~ /%SSHSRVMD5/) { ++ if(!$SSHSRVMD5) { ++ my $msg = "Fatal: Missing SSH server pubkey MD5. Is server running?"; ++ logmsg "$msg\n"; ++ stopservers($verbose); ++ die $msg; ++ } ++ $$thing =~ s/%SSHSRVMD5/$SSHSRVMD5/g; ++ } ++ + # The purpose of FTPTIME2 and FTPTIME3 is to provide times that can be + # used for time-out tests and that whould work on most hosts as these + # adjust for the startup/check time for this particular host. We needed +diff --git a/tests/sshhelp.pm b/tests/sshhelp.pm +index c5618a109..abdf9c458 100644 +--- a/tests/sshhelp.pm ++++ b/tests/sshhelp.pm +@@ -50,6 +50,7 @@ use vars qw( + $sftpcmds + $hstprvkeyf + $hstpubkeyf ++ $hstpubmd5f + $cliprvkeyf + $clipubkeyf + @sftppath +@@ -82,6 +83,7 @@ use vars qw( + $sftpcmds + $hstprvkeyf + $hstpubkeyf ++ $hstpubmd5f + $cliprvkeyf + $clipubkeyf + display_sshdconfig +@@ -122,6 +124,7 @@ $sftpcmds = 'curl_sftp_cmds'; # sftp client commands batch file + $knownhosts = 'curl_client_knownhosts'; # ssh knownhosts file + $hstprvkeyf = 'curl_host_rsa_key'; # host private key file + $hstpubkeyf = 'curl_host_rsa_key.pub'; # host public key file ++$hstpubmd5f = 'curl_host_rsa_key.pub_md5'; # md5 hash of host public key + $cliprvkeyf = 'curl_client_key'; # client private key file + $clipubkeyf = 'curl_client_key.pub'; # client public key file + +diff --git a/tests/sshserver.pl b/tests/sshserver.pl +index 9b3d122fd..cd92a62c5 100755 +--- a/tests/sshserver.pl ++++ b/tests/sshserver.pl +@@ -28,6 +28,9 @@ use strict; + use warnings; + use Cwd; + use Cwd 'abs_path'; ++use Digest::MD5; ++use Digest::MD5 'md5_hex'; ++use MIME::Base64; + + #*************************************************************************** + # Variables and subs imported from sshhelp module +@@ -48,6 +51,7 @@ use sshhelp qw( + $sftpcmds + $hstprvkeyf + $hstpubkeyf ++ $hstpubmd5f + $cliprvkeyf + $clipubkeyf + display_sshdconfig +@@ -367,10 +371,11 @@ if((($sshid =~ /OpenSSH/) && ($sshvernum < 299)) || + # + if((! -e $hstprvkeyf) || (! -s $hstprvkeyf) || + (! -e $hstpubkeyf) || (! -s $hstpubkeyf) || ++ (! -e $hstpubmd5f) || (! -s $hstpubmd5f) || + (! -e $cliprvkeyf) || (! -s $cliprvkeyf) || + (! -e $clipubkeyf) || (! -s $clipubkeyf)) { + # Make sure all files are gone so ssh-keygen doesn't complain +- unlink($hstprvkeyf, $hstpubkeyf, $cliprvkeyf, $clipubkeyf); ++ unlink($hstprvkeyf, $hstpubkeyf, $hstpubmd5f, $cliprvkeyf, $clipubkeyf); + logmsg 'generating host keys...' if($verbose); + if(system "\"$sshkeygen\" -q -t rsa -f $hstprvkeyf -C 'curl test server' -N ''") { + logmsg 'Could not generate host key'; +@@ -381,6 +386,24 @@ if((! -e $hstprvkeyf) || (! -s $hstprvkeyf) || + logmsg 'Could not generate client key'; + exit 1; + } ++ # Make sure that permissions are restricted so openssh doesn't complain ++ system "chmod 600 $hstprvkeyf"; ++ system "chmod 600 $cliprvkeyf"; ++ # Save md5 hash of public host key ++ open(RSAKEYFILE, "<$hstpubkeyf"); ++ my @rsahostkey = do { local $/ = ' '; }; ++ close(RSAKEYFILE); ++ if(!$rsahostkey[1]) { ++ logmsg 'Failed parsing base64 encoded RSA host key'; ++ exit 1; ++ } ++ open(PUBMD5FILE, ">$hstpubmd5f"); ++ print PUBMD5FILE md5_hex(decode_base64($rsahostkey[1])); ++ close(PUBMD5FILE); ++ if((! -e $hstpubmd5f) || (! -s $hstpubmd5f)) { ++ logmsg 'Failed writing md5 hash of RSA host key'; ++ exit 1; ++ } + } + + +@@ -1073,8 +1096,8 @@ elsif($verbose && ($rc >> 8)) { + #*************************************************************************** + # Clean up once the server has stopped + # +-unlink($hstprvkeyf, $hstpubkeyf, $cliprvkeyf, $clipubkeyf, $knownhosts); +-unlink($sshdconfig, $sshconfig, $sftpconfig); +- ++unlink($hstprvkeyf, $hstpubkeyf, $hstpubmd5f, ++ $cliprvkeyf, $clipubkeyf, $knownhosts, ++ $sshdconfig, $sshconfig, $sftpconfig); + + exit 0; +-- +2.47.1 + diff --git a/SOURCES/0066-crypto-initialization.patch b/SOURCES/0066-crypto-initialization.patch new file mode 100644 index 0000000..582c8d9 --- /dev/null +++ b/SOURCES/0066-crypto-initialization.patch @@ -0,0 +1,44 @@ +From a1c1af1b82bf9427b2bd5ad949d24923f995909a Mon Sep 17 00:00:00 2001 +From: Jacek Migacz +Date: Wed, 9 Jul 2025 14:33:09 +0200 +Subject: [PATCH] crypto: ensure crypto initialization works + +--- + lib/vtls/openssl.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c +index 161e79e..7c41f54 100644 +--- a/lib/vtls/openssl.c ++++ b/lib/vtls/openssl.c +@@ -3802,7 +3802,12 @@ static CURLcode Curl_ossl_md5sum(unsigned char *tmp, /* input */ + (void) unused; + + mdctx = EVP_MD_CTX_create(); +- EVP_DigestInit_ex(mdctx, EVP_md5(), NULL); ++ if(!mdctx) ++ return CURLE_OUT_OF_MEMORY; ++ if(!EVP_DigestInit_ex(mdctx, EVP_md5(), NULL)) { ++ EVP_MD_CTX_destroy(mdctx); ++ return CURLE_FAILED_INIT; ++ } + EVP_DigestUpdate(mdctx, tmp, tmplen); + EVP_DigestFinal_ex(mdctx, md5sum, &len); + EVP_MD_CTX_destroy(mdctx); +@@ -3820,7 +3825,12 @@ static CURLcode Curl_ossl_sha256sum(const unsigned char *tmp, /* input */ + (void) unused; + + mdctx = EVP_MD_CTX_create(); +- EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL); ++ if(!mdctx) ++ return CURLE_OUT_OF_MEMORY; ++ if(!EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL)) { ++ EVP_MD_CTX_destroy(mdctx); ++ return CURLE_FAILED_INIT; ++ } + EVP_DigestUpdate(mdctx, tmp, tmplen); + EVP_DigestFinal_ex(mdctx, sha256sum, &len); + EVP_MD_CTX_destroy(mdctx); +-- +2.50.0 + diff --git a/SOURCES/0067-curl-7.61.1-ntlm-force-http-1-1.patch b/SOURCES/0067-curl-7.61.1-ntlm-force-http-1-1.patch new file mode 100644 index 0000000..2ddace4 --- /dev/null +++ b/SOURCES/0067-curl-7.61.1-ntlm-force-http-1-1.patch @@ -0,0 +1,42 @@ +From cbea2fd2c74feabeb6f13b3e3df243b225b3b3ab Mon Sep 17 00:00:00 2001 +From: Johannes Schindelin +Date: Thu, 6 Dec 2018 17:26:13 +0100 +Subject: [PATCH] NTLM: force the connection to HTTP/1.1 + +Since v7.62.0, cURL tries to use HTTP/2 whenever the server announces +the capability. However, NTLM authentication only works with HTTP/1.1, +and will likely remain in that boat (for details, see +https://docs.microsoft.com/en-us/iis/get-started/whats-new-in-iis-10/http2-on-iis#when-is-http2-not-supported). + +When we just found out that we want to use NTLM, and when the current +connection runs in HTTP/2 mode, let's force the connection to be closed +and to be re-opened using HTTP/1.1. + +Fixes https://github.com/curl/curl/issues/3341. +Closes #3345 + +Signed-off-by: Johannes Schindelin +--- + lib/http.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/lib/http.c b/lib/http.c +index aed7aa80f..7be6f8b92 100644 +--- a/lib/http.c ++++ b/lib/http.c +@@ -526,6 +526,12 @@ CURLcode Curl_http_auth_act(struct connectdata *conn) + pickhost = pickoneauth(&data->state.authhost, authmask); + if(!pickhost) + data->state.authproblem = TRUE; ++ if(data->state.authhost.picked == CURLAUTH_NTLM && ++ conn->httpversion > 11) { ++ infof(data, "Forcing HTTP/1.1 for NTLM"); ++ connclose(conn, "Force HTTP/1.1 connection"); ++ conn->data->set.httpversion = CURL_HTTP_VERSION_1_1; ++ } + } + if(conn->bits.proxy_user_passwd && + ((data->req.httpcode == 407) || +-- +2.50.0 + diff --git a/SPECS/curl.spec b/SPECS/curl.spec index 8054b4c..0718243 100644 --- a/SPECS/curl.spec +++ b/SPECS/curl.spec @@ -1,7 +1,7 @@ Summary: A utility for getting files from remote servers (FTP, HTTP, and others) Name: curl Version: 7.61.1 -Release: 34%{?dist}.3 +Release: 34%{?dist}.8 License: MIT Source: https://curl.haxx.se/download/%{name}-%{version}.tar.xz @@ -184,6 +184,18 @@ Patch62: 0062-curl-7.61.1-socketpair-to-wait-on.patch # fix crash, when talking to a NTLM proxy in FIPS mode Patch63: 0063-curl-7.61.1-native-md5.patch +# asyn-thread: issue CURL_POLL_REMOVE before closing socket +Patch64: 0064-curl-7.61.1-EBADF.patch + +# libssh: Fix matching user-specified MD5 hex key +Patch65: 0065-md5-hex-key.patch + +# crypto: ensure crypto initialization works +Patch66: 0066-crypto-initialization.patch + +# NTLM: force the connection to HTTP/1.1 +Patch67: 0067-curl-7.61.1-ntlm-force-http-1-1.patch + # patch making libcurl multilib ready Patch101: 0101-curl-7.32.0-multilib.patch @@ -420,6 +432,10 @@ git apply %{PATCH52} %patch -P 61 -p1 %patch -P 62 -p1 %patch -P 63 -p1 +%patch -P 64 -p1 +%patch -P 65 -p1 +%patch -P 66 -p1 +%patch -P 67 -p1 # make tests/*.py use Python 3 sed -e '1 s|^#!/.*python|#!%{__python3}|' -i tests/*.py @@ -582,6 +598,22 @@ rm -f ${RPM_BUILD_ROOT}%{_libdir}/libcurl.la %{_libdir}/libcurl.so.4.[0-9].[0-9].minimal %changelog +* Mon Jul 21 2025 Jacek Migacz - 7.61.1-34.el8_10.8 +- NTLM: force the connection to HTTP/1.1 (RHEL-73788) + +* Wed Jul 09 2025 Jacek Migacz - 7.61.1-34.el8_10.7 +* crypto: ensure crypto initialization works (RHEL-102601) + +* Thu May 29 2025 Carlos Santos - 7.61.1-34.el8_10.6 +- libssh: Fix matching user-specified MD5 hex key (RHEL-94574) + +* Wed Jan 08 2025 Jacek Migacz - 7.61.1-34.el8_10.5 +- asyn-thread: fix EBADF regression (RHEL-85602) + +* Wed Jan 08 2025 Jacek Migacz - 7.61.1-34.el8_10.4 +- make up incomplete patch for host name wildcard checking (RHEL-5680) +- asyn-thread: issue CURL_POLL_REMOVE before closing socket (RHEL-85602) + * Wed Oct 30 2024 Jacek Migacz - 7.61.1-34.el8_10.3 - asyn-thread: create a socketpair to wait on (RHEL-34906) - fix crash, when talking to a NTLM proxy in FIPS mode (RHEL-32641)