]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
runtests: detect bad libssh differently for test 1459 (fixing CircleCI libssh job)
authorViktor Szakats <commit@vsz.me>
Sun, 16 Nov 2025 18:56:39 +0000 (19:56 +0100)
committerViktor Szakats <commit@vsz.me>
Sun, 16 Nov 2025 22:28:44 +0000 (23:28 +0100)
test 1459 "SFTP with corrupted known_hosts" was seen failing in the past.
To fix it, the test was automatically disabled when detecting libssh
0.9.3 or older, as in the curl CircleCI job, running on Ubuntu 20.04.
This work for a long time, until bumping the CircleCI runner to Ubuntu
22.04 (to have OpenSSL 3), where the test was running again, and failing
with the isssue seen in the past.

- Test skipped with Ubuntu 20.04 (libssh 0.9.3):
  https://app.circleci.com/pipelines/github/curl/curl/16445/workflows/7f198763-e0b0-4037-9245-4c4b40ab8726/jobs/155164
- Failure seen with Ubuntu 22.04 (libssh 0.9.6):
  https://app.circleci.com/pipelines/github/curl/curl/16452/workflows/b817a808-0fd4-40b0-8eb0-d064926efe12/jobs/155206?invite=true#step-107-211709_45
- Failure seen with Ubuntu 24.04 (libssh 0.10.6):
  https://app.circleci.com/pipelines/github/curl/curl/16455/workflows/86c631f1-3c5f-4438-b398-3df2bdab5d20/jobs/155218

Turns out the issue issue isn't libssh 0.9.3 itself, but
a CircleCI-specific default configuration in `/etc/ssh/ssh_config`:
```
# BEGIN ANSIBLE MANAGED BLOCK
Host *
StrictHostKeyChecking no     <------ this particular line
HashKnownHosts no
SendEnv LANG LC_*
# END ANSIBLE MANAGED BLOCK
```

libssh will consult configuration files on hard-coded default system
locations and alter its behavior based on settings found in them.

This libssh behavior is present in all supported versions:
https://gitlab.com/libssh/libssh-mirror/-/commit/5a2abd34ce9ad97c69906c5fb7b07e26e96fceaa
https://gitlab.com/libssh/libssh-mirror/-/tags/libssh-0.9.0

It means the existing disable logic based on libssh version worked by
coincidence, and what needs to be checked is these configurations
to decide if it's safe to run the test. Another, simpler option is
to also accept the result code 67, though in that case the test
wouldn't actually test what we want, but would pass anyway.

With the old `oldlibssh` workaround deleted, and the problematic setting
manually overridden (`StrictHostKeyChecking yes`):
- CircleCI Ubuntu 20.04 passes with 1459 enabled:
  https://app.circleci.com/pipelines/github/curl/curl/16483/workflows/87a9f389-76a2-4a32-acde-c0b411a4c842/jobs/155302
- CircleCI Ubuntu 22.04 does too:
  https://app.circleci.com/pipelines/github/curl/curl/16483/workflows/87a9f389-76a2-4a32-acde-c0b411a4c842/jobs/155303

To fix, replace the `runtests` `oldlibssh` detection logic to parse
libssh config files (instead of checking for libssh version) and disable
test 1459 based on that. Notice the detection is making a light attempt
to parse these files, and does not implement most config file features
(such as includes, quoted values and `=` operator.)

The new runtests workaround tests OK with the:
- default CircleCI configuration, disabling 1459 automatically.
- a sudoless configuration fix, with 1459 run successfully.
  Also keep setting this option in CircleCI jobs.
- a sudo configuration fix, with 1459 run successfully.
Ref: https://app.circleci.com/pipelines/github/curl/curl/16492/workflows/56f39335-97ba-412c-9a9b-3d662694375a

GHA jobs are not affected and they work fine, with 1459 running successfully
before and after this patch.

It's possible the libssh API offers ways to control config file use
and/or set the strict host checking option programatically. Maybe
to enable in debug mode (albeit CircleCI job are not debug-enabled),
or offer an option for them. It may be something for a future patch.

Follow-up to 23540923e1b09ce00dc08bab3bb3a2c0e62ba4e7 #8622
Follow-up to 4b01a57c95fd4c041dfa4a41834c761658ea89ee #8548
Follow-up to bdc664a64002a7df66f34159454844e6b6f5515f #8490
Follow-up to 7c140f6b2d90975629ba81a23acbef4363a3e6fe #8444

Ref: 6d9c5c91b9fd5f3a2733363d1ded8f70b6c24e5d #19549

Closes #19557

.circleci/config.yml
docs/tests/FILEFORMAT.md
tests/data/test1459
tests/runtests.pl

index 64fb03c8756950d2b89adc6c150c38dcc9282e32..30eec16e5ae0723d1670273c8b45ee8a136a82e2 100644 (file)
@@ -105,6 +105,10 @@ commands:
       - run:
           command: |
             source ~/venv/bin/activate
+            # Revert a CircleCI-specific local setting that makes test 1459
+            # return 67 (CURLE_LOGIN_DENIED) instead of the
+            # expected 60 (CURLE_PEER_FAILED_VERIFICATION).
+            echo 'StrictHostKeyChecking yes' >> ~/.ssh/config
             make -j3 V=1 test-ci TFLAGS='-j14'
 
 executors:
index 3897deb9cb09e7c2ecfa291a5b01c45186013cf9..c5c1bcfe90a7cc968f7d1410297ac4d20b2e80e9 100644 (file)
@@ -504,7 +504,7 @@ Features testable here are:
 - `large-size` (size_t is larger than 32-bit)
 - `libssh2`
 - `libssh`
-- `oldlibssh` (versions before 0.9.4)
+- `badlibssh` (libssh configuration incompatible with the test suite)
 - `libz`
 - `local-http`. The HTTP server runs on 127.0.0.1
 - `manual`
index e4901d74f06c5b3b05773a91a94b4b261f409465..6f3105e8ed21e2962f629fa6f05f59e1616b1446 100644 (file)
@@ -14,7 +14,7 @@ sftp
 </server>
 <features>
 sftp
-!oldlibssh
+!badlibssh
 </features>
 <name>
 SFTP with corrupted known_hosts
@@ -30,7 +30,8 @@ R93Ey5VtBeBblYTRlFXBWJgKFcTKBRJ/O4qBZwbUgt10AHj31i6h8NehfT19tR8wG/YCmj3KtYLHmwdz
 
 # Verify data after the test has been "shot"
 <verify>
-# old libssh installs return the wrong thing
+# badlibssh configurations return the wrong thing: 67 CURLE_LOGIN_DENIED,
+# instead of 60 CURLE_PEER_FAILED_VERIFICATION.
 <errorcode>
 60
 </errorcode>
index 226573941d354d5e55187df9bc399e717225eb3f..e1608e0aaa8b5b0799b482c3fa8e19ae0a0faeb1 100755 (executable)
@@ -632,11 +632,20 @@ sub checksystemfeatures {
             }
             if($libcurl =~ /libssh\/([0-9.]*)\//i) {
                 $feature{"libssh"} = 1;
-                if($1 =~ /(\d+)\.(\d+).(\d+)/) {
-                    my $v = $1 * 100 + $2 * 10 + $3;
-                    if($v < 94) {
-                        # before 0.9.4
-                        $feature{"oldlibssh"} = 1;
+                # Detect simple cases of default libssh configuration files ending up
+                # setting `StrictHostKeyChecking no`. include files, quoted values,
+                # '=value' format not implemented.
+                $feature{"badlibssh"} = 0;
+                foreach my $libssh_configfile (('/etc/ssh/ssh_config', $ENV{'HOME'} . '/.ssh/config')) {
+                    if(open(my $fd, '<', $libssh_configfile)) {
+                        while(my $line = <$fd>) {
+                            chomp $line;
+                            if($line =~ /^\s*StrictHostKeyChecking\s+(yes|no)\s*$/) {
+                                $feature{"badlibssh"} = ($1 eq 'no' ? 1 : 0);
+                                last;  # Do as openssh and libssh
+                            }
+                        }
+                        close($fd);
                     }
                 }
             }