Weekly Padgett

No. 0431 min read

Exit codes are an API. Yes, that little integer.

Corkscrew reported success without establishing a tunnel. Fix the damned status, but don't pretend OpenSSH just copies its ProxyCommand's return code.

A person holds a green circular paddle beside a striped barrier, with a car facing a brick wall.
File photoDramatization. No corkscrew was harmed.

You connect to a proxy, it accepts your connection, and then it closes before sending any status. Corkscrew[1]Ref. 1Corkscrew github.com reported success anyway, with exit status zero recorded in the audit. Nothing had established a tunnel, but there was the little integer telling the caller everything was fine.

The code took a break out of the loop and reached exit(0)[2]Ref. 2exit(0) man7.org. By then, the program hadn't preserved why the loop ended, so the final line couldn't tell a failed setup from anything else.

Standard error is for giving the operator enough context to investigate. Status is the machine-readable result for the caller. I want both. Writing a beautiful explanation of the failure doesn't excuse sending the machine the wrong answer (the machine wasn't admiring your prose anyway).

OpenSSH[3]Ref. 3OpenSSH openssh.com still speaks SSH over the stream. An empty stream can't complete an SSH handshake because the helper gave itself a passing grade.

The ProxyCommand documentation[4]Ref. 4ProxyCommand documentation man.openbsd.org describes a command that reads standard input and writes standard output. In the ordinary pipe-based path in OpenSSH's source[5]Ref. 5OpenSSH's source github.com, the client creates pipes, starts the helper and attaches those pipes as its connection. It does not wait for the helper's final exit status as a CONNECT success check before beginning SSH.

OpenSSH's documented exit status is the remote command's exit status, or 255 if an error occurred. The helper doesn't get to choose that number. It doesn't promise to pass through the ProxyCommand's numeric status. An arbitrary nonzero helper exit doesn't mean SSH returns that same value.

I can't fix this by replacing every zero with one, either. A relay can reach a normal end of stream, and calling an ordinary disconnection a failure would just annoy a different set of people. I need to preserve why the loop ended before I choose the damned integer.

References

  1. Corkscrew github.com ↩
  2. exit(0) man7.org ↩
  3. OpenSSH openssh.com ↩
  4. ProxyCommand documentation man.openbsd.org ↩
  5. OpenSSH's source github.com ↩
corkscrewunixsshtesting

More on this beat